From jose@calhariz.com Sun Nov 1 09:10:50 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 A5E8A7F54 for ; Sun, 1 Nov 2015 09:10:50 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 1F0B9AC003 for ; Sun, 1 Nov 2015 07:10:49 -0800 (PST) X-ASG-Debug-ID: 1446390645-04cb6c7b8618d200001-NocioJ Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [217.70.183.194]) by cuda.sgi.com with ESMTP id f7FlQbuUi0bf2u7f (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 01 Nov 2015 07:10:45 -0800 (PST) X-Barracuda-Envelope-From: jose@calhariz.com X-Barracuda-Apparent-Source-IP: 217.70.183.194 Received: from mfilter27-d.gandi.net (mfilter27-d.gandi.net [217.70.178.155]) by relay2-d.mail.gandi.net (Postfix) with ESMTP id 91DBEC5A40 for ; Sun, 1 Nov 2015 16:10:44 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at mfilter27-d.gandi.net Received: from relay2-d.mail.gandi.net ([IPv6:::ffff:217.70.183.194]) by mfilter27-d.gandi.net (mfilter27-d.gandi.net [::ffff:10.0.15.180]) (amavisd-new, port 10024) with ESMTP id EXzpSEy0YG4p for ; Sun, 1 Nov 2015 16:10:43 +0100 (CET) X-Originating-IP: 31.51.17.90 Received: from [192.168.1.1] (host31-51-17-90.range31-51.btcentralplus.com [31.51.17.90]) (Authenticated sender: jose@calhariz.com) by relay2-d.mail.gandi.net (Postfix) with ESMTPSA id F3D88C5A44 for ; Sun, 1 Nov 2015 16:10:42 +0100 (CET) Message-ID: <56362B71.4070709@calhariz.com> Date: Sun, 01 Nov 2015 15:10:41 +0000 From: Jose M Calhariz User-Agent: Mozilla/5.0 (X11; Linux i686 on x86_64; rv:31.0) Gecko/20100101 Icedove/31.8.0 MIME-Version: 1.0 To: xfs@oss.sgi.com Subject: Problems compiling xfsdump on Debian unstable Content-Type: multipart/signed; micalg=pgp-sha256; protocol="application/pgp-signature"; boundary="qVsehd3HWmHQjmB5FRtOvcxXR3p8hVJ7M" X-ASG-Orig-Subj: Problems compiling xfsdump on Debian unstable X-Barracuda-Connect: relay2-d.mail.gandi.net[217.70.183.194] X-Barracuda-Start-Time: 1446390645 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24009 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- This is an OpenPGP/MIME signed message (RFC 4880 and 3156) --qVsehd3HWmHQjmB5FRtOvcxXR3p8hVJ7M Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable I am trying to compile the latest xfsdump from the git repository. While I can compile it on Debian stable (jessie) and testing(stretch), I have problems compiling it on Debian unstable.=20 I think the problem is because of new software on Debian unstable. One fragment of the errors that I get when linking the .o files: cldmgr.o: In function `cldmgr_create': /home/cal/source.xfsdump/git-xfsdump/dump/cldmgr.c:82: undefined reference to `assert' /home/cal/source.xfsdump/git-xfsdump/dump/cldmgr.c:101: undefined reference to `_' /home/cal/source.xfsdump/git-xfsdump/dump/cldmgr.c:86: undefined reference to `_' content_common.o: In function `Media_prompt_change': /home/cal/source.xfsdump/git-xfsdump/dump/content_common.c:65: undefined reference to `_' /home/cal/source.xfsdump/git-xfsdump/dump/content_common.c:69: undefined reference to `assert' /home/cal/source.xfsdump/git-xfsdump/dump/content_common.c:74: undefined reference to `_' /home/cal/source.xfsdump/git-xfsdump/dump/content_common.c:80: undefined reference to `assert' /home/cal/source.xfsdump/git-xfsdump/dump/content_common.c:83: undefined reference to `_' /home/cal/source.xfsdump/git-xfsdump/dump/content_common.c:85: undefined reference to `_' /home/cal/source.xfsdump/git-xfsdump/dump/content_common.c:86: undefined reference to `assert' /home/cal/source.xfsdump/git-xfsdump/dump/content_common.c:106: undefined reference to `_' /home/cal/source.xfsdump/git-xfsdump/dump/content_common.c:112: undefined reference to `assert' /home/cal/source.xfsdump/git-xfsdump/dump/content_common.c:117: undefined reference to `_' /home/cal/source.xfsdump/git-xfsdump/dump/content_common.c:121: undefined reference to `assert' /home/cal/source.xfsdump/git-xfsdump/dump/content_common.c:108: undefined reference to `assert' /home/cal/source.xfsdump/git-xfsdump/dump/content_common.c:109: undefined reference to `_' /home/cal/source.xfsdump/git-xfsdump/dump/content_common.c:112: undefined reference to `assert' /home/cal/source.xfsdump/git-xfsdump/dump/content_common.c:117: undefined reference to `_' /home/cal/source.xfsdump/git-xfsdump/dump/content_common.c:121: undefined reference to `assert' dlog.o: In function `dlog_string_query_print': /home/cal/source.xfsdump/git-xfsdump/dump/dlog.c:362: undefined reference to `assert' dlog.o: In function `promptinput': /home/cal/source.xfsdump/git-xfsdump/dump/dlog.c:508: undefined reference to `_' /home/cal/source.xfsdump/git-xfsdump/dump/dlog.c:486: undefined reference to `_' /home/cal/source.xfsdump/git-xfsdump/dump/dlog.c:503: undefined reference to `_' /home/cal/source.xfsdump/git-xfsdump/dump/dlog.c:513: undefined reference to `assert' /home/cal/source.xfsdump/git-xfsdump/dump/dlog.c:499: undefined reference to `_' /home/cal/source.xfsdump/git-xfsdump/dump/dlog.c:490: undefined reference to `_' dlog.o: In function `dlog_init': /home/cal/source.xfsdump/git-xfsdump/dump/dlog.c:60: undefined reference to `assert' dlog.o: In function `dlog_multi_query': /home/cal/source.xfsdump/git-xfsdump/dump/dlog.c:189: undefined reference to `assert' /home/cal/source.xfsdump/git-xfsdump/dump/dlog.c:221: undefined reference to `_' /home/cal/source.xfsdump/git-xfsdump/dump/dlog.c:257: undefined reference to `_' /home/cal/source.xfsdump/git-xfsdump/dump/dlog.c:213: undefined reference to `_' dlog.o: In function `dlog_string_query': /home/cal/source.xfsdump/git-xfsdump/dump/dlog.c:298: undefined reference to `assert' /home/cal/source.xfsdump/git-xfsdump/dump/dlog.c:310: undefined reference to `_' drive.o: In function `drive_alloc': /home/cal/source.xfsdump/git-xfsdump/dump/drive.c:359: undefined reference to `assert' drive.o: In function `drive_init1': /home/cal/source.xfsdump/git-xfsdump/dump/drive.c:91: undefined reference to `assert' /home/cal/source.xfsdump/git-xfsdump/dump/drive.c:145: undefined reference to `assert' /home/cal/source.xfsdump/git-xfsdump/dump/drive.c:218: undefined reference to `assert' /home/cal/source.xfsdump/git-xfsdump/dump/drive.c:223: undefined reference to `_' /home/cal/source.xfsdump/git-xfsdump/dump/drive.c:172: undefined reference to `assert' /home/cal/source.xfsdump/git-xfsdump/dump/drive.c:186: undefined reference to `_' /home/cal/source.xfsdump/git-xfsdump/dump/drive.c:110: undefined reference to `assert' /home/cal/source.xfsdump/git-xfsdump/dump/drive.c:155: undefined reference to `_' /home/cal/source.xfsdump/git-xfsdump/dump/drive.c:132: undefined reference to `_' drive.o: In function `drive_allochdrs': /home/cal/source.xfsdump/git-xfsdump/dump/drive.c:414: undefined reference to `assert' /home/cal/source.xfsdump/git-xfsdump/dump/drive.c:400: undefined reference to `assert' drive_scsitape.o: In function `do_get_align_cnt': /home/cal/source.xfsdump/git-xfsdump/dump/drive_scsitape.c:2132: undefined reference to `assert' /home/cal/source.xfsdump/git-xfsdump/dump/drive_scsitape.c:2133: undefined reference to `assert' /home/cal/source.xfsdump/git-xfsdump/dump/drive_scsitape.c:2134: undefined reference to `assert' Software on testing that may makes a difference: gcc --version gcc (Debian 4.9.3-3) 4.9.3 Copyright (C) 2015 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is N= O warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOS= E. dpkg --status xfslibs-dev Package: xfslibs-dev Status: install ok installed Priority: extra Section: libdevel Installed-Size: 80 Maintainer: XFS Development Team Architecture: amd64 Source: xfsprogs Version: 3.2.1 Depends: libc6-dev | libc-dev, uuid-dev, xfsprogs (>=3D 3.0.0) Breaks: xfsprogs (<< 3.0.0) Description: XFS filesystem-specific static libraries and headers On Debian unstable: gcc --version gcc (Debian 5.2.1-23) 5.2.1 20151028 Copyright (C) 2015 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is N= O warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOS= E. 0 2 Dom Nov 01 15:02:32 CWD=3D~/source.xfsdump/git-xfsdump cal@chr-amd64-sid.mccoy[3895]>dpkg --status xfslibs-dev Package: xfslibs-dev Status: install ok installed Priority: extra Section: libdevel Installed-Size: 219 Maintainer: XFS Development Team Architecture: amd64 Source: xfsprogs Version: 4.2.0 Depends: libc6-dev | libc-dev, uuid-dev, xfsprogs (>=3D 3.0.0) Breaks: xfsprogs (<< 3.0.0) Description: XFS filesystem-specific static libraries and headers Why is important to me to compile xfsdump on unstable. Because it was removed from Debian testing and because of that the amanda software was removed too. As the maintainer of amanda for Debian I am doing my best to fix this problem. I am not on the list. Kind regards Jose M Calhariz --qVsehd3HWmHQjmB5FRtOvcxXR3p8hVJ7M Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAEBCAAGBQJWNitxAAoJEDSKd41ohe+PQxUP/20XfbhoDU3l55hYQUm39BuW FPVg1X1wtuGALY2EVQ+75b46VnzJVr8kOIaZaOBiyYOOS+NMr2ZZsJ1W1CwB/rGo k5Pz6VTBijK3b8W9GrX1v3Qm96hEXm4I0uYZum1ZJN7Q0up+aQpuoZZWpOuMXRCt 7/JS4C254pK2YW2hRW6hK4Uz7YhCUJnYCbTEyI0yKgWsj6g4ulycqilK52062NiA vXiSqd8Y/lOQIPfYQKY4C0Zb2n97L47qa1TlfjH4UOfdBEni4Ys7aVehdtnV7KxE J8izGqlcWtZy7beuxEKnxXlY8EKZGNa4giabcRmyt57i1lzLwNC0w77naSBJ7Uuc J3pvy2Rviz6Q8xOLxHUkYcAPp74RoC/UzAj7lgEp6V3ykpwSFyNcXWZt4M/mb1yB SkDHYkDrPkcI9Je2vY+f87XW5bcHyVr0W9Miuub2atnBjlqsJa1V0atJSY/2vKk/ 86gf5DcIqD9wEyhBc1qkyWrIydjwm93kC+3VO1KbyevsBjTyT4RcYLaOj8P9b+ma 63EYL7qiQM9Y6P1Mj2Lz12lc1aSNynYA3SYfW64zbteFgjBzj1D7ca7Np1UavXX4 KyzVOTnfot/Pv6hYZjSjmjG70pxi4rDwy5SGUpstFaLZdf8Y3mXnf+oJsK2GB6vy v36ye3HtfqAXh3y1Cjpc =Slbi -----END PGP SIGNATURE----- --qVsehd3HWmHQjmB5FRtOvcxXR3p8hVJ7M-- From david@fromorbit.com Sun Nov 1 16:34:57 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 7F1A77F59 for ; Sun, 1 Nov 2015 16:34:57 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 1B02FAC002 for ; Sun, 1 Nov 2015 14:34:53 -0800 (PST) X-ASG-Debug-ID: 1446417286-04bdf0330b1b17c0001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id O073XhY0g2Dg8Zaq for ; Sun, 01 Nov 2015 14:34:47 -0800 (PST) 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: A2BnBwCtkjZW/8m/LHlegzuBQqo4Bosuiy+CX4M0BAICgSFNAQEBAQEBgQuENgEBBDocIxAIAxgJJQ8FJQMhE4gvwVgBAQEHAgEgGYYXhUWILIEUBZZDimyCMYF2mkxjhBgqNIV+AQEB Received: from ppp121-44-191-201.lns20.syd7.internode.on.net (HELO dastard) ([121.44.191.201]) by ipmail07.adl2.internode.on.net with ESMTP; 02 Nov 2015 09:04:45 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1Zt1Cq-0000ZW-Kq; Mon, 02 Nov 2015 09:34:32 +1100 Date: Mon, 2 Nov 2015 09:34:32 +1100 From: Dave Chinner To: Jose M Calhariz Cc: xfs@oss.sgi.com Subject: Re: Problems compiling xfsdump on Debian unstable Message-ID: <20151101223432.GE10656@dastard> X-ASG-Orig-Subj: Re: Problems compiling xfsdump on Debian unstable References: <56362B71.4070709@calhariz.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <56362B71.4070709@calhariz.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: 1446417286 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24018 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Sun, Nov 01, 2015 at 03:10:41PM +0000, Jose M Calhariz wrote: > I am trying to compile the latest xfsdump from the git repository. > > While I can compile it on Debian stable (jessie) and testing(stretch), I > have problems compiling it on Debian unstable. > I think the problem is because of new software on Debian unstable. Known issue - xfsdump had an unhealthy dependency on the unclean header files that shipped with xfsprogs. We sanitised the xfsprogs headers in 4.2.0, and didn't notice that xfsdump started complaining because my build machine was still using 3.2.4 headers to build xfsdump. I have patches under review to fix the xfsdump problems, I'll be doing a release of it as soon as the review is finished... Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Sun Nov 1 17:30:10 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 7FCEB7F59 for ; Sun, 1 Nov 2015 17:30:10 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 73186304062 for ; Sun, 1 Nov 2015 15:30:07 -0800 (PST) X-ASG-Debug-ID: 1446420602-04cb6c7b8519b440001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id 0qVvIG1CR0LfUR7k for ; Sun, 01 Nov 2015 15:30:03 -0800 (PST) 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: A2CCBgCTnzZW/8m/LHleDoMtgUKqMwEBAwEGiy6LL4YTBAICgSJNAQEBAQEBgQuENQEBAQMBOhwoCwgDGAklDwUlAyEBEhuIDQfBUgEBCAIBIBmGF4VFhEeDZYEUBZZDiA2FEIFhlm+DcmODRlIqNIQ1gUkBAQE Received: from ppp121-44-191-201.lns20.syd7.internode.on.net (HELO dastard) ([121.44.191.201]) by ipmail07.adl2.internode.on.net with ESMTP; 02 Nov 2015 10:00:01 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1Zt24K-0000e4-IN; Mon, 02 Nov 2015 10:29:48 +1100 Date: Mon, 2 Nov 2015 10:29:48 +1100 From: Dave Chinner To: Ross Zwisler , linux-kernel@vger.kernel.org, "H. Peter Anvin" , "J. Bruce Fields" , Theodore Ts'o , Alexander Viro , Andreas Dilger , Dan Williams , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@lists.01.org, x86@kernel.org, xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox Subject: Re: [RFC 00/11] DAX fsynx/msync support Message-ID: <20151101232948.GF10656@dastard> X-ASG-Orig-Subj: Re: [RFC 00/11] DAX fsynx/msync support References: <1446149535-16200-1-git-send-email-ross.zwisler@linux.intel.com> <20151030035533.GU19199@dastard> <20151030183938.GC24643@linux.intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151030183938.GC24643@linux.intel.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: 1446420603 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24021 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri, Oct 30, 2015 at 12:39:38PM -0600, Ross Zwisler wrote: > On Fri, Oct 30, 2015 at 02:55:33PM +1100, Dave Chinner wrote: > > On Thu, Oct 29, 2015 at 02:12:04PM -0600, Ross Zwisler wrote: > > > This patch series adds support for fsync/msync to DAX. > > > > > > Patches 1 through 8 add various utilities that the DAX code will eventually > > > need, and the DAX code itself is added by patch 9. Patches 10 and 11 are > > > filesystem changes that are needed after the DAX code is added, but these > > > patches may change slightly as the filesystem fault handling for DAX is > > > being modified ([1] and [2]). > > > > > > I've marked this series as RFC because I'm still testing, but I wanted to > > > get this out there so people would see the direction I was going and > > > hopefully comment on any big red flags sooner rather than later. > > > > > > I realize that we are getting pretty dang close to the v4.4 merge window, > > > but I think that if we can get this reviewed and working it's a much better > > > solution than the "big hammer" approach that blindly flushes entire PMEM > > > namespaces [3]. > > > > We need the "big hammer" regardless of fsync. If REQ_FLUSH and > > REQ_FUA don't do the right thing when it comes to ordering journal > > writes against other IO operations, then the filesystems are not > > crash safe. i.e. we need REQ_FLUSH/REQ_FUA to commit all outstanding > > changes back to stable storage, just like they do for existing > > storage.... > > I think that what I've got here (when it's fully working) will protect all the > cases that we need. > > AFAIK there are three ways that data can be written to a PMEM namespace: > > 1) Through the PMEM driver via either pmem_make_request(), pmem_rw_page() or > pmem_rw_bytes(). All of these paths sync the newly written data durably to > media before the I/O completes so they shouldn't have any reliance on > REQ_FUA/REQ_FLUSH. I suspect that not all future pmem devices will use this driver/interface/semantics. Further, REQ_FLUSH/REQ_FUA are more than just "put the data on stable storage" commands. They are also IO barriers that affect scheduling of IOs in progress and in the request queues. A REQ_FLUSH/REQ_FUA IO cannot be dispatched before all prior IO has been dispatched and drained from the request queue, and IO submitted after a queued REQ_FLUSH/REQ_FUA cannot be scheduled ahead of the queued REQ_FLUSH/REQ_FUA operation. IOWs, REQ_FUA/REQ_FLUSH not only guarantee data is on stable storage, they also guarantee the order of IO dispatch and completion when concurrent IO is in progress. > 2) Through the DAX I/O path, dax_io(). As with PMEM we flush the newly > written data durably to media before the I/O operation completes, so this path > shouldn't have any reliance on REQ_FUA/REQ_FLUSH. That's fine, but that's not the problem we need solved ;) > 3) Through mmaps set up by DAX. This is the path we are trying to protect > with the dirty page tracking and flushing in this patch set, and I think that > this is the only path that has reliance on REQ_FLUSH. Quite possibly this is the case for the current intel pmem driver, but I don't look at the functionality from that perspective. Dirty page tracking is needed to enable "data writeback", whether it be CPU cachelines via pcommit() or dirty pages via submit_bio(). How the pages get dirty is irrelevant - the fact is they are dirty and we need to do /something/ to ensure they are correctly written back to the storage layer. REQ_FLUSH is needed to guarantee all data that has been written back to the storage layer is persistent in that layer. How a /driver/ manages that is up to the driver - the actual implementation is irrelevant to the higher layers. i.e. what we are concerned about at the filesystem level is that: a) "data writeback" is started correctly; b) the "data writeback" is completed; and c) volatile caches are completely flushed before we write the metadata changes that reference that data to the journal via FUA e.g. we could have pmem, but we are using buffered IO (i.e. non-DAX) and a hardware driver that doesn't flush CPU cachelines in the physical IO path. This requires that driver to flush CPU cachelines and place memory barriers in REQ_FLUSH operations, as well as after writing the data in REQ_FUA operations. Yes, this is different to the way the intel pmem drivers work (i.e. as noted in 1) above), but it is /not wrong/ as long as REQ_FLUSH/REQ_FUA also flush dirty cpu cachelines. IOWs, the high level code we write that implements fsync for DAX needs to be generic enough so that when something slightly different comes along we don't have to throw everything away and start again. I think your code will end up being generic enough to handle this, but let's make sure we don't implement something that can only work with pmem hardware/drivers that do all IO as fully synchronous to the stable domain... Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Sun Nov 1 17:36:53 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 8D8277F59 for ; Sun, 1 Nov 2015 17:36:53 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 7E8788F8033 for ; Sun, 1 Nov 2015 15:36:50 -0800 (PST) X-ASG-Debug-ID: 1446421006-04cb6c7b8619b680001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id XouhuFOGSgIqb5ey for ; Sun, 01 Nov 2015 15:36:47 -0800 (PST) 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: A2DGBgCHoDZW/8m/LHlegzuBQqozAQEDAQaLLosvhhMCAgEBAoEiTQEBAQEBAYELhDUBAQEDATocIxAIAxgJJQ8FJQMhExuIDQfBSAEBCAIBIBmGF4Q/gQaJQAWWQ4gNhRCcQmOCER2Baio0AYV9AQEB Received: from ppp121-44-191-201.lns20.syd7.internode.on.net (HELO dastard) ([121.44.191.201]) by ipmail07.adl2.internode.on.net with ESMTP; 02 Nov 2015 10:06:45 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1Zt2Aq-0000fH-HT; Mon, 02 Nov 2015 10:36:32 +1100 Date: Mon, 2 Nov 2015 10:36:32 +1100 From: Dave Chinner To: Dan Williams Cc: Ross Zwisler , "linux-kernel@vger.kernel.org" , "H. Peter Anvin" , "J. Bruce Fields" , Theodore Ts'o , Alexander Viro , Andreas Dilger , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel , Linux MM , "linux-nvdimm@lists.01.org" , X86 ML , xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox Subject: Re: [RFC 00/11] DAX fsynx/msync support Message-ID: <20151101233632.GG10656@dastard> X-ASG-Orig-Subj: Re: [RFC 00/11] DAX fsynx/msync support References: <1446149535-16200-1-git-send-email-ross.zwisler@linux.intel.com> <20151030194300.GA22670@linux.intel.com> 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: 1446421006 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24021 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri, Oct 30, 2015 at 12:51:40PM -0700, Dan Williams wrote: > On Fri, Oct 30, 2015 at 12:43 PM, Ross Zwisler > wrote: > > On Fri, Oct 30, 2015 at 11:34:07AM -0700, Dan Williams wrote: > >> This is great to have when the flush-the-world solution ends up > >> killing performance. However, there are a couple mitigating options > >> for workloads that dirty small amounts and flush often that we need to > >> collect data on: > >> > >> 1/ Using cache management and pcommit from userspace to skip calls to > >> msync / fsync. Although, this does not eliminate all calls to > >> blkdev_issue_flush as the fs may invoke it for other reasons. I > >> suspect turning on REQ_FUA support eliminates a number of those > >> invocations, and pmem already satisfies REQ_FUA semantics by default. > > > > Sure, I'll turn on REQ_FUA in addition to REQ_FLUSH - I agree that PMEM > > already handles the requirements of REQ_FUA, but I didn't realize that it > > might reduce the number of REQ_FLUSH bios we receive. > > I'll let Dave chime in, but a lot of the flush requirements come from > guaranteeing the state of the metadata, if metadata updates can be > done with REQ_FUA then there is no subsequent need to flush. No need for cache flushes in this case, but we still need the IO scheduler to order such operations correctly. > >> 2/ Turn off DAX and use the page cache. As Dave mentions [1] we > >> should enable this control on a per-inode basis. I'm folding in this > >> capability as a blkdev_ioctl for the next version of the raw block DAX > >> support patch. > > > > Umm...I think you just said "the way to avoid this delay is to just not use > > DAX". :) I don't think this is where we want to go - we are trying to make > > DAX better, not abandon it. > > That's a bit of an exaggeration. Avoiding DAX where it is not > necessary is not "abandoning DAX", it's using the right tool for the > job. Page cache is fine for many cases. Think btrfs - any file that uses COW can't use DAX for write. Everything has to be buffered, unless the nodatacow flag is set, and then DAX can be used. Indeed, on ext4 if you are using file encryption you can't use DAX. IOWs, we already know that we have to support mixed DAX/non-DAX access within the same filesystem, so I'm with Dan here... Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Sun Nov 1 19:15:06 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 AC5137F59 for ; Sun, 1 Nov 2015 19:15:06 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 8CCB38F8033 for ; Sun, 1 Nov 2015 17:15:03 -0800 (PST) X-ASG-Debug-ID: 1446426900-04cb6c7b8619e260001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id u5JPXvsarYSTCbcf for ; Sun, 01 Nov 2015 17:15:01 -0800 (PST) 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: A2DJBgBiuDZW/8m/LHlegzuBQqozAQEDAQaBZolIhSaGCYYTAgIBAQKBIk0BAQEBAQGBC4Q1AQEBAwEnExwjBQsIAw4HAwklDwUlAyETiCgHwUEBCwEgGYYXhUWFBIQ8BZZDjR2cQmOEGCo0hX4BAQE Received: from ppp121-44-191-201.lns20.syd7.internode.on.net (HELO dastard) ([121.44.191.201]) by ipmail07.adl2.internode.on.net with ESMTP; 02 Nov 2015 11:44:46 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1Zt3hh-0000pM-Hk; Mon, 02 Nov 2015 12:14:33 +1100 Date: Mon, 2 Nov 2015 12:14:33 +1100 From: Dave Chinner To: Brian Foster Cc: ross.zwisler@linux.intel.com, jack@suse.cz, xfs@oss.sgi.com Subject: Re: [PATCH 3/6] xfs: Don't use unwritten extents for DAX Message-ID: <20151102011433.GW19199@dastard> X-ASG-Orig-Subj: Re: [PATCH 3/6] xfs: Don't use unwritten extents for DAX References: <1445225238-30413-1-git-send-email-david@fromorbit.com> <1445225238-30413-4-git-send-email-david@fromorbit.com> <20151029142950.GE11663@bfoster.bfoster> <20151029233756.GS19199@dastard> <20151030123657.GC54905@bfoster.bfoster> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151030123657.GC54905@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: 1446426900 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24024 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri, Oct 30, 2015 at 08:36:57AM -0400, Brian Foster wrote: > On Fri, Oct 30, 2015 at 10:37:56AM +1100, Dave Chinner wrote: > > On Thu, Oct 29, 2015 at 10:29:50AM -0400, Brian Foster wrote: > > > On Mon, Oct 19, 2015 at 02:27:15PM +1100, Dave Chinner wrote: > > > > From: Dave Chinner > > > > > ... > > > > + /* > > > > + * For DAX, we do not allocate unwritten extents, but instead we zero > > > > + * the block before we commit the transaction. Ideally we'd like to do > > > > + * this outside the transaction context, but if we commit and then crash > > > > + * we may not have zeroed the blocks and this will be exposed on > > > > + * recovery of the allocation. Hence we must zero before commit. > > > > + * Further, if we are mapping unwritten extents here, we need to zero > > > > + * and convert them to written so that we don't need an unwritten extent > > > > + * callback for DAX. This also means that we need to be able to dip into > > > > + * the reserve block pool if there is no space left but we need to do > > > > + * unwritten extent conversion. > > > > + */ > > > > + if (IS_DAX(VFS_I(ip))) { > > > > + bmapi_flags = XFS_BMAPI_CONVERT | XFS_BMAPI_ZERO; > > > > + tp->t_flags |= XFS_TRANS_RESERVE; > > > > + } > > > > > > Am I following the commit log description correctly in that block > > > zeroing is only required for DAX faults? Do we zero blocks for DAX DIO > > > as well to be consistent, or is that also required (because it looks > > > like we still have end_io completion for dio writes anyways)? > > > > DAX DIO will do the zeroing rather than using unwritten extents, > > too. But we still have DIO IO completion as that needs to do file > > size updates. > > > > Right, my question is: is the DAX DIO zeroing required to avoid the > races described as the purpose for this patch, or is this just here as a > simplification? In other words, why not do block zeroing only for DAX > faults and not DAX/DIO? Because the only reason the DIO code does 'allocate unwritten; convert unwritten on IO completion' is so that if we have: allocate trans_commit .... log force journal IO submit .... journal IO completion submit data io crash We don't expose allocated blocks containing stale data to userspace via recovery. The allcoation uses unwritten extents to ensure that if the allocation is recovered without the correspending completion, it reads as zeros rather whatever was previously on disk in taht location. For DAX, we can zero the blocks inside the allocation transaction for direct IO, and hence even if we have the above happen, we'll only ever expose zeros. Hence we don't need unwritten extents in the DIO path to avoid stale data exposure, and so we can simply avoid all that extra overhead of unwritten extent conversion on completion... > I ask because my understanding is the purpose of this patch is a special > atomic zeroed allocation requirement just for mmap. The requirement is set by DAX+mmap; the implementation is a generic "allocate zeroed blocks" mechanism that can be applied to any allocation that uses unwritten extents to allocate zeroed blocks if zeroing is more efficient than using unwritten extents.... > Unless there is some > special mixed dio/mmap case I'm missing, doing so for DAX/DIO basically > causes a clear_pmem() over every page sized chunk of the target I/O > range for which we already have the data. I don't follow - this only zeros blocks when we do allocation of new blocks or overwrite unwritten extents, not on blocks which we already have written data extents allocated for... Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Sun Nov 1 19:21:51 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 DE51B7F59 for ; Sun, 1 Nov 2015 19:21:51 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id CEB2A304032 for ; Sun, 1 Nov 2015 17:21:48 -0800 (PST) X-ASG-Debug-ID: 1446427305-04cb6c7b8719e4d0001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id K7jBJMRLuMs5Awhz for ; Sun, 01 Nov 2015 17:21:46 -0800 (PST) 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: A2DbBgBiuTZW/8m/LHlegzuBAEKqMwEBAwEGiy6FJoYJhhMCAgEBAoEiTQEBAQEBAYELhDUBAQEEOhwjEAgDDgcDCSUPBSUDIROIL8FAAQEIAgEgGYYXhUWJQAWWQ40djy+NE2OEGCo0hX4BAQE Received: from ppp121-44-191-201.lns20.syd7.internode.on.net (HELO dastard) ([121.44.191.201]) by ipmail07.adl2.internode.on.net with ESMTP; 02 Nov 2015 11:51:44 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1Zt3oS-0000qD-55; Mon, 02 Nov 2015 12:21:32 +1100 Date: Mon, 2 Nov 2015 12:21:32 +1100 From: Dave Chinner To: Brian Foster Cc: ross.zwisler@linux.intel.com, jack@suse.cz, xfs@oss.sgi.com Subject: Re: [PATCH 2/6] xfs: introduce BMAPI_ZERO for allocating zeroed extents Message-ID: <20151102012132.GX19199@dastard> X-ASG-Orig-Subj: Re: [PATCH 2/6] xfs: introduce BMAPI_ZERO for allocating zeroed extents References: <1445225238-30413-1-git-send-email-david@fromorbit.com> <1445225238-30413-3-git-send-email-david@fromorbit.com> <20151029142757.GD11663@bfoster.bfoster> <20151029233548.GR19199@dastard> <20151030123608.GB54905@bfoster.bfoster> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151030123608.GB54905@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: 1446427305 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24024 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri, Oct 30, 2015 at 08:36:08AM -0400, Brian Foster wrote: > On Fri, Oct 30, 2015 at 10:35:48AM +1100, Dave Chinner wrote: > > On Thu, Oct 29, 2015 at 10:27:58AM -0400, Brian Foster wrote: > > > On Mon, Oct 19, 2015 at 02:27:14PM +1100, Dave Chinner wrote: > > > > From: Dave Chinner > > > > > ... > > > > > I suspect there's no use case to pass XFS_BMAPI_ZERO for new unwritten > > > allocations, but if the flag is passed, doesn't this cause duplicate > > > block zeroing? > > > > It probably would, but.... > > > > > Perhaps we should drop the zero flag from 'flags' after > > > allocation in xfs_bmapi_write() just to ensure this executes in one > > > place or the other..? > > > > I think that if we hit this, we're doing something else wrong - why > > would we allocate unwritten extents and still need to initialise > > them to zero? > > > > No idea, really (as noted above). ;) It just looked like it could be > invoked twice per bmapi call, nothing else I saw prevented it, and it > looks easily avoidable. Maybe somebody down the road decides to turn on > block zeroing unconditionally in the block allocator due to hardware > support or some such. Or maybe we'll never hit the problem. The point is > that this code will inevitably be modified/enhanced down the road and > nobody is going to remember that the zeroing is invoked twice in a > particular prealloc codepath. > > If we don't want to mess with the flags, how about an assert somewhere > so it's explicit the bmapi implementation doesn't expect this > combination of flags? Easy enough. I'll add this to the initial asserts in xfs_bmapi_write(): + /* + * we can allocate unwritten extents or pre-zero allocated blocks, + * but it makes no sense to do both at once. This would result in + * zeroing the unwritten extent twice, but it still being an + * unwritten extent.... + */ + ASSERT((flags & (XFS_BMAPI_PREALLOC|XFS_BMAPI_ZERO)) != + (XFS_BMAPI_PREALLOC|XFS_BMAPI_ZERO)); Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Sun Nov 1 20:54:26 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 746877F62 for ; Sun, 1 Nov 2015 20:54:26 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 52FB1304053 for ; Sun, 1 Nov 2015 18:54:23 -0800 (PST) X-ASG-Debug-ID: 1446432859-04cb6c7b851a0b80001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id Bt675rBTHykwyiw7 for ; Sun, 01 Nov 2015 18:54:19 -0800 (PST) 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: A2CDBgDYzzZW/+rW03ZegzuBQqo4AQEDAQaLLoUmhgmGEwQCAoEkTQEBAQEBAYELhDUBAQEDATocIwULCAMOCgklDwUlAyETiCgHwTEBAQgCIRmGF4VFiUAFlkONHYFhhD+HNI5uY4IRHYFqKjSENiWBIwEBAQ Received: from ppp118-211-214-234.lns20.syd4.internode.on.net (HELO dastard) ([118.211.214.234]) by ipmail07.adl2.internode.on.net with ESMTP; 02 Nov 2015 13:24:05 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1Zt5Fo-0000yd-AN; Mon, 02 Nov 2015 13:53:52 +1100 Date: Mon, 2 Nov 2015 13:53:52 +1100 From: Dave Chinner To: Andreas Gruenbacher Cc: Brian Foster , xfs@oss.sgi.com Subject: Re: [PATCH v2 0/5] xfs: SGI ACL Fixes Message-ID: <20151102025352.GY19199@dastard> X-ASG-Orig-Subj: Re: [PATCH v2 0/5] xfs: SGI ACL Fixes References: <1446217508-22157-1-git-send-email-agruenba@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1446217508-22157-1-git-send-email-agruenba@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: 1446432859 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24026 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri, Oct 30, 2015 at 04:05:03PM +0100, Andreas Gruenbacher wrote: > Here is a reworked patch queue that also handles setting SGI_ACL_{FILE,DEFAULT} > via XFS_IOC_ATTRMULTI_BY_HANDLE. Please review. > > Thanks, > Andreas > > Andreas Gruenbacher (5): > xfs: Validate the length of on-disk ACLs > xfs: Plug memory leak in xfs_attrmulti_attr_set Ok, I've taken these two patches for the upcoming merge window as they fix bugs, but I've taken Brian's cached ACL invalidation patch instead of these: > xfs: SGI ACLs: Fix caching and mode setting > xfs: Add namespace parameter to the xfs kuid/kgid <=> uid/gid wrappers > xfs: SGI ACLs: Map uid/gid namespaces I'm not yet convinced that these patches are the right way to solve the given issue as they may interact badly with xfsdump/restore. However, I do want the kernel code to behave correctly after xfs_restore runs and Brian's change is enough to do this. If we do decide that we need to make the above changes to the posix acl code, it's easy enough to replace this invalidation code. Cheers, Dave. -- Dave Chinner david@fromorbit.com From nscott@redhat.com Sun Nov 1 21:26:11 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 32C397F53 for ; Sun, 1 Nov 2015 21:26:11 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id C0881AC001 for ; Sun, 1 Nov 2015 19:26:07 -0800 (PST) X-ASG-Debug-ID: 1446434765-04cbb0660e1b3e60001-NocioJ Received: from mx3-phx2.redhat.com (mx3-phx2.redhat.com [209.132.183.24]) by cuda.sgi.com with ESMTP id HarF4HafDwsoZpNJ (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Sun, 01 Nov 2015 19:26:05 -0800 (PST) X-Barracuda-Envelope-From: nscott@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.24 Received: from zmail20.collab.prod.int.phx2.redhat.com (zmail20.collab.prod.int.phx2.redhat.com [10.5.83.23]) by mx3-phx2.redhat.com (8.13.8/8.13.8) with ESMTP id tA23PxXO007512; Sun, 1 Nov 2015 22:25:59 -0500 Date: Sun, 1 Nov 2015 22:25:58 -0500 (EST) From: Nathan Scott Reply-To: Nathan Scott To: Jose M Calhariz Cc: xfs@oss.sgi.com Message-ID: <1847596501.219026.1446434758818.JavaMail.zimbra@redhat.com> In-Reply-To: <56362B71.4070709@calhariz.com> References: <56362B71.4070709@calhariz.com> Subject: Re: Problems compiling xfsdump on Debian unstable MIME-Version: 1.0 X-ASG-Orig-Subj: Re: Problems compiling xfsdump on Debian unstable Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-Originating-IP: [10.64.50.239] X-Mailer: Zimbra 8.0.6_GA_5922 (ZimbraWebClient - FF37 (Linux)/8.0.6_GA_5922) Thread-Topic: Problems compiling xfsdump on Debian unstable Thread-Index: h43CLwGEPeFEPk41rTd5trB+BciaTg== X-Barracuda-Connect: mx3-phx2.redhat.com[209.132.183.24] X-Barracuda-Start-Time: 1446434765 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://192.48.176.25:443/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.24026 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.01 THREAD_INDEX thread-index: AcO7Y8iR61tzADqsRmmc5wNiFHEOig== 0.01 THREAD_TOPIC Thread-Topic: ...(Japanese Subject)... Hi Jose, ----- Original Message ----- > I am trying to compile the latest xfsdump from the git repository. The underlying problem was related to changes in xfsprogs header files which had unanticipated dependencies in xfsdump - Dave has been working through all these issues (iow, removing the unanticipated dependencies, by updating xfsdump code) and the next release of xfsdump will resolve this build failure. It's not a trivial change though, so our best bet (IMO) is to wait on those upstream changes from Dave and then get a new package build into unstable & testing. cheers. -- Nathan From agruenba@redhat.com Sun Nov 1 21:41:35 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 1EF127F5E for ; Sun, 1 Nov 2015 21:41:35 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 9E142AC002 for ; Sun, 1 Nov 2015 19:41:34 -0800 (PST) X-ASG-Debug-ID: 1446435690-04cbb0660c1b4510001-NocioJ Received: from mail-lf0-f48.google.com (mail-lf0-f48.google.com [209.85.215.48]) by cuda.sgi.com with ESMTP id EKVUbQRPdcEvQMbA (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Sun, 01 Nov 2015 19:41:31 -0800 (PST) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.85.215.48 Received: by lfgh9 with SMTP id h9so9431352lfg.1 for ; Sun, 01 Nov 2015 19:41:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat_com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=PggG/W8oWZzrjgc+fiyGK62ciddT7QbaXDXHAw3wk/4=; b=k4uLjHf6V7hrHnjhYdRUZ5mC+w3YB9NxqilfFTsqGrCjy1HNGlzIPwpxrp0uEb5zbU yg+Zopt6Dq+0ogcCa5q4yrDKh8hTi5bxeA4vGWX+bVkPpoLqRj4wkfMKLZNN/IHqVZT1 d2NIvP4HU+56QkQjMeKZ0qYdnGD6IFM7Ov6S05SPcDd+l+64otfviYz97ewayZ0aAC1u zb8f43Uo3h9jnrqq+nJ5Q2qBCLf6IQ2kcT5qVbG5kSlBvTIm8GGky2ZwI2pDzpWMBos5 A52x+8bXVhAV+RXZPzhjXlC61PZ2pcOFzXCrd2eFSImPsj9r9YESkgjWDQWtDm0CY4sL XbBA== 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=PggG/W8oWZzrjgc+fiyGK62ciddT7QbaXDXHAw3wk/4=; b=l/H3G6RYozu/aUo+hCJaDG/lHWx/1mUeSKgo7eX5oN8GF8NubGXsjch5Xi9gzpyyYE Fp02XF9KuoBbIhHDdOSLOYF2ockzmKnZIk0fMhSKtvI6DAO2Fxt3S02lKriQqxP7T19+ 7poBMttMPBMatP16SWtNc5xwgKh7NgPCiWjw4FehTMNlaw+tgiigPS8/qdBqK9E7x5if N/TsvhTiEqksxGueudN9JjMYCtq8ag2sA9qALImHhHBdYQ2GADe44LvgvSp1/6K4kEMk BdqNncZ/zE0h3fxuf/iADDrzvLceS+HvTTKJBsAkZmmuh4tCFk53sAqqTkYvsC+f4QJq 0/dg== X-Gm-Message-State: ALoCoQljZm9NqrrerIZkysY5OqkYFwBKuNZZHd5uY6Go5wMtil1pqDKZ2JXcm1s4Q3uuW+B5dHLB MIME-Version: 1.0 X-Received: by 10.25.144.143 with SMTP id s137mr5991608lfd.116.1446435690283; Sun, 01 Nov 2015 19:41:30 -0800 (PST) Received: by 10.112.53.42 with HTTP; Sun, 1 Nov 2015 19:41:30 -0800 (PST) In-Reply-To: <20151102025352.GY19199@dastard> References: <1446217508-22157-1-git-send-email-agruenba@redhat.com> <20151102025352.GY19199@dastard> Date: Mon, 2 Nov 2015 04:41:30 +0100 Message-ID: Subject: Re: [PATCH v2 0/5] xfs: SGI ACL Fixes From: Andreas Gruenbacher X-ASG-Orig-Subj: Re: [PATCH v2 0/5] xfs: SGI ACL Fixes To: Dave Chinner Cc: Brian Foster , xfs@oss.sgi.com Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-lf0-f48.google.com[209.85.215.48] X-Barracuda-Start-Time: 1446435691 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24026 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 Mon, Nov 2, 2015 at 3:53 AM, Dave Chinner wrote: > On Fri, Oct 30, 2015 at 04:05:03PM +0100, Andreas Gruenbacher wrote: >> Here is a reworked patch queue that also handles setting SGI_ACL_{FILE,DEFAULT} >> via XFS_IOC_ATTRMULTI_BY_HANDLE. Please review. >> >> Thanks, >> Andreas >> >> Andreas Gruenbacher (5): >> xfs: Validate the length of on-disk ACLs >> xfs: Plug memory leak in xfs_attrmulti_attr_set > > Ok, I've taken these two patches for the upcoming merge window as > they fix bugs, but I've taken Brian's cached ACL invalidation patch > instead of these: > >> xfs: SGI ACLs: Fix caching and mode setting >> xfs: Add namespace parameter to the xfs kuid/kgid <=> uid/gid wrappers >> xfs: SGI ACLs: Map uid/gid namespaces > > I'm not yet convinced that these patches are the right way to solve > the given issue as they may interact badly with xfsdump/restore. Well, what else do you need to be convinced? I guess it won't help if I try to explain everything all over again? Thanks, Andreas From dave@fromorbit.com Sun Nov 1 21:42:40 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 929247F5F for ; Sun, 1 Nov 2015 21:42:40 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 7159F8F8033 for ; Sun, 1 Nov 2015 19:42:40 -0800 (PST) X-ASG-Debug-ID: 1446435757-04cbb0660c1b4570001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id HGe8CGChCfG8fEae for ; Sun, 01 Nov 2015 19:42:38 -0800 (PST) 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: A2B5BgBt2jZW/+rW03ZegzuBQqo5AQEBAQEBBpBUjCKBJ00BAQEBAQGBC4Q2AQUnLzMIGDE5AxsZiC/BWYYwikmEPAWHRY5+jn6SD4hSY4FKAQs7HYFqKjSFfgEBAQ Received: from ppp118-211-214-234.lns20.syd4.internode.on.net (HELO dastard) ([118.211.214.234]) by ipmail07.adl2.internode.on.net with ESMTP; 02 Nov 2015 14:12:35 +1030 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1Zt60k-00014n-9D for xfs@oss.sgi.com; Mon, 02 Nov 2015 14:42:22 +1100 Received: from dave by disappointment with local (Exim 4.86) (envelope-from ) id 1Zt60k-0000SQ-8P for xfs@oss.sgi.com; Mon, 02 Nov 2015 14:42:22 +1100 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH 4/7] xfs: DAX does not use IO completion callbacks Date: Mon, 2 Nov 2015 14:42:12 +1100 X-ASG-Orig-Subj: [PATCH 4/7] xfs: DAX does not use IO completion callbacks Message-Id: <1446435735-1526-5-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1446435735-1526-1-git-send-email-david@fromorbit.com> References: <1446435735-1526-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1446435757 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24026 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner For DAX, we are now doing block zeroing during allocation. This means we no longer need a special DAX fault IO completion callback to do unwritten extent conversion. Because mmap never extends the file size (it SEGVs the process) we don't need a callback to update the file size, either. Hence we can remove the completion callbacks from the __dax_fault and __dax_mkwrite calls. Signed-off-by: Dave Chinner Reviewed-by: Brian Foster Signed-off-by: Dave Chinner --- fs/xfs/xfs_aops.c | 39 --------------------------------------- fs/xfs/xfs_aops.h | 1 - fs/xfs/xfs_file.c | 5 ++--- 3 files changed, 2 insertions(+), 43 deletions(-) diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 7b4f849..29e7e5d 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -1666,45 +1666,6 @@ xfs_end_io_direct_write( __xfs_end_io_direct_write(inode, ioend, offset, size); } -/* - * For DAX we need a mapping buffer callback for unwritten extent conversion - * when page faults allocate blocks and then zero them. Note that in this - * case the mapping indicated by the ioend may extend beyond EOF. We most - * definitely do not want to extend EOF here, so we trim back the ioend size to - * EOF. - */ -#ifdef CONFIG_FS_DAX -void -xfs_end_io_dax_write( - struct buffer_head *bh, - int uptodate) -{ - struct xfs_ioend *ioend = bh->b_private; - struct inode *inode = ioend->io_inode; - ssize_t size = ioend->io_size; - - ASSERT(IS_DAX(ioend->io_inode)); - - /* if there was an error zeroing, then don't convert it */ - if (!uptodate) - ioend->io_error = -EIO; - - /* - * Trim update to EOF, so we don't extend EOF during unwritten extent - * conversion of partial EOF blocks. - */ - spin_lock(&XFS_I(inode)->i_flags_lock); - if (ioend->io_offset + size > i_size_read(inode)) - size = i_size_read(inode) - ioend->io_offset; - spin_unlock(&XFS_I(inode)->i_flags_lock); - - __xfs_end_io_direct_write(inode, ioend, ioend->io_offset, size); - -} -#else -void xfs_end_io_dax_write(struct buffer_head *bh, int uptodate) { } -#endif - static inline ssize_t xfs_vm_do_dio( struct inode *inode, diff --git a/fs/xfs/xfs_aops.h b/fs/xfs/xfs_aops.h index d39ba25..f6ffc9a 100644 --- a/fs/xfs/xfs_aops.h +++ b/fs/xfs/xfs_aops.h @@ -60,7 +60,6 @@ int xfs_get_blocks_direct(struct inode *inode, sector_t offset, struct buffer_head *map_bh, int create); int xfs_get_blocks_dax_fault(struct inode *inode, sector_t offset, struct buffer_head *map_bh, int create); -void xfs_end_io_dax_write(struct buffer_head *bh, int uptodate); extern void xfs_count_page_state(struct page *, int *, int *); diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 7f873bc..403151a 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -1508,8 +1508,7 @@ xfs_filemap_page_mkwrite( xfs_ilock(XFS_I(inode), XFS_MMAPLOCK_SHARED); if (IS_DAX(inode)) { - ret = __dax_mkwrite(vma, vmf, xfs_get_blocks_dax_fault, - xfs_end_io_dax_write); + ret = __dax_mkwrite(vma, vmf, xfs_get_blocks_dax_fault, NULL); } else { ret = __block_page_mkwrite(vma, vmf, xfs_get_blocks); ret = block_page_mkwrite_return(ret); @@ -1571,7 +1570,7 @@ xfs_filemap_pmd_fault( file_update_time(vma->vm_file); xfs_ilock(XFS_I(inode), XFS_MMAPLOCK_SHARED); ret = __dax_pmd_fault(vma, addr, pmd, flags, xfs_get_blocks_dax_fault, - xfs_end_io_dax_write); + NULL); xfs_iunlock(XFS_I(inode), XFS_MMAPLOCK_SHARED); sb_end_pagefault(inode->i_sb); -- 2.5.0 From dave@fromorbit.com Sun Nov 1 21:42:41 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 17BDF7F61 for ; Sun, 1 Nov 2015 21:42:41 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id E97178F8033 for ; Sun, 1 Nov 2015 19:42:37 -0800 (PST) X-ASG-Debug-ID: 1446435755-04cbb0660d1b4570001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id ObaicWbNqaCmjGKz for ; Sun, 01 Nov 2015 19:42:35 -0800 (PST) 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: A2B1BgBt2jZW/+rW03ZegzurewEBAQEBAQaQVI1JTQEBAQEBAYELhRI7gQIDiGOgaKBxhjCKb4QWBZZDqV9jgUoBAQgBAQEBgkAqhjIBAQE Received: from ppp118-211-214-234.lns20.syd4.internode.on.net (HELO dastard) ([118.211.214.234]) by ipmail07.adl2.internode.on.net with ESMTP; 02 Nov 2015 14:12:35 +1030 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1Zt60k-00014j-7N for xfs@oss.sgi.com; Mon, 02 Nov 2015 14:42:22 +1100 Received: from dave by disappointment with local (Exim 4.86) (envelope-from ) id 1Zt60k-0000S7-6O for xfs@oss.sgi.com; Mon, 02 Nov 2015 14:42:22 +1100 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH 0/7] xfs: patches remaining for 4.4 merge window Date: Mon, 2 Nov 2015 14:42:08 +1100 X-ASG-Orig-Subj: [PATCH 0/7] xfs: patches remaining for 4.4 merge window Message-Id: <1446435735-1526-1-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.5.0 X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1446435755 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24026 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Hi folks, These are the outstanding patches I have for the 4.4 ,erge window. It is effectively v3 of the DAX block zeroing patch set - this version fixes the issues brian found, and marks all the unmodified reviewed patches as such. The final patch is also the fdatasync optimisation patch that Brain noticed a race condition in. It has the fix I mentioned in the review thread in it and it still works just fine. I'll merge these into the for-next branch as soon as reviews come through with an eye to sending Linus a pull request early next week. -Dave. From dave@fromorbit.com Sun Nov 1 21:42:41 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 1FCFC7F62 for ; Sun, 1 Nov 2015 21:42:41 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 93000AC001 for ; Sun, 1 Nov 2015 19:42:40 -0800 (PST) X-ASG-Debug-ID: 1446435755-04cbb0660d1b4570002-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id hrLUtXFNzNmoPCcy for ; Sun, 01 Nov 2015 19:42:37 -0800 (PST) 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: A2BCBwBt2jZW/+rW03Zegzt/AUKqOQEBAQEBAQaQVIwigSdNAQEBAQEBgQuENgEFJy8zCBgxOQMbGRmIFsFZhjCKSYQ8BZZDjn6HY4VrhEGIUmOBSgELOAMdgWoqNIV+AQEB Received: from ppp118-211-214-234.lns20.syd4.internode.on.net (HELO dastard) ([118.211.214.234]) by ipmail07.adl2.internode.on.net with ESMTP; 02 Nov 2015 14:12:35 +1030 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1Zt60k-00014k-7q for xfs@oss.sgi.com; Mon, 02 Nov 2015 14:42:22 +1100 Received: from dave by disappointment with local (Exim 4.86) (envelope-from ) id 1Zt60k-0000SA-74 for xfs@oss.sgi.com; Mon, 02 Nov 2015 14:42:22 +1100 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH 1/7] xfs: fix inode size update overflow in xfs_map_direct() Date: Mon, 2 Nov 2015 14:42:09 +1100 X-ASG-Orig-Subj: [PATCH 1/7] xfs: fix inode size update overflow in xfs_map_direct() Message-Id: <1446435735-1526-2-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1446435735-1526-1-git-send-email-david@fromorbit.com> References: <1446435735-1526-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1446435757 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24026 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner Both direct IO and DAX pass an offset and count into get_blocks that will overflow a s64 variable when an IO goes into the last supported block in a file (i.e. at offset 2^63 - 1FSB bytes). This can be seen from the tracing: xfs_get_blocks_alloc: [...] offset 0x7ffffffffffff000 count 4096 xfs_gbmap_direct: [...] offset 0x7ffffffffffff000 count 4096 xfs_gbmap_direct_none:[...] offset 0x7ffffffffffff000 count 4096 0x7ffffffffffff000 + 4096 = 0x8000000000000000, and hence that overflows the s64 offset and we fail to detect the need for a filesize update and an ioend is not allocated. This is *mostly* avoided for direct IO because such extending IOs occur with full block allocation, and so the "IS_UNWRITTEN()" check still evaluates as true and we get an ioend that way. However, doing single sector extending IOs to this last block will expose the fact that file size updates will not occur after the first allocating direct IO as the overflow will then be exposed. There is one further complexity: the DAX page fault path also exposes the same issue in block allocation. However, page faults cannot extend the file size, so in this case we want to allocate the block but do not want to allocate an ioend to enable file size update at IO completion. Hence we now need to distinguish between the direct IO patch allocation and dax fault path allocation to avoid leaking ioend structures. Signed-off-by: Dave Chinner Reviewed-by: Brian Foster Signed-off-by: Dave Chinner --- fs/xfs/xfs_aops.c | 50 ++++++++++++++++++++++++++++++++++++++++++++------ fs/xfs/xfs_aops.h | 2 ++ fs/xfs/xfs_file.c | 6 +++--- 3 files changed, 49 insertions(+), 9 deletions(-) diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index e4fff58..366e41eb 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -1259,13 +1259,28 @@ xfs_vm_releasepage( * the DIO. There is only going to be one reference to the ioend and its life * cycle is constrained by the DIO completion code. hence we don't need * reference counting here. + * + * Note that for DIO, an IO to the highest supported file block offset (i.e. + * 2^63 - 1FSB bytes) will result in the offset + count overflowing a signed 64 + * bit variable. Hence if we see this overflow, we have to assume that the IO is + * extending the file size. We won't know for sure until IO completion is run + * and the actual max write offset is communicated to the IO completion + * routine. + * + * For DAX page faults, we are preparing to never see unwritten extents here, + * nor should we ever extend the inode size. Hence we will soon have nothing to + * do here for this case, ensuring we don't have to provide an IO completion + * callback to free an ioend that we don't actually need for a fault into the + * page at offset (2^63 - 1FSB) bytes. */ + static void xfs_map_direct( struct inode *inode, struct buffer_head *bh_result, struct xfs_bmbt_irec *imap, - xfs_off_t offset) + xfs_off_t offset, + bool dax_fault) { struct xfs_ioend *ioend; xfs_off_t size = bh_result->b_size; @@ -1278,6 +1293,16 @@ xfs_map_direct( trace_xfs_gbmap_direct(XFS_I(inode), offset, size, type, imap); + /* XXX: preparation for removing unwritten extents in DAX */ +#if 0 + if (dax_fault) { + ASSERT(type == XFS_IO_OVERWRITE); + trace_xfs_gbmap_direct_none(XFS_I(inode), offset, size, type, + imap); + return; + } +#endif + if (bh_result->b_private) { ioend = bh_result->b_private; ASSERT(ioend->io_size > 0); @@ -1292,7 +1317,8 @@ xfs_map_direct( ioend->io_size, ioend->io_type, imap); } else if (type == XFS_IO_UNWRITTEN || - offset + size > i_size_read(inode)) { + offset + size > i_size_read(inode) || + offset + size < 0) { ioend = xfs_alloc_ioend(inode, type); ioend->io_offset = offset; ioend->io_size = size; @@ -1354,7 +1380,8 @@ __xfs_get_blocks( sector_t iblock, struct buffer_head *bh_result, int create, - bool direct) + bool direct, + bool dax_fault) { struct xfs_inode *ip = XFS_I(inode); struct xfs_mount *mp = ip->i_mount; @@ -1467,7 +1494,8 @@ __xfs_get_blocks( set_buffer_unwritten(bh_result); /* direct IO needs special help */ if (create && direct) - xfs_map_direct(inode, bh_result, &imap, offset); + xfs_map_direct(inode, bh_result, &imap, offset, + dax_fault); } /* @@ -1514,7 +1542,7 @@ xfs_get_blocks( struct buffer_head *bh_result, int create) { - return __xfs_get_blocks(inode, iblock, bh_result, create, false); + return __xfs_get_blocks(inode, iblock, bh_result, create, false, false); } int @@ -1524,7 +1552,17 @@ xfs_get_blocks_direct( struct buffer_head *bh_result, int create) { - return __xfs_get_blocks(inode, iblock, bh_result, create, true); + return __xfs_get_blocks(inode, iblock, bh_result, create, true, false); +} + +int +xfs_get_blocks_dax_fault( + struct inode *inode, + sector_t iblock, + struct buffer_head *bh_result, + int create) +{ + return __xfs_get_blocks(inode, iblock, bh_result, create, true, true); } static void diff --git a/fs/xfs/xfs_aops.h b/fs/xfs/xfs_aops.h index 86afd1a..d39ba25 100644 --- a/fs/xfs/xfs_aops.h +++ b/fs/xfs/xfs_aops.h @@ -58,6 +58,8 @@ int xfs_get_blocks(struct inode *inode, sector_t offset, struct buffer_head *map_bh, int create); int xfs_get_blocks_direct(struct inode *inode, sector_t offset, struct buffer_head *map_bh, int create); +int xfs_get_blocks_dax_fault(struct inode *inode, sector_t offset, + struct buffer_head *map_bh, int create); void xfs_end_io_dax_write(struct buffer_head *bh, int uptodate); extern void xfs_count_page_state(struct page *, int *, int *); diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 2f7b6bd..7f873bc 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -1508,7 +1508,7 @@ xfs_filemap_page_mkwrite( xfs_ilock(XFS_I(inode), XFS_MMAPLOCK_SHARED); if (IS_DAX(inode)) { - ret = __dax_mkwrite(vma, vmf, xfs_get_blocks_direct, + ret = __dax_mkwrite(vma, vmf, xfs_get_blocks_dax_fault, xfs_end_io_dax_write); } else { ret = __block_page_mkwrite(vma, vmf, xfs_get_blocks); @@ -1543,7 +1543,7 @@ xfs_filemap_fault( * changes to xfs_get_blocks_direct() to map unwritten extent * ioend for conversion on read-only mappings. */ - ret = __dax_fault(vma, vmf, xfs_get_blocks_direct, NULL); + ret = __dax_fault(vma, vmf, xfs_get_blocks_dax_fault, NULL); } else ret = filemap_fault(vma, vmf); xfs_iunlock(XFS_I(inode), XFS_MMAPLOCK_SHARED); @@ -1570,7 +1570,7 @@ xfs_filemap_pmd_fault( sb_start_pagefault(inode->i_sb); file_update_time(vma->vm_file); xfs_ilock(XFS_I(inode), XFS_MMAPLOCK_SHARED); - ret = __dax_pmd_fault(vma, addr, pmd, flags, xfs_get_blocks_direct, + ret = __dax_pmd_fault(vma, addr, pmd, flags, xfs_get_blocks_dax_fault, xfs_end_io_dax_write); xfs_iunlock(XFS_I(inode), XFS_MMAPLOCK_SHARED); sb_end_pagefault(inode->i_sb); -- 2.5.0 From dave@fromorbit.com Sun Nov 1 21:42:42 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 2C3F97F5F for ; Sun, 1 Nov 2015 21:42:42 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 1AACD8F8033 for ; Sun, 1 Nov 2015 19:42:42 -0800 (PST) X-ASG-Debug-ID: 1446435755-04cbb0660d1b4570003-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id xSp2zMK7PBxXxgYf for ; Sun, 01 Nov 2015 19:42:39 -0800 (PST) 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: A2B5BgBt2jZW/+rW03ZegzuBQqo5AQEBAQEBBpBUjCKBJ00BAQEBAQGBC4Q2AQUnLzMIGDE5AxsZiC/BWYYwikmEPAWWQ45+h2OSfmOBSgELgkIqNIV+AQEB Received: from ppp118-211-214-234.lns20.syd4.internode.on.net (HELO dastard) ([118.211.214.234]) by ipmail07.adl2.internode.on.net with ESMTP; 02 Nov 2015 14:12:35 +1030 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1Zt60k-00014m-8l for xfs@oss.sgi.com; Mon, 02 Nov 2015 14:42:22 +1100 Received: from dave by disappointment with local (Exim 4.86) (envelope-from ) id 1Zt60k-0000SL-80 for xfs@oss.sgi.com; Mon, 02 Nov 2015 14:42:22 +1100 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH 3/7] xfs: Don't use unwritten extents for DAX Date: Mon, 2 Nov 2015 14:42:11 +1100 X-ASG-Orig-Subj: [PATCH 3/7] xfs: Don't use unwritten extents for DAX Message-Id: <1446435735-1526-4-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1446435735-1526-1-git-send-email-david@fromorbit.com> References: <1446435735-1526-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1446435759 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24026 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner DAX has a page fault serialisation problem with block allocation. Because it allows concurrent page faults and does not have a page lock to serialise faults to the same page, it can get two concurrent faults to the page that race. When two read faults race, this isn't a huge problem as the data underlying the page is not changing and so "detect and drop" works just fine. The issues are to do with write faults. When two write faults occur, we serialise block allocation in get_blocks() so only one faul will allocate the extent. It will, however, be marked as an unwritten extent, and that is where the problem lies - the DAX fault code cannot differentiate between a block that was just allocated and a block that was preallocated and needs zeroing. The result is that both write faults end up zeroing the block and attempting to convert it back to written. The problem is that the first fault can zero and convert before the second fault starts zeroing, resulting in the zeroing for the second fault overwriting the data that the first fault wrote with zeros. The second fault then attempts to convert the unwritten extent, which is then a no-op because it's already written. Data loss occurs as a result of this race. Because there is no sane locking construct in the page fault code that we can use for serialisation across the page faults, we need to ensure block allocation and zeroing occurs atomically in the filesystem. This means we can still take concurrent page faults and the only time they will serialise is in the filesystem mapping/allocation callback. The page fault code will always see written, initialised extents, so we will be able to remove the unwritten extent handling from the DAX code when all filesystems are converted. Signed-off-by: Dave Chinner --- fs/dax.c | 5 +++++ fs/xfs/xfs_aops.c | 13 +++++++++---- fs/xfs/xfs_iomap.c | 21 ++++++++++++++++++++- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/fs/dax.c b/fs/dax.c index a86d3cc..131fd35a 100644 --- a/fs/dax.c +++ b/fs/dax.c @@ -29,6 +29,11 @@ #include #include +/* + * dax_clear_blocks() is called from within transaction context from XFS, + * and hence this means the stack from this point must follow GFP_NOFS + * semantics for all operations. + */ int dax_clear_blocks(struct inode *inode, sector_t block, long size) { struct block_device *bdev = inode->i_sb->s_bdev; diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 366e41eb..7b4f849 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -1293,15 +1293,12 @@ xfs_map_direct( trace_xfs_gbmap_direct(XFS_I(inode), offset, size, type, imap); - /* XXX: preparation for removing unwritten extents in DAX */ -#if 0 if (dax_fault) { ASSERT(type == XFS_IO_OVERWRITE); trace_xfs_gbmap_direct_none(XFS_I(inode), offset, size, type, imap); return; } -#endif if (bh_result->b_private) { ioend = bh_result->b_private; @@ -1429,10 +1426,12 @@ __xfs_get_blocks( if (error) goto out_unlock; + /* for DAX, we convert unwritten extents directly */ if (create && (!nimaps || (imap.br_startblock == HOLESTARTBLOCK || - imap.br_startblock == DELAYSTARTBLOCK))) { + imap.br_startblock == DELAYSTARTBLOCK) || + (IS_DAX(inode) && ISUNWRITTEN(&imap)))) { if (direct || xfs_get_extsz_hint(ip)) { /* * xfs_iomap_write_direct() expects the shared lock. It @@ -1477,6 +1476,12 @@ __xfs_get_blocks( goto out_unlock; } + if (IS_DAX(inode) && create) { + ASSERT(!ISUNWRITTEN(&imap)); + /* zeroing is not needed at a higher layer */ + new = 0; + } + /* trim mapping down to size requested */ if (direct || size > (1 << inode->i_blkbits)) xfs_map_trim_size(inode, iblock, bh_result, diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index c3cb5a5..f4f5b43 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -132,6 +132,7 @@ xfs_iomap_write_direct( int committed; int error; int lockmode; + int bmapi_flags = XFS_BMAPI_PREALLOC; rt = XFS_IS_REALTIME_INODE(ip); extsz = xfs_get_extsz_hint(ip); @@ -195,6 +196,23 @@ xfs_iomap_write_direct( * Allocate and setup the transaction */ tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT); + + /* + * For DAX, we do not allocate unwritten extents, but instead we zero + * the block before we commit the transaction. Ideally we'd like to do + * this outside the transaction context, but if we commit and then crash + * we may not have zeroed the blocks and this will be exposed on + * recovery of the allocation. Hence we must zero before commit. + * Further, if we are mapping unwritten extents here, we need to zero + * and convert them to written so that we don't need an unwritten extent + * callback for DAX. This also means that we need to be able to dip into + * the reserve block pool if there is no space left but we need to do + * unwritten extent conversion. + */ + if (IS_DAX(VFS_I(ip))) { + bmapi_flags = XFS_BMAPI_CONVERT | XFS_BMAPI_ZERO; + tp->t_flags |= XFS_TRANS_RESERVE; + } error = xfs_trans_reserve(tp, &M_RES(mp)->tr_write, resblks, resrtextents); /* @@ -221,7 +239,7 @@ xfs_iomap_write_direct( xfs_bmap_init(&free_list, &firstfsb); nimaps = 1; error = xfs_bmapi_write(tp, ip, offset_fsb, count_fsb, - XFS_BMAPI_PREALLOC, &firstfsb, resblks, imap, + bmapi_flags, &firstfsb, resblks, imap, &nimaps, &free_list); if (error) goto out_bmap_cancel; @@ -232,6 +250,7 @@ xfs_iomap_write_direct( error = xfs_bmap_finish(&tp, &free_list, &committed); if (error) goto out_bmap_cancel; + error = xfs_trans_commit(tp); if (error) goto out_unlock; -- 2.5.0 From dave@fromorbit.com Sun Nov 1 21:42:44 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 128477F7E for ; Sun, 1 Nov 2015 21:42:44 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id D8E26304039 for ; Sun, 1 Nov 2015 19:42:43 -0800 (PST) X-ASG-Debug-ID: 1446435760-04bdf0330a1b9e10001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id ctejGwhwga6JbbVq for ; Sun, 01 Nov 2015 19:42:41 -0800 (PST) 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: A2B5BgBt2jZW/+rW03ZegzuBQqo5AQEBAQEBBpBUjCKBJ00BAQEBAQGBC4Q2AQUnLzMIGDE5AxsZiC/BWYYwikkmhBYFlkOOfo1OhEGIUmOBSgELgkIqNIV+AQEB Received: from ppp118-211-214-234.lns20.syd4.internode.on.net (HELO dastard) ([118.211.214.234]) by ipmail07.adl2.internode.on.net with ESMTP; 02 Nov 2015 14:12:35 +1030 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1Zt60k-00014o-9d for xfs@oss.sgi.com; Mon, 02 Nov 2015 14:42:22 +1100 Received: from dave by disappointment with local (Exim 4.86) (envelope-from ) id 1Zt60k-0000SV-8r for xfs@oss.sgi.com; Mon, 02 Nov 2015 14:42:22 +1100 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH 5/7] xfs: add ->pfn_mkwrite support for DAX Date: Mon, 2 Nov 2015 14:42:13 +1100 X-ASG-Orig-Subj: [PATCH 5/7] xfs: add ->pfn_mkwrite support for DAX Message-Id: <1446435735-1526-6-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1446435735-1526-1-git-send-email-david@fromorbit.com> References: <1446435735-1526-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1446435760 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24026 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner ->pfn_mkwrite support is needed so that when a page with allocated backing store takes a write fault we can check that the fault has not raced with a truncate and is pointing to a region beyond the current end of file. This also allows us to update the timestamp on the inode, too, which fixes a generic/080 failure. Signed-off-by: Dave Chinner Reviewed-by: Brian Foster Signed-off-by: Dave Chinner --- fs/xfs/xfs_file.c | 35 +++++++++++++++++++++++++++++++++++ fs/xfs/xfs_trace.h | 1 + 2 files changed, 36 insertions(+) diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 403151a..e7cf9ec 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -1577,11 +1577,46 @@ xfs_filemap_pmd_fault( return ret; } +/* + * pfn_mkwrite was originally inteneded to ensure we capture time stamp + * updates on write faults. In reality, it's need to serialise against + * truncate similar to page_mkwrite. Hence we open-code dax_pfn_mkwrite() + * here and cycle the XFS_MMAPLOCK_SHARED to ensure we serialise the fault + * barrier in place. + */ +static int +xfs_filemap_pfn_mkwrite( + struct vm_area_struct *vma, + struct vm_fault *vmf) +{ + + struct inode *inode = file_inode(vma->vm_file); + struct xfs_inode *ip = XFS_I(inode); + int ret = VM_FAULT_NOPAGE; + loff_t size; + + trace_xfs_filemap_pfn_mkwrite(ip); + + sb_start_pagefault(inode->i_sb); + file_update_time(vma->vm_file); + + /* check if the faulting page hasn't raced with truncate */ + xfs_ilock(ip, XFS_MMAPLOCK_SHARED); + size = (i_size_read(inode) + PAGE_SIZE - 1) >> PAGE_SHIFT; + if (vmf->pgoff >= size) + ret = VM_FAULT_SIGBUS; + xfs_iunlock(ip, XFS_MMAPLOCK_SHARED); + sb_end_pagefault(inode->i_sb); + return ret; + +} + static const struct vm_operations_struct xfs_file_vm_ops = { .fault = xfs_filemap_fault, .pmd_fault = xfs_filemap_pmd_fault, .map_pages = filemap_map_pages, .page_mkwrite = xfs_filemap_page_mkwrite, + .pfn_mkwrite = xfs_filemap_pfn_mkwrite, }; STATIC int diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index 957f5cc..877079eb 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -689,6 +689,7 @@ DEFINE_INODE_EVENT(xfs_inode_free_eofblocks_invalid); DEFINE_INODE_EVENT(xfs_filemap_fault); DEFINE_INODE_EVENT(xfs_filemap_pmd_fault); DEFINE_INODE_EVENT(xfs_filemap_page_mkwrite); +DEFINE_INODE_EVENT(xfs_filemap_pfn_mkwrite); DECLARE_EVENT_CLASS(xfs_iref_class, TP_PROTO(struct xfs_inode *ip, unsigned long caller_ip), -- 2.5.0 From dave@fromorbit.com Sun Nov 1 21:42:44 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 16D657F80 for ; Sun, 1 Nov 2015 21:42:44 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 05C64304053 for ; Sun, 1 Nov 2015 19:42:44 -0800 (PST) X-ASG-Debug-ID: 1446435755-04cbb0660d1b4570004-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id zxUrE2eupmxVr3SI for ; Sun, 01 Nov 2015 19:42:41 -0800 (PST) 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: A2B4BgBt2jZW/+rW03ZegzuBQqo5AQEBAQEBBpBUjUlNAQEBAQEBgQuENgEFJy8RIggYMTkDGxmIL8FZhjCPBQWWQ45+kg+IUmOBSgELgkIqNIV+AQEB Received: from ppp118-211-214-234.lns20.syd4.internode.on.net (HELO dastard) ([118.211.214.234]) by ipmail07.adl2.internode.on.net with ESMTP; 02 Nov 2015 14:12:35 +1030 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1Zt60k-00014q-AZ for xfs@oss.sgi.com; Mon, 02 Nov 2015 14:42:22 +1100 Received: from dave by disappointment with local (Exim 4.86) (envelope-from ) id 1Zt60k-0000Sf-9p for xfs@oss.sgi.com; Mon, 02 Nov 2015 14:42:22 +1100 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH 7/7] xfs: optimise away log forces on timestamp updates for fdatasync Date: Mon, 2 Nov 2015 14:42:15 +1100 X-ASG-Orig-Subj: [PATCH 7/7] xfs: optimise away log forces on timestamp updates for fdatasync Message-Id: <1446435735-1526-8-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1446435735-1526-1-git-send-email-david@fromorbit.com> References: <1446435735-1526-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1446435761 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24026 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner xfs: timestamp updates cause excessive fdatasync log traffic Sage Weil reported that a ceph test workload was writing to the log on every fdatasync during an overwrite workload. Event tracing showed that the only metadata modification being made was the timestamp updates during the write(2) syscall, but fdatasync(2) is supposed to ignore them. The key observation was that the transactions in the log all looked like this: INODE: #regs: 4 ino: 0x8b flags: 0x45 dsize: 32 And contained a flags field of 0x45 or 0x85, and had data and attribute forks following the inode core. This means that the timestamp updates were triggering dirty relogging of previously logged parts of the inode that hadn't yet been flushed back to disk. There are two parts to this problem. The first is that XFS relogs dirty regions in subsequent transactions, so it carries around the fields that have been dirtied since the last time the inode was written back to disk, not since the last time the inode was forced into the log. The second part is that on v5 filesystems, the inode change count update during inode dirtying also sets the XFS_ILOG_CORE flag, so on v5 filesystems this makes a timestamp update dirty the entire inode. As a result when fdatasync is run, it looks at the dirty fields in the inode, and sees more than just the timestamp flag, even though the only metadata change since the last fdatasync was just the timestamps. Hence we force the log on every subsequent fdatasync even though it is not needed. To fix this, add a new field to the inode log item that tracks changes since the last time fsync/fdatasync forced the log to flush the changes to the journal. This flag is updated when we dirty the inode, but we do it before updating the change count so it does not carry the "core dirty" flag from timestamp updates. The fields are zeroed when the inode is marked clean (due to writeback/freeing) or when an fsync/datasync forces the log. Hence if we only dirty the timestamps on the inode between fsync/fdatasync calls, the fdatasync will not trigger another log force. Over 100 runs of the test program: Ext4 baseline: runtime: 1.63s +/- 0.24s avg lat: 1.59ms +/- 0.24ms iops: ~2000 XFS, vanilla kernel: runtime: 2.45s +/- 0.18s avg lat: 2.39ms +/- 0.18ms log forces: ~400/s iops: ~1000 XFS, patched kernel: runtime: 1.49s +/- 0.26s avg lat: 1.46ms +/- 0.25ms log forces: ~30/s iops: ~1500 Reported-by: Sage Weil Signed-off-by: Dave Chinner --- fs/xfs/xfs_file.c | 21 ++++++++++++++++----- fs/xfs/xfs_inode.c | 2 ++ fs/xfs/xfs_inode_item.c | 1 + fs/xfs/xfs_inode_item.h | 1 + fs/xfs/xfs_trans_inode.c | 9 +++++++++ 5 files changed, 29 insertions(+), 5 deletions(-) diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 0045b0a..39743ef 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -242,19 +242,30 @@ xfs_file_fsync( } /* - * All metadata updates are logged, which means that we just have - * to flush the log up to the latest LSN that touched the inode. + * All metadata updates are logged, which means that we just have to + * flush the log up to the latest LSN that touched the inode. If we have + * concurrent fsync/fdatasync() calls, we need them to all block on the + * log force before we clear the ili_fsync_fields field. This ensures + * that we don't get a racing sync operation that does not wait for the + * metadata to hit the journal before returning. If we race with + * clearing the ili_fsync_fields, then all that will happen is the log + * force will do nothing as the lsn will already be on disk. We can't + * race with setting ili_fsync_fields because that is done under + * XFS_ILOCK_EXCL, and that can't happen because we hold the lock shared + * until after the ili_fsync_fields is cleared. */ xfs_ilock(ip, XFS_ILOCK_SHARED); if (xfs_ipincount(ip)) { if (!datasync || - (ip->i_itemp->ili_fields & ~XFS_ILOG_TIMESTAMP)) + (ip->i_itemp->ili_fsync_fields & ~XFS_ILOG_TIMESTAMP)) lsn = ip->i_itemp->ili_last_lsn; } - xfs_iunlock(ip, XFS_ILOCK_SHARED); - if (lsn) + if (lsn) { error = _xfs_log_force_lsn(mp, lsn, XFS_LOG_SYNC, &log_flushed); + ip->i_itemp->ili_fsync_fields = 0; + } + xfs_iunlock(ip, XFS_ILOCK_SHARED); /* * If we only have a single device, and the log force about was diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index a0f2bae..8ee3939 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -2365,6 +2365,7 @@ retry: iip->ili_last_fields = iip->ili_fields; iip->ili_fields = 0; + iip->ili_fsync_fields = 0; iip->ili_logged = 1; xfs_trans_ail_copy_lsn(mp->m_ail, &iip->ili_flush_lsn, &iip->ili_item.li_lsn); @@ -3560,6 +3561,7 @@ xfs_iflush_int( */ iip->ili_last_fields = iip->ili_fields; iip->ili_fields = 0; + iip->ili_fsync_fields = 0; iip->ili_logged = 1; xfs_trans_ail_copy_lsn(mp->m_ail, &iip->ili_flush_lsn, diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index 62bd80f..d14b12b 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c @@ -719,6 +719,7 @@ xfs_iflush_abort( * attempted. */ iip->ili_fields = 0; + iip->ili_fsync_fields = 0; } /* * Release the inode's flush lock since we're done with it. diff --git a/fs/xfs/xfs_inode_item.h b/fs/xfs/xfs_inode_item.h index 488d812..4c7722e 100644 --- a/fs/xfs/xfs_inode_item.h +++ b/fs/xfs/xfs_inode_item.h @@ -34,6 +34,7 @@ typedef struct xfs_inode_log_item { unsigned short ili_logged; /* flushed logged data */ unsigned int ili_last_fields; /* fields when flushed */ unsigned int ili_fields; /* fields to be logged */ + unsigned int ili_fsync_fields; /* logged since last fsync */ } xfs_inode_log_item_t; static inline int xfs_inode_clean(xfs_inode_t *ip) diff --git a/fs/xfs/xfs_trans_inode.c b/fs/xfs/xfs_trans_inode.c index 17280cd..b97f1df 100644 --- a/fs/xfs/xfs_trans_inode.c +++ b/fs/xfs/xfs_trans_inode.c @@ -108,6 +108,15 @@ xfs_trans_log_inode( ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); /* + * Record the specific change for fdatasync optimisation. This + * allows fdatasync to skip log forces for inodes that are only + * timestamp dirty. We do this before the change count so that + * the core being logged in this case does not impact on fdatasync + * behaviour. + */ + ip->i_itemp->ili_fsync_fields |= flags; + + /* * First time we log the inode in a transaction, bump the inode change * counter if it is configured for this to occur. We don't use * inode_inc_version() because there is no need for extra locking around -- 2.5.0 From dave@fromorbit.com Sun Nov 1 21:42:44 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 A09C17F7E for ; Sun, 1 Nov 2015 21:42:44 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 8370B304053 for ; Sun, 1 Nov 2015 19:42:44 -0800 (PST) X-ASG-Debug-ID: 1446435757-04cbb0660c1b4570003-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id KZzsT1iIEgS35i8f for ; Sun, 01 Nov 2015 19:42:41 -0800 (PST) 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: A2B5BgBt2jZW/+rW03ZegzuBQqo5AQEBAQEBBpBUjCKBJ00BAQEBAQGBC4Q2AQUnLzMIGDE5AxsZiC/BWYYwikmEPAWHQocKh3ecTI0TY4FKAQsBOh2Baio0hX4BAQE Received: from ppp118-211-214-234.lns20.syd4.internode.on.net (HELO dastard) ([118.211.214.234]) by ipmail07.adl2.internode.on.net with ESMTP; 02 Nov 2015 14:12:35 +1030 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1Zt60k-00014l-8H for xfs@oss.sgi.com; Mon, 02 Nov 2015 14:42:22 +1100 Received: from dave by disappointment with local (Exim 4.86) (envelope-from ) id 1Zt60k-0000SF-7X for xfs@oss.sgi.com; Mon, 02 Nov 2015 14:42:22 +1100 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH 2/7] xfs: introduce BMAPI_ZERO for allocating zeroed extents Date: Mon, 2 Nov 2015 14:42:10 +1100 X-ASG-Orig-Subj: [PATCH 2/7] xfs: introduce BMAPI_ZERO for allocating zeroed extents Message-Id: <1446435735-1526-3-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1446435735-1526-1-git-send-email-david@fromorbit.com> References: <1446435735-1526-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1446435761 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24026 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner To enable DAX to do atomic allocation of zeroed extents, we need to drive the block zeroing deep into the allocator. Because xfs_bmapi_write() can return merged extents on allocation that were only partially allocated (i.e. requested range spans allocated and hole regions, allocation into the hole was contiguous), we cannot zero the extent returned from xfs_bmapi_write() as that can overwrite existing data with zeros. Hence we have to drive the extent zeroing into the allocation code, prior to where we merge the extents into the BMBT and return the resultant map. This means we need to propagate this need down to the xfs_alloc_vextent() and issue the block zeroing at this point. While this functionality is being introduced for DAX, there is no reason why it is specific to DAX - we can per-zero blocks during the allocation transaction on any type of device. It's just slow (and usually slower than unwritten allocation and conversion) on traditional block devices so doesn't tend to get used. We can, however, hook hardware zeroing optimisations via sb_issue_zeroout() to this operation, so it may be useful in future and hence the "allocate zeroed blocks" API needs to be implementation neutral. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_alloc.c | 10 +++++++++- fs/xfs/libxfs/xfs_alloc.h | 8 +++++--- fs/xfs/libxfs/xfs_bmap.c | 35 +++++++++++++++++++++++++++++++++-- fs/xfs/libxfs/xfs_bmap.h | 13 +++++++++++-- fs/xfs/xfs_bmap_util.c | 36 ++++++++++++++++++++++++++++++++++++ fs/xfs/xfs_mount.h | 3 +++ 6 files changed, 97 insertions(+), 8 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index e926197..3479294 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -2509,7 +2509,7 @@ xfs_alloc_vextent( * Try near allocation first, then anywhere-in-ag after * the first a.g. fails. */ - if ((args->userdata == XFS_ALLOC_INITIAL_USER_DATA) && + if ((args->userdata & XFS_ALLOC_INITIAL_USER_DATA) && (mp->m_flags & XFS_MOUNT_32BITINODES)) { args->fsbno = XFS_AGB_TO_FSB(mp, ((mp->m_agfrotor / rotorstep) % @@ -2640,6 +2640,14 @@ xfs_alloc_vextent( XFS_AG_CHECK_DADDR(mp, XFS_FSB_TO_DADDR(mp, args->fsbno), args->len); #endif + + /* Zero the extent if we were asked to do so */ + if (args->userdata & XFS_ALLOC_USERDATA_ZERO) { + error = xfs_zero_extent(args->ip, args->fsbno, args->len); + if (error) + goto error0; + } + } xfs_perag_put(args->pag); return 0; diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h index ca1c816..0ecde4d 100644 --- a/fs/xfs/libxfs/xfs_alloc.h +++ b/fs/xfs/libxfs/xfs_alloc.h @@ -101,6 +101,7 @@ typedef struct xfs_alloc_arg { struct xfs_mount *mp; /* file system mount point */ struct xfs_buf *agbp; /* buffer for a.g. freelist header */ struct xfs_perag *pag; /* per-ag struct for this agno */ + struct xfs_inode *ip; /* for userdata zeroing method */ xfs_fsblock_t fsbno; /* file system block number */ xfs_agnumber_t agno; /* allocation group number */ xfs_agblock_t agbno; /* allocation group-relative block # */ @@ -120,15 +121,16 @@ typedef struct xfs_alloc_arg { char wasdel; /* set if allocation was prev delayed */ char wasfromfl; /* set if allocation is from freelist */ char isfl; /* set if is freelist blocks - !acctg */ - char userdata; /* set if this is user data */ + char userdata; /* mask defining userdata treatment */ xfs_fsblock_t firstblock; /* io first block allocated */ } xfs_alloc_arg_t; /* * Defines for userdata */ -#define XFS_ALLOC_USERDATA 1 /* allocation is for user data*/ -#define XFS_ALLOC_INITIAL_USER_DATA 2 /* special case start of file */ +#define XFS_ALLOC_USERDATA (1 << 0)/* allocation is for user data*/ +#define XFS_ALLOC_INITIAL_USER_DATA (1 << 1)/* special case start of file */ +#define XFS_ALLOC_USERDATA_ZERO (1 << 2)/* zero extent on allocation */ xfs_extlen_t xfs_alloc_longest_free_extent(struct xfs_mount *mp, struct xfs_perag *pag, xfs_extlen_t need); diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index ab92d10..119c242 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -3802,8 +3802,13 @@ xfs_bmap_btalloc( args.wasdel = ap->wasdel; args.isfl = 0; args.userdata = ap->userdata; - if ((error = xfs_alloc_vextent(&args))) + if (ap->userdata & XFS_ALLOC_USERDATA_ZERO) + args.ip = ap->ip; + + error = xfs_alloc_vextent(&args); + if (error) return error; + if (tryagain && args.fsbno == NULLFSBLOCK) { /* * Exact allocation failed. Now try with alignment @@ -4302,11 +4307,14 @@ xfs_bmapi_allocate( /* * Indicate if this is the first user data in the file, or just any - * user data. + * user data. And if it is userdata, indicate whether it needs to + * be initialised to zero during allocation. */ if (!(bma->flags & XFS_BMAPI_METADATA)) { bma->userdata = (bma->offset == 0) ? XFS_ALLOC_INITIAL_USER_DATA : XFS_ALLOC_USERDATA; + if (bma->flags & XFS_BMAPI_ZERO) + bma->userdata |= XFS_ALLOC_USERDATA_ZERO; } bma->minlen = (bma->flags & XFS_BMAPI_CONTIG) ? bma->length : 1; @@ -4421,6 +4429,17 @@ xfs_bmapi_convert_unwritten( mval->br_state = (mval->br_state == XFS_EXT_UNWRITTEN) ? XFS_EXT_NORM : XFS_EXT_UNWRITTEN; + /* + * Before insertion into the bmbt, zero the range being converted + * if required. + */ + if (flags & XFS_BMAPI_ZERO) { + error = xfs_zero_extent(bma->ip, mval->br_startblock, + mval->br_blockcount); + if (error) + return error; + } + error = xfs_bmap_add_extent_unwritten_real(bma->tp, bma->ip, &bma->idx, &bma->cur, mval, bma->firstblock, bma->flist, &tmp_logflags); @@ -4514,6 +4533,18 @@ xfs_bmapi_write( ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL); ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); + /* zeroing is for currently only for data extents, not metadata */ + ASSERT((flags & (XFS_BMAPI_METADATA | XFS_BMAPI_ZERO)) != + (XFS_BMAPI_METADATA | XFS_BMAPI_ZERO)); + /* + * we can allocate unwritten extents or pre-zero allocated blocks, + * but it makes no sense to do both at once. This would result in + * zeroing the unwritten extent twice, but it still being an + * unwritten extent.... + */ + ASSERT((flags & (XFS_BMAPI_PREALLOC | XFS_BMAPI_ZERO)) != + (XFS_BMAPI_PREALLOC | XFS_BMAPI_ZERO)); + if (unlikely(XFS_TEST_ERROR( (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE), diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h index 6aaa0c1..a160f8a 100644 --- a/fs/xfs/libxfs/xfs_bmap.h +++ b/fs/xfs/libxfs/xfs_bmap.h @@ -52,9 +52,9 @@ struct xfs_bmalloca { xfs_extlen_t minleft; /* amount must be left after alloc */ bool eof; /* set if allocating past last extent */ bool wasdel; /* replacing a delayed allocation */ - bool userdata;/* set if is user data */ bool aeof; /* allocated space at eof */ bool conv; /* overwriting unwritten extents */ + char userdata;/* userdata mask */ int flags; }; @@ -109,6 +109,14 @@ typedef struct xfs_bmap_free */ #define XFS_BMAPI_CONVERT 0x040 +/* + * allocate zeroed extents - this requires all newly allocated user data extents + * to be initialised to zero. It will be ignored if XFS_BMAPI_METADATA is set. + * Use in conjunction with XFS_BMAPI_CONVERT to convert unwritten extents found + * during the allocation range to zeroed written extents. + */ +#define XFS_BMAPI_ZERO 0x080 + #define XFS_BMAPI_FLAGS \ { XFS_BMAPI_ENTIRE, "ENTIRE" }, \ { XFS_BMAPI_METADATA, "METADATA" }, \ @@ -116,7 +124,8 @@ typedef struct xfs_bmap_free { XFS_BMAPI_PREALLOC, "PREALLOC" }, \ { XFS_BMAPI_IGSTATE, "IGSTATE" }, \ { XFS_BMAPI_CONTIG, "CONTIG" }, \ - { XFS_BMAPI_CONVERT, "CONVERT" } + { XFS_BMAPI_CONVERT, "CONVERT" }, \ + { XFS_BMAPI_ZERO, "ZERO" } static inline int xfs_bmapi_aflag(int w) diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index eca325e..dbae649 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -57,6 +57,35 @@ xfs_fsb_to_db(struct xfs_inode *ip, xfs_fsblock_t fsb) } /* + * Routine to zero an extent on disk allocated to the specific inode. + * + * The VFS functions take a linearised filesystem block offset, so we have to + * convert the sparse xfs fsb to the right format first. + * VFS types are real funky, too. + */ +int +xfs_zero_extent( + struct xfs_inode *ip, + xfs_fsblock_t start_fsb, + xfs_off_t count_fsb) +{ + struct xfs_mount *mp = ip->i_mount; + xfs_daddr_t sector = xfs_fsb_to_db(ip, start_fsb); + sector_t block = XFS_BB_TO_FSBT(mp, sector); + ssize_t size = XFS_FSB_TO_B(mp, count_fsb); + + if (IS_DAX(VFS_I(ip))) + return dax_clear_blocks(VFS_I(ip), block, size); + + /* + * let the block layer decide on the fastest method of + * implementing the zeroing. + */ + return sb_issue_zeroout(mp->m_super, block, count_fsb, GFP_NOFS); + +} + +/* * Routine to be called at transaction's end by xfs_bmapi, xfs_bunmapi * caller. Frees all the extents that need freeing, which must be done * last due to locking considerations. We never free any extents in @@ -229,6 +258,13 @@ xfs_bmap_rtalloc( xfs_trans_mod_dquot_byino(ap->tp, ap->ip, ap->wasdel ? XFS_TRANS_DQ_DELRTBCOUNT : XFS_TRANS_DQ_RTBCOUNT, (long) ralen); + + /* Zero the extent if we were asked to do so */ + if (ap->userdata & XFS_ALLOC_USERDATA_ZERO) { + error = xfs_zero_extent(ap->ip, ap->blkno, ap->length); + if (error) + return error; + } } else { ap->length = 0; } diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 8795272..f20e5de 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -337,4 +337,7 @@ extern int xfs_dev_is_read_only(struct xfs_mount *, char *); extern void xfs_set_low_space_thresholds(struct xfs_mount *); +int xfs_zero_extent(struct xfs_inode *ip, xfs_fsblock_t start_fsb, + xfs_off_t count_fsb); + #endif /* __XFS_MOUNT_H__ */ -- 2.5.0 From dave@fromorbit.com Sun Nov 1 21:42:45 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 6D1E07F67 for ; Sun, 1 Nov 2015 21:42:45 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 5C43A304053 for ; Sun, 1 Nov 2015 19:42:42 -0800 (PST) X-ASG-Debug-ID: 1446435757-04cbb0660c1b4570002-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id pTia1fTkdNG9ZENT for ; Sun, 01 Nov 2015 19:42:40 -0800 (PST) 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: A2B5BgBt2jZW/+rW03ZegzuBQqo5AQEBAQEBBpBUjCKBJ00BAQEBAQGBC4Q2AQUnLxEiCBgxOQMbGYgvwVmGMIpJJoQWBZZDjn6HY4VrjRNjgUoBC4JCKjSFfgEBAQ Received: from ppp118-211-214-234.lns20.syd4.internode.on.net (HELO dastard) ([118.211.214.234]) by ipmail07.adl2.internode.on.net with ESMTP; 02 Nov 2015 14:12:35 +1030 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1Zt60k-00014p-A3 for xfs@oss.sgi.com; Mon, 02 Nov 2015 14:42:22 +1100 Received: from dave by disappointment with local (Exim 4.86) (envelope-from ) id 1Zt60k-0000Sa-9L for xfs@oss.sgi.com; Mon, 02 Nov 2015 14:42:22 +1100 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH 6/7] xfs: xfs_filemap_pmd_fault treats read faults as write faults Date: Mon, 2 Nov 2015 14:42:14 +1100 X-ASG-Orig-Subj: [PATCH 6/7] xfs: xfs_filemap_pmd_fault treats read faults as write faults Message-Id: <1446435735-1526-7-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1446435735-1526-1-git-send-email-david@fromorbit.com> References: <1446435735-1526-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1446435759 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24026 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner The code initially committed didn't have the same checks for write faults as the dax_pmd_fault code and hence treats all faults as write faults. We can get read faults through this path because they is no pmd_mkwrite path for write faults similar to the normal page fault path. Hence we need to ensure that we only do c/mtime updates on write faults, and freeze protection is unnecessary for read faults. Signed-off-by: Dave Chinner Reviewed-by: Brian Foster Signed-off-by: Dave Chinner --- fs/xfs/xfs_file.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index e7cf9ec..0045b0a 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -1482,7 +1482,7 @@ xfs_file_llseek( * * mmap_sem (MM) * sb_start_pagefault(vfs, freeze) - * i_mmap_lock (XFS - truncate serialisation) + * i_mmaplock (XFS - truncate serialisation) * page_lock (MM) * i_lock (XFS - extent map serialisation) */ @@ -1550,6 +1550,13 @@ xfs_filemap_fault( return ret; } +/* + * Similar to xfs_filemap_fault(), the DAX fault path can call into here on + * both read and write faults. Hence we need to handle both cases. There is no + * ->pmd_mkwrite callout for huge pages, so we have a single function here to + * handle both cases here. @flags carries the information on the type of fault + * occuring. + */ STATIC int xfs_filemap_pmd_fault( struct vm_area_struct *vma, @@ -1566,13 +1573,18 @@ xfs_filemap_pmd_fault( trace_xfs_filemap_pmd_fault(ip); - sb_start_pagefault(inode->i_sb); - file_update_time(vma->vm_file); + if (flags & FAULT_FLAG_WRITE) { + sb_start_pagefault(inode->i_sb); + file_update_time(vma->vm_file); + } + xfs_ilock(XFS_I(inode), XFS_MMAPLOCK_SHARED); ret = __dax_pmd_fault(vma, addr, pmd, flags, xfs_get_blocks_dax_fault, NULL); xfs_iunlock(XFS_I(inode), XFS_MMAPLOCK_SHARED); - sb_end_pagefault(inode->i_sb); + + if (flags & FAULT_FLAG_WRITE) + sb_end_pagefault(inode->i_sb); return ret; } -- 2.5.0 From david@fromorbit.com Sun Nov 1 21:53:57 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 44F057F66 for ; Sun, 1 Nov 2015 21:53:57 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id CB835AC002 for ; Sun, 1 Nov 2015 19:53:56 -0800 (PST) X-ASG-Debug-ID: 1446436433-04bdf0330c1ba2e0001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id HTTXkLbZOmcS8soy for ; Sun, 01 Nov 2015 19:53:54 -0800 (PST) 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: A2DCBgD73TZW/+rW03ZegzsjMG+qIQIBFQEBAQEBAQaBDYohhSaGCRcChXoEgSlNAQEBAQEBgQuFEjskNAUlAzSIL6BqoGkJGYYXim+CFwxCgTEFkmaDXYUdiACOao1YY4FKDAGCQSo0hDYlgSMBAQE Received: from ppp118-211-214-234.lns20.syd4.internode.on.net (HELO dastard) ([118.211.214.234]) by ipmail07.adl2.internode.on.net with ESMTP; 02 Nov 2015 14:23:27 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1Zt6BF-00018G-3l for xfs@oss.sgi.com; Mon, 02 Nov 2015 14:53:13 +1100 Date: Mon, 2 Nov 2015 14:53:13 +1100 From: Dave Chinner To: xfs@oss.sgi.com Subject: [ANNOUNCE] xfs: for-next branch updated to f108bf2 Message-ID: <20151102035313.GZ19199@dastard> X-ASG-Orig-Subj: [ANNOUNCE] xfs: for-next branch updated to f108bf2 MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="cmJC7u66zC7hs+87" 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: 1446436433 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24027 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- --cmJC7u66zC7hs+87 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Hi Folks, The for-next branch of the xfs kernel repository at git://git.kernel.org/pub/scm/linux/kernel/git/dgc/linux-xfs.git has just been updated. The new head of the for-next branch is commit: f108bf2 Merge branch 'xfs-misc-fixes-for-4.4-2' into for-next New Commits: Andreas Gruenbacher (2): [1c99cfd] xfs: Validate the length of on-disk ACLs [80e0f22] xfs: Plug memory leak in xfs_attrmulti_attr_set Brian Foster (1): [6caa105] xfs: invalidate cached acl if set directly via xattr Dave Chinner (1): [f108bf2] Merge branch 'xfs-misc-fixes-for-4.4-2' into for-next Jiri Kosina (1): [24ba16b] xfs: clear PF_NOFREEZE for xfsaild kthread Code Diffstat: fs/xfs/libxfs/xfs_format.h | 8 ++++++-- fs/xfs/xfs_acl.c | 13 ++++++++----- fs/xfs/xfs_ioctl.c | 5 ++++- fs/xfs/xfs_trans_ail.c | 1 + fs/xfs/xfs_xattr.c | 19 +++++++++++++++++-- 5 files changed, 36 insertions(+), 10 deletions(-) --=20 Dave Chinner david@fromorbit.com --cmJC7u66zC7hs+87 Content-Type: application/pgp-signature; name="signature.asc" Content-Description: Digital signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQIcBAEBAgAGBQJWNt4oAAoJEK3oKUf0dfod4sIP/0U5Sb60erzFD4oIeXDZmwef nDYV+SCt+vRuqKb8r2Zbilse3pHViiZJgRUKli9x/suepe2eBGARsv5xTp9qPZin 9HMnRl/KCKxZMtd4N/eR4YaDntdjoN8UIiMgASEuriWmGxtZTJ+LIYpdR7Us159T plrthX2klT3kIKY4x8hZpEHI7O9RJYzUQ59ZzM8zaZrekoh/nyKt1/wCprSr6TLv fjt2zZqJKIvotdmI35mLaVCkljyvxHk0oSIxLZDB5U7BvZULThwN9hExw6UgIxH3 MrjE367z6ltDqKn7CkDYzcGpaKJ4YNmaaq4cuHS8io/XitR/7qUSR12PbhP+P7Ic PS1pRwKq5QOAG0IwaZ2vBvBWwB234HDO8MpeD4GxRgov5PBjI+EkGezj7LqwJFEI 07R5QS9j6IPzNR5M2dZEGCjC4rk/GFryUEqXqQ574iY5sdN9FSIB5zYg2kqAEFj1 YTY4RjZ+xcnRXw2IRBcbYYXJ2WbdtKY0XNwHTEC/vT1FDx6H0ifjMFDrggPJTjzz 91bOl/k7fvrgzvUflvnayKn8IZxnsPMZT/ctA2c7pAPLLVukY0PFWwmmWi6vkVbJ MOKMpPHBE5fUwnGfH75xcNrVd898hxucoBP1G87cQcaGzUa7agrsyrAwlV72J5KO p/9WMS/gwMRDzM5y4oZa =Dp/c -----END PGP SIGNATURE----- --cmJC7u66zC7hs+87-- From lendingtree-partners-xfs=oss.sgi.com@fluoridesubstance.com Mon Nov 2 05:44:35 2015 Return-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.1 required=5.0 tests=HTML_IMAGE_RATIO_04, HTML_MESSAGE,MIME_QP_LONG_LINE,T_DKIM_INVALID,T_REMOTE_IMAGE 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 770977F59 for ; Mon, 2 Nov 2015 05:44:35 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 1E985AC007 for ; Mon, 2 Nov 2015 03:44:32 -0800 (PST) X-ASG-Debug-ID: 1446464659-04bdf033091ca860001-NocioJ Received: from mail.fluoridesubstance.com (dyna51.armadyl.org [64.110.25.51]) by cuda.sgi.com with ESMTP id 2c1C1GtPl28fT9LC for ; Mon, 02 Nov 2015 03:44:19 -0800 (PST) X-Barracuda-Envelope-From: lendingtree-partners-xfs=oss.sgi.com@fluoridesubstance.com X-Barracuda-Apparent-Source-IP: 64.110.25.51 DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; s=dkim; d=fluoridesubstance.com; h=Date:From:To:Subject:MIME-Version:Content-Type:Message-ID; i=lendingtree-partners@fluoridesubstance.com; bh=VUc+MiSrw3KzRdbHAZP0ZWh3WFc=; b=qYEFvgGPr6ryjllfY1KX9I9e1Borm/h0By1WHiVt/il9CoKXQyV2ACLLN2r/UoSEhIntOAHE+AfO zpPpmzVbwAPedqYsS1/PrrnyRqXgcsTja/F17/k2SQ8/SPhgkARCqyRVJ0cvEiifH+ZOv+eUSohC tvUWgPsicU1+Jn9HnlI= DomainKey-Signature: a=rsa-sha1; c=nofws; q=dns; s=dkim; d=fluoridesubstance.com; b=V/2aPSVgtKvt9fouNPXuIIAOdiieagLOErRqkrVICjAZkzP6yoedoE+HJSR/CxfOnyJ1n0W7c4Cu MZJjJ2JKgli6bJJQj6k4ZwYmoPCgdXvrFbX5dnt0JwMgZgbVNe5CGx5XHcoZqsmbQ3+jvh9LZUj4 u2G0G/SOeh8NVInF2es=; Received: by mail.fluoridesubstance.com id h6t6980001gs for ; Mon, 2 Nov 2015 05:35:36 -0600 (envelope-from ) Date: Mon, 2 Nov 2015 05:35:36 -0600 From: "LendingTree Partners" To: Subject: Mortgage rates are rising. Refi now. Don't miss out! MIME-Version: 1.0 X-ASG-Orig-Subj: Mortgage rates are rising. Refi now. Don't miss out! Content-Type: multipart/alternative; boundary="----=_Part_58_1148131817.1446464063789" Message-ID: <0.0.0.1F.1D1156297BA58BA.3D03B7@mail.fluoridesubstance.com> X-Barracuda-Connect: dyna51.armadyl.org[64.110.25.51] X-Barracuda-Start-Time: 1446464659 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 2.59 X-Barracuda-Spam-Status: No, SCORE=2.59 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC2_MV0250, DKIM_SIGNED, DKIM_VERIFIED, HTML_IMAGE_RATIO_04, HTML_MESSAGE, MARKETING_SUBJECT, MIME_QP_LONG_LINE, MIME_QP_LONG_LINE_2 X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24034 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 0.17 HTML_IMAGE_RATIO_04 BODY: HTML has a low ratio of text to image area 0.00 HTML_MESSAGE BODY: HTML included in message 0.00 MIME_QP_LONG_LINE RAW: Quoted-printable line longer than 76 chars 1.00 BSF_SC2_MV0250 Custom rule MV0250 0.82 MIME_QP_LONG_LINE_2 RAW: Quoted-printable line longer than 76 chars ------=_Part_58_1148131817.1446464063789 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit Mortgage rates are rising. Refi now. Don't miss out! http://www.fluoridesubstance.com/3efP86nM30T9aZsnFjnn0ntv0Mjh582/answer Update Preferences- http://www.fluoridesubstance.com/knew/648C86NL30a7ZsnFjnn0ntv0Mjh9d7 ------=_Part_58_1148131817.1446464063789 Content-Type: text/html; charset=us-ascii Content-Transfer-Encoding: quoted-printable =20 LendingTree=20 =20 =20
=20

Mortgage rates are rising. Refi now. Don't miss out!

=20
=20 =20 =20 =20 =20 =20 =20
View as webpage | Update Preferences
=20 =20 =20 =20 =20 =20 =20
3D""
=20 =20 =20 =20 =20 =20 =20
 
=20 =20 =20 =20 =20 =20 =20 =20 =20

Shop for it.

=20

3D"30  3D"15  3D"5/1
=20 =20 =20 =20 =20 =20 =20
3D""
=20 =20 =20 =20 =20 =20 =20 =20 =20 =20 =20 =20 =20

  View Multiple Offers Now!

 
 
=20 =20 =20 =20 =20 =20 =20 =20 =20
 

Advertising Disclosures

LendingTree, LLC dba LendingTreePar= tners.com is a duly licensed mortgage broker, as required, with its main of= fice located at 11115 Rushmore Dr., Charlotte, NC 28277, Telephone number 1= -877-703-8733. NMLS Unique Identifier #1136. LendingTreePartners.com is kno= wn as LT Technologies in Lieu of true name, LendingTree, LLC in NY. For a c= urrent list of applicable state licensing & disclosures, see the Lendin= gTree website or call for details. This is a commercial email from LendingT= reePartners.com and may be recurring.

LendingTreePartners.com: Update Preferences | Privacy Policy= | Terms of Use | Disclosures and Licenses

 
=20
=20
=20
=20
=20
=20
=20
=20
=20
 =20

=20

=20 =20 ------=_Part_58_1148131817.1446464063789-- From eflorac@intellique.com Mon Nov 2 06:05:15 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 6D31A29DF5 for ; Mon, 2 Nov 2015 06:05:15 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 58FAA304039 for ; Mon, 2 Nov 2015 04:05:11 -0800 (PST) X-ASG-Debug-ID: 1446465908-04cbb0660d1c6730001-NocioJ Received: from mail1.g1.pair.com (mail1.g1.pair.com [66.39.3.162]) by cuda.sgi.com with ESMTP id G8m8vQAGUTWNqn7C (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 02 Nov 2015 04:05:09 -0800 (PST) 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 98E5E2CB37; Mon, 2 Nov 2015 07:05:08 -0500 (EST) Received: from harpe.intellique.com (labo.djinux.com [82.225.196.72]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail1.g1.pair.com (Postfix) with ESMTPSA id 9D0792CA32; Mon, 2 Nov 2015 07:05:07 -0500 (EST) Date: Mon, 2 Nov 2015 13:05:10 +0100 From: Emmanuel Florac To: Stefan Ring Cc: "krautus@kr916.org" , Linux fs XFS Subject: Re: hdd + ssd Message-ID: <20151102130510.7292dec5@harpe.intellique.com> X-ASG-Orig-Subj: Re: hdd + ssd In-Reply-To: References: <20151022202324.5f00807f@linux> <20151023134805.3c7998e4@harpe.intellique.com> Organization: Intellique X-Mailer: Claws Mail 3.12.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: 1446465909 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/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=BSF_SC7_SA298e X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24035 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.20 BSF_SC7_SA298e Custom Rule SA298e Le Fri, 23 Oct 2015 23:34:00 +0200 Stefan Ring =C3=A9crivait: > Very good summary, thanks! Do you also happen to know if all of these > retain cache contents across reboots? Yes, they retain cache contents across reboots. --=20 ------------------------------------------------------------------------ Emmanuel Florac | Direction technique | Intellique | | +33 1 78 94 84 02 ------------------------------------------------------------------------ From david@fromorbit.com Mon Nov 2 06:20:40 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 2F05329DF5 for ; Mon, 2 Nov 2015 06:20:40 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id C860FAC001 for ; Mon, 2 Nov 2015 04:20:39 -0800 (PST) X-ASG-Debug-ID: 1446466832-04bdf0330c1cbdb0001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id ZUqZkxXxZxHdITUt for ; Mon, 02 Nov 2015 04:20:32 -0800 (PST) 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: A2CwBwDQUzdW/+rW03ZegzuBQoJdp18BAQEBAQEGiy6FJoYJhhMCAgEBAoEtTQEBAQEBAYELhDYBAQQ6HCMQCAMOCgklDwUlAyETiC/BHgEBCAIBIBmGF4VFiUAFlkONHYFhhD+HNIp8g3JjghEdgWoqNIQ2JYEjAQEB Received: from ppp118-211-214-234.lns20.syd4.internode.on.net (HELO dastard) ([118.211.214.234]) by ipmail07.adl2.internode.on.net with ESMTP; 02 Nov 2015 22:50:31 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZtE5y-000207-Df; Mon, 02 Nov 2015 23:20:18 +1100 Date: Mon, 2 Nov 2015 23:20:18 +1100 From: Dave Chinner To: Andreas Gruenbacher Cc: Brian Foster , xfs@oss.sgi.com Subject: Re: [PATCH v2 0/5] xfs: SGI ACL Fixes Message-ID: <20151102122018.GH10656@dastard> X-ASG-Orig-Subj: Re: [PATCH v2 0/5] xfs: SGI ACL Fixes References: <1446217508-22157-1-git-send-email-agruenba@redhat.com> <20151102025352.GY19199@dastard> 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: 1446466832 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24035 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Mon, Nov 02, 2015 at 04:41:30AM +0100, Andreas Gruenbacher wrote: > On Mon, Nov 2, 2015 at 3:53 AM, Dave Chinner wrote: > > On Fri, Oct 30, 2015 at 04:05:03PM +0100, Andreas Gruenbacher wrote: > >> Here is a reworked patch queue that also handles setting SGI_ACL_{FILE,DEFAULT} > >> via XFS_IOC_ATTRMULTI_BY_HANDLE. Please review. > >> > >> Thanks, > >> Andreas > >> > >> Andreas Gruenbacher (5): > >> xfs: Validate the length of on-disk ACLs > >> xfs: Plug memory leak in xfs_attrmulti_attr_set > > > > Ok, I've taken these two patches for the upcoming merge window as > > they fix bugs, but I've taken Brian's cached ACL invalidation patch > > instead of these: > > > >> xfs: SGI ACLs: Fix caching and mode setting > >> xfs: Add namespace parameter to the xfs kuid/kgid <=> uid/gid wrappers > >> xfs: SGI ACLs: Map uid/gid namespaces > > > > I'm not yet convinced that these patches are the right way to solve > > the given issue as they may interact badly with xfsdump/restore. > > Well, what else do you need to be convinced? I guess it won't help if > I try to explain everything all over again? No, it won't. There are bigger picture questions and issues that need to be sorted out first. We've basically got zero regression test coverage of the "set the ACL in on-disk format directly" code path, so we don't know if we're breaking anything. That's a big red flag to me, because I can't easily validate that the changes are working as expected.. IOWs, I don't know how the changes will impact dump/restore, apart from the fact that dump/restore expects to be able to set the ACL directly in the on-disk format without the kernel screwing with the mode. i.e. dump pulls the inode mode and ACLs in disk format from the disk via bulkstat and restore expects to be able to recreate them exactly without the kernel getting in it's way. Again, we have basically no test coverage here, so again there's nothing I can do to easily validate that the changes have not broken dump/restore in subtle but important ways. Further, we have no user namespace regression test coverage. I have absolutely no idea if xfs_restore will even run in a user namespace, let alone run correctly. We already know that xfsdump cannot be made to work in a confined user namespace due to it's use of bulkstat, so do we really care whether xfs_restore works in a namespace or not? As such, it's not immediately obvious to me that we should even allow setting acls directly in on-disk format in user namespaces. And if we don't allow it, then the last two patches can simply be dropped and replaced with simple CAP_SYS_ADMIN check. I don't have time to sit down and write special point tests to validate every change that comes through. However, ACLs are a security mechanism and so we have to get them right and that means we need such tests. If you want to convince me that your changes are correct, are needed and don't break anything, then provide the regression tests that prove it. Otherwise you're simply going to have to wait for me to find the time to do it myself - I've got a real long list of stuff I'd prefer to do than write ACL regression tests.... Cheers, Dave. -- Dave Chinner david@fromorbit.com From bfoster@redhat.com Mon Nov 2 08:15:17 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 1A6A829DF5 for ; Mon, 2 Nov 2015 08:15:17 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id E59588F8040 for ; Mon, 2 Nov 2015 06:15:13 -0800 (PST) X-ASG-Debug-ID: 1446473712-04cb6c7b871b6fb0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 8rj1YzbPZRRBsWQj (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 02 Nov 2015 06:15:12 -0800 (PST) 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 (Postfix) with ESMTPS id DE5C542E5AA; Mon, 2 Nov 2015 14:15:11 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-105.bos.redhat.com [10.18.41.105]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA2EFBRj032104; Mon, 2 Nov 2015 09:15:11 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id 458121201AB; Mon, 2 Nov 2015 09:15:10 -0500 (EST) Date: Mon, 2 Nov 2015 09:15:10 -0500 From: Brian Foster To: Dave Chinner Cc: ross.zwisler@linux.intel.com, jack@suse.cz, xfs@oss.sgi.com Subject: Re: [PATCH 3/6] xfs: Don't use unwritten extents for DAX Message-ID: <20151102141509.GA29346@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH 3/6] xfs: Don't use unwritten extents for DAX References: <1445225238-30413-1-git-send-email-david@fromorbit.com> <1445225238-30413-4-git-send-email-david@fromorbit.com> <20151029142950.GE11663@bfoster.bfoster> <20151029233756.GS19199@dastard> <20151030123657.GC54905@bfoster.bfoster> <20151102011433.GW19199@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151102011433.GW19199@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: 1446473712 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Mon, Nov 02, 2015 at 12:14:33PM +1100, Dave Chinner wrote: > On Fri, Oct 30, 2015 at 08:36:57AM -0400, Brian Foster wrote: > > On Fri, Oct 30, 2015 at 10:37:56AM +1100, Dave Chinner wrote: > > > On Thu, Oct 29, 2015 at 10:29:50AM -0400, Brian Foster wrote: > > > > On Mon, Oct 19, 2015 at 02:27:15PM +1100, Dave Chinner wrote: > > > > > From: Dave Chinner > > > > > > > ... > > > > > + /* > > > > > + * For DAX, we do not allocate unwritten extents, but instead we zero > > > > > + * the block before we commit the transaction. Ideally we'd like to do > > > > > + * this outside the transaction context, but if we commit and then crash > > > > > + * we may not have zeroed the blocks and this will be exposed on > > > > > + * recovery of the allocation. Hence we must zero before commit. > > > > > + * Further, if we are mapping unwritten extents here, we need to zero > > > > > + * and convert them to written so that we don't need an unwritten extent > > > > > + * callback for DAX. This also means that we need to be able to dip into > > > > > + * the reserve block pool if there is no space left but we need to do > > > > > + * unwritten extent conversion. > > > > > + */ > > > > > + if (IS_DAX(VFS_I(ip))) { > > > > > + bmapi_flags = XFS_BMAPI_CONVERT | XFS_BMAPI_ZERO; > > > > > + tp->t_flags |= XFS_TRANS_RESERVE; > > > > > + } > > > > > > > > Am I following the commit log description correctly in that block > > > > zeroing is only required for DAX faults? Do we zero blocks for DAX DIO > > > > as well to be consistent, or is that also required (because it looks > > > > like we still have end_io completion for dio writes anyways)? > > > > > > DAX DIO will do the zeroing rather than using unwritten extents, > > > too. But we still have DIO IO completion as that needs to do file > > > size updates. > > > > > > > Right, my question is: is the DAX DIO zeroing required to avoid the > > races described as the purpose for this patch, or is this just here as a > > simplification? In other words, why not do block zeroing only for DAX > > faults and not DAX/DIO? > > Because the only reason the DIO code does 'allocate unwritten; > convert unwritten on IO completion' is so that if we have: > > allocate > trans_commit > .... log force > journal IO submit > .... journal IO completion > submit data io > crash > > We don't expose allocated blocks containing stale data to userspace > via recovery. The allcoation uses unwritten extents to ensure that > if the allocation is recovered without the correspending completion, > it reads as zeros rather whatever was previously on disk in taht > location. > > For DAX, we can zero the blocks inside the allocation transaction > for direct IO, and hence even if we have the above happen, we'll > only ever expose zeros. Hence we don't need unwritten extents in the > DIO path to avoid stale data exposure, and so we can simply avoid > all that extra overhead of unwritten extent conversion on > completion... > Yeah, I get that bit. In fact, I was hoping to get to doing something similar for delalloc extents to deal with the similar issue there if the extent conversion makes it to the log and we crash before I/O (as I believe we've discussed in the past). That is for something unrelated, however... > > I ask because my understanding is the purpose of this patch is a special > > atomic zeroed allocation requirement just for mmap. > > The requirement is set by DAX+mmap; the implementation is a generic > "allocate zeroed blocks" mechanism that can be applied to any > allocation that uses unwritten extents to allocate zeroed blocks if > zeroing is more efficient than using unwritten extents.... > Ok, I take that to mean that there is no race or corruption vector so long as DAX/mmap uses the atomic zero allocation. The implementation mostly looks pretty good to me, but I suspect I'm not being clear with my question, which is... > > Unless there is some > > special mixed dio/mmap case I'm missing, doing so for DAX/DIO basically > > causes a clear_pmem() over every page sized chunk of the target I/O > > range for which we already have the data. > > I don't follow - this only zeros blocks when we do allocation of new > blocks or overwrite unwritten extents, not on blocks which we > already have written data extents allocated for... > Why are we assuming that block zeroing is more efficient than unwritten extents for DAX/dio? I haven't played with pmem enough to know for sure one way or another (or if hw support is imminent), but I'd expect the latter to be more efficient in general without any kind of hardware support. Just as an example, here's an 8GB pwrite test, large buffer size, to XFS on a ramdisk mounted with '-o dax:' - Before this series: # xfs_io -fc "truncate 0" -c "pwrite -b 10m 0 8g" /mnt/file wrote 8589934592/8589934592 bytes at offset 0 8.000 GiB, 820 ops; 0:00:04.00 (1.909 GiB/sec and 195.6591 ops/sec) - After this series: # xfs_io -fc "truncate 0" -c "pwrite -b 10m 0 8g" /mnt/file wrote 8589934592/8589934592 bytes at offset 0 8.000 GiB, 820 ops; 0:00:12.00 (659.790 MiB/sec and 66.0435 ops/sec) The impact is less with a smaller buffer size so the above is just meant to illustrate the point. FWIW, I'm also fine with getting this in as a matter of "correctness before performance" since this stuff is clearly still under development, but as far as I can see so far we should probably ultimately prefer unwritten extents for DAX/DIO (or at least plan to run some similar tests on real pmem hw). Thoughts? 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 Mon Nov 2 08:15:22 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 2035C29DFC for ; Mon, 2 Nov 2015 08:15:22 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 0CF148F8049 for ; Mon, 2 Nov 2015 06:15:21 -0800 (PST) X-ASG-Debug-ID: 1446473719-04cbb0660f1caf00001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id xjB61qqgJtsmGEDU (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 02 Nov 2015 06:15:19 -0800 (PST) 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 (Postfix) with ESMTPS id 50C958CF43; Mon, 2 Nov 2015 14:15:19 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-105.bos.redhat.com [10.18.41.105]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA2EFIjP003857; Mon, 2 Nov 2015 09:15:19 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id E11521201AB; Mon, 2 Nov 2015 09:15:17 -0500 (EST) Date: Mon, 2 Nov 2015 09:15:17 -0500 From: Brian Foster To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH 2/7] xfs: introduce BMAPI_ZERO for allocating zeroed extents Message-ID: <20151102141517.GB29346@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH 2/7] xfs: introduce BMAPI_ZERO for allocating zeroed extents References: <1446435735-1526-1-git-send-email-david@fromorbit.com> <1446435735-1526-3-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1446435735-1526-3-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.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1446473719 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Mon, Nov 02, 2015 at 02:42:10PM +1100, Dave Chinner wrote: > From: Dave Chinner > > To enable DAX to do atomic allocation of zeroed extents, we need to > drive the block zeroing deep into the allocator. Because > xfs_bmapi_write() can return merged extents on allocation that were > only partially allocated (i.e. requested range spans allocated and > hole regions, allocation into the hole was contiguous), we cannot > zero the extent returned from xfs_bmapi_write() as that can > overwrite existing data with zeros. > > Hence we have to drive the extent zeroing into the allocation code, > prior to where we merge the extents into the BMBT and return the > resultant map. This means we need to propagate this need down to > the xfs_alloc_vextent() and issue the block zeroing at this point. > > While this functionality is being introduced for DAX, there is no > reason why it is specific to DAX - we can per-zero blocks during the > allocation transaction on any type of device. It's just slow (and > usually slower than unwritten allocation and conversion) on > traditional block devices so doesn't tend to get used. We can, > however, hook hardware zeroing optimisations via sb_issue_zeroout() > to this operation, so it may be useful in future and hence the > "allocate zeroed blocks" API needs to be implementation neutral. > > Signed-off-by: Dave Chinner > --- Looks good with the assert fix: Reviewed-by: Brian Foster > fs/xfs/libxfs/xfs_alloc.c | 10 +++++++++- > fs/xfs/libxfs/xfs_alloc.h | 8 +++++--- > fs/xfs/libxfs/xfs_bmap.c | 35 +++++++++++++++++++++++++++++++++-- > fs/xfs/libxfs/xfs_bmap.h | 13 +++++++++++-- > fs/xfs/xfs_bmap_util.c | 36 ++++++++++++++++++++++++++++++++++++ > fs/xfs/xfs_mount.h | 3 +++ > 6 files changed, 97 insertions(+), 8 deletions(-) > > diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c > index e926197..3479294 100644 > --- a/fs/xfs/libxfs/xfs_alloc.c > +++ b/fs/xfs/libxfs/xfs_alloc.c > @@ -2509,7 +2509,7 @@ xfs_alloc_vextent( > * Try near allocation first, then anywhere-in-ag after > * the first a.g. fails. > */ > - if ((args->userdata == XFS_ALLOC_INITIAL_USER_DATA) && > + if ((args->userdata & XFS_ALLOC_INITIAL_USER_DATA) && > (mp->m_flags & XFS_MOUNT_32BITINODES)) { > args->fsbno = XFS_AGB_TO_FSB(mp, > ((mp->m_agfrotor / rotorstep) % > @@ -2640,6 +2640,14 @@ xfs_alloc_vextent( > XFS_AG_CHECK_DADDR(mp, XFS_FSB_TO_DADDR(mp, args->fsbno), > args->len); > #endif > + > + /* Zero the extent if we were asked to do so */ > + if (args->userdata & XFS_ALLOC_USERDATA_ZERO) { > + error = xfs_zero_extent(args->ip, args->fsbno, args->len); > + if (error) > + goto error0; > + } > + > } > xfs_perag_put(args->pag); > return 0; > diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h > index ca1c816..0ecde4d 100644 > --- a/fs/xfs/libxfs/xfs_alloc.h > +++ b/fs/xfs/libxfs/xfs_alloc.h > @@ -101,6 +101,7 @@ typedef struct xfs_alloc_arg { > struct xfs_mount *mp; /* file system mount point */ > struct xfs_buf *agbp; /* buffer for a.g. freelist header */ > struct xfs_perag *pag; /* per-ag struct for this agno */ > + struct xfs_inode *ip; /* for userdata zeroing method */ > xfs_fsblock_t fsbno; /* file system block number */ > xfs_agnumber_t agno; /* allocation group number */ > xfs_agblock_t agbno; /* allocation group-relative block # */ > @@ -120,15 +121,16 @@ typedef struct xfs_alloc_arg { > char wasdel; /* set if allocation was prev delayed */ > char wasfromfl; /* set if allocation is from freelist */ > char isfl; /* set if is freelist blocks - !acctg */ > - char userdata; /* set if this is user data */ > + char userdata; /* mask defining userdata treatment */ > xfs_fsblock_t firstblock; /* io first block allocated */ > } xfs_alloc_arg_t; > > /* > * Defines for userdata > */ > -#define XFS_ALLOC_USERDATA 1 /* allocation is for user data*/ > -#define XFS_ALLOC_INITIAL_USER_DATA 2 /* special case start of file */ > +#define XFS_ALLOC_USERDATA (1 << 0)/* allocation is for user data*/ > +#define XFS_ALLOC_INITIAL_USER_DATA (1 << 1)/* special case start of file */ > +#define XFS_ALLOC_USERDATA_ZERO (1 << 2)/* zero extent on allocation */ > > xfs_extlen_t xfs_alloc_longest_free_extent(struct xfs_mount *mp, > struct xfs_perag *pag, xfs_extlen_t need); > diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c > index ab92d10..119c242 100644 > --- a/fs/xfs/libxfs/xfs_bmap.c > +++ b/fs/xfs/libxfs/xfs_bmap.c > @@ -3802,8 +3802,13 @@ xfs_bmap_btalloc( > args.wasdel = ap->wasdel; > args.isfl = 0; > args.userdata = ap->userdata; > - if ((error = xfs_alloc_vextent(&args))) > + if (ap->userdata & XFS_ALLOC_USERDATA_ZERO) > + args.ip = ap->ip; > + > + error = xfs_alloc_vextent(&args); > + if (error) > return error; > + > if (tryagain && args.fsbno == NULLFSBLOCK) { > /* > * Exact allocation failed. Now try with alignment > @@ -4302,11 +4307,14 @@ xfs_bmapi_allocate( > > /* > * Indicate if this is the first user data in the file, or just any > - * user data. > + * user data. And if it is userdata, indicate whether it needs to > + * be initialised to zero during allocation. > */ > if (!(bma->flags & XFS_BMAPI_METADATA)) { > bma->userdata = (bma->offset == 0) ? > XFS_ALLOC_INITIAL_USER_DATA : XFS_ALLOC_USERDATA; > + if (bma->flags & XFS_BMAPI_ZERO) > + bma->userdata |= XFS_ALLOC_USERDATA_ZERO; > } > > bma->minlen = (bma->flags & XFS_BMAPI_CONTIG) ? bma->length : 1; > @@ -4421,6 +4429,17 @@ xfs_bmapi_convert_unwritten( > mval->br_state = (mval->br_state == XFS_EXT_UNWRITTEN) > ? XFS_EXT_NORM : XFS_EXT_UNWRITTEN; > > + /* > + * Before insertion into the bmbt, zero the range being converted > + * if required. > + */ > + if (flags & XFS_BMAPI_ZERO) { > + error = xfs_zero_extent(bma->ip, mval->br_startblock, > + mval->br_blockcount); > + if (error) > + return error; > + } > + > error = xfs_bmap_add_extent_unwritten_real(bma->tp, bma->ip, &bma->idx, > &bma->cur, mval, bma->firstblock, bma->flist, > &tmp_logflags); > @@ -4514,6 +4533,18 @@ xfs_bmapi_write( > ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL); > ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); > > + /* zeroing is for currently only for data extents, not metadata */ > + ASSERT((flags & (XFS_BMAPI_METADATA | XFS_BMAPI_ZERO)) != > + (XFS_BMAPI_METADATA | XFS_BMAPI_ZERO)); > + /* > + * we can allocate unwritten extents or pre-zero allocated blocks, > + * but it makes no sense to do both at once. This would result in > + * zeroing the unwritten extent twice, but it still being an > + * unwritten extent.... > + */ > + ASSERT((flags & (XFS_BMAPI_PREALLOC | XFS_BMAPI_ZERO)) != > + (XFS_BMAPI_PREALLOC | XFS_BMAPI_ZERO)); > + > if (unlikely(XFS_TEST_ERROR( > (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && > XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE), > diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h > index 6aaa0c1..a160f8a 100644 > --- a/fs/xfs/libxfs/xfs_bmap.h > +++ b/fs/xfs/libxfs/xfs_bmap.h > @@ -52,9 +52,9 @@ struct xfs_bmalloca { > xfs_extlen_t minleft; /* amount must be left after alloc */ > bool eof; /* set if allocating past last extent */ > bool wasdel; /* replacing a delayed allocation */ > - bool userdata;/* set if is user data */ > bool aeof; /* allocated space at eof */ > bool conv; /* overwriting unwritten extents */ > + char userdata;/* userdata mask */ > int flags; > }; > > @@ -109,6 +109,14 @@ typedef struct xfs_bmap_free > */ > #define XFS_BMAPI_CONVERT 0x040 > > +/* > + * allocate zeroed extents - this requires all newly allocated user data extents > + * to be initialised to zero. It will be ignored if XFS_BMAPI_METADATA is set. > + * Use in conjunction with XFS_BMAPI_CONVERT to convert unwritten extents found > + * during the allocation range to zeroed written extents. > + */ > +#define XFS_BMAPI_ZERO 0x080 > + > #define XFS_BMAPI_FLAGS \ > { XFS_BMAPI_ENTIRE, "ENTIRE" }, \ > { XFS_BMAPI_METADATA, "METADATA" }, \ > @@ -116,7 +124,8 @@ typedef struct xfs_bmap_free > { XFS_BMAPI_PREALLOC, "PREALLOC" }, \ > { XFS_BMAPI_IGSTATE, "IGSTATE" }, \ > { XFS_BMAPI_CONTIG, "CONTIG" }, \ > - { XFS_BMAPI_CONVERT, "CONVERT" } > + { XFS_BMAPI_CONVERT, "CONVERT" }, \ > + { XFS_BMAPI_ZERO, "ZERO" } > > > static inline int xfs_bmapi_aflag(int w) > diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c > index eca325e..dbae649 100644 > --- a/fs/xfs/xfs_bmap_util.c > +++ b/fs/xfs/xfs_bmap_util.c > @@ -57,6 +57,35 @@ xfs_fsb_to_db(struct xfs_inode *ip, xfs_fsblock_t fsb) > } > > /* > + * Routine to zero an extent on disk allocated to the specific inode. > + * > + * The VFS functions take a linearised filesystem block offset, so we have to > + * convert the sparse xfs fsb to the right format first. > + * VFS types are real funky, too. > + */ > +int > +xfs_zero_extent( > + struct xfs_inode *ip, > + xfs_fsblock_t start_fsb, > + xfs_off_t count_fsb) > +{ > + struct xfs_mount *mp = ip->i_mount; > + xfs_daddr_t sector = xfs_fsb_to_db(ip, start_fsb); > + sector_t block = XFS_BB_TO_FSBT(mp, sector); > + ssize_t size = XFS_FSB_TO_B(mp, count_fsb); > + > + if (IS_DAX(VFS_I(ip))) > + return dax_clear_blocks(VFS_I(ip), block, size); > + > + /* > + * let the block layer decide on the fastest method of > + * implementing the zeroing. > + */ > + return sb_issue_zeroout(mp->m_super, block, count_fsb, GFP_NOFS); > + > +} > + > +/* > * Routine to be called at transaction's end by xfs_bmapi, xfs_bunmapi > * caller. Frees all the extents that need freeing, which must be done > * last due to locking considerations. We never free any extents in > @@ -229,6 +258,13 @@ xfs_bmap_rtalloc( > xfs_trans_mod_dquot_byino(ap->tp, ap->ip, > ap->wasdel ? XFS_TRANS_DQ_DELRTBCOUNT : > XFS_TRANS_DQ_RTBCOUNT, (long) ralen); > + > + /* Zero the extent if we were asked to do so */ > + if (ap->userdata & XFS_ALLOC_USERDATA_ZERO) { > + error = xfs_zero_extent(ap->ip, ap->blkno, ap->length); > + if (error) > + return error; > + } > } else { > ap->length = 0; > } > diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h > index 8795272..f20e5de 100644 > --- a/fs/xfs/xfs_mount.h > +++ b/fs/xfs/xfs_mount.h > @@ -337,4 +337,7 @@ extern int xfs_dev_is_read_only(struct xfs_mount *, char *); > > extern void xfs_set_low_space_thresholds(struct xfs_mount *); > > +int xfs_zero_extent(struct xfs_inode *ip, xfs_fsblock_t start_fsb, > + xfs_off_t count_fsb); > + > #endif /* __XFS_MOUNT_H__ */ > -- > 2.5.0 > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From bfoster@redhat.com Mon Nov 2 08:15:33 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 D40B429DFC for ; Mon, 2 Nov 2015 08:15:33 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 9B9968F8037 for ; Mon, 2 Nov 2015 06:15:33 -0800 (PST) X-ASG-Debug-ID: 1446473732-04bdf0330b1cfe00001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id PH0nwoY4njOuqMY9 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 02 Nov 2015 06:15:32 -0800 (PST) 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 (Postfix) with ESMTPS id F1AEB8F289; Mon, 2 Nov 2015 14:15:31 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-105.bos.redhat.com [10.18.41.105]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA2EFVEU001554; Mon, 2 Nov 2015 09:15:31 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id 8FFAF1201AB; Mon, 2 Nov 2015 09:15:30 -0500 (EST) Date: Mon, 2 Nov 2015 09:15:30 -0500 From: Brian Foster To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH 3/7] xfs: Don't use unwritten extents for DAX Message-ID: <20151102141530.GC29346@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH 3/7] xfs: Don't use unwritten extents for DAX References: <1446435735-1526-1-git-send-email-david@fromorbit.com> <1446435735-1526-4-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1446435735-1526-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.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1446473732 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Mon, Nov 02, 2015 at 02:42:11PM +1100, Dave Chinner wrote: > From: Dave Chinner > > DAX has a page fault serialisation problem with block allocation. > Because it allows concurrent page faults and does not have a page > lock to serialise faults to the same page, it can get two concurrent > faults to the page that race. > > When two read faults race, this isn't a huge problem as the data > underlying the page is not changing and so "detect and drop" works > just fine. The issues are to do with write faults. > > When two write faults occur, we serialise block allocation in > get_blocks() so only one faul will allocate the extent. It will, > however, be marked as an unwritten extent, and that is where the > problem lies - the DAX fault code cannot differentiate between a > block that was just allocated and a block that was preallocated and > needs zeroing. The result is that both write faults end up zeroing > the block and attempting to convert it back to written. > > The problem is that the first fault can zero and convert before the > second fault starts zeroing, resulting in the zeroing for the second > fault overwriting the data that the first fault wrote with zeros. > The second fault then attempts to convert the unwritten extent, > which is then a no-op because it's already written. Data loss occurs > as a result of this race. > > Because there is no sane locking construct in the page fault code > that we can use for serialisation across the page faults, we need to > ensure block allocation and zeroing occurs atomically in the > filesystem. This means we can still take concurrent page faults and > the only time they will serialise is in the filesystem > mapping/allocation callback. The page fault code will always see > written, initialised extents, so we will be able to remove the > unwritten extent handling from the DAX code when all filesystems are > converted. > > Signed-off-by: Dave Chinner > --- I'm still not convinced that block zeroing is the right thing to do for DAX/dio (re: the discussion on the previous version), but the code looks fine to me and we should be able to easily optimize this in a separate patch if warranted: Reviewed-by: Brian Foster > fs/dax.c | 5 +++++ > fs/xfs/xfs_aops.c | 13 +++++++++---- > fs/xfs/xfs_iomap.c | 21 ++++++++++++++++++++- > 3 files changed, 34 insertions(+), 5 deletions(-) > > diff --git a/fs/dax.c b/fs/dax.c > index a86d3cc..131fd35a 100644 > --- a/fs/dax.c > +++ b/fs/dax.c > @@ -29,6 +29,11 @@ > #include > #include > > +/* > + * dax_clear_blocks() is called from within transaction context from XFS, > + * and hence this means the stack from this point must follow GFP_NOFS > + * semantics for all operations. > + */ > int dax_clear_blocks(struct inode *inode, sector_t block, long size) > { > struct block_device *bdev = inode->i_sb->s_bdev; > diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c > index 366e41eb..7b4f849 100644 > --- a/fs/xfs/xfs_aops.c > +++ b/fs/xfs/xfs_aops.c > @@ -1293,15 +1293,12 @@ xfs_map_direct( > > trace_xfs_gbmap_direct(XFS_I(inode), offset, size, type, imap); > > - /* XXX: preparation for removing unwritten extents in DAX */ > -#if 0 > if (dax_fault) { > ASSERT(type == XFS_IO_OVERWRITE); > trace_xfs_gbmap_direct_none(XFS_I(inode), offset, size, type, > imap); > return; > } > -#endif > > if (bh_result->b_private) { > ioend = bh_result->b_private; > @@ -1429,10 +1426,12 @@ __xfs_get_blocks( > if (error) > goto out_unlock; > > + /* for DAX, we convert unwritten extents directly */ > if (create && > (!nimaps || > (imap.br_startblock == HOLESTARTBLOCK || > - imap.br_startblock == DELAYSTARTBLOCK))) { > + imap.br_startblock == DELAYSTARTBLOCK) || > + (IS_DAX(inode) && ISUNWRITTEN(&imap)))) { > if (direct || xfs_get_extsz_hint(ip)) { > /* > * xfs_iomap_write_direct() expects the shared lock. It > @@ -1477,6 +1476,12 @@ __xfs_get_blocks( > goto out_unlock; > } > > + if (IS_DAX(inode) && create) { > + ASSERT(!ISUNWRITTEN(&imap)); > + /* zeroing is not needed at a higher layer */ > + new = 0; > + } > + > /* trim mapping down to size requested */ > if (direct || size > (1 << inode->i_blkbits)) > xfs_map_trim_size(inode, iblock, bh_result, > diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c > index c3cb5a5..f4f5b43 100644 > --- a/fs/xfs/xfs_iomap.c > +++ b/fs/xfs/xfs_iomap.c > @@ -132,6 +132,7 @@ xfs_iomap_write_direct( > int committed; > int error; > int lockmode; > + int bmapi_flags = XFS_BMAPI_PREALLOC; > > rt = XFS_IS_REALTIME_INODE(ip); > extsz = xfs_get_extsz_hint(ip); > @@ -195,6 +196,23 @@ xfs_iomap_write_direct( > * Allocate and setup the transaction > */ > tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT); > + > + /* > + * For DAX, we do not allocate unwritten extents, but instead we zero > + * the block before we commit the transaction. Ideally we'd like to do > + * this outside the transaction context, but if we commit and then crash > + * we may not have zeroed the blocks and this will be exposed on > + * recovery of the allocation. Hence we must zero before commit. > + * Further, if we are mapping unwritten extents here, we need to zero > + * and convert them to written so that we don't need an unwritten extent > + * callback for DAX. This also means that we need to be able to dip into > + * the reserve block pool if there is no space left but we need to do > + * unwritten extent conversion. > + */ > + if (IS_DAX(VFS_I(ip))) { > + bmapi_flags = XFS_BMAPI_CONVERT | XFS_BMAPI_ZERO; > + tp->t_flags |= XFS_TRANS_RESERVE; > + } > error = xfs_trans_reserve(tp, &M_RES(mp)->tr_write, > resblks, resrtextents); > /* > @@ -221,7 +239,7 @@ xfs_iomap_write_direct( > xfs_bmap_init(&free_list, &firstfsb); > nimaps = 1; > error = xfs_bmapi_write(tp, ip, offset_fsb, count_fsb, > - XFS_BMAPI_PREALLOC, &firstfsb, resblks, imap, > + bmapi_flags, &firstfsb, resblks, imap, > &nimaps, &free_list); > if (error) > goto out_bmap_cancel; > @@ -232,6 +250,7 @@ xfs_iomap_write_direct( > error = xfs_bmap_finish(&tp, &free_list, &committed); > if (error) > goto out_bmap_cancel; > + > error = xfs_trans_commit(tp); > if (error) > goto out_unlock; > -- > 2.5.0 > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From bfoster@redhat.com Mon Nov 2 08:15:47 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 138DB29E03 for ; Mon, 2 Nov 2015 08:15:47 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 6978EAC001 for ; Mon, 2 Nov 2015 06:15:43 -0800 (PST) X-ASG-Debug-ID: 1446473741-04cbb0660d1caf70001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id s6H4PaIItnbqTYZA (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 02 Nov 2015 06:15:41 -0800 (PST) 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 (Postfix) with ESMTPS id 402AAC1C7500; Mon, 2 Nov 2015 14:15:41 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-105.bos.redhat.com [10.18.41.105]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA2EFeMb004038; Mon, 2 Nov 2015 09:15:41 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id F03D21201AB; Mon, 2 Nov 2015 09:15:39 -0500 (EST) Date: Mon, 2 Nov 2015 09:15:39 -0500 From: Brian Foster To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH 7/7] xfs: optimise away log forces on timestamp updates for fdatasync Message-ID: <20151102141539.GD29346@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH 7/7] xfs: optimise away log forces on timestamp updates for fdatasync References: <1446435735-1526-1-git-send-email-david@fromorbit.com> <1446435735-1526-8-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1446435735-1526-8-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.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1446473741 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Mon, Nov 02, 2015 at 02:42:15PM +1100, Dave Chinner wrote: > From: Dave Chinner > > xfs: timestamp updates cause excessive fdatasync log traffic > > Sage Weil reported that a ceph test workload was writing to the > log on every fdatasync during an overwrite workload. Event tracing > showed that the only metadata modification being made was the > timestamp updates during the write(2) syscall, but fdatasync(2) > is supposed to ignore them. The key observation was that the > transactions in the log all looked like this: > > INODE: #regs: 4 ino: 0x8b flags: 0x45 dsize: 32 > > And contained a flags field of 0x45 or 0x85, and had data and > attribute forks following the inode core. This means that the > timestamp updates were triggering dirty relogging of previously > logged parts of the inode that hadn't yet been flushed back to > disk. > > There are two parts to this problem. The first is that XFS relogs > dirty regions in subsequent transactions, so it carries around the > fields that have been dirtied since the last time the inode was > written back to disk, not since the last time the inode was forced > into the log. > > The second part is that on v5 filesystems, the inode change count > update during inode dirtying also sets the XFS_ILOG_CORE flag, so > on v5 filesystems this makes a timestamp update dirty the entire > inode. > > As a result when fdatasync is run, it looks at the dirty fields in > the inode, and sees more than just the timestamp flag, even though > the only metadata change since the last fdatasync was just the > timestamps. Hence we force the log on every subsequent fdatasync > even though it is not needed. > > To fix this, add a new field to the inode log item that tracks > changes since the last time fsync/fdatasync forced the log to flush > the changes to the journal. This flag is updated when we dirty the > inode, but we do it before updating the change count so it does not > carry the "core dirty" flag from timestamp updates. The fields are > zeroed when the inode is marked clean (due to writeback/freeing) or > when an fsync/datasync forces the log. Hence if we only dirty the > timestamps on the inode between fsync/fdatasync calls, the fdatasync > will not trigger another log force. > > Over 100 runs of the test program: > > Ext4 baseline: > runtime: 1.63s +/- 0.24s > avg lat: 1.59ms +/- 0.24ms > iops: ~2000 > > XFS, vanilla kernel: > runtime: 2.45s +/- 0.18s > avg lat: 2.39ms +/- 0.18ms > log forces: ~400/s > iops: ~1000 > > XFS, patched kernel: > runtime: 1.49s +/- 0.26s > avg lat: 1.46ms +/- 0.25ms > log forces: ~30/s > iops: ~1500 > > Reported-by: Sage Weil > Signed-off-by: Dave Chinner > --- Looks good: Reviewed-by: Brian Foster > fs/xfs/xfs_file.c | 21 ++++++++++++++++----- > fs/xfs/xfs_inode.c | 2 ++ > fs/xfs/xfs_inode_item.c | 1 + > fs/xfs/xfs_inode_item.h | 1 + > fs/xfs/xfs_trans_inode.c | 9 +++++++++ > 5 files changed, 29 insertions(+), 5 deletions(-) > > diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c > index 0045b0a..39743ef 100644 > --- a/fs/xfs/xfs_file.c > +++ b/fs/xfs/xfs_file.c > @@ -242,19 +242,30 @@ xfs_file_fsync( > } > > /* > - * All metadata updates are logged, which means that we just have > - * to flush the log up to the latest LSN that touched the inode. > + * All metadata updates are logged, which means that we just have to > + * flush the log up to the latest LSN that touched the inode. If we have > + * concurrent fsync/fdatasync() calls, we need them to all block on the > + * log force before we clear the ili_fsync_fields field. This ensures > + * that we don't get a racing sync operation that does not wait for the > + * metadata to hit the journal before returning. If we race with > + * clearing the ili_fsync_fields, then all that will happen is the log > + * force will do nothing as the lsn will already be on disk. We can't > + * race with setting ili_fsync_fields because that is done under > + * XFS_ILOCK_EXCL, and that can't happen because we hold the lock shared > + * until after the ili_fsync_fields is cleared. > */ > xfs_ilock(ip, XFS_ILOCK_SHARED); > if (xfs_ipincount(ip)) { > if (!datasync || > - (ip->i_itemp->ili_fields & ~XFS_ILOG_TIMESTAMP)) > + (ip->i_itemp->ili_fsync_fields & ~XFS_ILOG_TIMESTAMP)) > lsn = ip->i_itemp->ili_last_lsn; > } > - xfs_iunlock(ip, XFS_ILOCK_SHARED); > > - if (lsn) > + if (lsn) { > error = _xfs_log_force_lsn(mp, lsn, XFS_LOG_SYNC, &log_flushed); > + ip->i_itemp->ili_fsync_fields = 0; > + } > + xfs_iunlock(ip, XFS_ILOCK_SHARED); > > /* > * If we only have a single device, and the log force about was > diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c > index a0f2bae..8ee3939 100644 > --- a/fs/xfs/xfs_inode.c > +++ b/fs/xfs/xfs_inode.c > @@ -2365,6 +2365,7 @@ retry: > > iip->ili_last_fields = iip->ili_fields; > iip->ili_fields = 0; > + iip->ili_fsync_fields = 0; > iip->ili_logged = 1; > xfs_trans_ail_copy_lsn(mp->m_ail, &iip->ili_flush_lsn, > &iip->ili_item.li_lsn); > @@ -3560,6 +3561,7 @@ xfs_iflush_int( > */ > iip->ili_last_fields = iip->ili_fields; > iip->ili_fields = 0; > + iip->ili_fsync_fields = 0; > iip->ili_logged = 1; > > xfs_trans_ail_copy_lsn(mp->m_ail, &iip->ili_flush_lsn, > diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c > index 62bd80f..d14b12b 100644 > --- a/fs/xfs/xfs_inode_item.c > +++ b/fs/xfs/xfs_inode_item.c > @@ -719,6 +719,7 @@ xfs_iflush_abort( > * attempted. > */ > iip->ili_fields = 0; > + iip->ili_fsync_fields = 0; > } > /* > * Release the inode's flush lock since we're done with it. > diff --git a/fs/xfs/xfs_inode_item.h b/fs/xfs/xfs_inode_item.h > index 488d812..4c7722e 100644 > --- a/fs/xfs/xfs_inode_item.h > +++ b/fs/xfs/xfs_inode_item.h > @@ -34,6 +34,7 @@ typedef struct xfs_inode_log_item { > unsigned short ili_logged; /* flushed logged data */ > unsigned int ili_last_fields; /* fields when flushed */ > unsigned int ili_fields; /* fields to be logged */ > + unsigned int ili_fsync_fields; /* logged since last fsync */ > } xfs_inode_log_item_t; > > static inline int xfs_inode_clean(xfs_inode_t *ip) > diff --git a/fs/xfs/xfs_trans_inode.c b/fs/xfs/xfs_trans_inode.c > index 17280cd..b97f1df 100644 > --- a/fs/xfs/xfs_trans_inode.c > +++ b/fs/xfs/xfs_trans_inode.c > @@ -108,6 +108,15 @@ xfs_trans_log_inode( > ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); > > /* > + * Record the specific change for fdatasync optimisation. This > + * allows fdatasync to skip log forces for inodes that are only > + * timestamp dirty. We do this before the change count so that > + * the core being logged in this case does not impact on fdatasync > + * behaviour. > + */ > + ip->i_itemp->ili_fsync_fields |= flags; > + > + /* > * First time we log the inode in a transaction, bump the inode change > * counter if it is configured for this to occur. We don't use > * inode_inc_version() because there is no need for extra locking around > -- > 2.5.0 > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From jmoyer@redhat.com Mon Nov 2 08:22:23 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 6F47829DF5 for ; Mon, 2 Nov 2015 08:22:23 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 4D28F8F8033 for ; Mon, 2 Nov 2015 06:22:23 -0800 (PST) X-ASG-Debug-ID: 1446474141-04cb6c7b851b73d0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id nDSXQs6lHv8cxaUK (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 02 Nov 2015 06:22:22 -0800 (PST) X-Barracuda-Envelope-From: jmoyer@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 (Postfix) with ESMTPS id 7CCB48E22B; Mon, 2 Nov 2015 14:22:19 +0000 (UTC) Received: from segfault.boston.devel.redhat.com (segfault.boston.devel.redhat.com [10.19.60.26]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA2EMFOY009695 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Mon, 2 Nov 2015 09:22:16 -0500 From: Jeff Moyer To: Dave Chinner Cc: Ross Zwisler , linux-kernel@vger.kernel.org, "H. Peter Anvin" , "J. Bruce Fields" , "Theodore Ts'o" , Alexander Viro , Andreas Dilger , Dan Williams , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@ml01.01.org, x86@kernel.org, xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox Subject: Re: [RFC 00/11] DAX fsynx/msync support References: <1446149535-16200-1-git-send-email-ross.zwisler@linux.intel.com> <20151030035533.GU19199@dastard> <20151030183938.GC24643@linux.intel.com> <20151101232948.GF10656@dastard> X-ASG-Orig-Subj: Re: [RFC 00/11] DAX fsynx/msync support X-PGP-KeyID: 1F78E1B4 X-PGP-CertKey: F6FE 280D 8293 F72C 65FD 5A58 1FF8 A7CA 1F78 E1B4 X-PCLoadLetter: What the f**k does that mean? Date: Mon, 02 Nov 2015 09:22:15 -0500 In-Reply-To: <20151101232948.GF10656@dastard> (Dave Chinner's message of "Mon, 2 Nov 2015 10:29:48 +1100") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain 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: 1446474142 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Dave Chinner writes: > Further, REQ_FLUSH/REQ_FUA are more than just "put the data on stable > storage" commands. They are also IO barriers that affect scheduling > of IOs in progress and in the request queues. A REQ_FLUSH/REQ_FUA > IO cannot be dispatched before all prior IO has been dispatched and > drained from the request queue, and IO submitted after a queued > REQ_FLUSH/REQ_FUA cannot be scheduled ahead of the queued > REQ_FLUSH/REQ_FUA operation. > > IOWs, REQ_FUA/REQ_FLUSH not only guarantee data is on stable > storage, they also guarantee the order of IO dispatch and > completion when concurrent IO is in progress. This hasn't been the case for several years, now. It used to work that way, and that was deemed a big performance problem. Since file systems already issued and waited for all I/O before sending down a barrier, we decided to get rid of the I/O ordering pieces of barriers (and stop calling them barriers). See commit 28e7d184521 (block: drop barrier ordering by queue draining). Cheers, Jeff From darrick.wong@oracle.com Mon Nov 2 11:56:28 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id B41DA7F59 for ; Mon, 2 Nov 2015 11:56:28 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id A724B304059 for ; Mon, 2 Nov 2015 09:56:28 -0800 (PST) X-ASG-Debug-ID: 1446486986-04cbb0660d1d4770001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id S7weeifthxfFE2PJ (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 02 Nov 2015 09:56:26 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tA2HuLjV002449 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Mon, 2 Nov 2015 17:56:21 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id tA2HuLUA000878 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Mon, 2 Nov 2015 17:56:21 GMT Received: from abhmp0017.oracle.com (abhmp0017.oracle.com [141.146.116.23]) by userv0121.oracle.com (8.13.8/8.13.8) with ESMTP id tA2HuKwH017143; Mon, 2 Nov 2015 17:56:20 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Mon, 02 Nov 2015 09:56:20 -0800 Date: Mon, 2 Nov 2015 09:56:19 -0800 From: "Darrick J. Wong" To: Dave Chinner Cc: xfs@oss.sgi.com Subject: [PATCH] xfs: don't leak uuid table on rmmod Message-ID: <20151102175619.GA2224@birch.djwong.org> X-ASG-Orig-Subj: [PATCH] xfs: don't leak uuid table on rmmod MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) X-Source-IP: userv0021.oracle.com [156.151.31.71] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1446486986 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24041 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Don't leak the UUID table when the module is unloaded. (Found with kmemleak.) Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_mount.c | 10 ++++++++++ fs/xfs/xfs_mount.h | 1 + fs/xfs/xfs_super.c | 1 + 3 files changed, 12 insertions(+) diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index bf92e0c..fe6fe8a 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -47,6 +47,16 @@ static DEFINE_MUTEX(xfs_uuid_table_mutex); static int xfs_uuid_table_size; static uuid_t *xfs_uuid_table; +void +xfs_uuid_table_free(void) +{ + if (xfs_uuid_table_size == 0) + return; + kmem_free(xfs_uuid_table); + xfs_uuid_table = NULL; + xfs_uuid_table_size = 0; +} + /* * 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. diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 7999e91..d6cbdcb 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -312,6 +312,7 @@ typedef struct xfs_perag { int pagb_count; /* pagb slots in use */ } xfs_perag_t; +extern void xfs_uuid_table_free(void); extern int xfs_log_sbcount(xfs_mount_t *); extern __uint64_t xfs_default_resblks(xfs_mount_t *mp); extern int xfs_mountfs(xfs_mount_t *mp); diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 904f637..29531ec 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -1896,6 +1896,7 @@ exit_xfs_fs(void) xfs_mru_cache_uninit(); xfs_destroy_workqueues(); xfs_destroy_zones(); + xfs_uuid_table_free(); } module_init(init_xfs_fs); From agruenba@redhat.com Mon Nov 2 13:53:01 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 A5FCA29DF5 for ; Mon, 2 Nov 2015 13:53:01 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 49A658F8033 for ; Mon, 2 Nov 2015 11:53:01 -0800 (PST) X-ASG-Debug-ID: 1446493979-04bdf0330b1deb20001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id HuVVsQFokrKBeHMA (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 02 Nov 2015 11:52:59 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id EF1A6461E7; Mon, 2 Nov 2015 19:52:58 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA2JqtJJ019637; Mon, 2 Nov 2015 14:52:56 -0500 From: Andreas Gruenbacher To: Dave Chinner Cc: Brian Foster , xfs@oss.sgi.com, Andreas Gruenbacher Subject: Re: [PATCH v2 0/5] xfs: SGI ACL Fixes Date: Mon, 2 Nov 2015 20:52:52 +0100 X-ASG-Orig-Subj: Re: [PATCH v2 0/5] xfs: SGI ACL Fixes Message-Id: <1446493974-24669-1-git-send-email-agruenba@redhat.com> References: <1446217508-22157-1-git-send-email-agruenba@redhat.com> <20151102025352.GY19199@dastard> In-Reply-To: <20151102025352.GY19199@dastard> 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: 1446493979 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Mon, Nov 2, 2015 at 3:53 AM, Dave Chinner wrote: > Ok, I've taken these two patches for the upcoming merge window as > they fix bugs, but I've taken Brian's cached ACL invalidation patch > instead [...] Then you'll also need these two patches. Andreas Andreas Gruenbacher (2): xfs: Fixes to "invalidate cached acl if set directly via xattr" xfs: invalidate cached acl if set via ioctl fs/xfs/xfs_acl.h | 3 +++ fs/xfs/xfs_ioctl.c | 10 +++++++++- fs/xfs/xfs_xattr.c | 36 ++++++++++++++++++++++++------------ 3 files changed, 36 insertions(+), 13 deletions(-) -- 2.5.0 From agruenba@redhat.com Mon Nov 2 13:53:03 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 B1E6D29DFC for ; Mon, 2 Nov 2015 13:53:03 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id A5F298F8033 for ; Mon, 2 Nov 2015 11:53:03 -0800 (PST) X-ASG-Debug-ID: 1446493982-04cb6c7b871c3620001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 2yb6DS8KnSCIsBKF (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 02 Nov 2015 11:53:02 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 05DC18E706; Mon, 2 Nov 2015 19:53:02 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA2JqtJK019637; Mon, 2 Nov 2015 14:52:59 -0500 From: Andreas Gruenbacher To: Dave Chinner Cc: Brian Foster , xfs@oss.sgi.com, Andreas Gruenbacher , Andreas Gruenbacher Subject: [PATCH 1/2] xfs: Fixes to "invalidate cached acl if set directly via xattr" Date: Mon, 2 Nov 2015 20:52:53 +0100 X-ASG-Orig-Subj: [PATCH 1/2] xfs: Fixes to "invalidate cached acl if set directly via xattr" Message-Id: <1446493974-24669-2-git-send-email-agruenba@redhat.com> In-Reply-To: <1446493974-24669-1-git-send-email-agruenba@redhat.com> References: <1446493974-24669-1-git-send-email-agruenba@redhat.com> References: <1446217508-22157-1-git-send-email-agruenba@redhat.com> <20151102025352.GY19199@dastard> In-Reply-To: <20151102025352.GY19199@dastard> 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: 1446493982 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Don't match arbitrary name prefixes like "S" when checking for the attribute names "SGI_ACL_{FILE,DEFAULT}". Function forget_cached_acl only exists in kernels that have POSIX ACL support; guard calls to that function by CONFIG_XFS_POSIX_ACL. Signed-off-by: Andreas Gruenbacher --- fs/xfs/xfs_xattr.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c index 2e1eb80..1542d64 100644 --- a/fs/xfs/xfs_xattr.c +++ b/fs/xfs/xfs_xattr.c @@ -80,10 +80,12 @@ xfs_xattr_set(struct dentry *dentry, const char *name, const void *value, * consistent. */ if (!error && (xflags & ATTR_ROOT)) { - if (!strncmp(name, SGI_ACL_FILE, strlen(name))) +#ifdef CONFIG_XFS_POSIX_ACL + if (!strcmp(name, SGI_ACL_FILE) forget_cached_acl(VFS_I(ip), ACL_TYPE_ACCESS); - else if (!strncmp(name, SGI_ACL_DEFAULT, strlen(name))) + else if (!strcmp(name, SGI_ACL_DEFAULT)) forget_cached_acl(VFS_I(ip), ACL_TYPE_DEFAULT); +#endif } return error; -- 2.5.0 From agruenba@redhat.com Mon Nov 2 13:53:09 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 8F3A229DF5 for ; Mon, 2 Nov 2015 13:53:09 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 299A4AC002 for ; Mon, 2 Nov 2015 11:53:05 -0800 (PST) X-ASG-Debug-ID: 1446493984-04bdf0330a1deb20001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id pJq5CHtmIVZH9F5f (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 02 Nov 2015 11:53:05 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id BBDCACDE; Mon, 2 Nov 2015 19:53:04 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA2JqtJL019637; Mon, 2 Nov 2015 14:53:02 -0500 From: Andreas Gruenbacher To: Dave Chinner Cc: Brian Foster , xfs@oss.sgi.com, Andreas Gruenbacher Subject: [PATCH 2/2] xfs: invalidate cached acl if set via ioctl Date: Mon, 2 Nov 2015 20:52:54 +0100 X-ASG-Orig-Subj: [PATCH 2/2] xfs: invalidate cached acl if set via ioctl Message-Id: <1446493974-24669-3-git-send-email-agruenba@redhat.com> In-Reply-To: <1446493974-24669-1-git-send-email-agruenba@redhat.com> References: <1446493974-24669-1-git-send-email-agruenba@redhat.com> References: <1446217508-22157-1-git-send-email-agruenba@redhat.com> <20151102025352.GY19199@dastard> In-Reply-To: <20151102025352.GY19199@dastard> 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: 1446493984 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Setting or removing the "SGI_ACL_[FILE|DEFAULT]" attributes via the XFS_IOC_ATTRMULTI_BY_HANDLE ioctl completely bypasses the POSIX ACL infrastructure, like setting the "trusted.SGI_ACL_[FILE|DEFAULT]" xattrs did until commit 6caa1056. Similar to that commit, invalidate cached acls when setting/removing them via the ioctl as well. Signed-off-by: Andreas Gruenbacher --- fs/xfs/xfs_acl.h | 3 +++ fs/xfs/xfs_ioctl.c | 10 +++++++++- fs/xfs/xfs_xattr.c | 38 ++++++++++++++++++++++++-------------- 3 files changed, 36 insertions(+), 15 deletions(-) diff --git a/fs/xfs/xfs_acl.h b/fs/xfs/xfs_acl.h index 3841b07..75af0a4 100644 --- a/fs/xfs/xfs_acl.h +++ b/fs/xfs/xfs_acl.h @@ -36,4 +36,7 @@ static inline struct posix_acl *xfs_get_acl(struct inode *inode, int type) # define posix_acl_access_exists(inode) 0 # define posix_acl_default_exists(inode) 0 #endif /* CONFIG_XFS_POSIX_ACL */ + +extern void xfs_forget_acl(struct inode *inode, const char *name, int xflags); + #endif /* __XFS_ACL_H__ */ diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c index 66bcfbd..d42738d 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c @@ -40,6 +40,7 @@ #include "xfs_symlink.h" #include "xfs_trans.h" #include "xfs_pnfs.h" +#include "xfs_acl.h" #include #include @@ -494,6 +495,8 @@ xfs_attrmulti_attr_set( return PTR_ERR(kbuf); error = xfs_attr_set(XFS_I(inode), name, kbuf, len, flags); + if (!error) + xfs_forget_acl(inode, name, flags); kfree(kbuf); return error; } @@ -504,9 +507,14 @@ xfs_attrmulti_attr_remove( unsigned char *name, __uint32_t flags) { + int error; + if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) return -EPERM; - return xfs_attr_remove(XFS_I(inode), name, flags); + error = xfs_attr_remove(XFS_I(inode), name, flags); + if (!error) + xfs_forget_acl(inode, name, flags); + return error; } STATIC int diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c index 1542d64..8294f86 100644 --- a/fs/xfs/xfs_xattr.c +++ b/fs/xfs/xfs_xattr.c @@ -53,6 +53,28 @@ xfs_xattr_get(struct dentry *dentry, const char *name, return asize; } +void +xfs_forget_acl( + struct inode *inode, + const char *name, + int xflags) +{ + /* + * Invalidate any cached ACLs if the user has bypassed the ACL + * interface. We don't validate the content whatsoever so it is caller + * responsibility to provide data in valid format and ensure i_mode is + * consistent. + */ + if (xflags & ATTR_ROOT) { +#ifdef CONFIG_XFS_POSIX_ACL + if (!strcmp(name, SGI_ACL_FILE)) + forget_cached_acl(inode, ACL_TYPE_ACCESS); + else if (!strcmp(name, SGI_ACL_DEFAULT)) + forget_cached_acl(inode, ACL_TYPE_DEFAULT); +#endif + } +} + static int xfs_xattr_set(struct dentry *dentry, const char *name, const void *value, size_t size, int flags, int xflags) @@ -73,20 +95,8 @@ xfs_xattr_set(struct dentry *dentry, const char *name, const void *value, return xfs_attr_remove(ip, (unsigned char *)name, xflags); error = xfs_attr_set(ip, (unsigned char *)name, (void *)value, size, xflags); - /* - * Invalidate any cached ACLs if the user has bypassed the ACL - * interface. We don't validate the content whatsoever so it is caller - * responsibility to provide data in valid format and ensure i_mode is - * consistent. - */ - if (!error && (xflags & ATTR_ROOT)) { -#ifdef CONFIG_XFS_POSIX_ACL - if (!strcmp(name, SGI_ACL_FILE) - forget_cached_acl(VFS_I(ip), ACL_TYPE_ACCESS); - else if (!strcmp(name, SGI_ACL_DEFAULT)) - forget_cached_acl(VFS_I(ip), ACL_TYPE_DEFAULT); -#endif - } + if (!error) + xfs_forget_acl(d_inode(dentry), name, xflags); return error; } -- 2.5.0 From david@fromorbit.com Mon Nov 2 14:10:50 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 9245029DF5 for ; Mon, 2 Nov 2015 14:10:50 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 73C538F8035 for ; Mon, 2 Nov 2015 12:10:47 -0800 (PST) X-ASG-Debug-ID: 1446495044-04cbb0660f1d9020001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id aFzwLt9VIARhNHd8 for ; Mon, 02 Nov 2015 12:10:44 -0800 (PST) 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: A2CdBwBvwjdW/+rW03ZegzuBQqpFAQEBAQEBBosuiy+GEwICAQECgTtNAQEBAQEBgQuENgEBBCcTHCMQCAMOCgklDwUlAyETiC/BbgEBCAIBIBmGF4VFhEeEeQWWQ4gNhRCcQmOCER2Baio0hDWBSQEBAQ Received: from ppp118-211-214-234.lns20.syd4.internode.on.net (HELO dastard) ([118.211.214.234]) by ipmail07.adl2.internode.on.net with ESMTP; 03 Nov 2015 06:40:42 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZtLQz-0002wo-8v; Tue, 03 Nov 2015 07:10:29 +1100 Date: Tue, 3 Nov 2015 07:10:29 +1100 From: Dave Chinner To: Jeff Moyer Cc: Ross Zwisler , linux-kernel@vger.kernel.org, "H. Peter Anvin" , "J. Bruce Fields" , Theodore Ts'o , Alexander Viro , Andreas Dilger , Dan Williams , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@ml01.01.org, x86@kernel.org, xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox Subject: Re: [RFC 00/11] DAX fsynx/msync support Message-ID: <20151102201029.GI10656@dastard> X-ASG-Orig-Subj: Re: [RFC 00/11] DAX fsynx/msync support References: <1446149535-16200-1-git-send-email-ross.zwisler@linux.intel.com> <20151030035533.GU19199@dastard> <20151030183938.GC24643@linux.intel.com> <20151101232948.GF10656@dastard> 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: 1446495044 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24046 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Mon, Nov 02, 2015 at 09:22:15AM -0500, Jeff Moyer wrote: > Dave Chinner writes: > > > Further, REQ_FLUSH/REQ_FUA are more than just "put the data on stable > > storage" commands. They are also IO barriers that affect scheduling > > of IOs in progress and in the request queues. A REQ_FLUSH/REQ_FUA > > IO cannot be dispatched before all prior IO has been dispatched and > > drained from the request queue, and IO submitted after a queued > > REQ_FLUSH/REQ_FUA cannot be scheduled ahead of the queued > > REQ_FLUSH/REQ_FUA operation. > > > > IOWs, REQ_FUA/REQ_FLUSH not only guarantee data is on stable > > storage, they also guarantee the order of IO dispatch and > > completion when concurrent IO is in progress. > > This hasn't been the case for several years, now. It used to work that > way, and that was deemed a big performance problem. Since file systems > already issued and waited for all I/O before sending down a barrier, we > decided to get rid of the I/O ordering pieces of barriers (and stop > calling them barriers). > > See commit 28e7d184521 (block: drop barrier ordering by queue draining). Yes, I realise that, even if I wasn't very clear about how I wrote it. ;) Correct me if I'm wrong: AFAIA, dispatch ordering (i.e. the "IO barrier") is still enforced by the scheduler via REQ_FUA|REQ_FLUSH -> ELEVATOR_INSERT_FLUSH -> REQ_SOFTBARRIER and subsequent IO scheduler calls to elv_dispatch_sort() that don't pass REQ_SOFTBARRIER in the queue. IOWs, if we queue a bunch of REQ_WRITE IOs followed by a REQ_WRITE|REQ_FLUSH IO, all of the prior REQ_WRITE IOs will be dispatched before the REQ_WRITE|REQ_FLUSH IO and hence be captured by the cache flush. Hence once the filesystem has waited on the REQ_WRITE|REQ_FLUSH IO to complete, we know that all the earlier REQ_WRITE IOs are on stable storage, too. Hence there's no need for the elevator to drain the queue to guarantee completion ordering - the dispatch ordering and flush/fua write semantics guarantee that when the flush/fua completes, all the IOs dispatch prior to that flush/fua write are also on stable storage... Cheers, Dave. -- Dave Chinner david@fromorbit.com From jmoyer@redhat.com Mon Nov 2 15:02:56 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 DBADE29DF5 for ; Mon, 2 Nov 2015 15:02:56 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id CC0E0304053 for ; Mon, 2 Nov 2015 13:02:53 -0800 (PST) X-ASG-Debug-ID: 1446498172-04cbb0660c1da8d0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id G2vloKt9rmjsrunv (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 02 Nov 2015 13:02:52 -0800 (PST) X-Barracuda-Envelope-From: jmoyer@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 (Postfix) with ESMTPS id 99F618F4E5; Mon, 2 Nov 2015 21:02:51 +0000 (UTC) Received: from segfault.boston.devel.redhat.com (segfault.boston.devel.redhat.com [10.19.60.26]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA2L2mF6029960 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Mon, 2 Nov 2015 16:02:48 -0500 From: Jeff Moyer To: Dave Chinner Cc: Ross Zwisler , linux-kernel@vger.kernel.org, "H. Peter Anvin" , "J. Bruce Fields" , "Theodore Ts'o" , Alexander Viro , Andreas Dilger , Dan Williams , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@ml01.01.org, x86@kernel.org, xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox , axboe@kernel.dk Subject: Re: [RFC 00/11] DAX fsynx/msync support References: <1446149535-16200-1-git-send-email-ross.zwisler@linux.intel.com> <20151030035533.GU19199@dastard> <20151030183938.GC24643@linux.intel.com> <20151101232948.GF10656@dastard> <20151102201029.GI10656@dastard> X-ASG-Orig-Subj: Re: [RFC 00/11] DAX fsynx/msync support X-PGP-KeyID: 1F78E1B4 X-PGP-CertKey: F6FE 280D 8293 F72C 65FD 5A58 1FF8 A7CA 1F78 E1B4 X-PCLoadLetter: What the f**k does that mean? Date: Mon, 02 Nov 2015 16:02:48 -0500 In-Reply-To: <20151102201029.GI10656@dastard> (Dave Chinner's message of "Tue, 3 Nov 2015 07:10:29 +1100") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain 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: 1446498172 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Dave Chinner writes: > On Mon, Nov 02, 2015 at 09:22:15AM -0500, Jeff Moyer wrote: >> Dave Chinner writes: >> >> > Further, REQ_FLUSH/REQ_FUA are more than just "put the data on stable >> > storage" commands. They are also IO barriers that affect scheduling >> > of IOs in progress and in the request queues. A REQ_FLUSH/REQ_FUA >> > IO cannot be dispatched before all prior IO has been dispatched and >> > drained from the request queue, and IO submitted after a queued >> > REQ_FLUSH/REQ_FUA cannot be scheduled ahead of the queued >> > REQ_FLUSH/REQ_FUA operation. >> > >> > IOWs, REQ_FUA/REQ_FLUSH not only guarantee data is on stable >> > storage, they also guarantee the order of IO dispatch and >> > completion when concurrent IO is in progress. >> >> This hasn't been the case for several years, now. It used to work that >> way, and that was deemed a big performance problem. Since file systems >> already issued and waited for all I/O before sending down a barrier, we >> decided to get rid of the I/O ordering pieces of barriers (and stop >> calling them barriers). >> >> See commit 28e7d184521 (block: drop barrier ordering by queue draining). > > Yes, I realise that, even if I wasn't very clear about how I wrote > it. ;) > > Correct me if I'm wrong: AFAIA, dispatch ordering (i.e. the "IO > barrier") is still enforced by the scheduler via REQ_FUA|REQ_FLUSH > -> ELEVATOR_INSERT_FLUSH -> REQ_SOFTBARRIER and subsequent IO > scheduler calls to elv_dispatch_sort() that don't pass > REQ_SOFTBARRIER in the queue. This part is right. > IOWs, if we queue a bunch of REQ_WRITE IOs followed by a > REQ_WRITE|REQ_FLUSH IO, all of the prior REQ_WRITE IOs will be > dispatched before the REQ_WRITE|REQ_FLUSH IO and hence be captured > by the cache flush. But this part is not. It is up to the I/O scheduler to decide when to dispatch requests. It can hold on to them for a variety of reasons. Flush requests, however, do not go through the I/O scheduler. At the very moment that the flush request is inserted, it goes directly to the dispatch queue (assuming no other flush is in progress). The prior requests may still be waiting in the I/O scheduler's internal lists. So, any newly dispatched I/Os will certainly not get past the REQ_FLUSH. However, the REQ_FLUSH is very likely to jump ahead of prior I/Os in the queue. > Hence once the filesystem has waited on the REQ_WRITE|REQ_FLUSH IO > to complete, we know that all the earlier REQ_WRITE IOs are on > stable storage, too. Hence there's no need for the elevator to drain > the queue to guarantee completion ordering - the dispatch ordering > and flush/fua write semantics guarantee that when the flush/fua > completes, all the IOs dispatch prior to that flush/fua write are > also on stable storage... Des xfs rely on this model for correctness? If so, I'd say we've got a problem. Cheers, Jeff From david@fromorbit.com Mon Nov 2 15:44:41 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 981F87F53 for ; Mon, 2 Nov 2015 15:44:41 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 79EE3304032 for ; Mon, 2 Nov 2015 13:44:41 -0800 (PST) X-ASG-Debug-ID: 1446500677-04cbb0660d1db9d0001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id nvLzwHeDffMyY3GV for ; Mon, 02 Nov 2015 13:44:38 -0800 (PST) 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: A2BUBwC72DdW/+rW03ZegzuBQqpGAQEBAQEBBosuhSaGCYYTBAICgTtNAQEBAQEBgQuENQEBAQMBMgEjIwULCAMOBAYJJQ8FJQMNFBMeiAoHwgEBAQEHAQEBAR8ZhheFRYRHhHkFlkOKbIIxgXaaTGOCDgMdgWoqNIQ1gUkBAQE Received: from ppp118-211-214-234.lns20.syd4.internode.on.net (HELO dastard) ([118.211.214.234]) by ipmail07.adl2.internode.on.net with ESMTP; 03 Nov 2015 08:14:37 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZtMts-0003DC-92; Tue, 03 Nov 2015 08:44:24 +1100 Date: Tue, 3 Nov 2015 08:44:24 +1100 From: Dave Chinner To: Brian Foster Cc: ross.zwisler@linux.intel.com, jack@suse.cz, xfs@oss.sgi.com, linux-fsdevel@vger.kernel.org, dan.j.williams@intel.com, linux-nvdimm@lists.01.org Subject: Re: [PATCH 3/6] xfs: Don't use unwritten extents for DAX Message-ID: <20151102214424.GJ10656@dastard> X-ASG-Orig-Subj: Re: [PATCH 3/6] xfs: Don't use unwritten extents for DAX References: <1445225238-30413-1-git-send-email-david@fromorbit.com> <1445225238-30413-4-git-send-email-david@fromorbit.com> <20151029142950.GE11663@bfoster.bfoster> <20151029233756.GS19199@dastard> <20151030123657.GC54905@bfoster.bfoster> <20151102011433.GW19199@dastard> <20151102141509.GA29346@bfoster.bfoster> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <20151102141509.GA29346@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: 1446500677 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24047 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- [add people to the cc list] On Mon, Nov 02, 2015 at 09:15:10AM -0500, Brian Foster wrote: > On Mon, Nov 02, 2015 at 12:14:33PM +1100, Dave Chinner wrote: > > On Fri, Oct 30, 2015 at 08:36:57AM -0400, Brian Foster wrote: > > > Unless there is some > > > special mixed dio/mmap case I'm missing, doing so for DAX/DIO basically > > > causes a clear_pmem() over every page sized chunk of the target I/O > > > range for which we already have the data. > > > > I don't follow - this only zeros blocks when we do allocation of new > > blocks or overwrite unwritten extents, not on blocks which we > > already have written data extents allocated for... > > > > Why are we assuming that block zeroing is more efficient than unwritten > extents for DAX/dio? I haven't played with pmem enough to know for sure > one way or another (or if hw support is imminent), but I'd expect the > latter to be more efficient in general without any kind of hardware > support. > > Just as an example, here's an 8GB pwrite test, large buffer size, to XFS > on a ramdisk mounted with '-o dax:' > > - Before this series: > > # xfs_io -fc "truncate 0" -c "pwrite -b 10m 0 8g" /mnt/file > wrote 8589934592/8589934592 bytes at offset 0 > 8.000 GiB, 820 ops; 0:00:04.00 (1.909 GiB/sec and 195.6591 ops/sec) > > - After this series: > > # xfs_io -fc "truncate 0" -c "pwrite -b 10m 0 8g" /mnt/file > wrote 8589934592/8589934592 bytes at offset 0 > 8.000 GiB, 820 ops; 0:00:12.00 (659.790 MiB/sec and 66.0435 ops/sec) That looks wrong. Much, much slower than it should be just zeroing pages and then writing to them again while cache hot. Oh, hell - dax_clear_blocks() is stupidly slow. A profile shows this loop spending most of the CPU time: ¿ ¿ jbe ea ¿ de: clflus %ds:(%rax) 84.67 ¿ add %rsi,%rax ¿ cmp %rax,%rdx ¿ ¿ ja de ¿ ea: add %r13,-0x38(%rbp) ¿ sub %r12,%r14 ¿ sub %r12,-0x40(%rbp) That is the overhead of __arch_wb_cache_pmem() i.e. issuing CPU cache flushes after each memset. None of these pmem memory operations are optimised yet - the implementations are correct, but performance still needs work. The conversion to non-temporal stores should get rid of this cache flush overhead (somewhat), but I was still expecting this code to be much closer to memset speed and not reduce performance to bugger all... > The impact is less with a smaller buffer size so the above is just meant > to illustrate the point. FWIW, I'm also fine with getting this in as a > matter of "correctness before performance" since this stuff is clearly > still under development, but as far as I can see so far we should > probably ultimately prefer unwritten extents for DAX/DIO (or at least > plan to run some similar tests on real pmem hw). Thoughts? We're going to have these problems initially, but from the XFS persepective those problems don't matter because we have a different problem to solve. That is, we need to move towards an architecture that is highly efficient for low latency, high IOPS storage subsystems. The first step towards that is to be able to offload block zeroing to the hardware so we can avoid using unwritten extents. In the long run, we don't want to use unwritten extents on DAX if we can avoid it - the CPU overhead of unwritten extent conversion isn't constant (i.e. it grows with the size of the BMBT) and it isn't deterministic (e.g. split/merge take much more CPU than a simple record write to clear an unwritten flag). We don't notice this overhead much with normal IO because of the fact that the CPU time for conversion is much less than the CPU time for the IO to complete, hence it's a win. But for PMEM, directly zeroing a 4k chunk of data should take *much less CPU* than synchronously starting a transaction, reserving space, looking up the extent in the BMBT, loading the buffers from cache, modifying the buffers, logging the changes and committing the transaction (which in itself will typically copy more than a single page of metadata into the CIL buffers). Realistically, dax_clear_blocks() should probably be implemented at the pmem driver layer through blkdev_issue_zeroout() because all it does is directly map the sector/len to pfn via bdev_direct_access() and then zero it - it's a sector based, block device operation. We don't actually need a special case path for DAX here. Optimisation of this operation has little to do with the filesystem. This comes back to the comments I made w.r.t. the pmem driver implementation doing synchronous IO by immediately forcing CPU cache flushes and barriers. it's obviously correct, but it looks like there's going to be a major performance penalty associated with it. This is why I recently suggested that a pmem driver that doesn't do CPU cache writeback during IO but does it on REQ_FLUSH is an architecture we'll likely have to support. In this case, the block device won't need to flush CPU cache lines for the zeroed blocks until the allocation transaction is actually committed to the journal. In that case, there's a good chance that we'd end up also committing the new data as well, hence avoiding two synchronous memory writes. i.e. the "big hammer" REQ_FLUSH implementation may well be *much* faster than fine-grained synchronous "stable on completion" writes for persistent memory. This, however, is not really a problem for the filesystem - it's a pmem driver architecture problem. ;) Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Mon Nov 2 20:13:01 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 E164129DF5 for ; Mon, 2 Nov 2015 20:13:01 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id BDEC7304053 for ; Mon, 2 Nov 2015 18:12:58 -0800 (PST) X-ASG-Debug-ID: 1446516773-04bdf0330b1e78f0001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id dB9OA88YkPPeAb79 for ; Mon, 02 Nov 2015 18:12:54 -0800 (PST) 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: A2DSBwAOFzhW/+rW03ZegzuBQqpNAQEBBosuhSWGCYUJgQoCAgEBAoE2TQEBAQEBAYELhDYBAQQ6HCMQCAMOCgklDwUlAyETiC/BfAEBAQcCASAZhheFRYgsgRQFlkONHZxDY4IRHYFqKjSFfgEBAQ Received: from ppp118-211-214-234.lns20.syd4.internode.on.net (HELO dastard) ([118.211.214.234]) by ipmail07.adl2.internode.on.net with ESMTP; 03 Nov 2015 12:42:44 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZtR5M-0003hz-30; Tue, 03 Nov 2015 13:12:32 +1100 Date: Tue, 3 Nov 2015 13:12:32 +1100 From: Dave Chinner To: Andreas Gruenbacher Cc: Brian Foster , xfs@oss.sgi.com Subject: Re: [PATCH 2/2] xfs: invalidate cached acl if set via ioctl Message-ID: <20151103021231.GA19199@dastard> X-ASG-Orig-Subj: Re: [PATCH 2/2] xfs: invalidate cached acl if set via ioctl References: <1446217508-22157-1-git-send-email-agruenba@redhat.com> <20151102025352.GY19199@dastard> <1446493974-24669-3-git-send-email-agruenba@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1446493974-24669-3-git-send-email-agruenba@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: 1446516773 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24057 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Mon, Nov 02, 2015 at 08:52:54PM +0100, Andreas Gruenbacher wrote: > Setting or removing the "SGI_ACL_[FILE|DEFAULT]" attributes via the > XFS_IOC_ATTRMULTI_BY_HANDLE ioctl completely bypasses the POSIX ACL > infrastructure, like setting the "trusted.SGI_ACL_[FILE|DEFAULT]" xattrs > did until commit 6caa1056. Similar to that commit, invalidate cached > acls when setting/removing them via the ioctl as well. > > Signed-off-by: Andreas Gruenbacher Thanks, Andreas. I've pulled the fixes in. I updated the original patch with the fix in patch 1, and applied this patch. I'll push out a rebased for-next branch after some further testing... Cheers, Dave. -- Dave Chinner david@fromorbit.com From dan.j.williams@intel.com Mon Nov 2 21:53:38 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 B094229DF5 for ; Mon, 2 Nov 2015 21:53:38 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 3B0F6AC001 for ; Mon, 2 Nov 2015 19:53:35 -0800 (PST) X-ASG-Debug-ID: 1446522808-04bdf0330b1e9d90001-NocioJ Received: from mail-wm0-f49.google.com (mail-wm0-f49.google.com [74.125.82.49]) by cuda.sgi.com with ESMTP id Iq46gEPipF8Qvovw (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Mon, 02 Nov 2015 19:53:29 -0800 (PST) X-Barracuda-Envelope-From: dan.j.williams@intel.com X-Barracuda-Apparent-Source-IP: 74.125.82.49 Received: by wmeg8 with SMTP id g8so4747738wme.1 for ; Mon, 02 Nov 2015 19:53:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=intel_com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type:content-transfer-encoding; bh=dXv1fnUe9T33n/zgsDqT5vQexPYxbb5b4UrHgAH5eeE=; b=s1eNLdXvxuzSxEtZnh3y0Zs4KXfpWID6kmUf4ZMiVq6UUHvYMSKA5S31XEmmG7ayRg HTjBaTTgWIC44Cu9JRfzEPp31RZsMK/fWeGRuffUuMRqe4FAfc0lSuQj1v7g6UYduGP9 LdTDDWuQJXXya64rpZHDmK6iE2w5S9NXD9dV4b3sbP/0R7X13+9Ev9nUVVKWZxVcDJAz Z+jYC7EI6r+ygDzwCBj9Jg6eiqoKVUnhYBAw39z+gJ2GV2FU3FOkzL34qIDk0Pd9L1NT E9fwlg05ktGCHs8NfpQiYBnQ3R9bYN/SWe/ZruELB3ZWyWicdJYmi7j1//XPfEdUvB9J p0aA== 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 :content-transfer-encoding; bh=dXv1fnUe9T33n/zgsDqT5vQexPYxbb5b4UrHgAH5eeE=; b=FIraoBGlRK43TfVNPRn71O2M+iUDJ+yYSKhGQz5lfthudGoimjHgksc5sDleaaTOqZ z474dPqbCJI34FP4clgSsDdFvYP53u1bnj0PTRgnnq7j5HLUAlc+0qAj5T+t9N5m1aTg CXmKlZ5JgCB3MXwH/QzeYNo+2sOVZNJ4qhU2FcLcXeDjOtF8sanZnJSbvpMVgJFSqX1j 6K/xy8t23twKYduUNVnAcFjP/Q/vtCcHTUAToQA1m9HN85U0yVDOI5O7w+ySqfbsAoMz mIL3pfsw9G9ezRZySIHdUNv8JpdKJcwfYMjxl/DSWKERkkTR7UD5V5V1e8UApoaQ7kI9 obmQ== X-Gm-Message-State: ALoCoQnyqhldSWOe43IE3lfK/ePnVI8ZFQ4zk1+KBCHiY0Sr21MaPfTyNd/NfK19nKRfc6h/dgd2 MIME-Version: 1.0 X-Received: by 10.28.213.212 with SMTP id m203mr16483978wmg.33.1446522807677; Mon, 02 Nov 2015 19:53:27 -0800 (PST) Received: by 10.27.88.132 with HTTP; Mon, 2 Nov 2015 19:53:27 -0800 (PST) In-Reply-To: <20151102214424.GJ10656@dastard> References: <1445225238-30413-1-git-send-email-david@fromorbit.com> <1445225238-30413-4-git-send-email-david@fromorbit.com> <20151029142950.GE11663@bfoster.bfoster> <20151029233756.GS19199@dastard> <20151030123657.GC54905@bfoster.bfoster> <20151102011433.GW19199@dastard> <20151102141509.GA29346@bfoster.bfoster> <20151102214424.GJ10656@dastard> Date: Mon, 2 Nov 2015 19:53:27 -0800 Message-ID: Subject: Re: [PATCH 3/6] xfs: Don't use unwritten extents for DAX From: Dan Williams X-ASG-Orig-Subj: Re: [PATCH 3/6] xfs: Don't use unwritten extents for DAX To: Dave Chinner Cc: Brian Foster , Ross Zwisler , Jan Kara , xfs@oss.sgi.com, linux-fsdevel , "linux-nvdimm@lists.01.org" Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-Barracuda-Connect: mail-wm0-f49.google.com[74.125.82.49] X-Barracuda-Start-Time: 1446522809 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24059 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 Mon, Nov 2, 2015 at 1:44 PM, Dave Chinner wrote: > [add people to the cc list] > > On Mon, Nov 02, 2015 at 09:15:10AM -0500, Brian Foster wrote: >> On Mon, Nov 02, 2015 at 12:14:33PM +1100, Dave Chinner wrote: >> > On Fri, Oct 30, 2015 at 08:36:57AM -0400, Brian Foster wrote: >> > > Unless there is some >> > > special mixed dio/mmap case I'm missing, doing so for DAX/DIO basica= lly >> > > causes a clear_pmem() over every page sized chunk of the target I/O >> > > range for which we already have the data. >> > >> > I don't follow - this only zeros blocks when we do allocation of new >> > blocks or overwrite unwritten extents, not on blocks which we >> > already have written data extents allocated for... >> > >> >> Why are we assuming that block zeroing is more efficient than unwritten >> extents for DAX/dio? I haven't played with pmem enough to know for sure >> one way or another (or if hw support is imminent), but I'd expect the >> latter to be more efficient in general without any kind of hardware >> support. >> >> Just as an example, here's an 8GB pwrite test, large buffer size, to XFS >> on a ramdisk mounted with '-o dax:' >> >> - Before this series: >> >> # xfs_io -fc "truncate 0" -c "pwrite -b 10m 0 8g" /mnt/file >> wrote 8589934592/8589934592 bytes at offset 0 >> 8.000 GiB, 820 ops; 0:00:04.00 (1.909 GiB/sec and 195.6591 ops/sec) >> >> - After this series: >> >> # xfs_io -fc "truncate 0" -c "pwrite -b 10m 0 8g" /mnt/file >> wrote 8589934592/8589934592 bytes at offset 0 >> 8.000 GiB, 820 ops; 0:00:12.00 (659.790 MiB/sec and 66.0435 ops/sec) > > That looks wrong. Much, much slower than it should be just zeroing > pages and then writing to them again while cache hot. > > Oh, hell - dax_clear_blocks() is stupidly slow. A profile shows this > loop spending most of the CPU time: > > =C2=BF =C2=BF jbe ea > =C2=BF de: clflus %ds:(%rax) > 84.67 =C2=BF add %rsi,%rax > =C2=BF cmp %rax,%rdx > =C2=BF =C2=BF ja de > =C2=BF ea: add %r13,-0x38(%rbp) > =C2=BF sub %r12,%r14 > =C2=BF sub %r12,-0x40(%rbp) > > That is the overhead of __arch_wb_cache_pmem() i.e. issuing CPU > cache flushes after each memset. Ideally this would be non-temporal and skip the second flush loop altogether. Outside of that another problem is that this cpu does not support the clwb instruction and is instead using the serializing and invalidating clflush instruction. > None of these pmem memory operations are optimised yet - the > implementations are correct, but performance still needs work. The > conversion to non-temporal stores should get rid of this cache flush > overhead (somewhat), but I was still expecting this code to be much > closer to memset speed and not reduce performance to bugger all... > >> The impact is less with a smaller buffer size so the above is just meant >> to illustrate the point. FWIW, I'm also fine with getting this in as a >> matter of "correctness before performance" since this stuff is clearly >> still under development, but as far as I can see so far we should >> probably ultimately prefer unwritten extents for DAX/DIO (or at least >> plan to run some similar tests on real pmem hw). Thoughts? > > We're going to have these problems initially, but from the XFS > persepective those problems don't matter because we have a different > problem to solve. That is, we need to move towards an architecture > that is highly efficient for low latency, high IOPS storage > subsystems. The first step towards that is to be able to offload > block zeroing to the hardware so we can avoid using unwritten > extents. > > In the long run, we don't want to use unwritten extents on DAX if we > can avoid it - the CPU overhead of unwritten extent conversion isn't > constant (i.e. it grows with the size of the BMBT) and it isn't > deterministic (e.g. split/merge take much more CPU than a simple > record write to clear an unwritten flag). We don't notice this > overhead much with normal IO because of the fact that the CPU time > for conversion is much less than the CPU time for the IO to > complete, hence it's a win. > > But for PMEM, directly zeroing a 4k chunk of data should take *much > less CPU* than synchronously starting a transaction, reserving > space, looking up the extent in the BMBT, loading the buffers from > cache, modifying the buffers, logging the changes and committing the > transaction (which in itself will typically copy more than a single > page of metadata into the CIL buffers). > > Realistically, dax_clear_blocks() should probably be implemented at > the pmem driver layer through blkdev_issue_zeroout() because all it > does is directly map the sector/len to pfn via bdev_direct_access() > and then zero it - it's a sector based, block device operation. We > don't actually need a special case path for DAX here. Optimisation > of this operation has little to do with the filesystem. > > This comes back to the comments I made w.r.t. the pmem driver > implementation doing synchronous IO by immediately forcing CPU cache > flushes and barriers. it's obviously correct, but it looks like > there's going to be a major performance penalty associated with it. > This is why I recently suggested that a pmem driver that doesn't do > CPU cache writeback during IO but does it on REQ_FLUSH is an > architecture we'll likely have to support. > The only thing we can realistically delay is wmb_pmem() i.e. the final sync waiting for data that has *left* the cpu cache. Unless/until we get a architecturally guaranteed method to write-back the entire cache, or flush the cache by physical-cache-way we're stuck with either non-temporal cycles or looping on potentially huge virtual address ranges. > In this case, the block device won't need to flush CPU cache lines > for the zeroed blocks until the allocation transaction is actually > committed to the journal. In that case, there's a good chance that > we'd end up also committing the new data as well, hence avoiding two > synchronous memory writes. i.e. the "big hammer" REQ_FLUSH > implementation may well be *much* faster than fine-grained > synchronous "stable on completion" writes for persistent memory. I can only see it being faster in the case where the flush is cheap to initiate. That's not the case yet so we're stuck doing it synchronously. > > This, however, is not really a problem for the filesystem - it's > a pmem driver architecture problem. ;) > It's a platform problem. Let's see how this looks when not using clflush instructions. Also, another benefit of pushing zeroing down into the driver is that for brd, as used in this example, it will rightly be a nop because there's no persistence to guarantee there. From david@fromorbit.com Mon Nov 2 23:04:34 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 1AD2D29DF5 for ; Mon, 2 Nov 2015 23:04:34 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id DED638F8033 for ; Mon, 2 Nov 2015 21:04:30 -0800 (PST) X-ASG-Debug-ID: 1446527067-04bdf033091eb780001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id r7LhScPDI7shFBqL for ; Mon, 02 Nov 2015 21:04:27 -0800 (PST) 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: A2CVBwAaPzhW/+rW03ZegzuBQqpMAQEBAQEBBosuhSWGCYYTAgIBAQKBOE0BAQEBAQGBC4Q1AQEBAwEyASMjBQsIAxIGCSUPBSUDDRQTiCgHwUsBAQEBBgEBAQEBAR0ZhheFRYgsgRQFlkONHZxDY4IOIIFqKjSFfgEBAQ Received: from ppp118-211-214-234.lns20.syd4.internode.on.net (HELO dastard) ([118.211.214.234]) by ipmail07.adl2.internode.on.net with ESMTP; 03 Nov 2015 15:34:26 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZtTlV-0003xB-Pc; Tue, 03 Nov 2015 16:04:13 +1100 Date: Tue, 3 Nov 2015 16:04:13 +1100 From: Dave Chinner To: Dan Williams Cc: Brian Foster , Ross Zwisler , Jan Kara , xfs@oss.sgi.com, linux-fsdevel , "linux-nvdimm@lists.01.org" Subject: Re: [PATCH 3/6] xfs: Don't use unwritten extents for DAX Message-ID: <20151103050413.GB19199@dastard> X-ASG-Orig-Subj: Re: [PATCH 3/6] xfs: Don't use unwritten extents for DAX References: <1445225238-30413-1-git-send-email-david@fromorbit.com> <1445225238-30413-4-git-send-email-david@fromorbit.com> <20151029142950.GE11663@bfoster.bfoster> <20151029233756.GS19199@dastard> <20151030123657.GC54905@bfoster.bfoster> <20151102011433.GW19199@dastard> <20151102141509.GA29346@bfoster.bfoster> <20151102214424.GJ10656@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit 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: 1446527067 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24060 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Mon, Nov 02, 2015 at 07:53:27PM -0800, Dan Williams wrote: > On Mon, Nov 2, 2015 at 1:44 PM, Dave Chinner wrote: > > [add people to the cc list] > > > > On Mon, Nov 02, 2015 at 09:15:10AM -0500, Brian Foster wrote: > >> On Mon, Nov 02, 2015 at 12:14:33PM +1100, Dave Chinner wrote: > >> > On Fri, Oct 30, 2015 at 08:36:57AM -0400, Brian Foster wrote: > >> > > Unless there is some > >> > > special mixed dio/mmap case I'm missing, doing so for DAX/DIO basically > >> > > causes a clear_pmem() over every page sized chunk of the target I/O > >> > > range for which we already have the data. > >> > > >> > I don't follow - this only zeros blocks when we do allocation of new > >> > blocks or overwrite unwritten extents, not on blocks which we > >> > already have written data extents allocated for... > >> > > >> > >> Why are we assuming that block zeroing is more efficient than unwritten > >> extents for DAX/dio? I haven't played with pmem enough to know for sure > >> one way or another (or if hw support is imminent), but I'd expect the > >> latter to be more efficient in general without any kind of hardware > >> support. > >> > >> Just as an example, here's an 8GB pwrite test, large buffer size, to XFS > >> on a ramdisk mounted with '-o dax:' > >> > >> - Before this series: > >> > >> # xfs_io -fc "truncate 0" -c "pwrite -b 10m 0 8g" /mnt/file > >> wrote 8589934592/8589934592 bytes at offset 0 > >> 8.000 GiB, 820 ops; 0:00:04.00 (1.909 GiB/sec and 195.6591 ops/sec) > >> > >> - After this series: > >> > >> # xfs_io -fc "truncate 0" -c "pwrite -b 10m 0 8g" /mnt/file > >> wrote 8589934592/8589934592 bytes at offset 0 > >> 8.000 GiB, 820 ops; 0:00:12.00 (659.790 MiB/sec and 66.0435 ops/sec) > > > > That looks wrong. Much, much slower than it should be just zeroing > > pages and then writing to them again while cache hot. > > > > Oh, hell - dax_clear_blocks() is stupidly slow. A profile shows this > > loop spending most of the CPU time: > > > > ¿ ¿ jbe ea > > ¿ de: clflus %ds:(%rax) > > 84.67 ¿ add %rsi,%rax > > ¿ cmp %rax,%rdx > > ¿ ¿ ja de > > ¿ ea: add %r13,-0x38(%rbp) > > ¿ sub %r12,%r14 > > ¿ sub %r12,-0x40(%rbp) > > > > That is the overhead of __arch_wb_cache_pmem() i.e. issuing CPU > > cache flushes after each memset. > > Ideally this would be non-temporal and skip the second flush loop > altogether. Outside of that another problem is that this cpu does not > support the clwb instruction and is instead using the serializing and > invalidating clflush instruction. Sure, it can be optimised to improve behaviour, and other hardware will be more performant, but we'll still be doing synchronous cache flushing operations here and so the fundamental problem still exists. > > This comes back to the comments I made w.r.t. the pmem driver > > implementation doing synchronous IO by immediately forcing CPU cache > > flushes and barriers. it's obviously correct, but it looks like > > there's going to be a major performance penalty associated with it. > > This is why I recently suggested that a pmem driver that doesn't do > > CPU cache writeback during IO but does it on REQ_FLUSH is an > > architecture we'll likely have to support. > > > > The only thing we can realistically delay is wmb_pmem() i.e. the final > sync waiting for data that has *left* the cpu cache. Unless/until we > get a architecturally guaranteed method to write-back the entire > cache, or flush the cache by physical-cache-way we're stuck with > either non-temporal cycles or looping on potentially huge virtual > address ranges. I'm missing something: why won't flushing the address range returned by bdev_direct_access() during a fsync operation work? i.e. we're working with exactly the same address as dax_clear_blocks() and dax_do_io() use, so why can't we look up that address and flush it from fsync? > > This, however, is not really a problem for the filesystem - it's > > a pmem driver architecture problem. ;) > > > > It's a platform problem. Let's see how this looks when not using > clflush instructions. Yes, clflush vs clwb is that's a platform problem. However, the architectural problem I've refered to is that is we've designed the DAX infrastructure around a CPU implementation that requires synchronous memory flushes for persistence, and so driven that synchronous flush requirement into the DAX implementation itself.... > Also, another benefit of pushing zeroing down into the driver is that > for brd, as used in this example, it will rightly be a nop because > there's no persistence to guarantee there. Precisely my point - different drivers and hardware have different semantics and optimisations, and only by separating the data copying from the persistence model do we end up with infrastructure that is flexible enough to work with different hardware/driver pmem models... Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Mon Nov 2 23:07:11 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 6D1E529E04 for ; Mon, 2 Nov 2015 23:07:11 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 5B87E304039 for ; Mon, 2 Nov 2015 21:07:08 -0800 (PST) X-ASG-Debug-ID: 1446527225-04cb6c7b851d0230001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id 3j3kukXIZKvMG8aV for ; Mon, 02 Nov 2015 21:07:06 -0800 (PST) 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: A2BWCABPQDhW/+rW03ZegzsjMG+qNAIBFQEBAQEBAQaBDYohhSWGCRcChXoEgTxNAQEBAQEBgQuEYy87JDQFJQM0iC+gV6EZCRmGF4pvghcMQh2BFAWHRY5+hR2IAIFhh2OFJoUGiFNjgVY7HYFqKjSENiWBIwEBAQ Received: from ppp118-211-214-234.lns20.syd4.internode.on.net (HELO dastard) ([118.211.214.234]) by ipmail07.adl2.internode.on.net with ESMTP; 03 Nov 2015 15:37:04 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZtTo4-0003xT-AS for xfs@oss.sgi.com; Tue, 03 Nov 2015 16:06:52 +1100 Date: Tue, 3 Nov 2015 16:06:52 +1100 From: Dave Chinner To: xfs@oss.sgi.com Subject: [ANNOUNCE] xfs: for-next branch rebased and updated to 264e89a Message-ID: <20151103050652.GC19199@dastard> X-ASG-Orig-Subj: [ANNOUNCE] xfs: for-next branch rebased and updated to 264e89a MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="UFHRwCdBEJvubb2X" 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: 1446527225 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24060 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- --UFHRwCdBEJvubb2X Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Hi folks, The for-next branch of the xfs kernel repository at git://git.kernel.org/pub/scm/linux/kernel/git/dgc/linux-xfs.git has just been updated. I rebased the xfs-misc-fixes-for-4.4-2 branch to fix the ACL build issue and added Andreas' and Darrick's bug fixes, and so the for-next branch has rebased as well. This update also includes all the DAX fixes queued up for 4.4. -Dave. The new head of the for-next branch is commit: 264e89a Merge branch 'xfs-dax-updates' into for-next New Commits: Andreas Gruenbacher (3): [86a21c7] xfs: Validate the length of on-disk ACLs [09cb22d] xfs: Plug memory leak in xfs_attrmulti_attr_set [47e1bf6] xfs: invalidate cached acl if set via ioctl Brian Foster (1): [67d8e04] xfs: invalidate cached acl if set directly via xattr Darrick J. Wong (1): [af3b638] xfs: don't leak uuid table on rmmod Dave Chinner (9): [3e12dbb] xfs: fix inode size update overflow in xfs_map_direct() [3fbbbea] xfs: introduce BMAPI_ZERO for allocating zeroed extents [1ca1915] xfs: Don't use unwritten extents for DAX [01a155e] xfs: DAX does not use IO completion callbacks [3af4928] xfs: add ->pfn_mkwrite support for DAX [13ad4fe] xfs: xfs_filemap_pmd_fault treats read faults as write faul= ts [fc0561c] xfs: optimise away log forces on timestamp updates for fdat= async [2da5c4b] Merge branch 'xfs-misc-fixes-for-4.4-2' into for-next [264e89a] Merge branch 'xfs-dax-updates' into for-next Jiri Kosina (1): [24ba16b] xfs: clear PF_NOFREEZE for xfsaild kthread Code Diffstat: fs/dax.c | 5 +++ fs/xfs/libxfs/xfs_alloc.c | 10 ++++- fs/xfs/libxfs/xfs_alloc.h | 8 ++-- fs/xfs/libxfs/xfs_bmap.c | 35 ++++++++++++++++- fs/xfs/libxfs/xfs_bmap.h | 13 ++++++- fs/xfs/libxfs/xfs_format.h | 8 +++- fs/xfs/xfs_acl.c | 13 ++++--- fs/xfs/xfs_acl.h | 3 ++ fs/xfs/xfs_aops.c | 96 ++++++++++++++++++++++++------------------= ---- fs/xfs/xfs_aops.h | 3 +- fs/xfs/xfs_bmap_util.c | 36 +++++++++++++++++ fs/xfs/xfs_file.c | 85 +++++++++++++++++++++++++++++++++------- fs/xfs/xfs_inode.c | 2 + fs/xfs/xfs_inode_item.c | 1 + fs/xfs/xfs_inode_item.h | 1 + fs/xfs/xfs_ioctl.c | 15 +++++++- fs/xfs/xfs_iomap.c | 21 +++++++++- fs/xfs/xfs_mount.c | 10 +++++ fs/xfs/xfs_mount.h | 4 ++ fs/xfs/xfs_super.c | 1 + fs/xfs/xfs_trace.h | 1 + fs/xfs/xfs_trans_ail.c | 1 + fs/xfs/xfs_trans_inode.c | 9 +++++ fs/xfs/xfs_xattr.c | 31 ++++++++++++++- 24 files changed, 331 insertions(+), 81 deletions(-) --=20 Dave Chinner david@fromorbit.com --UFHRwCdBEJvubb2X Content-Type: application/pgp-signature; name="signature.asc" Content-Description: Digital signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQIcBAEBAgAGBQJWOEDrAAoJEK3oKUf0dfodd9YP/iLeW2oVitZhob9fK3idws3U 8adrLkEZJEHp1QAfF9/yDK1oTGSCBrjBZmAUyCOUpYg1qQCrMn2hXRiRVF8rZbAI EiHXckneXuZ/jsuAKOayThwa/ZXmv8DWdWGRUlfTpzzhvywqYOO1R3keSxb7jiTA XEY+GjERewLwsEENPnSwbaYzmN/1KD5YSZn6fiBAsoG5LjnCx2MtcAZbTCZeXn4K ODS0dmTEzqircgTfHi+epq9OLfIYycwLH1LbJ+as+ykCFufoqvRrUt6ot0EXoBac jaziDo2PjYfRQG3jV7qfiK7wIdAp6t8RgkFgbssKGchbIk9lBU/EJRw8RlyZahT4 fQLrNDQdrKZBylHOa+fvVK+A8kQBo1GLIibS1zsukTHQx2H0yyxrRLe+eRVgb0H2 BMgUt5g6j0yMwTFh2+T51dGqz9dws4v2O35E8AEp5mphqkHSCoRpankgtQ3FY0Yr VnSrjyy0L0YIaDILlqXT9axrT2qUmV1JTstadIVTBOZSVLAIqbkib0FC0F08NhMw ZbOmzweYZyaOduCGzN0J7BGPMAm6arg3zSCjmN8364/Rd7+yxAf+y89xGvVJxLfD r8Uki01od32pbWQyIp7EILz7ULLz9d9tkWhwMKVEDtASzmMFoQfjxe4Ete75Pa4M s5ZNJ+Jm3sOCx7IVRQ16 =47T0 -----END PGP SIGNATURE----- --UFHRwCdBEJvubb2X-- From axrblsqjobae@merr.com Tue Nov 3 00:59:22 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.5 required=5.0 tests=FROM_LOCAL_NOVOWEL, HTML_FONT_SIZE_LARGE,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 DFB0A7F5F for ; Tue, 3 Nov 2015 00:59:21 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 7BDF5AC002 for ; Mon, 2 Nov 2015 22:59:21 -0800 (PST) X-ASG-Debug-ID: 1446533955-04bdf033091edaa0001-NocioJ Received: from merr.com.s7b1.psmtp.com (s18343115.onlinehome-server.info [217.160.253.88]) by cuda.sgi.com with ESMTP id 8LJJKXvm8Hv9iUay for ; Mon, 02 Nov 2015 22:59:16 -0800 (PST) X-Barracuda-Envelope-From: axrblsqjobae@merr.com X-Barracuda-Apparent-Source-IP: 217.160.253.88 Message-ID: <093E5EB21297999B12EE81805AE987C1@AHUVXBFOCQZC> From: "=?utf-8?B?0KPQstC+0LvRjNC90LXQvdC40LUg0L/QtdGA0YHQvtC90LDQu9Cw?=" To: Subject: =?utf-8?B?0JrQsNC6INGD0LLQvtC70LjRgtGMINGB0L7RgtGA0YPQtNC90LjQutCwLCDQtdGB0LvQuCDQvtC9INGN0YLQvtCz0L4g0L3QtSDRhdC+0YfQtdGC?= Date: Tue, 3 Nov 2015 09:59:17 +0300 X-ASG-Orig-Subj: =?utf-8?B?0JrQsNC6INGD0LLQvtC70LjRgtGMINGB0L7RgtGA0YPQtNC90LjQutCwLCDQtdGB0LvQuCDQvtC9INGN0YLQvtCz0L4g0L3QtSDRhdC+0YfQtdGC?= MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="----=_NextPart_000_003C_01D1161E.4D8421B0" 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: s18343115.onlinehome-server.info[217.160.253.88] X-Barracuda-Start-Time: 1446533955 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 2.53 X-Barracuda-Spam-Status: No, SCORE=2.53 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=FROM_LOCAL_NOVOWEL, HTML_FONT_SIZE_LARGE, HTML_MESSAGE, K2_FROM_LOCAL_NOVOWEL X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24062 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 HTML_FONT_SIZE_LARGE BODY: HTML font size is large 0.00 HTML_MESSAGE BODY: HTML included in message 0.20 FROM_LOCAL_NOVOWEL From: localpart has series of non-vowel letters 2.33 K2_FROM_LOCAL_NOVOWEL From: localpart has series of non-vowel letters Ýòî — ñîîáùåíèå èç íåñêîëüêèõ ÷àñòåé â ôîðìàòå MIME. ------=_NextPart_000_003C_01D1161E.4D8421B0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable =20 =D0=A3=D1=87=D0=B5=D0=B1=D0=BD=D1=8B=D0=B9 = =D1=86=D0=B5=D0=BD=D1=82=D1=80 = =D0=BF=D1=80=D0=B8=D0=B3=D0=BB=D0=B0=D1=88=D0=B0=D0=B5=D1=82 = =D0=BD=D0=B0 =D0=BE=D0=B1=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=BF=D0=BE =D1=82=D0=B5=D0=BC=D0=B5: =20 =D0=A3=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=BF=D0=B5=D1=80=D1=81=D0=BE=D0=BD=D0=B0=D0=BB=D0=B0. =D0=91=D0=B5=D0=B7=D0=BE=D0=BF=D0=B0=D1=81=D0=BD=D0=BE =D0=B8 = =D0=B1=D0=B5=D1=81=D0=BA=D0=BE=D0=BD=D1=84=D0=BB=D0=B8=D0=BA=D1=82=D0=BD=D0= =BE. =D0=A6=D0=B5=D0=BB=D0=B5=D0=B2=D0=B0=D1=8F = =D0=B0=D1=83=D0=B4=D0=B8=D1=82=D0=BE=D1=80=D0=B8=D1=8F: = =D0=A0=D1=83=D0=BA=D0=BE=D0=B2=D0=BE=D0=B4=D0=B8=D1=82=D0=B5=D0=BB=D0=B8 = =D0=B8 =D1=81=D0=BE=D1=82=D1=80=D1=83=D0=B4=D0=BD=D0=B8=D0=BA=D0=B8 = =D0=BA=D0=B0=D0=B4=D1=80=D0=BE=D0=B2=D1=8B=D1=85 = =D1=81=D0=BB=D1=83=D0=B6=D0=B1, = =D0=B4=D0=B8=D1=80=D0=B5=D0=BA=D1=82=D0=BE=D1=80=D0=B0 =D0=B8 =D0=BC=D0=B5=D0=BD=D0=B5=D0=B4=D0=B6=D0=B5=D1=80=D1=8B = =D0=BF=D0=BE =D0=BF=D0=B5=D1=80=D1=81=D0=BE=D0=BD=D0=B0=D0=BB=D1=83, = =D0=B1=D1=83=D1=85=D0=B3=D0=B0=D0=BB=D1=82=D0=B5=D1=80=D1=8B, = =D1=8E=D1=80=D0=B8=D1=81=D1=82=D1=8B, = =D1=80=D1=83=D0=BA=D0=BE=D0=B2=D0=BE=D0=B4=D0=B8=D1=82=D0=B5=D0=BB=D0=B8 = =D0=BA=D0=BE=D0=BC=D0=BF=D0=B0=D0=BD=D0=B8=D0=B9. =20 =20 18 =D0=BD=D0=BE=D1=8F=D0=B1=D1=80=D1=8F 2015 = =D0=B3=D0=BE=D0=B4=D0=B0, =D0=B3=D0=BE=D1=80=D0=BE=D0=B4 = =D0=9C=D0=BE=D1=81=D0=BA=D0=B2=D0=B0 | = (=D0=B0=D1=80=D1=82=D0=B8=D0=BA=D1=83=D0=BB: 250) =D0=97=D0=B0=D0=BD=D1=8F=D1=82=D0=B8=D0=B5 = =D0=BF=D1=80=D0=BE=D0=B2=D0=BE=D0=B4=D0=B8=D1=82=D1=81=D1=8F c 10:00 = =D0=B4=D0=BE 17:30 =D0=90=D0=B4=D1=80=D0=B5=D1=81 = =D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D0=B4=D0=B5=D0=BD=D0=B8=D1=8F = =D0=BC=D0=B5=D1=80=D0=BE=D0=BF=D1=80=D0=B8=D1=8F=D1=82=D0=B8=D1=8F: = =D1=83=D0=BB. = =D0=91=D0=B0=D1=83=D0=BC=D0=B0=D0=BD=D1=81=D0=BA=D0=B0=D1=8F, =D0=B4.6, = =D1=81=D1=82=D1=80.2, =D0=91.=D0=A6. = "=D0=92=D0=B8=D0=BA=D1=82=D0=BE=D1=80=D0=B8=D1=8F = =D0=9F=D0=BB=D0=B0=D0=B7=D0=B0". =D0=A3=D0=B7=D0=BD=D0=B0=D1=82=D1=8C =D0=92=D1=81=D1=8E = =D0=BF=D0=BE=D0=B4=D1=80=D0=BE=D0=B1=D0=BD=D1=83=D1=8E = =D0=B8=D0=BD=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=86=D0=B8=D1=8E =D0=B8 = =D0=BF=D0=BE=D0=B4=D0=B0=D1=82=D1=8C = =D0=B7=D0=B0=D1=8F=D0=B2=D0=BA=D1=83 =D0=BD=D0=B0 = =D0=BE=D0=B1=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D0=B5 =D0=92=D1=8B = =D0=BC=D0=BE=D0=B6=D0=B5=D1=82=D0=B5 =D0=BF=D0=BE = =D1=82=D0=B5=D0=BB=D0=B5=D1=84=D0=BE=D0=BD=D1=83 :=20 8 =D0=BA=D0=BE=D0=B4 =D0=B3=D0=BE=D1=80=D0=BE=D0=B4=D0=B0 ( 4 9 = 5 ) =D0=BD=D0=BE=D0=BC=D0=B5=D1=80 7 2 5 - 0 4 - 4 8. =D0=92=D1=8B =D0=BC=D0=BE=D0=B6=D0=B5=D1=82=D0=B5 = =D1=83=D1=87=D0=B0=D1=81=D1=82=D0=B2=D0=BE=D0=B2=D0=B0=D1=82=D1=8C = =D0=B2 =D0=BE=D0=B1=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D0=B8 = =D0=BA=D0=B0=D0=BA =D0=BE=D1=82 = =D0=BA=D0=BE=D0=BC=D0=BF=D0=B0=D0=BD=D0=B8=D0=B8, =D1=82=D0=B0=D0=BA = =D0=B8 =D0=BA=D0=B0=D0=BA =D1=87=D0=B0=D1=81=D1=82=D0=BD=D0=BE=D0=B5 = =D0=BB=D0=B8=D1=86=D0=BE. (=D0=BF=D0=BE=D0=B6=D0=B0=D0=BB=D1=83=D0=B9=D1=81=D1=82=D0=B0 = =D0=BD=D0=B5 =D0=BE=D1=82=D0=B2=D0=B5=D1=87=D0=B0=D0=B9=D1=82=D0=B5 = =D0=BD=D0=B0 =D0=BE=D0=B1=D1=80=D0=B0=D1=82=D0=BD=D1=8B=D0=B9 = =D0=B0=D0=B4=D1=80=D0=B5=D1=81 = =D1=8D=D0=BB.=D0=BF=D0=BE=D1=87=D1=82=D1=8B) =20 =20 = =D0=91=D0=BE=D0=BB=D1=8C=D1=88=D0=B8=D0=BD=D1=81=D1=82=D0=B2=D0=BE = =D1=81=D0=BF=D0=BE=D1=80=D0=BE=D0=B2, = =D0=B2=D0=BE=D0=B7=D0=BD=D0=B8=D0=BA=D0=B0=D1=8E=D1=89=D0=B8=D1=85 = =D0=B8=D0=B7 =D1=82=D1=80=D1=83=D0=B4=D0=BE=D0=B2=D1=8B=D1=85 = =D0=BE=D1=82=D0=BD=D0=BE=D1=88=D0=B5=D0=BD=D0=B8=D0=B9, = =D1=81=D0=B2=D1=8F=D0=B7=D0=B0=D0=BD=D0=BE =D1=81 = =D1=83=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5=D0=BC = =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BD=D0=B8=D0=BA=D0=BE=D0=B2, =D0=B0 =D1=82=D0=B0=D0=BA=D0=B6=D0=B5 =D1=81 = =D0=BD=D0=B5=D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D0=BD=D1=8B=D0=BC = =D0=BF=D1=80=D0=B8=D0=B2=D0=BB=D0=B5=D1=87=D0=B5=D0=BD=D0=B8=D0=B5=D0=BC = =D0=B8=D0=BD=D0=BE=D1=81=D1=82=D1=80=D0=B0=D0=BD=D0=BD=D1=8B=D1=85 = =D0=B3=D1=80=D0=B0=D0=B6=D0=B4=D0=B0=D0=BD =D0=BA = =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B5. = =D0=9D=D0=B5=D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D0=BD=D0=BE=D0=B5 = =D1=83=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5, =D0=BF=D0=BE=D0=BC=D0=B8=D0=BC=D0=BE = =D0=BD=D0=B5=D0=BE=D0=B1=D1=85=D0=BE=D0=B4=D0=B8=D0=BC=D0=BE=D1=81=D1=82=D0= =B8 = =D0=B2=D0=BE=D1=81=D1=81=D1=82=D0=B0=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=D0= =B8=D1=8F =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BD=D0=B8=D0=BA=D0=B0 = =D0=BD=D0=B0 =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B5, = =D0=B2=D0=BB=D0=B5=D1=87=D0=B5=D1=82 = =D0=BD=D0=B5=D0=B1=D0=BB=D0=B0=D0=B3=D0=BE=D0=BF=D1=80=D0=B8=D1=8F=D1=82=D0= =BD=D1=8B=D0=B5 = =D0=BC=D0=B0=D1=82=D0=B5=D1=80=D0=B8=D0=B0=D0=BB=D1=8C=D0=BD=D1=8B=D0=B5 = =D0=B8 = =D1=80=D0=B5=D0=BF=D1=83=D1=82=D0=B0=D1=86=D0=B8=D0=BE=D0=BD=D0=BD=D1=8B=D0= =B5 =D0=BF=D0=BE=D1=81=D0=BB=D0=B5=D0=B4=D1=81=D1=82=D0=B2=D0=B8=D1=8F = =D0=B4=D0=BB=D1=8F = =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BE=D0=B4=D0=B0=D1=82=D0=B5=D0=BB=D1=8F.= =D0=94=D0=BB=D1=8F =D1=82=D0=BE=D0=B3=D0=BE = =D1=87=D1=82=D0=BE=D0=B1=D1=8B = =D0=B3=D1=80=D0=B0=D0=BC=D0=BE=D1=82=D0=BD=D0=BE =D1=80=D0=B0=D1=81=D1=81=D1=82=D0=B0=D1=82=D1=8C=D1=81=D1=8F = =D1=81 =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BD=D0=B8=D0=BA=D0=BE=D0=BC, = =D0=BD=D0=B5=D0=B4=D0=BE=D1=81=D1=82=D0=B0=D1=82=D0=BE=D1=87=D0=BD=D0=BE = =D0=BD=D0=B0=D0=B9=D1=82=D0=B8 =D0=BF=D0=BE=D0=B2=D0=BE=D0=B4 = =D0=B4=D0=BB=D1=8F = =D1=83=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F, = =D0=BD=D0=B5=D0=BE=D0=B1=D1=85=D0=BE=D0=B4=D0=B8=D0=BC=D0=BE = =D1=87=D0=B5=D1=82=D0=BA=D0=BE=D0=B5 =D1=81=D0=BE=D0=B1=D0=BB=D1=8E=D0=B4=D0=B5=D0=BD=D0=B8=D0=B5 = =D1=83=D1=81=D1=82=D0=B0=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=D0=BD=D1=8B=D1= =85 =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D0=BE=D0=BC =D0=BD=D0=BE=D1=80=D0=BC, = =D0=BF=D1=80=D0=BE=D1=86=D0=B5=D0=B4=D1=83=D1=80, = =D1=81=D0=BE=D0=BF=D1=80=D0=BE=D0=B2=D0=BE=D0=B6=D0=B4=D0=B0=D0=B5=D0=BC=D1= =8B=D1=85 =D0=BA=D0=B0=D0=B4=D1=80=D0=BE=D0=B2=D0=BE=D0=B9 = =D0=B4=D0=BE=D0=BA=D1=83=D0=BC=D0=B5=D0=BD=D1=82=D0=B0=D1=86=D0=B8=D0=B5=D0= =B9. =D0=A1=D0=BE=D0=B1=D0=BB=D1=8E=D0=B4=D0=B5=D0=BD=D0=B8=D0=B5 = =D1=83=D1=81=D1=82=D0=B0=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=D0=BD=D1=8B=D1= =85 = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D0=BE=D0=B4=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=D1= =81=D1=82=D0=B2=D0=BE=D0=BC =D0=BD=D0=BE=D1=80=D0=BC =D0=B8 = =D0=BF=D1=80=D0=BE=D1=86=D0=B5=D0=B4=D1=83=D1=80 = =D0=BF=D1=80=D0=B5=D0=BA=D1=80=D0=B0=D1=89=D0=B5=D0=BD=D0=B8=D1=8F = =D1=82=D1=80=D1=83=D0=B4=D0=BE=D0=B2=D0=BE=D0=B3=D0=BE =D0=B4=D0=BE=D0=B3=D0=BE=D0=B2=D0=BE=D1=80=D0=B0 = =D0=BC=D0=B8=D0=BD=D0=B8=D0=BC=D0=B8=D0=B7=D0=B8=D1=80=D1=83=D0=B5=D1=82 = =D0=B2 =D0=B4=D0=B0=D0=BB=D1=8C=D0=BD=D0=B5=D0=B9=D1=88=D0=B5=D0=BC = =D1=80=D0=B8=D1=81=D0=BA=D0=B8, = =D1=81=D0=B2=D1=8F=D0=B7=D0=B0=D0=BD=D0=BD=D1=8B=D0=B5 =D1=81 = =D1=82=D1=80=D1=83=D0=B4=D0=BE=D0=B2=D1=8B=D0=BC = =D1=81=D0=BF=D0=BE=D1=80=D0=BE=D0=BC. =20 =20 =D0=9E=D0=BF=D0=B8=D1=81=D0=B0=D0=BD=D0=B8=D0=B5 = =D0=BF=D1=80=D0=BE=D0=B3=D1=80=D0=B0=D0=BC=D0=BC=D1=8B: =20 =20 1. =D0=A3=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D1=8F=D0=B5=D0=BC = =D1=81=D0=BE=D1=82=D1=80=D1=83=D0=B4=D0=BD=D0=B8=D0=BA=D0=B0 = =D0=B1=D0=B5=D0=B7 =D0=BF=D1=80=D0=BE=D0=B1=D0=BB=D0=B5=D0=BC. * = =D0=A4=D0=BE=D1=80=D0=BC=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5 = =D0=BF=D1=81=D0=B8=D1=85=D0=BE=D0=BB=D0=BE=D0=B3=D0=B8=D1=87=D0=B5=D1=81=D0= =BA=D0=BE=D0=B3=D0=BE =D0=BF=D0=BE=D1=80=D1=82=D1=80=D0=B5=D1=82=D0=B0 = =D1=81=D0=BE=D1=82=D1=80=D1=83=D0=B4=D0=BD=D0=B8=D0=BA=D0=B0 * =D0=9C=D0=B5=D1=82=D0=BE=D0=B4=D1=8B =D0=B8 = =D0=BF=D1=80=D0=B8=D0=B5=D0=BC=D1=8B = =D0=BF=D1=81=D0=B8=D1=85=D0=BE=D0=BB=D0=BE=D0=B3=D0=B8=D0=B8, = =D1=81=D0=BF=D0=BE=D1=81=D0=BE=D0=B1=D1=81=D1=82=D0=B2=D1=83=D1=8E=D1=89=D0= =B8=D0=B5 =D1=83=D0=B1=D0=B5=D0=B4=D0=B8=D1=82=D1=8C = =D1=81=D0=BE=D1=82=D1=80=D1=83=D0=B4=D0=BD=D0=B8=D0=BA=D0=B0 = =D1=83=D0=B2=D0=BE=D0=BB=D0=B8=D1=82=D1=8C=D1=81=D1=8F * =D0=9A=D0=BE=D0=BD=D1=84=D0=BB=D0=B8=D0=BA=D1=82=D1=8B = =D0=BF=D1=80=D0=B8 = =D1=83=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D0=B5=D0=BD=D0=B8=D0=B8 =D0=B8 = =D0=B1=D0=BE=D1=80=D1=8C=D0=B1=D0=B0 = =D0=BA=D0=BE=D0=BC=D0=BF=D1=80=D0=BE=D0=BC=D0=B0=D1=82=D0=BE=D0=B2 * =D0=A7=D1=82=D0=BE =D1=81=D0=B4=D0=B5=D0=BB=D0=B0=D1=82=D1=8C, = =D1=87=D1=82=D0=BE=D0=B1=D1=8B = =D1=81=D0=BE=D1=82=D1=80=D1=83=D0=B4=D0=BD=D0=B8=D0=BA =D0=BD=D0=B5 = =D1=81=D0=BC=D0=BE=D0=B3 = =D0=BF=D0=B5=D1=80=D0=B5=D0=B4=D1=83=D0=BC=D0=B0=D1=82=D1=8C * =D0=98=D0=BC=D0=B8=D0=B4=D0=B6=D0=B5=D0=B2=D1=8B=D0=B5 = =D0=B0=D1=81=D0=BF=D0=B5=D0=BA=D1=82=D1=8B = =D0=B2=D0=BE=D0=B7=D0=B4=D0=B5=D0=B9=D1=81=D1=82=D0=B2=D0=B8=D1=8F = =D0=BD=D0=B0 = =D1=83=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D1=8F=D1=8E=D1=89=D0=B5=D0=B3=D0=BE=D1= =81=D1=8F =D1=81=D0=BE=D1=82=D1=80=D1=83=D0=B4=D0=BD=D0=B8=D0=BA=D0=B0 * = =D0=97=D0=B0=D0=BA=D0=BE=D0=BD=D0=BE=D0=B4=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=D0= =BD=D1=8B=D0=B5 =D0=BC=D0=B5=D1=80=D1=8B = =D0=B1=D0=BE=D1=80=D1=8C=D0=B1=D1=8B =D1=81 = =C2=AB=D0=BA=D0=B0=D0=B4=D1=80=D0=BE=D0=B2=D1=8B=D0=BC = =D1=8D=D0=BA=D1=81=D1=82=D1=80=D0=B5=D0=BC=D0=B8=D0=B7=D0=BC=D0=BE=D0=BC=C2= =BB - = =D0=BD=D0=B5=D0=BE=D0=B1=D0=BE=D1=81=D0=BD=D0=BE=D0=B2=D0=B0=D0=BD=D0=BD=D1= =8B=D0=BC=D0=B8 =D0=B6=D0=B0=D0=BB=D0=BE=D0=B1=D0=B0=D0=BC=D0=B8 =D0=B2 =D1=82=D1=80=D1=83=D0=B4=D0=BE=D0=B2=D1=83=D1=8E = =D0=B8=D0=BD=D1=81=D0=BF=D0=B5=D0=BA=D1=86=D0=B8=D1=8E, = =D1=81=D1=83=D0=B4=D0=B5=D0=B1=D0=BD=D1=8B=D0=BC=D0=B8 = =D0=B8=D1=81=D0=BA=D0=B0=D0=BC=D0=B8 2. =D0=A3=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=BF=D0=BE = =D1=81=D0=BE=D0=B1=D1=81=D1=82=D0=B2=D0=B5=D0=BD=D0=BD=D0=BE=D0=BC=D1=83 = =D0=B6=D0=B5=D0=BB=D0=B0=D0=BD=D0=B8=D1=8E. * =D0=A7=D1=82=D0=BE =D0=BD=D1=83=D0=B6=D0=BD=D0=BE = =D0=B7=D0=BD=D0=B0=D1=82=D1=8C =D0=BE = =D0=B7=D0=B0=D1=8F=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B8, =D0=BE=D0=B1 = =D1=83=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D0=B5=D0=BD=D0=B8=D0=B8 = =D0=BF=D1=80=D0=B5=D0=B4=D1=83=D0=BF=D1=80=D0=B5=D0=B6=D0=B4=D0=B5=D0=BD=D0= =B8=D0=B8 = =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BE=D0=B4=D0=B0=D1=82=D0=B5=D0=BB=D1=8F * =D0=9E=D1=81=D0=BD=D0=BE=D0=B2=D0=BD=D1=8B=D0=B5 = =D0=B7=D0=B0=D0=B1=D0=BB=D1=83=D0=B6=D0=B4=D0=B5=D0=BD=D0=B8=D1=8F = =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BD=D0=B8=D0=BA=D0=BE=D0=B2 =D0=B8 = =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BE=D0=B4=D0=B0=D1=82=D0=B5=D0=BB=D0=B5=D0= =B9, =D0=BA=D0=B0=D0=BA =D1=81 =D0=BD=D0=B8=D0=BC=D0=B8 = =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=D1=82=D1=8C, = =D1=87=D1=82=D0=BE=D0=B1=D1=8B =D0=BD=D0=B5 = =D0=B4=D0=BE=D0=B2=D0=BE=D0=B4=D0=B8=D1=82=D1=8C =D0=B4=D0=B5=D0=BB=D0=B0 =D0=B4=D0=BE =D1=81=D1=83=D0=B4=D0=B0 * = =D0=9E=D0=B1=D1=8F=D0=B7=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=D0=BD=D1=8B=D0=B5 = =D0=B8 = =D1=80=D0=B5=D0=BA=D0=BE=D0=BC=D0=B5=D0=BD=D0=B4=D1=83=D0=B5=D0=BC=D1=8B=D0= =B5 =D0=BF=D1=80=D0=BE=D1=86=D0=B5=D0=B4=D1=83=D1=80=D1=8B, = =D0=BD=D0=B5=D0=BE=D0=B1=D1=85=D0=BE=D0=B4=D0=B8=D0=BC=D1=8B=D0=B5 = =D0=B4=D0=BE=D0=BA=D1=83=D0=BC=D0=B5=D0=BD=D1=82=D1=8B, = =D1=82=D0=B8=D0=BF=D0=B8=D1=87=D0=BD=D1=8B=D0=B5 = =D0=BE=D1=88=D0=B8=D0=B1=D0=BA=D0=B8 =D0=B8 =D0=B8=D1=85 = =D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5, = =D0=BA=D0=BE=D1=80=D1=80=D0=B5=D0=BA=D1=82=D0=B8=D1=80=D0=BE=D0=B2=D0=BA=D0= =B0 =D0=BF=D0=BE=D0=B2=D0=B5=D0=B4=D0=B5=D0=BD=D0=B8=D1=8F = =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BD=D0=B8=D0=BA=D0=B0 * =D0=92=D1=8B=D0=B4=D0=B0=D1=87=D0=B0 = =D0=B4=D0=BE=D0=BA=D1=83=D0=BC=D0=B5=D0=BD=D1=82=D0=BE=D0=B2 = =D0=BF=D1=80=D0=B8 = =D1=83=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D0=B5=D0=BD=D0=B8=D0=B8 * =D0=92=D0=BD=D0=BE=D1=81=D0=B8=D0=BC = =D0=B7=D0=B0=D0=BF=D0=B8=D1=81=D1=8C =D0=B2 = =D1=82=D1=80=D1=83=D0=B4=D0=BE=D0=B2=D1=83=D1=8E = =D0=BA=D0=BD=D0=B8=D0=B6=D0=BA=D1=83 = =D0=BF=D1=80=D0=B0=D0=B2=D0=B8=D0=BB=D1=8C=D0=BD=D0=BE, = =D0=BF=D0=BE=D1=87=D0=B5=D0=BC=D1=83 = =D0=B2=D0=BE=D0=B7=D0=BD=D0=B8=D0=BA=D0=B0=D1=8E=D1=82 = =D1=81=D0=BB=D0=BE=D0=B6=D0=BD=D0=BE=D1=81=D1=82=D0=B8 =D1=81 = =D0=B2=D0=BD=D0=B5=D1=81=D0=B5=D0=BD=D0=B8=D0=B5=D0=BC =D0=B7=D0=B0=D0=BF=D0=B8=D1=81=D0=B5=D0=B9: = =D1=83=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5 = =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BD=D0=B8=D0=BA=D0=B0, = =D1=80=D0=B0=D1=81=D1=82=D0=BE=D1=80=D0=B6=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=B8=D0=BB=D0=B8 = =D0=BF=D1=80=D0=B5=D0=BA=D1=80=D0=B0=D1=89=D0=B5=D0=BD=D0=B8=D0=B5 = =D1=82=D1=80=D1=83=D0=B4=D0=BE=D0=B2=D0=BE=D0=B3=D0=BE = =D0=B4=D0=BE=D0=B3=D0=BE=D0=B2=D0=BE=D1=80=D0=B0, =D0=BA=D0=B0=D0=BA =D0=BB=D0=B5=D0=B3=D0=BA=D0=BE = =D0=BD=D0=B0=D1=83=D1=87=D0=B8=D1=82=D1=8C=D1=81=D1=8F = =D0=BF=D0=B8=D1=81=D0=B0=D1=82=D1=8C = =D0=BF=D1=80=D0=B0=D0=B2=D0=B8=D0=BB=D1=8C=D0=BD=D1=83=D1=8E = =D0=B7=D0=B0=D0=BF=D0=B8=D1=81=D1=8C=20 * =D0=9E=D1=84=D0=BE=D1=80=D0=BC=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=BE=D0=BA=D0=BE=D0=BD=D1=87=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=D0=BD=D0=BE=D0= =B3=D0=BE =D1=80=D0=B0=D1=81=D1=87=D0=B5=D1=82=D0=B0 * =D0=98=D1=81=D0=BA=D0=BE=D0=B2=D0=B0=D1=8F = =D0=B4=D0=B0=D0=B2=D0=BD=D0=BE=D1=81=D1=82=D1=8C =D0=BF=D0=BE = =D1=81=D0=BF=D0=BE=D1=80=D0=B0=D0=BC =D0=BE=D0=B1 = =D1=83=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D0=B5=D0=BD=D0=B8=D0=B8 * =D0=9F=D1=80=D0=BE=D0=B1=D0=BB=D0=B5=D0=BC=D0=BD=D1=8B=D0=B5 = =D0=BC=D0=B5=D1=81=D1=82=D0=B0 =D0=B2=D1=81=D0=B5=D1=85 = =D0=B2=D0=B8=D0=B4=D0=BE=D0=B2 = =D1=83=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D0=B5=D0=BD=D0=B8=D0=B9 * =D0=9E=D1=82=D0=BF=D1=83=D1=81=D0=BA =D1=81 = =D0=BF=D0=BE=D1=81=D0=BB=D0=B5=D0=B4=D1=83=D1=8E=D1=89=D0=B8=D0=BC = =D1=83=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5=D0=BC 3. = =D0=A0=D0=B0=D1=81=D1=82=D0=BE=D1=80=D0=B6=D0=B5=D0=BD=D0=B8=D0=B5 = =D1=82=D1=80=D1=83=D0=B4=D0=BE=D0=B2=D0=BE=D0=B3=D0=BE = =D0=B4=D0=BE=D0=B3=D0=BE=D0=B2=D0=BE=D1=80=D0=B0 =D0=BF=D0=BE = =D1=81=D0=BE=D0=B3=D0=BB=D0=B0=D1=88=D0=B5=D0=BD=D0=B8=D1=8E = =D1=81=D1=82=D0=BE=D1=80=D0=BE=D0=BD: =D0=BD=D0=B0 = =D1=81=D1=82=D1=80=D0=B0=D0=B6=D0=B5 = =D0=B8=D0=BD=D1=82=D0=B5=D1=80=D0=B5=D1=81=D0=BE=D0=B2 = =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BE=D0=B4=D0=B0=D1=82=D0=B5=D0=BB=D1=8F.= =D0=9F=D0=BB=D1=8E=D1=81=D1=8B =D0=B8 = =D0=BC=D0=B8=D0=BD=D1=83=D1=81=D1=8B = =D0=B4=D0=B0=D0=BD=D0=BD=D0=BE=D0=B3=D0=BE = =D1=83=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F. = =D0=9E=D0=BF=D1=80=D0=B5=D0=B4=D0=B5=D0=BB=D1=8F=D0=B5=D0=BC = =D0=B2=D1=8B=D1=85=D0=BE=D0=B4=D0=BD=D0=BE=D0=B5 = =D0=BF=D0=BE=D1=81=D0=BE=D0=B1=D0=B8=D0=B5 = =D0=B8=D1=81=D1=85=D0=BE=D0=B4=D1=8F =D0=B8=D0=B7 = =D0=B8=D0=BD=D1=82=D0=B5=D1=80=D0=B5=D1=81=D0=BE=D0=B2 =D0=BA=D0=BE=D0=BC=D0=BF=D0=B0=D0=BD=D0=B8=D0=B8 4. = =D0=9F=D1=80=D0=B5=D0=BA=D1=80=D0=B0=D1=89=D0=B5=D0=BD=D0=B8=D0=B5 = =D1=82=D1=80=D1=83=D0=B4=D0=BE=D0=B2=D0=BE=D0=B3=D0=BE = =D0=B4=D0=BE=D0=B3=D0=BE=D0=B2=D0=BE=D1=80=D0=B0 =D0=B2 = =D1=81=D0=B2=D1=8F=D0=B7=D0=B8 =D1=81 = =D0=B8=D1=81=D1=82=D0=B5=D1=87=D0=B5=D0=BD=D0=B8=D0=B5=D0=BC = =D1=81=D1=80=D0=BE=D0=BA=D0=B0 =D0=B5=D0=B3=D0=BE = =D0=B4=D0=B5=D0=B9=D1=81=D1=82=D0=B2=D0=B8=D1=8F. =D0=9F=D0=BE=D1=80=D1=8F=D0=B4=D0=BE=D0=BA = =D1=80=D0=B0=D1=81=D1=82=D0=BE=D1=80=D0=B6=D0=B5=D0=BD=D0=B8=D1=8F, = =D0=BD=D1=8E=D0=B0=D0=BD=D1=81=D1=8B = =D0=BE=D1=84=D0=BE=D1=80=D0=BC=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F, = =D0=BE=D1=88=D0=B8=D0=B1=D0=BA=D0=B8 = =D0=BA=D0=BE=D1=82=D0=BE=D1=80=D1=8B=D0=B5 = =D0=BD=D0=B5=D0=BB=D1=8C=D0=B7=D1=8F = =D0=B4=D0=BE=D0=BF=D1=83=D1=81=D0=BA=D0=B0=D1=82=D1=8C 5. = =D0=A0=D0=B0=D1=81=D1=82=D0=BE=D1=80=D0=B6=D0=B5=D0=BD=D0=B8=D0=B5 = =D1=82=D1=80=D1=83=D0=B4=D0=BE=D0=B2=D0=BE=D0=B3=D0=BE = =D0=B4=D0=BE=D0=B3=D0=BE=D0=B2=D0=BE=D1=80=D0=B0 =D0=B7=D0=B0 = =D0=B4=D0=B8=D1=81=D1=86=D0=B8=D0=BF=D0=BB=D0=B8=D0=BD=D0=B0=D1=80=D0=BD=D1= =8B=D0=B5 =D0=BF=D1=80=D0=BE=D1=81=D1=82=D1=83=D0=BF=D0=BA=D0=B8 = =E2=80=93 =D0=BE=D1=84=D0=BE=D1=80=D0=BC=D0=BB=D1=8F=D0=B5=D0=BC =D0=BD=D0=B0=D0=BB=D0=BE=D0=B6=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=B2=D0=B7=D1=8B=D1=81=D0=BA=D0=B0=D0=BD=D0=B8=D1=8F = =D0=BF=D1=80=D0=B0=D0=B2=D0=B8=D0=BB=D1=8C=D0=BD=D0=BE.=20 * =D0=9F=D0=BE=D1=80=D1=8F=D0=B4=D0=BE=D0=BA = =D0=BD=D0=B0=D0=BB=D0=BE=D0=B6=D0=B5=D0=BD=D0=B8=D1=8F =D0=B8 = =D0=BE=D1=84=D0=BE=D1=80=D0=BC=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F, = =D0=B7=D0=B0=D0=B1=D0=BB=D1=83=D0=B6=D0=B4=D0=B5=D0=BD=D0=B8=D1=8F = =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BE=D0=B4=D0=B0=D1=82=D0=B5=D0=BB=D1=8F = =D0=B8 =D0=B5=D0=B3=D0=BE = =D0=BE=D1=81=D0=BD=D0=BE=D0=B2=D0=BD=D1=8B=D0=B5 = =D0=BE=D1=88=D0=B8=D0=B1=D0=BA=D0=B8. = =D0=9F=D0=BE=D0=B4=D0=B3=D0=BE=D1=82=D0=BE=D0=B2=D0=B8=D1=82=D0=B5=D0=BB=D1= =8C=D0=BD=D1=8B=D0=B5 = =D0=BC=D0=B5=D1=80=D0=BE=D0=BF=D1=80=D0=B8=D1=8F=D1=82=D0=B8=D1=8F, = =D0=BF=D1=80=D0=B5=D0=B4=D1=88=D0=B5=D1=81=D1=82=D0=B2=D1=83=D1=8E=D1=89=D0= =B8=D0=B5 =D1=83=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D0=B5=D0=BD=D0=B8=D1=8E * =D0=A1=D0=B1=D0=BE=D1=80 =D0=B8 = =D0=B0=D0=BD=D0=B0=D0=BB=D0=B8=D0=B7 = =D0=B8=D0=BD=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=86=D0=B8=D0=B8 =D0=BE = =D1=84=D0=B8=D0=B7=D0=B8=D1=87=D0=B5=D1=81=D0=BA=D0=BE=D0=BC = =D0=BB=D0=B8=D1=86=D0=B5. = =D0=A4=D0=BE=D1=80=D0=BC=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5 = =D0=BC=D0=B0=D1=82=D0=B5=D1=80=D0=B8=D0=B0=D0=BB=D0=BE=D0=B2 =D0=B8 = =D0=B4=D0=BE=D1=81=D1=8C=D0=B5 =D0=BD=D0=B0 =D1=81=D0=BE=D1=82=D1=80=D1=83=D0=B4=D0=BD=D0=B8=D0=BA=D0=B0, = =D0=BF=D0=BE=D0=B7=D0=B2=D0=BE=D0=BB=D1=8F=D1=8E=D1=89=D0=B8=D0=B5 = =D1=83=D0=B1=D0=B5=D0=B4=D0=B8=D1=82=D1=8C =D0=B5=D0=B3=D0=BE = =D1=83=D0=B2=D0=BE=D0=BB=D0=B8=D1=82=D1=8C=D1=81=D1=8F. = =D0=9F=D1=80=D0=BE=D0=B2=D0=BE=D0=BA=D0=B0=D1=86=D0=B8=D0=BE=D0=BD=D0=BD=D1= =8B=D0=B5 = =D0=BC=D0=B5=D1=80=D0=BE=D0=BF=D1=80=D0=B8=D1=8F=D1=82=D0=B8=D1=8F = =D0=B2 =D0=BA=D0=B0=D0=B4=D1=80=D0=BE=D0=B2=D0=BE=D0=B9 =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B5 6. =D0=A3=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D1=8F=D0=B5=D0=BC = =D0=B7=D0=B0 =D0=BF=D1=80=D0=BE=D0=B3=D1=83=D0=BB.=20 7. =D0=A3=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D1=8F=D0=B5=D0=BC = =D0=B7=D0=B0 = =D0=B0=D0=BB=D0=BA=D0=BE=D0=B3=D0=BE=D0=BB=D1=8C=D0=BD=D0=BE=D0=B5 = =D0=BE=D0=BF=D1=8C=D1=8F=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5. 8. =D0=A3=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=B7=D0=B0 = =D1=80=D0=B0=D0=B7=D0=B3=D0=BB=D0=B0=D1=88=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=BA=D0=BE=D0=BC=D0=BC=D0=B5=D1=80=D1=87=D0=B5=D1=81=D0=BA=D0=BE=D0=B9 = =D1=82=D0=B0=D0=B9=D0=BD=D1=8B =D0=B8 = =D0=BF=D0=B5=D1=80=D1=81=D0=BE=D0=BD=D0=B0=D0=BB=D1=8C=D0=BD=D1=8B=D1=85 = =D0=B4=D0=B0=D0=BD=D0=BD=D1=8B=D1=85.=20 9. =D0=A1=D1=83=D0=B4=D0=B5=D0=B1=D0=BD=D0=B0=D1=8F = =D0=BF=D1=80=D0=B0=D0=BA=D1=82=D0=B8=D0=BA=D0=B0 = =D1=80=D0=B0=D0=B7=D1=80=D0=B5=D1=88=D0=B5=D0=BD=D0=B8=D1=8F = =D1=82=D1=80=D1=83=D0=B4=D0=BE=D0=B2=D1=8B=D1=85 = =D0=BA=D0=BE=D0=BD=D1=84=D0=BB=D0=B8=D0=BA=D1=82=D0=BE=D0=B2 = =D1=81=D0=B2=D1=8F=D0=B7=D0=B0=D0=BD=D0=BD=D1=8B=D1=85 =D1=81 = =D0=A3=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5=D0=BC.=20 10. =D0=A3=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=B1=D0=B5=D1=80=D0=B5=D0=BC=D0=B5=D0=BD=D0=BD=D1=8B=D1=85 = =D0=B6=D0=B5=D0=BD=D1=89=D0=B8=D0=BD, = =D1=80=D1=83=D0=BA=D0=BE=D0=B2=D0=BE=D0=B4=D0=B8=D1=82=D0=B5=D0=BB=D0=B5=D0= =B9 =D0=BE=D1=80=D0=B3=D0=B0=D0=BD=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D0=B9, = =D1=81=D0=BE=D0=B2=D0=BC=D0=B5=D1=81=D1=82=D0=B8=D1=82=D0=B5=D0=BB=D0=B5=D0= =B9, = =D0=B8=D0=BD=D0=BE=D1=81=D1=82=D1=80=D0=B0=D0=BD=D0=BD=D1=8B=D1=85 = =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BD=D0=B8=D0=BA=D0=BE=D0=B2: = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D0=BD=D1=8B=D0=B5 = =D0=BF=D1=80=D0=BE=D1=86=D0=B5=D0=B4=D1=83=D1=80=D1=8B = =D1=80=D0=B0=D1=81=D1=82=D0=BE=D1=80=D0=B6=D0=B5=D0=BD=D0=B8=D1=8F = =D0=B4=D0=BE=D0=B3=D0=BE=D0=B2=D0=BE=D1=80=D0=B0.=20 11. =D0=A2=D1=80=D1=83=D0=B4=D0=BE=D0=B2=D1=8B=D0=B5 = =D1=81=D0=BF=D0=BE=D1=80=D1=8B: * =D0=92 =D1=81=D0=B2=D1=8F=D0=B7=D0=B8 =D1=81 = =D0=B8=D1=81=D1=82=D0=B5=D1=87=D0=B5=D0=BD=D0=B8=D0=B5=D0=BC = =D1=81=D1=80=D0=BE=D0=BA=D0=B0 = =D1=82=D1=80=D1=83=D0=B4=D0=BE=D0=B2=D0=BE=D0=B3=D0=BE = =D0=B4=D0=BE=D0=B3=D0=BE=D0=B2=D0=BE=D1=80=D0=B0 * =D0=A1=D0=B2=D1=8F=D0=B7=D0=B0=D0=BD=D0=BD=D1=8B=D0=B5 =D1=81 = =D1=83=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5=D0=BC = =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BD=D0=B8=D0=BA=D0=B0 =D0=BF=D0=BE = =D1=81=D0=BE=D0=B1=D1=81=D1=82=D0=B2=D0=B5=D0=BD=D0=BD=D0=BE=D0=BC=D1=83 = =D0=B6=D0=B5=D0=BB=D0=B0=D0=BD=D0=B8=D1=8E * =D0=A1=D0=B2=D1=8F=D0=B7=D0=B0=D0=BD=D0=BD=D1=8B=D0=B5 =D1=81 = =D1=83=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5=D0=BC = =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BD=D0=B8=D0=BA=D0=B0 =D0=B7=D0=B0 = =D0=BF=D1=80=D0=BE=D0=B3=D1=83=D0=BB * =D0=A1=D0=B2=D1=8F=D0=B7=D0=B0=D0=BD=D0=BD=D1=8B=D0=B5 =D1=81 = =D1=83=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5=D0=BC = =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BD=D0=B8=D0=BA=D0=B0 =D0=B7=D0=B0 = =D0=BF=D0=BE=D1=8F=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5 =D0=BD=D0=B0 = =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B5 =D0=B2 = =D1=81=D0=BE=D1=81=D1=82=D0=BE=D1=8F=D0=BD=D0=B8=D0=B8 = =D0=B0=D0=BB=D0=BA=D0=BE=D0=B3=D0=BE=D0=BB=D1=8C=D0=BD=D0=BE=D0=B3=D0=BE,= =D0=B8=D0=BB=D0=B8 = =D0=BD=D0=B0=D1=80=D0=BA=D0=BE=D1=82=D0=B8=D1=87=D0=B5=D1=81=D0=BA=D0=BE=D0= =B3=D0=BE =D0=BE=D0=BF=D1=8C=D1=8F=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F * =D0=92 =D1=81=D0=B2=D1=8F=D0=B7=D0=B8 =D1=81 = =D1=80=D0=B0=D1=81=D1=82=D0=BE=D1=80=D0=B6=D0=B5=D0=BD=D0=B8=D0=B5=D0=BC = =D1=82=D1=80=D1=83=D0=B4=D0=BE=D0=B2=D0=BE=D0=B3=D0=BE = =D0=B4=D0=BE=D0=B3=D0=BE=D0=B2=D0=BE=D1=80=D0=B0 =D0=BF=D0=BE = =D0=BF=D1=80=D0=B8=D1=87=D0=B8=D0=BD=D0=B5 = =D0=BD=D0=B5=D0=BE=D0=B4=D0=BD=D0=BE=D0=BA=D1=80=D0=B0=D1=82=D0=BD=D0=BE=D0= =B3=D0=BE = =D0=BD=D0=B5=D0=B8=D1=81=D0=BF=D0=BE=D0=BB=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BD=D0=B8=D0=BA=D0=BE=D0=BC = =D1=82=D1=80=D1=83=D0=B4=D0=BE=D0=B2=D1=8B=D1=85 = =D0=BE=D0=B1=D1=8F=D0=B7=D0=B0=D0=BD=D0=BD=D0=BE=D1=81=D1=82=D0=B5=D0=B9 = (=D0=BF.5 =D1=81=D1=82.81 =D0=A2=D0=9A =D0=A0=D0=A4) * =D0=92 =D1=81=D0=B2=D1=8F=D0=B7=D0=B8 =D1=81 = =D0=BD=D0=B5=D1=83=D0=B4=D0=BE=D0=B2=D0=BB=D0=B5=D1=82=D0=B2=D0=BE=D1=80=D0= =B8=D1=82=D0=B5=D0=BB=D1=8C=D0=BD=D1=8B=D0=BC = =D1=80=D0=B5=D0=B7=D1=83=D0=BB=D1=8C=D1=82=D0=B0=D1=82=D0=BE=D0=BC = =D0=B8=D1=81=D0=BF=D1=8B=D1=82=D0=B0=D0=BD=D0=B8=D1=8F = =D0=BF=D1=80=D0=B8 =D0=BF=D1=80=D0=B8=D0=B5=D0=BC=D0=B5 =D0=BD=D0=B0 = =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=83 * =D0=92 =D1=81=D0=B2=D1=8F=D0=B7=D0=B8 = =D1=83=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5=D0=BC = =D0=BF=D0=BE = =D1=81=D0=BE=D0=B3=D0=BB=D0=B0=D1=88=D0=B5=D0=BD=D0=B8=D1=8E = =D1=81=D1=82=D0=BE=D1=80=D0=BE=D0=BD * =D0=92 =D1=81=D0=B2=D1=8F=D0=B7=D0=B8 = =D1=83=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5=D0=BC = =D0=BF=D0=BE = =D1=81=D0=BE=D0=BA=D1=80=D0=B0=D1=89=D0=B5=D0=BD=D0=B8=D1=8E = =D1=88=D1=82=D0=B0=D1=82=D0=B0 =D0=B8 = =D1=87=D0=B8=D1=81=D0=BB=D0=B5=D0=BD=D0=BD=D0=BE=D1=81=D1=82=D0=B8 = =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BD=D0=B8=D0=BA=D0=BE=D0=B2 =D0=A2=D0=9E=D0=9F-10 =D0=BE=D1=88=D0=B8=D0=B1=D0=BE=D0=BA = =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BE=D0=B4=D0=B0=D1=82=D0=B5=D0=BB=D0=B5=D0= =B9 =D0=BF=D1=80=D0=B8 = =D1=83=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D0=B5=D0=BD=D0=B8=D0=B8.=20 =20 - - - =D0=A3=D1=87=D0=B0=D1=81=D1=82=D0=B8=D0=B5 =D0=B2 = =D0=B4=D0=B0=D0=BD=D0=BD=D0=BE=D0=BC = =D0=BE=D0=B1=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D0=B8 = =D1=81=D0=BE=D1=81=D1=82=D0=B0=D0=B2=D0=B8=D1=82: 11 800 = =D1=80=D1=83=D0=B1. =D0=9F=D0=BE=D1=81=D0=BB=D0=B5 = =D0=BE=D0=BA=D0=BE=D0=BD=D1=87=D0=B0=D0=BD=D0=B8=D1=8F = =D0=B7=D0=B0=D0=BD=D1=8F=D1=82=D0=B8=D1=8F =D0=92=D0=B0=D0=BC = =D0=B2=D1=8B=D0=B4=D0=B0=D0=B5=D1=82=D1=81=D1=8F =D0=BD=D0=B0=D1=88 = =D1=81=D0=B5=D1=80=D1=82=D0=B8=D1=84=D0=B8=D0=BA=D0=B0=D1=82. =D0=92 = =D0=BC=D0=B5=D1=80=D0=BE=D0=BF=D1=80=D0=B8=D1=8F=D1=82=D0=B8=D0=B5 = =D0=B2=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D0=BE: = =D0=BC=D0=B5=D1=82=D0=BE=D0=B4=D0=B8=D1=87=D0=B5=D1=81=D0=BA=D0=B8=D0=B9 = =D0=BC=D0=B0=D1=82=D0=B5=D1=80=D0=B8=D0=B0=D0=BB, = =D0=BE=D0=B1=D0=B5=D0=B4=D1=8B, = =D0=BA=D0=BE=D1=84=D0=B5-=D0=BF=D0=B0=D1=83=D0=B7=D1=8B. =D0=98=D0=BD=D0=BE=D0=B3=D0=BE=D1=80=D0=BE=D0=B4=D0=BD=D0=B8=D0=BC = =D1=83=D1=87=D0=B0=D1=81=D1=82=D0=BD=D0=B8=D0=BA=D0=B0=D0=BC = =D0=BF=D0=BE=D0=BC=D0=BE=D0=B3=D0=B0=D0=B5=D0=BC =D0=B2 = =D0=B1=D1=80=D0=BE=D0=BD=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B8 = =D0=B3=D0=BE=D1=81=D1=82=D0=B8=D0=BD=D0=B8=D1=86=D1=8B. =20 =20 ------=_NextPart_000_003C_01D1161E.4D8421B0 Content-Type: text/html; charset="utf-8" Content-Transfer-Encoding: quoted-printable
                   

=D0=A3=D1=87=D0=B5=D0=B1=D0=BD=D1=8B=D0=B9 = =D1=86=D0=B5=D0=BD=D1=82=D1=80 = =D0=BF=D1=80=D0=B8=D0=B3=D0=BB=D0=B0=D1=88=D0=B0=D0=B5=D1=82 = =D0=BD=D0=B0=20 =D0=BE=D0=B1=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D0=B5 =D0=BF=D0=BE = =D1=82=D0=B5=D0=BC=D0=B5:
 

=D0=A3=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=BF=D0=B5=D1=80=D1=81=D0=BE=D0=BD=D0=B0=D0=BB=D0=B0.
=D0=91=D0=B5=D0= =B7=D0=BE=D0=BF=D0=B0=D1=81=D0=BD=D0=BE =D0=B8=20 = =D0=B1=D0=B5=D1=81=D0=BA=D0=BE=D0=BD=D1=84=D0=BB=D0=B8=D0=BA=D1=82=D0=BD=D0= =BE.


=D0=A6=D0=B5=D0=BB=D0=B5=D0=B2=D0=B0=D1=8F = =D0=B0=D1=83=D0=B4=D0=B8=D1=82=D0=BE=D1=80=D0=B8=D1=8F: =
=D0=A0=D1=83=D0=BA=D0=BE=D0=B2=D0=BE=D0=B4=D0=B8=D1=82=D0=B5=D0=BB=D0= =B8 =D0=B8=20 =D1=81=D0=BE=D1=82=D1=80=D1=83=D0=B4=D0=BD=D0=B8=D0=BA=D0=B8 = =D0=BA=D0=B0=D0=B4=D1=80=D0=BE=D0=B2=D1=8B=D1=85 = =D1=81=D0=BB=D1=83=D0=B6=D0=B1, = =D0=B4=D0=B8=D1=80=D0=B5=D0=BA=D1=82=D0=BE=D1=80=D0=B0 = =D0=B8
=D0=BC=D0=B5=D0=BD=D0=B5=D0=B4=D0=B6=D0=B5=D1=80=D1=8B = =D0=BF=D0=BE =D0=BF=D0=B5=D1=80=D1=81=D0=BE=D0=BD=D0=B0=D0=BB=D1=83,=20 =D0=B1=D1=83=D1=85=D0=B3=D0=B0=D0=BB=D1=82=D0=B5=D1=80=D1=8B, = =D1=8E=D1=80=D0=B8=D1=81=D1=82=D1=8B, = =D1=80=D1=83=D0=BA=D0=BE=D0=B2=D0=BE=D0=B4=D0=B8=D1=82=D0=B5=D0=BB=D0=B8 = =D0=BA=D0=BE=D0=BC=D0=BF=D0=B0=D0=BD=D0=B8=D0=B9.
 

           

18 =D0=BD=D0=BE=D1=8F=D0=B1=D1=80=D1=8F = 2015 =D0=B3=D0=BE=D0=B4=D0=B0, =D0=B3=D0=BE=D1=80=D0=BE=D0=B4 = =D0=9C=D0=BE=D1=81=D0=BA=D0=B2=D0=B0 | = (=D0=B0=D1=80=D1=82=D0=B8=D0=BA=D1=83=D0=BB: = 250)

=D0=97=D0=B0=D0=BD=D1=8F=D1=82=D0=B8=D0=B5=20 =D0=BF=D1=80=D0=BE=D0=B2=D0=BE=D0=B4=D0=B8=D1=82=D1=81=D1=8F c = 10:00 =D0=B4=D0=BE 17:30

=D0=90=D0=B4=D1=80=D0=B5=D1=81 = =D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D0=B4=D0=B5=D0=BD=D0=B8=D1=8F = =D0=BC=D0=B5=D1=80=D0=BE=D0=BF=D1=80=D0=B8=D1=8F=D1=82=D0=B8=D1=8F: = =D1=83=D0=BB. = =D0=91=D0=B0=D1=83=D0=BC=D0=B0=D0=BD=D1=81=D0=BA=D0=B0=D1=8F,=20 =D0=B4.6, =D1=81=D1=82=D1=80.2, =D0=91.=D0=A6. "=D0=92=D0=B8=D0=BA=D1=82=D0=BE=D1=80=D0=B8=D1=8F = =D0=9F=D0=BB=D0=B0=D0=B7=D0=B0".

=D0=A3=D0=B7=D0=BD=D0=B0=D1=82=D1=8C= =D0=92=D1=81=D1=8E = =D0=BF=D0=BE=D0=B4=D1=80=D0=BE=D0=B1=D0=BD=D1=83=D1=8E = =D0=B8=D0=BD=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=86=D0=B8=D1=8E =D0=B8=20 =D0=BF=D0=BE=D0=B4=D0=B0=D1=82=D1=8C = =D0=B7=D0=B0=D1=8F=D0=B2=D0=BA=D1=83 =D0=BD=D0=B0 = =D0=BE=D0=B1=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D0=B5 =D0=92=D1=8B = =D0=BC=D0=BE=D0=B6=D0=B5=D1=82=D0=B5 =D0=BF=D0=BE = =D1=82=D0=B5=D0=BB=D0=B5=D1=84=D0=BE=D0=BD=D1=83 :=20

 8  =D0=BA=D0=BE=D0=B4=20 =D0=B3=D0=BE=D1=80=D0=BE=D0=B4=D0=B0  = ( 4 9 5=20 )  =D0=BD=D0=BE=D0=BC=D0=B5=D1=80  7 2 5 -=20 0 4 -=20 4 = 8.

=D0=92=D1=8B =D0=BC=D0=BE=D0=B6=D0=B5=D1=82=D0=B5 = =D1=83=D1=87=D0=B0=D1=81=D1=82=D0=B2=D0=BE=D0=B2=D0=B0=D1=82=D1=8C = =D0=B2 =D0=BE=D0=B1=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D0=B8 = =D0=BA=D0=B0=D0=BA =D0=BE=D1=82 = =D0=BA=D0=BE=D0=BC=D0=BF=D0=B0=D0=BD=D0=B8=D0=B8, =D1=82=D0=B0=D0=BA = =D0=B8 =D0=BA=D0=B0=D0=BA =D1=87=D0=B0=D1=81=D1=82=D0=BD=D0=BE=D0=B5=20 = =D0=BB=D0=B8=D1=86=D0=BE.
(=D0=BF=D0=BE=D0=B6=D0=B0=D0=BB=D1=83=D0=B9=D1= =81=D1=82=D0=B0 =D0=BD=D0=B5 = =D0=BE=D1=82=D0=B2=D0=B5=D1=87=D0=B0=D0=B9=D1=82=D0=B5 =D0=BD=D0=B0 = =D0=BE=D0=B1=D1=80=D0=B0=D1=82=D0=BD=D1=8B=D0=B9 = =D0=B0=D0=B4=D1=80=D0=B5=D1=81=20 = =D1=8D=D0=BB.=D0=BF=D0=BE=D1=87=D1=82=D1=8B)

                          =D0=91=D0=BE=D0=BB=D1=8C=D1=88=D0=B8=D0=BD=D1=81=D1=82=D0=B2=D0=BE= =D1=81=D0=BF=D0=BE=D1=80=D0=BE=D0=B2,=20 =D0=B2=D0=BE=D0=B7=D0=BD=D0=B8=D0=BA=D0=B0=D1=8E=D1=89=D0=B8=D1=85 = =D0=B8=D0=B7 =D1=82=D1=80=D1=83=D0=B4=D0=BE=D0=B2=D1=8B=D1=85 = =D0=BE=D1=82=D0=BD=D0=BE=D1=88=D0=B5=D0=BD=D0=B8=D0=B9, = =D1=81=D0=B2=D1=8F=D0=B7=D0=B0=D0=BD=D0=BE =D1=81 = =D1=83=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5=D0=BC = =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BD=D0=B8=D0=BA=D0=BE=D0=B2,
=D0=B0=20 =D1=82=D0=B0=D0=BA=D0=B6=D0=B5 =D1=81 = =D0=BD=D0=B5=D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D0=BD=D1=8B=D0=BC = =D0=BF=D1=80=D0=B8=D0=B2=D0=BB=D0=B5=D1=87=D0=B5=D0=BD=D0=B8=D0=B5=D0=BC = =D0=B8=D0=BD=D0=BE=D1=81=D1=82=D1=80=D0=B0=D0=BD=D0=BD=D1=8B=D1=85 = =D0=B3=D1=80=D0=B0=D0=B6=D0=B4=D0=B0=D0=BD =D0=BA = =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B5. = =D0=9D=D0=B5=D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D0=BD=D0=BE=D0=B5=20 = =D1=83=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5,
=D0=BF=D0= =BE=D0=BC=D0=B8=D0=BC=D0=BE = =D0=BD=D0=B5=D0=BE=D0=B1=D1=85=D0=BE=D0=B4=D0=B8=D0=BC=D0=BE=D1=81=D1=82=D0= =B8 = =D0=B2=D0=BE=D1=81=D1=81=D1=82=D0=B0=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=D0= =B8=D1=8F =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BD=D0=B8=D0=BA=D0=B0 = =D0=BD=D0=B0 =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B5,=20 =D0=B2=D0=BB=D0=B5=D1=87=D0=B5=D1=82 = =D0=BD=D0=B5=D0=B1=D0=BB=D0=B0=D0=B3=D0=BE=D0=BF=D1=80=D0=B8=D1=8F=D1=82=D0= =BD=D1=8B=D0=B5
=D0=BC=D0=B0=D1=82=D0=B5=D1=80=D0=B8=D0=B0=D0=BB=D1=8C= =D0=BD=D1=8B=D0=B5 =D0=B8 = =D1=80=D0=B5=D0=BF=D1=83=D1=82=D0=B0=D1=86=D0=B8=D0=BE=D0=BD=D0=BD=D1=8B=D0= =B5 =D0=BF=D0=BE=D1=81=D0=BB=D0=B5=D0=B4=D1=81=D1=82=D0=B2=D0=B8=D1=8F = =D0=B4=D0=BB=D1=8F=20 = =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BE=D0=B4=D0=B0=D1=82=D0=B5=D0=BB=D1=8F.= =D0=94=D0=BB=D1=8F =D1=82=D0=BE=D0=B3=D0=BE = =D1=87=D1=82=D0=BE=D0=B1=D1=8B = =D0=B3=D1=80=D0=B0=D0=BC=D0=BE=D1=82=D0=BD=D0=BE
=D1=80=D0=B0=D1=81=D1= =81=D1=82=D0=B0=D1=82=D1=8C=D1=81=D1=8F =D1=81 = =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BD=D0=B8=D0=BA=D0=BE=D0=BC,=20 = =D0=BD=D0=B5=D0=B4=D0=BE=D1=81=D1=82=D0=B0=D1=82=D0=BE=D1=87=D0=BD=D0=BE = =D0=BD=D0=B0=D0=B9=D1=82=D0=B8 =D0=BF=D0=BE=D0=B2=D0=BE=D0=B4 = =D0=B4=D0=BB=D1=8F = =D1=83=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F, = =D0=BD=D0=B5=D0=BE=D0=B1=D1=85=D0=BE=D0=B4=D0=B8=D0=BC=D0=BE = =D1=87=D0=B5=D1=82=D0=BA=D0=BE=D0=B5
=D1=81=D0=BE=D0=B1=D0=BB=D1=8E=D0= =B4=D0=B5=D0=BD=D0=B8=D0=B5=20 = =D1=83=D1=81=D1=82=D0=B0=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=D0=BD=D1=8B=D1= =85 =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D0=BE=D0=BC =D0=BD=D0=BE=D1=80=D0=BC, = =D0=BF=D1=80=D0=BE=D1=86=D0=B5=D0=B4=D1=83=D1=80, = =D1=81=D0=BE=D0=BF=D1=80=D0=BE=D0=B2=D0=BE=D0=B6=D0=B4=D0=B0=D0=B5=D0=BC=D1= =8B=D1=85 =D0=BA=D0=B0=D0=B4=D1=80=D0=BE=D0=B2=D0=BE=D0=B9=20 = =D0=B4=D0=BE=D0=BA=D1=83=D0=BC=D0=B5=D0=BD=D1=82=D0=B0=D1=86=D0=B8=D0=B5=D0= =B9.
=D0=A1=D0=BE=D0=B1=D0=BB=D1=8E=D0=B4=D0=B5=D0=BD=D0=B8=D0=B5 = =D1=83=D1=81=D1=82=D0=B0=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=D0=BD=D1=8B=D1= =85 = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D0=BE=D0=B4=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=D1= =81=D1=82=D0=B2=D0=BE=D0=BC =D0=BD=D0=BE=D1=80=D0=BC =D0=B8=20 =D0=BF=D1=80=D0=BE=D1=86=D0=B5=D0=B4=D1=83=D1=80 = =D0=BF=D1=80=D0=B5=D0=BA=D1=80=D0=B0=D1=89=D0=B5=D0=BD=D0=B8=D1=8F = =D1=82=D1=80=D1=83=D0=B4=D0=BE=D0=B2=D0=BE=D0=B3=D0=BE
=D0=B4=D0=BE=D0= =B3=D0=BE=D0=B2=D0=BE=D1=80=D0=B0 = =D0=BC=D0=B8=D0=BD=D0=B8=D0=BC=D0=B8=D0=B7=D0=B8=D1=80=D1=83=D0=B5=D1=82 = =D0=B2 =D0=B4=D0=B0=D0=BB=D1=8C=D0=BD=D0=B5=D0=B9=D1=88=D0=B5=D0=BC=20 =D1=80=D0=B8=D1=81=D0=BA=D0=B8, = =D1=81=D0=B2=D1=8F=D0=B7=D0=B0=D0=BD=D0=BD=D1=8B=D0=B5 =D1=81 = =D1=82=D1=80=D1=83=D0=B4=D0=BE=D0=B2=D1=8B=D0=BC = =D1=81=D0=BF=D0=BE=D1=80=D0=BE=D0=BC.
                         

=D0=9E=D0=BF=D0=B8=D1=81=D0=B0=D0=BD=D0=B8=D0=B5 = =D0=BF=D1=80=D0=BE=D0=B3=D1=80=D0=B0=D0=BC=D0=BC=D1=8B:

           
1.=20 =D0=A3=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D1=8F=D0=B5=D0=BC = =D1=81=D0=BE=D1=82=D1=80=D1=83=D0=B4=D0=BD=D0=B8=D0=BA=D0=B0 = =D0=B1=D0=B5=D0=B7 = =D0=BF=D1=80=D0=BE=D0=B1=D0=BB=D0=B5=D0=BC.
* =
=D0=A4=D0=BE=D1=80=D0=BC=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8= =D0=B5 = =D0=BF=D1=81=D0=B8=D1=85=D0=BE=D0=BB=D0=BE=D0=B3=D0=B8=D1=87=D0=B5=D1=81=D0= =BA=D0=BE=D0=B3=D0=BE =D0=BF=D0=BE=D1=80=D1=82=D1=80=D0=B5=D1=82=D0=B0=20 = =D1=81=D0=BE=D1=82=D1=80=D1=83=D0=B4=D0=BD=D0=B8=D0=BA=D0=B0
* =D0=9C=D0=B5=D1=82=D0=BE=D0=B4=D1=8B = =D0=B8 =D0=BF=D1=80=D0=B8=D0=B5=D0=BC=D1=8B=20 =D0=BF=D1=81=D0=B8=D1=85=D0=BE=D0=BB=D0=BE=D0=B3=D0=B8=D0=B8, = =D1=81=D0=BF=D0=BE=D1=81=D0=BE=D0=B1=D1=81=D1=82=D0=B2=D1=83=D1=8E=D1=89=D0= =B8=D0=B5 =D1=83=D0=B1=D0=B5=D0=B4=D0=B8=D1=82=D1=8C = =D1=81=D0=BE=D1=82=D1=80=D1=83=D0=B4=D0=BD=D0=B8=D0=BA=D0=B0 = =D1=83=D0=B2=D0=BE=D0=BB=D0=B8=D1=82=D1=8C=D1=81=D1=8F
* = =D0=9A=D0=BE=D0=BD=D1=84=D0=BB=D0=B8=D0=BA=D1=82=D1=8B = =D0=BF=D1=80=D0=B8 = =D1=83=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D0=B5=D0=BD=D0=B8=D0=B8 =D0=B8 = =D0=B1=D0=BE=D1=80=D1=8C=D0=B1=D0=B0=20 = =D0=BA=D0=BE=D0=BC=D0=BF=D1=80=D0=BE=D0=BC=D0=B0=D1=82=D0=BE=D0=B2
* =D0=A7=D1=82=D0=BE = =D1=81=D0=B4=D0=B5=D0=BB=D0=B0=D1=82=D1=8C, = =D1=87=D1=82=D0=BE=D0=B1=D1=8B=20 =D1=81=D0=BE=D1=82=D1=80=D1=83=D0=B4=D0=BD=D0=B8=D0=BA = =D0=BD=D0=B5 =D1=81=D0=BC=D0=BE=D0=B3 = =D0=BF=D0=B5=D1=80=D0=B5=D0=B4=D1=83=D0=BC=D0=B0=D1=82=D1=8C
*=20 =D0=98=D0=BC=D0=B8=D0=B4=D0=B6=D0=B5=D0=B2=D1=8B=D0=B5 = =D0=B0=D1=81=D0=BF=D0=B5=D0=BA=D1=82=D1=8B = =D0=B2=D0=BE=D0=B7=D0=B4=D0=B5=D0=B9=D1=81=D1=82=D0=B2=D0=B8=D1=8F = =D0=BD=D0=B0 = =D1=83=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D1=8F=D1=8E=D1=89=D0=B5=D0=B3=D0=BE=D1= =81=D1=8F = =D1=81=D0=BE=D1=82=D1=80=D1=83=D0=B4=D0=BD=D0=B8=D0=BA=D0=B0
* = =D0=97=D0=B0=D0=BA=D0=BE=D0=BD=D0=BE=D0=B4=D0=B0=D1=82=D0=B5=D0=BB= =D1=8C=D0=BD=D1=8B=D0=B5 =D0=BC=D0=B5=D1=80=D1=8B = =D0=B1=D0=BE=D1=80=D1=8C=D0=B1=D1=8B =D1=81 = =C2=AB=D0=BA=D0=B0=D0=B4=D1=80=D0=BE=D0=B2=D1=8B=D0=BC=20 = =D1=8D=D0=BA=D1=81=D1=82=D1=80=D0=B5=D0=BC=D0=B8=D0=B7=D0=BC=D0=BE=D0=BC=C2= =BB - = =D0=BD=D0=B5=D0=BE=D0=B1=D0=BE=D1=81=D0=BD=D0=BE=D0=B2=D0=B0=D0=BD=D0=BD=D1= =8B=D0=BC=D0=B8 =D0=B6=D0=B0=D0=BB=D0=BE=D0=B1=D0=B0=D0=BC=D0=B8 = =D0=B2
=D1=82=D1=80=D1=83=D0=B4=D0=BE=D0=B2=D1=83=D1=8E = =D0=B8=D0=BD=D1=81=D0=BF=D0=B5=D0=BA=D1=86=D0=B8=D1=8E,=20 =D1=81=D1=83=D0=B4=D0=B5=D0=B1=D0=BD=D1=8B=D0=BC=D0=B8 = =D0=B8=D1=81=D0=BA=D0=B0=D0=BC=D0=B8
2. = =D0=A3=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5=20 =D0=BF=D0=BE = =D1=81=D0=BE=D0=B1=D1=81=D1=82=D0=B2=D0=B5=D0=BD=D0=BD=D0=BE=D0=BC=D1=83 = =D0=B6=D0=B5=D0=BB=D0=B0=D0=BD=D0=B8=D1=8E.
* =D0=A7=D1=82=D0=BE=20 =D0=BD=D1=83=D0=B6=D0=BD=D0=BE =D0=B7=D0=BD=D0=B0=D1=82=D1=8C = =D0=BE =D0=B7=D0=B0=D1=8F=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B8, = =D0=BE=D0=B1 = =D1=83=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D0=B5=D0=BD=D0=B8=D0=B8 = =D0=BF=D1=80=D0=B5=D0=B4=D1=83=D0=BF=D1=80=D0=B5=D0=B6=D0=B4=D0=B5=D0=BD=D0= =B8=D0=B8=20 = =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BE=D0=B4=D0=B0=D1=82=D0=B5=D0=BB=D1=8F<= BR>* = =D0=9E=D1=81=D0=BD=D0=BE=D0=B2=D0=BD=D1=8B=D0=B5 = =D0=B7=D0=B0=D0=B1=D0=BB=D1=83=D0=B6=D0=B4=D0=B5=D0=BD=D0=B8=D1=8F=20 =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BD=D0=B8=D0=BA=D0=BE=D0=B2 = =D0=B8 = =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BE=D0=B4=D0=B0=D1=82=D0=B5=D0=BB=D0=B5=D0= =B9, =D0=BA=D0=B0=D0=BA =D1=81 =D0=BD=D0=B8=D0=BC=D0=B8 = =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=D1=82=D1=8C, = =D1=87=D1=82=D0=BE=D0=B1=D1=8B =D0=BD=D0=B5 = =D0=B4=D0=BE=D0=B2=D0=BE=D0=B4=D0=B8=D1=82=D1=8C
=D0=B4=D0=B5=D0=BB=D0= =B0=20 =D0=B4=D0=BE =D1=81=D1=83=D0=B4=D0=B0
* = =D0=9E=D0=B1=D1=8F=D0=B7=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=D0=BD=D1=8B= =D0=B5 =D0=B8=20 = =D1=80=D0=B5=D0=BA=D0=BE=D0=BC=D0=B5=D0=BD=D0=B4=D1=83=D0=B5=D0=BC=D1=8B=D0= =B5 =D0=BF=D1=80=D0=BE=D1=86=D0=B5=D0=B4=D1=83=D1=80=D1=8B, = =D0=BD=D0=B5=D0=BE=D0=B1=D1=85=D0=BE=D0=B4=D0=B8=D0=BC=D1=8B=D0=B5 = =D0=B4=D0=BE=D0=BA=D1=83=D0=BC=D0=B5=D0=BD=D1=82=D1=8B, = =D1=82=D0=B8=D0=BF=D0=B8=D1=87=D0=BD=D1=8B=D0=B5 = =D0=BE=D1=88=D0=B8=D0=B1=D0=BA=D0=B8 =D0=B8=20 = =D0=B8=D1=85
=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0= =B8=D0=B5, = =D0=BA=D0=BE=D1=80=D1=80=D0=B5=D0=BA=D1=82=D0=B8=D1=80=D0=BE=D0=B2=D0=BA=D0= =B0 =D0=BF=D0=BE=D0=B2=D0=B5=D0=B4=D0=B5=D0=BD=D0=B8=D1=8F = =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BD=D0=B8=D0=BA=D0=B0
* = =D0=92=D1=8B=D0=B4=D0=B0=D1=87=D0=B0 = =D0=B4=D0=BE=D0=BA=D1=83=D0=BC=D0=B5=D0=BD=D1=82=D0=BE=D0=B2 = =D0=BF=D1=80=D0=B8 = =D1=83=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D0=B5=D0=BD=D0=B8=D0=B8
* = =D0=92=D0=BD=D0=BE=D1=81=D0=B8=D0=BC = =D0=B7=D0=B0=D0=BF=D0=B8=D1=81=D1=8C =D0=B2 = =D1=82=D1=80=D1=83=D0=B4=D0=BE=D0=B2=D1=83=D1=8E = =D0=BA=D0=BD=D0=B8=D0=B6=D0=BA=D1=83 = =D0=BF=D1=80=D0=B0=D0=B2=D0=B8=D0=BB=D1=8C=D0=BD=D0=BE,=20 =D0=BF=D0=BE=D1=87=D0=B5=D0=BC=D1=83 = =D0=B2=D0=BE=D0=B7=D0=BD=D0=B8=D0=BA=D0=B0=D1=8E=D1=82 = =D1=81=D0=BB=D0=BE=D0=B6=D0=BD=D0=BE=D1=81=D1=82=D0=B8 =D1=81 = =D0=B2=D0=BD=D0=B5=D1=81=D0=B5=D0=BD=D0=B8=D0=B5=D0=BC
=D0=B7=D0=B0=D0= =BF=D0=B8=D1=81=D0=B5=D0=B9: = =D1=83=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5 = =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BD=D0=B8=D0=BA=D0=B0,=20 =D1=80=D0=B0=D1=81=D1=82=D0=BE=D1=80=D0=B6=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=B8=D0=BB=D0=B8 = =D0=BF=D1=80=D0=B5=D0=BA=D1=80=D0=B0=D1=89=D0=B5=D0=BD=D0=B8=D0=B5 = =D1=82=D1=80=D1=83=D0=B4=D0=BE=D0=B2=D0=BE=D0=B3=D0=BE = =D0=B4=D0=BE=D0=B3=D0=BE=D0=B2=D0=BE=D1=80=D0=B0,
=D0=BA=D0=B0=D0=BA = =D0=BB=D0=B5=D0=B3=D0=BA=D0=BE = =D0=BD=D0=B0=D1=83=D1=87=D0=B8=D1=82=D1=8C=D1=81=D1=8F=20 =D0=BF=D0=B8=D1=81=D0=B0=D1=82=D1=8C = =D0=BF=D1=80=D0=B0=D0=B2=D0=B8=D0=BB=D1=8C=D0=BD=D1=83=D1=8E = =D0=B7=D0=B0=D0=BF=D0=B8=D1=81=D1=8C
*=20 = =D0=9E=D1=84=D0=BE=D1=80=D0=BC=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=BE=D0=BA=D0=BE=D0=BD=D1=87=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=D0=BD=D0=BE=D0= =B3=D0=BE =D1=80=D0=B0=D1=81=D1=87=D0=B5=D1=82=D0=B0
*=20 =D0=98=D1=81=D0=BA=D0=BE=D0=B2=D0=B0=D1=8F = =D0=B4=D0=B0=D0=B2=D0=BD=D0=BE=D1=81=D1=82=D1=8C =D0=BF=D0=BE = =D1=81=D0=BF=D0=BE=D1=80=D0=B0=D0=BC =D0=BE=D0=B1 = =D1=83=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D0=B5=D0=BD=D0=B8=D0=B8
* = =D0=9F=D1=80=D0=BE=D0=B1=D0=BB=D0=B5=D0=BC=D0=BD=D1=8B=D0=B5 = =D0=BC=D0=B5=D1=81=D1=82=D0=B0 =D0=B2=D1=81=D0=B5=D1=85 = =D0=B2=D0=B8=D0=B4=D0=BE=D0=B2=20 = =D1=83=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D0=B5=D0=BD=D0=B8=D0=B9
* =D0=9E=D1=82=D0=BF=D1=83=D1=81=D0=BA = =D1=81 = =D0=BF=D0=BE=D1=81=D0=BB=D0=B5=D0=B4=D1=83=D1=8E=D1=89=D0=B8=D0=BC=20 = =D1=83=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5=D0=BC
= 3. = =D0=A0=D0=B0=D1=81=D1=82=D0=BE=D1=80=D0=B6=D0=B5=D0=BD=D0=B8=D0=B5=20 =D1=82=D1=80=D1=83=D0=B4=D0=BE=D0=B2=D0=BE=D0=B3=D0=BE = =D0=B4=D0=BE=D0=B3=D0=BE=D0=B2=D0=BE=D1=80=D0=B0 =D0=BF=D0=BE = =D1=81=D0=BE=D0=B3=D0=BB=D0=B0=D1=88=D0=B5=D0=BD=D0=B8=D1=8E = =D1=81=D1=82=D0=BE=D1=80=D0=BE=D0=BD: =D0=BD=D0=B0 = =D1=81=D1=82=D1=80=D0=B0=D0=B6=D0=B5 = =D0=B8=D0=BD=D1=82=D0=B5=D1=80=D0=B5=D1=81=D0=BE=D0=B2
    = =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BE=D0=B4=D0=B0=D1=82=D0=B5=D0=BB= =D1=8F.

=D0=9F=D0=BB=D1=8E=D1=81=D1=8B =D0=B8 = =D0=BC=D0=B8=D0=BD=D1=83=D1=81=D1=8B=20 =D0=B4=D0=B0=D0=BD=D0=BD=D0=BE=D0=B3=D0=BE = =D1=83=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F. = =D0=9E=D0=BF=D1=80=D0=B5=D0=B4=D0=B5=D0=BB=D1=8F=D0=B5=D0=BC = =D0=B2=D1=8B=D1=85=D0=BE=D0=B4=D0=BD=D0=BE=D0=B5 = =D0=BF=D0=BE=D1=81=D0=BE=D0=B1=D0=B8=D0=B5 = =D0=B8=D1=81=D1=85=D0=BE=D0=B4=D1=8F =D0=B8=D0=B7=20 = =D0=B8=D0=BD=D1=82=D0=B5=D1=80=D0=B5=D1=81=D0=BE=D0=B2
=D0=BA=D0=BE=D0= =BC=D0=BF=D0=B0=D0=BD=D0=B8=D0=B8
4.=20 =D0=9F=D1=80=D0=B5=D0=BA=D1=80=D0=B0=D1=89=D0=B5=D0=BD=D0=B8=D0=B5 = =D1=82=D1=80=D1=83=D0=B4=D0=BE=D0=B2=D0=BE=D0=B3=D0=BE = =D0=B4=D0=BE=D0=B3=D0=BE=D0=B2=D0=BE=D1=80=D0=B0 =D0=B2 = =D1=81=D0=B2=D1=8F=D0=B7=D0=B8 =D1=81 = =D0=B8=D1=81=D1=82=D0=B5=D1=87=D0=B5=D0=BD=D0=B8=D0=B5=D0=BC = =D1=81=D1=80=D0=BE=D0=BA=D0=B0 =D0=B5=D0=B3=D0=BE=20 = =D0=B4=D0=B5=D0=B9=D1=81=D1=82=D0=B2=D0=B8=D1=8F.
=D0=9F=D0=BE=D1=80= =D1=8F=D0=B4=D0=BE=D0=BA = =D1=80=D0=B0=D1=81=D1=82=D0=BE=D1=80=D0=B6=D0=B5=D0=BD=D0=B8=D1=8F, = =D0=BD=D1=8E=D0=B0=D0=BD=D1=81=D1=8B = =D0=BE=D1=84=D0=BE=D1=80=D0=BC=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F, = =D0=BE=D1=88=D0=B8=D0=B1=D0=BA=D0=B8 = =D0=BA=D0=BE=D1=82=D0=BE=D1=80=D1=8B=D0=B5=20 =D0=BD=D0=B5=D0=BB=D1=8C=D0=B7=D1=8F = =D0=B4=D0=BE=D0=BF=D1=83=D1=81=D0=BA=D0=B0=D1=82=D1=8C
5. = =D0=A0=D0=B0=D1=81=D1=82=D0=BE=D1=80=D0=B6=D0=B5=D0=BD=D0=B8=D0=B5=20 =D1=82=D1=80=D1=83=D0=B4=D0=BE=D0=B2=D0=BE=D0=B3=D0=BE = =D0=B4=D0=BE=D0=B3=D0=BE=D0=B2=D0=BE=D1=80=D0=B0 =D0=B7=D0=B0 = =D0=B4=D0=B8=D1=81=D1=86=D0=B8=D0=BF=D0=BB=D0=B8=D0=BD=D0=B0=D1=80=D0=BD=D1= =8B=D0=B5 =D0=BF=D1=80=D0=BE=D1=81=D1=82=D1=83=D0=BF=D0=BA=D0=B8 = =E2=80=93 = =D0=BE=D1=84=D0=BE=D1=80=D0=BC=D0=BB=D1=8F=D0=B5=D0=BC
    = =D0=BD=D0=B0=D0=BB=D0=BE=D0=B6=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=B2=D0=B7=D1=8B=D1=81=D0=BA=D0=B0=D0=BD=D0=B8=D1=8F = =D0=BF=D1=80=D0=B0=D0=B2=D0=B8=D0=BB=D1=8C=D0=BD=D0=BE.=20

* = =D0=9F=D0=BE=D1=80=D1=8F=D0=B4=D0=BE=D0=BA = =D0=BD=D0=B0=D0=BB=D0=BE=D0=B6=D0=B5=D0=BD=D0=B8=D1=8F =D0=B8=20 =D0=BE=D1=84=D0=BE=D1=80=D0=BC=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F, = =D0=B7=D0=B0=D0=B1=D0=BB=D1=83=D0=B6=D0=B4=D0=B5=D0=BD=D0=B8=D1=8F = =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BE=D0=B4=D0=B0=D1=82=D0=B5=D0=BB=D1=8F = =D0=B8 =D0=B5=D0=B3=D0=BE = =D0=BE=D1=81=D0=BD=D0=BE=D0=B2=D0=BD=D1=8B=D0=B5=20 = =D0=BE=D1=88=D0=B8=D0=B1=D0=BA=D0=B8.
=D0=9F=D0=BE=D0=B4=D0=B3=D0=BE=D1= =82=D0=BE=D0=B2=D0=B8=D1=82=D0=B5=D0=BB=D1=8C=D0=BD=D1=8B=D0=B5 = =D0=BC=D0=B5=D1=80=D0=BE=D0=BF=D1=80=D0=B8=D1=8F=D1=82=D0=B8=D1=8F, = =D0=BF=D1=80=D0=B5=D0=B4=D1=88=D0=B5=D1=81=D1=82=D0=B2=D1=83=D1=8E=D1=89=D0= =B8=D0=B5=20 = =D1=83=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D0=B5=D0=BD=D0=B8=D1=8E
* =D0=A1=D0=B1=D0=BE=D1=80 =D0=B8 = =D0=B0=D0=BD=D0=B0=D0=BB=D0=B8=D0=B7=20 =D0=B8=D0=BD=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=86=D0=B8=D0=B8 = =D0=BE =D1=84=D0=B8=D0=B7=D0=B8=D1=87=D0=B5=D1=81=D0=BA=D0=BE=D0=BC = =D0=BB=D0=B8=D1=86=D0=B5. = =D0=A4=D0=BE=D1=80=D0=BC=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5 = =D0=BC=D0=B0=D1=82=D0=B5=D1=80=D0=B8=D0=B0=D0=BB=D0=BE=D0=B2 =D0=B8 = =D0=B4=D0=BE=D1=81=D1=8C=D0=B5=20 = =D0=BD=D0=B0
=D1=81=D0=BE=D1=82=D1=80=D1=83=D0=B4=D0=BD=D0=B8=D0=BA=D0= =B0, =D0=BF=D0=BE=D0=B7=D0=B2=D0=BE=D0=BB=D1=8F=D1=8E=D1=89=D0=B8=D0=B5 = =D1=83=D0=B1=D0=B5=D0=B4=D0=B8=D1=82=D1=8C =D0=B5=D0=B3=D0=BE = =D1=83=D0=B2=D0=BE=D0=BB=D0=B8=D1=82=D1=8C=D1=81=D1=8F. = =D0=9F=D1=80=D0=BE=D0=B2=D0=BE=D0=BA=D0=B0=D1=86=D0=B8=D0=BE=D0=BD=D0=BD=D1= =8B=D0=B5=20 =D0=BC=D0=B5=D1=80=D0=BE=D0=BF=D1=80=D0=B8=D1=8F=D1=82=D0=B8=D1=8F = =D0=B2 = =D0=BA=D0=B0=D0=B4=D1=80=D0=BE=D0=B2=D0=BE=D0=B9
=D1=80=D0=B0=D0=B1=D0= =BE=D1=82=D0=B5
6. = =D0=A3=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D1=8F=D0=B5=D0=BC =D0=B7=D0=B0 = =D0=BF=D1=80=D0=BE=D0=B3=D1=83=D0=BB.
7. = =D0=A3=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D1=8F=D0=B5=D0=BC =D0=B7=D0=B0 = =D0=B0=D0=BB=D0=BA=D0=BE=D0=B3=D0=BE=D0=BB=D1=8C=D0=BD=D0=BE=D0=B5=20 =D0=BE=D0=BF=D1=8C=D1=8F=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5.
8. = =D0=A3=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=B7=D0=B0=20 =D1=80=D0=B0=D0=B7=D0=B3=D0=BB=D0=B0=D1=88=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=BA=D0=BE=D0=BC=D0=BC=D0=B5=D1=80=D1=87=D0=B5=D1=81=D0=BA=D0=BE=D0=B9 = =D1=82=D0=B0=D0=B9=D0=BD=D1=8B =D0=B8 = =D0=BF=D0=B5=D1=80=D1=81=D0=BE=D0=BD=D0=B0=D0=BB=D1=8C=D0=BD=D1=8B=D1=85 = =D0=B4=D0=B0=D0=BD=D0=BD=D1=8B=D1=85.
9. = =D0=A1=D1=83=D0=B4=D0=B5=D0=B1=D0=BD=D0=B0=D1=8F = =D0=BF=D1=80=D0=B0=D0=BA=D1=82=D0=B8=D0=BA=D0=B0 = =D1=80=D0=B0=D0=B7=D1=80=D0=B5=D1=88=D0=B5=D0=BD=D0=B8=D1=8F = =D1=82=D1=80=D1=83=D0=B4=D0=BE=D0=B2=D1=8B=D1=85=20 =D0=BA=D0=BE=D0=BD=D1=84=D0=BB=D0=B8=D0=BA=D1=82=D0=BE=D0=B2 = =D1=81=D0=B2=D1=8F=D0=B7=D0=B0=D0=BD=D0=BD=D1=8B=D1=85 =D1=81 = =D0=A3=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5=D0=BC. =
10. = =D0=A3=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=B1=D0=B5=D1=80=D0=B5=D0=BC=D0=B5=D0=BD=D0=BD=D1=8B=D1=85 = =D0=B6=D0=B5=D0=BD=D1=89=D0=B8=D0=BD,=20 = =D1=80=D1=83=D0=BA=D0=BE=D0=B2=D0=BE=D0=B4=D0=B8=D1=82=D0=B5=D0=BB=D0=B5=D0= =B9 =D0=BE=D1=80=D0=B3=D0=B0=D0=BD=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D0=B9, = =D1=81=D0=BE=D0=B2=D0=BC=D0=B5=D1=81=D1=82=D0=B8=D1=82=D0=B5=D0=BB=D0=B5=D0= =B9,
        = =D0=B8=D0=BD=D0=BE=D1=81=D1=82=D1=80=D0=B0=D0=BD=D0=BD=D1=8B=D1=85=20 =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BD=D0=B8=D0=BA=D0=BE=D0=B2: = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D0=BD=D1=8B=D0=B5 = =D0=BF=D1=80=D0=BE=D1=86=D0=B5=D0=B4=D1=83=D1=80=D1=8B = =D1=80=D0=B0=D1=81=D1=82=D0=BE=D1=80=D0=B6=D0=B5=D0=BD=D0=B8=D1=8F = =D0=B4=D0=BE=D0=B3=D0=BE=D0=B2=D0=BE=D1=80=D0=B0.
11. = =D0=A2=D1=80=D1=83=D0=B4=D0=BE=D0=B2=D1=8B=D0=B5 = =D1=81=D0=BF=D0=BE=D1=80=D1=8B:

 * =D0=92 = =D1=81=D0=B2=D1=8F=D0=B7=D0=B8 =D1=81 = =D0=B8=D1=81=D1=82=D0=B5=D1=87=D0=B5=D0=BD=D0=B8=D0=B5=D0=BC = =D1=81=D1=80=D0=BE=D0=BA=D0=B0 = =D1=82=D1=80=D1=83=D0=B4=D0=BE=D0=B2=D0=BE=D0=B3=D0=BE=20 =D0=B4=D0=BE=D0=B3=D0=BE=D0=B2=D0=BE=D1=80=D0=B0
 * = =D0=A1=D0=B2=D1=8F=D0=B7=D0=B0=D0=BD=D0=BD=D1=8B=D0=B5 =D1=81=20 =D1=83=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5=D0=BC = =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BD=D0=B8=D0=BA=D0=B0 =D0=BF=D0=BE = =D1=81=D0=BE=D0=B1=D1=81=D1=82=D0=B2=D0=B5=D0=BD=D0=BD=D0=BE=D0=BC=D1=83 = =D0=B6=D0=B5=D0=BB=D0=B0=D0=BD=D0=B8=D1=8E
* = =D0=A1=D0=B2=D1=8F=D0=B7=D0=B0=D0=BD=D0=BD=D1=8B=D0=B5 =D1=81 = =D1=83=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5=D0=BC = =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BD=D0=B8=D0=BA=D0=B0 =D0=B7=D0=B0=20 =D0=BF=D1=80=D0=BE=D0=B3=D1=83=D0=BB
* =D0=A1=D0=B2=D1=8F=D0=B7=D0=B0=D0=BD=D0=BD=D1=8B=D0=B5 = =D1=81 = =D1=83=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5=D0=BC=20 =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BD=D0=B8=D0=BA=D0=B0 = =D0=B7=D0=B0 =D0=BF=D0=BE=D1=8F=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=BD=D0=B0 =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B5 =D0=B2 = =D1=81=D0=BE=D1=81=D1=82=D0=BE=D1=8F=D0=BD=D0=B8=D0=B8 = =D0=B0=D0=BB=D0=BA=D0=BE=D0=B3=D0=BE=D0=BB=D1=8C=D0=BD=D0=BE=D0=B3=D0=BE,= =20 = =D0=B8=D0=BB=D0=B8
=D0=BD=D0=B0=D1=80=D0=BA=D0=BE=D1=82=D0=B8=D1=87=D0= =B5=D1=81=D0=BA=D0=BE=D0=B3=D0=BE = =D0=BE=D0=BF=D1=8C=D1=8F=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F
* =D0=92=20 =D1=81=D0=B2=D1=8F=D0=B7=D0=B8 =D1=81 = =D1=80=D0=B0=D1=81=D1=82=D0=BE=D1=80=D0=B6=D0=B5=D0=BD=D0=B8=D0=B5=D0=BC = =D1=82=D1=80=D1=83=D0=B4=D0=BE=D0=B2=D0=BE=D0=B3=D0=BE = =D0=B4=D0=BE=D0=B3=D0=BE=D0=B2=D0=BE=D1=80=D0=B0 =D0=BF=D0=BE = =D0=BF=D1=80=D0=B8=D1=87=D0=B8=D0=BD=D0=B5 = =D0=BD=D0=B5=D0=BE=D0=B4=D0=BD=D0=BE=D0=BA=D1=80=D0=B0=D1=82=D0=BD=D0=BE=D0= =B3=D0=BE=20 = =D0=BD=D0=B5=D0=B8=D1=81=D0=BF=D0=BE=D0=BB=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F<= BR>=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BD=D0=B8=D0=BA=D0=BE=D0=BC = =D1=82=D1=80=D1=83=D0=B4=D0=BE=D0=B2=D1=8B=D1=85 = =D0=BE=D0=B1=D1=8F=D0=B7=D0=B0=D0=BD=D0=BD=D0=BE=D1=81=D1=82=D0=B5=D0=B9 = (=D0=BF.5 =D1=81=D1=82.81 =D0=A2=D0=9A=20 =D0=A0=D0=A4)
* =D0=92 = =D1=81=D0=B2=D1=8F=D0=B7=D0=B8 =D1=81=20 = =D0=BD=D0=B5=D1=83=D0=B4=D0=BE=D0=B2=D0=BB=D0=B5=D1=82=D0=B2=D0=BE=D1=80=D0= =B8=D1=82=D0=B5=D0=BB=D1=8C=D0=BD=D1=8B=D0=BC = =D1=80=D0=B5=D0=B7=D1=83=D0=BB=D1=8C=D1=82=D0=B0=D1=82=D0=BE=D0=BC = =D0=B8=D1=81=D0=BF=D1=8B=D1=82=D0=B0=D0=BD=D0=B8=D1=8F = =D0=BF=D1=80=D0=B8 =D0=BF=D1=80=D0=B8=D0=B5=D0=BC=D0=B5 =D0=BD=D0=B0 = =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=83
* =D0=92 = =D1=81=D0=B2=D1=8F=D0=B7=D0=B8 = =D1=83=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5=D0=BC = =D0=BF=D0=BE = =D1=81=D0=BE=D0=B3=D0=BB=D0=B0=D1=88=D0=B5=D0=BD=D0=B8=D1=8E=20 =D1=81=D1=82=D0=BE=D1=80=D0=BE=D0=BD
* =D0=92 =D1=81=D0=B2=D1=8F=D0=B7=D0=B8 = =D1=83=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5=D0=BC = =D0=BF=D0=BE=20 =D1=81=D0=BE=D0=BA=D1=80=D0=B0=D1=89=D0=B5=D0=BD=D0=B8=D1=8E = =D1=88=D1=82=D0=B0=D1=82=D0=B0 =D0=B8 = =D1=87=D0=B8=D1=81=D0=BB=D0=B5=D0=BD=D0=BD=D0=BE=D1=81=D1=82=D0=B8 = =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BD=D0=B8=D0=BA=D0=BE=D0=B2
=D0=A2= =D0=9E=D0=9F-10 =D0=BE=D1=88=D0=B8=D0=B1=D0=BE=D0=BA=20 = =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BE=D0=B4=D0=B0=D1=82=D0=B5=D0=BB=D0=B5=D0= =B9 =D0=BF=D1=80=D0=B8 = =D1=83=D0=B2=D0=BE=D0=BB=D1=8C=D0=BD=D0=B5=D0=BD=D0=B8=D0=B8. =
             

- - = -
=D0=A3=D1=87=D0=B0=D1=81=D1=82=D0=B8=D0=B5 =D0=B2 = =D0=B4=D0=B0=D0=BD=D0=BD=D0=BE=D0=BC=20 =D0=BE=D0=B1=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D0=B8 = =D1=81=D0=BE=D1=81=D1=82=D0=B0=D0=B2=D0=B8=D1=82: 11 800 = =D1=80=D1=83=D0=B1.
=D0=9F=D0=BE=D1=81=D0=BB=D0=B5 = =D0=BE=D0=BA=D0=BE=D0=BD=D1=87=D0=B0=D0=BD=D0=B8=D1=8F = =D0=B7=D0=B0=D0=BD=D1=8F=D1=82=D0=B8=D1=8F =D0=92=D0=B0=D0=BC = =D0=B2=D1=8B=D0=B4=D0=B0=D0=B5=D1=82=D1=81=D1=8F =D0=BD=D0=B0=D1=88=20 = =D1=81=D0=B5=D1=80=D1=82=D0=B8=D1=84=D0=B8=D0=BA=D0=B0=D1=82.
=D0=92 = =D0=BC=D0=B5=D1=80=D0=BE=D0=BF=D1=80=D0=B8=D1=8F=D1=82=D0=B8=D0=B5 = =D0=B2=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D0=BE: = =D0=BC=D0=B5=D1=82=D0=BE=D0=B4=D0=B8=D1=87=D0=B5=D1=81=D0=BA=D0=B8=D0=B9 = =D0=BC=D0=B0=D1=82=D0=B5=D1=80=D0=B8=D0=B0=D0=BB, = =D0=BE=D0=B1=D0=B5=D0=B4=D1=8B,=20 = =D0=BA=D0=BE=D1=84=D0=B5-=D0=BF=D0=B0=D1=83=D0=B7=D1=8B.
=D0=98=D0=BD=D0= =BE=D0=B3=D0=BE=D1=80=D0=BE=D0=B4=D0=BD=D0=B8=D0=BC = =D1=83=D1=87=D0=B0=D1=81=D1=82=D0=BD=D0=B8=D0=BA=D0=B0=D0=BC = =D0=BF=D0=BE=D0=BC=D0=BE=D0=B3=D0=B0=D0=B5=D0=BC =D0=B2 = =D0=B1=D1=80=D0=BE=D0=BD=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B8 = = =D0=B3=D0=BE=D1=81=D1=82=D0=B8=D0=BD=D0=B8=D1=86=D1=8B.

                   
------=_NextPart_000_003C_01D1161E.4D8421B0-- From 3zGI4Vg0JAysWOfZPJHSaJKZfNTHPS.JVTeMZVZZ.ZNP.JVT@trix.bounces.google.com Tue Nov 3 01:31:30 2015 Return-Path: <3zGI4Vg0JAysWOfZPJHSaJKZfNTHPS.JVTeMZVZZ.ZNP.JVT@trix.bounces.google.com> X-Spam-Checker-Version: SpamAssassin 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,T_REMOTE_IMAGE 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 89AB17F5F for ; Tue, 3 Nov 2015 01:31:30 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 28891AC002 for ; Mon, 2 Nov 2015 23:31:26 -0800 (PST) X-ASG-Debug-ID: 1446535884-04bdf0330b1ee3d0001-NocioJ Received: from mail-oi0-f71.google.com (mail-oi0-f71.google.com [209.85.218.71]) by cuda.sgi.com with ESMTP id e1mmyMYL6fNEC1AD (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Mon, 02 Nov 2015 23:31:25 -0800 (PST) X-Barracuda-Envelope-From: 3zGI4Vg0JAysWOfZPJHSaJKZfNTHPS.JVTeMZVZZ.ZNP.JVT@trix.bounces.google.com X-Barracuda-Apparent-Source-IP: 209.85.218.71 Received: by oies66 with SMTP id s66so13536839oie.1 for ; Mon, 02 Nov 2015 23:31:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:reply-to:message-id:date:subject:from:to:content-type; bh=yc1FAPKNDDWvCnSyAt8SbpO6EQZZpv2LJ9KzEHqbK0I=; b=YjYTm8+1mWEs6eifudRUKRT+GDCE5frBs6t6AXgOPnP2lXpA1HkpdOzGTeshAXNVwe 4CPl3OLht6Ig+jBOamPDMy0382X6hCwkmby4oFgPgoBP8HeQO/tUo9YjF+kFcpKR5W5q ryN2egsCecjBh9VCP2WZJXpg4ugH6od9FF6sFKuMC90srYQtmA/Mx9RiosJsRA3K1oEQ YF5KzSFaXEZ/+DYi4blwGBUUUJRp9bXL4MxSFugLJl6DfgRT7sPc6J8/0lkLSDP5++mk G/PQIw8rxmf0+Xpt1mKaDt6JjRG3GTOvg+lvQQOcuwPcU0JoKwSU68erovppRoGifbFy ZF+A== MIME-Version: 1.0 X-Received: by 10.182.29.41 with SMTP id g9mt36306844obh.27.1446535884415; Mon, 02 Nov 2015 23:31:24 -0800 (PST) Reply-To: physicaltcdsy@gmail.com X-No-Auto-Attachment: 1 Message-ID: <001a11c200cc8bba2005239de101@google.com> Date: Tue, 03 Nov 2015 07:31:24 +0000 Subject: =?GB2312?B?0+tCMkLVubvhtci0q82zxr3MqLulsrm1xM3iw7O/zbunv6o=?= =?GB2312?B?t6LEo8q9?= From: physicaltcdsy@gmail.com X-ASG-Orig-Subj: =?GB2312?B?0+tCMkLVubvhtci0q82zxr3MqLulsrm1xM3iw7O/zbunv6o=?= =?GB2312?B?t6LEo8q9?= To: xfs@oss.sgi.com Content-Type: multipart/alternative; boundary=001a11c200cc8e42cc05239de123 X-Barracuda-Connect: mail-oi0-f71.google.com[209.85.218.71] X-Barracuda-Start-Time: 1446535884 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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, NO_REAL_NAME X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24062 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 NO_REAL_NAME From: does not include a real name -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 --001a11c200cc8e42cc05239de123 Content-Type: text/plain; charset=GB2312; format=flowed; delsp=yes Content-Transfer-Encoding: base64 MaGi0rvM7MvRy/fJz83yvNLQ0NK1xNrGpcXkv827p9PKz+SjrLDvxPq/qreitb1CMkKhotW5u+HJ z9P2sru1vbXE08XWyr/NDQq7p6GjDQoyoaK439Cn08q8/tOqz/qjrLDvxPq78bXDuPy24NK7ttTS u7jf1srBv9PF1sq/zbun0a/FzKGjDQozoaLIw9PQ0OjH87XEv827p9aqtcDE46Os0bjL2bPJvbvS u9CpvLHQ6Mfzv827p6GjDQo0oaIyNNChyrGyu7zkts/K08a1zca546Ossu7S7Luv06rP+rj4xPq1 xM341b60+MC0uPy24LXEwffBv6GjDQo1oaK497n6u8bSs6Gi0NDStb/Nu6fJ7rbIzdq+8qOsssm5 utDFz6K/7MvZssm8r6GjDQq801EtLVGjujE0Mjg3MDU0OTnD4rfRzqrE+tHdyr7I7bz+uabE3NLU vLDQp7n7oaMNCs7S0tHR+8frxPrM7tC0se21pSDJ+tLi0MvCoW8ooclfockpbyChoyDSqszu0LS0 y7HttaWjrMfrt8POyqO6DQpodHRwczovL2RvY3MuZ29vZ2xlLmNvbS9mb3Jtcy9kLzFsdEJfUjhh QVp3cC1IYlhtLUZVWFNUTmxJMHVRd25iR2M5NV9Bdngzc0J3L3ZpZXdmb3JtP2M9MCZ3PTEmdXNw PW1haWxfZm9ybV9saW5rDQo= --001a11c200cc8e42cc05239de123 Content-Type: text/html; charset=GB2312 Content-Transfer-Encoding: quoted-printable

1=A1=A2=D2=BB=CC=EC=CB=D1=CB=F7=C9= =CF=CD=F2=BC=D2=D0=D0=D2=B5=C4=DA=C6=A5=C5=E4=BF=CD=BB=A7=D3=CA=CF=E4=A3=AC= =B0=EF=C4=FA=BF=AA=B7=A2=B5=BDB2B=A1=A2=D5=B9=BB=E1=C9=CF=D3=F6=B2=BB=B5=BD= =B5=C4=D3=C5=D6=CA=BF=CD=BB=A7=A1=A3
2=A1=A2=B8=DF=D0=A7=D3=CA=BC=FE=D3= =AA=CF=FA=A3=AC=B0=EF=C4=FA=BB=F1=B5=C3=B8=FC=B6=E0=D2=BB=B6=D4=D2=BB=B8=DF= =D6=CA=C1=BF=D3=C5=D6=CA=BF=CD=BB=A7=D1=AF=C5=CC=A1=A3
3=A1=A2=C8=C3=D3= =D0=D0=E8=C7=F3=B5=C4=BF=CD=BB=A7=D6=AA=B5=C0=C4=E3=A3=AC=D1=B8=CB=D9=B3=C9= =BD=BB=D2=BB=D0=A9=BC=B1=D0=E8=C7=F3=BF=CD=BB=A7=A1=A3
4=A1=A224=D0=A1= =CA=B1=B2=BB=BC=E4=B6=CF=CA=D3=C6=B5=CD=C6=B9=E3=A3=AC=B2=EE=D2=EC=BB=AF=D3= =AA=CF=FA=B8=F8=C4=FA=B5=C4=CD=F8=D5=BE=B4=F8=C0=B4=B8=FC=B6=E0=B5=C4=C1=F7= =C1=BF=A1=A3
5=A1=A2=B8=F7=B9=FA=BB=C6=D2=B3=A1=A2=D0=D0=D2=B5=BF=CD=BB= =A7=C9=EE=B6=C8=CD=DA=BE=F2=A3=AC=B2=C9=B9=BA=D0=C5=CF=A2=BF=EC=CB=D9=B2=C9= =BC=AF=A1=A3
=BC=D3Q--Q=A3=BA1428705499=C3=E2=B7=D1=CE=AA=C4=FA=D1=DD=CA= =BE=C8=ED=BC=FE=B9=A6=C4=DC=D2=D4=BC=B0=D0=A7=B9=FB=A1=A3

=C8=E7=B9=FB=C4=FA=CE=DE=B7=A8=B2=E9=BF=B4=BB=F2=CC=E1=BD=BB=B4=CB=B1=ED=B5= =A5=A3=AC=BF=C9=D2=D4=D4=DA Google =B1=ED=B5=A5=D6=D0=CC=EE=D0=B4=A1=A3


<= /html> --001a11c200cc8e42cc05239de123-- From jack@suse.cz Tue Nov 3 03:16:18 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 4F0807F59 for ; Tue, 3 Nov 2015 03:16:18 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 1D03D304032 for ; Tue, 3 Nov 2015 01:16:14 -0800 (PST) X-ASG-Debug-ID: 1446542169-04bdf0330c1f0650001-NocioJ Received: from mx2.suse.de (mx2.suse.de [195.135.220.15]) by cuda.sgi.com with ESMTP id 490BoDgX2pb8eJ1W (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NO) for ; Tue, 03 Nov 2015 01:16:10 -0800 (PST) X-Barracuda-Envelope-From: jack@suse.cz X-Barracuda-Apparent-Source-IP: 195.135.220.15 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id D36CCAC77; Tue, 3 Nov 2015 09:15:50 +0000 (UTC) Received: by quack.suse.cz (Postfix, from userid 1000) id C88488281D; Tue, 3 Nov 2015 10:16:05 +0100 (CET) Date: Tue, 3 Nov 2015 10:16:05 +0100 From: Jan Kara To: Dave Chinner Cc: Brian Foster , ross.zwisler@linux.intel.com, jack@suse.cz, xfs@oss.sgi.com, linux-fsdevel@vger.kernel.org, dan.j.williams@intel.com, linux-nvdimm@lists.01.org Subject: Re: [PATCH 3/6] xfs: Don't use unwritten extents for DAX Message-ID: <20151103091605.GA4063@quack.suse.cz> X-ASG-Orig-Subj: Re: [PATCH 3/6] xfs: Don't use unwritten extents for DAX References: <1445225238-30413-1-git-send-email-david@fromorbit.com> <1445225238-30413-4-git-send-email-david@fromorbit.com> <20151029142950.GE11663@bfoster.bfoster> <20151029233756.GS19199@dastard> <20151030123657.GC54905@bfoster.bfoster> <20151102011433.GW19199@dastard> <20151102141509.GA29346@bfoster.bfoster> <20151102214424.GJ10656@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151102214424.GJ10656@dastard> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: mx2.suse.de[195.135.220.15] X-Barracuda-Start-Time: 1446542169 X-Barracuda-Encrypted: ECDHE-RSA-AES256-SHA X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24064 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Tue 03-11-15 08:44:24, Dave Chinner wrote: > Realistically, dax_clear_blocks() should probably be implemented at > the pmem driver layer through blkdev_issue_zeroout() because all it > does is directly map the sector/len to pfn via bdev_direct_access() > and then zero it - it's a sector based, block device operation. We > don't actually need a special case path for DAX here. Optimisation > of this operation has little to do with the filesystem. Yep. This is actually what I did in ext4 - the block zeroing is using the ext4 block zeroout path which ends up calling blkdev_issue_zeroout(). I didn't want to special-case DAX and figured out that if we want performance, we should implement blkdev_issue_zeroout() efficiently for pmem. After all ext4 uses blkdev_issue_zeroout() in other extent conversion cases where zeroing out is needed. Honza -- Jan Kara SUSE Labs, CR From hoper@free.fr Tue Nov 3 03:49:01 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 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 F19087F59 for ; Tue, 3 Nov 2015 03:49:00 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 7C185AC002 for ; Tue, 3 Nov 2015 01:49:00 -0800 (PST) X-ASG-Debug-ID: 1446544134-04cbb0660d1eb970001-NocioJ Received: from smtp3-g21.free.fr (smtp3-g21.free.fr [212.27.42.3]) by cuda.sgi.com with ESMTP id XBmoA1FrGIBjmBXY (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 01:48:55 -0800 (PST) X-Barracuda-Envelope-From: hoper@free.fr X-Barracuda-Apparent-Source-IP: 212.27.42.3 Received: from zimbra84-e15.priv.proxad.net (unknown [172.20.243.135]) by smtp3-g21.free.fr (Postfix) with ESMTP id E2737A6694 for ; Tue, 3 Nov 2015 10:48:53 +0100 (CET) Date: Tue, 3 Nov 2015 10:48:53 +0100 (CET) From: hoper@free.fr To: xfs@oss.sgi.com Message-ID: <752500470.262252528.1446544133651.JavaMail.root@zimbra84-e15.priv.proxad.net> In-Reply-To: <436040866.262250269.1446544069841.JavaMail.root@zimbra84-e15.priv.proxad.net> Subject: On-disk data for XFS_DINNODE_FMT_EXTENTS MIME-Version: 1.0 X-ASG-Orig-Subj: On-disk data for XFS_DINNODE_FMT_EXTENTS Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-Originating-IP: [90.85.16.234] X-Mailer: Zimbra 7.2.0-GA2598 (ZimbraWebClient - FF3.0 (Linux)/7.2.0-GA2598) X-Authenticated-User: hoper@free.fr X-Barracuda-Connect: smtp3-g21.free.fr[212.27.42.3] X-Barracuda-Start-Time: 1446544134 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=NO_REAL_NAME X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24065 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 NO_REAL_NAME From: does not include a real name Hi, I'm trying to understand how xfs is storing informations, but I guess that my documentation "XFS Filesystem Structure 2nd Edition Revision 2" is quite outdated :( I made an XFS filesystem, then made 60 files in /. # xfs_db -f /root/small xfs_db> inode 128 xfs_db> addr current byte offset 32768, length 256 buffer block 64 (fsbno 8), 8 bbs inode 128, dir inode 128, type inode xfs_db> p core.magic = 0x494e core.mode = 040755 core.version = 2 core.format = 2 (extents) [...] next_unlinked = null u.bmx[0] = [startoff,startblock,blockcount,extentflag] 0:[0,12,1,0] I made a small script in python which retrieve all theases information from disk, except the "12" (location of the X2DB block = 12*4096). From the manuel, and my understanding, this information, 12, should be found just next the di_unlinked. (page 43 on the manuel). But from an hex editor, from addr 32768, I got this : 49 4E 41 ED 02 02 00 00 00 00 00 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 56 37 5D 71 2D 26 3D 0B 56 37 5D 6C 02 78 F1 EC 56 37 5D 6C 02 78 F1 EC 00 00 00 00 00 00 10 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 01 80 00 01 00 00 00 00 00 00 00 00 00 00 00 00 First, 49 4E (IN) that's the begining of the inode core (96 bytes). All informations are here, and match the output of xfs_db. But after next_unlinked (FF FF FF FF here), and until next IN, I can't find any 12 :( Where is it ? Lot's of thanks to anyone that could give me help on this subject. From mw@dermichi.com Tue Nov 3 06:19:07 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 A2D4F7F50 for ; Tue, 3 Nov 2015 06:19:07 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 72FAA304043 for ; Tue, 3 Nov 2015 04:19:04 -0800 (PST) X-ASG-Debug-ID: 1446553134-04bdf0330c1f5950001-NocioJ Received: from firestarter.dermichi.com (firestarter.dermichi.com [194.177.153.153]) by cuda.sgi.com with ESMTP id WUnX2wFuSDkH0i6G (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 04:18:55 -0800 (PST) X-Barracuda-Envelope-From: mw@dermichi.com X-Barracuda-Apparent-Source-IP: 194.177.153.153 Received: from noclinksys.net4you.net ([194.177.153.180] helo=[127.0.0.1]) by firestarter.dermichi.com with esmtpsa (TLSv1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim) (envelope-from ) id 1ZtaY9-0006bx-Ul for xfs@oss.sgi.com; Tue, 03 Nov 2015 13:18:53 +0100 To: xfs@oss.sgi.com From: Michael Weissenbacher Subject: Is it possible to change sunit of log section post-mkfs X-Enigmail-Draft-Status: N1010 X-ASG-Orig-Subj: Is it possible to change sunit of log section post-mkfs Message-ID: <5638A62D.1020802@dermichi.com> Date: Tue, 3 Nov 2015 13:18:53 +0100 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Barracuda-Connect: firestarter.dermichi.com[194.177.153.153] X-Barracuda-Start-Time: 1446553135 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24067 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Hi! I have a XFS file system which lies on a 10-disk RAID-6 device that was created with Chunk Size = 1MiB. On mkfs.xfs time this was - as far as i know - specified with "-d su=1m,sw=8". xfs_info shows the following: meta-data=/dev/sdb1 isize=256 agcount=15, agsize=268435200 blks = sectsz=512 attr=2 data = bsize=4096 blocks=3905945088, imaxpct=5 = sunit=256 swidth=2048 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 Interestingly, the sunit value of the log seems to be incorrect - as it should be 256 too, like the sunit value of the data. I am pretty sure the reason is that the log sunit cannot be 256 blks (=1024KiB) and because of this mkfs.xfs did fall back to the default of 8 blks (=32KiB). I found evidence of this in the following thread: http://oss.sgi.com/archives/xfs/2012-06/msg00431.html What i want to achieve is to set the log sunit to the maximum possible of 64 blks (=256KiB). - Is that even possible without doing mkfs.xfs (and losing all data)? - Would it be an improvement performance-wise? - Would changing to an external log help? tia, Michael From bfoster@redhat.com Tue Nov 3 07:02:53 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 04FEA7F55 for ; Tue, 3 Nov 2015 07:02:53 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id E70938F8035 for ; Tue, 3 Nov 2015 05:02:49 -0800 (PST) X-ASG-Debug-ID: 1446555768-04cb6c7b871da180001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id wzFuyrSAdJah751a (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 05:02:49 -0800 (PST) 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 (Postfix) with ESMTPS id 083B442E5A5; Tue, 3 Nov 2015 13:02:48 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-105.bos.redhat.com [10.18.41.105]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3D2lt1018454; Tue, 3 Nov 2015 08:02:47 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id D73E91201AB; Tue, 3 Nov 2015 08:02:46 -0500 (EST) Date: Tue, 3 Nov 2015 08:02:46 -0500 From: Brian Foster To: Michael Weissenbacher Cc: xfs@oss.sgi.com Subject: Re: Is it possible to change sunit of log section post-mkfs Message-ID: <20151103130246.GA24445@bfoster.bfoster> X-ASG-Orig-Subj: Re: Is it possible to change sunit of log section post-mkfs References: <5638A62D.1020802@dermichi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <5638A62D.1020802@dermichi.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: 1446555768 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Tue, Nov 03, 2015 at 01:18:53PM +0100, Michael Weissenbacher wrote: > Hi! > I have a XFS file system which lies on a 10-disk RAID-6 device that was > created with Chunk Size = 1MiB. > On mkfs.xfs time this was - as far as i know - specified with "-d > su=1m,sw=8". > > xfs_info shows the following: > meta-data=/dev/sdb1 isize=256 agcount=15, > agsize=268435200 blks > = sectsz=512 attr=2 > data = bsize=4096 blocks=3905945088, imaxpct=5 > = sunit=256 swidth=2048 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 > > Interestingly, the sunit value of the log seems to be incorrect - as it > should be 256 too, like the sunit value of the data. I am pretty sure > the reason is that the log sunit cannot be 256 blks (=1024KiB) and > because of this mkfs.xfs did fall back to the default of 8 blks > (=32KiB). I found evidence of this in the following thread: > http://oss.sgi.com/archives/xfs/2012-06/msg00431.html > > What i want to achieve is to set the log sunit to the maximum possible > of 64 blks (=256KiB). > > - Is that even possible without doing mkfs.xfs (and losing all data)? > - Would it be an improvement performance-wise? > - Would changing to an external log help? > I don't believe there's any supported way to do this. Out of curiosity, I just tried an experiment to modify the superblock logsunit via xfs_db and run repair to zero the log. That seemed to work in terms of taking effect on the subsequent mount, but that's certainly not something I would suggest to do in production. Note that mkfs aligns the physical log based on the stripe unit as well, so it wouldn't really have the same effect anyways. Brian > tia, > Michael > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From arnd@arndb.de Tue Nov 3 07:44:13 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 7CDE77F56 for ; Tue, 3 Nov 2015 07:44:13 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 5A2A1304051 for ; Tue, 3 Nov 2015 05:44:10 -0800 (PST) X-ASG-Debug-ID: 1446558246-04cb6c7b841dafd0001-NocioJ Received: from mout.kundenserver.de (mout.kundenserver.de [212.227.17.10]) by cuda.sgi.com with ESMTP id YIEAh1AN3nFlOAkf (version=TLSv1.2 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 05:44:08 -0800 (PST) X-Barracuda-Envelope-From: arnd@arndb.de X-Barracuda-Apparent-Source-IP: 212.227.17.10 Received: from wuerfel.localnet ([134.3.118.24]) by mrelayeu.kundenserver.de (mreue103) with ESMTPSA (Nemesis) id 0Lsw94-1aZqOY2wXK-012b8o; Tue, 03 Nov 2015 14:44:00 +0100 From: Arnd Bergmann To: Dave Chinner Cc: Dave Chinner , Brian Foster , Andreas Gruenbacher , xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Subject: [PATCH] xfs: only modify ACLs if CONFIG_XFS_POSIX_ACL enabled Date: Tue, 03 Nov 2015 14:43:58 +0100 X-ASG-Orig-Subj: [PATCH] xfs: only modify ACLs if CONFIG_XFS_POSIX_ACL enabled Message-ID: <4425824.kIWhRaBxBZ@wuerfel> User-Agent: KMail/4.11.5 (Linux/3.16.0-10-generic; KDE/4.11.5; x86_64; ; ) MIME-Version: 1.0 Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="us-ascii" X-Provags-ID: V03:K0:IKzBcwP+e4iHMXkRDYjfgGZy7Wb2b2rhVV+Nlg4+C3mqxsbmf4d VPZ7lZ+ow3OFUhHf+KvzdBSqdQfFWgOIHRiROQANfFbhDfvehZObEXKjEZxGe9oC1M3mf+Z /I2gkwGNgoHQiozxyEJMVsaTv1JdN4seA9hr696HRovjGMJoP1n3iby/ys7rNEzwfkkMlg5 yZxOV/tMIEcksBVKUmwhw== X-UI-Out-Filterresults: notjunk:1;V01:K0:tR4k5bxNivo=:eeXM01pztZedAqYJJBiRwB HK8mmPhX9QdPR8RjKeQTsHJktvUPP44ehD7eoqTNDYYIGvXc3+qpnfsmjzN0OWafwqkMviXFw v0d3bKDaH6GBkZtDzW5V0tTX8b0w4qRAuLEcmzJf8z7BEk9kFPNGX9VIBo5m3L6P6j/sFKlLN 2pKK+9T3eKjpZXP5pe4dAUlocx0YBxdrvvgZRXEtypyuQsbDMSnGj70Y498fgkNzl0zee20VL u5hwB5NYkT9dHL+kxOteXw7efsnoZbBA3kyavTr18jp7AdNMjoZedJubiti6GfmFXRzBKZWzS tZkSHiBxNVeixfobttTmyP5U8rRlQp3o497RBdggSSY7Ga2kifJmLhPYTNyBIGHSynLIETmM7 kEAhvyW1xXu5C28URylNJ7jusnlz1mguOT0M27pNxtQC4ok0TB3MV90BqCfM5M7X1RJHbYKRl MhcNLE69Z7/hkdG24uUgqJNFrEX/szxBGr/ruB61AuiCEYUZVY70b7alvZi1gGZdXqRklC35/ Gurr6a83Uyv9ZbLAaZuvYdCTa01ZshwIbhidOaQ6gTJDZGLz+Bvch2gv7rzP75aXc8zHKcKUH gbeQYYxpjgmdSZ6RLhAOfnJYkrj6y+UPRlj4yRY2MWUywsjbYTipqMVq7jozkyYTMNbInUW9Z 0gnc99E2qz3HJ0ApCGXBwWe0f1Jab6beXBn0QbEVG+dfsHInikWR5efWiuF7oZ3YWwUYH51AG 0Jrp9TI2qb70GF3P X-Barracuda-Connect: mout.kundenserver.de[212.227.17.10] X-Barracuda-Start-Time: 1446558247 X-Barracuda-Encrypted: DHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24068 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- A recent bug fix added a call to forget_cached_acl(), but that function is not always available, so we can get a build error here: fs/xfs/xfs_xattr.c: In function 'xfs_xattr_set': fs/xfs/xfs_xattr.c:84:4: error: implicit declaration of function 'forget_cached_acl' [-Werror=implicit-function-declaration] This changes the code to use the same #ifdef that we already use to encapsule the existing ACL handling. Signed-off-by: Arnd Bergmann Fixes: 6caa105651cb ("xfs: invalidate cached acl if set directly via xattr") --- This started breaking ARM davinci_all_defconfig today in linux-next diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c index 2e1eb80d5374..6229325abdd3 100644 --- a/fs/xfs/xfs_xattr.c +++ b/fs/xfs/xfs_xattr.c @@ -73,6 +73,7 @@ xfs_xattr_set(struct dentry *dentry, const char *name, const void *value, return xfs_attr_remove(ip, (unsigned char *)name, xflags); error = xfs_attr_set(ip, (unsigned char *)name, (void *)value, size, xflags); +#ifdef CONFIG_XFS_POSIX_ACL /* * Invalidate any cached ACLs if the user has bypassed the ACL * interface. We don't validate the content whatsoever so it is caller @@ -85,6 +86,7 @@ xfs_xattr_set(struct dentry *dentry, const char *name, const void *value, else if (!strncmp(name, SGI_ACL_DEFAULT, strlen(name))) forget_cached_acl(VFS_I(ip), ACL_TYPE_DEFAULT); } +#endif return error; } From agruenba@redhat.com Tue Nov 3 07:48:06 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 5C8747F58 for ; Tue, 3 Nov 2015 07:48:06 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id CC1A5AC002 for ; Tue, 3 Nov 2015 05:48:02 -0800 (PST) X-ASG-Debug-ID: 1446558481-04cb6c7b841db100001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id KROKwXSzHpzNpLph (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 05:48:01 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id EF5CD14CADC; Tue, 3 Nov 2015 13:48:00 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3DlwPV017355; Tue, 3 Nov 2015 08:47:59 -0500 From: Andreas Gruenbacher To: Dave Chinner , xfs@oss.sgi.com Cc: Andreas Gruenbacher Subject: [PATCH] xfs: Fix error path in xfs_get_acl Date: Tue, 3 Nov 2015 14:47:57 +0100 X-ASG-Orig-Subj: [PATCH] xfs: Fix error path in xfs_get_acl Message-Id: <1446558477-21981-1-git-send-email-agruenba@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: 1446558481 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Here is another bugfix patch, previously discussed here: http://oss.sgi.com/archives/xfs/2015-10/msg00295.html Thanks, Andreas Error codes from xfs_attr_get other than -ENOATTR were not properly reported. Fix that. In addition, the declaration of struct xfs_inode in xfs_acl.h isn't needed. Signed-off-by: Andreas Gruenbacher --- fs/xfs/xfs_acl.c | 1 + fs/xfs/xfs_acl.h | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c index 763e365..6bb470f 100644 --- a/fs/xfs/xfs_acl.c +++ b/fs/xfs/xfs_acl.c @@ -163,6 +163,7 @@ xfs_get_acl(struct inode *inode, int type) */ if (error == -ENOATTR) goto out_update_cache; + acl = ERR_PTR(error); goto out; } diff --git a/fs/xfs/xfs_acl.h b/fs/xfs/xfs_acl.h index 75af0a4..52f8255 100644 --- a/fs/xfs/xfs_acl.h +++ b/fs/xfs/xfs_acl.h @@ -20,7 +20,6 @@ struct inode; struct posix_acl; -struct xfs_inode; #ifdef CONFIG_XFS_POSIX_ACL extern struct posix_acl *xfs_get_acl(struct inode *inode, int type); -- 2.5.0 From bfoster@redhat.com Tue Nov 3 07:50:30 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 B8BDE7F5A for ; Tue, 3 Nov 2015 07:50:30 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 4CFC8AC001 for ; Tue, 3 Nov 2015 05:50:30 -0800 (PST) X-ASG-Debug-ID: 1446558629-04bdf033091fa140001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id EH3FPRiYkdEKsTQh (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 05:50:29 -0800 (PST) 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 (Postfix) with ESMTPS id 1B77A8F4EF; Tue, 3 Nov 2015 13:50:29 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-105.bos.redhat.com [10.18.41.105]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3DoSbD000393; Tue, 3 Nov 2015 08:50:28 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id D2E861201AB; Tue, 3 Nov 2015 08:50:27 -0500 (EST) Date: Tue, 3 Nov 2015 08:50:27 -0500 From: Brian Foster To: hoper@free.fr Cc: xfs@oss.sgi.com Subject: Re: On-disk data for XFS_DINNODE_FMT_EXTENTS Message-ID: <20151103135026.GB24445@bfoster.bfoster> X-ASG-Orig-Subj: Re: On-disk data for XFS_DINNODE_FMT_EXTENTS References: <436040866.262250269.1446544069841.JavaMail.root@zimbra84-e15.priv.proxad.net> <752500470.262252528.1446544133651.JavaMail.root@zimbra84-e15.priv.proxad.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <752500470.262252528.1446544133651.JavaMail.root@zimbra84-e15.priv.proxad.net> 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: 1446558629 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Tue, Nov 03, 2015 at 10:48:53AM +0100, hoper@free.fr wrote: > Hi, > > I'm trying to understand how xfs is storing informations, > but I guess that my documentation "XFS Filesystem Structure > 2nd Edition Revision 2" is quite outdated :( > > I made an XFS filesystem, then made 60 files in /. > > # xfs_db -f /root/small > xfs_db> inode 128 > xfs_db> addr > current > byte offset 32768, length 256 > buffer block 64 (fsbno 8), 8 bbs > inode 128, dir inode 128, type inode > xfs_db> p > core.magic = 0x494e > core.mode = 040755 > core.version = 2 > core.format = 2 (extents) > [...] > next_unlinked = null > u.bmx[0] = [startoff,startblock,blockcount,extentflag] 0:[0,12,1,0] > > I made a small script in python which retrieve all theases information from disk, > except the "12" (location of the X2DB block = 12*4096). From the manuel, and my > understanding, this information, 12, should be found just next the di_unlinked. > (page 43 on the manuel). But from an hex editor, from addr 32768, I got this : > > 49 4E 41 ED 02 02 00 00 00 00 00 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 > 56 37 5D 71 2D 26 3D 0B 56 37 5D 6C 02 78 F1 EC 56 37 5D 6C 02 78 F1 EC 00 00 00 00 00 00 10 00 > 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 00 > FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 01 80 00 01 00 00 00 00 00 00 00 00 00 00 00 00 > > First, 49 4E (IN) that's the begining of the inode core (96 bytes). All informations are here, > and match the output of xfs_db. But after next_unlinked (FF FF FF FF here), and until next IN, > I can't find any 12 :( Where is it ? > The extent information is encoded in a format that's not easily interpreted from a raw hex dump. See xfs_iformat_extents() to start: dp = (xfs_bmbt_rec_t *) XFS_DFORK_PTR(dip, whichfork); xfs_validate_extents(ifp, nex, XFS_EXTFMT_INODE(ip)); for (i = 0; i < nex; i++, dp++) { xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, i); ep->l0 = get_unaligned_be64(&dp->l0); ep->l1 = get_unaligned_be64(&dp->l1); } So we start after di_next_unlinked and read in two 64-bit, big endian fields. That data in your dump above is: l0: 0x0000000000000000 l1: 0x0000000001800001 Then, these 64-bit fields have a special encoding themselves to map to actual extent data. From xfs_format.h: /* * Bmap btree record and extent descriptor. * l0:63 is an extent flag (value 1 indicates non-normal). * l0:9-62 are startoff. * l0:0-8 and l1:21-63 are startblock. * l1:0-20 are blockcount. */ We see that l0 is completely zeroed, so we can infer that this is a normal extent and startoff is zero. The block count is l1:0-20, which is 00001b or 1. The start block is (((l0 & 0x1FF) << 43) | (l1 >> 21)), which is: ((0x0 & 0x1FF) << 43) | (0x1800001 >> 21) 0x0 | 0xC = 0xC == 12 See __xfs_bmbt_get_all() for the code that implements this decoding. Brian > Lot's of thanks to anyone that could give me help on this subject. > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From agruenba@redhat.com Tue Nov 3 09:17:42 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 D785B7F5F for ; Tue, 3 Nov 2015 09:17:42 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id C2F36304039 for ; Tue, 3 Nov 2015 07:17:39 -0800 (PST) X-ASG-Debug-ID: 1446563857-04cb6c7b871dda90001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id riErEZ4KOapF7DgB (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:17:38 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 4A0518FAA4; Tue, 3 Nov 2015 15:17:36 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRZQ029477; Tue, 3 Nov 2015 10:17:28 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 00/51] Richacls Date: Tue, 3 Nov 2015 16:16:36 +0100 X-ASG-Orig-Subj: [PATCH v13 00/51] Richacls Message-Id: <1446563847-14005-1-git-send-email-agruenba@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: 1446563858 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Al and all, here is another update of the richacl patch queue. There haven't been any changes or comments on the core patches (patches 1-19) for quite a while, so can those patches please be merged? Changes since the last posting (https://lwn.net/Articles/661934/): * XFS: Access to richacls via the XFS_IOC_ATTRMULTI_BY_HANDLE ioctl has been fixed to work the same way as accessing them via xattrs. (Commit "xfs: Plug memory leak in xfs_attrmulti_attr_set" is queued for mainline, and has been added to here for now to avoid conflicts.) The complete patch queue is available in git form here: git://git.kernel.org/pub/scm/linux/kernel/git/agruen/linux-richacl.git \ richacl-2015-11-03 The richacl user-space utilitites, man pages, and test suite are available here: https://github.com/andreas-gruenbacher/richacl Changes to other user-space packages for richacl are available here: https://github.com/andreas-gruenbacher/coreutils https://github.com/andreas-gruenbacher/e2fsprogs https://github.com/andreas-gruenbacher/xfsprogs-dev https://github.com/andreas-gruenbacher/nfs-utils Please see the richacl homepage for more information: http://www.bestbits.at/richacl/ Thanks, Andreas Andreas Gruenbacher (49): vfs: Add IS_ACL() and IS_RICHACL() tests vfs: Add MAY_CREATE_FILE and MAY_CREATE_DIR permission flags vfs: Add MAY_DELETE_SELF and MAY_DELETE_CHILD permission flags vfs: Make the inode passed to inode_change_ok non-const vfs: Add permission flags for setting file attributes richacl: In-memory representation and helper functions richacl: Permission mapping functions richacl: Compute maximum file masks from an acl richacl: Permission check algorithm vfs: Cache base_acl objects in inodes vfs: Add get_richacl and set_richacl inode operations vfs: Cache richacl in struct inode richacl: Update the file masks in chmod() richacl: Check if an acl is equivalent to a file mode richacl: Create-time inheritance richacl: Automatic Inheritance richacl: xattr mapping functions richacl: Add richacl xattr handler vfs: Add richacl permission checking xfs: Fix error path in xfs_get_acl xfs: Make xfs_set_mode non-static xfs: Change how listxattr generates synthetic attributes xfs: Add richacl support xfs: Plug memory leak in xfs_attrmulti_attr_set xfs: Fix richacl access by ioctl richacl: acl editing helper functions richacl: Move everyone@ aces down the acl richacl: Propagate everyone@ permissions to other aces richacl: Set the owner permissions to the owner mask richacl: Set the other permissions to the other mask richacl: Isolate the owner and group classes richacl: Apply the file masks to a richacl richacl: Create richacl from mode values nfsd: Keep list of acls to dispose of in compoundargs nfsd: Use richacls as internal acl representation nfsd: Add richacl support nfsd: Add support for the v4.1 dacl attribute nfsd: Add support for the MAY_CREATE_{FILE,DIR} permissions richacl: Add support for unmapped identifiers nfsd: Add support for unmapped richace identifiers ext4: Don't allow unmapped identifiers in richacls xfs: Don't allow unmapped identifiers in richacls sunrpc: Allow to demand-allocate pages to encode into sunrpc: Add xdr_init_encode_pages nfs: Fix GETATTR bitmap verification nfs: Remove unused xdr page offsets in getacl/setacl arguments nfs: Distinguish missing users and groups from nobody nfs: Add richacl support nfs: Add support for the v4.1 dacl attribute Aneesh Kumar K.V (2): ext4: Add richacl support ext4: Add richacl feature flag drivers/staging/lustre/lustre/llite/llite_lib.c | 2 +- fs/Kconfig | 9 + fs/Makefile | 3 + fs/attr.c | 81 ++- fs/ext4/Kconfig | 11 + fs/ext4/Makefile | 1 + fs/ext4/ext4.h | 6 +- fs/ext4/file.c | 3 + fs/ext4/ialloc.c | 11 +- fs/ext4/inode.c | 12 +- fs/ext4/namei.c | 5 + fs/ext4/richacl.c | 145 ++++ fs/ext4/richacl.h | 40 ++ fs/ext4/super.c | 49 +- fs/ext4/xattr.c | 7 + fs/f2fs/acl.c | 4 +- fs/inode.c | 15 +- fs/jffs2/acl.c | 6 +- fs/namei.c | 111 ++- fs/nfs/inode.c | 3 - fs/nfs/nfs4idmap.c | 57 +- fs/nfs/nfs4proc.c | 734 ++++++++++++++----- fs/nfs/nfs4xdr.c | 261 ++++++- fs/nfs/super.c | 4 +- fs/nfs_common/Makefile | 1 + fs/nfs_common/nfs4acl.c | 44 ++ fs/nfsd/Kconfig | 1 + fs/nfsd/acl.h | 23 +- fs/nfsd/nfs4acl.c | 487 +++++++------ fs/nfsd/nfs4proc.c | 25 +- fs/nfsd/nfs4xdr.c | 268 ++++--- fs/nfsd/nfsd.h | 6 +- fs/nfsd/nfsfh.c | 8 +- fs/nfsd/vfs.c | 28 +- fs/nfsd/vfs.h | 17 +- fs/nfsd/xdr4.h | 12 +- fs/posix_acl.c | 26 +- fs/richacl_base.c | 685 ++++++++++++++++++ fs/richacl_compat.c | 915 ++++++++++++++++++++++++ fs/richacl_inode.c | 333 +++++++++ fs/richacl_xattr.c | 345 +++++++++ fs/xattr.c | 34 +- fs/xfs/Kconfig | 1 + fs/xfs/Makefile | 1 + fs/xfs/libxfs/xfs_format.h | 11 +- fs/xfs/xfs_acl.c | 42 +- fs/xfs/xfs_acl.h | 5 - fs/xfs/xfs_inode.c | 24 + fs/xfs/xfs_inode.h | 2 + fs/xfs/xfs_ioctl.c | 32 +- fs/xfs/xfs_iops.c | 44 +- fs/xfs/xfs_richacl.c | 151 ++++ fs/xfs/xfs_richacl.h | 26 + fs/xfs/xfs_super.c | 6 +- fs/xfs/xfs_super.h | 4 + fs/xfs/xfs_xattr.c | 170 ++--- include/linux/fs.h | 51 +- include/linux/nfs4.h | 24 +- include/linux/nfs4acl.h | 7 + include/linux/nfs_fs.h | 1 - include/linux/nfs_fs_sb.h | 3 + include/linux/nfs_xdr.h | 13 +- include/linux/posix_acl.h | 12 +- include/linux/richacl.h | 233 ++++++ include/linux/richacl_compat.h | 40 ++ include/linux/richacl_xattr.h | 44 ++ include/linux/sunrpc/xdr.h | 2 + include/uapi/linux/Kbuild | 2 + include/uapi/linux/fs.h | 3 +- include/uapi/linux/nfs4.h | 3 +- include/uapi/linux/richacl.h | 154 ++++ include/uapi/linux/richacl_xattr.h | 44 ++ include/uapi/linux/xattr.h | 2 + net/sunrpc/xdr.c | 34 + 74 files changed, 5159 insertions(+), 870 deletions(-) create mode 100644 fs/ext4/richacl.c create mode 100644 fs/ext4/richacl.h create mode 100644 fs/nfs_common/nfs4acl.c create mode 100644 fs/richacl_base.c create mode 100644 fs/richacl_compat.c create mode 100644 fs/richacl_inode.c create mode 100644 fs/richacl_xattr.c create mode 100644 fs/xfs/xfs_richacl.c create mode 100644 fs/xfs/xfs_richacl.h create mode 100644 include/linux/nfs4acl.h create mode 100644 include/linux/richacl.h create mode 100644 include/linux/richacl_compat.h create mode 100644 include/linux/richacl_xattr.h create mode 100644 include/uapi/linux/richacl.h create mode 100644 include/uapi/linux/richacl_xattr.h -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:17:49 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 E97337F6B for ; Tue, 3 Nov 2015 09:17:48 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 6643EAC008 for ; Tue, 3 Nov 2015 07:17:45 -0800 (PST) X-ASG-Debug-ID: 1446563863-04cbb0660d1f7b00001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id WilLEcWL5OzCbCSA (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:17:43 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 2641D8535A; Tue, 3 Nov 2015 15:17:43 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRZR029477; Tue, 3 Nov 2015 10:17:36 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 01/51] vfs: Add IS_ACL() and IS_RICHACL() tests Date: Tue, 3 Nov 2015 16:16:37 +0100 X-ASG-Orig-Subj: [PATCH v13 01/51] vfs: Add IS_ACL() and IS_RICHACL() tests Message-Id: <1446563847-14005-2-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446563863 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 The vfs does not apply the umask for file systems that support acls. The test used for this used to be called IS_POSIXACL(). Switch to a new IS_ACL() test to check for either posix acls or richacls instead. Add a new MS_RICHACL flag and IS_RICHACL() test for richacls alone. The IS_POSIXACL() test is still needed by nfsd. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/Kconfig | 3 +++ fs/namei.c | 8 ++++---- include/linux/fs.h | 12 ++++++++++++ include/uapi/linux/fs.h | 3 ++- 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/fs/Kconfig b/fs/Kconfig index da3f32f..bff2879 100644 --- a/fs/Kconfig +++ b/fs/Kconfig @@ -56,6 +56,9 @@ endif # BLOCK config FS_POSIX_ACL def_bool n +config FS_RICHACL + def_bool n + config EXPORTFS tristate diff --git a/fs/namei.c b/fs/namei.c index 33e9495..224ecf1 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -2798,7 +2798,7 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry, } mode = op->mode; - if ((open_flag & O_CREAT) && !IS_POSIXACL(dir)) + if ((open_flag & O_CREAT) && !IS_ACL(dir)) mode &= ~current_umask(); excl = (open_flag & (O_EXCL | O_CREAT)) == (O_EXCL | O_CREAT); @@ -2982,7 +2982,7 @@ static int lookup_open(struct nameidata *nd, struct path *path, /* Negative dentry, just create the file */ if (!dentry->d_inode && (op->open_flag & O_CREAT)) { umode_t mode = op->mode; - if (!IS_POSIXACL(dir->d_inode)) + if (!IS_ACL(dir->d_inode)) mode &= ~current_umask(); /* * This write is needed to ensure that a @@ -3553,7 +3553,7 @@ retry: if (IS_ERR(dentry)) return PTR_ERR(dentry); - if (!IS_POSIXACL(path.dentry->d_inode)) + if (!IS_ACL(path.dentry->d_inode)) mode &= ~current_umask(); error = security_path_mknod(&path, dentry, mode, dev); if (error) @@ -3622,7 +3622,7 @@ retry: if (IS_ERR(dentry)) return PTR_ERR(dentry); - if (!IS_POSIXACL(path.dentry->d_inode)) + if (!IS_ACL(path.dentry->d_inode)) mode &= ~current_umask(); error = security_path_mkdir(&path, dentry, mode); if (!error) diff --git a/include/linux/fs.h b/include/linux/fs.h index 72d8a84..4efa435 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1781,6 +1781,12 @@ struct super_operations { #define IS_IMMUTABLE(inode) ((inode)->i_flags & S_IMMUTABLE) #define IS_POSIXACL(inode) __IS_FLG(inode, MS_POSIXACL) +#ifdef CONFIG_FS_RICHACL +#define IS_RICHACL(inode) __IS_FLG(inode, MS_RICHACL) +#else +#define IS_RICHACL(inode) 0 +#endif + #define IS_DEADDIR(inode) ((inode)->i_flags & S_DEAD) #define IS_NOCMTIME(inode) ((inode)->i_flags & S_NOCMTIME) #define IS_SWAPFILE(inode) ((inode)->i_flags & S_SWAPFILE) @@ -1794,6 +1800,12 @@ struct super_operations { (inode)->i_rdev == WHITEOUT_DEV) /* + * IS_ACL() tells the VFS to not apply the umask + * and use check_acl for acl permission checks when defined. + */ +#define IS_ACL(inode) __IS_FLG(inode, MS_POSIXACL | MS_RICHACL) + +/* * Inode state bits. Protected by inode->i_lock * * Three bits determine the dirty state of the inode, I_DIRTY_SYNC, diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h index 9b964a5..6ac6bc9 100644 --- a/include/uapi/linux/fs.h +++ b/include/uapi/linux/fs.h @@ -81,7 +81,7 @@ struct inodes_stat_t { #define MS_VERBOSE 32768 /* War is peace. Verbosity is silence. MS_VERBOSE is deprecated. */ #define MS_SILENT 32768 -#define MS_POSIXACL (1<<16) /* VFS does not apply the umask */ +#define MS_POSIXACL (1<<16) /* Supports POSIX ACLs */ #define MS_UNBINDABLE (1<<17) /* change to unbindable */ #define MS_PRIVATE (1<<18) /* change to private */ #define MS_SLAVE (1<<19) /* change to slave */ @@ -91,6 +91,7 @@ struct inodes_stat_t { #define MS_I_VERSION (1<<23) /* Update inode I_version field */ #define MS_STRICTATIME (1<<24) /* Always perform atime updates */ #define MS_LAZYTIME (1<<25) /* Update the on-disk [acm]times lazily */ +#define MS_RICHACL (1<<26) /* Supports richacls */ /* These sb flags are internal to the kernel */ #define MS_NOSEC (1<<28) -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:17:52 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 386FC7F6F for ; Tue, 3 Nov 2015 09:17:52 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 06100304053 for ; Tue, 3 Nov 2015 07:17:52 -0800 (PST) X-ASG-Debug-ID: 1446563870-04bdf0330a1fc860001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id dEMoKAIlLATKHF2N (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:17:50 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 30BEFC0D61A1; Tue, 3 Nov 2015 15:17:50 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRZS029477; Tue, 3 Nov 2015 10:17:43 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 02/51] vfs: Add MAY_CREATE_FILE and MAY_CREATE_DIR permission flags Date: Tue, 3 Nov 2015 16:16:38 +0100 X-ASG-Orig-Subj: [PATCH v13 02/51] vfs: Add MAY_CREATE_FILE and MAY_CREATE_DIR permission flags Message-Id: <1446563847-14005-3-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446563870 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Richacls distinguish between creating non-directories and directories. To support that, add an isdir parameter to may_create(). When checking inode_permission() for create permission, pass in an additional MAY_CREATE_FILE or MAY_CREATE_DIR mask flag. To allow checking for delete *and* create access when replacing an existing file via vfs_rename(), add a replace parameter to may_delete(). Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/namei.c | 43 +++++++++++++++++++++++++------------------ include/linux/fs.h | 2 ++ 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 224ecf1..0259392 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -453,7 +453,9 @@ static int sb_permission(struct super_block *sb, struct inode *inode, int mask) * this, letting us set arbitrary permissions for filesystem access without * changing the "normal" UIDs which are used for other things. * - * When checking for MAY_APPEND, MAY_WRITE must also be set in @mask. + * MAY_WRITE must be set in @mask whenever MAY_APPEND, MAY_CREATE_FILE, or + * MAY_CREATE_DIR are set. That way, file systems that don't support these + * permissions will check for MAY_WRITE instead. */ int inode_permission(struct inode *inode, int mask) { @@ -2549,10 +2551,11 @@ EXPORT_SYMBOL(__check_sticky); * 10. We don't allow removal of NFS sillyrenamed files; it's handled by * nfs_async_unlink(). */ -static int may_delete(struct inode *dir, struct dentry *victim, bool isdir) +static int may_delete(struct inode *dir, struct dentry *victim, + bool isdir, bool replace) { struct inode *inode = d_backing_inode(victim); - int error; + int error, mask = MAY_WRITE | MAY_EXEC; if (d_is_negative(victim)) return -ENOENT; @@ -2561,7 +2564,9 @@ static int may_delete(struct inode *dir, struct dentry *victim, bool isdir) BUG_ON(victim->d_parent->d_inode != dir); audit_inode_child(dir, victim, AUDIT_TYPE_CHILD_DELETE); - error = inode_permission(dir, MAY_WRITE | MAY_EXEC); + if (replace) + mask |= isdir ? MAY_CREATE_DIR : MAY_CREATE_FILE; + error = inode_permission(dir, mask); if (error) return error; if (IS_APPEND(dir)) @@ -2592,14 +2597,16 @@ static int may_delete(struct inode *dir, struct dentry *victim, bool isdir) * 3. We should have write and exec permissions on dir * 4. We can't do it if dir is immutable (done in permission()) */ -static inline int may_create(struct inode *dir, struct dentry *child) +static inline int may_create(struct inode *dir, struct dentry *child, bool isdir) { + int mask = isdir ? MAY_CREATE_DIR : MAY_CREATE_FILE; + audit_inode_child(dir, child, AUDIT_TYPE_CHILD_CREATE); if (child->d_inode) return -EEXIST; if (IS_DEADDIR(dir)) return -ENOENT; - return inode_permission(dir, MAY_WRITE | MAY_EXEC); + return inode_permission(dir, MAY_WRITE | MAY_EXEC | mask); } /* @@ -2649,7 +2656,7 @@ EXPORT_SYMBOL(unlock_rename); int vfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool want_excl) { - int error = may_create(dir, dentry); + int error = may_create(dir, dentry, false); if (error) return error; @@ -3494,7 +3501,7 @@ EXPORT_SYMBOL(user_path_create); int vfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev) { - int error = may_create(dir, dentry); + int error = may_create(dir, dentry, false); if (error) return error; @@ -3586,7 +3593,7 @@ SYSCALL_DEFINE3(mknod, const char __user *, filename, umode_t, mode, unsigned, d int vfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) { - int error = may_create(dir, dentry); + int error = may_create(dir, dentry, true); unsigned max_links = dir->i_sb->s_max_links; if (error) @@ -3667,7 +3674,7 @@ EXPORT_SYMBOL(dentry_unhash); int vfs_rmdir(struct inode *dir, struct dentry *dentry) { - int error = may_delete(dir, dentry, 1); + int error = may_delete(dir, dentry, true, false); if (error) return error; @@ -3789,7 +3796,7 @@ SYSCALL_DEFINE1(rmdir, const char __user *, pathname) int vfs_unlink(struct inode *dir, struct dentry *dentry, struct inode **delegated_inode) { struct inode *target = dentry->d_inode; - int error = may_delete(dir, dentry, 0); + int error = may_delete(dir, dentry, false, false); if (error) return error; @@ -3923,7 +3930,7 @@ SYSCALL_DEFINE1(unlink, const char __user *, pathname) int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname) { - int error = may_create(dir, dentry); + int error = may_create(dir, dentry, false); if (error) return error; @@ -4006,7 +4013,7 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de if (!inode) return -ENOENT; - error = may_create(dir, new_dentry); + error = may_create(dir, new_dentry, false); if (error) return error; @@ -4194,19 +4201,19 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, if (source == target) return 0; - error = may_delete(old_dir, old_dentry, is_dir); + error = may_delete(old_dir, old_dentry, is_dir, false); if (error) return error; if (!target) { - error = may_create(new_dir, new_dentry); + error = may_create(new_dir, new_dentry, is_dir); } else { new_is_dir = d_is_dir(new_dentry); if (!(flags & RENAME_EXCHANGE)) - error = may_delete(new_dir, new_dentry, is_dir); + error = may_delete(new_dir, new_dentry, is_dir, true); else - error = may_delete(new_dir, new_dentry, new_is_dir); + error = may_delete(new_dir, new_dentry, new_is_dir, true); } if (error) return error; @@ -4469,7 +4476,7 @@ SYSCALL_DEFINE2(rename, const char __user *, oldname, const char __user *, newna int vfs_whiteout(struct inode *dir, struct dentry *dentry) { - int error = may_create(dir, dentry); + int error = may_create(dir, dentry, false); if (error) return error; diff --git a/include/linux/fs.h b/include/linux/fs.h index 4efa435..d6e2330 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -82,6 +82,8 @@ typedef void (dax_iodone_t)(struct buffer_head *bh_map, int uptodate); #define MAY_CHDIR 0x00000040 /* called from RCU mode, don't block */ #define MAY_NOT_BLOCK 0x00000080 +#define MAY_CREATE_FILE 0x00000100 +#define MAY_CREATE_DIR 0x00000200 /* * flags in file.f_mode. Note that FMODE_READ and FMODE_WRITE must correspond -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:18:01 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 ACAF77F6F for ; Tue, 3 Nov 2015 09:18:01 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 6AB628F8035 for ; Tue, 3 Nov 2015 07:17:58 -0800 (PST) X-ASG-Debug-ID: 1446563877-04bdf033091fc880001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id C4TE26lCBXBEMA8h (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:17:57 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id EE90EC100444; Tue, 3 Nov 2015 15:17:56 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRZT029477; Tue, 3 Nov 2015 10:17:50 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 03/51] vfs: Add MAY_DELETE_SELF and MAY_DELETE_CHILD permission flags Date: Tue, 3 Nov 2015 16:16:39 +0100 X-ASG-Orig-Subj: [PATCH v13 03/51] vfs: Add MAY_DELETE_SELF and MAY_DELETE_CHILD permission flags Message-Id: <1446563847-14005-4-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446563877 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Normally, deleting a file requires MAY_WRITE access to the parent directory. With richacls, a file may be deleted with MAY_DELETE_CHILD access to the parent directory or with MAY_DELETE_SELF access to the file. To support that, pass the MAY_DELETE_CHILD mask flag to inode_permission() when checking for delete access inside a directory, and MAY_DELETE_SELF when checking for delete access to a file itelf. The MAY_DELETE_SELF permission overrides the sticky directory check. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/namei.c | 21 ++++++++++++--------- include/linux/fs.h | 2 ++ 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 0259392..2eab19e 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -453,9 +453,9 @@ static int sb_permission(struct super_block *sb, struct inode *inode, int mask) * this, letting us set arbitrary permissions for filesystem access without * changing the "normal" UIDs which are used for other things. * - * MAY_WRITE must be set in @mask whenever MAY_APPEND, MAY_CREATE_FILE, or - * MAY_CREATE_DIR are set. That way, file systems that don't support these - * permissions will check for MAY_WRITE instead. + * MAY_WRITE must be set in @mask whenever MAY_APPEND, MAY_CREATE_FILE, + * MAY_CREATE_DIR, or MAY_DELETE_CHILD are set. That way, file systems that + * don't support these permissions will check for MAY_WRITE instead. */ int inode_permission(struct inode *inode, int mask) { @@ -2555,7 +2555,7 @@ static int may_delete(struct inode *dir, struct dentry *victim, bool isdir, bool replace) { struct inode *inode = d_backing_inode(victim); - int error, mask = MAY_WRITE | MAY_EXEC; + int error, mask = MAY_EXEC; if (d_is_negative(victim)) return -ENOENT; @@ -2565,15 +2565,18 @@ static int may_delete(struct inode *dir, struct dentry *victim, audit_inode_child(dir, victim, AUDIT_TYPE_CHILD_DELETE); if (replace) - mask |= isdir ? MAY_CREATE_DIR : MAY_CREATE_FILE; - error = inode_permission(dir, mask); + mask |= MAY_WRITE | (isdir ? MAY_CREATE_DIR : MAY_CREATE_FILE); + error = inode_permission(dir, mask | MAY_WRITE | MAY_DELETE_CHILD); + if (!error && check_sticky(dir, inode)) + error = -EPERM; + if (error && IS_RICHACL(inode) && + inode_permission(inode, MAY_DELETE_SELF) == 0) + error = 0; if (error) return error; if (IS_APPEND(dir)) return -EPERM; - - if (check_sticky(dir, inode) || IS_APPEND(inode) || - IS_IMMUTABLE(inode) || IS_SWAPFILE(inode)) + if (IS_APPEND(inode) || IS_IMMUTABLE(inode) || IS_SWAPFILE(inode)) return -EPERM; if (isdir) { if (!d_is_dir(victim)) diff --git a/include/linux/fs.h b/include/linux/fs.h index d6e2330..402acd7 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -84,6 +84,8 @@ typedef void (dax_iodone_t)(struct buffer_head *bh_map, int uptodate); #define MAY_NOT_BLOCK 0x00000080 #define MAY_CREATE_FILE 0x00000100 #define MAY_CREATE_DIR 0x00000200 +#define MAY_DELETE_CHILD 0x00000400 +#define MAY_DELETE_SELF 0x00000800 /* * flags in file.f_mode. Note that FMODE_READ and FMODE_WRITE must correspond -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:18:05 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 938BC29DFE for ; Tue, 3 Nov 2015 09:18:05 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 72EFA8F8033 for ; Tue, 3 Nov 2015 07:18:05 -0800 (PST) X-ASG-Debug-ID: 1446563884-04cb6c7b871ddad0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id zTj9fALV573rXpUU (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:18:04 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id D32C5A4507; Tue, 3 Nov 2015 15:18:03 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRZU029477; Tue, 3 Nov 2015 10:17:57 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 04/51] vfs: Make the inode passed to inode_change_ok non-const Date: Tue, 3 Nov 2015 16:16:40 +0100 X-ASG-Orig-Subj: [PATCH v13 04/51] vfs: Make the inode passed to inode_change_ok non-const Message-Id: <1446563847-14005-5-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446563884 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 We will need to call iop->permission and iop->get_acl from inode_change_ok() for additional permission checks, and both take a non-const inode. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/attr.c | 2 +- include/linux/fs.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/attr.c b/fs/attr.c index 6530ced..328be71 100644 --- a/fs/attr.c +++ b/fs/attr.c @@ -28,7 +28,7 @@ * Should be called as the first thing in ->setattr implementations, * possibly after taking additional locks. */ -int inode_change_ok(const struct inode *inode, struct iattr *attr) +int inode_change_ok(struct inode *inode, struct iattr *attr) { unsigned int ia_valid = attr->ia_valid; diff --git a/include/linux/fs.h b/include/linux/fs.h index 402acd7..aab32c8 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2871,7 +2871,7 @@ extern int buffer_migrate_page(struct address_space *, #define buffer_migrate_page NULL #endif -extern int inode_change_ok(const struct inode *, struct iattr *); +extern int inode_change_ok(struct inode *, struct iattr *); extern int inode_newsize_ok(const struct inode *, loff_t offset); extern void setattr_copy(struct inode *inode, const struct iattr *attr); -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:18:12 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 B0AFD29DFE for ; Tue, 3 Nov 2015 09:18:12 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 4C57FAC016 for ; Tue, 3 Nov 2015 07:18:12 -0800 (PST) X-ASG-Debug-ID: 1446563891-04bdf033091fc8d0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 3dIsTMuGNzdJFFrj (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:18:11 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id BE17E4F638; Tue, 3 Nov 2015 15:18:10 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRZV029477; Tue, 3 Nov 2015 10:18:04 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 05/51] vfs: Add permission flags for setting file attributes Date: Tue, 3 Nov 2015 16:16:41 +0100 X-ASG-Orig-Subj: [PATCH v13 05/51] vfs: Add permission flags for setting file attributes Message-Id: <1446563847-14005-6-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446563891 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Richacls support permissions that allow to take ownership of a file, change the file permissions, and set the file timestamps. Support that by introducing new permission mask flags and by checking for those mask flags in inode_change_ok(). Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/attr.c | 79 +++++++++++++++++++++++++++++++++++++++++++++--------- include/linux/fs.h | 3 +++ 2 files changed, 70 insertions(+), 12 deletions(-) diff --git a/fs/attr.c b/fs/attr.c index 328be71..85483e0 100644 --- a/fs/attr.c +++ b/fs/attr.c @@ -17,6 +17,65 @@ #include /** + * inode_extended_permission - permissions beyond read/write/execute + * + * Check for permissions that only richacls can currently grant. + */ +static int inode_extended_permission(struct inode *inode, int mask) +{ + if (!IS_RICHACL(inode)) + return -EPERM; + return inode_permission(inode, mask); +} + +static bool inode_uid_change_ok(struct inode *inode, kuid_t ia_uid) +{ + if (uid_eq(current_fsuid(), inode->i_uid) && + uid_eq(ia_uid, inode->i_uid)) + return true; + if (uid_eq(current_fsuid(), ia_uid) && + inode_extended_permission(inode, MAY_TAKE_OWNERSHIP) == 0) + return true; + if (capable_wrt_inode_uidgid(inode, CAP_CHOWN)) + return true; + return false; +} + +static bool inode_gid_change_ok(struct inode *inode, kgid_t ia_gid) +{ + int in_group = in_group_p(ia_gid); + if (uid_eq(current_fsuid(), inode->i_uid) && + (in_group || gid_eq(ia_gid, inode->i_gid))) + return true; + if (in_group && inode_extended_permission(inode, MAY_TAKE_OWNERSHIP) == 0) + return true; + if (capable_wrt_inode_uidgid(inode, CAP_CHOWN)) + return true; + return false; +} + +/** + * inode_owner_permitted_or_capable + * + * Check for permissions implicitly granted to the owner, like MAY_CHMOD or + * MAY_SET_TIMES. Equivalent to inode_owner_or_capable for file systems + * without support for those permissions. + */ +static bool inode_owner_permitted_or_capable(struct inode *inode, int mask) +{ + struct user_namespace *ns; + + if (uid_eq(current_fsuid(), inode->i_uid)) + return true; + if (inode_extended_permission(inode, mask) == 0) + return true; + ns = current_user_ns(); + if (ns_capable(ns, CAP_FOWNER) && kuid_has_mapping(ns, inode->i_uid)) + return true; + return false; +} + +/** * inode_change_ok - check if attribute changes to an inode are allowed * @inode: inode to check * @attr: attributes to change @@ -47,22 +106,18 @@ int inode_change_ok(struct inode *inode, struct iattr *attr) return 0; /* Make sure a caller can chown. */ - if ((ia_valid & ATTR_UID) && - (!uid_eq(current_fsuid(), inode->i_uid) || - !uid_eq(attr->ia_uid, inode->i_uid)) && - !capable_wrt_inode_uidgid(inode, CAP_CHOWN)) - return -EPERM; + if (ia_valid & ATTR_UID) + if (!inode_uid_change_ok(inode, attr->ia_uid)) + return -EPERM; /* Make sure caller can chgrp. */ - if ((ia_valid & ATTR_GID) && - (!uid_eq(current_fsuid(), inode->i_uid) || - (!in_group_p(attr->ia_gid) && !gid_eq(attr->ia_gid, inode->i_gid))) && - !capable_wrt_inode_uidgid(inode, CAP_CHOWN)) - return -EPERM; + if (ia_valid & ATTR_GID) + if (!inode_gid_change_ok(inode, attr->ia_gid)) + return -EPERM; /* Make sure a caller can chmod. */ if (ia_valid & ATTR_MODE) { - if (!inode_owner_or_capable(inode)) + if (!inode_owner_permitted_or_capable(inode, MAY_CHMOD)) return -EPERM; /* Also check the setgid bit! */ if (!in_group_p((ia_valid & ATTR_GID) ? attr->ia_gid : @@ -73,7 +128,7 @@ int inode_change_ok(struct inode *inode, struct iattr *attr) /* Check for setting the inode time. */ if (ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET | ATTR_TIMES_SET)) { - if (!inode_owner_or_capable(inode)) + if (!inode_owner_permitted_or_capable(inode, MAY_SET_TIMES)) return -EPERM; } diff --git a/include/linux/fs.h b/include/linux/fs.h index aab32c8..ba91a89 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -86,6 +86,9 @@ typedef void (dax_iodone_t)(struct buffer_head *bh_map, int uptodate); #define MAY_CREATE_DIR 0x00000200 #define MAY_DELETE_CHILD 0x00000400 #define MAY_DELETE_SELF 0x00000800 +#define MAY_TAKE_OWNERSHIP 0x00001000 +#define MAY_CHMOD 0x00002000 +#define MAY_SET_TIMES 0x00004000 /* * flags in file.f_mode. Note that FMODE_READ and FMODE_WRITE must correspond -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:18:20 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 3AA3629DF9 for ; Tue, 3 Nov 2015 09:18:20 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id E0DE3304043 for ; Tue, 3 Nov 2015 07:18:19 -0800 (PST) X-ASG-Debug-ID: 1446563897-04bdf033091fc8f0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id ystrGk7ZVjUhAfD2 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:18:17 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id A3B19C0D61B9; Tue, 3 Nov 2015 15:18:17 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRZW029477; Tue, 3 Nov 2015 10:18:11 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 06/51] richacl: In-memory representation and helper functions Date: Tue, 3 Nov 2015 16:16:42 +0100 X-ASG-Orig-Subj: [PATCH v13 06/51] richacl: In-memory representation and helper functions Message-Id: <1446563847-14005-7-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446563897 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 A richacl consists of an NFSv4 acl and an owner, group, and other mask. These three masks correspond to the owner, group, and other file permission bits, but they contain NFSv4 permissions instead of POSIX permissions. Each entry in the NFSv4 acl applies to the file owner (OWNER@), the owning group (GROUP@), everyone (EVERYONE@), or to a specific uid or gid. As in the standard POSIX file permission model, each process is the owner, group, or other file class. A richacl grants a requested access only if the NFSv4 acl in the richacl grants the access (according to the NFSv4 permission check algorithm), and the file mask that applies to the process includes the requested permissions. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/Makefile | 2 + fs/richacl_base.c | 67 ++++++++++++++++ include/linux/richacl.h | 179 +++++++++++++++++++++++++++++++++++++++++++ include/uapi/linux/Kbuild | 1 + include/uapi/linux/richacl.h | 99 ++++++++++++++++++++++++ 5 files changed, 348 insertions(+) create mode 100644 fs/richacl_base.c create mode 100644 include/linux/richacl.h create mode 100644 include/uapi/linux/richacl.h diff --git a/fs/Makefile b/fs/Makefile index f79cf40..fe3e9dd 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -48,6 +48,8 @@ obj-$(CONFIG_COREDUMP) += coredump.o obj-$(CONFIG_SYSCTL) += drop_caches.o obj-$(CONFIG_FHANDLE) += fhandle.o +obj-$(CONFIG_FS_RICHACL) += richacl.o +richacl-y := richacl_base.o obj-y += quota/ diff --git a/fs/richacl_base.c b/fs/richacl_base.c new file mode 100644 index 0000000..c3ec928 --- /dev/null +++ b/fs/richacl_base.c @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2006, 2010 Novell, Inc. + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * 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; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include +#include +#include +#include +#include + +MODULE_LICENSE("GPL"); + +/** + * richacl_alloc - allocate a richacl + * @count: number of entries + */ +struct richacl * +richacl_alloc(int count, gfp_t gfp) +{ + size_t size = sizeof(struct richacl) + count * sizeof(struct richace); + struct richacl *acl = kzalloc(size, gfp); + + if (acl) { + atomic_set(&acl->a_refcount, 1); + acl->a_count = count; + } + return acl; +} +EXPORT_SYMBOL_GPL(richacl_alloc); + +/** + * richacl_clone - create a copy of a richacl + */ +struct richacl * +richacl_clone(const struct richacl *acl, gfp_t gfp) +{ + int count = acl->a_count; + size_t size = sizeof(struct richacl) + count * sizeof(struct richace); + struct richacl *dup = kmalloc(size, gfp); + + if (dup) { + memcpy(dup, acl, size); + atomic_set(&dup->a_refcount, 1); + } + return dup; +} + +/** + * richace_copy - copy an acl entry + */ +void +richace_copy(struct richace *to, const struct richace *from) +{ + memcpy(to, from, sizeof(struct richace)); +} diff --git a/include/linux/richacl.h b/include/linux/richacl.h new file mode 100644 index 0000000..edb8480 --- /dev/null +++ b/include/linux/richacl.h @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2006, 2010 Novell, Inc. + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * 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; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#ifndef __RICHACL_H +#define __RICHACL_H + +#include + +struct richace { + unsigned short e_type; + unsigned short e_flags; + unsigned int e_mask; + union { + kuid_t uid; + kgid_t gid; + unsigned int special; + } e_id; +}; + +struct richacl { + atomic_t a_refcount; + unsigned int a_owner_mask; + unsigned int a_group_mask; + unsigned int a_other_mask; + unsigned short a_count; + unsigned short a_flags; + struct richace a_entries[0]; +}; + +#define richacl_for_each_entry(_ace, _acl) \ + for (_ace = (_acl)->a_entries; \ + _ace != (_acl)->a_entries + (_acl)->a_count; \ + _ace++) + +#define richacl_for_each_entry_reverse(_ace, _acl) \ + for (_ace = (_acl)->a_entries + (_acl)->a_count - 1; \ + _ace != (_acl)->a_entries - 1; \ + _ace--) + +/** + * richacl_get - grab another reference to a richacl handle + */ +static inline struct richacl * +richacl_get(struct richacl *acl) +{ + if (acl) + atomic_inc(&acl->a_refcount); + return acl; +} + +/** + * richacl_put - free a richacl handle + */ +static inline void +richacl_put(struct richacl *acl) +{ + if (acl && atomic_dec_and_test(&acl->a_refcount)) + kfree(acl); +} + +/** + * richace_is_owner - check if @ace is an OWNER@ entry + */ +static inline bool +richace_is_owner(const struct richace *ace) +{ + return (ace->e_flags & RICHACE_SPECIAL_WHO) && + ace->e_id.special == RICHACE_OWNER_SPECIAL_ID; +} + +/** + * richace_is_group - check if @ace is a GROUP@ entry + */ +static inline bool +richace_is_group(const struct richace *ace) +{ + return (ace->e_flags & RICHACE_SPECIAL_WHO) && + ace->e_id.special == RICHACE_GROUP_SPECIAL_ID; +} + +/** + * richace_is_everyone - check if @ace is an EVERYONE@ entry + */ +static inline bool +richace_is_everyone(const struct richace *ace) +{ + return (ace->e_flags & RICHACE_SPECIAL_WHO) && + ace->e_id.special == RICHACE_EVERYONE_SPECIAL_ID; +} + +/** + * richace_is_unix_user - check if @ace applies to a specific user + */ +static inline bool +richace_is_unix_user(const struct richace *ace) +{ + return !(ace->e_flags & RICHACE_SPECIAL_WHO) && + !(ace->e_flags & RICHACE_IDENTIFIER_GROUP); +} + +/** + * richace_is_unix_group - check if @ace applies to a specific group + */ +static inline bool +richace_is_unix_group(const struct richace *ace) +{ + return !(ace->e_flags & RICHACE_SPECIAL_WHO) && + (ace->e_flags & RICHACE_IDENTIFIER_GROUP); +} + +/** + * richace_is_inherit_only - check if @ace is for inheritance only + * + * ACEs with the %RICHACE_INHERIT_ONLY_ACE flag set have no effect during + * permission checking. + */ +static inline bool +richace_is_inherit_only(const struct richace *ace) +{ + return ace->e_flags & RICHACE_INHERIT_ONLY_ACE; +} + +/** + * richace_is_inheritable - check if @ace is inheritable + */ +static inline bool +richace_is_inheritable(const struct richace *ace) +{ + return ace->e_flags & (RICHACE_FILE_INHERIT_ACE | + RICHACE_DIRECTORY_INHERIT_ACE); +} + +/** + * richace_is_allow - check if @ace is an %ALLOW type entry + */ +static inline bool +richace_is_allow(const struct richace *ace) +{ + return ace->e_type == RICHACE_ACCESS_ALLOWED_ACE_TYPE; +} + +/** + * richace_is_deny - check if @ace is a %DENY type entry + */ +static inline bool +richace_is_deny(const struct richace *ace) +{ + return ace->e_type == RICHACE_ACCESS_DENIED_ACE_TYPE; +} + +/** + * richace_is_same_identifier - are both identifiers the same? + */ +static inline bool +richace_is_same_identifier(const struct richace *a, const struct richace *b) +{ + return !((a->e_flags ^ b->e_flags) & + (RICHACE_SPECIAL_WHO | RICHACE_IDENTIFIER_GROUP)) && + !memcmp(&a->e_id, &b->e_id, sizeof(a->e_id)); +} + +extern struct richacl *richacl_alloc(int, gfp_t); +extern struct richacl *richacl_clone(const struct richacl *, gfp_t); +extern void richace_copy(struct richace *, const struct richace *); + +#endif /* __RICHACL_H */ diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild index f7b2db4..8c82010 100644 --- a/include/uapi/linux/Kbuild +++ b/include/uapi/linux/Kbuild @@ -348,6 +348,7 @@ header-y += reboot.h header-y += reiserfs_fs.h header-y += reiserfs_xattr.h header-y += resource.h +header-y += richacl.h header-y += rfkill.h header-y += romfs_fs.h header-y += rose.h diff --git a/include/uapi/linux/richacl.h b/include/uapi/linux/richacl.h new file mode 100644 index 0000000..08856f8 --- /dev/null +++ b/include/uapi/linux/richacl.h @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2006, 2010 Novell, Inc. + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ + +#ifndef __UAPI_RICHACL_H +#define __UAPI_RICHACL_H + +/* a_flags values */ +#define RICHACL_WRITE_THROUGH 0x40 +#define RICHACL_MASKED 0x80 + +/* e_type values */ +#define RICHACE_ACCESS_ALLOWED_ACE_TYPE 0x0000 +#define RICHACE_ACCESS_DENIED_ACE_TYPE 0x0001 + +/* e_flags bitflags */ +#define RICHACE_FILE_INHERIT_ACE 0x0001 +#define RICHACE_DIRECTORY_INHERIT_ACE 0x0002 +#define RICHACE_NO_PROPAGATE_INHERIT_ACE 0x0004 +#define RICHACE_INHERIT_ONLY_ACE 0x0008 +#define RICHACE_IDENTIFIER_GROUP 0x0040 +#define RICHACE_SPECIAL_WHO 0x4000 + +/* e_mask bitflags */ +#define RICHACE_READ_DATA 0x00000001 +#define RICHACE_LIST_DIRECTORY 0x00000001 +#define RICHACE_WRITE_DATA 0x00000002 +#define RICHACE_ADD_FILE 0x00000002 +#define RICHACE_APPEND_DATA 0x00000004 +#define RICHACE_ADD_SUBDIRECTORY 0x00000004 +#define RICHACE_READ_NAMED_ATTRS 0x00000008 +#define RICHACE_WRITE_NAMED_ATTRS 0x00000010 +#define RICHACE_EXECUTE 0x00000020 +#define RICHACE_DELETE_CHILD 0x00000040 +#define RICHACE_READ_ATTRIBUTES 0x00000080 +#define RICHACE_WRITE_ATTRIBUTES 0x00000100 +#define RICHACE_WRITE_RETENTION 0x00000200 +#define RICHACE_WRITE_RETENTION_HOLD 0x00000400 +#define RICHACE_DELETE 0x00010000 +#define RICHACE_READ_ACL 0x00020000 +#define RICHACE_WRITE_ACL 0x00040000 +#define RICHACE_WRITE_OWNER 0x00080000 +#define RICHACE_SYNCHRONIZE 0x00100000 + +/* e_id values */ +#define RICHACE_OWNER_SPECIAL_ID 0 +#define RICHACE_GROUP_SPECIAL_ID 1 +#define RICHACE_EVERYONE_SPECIAL_ID 2 + +#define RICHACL_VALID_FLAGS ( \ + RICHACL_WRITE_THROUGH | \ + RICHACL_MASKED ) + +#define RICHACE_VALID_FLAGS ( \ + RICHACE_FILE_INHERIT_ACE | \ + RICHACE_DIRECTORY_INHERIT_ACE | \ + RICHACE_NO_PROPAGATE_INHERIT_ACE | \ + RICHACE_INHERIT_ONLY_ACE | \ + RICHACE_IDENTIFIER_GROUP | \ + RICHACE_SPECIAL_WHO ) + +#define RICHACE_INHERITANCE_FLAGS ( \ + RICHACE_FILE_INHERIT_ACE | \ + RICHACE_DIRECTORY_INHERIT_ACE | \ + RICHACE_NO_PROPAGATE_INHERIT_ACE | \ + RICHACE_INHERIT_ONLY_ACE ) + +/* Valid RICHACE_* flags for directories and non-directories */ +#define RICHACE_VALID_MASK ( \ + RICHACE_READ_DATA | RICHACE_LIST_DIRECTORY | \ + RICHACE_WRITE_DATA | RICHACE_ADD_FILE | \ + RICHACE_APPEND_DATA | RICHACE_ADD_SUBDIRECTORY | \ + RICHACE_READ_NAMED_ATTRS | \ + RICHACE_WRITE_NAMED_ATTRS | \ + RICHACE_EXECUTE | \ + RICHACE_DELETE_CHILD | \ + RICHACE_READ_ATTRIBUTES | \ + RICHACE_WRITE_ATTRIBUTES | \ + RICHACE_WRITE_RETENTION | \ + RICHACE_WRITE_RETENTION_HOLD | \ + RICHACE_DELETE | \ + RICHACE_READ_ACL | \ + RICHACE_WRITE_ACL | \ + RICHACE_WRITE_OWNER | \ + RICHACE_SYNCHRONIZE ) + +#endif /* __UAPI_RICHACL_H */ -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:18:26 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 C377029DF9 for ; Tue, 3 Nov 2015 09:18:26 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 9022B8F8035 for ; Tue, 3 Nov 2015 07:18:26 -0800 (PST) X-ASG-Debug-ID: 1446563904-04bdf0330b1fc920001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id DENNLT6AJMQL6Fx1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:18:24 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 8D791C0D61BC; Tue, 3 Nov 2015 15:18:24 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRZX029477; Tue, 3 Nov 2015 10:18:18 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 07/51] richacl: Permission mapping functions Date: Tue, 3 Nov 2015 16:16:43 +0100 X-ASG-Orig-Subj: [PATCH v13 07/51] richacl: Permission mapping functions Message-Id: <1446563847-14005-8-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446563904 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 We need to map from POSIX permissions to NFSv4 permissions when a chmod() is done, from NFSv4 permissions to POSIX permissions when an acl is set (which implicitly sets the file permission bits), and from the MAY_READ/MAY_WRITE/MAY_EXEC/MAY_APPEND flags to NFSv4 permissions when doing an access check in a richacl. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_base.c | 118 +++++++++++++++++++++++++++++++++++++++++++ include/linux/richacl.h | 3 ++ include/uapi/linux/richacl.h | 44 ++++++++++++++++ 3 files changed, 165 insertions(+) diff --git a/fs/richacl_base.c b/fs/richacl_base.c index c3ec928..a393001 100644 --- a/fs/richacl_base.c +++ b/fs/richacl_base.c @@ -65,3 +65,121 @@ richace_copy(struct richace *to, const struct richace *from) { memcpy(to, from, sizeof(struct richace)); } + +/* + * richacl_mask_to_mode - compute the file permission bits from mask + * @mask: %RICHACE_* permission mask + * + * Compute the file permission bits corresponding to a particular set of + * richacl permissions. + * + * See richacl_masks_to_mode(). + */ +static int +richacl_mask_to_mode(unsigned int mask) +{ + int mode = 0; + + if (mask & RICHACE_POSIX_MODE_READ) + mode |= S_IROTH; + if (mask & RICHACE_POSIX_MODE_WRITE) + mode |= S_IWOTH; + if (mask & RICHACE_POSIX_MODE_EXEC) + mode |= S_IXOTH; + + return mode; +} + +/** + * richacl_masks_to_mode - compute file permission bits from file masks + * + * When setting a richacl, we set the file permission bits to indicate maximum + * permissions: for example, we set the Write permission when a mask contains + * RICHACE_APPEND_DATA even if it does not also contain RICHACE_WRITE_DATA. + * + * Permissions which are not in RICHACE_POSIX_MODE_READ, + * RICHACE_POSIX_MODE_WRITE, or RICHACE_POSIX_MODE_EXEC cannot be represented + * in the file permission bits. Such permissions can still be effective, but + * not for new files or after a chmod(); they must be explicitly enabled in the + * richacl. + */ +int +richacl_masks_to_mode(const struct richacl *acl) +{ + return richacl_mask_to_mode(acl->a_owner_mask) << 6 | + richacl_mask_to_mode(acl->a_group_mask) << 3 | + richacl_mask_to_mode(acl->a_other_mask); +} +EXPORT_SYMBOL_GPL(richacl_masks_to_mode); + +/** + * richacl_mode_to_mask - compute a file mask from the lowest three mode bits + * @mode: mode to convert to richacl permissions + * + * When the file permission bits of a file are set with chmod(), this specifies + * the maximum permissions that processes will get. All permissions beyond + * that will be removed from the file masks, and become ineffective. + */ +unsigned int +richacl_mode_to_mask(umode_t mode) +{ + unsigned int mask = 0; + + if (mode & S_IROTH) + mask |= RICHACE_POSIX_MODE_READ; + if (mode & S_IWOTH) + mask |= RICHACE_POSIX_MODE_WRITE; + if (mode & S_IXOTH) + mask |= RICHACE_POSIX_MODE_EXEC; + + return mask; +} + +/** + * richacl_want_to_mask - convert the iop->permission want argument to a mask + * @want: @want argument of the permission inode operation + * + * When checking for append, @want is (MAY_WRITE | MAY_APPEND). + * + * Richacls use the iop->may_create and iop->may_delete hooks which are used + * for checking if creating and deleting files is allowed. These hooks do not + * use richacl_want_to_mask(), so we do not have to deal with mapping MAY_WRITE + * to RICHACE_ADD_FILE, RICHACE_ADD_SUBDIRECTORY, and RICHACE_DELETE_CHILD + * here. + */ +unsigned int +richacl_want_to_mask(unsigned int want) +{ + unsigned int mask = 0; + + if (want & MAY_READ) + mask |= RICHACE_READ_DATA; + if (want & MAY_DELETE_SELF) + mask |= RICHACE_DELETE; + if (want & MAY_TAKE_OWNERSHIP) + mask |= RICHACE_WRITE_OWNER; + if (want & MAY_CHMOD) + mask |= RICHACE_WRITE_ACL; + if (want & MAY_SET_TIMES) + mask |= RICHACE_WRITE_ATTRIBUTES; + if (want & MAY_EXEC) + mask |= RICHACE_EXECUTE; + /* + * differentiate MAY_WRITE from these request + */ + if (want & (MAY_APPEND | + MAY_CREATE_FILE | MAY_CREATE_DIR | + MAY_DELETE_CHILD)) { + if (want & MAY_APPEND) + mask |= RICHACE_APPEND_DATA; + if (want & MAY_CREATE_FILE) + mask |= RICHACE_ADD_FILE; + if (want & MAY_CREATE_DIR) + mask |= RICHACE_ADD_SUBDIRECTORY; + if (want & MAY_DELETE_CHILD) + mask |= RICHACE_DELETE_CHILD; + } else if (want & MAY_WRITE) + mask |= RICHACE_WRITE_DATA; + return mask; +} +EXPORT_SYMBOL_GPL(richacl_want_to_mask); diff --git a/include/linux/richacl.h b/include/linux/richacl.h index edb8480..9102ef0 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -175,5 +175,8 @@ richace_is_same_identifier(const struct richace *a, const struct richace *b) extern struct richacl *richacl_alloc(int, gfp_t); extern struct richacl *richacl_clone(const struct richacl *, gfp_t); extern void richace_copy(struct richace *, const struct richace *); +extern int richacl_masks_to_mode(const struct richacl *); +extern unsigned int richacl_mode_to_mask(umode_t); +extern unsigned int richacl_want_to_mask(unsigned int); #endif /* __RICHACL_H */ diff --git a/include/uapi/linux/richacl.h b/include/uapi/linux/richacl.h index 08856f8..1ed48ac 100644 --- a/include/uapi/linux/richacl.h +++ b/include/uapi/linux/richacl.h @@ -96,4 +96,48 @@ RICHACE_WRITE_OWNER | \ RICHACE_SYNCHRONIZE ) +/* + * The POSIX permissions are supersets of the following richacl permissions: + * + * - MAY_READ maps to READ_DATA or LIST_DIRECTORY, depending on the type + * of the file system object. + * + * - MAY_WRITE maps to WRITE_DATA or RICHACE_APPEND_DATA for files, and to + * ADD_FILE, RICHACE_ADD_SUBDIRECTORY, or RICHACE_DELETE_CHILD for directories. + * + * - MAY_EXECUTE maps to RICHACE_EXECUTE. + * + * (Some of these richacl permissions have the same bit values.) + */ +#define RICHACE_POSIX_MODE_READ ( \ + RICHACE_READ_DATA | \ + RICHACE_LIST_DIRECTORY) +#define RICHACE_POSIX_MODE_WRITE ( \ + RICHACE_WRITE_DATA | \ + RICHACE_ADD_FILE | \ + RICHACE_APPEND_DATA | \ + RICHACE_ADD_SUBDIRECTORY | \ + RICHACE_DELETE_CHILD) +#define RICHACE_POSIX_MODE_EXEC RICHACE_EXECUTE +#define RICHACE_POSIX_MODE_ALL ( \ + RICHACE_POSIX_MODE_READ | \ + RICHACE_POSIX_MODE_WRITE | \ + RICHACE_POSIX_MODE_EXEC) + +/* + * These permissions are always allowed no matter what the acl says. + */ +#define RICHACE_POSIX_ALWAYS_ALLOWED ( \ + RICHACE_SYNCHRONIZE | \ + RICHACE_READ_ATTRIBUTES | \ + RICHACE_READ_ACL) + +/* + * The owner is implicitly granted these permissions under POSIX. + */ +#define RICHACE_POSIX_OWNER_ALLOWED ( \ + RICHACE_WRITE_ATTRIBUTES | \ + RICHACE_WRITE_OWNER | \ + RICHACE_WRITE_ACL) + #endif /* __UAPI_RICHACL_H */ -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:18:33 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 7437D29E0D for ; Tue, 3 Nov 2015 09:18:33 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 637B8304043 for ; Tue, 3 Nov 2015 07:18:33 -0800 (PST) X-ASG-Debug-ID: 1446563911-04cbb0660c1f7ba0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 6Erd8fiZLcDAupEQ (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:18:32 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 7D8FE8FAA0; Tue, 3 Nov 2015 15:18:31 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRZY029477; Tue, 3 Nov 2015 10:18:25 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 08/51] richacl: Compute maximum file masks from an acl Date: Tue, 3 Nov 2015 16:16:44 +0100 X-ASG-Orig-Subj: [PATCH v13 08/51] richacl: Compute maximum file masks from an acl Message-Id: <1446563847-14005-9-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446563911 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Compute upper bound owner, group, and other file masks with as few permissions as possible without denying any permissions that the NFSv4 acl in a richacl grants. This algorithm is used when a file inherits an acl at create time and when an acl is set via a mechanism that does not provide file masks (such as setting an acl via nfsd). When user-space sets an acl via setxattr, the extended attribute already includes the file masks. Setting an acl also sets the file mode permission bits: they are determined by the file masks; see richacl_masks_to_mode(). Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_base.c | 157 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/richacl.h | 1 + 2 files changed, 158 insertions(+) diff --git a/fs/richacl_base.c b/fs/richacl_base.c index a393001..69b806c 100644 --- a/fs/richacl_base.c +++ b/fs/richacl_base.c @@ -183,3 +183,160 @@ richacl_want_to_mask(unsigned int want) return mask; } EXPORT_SYMBOL_GPL(richacl_want_to_mask); + +/* + * Note: functions like richacl_allowed_to_who(), richacl_group_class_allowed(), + * and richacl_compute_max_masks() iterate through the entire acl in reverse + * order as an optimization. + * + * In the standard algorithm, aces are considered in forward order. When a + * process matches an ace, the permissions in the ace are either allowed or + * denied depending on the ace type. Once a permission has been allowed or + * denied, it is no longer considered in further aces. + * + * By iterating through the acl in reverse order, we can compute the same + * result without having to keep track of which permissions have been allowed + * and denied already. + */ + +/** + * richacl_allowed_to_who - permissions allowed to a specific who value + * + * Compute the maximum mask values allowed to a specific who value, taking + * everyone@ aces into account. + */ +static unsigned int richacl_allowed_to_who(struct richacl *acl, + struct richace *who) +{ + struct richace *ace; + unsigned int allowed = 0; + + richacl_for_each_entry_reverse(ace, acl) { + if (richace_is_inherit_only(ace)) + continue; + if (richace_is_same_identifier(ace, who) || + richace_is_everyone(ace)) { + if (richace_is_allow(ace)) + allowed |= ace->e_mask; + else if (richace_is_deny(ace)) + allowed &= ~ace->e_mask; + } + } + return allowed; +} + +/** + * richacl_group_class_allowed - maximum permissions of the group class + * + * Compute the maximum mask values allowed to a process in the group class + * (i.e., a process which is not the owner but is in the owning group or + * matches a user or group acl entry). This includes permissions granted or + * denied by everyone@ aces. + * + * See richacl_compute_max_masks(). + */ +static unsigned int richacl_group_class_allowed(struct richacl *acl) +{ + struct richace *ace; + unsigned int everyone_allowed = 0, group_class_allowed = 0; + int had_group_ace = 0; + + richacl_for_each_entry_reverse(ace, acl) { + if (richace_is_inherit_only(ace) || + richace_is_owner(ace)) + continue; + + if (richace_is_everyone(ace)) { + if (richace_is_allow(ace)) + everyone_allowed |= ace->e_mask; + else if (richace_is_deny(ace)) + everyone_allowed &= ~ace->e_mask; + } else { + group_class_allowed |= + richacl_allowed_to_who(acl, ace); + + if (richace_is_group(ace)) + had_group_ace = 1; + } + } + /* + * If the acl doesn't contain any group@ aces, richacl_allowed_to_who() + * wasn't called for the owning group. We could make that call now, but + * we already know the result (everyone_allowed). + */ + if (!had_group_ace) + group_class_allowed |= everyone_allowed; + return group_class_allowed; +} + +/** + * richacl_compute_max_masks - compute upper bound masks + * + * Computes upper bound owner, group, and other masks so that none of the + * permissions allowed by the acl are disabled. + * + * We don't make assumptions about who the owner is so that the owner can + * change with no effect on the file masks or file mode permission bits; this + * means that we must assume that all entries can match the owner. + */ +void richacl_compute_max_masks(struct richacl *acl) +{ + unsigned int gmask = ~0; + struct richace *ace; + + /* + * @gmask contains all permissions which the group class is ever + * allowed. We use it to avoid adding permissions to the group mask + * from everyone@ allow aces which the group class is always denied + * through other aces. For example, the following acl would otherwise + * result in a group mask of rw: + * + * group@:w::deny + * everyone@:rw::allow + * + * Avoid computing @gmask for acls which do not include any group class + * deny aces: in such acls, the group class is never denied any + * permissions from everyone@ allow aces, and the group class cannot + * have fewer permissions than the other class. + */ + +restart: + acl->a_owner_mask = 0; + acl->a_group_mask = 0; + acl->a_other_mask = 0; + + richacl_for_each_entry_reverse(ace, acl) { + if (richace_is_inherit_only(ace)) + continue; + + if (richace_is_owner(ace)) { + if (richace_is_allow(ace)) + acl->a_owner_mask |= ace->e_mask; + else if (richace_is_deny(ace)) + acl->a_owner_mask &= ~ace->e_mask; + } else if (richace_is_everyone(ace)) { + if (richace_is_allow(ace)) { + acl->a_owner_mask |= ace->e_mask; + acl->a_group_mask |= ace->e_mask & gmask; + acl->a_other_mask |= ace->e_mask; + } else if (richace_is_deny(ace)) { + acl->a_owner_mask &= ~ace->e_mask; + acl->a_group_mask &= ~ace->e_mask; + acl->a_other_mask &= ~ace->e_mask; + } + } else { + if (richace_is_allow(ace)) { + acl->a_owner_mask |= ace->e_mask & gmask; + acl->a_group_mask |= ace->e_mask & gmask; + } else if (richace_is_deny(ace) && gmask == ~0) { + gmask = richacl_group_class_allowed(acl); + if (likely(gmask != ~0)) + /* should always be true */ + goto restart; + } + } + } + + acl->a_flags &= ~(RICHACL_WRITE_THROUGH | RICHACL_MASKED); +} +EXPORT_SYMBOL_GPL(richacl_compute_max_masks); diff --git a/include/linux/richacl.h b/include/linux/richacl.h index 9102ef0..3559b2c 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -178,5 +178,6 @@ extern void richace_copy(struct richace *, const struct richace *); extern int richacl_masks_to_mode(const struct richacl *); extern unsigned int richacl_mode_to_mask(umode_t); extern unsigned int richacl_want_to_mask(unsigned int); +extern void richacl_compute_max_masks(struct richacl *); #endif /* __RICHACL_H */ -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:18:41 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 0B94529E0D for ; Tue, 3 Nov 2015 09:18:41 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 78DEDAC002 for ; Tue, 3 Nov 2015 07:18:40 -0800 (PST) X-ASG-Debug-ID: 1446563918-04cbb0660e1f7bc0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id o6BSPpRZB4DsbrPb (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:18:39 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 6B00D8FAA5; Tue, 3 Nov 2015 15:18:38 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRZZ029477; Tue, 3 Nov 2015 10:18:32 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 09/51] richacl: Permission check algorithm Date: Tue, 3 Nov 2015 16:16:45 +0100 X-ASG-Orig-Subj: [PATCH v13 09/51] richacl: Permission check algorithm Message-Id: <1446563847-14005-10-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446563918 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 A richacl roughly grants a requested access if the NFSv4 acl in the richacl grants the requested permissions according to the NFSv4 permission check algorithm and the file mask that applies to the process includes the requested permissions. Signed-off-by: Andreas Gruenbacher Reviewed-by: "J. Bruce Fields" --- fs/Makefile | 2 +- fs/richacl_inode.c | 149 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/richacl.h | 3 + 3 files changed, 153 insertions(+), 1 deletion(-) create mode 100644 fs/richacl_inode.c diff --git a/fs/Makefile b/fs/Makefile index fe3e9dd..ec665fd 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -49,7 +49,7 @@ obj-$(CONFIG_SYSCTL) += drop_caches.o obj-$(CONFIG_FHANDLE) += fhandle.o obj-$(CONFIG_FS_RICHACL) += richacl.o -richacl-y := richacl_base.o +richacl-y := richacl_base.o richacl_inode.o obj-y += quota/ diff --git a/fs/richacl_inode.c b/fs/richacl_inode.c new file mode 100644 index 0000000..99b3c93 --- /dev/null +++ b/fs/richacl_inode.c @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2010 Novell, Inc. + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * 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; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include +#include +#include +#include +#include + +/** + * richacl_permission - richacl permission check algorithm + * @inode: inode to check + * @acl: rich acl of the inode + * @want: requested access (MAY_* flags) + * + * Checks if the current process is granted @mask flags in @acl. + */ +int +richacl_permission(struct inode *inode, const struct richacl *acl, + int want) +{ + const struct richace *ace; + unsigned int mask = richacl_want_to_mask(want); + unsigned int requested = mask, denied = 0; + int in_owning_group = in_group_p(inode->i_gid); + int in_owner_or_group_class = in_owning_group; + + /* + * A process is + * - in the owner file class if it owns the file, + * - in the group file class if it is in the file's owning group or + * it matches any of the user or group entries, and + * - in the other file class otherwise. + * The file class is only relevant for determining which file mask to + * apply, which only happens for masked acls. + */ + if (acl->a_flags & RICHACL_MASKED) { + if ((acl->a_flags & RICHACL_WRITE_THROUGH) && + uid_eq(current_fsuid(), inode->i_uid)) { + denied = requested & ~acl->a_owner_mask; + goto out; + } + } else { + /* + * When the acl is not masked, there is no need to determine if + * the process is in the group class and we can break out + * earlier of the loop below. + */ + in_owner_or_group_class = 1; + } + + /* + * Check if the acl grants the requested access and determine which + * file class the process is in. + */ + richacl_for_each_entry(ace, acl) { + unsigned int ace_mask = ace->e_mask; + + if (richace_is_inherit_only(ace)) + continue; + if (richace_is_owner(ace)) { + if (!uid_eq(current_fsuid(), inode->i_uid)) + continue; + goto entry_matches_owner; + } else if (richace_is_group(ace)) { + if (!in_owning_group) + continue; + } else if (richace_is_unix_user(ace)) { + if (!uid_eq(current_fsuid(), ace->e_id.uid)) + continue; + if (uid_eq(current_fsuid(), inode->i_uid)) + goto entry_matches_owner; + } else if (richace_is_unix_group(ace)) { + if (!in_group_p(ace->e_id.gid)) + continue; + } else + goto entry_matches_everyone; + + /* + * Apply the group file mask to entries other than owner@ and + * everyone@ or user entries matching the owner. This ensures + * that we grant the same permissions as the acl computed by + * richacl_apply_masks(). + * + * Without this restriction, the following richacl would grant + * rw access to processes which are both the owner and in the + * owning group, but not to other users in the owning group, + * which could not be represented without masks: + * + * owner:rw::mask + * group@:rw::allow + */ + if ((acl->a_flags & RICHACL_MASKED) && richace_is_allow(ace)) + ace_mask &= acl->a_group_mask; + +entry_matches_owner: + /* The process is in the owner or group file class. */ + in_owner_or_group_class = 1; + +entry_matches_everyone: + /* Check which mask flags the ACE allows or denies. */ + if (richace_is_deny(ace)) + denied |= ace_mask & mask; + mask &= ~ace_mask; + + /* + * Keep going until we know which file class + * the process is in. + */ + if (!mask && in_owner_or_group_class) + break; + } + denied |= mask; + + if (acl->a_flags & RICHACL_MASKED) { + /* + * The file class a process is in determines which file mask + * applies. Check if that file mask also grants the requested + * access. + */ + if (uid_eq(current_fsuid(), inode->i_uid)) + denied |= requested & ~acl->a_owner_mask; + else if (in_owner_or_group_class) + denied |= requested & ~acl->a_group_mask; + else { + if (acl->a_flags & RICHACL_WRITE_THROUGH) + denied = requested & ~acl->a_other_mask; + else + denied |= requested & ~acl->a_other_mask; + } + } + +out: + return denied ? -EACCES : 0; +} +EXPORT_SYMBOL_GPL(richacl_permission); diff --git a/include/linux/richacl.h b/include/linux/richacl.h index 3559b2c..1d9f5f7 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -180,4 +180,7 @@ extern unsigned int richacl_mode_to_mask(umode_t); extern unsigned int richacl_want_to_mask(unsigned int); extern void richacl_compute_max_masks(struct richacl *); +/* richacl_inode.c */ +extern int richacl_permission(struct inode *, const struct richacl *, int); + #endif /* __RICHACL_H */ -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:18:47 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 A374929E18 for ; Tue, 3 Nov 2015 09:18:47 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 4727AAC007 for ; Tue, 3 Nov 2015 07:18:47 -0800 (PST) X-ASG-Debug-ID: 1446563925-04bdf0330c1fc960001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id gMF0ABATkBaPTOuG (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:18:45 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 50A1042E5B6; Tue, 3 Nov 2015 15:18:45 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRZa029477; Tue, 3 Nov 2015 10:18:39 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 10/51] vfs: Cache base_acl objects in inodes Date: Tue, 3 Nov 2015 16:16:46 +0100 X-ASG-Orig-Subj: [PATCH v13 10/51] vfs: Cache base_acl objects in inodes Message-Id: <1446563847-14005-11-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446563925 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 POSIX ACLs and richacls are both objects allocated by kmalloc() with a reference count which are freed by kfree_rcu(). An inode can either cache an access and a default POSIX ACL, or a richacl (richacls do not have default acls). To allow an inode to cache either of the two kinds of acls, introduce a new base_acl type and convert i_acl and i_default_acl to that type. In most cases, the vfs then doesn't have to care which kind of acl an inode caches (if any). Signed-off-by: Andreas Gruenbacher --- drivers/staging/lustre/lustre/llite/llite_lib.c | 2 +- fs/f2fs/acl.c | 4 ++-- fs/inode.c | 4 ++-- fs/jffs2/acl.c | 6 ++++-- fs/posix_acl.c | 18 +++++++++--------- include/linux/fs.h | 25 ++++++++++++++++++++++--- include/linux/posix_acl.h | 12 ++++-------- include/linux/richacl.h | 2 +- 8 files changed, 45 insertions(+), 28 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c index b4ed6c8..5766f69 100644 --- a/drivers/staging/lustre/lustre/llite/llite_lib.c +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c @@ -1118,7 +1118,7 @@ void ll_clear_inode(struct inode *inode) } #ifdef CONFIG_FS_POSIX_ACL else if (lli->lli_posix_acl) { - LASSERT(atomic_read(&lli->lli_posix_acl->a_refcount) == 1); + LASSERT(atomic_read(&lli->lli_posix_acl->a_base.ba_refcount) == 1); LASSERT(lli->lli_remote_perms == NULL); posix_acl_release(lli->lli_posix_acl); lli->lli_posix_acl = NULL; diff --git a/fs/f2fs/acl.c b/fs/f2fs/acl.c index c8f25f7..a4207de 100644 --- a/fs/f2fs/acl.c +++ b/fs/f2fs/acl.c @@ -270,7 +270,7 @@ static struct posix_acl *f2fs_acl_clone(const struct posix_acl *acl, sizeof(struct posix_acl_entry); clone = kmemdup(acl, size, flags); if (clone) - atomic_set(&clone->a_refcount, 1); + atomic_set(&clone->a_base.ba_refcount, 1); } return clone; } @@ -282,7 +282,7 @@ static int f2fs_acl_create_masq(struct posix_acl *acl, umode_t *mode_p) umode_t mode = *mode_p; int not_equiv = 0; - /* assert(atomic_read(acl->a_refcount) == 1); */ + /* assert(atomic_read(acl->a_base.ba_refcount) == 1); */ FOREACH_ACL_ENTRY(pa, acl, pe) { switch(pa->e_tag) { diff --git a/fs/inode.c b/fs/inode.c index 78a17b8..2a387f4 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -233,9 +233,9 @@ void __destroy_inode(struct inode *inode) #ifdef CONFIG_FS_POSIX_ACL if (inode->i_acl && inode->i_acl != ACL_NOT_CACHED) - posix_acl_release(inode->i_acl); + put_base_acl(inode->i_acl); if (inode->i_default_acl && inode->i_default_acl != ACL_NOT_CACHED) - posix_acl_release(inode->i_default_acl); + put_base_acl(inode->i_default_acl); #endif this_cpu_dec(nr_inodes); } diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c index 2f7a3c0..04a5836 100644 --- a/fs/jffs2/acl.c +++ b/fs/jffs2/acl.c @@ -294,13 +294,15 @@ int jffs2_init_acl_post(struct inode *inode) int rc; if (inode->i_default_acl) { - rc = __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_DEFAULT, inode->i_default_acl); + rc = __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_DEFAULT, + *acl_by_type(inode, ACL_TYPE_DEFAULT)); if (rc) return rc; } if (inode->i_acl) { - rc = __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_ACCESS, inode->i_acl); + rc = __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_ACCESS, + *acl_by_type(inode, ACL_TYPE_ACCESS)); if (rc) return rc; } diff --git a/fs/posix_acl.c b/fs/posix_acl.c index 4fb17de..b3b2265 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c @@ -25,9 +25,9 @@ struct posix_acl **acl_by_type(struct inode *inode, int type) { switch (type) { case ACL_TYPE_ACCESS: - return &inode->i_acl; + return (struct posix_acl **)&inode->i_acl; case ACL_TYPE_DEFAULT: - return &inode->i_default_acl; + return (struct posix_acl **)&inode->i_default_acl; default: BUG(); } @@ -83,16 +83,16 @@ EXPORT_SYMBOL(forget_cached_acl); void forget_all_cached_acls(struct inode *inode) { - struct posix_acl *old_access, *old_default; + struct base_acl *old_access, *old_default; spin_lock(&inode->i_lock); old_access = inode->i_acl; old_default = inode->i_default_acl; inode->i_acl = inode->i_default_acl = ACL_NOT_CACHED; spin_unlock(&inode->i_lock); if (old_access != ACL_NOT_CACHED) - posix_acl_release(old_access); + put_base_acl(old_access); if (old_default != ACL_NOT_CACHED) - posix_acl_release(old_default); + put_base_acl(old_default); } EXPORT_SYMBOL(forget_all_cached_acls); @@ -129,7 +129,7 @@ EXPORT_SYMBOL(get_acl); void posix_acl_init(struct posix_acl *acl, int count) { - atomic_set(&acl->a_refcount, 1); + atomic_set(&acl->a_base.ba_refcount, 1); acl->a_count = count; } EXPORT_SYMBOL(posix_acl_init); @@ -162,7 +162,7 @@ posix_acl_clone(const struct posix_acl *acl, gfp_t flags) sizeof(struct posix_acl_entry); clone = kmemdup(acl, size, flags); if (clone) - atomic_set(&clone->a_refcount, 1); + atomic_set(&clone->a_base.ba_refcount, 1); } return clone; } @@ -384,7 +384,7 @@ static int posix_acl_create_masq(struct posix_acl *acl, umode_t *mode_p) umode_t mode = *mode_p; int not_equiv = 0; - /* assert(atomic_read(acl->a_refcount) == 1); */ + /* assert(atomic_read(acl->a_base.ba_refcount) == 1); */ FOREACH_ACL_ENTRY(pa, acl, pe) { switch(pa->e_tag) { @@ -439,7 +439,7 @@ static int __posix_acl_chmod_masq(struct posix_acl *acl, umode_t mode) struct posix_acl_entry *group_obj = NULL, *mask_obj = NULL; struct posix_acl_entry *pa, *pe; - /* assert(atomic_read(acl->a_refcount) == 1); */ + /* assert(atomic_read(acl->a_base.ba_refcount) == 1); */ FOREACH_ACL_ENTRY(pa, acl, pe) { switch(pa->e_tag) { diff --git a/include/linux/fs.h b/include/linux/fs.h index ba91a89..3c22c92 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -576,6 +576,12 @@ static inline void mapping_allow_writable(struct address_space *mapping) #define i_size_ordered_init(inode) do { } while (0) #endif +struct base_acl { + union { + atomic_t ba_refcount; + struct rcu_head ba_rcu; + }; +}; struct posix_acl; #define ACL_NOT_CACHED ((void *)(-1)) @@ -595,9 +601,9 @@ struct inode { kgid_t i_gid; unsigned int i_flags; -#ifdef CONFIG_FS_POSIX_ACL - struct posix_acl *i_acl; - struct posix_acl *i_default_acl; +#if defined(CONFIG_FS_POSIX_ACL) + struct base_acl *i_acl; + struct base_acl *i_default_acl; #endif const struct inode_operations *i_op; @@ -3059,4 +3065,17 @@ static inline bool dir_relax(struct inode *inode) extern bool path_noexec(const struct path *path); +static inline struct base_acl *get_base_acl(struct base_acl *acl) +{ + if (acl) + atomic_inc(&acl->ba_refcount); + return acl; +} + +static inline void put_base_acl(struct base_acl *acl) +{ + if (acl && atomic_dec_and_test(&acl->ba_refcount)) + kfree_rcu(acl, ba_rcu); +} + #endif /* _LINUX_FS_H */ diff --git a/include/linux/posix_acl.h b/include/linux/posix_acl.h index 3e96a6a..2c46441 100644 --- a/include/linux/posix_acl.h +++ b/include/linux/posix_acl.h @@ -43,10 +43,7 @@ struct posix_acl_entry { }; struct posix_acl { - union { - atomic_t a_refcount; - struct rcu_head a_rcu; - }; + struct base_acl a_base; unsigned int a_count; struct posix_acl_entry a_entries[0]; }; @@ -61,8 +58,7 @@ struct posix_acl { static inline struct posix_acl * posix_acl_dup(struct posix_acl *acl) { - if (acl) - atomic_inc(&acl->a_refcount); + get_base_acl(&acl->a_base); return acl; } @@ -72,8 +68,8 @@ posix_acl_dup(struct posix_acl *acl) static inline void posix_acl_release(struct posix_acl *acl) { - if (acl && atomic_dec_and_test(&acl->a_refcount)) - kfree_rcu(acl, a_rcu); + BUILD_BUG_ON(offsetof(struct posix_acl, a_base) != 0); + put_base_acl(&acl->a_base); } diff --git a/include/linux/richacl.h b/include/linux/richacl.h index 1d9f5f7..2baef35 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -57,7 +57,7 @@ static inline struct richacl * richacl_get(struct richacl *acl) { if (acl) - atomic_inc(&acl->a_refcount); + atomic_inc(&acl->a_base.ba_refcount); return acl; } -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:18:53 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 CD19A7F6B for ; Tue, 3 Nov 2015 09:18:53 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id AAD298F8033 for ; Tue, 3 Nov 2015 07:18:53 -0800 (PST) X-ASG-Debug-ID: 1446563932-04cb6c7b841ddb40001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id bUIdnqeN1hEiCVSw (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:18:52 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 3AF16ABC; Tue, 3 Nov 2015 15:18:52 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRZb029477; Tue, 3 Nov 2015 10:18:45 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 11/51] vfs: Add get_richacl and set_richacl inode operations Date: Tue, 3 Nov 2015 16:16:47 +0100 X-ASG-Orig-Subj: [PATCH v13 11/51] vfs: Add get_richacl and set_richacl inode operations Message-Id: <1446563847-14005-12-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446563932 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 These operations are similar to the get_acl and set_acl operations for POSIX ACLs. The distinction between access and default ACLs doesn't exist for richacls. Signed-off-by: Andreas Gruenbacher --- include/linux/fs.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/fs.h b/include/linux/fs.h index 3c22c92..08fde42 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1662,6 +1662,7 @@ struct inode_operations { const char * (*follow_link) (struct dentry *, void **); int (*permission) (struct inode *, int); struct posix_acl * (*get_acl)(struct inode *, int); + struct richacl * (*get_richacl)(struct inode *); int (*readlink) (struct dentry *, char __user *,int); void (*put_link) (struct inode *, void *); @@ -1691,6 +1692,7 @@ struct inode_operations { umode_t create_mode, int *opened); int (*tmpfile) (struct inode *, struct dentry *, umode_t); int (*set_acl)(struct inode *, struct posix_acl *, int); + int (*set_richacl)(struct inode *, struct richacl *); /* WARNING: probably going away soon, do not use! */ } ____cacheline_aligned; -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:19:01 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 479757F77 for ; Tue, 3 Nov 2015 09:19:01 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 35658304043 for ; Tue, 3 Nov 2015 07:19:01 -0800 (PST) X-ASG-Debug-ID: 1446563939-04cbb0660c1f7bf0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id nhOpB3Afby44qvCr (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:18:59 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 1D4DBA2C35; Tue, 3 Nov 2015 15:18:59 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRZc029477; Tue, 3 Nov 2015 10:18:52 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 12/51] vfs: Cache richacl in struct inode Date: Tue, 3 Nov 2015 16:16:48 +0100 X-ASG-Orig-Subj: [PATCH v13 12/51] vfs: Cache richacl in struct inode Message-Id: <1446563847-14005-13-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446563939 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Cache richacls in struct inode so that this doesn't have to be done individually in each filesystem. This is similar to POSIX ACLs. Signed-off-by: Andreas Gruenbacher --- fs/inode.c | 11 ++++++-- fs/posix_acl.c | 2 +- fs/richacl_base.c | 4 +-- fs/richacl_inode.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/fs.h | 5 +++- include/linux/richacl.h | 15 ++++++---- 6 files changed, 100 insertions(+), 12 deletions(-) diff --git a/fs/inode.c b/fs/inode.c index 2a387f4..8462ddb 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -174,8 +174,11 @@ int inode_init_always(struct super_block *sb, struct inode *inode) inode->i_private = NULL; inode->i_mapping = mapping; INIT_HLIST_HEAD(&inode->i_dentry); /* buggered by rcu freeing */ -#ifdef CONFIG_FS_POSIX_ACL - inode->i_acl = inode->i_default_acl = ACL_NOT_CACHED; +#if defined(CONFIG_FS_POSIX_ACL) || defined(CONFIG_FS_RICHACL) + inode->i_acl = ACL_NOT_CACHED; +# if defined(CONFIG_FS_POSIX_ACL) + inode->i_default_acl = ACL_NOT_CACHED; +# endif #endif #ifdef CONFIG_FSNOTIFY @@ -231,11 +234,13 @@ void __destroy_inode(struct inode *inode) atomic_long_dec(&inode->i_sb->s_remove_count); } -#ifdef CONFIG_FS_POSIX_ACL +#if defined(CONFIG_FS_POSIX_ACL) || defined(CONFIG_FS_RICHACL) if (inode->i_acl && inode->i_acl != ACL_NOT_CACHED) put_base_acl(inode->i_acl); +# if defined(CONFIG_FS_POSIX_ACL) if (inode->i_default_acl && inode->i_default_acl != ACL_NOT_CACHED) put_base_acl(inode->i_default_acl); +# endif #endif this_cpu_dec(nr_inodes); } diff --git a/fs/posix_acl.c b/fs/posix_acl.c index b3b2265..1d766a5 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c @@ -38,7 +38,7 @@ struct posix_acl *get_cached_acl(struct inode *inode, int type) { struct posix_acl **p = acl_by_type(inode, type); struct posix_acl *acl = ACCESS_ONCE(*p); - if (acl) { + if (acl && IS_POSIXACL(inode)) { spin_lock(&inode->i_lock); acl = *p; if (acl != ACL_NOT_CACHED) diff --git a/fs/richacl_base.c b/fs/richacl_base.c index 69b806c..d0ab5e9 100644 --- a/fs/richacl_base.c +++ b/fs/richacl_base.c @@ -33,7 +33,7 @@ richacl_alloc(int count, gfp_t gfp) struct richacl *acl = kzalloc(size, gfp); if (acl) { - atomic_set(&acl->a_refcount, 1); + atomic_set(&acl->a_base.ba_refcount, 1); acl->a_count = count; } return acl; @@ -52,7 +52,7 @@ richacl_clone(const struct richacl *acl, gfp_t gfp) if (dup) { memcpy(dup, acl, size); - atomic_set(&dup->a_refcount, 1); + atomic_set(&dup->a_base.ba_refcount, 1); } return dup; } diff --git a/fs/richacl_inode.c b/fs/richacl_inode.c index 99b3c93..c41a6c4 100644 --- a/fs/richacl_inode.c +++ b/fs/richacl_inode.c @@ -20,6 +20,81 @@ #include #include +struct richacl *get_cached_richacl(struct inode *inode) +{ + struct richacl *acl; + + acl = (struct richacl *)ACCESS_ONCE(inode->i_acl); + if (acl && IS_RICHACL(inode)) { + spin_lock(&inode->i_lock); + acl = (struct richacl *)inode->i_acl; + if (acl != ACL_NOT_CACHED) + acl = richacl_get(acl); + spin_unlock(&inode->i_lock); + } + return acl; +} +EXPORT_SYMBOL_GPL(get_cached_richacl); + +struct richacl *get_cached_richacl_rcu(struct inode *inode) +{ + return (struct richacl *)rcu_dereference(inode->i_acl); +} +EXPORT_SYMBOL_GPL(get_cached_richacl_rcu); + +void set_cached_richacl(struct inode *inode, struct richacl *acl) +{ + struct base_acl *old = NULL; + + spin_lock(&inode->i_lock); + old = inode->i_acl; + rcu_assign_pointer(inode->i_acl, &richacl_get(acl)->a_base); + spin_unlock(&inode->i_lock); + if (old != ACL_NOT_CACHED) + put_base_acl(old); +} +EXPORT_SYMBOL_GPL(set_cached_richacl); + +void forget_cached_richacl(struct inode *inode) +{ + struct base_acl *old = NULL; + + spin_lock(&inode->i_lock); + old = inode->i_acl; + inode->i_acl = ACL_NOT_CACHED; + spin_unlock(&inode->i_lock); + if (old != ACL_NOT_CACHED) + put_base_acl(old); +} +EXPORT_SYMBOL_GPL(forget_cached_richacl); + +struct richacl *get_richacl(struct inode *inode) +{ + struct richacl *acl; + + acl = get_cached_richacl(inode); + if (acl != ACL_NOT_CACHED) + return acl; + + if (!IS_RICHACL(inode)) + return NULL; + + /* + * A filesystem can force a ACL callback by just never filling the + * ACL cache. But normally you'd fill the cache either at inode + * instantiation time, or on the first ->get_richacl call. + * + * If the filesystem doesn't have a get_richacl() function at all, + * we'll just create the negative cache entry. + */ + if (!inode->i_op->get_richacl) { + set_cached_richacl(inode, NULL); + return NULL; + } + return inode->i_op->get_richacl(inode); +} +EXPORT_SYMBOL_GPL(get_richacl); + /** * richacl_permission - richacl permission check algorithm * @inode: inode to check diff --git a/include/linux/fs.h b/include/linux/fs.h index 08fde42..d91deef 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -583,6 +583,7 @@ struct base_acl { }; }; struct posix_acl; +struct richacl; #define ACL_NOT_CACHED ((void *)(-1)) #define IOP_FASTPERM 0x0001 @@ -601,9 +602,11 @@ struct inode { kgid_t i_gid; unsigned int i_flags; -#if defined(CONFIG_FS_POSIX_ACL) +#if defined(CONFIG_FS_POSIX_ACL) || defined(CONFIG_FS_RICHACL) struct base_acl *i_acl; +# if defined(CONFIG_FS_POSIX_ACL) struct base_acl *i_default_acl; +# endif #endif const struct inode_operations *i_op; diff --git a/include/linux/richacl.h b/include/linux/richacl.h index 2baef35..de7d0d9 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -31,7 +31,7 @@ struct richace { }; struct richacl { - atomic_t a_refcount; + struct base_acl a_base; unsigned int a_owner_mask; unsigned int a_group_mask; unsigned int a_other_mask; @@ -56,8 +56,7 @@ struct richacl { static inline struct richacl * richacl_get(struct richacl *acl) { - if (acl) - atomic_inc(&acl->a_base.ba_refcount); + get_base_acl(&acl->a_base); return acl; } @@ -67,10 +66,16 @@ richacl_get(struct richacl *acl) static inline void richacl_put(struct richacl *acl) { - if (acl && atomic_dec_and_test(&acl->a_refcount)) - kfree(acl); + BUILD_BUG_ON(offsetof(struct richacl, a_base) != 0); + put_base_acl(&acl->a_base); } +extern struct richacl *get_cached_richacl(struct inode *); +extern struct richacl *get_cached_richacl_rcu(struct inode *); +extern void set_cached_richacl(struct inode *, struct richacl *); +extern void forget_cached_richacl(struct inode *); +extern struct richacl *get_richacl(struct inode *); + /** * richace_is_owner - check if @ace is an OWNER@ entry */ -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:19:07 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 C0D0429E20 for ; Tue, 3 Nov 2015 09:19:07 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id AF7458F8033 for ; Tue, 3 Nov 2015 07:19:07 -0800 (PST) X-ASG-Debug-ID: 1446563946-04cbb0660c1f7c10001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id UmtHrt1OGU4Szdmj (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:19:06 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 09CFC8F4EF; Tue, 3 Nov 2015 15:19:06 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRZd029477; Tue, 3 Nov 2015 10:18:59 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 13/51] richacl: Update the file masks in chmod() Date: Tue, 3 Nov 2015 16:16:49 +0100 X-ASG-Orig-Subj: [PATCH v13 13/51] richacl: Update the file masks in chmod() Message-Id: <1446563847-14005-14-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446563946 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Doing a chmod() sets the file mode, which includes the file permission bits. When a file has a richacl, the permissions that the richacl grants need to be limited to what the new file permission bits allow. This is done by setting the file masks in the richacl to what the file permission bits map to. The richacl access check algorithm takes the file masks into account, which ensures that the richacl cannot grant too many permissions. It is possible to explicitly add permissions to the file masks which go beyond what the file permission bits can grant (like the RICHACE_WRITE_ACL permission). The POSIX.1 standard calls this an alternate file access control mechanism. A subsequent chmod() would ensure that those permissions are disabled again. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_base.c | 42 ++++++++++++++++++++++++++++++++++++++++++ fs/richacl_inode.c | 30 ++++++++++++++++++++++++++++++ include/linux/richacl.h | 2 ++ 3 files changed, 74 insertions(+) diff --git a/fs/richacl_base.c b/fs/richacl_base.c index d0ab5e9..00e87be 100644 --- a/fs/richacl_base.c +++ b/fs/richacl_base.c @@ -340,3 +340,45 @@ restart: acl->a_flags &= ~(RICHACL_WRITE_THROUGH | RICHACL_MASKED); } EXPORT_SYMBOL_GPL(richacl_compute_max_masks); + +/** + * __richacl_chmod - update the file masks to reflect the new mode + * @acl: access control list + * @mode: new file permission bits including the file type + * + * Return a copy of @acl where the file masks have been replaced by the file + * masks corresponding to the file permission bits in @mode, or returns @acl + * itself if the file masks are already up to date. Takes over a reference + * to @acl. + */ +struct richacl * +__richacl_chmod(struct richacl *acl, umode_t mode) +{ + unsigned int x = S_ISDIR(mode) ? 0 : RICHACE_DELETE_CHILD; + unsigned int owner_mask, group_mask, other_mask; + struct richacl *clone; + + owner_mask = richacl_mode_to_mask(mode >> 6) & ~x; + group_mask = richacl_mode_to_mask(mode >> 3) & ~x; + other_mask = richacl_mode_to_mask(mode) & ~x; + + if (acl->a_owner_mask == owner_mask && + acl->a_group_mask == group_mask && + acl->a_other_mask == other_mask && + (acl->a_flags & RICHACL_MASKED) && + (acl->a_flags & RICHACL_WRITE_THROUGH)) + return acl; + + clone = richacl_clone(acl, GFP_KERNEL); + richacl_put(acl); + if (!clone) + return ERR_PTR(-ENOMEM); + + clone->a_flags |= (RICHACL_WRITE_THROUGH | RICHACL_MASKED); + clone->a_owner_mask = owner_mask; + clone->a_group_mask = group_mask; + clone->a_other_mask = other_mask; + + return clone; +} +EXPORT_SYMBOL_GPL(__richacl_chmod); diff --git a/fs/richacl_inode.c b/fs/richacl_inode.c index c41a6c4..301f246 100644 --- a/fs/richacl_inode.c +++ b/fs/richacl_inode.c @@ -222,3 +222,33 @@ out: return denied ? -EACCES : 0; } EXPORT_SYMBOL_GPL(richacl_permission); + +/** + * richacl_chmod - filesystem chmod helper + * @inode: inode whose file permission bits to change + * @mode: new file permission bits including the file type + * + * Helper for filesystems to use to perform a chmod on the richacl of an inode. + */ +int +richacl_chmod(struct inode *inode, umode_t mode) +{ + struct richacl *acl; + int retval; + + if (S_ISLNK(mode)) + return -EOPNOTSUPP; + if (!inode->i_op->set_richacl) + return -EOPNOTSUPP; + acl = get_richacl(inode); + if (IS_ERR_OR_NULL(acl)) + return PTR_ERR(acl); + acl = __richacl_chmod(acl, mode); + if (IS_ERR(acl)) + return PTR_ERR(acl); + retval = inode->i_op->set_richacl(inode, acl); + richacl_put(acl); + + return retval; +} +EXPORT_SYMBOL(richacl_chmod); diff --git a/include/linux/richacl.h b/include/linux/richacl.h index de7d0d9..3626314 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -184,8 +184,10 @@ extern int richacl_masks_to_mode(const struct richacl *); extern unsigned int richacl_mode_to_mask(umode_t); extern unsigned int richacl_want_to_mask(unsigned int); extern void richacl_compute_max_masks(struct richacl *); +extern struct richacl *__richacl_chmod(struct richacl *, umode_t); /* richacl_inode.c */ extern int richacl_permission(struct inode *, const struct richacl *, int); +extern int richacl_chmod(struct inode *, umode_t); #endif /* __RICHACL_H */ -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:19:15 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 0A0EE29E1F for ; Tue, 3 Nov 2015 09:19:15 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 85C57AC007 for ; Tue, 3 Nov 2015 07:19:14 -0800 (PST) X-ASG-Debug-ID: 1446563953-04bdf0330b1fc9b0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id AfB9BuvL4zJudYJu (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:19:13 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id E8BBEC0D61A5; Tue, 3 Nov 2015 15:19:12 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRZe029477; Tue, 3 Nov 2015 10:19:06 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 14/51] richacl: Check if an acl is equivalent to a file mode Date: Tue, 3 Nov 2015 16:16:50 +0100 X-ASG-Orig-Subj: [PATCH v13 14/51] richacl: Check if an acl is equivalent to a file mode Message-Id: <1446563847-14005-15-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446563953 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 ACLs are considered equivalent to file modes if they only consist of owner@, group@, and everyone@ entries, the owner@ permissions do not depend on whether the owner is a member in the owning group, and no inheritance flags are set. This test is used to avoid storing richacls if the acl can be computed from the file permission bits. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_base.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/richacl.h | 1 + 2 files changed, 105 insertions(+) diff --git a/fs/richacl_base.c b/fs/richacl_base.c index 00e87be..56b5ad6 100644 --- a/fs/richacl_base.c +++ b/fs/richacl_base.c @@ -382,3 +382,107 @@ __richacl_chmod(struct richacl *acl, umode_t mode) return clone; } EXPORT_SYMBOL_GPL(__richacl_chmod); + +/** + * richacl_equiv_mode - compute the mode equivalent of @acl + * + * An acl is considered equivalent to a file mode if it only consists of + * owner@, group@, and everyone@ entries and the owner@ permissions do not + * depend on whether the owner is a member in the owning group. + */ +int +richacl_equiv_mode(const struct richacl *acl, umode_t *mode_p) +{ + umode_t mode = *mode_p; + + /* + * The RICHACE_DELETE_CHILD flag is meaningless for non-directories, so + * we ignore it. + */ + unsigned int x = S_ISDIR(mode) ? 0 : RICHACE_DELETE_CHILD; + struct { + unsigned int allowed; + unsigned int defined; /* allowed or denied */ + } owner = { + .defined = RICHACE_POSIX_ALWAYS_ALLOWED | + RICHACE_POSIX_OWNER_ALLOWED | x, + }, group = { + .defined = RICHACE_POSIX_ALWAYS_ALLOWED | x, + }, everyone = { + .defined = RICHACE_POSIX_ALWAYS_ALLOWED | x, + }; + const struct richace *ace; + + if (acl->a_flags & ~(RICHACL_WRITE_THROUGH | RICHACL_MASKED)) + return -1; + + richacl_for_each_entry(ace, acl) { + if (ace->e_flags & ~RICHACE_SPECIAL_WHO) + return -1; + + if (richace_is_owner(ace) || richace_is_everyone(ace)) { + x = ace->e_mask & ~owner.defined; + if (richace_is_allow(ace)) { + unsigned int group_denied = + group.defined & ~group.allowed; + + if (x & group_denied) + return -1; + owner.allowed |= x; + } else /* if (richace_is_deny(ace)) */ { + if (x & group.allowed) + return -1; + } + owner.defined |= x; + + if (richace_is_everyone(ace)) { + x = ace->e_mask; + if (richace_is_allow(ace)) { + group.allowed |= + x & ~group.defined; + everyone.allowed |= + x & ~everyone.defined; + } + group.defined |= x; + everyone.defined |= x; + } + } else if (richace_is_group(ace)) { + x = ace->e_mask & ~group.defined; + if (richace_is_allow(ace)) + group.allowed |= x; + group.defined |= x; + } else + return -1; + } + + if (group.allowed & ~owner.defined) + return -1; + + if (acl->a_flags & RICHACL_MASKED) { + if (acl->a_flags & RICHACL_WRITE_THROUGH) { + owner.allowed = acl->a_owner_mask; + everyone.allowed = acl->a_other_mask; + } else { + owner.allowed &= acl->a_owner_mask; + everyone.allowed &= acl->a_other_mask; + } + group.allowed &= acl->a_group_mask; + } + + mode = (mode & ~S_IRWXUGO) | + (richacl_mask_to_mode(owner.allowed) << 6) | + (richacl_mask_to_mode(group.allowed) << 3) | + richacl_mask_to_mode(everyone.allowed); + + /* Mask flags we can ignore */ + x = S_ISDIR(mode) ? 0 : RICHACE_DELETE_CHILD; + + if (((richacl_mode_to_mask(mode >> 6) ^ owner.allowed) & ~x) || + ((richacl_mode_to_mask(mode >> 3) ^ group.allowed) & ~x) || + ((richacl_mode_to_mask(mode) ^ everyone.allowed) & ~x)) + return -1; + + *mode_p = mode; + return 0; +} +EXPORT_SYMBOL_GPL(richacl_equiv_mode); diff --git a/include/linux/richacl.h b/include/linux/richacl.h index 3626314..ddd5aa6 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -185,6 +185,7 @@ extern unsigned int richacl_mode_to_mask(umode_t); extern unsigned int richacl_want_to_mask(unsigned int); extern void richacl_compute_max_masks(struct richacl *); extern struct richacl *__richacl_chmod(struct richacl *, umode_t); +extern int richacl_equiv_mode(const struct richacl *, umode_t *); /* richacl_inode.c */ extern int richacl_permission(struct inode *, const struct richacl *, int); -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:19:22 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 02E2429E1F for ; Tue, 3 Nov 2015 09:19:22 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id D472A304039 for ; Tue, 3 Nov 2015 07:19:21 -0800 (PST) X-ASG-Debug-ID: 1446563960-04cbb0660d1f7c30001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 9yex0y3R23sENT7C (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:19:20 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 07F4B8F4E4; Tue, 3 Nov 2015 15:19:20 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRZf029477; Tue, 3 Nov 2015 10:19:13 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 15/51] richacl: Create-time inheritance Date: Tue, 3 Nov 2015 16:16:51 +0100 X-ASG-Orig-Subj: [PATCH v13 15/51] richacl: Create-time inheritance Message-Id: <1446563847-14005-16-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446563960 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 When a new file is created, it can inherit an acl from its parent directory; this is similar to how default acls work in POSIX (draft) ACLs. As with POSIX ACLs, if a file inherits an acl from its parent directory, the intersection between the create mode and the permissions granted by the inherited acl determines the file masks and file permission bits, and the umask is ignored. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_base.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++ fs/richacl_inode.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/richacl.h | 2 ++ 3 files changed, 140 insertions(+) diff --git a/fs/richacl_base.c b/fs/richacl_base.c index 56b5ad6..9f7d91d 100644 --- a/fs/richacl_base.c +++ b/fs/richacl_base.c @@ -486,3 +486,71 @@ richacl_equiv_mode(const struct richacl *acl, umode_t *mode_p) return 0; } EXPORT_SYMBOL_GPL(richacl_equiv_mode); + +/** + * richacl_inherit - compute the inherited acl of a new file + * @dir_acl: acl of the containing directory + * @isdir: inherit by a directory or non-directory? + * + * A directory can have acl entries which files and/or directories created + * inside the directory will inherit. This function computes the acl for such + * a new file. If there is no inheritable acl, it will return %NULL. + */ +struct richacl * +richacl_inherit(const struct richacl *dir_acl, int isdir) +{ + const struct richace *dir_ace; + struct richacl *acl = NULL; + struct richace *ace; + int count = 0; + + if (isdir) { + richacl_for_each_entry(dir_ace, dir_acl) { + if (!richace_is_inheritable(dir_ace)) + continue; + count++; + } + if (!count) + return NULL; + acl = richacl_alloc(count, GFP_KERNEL); + if (!acl) + return ERR_PTR(-ENOMEM); + ace = acl->a_entries; + richacl_for_each_entry(dir_ace, dir_acl) { + if (!richace_is_inheritable(dir_ace)) + continue; + richace_copy(ace, dir_ace); + if (dir_ace->e_flags & RICHACE_NO_PROPAGATE_INHERIT_ACE) + ace->e_flags &= ~RICHACE_INHERITANCE_FLAGS; + else if (!(dir_ace->e_flags & RICHACE_DIRECTORY_INHERIT_ACE)) + ace->e_flags |= RICHACE_INHERIT_ONLY_ACE; + ace++; + } + } else { + richacl_for_each_entry(dir_ace, dir_acl) { + if (!(dir_ace->e_flags & RICHACE_FILE_INHERIT_ACE)) + continue; + count++; + } + if (!count) + return NULL; + acl = richacl_alloc(count, GFP_KERNEL); + if (!acl) + return ERR_PTR(-ENOMEM); + ace = acl->a_entries; + richacl_for_each_entry(dir_ace, dir_acl) { + if (!(dir_ace->e_flags & RICHACE_FILE_INHERIT_ACE)) + continue; + richace_copy(ace, dir_ace); + ace->e_flags &= ~RICHACE_INHERITANCE_FLAGS; + /* + * RICHACE_DELETE_CHILD is meaningless for + * non-directories, so clear it. + */ + ace->e_mask &= ~RICHACE_DELETE_CHILD; + ace++; + } + } + + return acl; +} diff --git a/fs/richacl_inode.c b/fs/richacl_inode.c index 301f246..d2bf076 100644 --- a/fs/richacl_inode.c +++ b/fs/richacl_inode.c @@ -252,3 +252,73 @@ richacl_chmod(struct inode *inode, umode_t mode) return retval; } EXPORT_SYMBOL(richacl_chmod); + +/* + * richacl_inherit_inode - compute inherited acl and file mode + * @dir_acl: acl of the containing directory + * @mode_p: mode of the new inode + * + * The file permission bits in @mode_p must be set to the create mode by the + * caller. + * + * If there is an inheritable acl, the maximum permissions that the acl grants + * are computed and the file masks of the new acl are set accordingly. + */ +static struct richacl * +richacl_inherit_inode(const struct richacl *dir_acl, umode_t *mode_p) +{ + struct richacl *acl; + umode_t mode = *mode_p; + + acl = richacl_inherit(dir_acl, S_ISDIR(mode)); + if (acl) { + if (richacl_equiv_mode(acl, &mode) == 0) { + *mode_p &= mode; + richacl_put(acl); + acl = NULL; + } else { + richacl_compute_max_masks(acl); + /* + * Ensure that the acl will not grant any permissions + * beyond the create mode. + */ + acl->a_flags |= RICHACL_MASKED; + acl->a_owner_mask &= + richacl_mode_to_mask(mode >> 6); + acl->a_group_mask &= + richacl_mode_to_mask(mode >> 3); + acl->a_other_mask &= + richacl_mode_to_mask(mode); + } + } else + *mode_p &= ~current_umask(); + + return acl; +} + +/** + * richacl_create - filesystem create helper + * @mode_p: mode of the new inode + * @dir: containing directory + * + * Compute the inherited acl for a new inode. If there is no acl to inherit, + * apply the umask. Use when creating a new inode on a richacl enabled file + * system. + */ +struct richacl *richacl_create(umode_t *mode_p, struct inode *dir) +{ + struct richacl *dir_acl, *acl = NULL; + + if (S_ISLNK(*mode_p)) + return NULL; + dir_acl = get_richacl(dir); + if (dir_acl) { + if (IS_ERR(dir_acl)) + return dir_acl; + acl = richacl_inherit_inode(dir_acl, mode_p); + richacl_put(dir_acl); + } else + *mode_p &= ~current_umask(); + return acl; +} +EXPORT_SYMBOL_GPL(richacl_create); diff --git a/include/linux/richacl.h b/include/linux/richacl.h index ddd5aa6..302872b 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -186,9 +186,11 @@ extern unsigned int richacl_want_to_mask(unsigned int); extern void richacl_compute_max_masks(struct richacl *); extern struct richacl *__richacl_chmod(struct richacl *, umode_t); extern int richacl_equiv_mode(const struct richacl *, umode_t *); +extern struct richacl *richacl_inherit(const struct richacl *, int); /* richacl_inode.c */ extern int richacl_permission(struct inode *, const struct richacl *, int); extern int richacl_chmod(struct inode *, umode_t); +extern struct richacl *richacl_create(umode_t *, struct inode *); #endif /* __RICHACL_H */ -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:19:28 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 945F729E1E for ; Tue, 3 Nov 2015 09:19:28 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 81CFB30404E for ; Tue, 3 Nov 2015 07:19:28 -0800 (PST) X-ASG-Debug-ID: 1446563966-04cb6c7b861ddb80001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id klWcyWTZOGi67bWv (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:19:27 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id B06F48E224; Tue, 3 Nov 2015 15:19:26 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRZg029477; Tue, 3 Nov 2015 10:19:20 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 16/51] richacl: Automatic Inheritance Date: Tue, 3 Nov 2015 16:16:52 +0100 X-ASG-Orig-Subj: [PATCH v13 16/51] richacl: Automatic Inheritance Message-Id: <1446563847-14005-17-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446563967 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Automatic Inheritance (AI) allows changes to the acl of a directory to propagate down to children. This is mostly implemented in user space: when a process changes the permissions of a directory and Automatic Inheritance is enabled for that directory, the process must propagate those changes to all children, recursively. The kernel enables this by keeping track of which permissions have been inherited at create time. In addition, it makes sure that permission propagation is turned off when the permissions are set explicitly (for example, upon create or chmod). Automatic Inheritance works as follows: - When the RICHACL_AUTO_INHERIT flag in the acl of a file or directory is not set, the file or directory is not affected by AI. - When the RICHACL_AUTO_INHERIT flag in the acl of a directory is set and a file or subdirectory is created in that directory, the inherited acl will have the RICHACL_AUTO_INHERIT flag set, and all inherited aces will have the RICHACE_INHERITED_ACE flag set. This allows user space to distinguish between aces which have been inherited and aces which have been explicitly added. - When the RICHACL_PROTECTED acl flag in the acl of a file or directory is set, AI will not modify the acl. This does not affect propagation of permissions from the file to its children (if the file is a directory). Linux does not have a way of creating files or directories without setting the file permission bits, so all files created inside a directory with RICHACL_AUTO_INHERIT set will have the RICHACL_PROTECTED flag set. This effectively disables Automatic Inheritance. Protocols which support creating files without specifying permissions can explicitly clear the RICHACL_PROTECTED flag after creating a file and reset the file masks to "undo" applying the create mode; see richacl_compute_max_masks(). They should set the RICHACL_DEFAULTED flag. (A mechanism that would allow to indicate to the kernel to ignore the create mode in the first place when there are inherited permissions would be nice to have.) Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_base.c | 10 +++++++++- fs/richacl_inode.c | 7 +++++++ include/linux/richacl.h | 12 ++++++++++++ include/uapi/linux/richacl.h | 11 ++++++++++- 4 files changed, 38 insertions(+), 2 deletions(-) diff --git a/fs/richacl_base.c b/fs/richacl_base.c index 9f7d91d..2a9c448 100644 --- a/fs/richacl_base.c +++ b/fs/richacl_base.c @@ -366,7 +366,8 @@ __richacl_chmod(struct richacl *acl, umode_t mode) acl->a_group_mask == group_mask && acl->a_other_mask == other_mask && (acl->a_flags & RICHACL_MASKED) && - (acl->a_flags & RICHACL_WRITE_THROUGH)) + (acl->a_flags & RICHACL_WRITE_THROUGH) && + (!richacl_is_auto_inherit(acl) || richacl_is_protected(acl))) return acl; clone = richacl_clone(acl, GFP_KERNEL); @@ -378,6 +379,8 @@ __richacl_chmod(struct richacl *acl, umode_t mode) clone->a_owner_mask = owner_mask; clone->a_group_mask = group_mask; clone->a_other_mask = other_mask; + if (richacl_is_auto_inherit(clone)) + clone->a_flags |= RICHACL_PROTECTED; return clone; } @@ -551,6 +554,11 @@ richacl_inherit(const struct richacl *dir_acl, int isdir) ace++; } } + if (richacl_is_auto_inherit(dir_acl)) { + acl->a_flags = RICHACL_AUTO_INHERIT; + richacl_for_each_entry(ace, acl) + ace->e_flags |= RICHACE_INHERITED_ACE; + } return acl; } diff --git a/fs/richacl_inode.c b/fs/richacl_inode.c index d2bf076..24276da 100644 --- a/fs/richacl_inode.c +++ b/fs/richacl_inode.c @@ -277,6 +277,13 @@ richacl_inherit_inode(const struct richacl *dir_acl, umode_t *mode_p) richacl_put(acl); acl = NULL; } else { + /* + * We need to set RICHACL_PROTECTED because we are + * doing an implicit chmod + */ + if (richacl_is_auto_inherit(acl)) + acl->a_flags |= RICHACL_PROTECTED; + richacl_compute_max_masks(acl); /* * Ensure that the acl will not grant any permissions diff --git a/include/linux/richacl.h b/include/linux/richacl.h index 302872b..7cfa64d 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -76,6 +76,18 @@ extern void set_cached_richacl(struct inode *, struct richacl *); extern void forget_cached_richacl(struct inode *); extern struct richacl *get_richacl(struct inode *); +static inline int +richacl_is_auto_inherit(const struct richacl *acl) +{ + return acl->a_flags & RICHACL_AUTO_INHERIT; +} + +static inline int +richacl_is_protected(const struct richacl *acl) +{ + return acl->a_flags & RICHACL_PROTECTED; +} + /** * richace_is_owner - check if @ace is an OWNER@ entry */ diff --git a/include/uapi/linux/richacl.h b/include/uapi/linux/richacl.h index 1ed48ac..8849a53 100644 --- a/include/uapi/linux/richacl.h +++ b/include/uapi/linux/richacl.h @@ -18,6 +18,9 @@ #define __UAPI_RICHACL_H /* a_flags values */ +#define RICHACL_AUTO_INHERIT 0x01 +#define RICHACL_PROTECTED 0x02 +#define RICHACL_DEFAULTED 0x04 #define RICHACL_WRITE_THROUGH 0x40 #define RICHACL_MASKED 0x80 @@ -31,6 +34,7 @@ #define RICHACE_NO_PROPAGATE_INHERIT_ACE 0x0004 #define RICHACE_INHERIT_ONLY_ACE 0x0008 #define RICHACE_IDENTIFIER_GROUP 0x0040 +#define RICHACE_INHERITED_ACE 0x0080 #define RICHACE_SPECIAL_WHO 0x4000 /* e_mask bitflags */ @@ -60,6 +64,9 @@ #define RICHACE_EVERYONE_SPECIAL_ID 2 #define RICHACL_VALID_FLAGS ( \ + RICHACL_AUTO_INHERIT | \ + RICHACL_PROTECTED | \ + RICHACL_DEFAULTED | \ RICHACL_WRITE_THROUGH | \ RICHACL_MASKED ) @@ -69,13 +76,15 @@ RICHACE_NO_PROPAGATE_INHERIT_ACE | \ RICHACE_INHERIT_ONLY_ACE | \ RICHACE_IDENTIFIER_GROUP | \ + RICHACE_INHERITED_ACE | \ RICHACE_SPECIAL_WHO ) #define RICHACE_INHERITANCE_FLAGS ( \ RICHACE_FILE_INHERIT_ACE | \ RICHACE_DIRECTORY_INHERIT_ACE | \ RICHACE_NO_PROPAGATE_INHERIT_ACE | \ - RICHACE_INHERIT_ONLY_ACE ) + RICHACE_INHERIT_ONLY_ACE | \ + RICHACE_INHERITED_ACE ) /* Valid RICHACE_* flags for directories and non-directories */ #define RICHACE_VALID_MASK ( \ -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:19:37 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 1335729E1E for ; Tue, 3 Nov 2015 09:19:37 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 71DCEAC002 for ; Tue, 3 Nov 2015 07:19:36 -0800 (PST) X-ASG-Debug-ID: 1446563973-04cbb0660c1f7c50001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id UeIfUm6BHnIMXjQN (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:19:34 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 995A98535A; Tue, 3 Nov 2015 15:19:33 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRZh029477; Tue, 3 Nov 2015 10:19:27 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 17/51] richacl: xattr mapping functions Date: Tue, 3 Nov 2015 16:16:53 +0100 X-ASG-Orig-Subj: [PATCH v13 17/51] richacl: xattr mapping functions Message-Id: <1446563847-14005-18-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446563974 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Map between "system.richacl" xattrs and the in-kernel representation. Signed-off-by: Andreas Gruenbacher --- fs/Makefile | 2 +- fs/richacl_xattr.c | 220 +++++++++++++++++++++++++++++++++++++ fs/xattr.c | 34 +++++- include/linux/richacl_xattr.h | 42 +++++++ include/uapi/linux/Kbuild | 1 + include/uapi/linux/richacl_xattr.h | 44 ++++++++ include/uapi/linux/xattr.h | 2 + 7 files changed, 338 insertions(+), 7 deletions(-) create mode 100644 fs/richacl_xattr.c create mode 100644 include/linux/richacl_xattr.h create mode 100644 include/uapi/linux/richacl_xattr.h diff --git a/fs/Makefile b/fs/Makefile index ec665fd..35e640d 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -49,7 +49,7 @@ obj-$(CONFIG_SYSCTL) += drop_caches.o obj-$(CONFIG_FHANDLE) += fhandle.o obj-$(CONFIG_FS_RICHACL) += richacl.o -richacl-y := richacl_base.o richacl_inode.o +richacl-y := richacl_base.o richacl_inode.o richacl_xattr.o obj-y += quota/ diff --git a/fs/richacl_xattr.c b/fs/richacl_xattr.c new file mode 100644 index 0000000..38473b6 --- /dev/null +++ b/fs/richacl_xattr.c @@ -0,0 +1,220 @@ +/* + * Copyright (C) 2006, 2010 Novell, Inc. + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * 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; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include +#include +#include +#include +#include + +MODULE_LICENSE("GPL"); + +/** + * richacl_from_xattr - convert a richacl xattr into the in-memory representation + */ +struct richacl * +richacl_from_xattr(struct user_namespace *user_ns, + const void *value, size_t size) +{ + const struct richacl_xattr *xattr_acl = value; + const struct richace_xattr *xattr_ace = (void *)(xattr_acl + 1); + struct richacl *acl; + struct richace *ace; + int count; + + if (size < sizeof(*xattr_acl) || + xattr_acl->a_version != RICHACL_XATTR_VERSION || + (xattr_acl->a_flags & ~RICHACL_VALID_FLAGS)) + return ERR_PTR(-EINVAL); + size -= sizeof(*xattr_acl); + count = le16_to_cpu(xattr_acl->a_count); + if (count > RICHACL_XATTR_MAX_COUNT) + return ERR_PTR(-EINVAL); + if (size != count * sizeof(*xattr_ace)) + return ERR_PTR(-EINVAL); + + acl = richacl_alloc(count, GFP_NOFS); + if (!acl) + return ERR_PTR(-ENOMEM); + + acl->a_flags = xattr_acl->a_flags; + acl->a_owner_mask = le32_to_cpu(xattr_acl->a_owner_mask); + if (acl->a_owner_mask & ~RICHACE_VALID_MASK) + goto fail_einval; + acl->a_group_mask = le32_to_cpu(xattr_acl->a_group_mask); + if (acl->a_group_mask & ~RICHACE_VALID_MASK) + goto fail_einval; + acl->a_other_mask = le32_to_cpu(xattr_acl->a_other_mask); + if (acl->a_other_mask & ~RICHACE_VALID_MASK) + goto fail_einval; + + richacl_for_each_entry(ace, acl) { + ace->e_type = le16_to_cpu(xattr_ace->e_type); + ace->e_flags = le16_to_cpu(xattr_ace->e_flags); + ace->e_mask = le32_to_cpu(xattr_ace->e_mask); + + if (ace->e_flags & ~RICHACE_VALID_FLAGS) + goto fail_einval; + if (ace->e_flags & RICHACE_SPECIAL_WHO) { + ace->e_id.special = le32_to_cpu(xattr_ace->e_id); + if (ace->e_id.special > RICHACE_EVERYONE_SPECIAL_ID) + goto fail_einval; + } else if (ace->e_flags & RICHACE_IDENTIFIER_GROUP) { + u32 id = le32_to_cpu(xattr_ace->e_id); + + ace->e_id.gid = make_kgid(user_ns, id); + if (!gid_valid(ace->e_id.gid)) + goto fail_einval; + } else { + u32 id = le32_to_cpu(xattr_ace->e_id); + + ace->e_id.uid = make_kuid(user_ns, id); + if (!uid_valid(ace->e_id.uid)) + goto fail_einval; + } + if (ace->e_type > RICHACE_ACCESS_DENIED_ACE_TYPE || + (ace->e_mask & ~RICHACE_VALID_MASK)) + goto fail_einval; + + xattr_ace++; + } + + return acl; + +fail_einval: + richacl_put(acl); + return ERR_PTR(-EINVAL); +} +EXPORT_SYMBOL_GPL(richacl_from_xattr); + +/** + * richacl_xattr_size - compute the size of the xattr representation of @acl + */ +size_t +richacl_xattr_size(const struct richacl *acl) +{ + size_t size = sizeof(struct richacl_xattr); + + size += sizeof(struct richace_xattr) * acl->a_count; + return size; +} +EXPORT_SYMBOL_GPL(richacl_xattr_size); + +/** + * richacl_to_xattr - convert @acl into its xattr representation + * @acl: the richacl to convert + * @buffer: buffer for the result + * @size: size of @buffer + */ +int +richacl_to_xattr(struct user_namespace *user_ns, + const struct richacl *acl, void *buffer, size_t size) +{ + struct richacl_xattr *xattr_acl = buffer; + struct richace_xattr *xattr_ace; + const struct richace *ace; + size_t real_size; + + real_size = richacl_xattr_size(acl); + if (!buffer) + return real_size; + if (real_size > size) + return -ERANGE; + + xattr_acl->a_version = RICHACL_XATTR_VERSION; + xattr_acl->a_flags = acl->a_flags; + xattr_acl->a_count = cpu_to_le16(acl->a_count); + + xattr_acl->a_owner_mask = cpu_to_le32(acl->a_owner_mask); + xattr_acl->a_group_mask = cpu_to_le32(acl->a_group_mask); + xattr_acl->a_other_mask = cpu_to_le32(acl->a_other_mask); + + xattr_ace = (void *)(xattr_acl + 1); + richacl_for_each_entry(ace, acl) { + xattr_ace->e_type = cpu_to_le16(ace->e_type); + xattr_ace->e_flags = cpu_to_le16(ace->e_flags); + xattr_ace->e_mask = cpu_to_le32(ace->e_mask); + if (ace->e_flags & RICHACE_SPECIAL_WHO) + xattr_ace->e_id = cpu_to_le32(ace->e_id.special); + else if (ace->e_flags & RICHACE_IDENTIFIER_GROUP) + xattr_ace->e_id = + cpu_to_le32(from_kgid(user_ns, ace->e_id.gid)); + else + xattr_ace->e_id = + cpu_to_le32(from_kuid(user_ns, ace->e_id.uid)); + xattr_ace++; + } + return real_size; +} +EXPORT_SYMBOL_GPL(richacl_to_xattr); + +/* + * Fix up the uids and gids in richacl extended attributes in place. + */ +static void richacl_fix_xattr_userns( + struct user_namespace *to, struct user_namespace *from, + void *value, size_t size) +{ + struct richacl_xattr *xattr_acl = value; + struct richace_xattr *xattr_ace = + (struct richace_xattr *)(xattr_acl + 1); + unsigned int count; + + if (!value) + return; + if (size < sizeof(*xattr_acl)) + return; + if (xattr_acl->a_version != cpu_to_le32(RICHACL_XATTR_VERSION)) + return; + size -= sizeof(*xattr_acl); + if (size % sizeof(*xattr_ace)) + return; + count = size / sizeof(*xattr_ace); + for (; count; count--, xattr_ace++) { + if (xattr_ace->e_flags & cpu_to_le16(RICHACE_SPECIAL_WHO)) + continue; + if (xattr_ace->e_flags & + cpu_to_le16(RICHACE_IDENTIFIER_GROUP)) { + u32 id = le32_to_cpu(xattr_ace->e_id); + kgid_t gid = make_kgid(from, id); + + xattr_ace->e_id = cpu_to_le32(from_kgid(to, gid)); + } else { + u32 id = le32_to_cpu(xattr_ace->e_id); + kuid_t uid = make_kuid(from, id); + + xattr_ace->e_id = cpu_to_le32(from_kuid(to, uid)); + } + } +} + +void richacl_fix_xattr_from_user(void *value, size_t size) +{ + struct user_namespace *user_ns = current_user_ns(); + + if (user_ns == &init_user_ns) + return; + richacl_fix_xattr_userns(&init_user_ns, user_ns, value, size); +} + +void richacl_fix_xattr_to_user(void *value, size_t size) +{ + struct user_namespace *user_ns = current_user_ns(); + + if (user_ns == &init_user_ns) + return; + richacl_fix_xattr_userns(user_ns, &init_user_ns, value, size); +} diff --git a/fs/xattr.c b/fs/xattr.c index 072fee1..f2313c6 100644 --- a/fs/xattr.c +++ b/fs/xattr.c @@ -21,6 +21,7 @@ #include #include #include +#include #include @@ -314,6 +315,18 @@ out: } EXPORT_SYMBOL_GPL(vfs_removexattr); +static void +fix_xattr_from_user(const char *kname, void *kvalue, size_t size) +{ + if (strncmp(kname, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) + return; + kname += XATTR_SYSTEM_PREFIX_LEN; + if (!strcmp(kname, XATTR_POSIX_ACL_ACCESS) || + !strcmp(kname, XATTR_POSIX_ACL_DEFAULT)) + posix_acl_fix_xattr_from_user(kvalue, size); + else if (!strcmp(kname, XATTR_RICHACL)) + richacl_fix_xattr_from_user(kvalue, size); +} /* * Extended attribute SET operations @@ -350,9 +363,7 @@ setxattr(struct dentry *d, const char __user *name, const void __user *value, error = -EFAULT; goto out; } - if ((strcmp(kname, XATTR_NAME_POSIX_ACL_ACCESS) == 0) || - (strcmp(kname, XATTR_NAME_POSIX_ACL_DEFAULT) == 0)) - posix_acl_fix_xattr_from_user(kvalue, size); + fix_xattr_from_user(kname, kvalue, size); } error = vfs_setxattr(d, kname, kvalue, size, flags); @@ -419,6 +430,19 @@ SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name, return error; } +static void +fix_xattr_to_user(const char *kname, void *kvalue, size_t size) +{ + if (strncmp(kname, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) + return; + kname += XATTR_SYSTEM_PREFIX_LEN; + if (!strcmp(kname, XATTR_POSIX_ACL_ACCESS) || + !strcmp(kname, XATTR_POSIX_ACL_DEFAULT)) + posix_acl_fix_xattr_to_user(kvalue, size); + else if (!strcmp(kname, XATTR_RICHACL)) + richacl_fix_xattr_to_user(kvalue, size); +} + /* * Extended attribute GET operations */ @@ -451,9 +475,7 @@ getxattr(struct dentry *d, const char __user *name, void __user *value, error = vfs_getxattr(d, kname, kvalue, size); if (error > 0) { - if ((strcmp(kname, XATTR_NAME_POSIX_ACL_ACCESS) == 0) || - (strcmp(kname, XATTR_NAME_POSIX_ACL_DEFAULT) == 0)) - posix_acl_fix_xattr_to_user(kvalue, size); + fix_xattr_to_user(kname, kvalue, size); if (size && copy_to_user(value, kvalue, error)) error = -EFAULT; } else if (error == -ERANGE && size >= XATTR_SIZE_MAX) { diff --git a/include/linux/richacl_xattr.h b/include/linux/richacl_xattr.h new file mode 100644 index 0000000..7fc5ca8 --- /dev/null +++ b/include/linux/richacl_xattr.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2006, 2010 Novell, Inc. + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * 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; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#ifndef __RICHACL_XATTR_H +#define __RICHACL_XATTR_H + +#include +#include + +extern struct richacl *richacl_from_xattr(struct user_namespace *, const void *, + size_t); +extern size_t richacl_xattr_size(const struct richacl *); +extern int richacl_to_xattr(struct user_namespace *, const struct richacl *, + void *, size_t); + +#ifdef CONFIG_FS_RICHACL +extern void richacl_fix_xattr_from_user(void *, size_t); +extern void richacl_fix_xattr_to_user(void *, size_t); +#else +static inline void richacl_fix_xattr_from_user(void *value, size_t size) +{ +} + +static inline void richacl_fix_xattr_to_user(void *value, size_t size) +{ +} +#endif + +#endif /* __RICHACL_XATTR_H */ diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild index 8c82010..18ad070 100644 --- a/include/uapi/linux/Kbuild +++ b/include/uapi/linux/Kbuild @@ -349,6 +349,7 @@ header-y += reiserfs_fs.h header-y += reiserfs_xattr.h header-y += resource.h header-y += richacl.h +header-y += richacl_xattr.h header-y += rfkill.h header-y += romfs_fs.h header-y += rose.h diff --git a/include/uapi/linux/richacl_xattr.h b/include/uapi/linux/richacl_xattr.h new file mode 100644 index 0000000..5178ca6 --- /dev/null +++ b/include/uapi/linux/richacl_xattr.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2006, 2010 Novell, Inc. + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ + +#ifndef __UAPI_RICHACL_XATTR_H +#define __UAPI_RICHACL_XATTR_H + +#include +#include + +struct richace_xattr { + __le16 e_type; + __le16 e_flags; + __le32 e_mask; + __le32 e_id; +}; + +struct richacl_xattr { + unsigned char a_version; + unsigned char a_flags; + __le16 a_count; + __le32 a_owner_mask; + __le32 a_group_mask; + __le32 a_other_mask; +}; + +#define RICHACL_XATTR_VERSION 0 +#define RICHACL_XATTR_MAX_COUNT \ + ((XATTR_SIZE_MAX - sizeof(struct richacl_xattr)) / \ + sizeof(struct richace_xattr)) + +#endif /* __UAPI_RICHACL_XATTR_H */ diff --git a/include/uapi/linux/xattr.h b/include/uapi/linux/xattr.h index 1590c49..1996903 100644 --- a/include/uapi/linux/xattr.h +++ b/include/uapi/linux/xattr.h @@ -73,5 +73,7 @@ #define XATTR_POSIX_ACL_DEFAULT "posix_acl_default" #define XATTR_NAME_POSIX_ACL_DEFAULT XATTR_SYSTEM_PREFIX XATTR_POSIX_ACL_DEFAULT +#define XATTR_RICHACL "richacl" +#define XATTR_NAME_RICHACL XATTR_SYSTEM_PREFIX XATTR_RICHACL #endif /* _UAPI_LINUX_XATTR_H */ -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:19:42 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 50B1A29E30 for ; Tue, 3 Nov 2015 09:19:42 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id E462CAC002 for ; Tue, 3 Nov 2015 07:19:41 -0800 (PST) X-ASG-Debug-ID: 1446563980-04bdf033091fc9f0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id hz8QUPQEMqcmipM1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:19:40 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 92E8A8F4E6; Tue, 3 Nov 2015 15:19:40 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRZi029477; Tue, 3 Nov 2015 10:19:34 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 18/51] richacl: Add richacl xattr handler Date: Tue, 3 Nov 2015 16:16:54 +0100 X-ASG-Orig-Subj: [PATCH v13 18/51] richacl: Add richacl xattr handler Message-Id: <1446563847-14005-19-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446563980 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Add richacl xattr handler implementing the xattr operations based on the get_richacl and set_richacl inode operations. Signed-off-by: Andreas Gruenbacher --- fs/richacl_xattr.c | 78 +++++++++++++++++++++++++++++++++++++++++++ include/linux/richacl_xattr.h | 2 ++ 2 files changed, 80 insertions(+) diff --git a/fs/richacl_xattr.c b/fs/richacl_xattr.c index 38473b6..767c1f7 100644 --- a/fs/richacl_xattr.c +++ b/fs/richacl_xattr.c @@ -18,7 +18,9 @@ #include #include #include +#include #include +#include MODULE_LICENSE("GPL"); @@ -161,6 +163,82 @@ richacl_to_xattr(struct user_namespace *user_ns, } EXPORT_SYMBOL_GPL(richacl_to_xattr); +static size_t +richacl_xattr_list(struct dentry *dentry, char *list, size_t list_len, + const char *name, size_t name_len, int handler_flags) +{ + const size_t size = sizeof(XATTR_NAME_RICHACL); + + if (!IS_RICHACL(d_backing_inode(dentry))) + return 0; + if (list && size <= list_len) + memcpy(list, XATTR_NAME_RICHACL, size); + return size; +} + +static int +richacl_xattr_get(struct dentry *dentry, const char *name, void *buffer, + size_t buffer_size, int handler_flags) +{ + struct inode *inode = d_backing_inode(dentry); + struct richacl *acl; + int error; + + if (strcmp(name, "") != 0) + return -EINVAL; + if (!IS_RICHACL(inode)) + return EOPNOTSUPP; + if (S_ISLNK(inode->i_mode)) + return -EOPNOTSUPP; + acl = get_richacl(inode); + if (IS_ERR(acl)) + return PTR_ERR(acl); + if (acl == NULL) + return -ENODATA; + error = richacl_to_xattr(&init_user_ns, acl, buffer, buffer_size); + richacl_put(acl); + return error; +} + +static int +richacl_xattr_set(struct dentry *dentry, const char *name, + const void *value, size_t size, int flags, int handler_flags) +{ + struct inode *inode = d_backing_inode(dentry); + struct richacl *acl = NULL; + int ret; + + if (strcmp(name, "") != 0) + return -EINVAL; + if (!IS_RICHACL(inode)) + return -EOPNOTSUPP; + if (!inode->i_op->set_richacl) + return -EOPNOTSUPP; + + if (!uid_eq(current_fsuid(), inode->i_uid) && + inode_permission(inode, MAY_CHMOD) && + !capable(CAP_FOWNER)) + return -EPERM; + + if (value) { + acl = richacl_from_xattr(&init_user_ns, value, size); + if (IS_ERR(acl)) + return PTR_ERR(acl); + } + + ret = inode->i_op->set_richacl(inode, acl); + richacl_put(acl); + return ret; +} + +struct xattr_handler richacl_xattr_handler = { + .prefix = XATTR_NAME_RICHACL, + .list = richacl_xattr_list, + .get = richacl_xattr_get, + .set = richacl_xattr_set, +}; +EXPORT_SYMBOL(richacl_xattr_handler); + /* * Fix up the uids and gids in richacl extended attributes in place. */ diff --git a/include/linux/richacl_xattr.h b/include/linux/richacl_xattr.h index 7fc5ca8..45ec27a 100644 --- a/include/linux/richacl_xattr.h +++ b/include/linux/richacl_xattr.h @@ -39,4 +39,6 @@ static inline void richacl_fix_xattr_to_user(void *value, size_t size) } #endif +extern struct xattr_handler richacl_xattr_handler; + #endif /* __RICHACL_XATTR_H */ -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:19:49 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 470C329E1E for ; Tue, 3 Nov 2015 09:19:49 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 16B558F8033 for ; Tue, 3 Nov 2015 07:19:49 -0800 (PST) X-ASG-Debug-ID: 1446563987-04bdf0330a1fca10001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id VgWJkRpYlrVZGcoH (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:19:47 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 82F598F4FB; Tue, 3 Nov 2015 15:19:47 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRZj029477; Tue, 3 Nov 2015 10:19:41 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 19/51] vfs: Add richacl permission checking Date: Tue, 3 Nov 2015 16:16:55 +0100 X-ASG-Orig-Subj: [PATCH v13 19/51] vfs: Add richacl permission checking Message-Id: <1446563847-14005-20-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446563987 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Hook the richacl permission checking function into the vfs. Signed-off-by: Andreas Gruenbacher --- fs/namei.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++-- fs/posix_acl.c | 6 +++--- 2 files changed, 52 insertions(+), 5 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 2eab19e..3822b5e 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include "internal.h" @@ -255,7 +256,40 @@ void putname(struct filename *name) __putname(name); } -static int check_acl(struct inode *inode, int mask) +static int check_richacl(struct inode *inode, int mask) +{ +#ifdef CONFIG_FS_RICHACL + struct richacl *acl; + + if (mask & MAY_NOT_BLOCK) { + acl = get_cached_richacl_rcu(inode); + if (!acl) + goto no_acl; + /* no ->get_richacl() calls in RCU mode... */ + if (acl == ACL_NOT_CACHED) + return -ECHILD; + return richacl_permission(inode, acl, mask & ~MAY_NOT_BLOCK); + } + + acl = get_richacl(inode); + if (IS_ERR(acl)) + return PTR_ERR(acl); + if (acl) { + int error = richacl_permission(inode, acl, mask); + richacl_put(acl); + return error; + } +no_acl: +#endif + if (mask & (MAY_DELETE_SELF | MAY_TAKE_OWNERSHIP | + MAY_CHMOD | MAY_SET_TIMES)) { + /* File permission bits cannot grant this. */ + return -EACCES; + } + return -EAGAIN; +} + +static int check_posix_acl(struct inode *inode, int mask) { #ifdef CONFIG_FS_POSIX_ACL struct posix_acl *acl; @@ -290,11 +324,24 @@ static int acl_permission_check(struct inode *inode, int mask) { unsigned int mode = inode->i_mode; + /* + * With POSIX ACLs, the (mode & S_IRWXU) bits exactly match the owner + * permissions, and we can skip checking posix acls for the owner. + * With richacls, the owner may be granted fewer permissions than the + * mode bits seem to suggest (for example, append but not write), and + * we always need to check the richacl. + */ + + if (IS_RICHACL(inode)) { + int error = check_richacl(inode, mask); + if (error != -EAGAIN) + return error; + } if (likely(uid_eq(current_fsuid(), inode->i_uid))) mode >>= 6; else { if (IS_POSIXACL(inode) && (mode & S_IRWXG)) { - int error = check_acl(inode, mask); + int error = check_posix_acl(inode, mask); if (error != -EAGAIN) return error; } diff --git a/fs/posix_acl.c b/fs/posix_acl.c index 1d766a5..3459bd5 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c @@ -100,13 +100,13 @@ struct posix_acl *get_acl(struct inode *inode, int type) { struct posix_acl *acl; + if (!IS_POSIXACL(inode)) + return NULL; + acl = get_cached_acl(inode, type); if (acl != ACL_NOT_CACHED) return acl; - if (!IS_POSIXACL(inode)) - return NULL; - /* * A filesystem can force a ACL callback by just never filling the * ACL cache. But normally you'd fill the cache either at inode -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:19:58 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 41F1029E1E for ; Tue, 3 Nov 2015 09:19:58 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id ABF98AC004 for ; Tue, 3 Nov 2015 07:19:57 -0800 (PST) X-ASG-Debug-ID: 1446563995-04cb6c7b871ddbd0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id SH9stbyQpNu7xyP7 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:19:55 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id D8DCD8E69D; Tue, 3 Nov 2015 15:19:54 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRZk029477; Tue, 3 Nov 2015 10:19:48 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: "Aneesh Kumar K.V" , Andreas Gruenbacher Subject: [PATCH v13 20/51] ext4: Add richacl support Date: Tue, 3 Nov 2015 16:16:56 +0100 X-ASG-Orig-Subj: [PATCH v13 20/51] ext4: Add richacl support Message-Id: <1446563847-14005-21-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446563995 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: "Aneesh Kumar K.V" Support the richacl permission model in ext4. The richacls are stored in "system.richacl" xattrs. Richacls need to be enabled by tune2fs or at file system create time. Signed-off-by: Aneesh Kumar K.V Signed-off-by: Andreas Gruenbacher --- fs/ext4/Kconfig | 11 +++++ fs/ext4/Makefile | 1 + fs/ext4/file.c | 3 ++ fs/ext4/ialloc.c | 11 ++++- fs/ext4/inode.c | 12 ++++- fs/ext4/namei.c | 5 ++ fs/ext4/richacl.c | 141 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ fs/ext4/richacl.h | 40 ++++++++++++++++ fs/ext4/xattr.c | 7 +++ 9 files changed, 228 insertions(+), 3 deletions(-) create mode 100644 fs/ext4/richacl.c create mode 100644 fs/ext4/richacl.h diff --git a/fs/ext4/Kconfig b/fs/ext4/Kconfig index b46e9fc..65c5230 100644 --- a/fs/ext4/Kconfig +++ b/fs/ext4/Kconfig @@ -22,6 +22,17 @@ config EXT3_FS_POSIX_ACL This config option is here only for backward compatibility. ext3 filesystem is now handled by the ext4 driver. +config EXT4_FS_RICHACL + bool "Ext4 Rich Access Control Lists (EXPERIMENTAL)" + depends on EXT4_FS + select FS_RICHACL + help + Richacls are an implementation of NFSv4 ACLs, extended by file masks + to cleanly integrate into the POSIX file permission model. To learn + more about them, see http://www.bestbits.at/richacl/. + + If you don't know what Richacls are, say N. + config EXT3_FS_SECURITY bool "Ext3 Security Labels" depends on EXT3_FS diff --git a/fs/ext4/Makefile b/fs/ext4/Makefile index 75285ea..ea0d539 100644 --- a/fs/ext4/Makefile +++ b/fs/ext4/Makefile @@ -14,3 +14,4 @@ ext4-$(CONFIG_EXT4_FS_POSIX_ACL) += acl.o ext4-$(CONFIG_EXT4_FS_SECURITY) += xattr_security.o ext4-$(CONFIG_EXT4_FS_ENCRYPTION) += crypto_policy.o crypto.o \ crypto_key.o crypto_fname.o +ext4-$(CONFIG_EXT4_FS_RICHACL) += richacl.o diff --git a/fs/ext4/file.c b/fs/ext4/file.c index 113837e..a03b4a5 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c @@ -30,6 +30,7 @@ #include "ext4_jbd2.h" #include "xattr.h" #include "acl.h" +#include "richacl.h" /* * Called when an inode is released. Note that this is different @@ -719,6 +720,8 @@ const struct inode_operations ext4_file_inode_operations = { .removexattr = generic_removexattr, .get_acl = ext4_get_acl, .set_acl = ext4_set_acl, + .get_richacl = ext4_get_richacl, + .set_richacl = ext4_set_richacl, .fiemap = ext4_fiemap, }; diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index 619bfc1..9657b3a 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c @@ -27,6 +27,7 @@ #include "ext4_jbd2.h" #include "xattr.h" #include "acl.h" +#include "richacl.h" #include @@ -697,6 +698,14 @@ out: return ret; } +static inline int +ext4_new_acl(handle_t *handle, struct inode *inode, struct inode *dir) +{ + if (IS_RICHACL(dir)) + return ext4_init_richacl(handle, inode, dir); + return ext4_init_acl(handle, inode, dir); +} + /* * There are two policies for allocating an inode. If the new inode is * a directory, then a forward search is made for a block group with both @@ -1052,7 +1061,7 @@ got: if (err) goto fail_drop; - err = ext4_init_acl(handle, inode, dir); + err = ext4_new_acl(handle, inode, dir); if (err) goto fail_free_drop; diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 612fbcf..647f3c3 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -42,6 +42,7 @@ #include "xattr.h" #include "acl.h" #include "truncate.h" +#include "richacl.h" #include @@ -4638,6 +4639,14 @@ static void ext4_wait_for_tail_page_commit(struct inode *inode) } } +static inline int +ext4_acl_chmod(struct inode *inode, umode_t mode) +{ + if (IS_RICHACL(inode)) + return richacl_chmod(inode, inode->i_mode); + return posix_acl_chmod(inode, inode->i_mode); +} + /* * ext4_setattr() * @@ -4806,8 +4815,7 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr) ext4_orphan_del(NULL, inode); if (!rc && (ia_valid & ATTR_MODE)) - rc = posix_acl_chmod(inode, inode->i_mode); - + rc = ext4_acl_chmod(inode, inode->i_mode); err_out: ext4_std_error(inode->i_sb, error); if (!error) diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 9f61e76..9b6e8b9 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -38,6 +38,7 @@ #include "xattr.h" #include "acl.h" +#include "richacl.h" #include /* @@ -3854,6 +3855,8 @@ const struct inode_operations ext4_dir_inode_operations = { .removexattr = generic_removexattr, .get_acl = ext4_get_acl, .set_acl = ext4_set_acl, + .get_richacl = ext4_get_richacl, + .set_richacl = ext4_set_richacl, .fiemap = ext4_fiemap, }; @@ -3865,4 +3868,6 @@ const struct inode_operations ext4_special_inode_operations = { .removexattr = generic_removexattr, .get_acl = ext4_get_acl, .set_acl = ext4_set_acl, + .get_richacl = ext4_get_richacl, + .set_richacl = ext4_set_richacl, }; diff --git a/fs/ext4/richacl.c b/fs/ext4/richacl.c new file mode 100644 index 0000000..906d048 --- /dev/null +++ b/fs/ext4/richacl.c @@ -0,0 +1,141 @@ +/* + * Copyright IBM Corporation, 2010 + * Copyright (C) 2015 Red Hat, Inc. + * Author: Aneesh Kumar K.V , + * Andreas Gruenbacher + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2.1 of the GNU Lesser 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. + * + */ + +#include +#include +#include + +#include "ext4.h" +#include "ext4_jbd2.h" +#include "xattr.h" +#include "acl.h" +#include "richacl.h" + +struct richacl * +ext4_get_richacl(struct inode *inode) +{ + const int name_index = EXT4_XATTR_INDEX_RICHACL; + void *value = NULL; + struct richacl *acl = NULL; + int retval; + + retval = ext4_xattr_get(inode, name_index, "", NULL, 0); + if (retval > 0) { + value = kmalloc(retval, GFP_NOFS); + if (!value) + return ERR_PTR(-ENOMEM); + retval = ext4_xattr_get(inode, name_index, "", value, retval); + } + if (retval > 0) { + acl = richacl_from_xattr(&init_user_ns, value, retval); + if (acl == ERR_PTR(-EINVAL)) + acl = ERR_PTR(-EIO); + } else if (retval != -ENODATA && retval != -ENOSYS) + acl = ERR_PTR(retval); + kfree(value); + + if (!IS_ERR(acl)) + set_cached_richacl(inode, acl); + + return acl; +} + +static int +__ext4_remove_richacl(handle_t *handle, struct inode *inode) +{ + const int name_index = EXT4_XATTR_INDEX_RICHACL; + int retval; + + retval = ext4_xattr_set_handle(handle, inode, name_index, "", + NULL, 0, 0); + if (!retval) + set_cached_richacl(inode, NULL); + return retval; +} + +static int +__ext4_set_richacl(handle_t *handle, struct inode *inode, struct richacl *acl) +{ + const int name_index = EXT4_XATTR_INDEX_RICHACL; + umode_t mode = inode->i_mode; + int retval, size; + void *value; + + if (richacl_equiv_mode(acl, &mode) == 0) { + inode->i_ctime = ext4_current_time(inode); + inode->i_mode = mode; + ext4_mark_inode_dirty(handle, inode); + return __ext4_remove_richacl(handle, inode); + } + + mode &= ~S_IRWXUGO; + mode |= richacl_masks_to_mode(acl); + + size = richacl_xattr_size(acl); + value = kmalloc(size, GFP_NOFS); + if (!value) + return -ENOMEM; + richacl_to_xattr(&init_user_ns, acl, value, size); + inode->i_mode = mode; + retval = ext4_xattr_set_handle(handle, inode, name_index, "", + value, size, 0); + kfree(value); + if (retval) + return retval; + + set_cached_richacl(inode, acl); + + return 0; +} + +int +ext4_set_richacl(struct inode *inode, struct richacl *acl) +{ + handle_t *handle; + int retval, retries = 0; + +retry: + handle = ext4_journal_start(inode, EXT4_HT_XATTR, + ext4_jbd2_credits_xattr(inode)); + if (IS_ERR(handle)) + return PTR_ERR(handle); + + if (acl) + retval = __ext4_set_richacl(handle, inode, acl); + else + retval = __ext4_remove_richacl(handle, inode); + + ext4_journal_stop(handle); + if (retval == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) + goto retry; + return retval; +} + +int +ext4_init_richacl(handle_t *handle, struct inode *inode, struct inode *dir) +{ + struct richacl *acl = richacl_create(&inode->i_mode, dir); + int error; + + error = PTR_ERR(acl); + if (IS_ERR(acl)) + return error; + if (acl) { + error = __ext4_set_richacl(handle, inode, acl); + richacl_put(acl); + } + return error; +} diff --git a/fs/ext4/richacl.h b/fs/ext4/richacl.h new file mode 100644 index 0000000..6fe9a92 --- /dev/null +++ b/fs/ext4/richacl.h @@ -0,0 +1,40 @@ +/* + * Copyright IBM Corporation, 2010 + * Copyright (C) 2015 Red Hat, Inc. + * Author Aneesh Kumar K.V + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2.1 of the GNU Lesser 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. + * + */ + +#ifndef __FS_EXT4_RICHACL_H +#define __FS_EXT4_RICHACL_H + +#include + +#ifdef CONFIG_EXT4_FS_RICHACL + +extern struct richacl *ext4_get_richacl(struct inode *); +extern int ext4_set_richacl(struct inode *, struct richacl *); + +extern int ext4_init_richacl(handle_t *, struct inode *, struct inode *); + +#else /* CONFIG_EXT4_FS_RICHACL */ + +#define ext4_get_richacl NULL +#define ext4_set_richacl NULL + +static inline int +ext4_init_richacl(handle_t *handle, struct inode *inode, struct inode *dir) +{ + return 0; +} + +#endif /* CONFIG_EXT4_FS_RICHACL */ +#endif /* __FS_EXT4_RICHACL_H */ diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index 16e28c0..4d79adb 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -55,6 +55,7 @@ #include #include #include +#include #include "ext4_jbd2.h" #include "ext4.h" #include "xattr.h" @@ -99,6 +100,9 @@ static const struct xattr_handler *ext4_xattr_handler_map[] = { #ifdef CONFIG_EXT4_FS_SECURITY [EXT4_XATTR_INDEX_SECURITY] = &ext4_xattr_security_handler, #endif +#ifdef CONFIG_EXT4_FS_RICHACL + [EXT4_XATTR_INDEX_RICHACL] = &richacl_xattr_handler, +#endif }; const struct xattr_handler *ext4_xattr_handlers[] = { @@ -111,6 +115,9 @@ const struct xattr_handler *ext4_xattr_handlers[] = { #ifdef CONFIG_EXT4_FS_SECURITY &ext4_xattr_security_handler, #endif +#ifdef CONFIG_EXT4_FS_RICHACL + &richacl_xattr_handler, +#endif NULL }; -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:20:05 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 BEB1629E1E for ; Tue, 3 Nov 2015 09:20:05 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 37B2AAC002 for ; Tue, 3 Nov 2015 07:20:05 -0800 (PST) X-ASG-Debug-ID: 1446564002-04cb6c7b841ddbe0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id eyhB4CGtdkOFg7C4 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:20:03 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 42374AB8; Tue, 3 Nov 2015 15:20:02 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRZl029477; Tue, 3 Nov 2015 10:19:55 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: "Aneesh Kumar K.V" , Andreas Gruenbacher Subject: [PATCH v13 21/51] ext4: Add richacl feature flag Date: Tue, 3 Nov 2015 16:16:57 +0100 X-ASG-Orig-Subj: [PATCH v13 21/51] ext4: Add richacl feature flag Message-Id: <1446563847-14005-22-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446564002 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: "Aneesh Kumar K.V" This feature flag selects richacl instead of posix acl support on the file system. In addition, the "acl" mount option is needed for enabling either of the two kinds of acls. Signed-off-by: Aneesh Kumar K.V Signed-off-by: Andreas Gruenbacher --- fs/ext4/ext4.h | 6 ++++-- fs/ext4/super.c | 49 ++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 44 insertions(+), 11 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index fd1f28b..b97a3b1 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -991,7 +991,7 @@ struct ext4_inode_info { #define EXT4_MOUNT_UPDATE_JOURNAL 0x01000 /* Update the journal format */ #define EXT4_MOUNT_NO_UID32 0x02000 /* Disable 32-bit UIDs */ #define EXT4_MOUNT_XATTR_USER 0x04000 /* Extended user attributes */ -#define EXT4_MOUNT_POSIX_ACL 0x08000 /* POSIX Access Control Lists */ +#define EXT4_MOUNT_ACL 0x08000 /* Access Control Lists */ #define EXT4_MOUNT_NO_AUTO_DA_ALLOC 0x10000 /* No auto delalloc mapping */ #define EXT4_MOUNT_BARRIER 0x20000 /* Use block barriers */ #define EXT4_MOUNT_QUOTA 0x80000 /* Some quota option set */ @@ -1582,6 +1582,7 @@ static inline int ext4_encrypted_inode(struct inode *inode) #define EXT4_FEATURE_INCOMPAT_LARGEDIR 0x4000 /* >2GB or 3-lvl htree */ #define EXT4_FEATURE_INCOMPAT_INLINE_DATA 0x8000 /* data in inode */ #define EXT4_FEATURE_INCOMPAT_ENCRYPT 0x10000 +#define EXT4_FEATURE_INCOMPAT_RICHACL 0x20000 #define EXT2_FEATURE_COMPAT_SUPP EXT4_FEATURE_COMPAT_EXT_ATTR #define EXT2_FEATURE_INCOMPAT_SUPP (EXT4_FEATURE_INCOMPAT_FILETYPE| \ @@ -1607,7 +1608,8 @@ static inline int ext4_encrypted_inode(struct inode *inode) EXT4_FEATURE_INCOMPAT_FLEX_BG| \ EXT4_FEATURE_INCOMPAT_MMP | \ EXT4_FEATURE_INCOMPAT_INLINE_DATA | \ - EXT4_FEATURE_INCOMPAT_ENCRYPT) + EXT4_FEATURE_INCOMPAT_ENCRYPT | \ + EXT4_FEATURE_INCOMPAT_RICHACL) #define EXT4_FEATURE_RO_COMPAT_SUPP (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER| \ EXT4_FEATURE_RO_COMPAT_LARGE_FILE| \ EXT4_FEATURE_RO_COMPAT_GDT_CSUM| \ diff --git a/fs/ext4/super.c b/fs/ext4/super.c index a63c7b0..7457ea8 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1270,6 +1270,28 @@ static ext4_fsblk_t get_sb_block(void **data) return sb_block; } +static int enable_acl(struct super_block *sb) +{ + sb->s_flags &= ~(MS_POSIXACL | MS_RICHACL); + if (test_opt(sb, ACL)) { + if (EXT4_HAS_INCOMPAT_FEATURE(sb, + EXT4_FEATURE_INCOMPAT_RICHACL)) { +#ifdef CONFIG_EXT4_FS_RICHACL + sb->s_flags |= MS_RICHACL; +#else + return -EOPNOTSUPP; +#endif + } else { +#ifdef CONFIG_EXT4_FS_POSIX_ACL + sb->s_flags |= MS_POSIXACL; +#else + return -EOPNOTSUPP; +#endif + } + } + return 0; +} + #define DEFAULT_JOURNAL_IOPRIO (IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 3)) static char deprecated_msg[] = "Mount option \"%s\" will be removed by %s\n" "Contact linux-ext4@vger.kernel.org if you think we should keep it.\n"; @@ -1416,9 +1438,9 @@ static const struct mount_opts { MOPT_NO_EXT2 | MOPT_DATAJ}, {Opt_user_xattr, EXT4_MOUNT_XATTR_USER, MOPT_SET}, {Opt_nouser_xattr, EXT4_MOUNT_XATTR_USER, MOPT_CLEAR}, -#ifdef CONFIG_EXT4_FS_POSIX_ACL - {Opt_acl, EXT4_MOUNT_POSIX_ACL, MOPT_SET}, - {Opt_noacl, EXT4_MOUNT_POSIX_ACL, MOPT_CLEAR}, +#if defined(CONFIG_EXT4_FS_POSIX_ACL) || defined(CONFIG_EXT4_FS_RICHACL) + {Opt_acl, EXT4_MOUNT_ACL, MOPT_SET}, + {Opt_noacl, EXT4_MOUNT_ACL, MOPT_CLEAR}, #else {Opt_acl, 0, MOPT_NOSUPPORT}, {Opt_noacl, 0, MOPT_NOSUPPORT}, @@ -1466,6 +1488,13 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token, #endif switch (token) { case Opt_noacl: +#ifdef CONFIG_EXT4_FS_RICHACL + if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RICHACL)) { + ext4_msg(sb, KERN_ERR, "Mount option \"%s\" incompatible " + "with richacl feature", opt); + return -1; + } +#endif case Opt_nouser_xattr: ext4_msg(sb, KERN_WARNING, deprecated_msg, opt, "3.5"); break; @@ -3576,8 +3605,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) set_opt(sb, NO_UID32); /* xattr user namespace & acls are now defaulted on */ set_opt(sb, XATTR_USER); -#ifdef CONFIG_EXT4_FS_POSIX_ACL - set_opt(sb, POSIX_ACL); +#if defined(CONFIG_EXT4_FS_POSIX_ACL) || defined(CONFIG_EXT4_FS_RICHACL) + set_opt(sb, ACL); #endif /* don't forget to enable journal_csum when metadata_csum is enabled. */ if (ext4_has_metadata_csum(sb)) @@ -3660,8 +3689,9 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) sb->s_iflags |= SB_I_CGROUPWB; } - sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | - (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0); + err = enable_acl(sb); + if (err) + goto failed_mount; if (le32_to_cpu(es->s_rev_level) == EXT4_GOOD_OLD_REV && (EXT4_HAS_COMPAT_FEATURE(sb, ~0U) || @@ -4981,8 +5011,9 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) if (sbi->s_mount_flags & EXT4_MF_FS_ABORTED) ext4_abort(sb, "Abort forced by user"); - sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | - (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0); + err = enable_acl(sb); + if (err) + goto restore_opts; es = sbi->s_es; -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:20:11 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 5415529E2C for ; Tue, 3 Nov 2015 09:20:11 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id DFB36AC004 for ; Tue, 3 Nov 2015 07:20:10 -0800 (PST) X-ASG-Debug-ID: 1446564009-04cbb0660e1f7cb0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id TOqxQcbX6dZybB7S (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:20:09 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 293468FAA3; Tue, 3 Nov 2015 15:20:09 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRZm029477; Tue, 3 Nov 2015 10:20:02 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 22/51] xfs: Fix error path in xfs_get_acl Date: Tue, 3 Nov 2015 16:16:58 +0100 X-ASG-Orig-Subj: [PATCH v13 22/51] xfs: Fix error path in xfs_get_acl Message-Id: <1446563847-14005-23-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446564009 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Error codes from xfs_attr_get other than -ENOATTR were not properly reported. Fix that. In addition, the declaration of struct xfs_inode in xfs_acl.h isn't needed. Signed-off-by: Andreas Gruenbacher --- fs/xfs/xfs_acl.c | 1 + fs/xfs/xfs_acl.h | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c index 4b64167..e87fd3f 100644 --- a/fs/xfs/xfs_acl.c +++ b/fs/xfs/xfs_acl.c @@ -160,6 +160,7 @@ xfs_get_acl(struct inode *inode, int type) */ if (error == -ENOATTR) goto out_update_cache; + acl = ERR_PTR(error); goto out; } diff --git a/fs/xfs/xfs_acl.h b/fs/xfs/xfs_acl.h index 3841b07..9ee0a0d 100644 --- a/fs/xfs/xfs_acl.h +++ b/fs/xfs/xfs_acl.h @@ -20,7 +20,6 @@ struct inode; struct posix_acl; -struct xfs_inode; #ifdef CONFIG_XFS_POSIX_ACL extern struct posix_acl *xfs_get_acl(struct inode *inode, int type); -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:20:19 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 4651C29E3E for ; Tue, 3 Nov 2015 09:20:19 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 355AF304039 for ; Tue, 3 Nov 2015 07:20:19 -0800 (PST) X-ASG-Debug-ID: 1446564016-04cb6c7b871ddc10001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 0nsN5vFWcYQCOPGj (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:20:17 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 458EE8F4E6; Tue, 3 Nov 2015 15:20:16 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRZn029477; Tue, 3 Nov 2015 10:20:09 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 23/51] xfs: Make xfs_set_mode non-static Date: Tue, 3 Nov 2015 16:16:59 +0100 X-ASG-Orig-Subj: [PATCH v13 23/51] xfs: Make xfs_set_mode non-static Message-Id: <1446563847-14005-24-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446564016 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Make xfs_set_mode non-static and move it from xfs_acl.c into xfs_inode.c. Signed-off-by: Andreas Gruenbacher --- fs/xfs/xfs_acl.c | 18 ------------------ fs/xfs/xfs_inode.c | 24 ++++++++++++++++++++++++ fs/xfs/xfs_inode.h | 2 ++ 3 files changed, 26 insertions(+), 18 deletions(-) diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c index e87fd3f..7b03383 100644 --- a/fs/xfs/xfs_acl.c +++ b/fs/xfs/xfs_acl.c @@ -232,24 +232,6 @@ __xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl) } static int -xfs_set_mode(struct inode *inode, umode_t mode) -{ - int error = 0; - - if (mode != inode->i_mode) { - struct iattr iattr; - - iattr.ia_valid = ATTR_MODE | ATTR_CTIME; - iattr.ia_mode = mode; - iattr.ia_ctime = current_fs_time(inode->i_sb); - - error = xfs_setattr_nonsize(XFS_I(inode), &iattr, XFS_ATTR_NOACL); - } - - return error; -} - -static int xfs_acl_exists(struct inode *inode, unsigned char *name) { int len = XFS_ACL_MAX_SIZE(XFS_M(inode->i_sb)); diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index dc40a6d..644fa04 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -3587,3 +3587,27 @@ xfs_iflush_int( corrupt_out: return -EFSCORRUPTED; } + +/* + * Set an inode's file mode. + * + * Called when updating an inode's file mode as part of setting an ACL only. + * The VFS goes through the setattr inode operation instead. + */ +int +xfs_set_mode(struct inode *inode, umode_t mode) +{ + int error = 0; + + if (mode != inode->i_mode) { + struct iattr iattr; + + iattr.ia_valid = ATTR_MODE | ATTR_CTIME; + iattr.ia_mode = mode; + iattr.ia_ctime = current_fs_time(inode->i_sb); + + error = xfs_setattr_nonsize(XFS_I(inode), &iattr, XFS_ATTR_NOACL); + } + + return error; +} diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index ca9e119..7b22db0 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h @@ -424,6 +424,8 @@ int xfs_dir_ialloc(struct xfs_trans **, struct xfs_inode *, umode_t, int xfs_droplink(struct xfs_trans *, struct xfs_inode *); int xfs_bumplink(struct xfs_trans *, struct xfs_inode *); +int xfs_set_mode(struct inode *, umode_t); + /* from xfs_file.c */ enum xfs_prealloc_flags { XFS_PREALLOC_SET = (1 << 1), -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:20:26 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 08B6829E2C for ; Tue, 3 Nov 2015 09:20:26 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 7776BAC004 for ; Tue, 3 Nov 2015 07:20:25 -0800 (PST) X-ASG-Debug-ID: 1446564023-04cbb0660c1f7cc0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id gq8LGOGcwQKRJHfp (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:20:23 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 2B296AB8; Tue, 3 Nov 2015 15:20:23 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRZo029477; Tue, 3 Nov 2015 10:20:16 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 24/51] xfs: Change how listxattr generates synthetic attributes Date: Tue, 3 Nov 2015 16:17:00 +0100 X-ASG-Orig-Subj: [PATCH v13 24/51] xfs: Change how listxattr generates synthetic attributes Message-Id: <1446563847-14005-25-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446564023 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Instead of adding the synthesized POSIX ACL attribute names after listing all non-synthesized attributes, generate them immediately when listing the non-synthesized attributes. In addition, merge xfs_xattr_put_listent and xfs_xattr_put_listent_sizes to ensure that the list size is computed correctly; the split version was overestimating the list size for non-root users. Signed-off-by: Andreas Gruenbacher --- fs/xfs/xfs_acl.c | 23 --------- fs/xfs/xfs_acl.h | 4 -- fs/xfs/xfs_xattr.c | 137 +++++++++++++++++++++++------------------------------ 3 files changed, 59 insertions(+), 105 deletions(-) diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c index 7b03383..778a464 100644 --- a/fs/xfs/xfs_acl.c +++ b/fs/xfs/xfs_acl.c @@ -231,29 +231,6 @@ __xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl) return error; } -static int -xfs_acl_exists(struct inode *inode, unsigned char *name) -{ - int len = XFS_ACL_MAX_SIZE(XFS_M(inode->i_sb)); - - return (xfs_attr_get(XFS_I(inode), name, NULL, &len, - ATTR_ROOT|ATTR_KERNOVAL) == 0); -} - -int -posix_acl_access_exists(struct inode *inode) -{ - return xfs_acl_exists(inode, SGI_ACL_FILE); -} - -int -posix_acl_default_exists(struct inode *inode) -{ - if (!S_ISDIR(inode->i_mode)) - return 0; - return xfs_acl_exists(inode, SGI_ACL_DEFAULT); -} - int xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type) { diff --git a/fs/xfs/xfs_acl.h b/fs/xfs/xfs_acl.h index 9ee0a0d..cf973f5 100644 --- a/fs/xfs/xfs_acl.h +++ b/fs/xfs/xfs_acl.h @@ -24,15 +24,11 @@ struct posix_acl; #ifdef CONFIG_XFS_POSIX_ACL extern struct posix_acl *xfs_get_acl(struct inode *inode, int type); extern int xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type); -extern int posix_acl_access_exists(struct inode *inode); -extern int posix_acl_default_exists(struct inode *inode); #else static inline struct posix_acl *xfs_get_acl(struct inode *inode, int type) { return NULL; } # define xfs_set_acl NULL -# define posix_acl_access_exists(inode) 0 -# define posix_acl_default_exists(inode) 0 #endif /* CONFIG_XFS_POSIX_ACL */ #endif /* __XFS_ACL_H__ */ diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c index c0368151..8428aed 100644 --- a/fs/xfs/xfs_xattr.c +++ b/fs/xfs/xfs_xattr.c @@ -106,47 +106,19 @@ const struct xattr_handler *xfs_xattr_handlers[] = { NULL }; -static unsigned int xfs_xattr_prefix_len(int flags) -{ - if (flags & XFS_ATTR_SECURE) - return sizeof("security"); - else if (flags & XFS_ATTR_ROOT) - return sizeof("trusted"); - else - return sizeof("user"); -} - -static const char *xfs_xattr_prefix(int flags) -{ - if (flags & XFS_ATTR_SECURE) - return xfs_xattr_security_handler.prefix; - else if (flags & XFS_ATTR_ROOT) - return xfs_xattr_trusted_handler.prefix; - else - return xfs_xattr_user_handler.prefix; -} - static int -xfs_xattr_put_listent( +__xfs_xattr_put_listent( struct xfs_attr_list_context *context, - int flags, - unsigned char *name, - int namelen, - int valuelen, - unsigned char *value) + char *prefix, + int prefix_len, + unsigned char *name, + int namelen) { - unsigned int prefix_len = xfs_xattr_prefix_len(flags); char *offset; int arraytop; - ASSERT(context->count >= 0); - - /* - * Only show root namespace entries if we are actually allowed to - * see them. - */ - if ((flags & XFS_ATTR_ROOT) && !capable(CAP_SYS_ADMIN)) - return 0; + if (!context->alist) + goto compute_size; arraytop = context->count + prefix_len + namelen + 1; if (arraytop > context->firstu) { @@ -154,17 +126,19 @@ xfs_xattr_put_listent( return 1; } offset = (char *)context->alist + context->count; - strncpy(offset, xfs_xattr_prefix(flags), prefix_len); + strncpy(offset, prefix, prefix_len); offset += prefix_len; strncpy(offset, (char *)name, namelen); /* real name */ offset += namelen; *offset = '\0'; + +compute_size: context->count += prefix_len + namelen + 1; return 0; } static int -xfs_xattr_put_listent_sizes( +xfs_xattr_put_listent( struct xfs_attr_list_context *context, int flags, unsigned char *name, @@ -172,24 +146,55 @@ xfs_xattr_put_listent_sizes( int valuelen, unsigned char *value) { - context->count += xfs_xattr_prefix_len(flags) + namelen + 1; - return 0; -} + char *prefix; + int prefix_len; -static int -list_one_attr(const char *name, const size_t len, void *data, - size_t size, ssize_t *result) -{ - char *p = data + *result; + ASSERT(context->count >= 0); - *result += len; - if (!size) - return 0; - if (*result > size) - return -ERANGE; + if (flags & XFS_ATTR_ROOT) { +#ifdef CONFIG_XFS_POSIX_ACL + if (namelen == SGI_ACL_FILE_SIZE && + strncmp(name, SGI_ACL_FILE, + SGI_ACL_FILE_SIZE) == 0) { + int ret = __xfs_xattr_put_listent( + context, XATTR_SYSTEM_PREFIX, + XATTR_SYSTEM_PREFIX_LEN, + XATTR_POSIX_ACL_ACCESS, + strlen(XATTR_POSIX_ACL_ACCESS)); + if (ret) + return ret; + } else if (namelen == SGI_ACL_DEFAULT_SIZE && + strncmp(name, SGI_ACL_DEFAULT, + SGI_ACL_DEFAULT_SIZE) == 0) { + int ret = __xfs_xattr_put_listent( + context, XATTR_SYSTEM_PREFIX, + XATTR_SYSTEM_PREFIX_LEN, + XATTR_POSIX_ACL_DEFAULT, + strlen(XATTR_POSIX_ACL_DEFAULT)); + if (ret) + return ret; + } +#endif - strcpy(p, name); - return 0; + /* + * Only show root namespace entries if we are actually allowed to + * see them. + */ + if (!capable(CAP_SYS_ADMIN)) + return 0; + + prefix = XATTR_TRUSTED_PREFIX; + prefix_len = XATTR_TRUSTED_PREFIX_LEN; + } else if (flags & XFS_ATTR_SECURE) { + prefix = XATTR_SECURITY_PREFIX; + prefix_len = XATTR_SECURITY_PREFIX_LEN; + } else { + prefix = XATTR_USER_PREFIX; + prefix_len = XATTR_USER_PREFIX_LEN; + } + + return __xfs_xattr_put_listent(context, prefix, prefix_len, name, + namelen); } ssize_t @@ -198,7 +203,6 @@ xfs_vn_listxattr(struct dentry *dentry, char *data, size_t size) struct xfs_attr_list_context context; struct attrlist_cursor_kern cursor = { 0 }; struct inode *inode = d_inode(dentry); - int error; /* * First read the regular on-disk attributes. @@ -207,37 +211,14 @@ xfs_vn_listxattr(struct dentry *dentry, char *data, size_t size) context.dp = XFS_I(inode); context.cursor = &cursor; context.resynch = 1; - context.alist = data; + context.alist = size ? data : NULL; context.bufsize = size; context.firstu = context.bufsize; - - if (size) - context.put_listent = xfs_xattr_put_listent; - else - context.put_listent = xfs_xattr_put_listent_sizes; + context.put_listent = xfs_xattr_put_listent; xfs_attr_list_int(&context); if (context.count < 0) return -ERANGE; - /* - * Then add the two synthetic ACL attributes. - */ - if (posix_acl_access_exists(inode)) { - error = list_one_attr(POSIX_ACL_XATTR_ACCESS, - strlen(POSIX_ACL_XATTR_ACCESS) + 1, - data, size, &context.count); - if (error) - return error; - } - - if (posix_acl_default_exists(inode)) { - error = list_one_attr(POSIX_ACL_XATTR_DEFAULT, - strlen(POSIX_ACL_XATTR_DEFAULT) + 1, - data, size, &context.count); - if (error) - return error; - } - return context.count; } -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:20:33 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 4A72129E2C for ; Tue, 3 Nov 2015 09:20:33 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 37CC38F8033 for ; Tue, 3 Nov 2015 07:20:33 -0800 (PST) X-ASG-Debug-ID: 1446564030-04cbb0660f1f7ce0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id WHlYGfiwgBp3Dy4Q (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:20:30 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 1391D8535A; Tue, 3 Nov 2015 15:20:30 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRZp029477; Tue, 3 Nov 2015 10:20:23 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 25/51] xfs: Add richacl support Date: Tue, 3 Nov 2015 16:17:01 +0100 X-ASG-Orig-Subj: [PATCH v13 25/51] xfs: Add richacl support Message-Id: <1446563847-14005-26-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446564030 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 The richacl feature flag (mkfs.xfs -m richacl=1) determines whether an xfs filesystem supports posix acls or richacls. Richacls are stored in "system.richacl" xattrs. On the grounds that richacls add relatively little overhead compared to the size of xfs itself, to keep the testing matrix small, and because xfs users are highly likely to enable richacls anyway, richacl support cannot be compiled out in xfs. Signed-off-by: Andreas Gruenbacher --- fs/xfs/Kconfig | 1 + fs/xfs/Makefile | 1 + fs/xfs/libxfs/xfs_format.h | 11 ++++- fs/xfs/xfs_iops.c | 44 +++++++++++++++---- fs/xfs/xfs_richacl.c | 103 +++++++++++++++++++++++++++++++++++++++++++++ fs/xfs/xfs_richacl.h | 23 ++++++++++ fs/xfs/xfs_super.c | 6 ++- fs/xfs/xfs_super.h | 4 ++ fs/xfs/xfs_xattr.c | 43 ++++++++++++++++--- 9 files changed, 218 insertions(+), 18 deletions(-) create mode 100644 fs/xfs/xfs_richacl.c create mode 100644 fs/xfs/xfs_richacl.h diff --git a/fs/xfs/Kconfig b/fs/xfs/Kconfig index 5d47b4d..3fd00f8 100644 --- a/fs/xfs/Kconfig +++ b/fs/xfs/Kconfig @@ -4,6 +4,7 @@ config XFS_FS depends on (64BIT || LBDAF) select EXPORTFS select LIBCRC32C + select FS_RICHACL help XFS is a high performance journaling filesystem which originated on the SGI IRIX platform. It is completely multi-threaded, can diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile index a096841..1e6b984 100644 --- a/fs/xfs/Makefile +++ b/fs/xfs/Makefile @@ -84,6 +84,7 @@ xfs-y += xfs_aops.o \ xfs_message.o \ xfs_mount.o \ xfs_mru_cache.o \ + xfs_richacl.o \ xfs_super.o \ xfs_symlink.o \ xfs_sysfs.o \ diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h index 9590a06..923247c 100644 --- a/fs/xfs/libxfs/xfs_format.h +++ b/fs/xfs/libxfs/xfs_format.h @@ -461,10 +461,13 @@ xfs_sb_has_ro_compat_feature( #define XFS_SB_FEAT_INCOMPAT_FTYPE (1 << 0) /* filetype in dirent */ #define XFS_SB_FEAT_INCOMPAT_SPINODES (1 << 1) /* sparse inode chunks */ #define XFS_SB_FEAT_INCOMPAT_META_UUID (1 << 2) /* metadata UUID */ +#define XFS_SB_FEAT_INCOMPAT_RICHACL (1 << 3) /* richacls */ + #define XFS_SB_FEAT_INCOMPAT_ALL \ (XFS_SB_FEAT_INCOMPAT_FTYPE| \ XFS_SB_FEAT_INCOMPAT_SPINODES| \ - XFS_SB_FEAT_INCOMPAT_META_UUID) + XFS_SB_FEAT_INCOMPAT_META_UUID| \ + XFS_SB_FEAT_INCOMPAT_RICHACL) #define XFS_SB_FEAT_INCOMPAT_UNKNOWN ~XFS_SB_FEAT_INCOMPAT_ALL static inline bool @@ -530,6 +533,12 @@ static inline bool xfs_sb_version_hasmetauuid(struct xfs_sb *sbp) (sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_META_UUID); } +static inline bool xfs_sb_version_hasrichacl(struct xfs_sb *sbp) +{ + return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) && + (sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_RICHACL); +} + /* * end of superblock version macros */ diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index 8294132..9e4103b 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -27,6 +27,7 @@ #include "xfs_bmap.h" #include "xfs_bmap_util.h" #include "xfs_acl.h" +#include "xfs_richacl.h" #include "xfs_quota.h" #include "xfs_error.h" #include "xfs_attr.h" @@ -42,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -133,7 +135,8 @@ xfs_generic_create( { struct inode *inode; struct xfs_inode *ip = NULL; - struct posix_acl *default_acl, *acl; + struct posix_acl *default_acl = NULL, *acl = NULL; + struct richacl *richacl = NULL; struct xfs_name name; int error; @@ -149,9 +152,15 @@ xfs_generic_create( rdev = 0; } - error = posix_acl_create(dir, &mode, &default_acl, &acl); - if (error) - return error; + if (IS_RICHACL(dir)) { + richacl = richacl_create(&mode, dir); + if (IS_ERR(richacl)) + return PTR_ERR(richacl); + } else { + error = posix_acl_create(dir, &mode, &default_acl, &acl); + if (error) + return error; + } if (!tmpfile) { xfs_dentry_to_name(&name, dentry, mode); @@ -180,6 +189,11 @@ xfs_generic_create( goto out_cleanup_inode; } #endif + if (richacl) { + error = xfs_set_richacl(inode, richacl); + if (error) + goto out_cleanup_inode; + } if (tmpfile) d_tmpfile(dentry, inode); @@ -189,10 +203,9 @@ xfs_generic_create( xfs_finish_inode_setup(ip); out_free_acl: - if (default_acl) - posix_acl_release(default_acl); - if (acl) - posix_acl_release(acl); + posix_acl_release(default_acl); + posix_acl_release(acl); + richacl_put(richacl); return error; out_cleanup_inode: @@ -534,6 +547,13 @@ xfs_setattr_time( } } +static inline int +xfs_acl_chmod(struct inode *inode, umode_t mode) +{ + if (IS_RICHACL(inode)) + return richacl_chmod(inode, inode->i_mode); + return posix_acl_chmod(inode, inode->i_mode); +} int xfs_setattr_nonsize( struct xfs_inode *ip, @@ -722,7 +742,7 @@ xfs_setattr_nonsize( * Posix ACL code seems to care about this issue either. */ if ((mask & ATTR_MODE) && !(flags & XFS_ATTR_NOACL)) { - error = posix_acl_chmod(inode, inode->i_mode); + error = xfs_acl_chmod(inode, inode->i_mode); if (error) return error; } @@ -1104,6 +1124,8 @@ xfs_vn_tmpfile( static const struct inode_operations xfs_inode_operations = { .get_acl = xfs_get_acl, .set_acl = xfs_set_acl, + .get_richacl = xfs_get_richacl, + .set_richacl = xfs_set_richacl, .getattr = xfs_vn_getattr, .setattr = xfs_vn_setattr, .setxattr = generic_setxattr, @@ -1132,6 +1154,8 @@ static const struct inode_operations xfs_dir_inode_operations = { .rename2 = xfs_vn_rename, .get_acl = xfs_get_acl, .set_acl = xfs_set_acl, + .get_richacl = xfs_get_richacl, + .set_richacl = xfs_set_richacl, .getattr = xfs_vn_getattr, .setattr = xfs_vn_setattr, .setxattr = generic_setxattr, @@ -1160,6 +1184,8 @@ static const struct inode_operations xfs_dir_ci_inode_operations = { .rename2 = xfs_vn_rename, .get_acl = xfs_get_acl, .set_acl = xfs_set_acl, + .get_richacl = xfs_get_richacl, + .set_richacl = xfs_set_richacl, .getattr = xfs_vn_getattr, .setattr = xfs_vn_setattr, .setxattr = generic_setxattr, diff --git a/fs/xfs/xfs_richacl.c b/fs/xfs/xfs_richacl.c new file mode 100644 index 0000000..92a036e --- /dev/null +++ b/fs/xfs/xfs_richacl.c @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2015 Red Hat, Inc. + * Author: Andreas Gruenbacher + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2.1 of the GNU Lesser 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. + * + */ + +#include "xfs.h" +#include "xfs_format.h" +#include "xfs_log_format.h" +#include "xfs_inode.h" +#include "xfs_attr.h" + +#include +#include + +struct richacl * +xfs_get_richacl(struct inode *inode) +{ + struct xfs_inode *ip = XFS_I(inode); + struct richacl *acl = NULL; + int size = XATTR_SIZE_MAX; + void *value; + int error; + + value = kmem_zalloc_large(size, KM_SLEEP); + if (!value) + return ERR_PTR(-ENOMEM); + + error = xfs_attr_get(ip, XATTR_RICHACL, value, &size, ATTR_ROOT); + if (error) { + /* + * If the attribute doesn't exist make sure we have a negative + * cache entry, for any other error assume it is transient and + * leave the cache entry as ACL_NOT_CACHED. + */ + if (error != -ENOATTR) + acl = ERR_PTR(error); + } else + acl = richacl_from_xattr(&init_user_ns, value, size); + + if (!IS_ERR(acl)) + set_cached_richacl(inode, acl); + kfree(value); + + return acl; +} + +static int +xfs_remove_richacl(struct inode *inode) +{ + struct xfs_inode *ip = XFS_I(inode); + int error; + + error = xfs_attr_remove(ip, XATTR_RICHACL, ATTR_ROOT); + if (error == -ENOATTR) + error = 0; + if (!error) + set_cached_richacl(inode, NULL); + return error; +} + +int +xfs_set_richacl(struct inode *inode, struct richacl *acl) +{ + struct xfs_inode *ip = XFS_I(inode); + umode_t mode = inode->i_mode; + int error, size; + void *value; + + if (!acl) + return xfs_remove_richacl(inode); + + if (richacl_equiv_mode(acl, &mode) == 0) { + xfs_set_mode(inode, mode); + return xfs_remove_richacl(inode); + } + + size = richacl_xattr_size(acl); + value = kmem_zalloc_large(size, KM_SLEEP); + if (!value) + return -ENOMEM; + richacl_to_xattr(&init_user_ns, acl, value, size); + error = xfs_attr_set(ip, XATTR_RICHACL, value, size, + ATTR_ROOT); + kfree(value); + if (error) + return error; + + mode &= ~S_IRWXUGO; + mode |= richacl_masks_to_mode(acl); + xfs_set_mode(inode, mode); + set_cached_richacl(inode, acl); + + return 0; +} diff --git a/fs/xfs/xfs_richacl.h b/fs/xfs/xfs_richacl.h new file mode 100644 index 0000000..431aa25 --- /dev/null +++ b/fs/xfs/xfs_richacl.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2015 Red Hat, Inc. + * Author: Andreas Gruenbacher + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2.1 of the GNU Lesser 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. + * + */ + +#ifndef __FS_XFS_RICHACL_H +#define __FS_XFS_RICHACL_H + +struct richacl; + +extern struct richacl *xfs_get_richacl(struct inode *); +extern int xfs_set_richacl(struct inode *, struct richacl *); + +#endif /* __FS_XFS_RICHACL_H */ diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 904f637..f82ce1a 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -1500,7 +1500,11 @@ xfs_fs_fill_super( sb->s_maxbytes = xfs_max_file_offset(sb->s_blocksize_bits); sb->s_max_links = XFS_MAXLINK; sb->s_time_gran = 1; - set_posix_acl_flag(sb); + + if (xfs_sb_version_hasrichacl(&mp->m_sb)) + set_richacl_flag(sb); + else + set_posix_acl_flag(sb); /* version 5 superblocks support inode version counters. */ if (XFS_SB_VERSION_NUM(&mp->m_sb) == XFS_SB_VERSION_5) diff --git a/fs/xfs/xfs_super.h b/fs/xfs/xfs_super.h index 499058f..7ae21d9 100644 --- a/fs/xfs/xfs_super.h +++ b/fs/xfs/xfs_super.h @@ -36,6 +36,9 @@ extern void xfs_qm_exit(void); # define set_posix_acl_flag(sb) do { } while (0) #endif +# define XFS_RICHACL_STRING "Richacls, " +# define set_richacl_flag(sb) ((sb)->s_flags |= MS_RICHACL) + #define XFS_SECURITY_STRING "security attributes, " #ifdef CONFIG_XFS_RT @@ -52,6 +55,7 @@ extern void xfs_qm_exit(void); #define XFS_VERSION_STRING "SGI XFS" #define XFS_BUILD_OPTIONS XFS_ACL_STRING \ + XFS_RICHACL_STRING \ XFS_SECURITY_STRING \ XFS_REALTIME_STRING \ XFS_DBG_STRING /* DBG must be last */ diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c index 8428aed..64aac05 100644 --- a/fs/xfs/xfs_xattr.c +++ b/fs/xfs/xfs_xattr.c @@ -28,6 +28,7 @@ #include "xfs_acl.h" #include +#include #include @@ -74,6 +75,24 @@ xfs_xattr_set(struct dentry *dentry, const char *name, const void *value, (void *)value, size, xflags); } +static int +xfs_xattr_get_trusted(struct dentry *dentry, const char *name, + void *value, size_t size, int xflags) +{ + if (strcmp(name, XATTR_RICHACL) == 0) + return -EOPNOTSUPP; + return xfs_xattr_get(dentry, name, value, size, xflags); +} + +static int +xfs_xattr_set_trusted(struct dentry *dentry, const char *name, + const void *value, size_t size, int flags, int xflags) +{ + if (strcmp(name, XATTR_RICHACL) == 0) + return -EOPNOTSUPP; + return xfs_xattr_set(dentry, name, value, size, flags, xflags); +} + static const struct xattr_handler xfs_xattr_user_handler = { .prefix = XATTR_USER_PREFIX, .flags = 0, /* no flags implies user namespace */ @@ -84,8 +103,8 @@ static const struct xattr_handler xfs_xattr_user_handler = { static const struct xattr_handler xfs_xattr_trusted_handler = { .prefix = XATTR_TRUSTED_PREFIX, .flags = ATTR_ROOT, - .get = xfs_xattr_get, - .set = xfs_xattr_set, + .get = xfs_xattr_get_trusted, + .set = xfs_xattr_set_trusted, }; static const struct xattr_handler xfs_xattr_security_handler = { @@ -103,6 +122,7 @@ const struct xattr_handler *xfs_xattr_handlers[] = { &posix_acl_access_xattr_handler, &posix_acl_default_xattr_handler, #endif + &richacl_xattr_handler, NULL }; @@ -152,10 +172,10 @@ xfs_xattr_put_listent( ASSERT(context->count >= 0); if (flags & XFS_ATTR_ROOT) { -#ifdef CONFIG_XFS_POSIX_ACL if (namelen == SGI_ACL_FILE_SIZE && strncmp(name, SGI_ACL_FILE, - SGI_ACL_FILE_SIZE) == 0) { + SGI_ACL_FILE_SIZE) == 0 && + IS_POSIXACL(&context->dp->i_vnode)) { int ret = __xfs_xattr_put_listent( context, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN, @@ -164,8 +184,9 @@ xfs_xattr_put_listent( if (ret) return ret; } else if (namelen == SGI_ACL_DEFAULT_SIZE && - strncmp(name, SGI_ACL_DEFAULT, - SGI_ACL_DEFAULT_SIZE) == 0) { + strncmp(name, SGI_ACL_DEFAULT, + SGI_ACL_DEFAULT_SIZE) == 0 && + IS_POSIXACL(&context->dp->i_vnode)) { int ret = __xfs_xattr_put_listent( context, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN, @@ -173,8 +194,16 @@ xfs_xattr_put_listent( strlen(XATTR_POSIX_ACL_DEFAULT)); if (ret) return ret; + } else if (namelen == strlen(XATTR_RICHACL) && + strncmp(name, XATTR_RICHACL, + strlen(XATTR_RICHACL)) == 0 && + IS_RICHACL(&context->dp->i_vnode)) { + return __xfs_xattr_put_listent( + context, XATTR_SYSTEM_PREFIX, + XATTR_SYSTEM_PREFIX_LEN, + XATTR_RICHACL, + strlen(XATTR_RICHACL)); } -#endif /* * Only show root namespace entries if we are actually allowed to -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:20:39 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 D12BC29E2C for ; Tue, 3 Nov 2015 09:20:39 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 58FF8AC002 for ; Tue, 3 Nov 2015 07:20:39 -0800 (PST) X-ASG-Debug-ID: 1446564037-04cbb0660c1f7cf0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 6YqDyEaHigYnnnj8 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:20:38 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 61E82C10045C; Tue, 3 Nov 2015 15:20:37 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRZq029477; Tue, 3 Nov 2015 10:20:30 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 26/51] xfs: Plug memory leak in xfs_attrmulti_attr_set Date: Tue, 3 Nov 2015 16:17:02 +0100 X-ASG-Orig-Subj: [PATCH v13 26/51] xfs: Plug memory leak in xfs_attrmulti_attr_set Message-Id: <1446563847-14005-27-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446564037 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 When setting attributes via XFS_IOC_ATTRMULTI_BY_HANDLE, the user-space buffer is copied into a new kernel-space buffer via memdup_user; that buffer then isn't freed. Signed-off-by: Andreas Gruenbacher Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner --- fs/xfs/xfs_ioctl.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c index ea7d85a..e939c20 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c @@ -482,6 +482,7 @@ xfs_attrmulti_attr_set( __uint32_t flags) { unsigned char *kbuf; + int error; if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) return -EPERM; @@ -492,7 +493,9 @@ xfs_attrmulti_attr_set( if (IS_ERR(kbuf)) return PTR_ERR(kbuf); - return xfs_attr_set(XFS_I(inode), name, kbuf, len, flags); + error = xfs_attr_set(XFS_I(inode), name, kbuf, len, flags); + kfree(kbuf); + return error; } int -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:20:45 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 EEAD629E35 for ; Tue, 3 Nov 2015 09:20:45 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id DEC39304043 for ; Tue, 3 Nov 2015 07:20:45 -0800 (PST) X-ASG-Debug-ID: 1446564044-04cb6c7b841ddc60001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id umV3XRzdB8vkeAHw (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:20:44 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 4845EA4505; Tue, 3 Nov 2015 15:20:44 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRZr029477; Tue, 3 Nov 2015 10:20:38 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 27/51] xfs: Fix richacl access by ioctl Date: Tue, 3 Nov 2015 16:17:03 +0100 X-ASG-Orig-Subj: [PATCH v13 27/51] xfs: Fix richacl access by ioctl Message-Id: <1446563847-14005-28-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446564044 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Make sure that the XFS_IOC_ATTRMULTI_BY_HANDLE ioctl exposes richacls in the same way as the xattr interface: check for mode-equivalent richacls, update the inode permission bits, and perform user namespace mapping. Signed-off-by: Andreas Gruenbacher --- fs/xfs/xfs_ioctl.c | 27 +++++++++++++++++++++++++++ fs/xfs/xfs_richacl.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++---- fs/xfs/xfs_richacl.h | 3 +++ 3 files changed, 78 insertions(+), 4 deletions(-) diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c index e939c20..deae7df 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c @@ -40,6 +40,7 @@ #include "xfs_symlink.h" #include "xfs_trans.h" #include "xfs_pnfs.h" +#include "xfs_richacl.h" #include #include @@ -48,6 +49,7 @@ #include #include #include +#include /* * xfs_find_handle maps from userspace xfs_fsop_handlereq structure to @@ -461,10 +463,20 @@ xfs_attrmulti_attr_get( if (!kbuf) return -ENOMEM; + if (flags & ATTR_ROOT) { + if (!strcmp(name, XATTR_RICHACL)) { + error = xfs_richacl_get_ioctl(inode, kbuf, (int *)len); + if (error) + goto out_kfree; + goto out_copy; + } + } + error = xfs_attr_get(XFS_I(inode), name, kbuf, (int *)len, flags); if (error) goto out_kfree; +out_copy: if (copy_to_user(ubuf, kbuf, *len)) error = -EFAULT; @@ -493,7 +505,16 @@ xfs_attrmulti_attr_set( if (IS_ERR(kbuf)) return PTR_ERR(kbuf); + if (flags & ATTR_ROOT) { + if (!strcmp(name, XATTR_RICHACL)) { + error = xfs_richacl_set_ioctl(inode, kbuf, len, flags); + goto out_kfree; + } + } + error = xfs_attr_set(XFS_I(inode), name, kbuf, len, flags); + +out_kfree: kfree(kbuf); return error; } @@ -506,6 +527,12 @@ xfs_attrmulti_attr_remove( { if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) return -EPERM; + + if (flags & ATTR_ROOT) { + if (!strcmp(name, XATTR_RICHACL)) + return xfs_richacl_set_ioctl(inode, NULL, 0, flags); + } + return xfs_attr_remove(XFS_I(inode), name, flags); } diff --git a/fs/xfs/xfs_richacl.c b/fs/xfs/xfs_richacl.c index 92a036e..f8f5a62 100644 --- a/fs/xfs/xfs_richacl.c +++ b/fs/xfs/xfs_richacl.c @@ -67,8 +67,8 @@ xfs_remove_richacl(struct inode *inode) return error; } -int -xfs_set_richacl(struct inode *inode, struct richacl *acl) +static int +__xfs_set_richacl(struct inode *inode, struct richacl *acl, int xflags) { struct xfs_inode *ip = XFS_I(inode); umode_t mode = inode->i_mode; @@ -88,8 +88,7 @@ xfs_set_richacl(struct inode *inode, struct richacl *acl) if (!value) return -ENOMEM; richacl_to_xattr(&init_user_ns, acl, value, size); - error = xfs_attr_set(ip, XATTR_RICHACL, value, size, - ATTR_ROOT); + error = xfs_attr_set(ip, XATTR_RICHACL, value, size, xflags); kfree(value); if (error) return error; @@ -101,3 +100,48 @@ xfs_set_richacl(struct inode *inode, struct richacl *acl) return 0; } + +int +xfs_set_richacl(struct inode *inode, struct richacl *acl) +{ + return __xfs_set_richacl(inode, acl, ATTR_ROOT); +} + +int +xfs_richacl_get_ioctl(struct inode *inode, void *value, int *len) +{ + struct user_namespace *user_ns = current_user_ns(); + struct richacl *acl; + int error; + + acl = get_richacl(inode); + if (IS_ERR_OR_NULL(acl)) + return PTR_ERR(acl); + error = richacl_to_xattr(user_ns, acl, value, *len); + if (error > 0) { + *len = error; + error = 0; + } + richacl_put(acl); + return error; +} + +int +xfs_richacl_set_ioctl(struct inode *inode, void *value, unsigned int size, + int xflags) +{ + struct user_namespace *user_ns = current_user_ns(); + struct richacl *acl = NULL; + int error; + + if (!IS_RICHACL(inode)) + return -EOPNOTSUPP; + if (value) { + acl = richacl_from_xattr(user_ns, value, size); + if (IS_ERR(acl)) + return PTR_ERR(acl); + } + error = __xfs_set_richacl(inode, acl, xflags); + richacl_put(acl); + return error; +} diff --git a/fs/xfs/xfs_richacl.h b/fs/xfs/xfs_richacl.h index 431aa25..1fd1fc1 100644 --- a/fs/xfs/xfs_richacl.h +++ b/fs/xfs/xfs_richacl.h @@ -20,4 +20,7 @@ struct richacl; extern struct richacl *xfs_get_richacl(struct inode *); extern int xfs_set_richacl(struct inode *, struct richacl *); +extern int xfs_richacl_get_ioctl(struct inode *, void *, int *); +extern int xfs_richacl_set_ioctl(struct inode *, void *, int, int); + #endif /* __FS_XFS_RICHACL_H */ -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:20:53 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 5560929E2C for ; Tue, 3 Nov 2015 09:20:53 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id E0A9FAC002 for ; Tue, 3 Nov 2015 07:20:52 -0800 (PST) X-ASG-Debug-ID: 1446564051-04bdf033091fcac0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id AFF6BkIuDW98ZBVg (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:20:51 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 341328FAA2; Tue, 3 Nov 2015 15:20:51 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRZs029477; Tue, 3 Nov 2015 10:20:44 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 28/51] richacl: acl editing helper functions Date: Tue, 3 Nov 2015 16:17:04 +0100 X-ASG-Orig-Subj: [PATCH v13 28/51] richacl: acl editing helper functions Message-Id: <1446563847-14005-29-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446564051 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 The file masks in richacls make chmod and creating new files more efficient than having to apply file permission bits to the acl directly. They also allow us to regain permissions from an acl even after a restrictive chmod, because the permissions in the acl itself are not being destroyed. In POSIX ACLs, the mask entry has a similar function. Protocols like nfsv4 do not understand file masks. For those protocols, we need to compute nfs4 acls which represent the effective permissions granted by a richacl: we need to "apply" the file masks to the acl. This is the first in a series of richacl transformation patches; it implements basic richacl editing functions. The following patches implement algorithms for transforming a richacl so that it can be evaluated as a plain nfs4 acl, with identical permission check results. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/Makefile | 3 +- fs/richacl_compat.c | 155 +++++++++++++++++++++++++++++++++++++++++ include/linux/richacl_compat.h | 40 +++++++++++ 3 files changed, 197 insertions(+), 1 deletion(-) create mode 100644 fs/richacl_compat.c create mode 100644 include/linux/richacl_compat.h diff --git a/fs/Makefile b/fs/Makefile index 35e640d..32b391b 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -49,7 +49,8 @@ obj-$(CONFIG_SYSCTL) += drop_caches.o obj-$(CONFIG_FHANDLE) += fhandle.o obj-$(CONFIG_FS_RICHACL) += richacl.o -richacl-y := richacl_base.o richacl_inode.o richacl_xattr.o +richacl-y := richacl_base.o richacl_inode.o \ + richacl_xattr.o richacl_compat.o obj-y += quota/ diff --git a/fs/richacl_compat.c b/fs/richacl_compat.c new file mode 100644 index 0000000..5c59999 --- /dev/null +++ b/fs/richacl_compat.c @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2006, 2010 Novell, Inc. + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * 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; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include +#include +#include +#include + +/** + * richacl_prepare - allocate richacl being constructed + * + * Allocate a richacl which can hold @count entries but which is initially + * empty. + */ +struct richacl *richacl_prepare(struct richacl_alloc *alloc, unsigned int count) +{ + alloc->acl = richacl_alloc(count, GFP_KERNEL); + if (!alloc->acl) + return NULL; + alloc->acl->a_count = 0; + alloc->count = count; + return alloc->acl; +} +EXPORT_SYMBOL_GPL(richacl_prepare); + +/** + * richacl_delete_entry - delete an entry in an acl + * @alloc: acl and number of allocated entries + * @ace: an entry in @alloc->acl + * + * Updates @ace so that it points to the entry before the deleted entry + * on return. (When deleting the first entry, @ace will point to the + * (non-existent) entry before the first entry). This behavior is the + * expected behavior when deleting entries while forward iterating over + * an acl. + */ +void +richacl_delete_entry(struct richacl_alloc *alloc, struct richace **ace) +{ + void *end = alloc->acl->a_entries + alloc->acl->a_count; + + memmove(*ace, *ace + 1, end - (void *)(*ace + 1)); + (*ace)--; + alloc->acl->a_count--; +} +EXPORT_SYMBOL_GPL(richacl_delete_entry); + +/** + * richacl_insert_entry - insert an entry in an acl + * @alloc: acl and number of allocated entries + * @ace: entry before which the new entry shall be inserted + * + * Insert a new entry in @alloc->acl at position @ace and zero-initialize + * it. This may require reallocating @alloc->acl. + */ +int +richacl_insert_entry(struct richacl_alloc *alloc, struct richace **ace) +{ + struct richacl *acl = alloc->acl; + unsigned int index = *ace - acl->a_entries; + size_t tail_size = (acl->a_count - index) * sizeof(struct richace); + + if (alloc->count == acl->a_count) { + size_t new_size = sizeof(struct richacl) + + (acl->a_count + 1) * sizeof(struct richace); + + acl = krealloc(acl, new_size, GFP_KERNEL); + if (!acl) + return -1; + *ace = acl->a_entries + index; + alloc->acl = acl; + alloc->count++; + } + + memmove(*ace + 1, *ace, tail_size); + memset(*ace, 0, sizeof(**ace)); + acl->a_count++; + return 0; +} +EXPORT_SYMBOL_GPL(richacl_insert_entry); + +/** + * richacl_append_entry - append an entry to an acl + * @alloc: acl and number of allocated entries + * + * This may require reallocating @alloc->acl. + */ +struct richace *richacl_append_entry(struct richacl_alloc *alloc) +{ + struct richacl *acl = alloc->acl; + struct richace *ace = acl->a_entries + acl->a_count; + + if (alloc->count > alloc->acl->a_count) { + acl->a_count++; + return ace; + } + return richacl_insert_entry(alloc, &ace) ? NULL : ace; +} +EXPORT_SYMBOL_GPL(richacl_append_entry); + +/** + * richace_change_mask - set the mask of @ace to @mask + * @alloc: acl and number of allocated entries + * @ace: entry to modify + * @mask: new mask for @ace + * + * If @ace is inheritable, a inherit-only ace is inserted before @ace which + * includes the inheritable permissions of @ace and the inheritance flags of + * @ace are cleared before changing the mask. + * + * If @mask is 0, the original ace is turned into an inherit-only entry if + * there are any inheritable permissions, and removed otherwise. + * + * The returned @ace points to the modified or inserted effective-only acl + * entry if that entry exists, to the entry that has become inheritable-only, + * or else to the previous entry in the acl. + */ +static int +richace_change_mask(struct richacl_alloc *alloc, struct richace **ace, + unsigned int mask) +{ + if (mask && (*ace)->e_mask == mask) + (*ace)->e_flags &= ~RICHACE_INHERIT_ONLY_ACE; + else if (mask & ~RICHACE_POSIX_ALWAYS_ALLOWED) { + if (richace_is_inheritable(*ace)) { + if (richacl_insert_entry(alloc, ace)) + return -1; + richace_copy(*ace, *ace + 1); + (*ace)->e_flags |= RICHACE_INHERIT_ONLY_ACE; + (*ace)++; + (*ace)->e_flags &= ~RICHACE_INHERITANCE_FLAGS | + RICHACE_INHERITED_ACE; + } + (*ace)->e_mask = mask; + } else { + if (richace_is_inheritable(*ace)) + (*ace)->e_flags |= RICHACE_INHERIT_ONLY_ACE; + else + richacl_delete_entry(alloc, ace); + } + return 0; +} diff --git a/include/linux/richacl_compat.h b/include/linux/richacl_compat.h new file mode 100644 index 0000000..a9ff630 --- /dev/null +++ b/include/linux/richacl_compat.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * 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; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#ifndef __RICHACL_COMPAT_H +#define __RICHACL_COMPAT_H + +#include + +/** + * struct richacl_alloc - remember how many entries are actually allocated + * @acl: acl with a_count <= @count + * @count: the actual number of entries allocated in @acl + * + * We pass around this structure while modifying an acl so that we do + * not have to reallocate when we remove existing entries followed by + * adding new entries. + */ +struct richacl_alloc { + struct richacl *acl; + unsigned int count; +}; + +struct richacl *richacl_prepare(struct richacl_alloc *, unsigned int); +struct richace *richacl_append_entry(struct richacl_alloc *); +int richacl_insert_entry(struct richacl_alloc *, struct richace **); +void richacl_delete_entry(struct richacl_alloc *, struct richace **); + +#endif /* __RICHACL_COMPAT_H */ -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:20:59 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 ACDC729E4C for ; Tue, 3 Nov 2015 09:20:59 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 7A53A304059 for ; Tue, 3 Nov 2015 07:20:59 -0800 (PST) X-ASG-Debug-ID: 1446564058-04bdf0330c1fcae0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id cLdaTJmS3Vy6NA2n (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:20:58 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 17BFB8E22D; Tue, 3 Nov 2015 15:20:58 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRZt029477; Tue, 3 Nov 2015 10:20:51 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 29/51] richacl: Move everyone@ aces down the acl Date: Tue, 3 Nov 2015 16:17:05 +0100 X-ASG-Orig-Subj: [PATCH v13 29/51] richacl: Move everyone@ aces down the acl Message-Id: <1446563847-14005-30-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446564058 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 The POSIX standard puts processes which are not the owner or a member in the owning group or which match any ace other then everyone@ on the other file class. We only know if a process is in the other class after processing the entire acl. Move all everyone@ aces in the acl down in the acl so that at most a single everyone@ allow ace remains at the end. Permissions which are not explicitly allowed are implicitly denied, so an everyone@ deny ace is unneeded. The everyone@ aces can be moved down the acl without changing the permissions that the acl grants. This transformation simplifies the following algorithms, and eventually allows us to turn the final everyone@ allow ace into an entry for the other class. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_compat.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/fs/richacl_compat.c b/fs/richacl_compat.c index 5c59999..962d314 100644 --- a/fs/richacl_compat.c +++ b/fs/richacl_compat.c @@ -153,3 +153,68 @@ richace_change_mask(struct richacl_alloc *alloc, struct richace **ace, } return 0; } + +/** + * richacl_move_everyone_aces_down - move everyone@ aces to the end of the acl + * @alloc: acl and number of allocated entries + * + * Move all everyone aces to the end of the acl so that only a single everyone@ + * allow ace remains at the end, and update the mask fields of all aces on the + * way. The last ace of the resulting acl will be an everyone@ allow ace only + * if @acl grants any permissions to @everyone. No @everyone deny aces will + * remain. + * + * This transformation does not alter the permissions that the acl grants. + * Having at most one everyone@ allow ace at the end of the acl helps us in the + * following algorithms. + */ +static int +richacl_move_everyone_aces_down(struct richacl_alloc *alloc) +{ + struct richace *ace; + unsigned int allowed = 0, denied = 0; + + richacl_for_each_entry(ace, alloc->acl) { + if (richace_is_inherit_only(ace)) + continue; + if (richace_is_everyone(ace)) { + if (richace_is_allow(ace)) + allowed |= (ace->e_mask & ~denied); + else if (richace_is_deny(ace)) + denied |= (ace->e_mask & ~allowed); + else + continue; + if (richace_change_mask(alloc, &ace, 0)) + return -1; + } else { + if (richace_is_allow(ace)) { + if (richace_change_mask(alloc, &ace, allowed | + (ace->e_mask & ~denied))) + return -1; + } else if (richace_is_deny(ace)) { + if (richace_change_mask(alloc, &ace, denied | + (ace->e_mask & ~allowed))) + return -1; + } + } + } + if (allowed & ~RICHACE_POSIX_ALWAYS_ALLOWED) { + struct richace *last_ace = ace - 1; + + if (alloc->acl->a_entries && + richace_is_everyone(last_ace) && + richace_is_allow(last_ace) && + richace_is_inherit_only(last_ace) && + last_ace->e_mask == allowed) + last_ace->e_flags &= ~RICHACE_INHERIT_ONLY_ACE; + else { + if (richacl_insert_entry(alloc, &ace)) + return -1; + ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE; + ace->e_flags = RICHACE_SPECIAL_WHO; + ace->e_mask = allowed; + ace->e_id.special = RICHACE_EVERYONE_SPECIAL_ID; + } + } + return 0; +} -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:21:07 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 2627629E2C for ; Tue, 3 Nov 2015 09:21:07 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 158988F8040 for ; Tue, 3 Nov 2015 07:21:07 -0800 (PST) X-ASG-Debug-ID: 1446564065-04cbb0660c1f7d50001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id GXgNP7Sb3GnIbmHA (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:21:05 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 0A14E8F4F8; Tue, 3 Nov 2015 15:21:05 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRZu029477; Tue, 3 Nov 2015 10:20:58 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 30/51] richacl: Propagate everyone@ permissions to other aces Date: Tue, 3 Nov 2015 16:17:06 +0100 X-ASG-Orig-Subj: [PATCH v13 30/51] richacl: Propagate everyone@ permissions to other aces Message-Id: <1446563847-14005-31-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446564065 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 The trailing everyone@ allow ace can grant permissions to all file classes including the owner and group class. Before we can apply the other mask to this entry to turn it into an "other class" entry, we need to ensure that members of the owner or group class will not lose any permissions from that ace. Conceptually, we do this by inserting additional :::allow entries before the trailing everyone@ allow ace with the same permissions as the trailing everyone@ allow ace for owner@, group@, and all explicitly mentioned users and groups. (In practice, we will rarely need to insert any additional aces in this step.) Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_compat.c | 198 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 198 insertions(+) diff --git a/fs/richacl_compat.c b/fs/richacl_compat.c index 962d314..e90d57c 100644 --- a/fs/richacl_compat.c +++ b/fs/richacl_compat.c @@ -218,3 +218,201 @@ richacl_move_everyone_aces_down(struct richacl_alloc *alloc) } return 0; } + +/** + * __richacl_propagate_everyone - propagate everyone@ permissions up for @who + * @alloc: acl and number of allocated entries + * @who: identifier to propagate permissions for + * @allow: permissions to propagate up + * + * Propagate the permissions in @allow up from the end of the acl to the start + * for the specified principal @who. + * + * The simplest possible approach to achieve this would be to insert a + * ":::allow" ace before the final everyone@ allow ace. Since this + * would often result in aces which are not needed or which could be merged + * with an existing ace, we make the following optimizations: + * + * - We go through the acl and determine which permissions are already + * allowed or denied to @who, and we remove those permissions from + * @allow. + * + * - If the acl contains an allow ace for @who and no aces after this entry + * deny permissions in @allow, we add the permissions in @allow to this + * ace. (Propagating permissions across a deny ace which can match the + * process can elevate permissions.) + * + * This transformation does not alter the permissions that the acl grants. + */ +static int +__richacl_propagate_everyone(struct richacl_alloc *alloc, struct richace *who, + unsigned int allow) +{ + struct richace *allow_last = NULL, *ace; + struct richacl *acl = alloc->acl; + + /* + * Remove the permissions from allow that are already determined for + * this who value, and figure out if there is an allow entry for + * this who value that is "reachable" from the trailing everyone@ + * allow ace. + */ + richacl_for_each_entry(ace, acl) { + if (richace_is_inherit_only(ace)) + continue; + if (richace_is_allow(ace)) { + if (richace_is_same_identifier(ace, who)) { + allow &= ~ace->e_mask; + allow_last = ace; + } + } else if (richace_is_deny(ace)) { + if (richace_is_same_identifier(ace, who)) + allow &= ~ace->e_mask; + else if (allow & ace->e_mask) + allow_last = NULL; + } + } + ace--; + + /* + * If for group class entries, all the remaining permissions will + * remain granted by the trailing everyone@ allow ace, no additional + * entry is needed. + */ + if (!richace_is_owner(who) && + richace_is_everyone(ace) && + !(allow & ~(ace->e_mask & acl->a_other_mask))) + allow = 0; + + if (allow) { + if (allow_last) + return richace_change_mask(alloc, &allow_last, + allow_last->e_mask | allow); + else { + struct richace who_copy; + + richace_copy(&who_copy, who); + if (richacl_insert_entry(alloc, &ace)) + return -1; + richace_copy(ace, &who_copy); + ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE; + ace->e_flags &= ~RICHACE_INHERITANCE_FLAGS; + ace->e_mask = allow; + } + } + return 0; +} + +/** + * richacl_propagate_everyone - propagate everyone@ permissions up the acl + * @alloc: acl and number of allocated entries + * + * Make sure that group@ and all other users and groups mentioned in the acl + * will not lose any permissions when finally applying the other mask to the + * everyone@ allow ace at the end of the acl. We modify the permissions of + * existing entries or add new entries before the final everyone@ allow ace to + * achieve that. + * + * For example, the following acl implicitly grants everyone rwpx access: + * + * joe:r::allow + * everyone@:rwpx::allow + * + * When applying mode 0660 to this acl, group@ would lose rwp access, and joe + * would lose wp access even though the mode does not exclude those + * permissions. After propagating the everyone@ permissions, the result for + * applying mode 0660 becomes: + * + * owner@:rwp::allow + * joe:rwp::allow + * group@:rwp::allow + * + * Deny aces complicate the matter. For example, the following acl grants + * everyone but joe write access: + * + * joe:wp::deny + * everyone@:rwpx::allow + * + * When applying mode 0660 to this acl, group@ would lose rwp access, and joe + * would lose r access. After propagating the everyone@ permissions, the + * result for applying mode 0660 becomes: + * + * owner@:rwp::allow + * joe:w::deny + * group@:rwp::allow + * joe:r::allow + */ +static int +richacl_propagate_everyone(struct richacl_alloc *alloc) +{ + struct richace who = { .e_flags = RICHACE_SPECIAL_WHO }; + struct richacl *acl = alloc->acl; + struct richace *ace; + unsigned int owner_allow, group_allow; + + if (!acl->a_count) + return 0; + ace = acl->a_entries + acl->a_count - 1; + if (richace_is_inherit_only(ace) || !richace_is_everyone(ace)) + return 0; + + /* + * Permissions the owner and group class are granted through the + * trailing everyone@ allow ace. + */ + owner_allow = ace->e_mask & acl->a_owner_mask; + group_allow = ace->e_mask & acl->a_group_mask; + + /* + * If the group or other masks hide permissions which the owner should + * be allowed, we need to propagate those permissions up. Otherwise, + * those permissions may be lost when applying the other mask to the + * trailing everyone@ allow ace, or when isolating the group class from + * the other class through additional deny aces. + */ + if (owner_allow & ~(acl->a_group_mask & acl->a_other_mask)) { + /* Propagate everyone@ permissions through to owner@. */ + who.e_id.special = RICHACE_OWNER_SPECIAL_ID; + if (__richacl_propagate_everyone(alloc, &who, owner_allow)) + return -1; + acl = alloc->acl; + } + + /* + * If the other mask hides permissions which the group class should be + * allowed, we need to propagate those permissions up to the owning + * group and to all other members in the group class. + */ + if (group_allow & ~acl->a_other_mask) { + int n; + + /* Propagate everyone@ permissions through to group@. */ + who.e_id.special = RICHACE_GROUP_SPECIAL_ID; + if (__richacl_propagate_everyone(alloc, &who, group_allow)) + return -1; + acl = alloc->acl; + + /* + * Start from the entry before the trailing everyone@ allow + * entry. We will not hit everyone@ entries in the loop. + */ + for (n = acl->a_count - 2; n != -1; n--) { + ace = acl->a_entries + n; + + if (richace_is_inherit_only(ace) || + richace_is_owner(ace) || + richace_is_group(ace)) + continue; + + /* + * Any inserted entry will end up below the current + * entry. + */ + if (__richacl_propagate_everyone(alloc, ace, + group_allow)) + return -1; + acl = alloc->acl; + } + } + return 0; +} -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:21:14 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 704E429E58 for ; Tue, 3 Nov 2015 09:21:14 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id E28F0AC006 for ; Tue, 3 Nov 2015 07:21:13 -0800 (PST) X-ASG-Debug-ID: 1446564072-04cb6c7b861ddca0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id jFbFuMs3h4M4apJ2 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:21:12 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id DB6BC8FAA5; Tue, 3 Nov 2015 15:21:11 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRZv029477; Tue, 3 Nov 2015 10:21:05 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 31/51] richacl: Set the owner permissions to the owner mask Date: Tue, 3 Nov 2015 16:17:07 +0100 X-ASG-Orig-Subj: [PATCH v13 31/51] richacl: Set the owner permissions to the owner mask Message-Id: <1446563847-14005-32-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446564072 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 In the write-through case, change the acl so that owner@ is granted the permissions set in the owner mask (to match what the permission check algorithm grants the owner). Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_compat.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/fs/richacl_compat.c b/fs/richacl_compat.c index e90d57c..d9fee8b 100644 --- a/fs/richacl_compat.c +++ b/fs/richacl_compat.c @@ -416,3 +416,49 @@ richacl_propagate_everyone(struct richacl_alloc *alloc) } return 0; } + +/** + * richacl_set_owner_permissions - set the owner permissions to the owner mask + * + * In the write-through case, change the acl so that owner@ is granted the + * permissions set in the owner mask (to match what the permission check + * algorithm grants the owner). This leaves at most one efective owner@ allow + * entry at the beginning of the acl. + */ +static int +richacl_set_owner_permissions(struct richacl_alloc *alloc) +{ + unsigned int x = RICHACE_POSIX_ALWAYS_ALLOWED; + unsigned int owner_mask = alloc->acl->a_owner_mask & ~x; + unsigned int denied = 0; + struct richace *ace; + + if (!((alloc->acl->a_flags & RICHACL_WRITE_THROUGH))) + return 0; + + richacl_for_each_entry(ace, alloc->acl) { + if (richace_is_owner(ace)) { + if (richace_is_allow(ace) && !(owner_mask & denied)) { + richace_change_mask(alloc, &ace, owner_mask); + owner_mask = 0; + } else + richace_change_mask(alloc, &ace, 0); + } else { + if (richace_is_deny(ace)) + denied |= ace->e_mask; + } + } + + if (owner_mask & (denied | + ~alloc->acl->a_other_mask | + ~alloc->acl->a_group_mask)) { + ace = alloc->acl->a_entries; + if (richacl_insert_entry(alloc, &ace)) + return -1; + ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE; + ace->e_flags = RICHACE_SPECIAL_WHO; + ace->e_mask = owner_mask; + ace->e_id.special = RICHACE_OWNER_SPECIAL_ID; + } + return 0; +} -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:21:20 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 4F88B29E5A for ; Tue, 3 Nov 2015 09:21:20 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 0C37C8F8033 for ; Tue, 3 Nov 2015 07:21:20 -0800 (PST) X-ASG-Debug-ID: 1446564078-04bdf0330c1fcb60001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 9zh4ChV6wJDOoCXv (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:21:19 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id C5001C0D61A2; Tue, 3 Nov 2015 15:21:18 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRZw029477; Tue, 3 Nov 2015 10:21:12 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 32/51] richacl: Set the other permissions to the other mask Date: Tue, 3 Nov 2015 16:17:08 +0100 X-ASG-Orig-Subj: [PATCH v13 32/51] richacl: Set the other permissions to the other mask Message-Id: <1446563847-14005-33-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446564079 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Change the acl so that everyone@ is granted the permissions set in the other mask. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_compat.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/fs/richacl_compat.c b/fs/richacl_compat.c index d9fee8b..76183c9 100644 --- a/fs/richacl_compat.c +++ b/fs/richacl_compat.c @@ -462,3 +462,44 @@ richacl_set_owner_permissions(struct richacl_alloc *alloc) } return 0; } + +/** + * richacl_set_other_permissions - set the other permissions to the other mask + * @alloc: acl and number of allocated entries + * @added: permissions added for everyone@ + * + * Change the acl so that everyone@ is granted the permissions set in the other + * mask. This leaves at most one efective everyone@ allow entry at the end of + * the acl. If everyone@ end up being granted additional permissions, these + * permissions are returned in @added. + */ +static int +richacl_set_other_permissions(struct richacl_alloc *alloc, unsigned int *added) +{ + struct richacl *acl = alloc->acl; + unsigned int x = RICHACE_POSIX_ALWAYS_ALLOWED; + unsigned int other_mask = acl->a_other_mask & ~x; + struct richace *ace; + + if (!(other_mask && + (acl->a_flags & RICHACL_WRITE_THROUGH))) + return 0; + + *added = other_mask; + ace = acl->a_entries + acl->a_count - 1; + if (acl->a_count == 0 || + !richace_is_everyone(ace) || + richace_is_inherit_only(ace)) { + ace++; + if (richacl_insert_entry(alloc, &ace)) + return -1; + ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE; + ace->e_flags = RICHACE_SPECIAL_WHO; + ace->e_mask = other_mask; + ace->e_id.special = RICHACE_EVERYONE_SPECIAL_ID; + } else { + *added &= ~ace->e_mask; + richace_change_mask(alloc, &ace, other_mask); + } + return 0; +} -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:21:27 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 C683629E2C for ; Tue, 3 Nov 2015 09:21:27 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 8A5C3304043 for ; Tue, 3 Nov 2015 07:21:27 -0800 (PST) X-ASG-Debug-ID: 1446564085-04bdf0330b1fcb70001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id xmVBcCnqZ3dcjV2X (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:21:26 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id AF8428F4E4; Tue, 3 Nov 2015 15:21:25 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRZx029477; Tue, 3 Nov 2015 10:21:19 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 33/51] richacl: Isolate the owner and group classes Date: Tue, 3 Nov 2015 16:17:09 +0100 X-ASG-Orig-Subj: [PATCH v13 33/51] richacl: Isolate the owner and group classes Message-Id: <1446563847-14005-34-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446564086 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 When applying the file masks to an acl, we need to ensure that no process gets more permissions than allowed by its file mask. This may require inserting an owner@ deny ace to ensure this if the owner mask contains fewer permissions than the group or other mask. For example, when applying mode 0446 to the following acl: everyone@:rw::allow A deny ace needs to be inserted so that the owner won't get elevated write access: owner@:w::deny everyone@:rw::allow Likewise, we may need to insert group class deny aces if the group mask contains fewer permissions than the other mask. For example, when applying mode 0646 to the following acl: owner@:rw::allow everyone@:rw::allow A deny ace needs to be inserted so that the owning group won't get elevated write access: owner@:rw::allow group@:w::deny everyone@:rw::allow Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_compat.c | 223 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 223 insertions(+) diff --git a/fs/richacl_compat.c b/fs/richacl_compat.c index 76183c9..7553f1a 100644 --- a/fs/richacl_compat.c +++ b/fs/richacl_compat.c @@ -503,3 +503,226 @@ richacl_set_other_permissions(struct richacl_alloc *alloc, unsigned int *added) } return 0; } + +/** + * richacl_max_allowed - maximum permissions that anybody is allowed + */ +static unsigned int +richacl_max_allowed(struct richacl *acl) +{ + struct richace *ace; + unsigned int allowed = 0; + + richacl_for_each_entry_reverse(ace, acl) { + if (richace_is_inherit_only(ace)) + continue; + if (richace_is_allow(ace)) + allowed |= ace->e_mask; + else if (richace_is_deny(ace)) { + if (richace_is_everyone(ace)) + allowed &= ~ace->e_mask; + } + } + return allowed; +} + +/** + * richacl_isolate_owner_class - limit the owner class to the owner file mask + * @alloc: acl and number of allocated entries + * + * POSIX requires that after a chmod, the owner class is granted no more + * permissions than the owner file permission bits. For richacls, this + * means that the owner class must not be granted any permissions that the + * owner mask does not include. + * + * When we apply file masks to an acl which grant more permissions to the group + * or other class than to the owner class, we may end up in a situation where + * the owner is granted additional permissions from other aces. For example, + * given this acl: + * + * everyone@:rwx::allow + * + * when file masks corresponding to mode 0406 are applied, after + * richacl_propagate_everyone() and __richacl_apply_masks(), we end up with: + * + * owner@:r::allow + * everyone@:rw::allow + * + * This acl still grants the owner rw access through the everyone@ allow ace. + * To fix this, we must deny the owner w access: + * + * owner@:w::deny + * owner@:r::allow + * everyone@:rw::allow + */ +static int +richacl_isolate_owner_class(struct richacl_alloc *alloc) +{ + struct richacl *acl = alloc->acl; + struct richace *ace; + unsigned int deny; + + deny = richacl_max_allowed(acl) & ~acl->a_owner_mask; + if (!deny) + return 0; + + /* + * Figure out if we can update an existig OWNER@ DENY entry. + */ + richacl_for_each_entry(ace, acl) { + if (richace_is_inherit_only(ace)) + continue; + if (richace_is_allow(ace)) + break; + if (richace_is_owner(ace)) + return richace_change_mask(alloc, &ace, + ace->e_mask | deny); + } + + /* Insert an owner@ deny entry at the front. */ + ace = acl->a_entries; + if (richacl_insert_entry(alloc, &ace)) + return -1; + ace->e_type = RICHACE_ACCESS_DENIED_ACE_TYPE; + ace->e_flags = RICHACE_SPECIAL_WHO; + ace->e_mask = deny; + ace->e_id.special = RICHACE_OWNER_SPECIAL_ID; + return 0; +} + +/** + * __richacl_isolate_who - isolate entry from everyone@ allow entry + * @alloc: acl and number of allocated entries + * @who: identifier to isolate + * @deny: permissions this identifier should not be allowed + * + * See richacl_isolate_group_class(). + */ +static int +__richacl_isolate_who(struct richacl_alloc *alloc, struct richace *who, + unsigned int deny) +{ + struct richacl *acl = alloc->acl; + struct richace *ace, who_copy; + int n; + + /* + * Compute the permissions already defined for @who. There are no + * everyone@ deny aces left in the acl at this stage. + */ + richacl_for_each_entry(ace, acl) { + if (richace_is_inherit_only(ace)) + continue; + if (richace_is_same_identifier(ace, who)) + deny &= ~ace->e_mask; + } + if (!deny) + return 0; + + /* + * Figure out if we can update an existig deny entry. Start from the + * entry before the trailing everyone@ allow entry. We will not hit + * everyone@ entries in the loop. + */ + for (n = acl->a_count - 2; n != -1; n--) { + ace = acl->a_entries + n; + if (richace_is_inherit_only(ace)) + continue; + if (richace_is_deny(ace)) { + if (richace_is_same_identifier(ace, who)) + return richace_change_mask(alloc, &ace, + ace->e_mask | deny); + } else if (richace_is_allow(ace) && + (ace->e_mask & deny)) + break; + } + + /* + * Insert a new entry before the trailing everyone@ deny entry. + */ + richace_copy(&who_copy, who); + ace = acl->a_entries + acl->a_count - 1; + if (richacl_insert_entry(alloc, &ace)) + return -1; + richace_copy(ace, &who_copy); + ace->e_type = RICHACE_ACCESS_DENIED_ACE_TYPE; + ace->e_flags &= ~RICHACE_INHERITANCE_FLAGS; + ace->e_mask = deny; + return 0; +} + +/** + * richacl_isolate_group_class - limit the group class to the group file mask + * @alloc: acl and number of allocated entries + * @deny: additional permissions to deny + * + * POSIX requires that after a chmod, the group class is granted no more + * permissions than the group file permission bits. For richacls, this + * means that the group class must not be granted any permissions that the + * group mask does not include. + * + * When we apply file masks to an acl which grant more permissions to the other + * class than to the group class, we may end up in a situation where processes + * in the group class are granted additional permission from other aces. For + * example, given this acl: + * + * joe:rwx::allow + * everyone@:rwx::allow + * + * when file masks corresponding to mode 0646 are applied, after + * richacl_propagate_everyone() and __richacl_apply_masks(), we end up with: + * + * joe:r::allow + * owner@:rw::allow + * group@:r::allow + * everyone@:rw::allow + * + * This acl still grants joe and group@ rw access through the everyone@ allow + * ace. To fix this, we must deny w access to group class aces before the + * everyone@ allow ace at the end of the acl: + * + * joe:r::allow + * owner@:rw::allow + * group@:r::allow + * joe:w::deny + * group@:w::deny + * everyone@:rw::allow + */ +static int +richacl_isolate_group_class(struct richacl_alloc *alloc, unsigned int deny) +{ + struct richace who = { + .e_flags = RICHACE_SPECIAL_WHO, + .e_id.special = RICHACE_GROUP_SPECIAL_ID, + }; + struct richace *ace; + + if (!alloc->acl->a_count) + return 0; + ace = alloc->acl->a_entries + alloc->acl->a_count - 1; + if (richace_is_inherit_only(ace) || !richace_is_everyone(ace)) + return 0; + deny |= ace->e_mask & ~alloc->acl->a_group_mask; + + if (deny) { + unsigned int n; + + if (__richacl_isolate_who(alloc, &who, deny)) + return -1; + /* + * Start from the entry before the trailing everyone@ allow + * entry. We will not hit everyone@ entries in the loop. + */ + for (n = alloc->acl->a_count - 2; n != -1; n--) { + ace = alloc->acl->a_entries + n; + + if (richace_is_inherit_only(ace) || + richace_is_owner(ace) || + richace_is_group(ace)) + continue; + if (__richacl_isolate_who(alloc, ace, deny)) + return -1; + } + } + return 0; +} -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:21:35 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 71CBB29E2C for ; Tue, 3 Nov 2015 09:21:35 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 6026D8F8033 for ; Tue, 3 Nov 2015 07:21:35 -0800 (PST) X-ASG-Debug-ID: 1446564092-04cbb0660e1f7da0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id nEQuG26H7HAHj4jG (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:21:33 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id A35218FAA3; Tue, 3 Nov 2015 15:21:32 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRa0029477; Tue, 3 Nov 2015 10:21:26 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 34/51] richacl: Apply the file masks to a richacl Date: Tue, 3 Nov 2015 16:17:10 +0100 X-ASG-Orig-Subj: [PATCH v13 34/51] richacl: Apply the file masks to a richacl Message-Id: <1446563847-14005-35-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446564093 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Put all the pieces of the acl transformation puzzle together for computing a richacl which has the file masks "applied" so that the standard nfsv4 access check algorithm can be used on the richacl. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_compat.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/richacl.h | 3 ++ 2 files changed, 104 insertions(+) diff --git a/fs/richacl_compat.c b/fs/richacl_compat.c index 7553f1a..ea3effd 100644 --- a/fs/richacl_compat.c +++ b/fs/richacl_compat.c @@ -726,3 +726,104 @@ richacl_isolate_group_class(struct richacl_alloc *alloc, unsigned int deny) } return 0; } + +/** + * __richacl_apply_masks - apply the file masks to all aces + * @alloc: acl and number of allocated entries + * + * Apply the owner mask to owner@ aces, the other mask to + * everyone@ aces, and the group mask to all other aces. + * + * The previous transformations have brought the acl into a + * form in which applying the masks will not lead to the + * accidental loss of permissions anymore. + */ +static int +__richacl_apply_masks(struct richacl_alloc *alloc, kuid_t owner) +{ + struct richace *ace; + + richacl_for_each_entry(ace, alloc->acl) { + unsigned int mask; + + if (richace_is_inherit_only(ace) || !richace_is_allow(ace)) + continue; + if (richace_is_owner(ace) || + (richace_is_unix_user(ace) && uid_eq(owner, ace->e_id.uid))) + mask = alloc->acl->a_owner_mask; + else if (richace_is_everyone(ace)) + mask = alloc->acl->a_other_mask; + else + mask = alloc->acl->a_group_mask; + if (richace_change_mask(alloc, &ace, ace->e_mask & mask)) + return -1; + } + return 0; +} + +/** + * richacl_apply_masks - apply the masks to the acl + * + * Transform @acl so that the standard NFSv4 permission check algorithm (which + * is not aware of file masks) will compute the same access decisions as the + * richacl permission check algorithm (which looks at the acl and the file + * masks). + * + * This algorithm is split into several steps: + * + * - Move everyone@ aces to the end of the acl. This simplifies the other + * transformations, and allows the everyone@ allow ace at the end of the + * acl to eventually allow permissions to the other class only. + * + * - Propagate everyone@ permissions up the acl. This transformation makes + * sure that the owner and group class aces won't lose any permissions when + * we apply the other mask to the everyone@ allow ace at the end of the acl. + * + * - Apply the file masks to all aces. + * + * - Make sure everyone is granted the other mask permissions. This step can + * elevate elevate permissions for the owner and group classes, which is + * corrected later. + * + * - Make sure that the group class is not granted any permissions from + * everyone@. + * + * - Make sure the owner is granted the owner mask permissions. + * + * - Make sure the owner is not granted any permissions beyond the owner + * mask from group class aces or from everyone@. + * + * NOTE: Depending on the acl and file masks, this algorithm can increase the + * number of aces by almost a factor of three in the worst case. This may make + * the acl too large for some purposes. + */ +int +richacl_apply_masks(struct richacl **acl, kuid_t owner) +{ + if ((*acl)->a_flags & RICHACL_MASKED) { + struct richacl_alloc alloc = { + .acl = richacl_clone(*acl, GFP_KERNEL), + .count = (*acl)->a_count, + }; + unsigned int added = 0; + + if (!alloc.acl) + return -ENOMEM; + if (richacl_move_everyone_aces_down(&alloc) || + richacl_propagate_everyone(&alloc) || + __richacl_apply_masks(&alloc, owner) || + richacl_set_other_permissions(&alloc, &added) || + richacl_isolate_group_class(&alloc, added) || + richacl_set_owner_permissions(&alloc) || + richacl_isolate_owner_class(&alloc)) { + richacl_put(alloc.acl); + return -ENOMEM; + } + + alloc.acl->a_flags &= ~(RICHACL_WRITE_THROUGH | RICHACL_MASKED); + richacl_put(*acl); + *acl = alloc.acl; + } + return 0; +} +EXPORT_SYMBOL_GPL(richacl_apply_masks); diff --git a/include/linux/richacl.h b/include/linux/richacl.h index 7cfa64d..3fdfc57 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -205,4 +205,7 @@ extern int richacl_permission(struct inode *, const struct richacl *, int); extern int richacl_chmod(struct inode *, umode_t); extern struct richacl *richacl_create(umode_t *, struct inode *); +/* richacl_compat.c */ +extern int richacl_apply_masks(struct richacl **, kuid_t); + #endif /* __RICHACL_H */ -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:21:43 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 4D02729E66 for ; Tue, 3 Nov 2015 09:21:43 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id BD5D6AC002 for ; Tue, 3 Nov 2015 07:21:42 -0800 (PST) X-ASG-Debug-ID: 1446564100-04cbb0660f1f7db0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id RZoNfxi1SjntA8gc (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:21:40 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id BB905220; Tue, 3 Nov 2015 15:21:39 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRa1029477; Tue, 3 Nov 2015 10:21:33 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 35/51] richacl: Create richacl from mode values Date: Tue, 3 Nov 2015 16:17:11 +0100 X-ASG-Orig-Subj: [PATCH v13 35/51] richacl: Create richacl from mode values Message-Id: <1446563847-14005-36-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446564100 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 A file can have "no acl" in the sense that only the file mode permission bits determine access. In that case, the getxattr system call fails with errno == ENODATA (No such attribute). Over the NFSv4 protocol, a file always has an acl, and we convert the file mode permission bits into an equivalent acl with richacl_from_mode. Such "trivial" acls can be converted back to a file mode with richacl_equiv_mode. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_compat.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/richacl.h | 1 + 2 files changed, 89 insertions(+) diff --git a/fs/richacl_compat.c b/fs/richacl_compat.c index ea3effd..3a11773 100644 --- a/fs/richacl_compat.c +++ b/fs/richacl_compat.c @@ -827,3 +827,91 @@ richacl_apply_masks(struct richacl **acl, kuid_t owner) return 0; } EXPORT_SYMBOL_GPL(richacl_apply_masks); + +/** + * richacl_from_mode - create an acl which corresponds to @mode + * + * The resulting acl doesn't have the RICHACL_MASKED flag set. + * + * @mode: file mode including the file type + */ +struct richacl * +richacl_from_mode(umode_t mode) +{ + unsigned int owner_mask = richacl_mode_to_mask(mode >> 6); + unsigned int group_mask = richacl_mode_to_mask(mode >> 3); + unsigned int other_mask = richacl_mode_to_mask(mode); + unsigned int denied; + unsigned int entries = 0; + struct richacl *acl; + struct richace *ace; + + /* RICHACE_DELETE_CHILD is meaningless for non-directories. */ + if (!S_ISDIR(mode)) { + owner_mask &= ~RICHACE_DELETE_CHILD; + group_mask &= ~RICHACE_DELETE_CHILD; + other_mask &= ~RICHACE_DELETE_CHILD; + } + + denied = ~owner_mask & (group_mask | other_mask); + if (denied) + entries++; /* owner@ deny entry needed */ + if (owner_mask & ~(group_mask & other_mask)) + entries++; /* owner@ allow entry needed */ + denied = ~group_mask & other_mask; + if (denied) + entries++; /* group@ deny entry needed */ + if (group_mask & ~other_mask) + entries++; /* group@ allow entry needed */ + if (other_mask) + entries++; /* everyone@ allow entry needed */ + + acl = richacl_alloc(entries, GFP_KERNEL); + if (!acl) + return NULL; + acl->a_owner_mask = owner_mask; + acl->a_group_mask = group_mask; + acl->a_other_mask = other_mask; + ace = acl->a_entries; + + denied = ~owner_mask & (group_mask | other_mask); + if (denied) { + ace->e_type = RICHACE_ACCESS_DENIED_ACE_TYPE; + ace->e_flags = RICHACE_SPECIAL_WHO; + ace->e_mask = denied; + ace->e_id.special = RICHACE_OWNER_SPECIAL_ID; + ace++; + } + if (owner_mask & ~(group_mask & other_mask)) { + ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE; + ace->e_flags = RICHACE_SPECIAL_WHO; + ace->e_mask = owner_mask; + ace->e_id.special = RICHACE_OWNER_SPECIAL_ID; + ace++; + } + denied = ~group_mask & other_mask; + if (denied) { + ace->e_type = RICHACE_ACCESS_DENIED_ACE_TYPE; + ace->e_flags = RICHACE_SPECIAL_WHO; + ace->e_mask = denied; + ace->e_id.special = RICHACE_GROUP_SPECIAL_ID; + ace++; + } + if (group_mask & ~other_mask) { + ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE; + ace->e_flags = RICHACE_SPECIAL_WHO; + ace->e_mask = group_mask; + ace->e_id.special = RICHACE_GROUP_SPECIAL_ID; + ace++; + } + if (other_mask) { + ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE; + ace->e_flags = RICHACE_SPECIAL_WHO; + ace->e_mask = other_mask; + ace->e_id.special = RICHACE_EVERYONE_SPECIAL_ID; + ace++; + } + + return acl; +} +EXPORT_SYMBOL_GPL(richacl_from_mode); diff --git a/include/linux/richacl.h b/include/linux/richacl.h index 3fdfc57..10bfd0f 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -207,5 +207,6 @@ extern struct richacl *richacl_create(umode_t *, struct inode *); /* richacl_compat.c */ extern int richacl_apply_masks(struct richacl **, kuid_t); +extern struct richacl *richacl_from_mode(umode_t); #endif /* __RICHACL_H */ -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:21:48 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 A8AB029E6A for ; Tue, 3 Nov 2015 09:21:48 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 9800830404E for ; Tue, 3 Nov 2015 07:21:48 -0800 (PST) X-ASG-Debug-ID: 1446564106-04cbb0660d1f7dc0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 7d7hm44F5ybQeABT (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:21:47 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 81E0149DAD; Tue, 3 Nov 2015 15:21:46 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRa2029477; Tue, 3 Nov 2015 10:21:40 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 36/51] nfsd: Keep list of acls to dispose of in compoundargs Date: Tue, 3 Nov 2015 16:17:12 +0100 X-ASG-Orig-Subj: [PATCH v13 36/51] nfsd: Keep list of acls to dispose of in compoundargs Message-Id: <1446563847-14005-37-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446564107 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 We will decode acls in requests into richacls. Even if unlikely, there can be more than one acl in a single request; those richacls need to be richacl_put() at the end of the request instead of kfree()d, so keep a list of acls in compoundargs for that. Signed-off-by: Andreas Gruenbacher Acked-by: J. Bruce Fields --- fs/nfsd/nfs4xdr.c | 27 +++++++++++++++++++++++++++ fs/nfsd/xdr4.h | 6 ++++++ 2 files changed, 33 insertions(+) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 51c9e9c..b8db5a7 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -40,6 +40,7 @@ #include #include #include +#include #include "idmap.h" #include "acl.h" @@ -196,6 +197,24 @@ svcxdr_tmpalloc(struct nfsd4_compoundargs *argp, u32 len) return tb->buf; } +static struct richacl * +svcxdr_alloc_richacl(struct nfsd4_compoundargs *argp, u32 nace) +{ + struct svcxdr_richacl *acls; + + acls = kmalloc(sizeof(*acls), GFP_KERNEL); + if (!acls) + return NULL; + acls->acl = richacl_alloc(nace, GFP_KERNEL); + if (!acls->acl) { + kfree(acls); + return NULL; + } + acls->next = argp->acls; + argp->acls = acls; + return acls->acl; +} + /* * For xdr strings that need to be passed to other kernel api's * as null-terminated strings. @@ -4437,6 +4456,13 @@ int nfsd4_release_compoundargs(void *rq, __be32 *p, void *resp) args->to_free = tb->next; kfree(tb); } + while (args->acls) { + struct svcxdr_richacl *acls = args->acls; + + args->acls = acls->next; + richacl_put(acls->acl); + kfree(acls); + } return 1; } @@ -4455,6 +4481,7 @@ nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_comp args->pagelen = rqstp->rq_arg.page_len; args->tmpp = NULL; args->to_free = NULL; + args->acls = NULL; args->ops = args->iops; args->rqstp = rqstp; diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index 9f99100..b698585 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -570,6 +570,11 @@ struct svcxdr_tmpbuf { char buf[]; }; +struct svcxdr_richacl { + struct svcxdr_richacl *next; + struct richacl *acl; +}; + struct nfsd4_compoundargs { /* scratch variables for XDR decode */ __be32 * p; @@ -579,6 +584,7 @@ struct nfsd4_compoundargs { __be32 tmp[8]; __be32 * tmpp; struct svcxdr_tmpbuf *to_free; + struct svcxdr_richacl *acls; struct svc_rqst *rqstp; -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:21:58 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 1882B29E66 for ; Tue, 3 Nov 2015 09:21:58 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id EAD19304039 for ; Tue, 3 Nov 2015 07:21:57 -0800 (PST) X-ASG-Debug-ID: 1446564114-04cb6c7b861ddcd0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id ajYg9kkO98PbkGGo (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:21:54 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 71CD391588; Tue, 3 Nov 2015 15:21:53 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRa3029477; Tue, 3 Nov 2015 10:21:47 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 37/51] nfsd: Use richacls as internal acl representation Date: Tue, 3 Nov 2015 16:17:13 +0100 X-ASG-Orig-Subj: [PATCH v13 37/51] nfsd: Use richacls as internal acl representation Message-Id: <1446563847-14005-38-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446564114 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 When converting from NFSv4 ACLs to POSIX ACLs, nfsd so far was using struct nfs4_acl as its internal representation. This representation is a subset of richacls, so get rid of struct nfs4_acl. Richacls even have a more compact in-memory representation, so a few more ACL entries can easily be supported. Signed-off-by: Andreas Gruenbacher Acked-by: J. Bruce Fields --- fs/Kconfig | 6 + fs/nfs_common/Makefile | 1 + fs/nfs_common/nfs4acl.c | 44 ++++++ fs/nfsd/Kconfig | 1 + fs/nfsd/acl.h | 24 ++-- fs/nfsd/nfs4acl.c | 368 ++++++++++++++++++++++-------------------------- fs/nfsd/nfs4proc.c | 15 +- fs/nfsd/nfs4xdr.c | 64 +++------ fs/nfsd/xdr4.h | 6 +- include/linux/nfs4.h | 23 --- include/linux/nfs4acl.h | 7 + 11 files changed, 274 insertions(+), 285 deletions(-) create mode 100644 fs/nfs_common/nfs4acl.c create mode 100644 include/linux/nfs4acl.h diff --git a/fs/Kconfig b/fs/Kconfig index bff2879..68bc3e1 100644 --- a/fs/Kconfig +++ b/fs/Kconfig @@ -265,6 +265,12 @@ config NFS_COMMON depends on NFSD || NFS_FS || LOCKD default y +config NFS_RICHACL + bool + depends on NFSD_V4 || NFS_V4 + select FS_RICHACL + default y + source "net/sunrpc/Kconfig" source "fs/ceph/Kconfig" source "fs/cifs/Kconfig" diff --git a/fs/nfs_common/Makefile b/fs/nfs_common/Makefile index d153ca3..e055139 100644 --- a/fs/nfs_common/Makefile +++ b/fs/nfs_common/Makefile @@ -4,5 +4,6 @@ obj-$(CONFIG_NFS_ACL_SUPPORT) += nfs_acl.o nfs_acl-objs := nfsacl.o +obj-$(CONFIG_NFS_RICHACL) += nfs4acl.o obj-$(CONFIG_GRACE_PERIOD) += grace.o diff --git a/fs/nfs_common/nfs4acl.c b/fs/nfs_common/nfs4acl.c new file mode 100644 index 0000000..02df064 --- /dev/null +++ b/fs/nfs_common/nfs4acl.c @@ -0,0 +1,44 @@ +#include +#include +#include + +static struct special_id { + char *who; + int len; +} special_who_map[] = { + [RICHACE_OWNER_SPECIAL_ID] = { + .who = "OWNER@", + .len = sizeof("OWNER@") - 1 }, + [RICHACE_GROUP_SPECIAL_ID] = { + .who = "GROUP@", + .len = sizeof("GROUP@") - 1 }, + [RICHACE_EVERYONE_SPECIAL_ID] = { + .who = "EVERYONE@", + .len = sizeof("EVERYONE@") - 1 } +}; + +int nfs4acl_who_to_special_id(const char *who, u32 len) +{ + int n; + + for (n = 0; n < ARRAY_SIZE(special_who_map); n++) { + if (len == special_who_map[n].len && + !memcmp(who, special_who_map[n].who, len)) + return n; + } + return -1; +} +EXPORT_SYMBOL(nfs4acl_who_to_special_id); + +bool nfs4acl_special_id_to_who(unsigned int special_who, + const char **who, unsigned int *len) +{ + struct special_id *special = &special_who_map[special_who]; + + if (special_who > ARRAY_SIZE(special_who_map) || !special->len) + return false; + *who = special->who; + *len = special->len; + return true; +} +EXPORT_SYMBOL(nfs4acl_special_id_to_who); diff --git a/fs/nfsd/Kconfig b/fs/nfsd/Kconfig index a0b77fc..811379a 100644 --- a/fs/nfsd/Kconfig +++ b/fs/nfsd/Kconfig @@ -70,6 +70,7 @@ config NFSD_V4 depends on NFSD && PROC_FS select NFSD_V3 select FS_POSIX_ACL + select FS_RICHACL select SUNRPC_GSS select CRYPTO select GRACE_PERIOD diff --git a/fs/nfsd/acl.h b/fs/nfsd/acl.h index 4cd7c69..1c5deb5 100644 --- a/fs/nfsd/acl.h +++ b/fs/nfsd/acl.h @@ -35,25 +35,27 @@ #ifndef LINUX_NFS4_ACL_H #define LINUX_NFS4_ACL_H -struct nfs4_acl; +struct richacl; +struct richace; struct svc_fh; struct svc_rqst; /* * Maximum ACL we'll accept from a client; chosen (somewhat * arbitrarily) so that kmalloc'ing the ACL shouldn't require a - * high-order allocation. This allows 204 ACEs on x86_64: + * high-order allocation. This allows 339 ACEs on x86_64: */ -#define NFS4_ACL_MAX ((PAGE_SIZE - sizeof(struct nfs4_acl)) \ - / sizeof(struct nfs4_ace)) +#define NFSD4_ACL_MAX ((PAGE_SIZE - sizeof(struct richacl)) \ + / sizeof(struct richace)) -int nfs4_acl_bytes(int entries); -int nfs4_acl_get_whotype(char *, u32); -__be32 nfs4_acl_write_who(struct xdr_stream *xdr, int who); +__be32 nfsd4_decode_ace_who(struct richace *ace, struct svc_rqst *rqstp, + char *who, u32 len); +__be32 nfsd4_encode_ace_who(struct xdr_stream *xdr, struct svc_rqst *rqstp, + struct richace *ace); -int nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry, - struct nfs4_acl **acl); -__be32 nfsd4_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, - struct nfs4_acl *acl); +int nfsd4_get_acl(struct svc_rqst *rqstp, struct dentry *dentry, + struct richacl **acl); +__be32 nfsd4_set_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, + struct richacl *acl); #endif /* LINUX_NFS4_ACL_H */ diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c index 6adabd6..6d3bb72 100644 --- a/fs/nfsd/nfs4acl.c +++ b/fs/nfsd/nfs4acl.c @@ -37,46 +37,50 @@ #include #include #include +#include +#include +#include #include "nfsfh.h" #include "nfsd.h" +#include "idmap.h" #include "acl.h" #include "vfs.h" -#define NFS4_ACL_TYPE_DEFAULT 0x01 -#define NFS4_ACL_DIR 0x02 -#define NFS4_ACL_OWNER 0x04 +#define FLAG_DEFAULT_ACL 0x01 +#define FLAG_DIRECTORY 0x02 +#define FLAG_OWNER 0x04 /* mode bit translations: */ -#define NFS4_READ_MODE (NFS4_ACE_READ_DATA) -#define NFS4_WRITE_MODE (NFS4_ACE_WRITE_DATA | NFS4_ACE_APPEND_DATA) -#define NFS4_EXECUTE_MODE NFS4_ACE_EXECUTE -#define NFS4_ANYONE_MODE (NFS4_ACE_READ_ATTRIBUTES | NFS4_ACE_READ_ACL | NFS4_ACE_SYNCHRONIZE) -#define NFS4_OWNER_MODE (NFS4_ACE_WRITE_ATTRIBUTES | NFS4_ACE_WRITE_ACL) +#define RICHACE_READ_MODE (RICHACE_READ_DATA) +#define RICHACE_WRITE_MODE (RICHACE_WRITE_DATA | RICHACE_APPEND_DATA) +#define RICHACE_EXECUTE_MODE RICHACE_EXECUTE +#define RICHACE_ANYONE_MODE (RICHACE_READ_ATTRIBUTES | RICHACE_READ_ACL | RICHACE_SYNCHRONIZE) +#define RICHACE_OWNER_MODE (RICHACE_WRITE_ATTRIBUTES | RICHACE_WRITE_ACL) /* flags used to simulate posix default ACLs */ -#define NFS4_INHERITANCE_FLAGS (NFS4_ACE_FILE_INHERIT_ACE \ - | NFS4_ACE_DIRECTORY_INHERIT_ACE) - -#define NFS4_SUPPORTED_FLAGS (NFS4_INHERITANCE_FLAGS \ - | NFS4_ACE_INHERIT_ONLY_ACE \ - | NFS4_ACE_IDENTIFIER_GROUP) +#define RICHACE_SUPPORTED_FLAGS ( \ + RICHACE_FILE_INHERIT_ACE | \ + RICHACE_DIRECTORY_INHERIT_ACE | \ + RICHACE_INHERIT_ONLY_ACE | \ + RICHACE_IDENTIFIER_GROUP | \ + RICHACE_SPECIAL_WHO) static u32 mask_from_posix(unsigned short perm, unsigned int flags) { - int mask = NFS4_ANYONE_MODE; + int mask = RICHACE_ANYONE_MODE; - if (flags & NFS4_ACL_OWNER) - mask |= NFS4_OWNER_MODE; + if (flags & FLAG_OWNER) + mask |= RICHACE_OWNER_MODE; if (perm & ACL_READ) - mask |= NFS4_READ_MODE; + mask |= RICHACE_READ_MODE; if (perm & ACL_WRITE) - mask |= NFS4_WRITE_MODE; - if ((perm & ACL_WRITE) && (flags & NFS4_ACL_DIR)) - mask |= NFS4_ACE_DELETE_CHILD; + mask |= RICHACE_WRITE_MODE; + if ((perm & ACL_WRITE) && (flags & FLAG_DIRECTORY)) + mask |= RICHACE_DELETE_CHILD; if (perm & ACL_EXECUTE) - mask |= NFS4_EXECUTE_MODE; + mask |= RICHACE_EXECUTE_MODE; return mask; } @@ -86,13 +90,13 @@ deny_mask_from_posix(unsigned short perm, u32 flags) u32 mask = 0; if (perm & ACL_READ) - mask |= NFS4_READ_MODE; + mask |= RICHACE_READ_MODE; if (perm & ACL_WRITE) - mask |= NFS4_WRITE_MODE; - if ((perm & ACL_WRITE) && (flags & NFS4_ACL_DIR)) - mask |= NFS4_ACE_DELETE_CHILD; + mask |= RICHACE_WRITE_MODE; + if ((perm & ACL_WRITE) && (flags & FLAG_DIRECTORY)) + mask |= RICHACE_DELETE_CHILD; if (perm & ACL_EXECUTE) - mask |= NFS4_EXECUTE_MODE; + mask |= RICHACE_EXECUTE_MODE; return mask; } @@ -108,32 +112,33 @@ deny_mask_from_posix(unsigned short perm, u32 flags) static void low_mode_from_nfs4(u32 perm, unsigned short *mode, unsigned int flags) { - u32 write_mode = NFS4_WRITE_MODE; + u32 write_mode = RICHACE_WRITE_MODE; - if (flags & NFS4_ACL_DIR) - write_mode |= NFS4_ACE_DELETE_CHILD; + if (flags & FLAG_DIRECTORY) + write_mode |= RICHACE_DELETE_CHILD; *mode = 0; - if ((perm & NFS4_READ_MODE) == NFS4_READ_MODE) + if ((perm & RICHACE_READ_MODE) == RICHACE_READ_MODE) *mode |= ACL_READ; if ((perm & write_mode) == write_mode) *mode |= ACL_WRITE; - if ((perm & NFS4_EXECUTE_MODE) == NFS4_EXECUTE_MODE) + if ((perm & RICHACE_EXECUTE_MODE) == RICHACE_EXECUTE_MODE) *mode |= ACL_EXECUTE; } -static short ace2type(struct nfs4_ace *); -static void _posix_to_nfsv4_one(struct posix_acl *, struct nfs4_acl *, +static short ace2type(struct richace *); +static void _posix_to_richacl_one(struct posix_acl *, struct richacl_alloc *, unsigned int); int -nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry, - struct nfs4_acl **acl) +nfsd4_get_acl(struct svc_rqst *rqstp, struct dentry *dentry, + struct richacl **acl) { struct inode *inode = d_inode(dentry); int error = 0; struct posix_acl *pacl = NULL, *dpacl = NULL; + struct richacl_alloc alloc; unsigned int flags = 0; - int size = 0; + int count; pacl = get_acl(inode, ACL_TYPE_ACCESS); if (!pacl) @@ -143,10 +148,10 @@ nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry, return PTR_ERR(pacl); /* allocate for worst case: one (deny, allow) pair each: */ - size += 2 * pacl->a_count; + count = 2 * pacl->a_count; if (S_ISDIR(inode->i_mode)) { - flags = NFS4_ACL_DIR; + flags = FLAG_DIRECTORY; dpacl = get_acl(inode, ACL_TYPE_DEFAULT); if (IS_ERR(dpacl)) { error = PTR_ERR(dpacl); @@ -154,20 +159,20 @@ nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry, } if (dpacl) - size += 2 * dpacl->a_count; + count += 2 * dpacl->a_count; } - *acl = kmalloc(nfs4_acl_bytes(size), GFP_KERNEL); - if (*acl == NULL) { + if (!richacl_prepare(&alloc, count)) { error = -ENOMEM; goto out; } - (*acl)->naces = 0; - _posix_to_nfsv4_one(pacl, *acl, flags & ~NFS4_ACL_TYPE_DEFAULT); + _posix_to_richacl_one(pacl, &alloc, flags); if (dpacl) - _posix_to_nfsv4_one(dpacl, *acl, flags | NFS4_ACL_TYPE_DEFAULT); + _posix_to_richacl_one(dpacl, &alloc, flags | FLAG_DEFAULT_ACL); + + *acl = alloc.acl; out: posix_acl_release(dpacl); @@ -230,21 +235,22 @@ summarize_posix_acl(struct posix_acl *acl, struct posix_acl_summary *pas) /* We assume the acl has been verified with posix_acl_valid. */ static void -_posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl, - unsigned int flags) +_posix_to_richacl_one(struct posix_acl *pacl, struct richacl_alloc *alloc, + unsigned int flags) { struct posix_acl_entry *pa, *group_owner_entry; - struct nfs4_ace *ace; + struct richace *ace; struct posix_acl_summary pas; unsigned short deny; - int eflag = ((flags & NFS4_ACL_TYPE_DEFAULT) ? - NFS4_INHERITANCE_FLAGS | NFS4_ACE_INHERIT_ONLY_ACE : 0); + int e_flags = ((flags & FLAG_DEFAULT_ACL) ? + (RICHACE_FILE_INHERIT_ACE | + RICHACE_DIRECTORY_INHERIT_ACE | + RICHACE_INHERIT_ONLY_ACE) : 0); BUG_ON(pacl->a_count < 3); summarize_posix_acl(pacl, &pas); pa = pacl->a_entries; - ace = acl->aces + acl->naces; /* We could deny everything not granted by the owner: */ deny = ~pas.owner; @@ -254,42 +260,35 @@ _posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl, */ deny &= pas.users | pas.group | pas.groups | pas.other; if (deny) { - ace->type = NFS4_ACE_ACCESS_DENIED_ACE_TYPE; - ace->flag = eflag; - ace->access_mask = deny_mask_from_posix(deny, flags); - ace->whotype = NFS4_ACL_WHO_OWNER; - ace++; - acl->naces++; + ace = richacl_append_entry(alloc); + ace->e_type = RICHACE_ACCESS_DENIED_ACE_TYPE; + ace->e_flags = e_flags | RICHACE_SPECIAL_WHO; + ace->e_mask = deny_mask_from_posix(deny, flags); + ace->e_id.special = RICHACE_OWNER_SPECIAL_ID; } - ace->type = NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE; - ace->flag = eflag; - ace->access_mask = mask_from_posix(pa->e_perm, flags | NFS4_ACL_OWNER); - ace->whotype = NFS4_ACL_WHO_OWNER; - ace++; - acl->naces++; + ace = richacl_append_entry(alloc); + ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE; + ace->e_flags = e_flags | RICHACE_SPECIAL_WHO; + ace->e_mask = mask_from_posix(pa->e_perm, flags | FLAG_OWNER); + ace->e_id.special = RICHACE_OWNER_SPECIAL_ID; pa++; while (pa->e_tag == ACL_USER) { deny = ~(pa->e_perm & pas.mask); deny &= pas.groups | pas.group | pas.other; if (deny) { - ace->type = NFS4_ACE_ACCESS_DENIED_ACE_TYPE; - ace->flag = eflag; - ace->access_mask = deny_mask_from_posix(deny, flags); - ace->whotype = NFS4_ACL_WHO_NAMED; - ace->who_uid = pa->e_uid; - ace++; - acl->naces++; + ace = richacl_append_entry(alloc); + ace->e_type = RICHACE_ACCESS_DENIED_ACE_TYPE; + ace->e_flags = e_flags; + ace->e_mask = deny_mask_from_posix(deny, flags); + ace->e_id.uid = pa->e_uid; } - ace->type = NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE; - ace->flag = eflag; - ace->access_mask = mask_from_posix(pa->e_perm & pas.mask, - flags); - ace->whotype = NFS4_ACL_WHO_NAMED; - ace->who_uid = pa->e_uid; - ace++; - acl->naces++; + ace = richacl_append_entry(alloc); + ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE; + ace->e_flags = e_flags; + ace->e_mask = mask_from_posix(pa->e_perm & pas.mask, flags); + ace->e_id.uid = pa->e_uid; pa++; } @@ -300,23 +299,19 @@ _posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl, group_owner_entry = pa; - ace->type = NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE; - ace->flag = eflag; - ace->access_mask = mask_from_posix(pas.group, flags); - ace->whotype = NFS4_ACL_WHO_GROUP; - ace++; - acl->naces++; + ace = richacl_append_entry(alloc); + ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE; + ace->e_flags = e_flags | RICHACE_SPECIAL_WHO; + ace->e_mask = mask_from_posix(pas.group, flags); + ace->e_id.special = RICHACE_GROUP_SPECIAL_ID; pa++; while (pa->e_tag == ACL_GROUP) { - ace->type = NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE; - ace->flag = eflag | NFS4_ACE_IDENTIFIER_GROUP; - ace->access_mask = mask_from_posix(pa->e_perm & pas.mask, - flags); - ace->whotype = NFS4_ACL_WHO_NAMED; - ace->who_gid = pa->e_gid; - ace++; - acl->naces++; + ace = richacl_append_entry(alloc); + ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE; + ace->e_flags = e_flags | RICHACE_IDENTIFIER_GROUP; + ace->e_mask = mask_from_posix(pa->e_perm & pas.mask, flags); + ace->e_id.gid = pa->e_gid; pa++; } @@ -326,12 +321,11 @@ _posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl, deny = ~pas.group & pas.other; if (deny) { - ace->type = NFS4_ACE_ACCESS_DENIED_ACE_TYPE; - ace->flag = eflag; - ace->access_mask = deny_mask_from_posix(deny, flags); - ace->whotype = NFS4_ACL_WHO_GROUP; - ace++; - acl->naces++; + ace = richacl_append_entry(alloc); + ace->e_type = RICHACE_ACCESS_DENIED_ACE_TYPE; + ace->e_flags = e_flags | RICHACE_SPECIAL_WHO; + ace->e_mask = deny_mask_from_posix(deny, flags); + ace->e_id.special = RICHACE_GROUP_SPECIAL_ID; } pa++; @@ -339,24 +333,22 @@ _posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl, deny = ~(pa->e_perm & pas.mask); deny &= pas.other; if (deny) { - ace->type = NFS4_ACE_ACCESS_DENIED_ACE_TYPE; - ace->flag = eflag | NFS4_ACE_IDENTIFIER_GROUP; - ace->access_mask = deny_mask_from_posix(deny, flags); - ace->whotype = NFS4_ACL_WHO_NAMED; - ace->who_gid = pa->e_gid; - ace++; - acl->naces++; + ace = richacl_append_entry(alloc); + ace->e_type = RICHACE_ACCESS_DENIED_ACE_TYPE; + ace->e_flags = e_flags | RICHACE_IDENTIFIER_GROUP; + ace->e_mask = deny_mask_from_posix(deny, flags); + ace->e_id.gid = pa->e_gid; } pa++; } if (pa->e_tag == ACL_MASK) pa++; - ace->type = NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE; - ace->flag = eflag; - ace->access_mask = mask_from_posix(pa->e_perm, flags); - ace->whotype = NFS4_ACL_WHO_EVERYONE; - acl->naces++; + ace = richacl_append_entry(alloc); + ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE; + ace->e_flags = e_flags | RICHACE_SPECIAL_WHO; + ace->e_mask = mask_from_posix(pa->e_perm, flags); + ace->e_id.special = RICHACE_EVERYONE_SPECIAL_ID; } static bool @@ -500,7 +492,7 @@ posix_state_to_acl(struct posix_acl_state *state, unsigned int flags) * and effective cases: when there are no inheritable ACEs, * calls ->set_acl with a NULL ACL structure. */ - if (state->empty && (flags & NFS4_ACL_TYPE_DEFAULT)) + if (state->empty && (flags & FLAG_DEFAULT_ACL)) return NULL; /* @@ -619,24 +611,24 @@ static void allow_bits_array(struct posix_ace_state_array *a, u32 mask) } static void process_one_v4_ace(struct posix_acl_state *state, - struct nfs4_ace *ace) + struct richace *ace) { - u32 mask = ace->access_mask; + u32 mask = ace->e_mask; int i; state->empty = 0; switch (ace2type(ace)) { case ACL_USER_OBJ: - if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) { + if (ace->e_type == RICHACE_ACCESS_ALLOWED_ACE_TYPE) { allow_bits(&state->owner, mask); } else { deny_bits(&state->owner, mask); } break; case ACL_USER: - i = find_uid(state, ace->who_uid); - if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) { + i = find_uid(state, ace->e_id.uid); + if (ace->e_type == RICHACE_ACCESS_ALLOWED_ACE_TYPE) { allow_bits(&state->users->aces[i].perms, mask); } else { deny_bits(&state->users->aces[i].perms, mask); @@ -645,7 +637,7 @@ static void process_one_v4_ace(struct posix_acl_state *state, } break; case ACL_GROUP_OBJ: - if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) { + if (ace->e_type == RICHACE_ACCESS_ALLOWED_ACE_TYPE) { allow_bits(&state->group, mask); } else { deny_bits(&state->group, mask); @@ -657,8 +649,8 @@ static void process_one_v4_ace(struct posix_acl_state *state, } break; case ACL_GROUP: - i = find_gid(state, ace->who_gid); - if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) { + i = find_gid(state, ace->e_id.gid); + if (ace->e_type == RICHACE_ACCESS_ALLOWED_ACE_TYPE) { allow_bits(&state->groups->aces[i].perms, mask); } else { deny_bits(&state->groups->aces[i].perms, mask); @@ -671,7 +663,7 @@ static void process_one_v4_ace(struct posix_acl_state *state, } break; case ACL_OTHER: - if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) { + if (ace->e_type == RICHACE_ACCESS_ALLOWED_ACE_TYPE) { allow_bits(&state->owner, mask); allow_bits(&state->group, mask); allow_bits(&state->other, mask); @@ -689,32 +681,33 @@ static void process_one_v4_ace(struct posix_acl_state *state, } } -static int nfs4_acl_nfsv4_to_posix(struct nfs4_acl *acl, +static int nfs4_richacl_to_posix(struct richacl *acl, struct posix_acl **pacl, struct posix_acl **dpacl, unsigned int flags) { struct posix_acl_state effective_acl_state, default_acl_state; - struct nfs4_ace *ace; + struct richace *ace; int ret; - ret = init_state(&effective_acl_state, acl->naces); + ret = init_state(&effective_acl_state, acl->a_count); if (ret) return ret; - ret = init_state(&default_acl_state, acl->naces); + ret = init_state(&default_acl_state, acl->a_count); if (ret) goto out_estate; ret = -EINVAL; - for (ace = acl->aces; ace < acl->aces + acl->naces; ace++) { - if (ace->type != NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE && - ace->type != NFS4_ACE_ACCESS_DENIED_ACE_TYPE) + richacl_for_each_entry(ace, acl) { + if (ace->e_type != RICHACE_ACCESS_ALLOWED_ACE_TYPE && + ace->e_type != RICHACE_ACCESS_DENIED_ACE_TYPE) goto out_dstate; - if (ace->flag & ~NFS4_SUPPORTED_FLAGS) + if (ace->e_flags & ~RICHACE_SUPPORTED_FLAGS) goto out_dstate; - if ((ace->flag & NFS4_INHERITANCE_FLAGS) == 0) { + if ((ace->e_flags & (RICHACE_FILE_INHERIT_ACE | + RICHACE_DIRECTORY_INHERIT_ACE)) == 0) { process_one_v4_ace(&effective_acl_state, ace); continue; } - if (!(flags & NFS4_ACL_DIR)) + if (!(flags & FLAG_DIRECTORY)) goto out_dstate; /* * Note that when only one of FILE_INHERIT or DIRECTORY_INHERIT @@ -723,7 +716,7 @@ static int nfs4_acl_nfsv4_to_posix(struct nfs4_acl *acl, */ process_one_v4_ace(&default_acl_state, ace); - if (!(ace->flag & NFS4_ACE_INHERIT_ONLY_ACE)) + if (!(ace->e_flags & RICHACE_INHERIT_ONLY_ACE)) process_one_v4_ace(&effective_acl_state, ace); } *pacl = posix_state_to_acl(&effective_acl_state, flags); @@ -733,7 +726,7 @@ static int nfs4_acl_nfsv4_to_posix(struct nfs4_acl *acl, goto out_dstate; } *dpacl = posix_state_to_acl(&default_acl_state, - flags | NFS4_ACL_TYPE_DEFAULT); + flags | FLAG_DEFAULT_ACL); if (IS_ERR(*dpacl)) { ret = PTR_ERR(*dpacl); *dpacl = NULL; @@ -752,8 +745,7 @@ out_estate: } __be32 -nfsd4_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, - struct nfs4_acl *acl) +nfsd4_set_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, struct richacl *acl) { __be32 error; int host_error; @@ -774,9 +766,9 @@ nfsd4_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, return nfserr_attrnotsupp; if (S_ISDIR(inode->i_mode)) - flags = NFS4_ACL_DIR; + flags = FLAG_DIRECTORY; - host_error = nfs4_acl_nfsv4_to_posix(acl, &pacl, &dpacl, flags); + host_error = nfs4_richacl_to_posix(acl, &pacl, &dpacl, flags); if (host_error == -EINVAL) return nfserr_attrnotsupp; if (host_error < 0) @@ -803,82 +795,62 @@ out_nfserr: static short -ace2type(struct nfs4_ace *ace) +ace2type(struct richace *ace) { - switch (ace->whotype) { - case NFS4_ACL_WHO_NAMED: - return (ace->flag & NFS4_ACE_IDENTIFIER_GROUP ? - ACL_GROUP : ACL_USER); - case NFS4_ACL_WHO_OWNER: + if (ace->e_flags & RICHACE_SPECIAL_WHO) { + switch (ace->e_id.special) { + case RICHACE_OWNER_SPECIAL_ID: return ACL_USER_OBJ; - case NFS4_ACL_WHO_GROUP: + case RICHACE_GROUP_SPECIAL_ID: return ACL_GROUP_OBJ; - case NFS4_ACL_WHO_EVERYONE: + case RICHACE_EVERYONE_SPECIAL_ID: return ACL_OTHER; + default: + BUG(); + } } - BUG(); - return -1; -} - -/* - * return the size of the struct nfs4_acl required to represent an acl - * with @entries entries. - */ -int nfs4_acl_bytes(int entries) -{ - return sizeof(struct nfs4_acl) + entries * sizeof(struct nfs4_ace); + return ace->e_flags & RICHACE_IDENTIFIER_GROUP ? ACL_GROUP : ACL_USER; } -static struct { - char *string; - int stringlen; - int type; -} s2t_map[] = { - { - .string = "OWNER@", - .stringlen = sizeof("OWNER@") - 1, - .type = NFS4_ACL_WHO_OWNER, - }, - { - .string = "GROUP@", - .stringlen = sizeof("GROUP@") - 1, - .type = NFS4_ACL_WHO_GROUP, - }, - { - .string = "EVERYONE@", - .stringlen = sizeof("EVERYONE@") - 1, - .type = NFS4_ACL_WHO_EVERYONE, - }, -}; - -int -nfs4_acl_get_whotype(char *p, u32 len) +__be32 nfsd4_decode_ace_who(struct richace *ace, struct svc_rqst *rqstp, + char *who, u32 len) { - int i; - - for (i = 0; i < ARRAY_SIZE(s2t_map); i++) { - if (s2t_map[i].stringlen == len && - 0 == memcmp(s2t_map[i].string, p, len)) - return s2t_map[i].type; + int special_id; + + special_id = nfs4acl_who_to_special_id(who, len); + if (special_id >= 0) { + ace->e_flags |= RICHACE_SPECIAL_WHO; + ace->e_flags &= ~RICHACE_IDENTIFIER_GROUP; + ace->e_id.special = special_id; + return nfs_ok; } - return NFS4_ACL_WHO_NAMED; + if (ace->e_flags & RICHACE_IDENTIFIER_GROUP) + return nfsd_map_name_to_gid(rqstp, who, len, &ace->e_id.gid); + else + return nfsd_map_name_to_uid(rqstp, who, len, &ace->e_id.uid); } -__be32 nfs4_acl_write_who(struct xdr_stream *xdr, int who) +__be32 nfsd4_encode_ace_who(struct xdr_stream *xdr, struct svc_rqst *rqstp, + struct richace *ace) { - __be32 *p; - int i; - - for (i = 0; i < ARRAY_SIZE(s2t_map); i++) { - if (s2t_map[i].type != who) - continue; - p = xdr_reserve_space(xdr, s2t_map[i].stringlen + 4); + if (ace->e_flags & RICHACE_SPECIAL_WHO) { + unsigned int special_id = ace->e_id.special; + const char *who; + unsigned int len; + __be32 *p; + + if (!nfs4acl_special_id_to_who(special_id, &who, &len)) { + WARN_ON_ONCE(1); + return nfserr_serverfault; + } + p = xdr_reserve_space(xdr, len + 4); if (!p) return nfserr_resource; - p = xdr_encode_opaque(p, s2t_map[i].string, - s2t_map[i].stringlen); + p = xdr_encode_opaque(p, who, len); return 0; } - WARN_ON_ONCE(1); - return nfserr_serverfault; + if (ace->e_flags & RICHACE_IDENTIFIER_GROUP) + return nfsd4_encode_group(xdr, rqstp, ace->e_id.gid); + else + return nfsd4_encode_user(xdr, rqstp, ace->e_id.uid); } diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 4ce6b97..2430235 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -159,12 +159,12 @@ is_create_with_attrs(struct nfsd4_open *open) * in the returned attr bitmap. */ static void -do_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, - struct nfs4_acl *acl, u32 *bmval) +do_set_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, struct richacl *acl, + u32 *bmval) { __be32 status; - status = nfsd4_set_nfs4_acl(rqstp, fhp, acl); + status = nfsd4_set_acl(rqstp, fhp, acl); if (status) /* * We should probably fail the whole open at this point, @@ -299,7 +299,7 @@ do_open_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, stru goto out; if (is_create_with_attrs(open) && open->op_acl != NULL) - do_set_nfs4_acl(rqstp, *resfh, open->op_acl, open->op_bmval); + do_set_acl(rqstp, *resfh, open->op_acl, open->op_bmval); nfsd4_set_open_owner_reply_cache(cstate, open, *resfh); accmode = NFSD_MAY_NOP; @@ -672,8 +672,7 @@ nfsd4_create(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, nfsd4_security_inode_setsecctx(&resfh, &create->cr_label, create->cr_bmval); if (create->cr_acl != NULL) - do_set_nfs4_acl(rqstp, &resfh, create->cr_acl, - create->cr_bmval); + do_set_acl(rqstp, &resfh, create->cr_acl, create->cr_bmval); fh_unlock(&cstate->current_fh); set_change_info(&create->cr_cinfo, &cstate->current_fh); @@ -938,8 +937,8 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, goto out; if (setattr->sa_acl != NULL) - status = nfsd4_set_nfs4_acl(rqstp, &cstate->current_fh, - setattr->sa_acl); + status = nfsd4_set_acl(rqstp, &cstate->current_fh, + setattr->sa_acl); if (status) goto out; if (setattr->sa_label.len) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index b8db5a7..8603f40 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -303,7 +303,7 @@ nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval) static __be32 nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, - struct iattr *iattr, struct nfs4_acl **acl, + struct iattr *iattr, struct richacl **acl, struct xdr_netobj *label) { int expected_len, len = 0; @@ -326,38 +326,31 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, } if (bmval[0] & FATTR4_WORD0_ACL) { u32 nace; - struct nfs4_ace *ace; + struct richace *ace; READ_BUF(4); len += 4; nace = be32_to_cpup(p++); - if (nace > NFS4_ACL_MAX) + if (nace > NFSD4_ACL_MAX) return nfserr_fbig; - *acl = svcxdr_tmpalloc(argp, nfs4_acl_bytes(nace)); + *acl = svcxdr_alloc_richacl(argp, nace); if (*acl == NULL) return nfserr_jukebox; - (*acl)->naces = nace; - for (ace = (*acl)->aces; ace < (*acl)->aces + nace; ace++) { + richacl_for_each_entry(ace, *acl) { READ_BUF(16); len += 16; - ace->type = be32_to_cpup(p++); - ace->flag = be32_to_cpup(p++); - ace->access_mask = be32_to_cpup(p++); + ace->e_type = be32_to_cpup(p++); + ace->e_flags = be32_to_cpup(p++); + ace->e_mask = be32_to_cpup(p++); + if (ace->e_flags & RICHACE_SPECIAL_WHO) + return nfserr_inval; dummy32 = be32_to_cpup(p++); READ_BUF(dummy32); len += XDR_QUADLEN(dummy32) << 2; READMEM(buf, dummy32); - ace->whotype = nfs4_acl_get_whotype(buf, dummy32); - status = nfs_ok; - if (ace->whotype != NFS4_ACL_WHO_NAMED) - ; - else if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP) - status = nfsd_map_name_to_gid(argp->rqstp, - buf, dummy32, &ace->who_gid); - else - status = nfsd_map_name_to_uid(argp->rqstp, - buf, dummy32, &ace->who_uid); + status = nfsd4_decode_ace_who(ace, argp->rqstp, + buf, dummy32); if (status) return status; } @@ -2148,18 +2141,6 @@ static u32 nfs4_file_type(umode_t mode) } static inline __be32 -nfsd4_encode_aclname(struct xdr_stream *xdr, struct svc_rqst *rqstp, - struct nfs4_ace *ace) -{ - if (ace->whotype != NFS4_ACL_WHO_NAMED) - return nfs4_acl_write_who(xdr, ace->whotype); - else if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP) - return nfsd4_encode_group(xdr, rqstp, ace->who_gid); - else - return nfsd4_encode_user(xdr, rqstp, ace->who_uid); -} - -static inline __be32 nfsd4_encode_layout_type(struct xdr_stream *xdr, enum pnfs_layouttype layout_type) { __be32 *p; @@ -2303,7 +2284,7 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, u32 rdattr_err = 0; __be32 status; int err; - struct nfs4_acl *acl = NULL; + struct richacl *acl = NULL; void *context = NULL; int contextlen; bool contextsupport = false; @@ -2349,7 +2330,7 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, fhp = tempfh; } if (bmval0 & FATTR4_WORD0_ACL) { - err = nfsd4_get_nfs4_acl(rqstp, dentry, &acl); + err = nfsd4_get_acl(rqstp, dentry, &acl); if (err == -EOPNOTSUPP) bmval0 &= ~FATTR4_WORD0_ACL; else if (err == -EINVAL) { @@ -2504,7 +2485,7 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, *p++ = cpu_to_be32(rdattr_err); } if (bmval0 & FATTR4_WORD0_ACL) { - struct nfs4_ace *ace; + struct richace *ace; if (acl == NULL) { p = xdr_reserve_space(xdr, 4); @@ -2517,17 +2498,16 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, p = xdr_reserve_space(xdr, 4); if (!p) goto out_resource; - *p++ = cpu_to_be32(acl->naces); + *p++ = cpu_to_be32(acl->a_count); - for (ace = acl->aces; ace < acl->aces + acl->naces; ace++) { + richacl_for_each_entry(ace, acl) { p = xdr_reserve_space(xdr, 4*3); if (!p) goto out_resource; - *p++ = cpu_to_be32(ace->type); - *p++ = cpu_to_be32(ace->flag); - *p++ = cpu_to_be32(ace->access_mask & - NFS4_ACE_MASK_ALL); - status = nfsd4_encode_aclname(xdr, rqstp, ace); + *p++ = cpu_to_be32(ace->e_type); + *p++ = cpu_to_be32(ace->e_flags & ~RICHACE_SPECIAL_WHO); + *p++ = cpu_to_be32(ace->e_mask & NFS4_ACE_MASK_ALL); + status = nfsd4_encode_ace_who(xdr, rqstp, ace); if (status) goto out; } @@ -2792,7 +2772,7 @@ out: if (context) security_release_secctx(context, contextlen); #endif /* CONFIG_NFSD_V4_SECURITY_LABEL */ - kfree(acl); + richacl_put(acl); if (tempfh) { fh_put(tempfh); kfree(tempfh); diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index b698585..c311066 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -118,7 +118,7 @@ struct nfsd4_create { u32 cr_bmval[3]; /* request */ struct iattr cr_iattr; /* request */ struct nfsd4_change_info cr_cinfo; /* response */ - struct nfs4_acl *cr_acl; + struct richacl *cr_acl; struct xdr_netobj cr_label; }; #define cr_datalen u.link.datalen @@ -248,7 +248,7 @@ struct nfsd4_open { struct nfs4_file *op_file; /* used during processing */ struct nfs4_ol_stateid *op_stp; /* used during processing */ struct nfs4_clnt_odstate *op_odstate; /* used during processing */ - struct nfs4_acl *op_acl; + struct richacl *op_acl; struct xdr_netobj op_label; }; @@ -332,7 +332,7 @@ struct nfsd4_setattr { stateid_t sa_stateid; /* request */ u32 sa_bmval[3]; /* request */ struct iattr sa_iattr; /* request */ - struct nfs4_acl *sa_acl; + struct richacl *sa_acl; struct xdr_netobj sa_label; }; diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h index 00121f2..1422fc6 100644 --- a/include/linux/nfs4.h +++ b/include/linux/nfs4.h @@ -16,29 +16,6 @@ #include #include -enum nfs4_acl_whotype { - NFS4_ACL_WHO_NAMED = 0, - NFS4_ACL_WHO_OWNER, - NFS4_ACL_WHO_GROUP, - NFS4_ACL_WHO_EVERYONE, -}; - -struct nfs4_ace { - uint32_t type; - uint32_t flag; - uint32_t access_mask; - int whotype; - union { - kuid_t who_uid; - kgid_t who_gid; - }; -}; - -struct nfs4_acl { - uint32_t naces; - struct nfs4_ace aces[0]; -}; - #define NFS4_MAXLABELLEN 2048 struct nfs4_label { diff --git a/include/linux/nfs4acl.h b/include/linux/nfs4acl.h new file mode 100644 index 0000000..db9f9a6 --- /dev/null +++ b/include/linux/nfs4acl.h @@ -0,0 +1,7 @@ +#ifndef __LINUX_NFS4ACL_H +#define __LINUX_NFS4ACL_H + +int nfs4acl_who_to_special_id(const char *, u32); +bool nfs4acl_special_id_to_who(unsigned int, const char **, unsigned int *); + +#endif -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:22:03 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 4005029E72 for ; Tue, 3 Nov 2015 09:22:03 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id ABECFAC009 for ; Tue, 3 Nov 2015 07:22:02 -0800 (PST) X-ASG-Debug-ID: 1446564120-04cb6c7b871ddce0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id bdlJmVUbbkJ8HbqP (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:22:01 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 617128FAA3; Tue, 3 Nov 2015 15:22:00 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRa4029477; Tue, 3 Nov 2015 10:21:54 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 38/51] nfsd: Add richacl support Date: Tue, 3 Nov 2015 16:17:14 +0100 X-ASG-Orig-Subj: [PATCH v13 38/51] nfsd: Add richacl support Message-Id: <1446563847-14005-39-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446564120 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On file systems with richacls enabled, get and set richacls directly instead of converting from / to posix acls. Signed-off-by: Andreas Gruenbacher Acked-by: J. Bruce Fields --- fs/nfsd/acl.h | 3 +- fs/nfsd/nfs4acl.c | 124 ++++++++++++++++++++++++++++++++++++++--------------- fs/nfsd/nfs4proc.c | 2 +- fs/nfsd/nfs4xdr.c | 34 +++++++++++---- 4 files changed, 117 insertions(+), 46 deletions(-) diff --git a/fs/nfsd/acl.h b/fs/nfsd/acl.h index 1c5deb5..d73c664 100644 --- a/fs/nfsd/acl.h +++ b/fs/nfsd/acl.h @@ -53,8 +53,7 @@ __be32 nfsd4_decode_ace_who(struct richace *ace, struct svc_rqst *rqstp, __be32 nfsd4_encode_ace_who(struct xdr_stream *xdr, struct svc_rqst *rqstp, struct richace *ace); -int nfsd4_get_acl(struct svc_rqst *rqstp, struct dentry *dentry, - struct richacl **acl); +struct richacl *nfsd4_get_acl(struct svc_rqst *rqstp, struct dentry *dentry); __be32 nfsd4_set_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, struct richacl *acl); diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c index 6d3bb72..f017a76 100644 --- a/fs/nfsd/nfs4acl.c +++ b/fs/nfsd/nfs4acl.c @@ -40,6 +40,8 @@ #include #include #include +#include +#include #include "nfsfh.h" #include "nfsd.h" @@ -129,32 +131,28 @@ static short ace2type(struct richace *); static void _posix_to_richacl_one(struct posix_acl *, struct richacl_alloc *, unsigned int); -int -nfsd4_get_acl(struct svc_rqst *rqstp, struct dentry *dentry, - struct richacl **acl) +static struct richacl * +nfsd4_get_posix_acl(struct svc_rqst *rqstp, struct dentry *dentry) { struct inode *inode = d_inode(dentry); - int error = 0; struct posix_acl *pacl = NULL, *dpacl = NULL; struct richacl_alloc alloc; unsigned int flags = 0; int count; pacl = get_acl(inode, ACL_TYPE_ACCESS); - if (!pacl) - pacl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL); - - if (IS_ERR(pacl)) - return PTR_ERR(pacl); + if (IS_ERR_OR_NULL(pacl)) + return (void *)pacl; - /* allocate for worst case: one (deny, allow) pair each: */ + /* Allocate for worst case: one (deny, allow) pair each. The resulting + acl will be released shortly and won't be cached. */ count = 2 * pacl->a_count; if (S_ISDIR(inode->i_mode)) { flags = FLAG_DIRECTORY; dpacl = get_acl(inode, ACL_TYPE_DEFAULT); if (IS_ERR(dpacl)) { - error = PTR_ERR(dpacl); + alloc.acl = (void *)dpacl; goto rel_pacl; } @@ -163,7 +161,7 @@ nfsd4_get_acl(struct svc_rqst *rqstp, struct dentry *dentry, } if (!richacl_prepare(&alloc, count)) { - error = -ENOMEM; + alloc.acl = ERR_PTR(-ENOMEM); goto out; } @@ -172,13 +170,37 @@ nfsd4_get_acl(struct svc_rqst *rqstp, struct dentry *dentry, if (dpacl) _posix_to_richacl_one(dpacl, &alloc, flags | FLAG_DEFAULT_ACL); - *acl = alloc.acl; - out: posix_acl_release(dpacl); rel_pacl: posix_acl_release(pacl); - return error; + return alloc.acl; +} + +struct richacl * +nfsd4_get_acl(struct svc_rqst *rqstp, struct dentry *dentry) +{ + struct inode *inode = d_inode(dentry); + struct richacl *acl; + int error; + + if (IS_RICHACL(inode)) + acl = get_richacl(inode); + else + acl = nfsd4_get_posix_acl(rqstp, dentry); + if (IS_ERR(acl)) + return acl; + else if (acl == NULL) { + acl = richacl_from_mode(inode->i_mode); + if (acl == NULL) + acl = ERR_PTR(-ENOMEM); + } + error = richacl_apply_masks(&acl, inode->i_uid); + if (error) { + richacl_put(acl); + acl = ERR_PTR(error); + } + return acl; } struct posix_acl_summary { @@ -744,56 +766,88 @@ out_estate: return ret; } -__be32 -nfsd4_set_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, struct richacl *acl) +static int +nfsd4_set_posix_acl(struct svc_rqst *rqstp, struct dentry *dentry, + struct richacl *acl) { - __be32 error; int host_error; - struct dentry *dentry; - struct inode *inode; + struct inode *inode = d_inode(dentry); struct posix_acl *pacl = NULL, *dpacl = NULL; unsigned int flags = 0; - /* Get inode */ - error = fh_verify(rqstp, fhp, 0, NFSD_MAY_SATTR); - if (error) - return error; - - dentry = fhp->fh_dentry; - inode = d_inode(dentry); - if (!inode->i_op->set_acl || !IS_POSIXACL(inode)) - return nfserr_attrnotsupp; + return -EOPNOTSUPP; if (S_ISDIR(inode->i_mode)) flags = FLAG_DIRECTORY; host_error = nfs4_richacl_to_posix(acl, &pacl, &dpacl, flags); if (host_error == -EINVAL) - return nfserr_attrnotsupp; + return -EOPNOTSUPP; if (host_error < 0) - goto out_nfserr; + return host_error; host_error = inode->i_op->set_acl(inode, pacl, ACL_TYPE_ACCESS); if (host_error < 0) goto out_release; - if (S_ISDIR(inode->i_mode)) { + if (S_ISDIR(inode->i_mode)) host_error = inode->i_op->set_acl(inode, dpacl, ACL_TYPE_DEFAULT); - } out_release: posix_acl_release(pacl); posix_acl_release(dpacl); -out_nfserr: + return host_error; +} + +static int +nfsd4_set_richacl(struct svc_rqst *rqstp, struct dentry *dentry, + struct richacl *acl) +{ + int host_error; + struct inode *inode = d_inode(dentry); + size_t size = richacl_xattr_size(acl); + char *buffer; + + if (!inode->i_op->setxattr || !IS_RICHACL(inode)) + return -EOPNOTSUPP; + + richacl_compute_max_masks(acl); + + buffer = kmalloc(size, GFP_KERNEL); + if (!buffer) + return -ENOMEM; + richacl_to_xattr(&init_user_ns, acl, buffer, size); + host_error = inode->i_op->setxattr(dentry, XATTR_NAME_RICHACL, + buffer, size, 0); + kfree(buffer); + return host_error; +} + +__be32 +nfsd4_set_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, struct richacl *acl) +{ + struct dentry *dentry; + int host_error; + __be32 error; + + error = fh_verify(rqstp, fhp, 0, NFSD_MAY_SATTR); + if (error) + return error; + dentry = fhp->fh_dentry; + + if (IS_RICHACL(d_inode(dentry))) + host_error = nfsd4_set_richacl(rqstp, dentry, acl); + else + host_error = nfsd4_set_posix_acl(rqstp, dentry, acl); + if (host_error == -EOPNOTSUPP) return nfserr_attrnotsupp; else return nfserrno(host_error); } - static short ace2type(struct richace *ace) { diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 2430235..1bcfda2 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -110,7 +110,7 @@ check_attr_support(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, * in current environment or not. */ if (bmval[0] & FATTR4_WORD0_ACL) { - if (!IS_POSIXACL(d_inode(dentry))) + if (!IS_ACL(d_inode(dentry))) return nfserr_attrnotsupp; } diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 8603f40..682a7d8 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -340,11 +340,24 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, richacl_for_each_entry(ace, *acl) { READ_BUF(16); len += 16; - ace->e_type = be32_to_cpup(p++); - ace->e_flags = be32_to_cpup(p++); - ace->e_mask = be32_to_cpup(p++); - if (ace->e_flags & RICHACE_SPECIAL_WHO) + + dummy32 = be32_to_cpup(p++); + if (dummy32 > RICHACE_ACCESS_DENIED_ACE_TYPE) + return nfserr_inval; + ace->e_type = dummy32; + + dummy32 = be32_to_cpup(p++); + if (dummy32 & (~RICHACE_VALID_FLAGS | + RICHACE_INHERITED_ACE | + RICHACE_SPECIAL_WHO)) return nfserr_inval; + ace->e_flags = dummy32; + + dummy32 = be32_to_cpup(p++); + if (dummy32 & ~NFS4_ACE_MASK_ALL) + return nfserr_inval; + ace->e_mask = dummy32; + dummy32 = be32_to_cpup(p++); READ_BUF(dummy32); len += XDR_QUADLEN(dummy32) << 2; @@ -2330,7 +2343,11 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, fhp = tempfh; } if (bmval0 & FATTR4_WORD0_ACL) { - err = nfsd4_get_acl(rqstp, dentry, &acl); + acl = nfsd4_get_acl(rqstp, dentry); + if (IS_ERR(acl)) { + err = PTR_ERR(acl); + acl = NULL; + } if (err == -EOPNOTSUPP) bmval0 &= ~FATTR4_WORD0_ACL; else if (err == -EINVAL) { @@ -2370,7 +2387,7 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, u32 word1 = nfsd_suppattrs1(minorversion); u32 word2 = nfsd_suppattrs2(minorversion); - if (!IS_POSIXACL(dentry->d_inode)) + if (!IS_ACL(d_inode(dentry))) word0 &= ~FATTR4_WORD0_ACL; if (!contextsupport) word2 &= ~FATTR4_WORD2_SECURITY_LABEL; @@ -2505,7 +2522,8 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, if (!p) goto out_resource; *p++ = cpu_to_be32(ace->e_type); - *p++ = cpu_to_be32(ace->e_flags & ~RICHACE_SPECIAL_WHO); + *p++ = cpu_to_be32(ace->e_flags & + ~(RICHACE_SPECIAL_WHO | RICHACE_INHERITED_ACE)); *p++ = cpu_to_be32(ace->e_mask & NFS4_ACE_MASK_ALL); status = nfsd4_encode_ace_who(xdr, rqstp, ace); if (status) @@ -2517,7 +2535,7 @@ out_acl: p = xdr_reserve_space(xdr, 4); if (!p) goto out_resource; - *p++ = cpu_to_be32(IS_POSIXACL(dentry->d_inode) ? + *p++ = cpu_to_be32(IS_ACL(d_inode(dentry)) ? ACL4_SUPPORT_ALLOW_ACL|ACL4_SUPPORT_DENY_ACL : 0); } if (bmval0 & FATTR4_WORD0_CANSETTIME) { -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:22:11 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 6B6FD29E66 for ; Tue, 3 Nov 2015 09:22:11 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id D310BAC001 for ; Tue, 3 Nov 2015 07:22:10 -0800 (PST) X-ASG-Debug-ID: 1446564128-04cb6c7b861ddcf0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id QplrGERyiFKMcQ8M (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:22:09 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 5AC0AC10046C; Tue, 3 Nov 2015 15:22:08 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRa5029477; Tue, 3 Nov 2015 10:22:01 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 39/51] nfsd: Add support for the v4.1 dacl attribute Date: Tue, 3 Nov 2015 16:17:15 +0100 X-ASG-Orig-Subj: [PATCH v13 39/51] nfsd: Add support for the v4.1 dacl attribute Message-Id: <1446563847-14005-40-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446564128 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Richacls support the Automatic Inheritance permission propagation mechanism as specified in NFSv4.1. Over NFS, this requires support for the dacl attribute: compared to the acl attribute, the dacl attribute has an additional flags field which indicates when Automatic Inheritance is in use. The server will only indicate dacl attribute support in protocol version 4.1 and later, on file systems with richacl support. This commit also adds support for the NFSv4.1 NFS4_ACE_WRITE_RETENTION and NFS4_ACE_WRITE_RETENTION_HOLD ACL permissions. Signed-off-by: Andreas Gruenbacher Acked-by: J. Bruce Fields --- fs/nfsd/nfs4proc.c | 3 +- fs/nfsd/nfs4xdr.c | 219 ++++++++++++++++++++++++++++++---------------- fs/nfsd/nfsd.h | 6 +- include/linux/nfs4.h | 1 + include/uapi/linux/nfs4.h | 3 +- 5 files changed, 155 insertions(+), 77 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 1bcfda2..a053e78 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -1781,7 +1781,8 @@ static inline u32 nfsd4_getattr_rsize(struct svc_rqst *rqstp, u32 bmap0 = bmap[0], bmap1 = bmap[1], bmap2 = bmap[2]; u32 ret = 0; - if (bmap0 & FATTR4_WORD0_ACL) + if (bmap0 & FATTR4_WORD0_ACL || + bmap1 & FATTR4_WORD1_DACL) return svc_max_payload(rqstp); if (bmap0 & FATTR4_WORD0_FS_LOCATIONS) return svc_max_payload(rqstp); diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 682a7d8..33d028c 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -301,6 +301,68 @@ nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval) DECODE_TAIL; } +static unsigned int +nfsd4_ace_mask(int minorversion) +{ + return minorversion == 0 ? NFS40_ACE_MASK_ALL : NFS4_ACE_MASK_ALL; +} + +static __be32 +nfsd4_decode_acl_entries(struct nfsd4_compoundargs *argp, struct richacl **acl, + unsigned short flags_mask, unsigned int ace_mask, + int *plen) +{ + struct richace *ace; + u32 dummy32; + char *buf; + int len = 0; + + DECODE_HEAD; + + flags_mask &= RICHACE_VALID_FLAGS & ~RICHACE_SPECIAL_WHO; + + READ_BUF(4); len += 4; + dummy32 = be32_to_cpup(p++); + + if (dummy32 > NFSD4_ACL_MAX) + return nfserr_fbig; + + *acl = svcxdr_alloc_richacl(argp, dummy32); + if (*acl == NULL) + return nfserr_jukebox; + + richacl_for_each_entry(ace, *acl) { + READ_BUF(16); len += 16; + + dummy32 = be32_to_cpup(p++); + if (dummy32 > RICHACE_ACCESS_DENIED_ACE_TYPE) + return nfserr_inval; + ace->e_type = dummy32; + + dummy32 = be32_to_cpup(p++); + if (dummy32 & ~flags_mask) + return nfserr_inval; + ace->e_flags = dummy32; + + dummy32 = be32_to_cpup(p++); + if (dummy32 & ~ace_mask) + return nfserr_inval; + ace->e_mask = dummy32; + + dummy32 = be32_to_cpup(p++); + READ_BUF(dummy32); + len += XDR_QUADLEN(dummy32) << 2; + READMEM(buf, dummy32); + status = nfsd4_decode_ace_who(ace, argp->rqstp, + buf, dummy32); + if (status) + return status; + } + *plen += len; + + DECODE_TAIL; +} + static __be32 nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, struct iattr *iattr, struct richacl **acl, @@ -312,6 +374,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, DECODE_HEAD; iattr->ia_valid = 0; + *acl = NULL; if ((status = nfsd4_decode_bitmap(argp, bmval))) return status; @@ -325,50 +388,18 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, iattr->ia_valid |= ATTR_SIZE; } if (bmval[0] & FATTR4_WORD0_ACL) { - u32 nace; - struct richace *ace; - - READ_BUF(4); len += 4; - nace = be32_to_cpup(p++); - - if (nace > NFSD4_ACL_MAX) - return nfserr_fbig; + if (bmval[1] & FATTR4_WORD1_DACL) + return nfserr_inval; - *acl = svcxdr_alloc_richacl(argp, nace); - if (*acl == NULL) + status = nfsd4_decode_acl_entries(argp, acl, + ~NFS4_ACE_INHERITED_ACE, + nfsd4_ace_mask(argp->minorversion), + &len); + if (status) + return status; + else if (*acl == NULL) return nfserr_jukebox; - - richacl_for_each_entry(ace, *acl) { - READ_BUF(16); len += 16; - - dummy32 = be32_to_cpup(p++); - if (dummy32 > RICHACE_ACCESS_DENIED_ACE_TYPE) - return nfserr_inval; - ace->e_type = dummy32; - - dummy32 = be32_to_cpup(p++); - if (dummy32 & (~RICHACE_VALID_FLAGS | - RICHACE_INHERITED_ACE | - RICHACE_SPECIAL_WHO)) - return nfserr_inval; - ace->e_flags = dummy32; - - dummy32 = be32_to_cpup(p++); - if (dummy32 & ~NFS4_ACE_MASK_ALL) - return nfserr_inval; - ace->e_mask = dummy32; - - dummy32 = be32_to_cpup(p++); - READ_BUF(dummy32); - len += XDR_QUADLEN(dummy32) << 2; - READMEM(buf, dummy32); - status = nfsd4_decode_ace_who(ace, argp->rqstp, - buf, dummy32); - if (status) - return status; - } - } else - *acl = NULL; + } if (bmval[1] & FATTR4_WORD1_MODE) { READ_BUF(4); len += 4; @@ -436,6 +467,22 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, goto xdr_error; } } + if (bmval[1] & FATTR4_WORD1_DACL) { + READ_BUF(4); + len += 4; + dummy32 = be32_to_cpup(p++); + if (dummy32 & (~RICHACL_VALID_FLAGS | RICHACL_MASKED)) + return nfserr_inval; + status = nfsd4_decode_acl_entries(argp, acl, + ~0, + nfsd4_ace_mask(argp->minorversion), + &len); + if (status) + return status; + else if (*acl == NULL) + return nfserr_jukebox; + (*acl)->a_flags = dummy32; + } label->len = 0; #ifdef CONFIG_NFSD_V4_SECURITY_LABEL @@ -2272,6 +2319,42 @@ out_resource: return nfserr_resource; } +static __be32 nfsd4_encode_acl_entries(struct xdr_stream *xdr, + struct richacl *acl, struct svc_rqst *rqstp, + unsigned short flags_mask, unsigned int ace_mask) +{ + __be32 *p; + + flags_mask &= ~RICHACE_SPECIAL_WHO; + + p = xdr_reserve_space(xdr, 4); + if (!p) + return nfserr_resource; + + if (acl == NULL) { + *p++ = cpu_to_be32(0); + } else { + struct richace *ace; + + *p++ = cpu_to_be32(acl->a_count); + + richacl_for_each_entry(ace, acl) { + __be32 status; + + p = xdr_reserve_space(xdr, 4*3); + if (!p) + return nfserr_resource; + *p++ = cpu_to_be32(ace->e_type); + *p++ = cpu_to_be32(ace->e_flags & flags_mask); + *p++ = cpu_to_be32(ace->e_mask & ace_mask); + status = nfsd4_encode_ace_who(xdr, rqstp, ace); + if (status) + return status; + } + } + return 0; +} + /* * Note: @fhp can be NULL; in this case, we might have to compose the filehandle * ourselves. @@ -2342,15 +2425,16 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, goto out; fhp = tempfh; } - if (bmval0 & FATTR4_WORD0_ACL) { + if ((bmval0 & FATTR4_WORD0_ACL) || (bmval1 & FATTR4_WORD1_DACL)) { acl = nfsd4_get_acl(rqstp, dentry); if (IS_ERR(acl)) { err = PTR_ERR(acl); acl = NULL; } - if (err == -EOPNOTSUPP) + if (err == -EOPNOTSUPP) { bmval0 &= ~FATTR4_WORD0_ACL; - else if (err == -EINVAL) { + bmval1 &= ~FATTR4_WORD1_DACL; + } else if (err == -EINVAL) { status = nfserr_attrnotsupp; goto out; } else if (err != 0) @@ -2389,6 +2473,8 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, if (!IS_ACL(d_inode(dentry))) word0 &= ~FATTR4_WORD0_ACL; + if (!IS_RICHACL(d_inode(dentry))) + word1 &= ~FATTR4_WORD1_DACL; if (!contextsupport) word2 &= ~FATTR4_WORD2_SECURITY_LABEL; if (!word2) { @@ -2502,35 +2588,12 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, *p++ = cpu_to_be32(rdattr_err); } if (bmval0 & FATTR4_WORD0_ACL) { - struct richace *ace; - - if (acl == NULL) { - p = xdr_reserve_space(xdr, 4); - if (!p) - goto out_resource; - - *p++ = cpu_to_be32(0); - goto out_acl; - } - p = xdr_reserve_space(xdr, 4); - if (!p) - goto out_resource; - *p++ = cpu_to_be32(acl->a_count); - - richacl_for_each_entry(ace, acl) { - p = xdr_reserve_space(xdr, 4*3); - if (!p) - goto out_resource; - *p++ = cpu_to_be32(ace->e_type); - *p++ = cpu_to_be32(ace->e_flags & - ~(RICHACE_SPECIAL_WHO | RICHACE_INHERITED_ACE)); - *p++ = cpu_to_be32(ace->e_mask & NFS4_ACE_MASK_ALL); - status = nfsd4_encode_ace_who(xdr, rqstp, ace); - if (status) - goto out; - } + status = nfsd4_encode_acl_entries(xdr, acl, rqstp, + ~NFS4_ACE_INHERITED_ACE, + nfsd4_ace_mask(minorversion)); + if (status) + goto out; } -out_acl: if (bmval0 & FATTR4_WORD0_ACLSUPPORT) { p = xdr_reserve_space(xdr, 4); if (!p) @@ -2746,6 +2809,16 @@ out_acl: } p = xdr_encode_hyper(p, ino); } + if (bmval1 & FATTR4_WORD1_DACL) { + p = xdr_reserve_space(xdr, 4); + if (!p) + goto out_resource; + *p++ = cpu_to_be32(acl->a_flags); + status = nfsd4_encode_acl_entries(xdr, acl, rqstp, + ~0, nfsd4_ace_mask(minorversion)); + if (status) + goto out; + } #ifdef CONFIG_NFSD_PNFS if (bmval1 & FATTR4_WORD1_FS_LAYOUT_TYPES) { status = nfsd4_encode_layout_type(xdr, exp->ex_layout_type); diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h index cf98052..cb5c3ed 100644 --- a/fs/nfsd/nfsd.h +++ b/fs/nfsd/nfsd.h @@ -339,7 +339,8 @@ void nfsd_lockd_shutdown(void); NFSD4_SUPPORTED_ATTRS_WORD0 #define NFSD4_1_SUPPORTED_ATTRS_WORD1 \ - (NFSD4_SUPPORTED_ATTRS_WORD1 | PNFSD_SUPPORTED_ATTRS_WORD1) + (NFSD4_SUPPORTED_ATTRS_WORD1 | PNFSD_SUPPORTED_ATTRS_WORD1 | \ + FATTR4_WORD1_DACL) #define NFSD4_1_SUPPORTED_ATTRS_WORD2 \ (NFSD4_SUPPORTED_ATTRS_WORD2 | PNFSD_SUPPORTED_ATTRS_WORD2 | \ @@ -386,7 +387,8 @@ static inline u32 nfsd_suppattrs2(u32 minorversion) (FATTR4_WORD0_SIZE | FATTR4_WORD0_ACL) #define NFSD_WRITEABLE_ATTRS_WORD1 \ (FATTR4_WORD1_MODE | FATTR4_WORD1_OWNER | FATTR4_WORD1_OWNER_GROUP \ - | FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_MODIFY_SET) + | FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_MODIFY_SET \ + | FATTR4_WORD1_DACL) #ifdef CONFIG_NFSD_V4_SECURITY_LABEL #define NFSD_WRITEABLE_ATTRS_WORD2 FATTR4_WORD2_SECURITY_LABEL #else diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h index 1422fc6..682ced3 100644 --- a/include/linux/nfs4.h +++ b/include/linux/nfs4.h @@ -394,6 +394,7 @@ enum lock_type4 { #define FATTR4_WORD1_TIME_MODIFY (1UL << 21) #define FATTR4_WORD1_TIME_MODIFY_SET (1UL << 22) #define FATTR4_WORD1_MOUNTED_ON_FILEID (1UL << 23) +#define FATTR4_WORD1_DACL (1UL << 26) #define FATTR4_WORD1_FS_LAYOUT_TYPES (1UL << 30) #define FATTR4_WORD2_LAYOUT_TYPES (1UL << 0) #define FATTR4_WORD2_LAYOUT_BLKSIZE (1UL << 1) diff --git a/include/uapi/linux/nfs4.h b/include/uapi/linux/nfs4.h index 2b871e0..b850ffd 100644 --- a/include/uapi/linux/nfs4.h +++ b/include/uapi/linux/nfs4.h @@ -121,7 +121,8 @@ #define NFS4_ACE_GENERIC_READ 0x00120081 #define NFS4_ACE_GENERIC_WRITE 0x00160106 #define NFS4_ACE_GENERIC_EXECUTE 0x001200A0 -#define NFS4_ACE_MASK_ALL 0x001F01FF +#define NFS40_ACE_MASK_ALL 0x001F01FF +#define NFS4_ACE_MASK_ALL 0x001F07FF #define EXCHGID4_FLAG_SUPP_MOVED_REFER 0x00000001 #define EXCHGID4_FLAG_SUPP_MOVED_MIGR 0x00000002 -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:22:17 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 5E69429E72 for ; Tue, 3 Nov 2015 09:22:17 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 1E4148F8035 for ; Tue, 3 Nov 2015 07:22:17 -0800 (PST) X-ASG-Debug-ID: 1446564135-04bdf0330c1fcbc0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id CI1Ca0XphDdVhRZo (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:22:15 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 6851F8535A; Tue, 3 Nov 2015 15:22:15 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRa6029477; Tue, 3 Nov 2015 10:22:09 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 40/51] nfsd: Add support for the MAY_CREATE_{FILE,DIR} permissions Date: Tue, 3 Nov 2015 16:17:16 +0100 X-ASG-Orig-Subj: [PATCH v13 40/51] nfsd: Add support for the MAY_CREATE_{FILE,DIR} permissions Message-Id: <1446563847-14005-41-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446564135 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 For local file systems, the vfs performs the necessary permission checks for operations like creating files and directories. NFSd duplicates several of those checks. The vfs checks have been extended to check for additional permissions like MAY_CREATE_FILE and MY_CREATE_DIR; the nfsd checks currently lack those extensions. Ideally, all duplicate checks should be removed; for now, just fix the duplicate checks instead though. Signed-off-by: Andreas Gruenbacher Acked-by: J. Bruce Fields --- fs/nfsd/nfs4proc.c | 5 +++-- fs/nfsd/nfsfh.c | 8 ++++---- fs/nfsd/vfs.c | 28 ++++++++++++++++++++-------- fs/nfsd/vfs.h | 17 +++++++++-------- 4 files changed, 36 insertions(+), 22 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index a053e78..8d476ff 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -599,14 +599,15 @@ static __be32 nfsd4_create(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_create *create) { + int access = create->cr_type == NF4DIR ? + NFSD_MAY_CREATE_DIR : NFSD_MAY_CREATE_FILE; struct svc_fh resfh; __be32 status; dev_t rdev; fh_init(&resfh, NFS4_FHSIZE); - status = fh_verify(rqstp, &cstate->current_fh, S_IFDIR, - NFSD_MAY_CREATE); + status = fh_verify(rqstp, &cstate->current_fh, S_IFDIR, access); if (status) return status; diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index 350041a..7159316 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c @@ -319,10 +319,10 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, int access) /* * We still have to do all these permission checks, even when * fh_dentry is already set: - * - fh_verify may be called multiple times with different - * "access" arguments (e.g. nfsd_proc_create calls - * fh_verify(...,NFSD_MAY_EXEC) first, then later (in - * nfsd_create) calls fh_verify(...,NFSD_MAY_CREATE). + * - fh_verify may be called multiple times with different + * "access" arguments (e.g. nfsd_proc_create calls + * fh_verify(...,NFSD_MAY_EXEC) first, then later (in + * nfsd_create) calls fh_verify(...,NFSD_MAY_CREATE_FILE). * - in the NFSv4 case, the filehandle may have been filled * in by fh_compose, and given a dentry, but further * compound operations performed with that filehandle diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 45c0497..fb35775 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -1128,6 +1128,8 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, __be32 err; __be32 err2; int host_err; + int access = (type == S_IFDIR) ? + NFSD_MAY_CREATE_DIR : NFSD_MAY_CREATE_FILE; err = nfserr_perm; if (!flen) @@ -1136,7 +1138,7 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, if (isdotent(fname, flen)) goto out; - err = fh_verify(rqstp, fhp, S_IFDIR, NFSD_MAY_CREATE); + err = fh_verify(rqstp, fhp, S_IFDIR, access); if (err) goto out; @@ -1301,7 +1303,7 @@ do_nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, /* If file doesn't exist, check for permissions to create one */ if (d_really_is_negative(dchild)) { - err = fh_verify(rqstp, fhp, S_IFDIR, NFSD_MAY_CREATE); + err = fh_verify(rqstp, fhp, S_IFDIR, NFSD_MAY_CREATE_FILE); if (err) goto out; } @@ -1485,7 +1487,7 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp, if (isdotent(fname, flen)) goto out; - err = fh_verify(rqstp, fhp, S_IFDIR, NFSD_MAY_CREATE); + err = fh_verify(rqstp, fhp, S_IFDIR, NFSD_MAY_CREATE_FILE); if (err) goto out; @@ -1532,7 +1534,7 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp, __be32 err; int host_err; - err = fh_verify(rqstp, ffhp, S_IFDIR, NFSD_MAY_CREATE); + err = fh_verify(rqstp, ffhp, S_IFDIR, NFSD_MAY_CREATE_FILE); if (err) goto out; err = fh_verify(rqstp, tfhp, 0, NFSD_MAY_NOP); @@ -1604,11 +1606,12 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen, struct inode *fdir, *tdir; __be32 err; int host_err; + int access; err = fh_verify(rqstp, ffhp, S_IFDIR, NFSD_MAY_REMOVE); if (err) goto out; - err = fh_verify(rqstp, tfhp, S_IFDIR, NFSD_MAY_CREATE); + err = fh_verify(rqstp, tfhp, S_IFDIR, NFSD_MAY_NOP); if (err) goto out; @@ -1647,6 +1650,13 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen, if (odentry == trap) goto out_dput_old; + host_err = 0; + access = S_ISDIR(d_inode(odentry)->i_mode) ? + NFSD_MAY_CREATE_DIR : NFSD_MAY_CREATE_FILE; + err = fh_verify(rqstp, tfhp, S_IFDIR, access); + if (err) + goto out_dput_old; + ndentry = lookup_one_len(tname, tdentry, tlen); host_err = PTR_ERR(ndentry); if (IS_ERR(ndentry)) @@ -1672,7 +1682,8 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen, out_dput_old: dput(odentry); out_nfserr: - err = nfserrno(host_err); + if (host_err) + err = nfserrno(host_err); /* * We cannot rely on fh_unlock on the two filehandles, * as that would do the wrong thing if the two directories @@ -2005,8 +2016,9 @@ nfsd_permission(struct svc_rqst *rqstp, struct svc_export *exp, uid_eq(inode->i_uid, current_fsuid())) return 0; - /* This assumes NFSD_MAY_{READ,WRITE,EXEC} == MAY_{READ,WRITE,EXEC} */ - err = inode_permission(inode, acc & (MAY_READ|MAY_WRITE|MAY_EXEC)); + /* This assumes NFSD_MAY_{READ,WRITE,EXEC} == MAY_{READ,WRITE,EXEC}. */ + err = inode_permission(inode, acc & (MAY_READ|MAY_WRITE|MAY_EXEC| + MAY_CREATE_DIR|MAY_CREATE_FILE)); /* Allow read access to binaries even when mode 111 */ if (err == -EACCES && S_ISREG(inode->i_mode) && diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h index fee2451..c849ef2 100644 --- a/fs/nfsd/vfs.h +++ b/fs/nfsd/vfs.h @@ -19,18 +19,19 @@ #define NFSD_MAY_TRUNC 0x010 #define NFSD_MAY_LOCK 0x020 #define NFSD_MAY_MASK 0x03f +#define NFSD_MAY_CREATE_FILE 0x103 /* == MAY_{EXEC|WRITE|CREATE_FILE} */ +#define NFSD_MAY_CREATE_DIR 0x203 /* == MAY_{EXEC|WRITE|CREATE_DIR} */ /* extra hints to permission and open routines: */ -#define NFSD_MAY_OWNER_OVERRIDE 0x040 -#define NFSD_MAY_LOCAL_ACCESS 0x080 /* for device special files */ -#define NFSD_MAY_BYPASS_GSS_ON_ROOT 0x100 -#define NFSD_MAY_NOT_BREAK_LEASE 0x200 -#define NFSD_MAY_BYPASS_GSS 0x400 -#define NFSD_MAY_READ_IF_EXEC 0x800 +#define NFSD_MAY_OWNER_OVERRIDE 0x04000 +#define NFSD_MAY_LOCAL_ACCESS 0x08000 /* for device special files */ +#define NFSD_MAY_BYPASS_GSS_ON_ROOT 0x10000 +#define NFSD_MAY_NOT_BREAK_LEASE 0x20000 +#define NFSD_MAY_BYPASS_GSS 0x40000 +#define NFSD_MAY_READ_IF_EXEC 0x80000 -#define NFSD_MAY_64BIT_COOKIE 0x1000 /* 64 bit readdir cookies for >= NFSv3 */ +#define NFSD_MAY_64BIT_COOKIE 0x100000 /* 64 bit readdir cookies for >= NFSv3 */ -#define NFSD_MAY_CREATE (NFSD_MAY_EXEC|NFSD_MAY_WRITE) #define NFSD_MAY_REMOVE (NFSD_MAY_EXEC|NFSD_MAY_WRITE|NFSD_MAY_TRUNC) /* -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:22:25 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 3418529E77 for ; Tue, 3 Nov 2015 09:22:25 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id E720E304051 for ; Tue, 3 Nov 2015 07:22:24 -0800 (PST) X-ASG-Debug-ID: 1446564142-04bdf0330c1fcbe0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id RwKEkome4Vt7MF2n (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:22:22 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 4C40C8FAA4; Tue, 3 Nov 2015 15:22:22 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRa7029477; Tue, 3 Nov 2015 10:22:16 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 41/51] richacl: Add support for unmapped identifiers Date: Tue, 3 Nov 2015 16:17:17 +0100 X-ASG-Orig-Subj: [PATCH v13 41/51] richacl: Add support for unmapped identifiers Message-Id: <1446563847-14005-42-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446564142 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Some remote file systems like nfs may return user or group identifiers that cannot be mapped to local uids / gids. Allow to represent such unmapped identifiers in richacls. (We still cannot represent unmapped owners and owning groups, however.) In the in-memory representation, the richacl is followed by a list of NUL-terminated strings, with no padding. Entries with an unmapped identifier have the RICHACE_UNMAPPED_WHO flag set, and ace->e_id.offs specifies the offset into this list. Multiple entries can refer to the same offset. The xattr representation is similar, but ace->e_id is ignored, and the list of unmapped identifier strings contains a string for each acl entry whose RICHACE_UNMAPPED_WHO flag is set. Signed-off-by: Andreas Gruenbacher --- fs/richacl_base.c | 139 ++++++++++++++++++++++++++++++++++++++++--- fs/richacl_compat.c | 18 +++--- fs/richacl_inode.c | 4 +- fs/richacl_xattr.c | 69 +++++++++++++++++---- include/linux/richacl.h | 31 ++++++++-- include/uapi/linux/richacl.h | 2 + 6 files changed, 227 insertions(+), 36 deletions(-) diff --git a/fs/richacl_base.c b/fs/richacl_base.c index 2a9c448..641b1bb 100644 --- a/fs/richacl_base.c +++ b/fs/richacl_base.c @@ -23,22 +23,25 @@ MODULE_LICENSE("GPL"); /** - * richacl_alloc - allocate a richacl + * __richacl_alloc - allocate a richacl * @count: number of entries + * @unmapped_size: size to reserve for unmapped identifiers */ struct richacl * -richacl_alloc(int count, gfp_t gfp) +__richacl_alloc(unsigned int count, size_t unmapped_size, gfp_t gfp) { - size_t size = sizeof(struct richacl) + count * sizeof(struct richace); + size_t size = sizeof(struct richacl) + count * sizeof(struct richace) + + unmapped_size; struct richacl *acl = kzalloc(size, gfp); if (acl) { atomic_set(&acl->a_base.ba_refcount, 1); acl->a_count = count; + acl->a_unmapped_size = unmapped_size; } return acl; } -EXPORT_SYMBOL_GPL(richacl_alloc); +EXPORT_SYMBOL_GPL(__richacl_alloc); /** * richacl_clone - create a copy of a richacl @@ -47,7 +50,8 @@ struct richacl * richacl_clone(const struct richacl *acl, gfp_t gfp) { int count = acl->a_count; - size_t size = sizeof(struct richacl) + count * sizeof(struct richace); + size_t size = sizeof(struct richacl) + count * sizeof(struct richace) + + acl->a_unmapped_size; struct richacl *dup = kmalloc(size, gfp); if (dup) { @@ -59,6 +63,9 @@ richacl_clone(const struct richacl *acl, gfp_t gfp) /** * richace_copy - copy an acl entry + * + * If @from has an unmapped who value (from->e_flags & RICHACE_UNMAPPED_WHO), + * it can only be copied within the same acl! */ void richace_copy(struct richace *to, const struct richace *from) @@ -66,6 +73,82 @@ richace_copy(struct richace *to, const struct richace *from) memcpy(to, from, sizeof(struct richace)); } +/** + * richacl_add_unmapped_identifier + * @pacl: Pointer to an acl + * @pace: acl entry within @acl + * @who: unmapped identifier + * @len: length of @who + * @gfp: memory allocation flags + * + * Add an unmapped identifier to an acl, possibly reallocating the acl. + */ +int richacl_add_unmapped_identifier(struct richacl **pacl, + struct richace **pace, + const char *who, + unsigned int len, gfp_t gfp) +{ + struct richacl *acl = *pacl; + size_t size = sizeof(struct richacl) + + acl->a_count * sizeof(struct richace) + + acl->a_unmapped_size + len + 1; + unsigned int index = *pace - acl->a_entries; + + acl = krealloc(*pacl, size, gfp); + if (acl) { + char *unmapped = (char *)(acl->a_entries + acl->a_count); + struct richace *ace = acl->a_entries + index; + + ace->e_flags |= RICHACE_UNMAPPED_WHO; + ace->e_flags &= ~RICHACE_SPECIAL_WHO; + ace->e_id.offs = acl->a_unmapped_size; + memcpy(unmapped + ace->e_id.offs, who, len); + unmapped[ace->e_id.offs + len] = 0; + acl->a_unmapped_size += len + 1; + *pace = ace; + *pacl = acl; + return 0; + } + return -1; +} +EXPORT_SYMBOL_GPL(richacl_add_unmapped_identifier); + +/** + * richace_unmapped_identifier - get unmapped identifier + * @acl: acl containing @ace + * @ace: acl entry + * + * Get the unmapped identifier of @ace as a NUL-terminated string, or NULL if + * @ace doesn't have an unmapped identifier. + */ +const char *richace_unmapped_identifier(const struct richace *ace, + const struct richacl *acl) +{ + const char *unmapped = (char *)(acl->a_entries + acl->a_count); + + if (!(ace->e_flags & RICHACE_UNMAPPED_WHO)) + return NULL; + return unmapped + ace->e_id.offs; +} +EXPORT_SYMBOL(richace_unmapped_identifier); + +/** + * richacl_has_unmapped_identifiers + * + * Check if an acl has unmapped identifiers. + */ +bool richacl_has_unmapped_identifiers(struct richacl *acl) +{ + struct richace *ace; + + richacl_for_each_entry(ace, acl) { + if (ace->e_flags & RICHACE_UNMAPPED_WHO) + return true; + } + return false; +} +EXPORT_SYMBOL_GPL(richacl_has_unmapped_identifiers); + /* * richacl_mask_to_mode - compute the file permission bits from mask * @mask: %RICHACE_* permission mask @@ -214,7 +297,7 @@ static unsigned int richacl_allowed_to_who(struct richacl *acl, richacl_for_each_entry_reverse(ace, acl) { if (richace_is_inherit_only(ace)) continue; - if (richace_is_same_identifier(ace, who) || + if (richace_is_same_identifier(acl, ace, who) || richace_is_everyone(ace)) { if (richace_is_allow(ace)) allowed |= ace->e_mask; @@ -505,45 +588,72 @@ richacl_inherit(const struct richacl *dir_acl, int isdir) const struct richace *dir_ace; struct richacl *acl = NULL; struct richace *ace; - int count = 0; + unsigned int count = 0, unmapped_size = 0, offset = 0; + const char *dir_unmapped; + char *unmapped; if (isdir) { richacl_for_each_entry(dir_ace, dir_acl) { if (!richace_is_inheritable(dir_ace)) continue; + count++; + dir_unmapped = + richace_unmapped_identifier(dir_ace, dir_acl); + if (dir_unmapped) + unmapped_size += strlen(dir_unmapped) + 1; } if (!count) return NULL; - acl = richacl_alloc(count, GFP_KERNEL); + acl = __richacl_alloc(count, unmapped_size, GFP_KERNEL); if (!acl) return ERR_PTR(-ENOMEM); ace = acl->a_entries; + unmapped = (char *)(acl->a_entries + acl->a_count); richacl_for_each_entry(dir_ace, dir_acl) { if (!richace_is_inheritable(dir_ace)) continue; + richace_copy(ace, dir_ace); if (dir_ace->e_flags & RICHACE_NO_PROPAGATE_INHERIT_ACE) ace->e_flags &= ~RICHACE_INHERITANCE_FLAGS; else if (!(dir_ace->e_flags & RICHACE_DIRECTORY_INHERIT_ACE)) ace->e_flags |= RICHACE_INHERIT_ONLY_ACE; + + dir_unmapped = + richace_unmapped_identifier(dir_ace, dir_acl); + if (dir_unmapped) { + size_t sz = strlen(dir_unmapped) + 1; + + ace->e_id.offs = offset; + memcpy(unmapped, dir_unmapped, sz); + unmapped += sz; + offset += sz; + } ace++; } } else { richacl_for_each_entry(dir_ace, dir_acl) { if (!(dir_ace->e_flags & RICHACE_FILE_INHERIT_ACE)) continue; + count++; + dir_unmapped = + richace_unmapped_identifier(dir_ace, dir_acl); + if (dir_unmapped) + unmapped_size += strlen(dir_unmapped) + 1; } if (!count) return NULL; - acl = richacl_alloc(count, GFP_KERNEL); + acl = __richacl_alloc(count, unmapped_size, GFP_KERNEL); if (!acl) return ERR_PTR(-ENOMEM); ace = acl->a_entries; + unmapped = (char *)(acl->a_entries + acl->a_count); richacl_for_each_entry(dir_ace, dir_acl) { if (!(dir_ace->e_flags & RICHACE_FILE_INHERIT_ACE)) continue; + richace_copy(ace, dir_ace); ace->e_flags &= ~RICHACE_INHERITANCE_FLAGS; /* @@ -551,6 +661,17 @@ richacl_inherit(const struct richacl *dir_acl, int isdir) * non-directories, so clear it. */ ace->e_mask &= ~RICHACE_DELETE_CHILD; + + dir_unmapped = + richace_unmapped_identifier(dir_ace, dir_acl); + if (dir_unmapped) { + size_t sz = strlen(dir_unmapped) + 1; + + ace->e_id.offs = offset; + memcpy(unmapped, dir_unmapped, sz); + unmapped += sz; + offset += sz; + } ace++; } } diff --git a/fs/richacl_compat.c b/fs/richacl_compat.c index 3a11773..24b5397 100644 --- a/fs/richacl_compat.c +++ b/fs/richacl_compat.c @@ -71,11 +71,13 @@ richacl_insert_entry(struct richacl_alloc *alloc, struct richace **ace) { struct richacl *acl = alloc->acl; unsigned int index = *ace - acl->a_entries; - size_t tail_size = (acl->a_count - index) * sizeof(struct richace); + size_t tail_size = (acl->a_count - index) * sizeof(struct richace) + + acl->a_unmapped_size; if (alloc->count == acl->a_count) { size_t new_size = sizeof(struct richacl) + - (acl->a_count + 1) * sizeof(struct richace); + (acl->a_count + 1) * sizeof(struct richace) + + acl->a_unmapped_size; acl = krealloc(acl, new_size, GFP_KERNEL); if (!acl) @@ -103,10 +105,6 @@ struct richace *richacl_append_entry(struct richacl_alloc *alloc) struct richacl *acl = alloc->acl; struct richace *ace = acl->a_entries + acl->a_count; - if (alloc->count > alloc->acl->a_count) { - acl->a_count++; - return ace; - } return richacl_insert_entry(alloc, &ace) ? NULL : ace; } EXPORT_SYMBOL_GPL(richacl_append_entry); @@ -261,12 +259,12 @@ __richacl_propagate_everyone(struct richacl_alloc *alloc, struct richace *who, if (richace_is_inherit_only(ace)) continue; if (richace_is_allow(ace)) { - if (richace_is_same_identifier(ace, who)) { + if (richace_is_same_identifier(acl, ace, who)) { allow &= ~ace->e_mask; allow_last = ace; } } else if (richace_is_deny(ace)) { - if (richace_is_same_identifier(ace, who)) + if (richace_is_same_identifier(acl, ace, who)) allow &= ~ace->e_mask; else if (allow & ace->e_mask) allow_last = NULL; @@ -613,7 +611,7 @@ __richacl_isolate_who(struct richacl_alloc *alloc, struct richace *who, richacl_for_each_entry(ace, acl) { if (richace_is_inherit_only(ace)) continue; - if (richace_is_same_identifier(ace, who)) + if (richace_is_same_identifier(acl, ace, who)) deny &= ~ace->e_mask; } if (!deny) @@ -629,7 +627,7 @@ __richacl_isolate_who(struct richacl_alloc *alloc, struct richace *who, if (richace_is_inherit_only(ace)) continue; if (richace_is_deny(ace)) { - if (richace_is_same_identifier(ace, who)) + if (richace_is_same_identifier(acl, ace, who)) return richace_change_mask(alloc, &ace, ace->e_mask | deny); } else if (richace_is_allow(ace) && diff --git a/fs/richacl_inode.c b/fs/richacl_inode.c index 24276da..026abae 100644 --- a/fs/richacl_inode.c +++ b/fs/richacl_inode.c @@ -161,8 +161,10 @@ richacl_permission(struct inode *inode, const struct richacl *acl, } else if (richace_is_unix_group(ace)) { if (!in_group_p(ace->e_id.gid)) continue; - } else + } else if (richace_is_everyone(ace)) goto entry_matches_everyone; + else + continue; /* * Apply the group file mask to entries other than owner@ and diff --git a/fs/richacl_xattr.c b/fs/richacl_xattr.c index 767c1f7..09b1012 100644 --- a/fs/richacl_xattr.c +++ b/fs/richacl_xattr.c @@ -35,7 +35,8 @@ richacl_from_xattr(struct user_namespace *user_ns, const struct richace_xattr *xattr_ace = (void *)(xattr_acl + 1); struct richacl *acl; struct richace *ace; - int count; + unsigned int count, offset; + char *unmapped; if (size < sizeof(*xattr_acl) || xattr_acl->a_version != RICHACL_XATTR_VERSION || @@ -45,10 +46,11 @@ richacl_from_xattr(struct user_namespace *user_ns, count = le16_to_cpu(xattr_acl->a_count); if (count > RICHACL_XATTR_MAX_COUNT) return ERR_PTR(-EINVAL); - if (size != count * sizeof(*xattr_ace)) + if (size < count * sizeof(*xattr_ace)) return ERR_PTR(-EINVAL); + size -= count * sizeof(*xattr_ace); - acl = richacl_alloc(count, GFP_NOFS); + acl = __richacl_alloc(count, size, GFP_NOFS); if (!acl) return ERR_PTR(-ENOMEM); @@ -63,6 +65,16 @@ richacl_from_xattr(struct user_namespace *user_ns, if (acl->a_other_mask & ~RICHACE_VALID_MASK) goto fail_einval; + unmapped = (char *)(acl->a_entries + count); + if (size) { + char *xattr_unmapped = (char *)(xattr_ace + count); + + if (xattr_unmapped[size - 1] != 0) + goto fail_einval; + memcpy(unmapped, xattr_unmapped, size); + } + offset = 0; + richacl_for_each_entry(ace, acl) { ace->e_type = le16_to_cpu(xattr_ace->e_type); ace->e_flags = le16_to_cpu(xattr_ace->e_flags); @@ -74,6 +86,15 @@ richacl_from_xattr(struct user_namespace *user_ns, ace->e_id.special = le32_to_cpu(xattr_ace->e_id); if (ace->e_id.special > RICHACE_EVERYONE_SPECIAL_ID) goto fail_einval; + } else if (ace->e_flags & RICHACE_UNMAPPED_WHO) { + size_t sz; + + if (offset == size) + goto fail_einval; + ace->e_id.offs = offset; + sz = strlen(unmapped) + 1; + unmapped += sz; + offset += sz; } else if (ace->e_flags & RICHACE_IDENTIFIER_GROUP) { u32 id = le32_to_cpu(xattr_ace->e_id); @@ -90,10 +111,12 @@ richacl_from_xattr(struct user_namespace *user_ns, if (ace->e_type > RICHACE_ACCESS_DENIED_ACE_TYPE || (ace->e_mask & ~RICHACE_VALID_MASK)) goto fail_einval; - xattr_ace++; } + if (offset != size) + goto fail_einval; + return acl; fail_einval: @@ -109,8 +132,15 @@ size_t richacl_xattr_size(const struct richacl *acl) { size_t size = sizeof(struct richacl_xattr); + const struct richace *ace; size += sizeof(struct richace_xattr) * acl->a_count; + richacl_for_each_entry(ace, acl) { + const char *unmapped = richace_unmapped_identifier(ace, acl); + + if (unmapped) + size += strlen(unmapped) + 1; + } return size; } EXPORT_SYMBOL_GPL(richacl_xattr_size); @@ -129,6 +159,7 @@ richacl_to_xattr(struct user_namespace *user_ns, struct richace_xattr *xattr_ace; const struct richace *ace; size_t real_size; + char *xattr_unmapped; real_size = richacl_xattr_size(acl); if (!buffer) @@ -145,18 +176,33 @@ richacl_to_xattr(struct user_namespace *user_ns, xattr_acl->a_other_mask = cpu_to_le32(acl->a_other_mask); xattr_ace = (void *)(xattr_acl + 1); + xattr_unmapped = (char *)(xattr_ace + acl->a_count); richacl_for_each_entry(ace, acl) { + const char *who; + xattr_ace->e_type = cpu_to_le16(ace->e_type); xattr_ace->e_flags = cpu_to_le16(ace->e_flags); xattr_ace->e_mask = cpu_to_le32(ace->e_mask); if (ace->e_flags & RICHACE_SPECIAL_WHO) xattr_ace->e_id = cpu_to_le32(ace->e_id.special); - else if (ace->e_flags & RICHACE_IDENTIFIER_GROUP) - xattr_ace->e_id = - cpu_to_le32(from_kgid(user_ns, ace->e_id.gid)); - else - xattr_ace->e_id = - cpu_to_le32(from_kuid(user_ns, ace->e_id.uid)); + else { + who = richace_unmapped_identifier(ace, acl); + if (who) { + size_t sz = strlen(who) + 1; + + xattr_ace->e_id = 0; + memcpy(xattr_unmapped, who, sz); + xattr_unmapped += sz; + } else if (ace->e_flags & RICHACE_IDENTIFIER_GROUP) { + u32 id = from_kgid(user_ns, ace->e_id.gid); + + xattr_ace->e_id = cpu_to_le32(id); + } else { + u32 id = from_kuid(user_ns, ace->e_id.uid); + + xattr_ace->e_id = cpu_to_le32(id); + } + } xattr_ace++; } return real_size; @@ -262,7 +308,8 @@ static void richacl_fix_xattr_userns( return; count = size / sizeof(*xattr_ace); for (; count; count--, xattr_ace++) { - if (xattr_ace->e_flags & cpu_to_le16(RICHACE_SPECIAL_WHO)) + if (xattr_ace->e_flags & cpu_to_le16(RICHACE_SPECIAL_WHO | + RICHACE_UNMAPPED_WHO)) continue; if (xattr_ace->e_flags & cpu_to_le16(RICHACE_IDENTIFIER_GROUP)) { diff --git a/include/linux/richacl.h b/include/linux/richacl.h index 10bfd0f..52e5c3d 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -27,6 +27,7 @@ struct richace { kuid_t uid; kgid_t gid; unsigned int special; + unsigned short offs; /* unmapped offset */ } e_id; }; @@ -37,6 +38,7 @@ struct richacl { unsigned int a_other_mask; unsigned short a_count; unsigned short a_flags; + unsigned short a_unmapped_size; struct richace a_entries[0]; }; @@ -182,14 +184,28 @@ richace_is_deny(const struct richace *ace) * richace_is_same_identifier - are both identifiers the same? */ static inline bool -richace_is_same_identifier(const struct richace *a, const struct richace *b) +richace_is_same_identifier(const struct richacl *acl, + const struct richace *ace1, + const struct richace *ace2) { - return !((a->e_flags ^ b->e_flags) & - (RICHACE_SPECIAL_WHO | RICHACE_IDENTIFIER_GROUP)) && - !memcmp(&a->e_id, &b->e_id, sizeof(a->e_id)); + const char *unmapped = (char *)(acl->a_entries + acl->a_count); + + return !((ace1->e_flags ^ ace2->e_flags) & + (RICHACE_SPECIAL_WHO | + RICHACE_IDENTIFIER_GROUP | + RICHACE_UNMAPPED_WHO)) && + ((ace1->e_flags & RICHACE_UNMAPPED_WHO) ? + !strcmp(unmapped + ace1->e_id.offs, + unmapped + ace2->e_id.offs) : + !memcmp(&ace1->e_id, &ace2->e_id, sizeof(ace1->e_id))); +} + +extern struct richacl *__richacl_alloc(unsigned int, size_t, gfp_t); +static inline struct richacl *richacl_alloc(unsigned int count, gfp_t gfp) +{ + return __richacl_alloc(count, 0, gfp); } -extern struct richacl *richacl_alloc(int, gfp_t); extern struct richacl *richacl_clone(const struct richacl *, gfp_t); extern void richace_copy(struct richace *, const struct richace *); extern int richacl_masks_to_mode(const struct richacl *); @@ -199,6 +215,11 @@ extern void richacl_compute_max_masks(struct richacl *); extern struct richacl *__richacl_chmod(struct richacl *, umode_t); extern int richacl_equiv_mode(const struct richacl *, umode_t *); extern struct richacl *richacl_inherit(const struct richacl *, int); +extern int richacl_add_unmapped_identifier(struct richacl **, struct richace **, + const char *, unsigned int, gfp_t); +extern const char *richace_unmapped_identifier(const struct richace *, + const struct richacl *); +extern bool richacl_has_unmapped_identifiers(struct richacl *); /* richacl_inode.c */ extern int richacl_permission(struct inode *, const struct richacl *, int); diff --git a/include/uapi/linux/richacl.h b/include/uapi/linux/richacl.h index 8849a53..132fee1 100644 --- a/include/uapi/linux/richacl.h +++ b/include/uapi/linux/richacl.h @@ -35,6 +35,7 @@ #define RICHACE_INHERIT_ONLY_ACE 0x0008 #define RICHACE_IDENTIFIER_GROUP 0x0040 #define RICHACE_INHERITED_ACE 0x0080 +#define RICHACE_UNMAPPED_WHO 0x2000 #define RICHACE_SPECIAL_WHO 0x4000 /* e_mask bitflags */ @@ -77,6 +78,7 @@ RICHACE_INHERIT_ONLY_ACE | \ RICHACE_IDENTIFIER_GROUP | \ RICHACE_INHERITED_ACE | \ + RICHACE_UNMAPPED_WHO | \ RICHACE_SPECIAL_WHO ) #define RICHACE_INHERITANCE_FLAGS ( \ -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:22:31 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 8ECB929E66 for ; Tue, 3 Nov 2015 09:22:31 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 029CAAC001 for ; Tue, 3 Nov 2015 07:22:30 -0800 (PST) X-ASG-Debug-ID: 1446564149-04cb6c7b841ddd10001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id q2nZ65i6F3d7WJ95 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:22:29 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 3D1EDA37F8; Tue, 3 Nov 2015 15:22:29 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRa8029477; Tue, 3 Nov 2015 10:22:22 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 42/51] nfsd: Add support for unmapped richace identifiers Date: Tue, 3 Nov 2015 16:17:18 +0100 X-ASG-Orig-Subj: [PATCH v13 42/51] nfsd: Add support for unmapped richace identifiers Message-Id: <1446563847-14005-43-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446564149 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Add support for encoding unmapped identifiers in richacl entries: local filesystems are not usually supposed to store unmapped identifiers, but allowing that for debugging purposes can be useful; for that, nfsd must also be able to encode them. Signed-off-by: Andreas Gruenbacher --- fs/nfsd/acl.h | 2 +- fs/nfsd/nfs4acl.c | 17 +++++++++++------ fs/nfsd/nfs4xdr.c | 4 ++-- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/fs/nfsd/acl.h b/fs/nfsd/acl.h index d73c664..4935144 100644 --- a/fs/nfsd/acl.h +++ b/fs/nfsd/acl.h @@ -51,7 +51,7 @@ struct svc_rqst; __be32 nfsd4_decode_ace_who(struct richace *ace, struct svc_rqst *rqstp, char *who, u32 len); __be32 nfsd4_encode_ace_who(struct xdr_stream *xdr, struct svc_rqst *rqstp, - struct richace *ace); + struct richace *ace, struct richacl *acl); struct richacl *nfsd4_get_acl(struct svc_rqst *rqstp, struct dentry *dentry); __be32 nfsd4_set_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c index f017a76..3cc83fd 100644 --- a/fs/nfsd/nfs4acl.c +++ b/fs/nfsd/nfs4acl.c @@ -885,17 +885,22 @@ __be32 nfsd4_decode_ace_who(struct richace *ace, struct svc_rqst *rqstp, } __be32 nfsd4_encode_ace_who(struct xdr_stream *xdr, struct svc_rqst *rqstp, - struct richace *ace) + struct richace *ace, struct richacl *acl) { - if (ace->e_flags & RICHACE_SPECIAL_WHO) { - unsigned int special_id = ace->e_id.special; + if (ace->e_flags & (RICHACE_SPECIAL_WHO | RICHACE_UNMAPPED_WHO)) { const char *who; unsigned int len; __be32 *p; - if (!nfs4acl_special_id_to_who(special_id, &who, &len)) { - WARN_ON_ONCE(1); - return nfserr_serverfault; + if (ace->e_flags & RICHACE_SPECIAL_WHO) { + if (!nfs4acl_special_id_to_who(ace->e_id.special, + &who, &len)) { + WARN_ON_ONCE(1); + return nfserr_serverfault; + } + } else { + who = richace_unmapped_identifier(ace, acl); + len = strlen(who); } p = xdr_reserve_space(xdr, len + 4); if (!p) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 33d028c..8728d0e 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -2325,7 +2325,7 @@ static __be32 nfsd4_encode_acl_entries(struct xdr_stream *xdr, { __be32 *p; - flags_mask &= ~RICHACE_SPECIAL_WHO; + flags_mask &= ~(RICHACE_SPECIAL_WHO | RICHACE_UNMAPPED_WHO); p = xdr_reserve_space(xdr, 4); if (!p) @@ -2347,7 +2347,7 @@ static __be32 nfsd4_encode_acl_entries(struct xdr_stream *xdr, *p++ = cpu_to_be32(ace->e_type); *p++ = cpu_to_be32(ace->e_flags & flags_mask); *p++ = cpu_to_be32(ace->e_mask & ace_mask); - status = nfsd4_encode_ace_who(xdr, rqstp, ace); + status = nfsd4_encode_ace_who(xdr, rqstp, ace, acl); if (status) return status; } -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:22:38 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 41F6629E66 for ; Tue, 3 Nov 2015 09:22:38 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 1FBBC304043 for ; Tue, 3 Nov 2015 07:22:38 -0800 (PST) X-ASG-Debug-ID: 1446564156-04cb6c7b861ddd60001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id GnvTO4YchoDLLSvs (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:22:37 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 92BB8227; Tue, 3 Nov 2015 15:22:36 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRa9029477; Tue, 3 Nov 2015 10:22:29 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 43/51] ext4: Don't allow unmapped identifiers in richacls Date: Tue, 3 Nov 2015 16:17:19 +0100 X-ASG-Orig-Subj: [PATCH v13 43/51] ext4: Don't allow unmapped identifiers in richacls Message-Id: <1446563847-14005-44-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446564157 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Don't allow acls which contain unmapped identifiers: they are meaningful for remote file systems only. Signed-off-by: Andreas Gruenbacher --- fs/ext4/richacl.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/ext4/richacl.c b/fs/ext4/richacl.c index 906d048..2115385 100644 --- a/fs/ext4/richacl.c +++ b/fs/ext4/richacl.c @@ -74,6 +74,10 @@ __ext4_set_richacl(handle_t *handle, struct inode *inode, struct richacl *acl) int retval, size; void *value; + /* Don't allow acls with unmapped identifiers. */ + if (richacl_has_unmapped_identifiers(acl)) + return -EINVAL; + if (richacl_equiv_mode(acl, &mode) == 0) { inode->i_ctime = ext4_current_time(inode); inode->i_mode = mode; -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:22:45 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 0407729E66 for ; Tue, 3 Nov 2015 09:22:45 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id C99138F8033 for ; Tue, 3 Nov 2015 07:22:44 -0800 (PST) X-ASG-Debug-ID: 1446564163-04bdf0330a1fcc10001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id h5dUI3IrUguVx19H (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:22:43 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 8363242E5A7; Tue, 3 Nov 2015 15:22:43 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRaA029477; Tue, 3 Nov 2015 10:22:37 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 44/51] xfs: Don't allow unmapped identifiers in richacls Date: Tue, 3 Nov 2015 16:17:20 +0100 X-ASG-Orig-Subj: [PATCH v13 44/51] xfs: Don't allow unmapped identifiers in richacls Message-Id: <1446563847-14005-45-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446564163 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Don't allow acls which contain unmapped identifiers: they are meaningful for remote file systems only. Signed-off-by: Andreas Gruenbacher --- fs/xfs/xfs_richacl.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/xfs/xfs_richacl.c b/fs/xfs/xfs_richacl.c index f8f5a62..4a2e21a 100644 --- a/fs/xfs/xfs_richacl.c +++ b/fs/xfs/xfs_richacl.c @@ -78,6 +78,10 @@ __xfs_set_richacl(struct inode *inode, struct richacl *acl, int xflags) if (!acl) return xfs_remove_richacl(inode); + /* Don't allow acls with unmapped identifiers. */ + if (richacl_has_unmapped_identifiers(acl)) + return -EINVAL; + if (richacl_equiv_mode(acl, &mode) == 0) { xfs_set_mode(inode, mode); return xfs_remove_richacl(inode); -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:22:52 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 DD9B829E66 for ; Tue, 3 Nov 2015 09:22:52 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 6CDDAAC002 for ; Tue, 3 Nov 2015 07:22:52 -0800 (PST) X-ASG-Debug-ID: 1446564170-04cb6c7b861dddc0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id WoJbxjPVRO6LGb1i (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:22:51 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id B21538E3E3; Tue, 3 Nov 2015 15:22:50 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRaB029477; Tue, 3 Nov 2015 10:22:44 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 45/51] sunrpc: Allow to demand-allocate pages to encode into Date: Tue, 3 Nov 2015 16:17:21 +0100 X-ASG-Orig-Subj: [PATCH v13 45/51] sunrpc: Allow to demand-allocate pages to encode into Message-Id: <1446563847-14005-46-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446564171 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 When encoding large, variable-length objects such as acls into xdr_bufs, it is easier to allocate buffer pages on demand rather than precomputing the required buffer size. Signed-off-by: Andreas Gruenbacher --- net/sunrpc/xdr.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index 4439ac4..63c1c36 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c @@ -537,6 +537,15 @@ static __be32 *xdr_get_next_encode_buffer(struct xdr_stream *xdr, */ xdr->scratch.iov_base = xdr->p; xdr->scratch.iov_len = frag1bytes; + + if (!*xdr->page_ptr) { + struct page *page = alloc_page(GFP_NOFS); + + if (!page) + return NULL; + *xdr->page_ptr = page; + } + p = page_address(*xdr->page_ptr); /* * Note this is where the next encode will start after we've -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:22:59 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 2905229E66 for ; Tue, 3 Nov 2015 09:22:59 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 068B78F8033 for ; Tue, 3 Nov 2015 07:22:58 -0800 (PST) X-ASG-Debug-ID: 1446564177-04cbb0660c1f7e20001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 8AjAz9Owx2VZ7Lxi (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:22:58 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 5369E8FAA0; Tue, 3 Nov 2015 15:22:57 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRaC029477; Tue, 3 Nov 2015 10:22:51 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 46/51] sunrpc: Add xdr_init_encode_pages Date: Tue, 3 Nov 2015 16:17:22 +0100 X-ASG-Orig-Subj: [PATCH v13 46/51] sunrpc: Add xdr_init_encode_pages Message-Id: <1446563847-14005-47-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446564177 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Initialize xdr_stream and xdr_buf from a pages array, for encoding into the pages. Signed-off-by: Andreas Gruenbacher --- include/linux/sunrpc/xdr.h | 2 ++ net/sunrpc/xdr.c | 25 +++++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h index 70c6b92..2c99cff 100644 --- a/include/linux/sunrpc/xdr.h +++ b/include/linux/sunrpc/xdr.h @@ -214,6 +214,8 @@ typedef void (*kxdreproc_t)(void *rqstp, struct xdr_stream *xdr, void *obj); typedef int (*kxdrdproc_t)(void *rqstp, struct xdr_stream *xdr, void *obj); extern void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p); +extern void xdr_init_encode_pages(struct xdr_stream *xdr, struct xdr_buf *buf, + struct page **pages, unsigned int len); extern __be32 *xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes); extern void xdr_commit_encode(struct xdr_stream *xdr); extern void xdr_truncate_encode(struct xdr_stream *xdr, size_t len); diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index 63c1c36..f97b96b 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c @@ -483,6 +483,31 @@ void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p) EXPORT_SYMBOL_GPL(xdr_init_encode); /** + * xdr_init_encode_pages - Initialize struct xdr_stream for encoding into pages + * @xdr: pointer to xdr_stream struct + * @buf: pointer to XDR buffer in which to encode data + * @pages: pages array in which to encode + * @len: maximum length of @buf + * + * Initialize @xdr and @buf for encoding into the @pages array. If a + * page in @pages is NULL, it will be allocated on demand. + */ +void xdr_init_encode_pages(struct xdr_stream *xdr, struct xdr_buf *buf, + struct page **pages, unsigned int len) +{ + memset(buf, 0, sizeof(*buf)); + buf->pages = pages; + buf->page_len = len; + buf->buflen = len; + + memset(xdr, 0, sizeof(*xdr)); + xdr->buf = buf; + xdr->iov = buf->head; + xdr->page_ptr = pages - 1; +} +EXPORT_SYMBOL_GPL(xdr_init_encode_pages); + +/** * xdr_commit_encode - Ensure all data is written to buffer * @xdr: pointer to xdr_stream * -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:23:06 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 D633229E66 for ; Tue, 3 Nov 2015 09:23:05 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 6DADCAC001 for ; Tue, 3 Nov 2015 07:23:05 -0800 (PST) X-ASG-Debug-ID: 1446564184-04bdf033091fcc40001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id U8xsRZXVrccK4nsR (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:23:04 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 3DCD2C0D61B8; Tue, 3 Nov 2015 15:23:04 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRaD029477; Tue, 3 Nov 2015 10:22:57 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 47/51] nfs: Fix GETATTR bitmap verification Date: Tue, 3 Nov 2015 16:17:23 +0100 X-ASG-Orig-Subj: [PATCH v13 47/51] nfs: Fix GETATTR bitmap verification Message-Id: <1446563847-14005-48-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446564184 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 When decoding GETATTR replies, the client checks the attribute bitmap for which attributes the server has sent. It misses bits at the word boundaries, though; fix that. Signed-off-by: Andreas Gruenbacher --- fs/nfs/nfs4xdr.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 788adf3..6f6d921 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -4375,6 +4375,11 @@ static int decode_statfs(struct xdr_stream *xdr, struct nfs_fsstat *fsstat) goto xdr_error; if ((status = decode_attr_files_total(xdr, bitmap, &fsstat->tfiles)) != 0) goto xdr_error; + + status = -EIO; + if (unlikely(bitmap[0])) + goto xdr_error; + if ((status = decode_attr_space_avail(xdr, bitmap, &fsstat->abytes)) != 0) goto xdr_error; if ((status = decode_attr_space_free(xdr, bitmap, &fsstat->fbytes)) != 0) @@ -4574,6 +4579,10 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap, goto xdr_error; fattr->valid |= status; + status = -EIO; + if (unlikely(bitmap[0])) + goto xdr_error; + status = decode_attr_mode(xdr, bitmap, &fmode); if (status < 0) goto xdr_error; @@ -4627,6 +4636,10 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap, goto xdr_error; fattr->valid |= status; + status = -EIO; + if (unlikely(bitmap[1])) + goto xdr_error; + status = decode_attr_mdsthreshold(xdr, bitmap, fattr->mdsthreshold); if (status < 0) goto xdr_error; @@ -4789,12 +4802,22 @@ static int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo) if ((status = decode_attr_maxwrite(xdr, bitmap, &fsinfo->wtmax)) != 0) goto xdr_error; fsinfo->wtpref = fsinfo->wtmax; + + status = -EIO; + if (unlikely(bitmap[0])) + goto xdr_error; + status = decode_attr_time_delta(xdr, bitmap, &fsinfo->time_delta); if (status != 0) goto xdr_error; status = decode_attr_pnfstype(xdr, bitmap, &fsinfo->layouttype); if (status != 0) goto xdr_error; + + status = -EIO; + if (unlikely(bitmap[1])) + goto xdr_error; + status = decode_attr_layout_blksize(xdr, bitmap, &fsinfo->blksize); if (status) goto xdr_error; -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:23:12 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 AEE8B29E66 for ; Tue, 3 Nov 2015 09:23:12 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 749B830404E for ; Tue, 3 Nov 2015 07:23:12 -0800 (PST) X-ASG-Debug-ID: 1446564191-04bdf0330b1fcc60001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id Y8s91nOa7lgZ8b4c (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:23:11 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 30341C0D61B5; Tue, 3 Nov 2015 15:23:11 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRaE029477; Tue, 3 Nov 2015 10:23:04 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 48/51] nfs: Remove unused xdr page offsets in getacl/setacl arguments Date: Tue, 3 Nov 2015 16:17:24 +0100 X-ASG-Orig-Subj: [PATCH v13 48/51] nfs: Remove unused xdr page offsets in getacl/setacl arguments Message-Id: <1446563847-14005-49-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446564191 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 The arguments passed around for getacl and setacl xdr encoding, struct nfs_setaclargs and struct nfs_getaclargs, both contain an array of pages, an offset into the first page, and the length of the page data. The offset is unused as it is always zero; remove it. Signed-off-by: Andreas Gruenbacher --- fs/nfs/nfs4proc.c | 5 ++--- fs/nfs/nfs4xdr.c | 4 ++-- include/linux/nfs_xdr.h | 2 -- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 5133bb1..eec5c4c 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -4530,7 +4530,7 @@ static inline int nfs4_server_supports_acls(struct nfs_server *server) #define NFS4ACL_MAXPAGES DIV_ROUND_UP(XATTR_SIZE_MAX, PAGE_SIZE) static int buf_to_pages_noslab(const void *buf, size_t buflen, - struct page **pages, unsigned int *pgbase) + struct page **pages) { struct page *newpage, **spages; int rc = 0; @@ -4674,7 +4674,6 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu goto out_free; args.acl_len = npages * PAGE_SIZE; - args.acl_pgbase = 0; dprintk("%s buf %p buflen %zu npages %d args.acl_len %zu\n", __func__, buf, buflen, npages, args.acl_len); @@ -4766,7 +4765,7 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl return -EOPNOTSUPP; if (npages > ARRAY_SIZE(pages)) return -ERANGE; - i = buf_to_pages_noslab(buf, buflen, arg.acl_pages, &arg.acl_pgbase); + i = buf_to_pages_noslab(buf, buflen, arg.acl_pages); if (i < 0) return i; nfs4_inode_return_delegation(inode); diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 6f6d921..eefed15 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -1659,7 +1659,7 @@ encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg, struct compoun *p = cpu_to_be32(FATTR4_WORD0_ACL); p = reserve_space(xdr, 4); *p = cpu_to_be32(arg->acl_len); - xdr_write_pages(xdr, arg->acl_pages, arg->acl_pgbase, arg->acl_len); + xdr_write_pages(xdr, arg->acl_pages, 0, arg->acl_len); } static void @@ -2491,7 +2491,7 @@ static void nfs4_xdr_enc_getacl(struct rpc_rqst *req, struct xdr_stream *xdr, encode_getattr_two(xdr, FATTR4_WORD0_ACL, 0, &hdr); xdr_inline_pages(&req->rq_rcv_buf, replen << 2, - args->acl_pages, args->acl_pgbase, args->acl_len); + args->acl_pages, 0, args->acl_len); encode_nops(&hdr); } diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 52faf7e..090ade4 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -685,7 +685,6 @@ struct nfs_setaclargs { struct nfs4_sequence_args seq_args; struct nfs_fh * fh; size_t acl_len; - unsigned int acl_pgbase; struct page ** acl_pages; }; @@ -697,7 +696,6 @@ struct nfs_getaclargs { struct nfs4_sequence_args seq_args; struct nfs_fh * fh; size_t acl_len; - unsigned int acl_pgbase; struct page ** acl_pages; }; -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:23:19 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 F238929E97 for ; Tue, 3 Nov 2015 09:23:19 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id DDD338F8040 for ; Tue, 3 Nov 2015 07:23:19 -0800 (PST) X-ASG-Debug-ID: 1446564198-04cbb0660d1f7e50001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id uYu5mlIoRTGLCS64 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:23:18 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 10489C100446; Tue, 3 Nov 2015 15:23:18 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRaF029477; Tue, 3 Nov 2015 10:23:11 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 49/51] nfs: Distinguish missing users and groups from nobody Date: Tue, 3 Nov 2015 16:17:25 +0100 X-ASG-Orig-Subj: [PATCH v13 49/51] nfs: Distinguish missing users and groups from nobody Message-Id: <1446563847-14005-50-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446564198 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 User and group names are mapped to IDs using the kernel keyring infrastructure. When a name does not exist, it is mapped to the nobody user or group; there is no way to tell the difference from the mapping result. In ACLs, we need to make that distinction. For that, use the new "xuid" and "xgid" maps: they behave like the old "uid" and "gid" maps except that the IDs of existing users and groups are prefixed by a "+" sign. When the "xuid" or "xgid" maps are not supported, nfs falls back to the "uid" and "gid" maps. Signed-off-by: Andreas Gruenbacher --- fs/nfs/nfs4idmap.c | 57 ++++++++++++++++++++++++++++++++++++++--------- fs/nfs/nfs4xdr.c | 6 +++-- include/linux/nfs_fs_sb.h | 1 + 3 files changed, 52 insertions(+), 12 deletions(-) diff --git a/fs/nfs/nfs4idmap.c b/fs/nfs/nfs4idmap.c index 2e49022..34dd404 100644 --- a/fs/nfs/nfs4idmap.c +++ b/fs/nfs/nfs4idmap.c @@ -100,10 +100,12 @@ static bool nfs_fattr_map_owner_name(struct nfs_server *server, struct nfs_fattr { struct nfs4_string *owner = fattr->owner_name; kuid_t uid; + int ret; if (!(fattr->valid & NFS_ATTR_FATTR_OWNER_NAME)) return false; - if (nfs_map_name_to_uid(server, owner->data, owner->len, &uid) == 0) { + ret = nfs_map_name_to_uid(server, owner->data, owner->len, &uid); + if (ret == 0 || ret == -ENOENT) { fattr->uid = uid; fattr->valid |= NFS_ATTR_FATTR_OWNER; } @@ -114,10 +116,12 @@ static bool nfs_fattr_map_group_name(struct nfs_server *server, struct nfs_fattr { struct nfs4_string *group = fattr->group_name; kgid_t gid; + int ret; if (!(fattr->valid & NFS_ATTR_FATTR_GROUP_NAME)) return false; - if (nfs_map_group_to_gid(server, group->data, group->len, &gid) == 0) { + ret = nfs_map_group_to_gid(server, group->data, group->len, &gid); + if (ret == 0 || ret == -ENOENT) { fattr->gid = gid; fattr->valid |= NFS_ATTR_FATTR_GROUP; } @@ -351,20 +355,23 @@ static ssize_t nfs_idmap_lookup_name(__u32 id, const char *type, char *buf, } /* Name -> ID */ +/* Returns -ENOENT for unknown names (with @id set to the nobody id). */ static int nfs_idmap_lookup_id(const char *name, size_t namelen, const char *type, __u32 *id, struct idmap *idmap) { - char id_str[NFS_UINT_MAXLEN]; + char id_str[NFS_UINT_MAXLEN + 1]; long id_long; ssize_t data_size; int ret = 0; - data_size = nfs_idmap_get_key(name, namelen, type, id_str, NFS_UINT_MAXLEN, idmap); + data_size = nfs_idmap_get_key(name, namelen, type, id_str, sizeof(id_str), idmap); if (data_size <= 0) { ret = -EINVAL; } else { ret = kstrtol(id_str, 10, &id_long); *id = (__u32)id_long; + if (!ret && *id_str != '+') + ret = -ENOENT; } return ret; } @@ -719,9 +726,24 @@ int nfs_map_name_to_uid(const struct nfs_server *server, const char *name, size_ __u32 id = -1; int ret = 0; - if (!nfs_map_string_to_numeric(name, namelen, &id)) - ret = nfs_idmap_lookup_id(name, namelen, "uid", &id, idmap); - if (ret == 0) { + if (!nfs_map_string_to_numeric(name, namelen, &id)) { + struct nfs_client *client = server->nfs_client; + const char *type; + + for(;;) { + type = "xuid"; + if (test_bit(NFS_CS_NOXUID, &client->cl_flags)) + type = "uid"; + + ret = nfs_idmap_lookup_id(name, namelen, type, &id, idmap); + if (ret != -EINVAL || test_bit(NFS_CS_NOXUID, &client->cl_flags)) + break; + printk(KERN_NOTICE "NFS: Falling back from nfsidmap " + "xuid/xgid to uid/gid\n"); + set_bit(NFS_CS_NOXUID, &client->cl_flags); + } + } + if (ret == 0 || ret == -ENOENT) { *uid = make_kuid(&init_user_ns, id); if (!uid_valid(*uid)) ret = -ERANGE; @@ -736,9 +758,24 @@ int nfs_map_group_to_gid(const struct nfs_server *server, const char *name, size __u32 id = -1; int ret = 0; - if (!nfs_map_string_to_numeric(name, namelen, &id)) - ret = nfs_idmap_lookup_id(name, namelen, "gid", &id, idmap); - if (ret == 0) { + if (!nfs_map_string_to_numeric(name, namelen, &id)) { + struct nfs_client *client = server->nfs_client; + const char *type; + + for(;;) { + type = "xgid"; + if (test_bit(NFS_CS_NOXUID, &client->cl_flags)) + type = "gid"; + + ret = nfs_idmap_lookup_id(name, namelen, type, &id, idmap); + if (ret != -EINVAL || test_bit(NFS_CS_NOXUID, &client->cl_flags)) + break; + printk(KERN_NOTICE "NFS: Falling back from nfsidmap " + "xuid/xgid to uid/gid\n"); + set_bit(NFS_CS_NOXUID, &client->cl_flags); + } + } + if (ret == 0 || ret == -ENOENT) { *gid = make_kgid(&init_user_ns, id); if (!gid_valid(*gid)) ret = -ERANGE; diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index eefed15..adeb894 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -3875,7 +3875,8 @@ static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, ret = NFS_ATTR_FATTR_OWNER_NAME; } } else if (len < XDR_MAX_NETOBJ) { - if (nfs_map_name_to_uid(server, (char *)p, len, uid) == 0) + ret = nfs_map_name_to_uid(server, (char *)p, len, uid); + if (ret == 0 || ret == -ENOENT) ret = NFS_ATTR_FATTR_OWNER; else dprintk("%s: nfs_map_name_to_uid failed!\n", @@ -3918,7 +3919,8 @@ static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, ret = NFS_ATTR_FATTR_GROUP_NAME; } } else if (len < XDR_MAX_NETOBJ) { - if (nfs_map_group_to_gid(server, (char *)p, len, gid) == 0) + ret = nfs_map_group_to_gid(server, (char *)p, len, gid); + if (ret == 0 || ret == -ENOENT) ret = NFS_ATTR_FATTR_GROUP; else dprintk("%s: nfs_map_group_to_gid failed!\n", diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index 570a7df..c7d42b7 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -36,6 +36,7 @@ struct nfs_client { #define NFS_CS_RENEWD 3 /* - renewd started */ #define NFS_CS_STOP_RENEW 4 /* no more state to renew */ #define NFS_CS_CHECK_LEASE_TIME 5 /* need to check lease time */ +#define NFS_CS_NOXUID 6 /* don't use idmap xuid / xgid */ unsigned long cl_flags; /* behavior switches */ #define NFS_CS_NORESVPORT 0 /* - use ephemeral src port */ #define NFS_CS_DISCRTRY 1 /* - disconnect on RPC retry */ -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:23:29 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 9820129E66 for ; Tue, 3 Nov 2015 09:23:29 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 44C818F8037 for ; Tue, 3 Nov 2015 07:23:29 -0800 (PST) X-ASG-Debug-ID: 1446564205-04bdf0330b1fcc70001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id qb9PgNFh8gBKT88O (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:23:25 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 012598FAA2; Tue, 3 Nov 2015 15:23:24 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRaG029477; Tue, 3 Nov 2015 10:23:18 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 50/51] nfs: Add richacl support Date: Tue, 3 Nov 2015 16:17:26 +0100 X-ASG-Orig-Subj: [PATCH v13 50/51] nfs: Add richacl support Message-Id: <1446563847-14005-51-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446564205 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Add support for the "system.richacl" xattr in nfs. The existing "system.nfs4_acl" xattr on nfs doesn't map user and group names to uids and gids; the "system.richacl" xattr does, and only keeps the on-the-wire names when there is no mapping. This allows to copy permissions across different file systems. Signed-off-by: Andreas Gruenbacher --- fs/nfs/inode.c | 3 - fs/nfs/nfs4proc.c | 731 ++++++++++++++++++++++++++++++++++------------ fs/nfs/nfs4xdr.c | 178 +++++++++-- fs/nfs/super.c | 4 +- include/linux/nfs_fs.h | 1 - include/linux/nfs_fs_sb.h | 2 + include/linux/nfs_xdr.h | 9 +- 7 files changed, 701 insertions(+), 227 deletions(-) diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 326d9e1..843d15d 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -1852,9 +1852,6 @@ struct inode *nfs_alloc_inode(struct super_block *sb) return NULL; nfsi->flags = 0UL; nfsi->cache_validity = 0UL; -#if IS_ENABLED(CONFIG_NFS_V4) - nfsi->nfs4_acl = NULL; -#endif /* CONFIG_NFS_V4 */ return &nfsi->vfs_inode; } EXPORT_SYMBOL_GPL(nfs_alloc_inode); diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index eec5c4c..7bb2dea 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -55,6 +55,9 @@ #include #include #include +#include +#include +#include #include "nfs4_fs.h" #include "delegation.h" @@ -2982,15 +2985,18 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f res.attr_bitmask[2] &= FATTR4_WORD2_NFS42_MASK; } memcpy(server->attr_bitmask, res.attr_bitmask, sizeof(server->attr_bitmask)); - server->caps &= ~(NFS_CAP_ACLS|NFS_CAP_HARDLINKS| - NFS_CAP_SYMLINKS|NFS_CAP_FILEID| + server->caps &= ~(NFS_CAP_ALLOW_ACLS|NFS_CAP_DENY_ACLS| + NFS_CAP_HARDLINKS|NFS_CAP_SYMLINKS|NFS_CAP_FILEID| NFS_CAP_MODE|NFS_CAP_NLINK|NFS_CAP_OWNER| NFS_CAP_OWNER_GROUP|NFS_CAP_ATIME| NFS_CAP_CTIME|NFS_CAP_MTIME| NFS_CAP_SECURITY_LABEL); - if (res.attr_bitmask[0] & FATTR4_WORD0_ACL && - res.acl_bitmask & ACL4_SUPPORT_ALLOW_ACL) - server->caps |= NFS_CAP_ACLS; + if (res.attr_bitmask[0] & FATTR4_WORD0_ACL) { + if (res.acl_bitmask & ACL4_SUPPORT_ALLOW_ACL) + server->caps |= NFS_CAP_ALLOW_ACLS; + if (res.acl_bitmask & ACL4_SUPPORT_DENY_ACL) + server->caps |= NFS_CAP_DENY_ACLS; + } if (res.has_links != 0) server->caps |= NFS_CAP_HARDLINKS; if (res.has_symlinks != 0) @@ -4518,45 +4524,11 @@ static int nfs4_proc_renew(struct nfs_client *clp, struct rpc_cred *cred) return 0; } -static inline int nfs4_server_supports_acls(struct nfs_server *server) -{ - return server->caps & NFS_CAP_ACLS; -} - -/* Assuming that XATTR_SIZE_MAX is a multiple of PAGE_SIZE, and that - * it's OK to put sizeof(void) * (XATTR_SIZE_MAX/PAGE_SIZE) bytes on - * the stack. +/* A arbitrary limit; we allocate at most DIV_ROUND_UP(NFS4ACL_SIZE_MAX, + * PAGE_SIZE) pages and put an array of DIV_ROUND_UP(NFS4ACL_SIZE_MAX, + * PAGE_SIZE) pages on the stack when encoding or decoding acls. */ -#define NFS4ACL_MAXPAGES DIV_ROUND_UP(XATTR_SIZE_MAX, PAGE_SIZE) - -static int buf_to_pages_noslab(const void *buf, size_t buflen, - struct page **pages) -{ - struct page *newpage, **spages; - int rc = 0; - size_t len; - spages = pages; - - do { - len = min_t(size_t, PAGE_SIZE, buflen); - newpage = alloc_page(GFP_KERNEL); - - if (newpage == NULL) - goto unwind; - memcpy(page_address(newpage), buf, len); - buf += len; - buflen -= len; - *pages++ = newpage; - rc++; - } while (buflen != 0); - - return rc; - -unwind: - for(; rc > 0; rc--) - __free_page(spages[rc-1]); - return -ENOMEM; -} +#define NFS4ACL_SIZE_MAX 65536 struct nfs4_cached_acl { int cached; @@ -4564,66 +4536,9 @@ struct nfs4_cached_acl { char data[0]; }; -static void nfs4_set_cached_acl(struct inode *inode, struct nfs4_cached_acl *acl) -{ - struct nfs_inode *nfsi = NFS_I(inode); - - spin_lock(&inode->i_lock); - kfree(nfsi->nfs4_acl); - nfsi->nfs4_acl = acl; - spin_unlock(&inode->i_lock); -} - static void nfs4_zap_acl_attr(struct inode *inode) { - nfs4_set_cached_acl(inode, NULL); -} - -static inline ssize_t nfs4_read_cached_acl(struct inode *inode, char *buf, size_t buflen) -{ - struct nfs_inode *nfsi = NFS_I(inode); - struct nfs4_cached_acl *acl; - int ret = -ENOENT; - - spin_lock(&inode->i_lock); - acl = nfsi->nfs4_acl; - if (acl == NULL) - goto out; - if (buf == NULL) /* user is just asking for length */ - goto out_len; - if (acl->cached == 0) - goto out; - ret = -ERANGE; /* see getxattr(2) man page */ - if (acl->len > buflen) - goto out; - memcpy(buf, acl->data, acl->len); -out_len: - ret = acl->len; -out: - spin_unlock(&inode->i_lock); - return ret; -} - -static void nfs4_write_cached_acl(struct inode *inode, struct page **pages, size_t pgbase, size_t acl_len) -{ - struct nfs4_cached_acl *acl; - size_t buflen = sizeof(*acl) + acl_len; - - if (buflen <= PAGE_SIZE) { - acl = kmalloc(buflen, GFP_KERNEL); - if (acl == NULL) - goto out; - acl->cached = 1; - _copy_from_pages(acl->data, pages, pgbase, acl_len); - } else { - acl = kmalloc(sizeof(*acl), GFP_KERNEL); - if (acl == NULL) - goto out; - acl->cached = 0; - } - acl->len = acl_len; -out: - nfs4_set_cached_acl(inode, acl); + forget_cached_richacl(inode); } /* @@ -4636,121 +4551,269 @@ out: * length. The next getxattr call will then produce another round trip to * the server, this time with the input buf of the required size. */ -static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen) +static struct richacl *__nfs4_get_acl_uncached(struct inode *inode) { - struct page *pages[NFS4ACL_MAXPAGES] = {NULL, }; + struct nfs_server *server = NFS_SERVER(inode); + struct page *pages[DIV_ROUND_UP(NFS4ACL_SIZE_MAX, PAGE_SIZE)] = {}; struct nfs_getaclargs args = { .fh = NFS_FH(inode), .acl_pages = pages, - .acl_len = buflen, + .acl_len = ARRAY_SIZE(pages) * PAGE_SIZE, }; struct nfs_getaclres res = { - .acl_len = buflen, + .server = server, }; struct rpc_message msg = { .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_GETACL], .rpc_argp = &args, .rpc_resp = &res, }; - unsigned int npages = DIV_ROUND_UP(buflen, PAGE_SIZE); - int ret = -ENOMEM, i; - - /* As long as we're doing a round trip to the server anyway, - * let's be prepared for a page of acl data. */ - if (npages == 0) - npages = 1; - if (npages > ARRAY_SIZE(pages)) - return -ERANGE; + int err, i; - for (i = 0; i < npages; i++) { - pages[i] = alloc_page(GFP_KERNEL); - if (!pages[i]) + if (ARRAY_SIZE(pages) > 1) { + /* for decoding across pages */ + res.acl_scratch = alloc_page(GFP_KERNEL); + err = -ENOMEM; + if (!res.acl_scratch) goto out_free; } - /* for decoding across pages */ - res.acl_scratch = alloc_page(GFP_KERNEL); - if (!res.acl_scratch) - goto out_free; - - args.acl_len = npages * PAGE_SIZE; - - dprintk("%s buf %p buflen %zu npages %d args.acl_len %zu\n", - __func__, buf, buflen, npages, args.acl_len); - ret = nfs4_call_sync(NFS_SERVER(inode)->client, NFS_SERVER(inode), + dprintk("%s args.acl_len %zu\n", + __func__, args.acl_len); + err = nfs4_call_sync(NFS_SERVER(inode)->client, NFS_SERVER(inode), &msg, &args.seq_args, &res.seq_res, 0); - if (ret) + if (err) goto out_free; - /* Handle the case where the passed-in buffer is too short */ - if (res.acl_flags & NFS4_ACL_TRUNC) { - /* Did the user only issue a request for the acl length? */ - if (buf == NULL) - goto out_ok; - ret = -ERANGE; - goto out_free; - } - nfs4_write_cached_acl(inode, pages, res.acl_data_offset, res.acl_len); - if (buf) { - if (res.acl_len > buflen) { - ret = -ERANGE; - goto out_free; - } - _copy_from_pages(buf, pages, res.acl_data_offset, res.acl_len); - } -out_ok: - ret = res.acl_len; + richacl_compute_max_masks(res.acl); + /* FIXME: Set inode->i_mode from res->mode? */ + set_cached_richacl(inode, res.acl); + err = 0; + out_free: - for (i = 0; i < npages; i++) - if (pages[i]) - __free_page(pages[i]); + if (err) { + richacl_put(res.acl); + res.acl = ERR_PTR(err); + } + for (i = 0; i < ARRAY_SIZE(pages) && pages[i]; i++) + __free_page(pages[i]); if (res.acl_scratch) __free_page(res.acl_scratch); - return ret; + return res.acl; } -static ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen) +static struct richacl *nfs4_get_acl_uncached(struct inode *inode) { struct nfs4_exception exception = { }; - ssize_t ret; + struct richacl *acl; do { - ret = __nfs4_get_acl_uncached(inode, buf, buflen); - trace_nfs4_get_acl(inode, ret); - if (ret >= 0) + acl = __nfs4_get_acl_uncached(inode); + trace_nfs4_get_acl(inode, IS_ERR(acl) ? PTR_ERR(acl) : 0); + if (!IS_ERR(acl)) break; - ret = nfs4_handle_exception(NFS_SERVER(inode), ret, &exception); + acl = ERR_PTR(nfs4_handle_exception(NFS_SERVER(inode), + PTR_ERR(acl), &exception)); } while (exception.retry); - return ret; + return acl; } -static ssize_t nfs4_proc_get_acl(struct inode *inode, void *buf, size_t buflen) +static struct richacl *nfs4_proc_get_acl(struct inode *inode) { struct nfs_server *server = NFS_SERVER(inode); + struct richacl *acl; int ret; - if (!nfs4_server_supports_acls(server)) - return -EOPNOTSUPP; + if (!(server->caps & (NFS_CAP_ALLOW_ACLS | NFS_CAP_DENY_ACLS))) + return ERR_PTR(-EOPNOTSUPP); ret = nfs_revalidate_inode(server, inode); if (ret < 0) - return ret; + return ERR_PTR(ret); if (NFS_I(inode)->cache_validity & NFS_INO_INVALID_ACL) nfs_zap_acl_cache(inode); - ret = nfs4_read_cached_acl(inode, buf, buflen); - if (ret != -ENOENT) - /* -ENOENT is returned if there is no ACL or if there is an ACL - * but no cached acl data, just the acl length */ - return ret; - return nfs4_get_acl_uncached(inode, buf, buflen); + acl = get_cached_richacl(inode); + if (acl != ACL_NOT_CACHED) + return acl; + return nfs4_get_acl_uncached(inode); +} + +static int +richacl_supported(struct nfs_server *server, struct richacl *acl) +{ + struct richace *ace; + + if (!(server->caps & (NFS_CAP_ALLOW_ACLS | NFS_CAP_DENY_ACLS))) + return -EOPNOTSUPP; + + richacl_for_each_entry(ace, acl) { + if (richace_is_allow(ace)) { + if (!(server->caps & NFS_CAP_ALLOW_ACLS)) + return -EINVAL; + } else if (richace_is_deny(ace)) { + if (!(server->caps & NFS_CAP_DENY_ACLS)) + return -EINVAL; + } else + return -EINVAL; + } + return 0; +} + +static int +nfs4_encode_user(struct xdr_stream *xdr, const struct nfs_server *server, + kuid_t uid) +{ + char name[IDMAP_NAMESZ]; + int len; + __be32 *p; + + len = nfs_map_uid_to_name(server, uid, name, IDMAP_NAMESZ); + if (len < 0) { + dprintk("nfs: couldn't resolve uid %d to string\n", + from_kuid(&init_user_ns, uid)); + return -ENOENT; + } + p = xdr_reserve_space(xdr, 4 + len); + if (!p) + return -EIO; + p = xdr_encode_opaque(p, name, len); + return 0; +} + +static int +nfs4_encode_group(struct xdr_stream *xdr, const struct nfs_server *server, + kgid_t gid) +{ + char name[IDMAP_NAMESZ]; + int len; + __be32 *p; + + len = nfs_map_gid_to_group(server, gid, name, IDMAP_NAMESZ); + if (len < 0) { + dprintk("nfs: couldn't resolve gid %d to string\n", + from_kgid(&init_user_ns, gid)); + return -ENOENT; + } + p = xdr_reserve_space(xdr, 4 + len); + if (!p) + return -EIO; + p = xdr_encode_opaque(p, name, len); + return 0; +} + +static unsigned int +nfs4_ace_mask(int minorversion) +{ + return minorversion == 0 ? NFS40_ACE_MASK_ALL : NFS4_ACE_MASK_ALL; +} + +static int +nfs4_encode_ace_who(struct xdr_stream *xdr, const struct nfs_server *server, + struct richace *ace, struct richacl *acl) +{ + const char *who; + __be32 *p; + + if (ace->e_flags & RICHACE_SPECIAL_WHO) { + unsigned int special_id = ace->e_id.special; + const char *who; + unsigned int len; + + if (!nfs4acl_special_id_to_who(special_id, &who, &len)) { + WARN_ON_ONCE(1); + return -EIO; + } + p = xdr_reserve_space(xdr, 4 + len); + if (!p) + return -EIO; + xdr_encode_opaque(p, who, len); + return 0; + } else { + who = richace_unmapped_identifier(ace, acl); + if (who) { + unsigned int len = strlen(who); + + p = xdr_reserve_space(xdr, 4 + len); + if (!p) + return -EIO; + xdr_encode_opaque(p, who, len); + return 0; + } else if (ace->e_flags & RICHACE_IDENTIFIER_GROUP) + return nfs4_encode_group(xdr, server, ace->e_id.gid); + else + return nfs4_encode_user(xdr, server, ace->e_id.uid); + } +} + +static int +nfs4_encode_acl(struct page **pages, unsigned int len, struct richacl *acl, + const struct nfs_server *server) +{ + int minorversion = server->nfs_client->cl_minorversion; + unsigned int ace_mask = nfs4_ace_mask(minorversion); + struct xdr_stream xdr; + struct xdr_buf buf; + __be32 *p; + struct richace *ace; + + /* Reject acls not understood by the server */ + if (server->attr_bitmask[1] & FATTR4_WORD1_DACL) { + BUILD_BUG_ON(NFS4_ACE_MASK_ALL != RICHACE_VALID_MASK); + } else { + if (acl->a_flags) + return -EINVAL; + richacl_for_each_entry(ace, acl) { + if (ace->e_flags & RICHACE_INHERITED_ACE) + return -EINVAL; + } + } + richacl_for_each_entry(ace, acl) { + if (ace->e_mask & ~ace_mask) + return -EINVAL; + } + + xdr_init_encode_pages(&xdr, &buf, pages, len); + + if (server->attr_bitmask[1] & FATTR4_WORD1_DACL) { + p = xdr_reserve_space(&xdr, 4); + if (!p) + goto fail; + *p = cpu_to_be32(acl ? acl->a_flags : 0); + } + + p = xdr_reserve_space(&xdr, 4); + if (!p) + goto fail; + if (!acl) { + *p++ = cpu_to_be32(0); + return buf.len; + } + *p++ = cpu_to_be32(acl->a_count); + + richacl_for_each_entry(ace, acl) { + p = xdr_reserve_space(&xdr, 4*3); + if (!p) + goto fail; + *p++ = cpu_to_be32(ace->e_type); + *p++ = cpu_to_be32(ace->e_flags & + ~(RICHACE_SPECIAL_WHO | RICHACE_UNMAPPED_WHO)); + *p++ = cpu_to_be32(ace->e_mask & NFS4_ACE_MASK_ALL); + if (nfs4_encode_ace_who(&xdr, server, ace, acl) != 0) + goto fail; + } + + return buf.len; + +fail: + return -ENOMEM; } -static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen) +static int __nfs4_proc_set_acl(struct inode *inode, struct richacl *acl) { struct nfs_server *server = NFS_SERVER(inode); - struct page *pages[NFS4ACL_MAXPAGES]; + struct page *pages[DIV_ROUND_UP(NFS4ACL_SIZE_MAX, PAGE_SIZE) + 1 /* scratch */] = {}; struct nfs_setaclargs arg = { + .server = server, .fh = NFS_FH(inode), .acl_pages = pages, - .acl_len = buflen, }; struct nfs_setaclres res; struct rpc_message msg = { @@ -4758,16 +4821,20 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl .rpc_argp = &arg, .rpc_resp = &res, }; - unsigned int npages = DIV_ROUND_UP(buflen, PAGE_SIZE); int ret, i; - if (!nfs4_server_supports_acls(server)) - return -EOPNOTSUPP; - if (npages > ARRAY_SIZE(pages)) - return -ERANGE; - i = buf_to_pages_noslab(buf, buflen, arg.acl_pages); - if (i < 0) - return i; + ret = richacl_supported(server, acl); + if (ret) + return ret; + + ret = nfs4_encode_acl(pages, NFS4ACL_SIZE_MAX, acl, server); + if (ret < 0) { + for (i = 0; i < ARRAY_SIZE(pages) && pages[i]; i++) + put_page(pages[i]); + return ret; + } + arg.acl_len = ret; + nfs4_inode_return_delegation(inode); ret = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 1); @@ -4775,8 +4842,8 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl * Free each page after tx, so the only ref left is * held by the network stack */ - for (; i > 0; i--) - put_page(pages[i-1]); + for (i = 0; i < ARRAY_SIZE(pages) && pages[i]; i++) + put_page(pages[i]); /* * Acl update can result in inode attribute update. @@ -4790,12 +4857,12 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl return ret; } -static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen) +static int nfs4_proc_set_acl(struct inode *inode, struct richacl *acl) { struct nfs4_exception exception = { }; int err; do { - err = __nfs4_proc_set_acl(inode, buf, buflen); + err = __nfs4_proc_set_acl(inode, acl); trace_nfs4_set_acl(inode, err); err = nfs4_handle_exception(NFS_SERVER(inode), err, &exception); @@ -6257,34 +6324,316 @@ nfs4_release_lockowner(struct nfs_server *server, struct nfs4_lock_state *lsp) rpc_call_async(server->client, &msg, 0, &nfs4_release_lockowner_ops, data); } +static int nfs4_xattr_set_richacl(struct dentry *dentry, const char *key, + const void *buf, size_t buflen, + int flags, int handler_flags) +{ + struct inode *inode = d_inode(dentry); + struct richacl *acl; + int error; + + if (strcmp(key, "") != 0) + return -EINVAL; + + if (buf) { + acl = richacl_from_xattr(&init_user_ns, buf, buflen); + if (IS_ERR(acl)) + return PTR_ERR(acl); + error = richacl_apply_masks(&acl, inode->i_uid); + } else { + /* + * "Remove the acl"; only permissions granted by the mode + * remain. We are using the cached mode here which could be + * outdated; should we do a GETATTR first to narrow down the + * race window? + */ + acl = richacl_from_mode(inode->i_mode); + error = 0; + } + + if (!error) + error = nfs4_proc_set_acl(inode, acl); + richacl_put(acl); + return error; +} + +static int nfs4_xattr_get_richacl(struct dentry *dentry, const char *key, + void *buf, size_t buflen, int handler_flags) +{ + struct inode *inode = d_inode(dentry); + struct richacl *acl; + int error; + umode_t mode = inode->i_mode & S_IFMT; + + if (strcmp(key, "") != 0) + return -EINVAL; + + acl = nfs4_proc_get_acl(inode); + if (IS_ERR(acl)) + return PTR_ERR(acl); + if (acl == NULL) + return -ENODATA; + error = -ENODATA; + if (richacl_equiv_mode(acl, &mode) == 0 && + ((mode ^ inode->i_mode) & S_IRWXUGO) == 0) + goto out; + error = richacl_to_xattr(&init_user_ns, acl, buf, buflen); +out: + richacl_put(acl); + return error; +} + +static size_t nfs4_xattr_list_richacl(struct dentry *dentry, char *list, + size_t list_len, const char *name, + size_t name_len, int handler_flags) +{ + struct nfs_server *server = NFS_SERVER(d_inode(dentry)); + size_t len = sizeof(XATTR_NAME_RICHACL); + + if (!(server->caps & (NFS_CAP_ALLOW_ACLS | NFS_CAP_DENY_ACLS))) + return 0; + + if (list && len <= list_len) + memcpy(list, XATTR_NAME_RICHACL, len); + return len; +} + #define XATTR_NAME_NFSV4_ACL "system.nfs4_acl" +static __be32 *richacl_put_nfs4_ace(__be32 *p, const struct richace *ace) +{ + *p++ = cpu_to_be32(ace->e_type); + *p++ = cpu_to_be32(ace->e_flags & + ~(RICHACE_INHERITED_ACE | + RICHACE_UNMAPPED_WHO | + RICHACE_SPECIAL_WHO)); + *p++ = cpu_to_be32(ace->e_mask); + + return p; +} + +static __be32 *richacl_put_name(__be32 *p, const char *who, int who_len) +{ + unsigned int padding = -who_len & 3; + + *p++ = cpu_to_be32(who_len); + memcpy(p, who, who_len); + memset((char *)p + who_len, 0, padding); + p += DIV_ROUND_UP(who_len, 4); + + return p; +} + +static int richacl_to_nfs4_acl(struct nfs_server *server, + const struct richacl *acl, + void *buf, size_t buflen) +{ + const struct richace *ace; + __be32 *p = buf; + size_t size = 0; + + size += 4; + if (buflen >= size) + *p++ = cpu_to_be32(acl->a_count); + + richacl_for_each_entry(ace, acl) { + char who_buf[IDMAP_NAMESZ]; + const char *who = who_buf; + int who_len; + + size += 3 * 4; + if (buflen >= size) + p = richacl_put_nfs4_ace(p, ace); + + if (richace_is_unix_user(ace)) { + who_len = nfs_map_uid_to_name(server, ace->e_id.uid, + who_buf, sizeof(who_buf)); + if (who_len < 0) + return -EIO; + } else if (richace_is_unix_group(ace)) { + who_len = nfs_map_gid_to_group(server, ace->e_id.gid, + who_buf, sizeof(who_buf)); + if (who_len < 0) + return -EIO; + } else if (ace->e_flags & RICHACE_SPECIAL_WHO) { + if (!nfs4acl_special_id_to_who(ace->e_id.special, + &who, &who_len)) + return -EIO; + } else { + who = richace_unmapped_identifier(ace, acl); + if (who) + who_len = strlen(who); + else + return -EIO; + } + + size += 4 + ALIGN(who_len, 4); + if (buflen >= size) + p = richacl_put_name(p, who, who_len); + } + if (buflen && buflen < size) + return -ERANGE; + return size; +} + +static int richace_get_nfs4_ace(struct richace *ace, const __be32 **pp, + size_t *buflen) +{ + const __be32 *p = *pp; + + if (*buflen < 3 * 4) + return -EINVAL; + ace->e_type = be32_to_cpu(*p++); + ace->e_flags = be32_to_cpu(*p++); + if (ace->e_flags & (RICHACE_SPECIAL_WHO | RICHACE_UNMAPPED_WHO)) + return -EINVAL; + ace->e_mask = be32_to_cpu(*p++); + *pp = p; + *buflen -= 3 * 4; + + return 0; +} + +static ssize_t richace_get_who(struct nfs_server *server, struct richacl *acl, + struct richace *ace, const __be32 **pp, + size_t *buflen) +{ + const __be32 *p = *pp; + u32 who_len, size; + int err, special_id; + char *who; + + if (*buflen < 4) + return -EINVAL; + who_len = be32_to_cpu(*p++); + *buflen -= 4; + size = ALIGN(who_len, 4); + if (*buflen < size || size == 0) + return -EINVAL; + who = (char *)p; + special_id = nfs4acl_who_to_special_id(who, who_len); + if (special_id >= 0) { + ace->e_flags |= RICHACE_SPECIAL_WHO; + ace->e_id.special = special_id; + goto out; + } + + if (ace->e_flags & RICHACE_IDENTIFIER_GROUP) { + err = nfs_map_group_to_gid(server, who, who_len, + &ace->e_id.gid); + if (err && err != -ENOENT) { + dprintk("%s: nfs_map_group_to_gid " + "failed!\n", __func__); + return err; + } + } else { + err = nfs_map_name_to_uid(server, who, who_len, + &ace->e_id.uid); + if (err && err != -ENOENT) { + dprintk("%s: nfs_map_name_to_gid " + "failed!\n", __func__); + return err; + } + } + + if (err == -ENOENT) { + err = -ENOMEM; + if (richacl_add_unmapped_identifier(&acl, &ace, + who, who_len, GFP_NOFS)) + return err; + } + +out: + *pp = p + size / 4; + *buflen -= size; + return 0; +} + +static struct richacl *richacl_from_nfs4_acl(struct nfs_server *server, + const void *buf, size_t buflen) +{ + struct richacl *acl = NULL; + struct richace *ace; + const __be32 *p = buf; + int count, err; + + if (buflen < 4) + return ERR_PTR(-EINVAL); + count = be32_to_cpu(*p++); + if (count > RICHACL_XATTR_MAX_COUNT) + return ERR_PTR(-EINVAL); + buflen -= 4; + acl = richacl_alloc(count, GFP_NOFS); + if (!acl) + return ERR_PTR(-ENOMEM); + richacl_for_each_entry(ace, acl) { + err = richace_get_nfs4_ace(ace, &p, &buflen); + if (err) + goto out; + err = richace_get_who(server, acl, ace, &p, &buflen); + if (err) + goto out; + + } + err = -EINVAL; + if (buflen != 0) + goto out; + err = 0; + +out: + if (err) { + richacl_put(acl); + acl = ERR_PTR(err); + } + return acl; +} + static int nfs4_xattr_set_nfs4_acl(struct dentry *dentry, const char *key, const void *buf, size_t buflen, int flags, int type) { - if (strcmp(key, "") != 0) + struct inode *inode = d_inode(dentry); + struct richacl *acl; + int error; + + if (!buf || strcmp(key, "") != 0) return -EINVAL; - return nfs4_proc_set_acl(d_inode(dentry), buf, buflen); + acl = richacl_from_nfs4_acl(NFS_SERVER(inode), (void *)buf, buflen); + if (IS_ERR(acl)) + return PTR_ERR(acl); + error = nfs4_proc_set_acl(inode, acl); + richacl_put(acl); + return error; } static int nfs4_xattr_get_nfs4_acl(struct dentry *dentry, const char *key, void *buf, size_t buflen, int type) { + struct inode *inode = d_inode(dentry); + struct richacl *acl; + int error; + if (strcmp(key, "") != 0) return -EINVAL; - - return nfs4_proc_get_acl(d_inode(dentry), buf, buflen); + acl = nfs4_proc_get_acl(inode); + if (IS_ERR(acl)) + return PTR_ERR(acl); + if (acl == NULL) + return -ENODATA; + error = richacl_to_nfs4_acl(NFS_SERVER(inode), acl, buf, buflen); + richacl_put(acl); + return error; } static size_t nfs4_xattr_list_nfs4_acl(struct dentry *dentry, char *list, size_t list_len, const char *name, size_t name_len, int type) { + struct nfs_server *server = NFS_SERVER(d_inode(dentry)); size_t len = sizeof(XATTR_NAME_NFSV4_ACL); - if (!nfs4_server_supports_acls(NFS_SERVER(d_inode(dentry)))) + if (!(server->caps & (NFS_CAP_ALLOW_ACLS | NFS_CAP_DENY_ACLS))) return 0; if (list && len <= list_len) @@ -8837,6 +9186,13 @@ const struct nfs_rpc_ops nfs_v4_clientops = { .clone_server = nfs_clone_server, }; +static const struct xattr_handler nfs4_xattr_richacl_handler = { + .prefix = XATTR_NAME_RICHACL, + .list = nfs4_xattr_list_richacl, + .get = nfs4_xattr_get_richacl, + .set = nfs4_xattr_set_richacl, +}; + static const struct xattr_handler nfs4_xattr_nfs4_acl_handler = { .prefix = XATTR_NAME_NFSV4_ACL, .list = nfs4_xattr_list_nfs4_acl, @@ -8845,6 +9201,7 @@ static const struct xattr_handler nfs4_xattr_nfs4_acl_handler = { }; const struct xattr_handler *nfs4_xattr_handlers[] = { + &nfs4_xattr_richacl_handler, &nfs4_xattr_nfs4_acl_handler, #ifdef CONFIG_NFS_V4_SECURITY_LABEL &nfs4_xattr_nfs4_label_handler, diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index adeb894..2f1d6be 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -52,6 +52,10 @@ #include #include #include +#include +#include +#include /* for RICHACL_XATTR_MAX_COUNT */ +#include #include "nfs4_fs.h" #include "internal.h" @@ -1650,16 +1654,24 @@ encode_restorefh(struct xdr_stream *xdr, struct compound_hdr *hdr) static void encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg, struct compound_hdr *hdr) { - __be32 *p; + int attrlen_offset; + __be32 attrlen, *p; encode_op_hdr(xdr, OP_SETATTR, decode_setacl_maxsz, hdr); encode_nfs4_stateid(xdr, &zero_stateid); + + /* Encode attribute bitmap. */ p = reserve_space(xdr, 2*4); *p++ = cpu_to_be32(1); *p = cpu_to_be32(FATTR4_WORD0_ACL); - p = reserve_space(xdr, 4); - *p = cpu_to_be32(arg->acl_len); + + attrlen_offset = xdr->buf->len; + xdr_reserve_space(xdr, 4); /* to be backfilled later */ + xdr_write_pages(xdr, arg->acl_pages, 0, arg->acl_len); + + attrlen = htonl(xdr->buf->len - attrlen_offset - 4); + write_bytes_to_xdr_buf(xdr->buf, attrlen_offset, &attrlen, 4); } static void @@ -2488,7 +2500,7 @@ static void nfs4_xdr_enc_getacl(struct rpc_rqst *req, struct xdr_stream *xdr, encode_sequence(xdr, &args->seq_args, &hdr); encode_putfh(xdr, args->fh, &hdr); replen = hdr.replen + op_decode_hdr_maxsz + 1; - encode_getattr_two(xdr, FATTR4_WORD0_ACL, 0, &hdr); + encode_getattr_two(xdr, FATTR4_WORD0_ACL, FATTR4_WORD1_MODE, &hdr); xdr_inline_pages(&req->rq_rcv_buf, replen << 2, args->acl_pages, 0, args->acl_len); @@ -5262,50 +5274,156 @@ decode_restorefh(struct xdr_stream *xdr) return decode_op_hdr(xdr, OP_RESTOREFH); } +static int +nfs4_decode_ace_who(struct richace *ace, + const char **unmapped, unsigned int *unmapped_len, + const struct nfs_server *server, + struct xdr_stream *xdr) +{ + char *who; + u32 len; + int special_id; + __be32 *p; + int error; + + p = xdr_inline_decode(xdr, 4); + if (!p) + return -ENOMEM; /* acl truncated */ + len = be32_to_cpup(p++); + if (len >= XDR_MAX_NETOBJ) { + dprintk("%s: name too long (%u)!\n", + __func__, len); + return -EIO; + } + who = (char *)xdr_inline_decode(xdr, len); + if (!who) + return -ENOMEM; /* acl truncated */ + + special_id = nfs4acl_who_to_special_id(who, len); + if (special_id >= 0) { + ace->e_flags |= RICHACE_SPECIAL_WHO; + ace->e_flags &= ~RICHACE_IDENTIFIER_GROUP; + ace->e_id.special = special_id; + return 0; + } + if (ace->e_flags & RICHACE_IDENTIFIER_GROUP) { + error = nfs_map_group_to_gid(server, who, len, &ace->e_id.gid); + if (error && error != -ENOENT) { + dprintk("%s: nfs_map_group_to_gid failed!\n", + __func__); + return error; + } + } else { + error = nfs_map_name_to_uid(server, who, len, &ace->e_id.uid); + if (error && error != -ENOENT) { + dprintk("%s: nfs_map_name_to_uid failed!\n", + __func__); + return error; + } + } + if (error == -ENOENT) { + *unmapped = who; + *unmapped_len = len; + } + return 0; +} + +static struct richacl * +decode_acl_entries(struct xdr_stream *xdr, const struct nfs_server *server) +{ + struct richacl *acl; + struct richace *ace; + uint32_t count; + __be32 *p; + int status; + + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) + return ERR_PTR(-ENOMEM); /* acl truncated */ + count = be32_to_cpup(p); + if (count > RICHACL_XATTR_MAX_COUNT) + return ERR_PTR(-EIO); + acl = richacl_alloc(count, GFP_NOFS); + if (!acl) + return ERR_PTR(-ENOMEM); + richacl_for_each_entry(ace, acl) { + const char *unmapped = NULL; + unsigned int unmapped_len; + + p = xdr_inline_decode(xdr, 4*3); + status = -ENOMEM; + if (unlikely(!p)) + goto out; /* acl truncated */ + ace->e_type = be32_to_cpup(p++); + ace->e_flags = be32_to_cpup(p++); + status = -EIO; + if (ace->e_flags & + (RICHACE_SPECIAL_WHO | RICHACE_UNMAPPED_WHO)) + goto out; + ace->e_mask = be32_to_cpup(p++); + status = nfs4_decode_ace_who(ace, &unmapped, + &unmapped_len, server, + xdr); + if (status) + goto out; + if (unmapped) { + status = -ENOMEM; + if (richacl_add_unmapped_identifier(&acl, &ace, + unmapped, unmapped_len, + GFP_NOFS)) + goto out; + } + } + status = 0; + +out: + if (status) { + richacl_put(acl); + acl = ERR_PTR(status); + } + return acl; +} + static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs_getaclres *res) { unsigned int savep; uint32_t attrlen, bitmap[3] = {0}; + struct richacl *acl = NULL; int status; - unsigned int pg_offset; - res->acl_len = 0; if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0) - goto out; - - xdr_enter_page(xdr, xdr->buf->page_len); - - /* Calculate the offset of the page data */ - pg_offset = xdr->buf->head[0].iov_len; - + return status; if ((status = decode_attr_bitmap(xdr, bitmap)) != 0) - goto out; + return status; if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0) - goto out; + return status; if (unlikely(bitmap[0] & (FATTR4_WORD0_ACL - 1U))) return -EIO; if (likely(bitmap[0] & FATTR4_WORD0_ACL)) { - - /* The bitmap (xdr len + bitmaps) and the attr xdr len words - * are stored with the acl data to handle the problem of - * variable length bitmaps.*/ - res->acl_data_offset = xdr_stream_pos(xdr) - pg_offset; - res->acl_len = attrlen; - - /* Check for receive buffer overflow */ - if (res->acl_len > (xdr->nwords << 2) || - res->acl_len + res->acl_data_offset > xdr->buf->page_len) { - res->acl_flags |= NFS4_ACL_TRUNC; - dprintk("NFS: acl reply: attrlen %u > page_len %u\n", - attrlen, xdr->nwords << 2); - } + acl = decode_acl_entries(xdr, res->server); + if (IS_ERR(acl)) + return PTR_ERR(acl); + bitmap[0] &= ~FATTR4_WORD0_ACL; } else - status = -EOPNOTSUPP; + return -EOPNOTSUPP; + + status = -EIO; + if (unlikely(bitmap[0])) + goto out; + + status = decode_attr_mode(xdr, bitmap, &res->mode); + if (status < 0) + goto out; + status = 0; out: + if (status) + richacl_put(acl); + else + res->acl = acl; return status; } diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 383a027..8ced33d 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -2319,7 +2319,7 @@ void nfs_fill_super(struct super_block *sb, struct nfs_mount_info *mount_info) /* The VFS shouldn't apply the umask to mode bits. We will do * so ourselves when necessary. */ - sb->s_flags |= MS_POSIXACL; + sb->s_flags |= MS_RICHACL; sb->s_time_gran = 1; } @@ -2346,7 +2346,7 @@ void nfs_clone_super(struct super_block *sb, struct nfs_mount_info *mount_info) /* The VFS shouldn't apply the umask to mode bits. We will do * so ourselves when necessary. */ - sb->s_flags |= MS_POSIXACL; + sb->s_flags |= MS_RICHACL; } nfs_initialise_sb(sb); diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index c0e9614..b84e194 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -176,7 +176,6 @@ struct nfs_inode { wait_queue_head_t waitqueue; #if IS_ENABLED(CONFIG_NFS_V4) - struct nfs4_cached_acl *nfs4_acl; /* NFSv4 state */ struct list_head open_states; struct nfs_delegation __rcu *delegation; diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index c7d42b7..cb282e1 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -244,5 +244,7 @@ struct nfs_server { #define NFS_CAP_ALLOCATE (1U << 20) #define NFS_CAP_DEALLOCATE (1U << 21) #define NFS_CAP_LAYOUTSTATS (1U << 22) +#define NFS_CAP_ALLOW_ACLS (1U << 23) +#define NFS_CAP_DENY_ACLS (1U << 24) #endif diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 090ade4..337c341 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -683,9 +683,10 @@ struct nfs_setattrargs { struct nfs_setaclargs { struct nfs4_sequence_args seq_args; + const struct nfs_server * server; struct nfs_fh * fh; - size_t acl_len; struct page ** acl_pages; + size_t acl_len; }; struct nfs_setaclres { @@ -703,9 +704,9 @@ struct nfs_getaclargs { #define NFS4_ACL_TRUNC 0x0001 /* ACL was truncated */ struct nfs_getaclres { struct nfs4_sequence_res seq_res; - size_t acl_len; - size_t acl_data_offset; - int acl_flags; + const struct nfs_server * server; + struct richacl * acl; + umode_t mode; struct page * acl_scratch; }; -- 2.5.0 From agruenba@redhat.com Tue Nov 3 09:23:33 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 9AC6129EA4 for ; Tue, 3 Nov 2015 09:23:33 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 87E74304039 for ; Tue, 3 Nov 2015 07:23:33 -0800 (PST) X-ASG-Debug-ID: 1446564212-04cbb0660e1f7e70001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id IN4x5z3T0eaM6YPr (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:23:32 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id E818914CACB; Tue, 3 Nov 2015 15:23:31 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-101.ams2.redhat.com [10.36.5.101]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FHRaH029477; Tue, 3 Nov 2015 10:23:25 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v13 51/51] nfs: Add support for the v4.1 dacl attribute Date: Tue, 3 Nov 2015 16:17:27 +0100 X-ASG-Orig-Subj: [PATCH v13 51/51] nfs: Add support for the v4.1 dacl attribute Message-Id: <1446563847-14005-52-git-send-email-agruenba@redhat.com> In-Reply-To: <1446563847-14005-1-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@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: 1446564212 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 The dacl attribute includes Automatic Inheritance flags not supported by the acl attribute. it is only supported in NFS version 4.1 and higher. On systems where NFS version 4.0 is still the default, an additional mount option is needed: mount -t nfs4 -o vers=4.1 [...] Signed-off-by: Andreas Gruenbacher --- fs/nfs/nfs4proc.c | 2 +- fs/nfs/nfs4xdr.c | 54 ++++++++++++++++++++++++++++++++++++++++++------- include/linux/nfs_xdr.h | 2 +- 3 files changed, 49 insertions(+), 9 deletions(-) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 7bb2dea..191369f 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -4556,7 +4556,7 @@ static struct richacl *__nfs4_get_acl_uncached(struct inode *inode) struct nfs_server *server = NFS_SERVER(inode); struct page *pages[DIV_ROUND_UP(NFS4ACL_SIZE_MAX, PAGE_SIZE)] = {}; struct nfs_getaclargs args = { - .fh = NFS_FH(inode), + .inode = inode, .acl_pages = pages, .acl_len = ARRAY_SIZE(pages) * PAGE_SIZE, }; diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 2f1d6be..a73f7c6 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -1661,9 +1661,16 @@ encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg, struct compoun encode_nfs4_stateid(xdr, &zero_stateid); /* Encode attribute bitmap. */ - p = reserve_space(xdr, 2*4); - *p++ = cpu_to_be32(1); - *p = cpu_to_be32(FATTR4_WORD0_ACL); + if (arg->server->attr_bitmask[1] & FATTR4_WORD1_DACL) { + p = reserve_space(xdr, 3*4); + *p++ = cpu_to_be32(2); + *p++ = 0; + *p = cpu_to_be32(FATTR4_WORD1_DACL); + } else { + p = reserve_space(xdr, 2*4); + *p++ = cpu_to_be32(1); + *p = cpu_to_be32(FATTR4_WORD0_ACL); + } attrlen_offset = xdr->buf->len; xdr_reserve_space(xdr, 4); /* to be backfilled later */ @@ -2498,9 +2505,12 @@ static void nfs4_xdr_enc_getacl(struct rpc_rqst *req, struct xdr_stream *xdr, encode_compound_hdr(xdr, req, &hdr); encode_sequence(xdr, &args->seq_args, &hdr); - encode_putfh(xdr, args->fh, &hdr); + encode_putfh(xdr, NFS_FH(args->inode), &hdr); replen = hdr.replen + op_decode_hdr_maxsz + 1; - encode_getattr_two(xdr, FATTR4_WORD0_ACL, FATTR4_WORD1_MODE, &hdr); + if (NFS_SERVER(args->inode)->attr_bitmask[1] & FATTR4_WORD1_DACL) + encode_getattr_two(xdr, 0, FATTR4_WORD1_MODE | FATTR4_WORD1_DACL, &hdr); + else + encode_getattr_two(xdr, FATTR4_WORD0_ACL, FATTR4_WORD1_MODE, &hdr); xdr_inline_pages(&req->rq_rcv_buf, replen << 2, args->acl_pages, 0, args->acl_len); @@ -5402,12 +5412,25 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req, if (unlikely(bitmap[0] & (FATTR4_WORD0_ACL - 1U))) return -EIO; - if (likely(bitmap[0] & FATTR4_WORD0_ACL)) { + + if (bitmap[0] & FATTR4_WORD0_ACL) { + struct richace *ace; + + if (bitmap[1] & FATTR4_WORD1_DACL) + return -EIO; + acl = decode_acl_entries(xdr, res->server); if (IS_ERR(acl)) return PTR_ERR(acl); + + status = -EIO; + richacl_for_each_entry(ace, acl) { + if (ace->e_flags & RICHACE_INHERITED_ACE) + goto out; + } + bitmap[0] &= ~FATTR4_WORD0_ACL; - } else + } else if (!(bitmap[1] & FATTR4_WORD1_DACL)) return -EOPNOTSUPP; status = -EIO; @@ -5417,6 +5440,23 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req, status = decode_attr_mode(xdr, bitmap, &res->mode); if (status < 0) goto out; + + if (bitmap[1] & FATTR4_WORD1_DACL) { + unsigned int flags; + __be32 *p; + + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) + return -EIO; + flags = be32_to_cpup(p); + + acl = decode_acl_entries(xdr, res->server); + if (IS_ERR(acl)) + return PTR_ERR(acl); + + acl->a_flags = flags; + bitmap[1] &= ~FATTR4_WORD1_DACL; + } status = 0; out: diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 337c341..9c2a078 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -695,7 +695,7 @@ struct nfs_setaclres { struct nfs_getaclargs { struct nfs4_sequence_args seq_args; - struct nfs_fh * fh; + struct inode * inode; size_t acl_len; struct page ** acl_pages; }; -- 2.5.0 From bfoster@redhat.com Tue Nov 3 09:31:33 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 B9B7029E10 for ; Tue, 3 Nov 2015 09:31:33 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id A6462304043 for ; Tue, 3 Nov 2015 07:31:33 -0800 (PST) X-ASG-Debug-ID: 1446564692-04cbb0660e1f82c0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id m6zEspFvQSkVN0la (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 07:31:32 -0800 (PST) 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 (Postfix) with ESMTPS id E3D3E811D9; Tue, 3 Nov 2015 15:31:31 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-105.bos.redhat.com [10.18.41.105]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3FVV26007401; Tue, 3 Nov 2015 10:31:31 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id 7CB1F1201AB; Tue, 3 Nov 2015 10:31:30 -0500 (EST) Date: Tue, 3 Nov 2015 10:31:30 -0500 From: Brian Foster To: hoper Cc: xfs@oss.sgi.com Subject: Re: On-disk data for XFS_DINNODE_FMT_EXTENTS Message-ID: <20151103153130.GC24445@bfoster.bfoster> X-ASG-Orig-Subj: Re: On-disk data for XFS_DINNODE_FMT_EXTENTS References: <436040866.262250269.1446544069841.JavaMail.root@zimbra84-e15.priv.proxad.net> <752500470.262252528.1446544133651.JavaMail.root@zimbra84-e15.priv.proxad.net> <20151103135026.GB24445@bfoster.bfoster> <7cfd3332920888f89d44df4dae08a9ed@hoper.dnsalias.net> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <7cfd3332920888f89d44df4dae08a9ed@hoper.dnsalias.net> 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: 1446564692 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 cc xfs On Tue, Nov 03, 2015 at 03:58:32PM +0100, hoper wrote: > Le 2015-11-03 14:50, Brian Foster a écrit : > >On Tue, Nov 03, 2015 at 10:48:53AM +0100, hoper@free.fr wrote: > >>Hi, > >> > >>I'm trying to understand how xfs is storing informations, > >>but I guess that my documentation "XFS Filesystem Structure > >>2nd Edition Revision 2" is quite outdated :( > >> > >>I made an XFS filesystem, then made 60 files in /. > >> > >># xfs_db -f /root/small > >>xfs_db> inode 128 > >>xfs_db> addr > >>current > >> byte offset 32768, length 256 > >> buffer block 64 (fsbno 8), 8 bbs > >> inode 128, dir inode 128, type inode > >>xfs_db> p > >>core.magic = 0x494e > >>core.mode = 040755 > >>core.version = 2 > >>core.format = 2 (extents) > >>[...] > >>next_unlinked = null > >>u.bmx[0] = [startoff,startblock,blockcount,extentflag] 0:[0,12,1,0] > >> > >>I made a small script in python which retrieve all theses information > >>from disk, > >>except the "12" (location of the X2DB block = 12*4096). From the manual, > >>and my > >>understanding, this information, 12, should be found just next the > >>di_unlinked. > >>(page 43 on the manual). But from an hex editor, from addr 32768, I got > >>this : > >> > >>49 4E 41 ED 02 02 00 00 00 00 00 00 00 00 00 00 00 00 00 02 00 00 00 00 > >>00 00 00 00 00 00 00 01 > >>56 37 5D 71 2D 26 3D 0B 56 37 5D 6C 02 78 F1 EC 56 37 5D 6C 02 78 F1 EC > >>00 00 00 00 00 00 10 00 > >>00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00 02 00 00 00 00 > >>00 00 00 00 00 00 00 00 > >>FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 01 80 00 01 00 00 00 00 > >>00 00 00 00 00 00 00 00 > >> > >>First, 49 4E (IN) that's the beginning of the inode core (96 bytes). All > >>informations are here, > >>and match the output of xfs_db. But after next_unlinked (FF FF FF FF > >>here), and until next IN, > >>I can't find any 12 :( Where is it ? > >> > > > >The extent information is encoded in a format that's not easily > >interpreted from a raw hex dump. See xfs_iformat_extents() to start: > > > > dp = (xfs_bmbt_rec_t *) XFS_DFORK_PTR(dip, whichfork); > > xfs_validate_extents(ifp, nex, XFS_EXTFMT_INODE(ip)); > > for (i = 0; i < nex; i++, dp++) { > > xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, > >i); > > ep->l0 = get_unaligned_be64(&dp->l0); > > ep->l1 = get_unaligned_be64(&dp->l1); > > } > > > >So we start after di_next_unlinked and read in two 64-bit, big endian > >fields. That data in your dump above is: > > > >l0: 0x0000000000000000 > >l1: 0x0000000001800001 > > > >Then, these 64-bit fields have a special encoding themselves to map to > >actual extent data. From xfs_format.h: > > > >/* > > * Bmap btree record and extent descriptor. > > * l0:63 is an extent flag (value 1 indicates non-normal). > > * l0:9-62 are startoff. > > * l0:0-8 and l1:21-63 are startblock. > > * l1:0-20 are blockcount. > > */ > > > >We see that l0 is completely zeroed, so we can infer that this is a > >normal extent and startoff is zero. The block count is l1:0-20, which is > >00001b or 1. The start block is (((l0 & 0x1FF) << 43) | (l1 >> 21)), > >which is: > > > > ((0x0 & 0x1FF) << 43) | (0x1800001 >> 21) > > 0x0 | 0xC > > = 0xC == 12 > > > >See __xfs_bmbt_get_all() for the code that implements this decoding. > > > >Brian > > > A perfect answer. Thank you very much. > > By the way, is there, by any chance, a new version of the manual I was > looking at ? > Because I didn't saw theses informations in it... And a good doc is far more > readable > for me than source code :) > > No, the manual is somewhat out of date. That said, many of the fundamental bits are unchanged. The following from the existing guide covers the extent list inode format and actually does describe the extent record encoding as well (see the first diagram): http://xfs.org/docs/xfsdocs-xml-dev/XFS_Filesystem_Structure//tmp/en-US/html/Data_Extents.html Brian From andreas.gruenbacher@gmail.com Tue Nov 3 09:54:36 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 D14F97F83 for ; Tue, 3 Nov 2015 09:54:36 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 67570AC009 for ; Tue, 3 Nov 2015 07:54:36 -0800 (PST) X-ASG-Debug-ID: 1446566073-04bdf0330b1fdba0001-NocioJ Received: from mail-wm0-f44.google.com (mail-wm0-f44.google.com [74.125.82.44]) by cuda.sgi.com with ESMTP id Y0otDbu1Xc7Zf3Yf (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 03 Nov 2015 07:54:34 -0800 (PST) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 74.125.82.44 Received: by wmec75 with SMTP id c75so90220673wme.1 for ; Tue, 03 Nov 2015 07:54:33 -0800 (PST) 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=ERJpf6nT/nkADFW2N7MPn/Of2TMm8rrwl9J3yNmTJi8=; b=JTDzOFcH1HM5My/qQMiuMPTlJeoDc8yyRFCvjTqzvZwI9uj/BYRDBft81aEg72X2Vo GXhRyyDNPwSPRIN/6gXjQO1XMvTi31tJ0h2qcZg/422rmQW+nb3SPb6f+jPb63lFLSj2 9DI5bg2wvzlGklQrfYEi51mBaL801ZInl1ZRzw9OjrNWGFx8xqn+uE+PUM42yBGHwiSU BzR77hMG0CmTReHFJG/WkV86AKtiLtC16TM/KMdmAWV5XJyBU96KREQsg9rt+LPF7Egv P1K8OTwQRiYJk9V3Xrwvjj5M7qu2m1e36sAznB55b10P9RaKEKRUL1A/uY96SMJxY/eI zMAQ== MIME-Version: 1.0 X-Received: by 10.28.131.84 with SMTP id f81mr19395290wmd.57.1446566073066; Tue, 03 Nov 2015 07:54:33 -0800 (PST) Received: by 10.27.11.17 with HTTP; Tue, 3 Nov 2015 07:54:33 -0800 (PST) In-Reply-To: <4425824.kIWhRaBxBZ@wuerfel> References: <4425824.kIWhRaBxBZ@wuerfel> Date: Tue, 3 Nov 2015 16:54:33 +0100 Message-ID: Subject: Re: [PATCH] xfs: only modify ACLs if CONFIG_XFS_POSIX_ACL enabled From: =?UTF-8?Q?Andreas_Gr=C3=BCnbacher?= X-ASG-Orig-Subj: Re: [PATCH] xfs: only modify ACLs if CONFIG_XFS_POSIX_ACL enabled To: Arnd Bergmann Cc: Dave Chinner , Dave Chinner , Brian Foster , Andreas Gruenbacher , xfs@oss.sgi.com, Linux Kernel Mailing List , linux-arm-kernel@lists.infradead.org Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-wm0-f44.google.com[74.125.82.44] X-Barracuda-Start-Time: 1446566074 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24071 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 Arnd, 2015-11-03 14:43 GMT+01:00 Arnd Bergmann : > A recent bug fix added a call to forget_cached_acl(), but that > function is not always available, so we can get a build error > here [...] didn't expect anybody to trip over this anytime soon... I've sent a fix yesterday, http://oss.sgi.com/archives/xfs/2015-11/msg00028.html and Dave has already fixed it in for-next: git//git.kernel.org/pub/scm/linux/kernel/git/dgc/linux-xfs.git Thanks, Andreas From trond.myklebust@primarydata.com Tue Nov 3 10:25:52 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 558217CBF for ; Tue, 3 Nov 2015 10:25:52 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 4481A8F8033 for ; Tue, 3 Nov 2015 08:25:49 -0800 (PST) X-ASG-Debug-ID: 1446567946-04cbb0660c1f9db0001-NocioJ Received: from mail-oi0-f48.google.com (mail-oi0-f48.google.com [209.85.218.48]) by cuda.sgi.com with ESMTP id EbnA4N6TurSdaS1B (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 03 Nov 2015 08:25:46 -0800 (PST) X-Barracuda-Envelope-From: trond.myklebust@primarydata.com X-Barracuda-Apparent-Source-IP: 209.85.218.48 Received: by oiad129 with SMTP id d129so11703115oia.0 for ; Tue, 03 Nov 2015 08:25:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=primarydata_com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=dLaT4nvAJq5p3EA2H/rcBJTFSLruL20tLhtHHkml+o8=; b=bleB/9fi6qr7N5fzWEVpaWLzTk7QsB7C8WA+AtOzLjE+XL4h2fGmMpq6CUwVd4vVTN y9wvKi3vFmm/BJWfy8FREaAaRyz1ZTRLVY6ySTh78+r+WlOzc2ET3NK5bTNkNqXDMt1i xJPTqWA/vY/UtyATjuFJVvzVoZl6pGxQEA/vCHLnCzetYBJwWKURCD6tjtygKOMETl4g EIN6CbgVhG4sNo60EHQLRxuJCWT+1UEj9KvGNcdo+Ik4n2RPpdHfPZ/JJVrbAWxA+yL1 R6bhJNEXPPE9eqEPPexpZsRxvLhPiSWoKBVnotEAosXhI0vZ5rIF8fE9e0f28W+zSINK pOKw== 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=dLaT4nvAJq5p3EA2H/rcBJTFSLruL20tLhtHHkml+o8=; b=m6xZpVFToWJ+GkaKcScsIBhbM0W/cEDGefUt6P+oHqjxGp+tiwd8QYQwBsCV8xnYFa Yd8A5qsxqDh2XSvdf7yDDZCUOGWwPd+v3EIcqbU/YUwOxSXwW4ntw0tUXWKoGWgMLVtI /w2uxzvKwVcmHmOzo0LEnCXzXtXfhY6Yu/1CjYihKYYFLGDE9/X74rYku6pmwKlp9cHF vUVM+dBGi/tO4lOFjvyjJYIBpxYuKX/v5pAmg/ibq/JM8cohg7gaUh8QdjnMlUIBzvof g6okgooQK+viX2AAF1YTi0XqXyCh9sG73y4ewGcPU0T7ANy5iy472M8s1TDE2xma3q/w Pyzw== X-Gm-Message-State: ALoCoQmv/atQ2y5WzgY9wHzNE3dpQmRBiDrBh8uibHpQSCUCnpCsCUIrforklvjZL8a/LLdN5ADh MIME-Version: 1.0 X-Received: by 10.202.84.209 with SMTP id i200mr18207922oib.133.1446567946326; Tue, 03 Nov 2015 08:25:46 -0800 (PST) Received: by 10.202.95.7 with HTTP; Tue, 3 Nov 2015 08:25:46 -0800 (PST) In-Reply-To: <1446563847-14005-46-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@redhat.com> <1446563847-14005-46-git-send-email-agruenba@redhat.com> Date: Tue, 3 Nov 2015 11:25:46 -0500 Message-ID: Subject: Re: [PATCH v13 45/51] sunrpc: Allow to demand-allocate pages to encode into From: Trond Myklebust X-ASG-Orig-Subj: Re: [PATCH v13 45/51] sunrpc: Allow to demand-allocate pages to encode into To: Andreas Gruenbacher Cc: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, Linux Kernel Mailing List , Linux FS-devel Mailing List , Linux NFS Mailing List , linux-cifs@vger.kernel.org, Linux API Mailing List Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-oi0-f48.google.com[209.85.218.48] X-Barracuda-Start-Time: 1446567946 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24071 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 Tue, Nov 3, 2015 at 10:17 AM, Andreas Gruenbacher wrote: > When encoding large, variable-length objects such as acls into xdr_bufs, > it is easier to allocate buffer pages on demand rather than precomputing > the required buffer size. > NACK. We're not doing allocations from inside the XDR encoders. This can and should be done before calling into the SUNRPC layer. Trond From trond.myklebust@primarydata.com Tue Nov 3 10:30:21 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 71A0F7F52 for ; Tue, 3 Nov 2015 10:30:21 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 40FBD304053 for ; Tue, 3 Nov 2015 08:30:21 -0800 (PST) X-ASG-Debug-ID: 1446568219-04cbb0660c1f9fb0001-NocioJ Received: from mail-ob0-f182.google.com (mail-ob0-f182.google.com [209.85.214.182]) by cuda.sgi.com with ESMTP id 7dEvidaimXAyDl94 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 03 Nov 2015 08:30:19 -0800 (PST) X-Barracuda-Envelope-From: trond.myklebust@primarydata.com X-Barracuda-Apparent-Source-IP: 209.85.214.182 Received: by obbza9 with SMTP id za9so16461064obb.1 for ; Tue, 03 Nov 2015 08:30:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=primarydata_com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=U64E7QOXNzcwkzcKfmchTrKOXLmtgJiwpT/4AGbI4ZA=; b=AKR9hJTqyi+092ibQAOvuhojo81edO6wT3MLMWU+u/hzCkxhVm6EIpwgXBW/usz5E6 gpXwPFoxx7B4mvbPezU1p9bGOuFRjkmZbBeOuL2pBAM3v0BtJRRtbpHNcwKbvpwRdqIP 2eM723vnlyfedWG9oCyrfN218QwPmPkpOdOr28KMpI/tChQdISUSdche9q1i8gRTU91Z tpRrAY9AvP86KKxdIyFLyBlIDmpu2MY+QpuShNVM4gDYcP8CGEXoeYfLi8+jlMhmJpQ5 x+zge8ayaB4pCvSD+53YWPg3bNkYxBJsfVVRBqpS/G3x0mB4nVnqFVOvAAOtwHEhYrn/ LyJg== 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=U64E7QOXNzcwkzcKfmchTrKOXLmtgJiwpT/4AGbI4ZA=; b=YSLzbAqnJYQm+5Z2DvwGUwl7ZMZd4GPuYE8JWN6yF7Y4ObFYevafJfUYJyKX7VMjSS XWkFIWFtMpPkg6w1Lb0Z+nDCEYhKKT2LUVaYeyShA8LrzLk5HzyQ4XE3cvik0hZh5W0X 69GHQKrIbsY2b9aQCQiaKgwHH/RPFJKaKOU0x/z9+5GPrrWWeTWPzlJ1ECF4Wr+ud2Rm 23qUdrpn0iPY7vkTVUvdPZ2Y3L3CSdy8vUuLx6kOseOZxipl8fWTvqV7K4CbIjw+Nl0U u2ZKn0IS2NdlNzYcY/cN78/3JYMbr+Yzk7EszrE3minyMiKOAJ9tpZvUSWlVf1yTVCNl VqDg== X-Gm-Message-State: ALoCoQmHEdscAJheBwttOnmszncEJ51eJ48jMNieBsGP1H8qG/rsZQAAt3JuRYSg97q5sYEV5R+n MIME-Version: 1.0 X-Received: by 10.60.76.42 with SMTP id h10mr18575492oew.13.1446568219404; Tue, 03 Nov 2015 08:30:19 -0800 (PST) Received: by 10.202.95.7 with HTTP; Tue, 3 Nov 2015 08:30:19 -0800 (PST) In-Reply-To: <1446563847-14005-48-git-send-email-agruenba@redhat.com> References: <1446563847-14005-1-git-send-email-agruenba@redhat.com> <1446563847-14005-48-git-send-email-agruenba@redhat.com> Date: Tue, 3 Nov 2015 11:30:19 -0500 Message-ID: Subject: Re: [PATCH v13 47/51] nfs: Fix GETATTR bitmap verification From: Trond Myklebust X-ASG-Orig-Subj: Re: [PATCH v13 47/51] nfs: Fix GETATTR bitmap verification To: Andreas Gruenbacher Cc: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, Linux Kernel Mailing List , Linux FS-devel Mailing List , Linux NFS Mailing List , linux-cifs@vger.kernel.org, Linux API Mailing List Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-ob0-f182.google.com[209.85.214.182] X-Barracuda-Start-Time: 1446568219 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24071 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 Tue, Nov 3, 2015 at 10:17 AM, Andreas Gruenbacher wrote: > When decoding GETATTR replies, the client checks the attribute bitmap > for which attributes the server has sent. It misses bits at the word > boundaries, though; fix that. > > Signed-off-by: Andreas Gruenbacher > --- > fs/nfs/nfs4xdr.c | 23 +++++++++++++++++++++++ > 1 file changed, 23 insertions(+) > > diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c > index 788adf3..6f6d921 100644 > --- a/fs/nfs/nfs4xdr.c > +++ b/fs/nfs/nfs4xdr.c > @@ -4375,6 +4375,11 @@ static int decode_statfs(struct xdr_stream *xdr, struct nfs_fsstat *fsstat) > goto xdr_error; > if ((status = decode_attr_files_total(xdr, bitmap, &fsstat->tfiles)) != 0) > goto xdr_error; > + > + status = -EIO; > + if (unlikely(bitmap[0])) > + goto xdr_error; > + > if ((status = decode_attr_space_avail(xdr, bitmap, &fsstat->abytes)) != 0) > goto xdr_error; > if ((status = decode_attr_space_free(xdr, bitmap, &fsstat->fbytes)) != 0) > @@ -4574,6 +4579,10 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap, > goto xdr_error; > fattr->valid |= status; > > + status = -EIO; > + if (unlikely(bitmap[0])) > + goto xdr_error; > + > status = decode_attr_mode(xdr, bitmap, &fmode); > if (status < 0) > goto xdr_error; > @@ -4627,6 +4636,10 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap, > goto xdr_error; > fattr->valid |= status; > > + status = -EIO; > + if (unlikely(bitmap[1])) > + goto xdr_error; > + > status = decode_attr_mdsthreshold(xdr, bitmap, fattr->mdsthreshold); > if (status < 0) > goto xdr_error; > @@ -4789,12 +4802,22 @@ static int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo) > if ((status = decode_attr_maxwrite(xdr, bitmap, &fsinfo->wtmax)) != 0) > goto xdr_error; > fsinfo->wtpref = fsinfo->wtmax; > + > + status = -EIO; > + if (unlikely(bitmap[0])) > + goto xdr_error; > + > status = decode_attr_time_delta(xdr, bitmap, &fsinfo->time_delta); > if (status != 0) > goto xdr_error; > status = decode_attr_pnfstype(xdr, bitmap, &fsinfo->layouttype); > if (status != 0) > goto xdr_error; > + > + status = -EIO; > + if (unlikely(bitmap[1])) > + goto xdr_error; > + > status = decode_attr_layout_blksize(xdr, bitmap, &fsinfo->blksize); > if (status) > goto xdr_error; > -- > 2.5.0 This patch can and should be merged separately from this patchset. Please submit it through the usual channels. Trond From david@fromorbit.com Tue Nov 3 13:11:55 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 A02A87FCB for ; Tue, 3 Nov 2015 13:11:55 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 92215304039 for ; Tue, 3 Nov 2015 11:11:52 -0800 (PST) X-ASG-Debug-ID: 1446577905-04cbb02422011a0001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id 2XU197AnpfKRWE9u for ; Tue, 03 Nov 2015 11:11:46 -0800 (PST) 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: A2C5BgAjBjlW/+rW03ZegztTb6pNAQEGiy6JKyGFbAQCAoFBTQEBAQEBAYELhDYBAQQ6HCMQCAMOCgklDwUlAyETiC0OwgUBAQEBAQUBAQEBAQEdGYV1hUWCcYUzgRQFlkaFHYd9nEZjghEdgWoqNAGFMwEBAQ Received: from ppp118-211-214-234.lns20.syd4.internode.on.net (HELO dastard) ([118.211.214.234]) by ipmail07.adl2.internode.on.net with ESMTP; 04 Nov 2015 05:41:44 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZtgzU-0005cZ-9B; Wed, 04 Nov 2015 06:11:32 +1100 Date: Wed, 4 Nov 2015 06:11:32 +1100 From: Dave Chinner To: Michael Weissenbacher Cc: xfs@oss.sgi.com Subject: Re: Is it possible to change sunit of log section post-mkfs Message-ID: <20151103191132.GD19199@dastard> X-ASG-Orig-Subj: Re: Is it possible to change sunit of log section post-mkfs References: <5638A62D.1020802@dermichi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <5638A62D.1020802@dermichi.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: 1446577906 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24076 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Tue, Nov 03, 2015 at 01:18:53PM +0100, Michael Weissenbacher wrote: > Hi! > I have a XFS file system which lies on a 10-disk RAID-6 device that was > created with Chunk Size = 1MiB. > On mkfs.xfs time this was - as far as i know - specified with "-d > su=1m,sw=8". > > xfs_info shows the following: > meta-data=/dev/sdb1 isize=256 agcount=15, > agsize=268435200 blks > = sectsz=512 attr=2 > data = bsize=4096 blocks=3905945088, imaxpct=5 > = sunit=256 swidth=2048 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 > > Interestingly, the sunit value of the log seems to be incorrect - as it > should be 256 too, like the sunit value of the data. I am pretty sure > the reason is that the log sunit cannot be 256 blks (=1024KiB) and > because of this mkfs.xfs did fall back to the default of 8 blks > (=32KiB). I found evidence of this in the following thread: > http://oss.sgi.com/archives/xfs/2012-06/msg00431.html > > What i want to achieve is to set the log sunit to the maximum possible > of 64 blks (=256KiB). Why? Is there a performance problem with the default setting? Cheers, Dave. -- Dave Chinner david@fromorbit.com From mw@dermichi.com Tue Nov 3 13:22:48 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 216A17FCC for ; Tue, 3 Nov 2015 13:22:48 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 025E38F8049 for ; Tue, 3 Nov 2015 11:22:44 -0800 (PST) X-ASG-Debug-ID: 1446578557-04bdf03f0401580001-NocioJ Received: from firestarter.dermichi.com (firestarter.dermichi.com [194.177.153.153]) by cuda.sgi.com with ESMTP id F5oDVXRiOEcmSVPI (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 11:22:38 -0800 (PST) X-Barracuda-Envelope-From: mw@dermichi.com X-Barracuda-Apparent-Source-IP: 194.177.153.153 Received: from 191-159-177-194.static.net4you.net ([194.177.159.191] helo=[192.168.17.108]) by firestarter.dermichi.com with esmtpsa (TLSv1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim) (envelope-from ) id 1ZthAC-0004WC-8f; Tue, 03 Nov 2015 20:22:36 +0100 Subject: Re: Is it possible to change sunit of log section post-mkfs To: Brian Foster X-ASG-Orig-Subj: Re: Is it possible to change sunit of log section post-mkfs References: <5638A62D.1020802@dermichi.com> <20151103130246.GA24445@bfoster.bfoster> Cc: xfs@oss.sgi.com From: Michael Weissenbacher Message-ID: <56390979.2090509@dermichi.com> Date: Tue, 3 Nov 2015 20:22:33 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <20151103130246.GA24445@bfoster.bfoster> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: firestarter.dermichi.com[194.177.153.153] X-Barracuda-Start-Time: 1446578558 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24078 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Hi Brian! On 2015-11-03 14:02, Brian Foster wrote: > I don't believe there's any supported way to do this. Well, at least i didn't miss anything in the documentation :-) On 2015-11-03 14:02, Brian Foster wrote: > Out of curiosity, > I just tried an experiment to modify the superblock logsunit via xfs_db > and run repair to zero the log. That seemed to work in terms of taking > effect on the subsequent mount, but that's certainly not something I > would suggest to do in production. Ok, so it would definitely be too risky for a production system. On 2015-11-03 14:02, Brian Foster wrote: > Note that mkfs aligns the physical > log based on the stripe unit as well, so it wouldn't really have the > same effect anyways. TBH, i didn't quite understand that part :-) Are you saying, even if i would modify the log's sunit size using xfs_db, it would still not be aligned correctly? thanks, Michael From mw@dermichi.com Tue Nov 3 13:32:27 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 ECEB27FCD for ; Tue, 3 Nov 2015 13:32:26 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 71244AC002 for ; Tue, 3 Nov 2015 11:32:20 -0800 (PST) X-ASG-Debug-ID: 1446579137-04cbb0242301850001-NocioJ Received: from firestarter.dermichi.com (firestarter.dermichi.com [194.177.153.153]) by cuda.sgi.com with ESMTP id 2UK82EkayX2gnIoe (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 11:32:18 -0800 (PST) X-Barracuda-Envelope-From: mw@dermichi.com X-Barracuda-Apparent-Source-IP: 194.177.153.153 Received: from 191-159-177-194.static.net4you.net ([194.177.159.191] helo=[192.168.17.108]) by firestarter.dermichi.com with esmtpsa (TLSv1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim) (envelope-from ) id 1ZthJY-0004tn-Fb; Tue, 03 Nov 2015 20:32:16 +0100 Subject: Re: Is it possible to change sunit of log section post-mkfs To: Dave Chinner X-ASG-Orig-Subj: Re: Is it possible to change sunit of log section post-mkfs References: <5638A62D.1020802@dermichi.com> <20151103191132.GD19199@dastard> Cc: xfs@oss.sgi.com From: Michael Weissenbacher X-Enigmail-Draft-Status: N1010 Message-ID: <56390BBE.6030102@dermichi.com> Date: Tue, 3 Nov 2015 20:32:14 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <20151103191132.GD19199@dastard> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 8bit X-Barracuda-Connect: firestarter.dermichi.com[194.177.153.153] X-Barracuda-Start-Time: 1446579137 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24077 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Hi Dave! >> >> What i want to achieve is to set the log sunit to the maximum possible >> of 64 blks (=256KiB). On 2015-11-03 20:11, Dave Chinner wrote: > > Why? Is there a performance problem with the default setting? > I am seeing very bad performance of "rm" on this file system. Of course I know that RAID-6 is kind of a worst case setup for that workload. But I was hoping that aligning the log correctly plus increasing the stripe size would help. Wouldn't the file system write more of the log at once with a bigger sunit size; resulting in fewer RMW cycles? I am already using delaylog, inode64, nobarrier to mount the fs; lazy-count=1. Maybe moving to an external log would be the best option? tia, Michael From bfoster@redhat.com Tue Nov 3 13:39:52 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 43AB37FAE for ; Tue, 3 Nov 2015 13:39:52 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 1452330404E for ; Tue, 3 Nov 2015 11:39:51 -0800 (PST) X-ASG-Debug-ID: 1446579590-04bdf03f0301b30001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id sGbao05d9SiMccVu (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 11:39:50 -0800 (PST) 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 (Postfix) with ESMTPS id 5BB36C100441; Tue, 3 Nov 2015 19:39:50 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-105.bos.redhat.com [10.18.41.105]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3JdoZI016970; Tue, 3 Nov 2015 14:39:50 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id B67CF1201AB; Tue, 3 Nov 2015 14:39:48 -0500 (EST) Date: Tue, 3 Nov 2015 14:39:48 -0500 From: Brian Foster To: Michael Weissenbacher Cc: xfs@oss.sgi.com Subject: Re: Is it possible to change sunit of log section post-mkfs Message-ID: <20151103193948.GD24445@bfoster.bfoster> X-ASG-Orig-Subj: Re: Is it possible to change sunit of log section post-mkfs References: <5638A62D.1020802@dermichi.com> <20151103130246.GA24445@bfoster.bfoster> <56390979.2090509@dermichi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <56390979.2090509@dermichi.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: 1446579590 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Tue, Nov 03, 2015 at 08:22:33PM +0100, Michael Weissenbacher wrote: > Hi Brian! > > On 2015-11-03 14:02, Brian Foster wrote: > > I don't believe there's any supported way to do this. > Well, at least i didn't miss anything in the documentation :-) > > On 2015-11-03 14:02, Brian Foster wrote: > > Out of curiosity, > > I just tried an experiment to modify the superblock logsunit via xfs_db > > and run repair to zero the log. That seemed to work in terms of taking > > effect on the subsequent mount, but that's certainly not something I > > would suggest to do in production. > Ok, so it would definitely be too risky for a production system. > > On 2015-11-03 14:02, Brian Foster wrote: > > Note that mkfs aligns the physical > > log based on the stripe unit as well, so it wouldn't really have the > > same effect anyways. > TBH, i didn't quite understand that part :-) > Are you saying, even if i would modify the log's sunit size using > xfs_db, it would still not be aligned correctly? > Yes, exactly. mkfs uses the log stripe unit to decide where to put the log on disk. If the log itself is not aligned, then there's little use in aligning the writes to the log. Brian > thanks, > Michael > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From david@fromorbit.com Tue Nov 3 13:48:55 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 6623E7FCB for ; Tue, 3 Nov 2015 13:48:55 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 0C33FAC005 for ; Tue, 3 Nov 2015 11:48:51 -0800 (PST) X-ASG-Debug-ID: 1446580128-04bdf03f0201e00001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id mB8MEJG449veBnkA for ; Tue, 03 Nov 2015 11:48:49 -0800 (PST) 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: A2C2BgAWDjlW/+rW03ZegzuBQqpNAQEGiy6JK4YNBAICgUFNAQEBAQEBgQuENQEBAQMBOhwjBQsIAw4KCSUPBSUDIROIJgfCJgEBAQEGAgEgGYV1hUWENINwgRQFlkaNGoFih2OTAWOCER2Baio0g2qBSgEBAQ Received: from ppp118-211-214-234.lns20.syd4.internode.on.net (HELO dastard) ([118.211.214.234]) by ipmail07.adl2.internode.on.net with ESMTP; 04 Nov 2015 06:18:48 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZthZL-0005gj-Ms; Wed, 04 Nov 2015 06:48:35 +1100 Date: Wed, 4 Nov 2015 06:48:35 +1100 From: Dave Chinner To: Michael Weissenbacher Cc: xfs@oss.sgi.com Subject: Re: Is it possible to change sunit of log section post-mkfs Message-ID: <20151103194835.GE19199@dastard> X-ASG-Orig-Subj: Re: Is it possible to change sunit of log section post-mkfs References: <5638A62D.1020802@dermichi.com> <20151103191132.GD19199@dastard> <56390BBE.6030102@dermichi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <56390BBE.6030102@dermichi.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: 1446580128 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24078 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Tue, Nov 03, 2015 at 08:32:14PM +0100, Michael Weissenbacher wrote: > Hi Dave! > > >> > >> What i want to achieve is to set the log sunit to the maximum possible > >> of 64 blks (=256KiB). > On 2015-11-03 20:11, Dave Chinner wrote: > > > > Why? Is there a performance problem with the default setting? > > > I am seeing very bad performance of "rm" on this file system. Of course > I know that RAID-6 is kind of a worst case setup for that workload. But > I was hoping that aligning the log correctly plus increasing the stripe > size would help. Wouldn't the file system write more of the log at once > with a bigger sunit size; resulting in fewer RMW cycles? "rm is slow" could be many, many thingsr. Generally rm is limited by directory/inode read speed, not log IO. You need to find out exactly what is "slow" in rm before going knob twiddling. Is there iowait time? If so, what IO is generating the iowait? Is rm CPU bound? Is the log sleeping waiting for buffer space? is the log tail pushing? etc, etc. > I am already using delaylog, inode64, nobarrier to mount the fs; > lazy-count=1. IOWs, the defaults. > Maybe moving to an external log would be the best option? You haven't even determined that there's a problem with the log yet. Twiddling knobs does not solve problems. Analyse the problem first, understand where the "slowness" is coming from, and that understanding will tell you is there's a knob that you can twiddle to alleviate the problem. Keep in mind that if you have lots of inodes, small files and/or metadata intensive workloads, then it's very likely the RAID setup is the problem, not the filesystem. Cheers, Dave. -- Dave Chinner david@fromorbit.com From adilger@dilger.ca Tue Nov 3 16:30:06 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 21C1B7FB7 for ; Tue, 3 Nov 2015 16:30:06 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 6D06BAC002 for ; Tue, 3 Nov 2015 14:30:02 -0800 (PST) X-ASG-Debug-ID: 1446589797-04cbb0242405d10001-NocioJ Received: from mail-pa0-f46.google.com (mail-pa0-f46.google.com [209.85.220.46]) by cuda.sgi.com with ESMTP id kQWBXLxP46xXh1KJ (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 03 Nov 2015 14:29:58 -0800 (PST) X-Barracuda-Envelope-From: adilger@dilger.ca X-Barracuda-Apparent-Source-IP: 209.85.220.46 Received: by padhx2 with SMTP id hx2so22830523pad.1 for ; Tue, 03 Nov 2015 14:29:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=dilger_ca.20150623.gappssmtp.com; s=20150623; h=subject:mime-version:content-type:from:in-reply-to:date:cc :message-id:references:to; bh=o1cBXJW5WN20pMmmfZmAlbiQWWH9qywUeaIraSPtw4s=; b=DOVBSFnG9GiaPfpNRCI695maHvh0R2Qg4bXwXHgC66ds5XgQp7oaNdTP6kzT6IpVZs BsXs6pc2JQooRGcBYZp1htaAw4yqsvqTnoPXTJ5LpfwlKq7DQI7YuLWC3wsA3ecPU1tO U55lLs+zUQpDyarEmHvGODZgV/dZa4dvkWuyn4GMmMvCSSfbp4rIgYwVlqMu3q+s4FD9 jedzAzP+Qe4Ttm89L5PppwMTYDYo0TlsX9p2zyB0G3ot1/ljB39zYW2DLoMwCLtty+Vw 4eyKqPqG8oFu3pNO3KQD/LovleqW4ZPu0vQ3++pPSJQY2XzKTqaUm7YUV4O4C4KD6D9M zcBQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:subject:mime-version:content-type:from :in-reply-to:date:cc:message-id:references:to; bh=o1cBXJW5WN20pMmmfZmAlbiQWWH9qywUeaIraSPtw4s=; b=EueFHjK2kzr62OX4ud4kK3YwvPJ1hx0SLZ4ltmBsFRS+kbUuKOR+kFEmbSoj+ANHmK GWbDVOlamNRzfEtpWdHZieSgMS5hT2VKg1Wbd3u33cssd3738tMQHnuclU0ymNfOaVvC WC3SgP68wMnaK+syIV2FaugNVJ8rj43MlVEuY44trT392nmIw3BZMMgk+9ZRL9cdW0Qj 2Q9VUZJmYyXI2HwynKCGeQlJsRzk/0u3FowQEopMgHtSOaKS6p41AESeCtFHxWPp1MJ2 3NGoTdHgjfCfCCQB8zAof+y1LHAbKyl8UoRvMPkYK/huEpahWz4+knblZanF2cFKqyMM SkMA== X-Gm-Message-State: ALoCoQmmQMzUCEIadoEukeLJX+Je0vbFdQKMervajS/ImuQjwtmhql4arM1y56UWsw2nrZ+uU4Zr X-Received: by 10.66.189.68 with SMTP id gg4mr37122089pac.6.1446589797075; Tue, 03 Nov 2015 14:29:57 -0800 (PST) Received: from cabot-wlan.adilger.int (S0106002191d9348b.cg.shawcable.net. [96.51.76.157]) by smtp.gmail.com with ESMTPSA id kj3sm16473383pbc.59.2015.11.03.14.29.54 (version=TLS1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 03 Nov 2015 14:29:56 -0800 (PST) Subject: Re: [PATCH v13 10/51] vfs: Cache base_acl objects in inodes Mime-Version: 1.0 (Mac OS X Mail 8.2 \(2104\)) X-ASG-Orig-Subj: Re: [PATCH v13 10/51] vfs: Cache base_acl objects in inodes Content-Type: multipart/signed; boundary="Apple-Mail=_124A55A8-7810-46A6-8154-225356928F53"; protocol="application/pgp-signature"; micalg=pgp-sha256 X-Pgp-Agent: GPGMail 2.5.2 From: Andreas Dilger In-Reply-To: <1446563847-14005-11-git-send-email-agruenba@redhat.com> Date: Tue, 3 Nov 2015 15:29:50 -0700 Cc: Alexander Viro , Theodore Ts'o , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Message-Id: References: <1446563847-14005-1-git-send-email-agruenba@redhat.com> <1446563847-14005-11-git-send-email-agruenba@redhat.com> To: Andreas Gruenbacher X-Mailer: Apple Mail (2.2104) X-Barracuda-Connect: mail-pa0-f46.google.com[209.85.220.46] X-Barracuda-Start-Time: 1446589797 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24082 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 --Apple-Mail=_124A55A8-7810-46A6-8154-225356928F53 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii On Nov 3, 2015, at 8:16 AM, Andreas Gruenbacher = wrote: >=20 > POSIX ACLs and richacls are both objects allocated by kmalloc() with a > reference count which are freed by kfree_rcu(). An inode can either > cache an access and a default POSIX ACL, or a richacl (richacls do not > have default acls). To allow an inode to cache either of the two = kinds > of acls, introduce a new base_acl type and convert i_acl and > i_default_acl to that type. In most cases, the vfs then doesn't have = to > care which kind of acl an inode caches (if any). For new wrapper functions like this better to name them as "NOUN_VERB" = so rather than "VERB_NOUN" so that related functions sort together, like base_acl_init(), base_acl_get(), base_acl_put(), base_acl_refcount(), = etc. > Signed-off-by: Andreas Gruenbacher > --- > drivers/staging/lustre/lustre/llite/llite_lib.c | 2 +- > fs/f2fs/acl.c | 4 ++-- > fs/inode.c | 4 ++-- > fs/jffs2/acl.c | 6 ++++-- > fs/posix_acl.c | 18 = +++++++++--------- > include/linux/fs.h | 25 = ++++++++++++++++++++++--- > include/linux/posix_acl.h | 12 ++++-------- > include/linux/richacl.h | 2 +- > 8 files changed, 45 insertions(+), 28 deletions(-) >=20 > diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c = b/drivers/staging/lustre/lustre/llite/llite_lib.c > index b4ed6c8..5766f69 100644 > --- a/drivers/staging/lustre/lustre/llite/llite_lib.c > +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c > @@ -1118,7 +1118,7 @@ void ll_clear_inode(struct inode *inode) > } > #ifdef CONFIG_FS_POSIX_ACL > else if (lli->lli_posix_acl) { > - LASSERT(atomic_read(&lli->lli_posix_acl->a_refcount) =3D=3D= 1); > + = LASSERT(atomic_read(&lli->lli_posix_acl->a_base.ba_refcount) =3D=3D 1); It probably makes sense to have a wrapper for this, like = base_acl_refcount() so that the details are similarly abstracted from the callers, or there isn't much benefit to having get_base_acl() and put_base_acl() at all. > LASSERT(lli->lli_remote_perms =3D=3D NULL); > posix_acl_release(lli->lli_posix_acl); > lli->lli_posix_acl =3D NULL; > diff --git a/fs/f2fs/acl.c b/fs/f2fs/acl.c > index c8f25f7..a4207de 100644 > --- a/fs/f2fs/acl.c > +++ b/fs/f2fs/acl.c > @@ -270,7 +270,7 @@ static struct posix_acl *f2fs_acl_clone(const = struct posix_acl *acl, > sizeof(struct posix_acl_entry); > clone =3D kmemdup(acl, size, flags); > if (clone) > - atomic_set(&clone->a_refcount, 1); > + atomic_set(&clone->a_base.ba_refcount, 1); This should be base_acl_init() since this should also reset the RCU = state if it was just copied from "acl" above. That wouldn't be quite correct = if there are other fields added to struct base_acl that don't need to be initialized when it is copied, so possibly base_acl_reinit() would be = better here and below if that will be the case in the near future (I haven't = looked through the whole patch series yet). > } > return clone; > } > @@ -282,7 +282,7 @@ static int f2fs_acl_create_masq(struct posix_acl = *acl, umode_t *mode_p) > umode_t mode =3D *mode_p; > int not_equiv =3D 0; >=20 > - /* assert(atomic_read(acl->a_refcount) =3D=3D 1); */ > + /* assert(atomic_read(acl->a_base.ba_refcount) =3D=3D 1); */ May as well make the comment use the base_acl_refcount() wrapper = function too. >=20 > FOREACH_ACL_ENTRY(pa, acl, pe) { > switch(pa->e_tag) { > diff --git a/fs/inode.c b/fs/inode.c > index 78a17b8..2a387f4 100644 > --- a/fs/inode.c > +++ b/fs/inode.c > @@ -233,9 +233,9 @@ void __destroy_inode(struct inode *inode) >=20 > #ifdef CONFIG_FS_POSIX_ACL > if (inode->i_acl && inode->i_acl !=3D ACL_NOT_CACHED) > - posix_acl_release(inode->i_acl); > + put_base_acl(inode->i_acl); > if (inode->i_default_acl && inode->i_default_acl !=3D = ACL_NOT_CACHED) > - posix_acl_release(inode->i_default_acl); > + put_base_acl(inode->i_default_acl); > #endif > this_cpu_dec(nr_inodes); > } > diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c > index 2f7a3c0..04a5836 100644 > --- a/fs/jffs2/acl.c > +++ b/fs/jffs2/acl.c > @@ -294,13 +294,15 @@ int jffs2_init_acl_post(struct inode *inode) > int rc; >=20 > if (inode->i_default_acl) { > - rc =3D __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_DEFAULT, = inode->i_default_acl); > + rc =3D __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_DEFAULT, > + *acl_by_type(inode, = ACL_TYPE_DEFAULT)); > if (rc) > return rc; > } >=20 > if (inode->i_acl) { > - rc =3D __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_ACCESS, = inode->i_acl); > + rc =3D __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_ACCESS, > + *acl_by_type(inode, = ACL_TYPE_ACCESS)); > if (rc) > return rc; > } > diff --git a/fs/posix_acl.c b/fs/posix_acl.c > index 4fb17de..b3b2265 100644 > --- a/fs/posix_acl.c > +++ b/fs/posix_acl.c > @@ -25,9 +25,9 @@ struct posix_acl **acl_by_type(struct inode *inode, = int type) > { > switch (type) { > case ACL_TYPE_ACCESS: > - return &inode->i_acl; > + return (struct posix_acl **)&inode->i_acl; > case ACL_TYPE_DEFAULT: > - return &inode->i_default_acl; > + return (struct posix_acl **)&inode->i_default_acl; This would be better to use container_of() to unwrap struct base_acl = from struct posix_acl. That avoids the hard requirement (which isn't = documented anywhere) that base_acl needs to be the first member of struct = posix_acl. I was originally going to write that you should add a comment that = base_acl needs to be the first member of both richacl and posix_acl, but = container_of() is both cleaner and safer. Looking further down, that IS actually needed due to the way kfree is = used on the base_acl pointer, but using container_of() is still cleaner and = safer than directly casting double pointers (which some compilers and static analysis tools will be unhappy with). > default: > BUG(); > } > @@ -83,16 +83,16 @@ EXPORT_SYMBOL(forget_cached_acl); >=20 > void forget_all_cached_acls(struct inode *inode) > { > - struct posix_acl *old_access, *old_default; > + struct base_acl *old_access, *old_default; > spin_lock(&inode->i_lock); > old_access =3D inode->i_acl; > old_default =3D inode->i_default_acl; > inode->i_acl =3D inode->i_default_acl =3D ACL_NOT_CACHED; > spin_unlock(&inode->i_lock); > if (old_access !=3D ACL_NOT_CACHED) > - posix_acl_release(old_access); > + put_base_acl(old_access); > if (old_default !=3D ACL_NOT_CACHED) > - posix_acl_release(old_default); > + put_base_acl(old_default); > } > EXPORT_SYMBOL(forget_all_cached_acls); >=20 > @@ -129,7 +129,7 @@ EXPORT_SYMBOL(get_acl); > void > posix_acl_init(struct posix_acl *acl, int count) > { > - atomic_set(&acl->a_refcount, 1); > + atomic_set(&acl->a_base.ba_refcount, 1); This should be base_acl_init(). > acl->a_count =3D count; > } > EXPORT_SYMBOL(posix_acl_init); > @@ -162,7 +162,7 @@ posix_acl_clone(const struct posix_acl *acl, gfp_t = flags) > sizeof(struct posix_acl_entry); > clone =3D kmemdup(acl, size, flags); > if (clone) > - atomic_set(&clone->a_refcount, 1); > + atomic_set(&clone->a_base.ba_refcount, 1); Also base_acl_init() or base_acl_reinit(). > } > return clone; > } > @@ -384,7 +384,7 @@ static int posix_acl_create_masq(struct posix_acl = *acl, umode_t *mode_p) > umode_t mode =3D *mode_p; > int not_equiv =3D 0; >=20 > - /* assert(atomic_read(acl->a_refcount) =3D=3D 1); */ > + /* assert(atomic_read(acl->a_base.ba_refcount) =3D=3D 1); */ base_acl_refcount(). > FOREACH_ACL_ENTRY(pa, acl, pe) { > switch(pa->e_tag) { > @@ -439,7 +439,7 @@ static int __posix_acl_chmod_masq(struct posix_acl = *acl, umode_t mode) > struct posix_acl_entry *group_obj =3D NULL, *mask_obj =3D NULL; > struct posix_acl_entry *pa, *pe; >=20 > - /* assert(atomic_read(acl->a_refcount) =3D=3D 1); */ > + /* assert(atomic_read(acl->a_base.ba_refcount) =3D=3D 1); */ ... > FOREACH_ACL_ENTRY(pa, acl, pe) { > switch(pa->e_tag) { > diff --git a/include/linux/fs.h b/include/linux/fs.h > index ba91a89..3c22c92 100644 > --- a/include/linux/fs.h > +++ b/include/linux/fs.h > @@ -576,6 +576,12 @@ static inline void mapping_allow_writable(struct = address_space *mapping) > #define i_size_ordered_init(inode) do { } while (0) > #endif >=20 > +struct base_acl { > + union { > + atomic_t ba_refcount; > + struct rcu_head ba_rcu; > + }; > +}; > struct posix_acl; Is this forward declaration of struct posix_acl even needed anymore = after the change below? There shouldn't be references to the struct in the = common code anymore (at least not by the end of the patch series. > #define ACL_NOT_CACHED ((void *)(-1)) >=20 > @@ -595,9 +601,9 @@ struct inode { > kgid_t i_gid; > unsigned int i_flags; >=20 > -#ifdef CONFIG_FS_POSIX_ACL > - struct posix_acl *i_acl; > - struct posix_acl *i_default_acl; > +#if defined(CONFIG_FS_POSIX_ACL) > + struct base_acl *i_acl; > + struct base_acl *i_default_acl; > #endif >=20 > const struct inode_operations *i_op; > @@ -3059,4 +3065,17 @@ static inline bool dir_relax(struct inode = *inode) >=20 > extern bool path_noexec(const struct path *path); >=20 > +static inline struct base_acl *get_base_acl(struct base_acl *acl) > +{ > + if (acl) > + atomic_inc(&acl->ba_refcount); > + return acl; > +} > + > +static inline void put_base_acl(struct base_acl *acl) > +{ > + if (acl && atomic_dec_and_test(&acl->ba_refcount)) > + kfree_rcu(acl, ba_rcu); Hmm, using the base_acl pointer as the pointer to kfree means that the base_acl structure DOES need to be the first one in both struct = posix_acl and struct richacl, so that needs to be commented at each structure so it doesn't accidentally break in the future. > +} > + > #endif /* _LINUX_FS_H */ > diff --git a/include/linux/posix_acl.h b/include/linux/posix_acl.h > index 3e96a6a..2c46441 100644 > --- a/include/linux/posix_acl.h > +++ b/include/linux/posix_acl.h > @@ -43,10 +43,7 @@ struct posix_acl_entry { > }; >=20 > struct posix_acl { > - union { > - atomic_t a_refcount; > - struct rcu_head a_rcu; > - }; > + struct base_acl a_base; struct base_acl a_base; /* must be first, see = base_acl_put() */ > unsigned int a_count; > struct posix_acl_entry a_entries[0]; > }; > @@ -61,8 +58,7 @@ struct posix_acl { > static inline struct posix_acl * > posix_acl_dup(struct posix_acl *acl) > { > - if (acl) > - atomic_inc(&acl->a_refcount); > + get_base_acl(&acl->a_base); > return acl; > } >=20 > @@ -72,8 +68,8 @@ posix_acl_dup(struct posix_acl *acl) > static inline void > posix_acl_release(struct posix_acl *acl) > { > - if (acl && atomic_dec_and_test(&acl->a_refcount)) > - kfree_rcu(acl, a_rcu); > + BUILD_BUG_ON(offsetof(struct posix_acl, a_base) !=3D 0); > + put_base_acl(&acl->a_base); > } >=20 >=20 > diff --git a/include/linux/richacl.h b/include/linux/richacl.h > index 1d9f5f7..2baef35 100644 > --- a/include/linux/richacl.h > +++ b/include/linux/richacl.h > @@ -57,7 +57,7 @@ static inline struct richacl * > richacl_get(struct richacl *acl) > { > if (acl) > - atomic_inc(&acl->a_refcount); > + atomic_inc(&acl->a_base.ba_refcount); > return acl; This should also use base_acl_get() for consistency. That said, where = is the call to base_acl_put() in the richacl code? Also, where is the change to struct richacl? It looks like this patch = would not be able to compile by itself. I was going to say that struct = richacl also needs a comment like struct posix_acl that struct base_acl needs to = be first. Cheers, Andreas --Apple-Mail=_124A55A8-7810-46A6-8154-225356928F53 Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename=signature.asc Content-Type: application/pgp-signature; name=signature.asc Content-Description: Message signed with OpenPGP using GPGMail -----BEGIN PGP SIGNATURE----- Comment: GPGTools - http://gpgtools.org iQIVAwUBVjk1X3Kl2rkXzB/gAQiSPA/9HwI8jDfYrPQGfFL4NjZZNxfBK6rnfVsw XRPQCXVJDDCjhM0t6RHBuQxJiGjBeHbqE3WkoqTUg7njFG5URFExY6XXOJBnjdTW nwxR0gM840ni52uLCaD+QkvIxbvbBYZQmFdtYv5wB78usBcFFSltEx7sXh7+lQru eMW3dlIAQhdKhhvN1BccVS3XBDD6TwNvgB4CK3/rOWCAU4YJLooeMPTebvEmcNYJ j5bMqBhPJT3oyYlN0Q8dIV/NOFC59lwBEoItzHSnYkPLTawFP9CUNeXHRNP/39t/ rwRFRNl30EQFwB5FfPWFNtJhKgjAtlojiTU2OgXbTTn7041dEhkdVqkhLmU9odky PD3UGjD6rSn3nnpvop7roAyoBUX5hU2G4gAKoo4aIwkp5kaN/L86JUHp1Sp23Ik2 JyxldGVwoLBSbgJKW6bBamP6IeA+kDuG1MwW5Af+9iPbM0Tf730kaON1B6X3s1xn EHhgVYaqx5G8GcIr8+XYVxnnC/fwnka03DFZxRI0A/oSdRxI0TS+98jcbPliNiE5 sHoxCvmuegRXMMfYBzQcG6d6SXDz+oG3TRtonZkn3qIuWV2dBTQTY1mjrdu5RR/r uIkBGaib0UjU6F5HHlTj4tNgXmkU4rPS7mOLcZ3mzr6eNinE3lr0oa9d9bY7zVLk uta4gJIXPtY= =vbcX -----END PGP SIGNATURE----- --Apple-Mail=_124A55A8-7810-46A6-8154-225356928F53-- From gervendas@vitally.com.br Tue Nov 3 17:21:52 2015 Return-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.4 required=5.0 tests=HTML_IMAGE_RATIO_02, HTML_MESSAGE,MPART_ALT_DIFF 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 776EA7FA7 for ; Tue, 3 Nov 2015 17:21:52 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 21174AC001 for ; Tue, 3 Nov 2015 15:21:49 -0800 (PST) X-ASG-Debug-ID: 1446592903-04bdf03f0406ab0001-NocioJ Received: from campanhas.mixdinternet.com.br (campanhas.mixdinternet.com.br [177.126.160.219]) by cuda.sgi.com with ESMTP id 3AdlbEDK9vkEz175 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 03 Nov 2015 15:21:45 -0800 (PST) X-Barracuda-Envelope-From: gervendas@vitally.com.br X-Barracuda-Apparent-Source-IP: 177.126.160.219 Received: from marketing.mixd.com.br (campanhas.mixdinternet.com.br [177.126.160.219]) by campanhas.mixdinternet.com.br (Postfix) with ESMTP id DA3ACE8AB0 for ; Tue, 3 Nov 2015 21:21:42 -0200 (BRST) To: xfs@oss.sgi.com Subject: Combo Start II Message-ID: X-ASG-Orig-Subj: Combo Start II Date: Tue, 03 Nov 2015 18:32:57 -0200 From: "Vitally" Reply-To: gervendas@vitally.com.br MIME-Version: 1.0 X-Mailer-LID: 173,261,262,208,205,204,174,175,181,182,270,177,183,207,203,185,186,189,188,187,190,191,193,194,495,192,491,195,196,198,199,197,200,201,462,202 List-Unsubscribe: X-Mailer-RecptId: 1152724 X-Mailer-SID: 2026 X-Mailer-Sent-By: 38 Content-Type: multipart/alternative; charset="UTF-8"; boundary="b1_8e4d0992afbd6b24d443b3fa9c5a9a24" Content-Transfer-Encoding: 8bit X-Barracuda-Connect: campanhas.mixdinternet.com.br[177.126.160.219] X-Barracuda-Start-Time: 1446592904 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.69 X-Barracuda-Spam-Status: No, SCORE=0.69 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=HTML_IMAGE_RATIO_02, HTML_MESSAGE, MPART_ALT_DIFF X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24086 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 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.14 MPART_ALT_DIFF BODY: HTML and text parts are different --b1_8e4d0992afbd6b24d443b3fa9c5a9a24 Content-Type: text/plain; format=flowed; charset="UTF-8" Content-Transfer-Encoding: 8bit Seu cliente de e-mail não pode ler este e-mail. Para visualizá-lo on-line, por favor, clique aqui: http://marketing.mixd.com.br/display.php?M=1152724&C=b7f7c673ed3fa1a6c03ea156ec566195&S=2026&L=203&N=1020 Para parar de receber nossos Emails:http://marketing.mixd.com.br/unsubscribe.php?M=1152724&C=b7f7c673ed3fa1a6c03ea156ec566195&L=203&N=2026 Mixd Email Marketing --b1_8e4d0992afbd6b24d443b3fa9c5a9a24 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: 8bit Combo
--b1_8e4d0992afbd6b24d443b3fa9c5a9a24-- From ross.zwisler@linux.intel.com Tue Nov 3 18:51:02 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 84D907FB2 for ; Tue, 3 Nov 2015 18:51:02 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 48A11304066 for ; Tue, 3 Nov 2015 16:50:59 -0800 (PST) X-ASG-Debug-ID: 1446598257-04bdf03f0408b30001-NocioJ Received: from mga11.intel.com ([192.55.52.93]) by cuda.sgi.com with ESMTP id PkPH1C40LLx20W1k for ; Tue, 03 Nov 2015 16:50:57 -0800 (PST) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 192.55.52.93 X-ASG-Whitelist: EmailCat (corporate) Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga102.fm.intel.com with ESMTP; 03 Nov 2015 16:50:58 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,240,1444719600"; d="scan'208";a="593551180" Received: from theros.lm.intel.com (HELO linux.intel.com) ([10.232.112.156]) by FMSMGA003.fm.intel.com with ESMTP; 03 Nov 2015 16:50:56 -0800 Date: Tue, 3 Nov 2015 17:50:56 -0700 From: Ross Zwisler To: Dave Chinner Cc: Dan Williams , Brian Foster , Ross Zwisler , Jan Kara , xfs@oss.sgi.com, linux-fsdevel , "linux-nvdimm@lists.01.org" Subject: Re: [PATCH 3/6] xfs: Don't use unwritten extents for DAX Message-ID: <20151104005056.GA24710@linux.intel.com> X-ASG-Orig-Subj: Re: [PATCH 3/6] xfs: Don't use unwritten extents for DAX Mail-Followup-To: Ross Zwisler , Dave Chinner , Dan Williams , Brian Foster , Jan Kara , xfs@oss.sgi.com, linux-fsdevel , "linux-nvdimm@lists.01.org" References: <1445225238-30413-1-git-send-email-david@fromorbit.com> <1445225238-30413-4-git-send-email-david@fromorbit.com> <20151029142950.GE11663@bfoster.bfoster> <20151029233756.GS19199@dastard> <20151030123657.GC54905@bfoster.bfoster> <20151102011433.GW19199@dastard> <20151102141509.GA29346@bfoster.bfoster> <20151102214424.GJ10656@dastard> <20151103050413.GB19199@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151103050413.GB19199@dastard> User-Agent: Mutt/1.5.23 (2014-03-12) X-Barracuda-Connect: UNKNOWN[192.55.52.93] X-Barracuda-Start-Time: 1446598257 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Tue, Nov 03, 2015 at 04:04:13PM +1100, Dave Chinner wrote: > On Mon, Nov 02, 2015 at 07:53:27PM -0800, Dan Williams wrote: > > On Mon, Nov 2, 2015 at 1:44 PM, Dave Chinner wrote: <> > > > This comes back to the comments I made w.r.t. the pmem driver > > > implementation doing synchronous IO by immediately forcing CPU cache > > > flushes and barriers. it's obviously correct, but it looks like > > > there's going to be a major performance penalty associated with it. > > > This is why I recently suggested that a pmem driver that doesn't do > > > CPU cache writeback during IO but does it on REQ_FLUSH is an > > > architecture we'll likely have to support. > > > > > > > The only thing we can realistically delay is wmb_pmem() i.e. the final > > sync waiting for data that has *left* the cpu cache. Unless/until we > > get a architecturally guaranteed method to write-back the entire > > cache, or flush the cache by physical-cache-way we're stuck with > > either non-temporal cycles or looping on potentially huge virtual > > address ranges. > > I'm missing something: why won't flushing the address range returned > by bdev_direct_access() during a fsync operation work? i.e. we're > working with exactly the same address as dax_clear_blocks() and > dax_do_io() use, so why can't we look up that address and flush it > from fsync? I could be wrong, but I don't see a reason why DAX can't use the strategy of writing data and marking it dirty in one step and then flushing later in response to fsync/msync. I think this could be used everywhere we write or zero data - dax_clear_blocks(), dax_io() etc. (I believe that lots of the block zeroing code will go away once we have the XFS and ext4 patches in that guarantee we will only get written and zeroed extents from the filesystem in response to get_block().) I think the PMEM driver, lacking the ability to mark things as dirty in the radix tree, etc, will need to keep doing things synchronously. Hmm...if we go this path, though, is that an argument against moving the zeroing from DAX down into the driver? True, with BRD it makes things nice and efficient because you can zero and never flush, and the driver knows there's nothing else to do. For PMEM, though, you lose the ability to zero the data and then queue the flushing for later, as you would be able to do if you left the zeroing code in DAX. The benefit of this is that if you are going to immediately re-write the newly zeroed data (which seems common), PMEM will end up doing an extra cache flush of the zeroes, only to have them overwritten and marked as dirty by DAX. If we leave the zeroing to DAX we can mark it dirty once, zero it once, write it once, and flush it once. This would make us lose the ability to do hardware-assisted flushing in the future that requires driver specific knowledge, though I don't think that exists yet. Perhaps we should leave the zeroing in DAX for now to take advantage of the single flush, and then move it down if a driver can improve performance with hardware assisted PMEM zeroing? From dan.j.williams@intel.com Tue Nov 3 19:02:42 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 E9A277FB4 for ; Tue, 3 Nov 2015 19:02:42 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id C9760304053 for ; Tue, 3 Nov 2015 17:02:39 -0800 (PST) X-ASG-Debug-ID: 1446598954-04cbb0242508f40001-NocioJ Received: from mail-wm0-f46.google.com (mail-wm0-f46.google.com [74.125.82.46]) by cuda.sgi.com with ESMTP id igRlfVOAjaWDUFdc (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 03 Nov 2015 17:02:35 -0800 (PST) X-Barracuda-Envelope-From: dan.j.williams@intel.com X-Barracuda-Apparent-Source-IP: 74.125.82.46 Received: by wmll128 with SMTP id l128so101639333wml.0 for ; Tue, 03 Nov 2015 17:02:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=intel_com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type; bh=N4jM+HDPSbVpZcWqeoxEBbchn71lxV50Clk0X0hO9ss=; b=E9fcSw8ZQsiYDJDSSI9tPgb1MRemRo6sf3prz3tGfc4Gfoe+wZtLLXxDnCgJIdij5W 7tTjuhHdgdA2HnIxh7kHBAhbL0nEztMTQvEid8QpzuuaJaftsFEiO/aVY7yGytcRXXab GLgJjoJWAP45DY/FXnFrxyepivGKZDBqDEQALHvimoTM6hFLobyXAUTZBFDSrGdnq3lm tqk2RNTGHr/NRrBNhb4ZRxZhKK/87SyXM+y5+Zgg+Oi4jQ1/C4Ghh2SsRqiNBkcLgJ6w btyJKhlwZnDVuN153jAMYr1fuVOU4eJaTKpiwxT/Cr7d3Y1EY5ZKcQjL41XbZ5N0uudz 7GiQ== 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:content-type; bh=N4jM+HDPSbVpZcWqeoxEBbchn71lxV50Clk0X0hO9ss=; b=mnXD8eC8Nc4enoeOEOOut4QR0uf+qRCBfqIoomA2/d49xxBhn8NfFqT0W3sXZd0kFD Y1ETeXq1leGxEySpoZYtdknYblG3PbbYV0a5lhPwR4tivpXRIf17txocNae8iP0JTvHE ls4dNY6Xc4uirjEsvUnbwasnZiUt/R7Lp1k72SOBPSPSjfVq6Y9Yz0NYM3qUDtmYBsoo 4o2+Do59WDp9I7iTtbPU3LYC/E5fDlOZtf2QQNLqc0R6LUTSlR9ajt0QMua4D4MlBdMP q6ygNxFtSvHsg3qh/RwasJkVkRTmCFdrdZd5BWStQoRcmQFN8uh0UeRdzAZjYHvclmnc cMzw== X-Gm-Message-State: ALoCoQkO02ccThDKh4J/WaU9fNgBRPRTO/wmlao0dROmQN+WOvBm0s1rx/v+ADzA/YPyQ4Z90Vw8 MIME-Version: 1.0 X-Received: by 10.28.11.13 with SMTP id 13mr137823wml.4.1446598954683; Tue, 03 Nov 2015 17:02:34 -0800 (PST) Received: by 10.27.88.132 with HTTP; Tue, 3 Nov 2015 17:02:34 -0800 (PST) In-Reply-To: <20151104005056.GA24710@linux.intel.com> References: <1445225238-30413-1-git-send-email-david@fromorbit.com> <1445225238-30413-4-git-send-email-david@fromorbit.com> <20151029142950.GE11663@bfoster.bfoster> <20151029233756.GS19199@dastard> <20151030123657.GC54905@bfoster.bfoster> <20151102011433.GW19199@dastard> <20151102141509.GA29346@bfoster.bfoster> <20151102214424.GJ10656@dastard> <20151103050413.GB19199@dastard> <20151104005056.GA24710@linux.intel.com> Date: Tue, 3 Nov 2015 17:02:34 -0800 Message-ID: Subject: Re: [PATCH 3/6] xfs: Don't use unwritten extents for DAX From: Dan Williams X-ASG-Orig-Subj: Re: [PATCH 3/6] xfs: Don't use unwritten extents for DAX To: Ross Zwisler , Dave Chinner , Dan Williams , Brian Foster , Jan Kara , xfs@oss.sgi.com, linux-fsdevel , "linux-nvdimm@lists.01.org" Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-wm0-f46.google.com[74.125.82.46] X-Barracuda-Start-Time: 1446598955 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24088 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 Tue, Nov 3, 2015 at 4:50 PM, Ross Zwisler wrote: > On Tue, Nov 03, 2015 at 04:04:13PM +1100, Dave Chinner wrote: >> On Mon, Nov 02, 2015 at 07:53:27PM -0800, Dan Williams wrote: >> > On Mon, Nov 2, 2015 at 1:44 PM, Dave Chinner wrote: > <> >> > > This comes back to the comments I made w.r.t. the pmem driver >> > > implementation doing synchronous IO by immediately forcing CPU cache >> > > flushes and barriers. it's obviously correct, but it looks like >> > > there's going to be a major performance penalty associated with it. >> > > This is why I recently suggested that a pmem driver that doesn't do >> > > CPU cache writeback during IO but does it on REQ_FLUSH is an >> > > architecture we'll likely have to support. >> > > >> > >> > The only thing we can realistically delay is wmb_pmem() i.e. the final >> > sync waiting for data that has *left* the cpu cache. Unless/until we >> > get a architecturally guaranteed method to write-back the entire >> > cache, or flush the cache by physical-cache-way we're stuck with >> > either non-temporal cycles or looping on potentially huge virtual >> > address ranges. >> >> I'm missing something: why won't flushing the address range returned >> by bdev_direct_access() during a fsync operation work? i.e. we're >> working with exactly the same address as dax_clear_blocks() and >> dax_do_io() use, so why can't we look up that address and flush it >> from fsync? > > I could be wrong, but I don't see a reason why DAX can't use the strategy of > writing data and marking it dirty in one step and then flushing later in > response to fsync/msync. I think this could be used everywhere we write or > zero data - dax_clear_blocks(), dax_io() etc. (I believe that lots of the > block zeroing code will go away once we have the XFS and ext4 patches in that > guarantee we will only get written and zeroed extents from the filesystem in > response to get_block().) I think the PMEM driver, lacking the ability to > mark things as dirty in the radix tree, etc, will need to keep doing things > synchronously. Not without numbers showing the relative performance of dirtying cache followed by flushing vs non-temporal + pcommit. > Hmm...if we go this path, though, is that an argument against moving the > zeroing from DAX down into the driver? True, with BRD it makes things nice > and efficient because you can zero and never flush, and the driver knows > there's nothing else to do. > > For PMEM, though, you lose the ability to zero the data and then queue the > flushing for later, as you would be able to do if you left the zeroing code in > DAX. The benefit of this is that if you are going to immediately re-write the > newly zeroed data (which seems common), PMEM will end up doing an extra cache > flush of the zeroes, only to have them overwritten and marked as dirty by DAX. > If we leave the zeroing to DAX we can mark it dirty once, zero it once, write > it once, and flush it once. Why do we lose the ability to flush later if the driver supports blkdev_issue_zeroout? > This would make us lose the ability to do hardware-assisted flushing in the > future that requires driver specific knowledge, though I don't think that > exists yet. ioatdma has supported memset() for a while now, but I would prioritize a non-temporal SIMD implementation first. > Perhaps we should leave the zeroing in DAX for now to take > advantage of the single flush, and then move it down if a driver can improve > performance with hardware assisted PMEM zeroing? Not convinced. I think we should implement the driver zeroing solution and take a look at performance. From adilger@dilger.ca Tue Nov 3 20:03:41 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 23D157FB5 for ; Tue, 3 Nov 2015 20:03:41 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id D319A30404E for ; Tue, 3 Nov 2015 18:03:37 -0800 (PST) X-ASG-Debug-ID: 1446602611-04bdf03f030a670001-NocioJ Received: from mail-pa0-f47.google.com (mail-pa0-f47.google.com [209.85.220.47]) by cuda.sgi.com with ESMTP id DAnWOjOL6f6X42xI (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 03 Nov 2015 18:03:31 -0800 (PST) X-Barracuda-Envelope-From: adilger@dilger.ca X-Barracuda-RBL-Trusted-Forwarder: 209.85.220.47 Received: by pacdm15 with SMTP id dm15so11760584pac.3 for ; Tue, 03 Nov 2015 18:03:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=dilger_ca.20150623.gappssmtp.com; s=20150623; h=subject:mime-version:content-type:from:in-reply-to:date:cc :message-id:references:to; bh=A4Y+KpB7hLu4qs6olVPr1LbXQxYXtI70FUt3HGSUJVU=; b=MDKarHMObf8fs3j9+Y+u3lYPT/NpgAaOw295haDD3TCkd6GxT9z4Eo5GEWXinsAKe5 UgoxAhCn7kD9aCQUh2BBfVaHXiKzLzz4yrWFsSu82yiUJk8qSgNrQ28TB2pQsOQ5iVte h9jUS/qFUVIVa37iL3mdKjSHqB4zLNFuIm73HlcQj4G9552MyyPxOfWeUarbr+L7w3R5 zsHRZICFPPXnmzNzbn8jtxCxj1s4IfjMiK/jsxYrBXPU+ELDs81Ij+B1pDMVUkTw8qVN gYvb1oXpuwXSY48E2aKnGEvCiphO2UuPwJQzqgJx1sRM1zaidlnREwvjq3e3HM/4Gb3Q 1eTg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:subject:mime-version:content-type:from :in-reply-to:date:cc:message-id:references:to; bh=A4Y+KpB7hLu4qs6olVPr1LbXQxYXtI70FUt3HGSUJVU=; b=bE9RMaxt5+8vaESwTb18/1YWuyB9mGmkcN8/fbULEpQ0i0ZXYWUpXEn+m9XwdXoPYm Puv+4BYqWS9G9994DiWA78qeVcHeRfscU7IRxqMjfoXxyEZcyJPklh8xcN05yNJggegP pad1I7tKOzPhMCSKZOJsJS9BgXc++odmzDoPLoteNlQgMgARv2to3MCe1JhM7UOeg/NZ 11gqsuNwEoEyeyoAWqrN/cYd03R33FP5cH1tuwTIyAo0Xlz9gntVxUKNMr3liJhLLvyM Q5sKohVWVNrydVh/QWIuCIS9k7fjU990MTwkjwcIwuVBCwAiciyW1hm8F0D4qO+0zgh2 Kb3g== X-Gm-Message-State: ALoCoQk77neofkbILdcIOV0Cb7GUqwpVJuI4Z/EEOrFGRyyNHer+CJaWU12cKy3WQ6qLebG+DJcr X-Received: by 10.66.153.139 with SMTP id vg11mr37734658pab.118.1446602611238; Tue, 03 Nov 2015 18:03:31 -0800 (PST) Received: from cabot-wlan.adilger.int (S0106002191d9348b.cg.shawcable.net. [96.51.76.157]) by smtp.gmail.com with ESMTPSA id e13sm1644641pat.11.2015.11.03.18.03.08 (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 03 Nov 2015 18:03:30 -0800 (PST) Subject: Re: [PATCH v13 12/51] vfs: Cache richacl in struct inode X-Barracuda-Apparent-Source-IP: 96.51.76.157 X-Barracuda-BBL-IP: 96.51.76.157 Mime-Version: 1.0 (Mac OS X Mail 8.2 \(2104\)) X-ASG-Orig-Subj: Re: [PATCH v13 12/51] vfs: Cache richacl in struct inode Content-Type: multipart/signed; boundary="Apple-Mail=_474FF3DA-AE9A-4839-BD4D-6C5C84BF4FC5"; protocol="application/pgp-signature"; micalg=pgp-sha256 X-Pgp-Agent: GPGMail 2.5.2 From: Andreas Dilger In-Reply-To: <1446563847-14005-13-git-send-email-agruenba@redhat.com> Date: Tue, 3 Nov 2015 19:03:00 -0700 Cc: Alexander Viro , Theodore Ts'o , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4 , XFS Developers , LKML , linux-fsdevel , Linux NFS Mailing List , linux-cifs@vger.kernel.org, Linux API Message-Id: <713E53A4-D073-4745-B57D-77AD07E89957@dilger.ca> References: <1446563847-14005-1-git-send-email-agruenba@redhat.com> <1446563847-14005-13-git-send-email-agruenba@redhat.com> To: Andreas Gruenbacher X-Mailer: Apple Mail (2.2104) X-Barracuda-Connect: mail-pa0-f47.google.com[209.85.220.47] X-Barracuda-Start-Time: 1446602611 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24091 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 --Apple-Mail=_474FF3DA-AE9A-4839-BD4D-6C5C84BF4FC5 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii On Nov 3, 2015, at 8:16 AM, Andreas Gruenbacher = wrote: >=20 > Cache richacls in struct inode so that this doesn't have to be done > individually in each filesystem. This is similar to POSIX ACLs. >=20 > Signed-off-by: Andreas Gruenbacher > --- > fs/inode.c | 11 ++++++-- > fs/posix_acl.c | 2 +- > fs/richacl_base.c | 4 +-- > fs/richacl_inode.c | 75 = +++++++++++++++++++++++++++++++++++++++++++++++++ > include/linux/fs.h | 5 +++- > include/linux/richacl.h | 15 ++++++---- > 6 files changed, 100 insertions(+), 12 deletions(-) >=20 > diff --git a/fs/inode.c b/fs/inode.c > index 2a387f4..8462ddb 100644 > --- a/fs/inode.c > +++ b/fs/inode.c > @@ -174,8 +174,11 @@ int inode_init_always(struct super_block *sb, = struct inode *inode) > inode->i_private =3D NULL; > inode->i_mapping =3D mapping; > INIT_HLIST_HEAD(&inode->i_dentry); /* buggered by rcu = freeing */ > -#ifdef CONFIG_FS_POSIX_ACL > - inode->i_acl =3D inode->i_default_acl =3D ACL_NOT_CACHED; > +#if defined(CONFIG_FS_POSIX_ACL) || defined(CONFIG_FS_RICHACL) > + inode->i_acl =3D ACL_NOT_CACHED; > +# if defined(CONFIG_FS_POSIX_ACL) > + inode->i_default_acl =3D ACL_NOT_CACHED; > +# endif > #endif >=20 > #ifdef CONFIG_FSNOTIFY > @@ -231,11 +234,13 @@ void __destroy_inode(struct inode *inode) > atomic_long_dec(&inode->i_sb->s_remove_count); > } >=20 > -#ifdef CONFIG_FS_POSIX_ACL > +#if defined(CONFIG_FS_POSIX_ACL) || defined(CONFIG_FS_RICHACL) > if (inode->i_acl && inode->i_acl !=3D ACL_NOT_CACHED) > put_base_acl(inode->i_acl); > +# if defined(CONFIG_FS_POSIX_ACL) > if (inode->i_default_acl && inode->i_default_acl !=3D = ACL_NOT_CACHED) > put_base_acl(inode->i_default_acl); > +# endif > #endif > this_cpu_dec(nr_inodes); > } > diff --git a/fs/posix_acl.c b/fs/posix_acl.c > index b3b2265..1d766a5 100644 > --- a/fs/posix_acl.c > +++ b/fs/posix_acl.c > @@ -38,7 +38,7 @@ struct posix_acl *get_cached_acl(struct inode = *inode, int type) > { > struct posix_acl **p =3D acl_by_type(inode, type); > struct posix_acl *acl =3D ACCESS_ONCE(*p); > - if (acl) { > + if (acl && IS_POSIXACL(inode)) { > spin_lock(&inode->i_lock); > acl =3D *p; > if (acl !=3D ACL_NOT_CACHED) > diff --git a/fs/richacl_base.c b/fs/richacl_base.c > index 69b806c..d0ab5e9 100644 > --- a/fs/richacl_base.c > +++ b/fs/richacl_base.c > @@ -33,7 +33,7 @@ richacl_alloc(int count, gfp_t gfp) > struct richacl *acl =3D kzalloc(size, gfp); >=20 > if (acl) { > - atomic_set(&acl->a_refcount, 1); > + atomic_set(&acl->a_base.ba_refcount, 1); > acl->a_count =3D count; > } > return acl; > @@ -52,7 +52,7 @@ richacl_clone(const struct richacl *acl, gfp_t gfp) >=20 > if (dup) { > memcpy(dup, acl, size); > - atomic_set(&dup->a_refcount, 1); > + atomic_set(&dup->a_base.ba_refcount, 1); These two calls should be base_acl_init(). There isn't any point to = have an abstraction that is only used by the posix_acl* code and not the = richacl code, as it will just result in richacl breaking in the future if/when = the abstraction is changed. > } > return dup; > } > diff --git a/fs/richacl_inode.c b/fs/richacl_inode.c > index 99b3c93..c41a6c4 100644 > --- a/fs/richacl_inode.c > +++ b/fs/richacl_inode.c > @@ -20,6 +20,81 @@ > #include > #include >=20 > +struct richacl *get_cached_richacl(struct inode *inode) > +{ > + struct richacl *acl; > + > + acl =3D (struct richacl *)ACCESS_ONCE(inode->i_acl); > + if (acl && IS_RICHACL(inode)) { > + spin_lock(&inode->i_lock); > + acl =3D (struct richacl *)inode->i_acl; > + if (acl !=3D ACL_NOT_CACHED) > + acl =3D richacl_get(acl); > + spin_unlock(&inode->i_lock); > + } > + return acl; > +} > +EXPORT_SYMBOL_GPL(get_cached_richacl); > + > +struct richacl *get_cached_richacl_rcu(struct inode *inode) > +{ > + return (struct richacl *)rcu_dereference(inode->i_acl); > +} > +EXPORT_SYMBOL_GPL(get_cached_richacl_rcu); > + > +void set_cached_richacl(struct inode *inode, struct richacl *acl) > +{ > + struct base_acl *old =3D NULL; > + > + spin_lock(&inode->i_lock); > + old =3D inode->i_acl; > + rcu_assign_pointer(inode->i_acl, &richacl_get(acl)->a_base); > + spin_unlock(&inode->i_lock); > + if (old !=3D ACL_NOT_CACHED) > + put_base_acl(old); > +} > +EXPORT_SYMBOL_GPL(set_cached_richacl); > + > +void forget_cached_richacl(struct inode *inode) > +{ > + struct base_acl *old =3D NULL; > + > + spin_lock(&inode->i_lock); > + old =3D inode->i_acl; > + inode->i_acl =3D ACL_NOT_CACHED; > + spin_unlock(&inode->i_lock); > + if (old !=3D ACL_NOT_CACHED) > + put_base_acl(old); > +} > +EXPORT_SYMBOL_GPL(forget_cached_richacl); > + > +struct richacl *get_richacl(struct inode *inode) > +{ > + struct richacl *acl; > + > + acl =3D get_cached_richacl(inode); > + if (acl !=3D ACL_NOT_CACHED) > + return acl; > + > + if (!IS_RICHACL(inode)) > + return NULL; > + > + /* > + * A filesystem can force a ACL callback by just never filling = the > + * ACL cache. But normally you'd fill the cache either at inode > + * instantiation time, or on the first ->get_richacl call. > + * > + * If the filesystem doesn't have a get_richacl() function at = all, > + * we'll just create the negative cache entry. > + */ > + if (!inode->i_op->get_richacl) { > + set_cached_richacl(inode, NULL); > + return NULL; > + } > + return inode->i_op->get_richacl(inode); > +} > +EXPORT_SYMBOL_GPL(get_richacl); > + > /** > * richacl_permission - richacl permission check algorithm > * @inode: inode to check > diff --git a/include/linux/fs.h b/include/linux/fs.h > index 08fde42..d91deef 100644 > --- a/include/linux/fs.h > +++ b/include/linux/fs.h > @@ -583,6 +583,7 @@ struct base_acl { > }; > }; > struct posix_acl; > +struct richacl; > #define ACL_NOT_CACHED ((void *)(-1)) >=20 > #define IOP_FASTPERM 0x0001 > @@ -601,9 +602,11 @@ struct inode { > kgid_t i_gid; > unsigned int i_flags; >=20 > -#if defined(CONFIG_FS_POSIX_ACL) > +#if defined(CONFIG_FS_POSIX_ACL) || defined(CONFIG_FS_RICHACL) > struct base_acl *i_acl; > +# if defined(CONFIG_FS_POSIX_ACL) > struct base_acl *i_default_acl; > +# endif > #endif >=20 > const struct inode_operations *i_op; > diff --git a/include/linux/richacl.h b/include/linux/richacl.h > index 2baef35..de7d0d9 100644 > --- a/include/linux/richacl.h > +++ b/include/linux/richacl.h > @@ -31,7 +31,7 @@ struct richace { > }; >=20 > struct richacl { > - atomic_t a_refcount; > + struct base_acl a_base; > unsigned int a_owner_mask; > unsigned int a_group_mask; > unsigned int a_other_mask; This should be in the previous patch where this wrapper is introduced. > @@ -56,8 +56,7 @@ struct richacl { > static inline struct richacl * > richacl_get(struct richacl *acl) > { > - if (acl) > - atomic_inc(&acl->a_base.ba_refcount); > + get_base_acl(&acl->a_base); Same. > return acl; > } >=20 > @@ -67,10 +66,16 @@ richacl_get(struct richacl *acl) > static inline void > richacl_put(struct richacl *acl) > { > - if (acl && atomic_dec_and_test(&acl->a_refcount)) > - kfree(acl); > + BUILD_BUG_ON(offsetof(struct richacl, a_base) !=3D 0); > + put_base_acl(&acl->a_base); Same. > } >=20 > +extern struct richacl *get_cached_richacl(struct inode *); > +extern struct richacl *get_cached_richacl_rcu(struct inode *); > +extern void set_cached_richacl(struct inode *, struct richacl *); > +extern void forget_cached_richacl(struct inode *); > +extern struct richacl *get_richacl(struct inode *); > + > /** > * richace_is_owner - check if @ace is an OWNER@ entry > */ > -- > 2.5.0 >=20 Cheers, Andreas --Apple-Mail=_474FF3DA-AE9A-4839-BD4D-6C5C84BF4FC5 Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename=signature.asc Content-Type: application/pgp-signature; name=signature.asc Content-Description: Message signed with OpenPGP using GPGMail -----BEGIN PGP SIGNATURE----- Comment: GPGTools - http://gpgtools.org iQIVAwUBVjlnVXKl2rkXzB/gAQgEKA//RqcPKXSvCfn2MOB6U7GOLw0TgGhL/6Ov HZA/tBbA0rFB6+6faaPw0mHy6pkSQjqQsxzHubTXbKnh5PQBGx4ncvPNU8TrpJtJ wPJXlD6OOT4mi6SUitptMg/tBdrUC6wLO/LWFXZ6abAGn+D6mlueD16QFJx3eRuj JEDHAMH5RL6H8dWOIn3MVt3AuEOeiCcUKqL5OE1CLqgHmNKMsBETBPoCDnEv14gd ZES0SRl3q8Q0yZoUkiPIu7f/nRWSjqcUiv4ZNDhoeSlKgDkO0+Wuh5dKVhbdqCEE u6rf2/oDdlvte2dwD3uj6k6eZJsTmYqUHeqBUHc0X/a8ec8WwT6bxZhy+Dul8CC5 x/LOmZoVzIdXLgtI4yXr/BjnVD0UJWZeqv1ag8rpe2U66Jz006fmyD8RP6DHwWu1 TDwexZ3cZwNS0eb15Y2Q4KPM1TOgQruQDmWnvQgZTwpK2bYM0vew/F88xQ9S8iZu 1XToZpi9uADaGvqTEFW3fieAl8Zq4r+z/luEW1InsBKjpqwkb5MpvpaLxZ7u4/2L w0q1FDe02Eez46s3maz24VOK/XD+8jC1ylcBSvHEGjJ3wouyhrN8qsik9xYOGIMa 7ThoKPKr1IDTI+czAsPWDVIV+Koqi6uYt884kubYCrZ//RU4P+F/QU70Z7JYeXx4 nhgOtb1WssQ= =c/dU -----END PGP SIGNATURE----- --Apple-Mail=_474FF3DA-AE9A-4839-BD4D-6C5C84BF4FC5-- From adilger@dilger.ca Tue Nov 3 20:13:23 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 C80757FB7 for ; Tue, 3 Nov 2015 20:13:23 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 841F38F8040 for ; Tue, 3 Nov 2015 18:13:23 -0800 (PST) X-ASG-Debug-ID: 1446603199-04bdf03f020ab30001-NocioJ Received: from mail-pa0-f43.google.com (mail-pa0-f43.google.com [209.85.220.43]) by cuda.sgi.com with ESMTP id H4fb9KROwDaJA9Mo (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 03 Nov 2015 18:13:20 -0800 (PST) X-Barracuda-Envelope-From: adilger@dilger.ca X-Barracuda-RBL-Trusted-Forwarder: 209.85.220.43 Received: by pacdm15 with SMTP id dm15so12027162pac.3 for ; Tue, 03 Nov 2015 18:13:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=dilger_ca.20150623.gappssmtp.com; s=20150623; h=subject:mime-version:content-type:from:in-reply-to:date:cc :message-id:references:to; bh=4jE+SPWEL016jmsItItl+QTK81RfC5jMRBPI6SK15BM=; b=utcEjT5MBK80g92Ejt1kwvElch+ghasnKMjoYBUvrFvTd4mh36gu0KlkoYzYUzMm+2 4bfC0wRSvJPON5k3cQonrrl8j1En0HdfzQ+dTCzY0BL4dHFOsLaOorVnQQ2Nw6GaCNMP Yl4rtg1kOeDCC16UxF4QhQdixUofXa7h7Vsy2WXhytjTPkh9M2GDmErv2IOo/ne0xzBd Zqq8PicPK2Og8zVE/1zXXMPvv3YeAg6tZ0HTt+tckUiq4Qajvv/EH/DysBHDimWGbGT0 hBI0iLA1GgCy3u84E2yGoZ7wJKFk2WfAfrKS8fffmto2kh6EYu7gDnfFLuHobNqa3+X6 rxIw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:subject:mime-version:content-type:from :in-reply-to:date:cc:message-id:references:to; bh=4jE+SPWEL016jmsItItl+QTK81RfC5jMRBPI6SK15BM=; b=luE5ZT92KeRqtw8jP9yTn4HiMPez3NSPtJEomnghxXjBkTWm9OBq2uEWl8I1+c3lWO jbV81N9CaJ8St3wvMR9vmzsNeZ7DlHp6dPPM1bRPG+y5VH452TWFMHNKUh7Z9uwtnfxQ 8kb4OM0s4LpmrcH0jM+WZlpozf1RvmV2jDC0QMZTTIJmYnVUjMu7PlS7kQ9RfqgHzksL yq1HEsz5F36jtho6MP3oMsq8XRXmF4Zlmf40cxirQfI17MW/Bgnp2UH0Pcw7x7S+j4lE zE6xlORPOxz6fcgXyallccrds4M+YnLZdz0FmlOLlFklWmWDzgs4MmqUFMV+h3s8PLfj pq/w== X-Gm-Message-State: ALoCoQkF8oejos50Nh6GA8+l1DX6i0nPHJHlRrSMv49lJBKB3KUr528JILO7Yj7yUyFBR4ClOa9M X-Received: by 10.68.248.6 with SMTP id yi6mr37996949pbc.158.1446603199684; Tue, 03 Nov 2015 18:13:19 -0800 (PST) Received: from cabot-wlan.adilger.int (S0106002191d9348b.cg.shawcable.net. [96.51.76.157]) by smtp.gmail.com with ESMTPSA id ve8sm31898683pbc.48.2015.11.03.18.13.14 (version=TLS1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 03 Nov 2015 18:13:18 -0800 (PST) Subject: Re: [PATCH v13 20/51] ext4: Add richacl support X-Barracuda-Apparent-Source-IP: 96.51.76.157 X-Barracuda-BBL-IP: 96.51.76.157 Mime-Version: 1.0 (Mac OS X Mail 8.2 \(2104\)) X-ASG-Orig-Subj: Re: [PATCH v13 20/51] ext4: Add richacl support Content-Type: multipart/signed; boundary="Apple-Mail=_59126A52-FAF0-4DF2-B107-A9EE09A9B3C7"; protocol="application/pgp-signature"; micalg=pgp-sha256 X-Pgp-Agent: GPGMail 2.5.2 From: Andreas Dilger In-Reply-To: <1446563847-14005-21-git-send-email-agruenba@redhat.com> Date: Tue, 3 Nov 2015 19:13:07 -0700 Cc: Alexander Viro , Theodore Ts'o , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4 , XFS Developers , LKML , linux-fsdevel , Linux NFS Mailing List , linux-cifs@vger.kernel.org, Linux API , "Aneesh Kumar K.V" Message-Id: <6A710DA3-0B03-4371-A1EB-7AF39F684EDC@dilger.ca> References: <1446563847-14005-1-git-send-email-agruenba@redhat.com> <1446563847-14005-21-git-send-email-agruenba@redhat.com> To: Andreas Gruenbacher X-Mailer: Apple Mail (2.2104) X-Barracuda-Connect: mail-pa0-f43.google.com[209.85.220.43] X-Barracuda-Start-Time: 1446603200 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24091 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 --Apple-Mail=_59126A52-FAF0-4DF2-B107-A9EE09A9B3C7 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii On Nov 3, 2015, at 8:16 AM, Andreas Gruenbacher = wrote: >=20 > From: "Aneesh Kumar K.V" >=20 > Support the richacl permission model in ext4. The richacls are stored > in "system.richacl" xattrs. Richacls need to be enabled by tune2fs or > at file system create time. Patch looks reasonable. One minor cleanup below that could be fixed = when the patch series is refreshed, and you can add: Reviewed-by: Andreas Dilger >=20 > Signed-off-by: Aneesh Kumar K.V > Signed-off-by: Andreas Gruenbacher > --- > fs/ext4/Kconfig | 11 +++++ > fs/ext4/Makefile | 1 + > fs/ext4/file.c | 3 ++ > fs/ext4/ialloc.c | 11 ++++- > fs/ext4/inode.c | 12 ++++- > fs/ext4/namei.c | 5 ++ > fs/ext4/richacl.c | 141 = ++++++++++++++++++++++++++++++++++++++++++++++++++++++ > fs/ext4/richacl.h | 40 ++++++++++++++++ > fs/ext4/xattr.c | 7 +++ > 9 files changed, 228 insertions(+), 3 deletions(-) > create mode 100644 fs/ext4/richacl.c > create mode 100644 fs/ext4/richacl.h >=20 > diff --git a/fs/ext4/Kconfig b/fs/ext4/Kconfig > index b46e9fc..65c5230 100644 > --- a/fs/ext4/Kconfig > +++ b/fs/ext4/Kconfig > @@ -22,6 +22,17 @@ config EXT3_FS_POSIX_ACL > This config option is here only for backward compatibility. = ext3 > filesystem is now handled by the ext4 driver. >=20 > +config EXT4_FS_RICHACL > + bool "Ext4 Rich Access Control Lists (EXPERIMENTAL)" > + depends on EXT4_FS > + select FS_RICHACL > + help > + Richacls are an implementation of NFSv4 ACLs, extended by file = masks > + to cleanly integrate into the POSIX file permission model. To = learn > + more about them, see http://www.bestbits.at/richacl/. > + > + If you don't know what Richacls are, say N. > + > config EXT3_FS_SECURITY > bool "Ext3 Security Labels" > depends on EXT3_FS > diff --git a/fs/ext4/Makefile b/fs/ext4/Makefile > index 75285ea..ea0d539 100644 > --- a/fs/ext4/Makefile > +++ b/fs/ext4/Makefile > @@ -14,3 +14,4 @@ ext4-$(CONFIG_EXT4_FS_POSIX_ACL) +=3D acl.o > ext4-$(CONFIG_EXT4_FS_SECURITY) +=3D xattr_security.o > ext4-$(CONFIG_EXT4_FS_ENCRYPTION) +=3D crypto_policy.o crypto.o \ > crypto_key.o crypto_fname.o > +ext4-$(CONFIG_EXT4_FS_RICHACL) +=3D richacl.o > diff --git a/fs/ext4/file.c b/fs/ext4/file.c > index 113837e..a03b4a5 100644 > --- a/fs/ext4/file.c > +++ b/fs/ext4/file.c > @@ -30,6 +30,7 @@ > #include "ext4_jbd2.h" > #include "xattr.h" > #include "acl.h" > +#include "richacl.h" >=20 > /* > * Called when an inode is released. Note that this is different > @@ -719,6 +720,8 @@ const struct inode_operations = ext4_file_inode_operations =3D { > .removexattr =3D generic_removexattr, > .get_acl =3D ext4_get_acl, > .set_acl =3D ext4_set_acl, > + .get_richacl =3D ext4_get_richacl, > + .set_richacl =3D ext4_set_richacl, > .fiemap =3D ext4_fiemap, > }; >=20 > diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c > index 619bfc1..9657b3a 100644 > --- a/fs/ext4/ialloc.c > +++ b/fs/ext4/ialloc.c > @@ -27,6 +27,7 @@ > #include "ext4_jbd2.h" > #include "xattr.h" > #include "acl.h" > +#include "richacl.h" >=20 > #include >=20 > @@ -697,6 +698,14 @@ out: > return ret; > } >=20 > +static inline int > +ext4_new_acl(handle_t *handle, struct inode *inode, struct inode = *dir) > +{ > + if (IS_RICHACL(dir)) > + return ext4_init_richacl(handle, inode, dir); > + return ext4_init_acl(handle, inode, dir); > +} > + > /* > * There are two policies for allocating an inode. If the new inode = is > * a directory, then a forward search is made for a block group with = both > @@ -1052,7 +1061,7 @@ got: > if (err) > goto fail_drop; >=20 > - err =3D ext4_init_acl(handle, inode, dir); > + err =3D ext4_new_acl(handle, inode, dir); > if (err) > goto fail_free_drop; >=20 > diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c > index 612fbcf..647f3c3 100644 > --- a/fs/ext4/inode.c > +++ b/fs/ext4/inode.c > @@ -42,6 +42,7 @@ > #include "xattr.h" > #include "acl.h" > #include "truncate.h" > +#include "richacl.h" >=20 > #include >=20 > @@ -4638,6 +4639,14 @@ static void = ext4_wait_for_tail_page_commit(struct inode *inode) > } > } >=20 > +static inline int > +ext4_acl_chmod(struct inode *inode, umode_t mode) > +{ > + if (IS_RICHACL(inode)) > + return richacl_chmod(inode, inode->i_mode); > + return posix_acl_chmod(inode, inode->i_mode); > +} > + > /* > * ext4_setattr() > * > @@ -4806,8 +4815,7 @@ int ext4_setattr(struct dentry *dentry, struct = iattr *attr) > ext4_orphan_del(NULL, inode); >=20 > if (!rc && (ia_valid & ATTR_MODE)) > - rc =3D posix_acl_chmod(inode, inode->i_mode); > - > + rc =3D ext4_acl_chmod(inode, inode->i_mode); > err_out: > ext4_std_error(inode->i_sb, error); > if (!error) > diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c > index 9f61e76..9b6e8b9 100644 > --- a/fs/ext4/namei.c > +++ b/fs/ext4/namei.c > @@ -38,6 +38,7 @@ >=20 > #include "xattr.h" > #include "acl.h" > +#include "richacl.h" >=20 > #include > /* > @@ -3854,6 +3855,8 @@ const struct inode_operations = ext4_dir_inode_operations =3D { > .removexattr =3D generic_removexattr, > .get_acl =3D ext4_get_acl, > .set_acl =3D ext4_set_acl, > + .get_richacl =3D ext4_get_richacl, > + .set_richacl =3D ext4_set_richacl, > .fiemap =3D ext4_fiemap, > }; >=20 > @@ -3865,4 +3868,6 @@ const struct inode_operations = ext4_special_inode_operations =3D { > .removexattr =3D generic_removexattr, > .get_acl =3D ext4_get_acl, > .set_acl =3D ext4_set_acl, > + .get_richacl =3D ext4_get_richacl, > + .set_richacl =3D ext4_set_richacl, > }; > diff --git a/fs/ext4/richacl.c b/fs/ext4/richacl.c > new file mode 100644 > index 0000000..906d048 > --- /dev/null > +++ b/fs/ext4/richacl.c > @@ -0,0 +1,141 @@ > +/* > + * Copyright IBM Corporation, 2010 > + * Copyright (C) 2015 Red Hat, Inc. > + * Author: Aneesh Kumar K.V , > + * Andreas Gruenbacher > + * > + * This program is free software; you can redistribute it and/or = modify it > + * under the terms of version 2.1 of the GNU Lesser 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. > + * > + */ > + > +#include > +#include > +#include > + > +#include "ext4.h" > +#include "ext4_jbd2.h" > +#include "xattr.h" > +#include "acl.h" > +#include "richacl.h" > + > +struct richacl * > +ext4_get_richacl(struct inode *inode) > +{ > + const int name_index =3D EXT4_XATTR_INDEX_RICHACL; > + void *value =3D NULL; > + struct richacl *acl =3D NULL; > + int retval; > + > + retval =3D ext4_xattr_get(inode, name_index, "", NULL, 0); > + if (retval > 0) { > + value =3D kmalloc(retval, GFP_NOFS); > + if (!value) > + return ERR_PTR(-ENOMEM); > + retval =3D ext4_xattr_get(inode, name_index, "", value, = retval); > + } > + if (retval > 0) { > + acl =3D richacl_from_xattr(&init_user_ns, value, = retval); > + if (acl =3D=3D ERR_PTR(-EINVAL)) > + acl =3D ERR_PTR(-EIO); > + } else if (retval !=3D -ENODATA && retval !=3D -ENOSYS) > + acl =3D ERR_PTR(retval); (style) Typically, the braces on if/else blocks are kept matching. > + kfree(value); > + > + if (!IS_ERR(acl)) > + set_cached_richacl(inode, acl); > + > + return acl; > +} > + > +static int > +__ext4_remove_richacl(handle_t *handle, struct inode *inode) > +{ > + const int name_index =3D EXT4_XATTR_INDEX_RICHACL; > + int retval; > + > + retval =3D ext4_xattr_set_handle(handle, inode, name_index, "", > + NULL, 0, 0); > + if (!retval) > + set_cached_richacl(inode, NULL); > + return retval; > +} > + > +static int > +__ext4_set_richacl(handle_t *handle, struct inode *inode, struct = richacl *acl) > +{ > + const int name_index =3D EXT4_XATTR_INDEX_RICHACL; > + umode_t mode =3D inode->i_mode; > + int retval, size; > + void *value; > + > + if (richacl_equiv_mode(acl, &mode) =3D=3D 0) { > + inode->i_ctime =3D ext4_current_time(inode); > + inode->i_mode =3D mode; > + ext4_mark_inode_dirty(handle, inode); > + return __ext4_remove_richacl(handle, inode); > + } > + > + mode &=3D ~S_IRWXUGO; > + mode |=3D richacl_masks_to_mode(acl); > + > + size =3D richacl_xattr_size(acl); > + value =3D kmalloc(size, GFP_NOFS); > + if (!value) > + return -ENOMEM; > + richacl_to_xattr(&init_user_ns, acl, value, size); > + inode->i_mode =3D mode; > + retval =3D ext4_xattr_set_handle(handle, inode, name_index, "", > + value, size, 0); > + kfree(value); > + if (retval) > + return retval; > + > + set_cached_richacl(inode, acl); > + > + return 0; > +} > + > +int > +ext4_set_richacl(struct inode *inode, struct richacl *acl) > +{ > + handle_t *handle; > + int retval, retries =3D 0; > + > +retry: > + handle =3D ext4_journal_start(inode, EXT4_HT_XATTR, > + ext4_jbd2_credits_xattr(inode)); > + if (IS_ERR(handle)) > + return PTR_ERR(handle); > + > + if (acl) > + retval =3D __ext4_set_richacl(handle, inode, acl); > + else > + retval =3D __ext4_remove_richacl(handle, inode); > + > + ext4_journal_stop(handle); > + if (retval =3D=3D -ENOSPC && = ext4_should_retry_alloc(inode->i_sb, &retries)) > + goto retry; > + return retval; > +} > + > +int > +ext4_init_richacl(handle_t *handle, struct inode *inode, struct inode = *dir) > +{ > + struct richacl *acl =3D richacl_create(&inode->i_mode, dir); > + int error; > + > + error =3D PTR_ERR(acl); > + if (IS_ERR(acl)) > + return error; > + if (acl) { > + error =3D __ext4_set_richacl(handle, inode, acl); > + richacl_put(acl); > + } > + return error; > +} > diff --git a/fs/ext4/richacl.h b/fs/ext4/richacl.h > new file mode 100644 > index 0000000..6fe9a92 > --- /dev/null > +++ b/fs/ext4/richacl.h > @@ -0,0 +1,40 @@ > +/* > + * Copyright IBM Corporation, 2010 > + * Copyright (C) 2015 Red Hat, Inc. > + * Author Aneesh Kumar K.V > + * > + * This program is free software; you can redistribute it and/or = modify it > + * under the terms of version 2.1 of the GNU Lesser 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. > + * > + */ > + > +#ifndef __FS_EXT4_RICHACL_H > +#define __FS_EXT4_RICHACL_H > + > +#include > + > +#ifdef CONFIG_EXT4_FS_RICHACL > + > +extern struct richacl *ext4_get_richacl(struct inode *); > +extern int ext4_set_richacl(struct inode *, struct richacl *); > + > +extern int ext4_init_richacl(handle_t *, struct inode *, struct inode = *); > + > +#else /* CONFIG_EXT4_FS_RICHACL */ > + > +#define ext4_get_richacl NULL > +#define ext4_set_richacl NULL > + > +static inline int > +ext4_init_richacl(handle_t *handle, struct inode *inode, struct inode = *dir) > +{ > + return 0; > +} > + > +#endif /* CONFIG_EXT4_FS_RICHACL */ > +#endif /* __FS_EXT4_RICHACL_H */ > diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c > index 16e28c0..4d79adb 100644 > --- a/fs/ext4/xattr.c > +++ b/fs/ext4/xattr.c > @@ -55,6 +55,7 @@ > #include > #include > #include > +#include > #include "ext4_jbd2.h" > #include "ext4.h" > #include "xattr.h" > @@ -99,6 +100,9 @@ static const struct xattr_handler = *ext4_xattr_handler_map[] =3D { > #ifdef CONFIG_EXT4_FS_SECURITY > [EXT4_XATTR_INDEX_SECURITY] =3D = &ext4_xattr_security_handler, > #endif > +#ifdef CONFIG_EXT4_FS_RICHACL > + [EXT4_XATTR_INDEX_RICHACL] =3D &richacl_xattr_handler, > +#endif > }; >=20 > const struct xattr_handler *ext4_xattr_handlers[] =3D { > @@ -111,6 +115,9 @@ const struct xattr_handler *ext4_xattr_handlers[] = =3D { > #ifdef CONFIG_EXT4_FS_SECURITY > &ext4_xattr_security_handler, > #endif > +#ifdef CONFIG_EXT4_FS_RICHACL > + &richacl_xattr_handler, > +#endif > NULL > }; >=20 > -- > 2.5.0 >=20 Cheers, Andreas --Apple-Mail=_59126A52-FAF0-4DF2-B107-A9EE09A9B3C7 Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename=signature.asc Content-Type: application/pgp-signature; name=signature.asc Content-Description: Message signed with OpenPGP using GPGMail -----BEGIN PGP SIGNATURE----- Comment: GPGTools - http://gpgtools.org iQIVAwUBVjlptHKl2rkXzB/gAQgjChAAkKzLoa4Jxvskyv0w9logUqsDIjZpujRv iH6EM3NEMZ5WWDESmwJHdJJ8iC3hThdex6borwxYKs3WPIXQYp1USHu3F5f/nl3x +wpmGjSetBnde/Mg4V7FUXI4Q+ClWyOn+Q55eHQ6xrDyT+9pEDr9Iy9mSnZPLKzL KBl/s/dOdhfdYyAcjMCLkFXBKeBrMgxvD5VyIbX1/uYQglLEwIVkwvgfAS2zKaSO Sfb8qzYykd8VaLdAPEHCeT0MgaRrCfBqDGPe29pAfm5YNkFpSQcckHwkrx6H1Bkc b4wO41mNejOZrkYdNF/5wiQWhSYuBwkL/v0MmanP0S/l/ilHrgDYZ+cFS9hSMY7K 35wbbWiq72QbAq0eEOH7f34UcBGTYdi4alrML0cDcSDyOJVgWMFulyVYvCx2Mb5S IY/WWTK9PnWdpbt168KZahtbrvhF7ds97/8wZ8cj8gcD9kWUsCuzZVGVEmqiHaAy Jp9cduKmhwxh8JXAlpi0sHJ0Ybf+W022zlDeAVJW4lKNdhsehyIJh1ZJU4yRVnyz 4FE1aCC4eQBZhTi4BAppco2lo+RLRmQa7H8od4fjzcJNYDFqiU8YbXJlgaDZ2BYu obw9NBUpIOQLPClZPWfkW95zueQzeVf+1cPYu8Q7jNP5cVphT/dAq6h/jbg9DmWS 8LYQyQqr3NE= =egkX -----END PGP SIGNATURE----- --Apple-Mail=_59126A52-FAF0-4DF2-B107-A9EE09A9B3C7-- From adilger@dilger.ca Tue Nov 3 20:18:36 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 29CEB7FB7 for ; Tue, 3 Nov 2015 20:18:36 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 93A60AC002 for ; Tue, 3 Nov 2015 18:18:32 -0800 (PST) X-ASG-Debug-ID: 1446603507-04cb6c296c0b160001-NocioJ Received: from mail-pa0-f52.google.com (mail-pa0-f52.google.com [209.85.220.52]) by cuda.sgi.com with ESMTP id yskIJSBz8UMDLdr3 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 03 Nov 2015 18:18:28 -0800 (PST) X-Barracuda-Envelope-From: adilger@dilger.ca X-Barracuda-RBL-Trusted-Forwarder: 209.85.220.52 Received: by pasz6 with SMTP id z6so37103649pas.2 for ; Tue, 03 Nov 2015 18:18:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=dilger_ca.20150623.gappssmtp.com; s=20150623; h=subject:mime-version:content-type:from:in-reply-to:date:cc :message-id:references:to; bh=PiEtZbidIrh+x77auObf5V2GbN8q6zbB77eGzMirCKI=; b=FEbrqpFToewot4neQhzenJyQ8iHBZrQvS7aWqxrt8y5M/NPF3/68Q7GEfk4HKECt6M xgFW4utjpCyCqB3s4BVp4oqtnLQeT9SHhpvntS0IkSt5Y1pKrlPLypW1b1Vn0azYdamB pDlJ8YL9hZ84FeyBpypZQgj8MZtTfW55ryhJIF8qx2TGd9vOLTWmYssBlUvBCiHsEhrc ckKs3keLM9snYufrebb5/r7otu/zzMXEFCeEXE4QTYTVkjcWXpT3W3IkxFT42yYBO9TE lT8wL3cmLmm2HcW2N+Lpqbd/ha4TJmSpmHPfLqnOrrdPYJ2msiys6qxyF8HYPd30ft3v 9e9g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:subject:mime-version:content-type:from :in-reply-to:date:cc:message-id:references:to; bh=PiEtZbidIrh+x77auObf5V2GbN8q6zbB77eGzMirCKI=; b=l7wxHvoCeutFoZoBnQ1GQxyzfP+JPG4vWqBL69wxnvz9r8QBnqU566cKspUH10363P sbNj3SB8gR06TLURxqPf8clIxOlBmiai7jDvq+ivhsLyH7GDc7DnEVn1CPSu2Y7TUj/b DJSfjBfol4y1FE5A57WAKSEgow3mH3LwMFuG1iRDdZ1rNv/DHcXRk/z6Oe+xZ7pLOms0 DAESWIL06MHhU4Cw4KGOma4wL/M1fhx6K7IctL47baIc7BHv51EKPMHfzFe6zYQlEOcg X8vXtpJFXEZZiXYyq4tbQ+AP9QYdbsi3buUzpfDdeX39VVdBI7G77PoHHo3IQB7FOlTl pa/A== X-Gm-Message-State: ALoCoQmWpPzz52cbax+Ij9UmuDJ251RStwM5NWuvpPah2GrjUVYR9u4Zxcn7LUOpSwiXelD7XwDB X-Received: by 10.68.68.132 with SMTP id w4mr34107686pbt.137.1446603507542; Tue, 03 Nov 2015 18:18:27 -0800 (PST) Received: from cabot-wlan.adilger.int (S0106002191d9348b.cg.shawcable.net. [96.51.76.157]) by smtp.gmail.com with ESMTPSA id ey17sm32021212pac.26.2015.11.03.18.18.23 (version=TLS1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 03 Nov 2015 18:18:26 -0800 (PST) Subject: Re: [PATCH v13 21/51] ext4: Add richacl feature flag X-Barracuda-Apparent-Source-IP: 96.51.76.157 X-Barracuda-BBL-IP: 96.51.76.157 Mime-Version: 1.0 (Mac OS X Mail 8.2 \(2104\)) X-ASG-Orig-Subj: Re: [PATCH v13 21/51] ext4: Add richacl feature flag Content-Type: multipart/signed; boundary="Apple-Mail=_CCEA3C87-F09E-4ABD-A2B3-E40C5E9468A2"; protocol="application/pgp-signature"; micalg=pgp-sha256 X-Pgp-Agent: GPGMail 2.5.2 From: Andreas Dilger In-Reply-To: <1446563847-14005-22-git-send-email-agruenba@redhat.com> Date: Tue, 3 Nov 2015 19:18:19 -0700 Cc: Alexander Viro , Theodore Ts'o , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org, "Aneesh Kumar K.V" Message-Id: <06282344-726E-49AD-936B-7BFF8F43B967@dilger.ca> References: <1446563847-14005-1-git-send-email-agruenba@redhat.com> <1446563847-14005-22-git-send-email-agruenba@redhat.com> To: Andreas Gruenbacher X-Mailer: Apple Mail (2.2104) X-Barracuda-Connect: mail-pa0-f52.google.com[209.85.220.52] X-Barracuda-Start-Time: 1446603508 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24091 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 --Apple-Mail=_CCEA3C87-F09E-4ABD-A2B3-E40C5E9468A2 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii > On Nov 3, 2015, at 8:16 AM, Andreas Gruenbacher = wrote: >=20 > From: "Aneesh Kumar K.V" >=20 > This feature flag selects richacl instead of posix acl support on the > file system. In addition, the "acl" mount option is needed for = enabling > either of the two kinds of acls. This patch confuses me. I thought the whole point of INCOMPAT_RICHACL was that the filesystem should never, ever be mounted without ACL = support because the ACLs will get confused without it. In that case, it doesn't make sense to have a mount option that _has_ to be specified to mount = the filesystem, and returns an error when trying to disable it. It makes more sense to just enable "acl" by default if INCOMPAT_RICHACL is set in the superblock and not need the mount option at all. Having a mount option made more sense when enabling this support was = optional for the filesystem, and it could be mounted without it enabled, but you wanted INCOMPAT_RICHACL to prevent that so it needs to be fixed. Cheers, Andreas > Signed-off-by: Aneesh Kumar K.V > Signed-off-by: Andreas Gruenbacher > --- > fs/ext4/ext4.h | 6 ++++-- > fs/ext4/super.c | 49 ++++++++++++++++++++++++++++++++++++++++--------- > 2 files changed, 44 insertions(+), 11 deletions(-) >=20 > diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h > index fd1f28b..b97a3b1 100644 > --- a/fs/ext4/ext4.h > +++ b/fs/ext4/ext4.h > @@ -991,7 +991,7 @@ struct ext4_inode_info { > #define EXT4_MOUNT_UPDATE_JOURNAL 0x01000 /* Update the journal = format */ > #define EXT4_MOUNT_NO_UID32 0x02000 /* Disable 32-bit UIDs = */ > #define EXT4_MOUNT_XATTR_USER 0x04000 /* Extended user = attributes */ > -#define EXT4_MOUNT_POSIX_ACL 0x08000 /* POSIX Access Control = Lists */ > +#define EXT4_MOUNT_ACL 0x08000 /* Access = Control Lists */ > #define EXT4_MOUNT_NO_AUTO_DA_ALLOC 0x10000 /* No auto delalloc = mapping */ > #define EXT4_MOUNT_BARRIER 0x20000 /* Use block barriers */ > #define EXT4_MOUNT_QUOTA 0x80000 /* Some quota option set = */ > @@ -1582,6 +1582,7 @@ static inline int ext4_encrypted_inode(struct = inode *inode) > #define EXT4_FEATURE_INCOMPAT_LARGEDIR 0x4000 /* >2GB = or 3-lvl htree */ > #define EXT4_FEATURE_INCOMPAT_INLINE_DATA 0x8000 /* data in inode = */ > #define EXT4_FEATURE_INCOMPAT_ENCRYPT 0x10000 > +#define EXT4_FEATURE_INCOMPAT_RICHACL 0x20000 >=20 > #define EXT2_FEATURE_COMPAT_SUPP EXT4_FEATURE_COMPAT_EXT_ATTR > #define EXT2_FEATURE_INCOMPAT_SUPP (EXT4_FEATURE_INCOMPAT_FILETYPE| = \ > @@ -1607,7 +1608,8 @@ static inline int ext4_encrypted_inode(struct = inode *inode) > EXT4_FEATURE_INCOMPAT_FLEX_BG| = \ > EXT4_FEATURE_INCOMPAT_MMP | \ > = EXT4_FEATURE_INCOMPAT_INLINE_DATA | \ > - EXT4_FEATURE_INCOMPAT_ENCRYPT) > + EXT4_FEATURE_INCOMPAT_ENCRYPT | = \ > + EXT4_FEATURE_INCOMPAT_RICHACL) > #define EXT4_FEATURE_RO_COMPAT_SUPP = (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER| \ > = EXT4_FEATURE_RO_COMPAT_LARGE_FILE| \ > = EXT4_FEATURE_RO_COMPAT_GDT_CSUM| \ > diff --git a/fs/ext4/super.c b/fs/ext4/super.c > index a63c7b0..7457ea8 100644 > --- a/fs/ext4/super.c > +++ b/fs/ext4/super.c > @@ -1270,6 +1270,28 @@ static ext4_fsblk_t get_sb_block(void **data) > return sb_block; > } >=20 > +static int enable_acl(struct super_block *sb) > +{ > + sb->s_flags &=3D ~(MS_POSIXACL | MS_RICHACL); > + if (test_opt(sb, ACL)) { > + if (EXT4_HAS_INCOMPAT_FEATURE(sb, > + = EXT4_FEATURE_INCOMPAT_RICHACL)) { > +#ifdef CONFIG_EXT4_FS_RICHACL > + sb->s_flags |=3D MS_RICHACL; > +#else > + return -EOPNOTSUPP; > +#endif > + } else { > +#ifdef CONFIG_EXT4_FS_POSIX_ACL > + sb->s_flags |=3D MS_POSIXACL; > +#else > + return -EOPNOTSUPP; > +#endif > + } > + } > + return 0; > +} > + > #define DEFAULT_JOURNAL_IOPRIO (IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 3)) > static char deprecated_msg[] =3D "Mount option \"%s\" will be removed = by %s\n" > "Contact linux-ext4@vger.kernel.org if you think we should keep = it.\n"; > @@ -1416,9 +1438,9 @@ static const struct mount_opts { > MOPT_NO_EXT2 | MOPT_DATAJ}, > {Opt_user_xattr, EXT4_MOUNT_XATTR_USER, MOPT_SET}, > {Opt_nouser_xattr, EXT4_MOUNT_XATTR_USER, MOPT_CLEAR}, > -#ifdef CONFIG_EXT4_FS_POSIX_ACL > - {Opt_acl, EXT4_MOUNT_POSIX_ACL, MOPT_SET}, > - {Opt_noacl, EXT4_MOUNT_POSIX_ACL, MOPT_CLEAR}, > +#if defined(CONFIG_EXT4_FS_POSIX_ACL) || = defined(CONFIG_EXT4_FS_RICHACL) > + {Opt_acl, EXT4_MOUNT_ACL, MOPT_SET}, > + {Opt_noacl, EXT4_MOUNT_ACL, MOPT_CLEAR}, > #else > {Opt_acl, 0, MOPT_NOSUPPORT}, > {Opt_noacl, 0, MOPT_NOSUPPORT}, > @@ -1466,6 +1488,13 @@ static int handle_mount_opt(struct super_block = *sb, char *opt, int token, > #endif > switch (token) { > case Opt_noacl: > +#ifdef CONFIG_EXT4_FS_RICHACL > + if (EXT4_HAS_INCOMPAT_FEATURE(sb, = EXT4_FEATURE_INCOMPAT_RICHACL)) { > + ext4_msg(sb, KERN_ERR, "Mount option \"%s\" incompatible = " > + "with richacl feature", opt); > + return -1; > + } > +#endif > case Opt_nouser_xattr: > ext4_msg(sb, KERN_WARNING, deprecated_msg, opt, "3.5"); > break; > @@ -3576,8 +3605,8 @@ static int ext4_fill_super(struct super_block = *sb, void *data, int silent) > set_opt(sb, NO_UID32); > /* xattr user namespace & acls are now defaulted on */ > set_opt(sb, XATTR_USER); > -#ifdef CONFIG_EXT4_FS_POSIX_ACL > - set_opt(sb, POSIX_ACL); > +#if defined(CONFIG_EXT4_FS_POSIX_ACL) || = defined(CONFIG_EXT4_FS_RICHACL) > + set_opt(sb, ACL); > #endif > /* don't forget to enable journal_csum when metadata_csum is = enabled. */ > if (ext4_has_metadata_csum(sb)) > @@ -3660,8 +3689,9 @@ static int ext4_fill_super(struct super_block = *sb, void *data, int silent) > sb->s_iflags |=3D SB_I_CGROUPWB; > } >=20 > - sb->s_flags =3D (sb->s_flags & ~MS_POSIXACL) | > - (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0); > + err =3D enable_acl(sb); > + if (err) > + goto failed_mount; >=20 > if (le32_to_cpu(es->s_rev_level) =3D=3D EXT4_GOOD_OLD_REV && > (EXT4_HAS_COMPAT_FEATURE(sb, ~0U) || > @@ -4981,8 +5011,9 @@ static int ext4_remount(struct super_block *sb, = int *flags, char *data) > if (sbi->s_mount_flags & EXT4_MF_FS_ABORTED) > ext4_abort(sb, "Abort forced by user"); >=20 > - sb->s_flags =3D (sb->s_flags & ~MS_POSIXACL) | > - (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0); > + err =3D enable_acl(sb); > + if (err) > + goto restore_opts; >=20 > es =3D sbi->s_es; >=20 > -- > 2.5.0 >=20 Cheers, Andreas --Apple-Mail=_CCEA3C87-F09E-4ABD-A2B3-E40C5E9468A2 Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename=signature.asc Content-Type: application/pgp-signature; name=signature.asc Content-Description: Message signed with OpenPGP using GPGMail -----BEGIN PGP SIGNATURE----- Comment: GPGTools - http://gpgtools.org iQIVAwUBVjlq63Kl2rkXzB/gAQj04Q/+Lfxvp1SYlSbQtf89x2V4Ya5sstQ7wSzN 3V/z/36Se9CdpCUmuGaKElq+MI7thPE7mn0vnDCNgd89QhL1i+eoieJ0FCiSHXel G3axLsRMGW9RdUQz+bdMRdSMnU3Grm9MRH33uspPqWKelTpMAIyonXGQmofQSOA1 KrNDIaPFg2U4c8y58SZ8l1EwcNnFxCpnbx4VG6a+WeNmdpTyqFfjgDA2t9qNPDnO 9i0wfIYxpi85OJZtybba/t1aIXPALfxPKY03Rbvc2MnK5OKWFjxAXHo8LNMAzt3y 6+leREMQj0trSHBLxC0UoKfLqXcrxczLdXoG4XgygMqJqSEflEOiiedd71EJoxwg dbVDuKjqxH4g1Ios91FNLubhC+GhS/6R+mssTtIwpSDtevV1Ev52hIpXsWw5VpY/ oZ+/tNcjYwsmO7nSiVxvGx2wkMo50EfTCKfpyYLI19WAAnhXUDG0F5GU0jYzoDao JQV43yT/Zswl3PzgrY31sI21tnxtW8ke69pxdC64C1xr2zZ4HZRiWw6biPWvpPlk JzP0/Kw/NsLuNL5gmSiDupv72uZ5UynvLZiaGtNnWSKZadS5j8OX7d3XmC8qRPsX GoQJiZBAQxPrIq6ESzcKuGvvbngDeaUzOmmaSDgic1HxCDK4fUoNXQKd5GPIBJsX RekIQDAukCc= =KMZQ -----END PGP SIGNATURE----- --Apple-Mail=_CCEA3C87-F09E-4ABD-A2B3-E40C5E9468A2-- From agruenba@redhat.com Tue Nov 3 20:19:35 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 91F9B7FBB for ; Tue, 3 Nov 2015 20:19:35 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 73E51304059 for ; Tue, 3 Nov 2015 18:19:35 -0800 (PST) X-ASG-Debug-ID: 1446603572-04cbb024230aa40001-NocioJ Received: from mail-lb0-f177.google.com (mail-lb0-f177.google.com [209.85.217.177]) by cuda.sgi.com with ESMTP id dDKGAgDBvfT0WzH1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 03 Nov 2015 18:19:34 -0800 (PST) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.85.217.177 Received: by lbbec13 with SMTP id ec13so5800349lbb.0 for ; Tue, 03 Nov 2015 18:19:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat_com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=AIuEDZAbRn4B/F2Sh18ZRoCR7ULBjQb17/+9e5rvtO0=; b=EsDP+B5ejvykVdVMNh5LjHvl59jyiw2QdjVkLDlnJ8aD+t0Skplu+yev8SjAGbGIqv +UMC5hCJl+Jehjtu1CnLjjxdSslg3ePrBf//OmUzm5MzFJV/V1uX5MgBYV0JeMixldQO rjazML97ovDgXNGj5bibTuzVY3Qd6/M8hYoB4hNqiZDpNLPr57ilq8AHxGaPa/nNc7Ar jzKfTxLFSWlznmKKXY7KpGZOgBh00PShwrSICU+iZPeKIZ1lTEj8WXCQSPUrZjY1IcKO 9UMNCNnDqVIW4ACXJo9+1KLDGm9VjUEwV7BvHZc6Q632EiIFPNg/7VUqSqg2j2RyyrZ7 Kk1Q== 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=AIuEDZAbRn4B/F2Sh18ZRoCR7ULBjQb17/+9e5rvtO0=; b=hDbRMHM/NE4XaL5iVls7zmyd1viSY/nkUEOghNuthhHXQ4Jw+8pFXCkdAV6GdUV2n6 L61oMeQAT9ECNEu2E9b5Az8FHcx2hX0+OlgPqxmsnkrd5qZKEekmqELyOgNUwy0uQyyr fFO93LZMh45DXS+Dk+KuCotVsqW0YeH003ftnkCX3wfw4Y5ouuTazmuCZr9joaw8NdzS 4twcUg9TlsiIaQC5jTcNYXd0cXkkk5ygYJrMvcp0x+BKkXwFMQl/jEzUbljE9pE0telT 30o5CHvg4P1UdkgrIa0h1RwA0sO4ggzU0OqrtPUf3Bi4XDLnHFwdW9y7Q3DRNX9AKd3U +x0w== X-Gm-Message-State: ALoCoQkMQDdq7mWUL5WniplmsZUjkUIiNIe6I57eNhwxbaZqxr7HU3hMRXbNr++M+TA9ii73xBul MIME-Version: 1.0 X-Received: by 10.112.151.106 with SMTP id up10mr10701572lbb.85.1446603572432; Tue, 03 Nov 2015 18:19:32 -0800 (PST) Received: by 10.112.53.42 with HTTP; Tue, 3 Nov 2015 18:19:32 -0800 (PST) In-Reply-To: <6A710DA3-0B03-4371-A1EB-7AF39F684EDC@dilger.ca> References: <1446563847-14005-1-git-send-email-agruenba@redhat.com> <1446563847-14005-21-git-send-email-agruenba@redhat.com> <6A710DA3-0B03-4371-A1EB-7AF39F684EDC@dilger.ca> Date: Wed, 4 Nov 2015 03:19:32 +0100 Message-ID: Subject: Re: [PATCH v13 20/51] ext4: Add richacl support From: Andreas Gruenbacher X-ASG-Orig-Subj: Re: [PATCH v13 20/51] ext4: Add richacl support To: Andreas Dilger Cc: Alexander Viro , "Theodore Ts'o" , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4 , XFS Developers , LKML , linux-fsdevel , Linux NFS Mailing List , linux-cifs@vger.kernel.org, Linux API , "Aneesh Kumar K.V" Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-lb0-f177.google.com[209.85.217.177] X-Barracuda-Start-Time: 1446603573 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24091 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, Nov 4, 2015 at 3:13 AM, Andreas Dilger wrote: > Patch looks reasonable. One minor cleanup below that could be fixed when > the patch series is refreshed, and you can add: > > Reviewed-by: Andreas Dilger Okay, thank you. Andreas From adilger@dilger.ca Tue Nov 3 20:21:01 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 DD9067F69 for ; Tue, 3 Nov 2015 20:21:01 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id A52C0304051 for ; Tue, 3 Nov 2015 18:21:01 -0800 (PST) X-ASG-Debug-ID: 1446603660-04bdf03f040ae30001-NocioJ Received: from mail-pa0-f48.google.com (mail-pa0-f48.google.com [209.85.220.48]) by cuda.sgi.com with ESMTP id CL5LZWCA84v474yr (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 03 Nov 2015 18:21:00 -0800 (PST) X-Barracuda-Envelope-From: adilger@dilger.ca X-Barracuda-RBL-Trusted-Forwarder: 209.85.220.48 Received: by pabfh17 with SMTP id fh17so36577115pab.0 for ; Tue, 03 Nov 2015 18:21:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=dilger_ca.20150623.gappssmtp.com; s=20150623; h=subject:mime-version:content-type:from:in-reply-to:date:cc :message-id:references:to; bh=cOF2i2lxBr5vH7S3ZDMTdu/0xBFpupR/Xs9y7gQrKxA=; b=ayD21kG8+NOtvPiP82T15d4v/qAy11EBtV3suFGIs/xRs87csuQkmAPZW8r23sSz1l HApk3otay7aPci77gm+K+qX85VnTAepIhvZQrEs8xlB0/7nQZreu9k+wnCCBDGNlnZhD Rx5heukrAha0B6wPbRohcB17lzf3kXghyMStRt6M6USCwm6kwnxSd+cTJGnpGmS8Q7st dkQ1zxpfjZpcNyVGtrKzj6GQnDMTHHAOO54CNuUT8PuAWZt0VpTZvsTAK/xXxXucGwpF 6pKSvBb0HjBiTwh2iK0NVjsEBjr5sv9RyEgQZru4Auc6nE8i0UR2HtRcPGqmedMATaqC bpFw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:subject:mime-version:content-type:from :in-reply-to:date:cc:message-id:references:to; bh=cOF2i2lxBr5vH7S3ZDMTdu/0xBFpupR/Xs9y7gQrKxA=; b=MYASXnnFVsrB+KcNZrxcwN1M2DsG2OCsKACmkQS030EtZkBkXx7nC+ZpgFb9Qjedrs lf+Ka9iREpXEM+txtqlV5xJPNbPr2PUFM5lbFbN+esWdNM3TOu9uqToE9BMlD2IVgyN6 6hmSx5NJWZumjjrLxYPqrUCz48RGzazJEJ64vHKR2QQZPYsASfqApp72U3S29TMeKKWT OicERuMtOriqQn2TmmeQQ/8G5Ev64O4RNhaYQX4x651bJkex/MUKq0BCrLDbLwSJxxtI cvaDzzBMAylgHSYeQTBXKYz1BjGSbUlofzPgiA9EqZ+QRvelTJQabT6TyeHk1EXLz5VH JVpQ== X-Gm-Message-State: ALoCoQm1nAMs0KvFzKJNqIR7H7kJW6iAZ8tK5J80genEeLG+mKSyuVfkPwcY14GUljUPR2PScid0 X-Received: by 10.68.103.161 with SMTP id fx1mr37707563pbb.42.1446603659981; Tue, 03 Nov 2015 18:20:59 -0800 (PST) Received: from cabot-wlan.adilger.int (S0106002191d9348b.cg.shawcable.net. [96.51.76.157]) by smtp.gmail.com with ESMTPSA id nu5sm31897923pbb.65.2015.11.03.18.20.52 (version=TLS1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 03 Nov 2015 18:20:59 -0800 (PST) Subject: Re: [PATCH v13 43/51] ext4: Don't allow unmapped identifiers in richacls X-Barracuda-Apparent-Source-IP: 96.51.76.157 X-Barracuda-BBL-IP: 96.51.76.157 Mime-Version: 1.0 (Mac OS X Mail 8.2 \(2104\)) X-ASG-Orig-Subj: Re: [PATCH v13 43/51] ext4: Don't allow unmapped identifiers in richacls Content-Type: multipart/signed; boundary="Apple-Mail=_951D32E2-636D-4F9D-890C-9450C7F0D2FA"; protocol="application/pgp-signature"; micalg=pgp-sha256 X-Pgp-Agent: GPGMail 2.5.2 From: Andreas Dilger In-Reply-To: <1446563847-14005-44-git-send-email-agruenba@redhat.com> Date: Tue, 3 Nov 2015 19:20:46 -0700 Cc: Alexander Viro , Theodore Ts'o , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Message-Id: <6E00DAEB-506C-4D93-8131-D12D459D7919@dilger.ca> References: <1446563847-14005-1-git-send-email-agruenba@redhat.com> <1446563847-14005-44-git-send-email-agruenba@redhat.com> To: Andreas Gruenbacher X-Mailer: Apple Mail (2.2104) X-Barracuda-Connect: mail-pa0-f48.google.com[209.85.220.48] X-Barracuda-Start-Time: 1446603660 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24091 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 --Apple-Mail=_951D32E2-636D-4F9D-890C-9450C7F0D2FA Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii > On Nov 3, 2015, at 8:17 AM, Andreas Gruenbacher = wrote: >=20 > Don't allow acls which contain unmapped identifiers: they are = meaningful > for remote file systems only. Looks fine. Reviewed-by: Andreas Dilger > Signed-off-by: Andreas Gruenbacher > --- > fs/ext4/richacl.c | 4 ++++ > 1 file changed, 4 insertions(+) >=20 > diff --git a/fs/ext4/richacl.c b/fs/ext4/richacl.c > index 906d048..2115385 100644 > --- a/fs/ext4/richacl.c > +++ b/fs/ext4/richacl.c > @@ -74,6 +74,10 @@ __ext4_set_richacl(handle_t *handle, struct inode = *inode, struct richacl *acl) > int retval, size; > void *value; >=20 > + /* Don't allow acls with unmapped identifiers. */ > + if (richacl_has_unmapped_identifiers(acl)) > + return -EINVAL; > + > if (richacl_equiv_mode(acl, &mode) =3D=3D 0) { > inode->i_ctime =3D ext4_current_time(inode); > inode->i_mode =3D mode; > -- > 2.5.0 >=20 Cheers, Andreas --Apple-Mail=_951D32E2-636D-4F9D-890C-9450C7F0D2FA Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename=signature.asc Content-Type: application/pgp-signature; name=signature.asc Content-Description: Message signed with OpenPGP using GPGMail -----BEGIN PGP SIGNATURE----- Comment: GPGTools - http://gpgtools.org iQIVAwUBVjlrf3Kl2rkXzB/gAQhIRhAAmFM6Z3Er7qv7heUk5sBoyGEDG2hJCU2M 6AM81ezeI9+BqJ3VHsNLivKEf4tDQLktfe8awj/hkJuBlSp2TT8ILjsr8qDJ+Zbb p4YwN9RG9VUMo3ncBD9UJmZdlv0cjTaEpnwVAAJBDLU//1Km0mLBxujQD6Pjr+/m aN4pxOjJBbApz9RneupgetsRu3H+Bm3II0grAL8DyjQJdPEZ/Vf7ZjDdcbfXXmLQ SMzBmOCs9xquwrgBwb7Ob1Yc+rVqotvQiwuelrl6ZAjbXGwz+nKVNSfxz9vZ+kIA EaevYOYOr4USHXPah3iw0fHNJjmiiLQ6RJPFfT/mjuNvahoC/Q/9O4prrFZq3lP2 s5KGEMEEtQgM6xVGABcY8sDumuZEKW1J/kK5aXSt09nkKmfw9aN2CkWcM5c4FZow 2bMFH6DT7tAnsu/bHcCfj1hbhxqOSDAPg4pjxxirFR+IAN64Wkuk/0KKsu/S2LwX hSmuJt4cKxmURIhMjHysmfnXc4kivMhc/YSKXXqRa0mfUw7+pUqMkzEUzdVIYrz0 qVbZBE6fNI+vZIdESJ3RO3PLw++JVsAfoPr+XXJDeNfy7FPCq+mzIZP+6uq8Q5iE p2Vgg0tafoyFHl88ttZFc2QksLdHHtEQ/A4NM2k6gZIiwbDpHiIgdtww5+/MQhrz /02xQ7FHhKM= =DK1q -----END PGP SIGNATURE----- --Apple-Mail=_951D32E2-636D-4F9D-890C-9450C7F0D2FA-- From agruenba@redhat.com Tue Nov 3 20:28:07 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 ABF5B7FB7 for ; Tue, 3 Nov 2015 20:28:07 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 248CFAC001 for ; Tue, 3 Nov 2015 18:28:07 -0800 (PST) X-ASG-Debug-ID: 1446604084-04cb6c296c0b4c0001-NocioJ Received: from mail-lb0-f179.google.com (mail-lb0-f179.google.com [209.85.217.179]) by cuda.sgi.com with ESMTP id 88WBnwZmPhskWlPV (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 03 Nov 2015 18:28:05 -0800 (PST) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.85.217.179 Received: by lbbkw15 with SMTP id kw15so46747lbb.0 for ; Tue, 03 Nov 2015 18:28:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat_com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=yLmTmPpmXwdczLAqThQLtFK3IdLdSXKlno6FZ3is5Og=; b=iSnTqYl7RpRFaKaB7NBqNB729af3BAw1XgMHDFZi3hQ8zy8I3YSWgYJ654D/5iDst3 WNGeurv67UnwaZJilS5OAgqzN41zkeHvGH2rUoa/jaXC4/VOoxbFGtq9q96FEMIpSJae GN04H3rqCisgB1WyHMjw37Fks86r98oWoAcv9lginYKqmrx29bLBbMOHZDlxrOq5X2JZ vtWeKjGTljnkrSRbD/rxYj7CIqFHNyJWia6FqF5PyCpPqceduPujLI+AqJAFf5xs9bGu /kgtn+PNJSpVTS+ryUOBwXO5AWN52v+sBo4tQUuuXGJmlYBBcyBMp0l9DhoPuzthaPza Hq8A== 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=yLmTmPpmXwdczLAqThQLtFK3IdLdSXKlno6FZ3is5Og=; b=iv/Jhg9VCig4HyJJ+x57nlt5r0VF7yZaOBnhWLrtSHiKGZDgVM7b3VZ3JZecVuSKLC VldmT91IET6dnDi4AzWgy0MvZZD5t2KufSI2l268rapBJvJTqGKO6UCXUSEX/ibxkNq8 z51xh7q7kKVdqeOjhO6c/tW7LjDCKp5V+lnoCyHpQOP8aUROR8j7k+gR+SrLvoTLv8/M 45FgYzTZkAkd0N9x5LDgLKyOADxly8vQrcxOm7N8bdUwYIrLpUakZ7dtOlyE6gb5W4MU K/R4BT/Ah4/wcKa8/5gVQjYVm+iR9jOkxshe4cGPmWmC94E7L4HgHNMkYV7+XDhU8UBg BtHA== X-Gm-Message-State: ALoCoQlf0t+Rvgcs1cmmgfWx5sBr2MoqAWY8PRBLtuTu3KZyZ7ZM9WD4JTTOuanvFFbudJoWlNxK MIME-Version: 1.0 X-Received: by 10.112.170.201 with SMTP id ao9mr9413349lbc.104.1446604083777; Tue, 03 Nov 2015 18:28:03 -0800 (PST) Received: by 10.112.53.42 with HTTP; Tue, 3 Nov 2015 18:28:03 -0800 (PST) In-Reply-To: <06282344-726E-49AD-936B-7BFF8F43B967@dilger.ca> References: <1446563847-14005-1-git-send-email-agruenba@redhat.com> <1446563847-14005-22-git-send-email-agruenba@redhat.com> <06282344-726E-49AD-936B-7BFF8F43B967@dilger.ca> Date: Wed, 4 Nov 2015 03:28:03 +0100 Message-ID: Subject: Re: [PATCH v13 21/51] ext4: Add richacl feature flag From: Andreas Gruenbacher X-ASG-Orig-Subj: Re: [PATCH v13 21/51] ext4: Add richacl feature flag To: Andreas Dilger Cc: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4 , XFS Developers , LKML , linux-fsdevel , Linux NFS Mailing List , linux-cifs@vger.kernel.org, Linux API , "Aneesh Kumar K.V" Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-lb0-f179.google.com[209.85.217.179] X-Barracuda-Start-Time: 1446604084 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24091 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 Andreas, On Wed, Nov 4, 2015 at 3:18 AM, Andreas Dilger wrote: > This patch confuses me. I thought the whole point of INCOMPAT_RICHACL > was that the filesystem should never, ever be mounted without ACL support > because the ACLs will get confused without it. In that case, it doesn't > make sense to have a mount option that _has_ to be specified to mount the > filesystem, and returns an error when trying to disable it. > > It makes more sense to just enable "acl" by default if INCOMPAT_RICHACL > is set in the superblock and not need the mount option at all. It's the commit message that's misleading here, I'll fix it. On richacl filesystems, the acl mount option is always on. It's only on POSIX ACL filesystems that the mount option can be used to turn POSIX ACLs off (which arguably wasn't such a good idea, but there we have it). Thanks, Andreas From adilger@dilger.ca Tue Nov 3 20:33:13 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 62E5F7FC7 for ; Tue, 3 Nov 2015 20:33:13 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id C3562AC002 for ; Tue, 3 Nov 2015 18:33:12 -0800 (PST) X-ASG-Debug-ID: 1446604390-04cb6c296a0b640001-NocioJ Received: from mail-pa0-f51.google.com (mail-pa0-f51.google.com [209.85.220.51]) by cuda.sgi.com with ESMTP id LJcFqd7y1MHAKOHo (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 03 Nov 2015 18:33:10 -0800 (PST) X-Barracuda-Envelope-From: adilger@dilger.ca X-Barracuda-RBL-Trusted-Forwarder: 209.85.220.51 Received: by pabfh17 with SMTP id fh17so36909943pab.0 for ; Tue, 03 Nov 2015 18:33:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=dilger_ca.20150623.gappssmtp.com; s=20150623; h=subject:mime-version:content-type:from:in-reply-to:date:cc :message-id:references:to; bh=OoT8vOo2EqSQIpZPZnCfIz/Of08VA/9hcdLbodd0r+w=; b=vZUgTS4ZnHxiJB7F7EC9v0hVJtae3Ybo3dtyLiqgzIXpVHH0sFMXN8E5OmkVjIv9vg OAzx4w8e9PjYpXTlD+mszv3ne+jY2PJwNYOZwWYJGVYbD2IWJn1yH8Q7TF4+aVINKsO5 pmjh3TSRcnF55Y3WRqYyVUMroXUzT4boCiNG5e3cCKJOI5ONkosoRZv3Fh4jjulpoWhG yuSj5F8ZSeQjlBJPSEcCYdGt3EV6lUa0w1BilTWy1wTCFJ+41k+OgXIiXgGJYLKEq2eB gxupubY/RKiIg0XUnlz+vnhweppSaePNWS+fI6FEfRsjnPlputJFlL8Hgb7hYQj19iyx bQmg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:subject:mime-version:content-type:from :in-reply-to:date:cc:message-id:references:to; bh=OoT8vOo2EqSQIpZPZnCfIz/Of08VA/9hcdLbodd0r+w=; b=H7sdN23aoWSa1tZb2uds7GDuYHlio29uP7By3Nh24tV9jxmQqRfqm5mZEODLXx/+JC ClgVKoqbGFI/cWMRy7UY1stsA9/qGxdeHUbYTSCto9iXYtO8E2Y6bzwvtVsPazXfxBOM ZNlX3EcDulKCW8OM68fJs1wPsN3LOrD3t0OQnUl3dklzPT+WtjlUF3CTrwfNw/gPVqO6 Ak4WwimR9gfvaDCnlEr2IZe3zkKIg2xnAGvu8ELAFojEKi6ZEClmkkwluqUd9hsGjgq4 jcZJoJNEKXk2NTJgOBl6ha+HdCjhKMMop69yQfYl6XAEVA1VYEieyjdmTnfRCtUIdhRV QoPQ== X-Gm-Message-State: ALoCoQmrFY7ikyutwHMz5GFUYx76fuiQLDI/X8pPbTm8AwgNVgcvHpu1NbDuZjAFoeuaBwfiVCZw X-Received: by 10.66.250.202 with SMTP id ze10mr37292122pac.132.1446604390342; Tue, 03 Nov 2015 18:33:10 -0800 (PST) Received: from cabot-wlan.adilger.int (S0106002191d9348b.cg.shawcable.net. [96.51.76.157]) by smtp.gmail.com with ESMTPSA id bn1sm32074431pad.17.2015.11.03.18.33.06 (version=TLS1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 03 Nov 2015 18:33:09 -0800 (PST) Subject: Re: [PATCH v13 02/51] vfs: Add MAY_CREATE_FILE and MAY_CREATE_DIR permission flags X-Barracuda-Apparent-Source-IP: 96.51.76.157 X-Barracuda-BBL-IP: 96.51.76.157 Mime-Version: 1.0 (Mac OS X Mail 8.2 \(2104\)) X-ASG-Orig-Subj: Re: [PATCH v13 02/51] vfs: Add MAY_CREATE_FILE and MAY_CREATE_DIR permission flags Content-Type: multipart/signed; boundary="Apple-Mail=_3E10B02B-D902-4579-9A2C-C87E3793B392"; protocol="application/pgp-signature"; micalg=pgp-sha256 X-Pgp-Agent: GPGMail 2.5.2 From: Andreas Dilger In-Reply-To: <1446563847-14005-3-git-send-email-agruenba@redhat.com> Date: Tue, 3 Nov 2015 19:33:02 -0700 Cc: Theodore Ts'o , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4 , XFS Developers , LKML , linux-fsdevel , Linux NFS Mailing List , linux-cifs@vger.kernel.org, Linux API Message-Id: <507E7A63-024B-4EBD-B0C3-4ABE8280440F@dilger.ca> References: <1446563847-14005-1-git-send-email-agruenba@redhat.com> <1446563847-14005-3-git-send-email-agruenba@redhat.com> To: Andreas Gruenbacher , Alexander Viro X-Mailer: Apple Mail (2.2104) X-Barracuda-Connect: mail-pa0-f51.google.com[209.85.220.51] X-Barracuda-Start-Time: 1446604390 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24091 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 --Apple-Mail=_3E10B02B-D902-4579-9A2C-C87E3793B392 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii On Nov 3, 2015, at 8:16 AM, Andreas Gruenbacher = wrote: >=20 > Richacls distinguish between creating non-directories and directories. = To > support that, add an isdir parameter to may_create(). When checking > inode_permission() for create permission, pass in an additional > MAY_CREATE_FILE or MAY_CREATE_DIR mask flag. >=20 > To allow checking for delete *and* create access when replacing an = existing > file via vfs_rename(), add a replace parameter to may_delete(). >=20 > Signed-off-by: Andreas Gruenbacher > Reviewed-by: J. Bruce Fields > --- > fs/namei.c | 43 +++++++++++++++++++++++++------------------ > include/linux/fs.h | 2 ++ > 2 files changed, 27 insertions(+), 18 deletions(-) >=20 > diff --git a/fs/namei.c b/fs/namei.c > index 224ecf1..0259392 100644 > --- a/fs/namei.c > +++ b/fs/namei.c > @@ -453,7 +453,9 @@ static int sb_permission(struct super_block *sb, = struct inode *inode, int mask) > * this, letting us set arbitrary permissions for filesystem access = without > * changing the "normal" UIDs which are used for other things. > * > - * When checking for MAY_APPEND, MAY_WRITE must also be set in @mask. > + * MAY_WRITE must be set in @mask whenever MAY_APPEND, = MAY_CREATE_FILE, or > + * MAY_CREATE_DIR are set. That way, file systems that don't support = these > + * permissions will check for MAY_WRITE instead. > */ > int inode_permission(struct inode *inode, int mask) > { > @@ -2549,10 +2551,11 @@ EXPORT_SYMBOL(__check_sticky); > * 10. We don't allow removal of NFS sillyrenamed files; it's handled = by > * nfs_async_unlink(). > */ > -static int may_delete(struct inode *dir, struct dentry *victim, bool = isdir) > +static int may_delete(struct inode *dir, struct dentry *victim, > + bool isdir, bool replace) > { > struct inode *inode =3D d_backing_inode(victim); > - int error; > + int error, mask =3D MAY_WRITE | MAY_EXEC; >=20 > if (d_is_negative(victim)) > return -ENOENT; > @@ -2561,7 +2564,9 @@ static int may_delete(struct inode *dir, struct = dentry *victim, bool isdir) > BUG_ON(victim->d_parent->d_inode !=3D dir); > audit_inode_child(dir, victim, AUDIT_TYPE_CHILD_DELETE); >=20 > - error =3D inode_permission(dir, MAY_WRITE | MAY_EXEC); > + if (replace) > + mask |=3D isdir ? MAY_CREATE_DIR : MAY_CREATE_FILE; > + error =3D inode_permission(dir, mask); > if (error) > return error; > if (IS_APPEND(dir)) > @@ -2592,14 +2597,16 @@ static int may_delete(struct inode *dir, = struct dentry *victim, bool isdir) > * 3. We should have write and exec permissions on dir > * 4. We can't do it if dir is immutable (done in permission()) > */ > -static inline int may_create(struct inode *dir, struct dentry *child) > +static inline int may_create(struct inode *dir, struct dentry *child, = bool isdir) > { > + int mask =3D isdir ? MAY_CREATE_DIR : MAY_CREATE_FILE; > + > audit_inode_child(dir, child, AUDIT_TYPE_CHILD_CREATE); > if (child->d_inode) > return -EEXIST; > if (IS_DEADDIR(dir)) > return -ENOENT; > - return inode_permission(dir, MAY_WRITE | MAY_EXEC); > + return inode_permission(dir, MAY_WRITE | MAY_EXEC | mask); > } >=20 > /* > @@ -2649,7 +2656,7 @@ EXPORT_SYMBOL(unlock_rename); > int vfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, > bool want_excl) > { > - int error =3D may_create(dir, dentry); > + int error =3D may_create(dir, dentry, false); > if (error) > return error; >=20 > @@ -3494,7 +3501,7 @@ EXPORT_SYMBOL(user_path_create); >=20 > int vfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, = dev_t dev) > { > - int error =3D may_create(dir, dentry); > + int error =3D may_create(dir, dentry, false); Passing "true" and "false" from the caller doesn't really make it clear to the reader what the argument is for. Since it isn't possible to check the file mode inside may_create() from dentry->d_inode->i_mode (inode doesn't exist yet) then passing "mode" as an argument would at least make the code more readable. "mode" is available in all of the callers. >=20 > if (error) > return error; > @@ -3586,7 +3593,7 @@ SYSCALL_DEFINE3(mknod, const char __user *, = filename, umode_t, mode, unsigned, d >=20 > int vfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) > { > - int error =3D may_create(dir, dentry); > + int error =3D may_create(dir, dentry, true); > unsigned max_links =3D dir->i_sb->s_max_links; >=20 > if (error) > @@ -3667,7 +3674,7 @@ EXPORT_SYMBOL(dentry_unhash); >=20 > int vfs_rmdir(struct inode *dir, struct dentry *dentry) > { > - int error =3D may_delete(dir, dentry, 1); > + int error =3D may_delete(dir, dentry, true, false); This is a prime example why passing "true" and "false" as function = arguments is not very useful, and especially prone to bugs when there are two of = them. That said, this is code originally from Al, so he may have a different opinion. Cheers, Andreas >=20 > if (error) > return error; > @@ -3789,7 +3796,7 @@ SYSCALL_DEFINE1(rmdir, const char __user *, = pathname) > int vfs_unlink(struct inode *dir, struct dentry *dentry, struct inode = **delegated_inode) > { > struct inode *target =3D dentry->d_inode; > - int error =3D may_delete(dir, dentry, 0); > + int error =3D may_delete(dir, dentry, false, false); >=20 > if (error) > return error; > @@ -3923,7 +3930,7 @@ SYSCALL_DEFINE1(unlink, const char __user *, = pathname) >=20 > int vfs_symlink(struct inode *dir, struct dentry *dentry, const char = *oldname) > { > - int error =3D may_create(dir, dentry); > + int error =3D may_create(dir, dentry, false); >=20 > if (error) > return error; > @@ -4006,7 +4013,7 @@ int vfs_link(struct dentry *old_dentry, struct = inode *dir, struct dentry *new_de > if (!inode) > return -ENOENT; >=20 > - error =3D may_create(dir, new_dentry); > + error =3D may_create(dir, new_dentry, false); > if (error) > return error; >=20 > @@ -4194,19 +4201,19 @@ int vfs_rename(struct inode *old_dir, struct = dentry *old_dentry, > if (source =3D=3D target) > return 0; >=20 > - error =3D may_delete(old_dir, old_dentry, is_dir); > + error =3D may_delete(old_dir, old_dentry, is_dir, false); > if (error) > return error; >=20 > if (!target) { > - error =3D may_create(new_dir, new_dentry); > + error =3D may_create(new_dir, new_dentry, is_dir); > } else { > new_is_dir =3D d_is_dir(new_dentry); >=20 > if (!(flags & RENAME_EXCHANGE)) > - error =3D may_delete(new_dir, new_dentry, = is_dir); > + error =3D may_delete(new_dir, new_dentry, = is_dir, true); > else > - error =3D may_delete(new_dir, new_dentry, = new_is_dir); > + error =3D may_delete(new_dir, new_dentry, = new_is_dir, true); > } > if (error) > return error; > @@ -4469,7 +4476,7 @@ SYSCALL_DEFINE2(rename, const char __user *, = oldname, const char __user *, newna >=20 > int vfs_whiteout(struct inode *dir, struct dentry *dentry) > { > - int error =3D may_create(dir, dentry); > + int error =3D may_create(dir, dentry, false); > if (error) > return error; >=20 > diff --git a/include/linux/fs.h b/include/linux/fs.h > index 4efa435..d6e2330 100644 > --- a/include/linux/fs.h > +++ b/include/linux/fs.h > @@ -82,6 +82,8 @@ typedef void (dax_iodone_t)(struct buffer_head = *bh_map, int uptodate); > #define MAY_CHDIR 0x00000040 > /* called from RCU mode, don't block */ > #define MAY_NOT_BLOCK 0x00000080 > +#define MAY_CREATE_FILE 0x00000100 > +#define MAY_CREATE_DIR 0x00000200 >=20 > /* > * flags in file.f_mode. Note that FMODE_READ and FMODE_WRITE must = correspond > -- > 2.5.0 >=20 Cheers, Andreas --Apple-Mail=_3E10B02B-D902-4579-9A2C-C87E3793B392 Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename=signature.asc Content-Type: application/pgp-signature; name=signature.asc Content-Description: Message signed with OpenPGP using GPGMail -----BEGIN PGP SIGNATURE----- Comment: GPGTools - http://gpgtools.org iQIVAwUBVjluXnKl2rkXzB/gAQhnew//Xe1j6dVAnqqkD270AcQPLVGrtC4VAGn4 LpMJ3phONjrAEorMAKDqDjD5KIJPm12T8uKHBpIwX/SvNLKwJvTUt54ghXdXRbIC HKAg1FvOSXKIhY8kBugK2WrzRLSv4Af4eBcIpFB+tuzyz4KjyFk16GPCqTW5a6f1 5F64AfiZXBoC3urtTNlsVU7GGy6p6PFmgKH2BJQk5PlhPQSRmUAE22rgCTvHUOX1 MEaAvVdNv79CldjGoc8GC5hrtYAxbFtG2UEveF/nWyUpGYo3+eWzBsbaH4i0DfLU EBvKaK5sPeO+Z+QRwiosebRLA+AYy8iVqjJtB8ROlEdLcqhYrZqyyMypwRxRz9cM LFelz+zuyuNnh29CaG9V1H0+MZMDsNCFLsN7wOrhz6MEWpFrF6Bm74H/zu+d3dAv KS6PaPXtcVkkdXncAMmcSWYXwgF1NukJEBF+433ZXjlBvPzINWp54vebogVNLOJk uRz1FPKv09nXrIouXwxqbaOC1qNQIjwNfiTHfDoqRZYHjVmCX51sKtNRk/oP8u++ QZs2YWhk/FxzDZb8TX2VS0GHF7JsKojI/G2cbvaRp2v2p+iebkMfctHrCKJZz2dE FUlTM5lX0L6nKWgPmFBz+tNmSPkQzMzNsNXbYB/iDPqkr2UJwk5CTgRZ/7wkbBON b5azRC83hBg= =PL0r -----END PGP SIGNATURE----- --Apple-Mail=_3E10B02B-D902-4579-9A2C-C87E3793B392-- From agruenba@redhat.com Tue Nov 3 20:43:34 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 D00A17FC2 for ; Tue, 3 Nov 2015 20:43:34 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 676D6AC002 for ; Tue, 3 Nov 2015 18:43:34 -0800 (PST) X-ASG-Debug-ID: 1446605011-04bdf03f050b820001-NocioJ Received: from mail-lb0-f173.google.com (mail-lb0-f173.google.com [209.85.217.173]) by cuda.sgi.com with ESMTP id 01nBAdhMBvIRYOVG (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 03 Nov 2015 18:43:32 -0800 (PST) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.85.217.173 Received: by lbbkw15 with SMTP id kw15so217343lbb.0 for ; Tue, 03 Nov 2015 18:43:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat_com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=EAff2Tri6RIcnnO0arbcjYPs/SE+xiEu1cV8isM93sA=; b=OMORgaFxonv/sCpJ2oH8Sm5A88ScKEbnGj9JqvU9rLdxw+VAhari8y+TSZwQKLTYy/ Jnkc6rAlyto3ghPn2z9Q6JkXzP4ZYAgaNZHsJ/RxD8o37Mr/KLM6NzfE7BpIyEl/66lo XWtZxoPNgMGqWljKKa0DHlIWD45GSTV2kkCNObLkMGUdFgXiiOWebDEW/eOdJYo2S8/h mVQooZIXEqa0Q5GOtocwuybSZE6nQ3Yqh2hsKPxdk3JnFYIEnpVyHbsEvg1aMs/EeBkj G0mQZ5qZeSK4b9AtBmINDz2/JEMECqMue59RK+kSoDziVK4s9iJq/CC0BP7bpVeClhBa ZKyw== 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=EAff2Tri6RIcnnO0arbcjYPs/SE+xiEu1cV8isM93sA=; b=E52XPMMYt+Irydn/zfmAztJdRzUk2q12bTRB5hXJMZjhtyA1uPXZqERjmP7CpNaQ9W ei7gOzC8v3dvJyrdhWfPH7Ysixadew/PfxLM0nRagi/KWsAFnK4HFu3J8sF+Xh4ve5oq NApyaxnDx4PAZlANvzT+zjAov9Fsfcq7vYG0AA1pKrP9uWjZBi2uTKqObTIMVPVnv8Rc wE/BJz4ld07ac7tO4Fzbja9Jqwd2LmlfaJ8stpeipE6bfEXj3Q5fxt5rkipCj/jQyhyQ CVTk/7WHS9/4TVyJ4L+kIdxqa9an9VX29saAhy13urlAkM8FjUUVbvQvn9Lhk2Q4lrZE XD/g== X-Gm-Message-State: ALoCoQkC57kd7myhvZz5JshC0ZJQc7QXpCZyikmz7Gno1IR/YbWeFbOY/ZP9JKqBilea6gKaBvop MIME-Version: 1.0 X-Received: by 10.112.236.8 with SMTP id uq8mr14840527lbc.116.1446605011151; Tue, 03 Nov 2015 18:43:31 -0800 (PST) Received: by 10.112.53.42 with HTTP; Tue, 3 Nov 2015 18:43:31 -0800 (PST) In-Reply-To: References: <1446563847-14005-1-git-send-email-agruenba@redhat.com> <1446563847-14005-22-git-send-email-agruenba@redhat.com> <06282344-726E-49AD-936B-7BFF8F43B967@dilger.ca> Date: Wed, 4 Nov 2015 03:43:31 +0100 Message-ID: Subject: Re: [PATCH v13 21/51] ext4: Add richacl feature flag From: Andreas Gruenbacher X-ASG-Orig-Subj: Re: [PATCH v13 21/51] ext4: Add richacl feature flag To: Andreas Dilger Cc: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4 , XFS Developers , LKML , linux-fsdevel , Linux NFS Mailing List , linux-cifs@vger.kernel.org, Linux API , "Aneesh Kumar K.V" Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-lb0-f173.google.com[209.85.217.173] X-Barracuda-Start-Time: 1446605012 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24091 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, Nov 4, 2015 at 3:28 AM, Andreas Gruenbacher wrote: > It's the commit message that's misleading here, I'll fix it. Commit message changed to: This feature flag selects richacl instead of POSIX ACL support on the filesystem. When this feature is off, the "acl" and "noacl" mount options control whether POSIX ACLs are enabled. When it is on, richacls are automatically enabled and using the "noacl" mount option leads to an error. Thanks, Andreas From agruenba@redhat.com Tue Nov 3 21:02:38 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 1B1587FC7 for ; Tue, 3 Nov 2015 21:02:38 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 85CD9AC003 for ; Tue, 3 Nov 2015 19:02:34 -0800 (PST) X-ASG-Debug-ID: 1446606147-04cb6c296a0c2d0001-NocioJ Received: from mail-lf0-f41.google.com (mail-lf0-f41.google.com [209.85.215.41]) by cuda.sgi.com with ESMTP id itjukA3SELaXw9tn (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 03 Nov 2015 19:02:28 -0800 (PST) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.85.215.41 Received: by lfbf136 with SMTP id f136so34330283lfb.0 for ; Tue, 03 Nov 2015 19:02:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat_com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=t2OpH9ZDWmHfJJqRidP2uevbtHaaYN/bb0xRG3zpRbQ=; b=saBMWxvZXS3h+ydIVs37kjVkfiGUyKb80NS4YUZSsxe4Vka8am5/O4Nqif4LF09eZi BZlXsmL20kwunkWOw8fyzQVbJzrPVguOaXl/3TqtG0M0pD2E2gIFx+iAmmA3IlQS8Yyb 5LSFg+qGvFhy3OzGRUl7Rc/LfLaOfgJlNhWFlLp790A1ySoiloOt8BRF4BokCPWzL2xc xU4cZmF3vafPmZwCzk5Ti3+4iigq5K93R2R6tt2aNk9xMXNo4XiCrGapJq+hyyf8UgS1 t8iGm8g20mqgPerA1qnqGGeHq2/jIN1PVtj1fzN0XepMfcAMCZ0f6U4ka78RyjWfQ2rq 5dsw== 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=t2OpH9ZDWmHfJJqRidP2uevbtHaaYN/bb0xRG3zpRbQ=; b=UkHzU5S4VuM24t8yvCF08DJXVXMwRDx72R5X5kJ8VlqH/qyOYrk98PtSa5XaXrp9gP zhwS8fW1ceJUxIeN0OQJQtkWpDTB49EwfSAxjIKxEEATrbt3cMdclrSTcMyxeJZX6q1X h9FLbl4jVWcSBH986zM7Suo4IlfIUBUxTI6XFbqIX3NcRM/+NWB0pBJm1EZJuCHfy6HJ yHypdK1pSIO2i6BluweQLtfHZ2s3yAEw5YRuyiYrNVPu4bXH6lOlBRXjS0TIu+6A9Iw4 VeSqOp0KnX9cUH1vLxesBBQigBGl0qFnIfUw5RwG4MaiMEtriLIAfMKCI8lXH8/kgL1v 3n0w== X-Gm-Message-State: ALoCoQns7bQEvRmDVPDDjaAlLXJWLei4l/vTu87kseYWARjYFG3oqTRfvAtrqvlI5S3oa160MQf3 MIME-Version: 1.0 X-Received: by 10.25.170.204 with SMTP id t195mr9255584lfe.41.1446606147373; Tue, 03 Nov 2015 19:02:27 -0800 (PST) Received: by 10.112.53.42 with HTTP; Tue, 3 Nov 2015 19:02:27 -0800 (PST) In-Reply-To: <507E7A63-024B-4EBD-B0C3-4ABE8280440F@dilger.ca> References: <1446563847-14005-1-git-send-email-agruenba@redhat.com> <1446563847-14005-3-git-send-email-agruenba@redhat.com> <507E7A63-024B-4EBD-B0C3-4ABE8280440F@dilger.ca> Date: Wed, 4 Nov 2015 04:02:27 +0100 Message-ID: Subject: Re: [PATCH v13 02/51] vfs: Add MAY_CREATE_FILE and MAY_CREATE_DIR permission flags From: Andreas Gruenbacher X-ASG-Orig-Subj: Re: [PATCH v13 02/51] vfs: Add MAY_CREATE_FILE and MAY_CREATE_DIR permission flags To: Andreas Dilger Cc: Alexander Viro , "Theodore Ts'o" , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4 , XFS Developers , LKML , linux-fsdevel , Linux NFS Mailing List , linux-cifs@vger.kernel.org, Linux API Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-lf0-f41.google.com[209.85.215.41] X-Barracuda-Start-Time: 1446606148 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24092 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, Nov 4, 2015 at 3:33 AM, Andreas Dilger wrote: > On Nov 3, 2015, at 8:16 AM, Andreas Gruenbacher wrote: >> @@ -3667,7 +3674,7 @@ EXPORT_SYMBOL(dentry_unhash); >> >> int vfs_rmdir(struct inode *dir, struct dentry *dentry) >> { >> - int error = may_delete(dir, dentry, 1); >> + int error = may_delete(dir, dentry, true, false); > > This is a prime example why passing "true" and "false" as function arguments > is not very useful, and especially prone to bugs when there are two of them. > > That said, this is code originally from Al, so he may have a different > opinion. Have you checked how vfs_rename uses the is_dir and new_is_dir variables? Using file modes there probably won't help readability. An enum maybe? Thanks, Andreas From ross.zwisler@linux.intel.com Tue Nov 3 22:46:20 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 1645E7FC8 for ; Tue, 3 Nov 2015 22:46:20 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 99DFEAC001 for ; Tue, 3 Nov 2015 20:46:16 -0800 (PST) X-ASG-Debug-ID: 1446612374-04cb6c296d0dda0001-NocioJ Received: from mga14.intel.com ([192.55.52.115]) by cuda.sgi.com with ESMTP id MHW97GE2rppHnik5 for ; Tue, 03 Nov 2015 20:46:14 -0800 (PST) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 192.55.52.115 Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga103.fm.intel.com with ESMTP; 03 Nov 2015 20:46:14 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,241,1444719600"; d="scan'208";a="842629723" Received: from theros.lm.intel.com (HELO linux.intel.com) ([10.232.112.156]) by fmsmga002.fm.intel.com with ESMTP; 03 Nov 2015 20:46:13 -0800 Date: Tue, 3 Nov 2015 21:46:13 -0700 From: Ross Zwisler To: Dan Williams Cc: Ross Zwisler , Dave Chinner , Brian Foster , Jan Kara , xfs@oss.sgi.com, linux-fsdevel , "linux-nvdimm@lists.01.org" Subject: Re: [PATCH 3/6] xfs: Don't use unwritten extents for DAX Message-ID: <20151104044613.GA29575@linux.intel.com> X-ASG-Orig-Subj: Re: [PATCH 3/6] xfs: Don't use unwritten extents for DAX Mail-Followup-To: Ross Zwisler , Dan Williams , Dave Chinner , Brian Foster , Jan Kara , xfs@oss.sgi.com, linux-fsdevel , "linux-nvdimm@lists.01.org" References: <20151029142950.GE11663@bfoster.bfoster> <20151029233756.GS19199@dastard> <20151030123657.GC54905@bfoster.bfoster> <20151102011433.GW19199@dastard> <20151102141509.GA29346@bfoster.bfoster> <20151102214424.GJ10656@dastard> <20151103050413.GB19199@dastard> <20151104005056.GA24710@linux.intel.com> 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-Barracuda-Connect: UNKNOWN[192.55.52.115] X-Barracuda-Start-Time: 1446612374 X-Barracuda-URL: https://192.48.176.15:443/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.24093 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS On Tue, Nov 03, 2015 at 05:02:34PM -0800, Dan Williams wrote: > On Tue, Nov 3, 2015 at 4:50 PM, Ross Zwisler > wrote: > > On Tue, Nov 03, 2015 at 04:04:13PM +1100, Dave Chinner wrote: > >> On Mon, Nov 02, 2015 at 07:53:27PM -0800, Dan Williams wrote: > >> > On Mon, Nov 2, 2015 at 1:44 PM, Dave Chinner wrote: > > <> > >> > > This comes back to the comments I made w.r.t. the pmem driver > >> > > implementation doing synchronous IO by immediately forcing CPU cache > >> > > flushes and barriers. it's obviously correct, but it looks like > >> > > there's going to be a major performance penalty associated with it. > >> > > This is why I recently suggested that a pmem driver that doesn't do > >> > > CPU cache writeback during IO but does it on REQ_FLUSH is an > >> > > architecture we'll likely have to support. > >> > > > >> > > >> > The only thing we can realistically delay is wmb_pmem() i.e. the final > >> > sync waiting for data that has *left* the cpu cache. Unless/until we > >> > get a architecturally guaranteed method to write-back the entire > >> > cache, or flush the cache by physical-cache-way we're stuck with > >> > either non-temporal cycles or looping on potentially huge virtual > >> > address ranges. > >> > >> I'm missing something: why won't flushing the address range returned > >> by bdev_direct_access() during a fsync operation work? i.e. we're > >> working with exactly the same address as dax_clear_blocks() and > >> dax_do_io() use, so why can't we look up that address and flush it > >> from fsync? > > > > I could be wrong, but I don't see a reason why DAX can't use the strategy of > > writing data and marking it dirty in one step and then flushing later in > > response to fsync/msync. I think this could be used everywhere we write or > > zero data - dax_clear_blocks(), dax_io() etc. (I believe that lots of the > > block zeroing code will go away once we have the XFS and ext4 patches in that > > guarantee we will only get written and zeroed extents from the filesystem in > > response to get_block().) I think the PMEM driver, lacking the ability to > > mark things as dirty in the radix tree, etc, will need to keep doing things > > synchronously. > > Not without numbers showing the relative performance of dirtying cache > followed by flushing vs non-temporal + pcommit. Sorry - do you mean that you want to make sure that we get a performance benefit from the "dirty and flush later" path vs the "write and flush now" path? Sure, that seems reasonable. > > Hmm...if we go this path, though, is that an argument against moving the > > zeroing from DAX down into the driver? True, with BRD it makes things nice > > and efficient because you can zero and never flush, and the driver knows > > there's nothing else to do. > > > > For PMEM, though, you lose the ability to zero the data and then queue the > > flushing for later, as you would be able to do if you left the zeroing code in > > DAX. The benefit of this is that if you are going to immediately re-write the > > newly zeroed data (which seems common), PMEM will end up doing an extra cache > > flush of the zeroes, only to have them overwritten and marked as dirty by DAX. > > If we leave the zeroing to DAX we can mark it dirty once, zero it once, write > > it once, and flush it once. > > Why do we lose the ability to flush later if the driver supports > blkdev_issue_zeroout? I think that if you implement zeroing in the driver you'd need to also flush in the driver because you wouldn't have access to the radix tree to be able to mark entries as dirty so you can flush them later. As I think about this more, though, I'm not sure that having the zeroing flush later could work. I'm guessing that the filesystem must require a sync point between the zeroing and the subsequent follow-up writes so that you can sync metadata for the block allocation. Otherwise you could end up in a situation where you've got your metadata pointing at newly allocated blocks but the new zeros are still in the processor cache - if you lose power you've just created an information leak. Dave, Jan, does this make sense? > > This would make us lose the ability to do hardware-assisted flushing in the > > future that requires driver specific knowledge, though I don't think that > > exists yet. > > ioatdma has supported memset() for a while now, but I would prioritize > a non-temporal SIMD implementation first. Sweet, didn't know about that, obviously. :) Thanks for the pointer. > > Perhaps we should leave the zeroing in DAX for now to take > > advantage of the single flush, and then move it down if a driver can improve > > performance with hardware assisted PMEM zeroing? > > Not convinced. I think we should implement the driver zeroing > solution and take a look at performance. I agree, this should all be driven by performance measurements. Thanks for the feedback. From jack@suse.cz Wed Nov 4 03:06:27 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 960C47FD6 for ; Wed, 4 Nov 2015 03:06:27 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 5E3708F8035 for ; Wed, 4 Nov 2015 01:06:24 -0800 (PST) X-ASG-Debug-ID: 1446627976-04bdf03f0314520001-NocioJ Received: from mx2.suse.de (mx2.suse.de [195.135.220.15]) by cuda.sgi.com with ESMTP id 5H2Uess5sS9Os1h0 (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NO) for ; Wed, 04 Nov 2015 01:06:18 -0800 (PST) X-Barracuda-Envelope-From: jack@suse.cz X-Barracuda-Apparent-Source-IP: 195.135.220.15 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 8B46AAC82; Wed, 4 Nov 2015 09:05:57 +0000 (UTC) Received: by quack.suse.cz (Postfix, from userid 1000) id EE83E80F24; Wed, 4 Nov 2015 10:06:12 +0100 (CET) Date: Wed, 4 Nov 2015 10:06:12 +0100 From: Jan Kara To: Ross Zwisler Cc: Dan Williams , Dave Chinner , Brian Foster , Jan Kara , xfs@oss.sgi.com, linux-fsdevel , "linux-nvdimm@lists.01.org" Subject: Re: [PATCH 3/6] xfs: Don't use unwritten extents for DAX Message-ID: <20151104090612.GA10124@quack.suse.cz> X-ASG-Orig-Subj: Re: [PATCH 3/6] xfs: Don't use unwritten extents for DAX References: <20151029233756.GS19199@dastard> <20151030123657.GC54905@bfoster.bfoster> <20151102011433.GW19199@dastard> <20151102141509.GA29346@bfoster.bfoster> <20151102214424.GJ10656@dastard> <20151103050413.GB19199@dastard> <20151104005056.GA24710@linux.intel.com> <20151104044613.GA29575@linux.intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151104044613.GA29575@linux.intel.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: mx2.suse.de[195.135.220.15] X-Barracuda-Start-Time: 1446627977 X-Barracuda-Encrypted: ECDHE-RSA-AES256-SHA X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24098 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Tue 03-11-15 21:46:13, Ross Zwisler wrote: > On Tue, Nov 03, 2015 at 05:02:34PM -0800, Dan Williams wrote: > > > Hmm...if we go this path, though, is that an argument against moving the > > > zeroing from DAX down into the driver? True, with BRD it makes things nice > > > and efficient because you can zero and never flush, and the driver knows > > > there's nothing else to do. > > > > > > For PMEM, though, you lose the ability to zero the data and then queue the > > > flushing for later, as you would be able to do if you left the zeroing code in > > > DAX. The benefit of this is that if you are going to immediately re-write the > > > newly zeroed data (which seems common), PMEM will end up doing an extra cache > > > flush of the zeroes, only to have them overwritten and marked as dirty by DAX. > > > If we leave the zeroing to DAX we can mark it dirty once, zero it once, write > > > it once, and flush it once. > > > > Why do we lose the ability to flush later if the driver supports > > blkdev_issue_zeroout? > > I think that if you implement zeroing in the driver you'd need to also > flush in the driver because you wouldn't have access to the radix tree to > be able to mark entries as dirty so you can flush them later. > > As I think about this more, though, I'm not sure that having the zeroing > flush later could work. I'm guessing that the filesystem must require a > sync point between the zeroing and the subsequent follow-up writes so > that you can sync metadata for the block allocation. Otherwise you could > end up in a situation where you've got your metadata pointing at newly > allocated blocks but the new zeros are still in the processor cache - if > you lose power you've just created an information leak. Dave, Jan, does > this make sense? So the problem you describe does not exist. Thing to keep in mind is that filesystem are designed to work reliably with 'non-persistent' cache in the disk which is common these days. That's why we bother with all that REQ_FLUSH | REQ_FUA and blkdev_issue_flush() stuff after all. Processor cache is exactly that kind of the cache attached to the PMEM storage. And Dave and I try to steer you to a solution that would also treat it equally in DAX filesystems as well :). Now how the problem is currently solved: When we allocate blocks, we just record that information in a transaction in the journal. For DAX case we also submit the IO zeroing those blocks and wait for it. Now if we crash before the transaction gets committed, blocks won't be seen in the inode after a journal recovery and thus no data exposure can happen. As a part of transaction commit, we call blkdev_issue_flush() (or submit REQ_FLUSH request). We expect that to force out all the IO in volatile caches into the persistent storage. So this will also force the zeroing into persistent storage for normal disks and AFAIU if you do zeroing with non-temporal writes in pmem driver and then do wmb_pmem() in response to a flush request we get the same persistency guarantee in pmem case as well. So after a transaction commit we are guaranteed to see zeros in those allocated blocks. So the transaction commit and the corresponding flush request in particular is the sync point you speak about above but the good thing is that in most cases this will happen after real data gets written into those blocks so we save the unnecessary flush. Honza -- Jan Kara SUSE Labs, CR From ross.zwisler@linux.intel.com Wed Nov 4 09:36:22 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 E1A4D7FC1 for ; Wed, 4 Nov 2015 09:36:22 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id D00C6304043 for ; Wed, 4 Nov 2015 07:36:22 -0800 (PST) X-ASG-Debug-ID: 1446651380-04cbb024241f540001-NocioJ Received: from mga01.intel.com ([192.55.52.88]) by cuda.sgi.com with ESMTP id vZZ0UmJsdrWd26MU for ; Wed, 04 Nov 2015 07:36:21 -0800 (PST) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 192.55.52.88 X-ASG-Whitelist: EmailCat (corporate) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga101.fm.intel.com with ESMTP; 04 Nov 2015 07:35:51 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,243,1444719600"; d="scan'208";a="826919632" Received: from theros.lm.intel.com (HELO linux.intel.com) ([10.232.112.156]) by fmsmga001.fm.intel.com with ESMTP; 04 Nov 2015 07:35:51 -0800 Date: Wed, 4 Nov 2015 08:35:51 -0700 From: Ross Zwisler To: Jan Kara Cc: Ross Zwisler , Dan Williams , Dave Chinner , Brian Foster , xfs@oss.sgi.com, linux-fsdevel , "linux-nvdimm@lists.01.org" Subject: Re: [PATCH 3/6] xfs: Don't use unwritten extents for DAX Message-ID: <20151104153551.GA9981@linux.intel.com> X-ASG-Orig-Subj: Re: [PATCH 3/6] xfs: Don't use unwritten extents for DAX Mail-Followup-To: Ross Zwisler , Jan Kara , Dan Williams , Dave Chinner , Brian Foster , xfs@oss.sgi.com, linux-fsdevel , "linux-nvdimm@lists.01.org" References: <20151030123657.GC54905@bfoster.bfoster> <20151102011433.GW19199@dastard> <20151102141509.GA29346@bfoster.bfoster> <20151102214424.GJ10656@dastard> <20151103050413.GB19199@dastard> <20151104005056.GA24710@linux.intel.com> <20151104044613.GA29575@linux.intel.com> <20151104090612.GA10124@quack.suse.cz> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151104090612.GA10124@quack.suse.cz> User-Agent: Mutt/1.5.23 (2014-03-12) X-Barracuda-Connect: UNKNOWN[192.55.52.88] X-Barracuda-Start-Time: 1446651380 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Wed, Nov 04, 2015 at 10:06:12AM +0100, Jan Kara wrote: > On Tue 03-11-15 21:46:13, Ross Zwisler wrote: > > On Tue, Nov 03, 2015 at 05:02:34PM -0800, Dan Williams wrote: > > > > Hmm...if we go this path, though, is that an argument against moving the > > > > zeroing from DAX down into the driver? True, with BRD it makes things nice > > > > and efficient because you can zero and never flush, and the driver knows > > > > there's nothing else to do. > > > > > > > > For PMEM, though, you lose the ability to zero the data and then queue the > > > > flushing for later, as you would be able to do if you left the zeroing code in > > > > DAX. The benefit of this is that if you are going to immediately re-write the > > > > newly zeroed data (which seems common), PMEM will end up doing an extra cache > > > > flush of the zeroes, only to have them overwritten and marked as dirty by DAX. > > > > If we leave the zeroing to DAX we can mark it dirty once, zero it once, write > > > > it once, and flush it once. > > > > > > Why do we lose the ability to flush later if the driver supports > > > blkdev_issue_zeroout? > > > > I think that if you implement zeroing in the driver you'd need to also > > flush in the driver because you wouldn't have access to the radix tree to > > be able to mark entries as dirty so you can flush them later. > > > > As I think about this more, though, I'm not sure that having the zeroing > > flush later could work. I'm guessing that the filesystem must require a > > sync point between the zeroing and the subsequent follow-up writes so > > that you can sync metadata for the block allocation. Otherwise you could > > end up in a situation where you've got your metadata pointing at newly > > allocated blocks but the new zeros are still in the processor cache - if > > you lose power you've just created an information leak. Dave, Jan, does > > this make sense? > > So the problem you describe does not exist. Thing to keep in mind is that > filesystem are designed to work reliably with 'non-persistent' cache in the > disk which is common these days. That's why we bother with all that > REQ_FLUSH | REQ_FUA and blkdev_issue_flush() stuff after all. Processor > cache is exactly that kind of the cache attached to the PMEM storage. And > Dave and I try to steer you to a solution that would also treat it equally > in DAX filesystems as well :). And I'm always grateful for the guidance. :) > Now how the problem is currently solved: When we allocate blocks, we just > record that information in a transaction in the journal. For DAX case we > also submit the IO zeroing those blocks and wait for it. Now if we crash > before the transaction gets committed, blocks won't be seen in the inode > after a journal recovery and thus no data exposure can happen. As a part of > transaction commit, we call blkdev_issue_flush() (or submit REQ_FLUSH > request). We expect that to force out all the IO in volatile caches into > the persistent storage. So this will also force the zeroing into persistent > storage for normal disks and AFAIU if you do zeroing with non-temporal > writes in pmem driver and then do wmb_pmem() in response to a flush request > we get the same persistency guarantee in pmem case as well. So after a > transaction commit we are guaranteed to see zeros in those allocated > blocks. > > So the transaction commit and the corresponding flush request in particular > is the sync point you speak about above but the good thing is that in most > cases this will happen after real data gets written into those blocks so we > save the unnecessary flush. Cool, thank you for the explanation, that makes sense to me. When dealing with normal SSDs and the page cache, does the filesystem keep the zeroes in the page cache, or does it issue it directly to the driver via sb_issue_zeroout()/blkdev_issue_zeroout()? If we keep it in the page cache so that the follow-up writes just update the dirty pages and we end up writing to media once, this seems like it would flow nicely into the idea of zeroing new blocks at the DAX level without flushing and just marking them as dirty in the radix tree. If the zeroing happens via sb_issue_zeroout() then this probably doesn't make sense because the existing flow won't include a fsync/msync type step of the newly zeroed data in the page cache. From jack@suse.cz Wed Nov 4 11:21:59 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 D30F87FD6 for ; Wed, 4 Nov 2015 11:21:59 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id A7F298F8035 for ; Wed, 4 Nov 2015 09:21:56 -0800 (PST) X-ASG-Debug-ID: 1446657712-04bdf03f0420e20001-NocioJ Received: from mx2.suse.de (mx2.suse.de [195.135.220.15]) by cuda.sgi.com with ESMTP id bFcSuACIqFpbNsBV (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NO) for ; Wed, 04 Nov 2015 09:21:53 -0800 (PST) X-Barracuda-Envelope-From: jack@suse.cz X-Barracuda-Apparent-Source-IP: 195.135.220.15 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 5A004AC1D; Wed, 4 Nov 2015 17:21:32 +0000 (UTC) Received: by quack.suse.cz (Postfix, from userid 1000) id E494B80F24; Wed, 4 Nov 2015 18:21:48 +0100 (CET) Date: Wed, 4 Nov 2015 18:21:48 +0100 From: Jan Kara To: Ross Zwisler Cc: Jan Kara , Dan Williams , Dave Chinner , Brian Foster , xfs@oss.sgi.com, linux-fsdevel , "linux-nvdimm@lists.01.org" Subject: Re: [PATCH 3/6] xfs: Don't use unwritten extents for DAX Message-ID: <20151104172148.GB20212@quack.suse.cz> X-ASG-Orig-Subj: Re: [PATCH 3/6] xfs: Don't use unwritten extents for DAX References: <20151102011433.GW19199@dastard> <20151102141509.GA29346@bfoster.bfoster> <20151102214424.GJ10656@dastard> <20151103050413.GB19199@dastard> <20151104005056.GA24710@linux.intel.com> <20151104044613.GA29575@linux.intel.com> <20151104090612.GA10124@quack.suse.cz> <20151104153551.GA9981@linux.intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151104153551.GA9981@linux.intel.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: mx2.suse.de[195.135.220.15] X-Barracuda-Start-Time: 1446657713 X-Barracuda-Encrypted: ECDHE-RSA-AES256-SHA X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24107 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Wed 04-11-15 08:35:51, Ross Zwisler wrote: > On Wed, Nov 04, 2015 at 10:06:12AM +0100, Jan Kara wrote: > > Now how the problem is currently solved: When we allocate blocks, we just > > record that information in a transaction in the journal. For DAX case we > > also submit the IO zeroing those blocks and wait for it. Now if we crash > > before the transaction gets committed, blocks won't be seen in the inode > > after a journal recovery and thus no data exposure can happen. As a part of > > transaction commit, we call blkdev_issue_flush() (or submit REQ_FLUSH > > request). We expect that to force out all the IO in volatile caches into > > the persistent storage. So this will also force the zeroing into persistent > > storage for normal disks and AFAIU if you do zeroing with non-temporal > > writes in pmem driver and then do wmb_pmem() in response to a flush request > > we get the same persistency guarantee in pmem case as well. So after a > > transaction commit we are guaranteed to see zeros in those allocated > > blocks. > > > > So the transaction commit and the corresponding flush request in particular > > is the sync point you speak about above but the good thing is that in most > > cases this will happen after real data gets written into those blocks so we > > save the unnecessary flush. > > Cool, thank you for the explanation, that makes sense to me. > > When dealing with normal SSDs and the page cache, does the filesystem keep the > zeroes in the page cache, or does it issue it directly to the driver via > sb_issue_zeroout()/blkdev_issue_zeroout()? If we keep it in the page cache so Currently we use sb_issue_zeroout() for zeroing out blocks in ext4 (for DAX and in some other cases to avoid splitting extents too much). Note that zeroing blocks in page cache won't work on it's own - blkdev_issue_flush() doesn't force out any dirty pages from page cache so transaction commit wouldn't make sure stale block contents is not exposed. However we actually do have a mechanism in ext4 to force out data from page cache during transaction commit - that is what data=ordered mode is all about - we can attach inode to a transaction and all dirty data of that inode that has underlying blocks allocated is flushed as a part of transaction commit. So this makes sure stale data cannot be seen after a crash in data=ordered mode. XFS doesn't have this mechanism and thus it normally has to put allocated blocks in unwritten extents, submit IO to write data to those blocks, and convert extent to written once IO finishes. > that the follow-up writes just update the dirty pages and we end up > writing to media once, this seems like it would flow nicely into the idea > of zeroing new blocks at the DAX level without flushing and just marking > them as dirty in the radix tree. So for ext4 you could make this work the same way data=ordered mode works - just store zeroes into allocated blocks, mark page as dirty in the radix tree, attach inode to the running transaction, and on transaction commit do the flush. However note that for DAX page faults zeroing needs to happen under fs lock serializing faults to the same page which effectively means it happens inside filesystem's block mapping function and at that place we don't have a page to zero out. So it would require considerable plumbing to make this work even for ext4 and I'm not even speaking of XFS where the flushing mechanism on transaction commit doesn't currently exist AFAIK. Frankly since the savings would be realized only for allocating writes into mmaped file which aren't than common, I'm not convinced this would be worth it. > If the zeroing happens via sb_issue_zeroout() then this probably doesn't > make sense because the existing flow won't include a fsync/msync type > step of the newly zeroed data in the page cache. Honza -- Jan Kara SUSE Labs, CR From jmoyer@redhat.com Wed Nov 4 12:35:07 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 E365A7FD7 for ; Wed, 4 Nov 2015 12:35:07 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id D1C3F30404E for ; Wed, 4 Nov 2015 10:35:07 -0800 (PST) X-ASG-Debug-ID: 1446662103-04cbb0242424050001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id dyPxwZo48v6dofSC (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 04 Nov 2015 10:35:04 -0800 (PST) X-Barracuda-Envelope-From: jmoyer@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 (Postfix) with ESMTPS id 5C747376B83; Wed, 4 Nov 2015 18:35:02 +0000 (UTC) Received: from segfault.boston.devel.redhat.com (segfault.boston.devel.redhat.com [10.19.60.26]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA4IYweD007749 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Wed, 4 Nov 2015 13:34:59 -0500 From: Jeff Moyer To: Dave Chinner Cc: linux-nvdimm@ml01.01.org, "J. Bruce Fields" , linux-mm@kvack.org, Andreas Dilger , "H. Peter Anvin" , Jeff Layton , x86@kernel.org, Ingo Molnar , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, Alexander Viro , Thomas Gleixner , axboe@kernel.dk, "Theodore Ts'o" , linux-kernel@vger.kernel.org, Jan Kara , linux-fsdevel@vger.kernel.org, Andrew Morton , Matthew Wilcox Subject: Re: [RFC 00/11] DAX fsynx/msync support References: <1446149535-16200-1-git-send-email-ross.zwisler@linux.intel.com> <20151030035533.GU19199@dastard> <20151030183938.GC24643@linux.intel.com> <20151101232948.GF10656@dastard> <20151102201029.GI10656@dastard> X-ASG-Orig-Subj: Re: [RFC 00/11] DAX fsynx/msync support X-PGP-KeyID: 1F78E1B4 X-PGP-CertKey: F6FE 280D 8293 F72C 65FD 5A58 1FF8 A7CA 1F78 E1B4 X-PCLoadLetter: What the f**k does that mean? Date: Wed, 04 Nov 2015 13:34:58 -0500 In-Reply-To: (Jeff Moyer's message of "Mon, 02 Nov 2015 16:02:48 -0500") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain 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: 1446662103 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Jeff Moyer writes: >> Hence once the filesystem has waited on the REQ_WRITE|REQ_FLUSH IO >> to complete, we know that all the earlier REQ_WRITE IOs are on >> stable storage, too. Hence there's no need for the elevator to drain >> the queue to guarantee completion ordering - the dispatch ordering >> and flush/fua write semantics guarantee that when the flush/fua >> completes, all the IOs dispatch prior to that flush/fua write are >> also on stable storage... > > Des xfs rely on this model for correctness? If so, I'd say we've got a > problem. Dave? From prvs=87502b8a99=clm@fb.com Wed Nov 4 12:51:14 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 7A03C7FD7 for ; Wed, 4 Nov 2015 12:51:14 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 5C2538F8049 for ; Wed, 4 Nov 2015 10:51:11 -0800 (PST) X-ASG-Debug-ID: 1446663069-04cb6c296d21640001-NocioJ Received: from mx0b-00082601.pphosted.com (mx0b-00082601.pphosted.com [67.231.153.30]) by cuda.sgi.com with ESMTP id nAkDOEhxvbf8qDAE (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 04 Nov 2015 10:51:10 -0800 (PST) X-Barracuda-Envelope-From: prvs=87502b8a99=clm@fb.com X-Barracuda-Apparent-Source-IP: 67.231.153.30 X-ASG-Whitelist: EmailCat (corporate) Received: from pps.filterd (m0001255.ppops.net [127.0.0.1]) by mx0b-00082601.pphosted.com (8.15.0.59/8.15.0.59) with SMTP id tA4IklFq024434; Wed, 4 Nov 2015 10:51:08 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=fb.com; h=date : from : to : subject : message-id : mime-version : content-type; s=facebook; bh=DQGZwvTVlaNBKHbdbFdct7acUsDjvysL8W3Wvq3rNGY=; b=DJ1kxVo/l0cFAAP80JM3y30iNcNcgWbyMClbsmjk9RWV5CrPf/IPFX+Q6gqoUSfpImB4 5JB7ZktH6+Gy+XV7+EfSGkPrcN2NQYsJFh7WoV1K8xcevGn6ofiOLWfu77IL2Sq0FT8x oi5ZJEHlA18y6Wd2JoSXOyaQjDXrNhtwVTU= Received: from mail.thefacebook.com ([199.201.64.23]) by mx0b-00082601.pphosted.com with ESMTP id 1xxfbqfpfg-2 (version=TLSv1/SSLv3 cipher=AES128-SHA bits=128 verify=NOT); Wed, 04 Nov 2015 10:51:08 -0800 Received: from localhost (192.168.52.123) by mail.thefacebook.com (192.168.16.11) with Microsoft SMTP Server (TLS) id 14.3.248.2; Wed, 4 Nov 2015 10:51:06 -0800 Date: Wed, 4 Nov 2015 13:51:03 -0500 From: Chris Mason To: Dave Chinner , , Tejun Heo Subject: [PATCH RFC] use WQ_MEM_RECLAIM for m_log_workqueue Message-ID: <20151104185103.GC5458@ret.masoncoding.com> X-ASG-Orig-Subj: [PATCH RFC] use WQ_MEM_RECLAIM for m_log_workqueue MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Disposition: inline User-Agent: Mutt/1.5.23.1 (2014-03-12) X-Originating-IP: [192.168.52.123] X-Proofpoint-Spam-Reason: safe X-FB-Internal: Safe X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:,, definitions=2015-11-04_12:,, signatures=0 X-Barracuda-Connect: mx0b-00082601.pphosted.com[67.231.153.30] X-Barracuda-Start-Time: 1446663070 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 We're consistently hitting deadlocks here with XFS on recent kernels. After some digging through the crash files, it looks like everyone in the system is waiting for XFS to reclaim memory. Something like this: PID: 2733434 TASK: ffff8808cd242800 CPU: 19 COMMAND: "java" #0 [ffff880019c53588] __schedule at ffffffff818c4df2 #1 [ffff880019c535d8] schedule at ffffffff818c5517 #2 [ffff880019c535f8] _xfs_log_force_lsn at ffffffff81316348 #3 [ffff880019c53688] xfs_log_force_lsn at ffffffff813164fb #4 [ffff880019c536b8] xfs_iunpin_wait at ffffffff8130835e #5 [ffff880019c53728] xfs_reclaim_inode at ffffffff812fd453 #6 [ffff880019c53778] xfs_reclaim_inodes_ag at ffffffff812fd8c7 #7 [ffff880019c53928] xfs_reclaim_inodes_nr at ffffffff812fe433 #8 [ffff880019c53958] xfs_fs_free_cached_objects at ffffffff8130d3b9 #9 [ffff880019c53968] super_cache_scan at ffffffff811a6f73 #10 [ffff880019c539c8] shrink_slab at ffffffff811460e6 #11 [ffff880019c53aa8] shrink_zone at ffffffff8114a53f #12 [ffff880019c53b48] do_try_to_free_pages at ffffffff8114a8ba #13 [ffff880019c53be8] try_to_free_pages at ffffffff8114ad5a #14 [ffff880019c53c78] __alloc_pages_nodemask at ffffffff8113e1b8 #15 [ffff880019c53d88] alloc_kmem_pages_node at ffffffff8113e671 #16 [ffff880019c53dd8] copy_process at ffffffff8104f781 #17 [ffff880019c53ec8] do_fork at ffffffff8105129c #18 [ffff880019c53f38] sys_clone at ffffffff810515b6 #19 [ffff880019c53f48] stub_clone at ffffffff818c8e4d xfs_log_force_lsn is waiting for logs to get cleaned, which is waiting for IO, which is waiting for workers to complete the IO which is waiting for worker threads that don't exist yet: PID: 2752451 TASK: ffff880bd6bdda00 CPU: 37 COMMAND: "kworker/37:1" #0 [ffff8808d20abbb0] __schedule at ffffffff818c4df2 #1 [ffff8808d20abc00] schedule at ffffffff818c5517 #2 [ffff8808d20abc20] schedule_timeout at ffffffff818c7c6c #3 [ffff8808d20abcc0] wait_for_completion_killable at ffffffff818c6495 #4 [ffff8808d20abd30] kthread_create_on_node at ffffffff8106ec82 #5 [ffff8808d20abdf0] create_worker at ffffffff8106752f #6 [ffff8808d20abe40] worker_thread at ffffffff810699be #7 [ffff8808d20abec0] kthread at ffffffff8106ef59 #8 [ffff8808d20abf50] ret_from_fork at ffffffff818c8ac8 I think we should be using WQ_MEM_RECLAIM to make sure this thread pool makes progress when we're not able to allocate new workers. Outside of extensive analysis from gcc, this patch is untested. If it looks good, we'll try it here and report back about the results. Signed-off-by: Chris Mason diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 904f637..40276bd 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -843,7 +843,8 @@ xfs_init_mount_workqueues( goto out_destroy_cil; mp->m_log_workqueue = alloc_workqueue("xfs-log/%s", - WQ_FREEZABLE|WQ_HIGHPRI, 0, mp->m_fsname); + WQ_MEM_RECLAIM|WQ_FREEZABLE|WQ_HIGHPRI, + 0, mp->m_fsname); if (!mp->m_log_workqueue) goto out_destroy_reclaim; From agruenba@redhat.com Wed Nov 4 15:54:55 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 E69127FDB for ; Wed, 4 Nov 2015 15:54:55 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id D69B130404E for ; Wed, 4 Nov 2015 13:54:52 -0800 (PST) X-ASG-Debug-ID: 1446674089-04cb6c296d26040001-NocioJ Received: from mail-lb0-f180.google.com (mail-lb0-f180.google.com [209.85.217.180]) by cuda.sgi.com with ESMTP id HvE8NB6mA9G9YZjm (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Wed, 04 Nov 2015 13:54:50 -0800 (PST) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.85.217.180 Received: by lbbes7 with SMTP id es7so22457521lbb.2 for ; Wed, 04 Nov 2015 13:54:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat_com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=t3ztIN1h/QjSnnrg8g7vHZT4w45dNdlwegl3toFWcLM=; b=JvajgmUHzyCrtmBWI/qq85c5wyBA2ZczRTSNUxaWm6blpjQzC53xqLjCfc9pwKuT8j Oi97J38LosMHIYKosXDwpZHB1qm4gB5Rv2D+z6DinMx81bKeykx+FSqEk8qaAM7C1tNa NVwLW3DHN8Wz484cy1ByzjZWzBgIcSx/MRgKqncIMR6ltlfBrYDXUVtPeDX3NJkTnTHx MjI9bwNF+RMqDye0Chb0SmmzxPOrdnXNhhIeXTkFpiQc+eQ5wITuWK6+ONdJnZBx1xcO wTGO63+GcuELFsr9yFvSR5vJXJXhG8CmfHfUPtYxjp4MOjlk82dWs7AS5XDwr1hTFQOx cTMg== 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=t3ztIN1h/QjSnnrg8g7vHZT4w45dNdlwegl3toFWcLM=; b=RZIVi0VYW63crngXdRFxNFRyPsYhYMMA/4EyF0iBaA2Ux8JaNbTJl3nfWUwu94nP/A 7cRC6q7g95T3upMA5J0IOgw9szETaIlEWFYk5qV95TtJOvhgi5EC9RZ8XEU+xs0KNr/O 1NcmLAqRv88k/CkXVfNja2jW5ur6yLkNQOh0CFewZW5c7qxEBIy2JtI8Yx2AyyFsPWvJ qqDU/y/u5OdMflqfZxAKK/lM/sBBCoLAHwN4lJYG4+H63CrB35hwn0Wyn47fg2ky0UXR C+vB/ieQyNH92uLJdYam8zxGieILPJoPQkqAAT4QLSiiNpvoiQH9DvWTmDT8OBQyXTAV 7TsQ== X-Gm-Message-State: ALoCoQlIOPcpUdT4SSec+rr5Cl5HUncSOBDJEfqYmO1ExLFPzdoLV3mTMFGzrZTkW4zlUrs1YVwt MIME-Version: 1.0 X-Received: by 10.112.168.37 with SMTP id zt5mr2103389lbb.44.1446674088930; Wed, 04 Nov 2015 13:54:48 -0800 (PST) Received: by 10.112.53.42 with HTTP; Wed, 4 Nov 2015 13:54:48 -0800 (PST) In-Reply-To: References: <1446563847-14005-1-git-send-email-agruenba@redhat.com> <1446563847-14005-11-git-send-email-agruenba@redhat.com> Date: Wed, 4 Nov 2015 22:54:48 +0100 Message-ID: Subject: Re: [PATCH v13 10/51] vfs: Cache base_acl objects in inodes From: Andreas Gruenbacher X-ASG-Orig-Subj: Re: [PATCH v13 10/51] vfs: Cache base_acl objects in inodes To: Andreas Dilger Cc: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4 , XFS Developers , LKML , linux-fsdevel , Linux NFS Mailing List , linux-cifs@vger.kernel.org, Linux API Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-lb0-f180.google.com[209.85.217.180] X-Barracuda-Start-Time: 1446674090 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24116 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 Andreas, On Tue, Nov 3, 2015 at 11:29 PM, Andreas Dilger wrote: > On Nov 3, 2015, at 8:16 AM, Andreas Gruenbacher wrote: >> >> POSIX ACLs and richacls are both objects allocated by kmalloc() with a >> reference count which are freed by kfree_rcu(). An inode can either >> cache an access and a default POSIX ACL, or a richacl (richacls do not >> have default acls). To allow an inode to cache either of the two kinds >> of acls, introduce a new base_acl type and convert i_acl and >> i_default_acl to that type. In most cases, the vfs then doesn't have to >> care which kind of acl an inode caches (if any). > > For new wrapper functions like this better to name them as "NOUN_VERB" so > rather than "VERB_NOUN" so that related functions sort together, like > base_acl_init(), base_acl_get(), base_acl_put(), base_acl_refcount(), etc. That's better, yes. I agree with all your comments and I've changed things accordingly. >> @@ -270,7 +270,7 @@ static struct posix_acl *f2fs_acl_clone(const struct posix_acl *acl, >> sizeof(struct posix_acl_entry); >> clone = kmemdup(acl, size, flags); >> if (clone) >> - atomic_set(&clone->a_refcount, 1); >> + atomic_set(&clone->a_base.ba_refcount, 1); > > This should be base_acl_init() since this should also reset the RCU state > if it was just copied from "acl" above. Yes. The rcu_head doesn't need initializing or resetting though. > That wouldn't be quite correct if > there are other fields added to struct base_acl that don't need to be > initialized when it is copied, so possibly base_acl_reinit() would be better > here and below if that will be the case in the near future (I haven't looked > through the whole patch series yet). We won't need a base_acl_reinit() function for now. >> @@ -25,9 +25,9 @@ struct posix_acl **acl_by_type(struct inode *inode, int type) >> { >> switch (type) { >> case ACL_TYPE_ACCESS: >> - return &inode->i_acl; >> + return (struct posix_acl **)&inode->i_acl; >> case ACL_TYPE_DEFAULT: >> - return &inode->i_default_acl; >> + return (struct posix_acl **)&inode->i_default_acl; > > This would be better to use container_of() to unwrap struct base_acl from > struct posix_acl. That avoids the hard requirement (which isn't documented > anywhere) that base_acl needs to be the first member of struct posix_acl. > > I was originally going to write that you should add a comment that base_acl > needs to be the first member of both richacl and posix_acl, but container_of() > is both cleaner and safer. > > Looking further down, that IS actually needed due to the way kfree is used on > the base_acl pointer, but using container_of() is still cleaner and safer > than directly casting double pointers (which some compilers and static > analysis tools will be unhappy with). Well, we would end up with &container_of() here which doesn't work and doesn't make sense, either. Let me change acl_by_type to return a base_acl ** to clean this up. >> @@ -576,6 +576,12 @@ static inline void mapping_allow_writable(struct address_space *mapping) >> #define i_size_ordered_init(inode) do { } while (0) >> #endif >> >> +struct base_acl { >> + union { >> + atomic_t ba_refcount; >> + struct rcu_head ba_rcu; >> + }; >> +}; >> struct posix_acl; > > Is this forward declaration of struct posix_acl even needed anymore after > the change below? There shouldn't be references to the struct in the common > code anymore (at least not by the end of the patch series. The get_acl and set_acl inode operations expect struct posix_acl to be declared. > Hmm, using the base_acl pointer as the pointer to kfree means that the > base_acl structure DOES need to be the first one in both struct posix_acl > and struct richacl, so that needs to be commented at each structure so > it doesn't accidentally break in the future. Yes. I've added comments; there are also BUILD_BUG_ON() asserts in posix_acl_release and richacl_put. >> @@ -57,7 +57,7 @@ static inline struct richacl * >> richacl_get(struct richacl *acl) >> { >> if (acl) >> - atomic_inc(&acl->a_refcount); >> + atomic_inc(&acl->a_base.ba_refcount); >> return acl; > > This should also use base_acl_get() for consistency. That said, where is > the call to base_acl_put() in the richacl code? > Also, where is the change to struct richacl? It looks like this patch would > not be able to compile by itself. Ah, a little problem in how the patches are split. I've fixed it. This code doesn't get pulled into the build because nothing requires CONFIG_FS_RICHACL at that point; that's why I didn't notice. Thanks, Andreas From agruenba@redhat.com Wed Nov 4 16:10:49 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 D49007F4E for ; Wed, 4 Nov 2015 16:10:49 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id B5924304053 for ; Wed, 4 Nov 2015 14:10:46 -0800 (PST) X-ASG-Debug-ID: 1446675043-04cb6c296c26510001-NocioJ Received: from mail-lb0-f176.google.com (mail-lb0-f176.google.com [209.85.217.176]) by cuda.sgi.com with ESMTP id n3QNOlM8hbHG6GKV (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Wed, 04 Nov 2015 14:10:44 -0800 (PST) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.85.217.176 Received: by lbblt2 with SMTP id lt2so3726551lbb.3 for ; Wed, 04 Nov 2015 14:10:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat_com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=ygp3jgQbPLAGLPq1REX2wehuTHOjOU3mLdpD8mf54NI=; b=dypT4c0fPiTegfnNGmzvog9FRzyUonor17cfj75JZHbTqLH1tpPYK1V5xReCFeXjZW kpLTEFuJO87Rk8m/mqtd5Ev+ghXowiA5SixhcQ04gQfKYvYYXeuWGHTrjlJmArqYDuui 4rCzdpGTblqToyem4ezZnqhhfnRAH/otV/i+wRwqP6vkwMWj5xM0sFgBphJ4Tdjz6iIG 8LaOT6PL/xe+e79PvTTGmtmSuiItvYXd1Azj1eTPq5uGF62gXiGj4EEweTcOmBt0riHw bgWnsROERFXic2eAXcE6yn/wxRGZxLiPk3X9uWLmItUajVchLwtm/5nBU82dMCZ4piYD GAfg== 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=ygp3jgQbPLAGLPq1REX2wehuTHOjOU3mLdpD8mf54NI=; b=ZljUK/DPJ+DKx9O7sLyU94oqURahk+ILFLd034Cr9E/C3nVb7VxVMIAOOtICgzrWZr ieaCsxbx1uBPyBz/Zl3RLxPOX7NVl11/J/4O8K5zCx6d55fKzKbapA1q5HccBY3IUG3h VT59TP4yZVVwW8wH5GlWsQfCJhbSrLZA4vmtcq7Ds4/rwKcRpRBsprr4LWJs/qp6r5om VAtBvWDDxW8rMddi37nmPY8dlXwtl1ATAkYcYeQogxf8V1TuAeey/hmgG9Qd+ypR7gP1 vtam7hpJyg+av7NNIrjWEyTuF3U+Og90ry19sMGkNa8nakpftjVpVwLTjK5w0WUDoH6w CIWA== X-Gm-Message-State: ALoCoQkta++VNFe9YGk76SqBFsW+eJOBVEikVO16biBjtawUqdDVWonXx/afIQ1ypGmv3tcKKU/g MIME-Version: 1.0 X-Received: by 10.112.64.72 with SMTP id m8mr2093953lbs.41.1446675043196; Wed, 04 Nov 2015 14:10:43 -0800 (PST) Received: by 10.112.53.42 with HTTP; Wed, 4 Nov 2015 14:10:43 -0800 (PST) In-Reply-To: <713E53A4-D073-4745-B57D-77AD07E89957@dilger.ca> References: <1446563847-14005-1-git-send-email-agruenba@redhat.com> <1446563847-14005-13-git-send-email-agruenba@redhat.com> <713E53A4-D073-4745-B57D-77AD07E89957@dilger.ca> Date: Wed, 4 Nov 2015 23:10:43 +0100 Message-ID: Subject: Re: [PATCH v13 12/51] vfs: Cache richacl in struct inode From: Andreas Gruenbacher X-ASG-Orig-Subj: Re: [PATCH v13 12/51] vfs: Cache richacl in struct inode To: Andreas Dilger Cc: Alexander Viro , "Theodore Ts'o" , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4 , XFS Developers , LKML , linux-fsdevel , Linux NFS Mailing List , linux-cifs@vger.kernel.org, Linux API Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-lb0-f176.google.com[209.85.217.176] X-Barracuda-Start-Time: 1446675044 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24116 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 Andreas, On Wed, Nov 4, 2015 at 3:03 AM, Andreas Dilger wrote: >> @@ -33,7 +33,7 @@ richacl_alloc(int count, gfp_t gfp) >> struct richacl *acl = kzalloc(size, gfp); >> >> if (acl) { >> - atomic_set(&acl->a_refcount, 1); >> + atomic_set(&acl->a_base.ba_refcount, 1); >> acl->a_count = count; >> } >> return acl; >> @@ -52,7 +52,7 @@ richacl_clone(const struct richacl *acl, gfp_t gfp) >> >> if (dup) { >> memcpy(dup, acl, size); >> - atomic_set(&dup->a_refcount, 1); >> + atomic_set(&dup->a_base.ba_refcount, 1); > > These two calls should be base_acl_init(). Yes. This should all be fixed in the next snapshot. Thanks, Andreas From Trainer-SvenBuntfuss@t-online.de Wed Nov 4 18:07:02 2015 Return-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=FREEMAIL_FORGED_REPLYTO, FREEMAIL_REPLYTO_END_DIGIT,HTML_MESSAGE,MISSING_MIMEOLE,T_FRT_CONTACT 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 084BB7FE5 for ; Wed, 4 Nov 2015 18:07:02 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id C3686304053 for ; Wed, 4 Nov 2015 16:06:58 -0800 (PST) X-ASG-Debug-ID: 1446682014-04bdf03f032b090001-NocioJ Received: from mailout12.t-online.de (mailout12.t-online.de [194.25.134.22]) by cuda.sgi.com with ESMTP id ku5H2IBGBuWdywJ6 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 04 Nov 2015 16:06:55 -0800 (PST) X-Barracuda-Envelope-From: Trainer-SvenBuntfuss@t-online.de X-Barracuda-Apparent-Source-IP: 194.25.134.22 Received: from fwd13.aul.t-online.de (fwd13.aul.t-online.de [172.20.27.62]) by mailout12.t-online.de (Postfix) with SMTP id B3F264D8506; Thu, 5 Nov 2015 01:06:53 +0100 (CET) Received: from spica07.aul.t-online.de (GurxMqZcQhnC3lFDzVTPt1AGaf04bvmqzRES5Aw4QTKko2zk-IwiAiIKDlw5ikoZ0E@[172.20.102.133]) by fwd13.aul.t-online.de with esmtp id 1Zu84r-2SngxM0; Thu, 5 Nov 2015 01:06:53 +0100 Date: Thu, 5 Nov 2015 01:06:53 +0100 (MET) From: Odell Fossoun Sender: Odell Fossoun Reply-To: "odellfossoun8@hotmail.com" To: "odellfossoun@hotmail.com" Message-ID: <1446682013074.168753.2d5b9c6128d1dccbb4cd705cdf585f99dd0c4c0a@spica.telekom.de> Subject: =?UTF-8?Q?odoslanie_spr=C3=A1vy?= MIME-Version: 1.0 X-ASG-Orig-Subj: =?UTF-8?Q?odoslanie_spr=C3=A1vy?= Content-Type: multipart/alternative; boundary="----=_Part_199465_784053254.1446682013075" Importance: normal X-MSMail-Priority: normal X-Priority: 3 X-UMS: email X-ID: GurxMqZcQhnC3lFDzVTPt1AGaf04bvmqzRES5Aw4QTKko2zk-IwiAiIKDlw5ikoZ0E@t-dialin.net X-TOI-MSGID: 42f611c9-38fe-4d2d-9413-ad9d329ca100 X-Barracuda-Connect: mailout12.t-online.de[194.25.134.22] X-Barracuda-Start-Time: 1446682015 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/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=BSF_SC0_MISMATCH_TO, HTML_MESSAGE, K2_MISSING_MIMEOLE, MISSING_MIMEOLE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24120 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.00 HTML_MESSAGE BODY: HTML included in message 0.20 MISSING_MIMEOLE Message has X-MSMail-Priority, but no X-MimeOLE 1.19 K2_MISSING_MIMEOLE Message has X-MSMail-Priority, but no X-MimeOLE ------=_Part_199465_784053254.1446682013075 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Drah=C3=BD priate=C4=BE, P=C3=A1=C4=8Dilo sa moje predch=C3=A1dzaj=C3=BAce spr=C3=A1va doraz=C3=AD d= o va=C5=A1ej schr=C3=A1nky? =C4=8Cakal som na=20 odpove=C4=8F, tak=C5=BEe som sa rozhodol V=C3=A1s kontaktova=C5=A5 znovu oh= =C4=BEadom svojho=20 zosnul=C3=A9ho str=C3=BDka dedi=C4=8Dstva. Ak m=C3=A1te z=C3=A1ujem o viac inform=C3=A1ci=C3=AD potvrdi=C5=A5 =C3=BAda= je ni=C5=BE=C5=A1ie. Krstn=C3=A9 meno: priezvisko: Krajina p=C3=B4vodu: S pozdravom, Odell Fossoun ------=_Part_199465_784053254.1446682013075 Content-Type: text/html; charset="utf-8" Content-Transfer-Encoding: quoted-printable

Drahý priate=C4=BE,


Pá=C4=8Dilo sa moje predchádzajúce sprá= ;va dorazí do vašej schránky? =C4=8Cakal som na odpove= =C4=8F, tak=C5=BEe som sa rozhodol Vás kontaktova=C5=A5 znovu oh=C4= =BEadom svojho zosnulého strýka dedi=C4=8Dstva.


Ak máte záujem o viac informácií potvr= di=C5=A5 údaje ni=C5=BEšie.


Krstné meno:
priezvisko:
Krajina pôvodu:


S pozdravom,
Odell Fossoun



------=_Part_199465_784053254.1446682013075-- From david@fromorbit.com Thu Nov 5 02:33:20 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 47D477FB5 for ; Thu, 5 Nov 2015 02:33:20 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 176878F8049 for ; Thu, 5 Nov 2015 00:33:16 -0800 (PST) X-ASG-Debug-ID: 1446712393-04bdf03f03392d0001-NocioJ Received: from ipmail06.adl6.internode.on.net (ipmail06.adl6.internode.on.net [150.101.137.145]) by cuda.sgi.com with ESMTP id XHzaOWeJ3Q6QTXxq for ; Thu, 05 Nov 2015 00:33:13 -0800 (PST) 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: A2AhCgDYEztWPHy2LHleKAECgxCBQoZcpBsBAQEBAQEGiy+JLYYMAgIBAQKBM00BAQEBAQEHAQEBAUE/hDUBAQEDAScTHCMFCwgDDgoJJQ8FJQMHGhOIJgfCAgEBCAIBIBmFdIVFhESEdQWWSIgNhQ6cSoJ0HYFqKjSDVoFJAQEB Received: from ppp121-44-182-124.lns20.syd7.internode.on.net (HELO dastard) ([121.44.182.124]) by ipmail06.adl6.internode.on.net with ESMTP; 05 Nov 2015 19:03:10 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZuFyn-0003v0-GF; Thu, 05 Nov 2015 19:33:09 +1100 Date: Thu, 5 Nov 2015 19:33:09 +1100 From: Dave Chinner To: Jeff Moyer Cc: Ross Zwisler , linux-kernel@vger.kernel.org, "H. Peter Anvin" , "J. Bruce Fields" , Theodore Ts'o , Alexander Viro , Andreas Dilger , Dan Williams , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@ml01.01.org, x86@kernel.org, xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox , axboe@kernel.dk Subject: Re: [RFC 00/11] DAX fsynx/msync support Message-ID: <20151105083309.GJ19199@dastard> X-ASG-Orig-Subj: Re: [RFC 00/11] DAX fsynx/msync support References: <1446149535-16200-1-git-send-email-ross.zwisler@linux.intel.com> <20151030035533.GU19199@dastard> <20151030183938.GC24643@linux.intel.com> <20151101232948.GF10656@dastard> <20151102201029.GI10656@dastard> 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: 1446712393 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24128 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- [ sorry for slow response, been without an internet connection for ~36 hours ] On Mon, Nov 02, 2015 at 04:02:48PM -0500, Jeff Moyer wrote: > Dave Chinner writes: > > > On Mon, Nov 02, 2015 at 09:22:15AM -0500, Jeff Moyer wrote: > >> Dave Chinner writes: > >> > >> > Further, REQ_FLUSH/REQ_FUA are more than just "put the data on stable > >> > storage" commands. They are also IO barriers that affect scheduling > >> > of IOs in progress and in the request queues. A REQ_FLUSH/REQ_FUA > >> > IO cannot be dispatched before all prior IO has been dispatched and > >> > drained from the request queue, and IO submitted after a queued > >> > REQ_FLUSH/REQ_FUA cannot be scheduled ahead of the queued > >> > REQ_FLUSH/REQ_FUA operation. > >> > > >> > IOWs, REQ_FUA/REQ_FLUSH not only guarantee data is on stable > >> > storage, they also guarantee the order of IO dispatch and > >> > completion when concurrent IO is in progress. > >> > >> This hasn't been the case for several years, now. It used to work that > >> way, and that was deemed a big performance problem. Since file systems > >> already issued and waited for all I/O before sending down a barrier, we > >> decided to get rid of the I/O ordering pieces of barriers (and stop > >> calling them barriers). > >> > >> See commit 28e7d184521 (block: drop barrier ordering by queue draining). > > > > Yes, I realise that, even if I wasn't very clear about how I wrote > > it. ;) > > > > Correct me if I'm wrong: AFAIA, dispatch ordering (i.e. the "IO > > barrier") is still enforced by the scheduler via REQ_FUA|REQ_FLUSH > > -> ELEVATOR_INSERT_FLUSH -> REQ_SOFTBARRIER and subsequent IO > > scheduler calls to elv_dispatch_sort() that don't pass > > REQ_SOFTBARRIER in the queue. > > This part is right. > > > IOWs, if we queue a bunch of REQ_WRITE IOs followed by a > > REQ_WRITE|REQ_FLUSH IO, all of the prior REQ_WRITE IOs will be > > dispatched before the REQ_WRITE|REQ_FLUSH IO and hence be captured > > by the cache flush. > > But this part is not. It is up to the I/O scheduler to decide when to > dispatch requests. It can hold on to them for a variety of reasons. > Flush requests, however, do not go through the I/O scheduler. At the That's pure REQ_FLUSH bios, right? Aren't data IOs with REQ_FLUSH|REQ_FUA sorted like any other IO? > very moment that the flush request is inserted, it goes directly to the > dispatch queue (assuming no other flush is in progress). The prior > requests may still be waiting in the I/O scheduler's internal lists. > > So, any newly dispatched I/Os will certainly not get past the REQ_FLUSH. > However, the REQ_FLUSH is very likely to jump ahead of prior I/Os in the > queue. Uh, ok, that's different, and most definitely not the "IO barrier" I was under the impression REQ_FLUSH|REQ_FUA gave us. > > Hence once the filesystem has waited on the REQ_WRITE|REQ_FLUSH IO > > to complete, we know that all the earlier REQ_WRITE IOs are on > > stable storage, too. Hence there's no need for the elevator to drain > > the queue to guarantee completion ordering - the dispatch ordering > > and flush/fua write semantics guarantee that when the flush/fua > > completes, all the IOs dispatch prior to that flush/fua write are > > also on stable storage... > > Des xfs rely on this model for correctness? If so, I'd say we've got a > problem No, it doesn't. The XFS integrity model doesn't trust the IO layers to tell the truth about IO ordering and completion or for it's developers to fully understand how IO layer ordering works. :P i.e. we wait for full completions of all dependent IO before issuing flushes or log writes that use REQ_FLUSH|REQ_FUA semantics to ensure the dependent IOs are fully caught by the cache flushes... Cheers, Dave. -- Dave Chinner david@fromorbit.com From agruenba@redhat.com Thu Nov 5 05:07:14 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 422D17FC1 for ; Thu, 5 Nov 2015 05:07:14 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 9D9DBAC002 for ; Thu, 5 Nov 2015 03:07:10 -0800 (PST) X-ASG-Debug-ID: 1446721626-04cb6c296d395c0001-NocioJ Received: from mail-lb0-f182.google.com (mail-lb0-f182.google.com [209.85.217.182]) by cuda.sgi.com with ESMTP id qxZUHTWLEP6QuVCy (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Thu, 05 Nov 2015 03:07:07 -0800 (PST) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.85.217.182 Received: by lbbes7 with SMTP id es7so32680421lbb.2 for ; Thu, 05 Nov 2015 03:07:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat_com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=73ighuDmZ4NeGWtHn+xzzZO0m7T0/psa10yE9jbv1/Q=; b=eJpzOh/qMSt3CFaqxEYdp1TPQmGJGuX8STrV9rAnmUBWi5WJjyStP2UqyAAoJEILvc VPlrMa60AVi63zBSZkrrVsuC1Ws2b1m1hoSxtbH2YREYSn528M1Tzm1OkZOtqfzG1Wbh Md9981Ef9Z/fsSy2LjlWNMH3GMBg2a5zYnQEHb9ZcsiWurWlbbszFkysyHlPHNFk2fPm qUZ9sy5GET6o6YMnDNlAAQ9SjmJ5bqhBGtq+Pyc11mUINXKWts70JsUQ0Zhg0uUxLULa Ww0H5UD/dt52Nn3TSe5WEO0MJdeL6gfUWWppTxmq223IfQgXaW2QltBGBnFVV44F4oH1 0j5w== 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=73ighuDmZ4NeGWtHn+xzzZO0m7T0/psa10yE9jbv1/Q=; b=fYV9K0lYYDgZUttH41daZwr2HiimwTqn7Ai4tJ/Td77EiPSEUEHMwlSCtjHvOGl8Lv szYB87xPrEG6hOcGKJsFgoUKixGe/pzBBZcc8PuXm1tkWU4BEm5/NiMk/Nj5ycHHdoFY lkeRdH2kUttpM5Nh7XbpIurINLUuaqhzrQqSoMvXSRxfaP/whlEZumN39y9kH5tOl/Qp 9slCpM8RKuzbk94Y8snlrEoVkrrF3BJA7dnKAIVgWTo9hEigiwZhb/v3ZrWmWhAW5Biv xpbyUSuf6jEhHBeOLHT6y7TlSri4Z3KLRCAWlmaupIiqfga9SjnzrOpFP5FTbu5mxTCP LRhA== X-Gm-Message-State: ALoCoQnC8oNckTT6B5biIbR03Cz+lBsuFVKdFj5LlBR2XgHhVvFaSyfY/rygUrZpt/Oux6dtpWWE MIME-Version: 1.0 X-Received: by 10.112.205.194 with SMTP id li2mr3380753lbc.75.1446721625486; Thu, 05 Nov 2015 03:07:05 -0800 (PST) Received: by 10.112.53.42 with HTTP; Thu, 5 Nov 2015 03:07:05 -0800 (PST) In-Reply-To: References: <1446563847-14005-1-git-send-email-agruenba@redhat.com> <1446563847-14005-46-git-send-email-agruenba@redhat.com> Date: Thu, 5 Nov 2015 12:07:05 +0100 Message-ID: Subject: Re: [PATCH v13 45/51] sunrpc: Allow to demand-allocate pages to encode into From: Andreas Gruenbacher X-ASG-Orig-Subj: Re: [PATCH v13 45/51] sunrpc: Allow to demand-allocate pages to encode into To: Trond Myklebust Cc: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Anna Schumaker , Dave Chinner , linux-ext4 , XFS Developers , Linux Kernel Mailing List , Linux FS-devel Mailing List , Linux NFS Mailing List , linux-cifs@vger.kernel.org, Linux API Mailing List Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-lb0-f182.google.com[209.85.217.182] X-Barracuda-Start-Time: 1446721626 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24131 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 Trond, On Tue, Nov 3, 2015 at 5:25 PM, Trond Myklebust wrote: > On Tue, Nov 3, 2015 at 10:17 AM, Andreas Gruenbacher > wrote: >> When encoding large, variable-length objects such as acls into xdr_bufs, >> it is easier to allocate buffer pages on demand rather than precomputing >> the required buffer size. > > NACK. We're not doing allocations from inside the XDR encoders. This > can and should be done before calling into the SUNRPC layer. an XDR-encoded ACL can be up to 64k (16 pages) in size. In practice, large ACLs like that will almost never occur and almost all ACLs will fit into a single page though. The XDR-encoded ACL contains strings for the user and group names which need to be looked up when the idmapper is used. Those lookups are somewhat expensive; in addition, the lookup results can change over time. When precomputing the size, allocating space, and then encoding the ACL, we could run out of space when encoding. So we could always allocate the maximum 16 pages, encode the acl, and free the unused pages. This would be rather wasteful though. Given how simple it is to allocate pages as we go, this seems the better choice here. This doesn't break any existing code either; NULL page pointers would have oopsed in xdr_get_next_encode_buffer before. >From the memory management point of view, there is no difference in preallocating GFP_NOFS pages and allocating them on demand; the pages are allocated in the same task and locking context in both cases. So could you please explain why you object to this change? Thanks, Andreas From agruenba@redhat.com Thu Nov 5 05:39:55 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 882CE7FC2 for ; Thu, 5 Nov 2015 05:39:55 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 7CD4D304053 for ; Thu, 5 Nov 2015 03:39:55 -0800 (PST) X-ASG-Debug-ID: 1446723591-04cbb0242542140001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id hY64vQkQMZLK6UQD (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 05 Nov 2015 03:39:51 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 36B8C8E694; Thu, 5 Nov 2015 11:39:50 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-134.ams2.redhat.com [10.36.7.134]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA5Bdfbb015870; Thu, 5 Nov 2015 06:39:42 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v14 00/22] Richacls (Core and Ext4) Date: Thu, 5 Nov 2015 12:39:18 +0100 X-ASG-Orig-Subj: [PATCH v14 00/22] Richacls (Core and Ext4) Message-Id: <1446723580-3747-1-git-send-email-agruenba@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: 1446723591 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Here is another update to the richacl patch queue. This posting contains the patches ready to be merged; the patches later in the queue still need some more review. Changes since the last posting (http://lwn.net/Articles/662881/): * Functions {get,put}_base_acl renamed to base_acl_{get,put}. Functions base_acl_init and base_acl_refcount added and used where appropriate. Better document that struct base_acl must be the first member in an ACL. * Function acl_by_type un-exported and changed to return a struct base_acl pointer. * The "Cache base_acl objects in inodes" and "Cache richacl in struct inode" patches were not perfectly split. * Fix the commit message of "Add richacl feature flag". The complete patch queue is available in git form here: git://git.kernel.org/pub/scm/linux/kernel/git/agruen/linux-richacl.git \ richacl-2015-11-05 The richacl user-space utilitites, man pages, and test suite are available here: https://github.com/andreas-gruenbacher/richacl Changes to other user-space packages for richacl are available here: https://github.com/andreas-gruenbacher/coreutils https://github.com/andreas-gruenbacher/e2fsprogs https://github.com/andreas-gruenbacher/xfsprogs-dev https://github.com/andreas-gruenbacher/nfs-utils Please see the richacl homepage for more information: http://www.bestbits.at/richacl/ Thanks, Andreas Andreas Gruenbacher (20): vfs: Add IS_ACL() and IS_RICHACL() tests vfs: Add MAY_CREATE_FILE and MAY_CREATE_DIR permission flags vfs: Add MAY_DELETE_SELF and MAY_DELETE_CHILD permission flags vfs: Make the inode passed to inode_change_ok non-const vfs: Add permission flags for setting file attributes richacl: In-memory representation and helper functions richacl: Permission mapping functions richacl: Compute maximum file masks from an acl richacl: Permission check algorithm posix_acl: Unexport acl_by_type and make it static vfs: Cache base_acl objects in inodes vfs: Add get_richacl and set_richacl inode operations vfs: Cache richacl in struct inode richacl: Update the file masks in chmod() richacl: Check if an acl is equivalent to a file mode richacl: Create-time inheritance richacl: Automatic Inheritance richacl: xattr mapping functions richacl: Add richacl xattr handler vfs: Add richacl permission checking Aneesh Kumar K.V (2): ext4: Add richacl support ext4: Add richacl feature flag drivers/staging/lustre/lustre/llite/llite_lib.c | 2 +- fs/Kconfig | 3 + fs/Makefile | 2 + fs/attr.c | 81 +++- fs/ext4/Kconfig | 11 + fs/ext4/Makefile | 1 + fs/ext4/ext4.h | 6 +- fs/ext4/file.c | 3 + fs/ext4/ialloc.c | 11 +- fs/ext4/inode.c | 12 +- fs/ext4/namei.c | 5 + fs/ext4/richacl.c | 142 ++++++ fs/ext4/richacl.h | 40 ++ fs/ext4/super.c | 49 +- fs/ext4/xattr.c | 7 + fs/f2fs/acl.c | 4 +- fs/inode.c | 15 +- fs/jffs2/acl.c | 10 +- fs/namei.c | 111 +++-- fs/posix_acl.c | 50 +-- fs/richacl_base.c | 564 ++++++++++++++++++++++++ fs/richacl_inode.c | 333 ++++++++++++++ fs/richacl_xattr.c | 298 +++++++++++++ fs/xattr.c | 34 +- include/linux/fs.h | 60 ++- include/linux/posix_acl.h | 13 +- include/linux/richacl.h | 208 +++++++++ include/linux/richacl_xattr.h | 44 ++ include/uapi/linux/Kbuild | 2 + include/uapi/linux/fs.h | 3 +- include/uapi/linux/richacl.h | 152 +++++++ include/uapi/linux/richacl_xattr.h | 44 ++ include/uapi/linux/xattr.h | 2 + 33 files changed, 2213 insertions(+), 109 deletions(-) create mode 100644 fs/ext4/richacl.c create mode 100644 fs/ext4/richacl.h create mode 100644 fs/richacl_base.c create mode 100644 fs/richacl_inode.c create mode 100644 fs/richacl_xattr.c create mode 100644 include/linux/richacl.h create mode 100644 include/linux/richacl_xattr.h create mode 100644 include/uapi/linux/richacl.h create mode 100644 include/uapi/linux/richacl_xattr.h -- 2.5.0 From agruenba@redhat.com Thu Nov 5 05:40:02 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 31B1C7FD6 for ; Thu, 5 Nov 2015 05:40:02 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 065228F8035 for ; Thu, 5 Nov 2015 03:39:58 -0800 (PST) X-ASG-Debug-ID: 1446723597-04bdf03f033dac0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id eF8z4E3lKkgXLNGt (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 05 Nov 2015 03:39:57 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 16EA68E361; Thu, 5 Nov 2015 11:39:57 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-134.ams2.redhat.com [10.36.7.134]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA5Bdfbc015870; Thu, 5 Nov 2015 06:39:50 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v14 01/22] vfs: Add IS_ACL() and IS_RICHACL() tests Date: Thu, 5 Nov 2015 12:39:19 +0100 X-ASG-Orig-Subj: [PATCH v14 01/22] vfs: Add IS_ACL() and IS_RICHACL() tests Message-Id: <1446723580-3747-2-git-send-email-agruenba@redhat.com> In-Reply-To: <1446723580-3747-1-git-send-email-agruenba@redhat.com> References: <1446723580-3747-1-git-send-email-agruenba@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: 1446723597 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 The vfs does not apply the umask for file systems that support acls. The test used for this used to be called IS_POSIXACL(). Switch to a new IS_ACL() test to check for either posix acls or richacls instead. Add a new MS_RICHACL flag and IS_RICHACL() test for richacls alone. The IS_POSIXACL() test is still needed by nfsd. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/Kconfig | 3 +++ fs/namei.c | 8 ++++---- include/linux/fs.h | 12 ++++++++++++ include/uapi/linux/fs.h | 3 ++- 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/fs/Kconfig b/fs/Kconfig index da3f32f..bff2879 100644 --- a/fs/Kconfig +++ b/fs/Kconfig @@ -56,6 +56,9 @@ endif # BLOCK config FS_POSIX_ACL def_bool n +config FS_RICHACL + def_bool n + config EXPORTFS tristate diff --git a/fs/namei.c b/fs/namei.c index 33e9495..224ecf1 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -2798,7 +2798,7 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry, } mode = op->mode; - if ((open_flag & O_CREAT) && !IS_POSIXACL(dir)) + if ((open_flag & O_CREAT) && !IS_ACL(dir)) mode &= ~current_umask(); excl = (open_flag & (O_EXCL | O_CREAT)) == (O_EXCL | O_CREAT); @@ -2982,7 +2982,7 @@ static int lookup_open(struct nameidata *nd, struct path *path, /* Negative dentry, just create the file */ if (!dentry->d_inode && (op->open_flag & O_CREAT)) { umode_t mode = op->mode; - if (!IS_POSIXACL(dir->d_inode)) + if (!IS_ACL(dir->d_inode)) mode &= ~current_umask(); /* * This write is needed to ensure that a @@ -3553,7 +3553,7 @@ retry: if (IS_ERR(dentry)) return PTR_ERR(dentry); - if (!IS_POSIXACL(path.dentry->d_inode)) + if (!IS_ACL(path.dentry->d_inode)) mode &= ~current_umask(); error = security_path_mknod(&path, dentry, mode, dev); if (error) @@ -3622,7 +3622,7 @@ retry: if (IS_ERR(dentry)) return PTR_ERR(dentry); - if (!IS_POSIXACL(path.dentry->d_inode)) + if (!IS_ACL(path.dentry->d_inode)) mode &= ~current_umask(); error = security_path_mkdir(&path, dentry, mode); if (!error) diff --git a/include/linux/fs.h b/include/linux/fs.h index 72d8a84..4efa435 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1781,6 +1781,12 @@ struct super_operations { #define IS_IMMUTABLE(inode) ((inode)->i_flags & S_IMMUTABLE) #define IS_POSIXACL(inode) __IS_FLG(inode, MS_POSIXACL) +#ifdef CONFIG_FS_RICHACL +#define IS_RICHACL(inode) __IS_FLG(inode, MS_RICHACL) +#else +#define IS_RICHACL(inode) 0 +#endif + #define IS_DEADDIR(inode) ((inode)->i_flags & S_DEAD) #define IS_NOCMTIME(inode) ((inode)->i_flags & S_NOCMTIME) #define IS_SWAPFILE(inode) ((inode)->i_flags & S_SWAPFILE) @@ -1794,6 +1800,12 @@ struct super_operations { (inode)->i_rdev == WHITEOUT_DEV) /* + * IS_ACL() tells the VFS to not apply the umask + * and use check_acl for acl permission checks when defined. + */ +#define IS_ACL(inode) __IS_FLG(inode, MS_POSIXACL | MS_RICHACL) + +/* * Inode state bits. Protected by inode->i_lock * * Three bits determine the dirty state of the inode, I_DIRTY_SYNC, diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h index 9b964a5..6ac6bc9 100644 --- a/include/uapi/linux/fs.h +++ b/include/uapi/linux/fs.h @@ -81,7 +81,7 @@ struct inodes_stat_t { #define MS_VERBOSE 32768 /* War is peace. Verbosity is silence. MS_VERBOSE is deprecated. */ #define MS_SILENT 32768 -#define MS_POSIXACL (1<<16) /* VFS does not apply the umask */ +#define MS_POSIXACL (1<<16) /* Supports POSIX ACLs */ #define MS_UNBINDABLE (1<<17) /* change to unbindable */ #define MS_PRIVATE (1<<18) /* change to private */ #define MS_SLAVE (1<<19) /* change to slave */ @@ -91,6 +91,7 @@ struct inodes_stat_t { #define MS_I_VERSION (1<<23) /* Update inode I_version field */ #define MS_STRICTATIME (1<<24) /* Always perform atime updates */ #define MS_LAZYTIME (1<<25) /* Update the on-disk [acm]times lazily */ +#define MS_RICHACL (1<<26) /* Supports richacls */ /* These sb flags are internal to the kernel */ #define MS_NOSEC (1<<28) -- 2.5.0 From agruenba@redhat.com Thu Nov 5 05:40:05 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 EB0F17FE7 for ; Thu, 5 Nov 2015 05:40:05 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id DE2BF304059 for ; Thu, 5 Nov 2015 03:40:05 -0800 (PST) X-ASG-Debug-ID: 1446723604-04cbb02424421c0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id FpuJ6LuhoawckAYK (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 05 Nov 2015 03:40:04 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 0ED10C0032EA; Thu, 5 Nov 2015 11:40:04 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-134.ams2.redhat.com [10.36.7.134]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA5Bdfbd015870; Thu, 5 Nov 2015 06:39:57 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v14 02/22] vfs: Add MAY_CREATE_FILE and MAY_CREATE_DIR permission flags Date: Thu, 5 Nov 2015 12:39:20 +0100 X-ASG-Orig-Subj: [PATCH v14 02/22] vfs: Add MAY_CREATE_FILE and MAY_CREATE_DIR permission flags Message-Id: <1446723580-3747-3-git-send-email-agruenba@redhat.com> In-Reply-To: <1446723580-3747-1-git-send-email-agruenba@redhat.com> References: <1446723580-3747-1-git-send-email-agruenba@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: 1446723604 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Richacls distinguish between creating non-directories and directories. To support that, add an isdir parameter to may_create(). When checking inode_permission() for create permission, pass in an additional MAY_CREATE_FILE or MAY_CREATE_DIR mask flag. To allow checking for delete *and* create access when replacing an existing file via vfs_rename(), add a replace parameter to may_delete(). Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/namei.c | 43 +++++++++++++++++++++++++------------------ include/linux/fs.h | 2 ++ 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 224ecf1..0259392 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -453,7 +453,9 @@ static int sb_permission(struct super_block *sb, struct inode *inode, int mask) * this, letting us set arbitrary permissions for filesystem access without * changing the "normal" UIDs which are used for other things. * - * When checking for MAY_APPEND, MAY_WRITE must also be set in @mask. + * MAY_WRITE must be set in @mask whenever MAY_APPEND, MAY_CREATE_FILE, or + * MAY_CREATE_DIR are set. That way, file systems that don't support these + * permissions will check for MAY_WRITE instead. */ int inode_permission(struct inode *inode, int mask) { @@ -2549,10 +2551,11 @@ EXPORT_SYMBOL(__check_sticky); * 10. We don't allow removal of NFS sillyrenamed files; it's handled by * nfs_async_unlink(). */ -static int may_delete(struct inode *dir, struct dentry *victim, bool isdir) +static int may_delete(struct inode *dir, struct dentry *victim, + bool isdir, bool replace) { struct inode *inode = d_backing_inode(victim); - int error; + int error, mask = MAY_WRITE | MAY_EXEC; if (d_is_negative(victim)) return -ENOENT; @@ -2561,7 +2564,9 @@ static int may_delete(struct inode *dir, struct dentry *victim, bool isdir) BUG_ON(victim->d_parent->d_inode != dir); audit_inode_child(dir, victim, AUDIT_TYPE_CHILD_DELETE); - error = inode_permission(dir, MAY_WRITE | MAY_EXEC); + if (replace) + mask |= isdir ? MAY_CREATE_DIR : MAY_CREATE_FILE; + error = inode_permission(dir, mask); if (error) return error; if (IS_APPEND(dir)) @@ -2592,14 +2597,16 @@ static int may_delete(struct inode *dir, struct dentry *victim, bool isdir) * 3. We should have write and exec permissions on dir * 4. We can't do it if dir is immutable (done in permission()) */ -static inline int may_create(struct inode *dir, struct dentry *child) +static inline int may_create(struct inode *dir, struct dentry *child, bool isdir) { + int mask = isdir ? MAY_CREATE_DIR : MAY_CREATE_FILE; + audit_inode_child(dir, child, AUDIT_TYPE_CHILD_CREATE); if (child->d_inode) return -EEXIST; if (IS_DEADDIR(dir)) return -ENOENT; - return inode_permission(dir, MAY_WRITE | MAY_EXEC); + return inode_permission(dir, MAY_WRITE | MAY_EXEC | mask); } /* @@ -2649,7 +2656,7 @@ EXPORT_SYMBOL(unlock_rename); int vfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool want_excl) { - int error = may_create(dir, dentry); + int error = may_create(dir, dentry, false); if (error) return error; @@ -3494,7 +3501,7 @@ EXPORT_SYMBOL(user_path_create); int vfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev) { - int error = may_create(dir, dentry); + int error = may_create(dir, dentry, false); if (error) return error; @@ -3586,7 +3593,7 @@ SYSCALL_DEFINE3(mknod, const char __user *, filename, umode_t, mode, unsigned, d int vfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) { - int error = may_create(dir, dentry); + int error = may_create(dir, dentry, true); unsigned max_links = dir->i_sb->s_max_links; if (error) @@ -3667,7 +3674,7 @@ EXPORT_SYMBOL(dentry_unhash); int vfs_rmdir(struct inode *dir, struct dentry *dentry) { - int error = may_delete(dir, dentry, 1); + int error = may_delete(dir, dentry, true, false); if (error) return error; @@ -3789,7 +3796,7 @@ SYSCALL_DEFINE1(rmdir, const char __user *, pathname) int vfs_unlink(struct inode *dir, struct dentry *dentry, struct inode **delegated_inode) { struct inode *target = dentry->d_inode; - int error = may_delete(dir, dentry, 0); + int error = may_delete(dir, dentry, false, false); if (error) return error; @@ -3923,7 +3930,7 @@ SYSCALL_DEFINE1(unlink, const char __user *, pathname) int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname) { - int error = may_create(dir, dentry); + int error = may_create(dir, dentry, false); if (error) return error; @@ -4006,7 +4013,7 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de if (!inode) return -ENOENT; - error = may_create(dir, new_dentry); + error = may_create(dir, new_dentry, false); if (error) return error; @@ -4194,19 +4201,19 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, if (source == target) return 0; - error = may_delete(old_dir, old_dentry, is_dir); + error = may_delete(old_dir, old_dentry, is_dir, false); if (error) return error; if (!target) { - error = may_create(new_dir, new_dentry); + error = may_create(new_dir, new_dentry, is_dir); } else { new_is_dir = d_is_dir(new_dentry); if (!(flags & RENAME_EXCHANGE)) - error = may_delete(new_dir, new_dentry, is_dir); + error = may_delete(new_dir, new_dentry, is_dir, true); else - error = may_delete(new_dir, new_dentry, new_is_dir); + error = may_delete(new_dir, new_dentry, new_is_dir, true); } if (error) return error; @@ -4469,7 +4476,7 @@ SYSCALL_DEFINE2(rename, const char __user *, oldname, const char __user *, newna int vfs_whiteout(struct inode *dir, struct dentry *dentry) { - int error = may_create(dir, dentry); + int error = may_create(dir, dentry, false); if (error) return error; diff --git a/include/linux/fs.h b/include/linux/fs.h index 4efa435..d6e2330 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -82,6 +82,8 @@ typedef void (dax_iodone_t)(struct buffer_head *bh_map, int uptodate); #define MAY_CHDIR 0x00000040 /* called from RCU mode, don't block */ #define MAY_NOT_BLOCK 0x00000080 +#define MAY_CREATE_FILE 0x00000100 +#define MAY_CREATE_DIR 0x00000200 /* * flags in file.f_mode. Note that FMODE_READ and FMODE_WRITE must correspond -- 2.5.0 From agruenba@redhat.com Thu Nov 5 05:40:13 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 6F7BC7FC2 for ; Thu, 5 Nov 2015 05:40:13 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id CDFFCAC002 for ; Thu, 5 Nov 2015 03:40:12 -0800 (PST) X-ASG-Debug-ID: 1446723611-04cb6c296a3a1b0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 8cNrSEKaPng6ZbmR (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 05 Nov 2015 03:40:11 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id E74C09246C; Thu, 5 Nov 2015 11:40:10 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-134.ams2.redhat.com [10.36.7.134]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA5Bdfbe015870; Thu, 5 Nov 2015 06:40:04 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v14 03/22] vfs: Add MAY_DELETE_SELF and MAY_DELETE_CHILD permission flags Date: Thu, 5 Nov 2015 12:39:21 +0100 X-ASG-Orig-Subj: [PATCH v14 03/22] vfs: Add MAY_DELETE_SELF and MAY_DELETE_CHILD permission flags Message-Id: <1446723580-3747-4-git-send-email-agruenba@redhat.com> In-Reply-To: <1446723580-3747-1-git-send-email-agruenba@redhat.com> References: <1446723580-3747-1-git-send-email-agruenba@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: 1446723611 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Normally, deleting a file requires MAY_WRITE access to the parent directory. With richacls, a file may be deleted with MAY_DELETE_CHILD access to the parent directory or with MAY_DELETE_SELF access to the file. To support that, pass the MAY_DELETE_CHILD mask flag to inode_permission() when checking for delete access inside a directory, and MAY_DELETE_SELF when checking for delete access to a file itelf. The MAY_DELETE_SELF permission overrides the sticky directory check. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/namei.c | 21 ++++++++++++--------- include/linux/fs.h | 2 ++ 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 0259392..2eab19e 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -453,9 +453,9 @@ static int sb_permission(struct super_block *sb, struct inode *inode, int mask) * this, letting us set arbitrary permissions for filesystem access without * changing the "normal" UIDs which are used for other things. * - * MAY_WRITE must be set in @mask whenever MAY_APPEND, MAY_CREATE_FILE, or - * MAY_CREATE_DIR are set. That way, file systems that don't support these - * permissions will check for MAY_WRITE instead. + * MAY_WRITE must be set in @mask whenever MAY_APPEND, MAY_CREATE_FILE, + * MAY_CREATE_DIR, or MAY_DELETE_CHILD are set. That way, file systems that + * don't support these permissions will check for MAY_WRITE instead. */ int inode_permission(struct inode *inode, int mask) { @@ -2555,7 +2555,7 @@ static int may_delete(struct inode *dir, struct dentry *victim, bool isdir, bool replace) { struct inode *inode = d_backing_inode(victim); - int error, mask = MAY_WRITE | MAY_EXEC; + int error, mask = MAY_EXEC; if (d_is_negative(victim)) return -ENOENT; @@ -2565,15 +2565,18 @@ static int may_delete(struct inode *dir, struct dentry *victim, audit_inode_child(dir, victim, AUDIT_TYPE_CHILD_DELETE); if (replace) - mask |= isdir ? MAY_CREATE_DIR : MAY_CREATE_FILE; - error = inode_permission(dir, mask); + mask |= MAY_WRITE | (isdir ? MAY_CREATE_DIR : MAY_CREATE_FILE); + error = inode_permission(dir, mask | MAY_WRITE | MAY_DELETE_CHILD); + if (!error && check_sticky(dir, inode)) + error = -EPERM; + if (error && IS_RICHACL(inode) && + inode_permission(inode, MAY_DELETE_SELF) == 0) + error = 0; if (error) return error; if (IS_APPEND(dir)) return -EPERM; - - if (check_sticky(dir, inode) || IS_APPEND(inode) || - IS_IMMUTABLE(inode) || IS_SWAPFILE(inode)) + if (IS_APPEND(inode) || IS_IMMUTABLE(inode) || IS_SWAPFILE(inode)) return -EPERM; if (isdir) { if (!d_is_dir(victim)) diff --git a/include/linux/fs.h b/include/linux/fs.h index d6e2330..402acd7 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -84,6 +84,8 @@ typedef void (dax_iodone_t)(struct buffer_head *bh_map, int uptodate); #define MAY_NOT_BLOCK 0x00000080 #define MAY_CREATE_FILE 0x00000100 #define MAY_CREATE_DIR 0x00000200 +#define MAY_DELETE_CHILD 0x00000400 +#define MAY_DELETE_SELF 0x00000800 /* * flags in file.f_mode. Note that FMODE_READ and FMODE_WRITE must correspond -- 2.5.0 From agruenba@redhat.com Thu Nov 5 05:40:19 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 26DAB7FDF for ; Thu, 5 Nov 2015 05:40:19 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 1AB2B304051 for ; Thu, 5 Nov 2015 03:40:19 -0800 (PST) X-ASG-Debug-ID: 1446723617-04cbb0242342230001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id XEGHLlkm7ZgOEfik (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 05 Nov 2015 03:40:18 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id B2C69935F5; Thu, 5 Nov 2015 11:40:17 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-134.ams2.redhat.com [10.36.7.134]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA5Bdfbf015870; Thu, 5 Nov 2015 06:40:11 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v14 04/22] vfs: Make the inode passed to inode_change_ok non-const Date: Thu, 5 Nov 2015 12:39:22 +0100 X-ASG-Orig-Subj: [PATCH v14 04/22] vfs: Make the inode passed to inode_change_ok non-const Message-Id: <1446723580-3747-5-git-send-email-agruenba@redhat.com> In-Reply-To: <1446723580-3747-1-git-send-email-agruenba@redhat.com> References: <1446723580-3747-1-git-send-email-agruenba@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: 1446723618 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 We will need to call iop->permission and iop->get_acl from inode_change_ok() for additional permission checks, and both take a non-const inode. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/attr.c | 2 +- include/linux/fs.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/attr.c b/fs/attr.c index 6530ced..328be71 100644 --- a/fs/attr.c +++ b/fs/attr.c @@ -28,7 +28,7 @@ * Should be called as the first thing in ->setattr implementations, * possibly after taking additional locks. */ -int inode_change_ok(const struct inode *inode, struct iattr *attr) +int inode_change_ok(struct inode *inode, struct iattr *attr) { unsigned int ia_valid = attr->ia_valid; diff --git a/include/linux/fs.h b/include/linux/fs.h index 402acd7..aab32c8 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2871,7 +2871,7 @@ extern int buffer_migrate_page(struct address_space *, #define buffer_migrate_page NULL #endif -extern int inode_change_ok(const struct inode *, struct iattr *); +extern int inode_change_ok(struct inode *, struct iattr *); extern int inode_newsize_ok(const struct inode *, loff_t offset); extern void setattr_copy(struct inode *inode, const struct iattr *attr); -- 2.5.0 From agruenba@redhat.com Thu Nov 5 05:40:26 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 7B8C77FC2 for ; Thu, 5 Nov 2015 05:40:26 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 15D56AC002 for ; Thu, 5 Nov 2015 03:40:25 -0800 (PST) X-ASG-Debug-ID: 1446723624-04bdf03f053db10001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 2GHjiM6D8DTjjUag (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 05 Nov 2015 03:40:25 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 9FE3319CBD1; Thu, 5 Nov 2015 11:40:24 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-134.ams2.redhat.com [10.36.7.134]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA5Bdfbg015870; Thu, 5 Nov 2015 06:40:18 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v14 05/22] vfs: Add permission flags for setting file attributes Date: Thu, 5 Nov 2015 12:39:23 +0100 X-ASG-Orig-Subj: [PATCH v14 05/22] vfs: Add permission flags for setting file attributes Message-Id: <1446723580-3747-6-git-send-email-agruenba@redhat.com> In-Reply-To: <1446723580-3747-1-git-send-email-agruenba@redhat.com> References: <1446723580-3747-1-git-send-email-agruenba@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: 1446723625 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Richacls support permissions that allow to take ownership of a file, change the file permissions, and set the file timestamps. Support that by introducing new permission mask flags and by checking for those mask flags in inode_change_ok(). Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/attr.c | 79 +++++++++++++++++++++++++++++++++++++++++++++--------- include/linux/fs.h | 3 +++ 2 files changed, 70 insertions(+), 12 deletions(-) diff --git a/fs/attr.c b/fs/attr.c index 328be71..85483e0 100644 --- a/fs/attr.c +++ b/fs/attr.c @@ -17,6 +17,65 @@ #include /** + * inode_extended_permission - permissions beyond read/write/execute + * + * Check for permissions that only richacls can currently grant. + */ +static int inode_extended_permission(struct inode *inode, int mask) +{ + if (!IS_RICHACL(inode)) + return -EPERM; + return inode_permission(inode, mask); +} + +static bool inode_uid_change_ok(struct inode *inode, kuid_t ia_uid) +{ + if (uid_eq(current_fsuid(), inode->i_uid) && + uid_eq(ia_uid, inode->i_uid)) + return true; + if (uid_eq(current_fsuid(), ia_uid) && + inode_extended_permission(inode, MAY_TAKE_OWNERSHIP) == 0) + return true; + if (capable_wrt_inode_uidgid(inode, CAP_CHOWN)) + return true; + return false; +} + +static bool inode_gid_change_ok(struct inode *inode, kgid_t ia_gid) +{ + int in_group = in_group_p(ia_gid); + if (uid_eq(current_fsuid(), inode->i_uid) && + (in_group || gid_eq(ia_gid, inode->i_gid))) + return true; + if (in_group && inode_extended_permission(inode, MAY_TAKE_OWNERSHIP) == 0) + return true; + if (capable_wrt_inode_uidgid(inode, CAP_CHOWN)) + return true; + return false; +} + +/** + * inode_owner_permitted_or_capable + * + * Check for permissions implicitly granted to the owner, like MAY_CHMOD or + * MAY_SET_TIMES. Equivalent to inode_owner_or_capable for file systems + * without support for those permissions. + */ +static bool inode_owner_permitted_or_capable(struct inode *inode, int mask) +{ + struct user_namespace *ns; + + if (uid_eq(current_fsuid(), inode->i_uid)) + return true; + if (inode_extended_permission(inode, mask) == 0) + return true; + ns = current_user_ns(); + if (ns_capable(ns, CAP_FOWNER) && kuid_has_mapping(ns, inode->i_uid)) + return true; + return false; +} + +/** * inode_change_ok - check if attribute changes to an inode are allowed * @inode: inode to check * @attr: attributes to change @@ -47,22 +106,18 @@ int inode_change_ok(struct inode *inode, struct iattr *attr) return 0; /* Make sure a caller can chown. */ - if ((ia_valid & ATTR_UID) && - (!uid_eq(current_fsuid(), inode->i_uid) || - !uid_eq(attr->ia_uid, inode->i_uid)) && - !capable_wrt_inode_uidgid(inode, CAP_CHOWN)) - return -EPERM; + if (ia_valid & ATTR_UID) + if (!inode_uid_change_ok(inode, attr->ia_uid)) + return -EPERM; /* Make sure caller can chgrp. */ - if ((ia_valid & ATTR_GID) && - (!uid_eq(current_fsuid(), inode->i_uid) || - (!in_group_p(attr->ia_gid) && !gid_eq(attr->ia_gid, inode->i_gid))) && - !capable_wrt_inode_uidgid(inode, CAP_CHOWN)) - return -EPERM; + if (ia_valid & ATTR_GID) + if (!inode_gid_change_ok(inode, attr->ia_gid)) + return -EPERM; /* Make sure a caller can chmod. */ if (ia_valid & ATTR_MODE) { - if (!inode_owner_or_capable(inode)) + if (!inode_owner_permitted_or_capable(inode, MAY_CHMOD)) return -EPERM; /* Also check the setgid bit! */ if (!in_group_p((ia_valid & ATTR_GID) ? attr->ia_gid : @@ -73,7 +128,7 @@ int inode_change_ok(struct inode *inode, struct iattr *attr) /* Check for setting the inode time. */ if (ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET | ATTR_TIMES_SET)) { - if (!inode_owner_or_capable(inode)) + if (!inode_owner_permitted_or_capable(inode, MAY_SET_TIMES)) return -EPERM; } diff --git a/include/linux/fs.h b/include/linux/fs.h index aab32c8..ba91a89 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -86,6 +86,9 @@ typedef void (dax_iodone_t)(struct buffer_head *bh_map, int uptodate); #define MAY_CREATE_DIR 0x00000200 #define MAY_DELETE_CHILD 0x00000400 #define MAY_DELETE_SELF 0x00000800 +#define MAY_TAKE_OWNERSHIP 0x00001000 +#define MAY_CHMOD 0x00002000 +#define MAY_SET_TIMES 0x00004000 /* * flags in file.f_mode. Note that FMODE_READ and FMODE_WRITE must correspond -- 2.5.0 From agruenba@redhat.com Thu Nov 5 05:40:34 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 143357FC2 for ; Thu, 5 Nov 2015 05:40:34 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id E956E304053 for ; Thu, 5 Nov 2015 03:40:33 -0800 (PST) X-ASG-Debug-ID: 1446723631-04cb6c296b3a1e0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 6CUorH0IJGBdOjgC (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 05 Nov 2015 03:40:32 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 7E3E48E39D; Thu, 5 Nov 2015 11:40:31 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-134.ams2.redhat.com [10.36.7.134]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA5Bdfbh015870; Thu, 5 Nov 2015 06:40:25 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v14 06/22] richacl: In-memory representation and helper functions Date: Thu, 5 Nov 2015 12:39:24 +0100 X-ASG-Orig-Subj: [PATCH v14 06/22] richacl: In-memory representation and helper functions Message-Id: <1446723580-3747-7-git-send-email-agruenba@redhat.com> In-Reply-To: <1446723580-3747-1-git-send-email-agruenba@redhat.com> References: <1446723580-3747-1-git-send-email-agruenba@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: 1446723632 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 A richacl consists of an NFSv4 acl and an owner, group, and other mask. These three masks correspond to the owner, group, and other file permission bits, but they contain NFSv4 permissions instead of POSIX permissions. Each entry in the NFSv4 acl applies to the file owner (OWNER@), the owning group (GROUP@), everyone (EVERYONE@), or to a specific uid or gid. As in the standard POSIX file permission model, each process is the owner, group, or other file class. A richacl grants a requested access only if the NFSv4 acl in the richacl grants the access (according to the NFSv4 permission check algorithm), and the file mask that applies to the process includes the requested permissions. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/Makefile | 2 + fs/richacl_base.c | 67 ++++++++++++++++ include/linux/richacl.h | 179 +++++++++++++++++++++++++++++++++++++++++++ include/uapi/linux/Kbuild | 1 + include/uapi/linux/richacl.h | 99 ++++++++++++++++++++++++ 5 files changed, 348 insertions(+) create mode 100644 fs/richacl_base.c create mode 100644 include/linux/richacl.h create mode 100644 include/uapi/linux/richacl.h diff --git a/fs/Makefile b/fs/Makefile index f79cf40..fe3e9dd 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -48,6 +48,8 @@ obj-$(CONFIG_COREDUMP) += coredump.o obj-$(CONFIG_SYSCTL) += drop_caches.o obj-$(CONFIG_FHANDLE) += fhandle.o +obj-$(CONFIG_FS_RICHACL) += richacl.o +richacl-y := richacl_base.o obj-y += quota/ diff --git a/fs/richacl_base.c b/fs/richacl_base.c new file mode 100644 index 0000000..c3ec928 --- /dev/null +++ b/fs/richacl_base.c @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2006, 2010 Novell, Inc. + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * 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; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include +#include +#include +#include +#include + +MODULE_LICENSE("GPL"); + +/** + * richacl_alloc - allocate a richacl + * @count: number of entries + */ +struct richacl * +richacl_alloc(int count, gfp_t gfp) +{ + size_t size = sizeof(struct richacl) + count * sizeof(struct richace); + struct richacl *acl = kzalloc(size, gfp); + + if (acl) { + atomic_set(&acl->a_refcount, 1); + acl->a_count = count; + } + return acl; +} +EXPORT_SYMBOL_GPL(richacl_alloc); + +/** + * richacl_clone - create a copy of a richacl + */ +struct richacl * +richacl_clone(const struct richacl *acl, gfp_t gfp) +{ + int count = acl->a_count; + size_t size = sizeof(struct richacl) + count * sizeof(struct richace); + struct richacl *dup = kmalloc(size, gfp); + + if (dup) { + memcpy(dup, acl, size); + atomic_set(&dup->a_refcount, 1); + } + return dup; +} + +/** + * richace_copy - copy an acl entry + */ +void +richace_copy(struct richace *to, const struct richace *from) +{ + memcpy(to, from, sizeof(struct richace)); +} diff --git a/include/linux/richacl.h b/include/linux/richacl.h new file mode 100644 index 0000000..edb8480 --- /dev/null +++ b/include/linux/richacl.h @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2006, 2010 Novell, Inc. + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * 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; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#ifndef __RICHACL_H +#define __RICHACL_H + +#include + +struct richace { + unsigned short e_type; + unsigned short e_flags; + unsigned int e_mask; + union { + kuid_t uid; + kgid_t gid; + unsigned int special; + } e_id; +}; + +struct richacl { + atomic_t a_refcount; + unsigned int a_owner_mask; + unsigned int a_group_mask; + unsigned int a_other_mask; + unsigned short a_count; + unsigned short a_flags; + struct richace a_entries[0]; +}; + +#define richacl_for_each_entry(_ace, _acl) \ + for (_ace = (_acl)->a_entries; \ + _ace != (_acl)->a_entries + (_acl)->a_count; \ + _ace++) + +#define richacl_for_each_entry_reverse(_ace, _acl) \ + for (_ace = (_acl)->a_entries + (_acl)->a_count - 1; \ + _ace != (_acl)->a_entries - 1; \ + _ace--) + +/** + * richacl_get - grab another reference to a richacl handle + */ +static inline struct richacl * +richacl_get(struct richacl *acl) +{ + if (acl) + atomic_inc(&acl->a_refcount); + return acl; +} + +/** + * richacl_put - free a richacl handle + */ +static inline void +richacl_put(struct richacl *acl) +{ + if (acl && atomic_dec_and_test(&acl->a_refcount)) + kfree(acl); +} + +/** + * richace_is_owner - check if @ace is an OWNER@ entry + */ +static inline bool +richace_is_owner(const struct richace *ace) +{ + return (ace->e_flags & RICHACE_SPECIAL_WHO) && + ace->e_id.special == RICHACE_OWNER_SPECIAL_ID; +} + +/** + * richace_is_group - check if @ace is a GROUP@ entry + */ +static inline bool +richace_is_group(const struct richace *ace) +{ + return (ace->e_flags & RICHACE_SPECIAL_WHO) && + ace->e_id.special == RICHACE_GROUP_SPECIAL_ID; +} + +/** + * richace_is_everyone - check if @ace is an EVERYONE@ entry + */ +static inline bool +richace_is_everyone(const struct richace *ace) +{ + return (ace->e_flags & RICHACE_SPECIAL_WHO) && + ace->e_id.special == RICHACE_EVERYONE_SPECIAL_ID; +} + +/** + * richace_is_unix_user - check if @ace applies to a specific user + */ +static inline bool +richace_is_unix_user(const struct richace *ace) +{ + return !(ace->e_flags & RICHACE_SPECIAL_WHO) && + !(ace->e_flags & RICHACE_IDENTIFIER_GROUP); +} + +/** + * richace_is_unix_group - check if @ace applies to a specific group + */ +static inline bool +richace_is_unix_group(const struct richace *ace) +{ + return !(ace->e_flags & RICHACE_SPECIAL_WHO) && + (ace->e_flags & RICHACE_IDENTIFIER_GROUP); +} + +/** + * richace_is_inherit_only - check if @ace is for inheritance only + * + * ACEs with the %RICHACE_INHERIT_ONLY_ACE flag set have no effect during + * permission checking. + */ +static inline bool +richace_is_inherit_only(const struct richace *ace) +{ + return ace->e_flags & RICHACE_INHERIT_ONLY_ACE; +} + +/** + * richace_is_inheritable - check if @ace is inheritable + */ +static inline bool +richace_is_inheritable(const struct richace *ace) +{ + return ace->e_flags & (RICHACE_FILE_INHERIT_ACE | + RICHACE_DIRECTORY_INHERIT_ACE); +} + +/** + * richace_is_allow - check if @ace is an %ALLOW type entry + */ +static inline bool +richace_is_allow(const struct richace *ace) +{ + return ace->e_type == RICHACE_ACCESS_ALLOWED_ACE_TYPE; +} + +/** + * richace_is_deny - check if @ace is a %DENY type entry + */ +static inline bool +richace_is_deny(const struct richace *ace) +{ + return ace->e_type == RICHACE_ACCESS_DENIED_ACE_TYPE; +} + +/** + * richace_is_same_identifier - are both identifiers the same? + */ +static inline bool +richace_is_same_identifier(const struct richace *a, const struct richace *b) +{ + return !((a->e_flags ^ b->e_flags) & + (RICHACE_SPECIAL_WHO | RICHACE_IDENTIFIER_GROUP)) && + !memcmp(&a->e_id, &b->e_id, sizeof(a->e_id)); +} + +extern struct richacl *richacl_alloc(int, gfp_t); +extern struct richacl *richacl_clone(const struct richacl *, gfp_t); +extern void richace_copy(struct richace *, const struct richace *); + +#endif /* __RICHACL_H */ diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild index f7b2db4..8c82010 100644 --- a/include/uapi/linux/Kbuild +++ b/include/uapi/linux/Kbuild @@ -348,6 +348,7 @@ header-y += reboot.h header-y += reiserfs_fs.h header-y += reiserfs_xattr.h header-y += resource.h +header-y += richacl.h header-y += rfkill.h header-y += romfs_fs.h header-y += rose.h diff --git a/include/uapi/linux/richacl.h b/include/uapi/linux/richacl.h new file mode 100644 index 0000000..08856f8 --- /dev/null +++ b/include/uapi/linux/richacl.h @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2006, 2010 Novell, Inc. + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ + +#ifndef __UAPI_RICHACL_H +#define __UAPI_RICHACL_H + +/* a_flags values */ +#define RICHACL_WRITE_THROUGH 0x40 +#define RICHACL_MASKED 0x80 + +/* e_type values */ +#define RICHACE_ACCESS_ALLOWED_ACE_TYPE 0x0000 +#define RICHACE_ACCESS_DENIED_ACE_TYPE 0x0001 + +/* e_flags bitflags */ +#define RICHACE_FILE_INHERIT_ACE 0x0001 +#define RICHACE_DIRECTORY_INHERIT_ACE 0x0002 +#define RICHACE_NO_PROPAGATE_INHERIT_ACE 0x0004 +#define RICHACE_INHERIT_ONLY_ACE 0x0008 +#define RICHACE_IDENTIFIER_GROUP 0x0040 +#define RICHACE_SPECIAL_WHO 0x4000 + +/* e_mask bitflags */ +#define RICHACE_READ_DATA 0x00000001 +#define RICHACE_LIST_DIRECTORY 0x00000001 +#define RICHACE_WRITE_DATA 0x00000002 +#define RICHACE_ADD_FILE 0x00000002 +#define RICHACE_APPEND_DATA 0x00000004 +#define RICHACE_ADD_SUBDIRECTORY 0x00000004 +#define RICHACE_READ_NAMED_ATTRS 0x00000008 +#define RICHACE_WRITE_NAMED_ATTRS 0x00000010 +#define RICHACE_EXECUTE 0x00000020 +#define RICHACE_DELETE_CHILD 0x00000040 +#define RICHACE_READ_ATTRIBUTES 0x00000080 +#define RICHACE_WRITE_ATTRIBUTES 0x00000100 +#define RICHACE_WRITE_RETENTION 0x00000200 +#define RICHACE_WRITE_RETENTION_HOLD 0x00000400 +#define RICHACE_DELETE 0x00010000 +#define RICHACE_READ_ACL 0x00020000 +#define RICHACE_WRITE_ACL 0x00040000 +#define RICHACE_WRITE_OWNER 0x00080000 +#define RICHACE_SYNCHRONIZE 0x00100000 + +/* e_id values */ +#define RICHACE_OWNER_SPECIAL_ID 0 +#define RICHACE_GROUP_SPECIAL_ID 1 +#define RICHACE_EVERYONE_SPECIAL_ID 2 + +#define RICHACL_VALID_FLAGS ( \ + RICHACL_WRITE_THROUGH | \ + RICHACL_MASKED ) + +#define RICHACE_VALID_FLAGS ( \ + RICHACE_FILE_INHERIT_ACE | \ + RICHACE_DIRECTORY_INHERIT_ACE | \ + RICHACE_NO_PROPAGATE_INHERIT_ACE | \ + RICHACE_INHERIT_ONLY_ACE | \ + RICHACE_IDENTIFIER_GROUP | \ + RICHACE_SPECIAL_WHO ) + +#define RICHACE_INHERITANCE_FLAGS ( \ + RICHACE_FILE_INHERIT_ACE | \ + RICHACE_DIRECTORY_INHERIT_ACE | \ + RICHACE_NO_PROPAGATE_INHERIT_ACE | \ + RICHACE_INHERIT_ONLY_ACE ) + +/* Valid RICHACE_* flags for directories and non-directories */ +#define RICHACE_VALID_MASK ( \ + RICHACE_READ_DATA | RICHACE_LIST_DIRECTORY | \ + RICHACE_WRITE_DATA | RICHACE_ADD_FILE | \ + RICHACE_APPEND_DATA | RICHACE_ADD_SUBDIRECTORY | \ + RICHACE_READ_NAMED_ATTRS | \ + RICHACE_WRITE_NAMED_ATTRS | \ + RICHACE_EXECUTE | \ + RICHACE_DELETE_CHILD | \ + RICHACE_READ_ATTRIBUTES | \ + RICHACE_WRITE_ATTRIBUTES | \ + RICHACE_WRITE_RETENTION | \ + RICHACE_WRITE_RETENTION_HOLD | \ + RICHACE_DELETE | \ + RICHACE_READ_ACL | \ + RICHACE_WRITE_ACL | \ + RICHACE_WRITE_OWNER | \ + RICHACE_SYNCHRONIZE ) + +#endif /* __UAPI_RICHACL_H */ -- 2.5.0 From agruenba@redhat.com Thu Nov 5 05:40:40 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 5A95F7FC2 for ; Thu, 5 Nov 2015 05:40:40 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 4C6548F8035 for ; Thu, 5 Nov 2015 03:40:40 -0800 (PST) X-ASG-Debug-ID: 1446723638-04cb6c296a3a1e0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id ydsJzNnw1uHLrQgu (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 05 Nov 2015 03:40:39 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 53D73935D1; Thu, 5 Nov 2015 11:40:38 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-134.ams2.redhat.com [10.36.7.134]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA5Bdfbi015870; Thu, 5 Nov 2015 06:40:32 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v14 07/22] richacl: Permission mapping functions Date: Thu, 5 Nov 2015 12:39:25 +0100 X-ASG-Orig-Subj: [PATCH v14 07/22] richacl: Permission mapping functions Message-Id: <1446723580-3747-8-git-send-email-agruenba@redhat.com> In-Reply-To: <1446723580-3747-1-git-send-email-agruenba@redhat.com> References: <1446723580-3747-1-git-send-email-agruenba@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: 1446723638 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 We need to map from POSIX permissions to NFSv4 permissions when a chmod() is done, from NFSv4 permissions to POSIX permissions when an acl is set (which implicitly sets the file permission bits), and from the MAY_READ/MAY_WRITE/MAY_EXEC/MAY_APPEND flags to NFSv4 permissions when doing an access check in a richacl. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_base.c | 118 +++++++++++++++++++++++++++++++++++++++++++ include/linux/richacl.h | 3 ++ include/uapi/linux/richacl.h | 44 ++++++++++++++++ 3 files changed, 165 insertions(+) diff --git a/fs/richacl_base.c b/fs/richacl_base.c index c3ec928..a393001 100644 --- a/fs/richacl_base.c +++ b/fs/richacl_base.c @@ -65,3 +65,121 @@ richace_copy(struct richace *to, const struct richace *from) { memcpy(to, from, sizeof(struct richace)); } + +/* + * richacl_mask_to_mode - compute the file permission bits from mask + * @mask: %RICHACE_* permission mask + * + * Compute the file permission bits corresponding to a particular set of + * richacl permissions. + * + * See richacl_masks_to_mode(). + */ +static int +richacl_mask_to_mode(unsigned int mask) +{ + int mode = 0; + + if (mask & RICHACE_POSIX_MODE_READ) + mode |= S_IROTH; + if (mask & RICHACE_POSIX_MODE_WRITE) + mode |= S_IWOTH; + if (mask & RICHACE_POSIX_MODE_EXEC) + mode |= S_IXOTH; + + return mode; +} + +/** + * richacl_masks_to_mode - compute file permission bits from file masks + * + * When setting a richacl, we set the file permission bits to indicate maximum + * permissions: for example, we set the Write permission when a mask contains + * RICHACE_APPEND_DATA even if it does not also contain RICHACE_WRITE_DATA. + * + * Permissions which are not in RICHACE_POSIX_MODE_READ, + * RICHACE_POSIX_MODE_WRITE, or RICHACE_POSIX_MODE_EXEC cannot be represented + * in the file permission bits. Such permissions can still be effective, but + * not for new files or after a chmod(); they must be explicitly enabled in the + * richacl. + */ +int +richacl_masks_to_mode(const struct richacl *acl) +{ + return richacl_mask_to_mode(acl->a_owner_mask) << 6 | + richacl_mask_to_mode(acl->a_group_mask) << 3 | + richacl_mask_to_mode(acl->a_other_mask); +} +EXPORT_SYMBOL_GPL(richacl_masks_to_mode); + +/** + * richacl_mode_to_mask - compute a file mask from the lowest three mode bits + * @mode: mode to convert to richacl permissions + * + * When the file permission bits of a file are set with chmod(), this specifies + * the maximum permissions that processes will get. All permissions beyond + * that will be removed from the file masks, and become ineffective. + */ +unsigned int +richacl_mode_to_mask(umode_t mode) +{ + unsigned int mask = 0; + + if (mode & S_IROTH) + mask |= RICHACE_POSIX_MODE_READ; + if (mode & S_IWOTH) + mask |= RICHACE_POSIX_MODE_WRITE; + if (mode & S_IXOTH) + mask |= RICHACE_POSIX_MODE_EXEC; + + return mask; +} + +/** + * richacl_want_to_mask - convert the iop->permission want argument to a mask + * @want: @want argument of the permission inode operation + * + * When checking for append, @want is (MAY_WRITE | MAY_APPEND). + * + * Richacls use the iop->may_create and iop->may_delete hooks which are used + * for checking if creating and deleting files is allowed. These hooks do not + * use richacl_want_to_mask(), so we do not have to deal with mapping MAY_WRITE + * to RICHACE_ADD_FILE, RICHACE_ADD_SUBDIRECTORY, and RICHACE_DELETE_CHILD + * here. + */ +unsigned int +richacl_want_to_mask(unsigned int want) +{ + unsigned int mask = 0; + + if (want & MAY_READ) + mask |= RICHACE_READ_DATA; + if (want & MAY_DELETE_SELF) + mask |= RICHACE_DELETE; + if (want & MAY_TAKE_OWNERSHIP) + mask |= RICHACE_WRITE_OWNER; + if (want & MAY_CHMOD) + mask |= RICHACE_WRITE_ACL; + if (want & MAY_SET_TIMES) + mask |= RICHACE_WRITE_ATTRIBUTES; + if (want & MAY_EXEC) + mask |= RICHACE_EXECUTE; + /* + * differentiate MAY_WRITE from these request + */ + if (want & (MAY_APPEND | + MAY_CREATE_FILE | MAY_CREATE_DIR | + MAY_DELETE_CHILD)) { + if (want & MAY_APPEND) + mask |= RICHACE_APPEND_DATA; + if (want & MAY_CREATE_FILE) + mask |= RICHACE_ADD_FILE; + if (want & MAY_CREATE_DIR) + mask |= RICHACE_ADD_SUBDIRECTORY; + if (want & MAY_DELETE_CHILD) + mask |= RICHACE_DELETE_CHILD; + } else if (want & MAY_WRITE) + mask |= RICHACE_WRITE_DATA; + return mask; +} +EXPORT_SYMBOL_GPL(richacl_want_to_mask); diff --git a/include/linux/richacl.h b/include/linux/richacl.h index edb8480..9102ef0 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -175,5 +175,8 @@ richace_is_same_identifier(const struct richace *a, const struct richace *b) extern struct richacl *richacl_alloc(int, gfp_t); extern struct richacl *richacl_clone(const struct richacl *, gfp_t); extern void richace_copy(struct richace *, const struct richace *); +extern int richacl_masks_to_mode(const struct richacl *); +extern unsigned int richacl_mode_to_mask(umode_t); +extern unsigned int richacl_want_to_mask(unsigned int); #endif /* __RICHACL_H */ diff --git a/include/uapi/linux/richacl.h b/include/uapi/linux/richacl.h index 08856f8..1ed48ac 100644 --- a/include/uapi/linux/richacl.h +++ b/include/uapi/linux/richacl.h @@ -96,4 +96,48 @@ RICHACE_WRITE_OWNER | \ RICHACE_SYNCHRONIZE ) +/* + * The POSIX permissions are supersets of the following richacl permissions: + * + * - MAY_READ maps to READ_DATA or LIST_DIRECTORY, depending on the type + * of the file system object. + * + * - MAY_WRITE maps to WRITE_DATA or RICHACE_APPEND_DATA for files, and to + * ADD_FILE, RICHACE_ADD_SUBDIRECTORY, or RICHACE_DELETE_CHILD for directories. + * + * - MAY_EXECUTE maps to RICHACE_EXECUTE. + * + * (Some of these richacl permissions have the same bit values.) + */ +#define RICHACE_POSIX_MODE_READ ( \ + RICHACE_READ_DATA | \ + RICHACE_LIST_DIRECTORY) +#define RICHACE_POSIX_MODE_WRITE ( \ + RICHACE_WRITE_DATA | \ + RICHACE_ADD_FILE | \ + RICHACE_APPEND_DATA | \ + RICHACE_ADD_SUBDIRECTORY | \ + RICHACE_DELETE_CHILD) +#define RICHACE_POSIX_MODE_EXEC RICHACE_EXECUTE +#define RICHACE_POSIX_MODE_ALL ( \ + RICHACE_POSIX_MODE_READ | \ + RICHACE_POSIX_MODE_WRITE | \ + RICHACE_POSIX_MODE_EXEC) + +/* + * These permissions are always allowed no matter what the acl says. + */ +#define RICHACE_POSIX_ALWAYS_ALLOWED ( \ + RICHACE_SYNCHRONIZE | \ + RICHACE_READ_ATTRIBUTES | \ + RICHACE_READ_ACL) + +/* + * The owner is implicitly granted these permissions under POSIX. + */ +#define RICHACE_POSIX_OWNER_ALLOWED ( \ + RICHACE_WRITE_ATTRIBUTES | \ + RICHACE_WRITE_OWNER | \ + RICHACE_WRITE_ACL) + #endif /* __UAPI_RICHACL_H */ -- 2.5.0 From agruenba@redhat.com Thu Nov 5 05:40:47 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 117847FC2 for ; Thu, 5 Nov 2015 05:40:47 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 91414AC002 for ; Thu, 5 Nov 2015 03:40:46 -0800 (PST) X-ASG-Debug-ID: 1446723645-04bdf03f043db30001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 7RTPhhCGOg1dLF1K (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 05 Nov 2015 03:40:45 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 32EE28F2FF; Thu, 5 Nov 2015 11:40:45 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-134.ams2.redhat.com [10.36.7.134]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA5Bdfbj015870; Thu, 5 Nov 2015 06:40:38 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v14 08/22] richacl: Compute maximum file masks from an acl Date: Thu, 5 Nov 2015 12:39:26 +0100 X-ASG-Orig-Subj: [PATCH v14 08/22] richacl: Compute maximum file masks from an acl Message-Id: <1446723580-3747-9-git-send-email-agruenba@redhat.com> In-Reply-To: <1446723580-3747-1-git-send-email-agruenba@redhat.com> References: <1446723580-3747-1-git-send-email-agruenba@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: 1446723645 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Compute upper bound owner, group, and other file masks with as few permissions as possible without denying any permissions that the NFSv4 acl in a richacl grants. This algorithm is used when a file inherits an acl at create time and when an acl is set via a mechanism that does not provide file masks (such as setting an acl via nfsd). When user-space sets an acl via setxattr, the extended attribute already includes the file masks. Setting an acl also sets the file mode permission bits: they are determined by the file masks; see richacl_masks_to_mode(). Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_base.c | 157 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/richacl.h | 1 + 2 files changed, 158 insertions(+) diff --git a/fs/richacl_base.c b/fs/richacl_base.c index a393001..69b806c 100644 --- a/fs/richacl_base.c +++ b/fs/richacl_base.c @@ -183,3 +183,160 @@ richacl_want_to_mask(unsigned int want) return mask; } EXPORT_SYMBOL_GPL(richacl_want_to_mask); + +/* + * Note: functions like richacl_allowed_to_who(), richacl_group_class_allowed(), + * and richacl_compute_max_masks() iterate through the entire acl in reverse + * order as an optimization. + * + * In the standard algorithm, aces are considered in forward order. When a + * process matches an ace, the permissions in the ace are either allowed or + * denied depending on the ace type. Once a permission has been allowed or + * denied, it is no longer considered in further aces. + * + * By iterating through the acl in reverse order, we can compute the same + * result without having to keep track of which permissions have been allowed + * and denied already. + */ + +/** + * richacl_allowed_to_who - permissions allowed to a specific who value + * + * Compute the maximum mask values allowed to a specific who value, taking + * everyone@ aces into account. + */ +static unsigned int richacl_allowed_to_who(struct richacl *acl, + struct richace *who) +{ + struct richace *ace; + unsigned int allowed = 0; + + richacl_for_each_entry_reverse(ace, acl) { + if (richace_is_inherit_only(ace)) + continue; + if (richace_is_same_identifier(ace, who) || + richace_is_everyone(ace)) { + if (richace_is_allow(ace)) + allowed |= ace->e_mask; + else if (richace_is_deny(ace)) + allowed &= ~ace->e_mask; + } + } + return allowed; +} + +/** + * richacl_group_class_allowed - maximum permissions of the group class + * + * Compute the maximum mask values allowed to a process in the group class + * (i.e., a process which is not the owner but is in the owning group or + * matches a user or group acl entry). This includes permissions granted or + * denied by everyone@ aces. + * + * See richacl_compute_max_masks(). + */ +static unsigned int richacl_group_class_allowed(struct richacl *acl) +{ + struct richace *ace; + unsigned int everyone_allowed = 0, group_class_allowed = 0; + int had_group_ace = 0; + + richacl_for_each_entry_reverse(ace, acl) { + if (richace_is_inherit_only(ace) || + richace_is_owner(ace)) + continue; + + if (richace_is_everyone(ace)) { + if (richace_is_allow(ace)) + everyone_allowed |= ace->e_mask; + else if (richace_is_deny(ace)) + everyone_allowed &= ~ace->e_mask; + } else { + group_class_allowed |= + richacl_allowed_to_who(acl, ace); + + if (richace_is_group(ace)) + had_group_ace = 1; + } + } + /* + * If the acl doesn't contain any group@ aces, richacl_allowed_to_who() + * wasn't called for the owning group. We could make that call now, but + * we already know the result (everyone_allowed). + */ + if (!had_group_ace) + group_class_allowed |= everyone_allowed; + return group_class_allowed; +} + +/** + * richacl_compute_max_masks - compute upper bound masks + * + * Computes upper bound owner, group, and other masks so that none of the + * permissions allowed by the acl are disabled. + * + * We don't make assumptions about who the owner is so that the owner can + * change with no effect on the file masks or file mode permission bits; this + * means that we must assume that all entries can match the owner. + */ +void richacl_compute_max_masks(struct richacl *acl) +{ + unsigned int gmask = ~0; + struct richace *ace; + + /* + * @gmask contains all permissions which the group class is ever + * allowed. We use it to avoid adding permissions to the group mask + * from everyone@ allow aces which the group class is always denied + * through other aces. For example, the following acl would otherwise + * result in a group mask of rw: + * + * group@:w::deny + * everyone@:rw::allow + * + * Avoid computing @gmask for acls which do not include any group class + * deny aces: in such acls, the group class is never denied any + * permissions from everyone@ allow aces, and the group class cannot + * have fewer permissions than the other class. + */ + +restart: + acl->a_owner_mask = 0; + acl->a_group_mask = 0; + acl->a_other_mask = 0; + + richacl_for_each_entry_reverse(ace, acl) { + if (richace_is_inherit_only(ace)) + continue; + + if (richace_is_owner(ace)) { + if (richace_is_allow(ace)) + acl->a_owner_mask |= ace->e_mask; + else if (richace_is_deny(ace)) + acl->a_owner_mask &= ~ace->e_mask; + } else if (richace_is_everyone(ace)) { + if (richace_is_allow(ace)) { + acl->a_owner_mask |= ace->e_mask; + acl->a_group_mask |= ace->e_mask & gmask; + acl->a_other_mask |= ace->e_mask; + } else if (richace_is_deny(ace)) { + acl->a_owner_mask &= ~ace->e_mask; + acl->a_group_mask &= ~ace->e_mask; + acl->a_other_mask &= ~ace->e_mask; + } + } else { + if (richace_is_allow(ace)) { + acl->a_owner_mask |= ace->e_mask & gmask; + acl->a_group_mask |= ace->e_mask & gmask; + } else if (richace_is_deny(ace) && gmask == ~0) { + gmask = richacl_group_class_allowed(acl); + if (likely(gmask != ~0)) + /* should always be true */ + goto restart; + } + } + } + + acl->a_flags &= ~(RICHACL_WRITE_THROUGH | RICHACL_MASKED); +} +EXPORT_SYMBOL_GPL(richacl_compute_max_masks); diff --git a/include/linux/richacl.h b/include/linux/richacl.h index 9102ef0..3559b2c 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -178,5 +178,6 @@ extern void richace_copy(struct richace *, const struct richace *); extern int richacl_masks_to_mode(const struct richacl *); extern unsigned int richacl_mode_to_mask(umode_t); extern unsigned int richacl_want_to_mask(unsigned int); +extern void richacl_compute_max_masks(struct richacl *); #endif /* __RICHACL_H */ -- 2.5.0 From agruenba@redhat.com Thu Nov 5 05:40:54 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 122A98006 for ; Thu, 5 Nov 2015 05:40:54 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 01E458F8033 for ; Thu, 5 Nov 2015 03:40:53 -0800 (PST) X-ASG-Debug-ID: 1446723652-04cb6c296c3a200001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 2CjLONPpdIBI7GI1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 05 Nov 2015 03:40:52 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 0D229935DA; Thu, 5 Nov 2015 11:40:52 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-134.ams2.redhat.com [10.36.7.134]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA5Bdfbk015870; Thu, 5 Nov 2015 06:40:45 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v14 09/22] richacl: Permission check algorithm Date: Thu, 5 Nov 2015 12:39:27 +0100 X-ASG-Orig-Subj: [PATCH v14 09/22] richacl: Permission check algorithm Message-Id: <1446723580-3747-10-git-send-email-agruenba@redhat.com> In-Reply-To: <1446723580-3747-1-git-send-email-agruenba@redhat.com> References: <1446723580-3747-1-git-send-email-agruenba@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: 1446723652 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 A richacl roughly grants a requested access if the NFSv4 acl in the richacl grants the requested permissions according to the NFSv4 permission check algorithm and the file mask that applies to the process includes the requested permissions. Signed-off-by: Andreas Gruenbacher Reviewed-by: "J. Bruce Fields" --- fs/Makefile | 2 +- fs/richacl_inode.c | 149 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/richacl.h | 3 + 3 files changed, 153 insertions(+), 1 deletion(-) create mode 100644 fs/richacl_inode.c diff --git a/fs/Makefile b/fs/Makefile index fe3e9dd..ec665fd 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -49,7 +49,7 @@ obj-$(CONFIG_SYSCTL) += drop_caches.o obj-$(CONFIG_FHANDLE) += fhandle.o obj-$(CONFIG_FS_RICHACL) += richacl.o -richacl-y := richacl_base.o +richacl-y := richacl_base.o richacl_inode.o obj-y += quota/ diff --git a/fs/richacl_inode.c b/fs/richacl_inode.c new file mode 100644 index 0000000..99b3c93 --- /dev/null +++ b/fs/richacl_inode.c @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2010 Novell, Inc. + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * 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; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include +#include +#include +#include +#include + +/** + * richacl_permission - richacl permission check algorithm + * @inode: inode to check + * @acl: rich acl of the inode + * @want: requested access (MAY_* flags) + * + * Checks if the current process is granted @mask flags in @acl. + */ +int +richacl_permission(struct inode *inode, const struct richacl *acl, + int want) +{ + const struct richace *ace; + unsigned int mask = richacl_want_to_mask(want); + unsigned int requested = mask, denied = 0; + int in_owning_group = in_group_p(inode->i_gid); + int in_owner_or_group_class = in_owning_group; + + /* + * A process is + * - in the owner file class if it owns the file, + * - in the group file class if it is in the file's owning group or + * it matches any of the user or group entries, and + * - in the other file class otherwise. + * The file class is only relevant for determining which file mask to + * apply, which only happens for masked acls. + */ + if (acl->a_flags & RICHACL_MASKED) { + if ((acl->a_flags & RICHACL_WRITE_THROUGH) && + uid_eq(current_fsuid(), inode->i_uid)) { + denied = requested & ~acl->a_owner_mask; + goto out; + } + } else { + /* + * When the acl is not masked, there is no need to determine if + * the process is in the group class and we can break out + * earlier of the loop below. + */ + in_owner_or_group_class = 1; + } + + /* + * Check if the acl grants the requested access and determine which + * file class the process is in. + */ + richacl_for_each_entry(ace, acl) { + unsigned int ace_mask = ace->e_mask; + + if (richace_is_inherit_only(ace)) + continue; + if (richace_is_owner(ace)) { + if (!uid_eq(current_fsuid(), inode->i_uid)) + continue; + goto entry_matches_owner; + } else if (richace_is_group(ace)) { + if (!in_owning_group) + continue; + } else if (richace_is_unix_user(ace)) { + if (!uid_eq(current_fsuid(), ace->e_id.uid)) + continue; + if (uid_eq(current_fsuid(), inode->i_uid)) + goto entry_matches_owner; + } else if (richace_is_unix_group(ace)) { + if (!in_group_p(ace->e_id.gid)) + continue; + } else + goto entry_matches_everyone; + + /* + * Apply the group file mask to entries other than owner@ and + * everyone@ or user entries matching the owner. This ensures + * that we grant the same permissions as the acl computed by + * richacl_apply_masks(). + * + * Without this restriction, the following richacl would grant + * rw access to processes which are both the owner and in the + * owning group, but not to other users in the owning group, + * which could not be represented without masks: + * + * owner:rw::mask + * group@:rw::allow + */ + if ((acl->a_flags & RICHACL_MASKED) && richace_is_allow(ace)) + ace_mask &= acl->a_group_mask; + +entry_matches_owner: + /* The process is in the owner or group file class. */ + in_owner_or_group_class = 1; + +entry_matches_everyone: + /* Check which mask flags the ACE allows or denies. */ + if (richace_is_deny(ace)) + denied |= ace_mask & mask; + mask &= ~ace_mask; + + /* + * Keep going until we know which file class + * the process is in. + */ + if (!mask && in_owner_or_group_class) + break; + } + denied |= mask; + + if (acl->a_flags & RICHACL_MASKED) { + /* + * The file class a process is in determines which file mask + * applies. Check if that file mask also grants the requested + * access. + */ + if (uid_eq(current_fsuid(), inode->i_uid)) + denied |= requested & ~acl->a_owner_mask; + else if (in_owner_or_group_class) + denied |= requested & ~acl->a_group_mask; + else { + if (acl->a_flags & RICHACL_WRITE_THROUGH) + denied = requested & ~acl->a_other_mask; + else + denied |= requested & ~acl->a_other_mask; + } + } + +out: + return denied ? -EACCES : 0; +} +EXPORT_SYMBOL_GPL(richacl_permission); diff --git a/include/linux/richacl.h b/include/linux/richacl.h index 3559b2c..1d9f5f7 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -180,4 +180,7 @@ extern unsigned int richacl_mode_to_mask(umode_t); extern unsigned int richacl_want_to_mask(unsigned int); extern void richacl_compute_max_masks(struct richacl *); +/* richacl_inode.c */ +extern int richacl_permission(struct inode *, const struct richacl *, int); + #endif /* __RICHACL_H */ -- 2.5.0 From agruenba@redhat.com Thu Nov 5 05:41:00 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 69A667FE9 for ; Thu, 5 Nov 2015 05:41:00 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 5CB308F8037 for ; Thu, 5 Nov 2015 03:41:00 -0800 (PST) X-ASG-Debug-ID: 1446723659-04cb6c296d3a210001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 2BUQLDCSHZy2lc9D (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 05 Nov 2015 03:40:59 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id EA28C8F50D; Thu, 5 Nov 2015 11:40:58 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-134.ams2.redhat.com [10.36.7.134]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA5Bdfbl015870; Thu, 5 Nov 2015 06:40:52 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v14 10/22] posix_acl: Unexport acl_by_type and make it static Date: Thu, 5 Nov 2015 12:39:28 +0100 X-ASG-Orig-Subj: [PATCH v14 10/22] posix_acl: Unexport acl_by_type and make it static Message-Id: <1446723580-3747-11-git-send-email-agruenba@redhat.com> In-Reply-To: <1446723580-3747-1-git-send-email-agruenba@redhat.com> References: <1446723580-3747-1-git-send-email-agruenba@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: 1446723659 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 acl_by_type(inode, type) returns a pointer to either inode->i_acl or inode->i_default_acl depending on type. This is useful in fs/posix_acl.c, but should never have been visible outside that file. Signed-off-by: Andreas Gruenbacher --- fs/posix_acl.c | 3 +-- include/linux/posix_acl.h | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/fs/posix_acl.c b/fs/posix_acl.c index 4fb17de..aacfb58 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c @@ -21,7 +21,7 @@ #include #include -struct posix_acl **acl_by_type(struct inode *inode, int type) +static struct posix_acl **acl_by_type(struct inode *inode, int type) { switch (type) { case ACL_TYPE_ACCESS: @@ -32,7 +32,6 @@ struct posix_acl **acl_by_type(struct inode *inode, int type) BUG(); } } -EXPORT_SYMBOL(acl_by_type); struct posix_acl *get_cached_acl(struct inode *inode, int type) { diff --git a/include/linux/posix_acl.h b/include/linux/posix_acl.h index 3e96a6a..5b5a80c 100644 --- a/include/linux/posix_acl.h +++ b/include/linux/posix_acl.h @@ -99,7 +99,6 @@ extern int posix_acl_create(struct inode *, umode_t *, struct posix_acl **, extern int simple_set_acl(struct inode *, struct posix_acl *, int); extern int simple_acl_create(struct inode *, struct inode *); -struct posix_acl **acl_by_type(struct inode *inode, int type); struct posix_acl *get_cached_acl(struct inode *inode, int type); struct posix_acl *get_cached_acl_rcu(struct inode *inode, int type); void set_cached_acl(struct inode *inode, int type, struct posix_acl *acl); -- 2.5.0 From agruenba@redhat.com Thu Nov 5 05:41:08 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 899EB7FDB for ; Thu, 5 Nov 2015 05:41:08 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 6BBE9304051 for ; Thu, 5 Nov 2015 03:41:08 -0800 (PST) X-ASG-Debug-ID: 1446723666-04cb6c296b3a210001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id mWg9hRFtCdUvXxjb (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 05 Nov 2015 03:41:06 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 29648C0D61A5; Thu, 5 Nov 2015 11:41:06 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-134.ams2.redhat.com [10.36.7.134]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA5Bdfbm015870; Thu, 5 Nov 2015 06:40:59 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v14 11/22] vfs: Cache base_acl objects in inodes Date: Thu, 5 Nov 2015 12:39:29 +0100 X-ASG-Orig-Subj: [PATCH v14 11/22] vfs: Cache base_acl objects in inodes Message-Id: <1446723580-3747-12-git-send-email-agruenba@redhat.com> In-Reply-To: <1446723580-3747-1-git-send-email-agruenba@redhat.com> References: <1446723580-3747-1-git-send-email-agruenba@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: 1446723666 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 POSIX ACLs and richacls are both objects allocated by kmalloc() with a reference count which are freed by kfree_rcu(). An inode can either cache an access and a default POSIX ACL, or a richacl (richacls do not have default acls). To allow an inode to cache either of the two kinds of acls, introduce a new base_acl type and convert i_acl and i_default_acl to that type. In most cases, the vfs then doesn't care which kind of acl an inode caches (if any). Signed-off-by: Andreas Gruenbacher --- drivers/staging/lustre/lustre/llite/llite_lib.c | 2 +- fs/f2fs/acl.c | 4 +-- fs/inode.c | 4 +-- fs/jffs2/acl.c | 10 ++++-- fs/posix_acl.c | 41 +++++++++++++------------ fs/richacl_base.c | 4 +-- include/linux/fs.h | 34 ++++++++++++++++++-- include/linux/posix_acl.h | 12 +++----- include/linux/richacl.h | 9 +++--- 9 files changed, 75 insertions(+), 45 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c index b4ed6c8..46912c2 100644 --- a/drivers/staging/lustre/lustre/llite/llite_lib.c +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c @@ -1118,7 +1118,7 @@ void ll_clear_inode(struct inode *inode) } #ifdef CONFIG_FS_POSIX_ACL else if (lli->lli_posix_acl) { - LASSERT(atomic_read(&lli->lli_posix_acl->a_refcount) == 1); + LASSERT(base_acl_refcount(&lli->lli_posix_acl->a_base) == 1); LASSERT(lli->lli_remote_perms == NULL); posix_acl_release(lli->lli_posix_acl); lli->lli_posix_acl = NULL; diff --git a/fs/f2fs/acl.c b/fs/f2fs/acl.c index c8f25f7..9646197 100644 --- a/fs/f2fs/acl.c +++ b/fs/f2fs/acl.c @@ -270,7 +270,7 @@ static struct posix_acl *f2fs_acl_clone(const struct posix_acl *acl, sizeof(struct posix_acl_entry); clone = kmemdup(acl, size, flags); if (clone) - atomic_set(&clone->a_refcount, 1); + base_acl_init(&clone->a_base); } return clone; } @@ -282,7 +282,7 @@ static int f2fs_acl_create_masq(struct posix_acl *acl, umode_t *mode_p) umode_t mode = *mode_p; int not_equiv = 0; - /* assert(atomic_read(acl->a_refcount) == 1); */ + /* assert(base_acl_refcount(&acl->a_base) == 1); */ FOREACH_ACL_ENTRY(pa, acl, pe) { switch(pa->e_tag) { diff --git a/fs/inode.c b/fs/inode.c index 78a17b8..5c46ae5 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -233,9 +233,9 @@ void __destroy_inode(struct inode *inode) #ifdef CONFIG_FS_POSIX_ACL if (inode->i_acl && inode->i_acl != ACL_NOT_CACHED) - posix_acl_release(inode->i_acl); + base_acl_put(inode->i_acl); if (inode->i_default_acl && inode->i_default_acl != ACL_NOT_CACHED) - posix_acl_release(inode->i_default_acl); + base_acl_put(inode->i_default_acl); #endif this_cpu_dec(nr_inodes); } diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c index 2f7a3c0..569cb1b 100644 --- a/fs/jffs2/acl.c +++ b/fs/jffs2/acl.c @@ -294,13 +294,19 @@ int jffs2_init_acl_post(struct inode *inode) int rc; if (inode->i_default_acl) { - rc = __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_DEFAULT, inode->i_default_acl); + struct posix_acl *default_acl = container_of( + inode->i_default_acl, struct posix_acl, a_base); + + rc = __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_DEFAULT, default_acl); if (rc) return rc; } if (inode->i_acl) { - rc = __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_ACCESS, inode->i_acl); + struct posix_acl *acl = container_of( + inode->i_acl, struct posix_acl, a_base); + + rc = __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_ACCESS, acl); if (rc) return rc; } diff --git a/fs/posix_acl.c b/fs/posix_acl.c index aacfb58..4573315 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c @@ -21,7 +21,7 @@ #include #include -static struct posix_acl **acl_by_type(struct inode *inode, int type) +static struct base_acl **acl_by_type(struct inode *inode, int type) { switch (type) { case ACL_TYPE_ACCESS: @@ -35,63 +35,64 @@ static struct posix_acl **acl_by_type(struct inode *inode, int type) struct posix_acl *get_cached_acl(struct inode *inode, int type) { - struct posix_acl **p = acl_by_type(inode, type); - struct posix_acl *acl = ACCESS_ONCE(*p); + struct base_acl **p = acl_by_type(inode, type); + struct base_acl *acl = ACCESS_ONCE(*p); if (acl) { spin_lock(&inode->i_lock); acl = *p; if (acl != ACL_NOT_CACHED) - acl = posix_acl_dup(acl); + base_acl_get(acl); spin_unlock(&inode->i_lock); } - return acl; + return container_of(acl, struct posix_acl, a_base); } EXPORT_SYMBOL(get_cached_acl); struct posix_acl *get_cached_acl_rcu(struct inode *inode, int type) { - return rcu_dereference(*acl_by_type(inode, type)); + struct base_acl *acl = rcu_dereference(*acl_by_type(inode, type)); + return container_of(acl, struct posix_acl, a_base); } EXPORT_SYMBOL(get_cached_acl_rcu); void set_cached_acl(struct inode *inode, int type, struct posix_acl *acl) { - struct posix_acl **p = acl_by_type(inode, type); - struct posix_acl *old; + struct base_acl **p = acl_by_type(inode, type); + struct base_acl *old; spin_lock(&inode->i_lock); old = *p; - rcu_assign_pointer(*p, posix_acl_dup(acl)); + rcu_assign_pointer(*p, &posix_acl_dup(acl)->a_base); spin_unlock(&inode->i_lock); if (old != ACL_NOT_CACHED) - posix_acl_release(old); + base_acl_put(old); } EXPORT_SYMBOL(set_cached_acl); void forget_cached_acl(struct inode *inode, int type) { - struct posix_acl **p = acl_by_type(inode, type); - struct posix_acl *old; + struct base_acl **p = acl_by_type(inode, type); + struct base_acl *old; spin_lock(&inode->i_lock); old = *p; *p = ACL_NOT_CACHED; spin_unlock(&inode->i_lock); if (old != ACL_NOT_CACHED) - posix_acl_release(old); + base_acl_put(old); } EXPORT_SYMBOL(forget_cached_acl); void forget_all_cached_acls(struct inode *inode) { - struct posix_acl *old_access, *old_default; + struct base_acl *old_access, *old_default; spin_lock(&inode->i_lock); old_access = inode->i_acl; old_default = inode->i_default_acl; inode->i_acl = inode->i_default_acl = ACL_NOT_CACHED; spin_unlock(&inode->i_lock); if (old_access != ACL_NOT_CACHED) - posix_acl_release(old_access); + base_acl_put(old_access); if (old_default != ACL_NOT_CACHED) - posix_acl_release(old_default); + base_acl_put(old_default); } EXPORT_SYMBOL(forget_all_cached_acls); @@ -128,7 +129,7 @@ EXPORT_SYMBOL(get_acl); void posix_acl_init(struct posix_acl *acl, int count) { - atomic_set(&acl->a_refcount, 1); + base_acl_init(&acl->a_base); acl->a_count = count; } EXPORT_SYMBOL(posix_acl_init); @@ -161,7 +162,7 @@ posix_acl_clone(const struct posix_acl *acl, gfp_t flags) sizeof(struct posix_acl_entry); clone = kmemdup(acl, size, flags); if (clone) - atomic_set(&clone->a_refcount, 1); + base_acl_init(&clone->a_base); } return clone; } @@ -383,7 +384,7 @@ static int posix_acl_create_masq(struct posix_acl *acl, umode_t *mode_p) umode_t mode = *mode_p; int not_equiv = 0; - /* assert(atomic_read(acl->a_refcount) == 1); */ + /* assert(base_acl_refcount(&acl->a_base) == 1); */ FOREACH_ACL_ENTRY(pa, acl, pe) { switch(pa->e_tag) { @@ -438,7 +439,7 @@ static int __posix_acl_chmod_masq(struct posix_acl *acl, umode_t mode) struct posix_acl_entry *group_obj = NULL, *mask_obj = NULL; struct posix_acl_entry *pa, *pe; - /* assert(atomic_read(acl->a_refcount) == 1); */ + /* assert(base_acl_refcount(&acl->a_base) == 1); */ FOREACH_ACL_ENTRY(pa, acl, pe) { switch(pa->e_tag) { diff --git a/fs/richacl_base.c b/fs/richacl_base.c index 69b806c..5826842 100644 --- a/fs/richacl_base.c +++ b/fs/richacl_base.c @@ -33,7 +33,7 @@ richacl_alloc(int count, gfp_t gfp) struct richacl *acl = kzalloc(size, gfp); if (acl) { - atomic_set(&acl->a_refcount, 1); + base_acl_init(&acl->a_base); acl->a_count = count; } return acl; @@ -52,7 +52,7 @@ richacl_clone(const struct richacl *acl, gfp_t gfp) if (dup) { memcpy(dup, acl, size); - atomic_set(&dup->a_refcount, 1); + base_acl_init(&dup->a_base); } return dup; } diff --git a/include/linux/fs.h b/include/linux/fs.h index ba91a89..2fd840e 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -576,6 +576,12 @@ static inline void mapping_allow_writable(struct address_space *mapping) #define i_size_ordered_init(inode) do { } while (0) #endif +struct base_acl { + union { + atomic_t ba_refcount; + struct rcu_head ba_rcu; + }; +}; struct posix_acl; #define ACL_NOT_CACHED ((void *)(-1)) @@ -595,9 +601,9 @@ struct inode { kgid_t i_gid; unsigned int i_flags; -#ifdef CONFIG_FS_POSIX_ACL - struct posix_acl *i_acl; - struct posix_acl *i_default_acl; +#if defined(CONFIG_FS_POSIX_ACL) + struct base_acl *i_acl; + struct base_acl *i_default_acl; #endif const struct inode_operations *i_op; @@ -3059,4 +3065,26 @@ static inline bool dir_relax(struct inode *inode) extern bool path_noexec(const struct path *path); +static inline void base_acl_get(struct base_acl *acl) +{ + if (acl) + atomic_inc(&acl->ba_refcount); +} + +static inline void base_acl_put(struct base_acl *acl) +{ + if (acl && atomic_dec_and_test(&acl->ba_refcount)) + kfree_rcu(acl, ba_rcu); +} + +static inline void base_acl_init(struct base_acl *acl) +{ + atomic_set(&acl->ba_refcount, 1); +} + +static inline int base_acl_refcount(struct base_acl *acl) +{ + return atomic_read(&acl->ba_refcount); +} + #endif /* _LINUX_FS_H */ diff --git a/include/linux/posix_acl.h b/include/linux/posix_acl.h index 5b5a80c..cef5428 100644 --- a/include/linux/posix_acl.h +++ b/include/linux/posix_acl.h @@ -43,10 +43,7 @@ struct posix_acl_entry { }; struct posix_acl { - union { - atomic_t a_refcount; - struct rcu_head a_rcu; - }; + struct base_acl a_base; /* must be first, see posix_acl_release() */ unsigned int a_count; struct posix_acl_entry a_entries[0]; }; @@ -61,8 +58,7 @@ struct posix_acl { static inline struct posix_acl * posix_acl_dup(struct posix_acl *acl) { - if (acl) - atomic_inc(&acl->a_refcount); + base_acl_get(&acl->a_base); return acl; } @@ -72,8 +68,8 @@ posix_acl_dup(struct posix_acl *acl) static inline void posix_acl_release(struct posix_acl *acl) { - if (acl && atomic_dec_and_test(&acl->a_refcount)) - kfree_rcu(acl, a_rcu); + BUILD_BUG_ON(offsetof(struct posix_acl, a_base) != 0); + base_acl_put(&acl->a_base); } diff --git a/include/linux/richacl.h b/include/linux/richacl.h index 1d9f5f7..7628fad 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -31,7 +31,7 @@ struct richace { }; struct richacl { - atomic_t a_refcount; + struct base_acl a_base; /* must be first, see richacl_put() */ unsigned int a_owner_mask; unsigned int a_group_mask; unsigned int a_other_mask; @@ -56,8 +56,7 @@ struct richacl { static inline struct richacl * richacl_get(struct richacl *acl) { - if (acl) - atomic_inc(&acl->a_refcount); + base_acl_get(&acl->a_base); return acl; } @@ -67,8 +66,8 @@ richacl_get(struct richacl *acl) static inline void richacl_put(struct richacl *acl) { - if (acl && atomic_dec_and_test(&acl->a_refcount)) - kfree(acl); + BUILD_BUG_ON(offsetof(struct richacl, a_base) != 0); + base_acl_put(&acl->a_base); } /** -- 2.5.0 From agruenba@redhat.com Thu Nov 5 05:41:15 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 325A77FD7 for ; Thu, 5 Nov 2015 05:41:15 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id A7430AC001 for ; Thu, 5 Nov 2015 03:41:14 -0800 (PST) X-ASG-Debug-ID: 1446723673-04cb6c296b3a220001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 0kyrtnKVEHzubgWc (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 05 Nov 2015 03:41:13 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 06A2CC0032EA; Thu, 5 Nov 2015 11:41:13 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-134.ams2.redhat.com [10.36.7.134]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA5Bdfbn015870; Thu, 5 Nov 2015 06:41:06 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v14 12/22] vfs: Add get_richacl and set_richacl inode operations Date: Thu, 5 Nov 2015 12:39:30 +0100 X-ASG-Orig-Subj: [PATCH v14 12/22] vfs: Add get_richacl and set_richacl inode operations Message-Id: <1446723580-3747-13-git-send-email-agruenba@redhat.com> In-Reply-To: <1446723580-3747-1-git-send-email-agruenba@redhat.com> References: <1446723580-3747-1-git-send-email-agruenba@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: 1446723673 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 These operations are similar to the get_acl and set_acl operations for POSIX ACLs. The distinction between access and default ACLs doesn't exist for richacls. Signed-off-by: Andreas Gruenbacher --- include/linux/fs.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/fs.h b/include/linux/fs.h index 2fd840e..3c36c72 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1662,6 +1662,7 @@ struct inode_operations { const char * (*follow_link) (struct dentry *, void **); int (*permission) (struct inode *, int); struct posix_acl * (*get_acl)(struct inode *, int); + struct richacl * (*get_richacl)(struct inode *); int (*readlink) (struct dentry *, char __user *,int); void (*put_link) (struct inode *, void *); @@ -1691,6 +1692,7 @@ struct inode_operations { umode_t create_mode, int *opened); int (*tmpfile) (struct inode *, struct dentry *, umode_t); int (*set_acl)(struct inode *, struct posix_acl *, int); + int (*set_richacl)(struct inode *, struct richacl *); /* WARNING: probably going away soon, do not use! */ } ____cacheline_aligned; -- 2.5.0 From agruenba@redhat.com Thu Nov 5 05:41:21 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 A61467FEB for ; Thu, 5 Nov 2015 05:41:21 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 984EC8F8033 for ; Thu, 5 Nov 2015 03:41:21 -0800 (PST) X-ASG-Debug-ID: 1446723680-04cbb0242342400001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id Ikhp6BBCGoQC6BVT (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 05 Nov 2015 03:41:20 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id D630CE7066; Thu, 5 Nov 2015 11:41:19 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-134.ams2.redhat.com [10.36.7.134]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA5Bdfbo015870; Thu, 5 Nov 2015 06:41:13 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v14 13/22] vfs: Cache richacl in struct inode Date: Thu, 5 Nov 2015 12:39:31 +0100 X-ASG-Orig-Subj: [PATCH v14 13/22] vfs: Cache richacl in struct inode Message-Id: <1446723580-3747-14-git-send-email-agruenba@redhat.com> In-Reply-To: <1446723580-3747-1-git-send-email-agruenba@redhat.com> References: <1446723580-3747-1-git-send-email-agruenba@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: 1446723680 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Cache richacls in struct inode so that this doesn't have to be done individually in each filesystem. This is similar to POSIX ACLs. Signed-off-by: Andreas Gruenbacher --- fs/inode.c | 11 +++++-- fs/posix_acl.c | 2 +- fs/richacl_inode.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/fs.h | 5 +++- include/linux/richacl.h | 6 ++++ 5 files changed, 96 insertions(+), 5 deletions(-) diff --git a/fs/inode.c b/fs/inode.c index 5c46ae5..5e8710c 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -174,8 +174,11 @@ int inode_init_always(struct super_block *sb, struct inode *inode) inode->i_private = NULL; inode->i_mapping = mapping; INIT_HLIST_HEAD(&inode->i_dentry); /* buggered by rcu freeing */ -#ifdef CONFIG_FS_POSIX_ACL - inode->i_acl = inode->i_default_acl = ACL_NOT_CACHED; +#if defined(CONFIG_FS_POSIX_ACL) || defined(CONFIG_FS_RICHACL) + inode->i_acl = ACL_NOT_CACHED; +# if defined(CONFIG_FS_POSIX_ACL) + inode->i_default_acl = ACL_NOT_CACHED; +# endif #endif #ifdef CONFIG_FSNOTIFY @@ -231,11 +234,13 @@ void __destroy_inode(struct inode *inode) atomic_long_dec(&inode->i_sb->s_remove_count); } -#ifdef CONFIG_FS_POSIX_ACL +#if defined(CONFIG_FS_POSIX_ACL) || defined(CONFIG_FS_RICHACL) if (inode->i_acl && inode->i_acl != ACL_NOT_CACHED) base_acl_put(inode->i_acl); +# if defined(CONFIG_FS_POSIX_ACL) if (inode->i_default_acl && inode->i_default_acl != ACL_NOT_CACHED) base_acl_put(inode->i_default_acl); +# endif #endif this_cpu_dec(nr_inodes); } diff --git a/fs/posix_acl.c b/fs/posix_acl.c index 4573315..b0eb1dc 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c @@ -37,7 +37,7 @@ struct posix_acl *get_cached_acl(struct inode *inode, int type) { struct base_acl **p = acl_by_type(inode, type); struct base_acl *acl = ACCESS_ONCE(*p); - if (acl) { + if (acl && IS_POSIXACL(inode)) { spin_lock(&inode->i_lock); acl = *p; if (acl != ACL_NOT_CACHED) diff --git a/fs/richacl_inode.c b/fs/richacl_inode.c index 99b3c93..52c1595 100644 --- a/fs/richacl_inode.c +++ b/fs/richacl_inode.c @@ -20,6 +20,83 @@ #include #include +struct richacl *get_cached_richacl(struct inode *inode) +{ + struct base_acl *acl; + + acl = ACCESS_ONCE(inode->i_acl); + if (acl && IS_RICHACL(inode)) { + spin_lock(&inode->i_lock); + acl = inode->i_acl; + if (acl != ACL_NOT_CACHED) + base_acl_get(acl); + spin_unlock(&inode->i_lock); + } + return container_of(acl, struct richacl, a_base); +} +EXPORT_SYMBOL_GPL(get_cached_richacl); + +struct richacl *get_cached_richacl_rcu(struct inode *inode) +{ + struct base_acl *acl = rcu_dereference(inode->i_acl); + + return container_of(acl, struct richacl, a_base); +} +EXPORT_SYMBOL_GPL(get_cached_richacl_rcu); + +void set_cached_richacl(struct inode *inode, struct richacl *acl) +{ + struct base_acl *old = NULL; + + spin_lock(&inode->i_lock); + old = inode->i_acl; + rcu_assign_pointer(inode->i_acl, &richacl_get(acl)->a_base); + spin_unlock(&inode->i_lock); + if (old != ACL_NOT_CACHED) + base_acl_put(old); +} +EXPORT_SYMBOL_GPL(set_cached_richacl); + +void forget_cached_richacl(struct inode *inode) +{ + struct base_acl *old = NULL; + + spin_lock(&inode->i_lock); + old = inode->i_acl; + inode->i_acl = ACL_NOT_CACHED; + spin_unlock(&inode->i_lock); + if (old != ACL_NOT_CACHED) + base_acl_put(old); +} +EXPORT_SYMBOL_GPL(forget_cached_richacl); + +struct richacl *get_richacl(struct inode *inode) +{ + struct richacl *acl; + + acl = get_cached_richacl(inode); + if (acl != ACL_NOT_CACHED) + return acl; + + if (!IS_RICHACL(inode)) + return NULL; + + /* + * A filesystem can force a ACL callback by just never filling the + * ACL cache. But normally you'd fill the cache either at inode + * instantiation time, or on the first ->get_richacl call. + * + * If the filesystem doesn't have a get_richacl() function at all, + * we'll just create the negative cache entry. + */ + if (!inode->i_op->get_richacl) { + set_cached_richacl(inode, NULL); + return NULL; + } + return inode->i_op->get_richacl(inode); +} +EXPORT_SYMBOL_GPL(get_richacl); + /** * richacl_permission - richacl permission check algorithm * @inode: inode to check diff --git a/include/linux/fs.h b/include/linux/fs.h index 3c36c72..05fb943 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -583,6 +583,7 @@ struct base_acl { }; }; struct posix_acl; +struct richacl; #define ACL_NOT_CACHED ((void *)(-1)) #define IOP_FASTPERM 0x0001 @@ -601,9 +602,11 @@ struct inode { kgid_t i_gid; unsigned int i_flags; -#if defined(CONFIG_FS_POSIX_ACL) +#if defined(CONFIG_FS_POSIX_ACL) || defined(CONFIG_FS_RICHACL) struct base_acl *i_acl; +# if defined(CONFIG_FS_POSIX_ACL) struct base_acl *i_default_acl; +# endif #endif const struct inode_operations *i_op; diff --git a/include/linux/richacl.h b/include/linux/richacl.h index 7628fad..7bf912b6 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -70,6 +70,12 @@ richacl_put(struct richacl *acl) base_acl_put(&acl->a_base); } +extern struct richacl *get_cached_richacl(struct inode *); +extern struct richacl *get_cached_richacl_rcu(struct inode *); +extern void set_cached_richacl(struct inode *, struct richacl *); +extern void forget_cached_richacl(struct inode *); +extern struct richacl *get_richacl(struct inode *); + /** * richace_is_owner - check if @ace is an OWNER@ entry */ -- 2.5.0 From agruenba@redhat.com Thu Nov 5 05:41:28 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 A832E7FD7 for ; Thu, 5 Nov 2015 05:41:28 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 9B6BA304053 for ; Thu, 5 Nov 2015 03:41:28 -0800 (PST) X-ASG-Debug-ID: 1446723687-04cbb0242342430001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 37skatNcsUU11VtF (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 05 Nov 2015 03:41:27 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id C831614CAA7; Thu, 5 Nov 2015 11:41:26 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-134.ams2.redhat.com [10.36.7.134]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA5Bdfbp015870; Thu, 5 Nov 2015 06:41:20 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v14 14/22] richacl: Update the file masks in chmod() Date: Thu, 5 Nov 2015 12:39:32 +0100 X-ASG-Orig-Subj: [PATCH v14 14/22] richacl: Update the file masks in chmod() Message-Id: <1446723580-3747-15-git-send-email-agruenba@redhat.com> In-Reply-To: <1446723580-3747-1-git-send-email-agruenba@redhat.com> References: <1446723580-3747-1-git-send-email-agruenba@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: 1446723687 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Doing a chmod() sets the file mode, which includes the file permission bits. When a file has a richacl, the permissions that the richacl grants need to be limited to what the new file permission bits allow. This is done by setting the file masks in the richacl to what the file permission bits map to. The richacl access check algorithm takes the file masks into account, which ensures that the richacl cannot grant too many permissions. It is possible to explicitly add permissions to the file masks which go beyond what the file permission bits can grant (like the RICHACE_WRITE_ACL permission). The POSIX.1 standard calls this an alternate file access control mechanism. A subsequent chmod() would ensure that those permissions are disabled again. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_base.c | 42 ++++++++++++++++++++++++++++++++++++++++++ fs/richacl_inode.c | 30 ++++++++++++++++++++++++++++++ include/linux/richacl.h | 2 ++ 3 files changed, 74 insertions(+) diff --git a/fs/richacl_base.c b/fs/richacl_base.c index 5826842..e4dd779 100644 --- a/fs/richacl_base.c +++ b/fs/richacl_base.c @@ -340,3 +340,45 @@ restart: acl->a_flags &= ~(RICHACL_WRITE_THROUGH | RICHACL_MASKED); } EXPORT_SYMBOL_GPL(richacl_compute_max_masks); + +/** + * __richacl_chmod - update the file masks to reflect the new mode + * @acl: access control list + * @mode: new file permission bits including the file type + * + * Return a copy of @acl where the file masks have been replaced by the file + * masks corresponding to the file permission bits in @mode, or returns @acl + * itself if the file masks are already up to date. Takes over a reference + * to @acl. + */ +struct richacl * +__richacl_chmod(struct richacl *acl, umode_t mode) +{ + unsigned int x = S_ISDIR(mode) ? 0 : RICHACE_DELETE_CHILD; + unsigned int owner_mask, group_mask, other_mask; + struct richacl *clone; + + owner_mask = richacl_mode_to_mask(mode >> 6) & ~x; + group_mask = richacl_mode_to_mask(mode >> 3) & ~x; + other_mask = richacl_mode_to_mask(mode) & ~x; + + if (acl->a_owner_mask == owner_mask && + acl->a_group_mask == group_mask && + acl->a_other_mask == other_mask && + (acl->a_flags & RICHACL_MASKED) && + (acl->a_flags & RICHACL_WRITE_THROUGH)) + return acl; + + clone = richacl_clone(acl, GFP_KERNEL); + richacl_put(acl); + if (!clone) + return ERR_PTR(-ENOMEM); + + clone->a_flags |= (RICHACL_WRITE_THROUGH | RICHACL_MASKED); + clone->a_owner_mask = owner_mask; + clone->a_group_mask = group_mask; + clone->a_other_mask = other_mask; + + return clone; +} +EXPORT_SYMBOL_GPL(__richacl_chmod); diff --git a/fs/richacl_inode.c b/fs/richacl_inode.c index 52c1595..e329826 100644 --- a/fs/richacl_inode.c +++ b/fs/richacl_inode.c @@ -224,3 +224,33 @@ out: return denied ? -EACCES : 0; } EXPORT_SYMBOL_GPL(richacl_permission); + +/** + * richacl_chmod - filesystem chmod helper + * @inode: inode whose file permission bits to change + * @mode: new file permission bits including the file type + * + * Helper for filesystems to use to perform a chmod on the richacl of an inode. + */ +int +richacl_chmod(struct inode *inode, umode_t mode) +{ + struct richacl *acl; + int retval; + + if (S_ISLNK(mode)) + return -EOPNOTSUPP; + if (!inode->i_op->set_richacl) + return -EOPNOTSUPP; + acl = get_richacl(inode); + if (IS_ERR_OR_NULL(acl)) + return PTR_ERR(acl); + acl = __richacl_chmod(acl, mode); + if (IS_ERR(acl)) + return PTR_ERR(acl); + retval = inode->i_op->set_richacl(inode, acl); + richacl_put(acl); + + return retval; +} +EXPORT_SYMBOL(richacl_chmod); diff --git a/include/linux/richacl.h b/include/linux/richacl.h index 7bf912b6..a2d5600 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -184,8 +184,10 @@ extern int richacl_masks_to_mode(const struct richacl *); extern unsigned int richacl_mode_to_mask(umode_t); extern unsigned int richacl_want_to_mask(unsigned int); extern void richacl_compute_max_masks(struct richacl *); +extern struct richacl *__richacl_chmod(struct richacl *, umode_t); /* richacl_inode.c */ extern int richacl_permission(struct inode *, const struct richacl *, int); +extern int richacl_chmod(struct inode *, umode_t); #endif /* __RICHACL_H */ -- 2.5.0 From agruenba@redhat.com Thu Nov 5 05:41:37 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 7CD8F7FD7 for ; Thu, 5 Nov 2015 05:41:37 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id EF3DAAC001 for ; Thu, 5 Nov 2015 03:41:36 -0800 (PST) X-ASG-Debug-ID: 1446723695-04cbb0242342470001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id bXOsYznIWyb5XHyG (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 05 Nov 2015 03:41:35 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 06BBE8F50D; Thu, 5 Nov 2015 11:41:33 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-134.ams2.redhat.com [10.36.7.134]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA5Bdfbq015870; Thu, 5 Nov 2015 06:41:27 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v14 15/22] richacl: Check if an acl is equivalent to a file mode Date: Thu, 5 Nov 2015 12:39:33 +0100 X-ASG-Orig-Subj: [PATCH v14 15/22] richacl: Check if an acl is equivalent to a file mode Message-Id: <1446723580-3747-16-git-send-email-agruenba@redhat.com> In-Reply-To: <1446723580-3747-1-git-send-email-agruenba@redhat.com> References: <1446723580-3747-1-git-send-email-agruenba@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: 1446723695 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 ACLs are considered equivalent to file modes if they only consist of owner@, group@, and everyone@ entries, the owner@ permissions do not depend on whether the owner is a member in the owning group, and no inheritance flags are set. This test is used to avoid storing richacls if the acl can be computed from the file permission bits. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_base.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/richacl.h | 1 + 2 files changed, 105 insertions(+) diff --git a/fs/richacl_base.c b/fs/richacl_base.c index e4dd779..74e5cb5 100644 --- a/fs/richacl_base.c +++ b/fs/richacl_base.c @@ -382,3 +382,107 @@ __richacl_chmod(struct richacl *acl, umode_t mode) return clone; } EXPORT_SYMBOL_GPL(__richacl_chmod); + +/** + * richacl_equiv_mode - compute the mode equivalent of @acl + * + * An acl is considered equivalent to a file mode if it only consists of + * owner@, group@, and everyone@ entries and the owner@ permissions do not + * depend on whether the owner is a member in the owning group. + */ +int +richacl_equiv_mode(const struct richacl *acl, umode_t *mode_p) +{ + umode_t mode = *mode_p; + + /* + * The RICHACE_DELETE_CHILD flag is meaningless for non-directories, so + * we ignore it. + */ + unsigned int x = S_ISDIR(mode) ? 0 : RICHACE_DELETE_CHILD; + struct { + unsigned int allowed; + unsigned int defined; /* allowed or denied */ + } owner = { + .defined = RICHACE_POSIX_ALWAYS_ALLOWED | + RICHACE_POSIX_OWNER_ALLOWED | x, + }, group = { + .defined = RICHACE_POSIX_ALWAYS_ALLOWED | x, + }, everyone = { + .defined = RICHACE_POSIX_ALWAYS_ALLOWED | x, + }; + const struct richace *ace; + + if (acl->a_flags & ~(RICHACL_WRITE_THROUGH | RICHACL_MASKED)) + return -1; + + richacl_for_each_entry(ace, acl) { + if (ace->e_flags & ~RICHACE_SPECIAL_WHO) + return -1; + + if (richace_is_owner(ace) || richace_is_everyone(ace)) { + x = ace->e_mask & ~owner.defined; + if (richace_is_allow(ace)) { + unsigned int group_denied = + group.defined & ~group.allowed; + + if (x & group_denied) + return -1; + owner.allowed |= x; + } else /* if (richace_is_deny(ace)) */ { + if (x & group.allowed) + return -1; + } + owner.defined |= x; + + if (richace_is_everyone(ace)) { + x = ace->e_mask; + if (richace_is_allow(ace)) { + group.allowed |= + x & ~group.defined; + everyone.allowed |= + x & ~everyone.defined; + } + group.defined |= x; + everyone.defined |= x; + } + } else if (richace_is_group(ace)) { + x = ace->e_mask & ~group.defined; + if (richace_is_allow(ace)) + group.allowed |= x; + group.defined |= x; + } else + return -1; + } + + if (group.allowed & ~owner.defined) + return -1; + + if (acl->a_flags & RICHACL_MASKED) { + if (acl->a_flags & RICHACL_WRITE_THROUGH) { + owner.allowed = acl->a_owner_mask; + everyone.allowed = acl->a_other_mask; + } else { + owner.allowed &= acl->a_owner_mask; + everyone.allowed &= acl->a_other_mask; + } + group.allowed &= acl->a_group_mask; + } + + mode = (mode & ~S_IRWXUGO) | + (richacl_mask_to_mode(owner.allowed) << 6) | + (richacl_mask_to_mode(group.allowed) << 3) | + richacl_mask_to_mode(everyone.allowed); + + /* Mask flags we can ignore */ + x = S_ISDIR(mode) ? 0 : RICHACE_DELETE_CHILD; + + if (((richacl_mode_to_mask(mode >> 6) ^ owner.allowed) & ~x) || + ((richacl_mode_to_mask(mode >> 3) ^ group.allowed) & ~x) || + ((richacl_mode_to_mask(mode) ^ everyone.allowed) & ~x)) + return -1; + + *mode_p = mode; + return 0; +} +EXPORT_SYMBOL_GPL(richacl_equiv_mode); diff --git a/include/linux/richacl.h b/include/linux/richacl.h index a2d5600..b7128bf 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -185,6 +185,7 @@ extern unsigned int richacl_mode_to_mask(umode_t); extern unsigned int richacl_want_to_mask(unsigned int); extern void richacl_compute_max_masks(struct richacl *); extern struct richacl *__richacl_chmod(struct richacl *, umode_t); +extern int richacl_equiv_mode(const struct richacl *, umode_t *); /* richacl_inode.c */ extern int richacl_permission(struct inode *, const struct richacl *, int); -- 2.5.0 From agruenba@redhat.com Thu Nov 5 05:41:42 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 C9F0B8029 for ; Thu, 5 Nov 2015 05:41:42 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 91C56304053 for ; Thu, 5 Nov 2015 03:41:42 -0800 (PST) X-ASG-Debug-ID: 1446723701-04bdf03f033dbb0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id Uk3kbpTfAaWHvGIM (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 05 Nov 2015 03:41:41 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id A2B408E25D; Thu, 5 Nov 2015 11:41:40 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-134.ams2.redhat.com [10.36.7.134]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA5Bdfbr015870; Thu, 5 Nov 2015 06:41:34 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v14 16/22] richacl: Create-time inheritance Date: Thu, 5 Nov 2015 12:39:34 +0100 X-ASG-Orig-Subj: [PATCH v14 16/22] richacl: Create-time inheritance Message-Id: <1446723580-3747-17-git-send-email-agruenba@redhat.com> In-Reply-To: <1446723580-3747-1-git-send-email-agruenba@redhat.com> References: <1446723580-3747-1-git-send-email-agruenba@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: 1446723701 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 When a new file is created, it can inherit an acl from its parent directory; this is similar to how default acls work in POSIX (draft) ACLs. As with POSIX ACLs, if a file inherits an acl from its parent directory, the intersection between the create mode and the permissions granted by the inherited acl determines the file masks and file permission bits, and the umask is ignored. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_base.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++ fs/richacl_inode.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/richacl.h | 2 ++ 3 files changed, 140 insertions(+) diff --git a/fs/richacl_base.c b/fs/richacl_base.c index 74e5cb5..3753216 100644 --- a/fs/richacl_base.c +++ b/fs/richacl_base.c @@ -486,3 +486,71 @@ richacl_equiv_mode(const struct richacl *acl, umode_t *mode_p) return 0; } EXPORT_SYMBOL_GPL(richacl_equiv_mode); + +/** + * richacl_inherit - compute the inherited acl of a new file + * @dir_acl: acl of the containing directory + * @isdir: inherit by a directory or non-directory? + * + * A directory can have acl entries which files and/or directories created + * inside the directory will inherit. This function computes the acl for such + * a new file. If there is no inheritable acl, it will return %NULL. + */ +struct richacl * +richacl_inherit(const struct richacl *dir_acl, int isdir) +{ + const struct richace *dir_ace; + struct richacl *acl = NULL; + struct richace *ace; + int count = 0; + + if (isdir) { + richacl_for_each_entry(dir_ace, dir_acl) { + if (!richace_is_inheritable(dir_ace)) + continue; + count++; + } + if (!count) + return NULL; + acl = richacl_alloc(count, GFP_KERNEL); + if (!acl) + return ERR_PTR(-ENOMEM); + ace = acl->a_entries; + richacl_for_each_entry(dir_ace, dir_acl) { + if (!richace_is_inheritable(dir_ace)) + continue; + richace_copy(ace, dir_ace); + if (dir_ace->e_flags & RICHACE_NO_PROPAGATE_INHERIT_ACE) + ace->e_flags &= ~RICHACE_INHERITANCE_FLAGS; + else if (!(dir_ace->e_flags & RICHACE_DIRECTORY_INHERIT_ACE)) + ace->e_flags |= RICHACE_INHERIT_ONLY_ACE; + ace++; + } + } else { + richacl_for_each_entry(dir_ace, dir_acl) { + if (!(dir_ace->e_flags & RICHACE_FILE_INHERIT_ACE)) + continue; + count++; + } + if (!count) + return NULL; + acl = richacl_alloc(count, GFP_KERNEL); + if (!acl) + return ERR_PTR(-ENOMEM); + ace = acl->a_entries; + richacl_for_each_entry(dir_ace, dir_acl) { + if (!(dir_ace->e_flags & RICHACE_FILE_INHERIT_ACE)) + continue; + richace_copy(ace, dir_ace); + ace->e_flags &= ~RICHACE_INHERITANCE_FLAGS; + /* + * RICHACE_DELETE_CHILD is meaningless for + * non-directories, so clear it. + */ + ace->e_mask &= ~RICHACE_DELETE_CHILD; + ace++; + } + } + + return acl; +} diff --git a/fs/richacl_inode.c b/fs/richacl_inode.c index e329826..ec3d2c8 100644 --- a/fs/richacl_inode.c +++ b/fs/richacl_inode.c @@ -254,3 +254,73 @@ richacl_chmod(struct inode *inode, umode_t mode) return retval; } EXPORT_SYMBOL(richacl_chmod); + +/* + * richacl_inherit_inode - compute inherited acl and file mode + * @dir_acl: acl of the containing directory + * @mode_p: mode of the new inode + * + * The file permission bits in @mode_p must be set to the create mode by the + * caller. + * + * If there is an inheritable acl, the maximum permissions that the acl grants + * are computed and the file masks of the new acl are set accordingly. + */ +static struct richacl * +richacl_inherit_inode(const struct richacl *dir_acl, umode_t *mode_p) +{ + struct richacl *acl; + umode_t mode = *mode_p; + + acl = richacl_inherit(dir_acl, S_ISDIR(mode)); + if (acl) { + if (richacl_equiv_mode(acl, &mode) == 0) { + *mode_p &= mode; + richacl_put(acl); + acl = NULL; + } else { + richacl_compute_max_masks(acl); + /* + * Ensure that the acl will not grant any permissions + * beyond the create mode. + */ + acl->a_flags |= RICHACL_MASKED; + acl->a_owner_mask &= + richacl_mode_to_mask(mode >> 6); + acl->a_group_mask &= + richacl_mode_to_mask(mode >> 3); + acl->a_other_mask &= + richacl_mode_to_mask(mode); + } + } else + *mode_p &= ~current_umask(); + + return acl; +} + +/** + * richacl_create - filesystem create helper + * @mode_p: mode of the new inode + * @dir: containing directory + * + * Compute the inherited acl for a new inode. If there is no acl to inherit, + * apply the umask. Use when creating a new inode on a richacl enabled file + * system. + */ +struct richacl *richacl_create(umode_t *mode_p, struct inode *dir) +{ + struct richacl *dir_acl, *acl = NULL; + + if (S_ISLNK(*mode_p)) + return NULL; + dir_acl = get_richacl(dir); + if (dir_acl) { + if (IS_ERR(dir_acl)) + return dir_acl; + acl = richacl_inherit_inode(dir_acl, mode_p); + richacl_put(dir_acl); + } else + *mode_p &= ~current_umask(); + return acl; +} +EXPORT_SYMBOL_GPL(richacl_create); diff --git a/include/linux/richacl.h b/include/linux/richacl.h index b7128bf..c8fae91a 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -186,9 +186,11 @@ extern unsigned int richacl_want_to_mask(unsigned int); extern void richacl_compute_max_masks(struct richacl *); extern struct richacl *__richacl_chmod(struct richacl *, umode_t); extern int richacl_equiv_mode(const struct richacl *, umode_t *); +extern struct richacl *richacl_inherit(const struct richacl *, int); /* richacl_inode.c */ extern int richacl_permission(struct inode *, const struct richacl *, int); extern int richacl_chmod(struct inode *, umode_t); +extern struct richacl *richacl_create(umode_t *, struct inode *); #endif /* __RICHACL_H */ -- 2.5.0 From agruenba@redhat.com Thu Nov 5 05:41:49 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 018017FD7 for ; Thu, 5 Nov 2015 05:41:49 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 8321DAC002 for ; Thu, 5 Nov 2015 03:41:48 -0800 (PST) X-ASG-Debug-ID: 1446723707-04bdf03f023dbc0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id Af0bMmg0gpuYVH36 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 05 Nov 2015 03:41:47 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 56D02E7066; Thu, 5 Nov 2015 11:41:47 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-134.ams2.redhat.com [10.36.7.134]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA5Bdfbs015870; Thu, 5 Nov 2015 06:41:41 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v14 17/22] richacl: Automatic Inheritance Date: Thu, 5 Nov 2015 12:39:35 +0100 X-ASG-Orig-Subj: [PATCH v14 17/22] richacl: Automatic Inheritance Message-Id: <1446723580-3747-18-git-send-email-agruenba@redhat.com> In-Reply-To: <1446723580-3747-1-git-send-email-agruenba@redhat.com> References: <1446723580-3747-1-git-send-email-agruenba@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: 1446723707 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Barracuda-BRTS-Status: 1 X-Virus-Scanned: by bsmtpd at sgi.com Automatic Inheritance (AI) allows changes to the acl of a directory to propagate down to children. This is mostly implemented in user space: when a process changes the permissions of a directory and Automatic Inheritance is enabled for that directory, the process must propagate those changes to all children, recursively. The kernel enables this by keeping track of which permissions have been inherited at create time. In addition, it makes sure that permission propagation is turned off when the permissions are set explicitly (for example, upon create or chmod). Automatic Inheritance works as follows: - When the RICHACL_AUTO_INHERIT flag in the acl of a file or directory is not set, the file or directory is not affected by AI. - When the RICHACL_AUTO_INHERIT flag in the acl of a directory is set and a file or subdirectory is created in that directory, the inherited acl will have the RICHACL_AUTO_INHERIT flag set, and all inherited aces will have the RICHACE_INHERITED_ACE flag set. This allows user space to distinguish between aces which have been inherited and aces which have been explicitly added. - When the RICHACL_PROTECTED acl flag in the acl of a file or directory is set, AI will not modify the acl. This does not affect propagation of permissions from the file to its children (if the file is a directory). Linux does not have a way of creating files or directories without setting the file permission bits, so all files created inside a directory with RICHACL_AUTO_INHERIT set will have the RICHACL_PROTECTED flag set. This effectively disables Automatic Inheritance. Protocols which support creating files without specifying permissions can explicitly clear the RICHACL_PROTECTED flag after creating a file and reset the file masks to "undo" applying the create mode; see richacl_compute_max_masks(). They should set the RICHACL_DEFAULTED flag. (A mechanism that would allow to indicate to the kernel to ignore the create mode in the first place when there are inherited permissions would be nice to have.) Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_base.c | 10 +++++++++- fs/richacl_inode.c | 7 +++++++ include/linux/richacl.h | 12 ++++++++++++ include/uapi/linux/richacl.h | 11 ++++++++++- 4 files changed, 38 insertions(+), 2 deletions(-) diff --git a/fs/richacl_base.c b/fs/richacl_base.c index 3753216..b67280d 100644 --- a/fs/richacl_base.c +++ b/fs/richacl_base.c @@ -366,7 +366,8 @@ __richacl_chmod(struct richacl *acl, umode_t mode) acl->a_group_mask == group_mask && acl->a_other_mask == other_mask && (acl->a_flags & RICHACL_MASKED) && - (acl->a_flags & RICHACL_WRITE_THROUGH)) + (acl->a_flags & RICHACL_WRITE_THROUGH) && + (!richacl_is_auto_inherit(acl) || richacl_is_protected(acl))) return acl; clone = richacl_clone(acl, GFP_KERNEL); @@ -378,6 +379,8 @@ __richacl_chmod(struct richacl *acl, umode_t mode) clone->a_owner_mask = owner_mask; clone->a_group_mask = group_mask; clone->a_other_mask = other_mask; + if (richacl_is_auto_inherit(clone)) + clone->a_flags |= RICHACL_PROTECTED; return clone; } @@ -551,6 +554,11 @@ richacl_inherit(const struct richacl *dir_acl, int isdir) ace++; } } + if (richacl_is_auto_inherit(dir_acl)) { + acl->a_flags = RICHACL_AUTO_INHERIT; + richacl_for_each_entry(ace, acl) + ace->e_flags |= RICHACE_INHERITED_ACE; + } return acl; } diff --git a/fs/richacl_inode.c b/fs/richacl_inode.c index ec3d2c8..99a1ab6 100644 --- a/fs/richacl_inode.c +++ b/fs/richacl_inode.c @@ -279,6 +279,13 @@ richacl_inherit_inode(const struct richacl *dir_acl, umode_t *mode_p) richacl_put(acl); acl = NULL; } else { + /* + * We need to set RICHACL_PROTECTED because we are + * doing an implicit chmod + */ + if (richacl_is_auto_inherit(acl)) + acl->a_flags |= RICHACL_PROTECTED; + richacl_compute_max_masks(acl); /* * Ensure that the acl will not grant any permissions diff --git a/include/linux/richacl.h b/include/linux/richacl.h index c8fae91a..c524a4b 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -76,6 +76,18 @@ extern void set_cached_richacl(struct inode *, struct richacl *); extern void forget_cached_richacl(struct inode *); extern struct richacl *get_richacl(struct inode *); +static inline int +richacl_is_auto_inherit(const struct richacl *acl) +{ + return acl->a_flags & RICHACL_AUTO_INHERIT; +} + +static inline int +richacl_is_protected(const struct richacl *acl) +{ + return acl->a_flags & RICHACL_PROTECTED; +} + /** * richace_is_owner - check if @ace is an OWNER@ entry */ diff --git a/include/uapi/linux/richacl.h b/include/uapi/linux/richacl.h index 1ed48ac..8849a53 100644 --- a/include/uapi/linux/richacl.h +++ b/include/uapi/linux/richacl.h @@ -18,6 +18,9 @@ #define __UAPI_RICHACL_H /* a_flags values */ +#define RICHACL_AUTO_INHERIT 0x01 +#define RICHACL_PROTECTED 0x02 +#define RICHACL_DEFAULTED 0x04 #define RICHACL_WRITE_THROUGH 0x40 #define RICHACL_MASKED 0x80 @@ -31,6 +34,7 @@ #define RICHACE_NO_PROPAGATE_INHERIT_ACE 0x0004 #define RICHACE_INHERIT_ONLY_ACE 0x0008 #define RICHACE_IDENTIFIER_GROUP 0x0040 +#define RICHACE_INHERITED_ACE 0x0080 #define RICHACE_SPECIAL_WHO 0x4000 /* e_mask bitflags */ @@ -60,6 +64,9 @@ #define RICHACE_EVERYONE_SPECIAL_ID 2 #define RICHACL_VALID_FLAGS ( \ + RICHACL_AUTO_INHERIT | \ + RICHACL_PROTECTED | \ + RICHACL_DEFAULTED | \ RICHACL_WRITE_THROUGH | \ RICHACL_MASKED ) @@ -69,13 +76,15 @@ RICHACE_NO_PROPAGATE_INHERIT_ACE | \ RICHACE_INHERIT_ONLY_ACE | \ RICHACE_IDENTIFIER_GROUP | \ + RICHACE_INHERITED_ACE | \ RICHACE_SPECIAL_WHO ) #define RICHACE_INHERITANCE_FLAGS ( \ RICHACE_FILE_INHERIT_ACE | \ RICHACE_DIRECTORY_INHERIT_ACE | \ RICHACE_NO_PROPAGATE_INHERIT_ACE | \ - RICHACE_INHERIT_ONLY_ACE ) + RICHACE_INHERIT_ONLY_ACE | \ + RICHACE_INHERITED_ACE ) /* Valid RICHACE_* flags for directories and non-directories */ #define RICHACE_VALID_MASK ( \ -- 2.5.0 From agruenba@redhat.com Thu Nov 5 05:41:56 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 9B2D37FD7 for ; Thu, 5 Nov 2015 05:41:56 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 50901304051 for ; Thu, 5 Nov 2015 03:41:56 -0800 (PST) X-ASG-Debug-ID: 1446723714-04bdf03f023dbe0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id PHLr9r1vCGRGlFxR (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 05 Nov 2015 03:41:54 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 3840C14CAA7; Thu, 5 Nov 2015 11:41:54 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-134.ams2.redhat.com [10.36.7.134]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA5Bdfbt015870; Thu, 5 Nov 2015 06:41:47 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v14 18/22] richacl: xattr mapping functions Date: Thu, 5 Nov 2015 12:39:36 +0100 X-ASG-Orig-Subj: [PATCH v14 18/22] richacl: xattr mapping functions Message-Id: <1446723580-3747-19-git-send-email-agruenba@redhat.com> In-Reply-To: <1446723580-3747-1-git-send-email-agruenba@redhat.com> References: <1446723580-3747-1-git-send-email-agruenba@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: 1446723714 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Barracuda-BRTS-Status: 1 X-Virus-Scanned: by bsmtpd at sgi.com Map between "system.richacl" xattrs and the in-kernel representation. Signed-off-by: Andreas Gruenbacher --- fs/Makefile | 2 +- fs/richacl_xattr.c | 220 +++++++++++++++++++++++++++++++++++++ fs/xattr.c | 34 +++++- include/linux/richacl_xattr.h | 42 +++++++ include/uapi/linux/Kbuild | 1 + include/uapi/linux/richacl_xattr.h | 44 ++++++++ include/uapi/linux/xattr.h | 2 + 7 files changed, 338 insertions(+), 7 deletions(-) create mode 100644 fs/richacl_xattr.c create mode 100644 include/linux/richacl_xattr.h create mode 100644 include/uapi/linux/richacl_xattr.h diff --git a/fs/Makefile b/fs/Makefile index ec665fd..35e640d 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -49,7 +49,7 @@ obj-$(CONFIG_SYSCTL) += drop_caches.o obj-$(CONFIG_FHANDLE) += fhandle.o obj-$(CONFIG_FS_RICHACL) += richacl.o -richacl-y := richacl_base.o richacl_inode.o +richacl-y := richacl_base.o richacl_inode.o richacl_xattr.o obj-y += quota/ diff --git a/fs/richacl_xattr.c b/fs/richacl_xattr.c new file mode 100644 index 0000000..38473b6 --- /dev/null +++ b/fs/richacl_xattr.c @@ -0,0 +1,220 @@ +/* + * Copyright (C) 2006, 2010 Novell, Inc. + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * 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; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include +#include +#include +#include +#include + +MODULE_LICENSE("GPL"); + +/** + * richacl_from_xattr - convert a richacl xattr into the in-memory representation + */ +struct richacl * +richacl_from_xattr(struct user_namespace *user_ns, + const void *value, size_t size) +{ + const struct richacl_xattr *xattr_acl = value; + const struct richace_xattr *xattr_ace = (void *)(xattr_acl + 1); + struct richacl *acl; + struct richace *ace; + int count; + + if (size < sizeof(*xattr_acl) || + xattr_acl->a_version != RICHACL_XATTR_VERSION || + (xattr_acl->a_flags & ~RICHACL_VALID_FLAGS)) + return ERR_PTR(-EINVAL); + size -= sizeof(*xattr_acl); + count = le16_to_cpu(xattr_acl->a_count); + if (count > RICHACL_XATTR_MAX_COUNT) + return ERR_PTR(-EINVAL); + if (size != count * sizeof(*xattr_ace)) + return ERR_PTR(-EINVAL); + + acl = richacl_alloc(count, GFP_NOFS); + if (!acl) + return ERR_PTR(-ENOMEM); + + acl->a_flags = xattr_acl->a_flags; + acl->a_owner_mask = le32_to_cpu(xattr_acl->a_owner_mask); + if (acl->a_owner_mask & ~RICHACE_VALID_MASK) + goto fail_einval; + acl->a_group_mask = le32_to_cpu(xattr_acl->a_group_mask); + if (acl->a_group_mask & ~RICHACE_VALID_MASK) + goto fail_einval; + acl->a_other_mask = le32_to_cpu(xattr_acl->a_other_mask); + if (acl->a_other_mask & ~RICHACE_VALID_MASK) + goto fail_einval; + + richacl_for_each_entry(ace, acl) { + ace->e_type = le16_to_cpu(xattr_ace->e_type); + ace->e_flags = le16_to_cpu(xattr_ace->e_flags); + ace->e_mask = le32_to_cpu(xattr_ace->e_mask); + + if (ace->e_flags & ~RICHACE_VALID_FLAGS) + goto fail_einval; + if (ace->e_flags & RICHACE_SPECIAL_WHO) { + ace->e_id.special = le32_to_cpu(xattr_ace->e_id); + if (ace->e_id.special > RICHACE_EVERYONE_SPECIAL_ID) + goto fail_einval; + } else if (ace->e_flags & RICHACE_IDENTIFIER_GROUP) { + u32 id = le32_to_cpu(xattr_ace->e_id); + + ace->e_id.gid = make_kgid(user_ns, id); + if (!gid_valid(ace->e_id.gid)) + goto fail_einval; + } else { + u32 id = le32_to_cpu(xattr_ace->e_id); + + ace->e_id.uid = make_kuid(user_ns, id); + if (!uid_valid(ace->e_id.uid)) + goto fail_einval; + } + if (ace->e_type > RICHACE_ACCESS_DENIED_ACE_TYPE || + (ace->e_mask & ~RICHACE_VALID_MASK)) + goto fail_einval; + + xattr_ace++; + } + + return acl; + +fail_einval: + richacl_put(acl); + return ERR_PTR(-EINVAL); +} +EXPORT_SYMBOL_GPL(richacl_from_xattr); + +/** + * richacl_xattr_size - compute the size of the xattr representation of @acl + */ +size_t +richacl_xattr_size(const struct richacl *acl) +{ + size_t size = sizeof(struct richacl_xattr); + + size += sizeof(struct richace_xattr) * acl->a_count; + return size; +} +EXPORT_SYMBOL_GPL(richacl_xattr_size); + +/** + * richacl_to_xattr - convert @acl into its xattr representation + * @acl: the richacl to convert + * @buffer: buffer for the result + * @size: size of @buffer + */ +int +richacl_to_xattr(struct user_namespace *user_ns, + const struct richacl *acl, void *buffer, size_t size) +{ + struct richacl_xattr *xattr_acl = buffer; + struct richace_xattr *xattr_ace; + const struct richace *ace; + size_t real_size; + + real_size = richacl_xattr_size(acl); + if (!buffer) + return real_size; + if (real_size > size) + return -ERANGE; + + xattr_acl->a_version = RICHACL_XATTR_VERSION; + xattr_acl->a_flags = acl->a_flags; + xattr_acl->a_count = cpu_to_le16(acl->a_count); + + xattr_acl->a_owner_mask = cpu_to_le32(acl->a_owner_mask); + xattr_acl->a_group_mask = cpu_to_le32(acl->a_group_mask); + xattr_acl->a_other_mask = cpu_to_le32(acl->a_other_mask); + + xattr_ace = (void *)(xattr_acl + 1); + richacl_for_each_entry(ace, acl) { + xattr_ace->e_type = cpu_to_le16(ace->e_type); + xattr_ace->e_flags = cpu_to_le16(ace->e_flags); + xattr_ace->e_mask = cpu_to_le32(ace->e_mask); + if (ace->e_flags & RICHACE_SPECIAL_WHO) + xattr_ace->e_id = cpu_to_le32(ace->e_id.special); + else if (ace->e_flags & RICHACE_IDENTIFIER_GROUP) + xattr_ace->e_id = + cpu_to_le32(from_kgid(user_ns, ace->e_id.gid)); + else + xattr_ace->e_id = + cpu_to_le32(from_kuid(user_ns, ace->e_id.uid)); + xattr_ace++; + } + return real_size; +} +EXPORT_SYMBOL_GPL(richacl_to_xattr); + +/* + * Fix up the uids and gids in richacl extended attributes in place. + */ +static void richacl_fix_xattr_userns( + struct user_namespace *to, struct user_namespace *from, + void *value, size_t size) +{ + struct richacl_xattr *xattr_acl = value; + struct richace_xattr *xattr_ace = + (struct richace_xattr *)(xattr_acl + 1); + unsigned int count; + + if (!value) + return; + if (size < sizeof(*xattr_acl)) + return; + if (xattr_acl->a_version != cpu_to_le32(RICHACL_XATTR_VERSION)) + return; + size -= sizeof(*xattr_acl); + if (size % sizeof(*xattr_ace)) + return; + count = size / sizeof(*xattr_ace); + for (; count; count--, xattr_ace++) { + if (xattr_ace->e_flags & cpu_to_le16(RICHACE_SPECIAL_WHO)) + continue; + if (xattr_ace->e_flags & + cpu_to_le16(RICHACE_IDENTIFIER_GROUP)) { + u32 id = le32_to_cpu(xattr_ace->e_id); + kgid_t gid = make_kgid(from, id); + + xattr_ace->e_id = cpu_to_le32(from_kgid(to, gid)); + } else { + u32 id = le32_to_cpu(xattr_ace->e_id); + kuid_t uid = make_kuid(from, id); + + xattr_ace->e_id = cpu_to_le32(from_kuid(to, uid)); + } + } +} + +void richacl_fix_xattr_from_user(void *value, size_t size) +{ + struct user_namespace *user_ns = current_user_ns(); + + if (user_ns == &init_user_ns) + return; + richacl_fix_xattr_userns(&init_user_ns, user_ns, value, size); +} + +void richacl_fix_xattr_to_user(void *value, size_t size) +{ + struct user_namespace *user_ns = current_user_ns(); + + if (user_ns == &init_user_ns) + return; + richacl_fix_xattr_userns(user_ns, &init_user_ns, value, size); +} diff --git a/fs/xattr.c b/fs/xattr.c index 072fee1..f2313c6 100644 --- a/fs/xattr.c +++ b/fs/xattr.c @@ -21,6 +21,7 @@ #include #include #include +#include #include @@ -314,6 +315,18 @@ out: } EXPORT_SYMBOL_GPL(vfs_removexattr); +static void +fix_xattr_from_user(const char *kname, void *kvalue, size_t size) +{ + if (strncmp(kname, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) + return; + kname += XATTR_SYSTEM_PREFIX_LEN; + if (!strcmp(kname, XATTR_POSIX_ACL_ACCESS) || + !strcmp(kname, XATTR_POSIX_ACL_DEFAULT)) + posix_acl_fix_xattr_from_user(kvalue, size); + else if (!strcmp(kname, XATTR_RICHACL)) + richacl_fix_xattr_from_user(kvalue, size); +} /* * Extended attribute SET operations @@ -350,9 +363,7 @@ setxattr(struct dentry *d, const char __user *name, const void __user *value, error = -EFAULT; goto out; } - if ((strcmp(kname, XATTR_NAME_POSIX_ACL_ACCESS) == 0) || - (strcmp(kname, XATTR_NAME_POSIX_ACL_DEFAULT) == 0)) - posix_acl_fix_xattr_from_user(kvalue, size); + fix_xattr_from_user(kname, kvalue, size); } error = vfs_setxattr(d, kname, kvalue, size, flags); @@ -419,6 +430,19 @@ SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name, return error; } +static void +fix_xattr_to_user(const char *kname, void *kvalue, size_t size) +{ + if (strncmp(kname, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) + return; + kname += XATTR_SYSTEM_PREFIX_LEN; + if (!strcmp(kname, XATTR_POSIX_ACL_ACCESS) || + !strcmp(kname, XATTR_POSIX_ACL_DEFAULT)) + posix_acl_fix_xattr_to_user(kvalue, size); + else if (!strcmp(kname, XATTR_RICHACL)) + richacl_fix_xattr_to_user(kvalue, size); +} + /* * Extended attribute GET operations */ @@ -451,9 +475,7 @@ getxattr(struct dentry *d, const char __user *name, void __user *value, error = vfs_getxattr(d, kname, kvalue, size); if (error > 0) { - if ((strcmp(kname, XATTR_NAME_POSIX_ACL_ACCESS) == 0) || - (strcmp(kname, XATTR_NAME_POSIX_ACL_DEFAULT) == 0)) - posix_acl_fix_xattr_to_user(kvalue, size); + fix_xattr_to_user(kname, kvalue, size); if (size && copy_to_user(value, kvalue, error)) error = -EFAULT; } else if (error == -ERANGE && size >= XATTR_SIZE_MAX) { diff --git a/include/linux/richacl_xattr.h b/include/linux/richacl_xattr.h new file mode 100644 index 0000000..7fc5ca8 --- /dev/null +++ b/include/linux/richacl_xattr.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2006, 2010 Novell, Inc. + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * 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; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#ifndef __RICHACL_XATTR_H +#define __RICHACL_XATTR_H + +#include +#include + +extern struct richacl *richacl_from_xattr(struct user_namespace *, const void *, + size_t); +extern size_t richacl_xattr_size(const struct richacl *); +extern int richacl_to_xattr(struct user_namespace *, const struct richacl *, + void *, size_t); + +#ifdef CONFIG_FS_RICHACL +extern void richacl_fix_xattr_from_user(void *, size_t); +extern void richacl_fix_xattr_to_user(void *, size_t); +#else +static inline void richacl_fix_xattr_from_user(void *value, size_t size) +{ +} + +static inline void richacl_fix_xattr_to_user(void *value, size_t size) +{ +} +#endif + +#endif /* __RICHACL_XATTR_H */ diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild index 8c82010..18ad070 100644 --- a/include/uapi/linux/Kbuild +++ b/include/uapi/linux/Kbuild @@ -349,6 +349,7 @@ header-y += reiserfs_fs.h header-y += reiserfs_xattr.h header-y += resource.h header-y += richacl.h +header-y += richacl_xattr.h header-y += rfkill.h header-y += romfs_fs.h header-y += rose.h diff --git a/include/uapi/linux/richacl_xattr.h b/include/uapi/linux/richacl_xattr.h new file mode 100644 index 0000000..5178ca6 --- /dev/null +++ b/include/uapi/linux/richacl_xattr.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2006, 2010 Novell, Inc. + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ + +#ifndef __UAPI_RICHACL_XATTR_H +#define __UAPI_RICHACL_XATTR_H + +#include +#include + +struct richace_xattr { + __le16 e_type; + __le16 e_flags; + __le32 e_mask; + __le32 e_id; +}; + +struct richacl_xattr { + unsigned char a_version; + unsigned char a_flags; + __le16 a_count; + __le32 a_owner_mask; + __le32 a_group_mask; + __le32 a_other_mask; +}; + +#define RICHACL_XATTR_VERSION 0 +#define RICHACL_XATTR_MAX_COUNT \ + ((XATTR_SIZE_MAX - sizeof(struct richacl_xattr)) / \ + sizeof(struct richace_xattr)) + +#endif /* __UAPI_RICHACL_XATTR_H */ diff --git a/include/uapi/linux/xattr.h b/include/uapi/linux/xattr.h index 1590c49..1996903 100644 --- a/include/uapi/linux/xattr.h +++ b/include/uapi/linux/xattr.h @@ -73,5 +73,7 @@ #define XATTR_POSIX_ACL_DEFAULT "posix_acl_default" #define XATTR_NAME_POSIX_ACL_DEFAULT XATTR_SYSTEM_PREFIX XATTR_POSIX_ACL_DEFAULT +#define XATTR_RICHACL "richacl" +#define XATTR_NAME_RICHACL XATTR_SYSTEM_PREFIX XATTR_RICHACL #endif /* _UAPI_LINUX_XATTR_H */ -- 2.5.0 From agruenba@redhat.com Thu Nov 5 05:42:03 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 8E9E17FD7 for ; Thu, 5 Nov 2015 05:42:03 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id F389CAC003 for ; Thu, 5 Nov 2015 03:42:02 -0800 (PST) X-ASG-Debug-ID: 1446723721-04cb6c296b3a2b0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id TbjhDFJ15hqn6Jv8 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 05 Nov 2015 03:42:01 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 22AA8C01F2C9; Thu, 5 Nov 2015 11:42:01 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-134.ams2.redhat.com [10.36.7.134]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA5Bdfbu015870; Thu, 5 Nov 2015 06:41:54 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v14 19/22] richacl: Add richacl xattr handler Date: Thu, 5 Nov 2015 12:39:37 +0100 X-ASG-Orig-Subj: [PATCH v14 19/22] richacl: Add richacl xattr handler Message-Id: <1446723580-3747-20-git-send-email-agruenba@redhat.com> In-Reply-To: <1446723580-3747-1-git-send-email-agruenba@redhat.com> References: <1446723580-3747-1-git-send-email-agruenba@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: 1446723721 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Add richacl xattr handler implementing the xattr operations based on the get_richacl and set_richacl inode operations. Signed-off-by: Andreas Gruenbacher --- fs/richacl_xattr.c | 78 +++++++++++++++++++++++++++++++++++++++++++ include/linux/richacl_xattr.h | 2 ++ 2 files changed, 80 insertions(+) diff --git a/fs/richacl_xattr.c b/fs/richacl_xattr.c index 38473b6..767c1f7 100644 --- a/fs/richacl_xattr.c +++ b/fs/richacl_xattr.c @@ -18,7 +18,9 @@ #include #include #include +#include #include +#include MODULE_LICENSE("GPL"); @@ -161,6 +163,82 @@ richacl_to_xattr(struct user_namespace *user_ns, } EXPORT_SYMBOL_GPL(richacl_to_xattr); +static size_t +richacl_xattr_list(struct dentry *dentry, char *list, size_t list_len, + const char *name, size_t name_len, int handler_flags) +{ + const size_t size = sizeof(XATTR_NAME_RICHACL); + + if (!IS_RICHACL(d_backing_inode(dentry))) + return 0; + if (list && size <= list_len) + memcpy(list, XATTR_NAME_RICHACL, size); + return size; +} + +static int +richacl_xattr_get(struct dentry *dentry, const char *name, void *buffer, + size_t buffer_size, int handler_flags) +{ + struct inode *inode = d_backing_inode(dentry); + struct richacl *acl; + int error; + + if (strcmp(name, "") != 0) + return -EINVAL; + if (!IS_RICHACL(inode)) + return EOPNOTSUPP; + if (S_ISLNK(inode->i_mode)) + return -EOPNOTSUPP; + acl = get_richacl(inode); + if (IS_ERR(acl)) + return PTR_ERR(acl); + if (acl == NULL) + return -ENODATA; + error = richacl_to_xattr(&init_user_ns, acl, buffer, buffer_size); + richacl_put(acl); + return error; +} + +static int +richacl_xattr_set(struct dentry *dentry, const char *name, + const void *value, size_t size, int flags, int handler_flags) +{ + struct inode *inode = d_backing_inode(dentry); + struct richacl *acl = NULL; + int ret; + + if (strcmp(name, "") != 0) + return -EINVAL; + if (!IS_RICHACL(inode)) + return -EOPNOTSUPP; + if (!inode->i_op->set_richacl) + return -EOPNOTSUPP; + + if (!uid_eq(current_fsuid(), inode->i_uid) && + inode_permission(inode, MAY_CHMOD) && + !capable(CAP_FOWNER)) + return -EPERM; + + if (value) { + acl = richacl_from_xattr(&init_user_ns, value, size); + if (IS_ERR(acl)) + return PTR_ERR(acl); + } + + ret = inode->i_op->set_richacl(inode, acl); + richacl_put(acl); + return ret; +} + +struct xattr_handler richacl_xattr_handler = { + .prefix = XATTR_NAME_RICHACL, + .list = richacl_xattr_list, + .get = richacl_xattr_get, + .set = richacl_xattr_set, +}; +EXPORT_SYMBOL(richacl_xattr_handler); + /* * Fix up the uids and gids in richacl extended attributes in place. */ diff --git a/include/linux/richacl_xattr.h b/include/linux/richacl_xattr.h index 7fc5ca8..45ec27a 100644 --- a/include/linux/richacl_xattr.h +++ b/include/linux/richacl_xattr.h @@ -39,4 +39,6 @@ static inline void richacl_fix_xattr_to_user(void *value, size_t size) } #endif +extern struct xattr_handler richacl_xattr_handler; + #endif /* __RICHACL_XATTR_H */ -- 2.5.0 From agruenba@redhat.com Thu Nov 5 05:42:09 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 558E0803B for ; Thu, 5 Nov 2015 05:42:09 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 014EFAC002 for ; Thu, 5 Nov 2015 03:42:08 -0800 (PST) X-ASG-Debug-ID: 1446723728-04bdf03f053dc10001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id coLrwlcEPyVrZnLd (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 05 Nov 2015 03:42:08 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id EB925130B; Thu, 5 Nov 2015 11:42:07 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-134.ams2.redhat.com [10.36.7.134]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA5Bdfbv015870; Thu, 5 Nov 2015 06:42:01 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v14 20/22] vfs: Add richacl permission checking Date: Thu, 5 Nov 2015 12:39:38 +0100 X-ASG-Orig-Subj: [PATCH v14 20/22] vfs: Add richacl permission checking Message-Id: <1446723580-3747-21-git-send-email-agruenba@redhat.com> In-Reply-To: <1446723580-3747-1-git-send-email-agruenba@redhat.com> References: <1446723580-3747-1-git-send-email-agruenba@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: 1446723728 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Hook the richacl permission checking function into the vfs. Signed-off-by: Andreas Gruenbacher --- fs/namei.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++-- fs/posix_acl.c | 6 +++--- 2 files changed, 52 insertions(+), 5 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 2eab19e..3822b5e 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include "internal.h" @@ -255,7 +256,40 @@ void putname(struct filename *name) __putname(name); } -static int check_acl(struct inode *inode, int mask) +static int check_richacl(struct inode *inode, int mask) +{ +#ifdef CONFIG_FS_RICHACL + struct richacl *acl; + + if (mask & MAY_NOT_BLOCK) { + acl = get_cached_richacl_rcu(inode); + if (!acl) + goto no_acl; + /* no ->get_richacl() calls in RCU mode... */ + if (acl == ACL_NOT_CACHED) + return -ECHILD; + return richacl_permission(inode, acl, mask & ~MAY_NOT_BLOCK); + } + + acl = get_richacl(inode); + if (IS_ERR(acl)) + return PTR_ERR(acl); + if (acl) { + int error = richacl_permission(inode, acl, mask); + richacl_put(acl); + return error; + } +no_acl: +#endif + if (mask & (MAY_DELETE_SELF | MAY_TAKE_OWNERSHIP | + MAY_CHMOD | MAY_SET_TIMES)) { + /* File permission bits cannot grant this. */ + return -EACCES; + } + return -EAGAIN; +} + +static int check_posix_acl(struct inode *inode, int mask) { #ifdef CONFIG_FS_POSIX_ACL struct posix_acl *acl; @@ -290,11 +324,24 @@ static int acl_permission_check(struct inode *inode, int mask) { unsigned int mode = inode->i_mode; + /* + * With POSIX ACLs, the (mode & S_IRWXU) bits exactly match the owner + * permissions, and we can skip checking posix acls for the owner. + * With richacls, the owner may be granted fewer permissions than the + * mode bits seem to suggest (for example, append but not write), and + * we always need to check the richacl. + */ + + if (IS_RICHACL(inode)) { + int error = check_richacl(inode, mask); + if (error != -EAGAIN) + return error; + } if (likely(uid_eq(current_fsuid(), inode->i_uid))) mode >>= 6; else { if (IS_POSIXACL(inode) && (mode & S_IRWXG)) { - int error = check_acl(inode, mask); + int error = check_posix_acl(inode, mask); if (error != -EAGAIN) return error; } diff --git a/fs/posix_acl.c b/fs/posix_acl.c index b0eb1dc..6dbddb6 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c @@ -100,13 +100,13 @@ struct posix_acl *get_acl(struct inode *inode, int type) { struct posix_acl *acl; + if (!IS_POSIXACL(inode)) + return NULL; + acl = get_cached_acl(inode, type); if (acl != ACL_NOT_CACHED) return acl; - if (!IS_POSIXACL(inode)) - return NULL; - /* * A filesystem can force a ACL callback by just never filling the * ACL cache. But normally you'd fill the cache either at inode -- 2.5.0 From agruenba@redhat.com Thu Nov 5 05:42:17 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 BAC2F7FD7 for ; Thu, 5 Nov 2015 05:42:17 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id AB8F28F8033 for ; Thu, 5 Nov 2015 03:42:17 -0800 (PST) X-ASG-Debug-ID: 1446723735-04cb6c296c3a300001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 2k6jo71eKgMhij7H (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 05 Nov 2015 03:42:16 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 6280EC18F420; Thu, 5 Nov 2015 11:42:15 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-134.ams2.redhat.com [10.36.7.134]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA5Bdfbw015870; Thu, 5 Nov 2015 06:42:08 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: "Aneesh Kumar K.V" , Andreas Gruenbacher Subject: [PATCH v14 21/22] ext4: Add richacl support Date: Thu, 5 Nov 2015 12:39:39 +0100 X-ASG-Orig-Subj: [PATCH v14 21/22] ext4: Add richacl support Message-Id: <1446723580-3747-22-git-send-email-agruenba@redhat.com> In-Reply-To: <1446723580-3747-1-git-send-email-agruenba@redhat.com> References: <1446723580-3747-1-git-send-email-agruenba@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: 1446723735 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: "Aneesh Kumar K.V" Support the richacl permission model in ext4. The richacls are stored in "system.richacl" xattrs. Richacls need to be enabled by tune2fs or at file system create time. Signed-off-by: Aneesh Kumar K.V Signed-off-by: Andreas Gruenbacher Reviewed-by: Andreas Dilger --- fs/ext4/Kconfig | 11 +++++ fs/ext4/Makefile | 1 + fs/ext4/file.c | 3 ++ fs/ext4/ialloc.c | 11 ++++- fs/ext4/inode.c | 12 ++++- fs/ext4/namei.c | 5 ++ fs/ext4/richacl.c | 142 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ fs/ext4/richacl.h | 40 +++++++++++++++ fs/ext4/xattr.c | 7 +++ 9 files changed, 229 insertions(+), 3 deletions(-) create mode 100644 fs/ext4/richacl.c create mode 100644 fs/ext4/richacl.h diff --git a/fs/ext4/Kconfig b/fs/ext4/Kconfig index b46e9fc..65c5230 100644 --- a/fs/ext4/Kconfig +++ b/fs/ext4/Kconfig @@ -22,6 +22,17 @@ config EXT3_FS_POSIX_ACL This config option is here only for backward compatibility. ext3 filesystem is now handled by the ext4 driver. +config EXT4_FS_RICHACL + bool "Ext4 Rich Access Control Lists (EXPERIMENTAL)" + depends on EXT4_FS + select FS_RICHACL + help + Richacls are an implementation of NFSv4 ACLs, extended by file masks + to cleanly integrate into the POSIX file permission model. To learn + more about them, see http://www.bestbits.at/richacl/. + + If you don't know what Richacls are, say N. + config EXT3_FS_SECURITY bool "Ext3 Security Labels" depends on EXT3_FS diff --git a/fs/ext4/Makefile b/fs/ext4/Makefile index 75285ea..ea0d539 100644 --- a/fs/ext4/Makefile +++ b/fs/ext4/Makefile @@ -14,3 +14,4 @@ ext4-$(CONFIG_EXT4_FS_POSIX_ACL) += acl.o ext4-$(CONFIG_EXT4_FS_SECURITY) += xattr_security.o ext4-$(CONFIG_EXT4_FS_ENCRYPTION) += crypto_policy.o crypto.o \ crypto_key.o crypto_fname.o +ext4-$(CONFIG_EXT4_FS_RICHACL) += richacl.o diff --git a/fs/ext4/file.c b/fs/ext4/file.c index 113837e..a03b4a5 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c @@ -30,6 +30,7 @@ #include "ext4_jbd2.h" #include "xattr.h" #include "acl.h" +#include "richacl.h" /* * Called when an inode is released. Note that this is different @@ -719,6 +720,8 @@ const struct inode_operations ext4_file_inode_operations = { .removexattr = generic_removexattr, .get_acl = ext4_get_acl, .set_acl = ext4_set_acl, + .get_richacl = ext4_get_richacl, + .set_richacl = ext4_set_richacl, .fiemap = ext4_fiemap, }; diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index 619bfc1..9657b3a 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c @@ -27,6 +27,7 @@ #include "ext4_jbd2.h" #include "xattr.h" #include "acl.h" +#include "richacl.h" #include @@ -697,6 +698,14 @@ out: return ret; } +static inline int +ext4_new_acl(handle_t *handle, struct inode *inode, struct inode *dir) +{ + if (IS_RICHACL(dir)) + return ext4_init_richacl(handle, inode, dir); + return ext4_init_acl(handle, inode, dir); +} + /* * There are two policies for allocating an inode. If the new inode is * a directory, then a forward search is made for a block group with both @@ -1052,7 +1061,7 @@ got: if (err) goto fail_drop; - err = ext4_init_acl(handle, inode, dir); + err = ext4_new_acl(handle, inode, dir); if (err) goto fail_free_drop; diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 612fbcf..647f3c3 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -42,6 +42,7 @@ #include "xattr.h" #include "acl.h" #include "truncate.h" +#include "richacl.h" #include @@ -4638,6 +4639,14 @@ static void ext4_wait_for_tail_page_commit(struct inode *inode) } } +static inline int +ext4_acl_chmod(struct inode *inode, umode_t mode) +{ + if (IS_RICHACL(inode)) + return richacl_chmod(inode, inode->i_mode); + return posix_acl_chmod(inode, inode->i_mode); +} + /* * ext4_setattr() * @@ -4806,8 +4815,7 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr) ext4_orphan_del(NULL, inode); if (!rc && (ia_valid & ATTR_MODE)) - rc = posix_acl_chmod(inode, inode->i_mode); - + rc = ext4_acl_chmod(inode, inode->i_mode); err_out: ext4_std_error(inode->i_sb, error); if (!error) diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 9f61e76..9b6e8b9 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -38,6 +38,7 @@ #include "xattr.h" #include "acl.h" +#include "richacl.h" #include /* @@ -3854,6 +3855,8 @@ const struct inode_operations ext4_dir_inode_operations = { .removexattr = generic_removexattr, .get_acl = ext4_get_acl, .set_acl = ext4_set_acl, + .get_richacl = ext4_get_richacl, + .set_richacl = ext4_set_richacl, .fiemap = ext4_fiemap, }; @@ -3865,4 +3868,6 @@ const struct inode_operations ext4_special_inode_operations = { .removexattr = generic_removexattr, .get_acl = ext4_get_acl, .set_acl = ext4_set_acl, + .get_richacl = ext4_get_richacl, + .set_richacl = ext4_set_richacl, }; diff --git a/fs/ext4/richacl.c b/fs/ext4/richacl.c new file mode 100644 index 0000000..d581be4 --- /dev/null +++ b/fs/ext4/richacl.c @@ -0,0 +1,142 @@ +/* + * Copyright IBM Corporation, 2010 + * Copyright (C) 2015 Red Hat, Inc. + * Author: Aneesh Kumar K.V , + * Andreas Gruenbacher + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2.1 of the GNU Lesser 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. + * + */ + +#include +#include +#include + +#include "ext4.h" +#include "ext4_jbd2.h" +#include "xattr.h" +#include "acl.h" +#include "richacl.h" + +struct richacl * +ext4_get_richacl(struct inode *inode) +{ + const int name_index = EXT4_XATTR_INDEX_RICHACL; + void *value = NULL; + struct richacl *acl = NULL; + int retval; + + retval = ext4_xattr_get(inode, name_index, "", NULL, 0); + if (retval > 0) { + value = kmalloc(retval, GFP_NOFS); + if (!value) + return ERR_PTR(-ENOMEM); + retval = ext4_xattr_get(inode, name_index, "", value, retval); + } + if (retval > 0) { + acl = richacl_from_xattr(&init_user_ns, value, retval); + if (acl == ERR_PTR(-EINVAL)) + acl = ERR_PTR(-EIO); + } else if (retval != -ENODATA && retval != -ENOSYS) { + acl = ERR_PTR(retval); + } + kfree(value); + + if (!IS_ERR(acl)) + set_cached_richacl(inode, acl); + + return acl; +} + +static int +__ext4_remove_richacl(handle_t *handle, struct inode *inode) +{ + const int name_index = EXT4_XATTR_INDEX_RICHACL; + int retval; + + retval = ext4_xattr_set_handle(handle, inode, name_index, "", + NULL, 0, 0); + if (!retval) + set_cached_richacl(inode, NULL); + return retval; +} + +static int +__ext4_set_richacl(handle_t *handle, struct inode *inode, struct richacl *acl) +{ + const int name_index = EXT4_XATTR_INDEX_RICHACL; + umode_t mode = inode->i_mode; + int retval, size; + void *value; + + if (richacl_equiv_mode(acl, &mode) == 0) { + inode->i_ctime = ext4_current_time(inode); + inode->i_mode = mode; + ext4_mark_inode_dirty(handle, inode); + return __ext4_remove_richacl(handle, inode); + } + + mode &= ~S_IRWXUGO; + mode |= richacl_masks_to_mode(acl); + + size = richacl_xattr_size(acl); + value = kmalloc(size, GFP_NOFS); + if (!value) + return -ENOMEM; + richacl_to_xattr(&init_user_ns, acl, value, size); + inode->i_mode = mode; + retval = ext4_xattr_set_handle(handle, inode, name_index, "", + value, size, 0); + kfree(value); + if (retval) + return retval; + + set_cached_richacl(inode, acl); + + return 0; +} + +int +ext4_set_richacl(struct inode *inode, struct richacl *acl) +{ + handle_t *handle; + int retval, retries = 0; + +retry: + handle = ext4_journal_start(inode, EXT4_HT_XATTR, + ext4_jbd2_credits_xattr(inode)); + if (IS_ERR(handle)) + return PTR_ERR(handle); + + if (acl) + retval = __ext4_set_richacl(handle, inode, acl); + else + retval = __ext4_remove_richacl(handle, inode); + + ext4_journal_stop(handle); + if (retval == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) + goto retry; + return retval; +} + +int +ext4_init_richacl(handle_t *handle, struct inode *inode, struct inode *dir) +{ + struct richacl *acl = richacl_create(&inode->i_mode, dir); + int error; + + error = PTR_ERR(acl); + if (IS_ERR(acl)) + return error; + if (acl) { + error = __ext4_set_richacl(handle, inode, acl); + richacl_put(acl); + } + return error; +} diff --git a/fs/ext4/richacl.h b/fs/ext4/richacl.h new file mode 100644 index 0000000..6fe9a92 --- /dev/null +++ b/fs/ext4/richacl.h @@ -0,0 +1,40 @@ +/* + * Copyright IBM Corporation, 2010 + * Copyright (C) 2015 Red Hat, Inc. + * Author Aneesh Kumar K.V + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2.1 of the GNU Lesser 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. + * + */ + +#ifndef __FS_EXT4_RICHACL_H +#define __FS_EXT4_RICHACL_H + +#include + +#ifdef CONFIG_EXT4_FS_RICHACL + +extern struct richacl *ext4_get_richacl(struct inode *); +extern int ext4_set_richacl(struct inode *, struct richacl *); + +extern int ext4_init_richacl(handle_t *, struct inode *, struct inode *); + +#else /* CONFIG_EXT4_FS_RICHACL */ + +#define ext4_get_richacl NULL +#define ext4_set_richacl NULL + +static inline int +ext4_init_richacl(handle_t *handle, struct inode *inode, struct inode *dir) +{ + return 0; +} + +#endif /* CONFIG_EXT4_FS_RICHACL */ +#endif /* __FS_EXT4_RICHACL_H */ diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index 16e28c0..4d79adb 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -55,6 +55,7 @@ #include #include #include +#include #include "ext4_jbd2.h" #include "ext4.h" #include "xattr.h" @@ -99,6 +100,9 @@ static const struct xattr_handler *ext4_xattr_handler_map[] = { #ifdef CONFIG_EXT4_FS_SECURITY [EXT4_XATTR_INDEX_SECURITY] = &ext4_xattr_security_handler, #endif +#ifdef CONFIG_EXT4_FS_RICHACL + [EXT4_XATTR_INDEX_RICHACL] = &richacl_xattr_handler, +#endif }; const struct xattr_handler *ext4_xattr_handlers[] = { @@ -111,6 +115,9 @@ const struct xattr_handler *ext4_xattr_handlers[] = { #ifdef CONFIG_EXT4_FS_SECURITY &ext4_xattr_security_handler, #endif +#ifdef CONFIG_EXT4_FS_RICHACL + &richacl_xattr_handler, +#endif NULL }; -- 2.5.0 From agruenba@redhat.com Thu Nov 5 05:42:24 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 41BE27FD7 for ; Thu, 5 Nov 2015 05:42:24 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 3339A304053 for ; Thu, 5 Nov 2015 03:42:24 -0800 (PST) X-ASG-Debug-ID: 1446723742-04cb6c296d3a330001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id pNszCi1PzXGjEZpN (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 05 Nov 2015 03:42:23 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 7FBE28F2FF; Thu, 5 Nov 2015 11:42:22 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-134.ams2.redhat.com [10.36.7.134]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA5Bdfbx015870; Thu, 5 Nov 2015 06:42:15 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: "Aneesh Kumar K.V" , Andreas Gruenbacher Subject: [PATCH v14 22/22] ext4: Add richacl feature flag Date: Thu, 5 Nov 2015 12:39:40 +0100 X-ASG-Orig-Subj: [PATCH v14 22/22] ext4: Add richacl feature flag Message-Id: <1446723580-3747-23-git-send-email-agruenba@redhat.com> In-Reply-To: <1446723580-3747-1-git-send-email-agruenba@redhat.com> References: <1446723580-3747-1-git-send-email-agruenba@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: 1446723743 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: "Aneesh Kumar K.V" This feature flag selects richacl instead of POSIX ACL support on the filesystem. When this feature is off, the "acl" and "noacl" mount options control whether POSIX ACLs are enabled. When it is on, richacls are automatically enabled and using the "noacl" mount option leads to an error. Signed-off-by: Aneesh Kumar K.V Signed-off-by: Andreas Gruenbacher --- fs/ext4/ext4.h | 6 ++++-- fs/ext4/super.c | 49 ++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 44 insertions(+), 11 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index fd1f28b..b97a3b1 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -991,7 +991,7 @@ struct ext4_inode_info { #define EXT4_MOUNT_UPDATE_JOURNAL 0x01000 /* Update the journal format */ #define EXT4_MOUNT_NO_UID32 0x02000 /* Disable 32-bit UIDs */ #define EXT4_MOUNT_XATTR_USER 0x04000 /* Extended user attributes */ -#define EXT4_MOUNT_POSIX_ACL 0x08000 /* POSIX Access Control Lists */ +#define EXT4_MOUNT_ACL 0x08000 /* Access Control Lists */ #define EXT4_MOUNT_NO_AUTO_DA_ALLOC 0x10000 /* No auto delalloc mapping */ #define EXT4_MOUNT_BARRIER 0x20000 /* Use block barriers */ #define EXT4_MOUNT_QUOTA 0x80000 /* Some quota option set */ @@ -1582,6 +1582,7 @@ static inline int ext4_encrypted_inode(struct inode *inode) #define EXT4_FEATURE_INCOMPAT_LARGEDIR 0x4000 /* >2GB or 3-lvl htree */ #define EXT4_FEATURE_INCOMPAT_INLINE_DATA 0x8000 /* data in inode */ #define EXT4_FEATURE_INCOMPAT_ENCRYPT 0x10000 +#define EXT4_FEATURE_INCOMPAT_RICHACL 0x20000 #define EXT2_FEATURE_COMPAT_SUPP EXT4_FEATURE_COMPAT_EXT_ATTR #define EXT2_FEATURE_INCOMPAT_SUPP (EXT4_FEATURE_INCOMPAT_FILETYPE| \ @@ -1607,7 +1608,8 @@ static inline int ext4_encrypted_inode(struct inode *inode) EXT4_FEATURE_INCOMPAT_FLEX_BG| \ EXT4_FEATURE_INCOMPAT_MMP | \ EXT4_FEATURE_INCOMPAT_INLINE_DATA | \ - EXT4_FEATURE_INCOMPAT_ENCRYPT) + EXT4_FEATURE_INCOMPAT_ENCRYPT | \ + EXT4_FEATURE_INCOMPAT_RICHACL) #define EXT4_FEATURE_RO_COMPAT_SUPP (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER| \ EXT4_FEATURE_RO_COMPAT_LARGE_FILE| \ EXT4_FEATURE_RO_COMPAT_GDT_CSUM| \ diff --git a/fs/ext4/super.c b/fs/ext4/super.c index a63c7b0..7457ea8 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1270,6 +1270,28 @@ static ext4_fsblk_t get_sb_block(void **data) return sb_block; } +static int enable_acl(struct super_block *sb) +{ + sb->s_flags &= ~(MS_POSIXACL | MS_RICHACL); + if (test_opt(sb, ACL)) { + if (EXT4_HAS_INCOMPAT_FEATURE(sb, + EXT4_FEATURE_INCOMPAT_RICHACL)) { +#ifdef CONFIG_EXT4_FS_RICHACL + sb->s_flags |= MS_RICHACL; +#else + return -EOPNOTSUPP; +#endif + } else { +#ifdef CONFIG_EXT4_FS_POSIX_ACL + sb->s_flags |= MS_POSIXACL; +#else + return -EOPNOTSUPP; +#endif + } + } + return 0; +} + #define DEFAULT_JOURNAL_IOPRIO (IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 3)) static char deprecated_msg[] = "Mount option \"%s\" will be removed by %s\n" "Contact linux-ext4@vger.kernel.org if you think we should keep it.\n"; @@ -1416,9 +1438,9 @@ static const struct mount_opts { MOPT_NO_EXT2 | MOPT_DATAJ}, {Opt_user_xattr, EXT4_MOUNT_XATTR_USER, MOPT_SET}, {Opt_nouser_xattr, EXT4_MOUNT_XATTR_USER, MOPT_CLEAR}, -#ifdef CONFIG_EXT4_FS_POSIX_ACL - {Opt_acl, EXT4_MOUNT_POSIX_ACL, MOPT_SET}, - {Opt_noacl, EXT4_MOUNT_POSIX_ACL, MOPT_CLEAR}, +#if defined(CONFIG_EXT4_FS_POSIX_ACL) || defined(CONFIG_EXT4_FS_RICHACL) + {Opt_acl, EXT4_MOUNT_ACL, MOPT_SET}, + {Opt_noacl, EXT4_MOUNT_ACL, MOPT_CLEAR}, #else {Opt_acl, 0, MOPT_NOSUPPORT}, {Opt_noacl, 0, MOPT_NOSUPPORT}, @@ -1466,6 +1488,13 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token, #endif switch (token) { case Opt_noacl: +#ifdef CONFIG_EXT4_FS_RICHACL + if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RICHACL)) { + ext4_msg(sb, KERN_ERR, "Mount option \"%s\" incompatible " + "with richacl feature", opt); + return -1; + } +#endif case Opt_nouser_xattr: ext4_msg(sb, KERN_WARNING, deprecated_msg, opt, "3.5"); break; @@ -3576,8 +3605,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) set_opt(sb, NO_UID32); /* xattr user namespace & acls are now defaulted on */ set_opt(sb, XATTR_USER); -#ifdef CONFIG_EXT4_FS_POSIX_ACL - set_opt(sb, POSIX_ACL); +#if defined(CONFIG_EXT4_FS_POSIX_ACL) || defined(CONFIG_EXT4_FS_RICHACL) + set_opt(sb, ACL); #endif /* don't forget to enable journal_csum when metadata_csum is enabled. */ if (ext4_has_metadata_csum(sb)) @@ -3660,8 +3689,9 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) sb->s_iflags |= SB_I_CGROUPWB; } - sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | - (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0); + err = enable_acl(sb); + if (err) + goto failed_mount; if (le32_to_cpu(es->s_rev_level) == EXT4_GOOD_OLD_REV && (EXT4_HAS_COMPAT_FEATURE(sb, ~0U) || @@ -4981,8 +5011,9 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) if (sbi->s_mount_flags & EXT4_MF_FS_ABORTED) ext4_abort(sb, "Abort forced by user"); - sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | - (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0); + err = enable_acl(sb); + if (err) + goto restore_opts; es = sbi->s_es; -- 2.5.0 From prvs=875189c0cb=clm@fb.com Thu Nov 5 06:11:09 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 F40C97F4E for ; Thu, 5 Nov 2015 06:11:08 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id E42568F8035 for ; Thu, 5 Nov 2015 04:11:05 -0800 (PST) X-ASG-Debug-ID: 1446725464-04cbb02423439a0001-NocioJ Received: from mx0a-00082601.pphosted.com (mx0a-00082601.pphosted.com [67.231.145.42]) by cuda.sgi.com with ESMTP id FoUCEhJQbzDzURNZ (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 05 Nov 2015 04:11:04 -0800 (PST) X-Barracuda-Envelope-From: prvs=875189c0cb=clm@fb.com X-Barracuda-Apparent-Source-IP: 67.231.145.42 X-ASG-Whitelist: EmailCat (corporate) Received: from pps.filterd (m0044008.ppops.net [127.0.0.1]) by mx0a-00082601.pphosted.com (8.15.0.59/8.15.0.59) with SMTP id tA5C9CtQ018861; Thu, 5 Nov 2015 04:11:03 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=fb.com; h=date : from : to : subject : message-id : references : mime-version : content-type : in-reply-to; s=facebook; bh=SLsRcS4J6G2CkgjiwFaI5ra63JeJEZqwvhmcJGmY7MY=; b=QXr+rh8LgWbVaJahrddHt2ACI8q01zJsyo1brTWg3GzWz3rdigzZvaRJzEO6b5Q1If0x rROrx4SY+PjJsY5Rpn9RWFzdxwF2XvvwR1scESgug7heKmn62W9W5SASf+IeigmTYO9Y Yze74nMGlDs4zpbkIaSSEVkGTVcwotkWFL0= Received: from mail.thefacebook.com ([199.201.64.23]) by mx0a-00082601.pphosted.com with ESMTP id 1xy37sr3cp-1 (version=TLSv1/SSLv3 cipher=AES128-SHA bits=128 verify=NOT); Thu, 05 Nov 2015 04:11:03 -0800 Received: from localhost (192.168.52.123) by mail.thefacebook.com (192.168.16.14) with Microsoft SMTP Server (TLS) id 14.3.248.2; Thu, 5 Nov 2015 04:11:01 -0800 Date: Thu, 5 Nov 2015 07:10:59 -0500 From: Chris Mason To: Dave Chinner , , Tejun Heo Subject: Re: [PATCH RFC] use WQ_MEM_RECLAIM for m_log_workqueue Message-ID: <20151105121059.GJ5458@ret.masoncoding.com> X-ASG-Orig-Subj: Re: [PATCH RFC] use WQ_MEM_RECLAIM for m_log_workqueue References: <20151104185103.GC5458@ret.masoncoding.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Disposition: inline In-Reply-To: <20151104185103.GC5458@ret.masoncoding.com> User-Agent: Mutt/1.5.23.1 (2014-03-12) X-Originating-IP: [192.168.52.123] X-Proofpoint-Spam-Reason: safe X-FB-Internal: Safe X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:,, definitions=2015-11-05_11:,, signatures=0 X-Barracuda-Connect: mx0a-00082601.pphosted.com[67.231.145.42] X-Barracuda-Start-Time: 1446725464 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Wed, Nov 04, 2015 at 01:51:03PM -0500, Chris Mason wrote: > I think we should be using WQ_MEM_RECLAIM to make sure this thread pool > makes progress when we're not able to allocate new workers. Thinking harder, it's probably best to just flag them all WQ_MEM_RECLAIM. This is what btrfs does, and it saves you from painful discoveries about how different queues depend on each other. Tejun did verify in the dump that progress on m_log_workqueue was stuck waiting for more threads. I'll start testing and send a v2. -chris From trond.myklebust@primarydata.com Thu Nov 5 09:57:12 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 E44947F76 for ; Thu, 5 Nov 2015 09:57:12 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id C39D4304059 for ; Thu, 5 Nov 2015 07:57:09 -0800 (PST) X-ASG-Debug-ID: 1446739024-04cbb024224d920001-NocioJ Received: from mail-ob0-f170.google.com (mail-ob0-f170.google.com [209.85.214.170]) by cuda.sgi.com with ESMTP id gvGktpjbaQAsttgY (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Thu, 05 Nov 2015 07:57:04 -0800 (PST) X-Barracuda-Envelope-From: trond.myklebust@primarydata.com X-Barracuda-Apparent-Source-IP: 209.85.214.170 Received: by obbza9 with SMTP id za9so69598082obb.1 for ; Thu, 05 Nov 2015 07:57:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=primarydata_com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=bID5xS8FXvCmXUDpOKRa+5Ke6g86fjmxRYzMihodbpY=; b=IoyoBTivorKyxIaWYmt/1W0EiFm8WtPeWfkavadwc/jpwVeUOlaWfubKE0kzBrwUFq iROZjxfcxf0dqKGGlhdVQY8c9xM7527aYZJoe/HWQZV5dDkYraoe20mdFHGTqIkzlJNo igmk4kIXYvkllnk4wZBOw5OT4J+sa5I3fyueUdr/S3SbdwAsDJvWPwGddXzmhB5eNxVo WZUyFpcdQXC65G/wZ4IcolbVKBSDHAxoic1gtFriVOzdBI5QWw7sSir6d5NhD+kyqaDj OGQMO6WQu3tqkt5qAclOh9we98Z23wfxvFFwJ5L6aTVPnDM1vtabeSEBZ4jfwvz/zaJ+ ZA9A== 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=bID5xS8FXvCmXUDpOKRa+5Ke6g86fjmxRYzMihodbpY=; b=FJtyJT6LZ/oLDowuu9ogJZiWObN7B6x9YOXGiSz+Cs2h7jiO8or6+y7FWWP6D9bHaU tXcBoQiFRbBDxM3v7gS/x1fAzFfUKM1mRKFqj5PQ+c8cdhNwL/jexw9lAh837bXUkHv1 iZWNy6+mlFI5OFQ00/uumei6+sN5hYHaXQAf5QObMBY3cTzv/aBFwqNrLHY96WKRVhf+ sSr3eEHA0cRpbp5VGZ/z/moBV/Fe+qmurGoSoSogR/z/5y57mKpqy2JCF26Bq6FTIwb3 8NK1CaVO/2BwPcYwxl+CoUhS5IJEMeayCXFyX8EIGcCMTJYq2ba4hAY0PsAPOns1wyFS 8Y7A== X-Gm-Message-State: ALoCoQlI9bFS8ZACTtdroHDfRP3ffczsUbKTg9iQNwUIaUj0XDMRQ3v5EsxjhpOeG29eKKJcCUyr MIME-Version: 1.0 X-Received: by 10.182.176.102 with SMTP id ch6mr4915979obc.31.1446739024101; Thu, 05 Nov 2015 07:57:04 -0800 (PST) Received: by 10.202.95.7 with HTTP; Thu, 5 Nov 2015 07:57:04 -0800 (PST) In-Reply-To: References: <1446563847-14005-1-git-send-email-agruenba@redhat.com> <1446563847-14005-46-git-send-email-agruenba@redhat.com> Date: Thu, 5 Nov 2015 10:57:04 -0500 Message-ID: Subject: Re: [PATCH v13 45/51] sunrpc: Allow to demand-allocate pages to encode into From: Trond Myklebust X-ASG-Orig-Subj: Re: [PATCH v13 45/51] sunrpc: Allow to demand-allocate pages to encode into To: Andreas Gruenbacher Cc: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Anna Schumaker , Dave Chinner , linux-ext4 , XFS Developers , Linux Kernel Mailing List , Linux FS-devel Mailing List , Linux NFS Mailing List , linux-cifs@vger.kernel.org, Linux API Mailing List Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-ob0-f170.google.com[209.85.214.170] X-Barracuda-Start-Time: 1446739024 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24136 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, Nov 5, 2015 at 6:07 AM, Andreas Gruenbacher wrote: > Trond, > > On Tue, Nov 3, 2015 at 5:25 PM, Trond Myklebust > wrote: >> On Tue, Nov 3, 2015 at 10:17 AM, Andreas Gruenbacher >> wrote: >>> When encoding large, variable-length objects such as acls into xdr_bufs, >>> it is easier to allocate buffer pages on demand rather than precomputing >>> the required buffer size. >> >> NACK. We're not doing allocations from inside the XDR encoders. This >> can and should be done before calling into the SUNRPC layer. > > an XDR-encoded ACL can be up to 64k (16 pages) in size. In practice, > large ACLs like that will almost never occur and almost all ACLs will > fit into a single page though. > > The XDR-encoded ACL contains strings for the user and group names > which need to be looked up when the idmapper is used. Those lookups > are somewhat expensive; in addition, the lookup results can change > over time. When precomputing the size, allocating space, and then > encoding the ACL, we could run out of space when encoding. > > So we could always allocate the maximum 16 pages, encode the acl, and > free the unused pages. This would be rather wasteful though. > > Given how simple it is to allocate pages as we go, this seems the > better choice here. This doesn't break any existing code either; NULL > page pointers would have oopsed in xdr_get_next_encode_buffer before. > > From the memory management point of view, there is no difference in > preallocating GFP_NOFS pages and allocating them on demand; the pages > are allocated in the same task and locking context in both cases. > > So could you please explain why you object to this change? > Allocating memory deep in the bowels of the RPC code with the expectation that it will be freed by the caller of the RPC request is a layering violation of the ugliest sort. How is anyone who is unfamiliar with the code going to be able to understand what is going on without tracing through 1000 lines of code to spot where the allocation is happening? Aside from that, we do not want any non-critical blocking while holding the RPC socket lock. Your allocation request will block all further traffic to the server until it is satisfied. That includes blocking page writeback, which might actually free up memory to satisfy the allocation. As I said above, there is no reason whatsoever to have to do all this inside encode_setacl(). The entire ACL encoding into pages can be done before even calling into the RPC layer, just like we do today. From hanno@hboeck.de Thu Nov 5 10:46:49 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 ED2077F61 for ; Thu, 5 Nov 2015 10:46:48 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 74E76AC001 for ; Thu, 5 Nov 2015 08:46:42 -0800 (PST) X-ASG-Debug-ID: 1446741997-04cbb0242451e40001-NocioJ Received: from zucker2.schokokeks.org (zucker2.schokokeks.org [178.63.68.90]) by cuda.sgi.com with ESMTP id eENsDuAbIiFa6hmV (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NO) for ; Thu, 05 Nov 2015 08:46:38 -0800 (PST) X-Barracuda-Envelope-From: hanno@hboeck.de X-Barracuda-Apparent-Source-IP: 178.63.68.90 Received: from pc1 (0x3ec66991.inet.dsl.telianet.dk [::ffff:62.198.105.145]) (AUTH: LOGIN hanno-default@schokokeks.org, TLS: TLSv1/SSLv3,128bits,ECDHE-RSA-AES128-GCM-SHA256) by zucker.schokokeks.org with ESMTPSA; Thu, 05 Nov 2015 17:46:36 +0100 id 0000000000000039.00000000563B87EC.00005854 Date: Thu, 5 Nov 2015 17:47:32 +0100 From: Hanno =?UTF-8?B?QsO2Y2s=?= To: xfs@oss.sgi.com Subject: Several bugs in xfs-progs when parsing invalid input Message-ID: <20151105174732.2378bc35@pc1> X-ASG-Orig-Subj: Several bugs in xfs-progs when parsing invalid input X-Mailer: Claws Mail 3.13.0 (GTK+ 2.24.28; x86_64-pc-linux-gnu) Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha512; protocol="application/pgp-signature"; boundary="=_zucker.schokokeks.org-22612-1446741996-0001-2" X-Barracuda-Connect: zucker2.schokokeks.org[178.63.68.90] X-Barracuda-Start-Time: 1446741998 X-Barracuda-Encrypted: ECDHE-RSA-AES256-SHA X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24136 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- This is a MIME-formatted message. If you see this text it means that your E-mail software does not support MIME-formatted messages. --=_zucker.schokokeks.org-22612-1446741996-0001-2 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Hi, A while ago I reported a couple of bugs into your bugtracker about issues in xfs_repair that I found through fuzzing (with the tool american fuzzy lop). http://oss.sgi.com/bugzilla/show_bug.cgi?id=3D1119 null pointer access http://oss.sgi.com/bugzilla/show_bug.cgi?id=3D1120 out of bounds heap read access http://oss.sgi.com/bugzilla/show_bug.cgi?id=3D1121 http://oss.sgi.com/bugzilla/show_bug.cgi?id=3D1122 2x assert When opening these bugs I got an error message. I then contacted your support and almost two months(!) later I got a reply telling me that I should not use bugzilla, instead I should report bugs to this mailing list. Your webpage however clearly states that I should use bugzilla: http://oss.sgi.com/projects/xfs/ This is all a bit ridiculous. If you don't want people to use your bugzilla don't say so on your webpage and preferrably disable the creation of new bugs. Anyway: Please have a look at the bugs I reported (and once they're fixed I'll happily re-test the code to see if there are more issues that can be found via fuzzing). --=20 Hanno B=C3=B6ck http://hboeck.de/ mail/jabber: hanno@hboeck.de GPG: BBB51E42 --=_zucker.schokokeks.org-22612-1446741996-0001-2 Content-Type: application/pgp-signature Content-Transfer-Encoding: 7bit Content-Description: OpenPGP digital signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAEBCgAGBQJWO4gkAAoJEKWIAHK7tR5C+wwP/j1hhfcCHf0mHC2fK5Yldwjq nrIdfg2oVHLLno8UUrwiOJTdfsefj0mX4FxTOzqO/WxQDD9Md9me37/YOme5TRgN CSTjOrVTN9oie1m2PjOpSrfFrX1IwbkkaX/xN4YiFOs86lBY5enf4KZCfWhRjWgA mqJhgTvgKLOR87Cmz6gQijZ1plRloEkEejVqEbC1dBQ1AiiJUc648AzbVStp6LVM +9Jr16F1ctHmDbsb6zKlRSFBre1MX/JsTCn+E3H4MiabiRBoigU+/Ie8P0jX9WoT ML/0ix85eOQH6S/q4aEnUjNiSC71oovvOZ6wIQeCg2r+wNjtAtVdxD5ADx7kNOxI GD6ASU+dAfE4i65tklWXAu6WdCKF5YbHJez/aoLcxYQDPbUSw1hK1V/agQtvRgjk LbRwfYeLcykIV2IxidPsjg71opBjqdZrzbu96uiQDdY9xbKL5RFf2Jt8hjF8z6xo seLNokg7cHZd2eBEbmOS1WGgjnEWboVDn3zdu9s2mnMgpAaR/JPtpS95qP+uYHWV RR2rL865plrReFfUZYpj7dTHKXcgP8KknHyTC1zE+AYoNyoJvH2j/WeCrsBLYkYw WfzacmLGrMfhApvi7+wrqpWW6J2wDnZ6KBhgx4KAtGeIJIUr2O/zA12dTm0VrVvZ i+DP92wP9RY1VyuV6/vJ =c32S -----END PGP SIGNATURE----- --=_zucker.schokokeks.org-22612-1446741996-0001-2-- From jmoyer@redhat.com Thu Nov 5 13:49:30 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 80B967F8D for ; Thu, 5 Nov 2015 13:49:30 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id CD9B0AC001 for ; Thu, 5 Nov 2015 11:49:29 -0800 (PST) X-ASG-Debug-ID: 1446752968-04cbb024245d610001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 3QyEVUC55SHGagLy (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 05 Nov 2015 11:49:28 -0800 (PST) X-Barracuda-Envelope-From: jmoyer@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 (Postfix) with ESMTPS id C00B2C0D61A9; Thu, 5 Nov 2015 19:49:25 +0000 (UTC) Received: from segfault.boston.devel.redhat.com (segfault.boston.devel.redhat.com [10.19.60.26]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA5JnL6i001419 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Thu, 5 Nov 2015 14:49:22 -0500 From: Jeff Moyer To: Dave Chinner Cc: Ross Zwisler , linux-kernel@vger.kernel.org, "H. Peter Anvin" , "J. Bruce Fields" , "Theodore Ts'o" , Alexander Viro , Andreas Dilger , Dan Williams , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@ml01.01.org, x86@kernel.org, xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox , axboe@kernel.dk Subject: Re: [RFC 00/11] DAX fsynx/msync support References: <1446149535-16200-1-git-send-email-ross.zwisler@linux.intel.com> <20151030035533.GU19199@dastard> <20151030183938.GC24643@linux.intel.com> <20151101232948.GF10656@dastard> <20151102201029.GI10656@dastard> <20151105083309.GJ19199@dastard> X-ASG-Orig-Subj: Re: [RFC 00/11] DAX fsynx/msync support X-PGP-KeyID: 1F78E1B4 X-PGP-CertKey: F6FE 280D 8293 F72C 65FD 5A58 1FF8 A7CA 1F78 E1B4 X-PCLoadLetter: What the f**k does that mean? Date: Thu, 05 Nov 2015 14:49:21 -0500 In-Reply-To: <20151105083309.GJ19199@dastard> (Dave Chinner's message of "Thu, 5 Nov 2015 19:33:09 +1100") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain 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: 1446752968 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Dave Chinner writes: >> But this part is not. It is up to the I/O scheduler to decide when to >> dispatch requests. It can hold on to them for a variety of reasons. >> Flush requests, however, do not go through the I/O scheduler. At the > > That's pure REQ_FLUSH bios, right? Aren't data IOs with > REQ_FLUSH|REQ_FUA sorted like any other IO? No, they also go through the flush machinery, and so short-circuit the I/O scheduler. >> Des xfs rely on this model for correctness? If so, I'd say we've got a >> problem > > No, it doesn't. The XFS integrity model doesn't trust the IO layers > to tell the truth about IO ordering and completion or for it's > developers to fully understand how IO layer ordering works. :P > > i.e. we wait for full completions of all dependent IO before issuing > flushes or log writes that use REQ_FLUSH|REQ_FUA semantics to ensure > the dependent IOs are fully caught by the cache flushes... OK, phew! ;-) -Jeff From axboe@kernel.dk Thu Nov 5 14:54:27 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 E92E17F69 for ; Thu, 5 Nov 2015 14:54:26 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 87CBFAC001 for ; Thu, 5 Nov 2015 12:54:23 -0800 (PST) X-ASG-Debug-ID: 1446756861-04bdf03f055c830001-NocioJ Received: from mail-io0-f171.google.com (mail-io0-f171.google.com [209.85.223.171]) by cuda.sgi.com with ESMTP id 1XbSe6GxNEZRJLNk (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Thu, 05 Nov 2015 12:54:21 -0800 (PST) X-Barracuda-Envelope-From: axboe@kernel.dk X-Barracuda-RBL-Trusted-Forwarder: 209.85.223.171 Received: by iodd200 with SMTP id d200so103536260iod.0 for ; Thu, 05 Nov 2015 12:54:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel_dk.20150623.gappssmtp.com; s=20150623; h=subject:to:references:cc:from:message-id:date:user-agent :mime-version:in-reply-to:content-type:content-transfer-encoding; bh=MBzeWYsf6lngQ+jiU950oq/SOS9HaWr70k/TpYIVqiA=; b=OZo7Me1hQLazE0C7QdzB5+wc+qnYuuW/dREr2NLqxMCrk5wRCttcDCXaeyw79HuJHv LCeuaD/SrVrK23y83bJinaUfpjk1gSK3VXYJ0bfm5AdBWhuYrhpAzm83+pvJ5EAzlRIk 5hR+IvQqP78rWDMmWdORBA+l9Fl+uBzw0TBYEV/bjAxbnne4ONRpCmu0AplNy8vMZrQG lakWUN2gp+S/8mD/SHsfNEsiSDTr2rY8wNVpxPbJFX7s4cM2rZzrPzFGdbDYD/9FYlHK ypa4bFdjisRYq0UEbfgGn6fX73pA/Y2DWWljiIQ5JNayj+QeyF/hHYlubVwpxH3at+rJ Ga/g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:subject:to:references:cc:from:message-id:date :user-agent:mime-version:in-reply-to:content-type :content-transfer-encoding; bh=MBzeWYsf6lngQ+jiU950oq/SOS9HaWr70k/TpYIVqiA=; b=Ogyi1WcygoZ0zD0yPJdr6XFk0nSeoBKEJ3YnSeHXoOJVkOGrqrpfOa/TejAz5J5/R2 +Bp/fMBGN3A2sPYjqVoQZ/LEiAJZrVxNcuds+Wz+eJaAqkXWmf1WLZ9xdz1y14MwkoLt ZEbIFwoGIIpK40RTDl4K+L450WK07YQivZ/gJpLcBIEU1w/MOegRFD8Z9TWZyn/qcAk0 coHvgJnLxxSko7i+ouhjcTdWPyNJwyYatWjEkw480LgbxrKZwwhQK9e2PZUVwDmvBumO kYKLN6+e660Z/o8blPrWnP2qiFYigxwkwgu2WgW9gN/Tr+/KFel8FelSMCFaZCaWVRfQ /wGg== X-Gm-Message-State: ALoCoQl/wOSLx7J4uZfIzcUd8FTbZxirfoyWPhW0C6VTeSP8vcjNPFTA4MgVeE0wMmVcizKnpDWP X-Received: by 10.107.128.137 with SMTP id k9mr12188928ioi.162.1446756861295; Thu, 05 Nov 2015 12:54:21 -0800 (PST) Received: from [192.168.1.120] ([216.160.245.98]) by smtp.gmail.com with ESMTPSA id l4sm241900igx.12.2015.11.05.12.54.19 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 05 Nov 2015 12:54:20 -0800 (PST) Subject: Re: [RFC 00/11] DAX fsynx/msync support X-Barracuda-BBL-IP: 192.168.1.120 To: Dave Chinner , Jeff Moyer X-ASG-Orig-Subj: Re: [RFC 00/11] DAX fsynx/msync support References: <1446149535-16200-1-git-send-email-ross.zwisler@linux.intel.com> <20151030035533.GU19199@dastard> <20151030183938.GC24643@linux.intel.com> <20151101232948.GF10656@dastard> <20151102201029.GI10656@dastard> <20151105083309.GJ19199@dastard> Cc: Ross Zwisler , linux-kernel@vger.kernel.org, "H. Peter Anvin" , "J. Bruce Fields" , Theodore Ts'o , Alexander Viro , Andreas Dilger , Dan Williams , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@ml01.01.org, x86@kernel.org, xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox From: Jens Axboe Message-ID: <563BC1FB.60004@kernel.dk> Date: Thu, 5 Nov 2015 13:54:19 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <20151105083309.GJ19199@dastard> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mail-io0-f171.google.com[209.85.223.171] X-Barracuda-Start-Time: 1446756861 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24141 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 11/05/2015 01:33 AM, Dave Chinner wrote: >> Des xfs rely on this model for correctness? If so, I'd say we've got a >> problem > > No, it doesn't. The XFS integrity model doesn't trust the IO layers > to tell the truth about IO ordering and completion or for it's > developers to fully understand how IO layer ordering works. :P That's good, because the storage developers simplified the model so that fs developers would be able to get and use it. > i.e. we wait for full completions of all dependent IO before issuing > flushes or log writes that use REQ_FLUSH|REQ_FUA semantics to ensure > the dependent IOs are fully caught by the cache flushes... ... which is what you are supposed to do, that's how it works. -- Jens Axboe From ross.zwisler@linux.intel.com Thu Nov 5 17:48:33 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 42C547F86 for ; Thu, 5 Nov 2015 17:48:33 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 321FA8F804B for ; Thu, 5 Nov 2015 15:48:30 -0800 (PST) X-ASG-Debug-ID: 1446767308-04cb6c296a62ee0001-NocioJ Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by cuda.sgi.com with ESMTP id oqSjCadGPpgeZL19 for ; Thu, 05 Nov 2015 15:48:28 -0800 (PST) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 134.134.136.24 X-ASG-Whitelist: EmailCat (corporate) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga102.jf.intel.com with ESMTP; 05 Nov 2015 15:48:29 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,249,1444719600"; d="scan'208";a="828377962" Received: from theros.lm.intel.com (HELO linux.intel.com) ([10.232.112.156]) by fmsmga001.fm.intel.com with ESMTP; 05 Nov 2015 15:48:28 -0800 Date: Thu, 5 Nov 2015 16:48:27 -0700 From: Ross Zwisler To: Dave Chinner Cc: xfs@oss.sgi.com, ross.zwisler@linux.intel.com, jack@suse.cz Subject: Re: [PATCH 0/6 V2] xfs: upfront block zeroing for DAX Message-ID: <20151105234827.GA5771@linux.intel.com> X-ASG-Orig-Subj: Re: [PATCH 0/6 V2] xfs: upfront block zeroing for DAX References: <1445225238-30413-1-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1445225238-30413-1-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-Barracuda-Connect: mga09.intel.com[134.134.136.24] X-Barracuda-Start-Time: 1446767308 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Mon, Oct 19, 2015 at 02:27:12PM +1100, Dave Chinner wrote: > Hi folks, > > This is an updated patch set that was first posted here: > > http://oss.sgi.com/archives/xfs/2015-10/msg00006.html > > I've dropped the DAX locking revert patch from it; that's on it's > way to Linus via other channels and is essentially independent to > this set of XFS changes. > > The only real change in the XFS code between the two versions is the > addition of XFS_TRANS_RESERVE in the DAX path in > xfs_iomap_write_direct() to allow it to dip into the reserve block > pool for unwritten extent conversion rather than reporting ENOSPC. > > Patches are against 4.3-rc5 + XFS for-next branch. > > -Dave. Hey Dave, I was going to start testing these, but I'm having trouble finding a baseline where they apply cleanly. It looks like xfs/for-next already contains v1 of the series, and they don't seem to apply cleanly to the current xfs/xfs-misc-fixes-for-4.4-2 nor to v4.3. The xfs repo I'm looking at is git://git.kernel.org/pub/scm/linux/kernel/git/dgc/linux-xfs.git What am I missing? Thanks, - Ross From alau2@cisco.com Thu Nov 5 20:06:51 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 588FA7F86 for ; Thu, 5 Nov 2015 20:06:51 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id B4DE9AC004 for ; Thu, 5 Nov 2015 18:06:47 -0800 (PST) X-ASG-Debug-ID: 1446775604-04cbb024256f340001-NocioJ Received: from alln-iport-6.cisco.com (alln-iport-6.cisco.com [173.37.142.93]) by cuda.sgi.com with ESMTP id SzAZy3uQsjZxaK70 (version=TLSv1 cipher=IDEA-CBC-SHA bits=128 verify=NO) for ; Thu, 05 Nov 2015 18:06:44 -0800 (PST) X-Barracuda-Envelope-From: alau2@cisco.com X-Barracuda-Apparent-Source-IP: 173.37.142.93 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=cisco.com; i=@cisco.com; l=2579; q=dns/txt; s=iport; t=1446775605; x=1447985205; h=from:to:cc:subject:date:message-id:references: in-reply-to:content-transfer-encoding:mime-version; bh=RC6GgwgeCzK77D+160/7w7wtJGbWwmh+aQYm8fhWo4U=; b=R9QknTpX67IgLrCyVErfvo5TbnhLJJ8YKaLIIYhJ769+dqXIF33UGiFe pqgVqSlbTZf6EesSBLtjvU5+zUWCn7aO72Y0AuWP2FnO3OmHtWlFMedbz vzm6rephN/7Niyu96dUsNd4QMhbSOFGOab9ylZhbKnTVts0AxQ+kyE4sK 0=; X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A0APAgCeCjxW/40NJK1EGoM7U28GvgMBDYFgJYVrAoE9OBQBAQEBAQEBgQqENQEBAQQ6PwwEAgEIDgMEAQEBHgkHMhQJCAIEDgUIiCYNO8BEAQEBAQEBAQEBAQEBAQEBAQEBAQEBGItSiTkFlkgBhRyHf4Fhh2SFPI1HAR8BAUKEBHIBAQEBhAmBBwEBAQ X-IronPort-AV: E=Sophos;i="5.20,250,1444694400"; d="scan'208";a="205436333" Received: from alln-core-8.cisco.com ([173.36.13.141]) by alln-iport-6.cisco.com with ESMTP; 06 Nov 2015 02:06:44 +0000 Received: from XCH-ALN-020.cisco.com (xch-aln-020.cisco.com [173.36.7.30]) by alln-core-8.cisco.com (8.14.5/8.14.5) with ESMTP id tA626hs4006852 (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=FAIL); Fri, 6 Nov 2015 02:06:43 GMT Received: from xch-aln-020.cisco.com (173.36.7.30) by XCH-ALN-020.cisco.com (173.36.7.30) with Microsoft SMTP Server (TLS) id 15.0.1104.5; Thu, 5 Nov 2015 20:06:42 -0600 Received: from xch-aln-020.cisco.com ([173.36.7.30]) by XCH-ALN-020.cisco.com ([173.36.7.30]) with mapi id 15.00.1104.000; Thu, 5 Nov 2015 20:06:42 -0600 From: "Al Lau (alau2)" To: Dave Chinner CC: "xfs@oss.sgi.com" Subject: RE: mkfs.xfs -n size=65536 Thread-Topic: mkfs.xfs -n size=65536 X-ASG-Orig-Subj: RE: mkfs.xfs -n size=65536 Thread-Index: AdEC1680Gy4Y381SQNu4wXlh8fvUqwCn49kAAAhmBND///HgAIAAThiA///B5ACAACU6gIAAHJQA/9sHP2A= Date: Fri, 6 Nov 2015 02:06:42 +0000 Message-ID: <0da393a1fb794f73ba7ad4a74e0b6fc9@XCH-ALN-020.cisco.com> References: <0F279340237AA148AD7E3C6A70561A5E01266BE7@xmb-rcd-x14.cisco.com> <20151013002308.GI27164@dastard> <8a1b26a3b869448e805485c529c447a4@XCH-ALN-020.cisco.com> <20151013033304.GL27164@dastard> <20151013043016.GE31326@dastard> <20151013082548.GH31326@dastard> In-Reply-To: <20151013082548.GH31326@dastard> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-exchange-transport-fromentityheader: Hosted x-originating-ip: [10.128.10.57] Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-Barracuda-Connect: alln-iport-6.cisco.com[173.37.142.93] X-Barracuda-Start-Time: 1446775604 X-Barracuda-Encrypted: IDEA-CBC-SHA X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.12 X-Barracuda-Spam-Status: No, SCORE=0.12 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_SA085, DKIM_SIGNED, DKIM_VERIFIED, THREAD_INDEX, THREAD_TOPIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24151 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.01 THREAD_INDEX thread-index: AcO7Y8iR61tzADqsRmmc5wNiFHEOig== 0.01 THREAD_TOPIC Thread-Topic: ...(Japanese Subject)... -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature 0.10 BSF_SC0_SA085 Custom Rule SA085 We run the systemtap script in the background. The kmem_alloc message appe= ared in the /var/log/messages. The call stack is captured by the systemtap= is follow. 0xffffffffa02a0030 : xfs_err+0x0/0x90 [xfs] 0xffffffffa02a853d : kmem_alloc+0xbd/0xf0 [xfs] 0xffffffffa02eeb6e : xfs_log_commit_cil+0x39e/0x4c0 [xfs] 0xffffffffa02a7d3c : xfs_trans_commit+0x11c/0x240 [xfs] 0xffffffffa02dd353 : xfs_remove+0x343/0x380 [xfs] 0xffffffffa029d93a : xfs_vn_unlink+0x5a/0xc0 [xfs] 0xffffffff811bde51 0xffffffff811be056 (inexact) 0xffffffff811b166e (inexact) 0xffffffff810823cc (inexact) 0xffffffff811c11b6 (inexact) 0xffffffff815f3219 (inexact) Nov 5 18:13:21 csx-ceph1-003 kernel: XFS: possible memory allocation deadl= ock in kmem_alloc (mode:0x8250) #! /usr/bin/env stap probe module("xfs").function("xfs_err").call { print_backtrace(); } # nohup stap -o /var/systemtap/kmem_alloc_bt.out backtrace.stp & Redhat support case is https://access.redhat.com/support/cases/#/case/01500= 239 Thanks, -Al -----Original Message----- From: Dave Chinner [mailto:david@fromorbit.com]=20 Sent: Tuesday, October 13, 2015 1:26 AM To: Al Lau (alau2) Cc: xfs@oss.sgi.com Subject: Re: mkfs.xfs -n size=3D65536 On Tue, Oct 13, 2015 at 07:28:48AM +0000, Al Lau (alau2) wrote: > Are the xfs_db and filefrag the utilities to use to determine file fragme= ntation? >=20 > # df -k /var/kmem_alloc > Filesystem 1K-blocks Used Available Use% Mounted on > /dev/sdf1 3905109820 3359385616 545724204 87% /var/kmem_alloc > # xfs_db -r -c frag /dev/sdf1 > actual 438970, ideal 388168, fragmentation factor 11.57% http://xfs.org/index.php/XFS_FAQ#Q:_The_xfs_db_.22frag.22_command_says_I.27= m_over_50.25._Is_that_bad.3F > # ls -l fragmented > -rw-r--r--. 1 root root 3360239878657 Oct 13 07:25 fragmented #=20 > filefrag fragmented > fragmented: 385533 extents found That's a lot of extents, but for a 3TB sparse file that is being written in= random 4k blocks, that's expected and there's little you can do about it. = Preallocation of the file or use of extent size hints will reduce physical = fragmentation, but you only want to use those if the file will eventually b= ecome non-sparse and sequential read IO performance is required... i.e. the definition of "fragmented" really depends on the application, IO p= atterns and whether the current physical layout is acheiving the desired pe= rformance attributes of the file in question.... Cheers, Dave. -- Dave Chinner david@fromorbit.com From rostnefttorg@yandex.ru Fri Nov 6 04:39:53 2015 Return-Path: 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 33C657F75 for ; Fri, 6 Nov 2015 04:39:53 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id BDD70304039 for ; Fri, 6 Nov 2015 02:39:48 -0800 (PST) X-ASG-Debug-ID: 1446806368-04bdf03f037b190001-NocioJ Received: from 150-222-216-178.omsk.mts.ru ([95.213.182.46]) by cuda.sgi.com with ESMTP id Vzms6eg7kXEq4ajh for ; Fri, 06 Nov 2015 02:39:29 -0800 (PST) X-Barracuda-Envelope-From: rostnefttorg@yandex.ru X-Barracuda-Apparent-Source-IP: 95.213.182.46 From: "=?utf-8?B?0J7Qu9C10LMg0JLQu9Cw0LTQuNC80LjRgNC+0LLQuNGH?=" Subject: =?utf-8?B?0J7QntCeINCg0J7QodCi0J3QldCk0KLQldCi0J7QoNCTINC/0YDQtdC00LvQvtC20LXQvdC40LUg0L/QviDQvdC10YTRgtC10L/RgNC+0LTRg9C60YLQsNC8?= To: "xfs" X-ASG-Orig-Subj: =?utf-8?B?0J7QntCeINCg0J7QodCi0J3QldCk0KLQldCi0J7QoNCTINC/0YDQtdC00LvQvtC20LXQvdC40LUg0L/QviDQvdC10YTRgtC10L/RgNC+0LTRg9C60YLQsNC8?= Content-Type: multipart/mixed; boundary="1XmTJMNGXzXxUECqr=_fLDDp5FC8IM6PQ5" MIME-Version: 1.0 Reply-To: "partner-neft@yandex.ru" Organization: =?utf-8?B?0J7QntCeINCg0L7RgdC90LXRhNGC0LXRgtC+0YDQsw==?= Date: Fri, 6 Nov 2015 13:39:28 +0300 Priority: urgent X-Priority: 1 Importance: high X-Confirm-Reading-To: partner-neft@yandex.ru Disposition-Notification-To: partner-neft@yandex.ru Return-Receipt-To: partner-neft@yandex.ru X-Antivirus: avast! (VPS 151105-0, 05.11.2015), Outbound message X-Antivirus-Status: Not-Tested X-Barracuda-Connect: UNKNOWN[95.213.182.46] X-Barracuda-Start-Time: 1446806368 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Barracuda-BRTS-Status: 1 X-Virus-Scanned: by bsmtpd at sgi.com 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 Message-Id: <20151106103948.3548CA420AB@cuda.sgi.com> This is a multi-part message in MIME format --1XmTJMNGXzXxUECqr=_fLDDp5FC8IM6PQ5 Content-Type: multipart/alternative; boundary="U3o6LGeIEfWQDmGgX=_lPjREOLeBag01w4" --U3o6LGeIEfWQDmGgX=_lPjREOLeBag01w4 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline =D0=97=D0=B4=D1=80=D0=B0=D0=B2=D1=81=D1=82=D0=B2=D1=83=D0=B9=D1=82=D0=B5= !=D0=9D=D0=B0=D1=88=D0=B0 =D0=BA=D0=BE=D0=BC=D0=BF=D0=B0=D0=BD=D0=B8=D1= =8F =D0=9E=D0=9E=D0=9E "=D0=A0=D0=9E=D0=A1=D0=A2=D0=9D=D0=95=D0=A4=D0=A2= =D0=95=D0=A2=D0=9E=D0=A0=D0=93" =D0=9F=D1=80=D0=B5=D0=B4=D0=BB=D0=B0=D0= =B3=D0=B0=D0=B5=D1=82 =D0=BA =D0=BF=D1=80=D0=BE=D0=B4=D0=B0=D0=B6=D0=B5= : =D0=B4=D0=B8=D0=B7=D0=B5=D0=BB=D1=8C=D0=BD=D0=BE=D0=B5 =D1=82=D0=BE=D0= =BF=D0=BB=D0=B8=D0=B2=D0=BE =D0=BB=D0=B5=D1=82=D0=BD=D0=B5=D0=B5,=D0=B7= =D0=B8=D0=BC=D0=BD=D0=B5=D0=B5, =D0=BC=D0=B0=D0=B7=D1=83=D1=82 =D0=9C1= 00, =D0=9C40,=D0=B3=D0=B0=D0=B7=D0=BE=D0=B2=D1=8B=D0=B9 =D0=BA=D0=BE=D0= =BD=D0=B4=D0=B5=D0=BD=D1=81=D0=B0=D1=82 =D1=81=D0=B2=D0=B5=D1=82=D0=BB= =D1=8B=D0=B9 =D0=B8 =D1=82=D1=91=D0=BC=D0=BD=D1=8B=D0=B9, =D0=BD=D0=B5= =D1=84=D1=82=D1=8C, =D0=B1=D0=B5=D0=BD=D0=B7=D0=B8=D0=BD, =D0=B1=D0=B8= =D1=82=D1=83=D0=BC 60/90, =D0=B1=D0=B8=D1=82=D1=83=D0=BC 90/130, =D1=82= =D0=BE=D0=BF=D0=BB=D0=B8=D0=B2=D0=BE =D0=BF=D0=B5=D1=87=D0=BD=D0=BE=D0= =B5 =D1=81=D0=B2=D0=B5=D1=82=D0=BB=D0=BE=D0=B5 =D0=B8 =D1=82=D1=91=D0=BC= =D0=BD=D0=BE=D0=B5, =D0=B4=D0=B8=D1=81=D1=82=D0=B8=D0=BB=D1=8F=D1=82 =D0= =B3=D0=B0=D0=B7=D0=BE=D0=B2=D0=BE=D0=B3=D0=BE =D0=BA=D0=BE=D0=BD=D0=B4= =D0=B5=D0=BD=D1=81=D0=B0=D1=82=D0=B0,=D0=A1=D0=9F=D0=91=D0=A2, =D0=BD=D0= =B5=D1=84=D1=80=D0=B0=D1=81, =D0=B1=D0=B5=D0=BD=D0=B7=D0=B8=D0=BD =D0=BF= =D1=80=D1=8F=D0=BC=D0=BE=D0=B3=D0=BE=D0=BD=D0=BD=D1=8B=D0=B9,=D1=84=D1= =80=D0=B0=D0=BA=D1=86=D0=B8=D1=8F =D1=83=D0=B3=D0=BB=D0=B5=D0=B2=D0=BE= =D0=B4=D0=BE=D1=80=D0=BE=D0=B4=D0=BD=D0=B0=D1=8F =D0=B4=D0=B8=D1=81=D1= =82=D0=B8=D0=BB=D1=8F=D1=82=D0=BD=D0=B0=D1=8F =D0=B3=D0=B0=D0=B7=D0=BE= =D0=B9=D0=BB=D0=B5=D0=B2=D0=B0=D1=8F, =D1=81=D1=83=D0=B4=D0=BE=D0=B2=D0= =BE=D0=B5 =D0=BC=D0=B0=D0=BB=D0=BE=D0=B2=D1=8F=D0=B7=D0=BA=D0=BE=D0=B5= =D1=82=D0=BE=D0=BF=D0=BB=D0=B8=D0=B2=D0=BE,=D0=A4-5,=D0=B0=D0=B2=D0=B8= =D0=B0=D0=BA=D0=B5=D1=80=D0=BE=D1=81=D0=B8=D0=BD,=D0=B3=D0=B0=D0=B7=D0= =BE=D0=B9=D0=BB=D1=8C,=D0=91=D0=93=D0=A1, =D1=80=D0=B0=D0=B1=D0=BE=D1=82= =D0=B0=D0=B5=D0=BC =D0=BF=D0=BE =D0=A0=D0=BE=D1=81=D1=81=D0=B8=D0=B8 =D0= =B8 =D1=8D=D0=BA=D1=81=D0=BF=D0=BE=D1=80=D1=82.=D0=A2=D0=B0=D0=BA=D0=B6= =D0=B5 =D0=BD=D0=B0=D1=88=D0=B0 =D0=BA=D0=BE=D0=BC=D0=BF=D0=B0=D0=BD=D0= =B8=D1=8F =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=B0=D0=B5=D1=82 =D0=BD=D0=B5= =D1=84=D1=82=D0=B5=D0=BF=D1=80=D0=BE=D0=B4=D1=83=D0=BA=D1=82=D1=8B =D0= =BF=D0=BE =D0=A0=D0=BE=D1=81=D1=81=D0=B8=D0=B8 =D0=B8 =D0=AD=D0=BA=D1=81= =D0=BF=D0=BE=D1=80=D1=82.=D0=9F=D1=80=D0=BE=D1=81=D0=B8=D0=BC =D0=BE=D1= =82=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D1=8F=D1=82=D1=8C =D1=81=D0=B2=D0=BE= =D0=B8 =D0=BF=D1=80=D0=B5=D0=B4=D0=BB=D0=BE=D0=B6=D0=B5=D0=BD=D0=B8=D1= =8F. =D0=A2=D0=B5=D0=BB:+7-923-679-84-94 =D0=A1=D0=B0=D0=B9=D1=82:htt= p://rostnefttorg.wix.com/strategic-consulting --U3o6LGeIEfWQDmGgX=_lPjREOLeBag01w4 Content-Type: text/html; charset="utf-8" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline

=D0=97=D0=B4=D1=80=D0=B0=D0=B2=D1=81=D1= =82=D0=B2=D1=83=D0=B9=D1=82=D0=B5!=D0=9D=D0=B0=D1=88=D0=B0 =D0=BA=D0=BE= =D0=BC=D0=BF=D0=B0=D0=BD=D0=B8=D1=8F =D0=9E=D0=9E=D0=9E "=D0=A0=D0=9E=D0= =A1=D0=A2=D0=9D=D0=95=D0=A4=D0=A2=D0=95=D0=A2=D0=9E=D0=A0=D0=93" =D0=9F= =D0=BA=D0=BE=D0=BD=D0=B4=D0=B5=D0= =BD=D1=81=D0=B0=D1=82 =D1=81=D0=B2=D0=B5=D1=82=D0=BB=D1=8B=D0=B9 =D0=B8= =D1=82=D1=91=D0=BC=D0=BD=D1=8B=D0=B9, =D0=BD=D0=B5=D1=84=D1=82=D1=8C,= =D0=B1=D0=B5=D0=BD=D0=B7=D0=B8=D0=BD, =D0=B1=D0=B8=D1=82=D1=83=D0=BC = 60/90, =D0=B1=D0=B8=D1=82=D1=83=D0=BC 90/130, =D1=82=D0=BE=D0=BF=D0=BB= =D0=B8=D0=B2=D0=BE =D0=BF=D0=B5=D1=87=D0=BD=D0=BE=D0=B5 =D1=81=D0=B2=D0=B5=D1=82=D0=BB= =D0=BE=D0=B5 =D0=B8 =D1=82=D1=91=D0=BC=D0=BD=D0=BE=D0=B5, =D0=B4=D0=B8= =D1=81=D1=82=D0=B8=D0=BB=D1=8F=D1=82 =D0=B3=D0=B0=D0=B7=D0=BE=D0=B2=D0= =BE=D0=B3=D0=BE =D0=BA=D0=BE=D0=BD=D0=B4=D0=B5=D0=BD=D1=81=D0=B0=D1=82= =D0=B0,=D0=A1=D0=9F=D0=91=D0=A2, =D0=BD=D0=B5=D1=84=D1=80=D0=B0=D1=81,= =D0=B1=D0=B5=D0=BD=D0=B7=D0=B8=D0=BD = =D0=BF=D1=80=D1=8F=D0=BC=D0=BE=D0=B3=D0=BE=D0=BD= =D0=BD=D1=8B=D0=B9,=D1=84=D1=80=D0=B0=D0=BA=D1=86=D0=B8=D1=8F =D1=83=D0= =B3=D0=BB=D0=B5=D0=B2=D0=BE=D0=B4=D0=BE=D1=80=D0=BE=D0=B4=D0=BD=D0=B0=D1= =8F =D0=B4=D0=B8=D1=81=D1=82=D0=B8=D0=BB=D1=8F=D1=82=D0=BD=D0=B0=D1=8F= =D0=B3=D0=B0=D0=B7=D0=BE=D0=B9=D0=BB=D0=B5=D0=B2=D0=B0=D1=8F, =D1=81=D1= =83=D0=B4=D0=BE=D0=B2=D0=BE=D0=B5 =D0=BC=D0=B0=D0=BB=D0=BE=D0=B2=D1=8F= =D0=B7=D0=BA=D0=BE=D0=B5 = =D1=82=D0=BE=D0=BF=D0=BB=D0=B8=D0=B2=D0=BE,=D0=A4-5,=D0=B0=D0=B2= =D0=B8=D0=B0=D0=BA=D0=B5=D1=80=D0=BE=D1=81=D0=B8=D0=BD,=D0=B3=D0=B0=D0= =B7=D0=BE=D0=B9=D0=BB=D1=8C,=D0=91=D0=93=D0=A1, =D1=80=D0=B0=D0=B1=D0=BE= =D1=82=D0=B0=D0=B5=D0=BC =D0=BF=D0=BE =D0=A0=D0=BE=D1=81=D1=81=D0=B8=D0= =B8 =D0=B8 =D1=8D=D0=BA=D1=81=D0=BF=D0=BE=D1=80=D1=82.=D0=A2=D0=B0=D0=BA= =D0=B6=D0=B5 =D0=BD=D0=B0=D1=88=D0=B0 =D0=BA=D0=BE=D0=BC=D0=BF=D0=B0=D0= =BD=D0=B8=D1=8F =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=B0=D0=B5=D1=82 =D0=BD= =D0=B5=D1=84=D1=82=D0=B5=D0=BF=D1=80=D0=BE=D0=B4=D1=83=D0=BA=D1=82=D1=8B= =D0=BF=D0=BE =D0=A0=D0=BE=D1=81=D1=81=D0=B8=D0=B8 =D0=B8 =D0=AD=D0=BA= =D1=81=D0=BF=D0=BE=D1=80=D1=82.=D0=9F=D1=80=D0=BE=D1=81=D0=B8=D0=BC =D0= =BE=D1=82=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D1=8F=D1=82=D1=8C =D1=81=D0=B2= =D0=BE=D0=B8 =D0=BF=D1=80=D0=B5=D0=B4=D0=BB=D0=BE=D0=B6=D0=B5=D0=BD=D0= =B8=D1=8F.  =D0=A2=D0=B5=D0=BB:+7-923-679-84-94 =D0=A1=D0=B0=D0=B9=D1=82:http://rostnefttorg.wix.com/strategic-consulting

--U3o6LGeIEfWQDmGgX=_lPjREOLeBag01w4-- --1XmTJMNGXzXxUECqr=_fLDDp5FC8IM6PQ5 Content-Type: application/octet-stream; name="=?utf-8?B?0J/RgNC10LTQu9C+0LbQtdC90LjQtSDQntCe0J4g0KDQntCh0KLQndCV0KTQotCV0KLQntCg0JMgMzAuMDkucGRm?=" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="=?utf-8?B?0J/RgNC10LTQu9C+0LbQtdC90LjQtSDQntCe0J4g0KDQntCh0KLQndCV0KTQotCV0KLQntCg0JMgMzAuMDkucGRm?=" JVBERi0xLjUNCiW1tbW1DQoxIDAgb2JqDQo8PC9UeXBlL0NhdGFsb2cvUGFnZXMgMiAwIFIvTGFu ZyhydS1SVSkgL1N0cnVjdFRyZWVSb290IDEwOCAwIFIvTWFya0luZm88PC9NYXJrZWQgdHJ1ZT4+ Pj4NCmVuZG9iag0KMiAwIG9iag0KPDwvVHlwZS9QYWdlcy9Db3VudCA4L0tpZHNbIDMgMCBSIDU0 IDAgUiA5MCAwIFIgOTcgMCBSIDk5IDAgUiAxMDEgMCBSIDEwMyAwIFIgMTA1IDAgUl0gPj4NCmVu ZG9iag0KMyAwIG9iag0KPDwvVHlwZS9QYWdlL1BhcmVudCAyIDAgUi9SZXNvdXJjZXM8PC9Gb250 PDwvRjEgNSAwIFIvRjIgOCAwIFIvRjMgMTMgMCBSL0Y0IDE1IDAgUi9GNSAxNyAwIFIvRjYgMjIg MCBSL0Y3IDI0IDAgUi9GOCAyNiAwIFIvRjkgMzEgMCBSL0YxMCAzMyAwIFIvRjExIDM4IDAgUi9G MTIgNDAgMCBSL0YxMyA0MiAwIFIvRjE0IDQ3IDAgUi9GMTUgNDkgMCBSPj4vWE9iamVjdDw8L0lt YWdlNyA3IDAgUj4+L1Byb2NTZXRbL1BERi9UZXh0L0ltYWdlQi9JbWFnZUMvSW1hZ2VJXSA+Pi9N ZWRpYUJveFsgMCAwIDU5NS4zMiA4NDEuOTJdIC9Db250ZW50cyA0IDAgUi9Hcm91cDw8L1R5cGUv R3JvdXAvUy9UcmFuc3BhcmVuY3kvQ1MvRGV2aWNlUkdCPj4vVGFicy9TL1N0cnVjdFBhcmVudHMg MD4+DQplbmRvYmoNCjQgMCBvYmoNCjw8L0ZpbHRlci9GbGF0ZURlY29kZS9MZW5ndGggNTk3Nj4+ DQpzdHJlYW0NCnic5V1bjxy3lX4XoP/QjyNspsQ7WcFgsH2ZDrJAsN6F3pw8CI7tGFhbXq8W3vz7 nAtZvBSrmhpJjpO10ZrpbvKQPJfvXEjWvD7+9P67b95+9f7w8PD6+P7926/+8vWfD1++fvPuxz+9 fvPXH79+/cXbb7/74e3779798Ph4OF3Oh9Obly9eX+VBykmYw5tvXr6QBwH/y0Owk4SPvHSTPbz5 /uULcfgW//ndyxdf3h1e/enw5t9evniC7kgidVLaTEYWnaDp4dW9Sf++mvG33Pe/X76Y50lZ6j6L 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 Ev7dM18t5e6Pr7aCIP6zf1Xj/ZMovavoSaxGDz5v39ZP1tnFEy2WvxmBnEPFE6tynqzSuHyvchBC Iu48LUJzA9gRgcN/HHCkU6pe8aKWOVag4T8OMzQ+mcFXvBwFDQ1po51bMaxRo9wBQdzgC4+nEvpl wkh7TsUXMomq+uqKWk0hsXidmva7roS2t1FGejzlt7gi83hPyBwvpNL16+sCY6vKZj7kRM+hbagB ojA+MbXuo2C2KuRgIyW1G6bSexhBWiGeExijYoYNDv8GHv5Zr8S202JBJLZrzPw+uf3xR//07huf MqLnisvj/lviH5lrBDTiwOPCm9XQW0O6nDc8oiMfVGcrPD5Es1rNviL2nmuT/jruPM3bVP4GwTo5 7A0KZW5kc3RyZWFtDQplbmRvYmoNCjUgMCBvYmoNCjw8L1R5cGUvRm9udC9TdWJ0eXBlL1RydWVU eXBlL05hbWUvRjEvQmFzZUZvbnQvQUJDREVFK0NhbGlicmkvRW5jb2RpbmcvV2luQW5zaUVuY29k aW5nL0ZvbnREZXNjcmlwdG9yIDYgMCBSL0ZpcnN0Q2hhciAzMi9MYXN0Q2hhciAxMTUvV2lkdGhz IDI0MiAwIFI+Pg0KZW5kb2JqDQo2IDAgb2JqDQo8PC9UeXBlL0ZvbnREZXNjcmlwdG9yL0ZvbnRO YW1lL0FCQ0RFRStDYWxpYnJpL0ZsYWdzIDMyL0l0YWxpY0FuZ2xlIDAvQXNjZW50IDc1MC9EZXNj ZW50IC0yNTAvQ2FwSGVpZ2h0IDc1MC9BdmdXaWR0aCA1MjEvTWF4V2lkdGggMTc0My9Gb250V2Vp Z2h0IDQwMC9YSGVpZ2h0IDI1MC9TdGVtViA1Mi9Gb250QkJveFsgLTUwMyAtMjUwIDEyNDAgNzUw XSAvRm9udEZpbGUyIDI0MyAwIFI+Pg0KZW5kb2JqDQo3IDAgb2JqDQo8PC9UeXBlL1hPYmplY3Qv U3VidHlwZS9JbWFnZS9XaWR0aCAyNzUvSGVpZ2h0IDI0OS9Db2xvclNwYWNlL0RldmljZVJHQi9C aXRzUGVyQ29tcG9uZW50IDgvRmlsdGVyL0RDVERlY29kZS9JbnRlcnBvbGF0ZSB0cnVlL0xlbmd0 aCAxMDUyND4+DQpzdHJlYW0NCv/Y/+AAEEpGSUYAAQEBAGAAYAAA/9sAQwAIBgYHBgUIBwcHCQkI CgwUDQwLCwwZEhMPFB0aHx4dGhwcICQuJyAiLCMcHCg3KSwwMTQ0NB8nOT04MjwuMzQy/9sAQwEJ CQkMCwwYDQ0YMiEcITIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy MjIyMjIy/8AAEQgA+QETAwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkK C//EALUQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNi coIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SF hoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn 6Onq8fLz9PX29/j5+v/EAB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQE AwQHBQQEAAECdwABAgMRBAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBka JicoKSo1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWW l5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5 +v/aAAwDAQACEQMRAD8A9/ooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAK KKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiikJAoA WmlsdKjiuoJ3dYpkdl+8FYHH1rH8XyX0XhbUJNNLreLGDGU+8ORnH4ZqoxcpKPcTelzZ8wRgCSRc n14pIbmGfd5UqSbThtrA4NeCWf8AwkXjDUPKhvrmWSOIuyPIF7Y9vWvRfAHhjVPD73T3zRxxTKoE KvuOR3J+nFduIwUaMW5TXN2M41OZ7Hd/jTHmjjUs0ihR1JPSuJ+IuvXOk2lpb2sjRNcswMinBwB0 H5/pXE/8Iz4lufDp1JLsva+U0wVrgljU0cEpwVScrJhKpZ2SPXbDX9K1OZ4bLULeeSMAsqOCRmtI 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 lWLq4CceXlaK5aie50dp4s0C+uPIt9Utnl4+Xfgn86e0uh3BkJexcliHJKnJxzn8K4qT4QWTPuj1 S5GGJQFRwPTisOf4SatFvEN3bSqSdvzFT/nFZRo4Zv3alvkDlPqiLx7olha6zDFpT77i4Uym3Tna O2AO3euUtdY1fS2MVrc3Nqc4ZQSvP0ruLCwufBN6up67pk99Ko2x3Mb7liXpiuW8TeIZvEesG6ht AowBGqpllHua9fDTcrU370V1ZjJdVoN/tjXtbmtbW4vJrpxIGSPAznPavoeEkwpkEHaMg9q8V8Ba BqreIrO9ktHjtomLtLIuBjbkYz65r2xCCMjpXmZpOHOoU9l2NaKdrsdRRRXlm4UUUUAFFFFABSEZ paKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigApMUtFACUUtFADWRXUq ygg9QRUa2luhykESn2QCpqBRdhYQKAMAACloooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKA CiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigD//2Q0K ZW5kc3RyZWFtDQplbmRvYmoNCjggMCBvYmoNCjw8L1R5cGUvRm9udC9TdWJ0eXBlL1R5cGUwL0Jh c2VGb250L0FCQ0RFRStDYWxpYnJpLEJvbGQvRW5jb2RpbmcvSWRlbnRpdHktSC9EZXNjZW5kYW50 Rm9udHMgOSAwIFIvVG9Vbmljb2RlIDI0NCAwIFI+Pg0KZW5kb2JqDQo5IDAgb2JqDQpbIDEwIDAg Ul0gDQplbmRvYmoNCjEwIDAgb2JqDQo8PC9CYXNlRm9udC9BQkNERUUrQ2FsaWJyaSxCb2xkL1N1 YnR5cGUvQ0lERm9udFR5cGUyL1R5cGUvRm9udC9DSURUb0dJRE1hcC9JZGVudGl0eS9EVyAxMDAw L0NJRFN5c3RlbUluZm8gMTEgMCBSL0ZvbnREZXNjcmlwdG9yIDEyIDAgUi9XIDI0NiAwIFI+Pg0K ZW5kb2JqDQoxMSAwIG9iag0KPDwvT3JkZXJpbmcoSWRlbnRpdHkpIC9SZWdpc3RyeShBZG9iZSkg L1N1cHBsZW1lbnQgMD4+DQplbmRvYmoNCjEyIDAgb2JqDQo8PC9UeXBlL0ZvbnREZXNjcmlwdG9y L0ZvbnROYW1lL0FCQ0RFRStDYWxpYnJpLEJvbGQvRmxhZ3MgMzIvSXRhbGljQW5nbGUgMC9Bc2Nl bnQgNzUwL0Rlc2NlbnQgLTI1MC9DYXBIZWlnaHQgNzUwL0F2Z1dpZHRoIDUzNi9NYXhXaWR0aCAx NzU5L0ZvbnRXZWlnaHQgNzAwL1hIZWlnaHQgMjUwL1N0ZW1WIDUzL0ZvbnRCQm94WyAtNTE5IC0y NTAgMTI0MCA3NTBdIC9Gb250RmlsZTIgMjQ1IDAgUj4+DQplbmRvYmoNCjEzIDAgb2JqDQo8PC9U eXBlL0ZvbnQvU3VidHlwZS9UcnVlVHlwZS9OYW1lL0YzL0Jhc2VGb250L0FCQ0RFRStDYWxpYnJp LEJvbGQvRW5jb2RpbmcvV2luQW5zaUVuY29kaW5nL0ZvbnREZXNjcmlwdG9yIDE0IDAgUi9GaXJz dENoYXIgMzIvTGFzdENoYXIgMTE4L1dpZHRocyAyNDcgMCBSPj4NCmVuZG9iag0KMTQgMCBvYmoN Cjw8L1R5cGUvRm9udERlc2NyaXB0b3IvRm9udE5hbWUvQUJDREVFK0NhbGlicmksQm9sZC9GbGFn cyAzMi9JdGFsaWNBbmdsZSAwL0FzY2VudCA3NTAvRGVzY2VudCAtMjUwL0NhcEhlaWdodCA3NTAv QXZnV2lkdGggNTM2L01heFdpZHRoIDE3NTkvRm9udFdlaWdodCA3MDAvWEhlaWdodCAyNTAvU3Rl bVYgNTMvRm9udEJCb3hbIC01MTkgLTI1MCAxMjQwIDc1MF0gL0ZvbnRGaWxlMiAyNDggMCBSPj4N CmVuZG9iag0KMTUgMCBvYmoNCjw8L1R5cGUvRm9udC9TdWJ0eXBlL1RydWVUeXBlL05hbWUvRjQv QmFzZUZvbnQvVGltZXMjMjBOZXcjMjBSb21hbixCb2xkL0VuY29kaW5nL1dpbkFuc2lFbmNvZGlu Zy9Gb250RGVzY3JpcHRvciAxNiAwIFIvRmlyc3RDaGFyIDMyL0xhc3RDaGFyIDU3L1dpZHRocyAy NDkgMCBSPj4NCmVuZG9iag0KMTYgMCBvYmoNCjw8L1R5cGUvRm9udERlc2NyaXB0b3IvRm9udE5h bWUvVGltZXMjMjBOZXcjMjBSb21hbixCb2xkL0ZsYWdzIDMyL0l0YWxpY0FuZ2xlIDAvQXNjZW50 IDg5MS9EZXNjZW50IC0yMTYvQ2FwSGVpZ2h0IDY3Ny9BdmdXaWR0aCA0MjcvTWF4V2lkdGggMjU1 OC9Gb250V2VpZ2h0IDcwMC9YSGVpZ2h0IDI1MC9MZWFkaW5nIDQyL1N0ZW1WIDQyL0ZvbnRCQm94 WyAtNTU4IC0yMTYgMjAwMCA2NzddID4+DQplbmRvYmoNCjE3IDAgb2JqDQo8PC9UeXBlL0ZvbnQv U3VidHlwZS9UeXBlMC9CYXNlRm9udC9BQkNERUUrQm9vayMyMEFudGlxdWEsQm9sZC9FbmNvZGlu Zy9JZGVudGl0eS1IL0Rlc2NlbmRhbnRGb250cyAxOCAwIFIvVG9Vbmljb2RlIDI1MCAwIFI+Pg0K ZW5kb2JqDQoxOCAwIG9iag0KWyAxOSAwIFJdIA0KZW5kb2JqDQoxOSAwIG9iag0KPDwvQmFzZUZv bnQvQUJDREVFK0Jvb2sjMjBBbnRpcXVhLEJvbGQvU3VidHlwZS9DSURGb250VHlwZTIvVHlwZS9G b250L0NJRFRvR0lETWFwL0lkZW50aXR5L0RXIDEwMDAvQ0lEU3lzdGVtSW5mbyAyMCAwIFIvRm9u dERlc2NyaXB0b3IgMjEgMCBSL1cgMjUyIDAgUj4+DQplbmRvYmoNCjIwIDAgb2JqDQo8PC9PcmRl cmluZyhJZGVudGl0eSkgL1JlZ2lzdHJ5KEFkb2JlKSAvU3VwcGxlbWVudCAwPj4NCmVuZG9iag0K MjEgMCBvYmoNCjw8L1R5cGUvRm9udERlc2NyaXB0b3IvRm9udE5hbWUvQUJDREVFK0Jvb2sjMjBB bnRpcXVhLEJvbGQvRmxhZ3MgMzIvSXRhbGljQW5nbGUgMC9Bc2NlbnQgOTIzL0Rlc2NlbnQgLTI2 NS9DYXBIZWlnaHQgNzI2L0F2Z1dpZHRoIDQ1OS9NYXhXaWR0aCAxMzI3L0ZvbnRXZWlnaHQgNzAw L1hIZWlnaHQgMjUwL0xlYWRpbmcgMTcvU3RlbVYgNDUvRm9udEJCb3hbIC0xMzQgLTI2NSAxMTkz IDcyNl0gL0ZvbnRGaWxlMiAyNTEgMCBSPj4NCmVuZG9iag0KMjIgMCBvYmoNCjw8L1R5cGUvRm9u dC9TdWJ0eXBlL1RydWVUeXBlL05hbWUvRjYvQmFzZUZvbnQvQUJDREVFK0Jvb2sjMjBBbnRpcXVh LEJvbGQvRW5jb2RpbmcvV2luQW5zaUVuY29kaW5nL0ZvbnREZXNjcmlwdG9yIDIzIDAgUi9GaXJz dENoYXIgMzIvTGFzdENoYXIgMTIxL1dpZHRocyAyNTMgMCBSPj4NCmVuZG9iag0KMjMgMCBvYmoN Cjw8L1R5cGUvRm9udERlc2NyaXB0b3IvRm9udE5hbWUvQUJDREVFK0Jvb2sjMjBBbnRpcXVhLEJv bGQvRmxhZ3MgMzIvSXRhbGljQW5nbGUgMC9Bc2NlbnQgOTIzL0Rlc2NlbnQgLTI2NS9DYXBIZWln aHQgNzI2L0F2Z1dpZHRoIDQ1OS9NYXhXaWR0aCAxMzI3L0ZvbnRXZWlnaHQgNzAwL1hIZWlnaHQg MjUwL0xlYWRpbmcgMTcvU3RlbVYgNDUvRm9udEJCb3hbIC0xMzQgLTI2NSAxMTkzIDcyNl0gL0Zv bnRGaWxlMiAyNTQgMCBSPj4NCmVuZG9iag0KMjQgMCBvYmoNCjw8L1R5cGUvRm9udC9TdWJ0eXBl L1RydWVUeXBlL05hbWUvRjcvQmFzZUZvbnQvQUJDREVFK0Jvb2sjMjBBbnRpcXVhL0VuY29kaW5n L1dpbkFuc2lFbmNvZGluZy9Gb250RGVzY3JpcHRvciAyNSAwIFIvRmlyc3RDaGFyIDQ2L0xhc3RD aGFyIDQ2L1dpZHRocyAyNTUgMCBSPj4NCmVuZG9iag0KMjUgMCBvYmoNCjw8L1R5cGUvRm9udERl c2NyaXB0b3IvRm9udE5hbWUvQUJDREVFK0Jvb2sjMjBBbnRpcXVhL0ZsYWdzIDMyL0l0YWxpY0Fu Z2xlIDAvQXNjZW50IDkyMy9EZXNjZW50IC0yODIvQ2FwSGVpZ2h0IDcyNy9BdmdXaWR0aCA0NDUv TWF4V2lkdGggMTI5MC9Gb250V2VpZ2h0IDQwMC9YSGVpZ2h0IDI1MC9TdGVtViA0NC9Gb250QkJv eFsgLTEzNiAtMjgyIDExNTQgNzI3XSAvRm9udEZpbGUyIDI1NiAwIFI+Pg0KZW5kb2JqDQoyNiAw IG9iag0KPDwvVHlwZS9Gb250L1N1YnR5cGUvVHlwZTAvQmFzZUZvbnQvQUJDREVFK0NhbWJyaWEs Qm9sZEl0YWxpYy9FbmNvZGluZy9JZGVudGl0eS1IL0Rlc2NlbmRhbnRGb250cyAyNyAwIFIvVG9V bmljb2RlIDI1NyAwIFI+Pg0KZW5kb2JqDQoyNyAwIG9iag0KWyAyOCAwIFJdIA0KZW5kb2JqDQoy OCAwIG9iag0KPDwvQmFzZUZvbnQvQUJDREVFK0NhbWJyaWEsQm9sZEl0YWxpYy9TdWJ0eXBlL0NJ REZvbnRUeXBlMi9UeXBlL0ZvbnQvQ0lEVG9HSURNYXAvSWRlbnRpdHkvRFcgMTAwMC9DSURTeXN0 ZW1JbmZvIDI5IDAgUi9Gb250RGVzY3JpcHRvciAzMCAwIFIvVyAyNTkgMCBSPj4NCmVuZG9iag0K MjkgMCBvYmoNCjw8L09yZGVyaW5nKElkZW50aXR5KSAvUmVnaXN0cnkoQWRvYmUpIC9TdXBwbGVt ZW50IDA+Pg0KZW5kb2JqDQozMCAwIG9iag0KPDwvVHlwZS9Gb250RGVzY3JpcHRvci9Gb250TmFt ZS9BQkNERUUrQ2FtYnJpYSxCb2xkSXRhbGljL0ZsYWdzIDMyL0l0YWxpY0FuZ2xlIC0xMi40L0Fz Y2VudCA5NTAvRGVzY2VudCAtMjIyL0NhcEhlaWdodCA3NzgvQXZnV2lkdGggNTg1L01heFdpZHRo IDI0ODgvRm9udFdlaWdodCA3MDAvWEhlaWdodCAyNTAvU3RlbVYgNTgvRm9udEJCb3hbIC0xMTEw IC0yMjIgMTM3OCA3NzhdIC9Gb250RmlsZTIgMjU4IDAgUj4+DQplbmRvYmoNCjMxIDAgb2JqDQo8 PC9UeXBlL0ZvbnQvU3VidHlwZS9UcnVlVHlwZS9OYW1lL0Y5L0Jhc2VGb250L0FCQ0RFRStDYW1i cmlhLEJvbGRJdGFsaWMvRW5jb2RpbmcvV2luQW5zaUVuY29kaW5nL0ZvbnREZXNjcmlwdG9yIDMy IDAgUi9GaXJzdENoYXIgMzIvTGFzdENoYXIgMzIvV2lkdGhzIDI2MCAwIFI+Pg0KZW5kb2JqDQoz MiAwIG9iag0KPDwvVHlwZS9Gb250RGVzY3JpcHRvci9Gb250TmFtZS9BQkNERUUrQ2FtYnJpYSxC b2xkSXRhbGljL0ZsYWdzIDMyL0l0YWxpY0FuZ2xlIC0xMi40L0FzY2VudCA5NTAvRGVzY2VudCAt MjIyL0NhcEhlaWdodCA3NzgvQXZnV2lkdGggNTg1L01heFdpZHRoIDI0ODgvRm9udFdlaWdodCA3 MDAvWEhlaWdodCAyNTAvU3RlbVYgNTgvRm9udEJCb3hbIC0xMTEwIC0yMjIgMTM3OCA3NzhdIC9G b250RmlsZTIgMjYxIDAgUj4+DQplbmRvYmoNCjMzIDAgb2JqDQo8PC9UeXBlL0ZvbnQvU3VidHlw ZS9UeXBlMC9CYXNlRm9udC9BQkNERUUrQm9vayMyMEFudGlxdWEsQm9sZEl0YWxpYy9FbmNvZGlu Zy9JZGVudGl0eS1IL0Rlc2NlbmRhbnRGb250cyAzNCAwIFIvVG9Vbmljb2RlIDI2MiAwIFI+Pg0K ZW5kb2JqDQozNCAwIG9iag0KWyAzNSAwIFJdIA0KZW5kb2JqDQozNSAwIG9iag0KPDwvQmFzZUZv bnQvQUJDREVFK0Jvb2sjMjBBbnRpcXVhLEJvbGRJdGFsaWMvU3VidHlwZS9DSURGb250VHlwZTIv VHlwZS9Gb250L0NJRFRvR0lETWFwL0lkZW50aXR5L0RXIDEwMDAvQ0lEU3lzdGVtSW5mbyAzNiAw IFIvRm9udERlc2NyaXB0b3IgMzcgMCBSL1cgMjY0IDAgUj4+DQplbmRvYmoNCjM2IDAgb2JqDQo8 PC9PcmRlcmluZyhJZGVudGl0eSkgL1JlZ2lzdHJ5KEFkb2JlKSAvU3VwcGxlbWVudCAwPj4NCmVu ZG9iag0KMzcgMCBvYmoNCjw8L1R5cGUvRm9udERlc2NyaXB0b3IvRm9udE5hbWUvQUJDREVFK0Jv b2sjMjBBbnRpcXVhLEJvbGRJdGFsaWMvRmxhZ3MgMzIvSXRhbGljQW5nbGUgLTkuNS9Bc2NlbnQg OTIzL0Rlc2NlbnQgLTI3NS9DYXBIZWlnaHQgNzMwL0F2Z1dpZHRoIDQ0Ny9NYXhXaWR0aCAxMzcw L0ZvbnRXZWlnaHQgNzAwL1hIZWlnaHQgMjUwL0xlYWRpbmcgMy9TdGVtViA0NC9Gb250QkJveFsg LTE3OCAtMjc1IDExOTIgNzMwXSAvRm9udEZpbGUyIDI2MyAwIFI+Pg0KZW5kb2JqDQozOCAwIG9i ag0KPDwvVHlwZS9Gb250L1N1YnR5cGUvVHJ1ZVR5cGUvTmFtZS9GMTEvQmFzZUZvbnQvQUJDREVF K0Jvb2sjMjBBbnRpcXVhLEJvbGRJdGFsaWMvRW5jb2RpbmcvV2luQW5zaUVuY29kaW5nL0ZvbnRE ZXNjcmlwdG9yIDM5IDAgUi9GaXJzdENoYXIgMzIvTGFzdENoYXIgODAvV2lkdGhzIDI2NSAwIFI+ Pg0KZW5kb2JqDQozOSAwIG9iag0KPDwvVHlwZS9Gb250RGVzY3JpcHRvci9Gb250TmFtZS9BQkNE RUUrQm9vayMyMEFudGlxdWEsQm9sZEl0YWxpYy9GbGFncyAzMi9JdGFsaWNBbmdsZSAtOS41L0Fz Y2VudCA5MjMvRGVzY2VudCAtMjc1L0NhcEhlaWdodCA3MzAvQXZnV2lkdGggNDQ3L01heFdpZHRo IDEzNzAvRm9udFdlaWdodCA3MDAvWEhlaWdodCAyNTAvTGVhZGluZyAzL1N0ZW1WIDQ0L0ZvbnRC Qm94WyAtMTc4IC0yNzUgMTE5MiA3MzBdIC9Gb250RmlsZTIgMjY2IDAgUj4+DQplbmRvYmoNCjQw IDAgb2JqDQo8PC9UeXBlL0ZvbnQvU3VidHlwZS9UcnVlVHlwZS9OYW1lL0YxMi9CYXNlRm9udC9B cmlhbCxCb2xkL0VuY29kaW5nL1dpbkFuc2lFbmNvZGluZy9Gb250RGVzY3JpcHRvciA0MSAwIFIv Rmlyc3RDaGFyIDMyL0xhc3RDaGFyIDEyMS9XaWR0aHMgMjY3IDAgUj4+DQplbmRvYmoNCjQxIDAg b2JqDQo8PC9UeXBlL0ZvbnREZXNjcmlwdG9yL0ZvbnROYW1lL0FyaWFsLEJvbGQvRmxhZ3MgMzIv SXRhbGljQW5nbGUgMC9Bc2NlbnQgOTA1L0Rlc2NlbnQgLTIxMC9DYXBIZWlnaHQgNzI4L0F2Z1dp ZHRoIDQ3OS9NYXhXaWR0aCAyNjI4L0ZvbnRXZWlnaHQgNzAwL1hIZWlnaHQgMjUwL0xlYWRpbmcg MzMvU3RlbVYgNDcvRm9udEJCb3hbIC02MjggLTIxMCAyMDAwIDcyOF0gPj4NCmVuZG9iag0KNDIg MCBvYmoNCjw8L1R5cGUvRm9udC9TdWJ0eXBlL1R5cGUwL0Jhc2VGb250L0FyaWFsLEJvbGQvRW5j b2RpbmcvSWRlbnRpdHktSC9EZXNjZW5kYW50Rm9udHMgNDMgMCBSL1RvVW5pY29kZSAyNjggMCBS Pj4NCmVuZG9iag0KNDMgMCBvYmoNClsgNDQgMCBSXSANCmVuZG9iag0KNDQgMCBvYmoNCjw8L0Jh c2VGb250L0FyaWFsLEJvbGQvU3VidHlwZS9DSURGb250VHlwZTIvVHlwZS9Gb250L0NJRFRvR0lE TWFwL0lkZW50aXR5L0RXIDEwMDAvQ0lEU3lzdGVtSW5mbyA0NSAwIFIvRm9udERlc2NyaXB0b3Ig NDYgMCBSL1cgMjcwIDAgUj4+DQplbmRvYmoNCjQ1IDAgb2JqDQo8PC9PcmRlcmluZyhJZGVudGl0 eSkgL1JlZ2lzdHJ5KEFkb2JlKSAvU3VwcGxlbWVudCAwPj4NCmVuZG9iag0KNDYgMCBvYmoNCjw8 L1R5cGUvRm9udERlc2NyaXB0b3IvRm9udE5hbWUvQXJpYWwsQm9sZC9GbGFncyAzMi9JdGFsaWNB bmdsZSAwL0FzY2VudCA5MDUvRGVzY2VudCAtMjEwL0NhcEhlaWdodCA3MjgvQXZnV2lkdGggNDc5 L01heFdpZHRoIDI2MjgvRm9udFdlaWdodCA3MDAvWEhlaWdodCAyNTAvTGVhZGluZyAzMy9TdGVt ViA0Ny9Gb250QkJveFsgLTYyOCAtMjEwIDIwMDAgNzI4XSAvRm9udEZpbGUyIDI2OSAwIFI+Pg0K ZW5kb2JqDQo0NyAwIG9iag0KPDwvVHlwZS9Gb250L1N1YnR5cGUvVHJ1ZVR5cGUvTmFtZS9GMTQv QmFzZUZvbnQvQXJpYWwvRW5jb2RpbmcvV2luQW5zaUVuY29kaW5nL0ZvbnREZXNjcmlwdG9yIDQ4 IDAgUi9GaXJzdENoYXIgMzIvTGFzdENoYXIgNTcvV2lkdGhzIDI3MSAwIFI+Pg0KZW5kb2JqDQo0 OCAwIG9iag0KPDwvVHlwZS9Gb250RGVzY3JpcHRvci9Gb250TmFtZS9BcmlhbC9GbGFncyAzMi9J dGFsaWNBbmdsZSAwL0FzY2VudCA5MDUvRGVzY2VudCAtMjEwL0NhcEhlaWdodCA3MjgvQXZnV2lk dGggNDQxL01heFdpZHRoIDI2NjUvRm9udFdlaWdodCA0MDAvWEhlaWdodCAyNTAvTGVhZGluZyAz My9TdGVtViA0NC9Gb250QkJveFsgLTY2NSAtMjEwIDIwMDAgNzI4XSA+Pg0KZW5kb2JqDQo0OSAw IG9iag0KPDwvVHlwZS9Gb250L1N1YnR5cGUvVHlwZTAvQmFzZUZvbnQvQXJpYWwvRW5jb2Rpbmcv SWRlbnRpdHktSC9EZXNjZW5kYW50Rm9udHMgNTAgMCBSL1RvVW5pY29kZSAyNzIgMCBSPj4NCmVu ZG9iag0KNTAgMCBvYmoNClsgNTEgMCBSXSANCmVuZG9iag0KNTEgMCBvYmoNCjw8L0Jhc2VGb250 L0FyaWFsL1N1YnR5cGUvQ0lERm9udFR5cGUyL1R5cGUvRm9udC9DSURUb0dJRE1hcC9JZGVudGl0 eS9EVyAxMDAwL0NJRFN5c3RlbUluZm8gNTIgMCBSL0ZvbnREZXNjcmlwdG9yIDUzIDAgUi9XIDI3 NCAwIFI+Pg0KZW5kb2JqDQo1MiAwIG9iag0KPDwvT3JkZXJpbmcoSWRlbnRpdHkpIC9SZWdpc3Ry eShBZG9iZSkgL1N1cHBsZW1lbnQgMD4+DQplbmRvYmoNCjUzIDAgb2JqDQo8PC9UeXBlL0ZvbnRE ZXNjcmlwdG9yL0ZvbnROYW1lL0FyaWFsL0ZsYWdzIDMyL0l0YWxpY0FuZ2xlIDAvQXNjZW50IDkw NS9EZXNjZW50IC0yMTAvQ2FwSGVpZ2h0IDcyOC9BdmdXaWR0aCA0NDEvTWF4V2lkdGggMjY2NS9G b250V2VpZ2h0IDQwMC9YSGVpZ2h0IDI1MC9MZWFkaW5nIDMzL1N0ZW1WIDQ0L0ZvbnRCQm94WyAt NjY1IC0yMTAgMjAwMCA3MjhdIC9Gb250RmlsZTIgMjczIDAgUj4+DQplbmRvYmoNCjU0IDAgb2Jq DQo8PC9UeXBlL1BhZ2UvUGFyZW50IDIgMCBSL1Jlc291cmNlczw8L0ZvbnQ8PC9GMSA1IDAgUi9G MTMgNDIgMCBSL0YxMiA0MCAwIFIvRjIgOCAwIFIvRjMgMTMgMCBSL0YxNSA0OSAwIFIvRjE0IDQ3 IDAgUi9GMTYgNTcgMCBSL0YxNyA1OSAwIFIvRjE4IDY0IDAgUi9GMTkgNjkgMCBSL0YyMCA3MSAw IFIvRjIxIDc2IDAgUi9GMjIgODEgMCBSL0YyMyA4MyAwIFIvRjI0IDg4IDAgUi9GNCAxNSAwIFI+ Pi9YT2JqZWN0PDwvSW1hZ2U1NiA1NiAwIFI+Pi9Qcm9jU2V0Wy9QREYvVGV4dC9JbWFnZUIvSW1h Z2VDL0ltYWdlSV0gPj4vTWVkaWFCb3hbIDAgMCA1OTUuMzIgODQxLjkyXSAvQ29udGVudHMgNTUg MCBSL0dyb3VwPDwvVHlwZS9Hcm91cC9TL1RyYW5zcGFyZW5jeS9DUy9EZXZpY2VSR0I+Pi9UYWJz L1MvU3RydWN0UGFyZW50cyAxPj4NCmVuZG9iag0KNTUgMCBvYmoNCjw8L0ZpbHRlci9GbGF0ZURl Y29kZS9MZW5ndGggNDcxNz4+DQpzdHJlYW0NCnic7V1LjyS3Db4PMP+hj7tBukZvlYJBA909PYED GHCAvRk+LDa7jg9+xNhL/n1EUe9SVat6emYna9sY96skkRT5iaQo+W7/++efPr3/8Hlzf3+3//z5 /Yd/f/zX5vu7d7/+9sPdu//+9vHuu/c//vTL+88//frLbrc5PBw3h3e3N3ePdEPpQMTm3afbG7oh 9l+6GeVA7VeaqkFu3v18e0M2P8J//n578/2bzdsfNu/+cXtzss2hi9CIcTEImjWyj27ebkX471sD 71Lb/9zeGDMw6ZobsmGSDlpie7b5YDu4++bn9z9+lGrz8Ovmn+Vg3D5MdDlY1vfm9O1xs7n7DoTx 7fGbhw0peeYLTBM1CIZ93hMm6G7L7avcE6bMbsv8e3naUW3fK73bCngd7XePO/uWEJ6+Useda33a SXh5tN/InXJvd5Tn7Rm++u+hE3hMYcPwq22cf3RE+f72rs0IJI+7LYWf+X7Htf8iEBZ+YNBIaNed EPib5Y3sjf35sNtq371mO5OR6Tg47RznR/urctIJLIfWHPsu9cSKnTXEzo2VNy/E/mb7dtK0NWOW 7IHKesb4wQ3u+DOWpP0uyZOQA06nOHrxP+yYew1zprxUqWVOerE9JvEJP4CdJp7mA6QiD9mk+sFS w7bJeJVThg9jpnL7XZhcP4w8euqEn+hjn2wpU4Mu+182E5qZSU3kSAfa0wfrNjWlxmC9INYj6jZY zcFJADRMjU4CmuKPF1ubazsWhhYN5us3MkH4QHgu8H4bU4DK1VSdMTEnD6Q6Wdg+zqvc77bjVNBg e6Dh9nOFrN0KL9k46ILNerU6o5FSDiYZ4oObhxFJ7rM4ogel8n4mgo6P2tZ8LB7tJJZSMShWEVur m4nqZhdWnAruLCbgixC7rckbHrAhvkjpfo1KFyb3WT52idZyNoyykpdzLJT/ix+e+Oaafb3QMP/v JK8yUsEGI5KVrkHi7QwUBxfvLBLre4d3E3pbCktGp7AZufPOM4CBLp/9W59UmEUDYWqpBGE42H2M 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 uyD1NXhdMzmdWb+LkuwK5/N+V5+mMne5ed53rztIOYWikaypS1jF24EvMZisr/blwGesphLRsfD7 FqwGNb9ehgiWsMZrbC5ZfySBGoNCvt1mImBroOYpuIfRRCL2zZvJEnx+bdD/tdO/vLQZ7aoQJqW8 117a8nFWGmlN4hEdqle3tF3Col/aWrOw90sb71za/uh6/ly0dKmA5ASWxUIFrrKIj8Lda/4SUdpi xr0OvYLJxPubfBWMCP8XOLMuIa7B48qZ7Y+63P8JqJZTjLpKK5paUOL08qirVJs/I7C15r28RGlm TUs8f/SVj7NyiapJPD4h+sosyxuWutyuhITl5RLOmDBQ+1ZzFhKNk4BrbbLxz+2npu6351EYCtUI xTyujDrrGov/ATD8LesNCmVuZHN0cmVhbQ0KZW5kb2JqDQo1NiAwIG9iag0KPDwvVHlwZS9YT2Jq ZWN0L1N1YnR5cGUvSW1hZ2UvV2lkdGggMjc1L0hlaWdodCAyNDkvQ29sb3JTcGFjZS9EZXZpY2VS R0IvQml0c1BlckNvbXBvbmVudCA4L0ZpbHRlci9EQ1REZWNvZGUvSW50ZXJwb2xhdGUgdHJ1ZS9M ZW5ndGggMTA1MjQ+Pg0Kc3RyZWFtDQr/2P/gABBKRklGAAEBAQBgAGAAAP/bAEMACAYGBwYFCAcH BwkJCAoMFA0MCwsMGRITDxQdGh8eHRocHCAkLicgIiwjHBwoNyksMDE0NDQfJzk9ODI8LjM0Mv/b AEMBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIy MjIyMjIyMjIyMv/AABEIAPkBEwMBIgACEQEDEQH/xAAfAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUG BwgJCgv/xAC1EAACAQMDAgQDBQUEBAAAAX0BAgMABBEFEiExQQYTUWEHInEUMoGRoQgjQrHBFVLR 8CQzYnKCCQoWFxgZGiUmJygpKjQ1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5 eoOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4eLj 5OXm5+jp6vHy8/T19vf4+fr/xAAfAQADAQEBAQEBAQEBAAAAAAAAAQIDBAUGBwgJCgv/xAC1EQAC AQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXx FxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqS k5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T1 9vf4+fr/2gAMAwEAAhEDEQA/APf6KKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAK KKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAoo pCQKAFppbHSo4rqCd3WKZHZfvBWBx9ax/F8l9F4W1CTTS63ixgxlPvDkZx+GaqMXKSj3E3pc2fME YAkkXJ9eKSG5hn3eVKkm04bawODXgln/AMJF4w1Dyob65lkjiLsjyBe2Pb1r0XwB4Y1Tw+90980c cUyqBCr7jkdyfpxXbiMFGjFuU1zdjONTmex3f40x5o41LNIoUdST0rifiLr1zpNpaW9rI0TXLMDI pwcAdB+f6VxP/CM+Jbnw6dSS7L2vlNMFa4JY1NHBKcFUnKyYSqWdkj12w1/StTmeGy1C3nkjALKj gkZrSBzXzv4c8ParrV3I2mSCN449zMH2/QE+9bWg+KNd8PeJIrDVruUwrII5oJG3BM9wfxFdFbLO VtU5Xa6dRRq90e30VFLMkFtJO5+RELnAzwBmvP7T4p28mqSQT2Mi2u8hJ0OTtHcr/hXn0qFSrfkV 7Gjkluei0Vnadrmm6rCstneRSq3QA4P5da0azacXZoad9gooopDCiiigAooooAKKKKACiiigAooo oAKKKKACiiigAooooAKKKKACkzzimswXJJAA70I6OAUYMPUc0AY3iLxPY+GrdJbsSOXPypGMk06W ZPEnhd5LCdoxdQHy3BwVJHQ+9ZHxE0P+1fD7XEZCy2YabkZ3KByK8stde1yztIdN0e6kSOUgLGmC 25uw/E16WGwirUlODtJPW5jOo4yszR8EXn/CPeLUjupPLSd2tpQTxuzwc9Ov869pvIPtenzwZI82 NlyPcV4RrvhDWdIgS71FVeOX5mkDZ2uecH3969W8C60mseGoYXcm5toxFN1644OfcVrmFOMuWvTd +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 CiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA/ /9kNCmVuZHN0cmVhbQ0KZW5kb2JqDQo1NyAwIG9iag0KPDwvVHlwZS9Gb250L1N1YnR5cGUvVHJ1 ZVR5cGUvTmFtZS9GMTYvQmFzZUZvbnQvQXJpYWwsSXRhbGljL0VuY29kaW5nL1dpbkFuc2lFbmNv ZGluZy9Gb250RGVzY3JpcHRvciA1OCAwIFIvRmlyc3RDaGFyIDMyL0xhc3RDaGFyIDU3L1dpZHRo cyAyNzUgMCBSPj4NCmVuZG9iag0KNTggMCBvYmoNCjw8L1R5cGUvRm9udERlc2NyaXB0b3IvRm9u dE5hbWUvQXJpYWwsSXRhbGljL0ZsYWdzIDMyL0l0YWxpY0FuZ2xlIC0xMi9Bc2NlbnQgOTA1L0Rl c2NlbnQgLTIwOC9DYXBIZWlnaHQgNzI4L0F2Z1dpZHRoIDQ0MS9NYXhXaWR0aCAxODc2L0ZvbnRX ZWlnaHQgNDAwL1hIZWlnaHQgMjUwL0xlYWRpbmcgMzMvU3RlbVYgNDQvRm9udEJCb3hbIC01MTcg LTIwOCAxMzU5IDcyOF0gPj4NCmVuZG9iag0KNTkgMCBvYmoNCjw8L1R5cGUvRm9udC9TdWJ0eXBl L1R5cGUwL0Jhc2VGb250L0FyaWFsLEl0YWxpYy9FbmNvZGluZy9JZGVudGl0eS1IL0Rlc2NlbmRh bnRGb250cyA2MCAwIFIvVG9Vbmljb2RlIDI3NiAwIFI+Pg0KZW5kb2JqDQo2MCAwIG9iag0KWyA2 MSAwIFJdIA0KZW5kb2JqDQo2MSAwIG9iag0KPDwvQmFzZUZvbnQvQXJpYWwsSXRhbGljL1N1YnR5 cGUvQ0lERm9udFR5cGUyL1R5cGUvRm9udC9DSURUb0dJRE1hcC9JZGVudGl0eS9EVyAxMDAwL0NJ RFN5c3RlbUluZm8gNjIgMCBSL0ZvbnREZXNjcmlwdG9yIDYzIDAgUi9XIDI3OCAwIFI+Pg0KZW5k b2JqDQo2MiAwIG9iag0KPDwvT3JkZXJpbmcoSWRlbnRpdHkpIC9SZWdpc3RyeShBZG9iZSkgL1N1 cHBsZW1lbnQgMD4+DQplbmRvYmoNCjYzIDAgb2JqDQo8PC9UeXBlL0ZvbnREZXNjcmlwdG9yL0Zv bnROYW1lL0FyaWFsLEl0YWxpYy9GbGFncyAzMi9JdGFsaWNBbmdsZSAtMTIvQXNjZW50IDkwNS9E ZXNjZW50IC0yMDgvQ2FwSGVpZ2h0IDcyOC9BdmdXaWR0aCA0NDEvTWF4V2lkdGggMTg3Ni9Gb250 V2VpZ2h0IDQwMC9YSGVpZ2h0IDI1MC9MZWFkaW5nIDMzL1N0ZW1WIDQ0L0ZvbnRCQm94WyAtNTE3 IC0yMDggMTM1OSA3MjhdIC9Gb250RmlsZTIgMjc3IDAgUj4+DQplbmRvYmoNCjY0IDAgb2JqDQo8 PC9UeXBlL0ZvbnQvU3VidHlwZS9UeXBlMC9CYXNlRm9udC9UaW1lcyMyME5ldyMyMFJvbWFuL0Vu Y29kaW5nL0lkZW50aXR5LUgvRGVzY2VuZGFudEZvbnRzIDY1IDAgUi9Ub1VuaWNvZGUgMjc5IDAg Uj4+DQplbmRvYmoNCjY1IDAgb2JqDQpbIDY2IDAgUl0gDQplbmRvYmoNCjY2IDAgb2JqDQo8PC9C YXNlRm9udC9UaW1lcyMyME5ldyMyMFJvbWFuL1N1YnR5cGUvQ0lERm9udFR5cGUyL1R5cGUvRm9u dC9DSURUb0dJRE1hcC9JZGVudGl0eS9EVyAxMDAwL0NJRFN5c3RlbUluZm8gNjcgMCBSL0ZvbnRE ZXNjcmlwdG9yIDY4IDAgUi9XIDI4MSAwIFI+Pg0KZW5kb2JqDQo2NyAwIG9iag0KPDwvT3JkZXJp bmcoSWRlbnRpdHkpIC9SZWdpc3RyeShBZG9iZSkgL1N1cHBsZW1lbnQgMD4+DQplbmRvYmoNCjY4 IDAgb2JqDQo8PC9UeXBlL0ZvbnREZXNjcmlwdG9yL0ZvbnROYW1lL1RpbWVzIzIwTmV3IzIwUm9t YW4vRmxhZ3MgMzIvSXRhbGljQW5nbGUgMC9Bc2NlbnQgODkxL0Rlc2NlbnQgLTIxNi9DYXBIZWln aHQgNjkzL0F2Z1dpZHRoIDQwMS9NYXhXaWR0aCAyNTY4L0ZvbnRXZWlnaHQgNDAwL1hIZWlnaHQg MjUwL0xlYWRpbmcgNDIvU3RlbVYgNDAvRm9udEJCb3hbIC01NjggLTIxNiAyMDAwIDY5M10gL0Zv bnRGaWxlMiAyODAgMCBSPj4NCmVuZG9iag0KNjkgMCBvYmoNCjw8L1R5cGUvRm9udC9TdWJ0eXBl L1RydWVUeXBlL05hbWUvRjE5L0Jhc2VGb250L1RpbWVzIzIwTmV3IzIwUm9tYW4vRW5jb2Rpbmcv V2luQW5zaUVuY29kaW5nL0ZvbnREZXNjcmlwdG9yIDcwIDAgUi9GaXJzdENoYXIgMzIvTGFzdENo YXIgMTE4L1dpZHRocyAyODIgMCBSPj4NCmVuZG9iag0KNzAgMCBvYmoNCjw8L1R5cGUvRm9udERl c2NyaXB0b3IvRm9udE5hbWUvVGltZXMjMjBOZXcjMjBSb21hbi9GbGFncyAzMi9JdGFsaWNBbmds ZSAwL0FzY2VudCA4OTEvRGVzY2VudCAtMjE2L0NhcEhlaWdodCA2OTMvQXZnV2lkdGggNDAxL01h eFdpZHRoIDI1NjgvRm9udFdlaWdodCA0MDAvWEhlaWdodCAyNTAvTGVhZGluZyA0Mi9TdGVtViA0 MC9Gb250QkJveFsgLTU2OCAtMjE2IDIwMDAgNjkzXSA+Pg0KZW5kb2JqDQo3MSAwIG9iag0KPDwv VHlwZS9Gb250L1N1YnR5cGUvVHlwZTAvQmFzZUZvbnQvVGltZXMjMjBOZXcjMjBSb21hbixCb2xk L0VuY29kaW5nL0lkZW50aXR5LUgvRGVzY2VuZGFudEZvbnRzIDcyIDAgUi9Ub1VuaWNvZGUgMjgz IDAgUj4+DQplbmRvYmoNCjcyIDAgb2JqDQpbIDczIDAgUl0gDQplbmRvYmoNCjczIDAgb2JqDQo8 PC9CYXNlRm9udC9UaW1lcyMyME5ldyMyMFJvbWFuLEJvbGQvU3VidHlwZS9DSURGb250VHlwZTIv VHlwZS9Gb250L0NJRFRvR0lETWFwL0lkZW50aXR5L0RXIDEwMDAvQ0lEU3lzdGVtSW5mbyA3NCAw IFIvRm9udERlc2NyaXB0b3IgNzUgMCBSL1cgMjg1IDAgUj4+DQplbmRvYmoNCjc0IDAgb2JqDQo8 PC9PcmRlcmluZyhJZGVudGl0eSkgL1JlZ2lzdHJ5KEFkb2JlKSAvU3VwcGxlbWVudCAwPj4NCmVu ZG9iag0KNzUgMCBvYmoNCjw8L1R5cGUvRm9udERlc2NyaXB0b3IvRm9udE5hbWUvVGltZXMjMjBO ZXcjMjBSb21hbixCb2xkL0ZsYWdzIDMyL0l0YWxpY0FuZ2xlIDAvQXNjZW50IDg5MS9EZXNjZW50 IC0yMTYvQ2FwSGVpZ2h0IDY3Ny9BdmdXaWR0aCA0MjcvTWF4V2lkdGggMjU1OC9Gb250V2VpZ2h0 IDcwMC9YSGVpZ2h0IDI1MC9MZWFkaW5nIDQyL1N0ZW1WIDQyL0ZvbnRCQm94WyAtNTU4IC0yMTYg MjAwMCA2NzddIC9Gb250RmlsZTIgMjg0IDAgUj4+DQplbmRvYmoNCjc2IDAgb2JqDQo8PC9UeXBl L0ZvbnQvU3VidHlwZS9UeXBlMC9CYXNlRm9udC9BcmlhbCxCb2xkSXRhbGljL0VuY29kaW5nL0lk ZW50aXR5LUgvRGVzY2VuZGFudEZvbnRzIDc3IDAgUi9Ub1VuaWNvZGUgMjg2IDAgUj4+DQplbmRv YmoNCjc3IDAgb2JqDQpbIDc4IDAgUl0gDQplbmRvYmoNCjc4IDAgb2JqDQo8PC9CYXNlRm9udC9B cmlhbCxCb2xkSXRhbGljL1N1YnR5cGUvQ0lERm9udFR5cGUyL1R5cGUvRm9udC9DSURUb0dJRE1h cC9JZGVudGl0eS9EVyAxMDAwL0NJRFN5c3RlbUluZm8gNzkgMCBSL0ZvbnREZXNjcmlwdG9yIDgw IDAgUi9XIDI4OCAwIFI+Pg0KZW5kb2JqDQo3OSAwIG9iag0KPDwvT3JkZXJpbmcoSWRlbnRpdHkp IC9SZWdpc3RyeShBZG9iZSkgL1N1cHBsZW1lbnQgMD4+DQplbmRvYmoNCjgwIDAgb2JqDQo8PC9U eXBlL0ZvbnREZXNjcmlwdG9yL0ZvbnROYW1lL0FyaWFsLEJvbGRJdGFsaWMvRmxhZ3MgMzIvSXRh bGljQW5nbGUgLTEyL0FzY2VudCA5MDUvRGVzY2VudCAtMjEwL0NhcEhlaWdodCA3MjgvQXZnV2lk dGggNDc5L01heFdpZHRoIDE5NTAvRm9udFdlaWdodCA3MDAvWEhlaWdodCAyNTAvTGVhZGluZyAz My9TdGVtViA0Ny9Gb250QkJveFsgLTU2MCAtMjEwIDEzOTAgNzI4XSAvRm9udEZpbGUyIDI4NyAw IFI+Pg0KZW5kb2JqDQo4MSAwIG9iag0KPDwvVHlwZS9Gb250L1N1YnR5cGUvVHJ1ZVR5cGUvTmFt ZS9GMjIvQmFzZUZvbnQvQXJpYWwsQm9sZEl0YWxpYy9FbmNvZGluZy9XaW5BbnNpRW5jb2Rpbmcv Rm9udERlc2NyaXB0b3IgODIgMCBSL0ZpcnN0Q2hhciAzMi9MYXN0Q2hhciA3OS9XaWR0aHMgMjg5 IDAgUj4+DQplbmRvYmoNCjgyIDAgb2JqDQo8PC9UeXBlL0ZvbnREZXNjcmlwdG9yL0ZvbnROYW1l L0FyaWFsLEJvbGRJdGFsaWMvRmxhZ3MgMzIvSXRhbGljQW5nbGUgLTEyL0FzY2VudCA5MDUvRGVz Y2VudCAtMjEwL0NhcEhlaWdodCA3MjgvQXZnV2lkdGggNDc5L01heFdpZHRoIDE5NTAvRm9udFdl aWdodCA3MDAvWEhlaWdodCAyNTAvTGVhZGluZyAzMy9TdGVtViA0Ny9Gb250QkJveFsgLTU2MCAt MjEwIDEzOTAgNzI4XSA+Pg0KZW5kb2JqDQo4MyAwIG9iag0KPDwvVHlwZS9Gb250L1N1YnR5cGUv VHlwZTAvQmFzZUZvbnQvVGltZXMjMjBOZXcjMjBSb21hbixCb2xkSXRhbGljL0VuY29kaW5nL0lk ZW50aXR5LUgvRGVzY2VuZGFudEZvbnRzIDg0IDAgUi9Ub1VuaWNvZGUgMjkwIDAgUj4+DQplbmRv YmoNCjg0IDAgb2JqDQpbIDg1IDAgUl0gDQplbmRvYmoNCjg1IDAgb2JqDQo8PC9CYXNlRm9udC9U aW1lcyMyME5ldyMyMFJvbWFuLEJvbGRJdGFsaWMvU3VidHlwZS9DSURGb250VHlwZTIvVHlwZS9G b250L0NJRFRvR0lETWFwL0lkZW50aXR5L0RXIDEwMDAvQ0lEU3lzdGVtSW5mbyA4NiAwIFIvRm9u dERlc2NyaXB0b3IgODcgMCBSL1cgMjkyIDAgUj4+DQplbmRvYmoNCjg2IDAgb2JqDQo8PC9PcmRl cmluZyhJZGVudGl0eSkgL1JlZ2lzdHJ5KEFkb2JlKSAvU3VwcGxlbWVudCAwPj4NCmVuZG9iag0K ODcgMCBvYmoNCjw8L1R5cGUvRm9udERlc2NyaXB0b3IvRm9udE5hbWUvVGltZXMjMjBOZXcjMjBS b21hbixCb2xkSXRhbGljL0ZsYWdzIDMyL0l0YWxpY0FuZ2xlIC0xNi40L0FzY2VudCA4OTEvRGVz Y2VudCAtMjE2L0NhcEhlaWdodCA2NzcvQXZnV2lkdGggNDEyL01heFdpZHRoIDE5NDgvRm9udFdl aWdodCA3MDAvWEhlaWdodCAyNTAvTGVhZGluZyA0Mi9TdGVtViA0MS9Gb250QkJveFsgLTU0NyAt MjE2IDE0MDEgNjc3XSAvRm9udEZpbGUyIDI5MSAwIFI+Pg0KZW5kb2JqDQo4OCAwIG9iag0KPDwv VHlwZS9Gb250L1N1YnR5cGUvVHJ1ZVR5cGUvTmFtZS9GMjQvQmFzZUZvbnQvVGltZXMjMjBOZXcj MjBSb21hbixCb2xkSXRhbGljL0VuY29kaW5nL1dpbkFuc2lFbmNvZGluZy9Gb250RGVzY3JpcHRv ciA4OSAwIFIvRmlyc3RDaGFyIDMyL0xhc3RDaGFyIDQ1L1dpZHRocyAyOTMgMCBSPj4NCmVuZG9i ag0KODkgMCBvYmoNCjw8L1R5cGUvRm9udERlc2NyaXB0b3IvRm9udE5hbWUvVGltZXMjMjBOZXcj MjBSb21hbixCb2xkSXRhbGljL0ZsYWdzIDMyL0l0YWxpY0FuZ2xlIC0xNi40L0FzY2VudCA4OTEv RGVzY2VudCAtMjE2L0NhcEhlaWdodCA2NzcvQXZnV2lkdGggNDEyL01heFdpZHRoIDE5NDgvRm9u dFdlaWdodCA3MDAvWEhlaWdodCAyNTAvTGVhZGluZyA0Mi9TdGVtViA0MS9Gb250QkJveFsgLTU0 NyAtMjE2IDE0MDEgNjc3XSA+Pg0KZW5kb2JqDQo5MCAwIG9iag0KPDwvVHlwZS9QYWdlL1BhcmVu dCAyIDAgUi9SZXNvdXJjZXM8PC9Gb250PDwvRjEgNSAwIFIvRjIwIDcxIDAgUi9GNCAxNSAwIFIv RjMgMTMgMCBSL0YyIDggMCBSL0YxOCA2NCAwIFIvRjE5IDY5IDAgUi9GMjUgOTIgMCBSPj4vWE9i amVjdDw8L0ltYWdlNTYgNTYgMCBSPj4vUHJvY1NldFsvUERGL1RleHQvSW1hZ2VCL0ltYWdlQy9J bWFnZUldID4+L01lZGlhQm94WyAwIDAgNTk1LjMyIDg0MS45Ml0gL0NvbnRlbnRzIDkxIDAgUi9H cm91cDw8L1R5cGUvR3JvdXAvUy9UcmFuc3BhcmVuY3kvQ1MvRGV2aWNlUkdCPj4vVGFicy9TL1N0 cnVjdFBhcmVudHMgMj4+DQplbmRvYmoNCjkxIDAgb2JqDQo8PC9GaWx0ZXIvRmxhdGVEZWNvZGUv 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 LWPTXiVvVZJioO1VHOXUDwVFIUWTEe5kgruHyZhIB4BwyFmqGiBkNrgRFMDxZ8zXXMcBuU14vlIW Y2oOlFsgjUf8BunPw7oYa3sW3HxCtfQER63koPErXuEs90ONLyXsZWsy2zXDK/UK2u0ROGhjW4ia jX5eQKUtA/McJ/r/fjbIaw0KZW5kc3RyZWFtDQplbmRvYmoNCjkyIDAgb2JqDQo8PC9UeXBlL0Zv bnQvU3VidHlwZS9UeXBlMC9CYXNlRm9udC9BQkNERUUrQ2FsaWJyaS9FbmNvZGluZy9JZGVudGl0 eS1IL0Rlc2NlbmRhbnRGb250cyA5MyAwIFIvVG9Vbmljb2RlIDI5NCAwIFI+Pg0KZW5kb2JqDQo5 MyAwIG9iag0KWyA5NCAwIFJdIA0KZW5kb2JqDQo5NCAwIG9iag0KPDwvQmFzZUZvbnQvQUJDREVF K0NhbGlicmkvU3VidHlwZS9DSURGb250VHlwZTIvVHlwZS9Gb250L0NJRFRvR0lETWFwL0lkZW50 aXR5L0RXIDEwMDAvQ0lEU3lzdGVtSW5mbyA5NSAwIFIvRm9udERlc2NyaXB0b3IgOTYgMCBSL1cg Mjk2IDAgUj4+DQplbmRvYmoNCjk1IDAgb2JqDQo8PC9PcmRlcmluZyhJZGVudGl0eSkgL1JlZ2lz dHJ5KEFkb2JlKSAvU3VwcGxlbWVudCAwPj4NCmVuZG9iag0KOTYgMCBvYmoNCjw8L1R5cGUvRm9u dERlc2NyaXB0b3IvRm9udE5hbWUvQUJDREVFK0NhbGlicmkvRmxhZ3MgMzIvSXRhbGljQW5nbGUg MC9Bc2NlbnQgNzUwL0Rlc2NlbnQgLTI1MC9DYXBIZWlnaHQgNzUwL0F2Z1dpZHRoIDUyMS9NYXhX aWR0aCAxNzQzL0ZvbnRXZWlnaHQgNDAwL1hIZWlnaHQgMjUwL1N0ZW1WIDUyL0ZvbnRCQm94WyAt NTAzIC0yNTAgMTI0MCA3NTBdIC9Gb250RmlsZTIgMjk1IDAgUj4+DQplbmRvYmoNCjk3IDAgb2Jq DQo8PC9UeXBlL1BhZ2UvUGFyZW50IDIgMCBSL1Jlc291cmNlczw8L0ZvbnQ8PC9GMSA1IDAgUi9G MiA4IDAgUi9GMyAxMyAwIFIvRjI1IDkyIDAgUi9GMTkgNjkgMCBSL0YxOCA2NCAwIFI+Pi9YT2Jq ZWN0PDwvSW1hZ2U1NiA1NiAwIFI+Pi9Qcm9jU2V0Wy9QREYvVGV4dC9JbWFnZUIvSW1hZ2VDL0lt YWdlSV0gPj4vTWVkaWFCb3hbIDAgMCA1OTUuMzIgODQxLjkyXSAvQ29udGVudHMgOTggMCBSL0dy b3VwPDwvVHlwZS9Hcm91cC9TL1RyYW5zcGFyZW5jeS9DUy9EZXZpY2VSR0I+Pi9UYWJzL1MvU3Ry dWN0UGFyZW50cyAzPj4NCmVuZG9iag0KOTggMCBvYmoNCjw8L0ZpbHRlci9GbGF0ZURlY29kZS9M ZW5ndGggNjAwOD4+DQpzdHJlYW0NCnic7T3LbiQ3kvcG+h/qKC1GKb4fgFBAVUm16AVmMAs0sAfP HBpe2+vDjGcHfdm/X0aQzCSZTJKplmTt2jbU9cqMJIPBeEfw/vTPrz//+OX7r4eHh/vT169fvv+v H/7z8N3951/+8df7z//zjx/u//zlp5///uXrz7/8/Xg8nB8vh/Pnjx/ur/RA6UTE4fOPHz/QA3H/ 04ORE3Vfaaomefj8t48fyOEn+OdfP3747uZw+9fD53/7+OHJ3Q4g4k2Mi0nQ5CZ36eH2TsR/by28 W+79748frJ2YxNstOTBJJy39/ezwvQNw/+lvX376QarD4y+Hf88fxt3FROcPS2Afnv54ORzu/wzI +OPl0+OBZHNmByq25kz4RBSCPJCJUGYOn7//7oGwCyXsJAg7n92fcp/5McfD/ZVXwFImJp1DBYA3 d7fl3bVBUWYnwtLbYSjnqxvK+ahhVBzeulfiXqV7FfD+KN1PJ3284w+EkHKgM3CrJ8tL4Keno3gg XBr39gSvQ9NkTE3CZrDaC0LDglCgrIB7pfkkHBqALNwLn9zS//OHjx9+/JcKAJavqNwmY6UVgJ3p 2M2SPz0icmCaDkF+qvTs/k5HStz3VBHOOOH80b2qI4VrmTneSf8bIFXDV1cPxv0Ev7CTv4ue/dfk eqRsuRPusg/hEoV3A6qZ8h8D3AbSeHfnMiYnZtMpd9ZBJCAXIHoyNAdy1wIia0C4G5zcMRLVX1DG HU3oDGbEOi4ALCUs4R0gnVzCT5cjFcnysUe/xJy2UK1LVLN8JEZMnO+YnanRu9COe+GSqbCnNsnd jpO7JJMqyf0pJ/fzKRDoxRMoPSE+1ELSgVbnK92GAYJ/uoSPl3gVUjlQNW4f4b/yJI14Dpc4+OFZ 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 RjE5IDY5IDAgUi9GMTQgNDcgMCBSL0YxNSA0OSAwIFI+Pi9YT2JqZWN0PDwvSW1hZ2U1NiA1NiAw IFI+Pi9Qcm9jU2V0Wy9QREYvVGV4dC9JbWFnZUIvSW1hZ2VDL0ltYWdlSV0gPj4vTWVkaWFCb3hb IDAgMCA1OTUuMzIgODQxLjkyXSAvQ29udGVudHMgMTAwIDAgUi9Hcm91cDw8L1R5cGUvR3JvdXAv Uy9UcmFuc3BhcmVuY3kvQ1MvRGV2aWNlUkdCPj4vVGFicy9TL1N0cnVjdFBhcmVudHMgND4+DQpl bmRvYmoNCjEwMCAwIG9iag0KPDwvRmlsdGVyL0ZsYXRlRGVjb2RlL0xlbmd0aCA0NzE4Pj4NCnN0 cmVhbQ0KeJzlHcuOHLfxLkD/MEfpsBTfD2AxwDx2AgUw4AC6GT4IjuwYiB9JdMnfh1Uku0k2m81e 7cprJIE8O91ksVisN4ucd6d/f/75x48/fD7c3787ff788Yd/fPr74bt3H377/ft3H/77+6d33378 6edfP37++bdfj8fD+Xo5nD+8fvXuxg6MESoPH358/YodqP8/O1hFmH9kmCbq8OGX16/o4Sf4z19e v/ruzeHt94cPf3396sF3BxCpExeSSJZ18k0Pb+9k+u9bB3/Nff/1+pVzhCvs7uiBK0aMCv354QcP 4N37Xz7+9Enpw/W3w9/KwYRvTE05WAb78PDN5XB49y0Q45vL++uBFnP2g65PmmrCbIB5T8WNHu+E /1SW8pM6Gv8nO1PBb0fp/xQsvOWKUir85/XI6D2+Ds8vR/ywRzV3vNPwtz46eOM7iav/1AHexb+5 ACx8e1MBzMMFB9aX4x20erjiV/8U3uLAFGBA53NEwCPGQxcYjZ8QiTvEQuJQ/mNlHY0gVNV0UPbI RIYDv0ao4mhxOjCHeVx6ObI4fjlKm+EE54SKYsw3d2/rns1l87Qn3NToZhNG+rATokkv8VWxLjAX v5JDiBpdj5Y4O3C6Ltm9ehj/bBNecrYgQgdM/mZ1wB4Wj+i0grmSnFhdYz60fFHqtKPEzELHNoSu jQZjkmhewUqi6fk9LjlKgecAJrPvzCFs4GFxCdIa5BC4HZDwj/j5DDD46YRvGANUeS6LSd4ywR3h Ks41KMIM8VHu59wRzeopn6ISmAQAtQk75QKAr+0694uDp2Y9mqVEugLPw1u58u9u8ccXf9nbpM0m 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 GyutISbHqnNhJbiRZo0Olq5ed4d3MS4mPsw+fvm8H5aj2L4K4WnurIOzEhVBNnimtc+VeEZJspYt y8ImI8umO1lq7jnCTNPdZ3dytkA+4sa7BZDHRJAyyfI7TvYzFieimNUqX1m8jW5uOnYRqtPgpee9 9nEVHssvaPdVdJIKQpTRpc9ebPw3huAIRXa1Y+tmmy+9KHNs6eEksS7QabmI7fsb8Ldesq5Y6CA4 T7pyDwc62NHJYbVZZGYp9HWKDiMXc1IJMfz2OKusaKBEpFq951NwlnC3vjgNDhy4VStxIFxtymcO bNxlsqWXWGA3nokj9rns10DhmpIcp85lzJq4vGmorzGhvsbZVdVl4eB/3m/fbcyOQUqmItv48fhH aSDJUfPlZNlggOoym/UA2igsApvi03RT/ClGn/h3DEjDbx7E33qBw9zTj0eMxdIWaz7yEVtUb/Z0 ROUdQco5tVHDYIhc/4rZSixMNdzkW4BaW/5Wd784TNREQw4/hav2vZXGe33m895jIf/0ixtPE/ML 7yTKEtHBmF9470apaopDMX/+awFJxUHML7PG88/2hDTA0jy1b73WC85ZCMD/APGmyDANCmVuZHN0 cmVhbQ0KZW5kb2JqDQoxMDEgMCBvYmoNCjw8L1R5cGUvUGFnZS9QYXJlbnQgMiAwIFIvUmVzb3Vy Y2VzPDwvRm9udDw8L0YxIDUgMCBSL0YyNSA5MiAwIFIvRjIgOCAwIFIvRjMgMTMgMCBSL0YxOSA2 OSAwIFIvRjE4IDY0IDAgUi9GMTUgNDkgMCBSL0YxNCA0NyAwIFIvRjIwIDcxIDAgUj4+L1hPYmpl Y3Q8PC9JbWFnZTU2IDU2IDAgUj4+L1Byb2NTZXRbL1BERi9UZXh0L0ltYWdlQi9JbWFnZUMvSW1h Z2VJXSA+Pi9NZWRpYUJveFsgMCAwIDU5NS4zMiA4NDEuOTJdIC9Db250ZW50cyAxMDIgMCBSL0dy b3VwPDwvVHlwZS9Hcm91cC9TL1RyYW5zcGFyZW5jeS9DUy9EZXZpY2VSR0I+Pi9UYWJzL1MvU3Ry dWN0UGFyZW50cyA1Pj4NCmVuZG9iag0KMTAyIDAgb2JqDQo8PC9GaWx0ZXIvRmxhdGVEZWNvZGUv TGVuZ3RoIDQ2NTI+Pg0Kc3RyZWFtDQp4nN1dW68ctw1+N+D/sC8FzilwxrprBBgL7LVIgQAp4De3 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 iCnidH7gw43o1ufkgsVNbsijFj21J/rXBCavLDlpGaldTKXmU062XC31NlSO9C93JITVzP4XvtUx XA0KZW5kc3RyZWFtDQplbmRvYmoNCjEwMyAwIG9iag0KPDwvVHlwZS9QYWdlL1BhcmVudCAyIDAg Ui9SZXNvdXJjZXM8PC9Gb250PDwvRjEgNSAwIFIvRjEzIDQyIDAgUi9GMTUgNDkgMCBSL0YxNCA0 NyAwIFIvRjEyIDQwIDAgUi9GMjIgODEgMCBSL0YyMSA3NiAwIFI+Pi9YT2JqZWN0PDwvSW1hZ2U1 NiA1NiAwIFI+Pi9Qcm9jU2V0Wy9QREYvVGV4dC9JbWFnZUIvSW1hZ2VDL0ltYWdlSV0gPj4vTWVk aWFCb3hbIDAgMCA1OTUuMzIgODQxLjkyXSAvQ29udGVudHMgMTA0IDAgUi9Hcm91cDw8L1R5cGUv R3JvdXAvUy9UcmFuc3BhcmVuY3kvQ1MvRGV2aWNlUkdCPj4vVGFicy9TL1N0cnVjdFBhcmVudHMg Nj4+DQplbmRvYmoNCjEwNCAwIG9iag0KPDwvRmlsdGVyL0ZsYXRlRGVjb2RlL0xlbmd0aCA2MzI2 Pj4NCnN0cmVhbQ0KeJztXUuPHDlyvgvQf6iLgW4DneKbmUajgHr1QAsPdryrm7wHQdaMB8bOrMe6 +N+bwWcEk8litaSR7DUGo+6uymSSwS/ewchXh98+/vzju/cfd4+Prw4fP757/+8f/m339tWbX//2 l1dv/vtvH1798O6nn3959/HnX3/Z73fH82l3fPPyxasnvuN8Ymr35seXL/iOuf/4btYTdx9Zbia9 e/PXly/Y7if457uXL97e7e7/snvzh5cvLu52GCLdJKSaFEc3uUt39w8q/Xu/wG/l3v98+WJZJqH9 7QvbCc0nq8P9YvfeDfDq9V/f/fRBm935192/0IdJdzGz9GFo7N3l+9Nu9+oHIMb3p9fnHaNrlp1F MzMpEcZ8ZEItTOinvXS/Wr7X7oex+wcFP2f/jfuVMRk/OsHHe+5/X+JnOtwl9sb90Kd8s7sL7tgv MPTB/Wr82EtzaMaO+weYhDrAx+5bd9WxetJ5L+ASffRPleGp4SvlPj6ER6rTnrNH/7efsA4jmsP+ YYafR/qxjc8/7S1aKdzs1jKXRcvwrSlPzRcrthfwN+fhb3kJ37u/DVpafLL72N2iwiTzrNLazntM 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 BZz5hZ5qRAEw8iaT9ExcLYl6FOR+QyGXmM9Nixg6pkWHhVkar+htR4046BA8pytcMt7VbbE+lFYl MGktiSyvIjuiV0TlVw0iH6sURAbvoXK9Nk3W1Lzpgl8J1TBdC8mx7Vol0n2HnupswTFbJJ/Dhs3m K3EFZQD3qsPFITdpXh5Rkn7VfpVKAHJWPq2KNV/IGEsE0Dl7Un1AljXc5cdC8RaGxxXMjb/gZlaT QZjzka8TK8egfD3tnoRwM7NtdY5THN6WVY1cNTTIfDmn1tekpEJ0ZCupNE6kT1EG9GqjQv9gJue9 LoZWao2S13RCRnet19di52lcu8IbVpUlROnvIWcDuce4iRZ6ZiAJaUv0IVLaoFJp1JytvKW+vLCI ewGdwiZBnJ/pgaKon71zjBS0CRuxar/IUr/07Xd7jbVdzGcqkmN+myNU8fhThPoBCZ1tDylrttVh NOzuUEG3BmXK5VbVR0GsJPTxFvqSgLyqLvUySZbB0Ozs3AJozOPguwlAG/UC6NqqDnSrBQYz/kVd 6L6NSP//AJfi7aMNCmVuZHN0cmVhbQ0KZW5kb2JqDQoxMDUgMCBvYmoNCjw8L1R5cGUvUGFnZS9Q YXJlbnQgMiAwIFIvUmVzb3VyY2VzPDwvRm9udDw8L0YxIDUgMCBSL0YxMyA0MiAwIFIvRjEyIDQw IDAgUj4+L1hPYmplY3Q8PC9JbWFnZTU2IDU2IDAgUj4+L1Byb2NTZXRbL1BERi9UZXh0L0ltYWdl Qi9JbWFnZUMvSW1hZ2VJXSA+Pi9NZWRpYUJveFsgMCAwIDU5NS4zMiA4NDEuOTJdIC9Db250ZW50 cyAxMDYgMCBSL0dyb3VwPDwvVHlwZS9Hcm91cC9TL1RyYW5zcGFyZW5jeS9DUy9EZXZpY2VSR0I+ Pi9UYWJzL1MvU3RydWN0UGFyZW50cyA3Pj4NCmVuZG9iag0KMTA2IDAgb2JqDQo8PC9GaWx0ZXIv RmxhdGVEZWNvZGUvTGVuZ3RoIDEyODY+Pg0Kc3RyZWFtDQp4nM1YW2sjNxR+N/g/6NEujKz7pQRR X5JlCwvb4rewDybrpIEm2aYudP99j6SZsTQXZRxaKMEz0YzOp3P5zjnSrNavp8f7w90JXV2t1qfT 4e6341d0u9q/fPuy2n//dlx9Pjw8Ph9Ojy/PzqHNbos2+/lsdUMRpZgItL+fzygi8EeRkZjCI00V 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 07uY3sX0LqZzvlRdouGY3sX0LqZ3WfT+NNicvzXFnxx2u8f7/XHzeH+1+2H7yzzk52rwaHvYXc8/ z3f2vGXn+BPp1t8f7n47fr/7PXRD/wZw1/vjbvOQvx5cP//jwxM0/Wn/27LQfLvbPt8dlmvmvL3+ 7vrq8np38XLLTvLGf66BsD1e7q/t8+F4+fMWF/PTf/eHVz/t9682X++fvXmNPs07v77c7Y7s5HHz w/bZYX/r81cv8fvW568vt1f7F7duXFxdPt/dart8D5q9OGxfb765fPHmsLNnffjm9a/zLNyUk+Zb iDnm830Cr3S+TeDV8n+rvFr+b5VXdb6i51WbL8tvePp/y+7nEr3bx7njR92OnoZJ4tn3pL8aP2hP s86/s7GtcY1rXOMa17jGNa5xjWtcoyu+NRl/Pi07NbYTY79n8a7TwDV+mvGuU9z7Fssa13iPY/VE 21RuXpGs8TxxrPE+xJtXfeeOH+XVoU3Gs70//Nyi/MOiieqd974fGj/o/fAiuk/vJfEa13hKPMs/ Fdhkcf9nwceKN9vH/wCJyKDmDQplbmRzdHJlYW0NCmVuZG9iag0KMjQyIDAgb2JqDQpbIDIyNiAw IDAgMCAwIDAgMCAwIDMwMyAzMDMgMCAwIDI1MCAzMDYgMjUyIDAgNTA3IDUwNyA1MDcgNTA3IDUw NyA1MDcgNTA3IDUwNyA1MDcgNTA3IDI2OCAwIDAgMCAwIDAgMCAwIDAgMCA2MTUgNDg4IDAgMCAw IDI1MiAwIDAgMCAwIDY0NiAwIDAgMCAwIDAgMCAwIDAgODkwIDAgMCAwIDAgMCAwIDAgMCAwIDAg MCAwIDAgNDk4IDAgMCAwIDIzMCAwIDAgMjMwIDAgMCAwIDAgMCAwIDM5MV0gDQplbmRvYmoNCjI0 MyAwIG9iag0KPDwvRmlsdGVyL0ZsYXRlRGVjb2RlL0xlbmd0aCA4MzM4OS9MZW5ndGgxIDE3OTI0 MD4+DQpzdHJlYW0NCnic7HwHfFRV2v45907LlMxMkkmbJDNhkklCKgmEhJaBFAihJWEgoSaEqiIQ QIqAEcQSxbJW7B3XWCaDShQL9o5lXXVti7uuuiqWtYMk33PuO4e2rr/v+31+63//v5zJc5/nvKfc c957zrnvmCDjjDEXLjo2paqxdmzi6Pd7mXLDBMaS36keUzV1sfmtHxgLFTFmHl09ZkKlf7/uZsa6 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 ipuluEmKG6W4QYrrpbhOimuluEaKq6W4SoorpdguxRVSXC7FZVJcKsUlUlwsxe+kuEiKC6W4QIrz pdgmxXlSnCtFpxTnSHG2FGdJcaYUW6WQYQ+XYQ+XYQ+XYQ+XYQ+XYQ+XYQ+XYQ+XYQ+XYQ+XYQ+X YQ+XYQ+XYQ+XYQ+XYQ+XYQ+XYQ9vl0LGP1zGP1zGP1zGP1zGP1zGP1zGP1zGP1zGP1zGP1zGP1zG P1zGP1zGP1zGP1zGP1zGP1zGP1zGP1zGP1zGP1zGP1zGP1zGP1zGP1zGP1zGP1zGP1zGP1zGP1zG P1zGP1yGPVyGPVyGPVxGO1xGO1xGO1xGO1xGO1xGO1xGO1xGO1xGO7xypxCImsNpozyImcNpLtBm yp0eThsG6qDcaUSbwmlW0EbKbSA6lWg90bpw6mjQ2nBqJWgN0SlEq6lsFeVWErWTcUU4dQxoOdEy opOpylKik4hODKdUg04gWkK0mGgR0cJwShVoAeXmE7URzSNqJWohmks0h9rNptwsoplEM4iaiZqI phNNIwoSTSVqJGogqieaQjSZaBLRRKIJRHVE48PuWlAt0biwezxoLFFN2F0Hqg67J4CqiCqJxlDZ aGoXIKqgdqOIRhKNoJrDiYZR83KiMqKhRKVEQ6izwUQl1Esx0SCiIuqskKiA2uUT5RHlEg0kyiHK Jsqirv1EmdRnBpGPaAB1nU7kpXYeojSiVKIUIjdRcjh5EiiJKDGcPBmUQBRPRhdRHBljiWKInFTm ILKTMZrIRmSlMguRmSiKykxERiJDOGkKSB9OqgfpiFQyKpTjREwj3kfUq1Xhhyj3E9FBogNU9iPl fiD6nug7om/DiVNB34QTG0FfU+4fRF8RfUllX1Duc6L9RJ9R2adEn5Dx70QfE31E9CFV+RvlPqDc Xyn3F6L3ifZR2Z+J3iPju0TvEL1N9BZV+RPl3iR6I5wwHfR6OGEa6I9Er5HxD0SvEr1C9DJVeYlo LxlfJHqB6Hmi56jKs0TPkPFpoqeIniR6guhxqvkY5R4l2kP0CJU9TPQQGR8k2k30ANH9RD1Ucxfl 7iO6l+geop3h+ApQOBw/E9RNFCK6m+guojuJ7iDqIro9HI/zmv+eermNaAeV3Up0C9HNRDcR3Uh0 A9H1RNdRZ9dSL9cQXU1lVxFdSbSd6ApqcDnlLiO6lOgSKruYevkd0UVUdiHRBUTnE20jOo9qnku5 TqJziM4mOovozLCrFbQ17JoHOoNoS9i1ELSZ6PSwKwjqCLtwGPPTwq5S0CaijdR8A7U7lWh92DUf tI6aryVaQ3QK0WqiVUQrqet2ar6CaHnY1QZaRp2dTDWXEp1EdCLRCURLqN1iokU0soXUfAHRfKrZ RjSPqJWohWgu0Rya9Gwa2SyimTTpGdR1M92oiWg6DXca3ShIvUwlaiRqIKoPxwVAU8Jx4g6Tw3Fi eU8Kx20BTQzH5YMmUJU6ovHhOMQFvJZy44jGkrEmHLcJVB2OOwtUFY47DVQZjusAjQnH1IBGEwWI KohGhWPwfucjKTci7GwGDScaFnaKpVFOVBZ2jgUNDTubQKVh5wzQECobTFQSduaBiqnmoLBTTKwo 7BR7s5CogJrn0x3yiHKps4FEOdRZNlEWkZ8oM+wUXsog8lGfA6jPdOrMS714iNKoXSpRCpGbKJko KeyYDUoMO+aAEsKOuaB4IhdRHFEsUQw1cFIDBxntRNFENiIr1bRQTTMZo4hMREYiA9XUU00dGVUi hYgTsUCffZ5HoNfe5jlkn+/5CfogcAD4EbYfYPse+A74FvgG9q+Bf6DsK+S/BL4APgf2w/4Z8CnK PkH+78DHwEfAh9GLPH+LXuz5APgr8Bfgfdj2gf8MvAe8i/w74LeBt4A/AW/aTvS8YRvkeR38R9tJ ntdsfs8fgFehX7Hlel4GXgL2ovxF2F6wLfU8D/0c9LPQz9hO8DxtW+J5yrbY86RtkecJtH0c/T0G PAoE+vbg+gjwMPCQdYXnQWu7Z7d1pecB6yrP/UAPsAv2+4B7UXYPynbCFga6gRBwt2Wd5y7Les+d lg2eOywbPV2WTZ7bgd8DtwE7gFuBWyz5npvBNwE3os0N4OstJ3qug74W+hrgauir0NeV6Gs7+roC tsuBy4BLgUuAi4Hfod1F6O9C8yTPBebJnvPNizzbzLd4zjPv8GxVMz1nqGWeLbzMsznYETy9qyN4 WnBjcFPXxqBlI7dsdG+s23jqxq6Nb28MxBjMG4Lrg6d2rQ+uC64Jru1aE3xAOZMtVLYGRgRP6Vod 1K2OW71qtfrNat61mlet5kWrucJWO1Z7V6vWVcH24Mqu9iBrn9Le0R5q1w0Pte9rV1g7N/f07dnZ 7k6rAQc2tNscNSuCy4LLu5YFT164NHgCBrikbFFwcdei4MKy+cEFXfODbWXzgq1lLcG5ZbODc7pm B2eVzQjO7JoRbC5rCk5H/WllU4PBrqnBxrL6YENXfXBy2aTgJNgnltUFJ3TVBceXjQvWdo0Lji2r CVZj8izFkeJNUR1iAJNSMBLm5mOK3AH3PveXbh1zh9x73GqMPdmTrOTYk3jl5CS+LOm0pAuSVHvi S4lKIDEnr8ae8FLCnxO+SNDFBhJyCmpYvCPeG6+6xNziJ06t0biiinjQEG2uE+N9/hq7i9tdHpdS 7XFx5tzn/NKpuh5xvORQ7HZut/fZlYAd1e3RnmhFXPqi1UD0oKE1dpvHpohLn02ND9hgET1mWadM rbFbPBYlWGGZbFEClorKmoAlv6iGqdzLOeMOkGoSo+AuTw329c54rud4n3dPbczNresxsYa6kGnK zBA/O5TZKK6B+hkhw9khFpwxs6mb8/Obu7lSOTUUJ35jq+W3btvGxqTWhVIbm0LXpzbXhTogAkL0 QbDU7ng2pjl3zsrVK3NzV83BZc7KVbnaD3J8tcjlCqP4WbkKefFZreVZ7i8mqgaauxJplTSu+uVW /68n/lsP4D8/dTPxRwaj+5Qz2HxlC7AZOB3oAE4DNgEbgQ3AqcB6YB2wFlgDnAKsBlYBK4EVwHJg GXAysBQ4CTgROAFYAiwGFgELgQXAfKANmAe0Ai3AXGAOMBuYBcwEZgDNQBMwHZgGBIGpQCPQANQD U4DJwCRgIjABqAPGA7XAOGAsUANUA1VAJTAGGA0EgApgFDASGAEMB4YB5UAZMBQoBYYAg4ESoBgY BBQBhUABkA/kAbnAQCAHyAayAD+QCWQAPmAAkA54AQ+QBqQCKYAbSAaSgEQgAYgHXEAcEAvEAE7A AdiBaMAGWAELYAaiABNgBAyAHtCN7sNVBRSAA4zN57DxXuAQ8BNwEDgA/Aj8AHwPfAd8C3wDfA38 A/gK+BL4Avgc2A98BnwKfAL8HfgY+Aj4EPgb8AHwV+AvwPvAPuDPwHvAu8A7wNvAW8CfgDeBN4DX gT8CrwF/AF4FXgFeBl4C9gIvAi8AzwPPAc8CzwBPA08BTwJPAI8DjwGPAnuAR4CHgYeAB4HdwAPA /UAPsAu4D7gXuAfYCYSBbiAE3A3cBdwJ3AF0AbcDvwduA3YAtwK3ADcDNwE3AjcA1wPXAdcC1wBX A1cBVwLbgSuAy4HLgEuBS4CLgd8BFwEXAhcA5wPbgPOAc4FO4BzgbOAs4ExgK5s/uoNj/3Psf479 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 NTWqqVFNjWpqVFOjmhrV1KimRjU1qqlRTY1qalRTo5oa1dSopkY1NaqpUU2NampUU6OaGtXUqKZG NTWqqVFNjWpqTKfGdGpMp8Z0akynxnRqTKfGdGpUR6VqYUjGCRnfL+MbZDxOhrfI8MZofxotoc8S 2rTQpoUO42gwzqcPyH+J/JfIf4n8l8i/Rf4t8m+Rf4v8W+TfIo4WcbSIo0UcLeJoEUeLOFrE0aJX asJT/zTvhqJjY5814y5FjTl3pRn3HVwF3y3ijvdn3Uwz49awsuKHIVXxH5iJW3ArZmE2bkMtbseP cAfMxgqzscJsrDAbK8zGCrOxwmysMBsrzMYKs7HCXKwwFyvMxQpzscJcrDAXK8zFCnNxj7EoR4WZ l5/sqULsGT2e1ONJPZ6kW/4+fYpP1+jdpN5N6t2k3k3q3aTYM2LPiD0j9ozYM2LPiD0j9ozYM2LP iD0j9ozYM2LPiD0j9ozYM2LPiD0j9ozYM2LPiD0j9ozYM2LPiD0j9ozYM2LPiD0j9ozY8zPr0rCB 2m9S+NX3Z1Y+o/boRBnV+Xyrz4e58S433uXGu45td2yZYyt0SrlMj9Mp5bI9bvQ3oDc49C6H3pVl nSzrZFknyzpZ1smyTpZ1sqyTZZ0s62RZJ8s6WdbJsk6WdbKsk2WdLOtkWSfLOlnWybJOlnWyrJNl nSzrZFknyzpZ1smyTpZ1sqyTZV10ikxqebOcN8tjNdGB/Fkug2/ogF06ICuT22UycfSXmYn5X2Zk 8ov8r1m8W8675bxbzrvlvFsuq1pZ1cqqVla1sqqVVa2samVVK6taWdXKqlZWtbKqlVWtrGplVSur WlnVyqpWVrWyqpVVraxqZVUrq1pZ1cqqVla1sqqVVa2samVVK6tafXxpoY8/Kou3Rv+d01RRPyDq 56MK+TbKt1GujfLaV077+uRB+TTKp1E+jfJplE9jVBKbwdcbwq7YjeGd2O3q4t7QF3sw/0u7d0di t4dsVOSfu6KjHJGN3aQibsbtoTl2R1QWu9PZ94Tu2EP5/62osDv2cNhdYX9bYX9bcRA+hMk4GFU4 BN90zOW4At/Ct1GDK/EdXIWrcQ2+i2vxPVyH6/F9zMANuBE34Wb8IOwu5DMi0s7YzNAll22xn4cd MXd60WWx61T79Zjh3ZtkeTNuDU2xWZiN23B7tG/sjvBcbI7j7gsdsfvxMzyAueEl+b1UEQtvVsRR jDEoQSnKMBblqEACldgDe2Iv7I1x2AfjsS8mYCL2w/44AJNCHw37aNhHwz4a9tGwj4Z9NOyrOCM0 VZyJs/AxnI1zcC7Ow/m4AB/HJzAVn8Q0XIhvyuNyXIFv4duowZX4Dq7C1bgG38W1+B6uw/X4Pmbg BtyIm3AzfhBeiopVzmYqrqXilthDYUAt3R4G1clw9Bku5LiQ48AIB/IVtsWKk7XiZB2RpXKOyjkr TNYKk7XCZK0wWStM1gqTpX6O+jnq56ifo36O+jnq56ifo36O+jnq56ifo36O+jnq56ifo36O+jnq 56ifo36O+jnq56ifo36O+iPUH6H+CPVHqD9C/RHqj1B/xCqXtcplrXJZq1zWKpe1ymWtclmrXJa6 OermqJujbo66OermqJujbo66OermqJujbo66OermqJujbo66OermqJujbo66OermqJvTczeo7nwv zqTpLar79mgPandSeyu1d0TX0riexvUqvduRy2ndSevO2A+8nhl6nDWo8tMqP63y0yo/zYf3+FDP h3o+DMR+GpbpgPU6YL0OWK8D1uulN82GN3jUzKNmHtXzqJ5H9Tyq51E9j+p5VM+jeh7V86ieR/U8 qudRPY/qeVTPo3oe1fOonkf1PKrnUT2P6nlUz6N6HtXzqJ5H9Tyq51E9j+p5VM+jTh518qiTR508 6uRRJ486edSpQ9I6JK1D0jokrUPSOiStQ9I6JK1D0jokrUPSOiStQ9I6JK1D0jokzeN6HtfzuJ7H 9Tyu53E9j+t5XM/jZh4387iZx808buZxM4+bedzM42YeN/O4mcfNPG7mcTOPm3nczONmHjfzuJnH zTxu5nEzj5ujGg4mOZjk4E5+v8bFHZxr49x2zvVxro9zfZzr43+C/89zL829dOxu793L6TlhPge7 OdjNwW4OdnOwl4MD6mQRF9u52M7FNBfTXExzMc3FNBfTXExyMcnFJBeTXExyMcnFJBeTXExyMcnF JBeTXExyMcnFJBeTXExyMcnFJBeTXExyMcnFJBeTXExyqY9LfVzq41Ifl/q41MelPi71camPS31c 6uNSH5f6uNTHpT4u9XEpzaU0l9JcSnMpzaU0l9JcSnOpnUvtXGrnUjuX2rnUzqV2LrVzqZ1L7Vxq 51I7l9q51M6ldi61c6mdS+1caudSO5faudTOpfboI1zKcilb6Mb/dmGICwNcGOBAlgP5+6YB6g5Q d4C6A9QdoO4AdbPUzVI3S90sdbPUzVI3S90sdbPUzVI3S90sdbPUzVI3S90sdbPUzVI3S90sdbPU zVI3S90sdbPUGaDOAHUGqDNAnQHqDFBngDoD0dEmw7smw7u6P209L4/dLYt7ZFGI3vOHMNd6/7B1 e5Jd3YE4CB/CZByMKhyCbzrmclyBb+HbsIOk9TCth2k9TOthWg/TepjWw7QepvUwrYdpPUzrYVoP 03qY1sO0Hqb1cPRtWnfTulvEaRGndUFKF6R0QUoXpAr6/70D6P4/Vb4dfCz/y8b/vtq7+dHNj25+ dPOjmx/d/OjmRzc/uvnRzY9ufnTzo5sf3fzo5kc3P7r50c2Pbn5086ObH9386OZHNz+6KZimYJqC aQqmKZimYJqCaQqmdUNKN6R0Q0o3pHRDSjekdENKN6R0Q0o3pHRDSjekdENKN6R0Q0o3pP4vuiHF oRSHUhxKcSjFoRSHUhxKcSjFoRSHUhxKcSjFoRSHUhxKcSjFoRSHUhxKcSjFoRSHUoU1vr/wbyFP 5VWaV2nTJm3aJGmfpn1e4zSN0zRO0zhN4zSN0zRO0zhN4zSN0zRO0zhN4zSN0zRO0zhN4zSN0zRO 0zhN4zSN0zRO0zhN43yOaTmm5ZiWY1qOaTmm5ZiWY1qOaTmm5ZiWY1qOaTmm5ZiWY7oiXwszcANu hHqTY1qO6Wgvszjzjz2j0u4udHrWTM3+n3rE3v0Ge1R3protodtKdNsWnbavTiuPpr8/UWZYjWfi Fvflt7vWXaFfZfc7Oqc3+63OQ846jsJZCg99YNfUr7r7VXe/6u5X3f2qu///07TpV339qq9f9fWr vn7V16/6+lVf///TXVH+biVHqWXv37cMRfHR93Jc2h19gbYNtG3gXy//emmbv7Np48QY+nbRt6sw /+Z4/XP3CA/aKc313sOhi65ddO2iaxddu+jaRdcuujbQtYGuDXRtoGsDXRvo2kDXBro20LWBrg10 baBrA10b6NpA1wa6NtC1ga4NdG2gawNdG+jaQNcGujaoqV411aumetVUr5rqVVO9aqpXTfXSvYvu XXTvonsX3bvo3kX3Lrp30b2L7l1076J7F9276N5F9y66d9G9i+5ddO+iexfdu+jeRfcuundV5POc gRtwI27CzfhB6CpovGu0E3LRPrGF0YTYq3acr6nL18Os2LLwdGynfUYmzIntCk1xkzN+rLvX48Nz 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 6mtSfU19S6qvqW/br9nvqEvspfY6daW93v5c3WR/YX+pbrE327vV7fY39o/qPqnKph6RqmzqUdtx KerPUpVNPS5V2dRfpSqbprjiXbU0r9Rj06JdKa7GWoyrmau5luhKd6VrtV2tXK20Oq7WrnZaXVe2 q5PW0NXZ1VlLdXV1XaVd4urm6q6lua519dDSXX1dN2mtXAWuYVprdx13fS1LqrtpHaW6m3a1VGvT ukm1Nq1IqrVpxVKtTRsl1dq0sZ7enlu0efKpPe1tqdam/VtYIlxbJXXatM/EzeJ27YDUadNOSJ02 XZc6bbolddp0t9Rp0z1Sp02vIXXa9CSp06YnS502vY7UadObiTlinp4qddr0DKnTpreVOm365VKn Te8gddr0jlKnTb9a6rTpPaVOm3691GnTe4vtYofeT6qs6f2lypo+QKqs6blSZU2/Xaqs6XdKlTU9 P0wNs/WCMBEWpt8TFhUWo98vldX0B8KOhB3RA+EUruilpCo7gHphiPjCKYIUisSfRlFYh3WKw9pt YFVvAH9D/FnUCKugTalASRfwsB0J4KH8Pw/t+T9gSMQMY8QMB2L2Qa2++IsEbg5AiwPpFupAtwJD OwJDh4E53I2/TjSc7qcaVIy/WPJTAD2XAmHjgLCC4hWvEkYJ/IRwohIBzL0EmNsInsZKY0pTmihN 4W+mNEM+FVgcz1jcAljcA7YnELkL64XGKwOAy+mMy+mMyy2ByyPgL1EeoQxljDIGbY4FUicCqZ+g TGWC8jS1ViYBtVswardg1G7BqJ0G1H4J+bnA7jRg93tYD1YoK6id8r7yEWUpq4Dm2YzmKtA8A7YV MN1kTI9gTFcZ0yMY02MY069gTL+UMb0NY3oSMP0lqq3OVedSsjpP/QfVVecD5VMY5VMY5esA5ZfA /h+wvhZjfX3G+mRg/X9gVwPx6wDx18B+Atyvxbhfi3G/HnBfUAPNC/RvyOjfmNG/EdA/jppq8Vo8 NdMStATqLFcC5LESUBOsBI1gG2tNUAvrAaXK9QC12mptYdtp7bA3W8uGba+1RxmsDbBYG+CRz1pf yc9aX8XPV1/Jz1dfxc9Ud8U6UUrt9ZH6I6RgtZhA4fqT+iS6TJ+sT6Fo/Rl9GrXVp+szqaY+S/8H xevz9dcpASvKG5Qu1UQpQ64rlCXXFRJyXYGNMCKooxFpRFILubpQOlaXT0kzPjM+ozrGemM9hRuf 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 RhxjepCQf+trEnXuw1TDbdliqW217VOxyv6c/Tmx0xF1vCA+SfhYf1ize27z5Ghvex7yatr7vm6+ m2w3+O70rbRVJeYn3m37c+LSxOW2jUm2JJfto6Rvk761NQnt3mxpG/3jxHXnTdtIOxP3dEqfW2nb edKRpD7tqR9pFGkcKV+lx89OiduSnk1a222FlZ7ulFardOp8qbuj+4T2tKz7Y+3pqJl69DpPGkTK 8D/RKa00k3pyVvL/2v9ee3q/52ekvSq1ni/1GNTL16tf72VWerRTekKl986b6nufaksp/pS09nSj lSacN2WrNNM6d0011lGW26zSzvZk1t6TcjT18tT81JWpr8h0duupa8+XzNZT/5jabKV4R5JvST2l 3lUj+f6k/hnt6dr+49vTLCvdRYr2v2vAQNKoS/tdmtn/Lo79Lv39wD9dtk2lLwdNIeUPTiMFBjcM PgwNg49f/qchj8s0uGHIuiF7SCfTbemu9LWk9zNGkG7MmDJshZXevCI6Mm3krlEPXjWINGK0b/SU 0eHMl6y0LvOdzPfH9CWlj4mNrctqkenq6qvXqvTluL7jnrDSyqu/5PqJcY3qqnHcV6QnrvFfG7t2 9XW9brqWtPnm7KurzdKcG81Stw6U5W4dNcGDUQdOWDExSaXMidNVik+yTUqZ1G9inFw2qXCymKxP zp/cMrllSp8pByiXOfX2qbdPyuaYK3OkoqmRqTXZukrp2VNUCmaXQDC7Mvu+7EqeR7Ibp82ZFpx2 fNrx6d2mr6RcOs/Uk+knsytvy70tPGP7HTfOavjhih8+/cPV8+6b11g0s6iy7Vz0WtFroeElj5Ws KmtZIBaMWxBccPeC6IL7Fqxb8N6CzxccWXAyokf8kcsjoyLXR7IjR8q7lQ8sLytfUr6ifHP53uiY 6O3RN6N7K9Iqdlacig2PFcYqY0/H3lqYtvD2hW9WFlU+WvlW5fbKvVWeqj5V46tWVG1bNGDR+EVF ixYtWrbopUXrFn10j/+e8fc8dc+b99RV69Up1ROq86vXVn+5+PLF0cVrF+9d0nfJqCV3L3l4ScNS /9I5S19ZeqCmT81fviNqrTs7MnWNOzWfdyQZUe5N6khmLPmO2Tfh7DnXdaaYY/288actBnVKXaPI vaM6kowP917fkczIIKNpt9Upm3s/QUTeOa6R+KmisToTebtPINI+nvRstxWJ29qiZ/fHEnd2P9p/ lqybuC7p8Y4oalqJOD1ORWKzVJ+kZ9usJ++qqCzL7pTPVXnLgrS7LnEPMf1ZauxUrW1D3QrOO1Xq WCc+P2t9GNdpRehYE56Vus9ZB1afvQ4Q+x1W3F/WFvFVO9ROGkf+8bZYiD9esfxFdDIjkBnhLD8S FYmB0muz2uNjm0eJcikTZPkOD/cfTzvyeZz72anNXJ8zGoiBOztF0/PE2M4x9dx4akXtzWocmRH0 2rbYKWM6d8bLdrken5J91aCpt/dsNVcydWbV6n2Ktaq1l491yFp52laUHr16tnasPuZ4lOubLN+z VZag9nu9fPKJvKPWMu7IZz16JW5rG6cpaTzfyxtoo/cydaXud6yonddUqUmtn20raPsayprpO8+a +cQ5a2a9uVKyRvrb+sLzU6YOpWTZxMyen6XciLYu3pBWPHvmtlncnJHStuaI6T8L60+QvpV2Scn2 P6E8/4r0VKfZnZG6tkev9rV2p9VqjTkepF/M8ZW69tJ+AwaamKvagIFqJeqU5KpmrmhqTfw/TGod 7ZTOLaFW107JWmXb07k11Or6byW1/l5wal+lvyOdbSmZ2tfu70hqNb/gpHYYF5jOto7al3RK59pP 7Vc6JTnSTU//e+nclv+1ugtLpp3lfiXp2ayWCZ6rv0zcKXc6KlXLO1ktcncjr66unuCR+x7zmUzs mtLlTsm8q9air8ykdkTXqt2U3Dc1jmtUeyK5b2qkRrXaj+jt+xaZ0rP1qbnZutyzqKt0a2dj5tPZ 9xTJO2p3Qz15lkmWp4auWguqp+nymLqW0uly/9TLNzFpaq7ca8l9lkqZ6k6S3Gepq8ypuTISWc9I MkzIHZnaodnU3owky1ND7uAoKXdjHfuziZnjvlL2+FJaYtpx0w5ZLao36DV1TsqWLav9nk22Zbbb dR6e68/Oo+CybeaV0LVaY7t9svFr+Xtr8vfV7BHjoP0vYrCw8eQDrhpV7rD6DUdN/VajTf42on2W 8THfzdcYLWKj0aIFRX8tR8zQcjnniUFavuirzZf/r7cxjZJz7WFjq9Bo5wvhoGwyZftSNpmyHtXe YUodE27tLpHG86E8n8vzYTwfSlsjaGsQtV9Werzk3kRvX3u1sd6+2HgevSPt+40X7J+LofYvxAj7 QZ4dMhrtX/Ftt01ts/xNTuNi+RuQqFlDSx+LSpEsrhTdYIy4RIyFfNovgEIoN3aLKKoqIAYLoRKq +Ia7yNgk7oFqWAxL4H6RKpbBA/AgPAQPwyPwKPwIlsPbfAN/B06SbwVDpGoCNMgWmdo0mA63we0Q ElO1zaI3PZ5rnymy7HcKn30uhEWJfSk9vVf0t98v+jqeNzY5VsEL8JFIdXwMO+ETaIBPoRGa4DP4 O+yC3SI1oZvRmLDX2JTwD+FIOEz+azhqbNITxJX6YM4jxSX6VZzDRqNeDCVQChXGbj0G2EbHNjq2 0RcBttFfF5n6OvgDfCsynZeL3s4hMFekOoOQCwsgAlVQA/cCNnKugJ/A8/CCGORcw/lrOAJH4Rgc h28BG7ryIB8KoEL0dguR6faL3mrsHmFce1TuEF4/KXoyarcxarcx2voz2iYy2u5jtM1htM1ltGUz 2m6htPwdsevtMxkrdxivyd9vZdw8TAtR+1+Mp+37GWdfCI/9gPFX+yExUY2zg5Q6ILq3z4q7RFan 9ufSfjntz6D96yida7Utf5PpatpeRdtrrPayRVKnVjy0MppWSmgli1ayrDkxGpUHaek2WvoJrWTT wl9VT/+gcim08Wfa+DNtDNLmGu/QThbthGhnIu3MoZ3xWsj4iLaytKeM31HzXdrrQXtVKCunzTSU VdHa4/Zm4xjqNtq/ZGYdYsx9Zc3YxE4zdiitjrBmv5yxn1BzNzNvsvEc49drRhj5M13uN4lfiPuN w2IZPAAPwkPwMDwCj8KPYDlsM06LD6AOPoTtsAPq4W/wEXwMO+ETaITdRqvYA/8Fe2EfNMN+o158 Dl/AceNT8Y2xT8ThBLTAt3DS+ET8L+b0KTgNZ+B/QytaDOOwJkBTUfGAfY5x1P4fRov9Ls5Bo8Xx kXHY8THshE+gAT6FRmiCz+DvsAt2w5fGacch+Ar+AYfhazgC/4SjcAyOwzcQB7Q4WsFgzvYw6p3X GqedN8EEmAhTjH3O2znPgDk8vxPuMjY55xqHnUHIhfk8W8A5AlHyC6ESqriu5lzD+V54kPxDgB+c P+a8gvNP4Kfkn4CfwZPwc9p/nvsvkl9Nfg3518m/C/jIiY+c+MiJj5x/N1qduwAfOfGREx8596Jx HzQDPnIeMj51fgX/oC+H4WvjE+cR+CdtH6XtY3Ac4pTFd84W7n/LNT5y5UE+FOAvm3hM+PHUKWEX jxlN7atXAldvcyV/e3wxo7zRvkP0Exp3W8SNjMwGRmYDI7OBkdnAyGxgZDYwMhsYmQ2MzAZGZgOl 9zDSTjPSTjPSTjPSTjPSTjPSTjOKDjNiWhgxLYyYFkZMC+/7kPfttf+QmZADucYX9jzjC0ZNA6Om gVHTwKhpYNQ0MGoaGDUNjJoGRk0Do6aBUdPAqGnAky14sgVPtuDFBrzYgOda8FoDXmvAWy14qgVP NeCVBrzRgNVPY/XTWP00Vj+N1U9j1cNY9TAWbcGiLVi0BSs2YMUWrNiAFRuwYoOasR8KJ7bMZCbr rL3PsfY+Za8Xl9j/JnrYWW2UfQ9a9t2n7PsIVz/g6gbsWyn3FmIW66SfddLPOulnnfSzTvpZJ/2s k37WST/rpJ910s+bhrJWprFWpjFn9zBn9zBn9zBndzNnTzBnTzBnTzBnTzBnT7CeJjNnm5izTczZ JuZsE3MWfxNtZ4pBzNOvmaeHmadfM08P23NFuj0PwiLfWkcvZh31s3b6WTv9rJ1+1k4/a6eftdPP 2uln7fSzdvpZO/2snX7WTj9zsYm52MRcbGIu7mHunWDO7WHO7WHONbHG+Vnj/KxvftY3P+uan7nS xNrmZ21LY640sb75Gf97GP97GP97GP97GP+7Gf+7Gf8nGP8nWP+SWf+SGf9NjPk9jPkTjPkm1kA/ 65+f9c/P+ufHU7OMr+Wop4/MbXZpjxG9Z7B2zTT2ENWf4fnD+ON3PH2JMT/C/hF5ZqX9E9Yx6cNP Kb2bUo1E6seMJVxVUbeJuvJuvrUOfkjdodTdTr3xQqfkS5RcTMlmSv6X/A19tcuSI+c11dKdPJ/M 8+08l2PkelpaztMXaGkQLW2kpXRV/rDaLe5XxxbWv2T2gnMgDMVQCmWwACIQhUfFMNFdq1Vz/Vla f1y+XXl2FbwrRtnXQzP73P1iPHvFZNZvP3vFVPuXnA+xs/qKe/9gZ2an5nZq9GJnmSpXduqHRRbr 2Bz2XXeKbPtdag+WLf8pFta5ORCGYiiFMlgAEYjCo3L08Y472bHdxXmuKFE1/dT0U9NPTT81/dT0 U9NPTT81/dT0U3MENa+j5ghqXqdqJlMzmZrJ1EymZjI1k6mZTM1kaiZTM9mqOdGqKfcod+Kxucwr aeN31E7hlPwbN+TvC7KWT4PpcBvcLtzs4Nzs4Nzs4Nzs4Nxu+TuGDiws/3aTu+XfuaH249JHn4ud 2iBjvzYYLochkA5DIQOGwXC4AkbASBgFV8JVMBoy4QcwBsZCFlwN4+AauBaug+vhBrgRboLxcDPc ArfCBJgIk2AyTIGp8LTRrD0Dz8JKeB5WwQvwIvwSVsOv4CV4GV6BV+E1WAO/ht/AWngd1sEb8Cb8 Ft6C3xnfYJFmbb2xW3sPNsBG2ASbub/FaNDeh62wDT6AOvYTH8J22MG8ncPIvcv42LHJ+MaxGbbA +7AVtsEHUAcfshpshx1GQ0J3oznBb+xP6Am9oDekQKqxX/8x/MJo1rGBvtI4rL9kfKO/DK/Aq/Aa vMX9DZw3wiby9UaD/jHl2bfoLcZ+5/eNZmdfuBgCcInxjbMf9IcBcCkMZOW4DAYRtwbD5ZQbAlfA CK5H8mwsq00W5+nGNy6bsd9lBwckgA5OcIEbPOAFHyRCEiRDN+gOPeAi8BvNrp7QC3pDCqRCGnwP +gD6Xeh3od+Fftcl0A/6wwC4FAaiaQT7hpHwA1a+MTCWe9fCeLgZ5vK+XM6FPJtHuSIIwd1QQRuL YQkshRrK/pj7v6T8y5R/xdjtepXr1+A4904Y+92a0eymr+6LjAY3/XD3NA67A4yhSs3GaLGDAxJA Bye4wA0e8EIidDMOat2hB1wEfugJvaA3pEAqpDHC+hpfaxdDAC6BftAfBsClMBAug0HEmsFwOQyB dBgKGTAMhsMVMAJGwii4Eq6C0ZAJP4AxMBay4GoYB9fAtSDj2fVwA9wIN8F4uBlugVthAkyESTAZ psBUyDYOadNgOtwGt8MM+jcT7oBZMBsW05clsBRq4F64D+6HZfAAPAgPwcPAtw5thXFK+wk8Dj+F J+Bn8CT8HJ4mZj4Dz8JKeB5WwQvwIvwSVsOv4CV4GV6BV4HVUFsDv4bfwFp4HdbBG/Am/Bbeglpi +Xp4DzbARtgEW+B92Arb4AOoM44QRY4QRY4QRY4QpR8iSpeyDqQS+bNYB1KJ/llE7U8dRDwHEc9B xHMQ8RxEPAcRz0HEcxDxHEQ8BxHPQcRzEPEca42vHa/DOngD3oTfwlvwO/gjvA3vwLvwJ/gz/AX+ CrWwHt6DDbARPhTJju2wQyQndBeeBL9ISugJvaA3pECqSNKXG1/r/0kU+jH5J8k/ZRzUfyE8Oj4g mh3RV/GMvui/4hmadTTraNaJ0vrrxiF9HaBXRy9R7oj+e8r/gXtv8/wdQK+OXh2dOjqJfkf0LZTZ xrMPuK6DD2E77IB6kax/zLv5hqfzDU9v4N6nxiki5RH9M7TxrU4/SN1/kD9Mnj22zh5b/yfwzUU/ Rvnj8A3E4QS00LdvjUPOJONrZzJ0g+6QYpxypkIafA/6wPeFx9kXLoYADGRXeBkMgsFwBfdGcB4J o4i8o2GsccSZJZJdNpHksoMDEkAHJ7jADR7wgg8SIQmSoRt0hx5wEfiFx9UTekFvSIFUSIPvQR9A pwudLnS60Om6BPpBfxgAlwJxxjUE0omIQyGD/HAi5xXkRxhHiMRHXKPIXwWjIVNGZvoxBiaRnwxT jIOuqdSbbZxyzUVbIc/mUa8IQnA38E3Xxb7StRAW894lsBRqKP8I72POE6mPuJ7k/BRt/QKehmfg Zdp7BV7l+Wuwhntxyp2g7mnjlFsYh9ya8LhdRG5s6PZw7s79i0Qy0fyIm1XJ3Zt7KZBqfO1Ogz7y J5Jydlt7qUeYlc1qX/bX9vvL5N9Tpn6CIvdYx0SC7RZjpn2y/MmU8Mifaqln6bbhxgHbKBhtHLRd w/kWY6ftVmOTbSJMNuppqZEdxQF2FAc8s4xNnjnwEPmH4RF4FH4Ey+E/4TH4MayAn8Dj8FN4An4G T8LP4Sn4BTwNz8Cz8ByshOdhFbwAL8IvYbVxwDfEOCDsKG2xzeLbsNQ/Fv1x9MdtY4xG9MdtN3B+ xNhne9TYR9wKELMClNzkuc1o9NwOM+E/IM/Y57kbwlACZRCFh4w4fYvTtzh9i9O3OH2L07c4fYvT tzh9i9O3OH2L07c4fYvTtzh9i9O3OH2L07c4fYvTtzh9i9O3OH2L07c4fYvTtzh9i9O3OH2LeycY +7wTYRJMhikwFbJhmrGPvsfx4WjjUzzUaFN+NN5VP4u4mL6vod9rbHca79ryoRgeMbZig63y2wh9 X0Pf19D3NfR9DX3fSt+30vet9H0rfd9K37d6Ko13PVVwD9wLDxjvomsruraiayu6tqJrK7q2omsr uraK6/BADA/E0HYAD8TQd4oRdIwRdAydn6GkGSXN9hmt36I32fo2M9T6NjPU+hlhI6PrGKPrGOqa UdeMumbUNaOuGXXNeCaGZ2J4JoZnYngmhmdieCaGZ2J4JoZnYngmhmdieCaGZ2J4JoZnYngmhmdi eCaGZ2J4JoZnYngmhmdieCaGZ2J4JoZnYngmhmdiWKAZCzRjgWYs0IwFmrFAMxZoxgLNeCYmbsAK QawQxBc7sEIQf+yw3SLS6P1sej8bb2Xw7fUF6zv0SGtdHWatq8Os78VBfLUDX+3AVzvw1Q6sMRtr zMYas7HGbKwxG2vMxhpBrBHEGkGsEcQaQawRxBpBrBHEGkGsEcQaQawRxBpBrBHEGkGsEcQaQawR xBpBrBHEGkGsEcQaQawRxBpBrBHEGkGsEcQaQawRxBqzscZsrDEba8zGGrOxxmysMRtrzMYaQeFk LByjx4Pp8RJ6vJge96SHpfTwTpGKjd7APm9gm3psU48dkrGB/POj1+j/G/T/Dfr/Bv1/g/7X0/96 +l9P/+vpfz39r0dHPTrq0VGPjnp01KOjHh316KhnroSwdNd4d1wMtU1jlM4i1oWIc3cT4+ZDGEqM T9RPLtpi3WJixlJjk/ce44C3GhbDElgKNXAv3Af3wzJ4AB4EYqOX2OglNnqJjV5io5fY6CU2eomN XmKjl9joJS56iYte4qKXuOglLnqJi17iope4mOQGD3iJeZr66ZfUHmeONzHHm5jjTdjNi928avZU Gk3M3SbmbhNzt4m524T2ONrjaI+jPY72ONrjaI+jPY72ONrjaI+jPY72ONrjaI+jPY72ONrjaI+j PY72ONrjaI+jPY72ONrjaI+jPY72ONrjaI+jPY52GbNmGbuwdiMWfrc9Zske7RIj6NFqnn/B81N4 owVvtOCNFsp+9t/E3Xuc3HV97/Hfzkx2k8kuoxBuiiAFEWwpCmJVtEovRmtRtNWTgxVtDUoQQSEB FuUiidxJCJAARhHqGi6haJXYZmMTl0uaEBmWLLtMNJNsQpyZZSczO7ubDVk03/P8jpGDPe2jp4/H efT88WIu+9vf7/d9f67fITsfx77Vse8RKVkrPV6kZK32eH50S8z9LDTBQhNW2WWVXVbZZZVdVtll lV1W2WWVXVbZZZVdVtlllV1W2WWVXVbZZZVdVtlllV1W2WWVXVbZZZVdVtlllV1W2WWVXVbZZZVd VtlllV1W2WWVXVbZlZxqJZ1s8zTbPJ2akxzCPk/H75wUAVUR8IKV3GIlR1jJW6zkCCt5i5UstJIf sN3TbPc02z3Ndk+z3dNW1WlVnVbVaVWdVtVpVZ1W1WlVnVbVaVWdVtVpVZ1W1WlVnVbVaVWdVtVp VZ1W1WlVnVbVaVWdVtVpVZ1W1WlVnVbVaVWdVtVpVZ1W1WlVnVbVKY5nNeP4nVaxySoe3f//Y2Nf sTyZbr0brHeDtW6wroOt6WA/+b71bLCeDdazwXo2WM+GpDU1j40v4cGXhqHUAr99i/qwJH7G7t29 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 d+ObWIZv4du4B98JM1XOmSrnTPuubvuubvuublU0q4pmVdGsKppVRbOqaFYVzaqiWVU0q4pmVdGs KprVZzb0mQ19ZkOf2dBnNvSZDX1mQ5/Z0Gc29JkNfWZDn9nQZzYyu0M1M4E9eAl7MYmX8SuICZV5 vso8X2WeqzLnVebF9n8F+7+C/V/B/q9g/1ew/yvYJRTtEop2CWW7hKIKPnPKztCwUyjaKRRV8rkq +dwp7mmKe1LRZ6roObuG4pR9XofQaE3QghTSSU6lz9lRFO0oinYURTuKosqfU/lzdhZFO4ti6xGO fQOO8d6bvD4Ocq1dRlFnMFNnkGt9q5+/zeMpyTF2HUUdwkwdQs7Oo2jnUbTzKNp5FO08inYeRZ3D XJ3DXJ3DXJ3D3FZ5tFUebZVHWy/GXMwLnbqJzle6CTnUfragk8jrJPKt9yTZ1u8nh7f+AI96/k8e n/TYG7p1GflWtrTvLbTGb+R8Q8jrOPI6jryOI28v3G0v3G0vvNZeeK0OJG8/vNZ+uLvttCRrT9xt X9CwL2jYFzTsCxr2BSVdyir7goZ9QUO3sli3srjtb0K17dM4O8y3P2i0ne+5mGq7ABfiy/iKc14E 67J3KNk7NOwdGvYODR1OVoeTtYdo2EM02m50/E3NbzZs6Hqy9hMN+4mG/UTDfqKhC5qvC8rqgo6x r2johObrhLL2Fg17i4a9RcPeomFv0bC3aOiQFuuQFuuQFuuQFrftdO5fogS5vk2u1zX9UNf0Q13T Kl3TKt3SfN3SYt3SKt3SfN1S1l6/YK9fsNcv2OsX7PUL9voFe/2CvX7BXr9gr1+w1y/Y6xfs9Qv2 +gV7/YK9fsFev2CvX9B15XVdeV1XXteV13XldV15XVde15XXdeV1XXldV17Xldd15XVdeV1XXteV 13XldV35qSe7p1PwrtA99d34jHN/zuvZOAef994XPJ6LOTgPF4ayDi2vQ8vr0PJTr/Y7i7x/v2Mf CGunPuj5Q9gdCtOS5HAdXH6atU07KHRPOzjJZv8q9GXtC7OfxKwwW2c3O/s3nl8WqtlOfBW/7fS+ 7vk3cF2S0/HldHw5HV9Ox5fT8eV0fDkdX07Hl9Px5XR8OR1fTseX0/HldHw5HV9Ox5fT8eV0fDkd X07Hl9Px5XR8OR1fTseX0/HldHw5HV9Ox5fT8eX+P3Z8ud/p+A5OFoYPtJydnNXyWfxtclnL3yV/ 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 V+2sBsJdrgBoSBfDnjRfhJ/ofjb2Sf5wrWmKJtNa3shpuBwgQ0tj7rpmbIaubesn8/ps6jUOWQ6t /qu/kO93A5fr9LFol5ciu5G7k2MvbSvxwvHl6JQnFa/htsGCmlV7tcpZRna1mM0rtsnpOrVjt/Dh MSraC7P9KXN07iZHmXmO2rxq0H2FcjDNur90wW4RpzB61x7/cSQs/Nl7wN8BTx4S+w0KZW5kc3Ry ZWFtDQplbmRvYmoNCjI0NiAwIG9iag0KWyAwWyA1MDddICAzWyAyMjZdICA2NzZbIDYwNiA1NTYg NTYxIDQzMl0gIDY4MlsgNjczIDQ4OF0gIDY4NlsgODMzIDQ4MiA2NTIgNjUyXSAgNjk0WyA1NjNd ICA2OTZbIDYyOV0gIDY5OFsgODc0IDYzMV0gIDcwMVsgNjc2XSAgNzAzWyA2MzAgNTMyIDUyOV0g IDcwN1sgNDk1IDU0N10gIDcxMVsgNzI0IDU1MSA2NThdICA3MTVbIDU2OSA4OTddICA3MTlbIDc5 OCA1NTNdICA3MjRbIDU3NF0gIDc4MFsgNDk0IDUzMl0gIDc4M1sgNDk1IDM1NV0gIDc4OFsgNTgy XSAgNzkwWyA1MDNdICA3OTNbIDczNyA0MjcgNTU3XSAgODAxWyA0OTVdICA4MDNbIDUyNl0gIDgw NVsgNzEzIDU0NV0gIDgwOFsgNTM4XSAgODEwWyA1MzRdICA4MTJbIDUzNyA0MThdICA4MTVbIDM5 MF0gIDgxN1sgNDc0XSAgODIwWyA2NzVdICA4MjJbIDU2Ml0gIDgyOFsgNzEyIDQ5NV0gIDgzM1sg NDk4XSAgODQyWyAzMjZdICA4NTNbIDI1OF0gIDg1NVsgMjc2IDI2N10gIDg3MlsgNTM5IDUzOV0g IDEwMDZbIDUwN10gIDEwMDlbIDUwN10gIDEwMTJbIDUwNyA1MDddIF0gDQplbmRvYmoNCjI0NyAw IG9iag0KWyAyMjYgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMzA2IDAgMCAwIDUwNyAwIDAgMCAw IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCA2MzcgMCAwIDAgMCAwIDAgMCAwIDAg MCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCA1MzcgNTAzIDAgMCAwIDI0NiAw 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 oxYOtbccJlfJ9HBNcNN5P/aiN93lQgsaS5yG6k7WeesRXHox0yK6ychWWkNTqzp5DXq47EXJGJeO M9XxlV1fNs6tuvM293BaecqwhnYTVveqMC59ddNtlc+jsAvZh1Jnavay38vEsbmFCbv7OTw4eNfK fsAzp4IPXdekzo8pdpgm82sREDlhf8Uyje3RiRfLTq2qVtGkGx8vODH9TOydsd2iTtzxbD4q987w mrZPRjp5mznobjextqz0XOpG+X0YWRwy5n1esMz3UW5ZQVb30xWlXdacndV8Yzth/13H0oUDpltW VfnL1WquPPZXlld1Ne+QLGu/1nbjtsl2Ve08PPMyqKZCBmXxvY9kygxKB3ZpEK+c+V9TAT9fkajn kz0E/fouyX5fWcHw4d+O0Eq12lk2pavS1dnN0S38Dx4ZeyCpc5nT8Yruq/ptMogOTDBy7T/id3gt +kp4yfTl4Xe6KS96vtVrPCD34bbjfm+PtGyBvFI8Fj12+9Cvm6bJnqJbCy3ajCwPPTPL/x53pmZF gylTn9wPXZPT62DPykcxrRtOH3l96PbmhgHqYaOGaGUf2LG5R7FF0yI6rqJE1sO8qL1wYMqmGA8q ZVAxatW00Pbogb72Lqcv3662097RZY6Xypucm23tbdBC71ZPxntNXugbcag6ZHdWyTiFtcL7/JCd +atP4/Jd7UL9Y683/DL2y/3b1yM2pJtMXe8/52jxPfuI4UZeG2t2uC7q2GNH4IfBEbPmt95xe0H6 6EluPk8fn5/zRBLfubFcp3H3G3t8b3hGdlm0uqx3j2cpDrdW9Er/fHPU6Msf0f8CqD9ATA0KZW5k c3RyZWFtDQplbmRvYmoNCjI0OSAwIG9iag0KWyAyNTAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAg MzMzIDI1MCAwIDAgNTAwIDUwMCAwIDUwMCAwIDAgMCA1MDAgNTAwXSANCmVuZG9iag0KMjUwIDAg b2JqDQo8PC9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVuZ3RoIDM1MD4+DQpzdHJlYW0NCnicXZJPa4NA EMXvfoo9poegu5rSgAiJRvDQP9T2VHowu2Mq1HVZzcFv33VGbKKQyG/2vXmDO35aZIVuBua/2U6W MLC60cpC312tBHaGS6M9vmOqkcNM+C/byni+M5djP0Bb6Lrz4pj57+6wH+zINgfVneHB81+tAtvo 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 udu/dqHX2775q9CxNbVu4aLlsq5f4v/Kt6TCv9lX4W1f+/T3JD8tJ6/1VbTj6cqZNe1Ply6pCKwt XVvpq6+o7bj50HmX9CvrynBZ5x36nswOyZmdJ5d18yXfk3yJnHyzXNYlclmXyGXdXHozL4tVniG7 gqk17RqMrS2fG9Qdgl5HE7suNrF2rNPSMIbP8lMS3Wtidyrkvz2pp4OiwTfWb6RbTsoqyyqTk+iY JCeZ5A8lQknuNackxu5km0JJFnpsJTfTr3cbI/jUGMGCRrJaLSc30tCsbsxQPgmVcjXsyguhE/1w Sl9Jh+n+QPpSOtL9jfSuMgBfzwQ6qqkA5To64o344f8yLv2A/PQnWUE7FgWwqB80monp5KS2QElL 52e4gRyviuKzqIdU2EmriUiLqwo6SPg1bpWewiWwYgRW4Hxa7y5AGzaI31AOW1km5aDFQvyWtm7Z +ITlSvdiNtOyUjjIfjSuwtesRPoN5etiBmmD9CE9nU47hy3owAN4FG8zxnIohxjaxy/CSqrJvegW 98KNBAzDOEzGVEpZQGnn4Goq9wb8Dl9QrUQUoowOLyupNpuwT0iTcqXHpUPUhqVUy2txE/ZiH17H YbZPmCv5pa3SozDDRnlOwhRq/SwsRgvW4wl8yRysRFwv3ijV0ftUT6qLBylUz0Isw9nUDy1U8q14 mHJ8Fi/gZbKfLawS1olLJUg6qY7e0VJPpaOIrmqq8RSq7TJciMtwPV2b+JuP4294D5/gU6ZnTlbK ZrGN7BNhstRGLTFQrUpRSa2dQi2ai3rqz2XUspVU9qXU4j/iLtyD7VT2frxN1/v4EB/jC2ZnHpbE hrARrIqdSfndKWjE6QqlwqK4T10rfUbHXpFGR4VkDOWfQo+kUiZQ2xfgLPyC+vMCrKVxvRybqc/l Ou6lEl6l3v2GjprZrJDVU67vCsuFRuF84SWxRXxQUaYYp9inzFGOV96pfLv7y573pGSpiq6Z0jOS /NdC5a/DS6De89I1hErNoUO9/KlxBbVtAibSNR0zaDxnUzuX4kyqx9m8Jr/E+VSbFrouRSu1+Ebc gjsh7zA3Ue3+B/fBT9dWbOPXA3gIT+JpvIN/4Eu6vmZq6lU9s1KPuFkc81KfpLNMugrpKmIjWQmr ZKexuayOLWYr2C/YxXRdQz22iW1h97I9bB87yHoEnzBcKBMeEz4UjoomcaK4VLxIvEfcKz4lvqXw Kj5URimXqXQqt9p97L2eB3r+IsVLa6U2abN0QDpEvS1/Zq7k/a2my0cMSqU+GIIM6oPh1P5q/gn4 FEyjPpD5Nwfz6dAnj/Ui3hdno4H6oon64SJcg9/QdR3viZuI8RtxB/XHFhqn+9CO+7GD5uiD2EPz Zx/1xDPEy2fxHF6m6wBx/nW8QdvfN+l6B+8S6z6j6yiN69c4hu7QHwgTmJJ6zMQs1GMx1GfxxKQU NpSuTJZFvVZMVwVdlXSNY1PZbHY69d6ZrJE1swuo79rYLexW3nuddO2h62n2LHuVHWIfso/Zp0wS mKARDIJZsAux1LM+IVUooGuMMFmYI8wTFgpLhBuEm4V7BL+wU9gnvC4cFo4IX4gGMUp0iW4xRkwS c2kMJovzxPniYvFssVFcJ/5K/IO4UdwkPiQ+Iv5T7FE0KO5S3K3Yr9hPHV+vXKe8UnmD8jaVXpWu Gqeap7pQrVKnq89Rf6jxacYSO7LYt73tM8TXK2k2FgrNPSW4ju0iTsyB/KUQv6WD8xbo2bmIwj09 U9kUOoxvpz6Kp2cumiFnUk8KOKcnpWcuLlLEKGYrrmY3sD3y96xjnHIb1uE24vJ9+BytZLeXWDyU jrMrWCGuUFqEz2mmfYGn6Ol2YvNuCvlxp/g1rqSZsIA85y/Y9UwQZrOr2HniEHYuW0ZlxuIT4Rz2 K5zNeogrjxEXjuEF8vDdzCTOpbw/Z7fjXJpBt4mr2SnwKCcqz6KD0Rx0ElOmk3d5jbj1PLHocmq3 IH8kKpOVPIQak9qVik52eQAq9QPscvlHYsKD20QROpWyk112vygKE7RqhRxkGK/p+NKdMdnyWfGk o8WTLZ8XT7IcLUZJsaW7+GgxBYflJloTrSkEjObDMa+451ipEt/Aq5D/SvEF0jvsIeVK6nU3kjog qIydwoFtdr3eySwUandGW17pfsnyEkq6D5YMy2X5KlElqtNSxdS0Anue0xGl8iWljhhewGaeKQxJ Tp9odBZFs0bf2Hnzxo6dP1+58qaenn/07MvQPsOuDjQXfvP6vHJ6TEnyz/AuEJ3CLuWVtAp4kNhu SuhkZ5XqnSpR+7FYEf2x3Usln3vQfYTa0k2tYKJcTr5cplqkUlO+FReiclVjhuWWqHPU+cN6bsxV leSGIuJ4NjXHN2na1OrUnB5/fj6bmj1kwtSp49KzKQYmHe7ZyJ5h0bRixN6vUDC1QY8dYhq5jZxu Zjn4ysGRo3Pcw3LtaQW2woJCl6BWGRPH12g3npNy8ZYRPRuT1jJ3sysnqefNo7HyTyLrqEc3sBTo kbCDWnkgoNKLcp9qxxvq2vhATaImHaEGRXYfgj02j6X09RDr6e6ZIxyiPQqt9KUWo8EkCDT0gihY dJZt6BS+3q4+TQdRsNssz76wHyVHS45aba6R2dlqpWV/sdxnBYX0r6DQmV+oUjOafGk93blVQl66 xmC6xDVrRFn3c8P1pst75s67V7nsjOjkMRq2fMPX11/uHSn/PetC6R3xSdoVyePjKbXE71UoHXsN xuguTaKlCzQ8RywH5abIjbFbbPJY2KwWQW6SQHGXMz+vsMBqSUv1JakKG/ffcN2uhec+f+3VT9d/ OaowfcyCnFOKMs5dcKZwG03inBvW9nzY827PGz17b7yKGdifeh7pebYovWYFG8Uu2nntburXeOkr sU15Pq1h1TtgE1K2Op1mt7lTKO9wK5LETjZ925DTUmBwPCgchSB8Sv3vY4sC0c/FdYqntOvTLQe7 3+62HOkmNr3TXVxyxGobmdM9LNeVNqKwgF+2EbymamVaalphcqFLJVijXE6X08McajnhfJ1uj9uu MSo1KoVZa+85YtQYNazpyxij0aiyRgcMhpZdYzvVhmKDVaexxt3NEg+xlESbZo1m/DDziiXm/6Xs S8CjKLO166uvlt67el+SdLo76e7s3eklnQ5ZCgiERRZDFkA6LLJJkDXsYRcRNRoVFcdREWVGhVF2 Im6oiOMMiP7DOKMo3tGEuXM1d9ALuHbxn6+6gzjL//z3yZN0VXfzwHnPOe9531PV4S7JLe35W8Kp 1KnhPeRXvCPyP2Hgc4Cwn9oqlo2iRztm2ec6VjGrbSvsaxx32+9w/NL+iEPjF/yGCqHCwEDmsxQo i9LpKEUPmn7IxOZ0ZfWgY6LS93oepXG4ENCD8aj1ffcZr6tAOEarKC1tPqR7HxUEhHc/uJSChFVf ukRiBxgupHrr+gEFOCNVUx6ikihpAziMsShJGZRLXkW8FsktRiNbxA2gWMw2Hl70vSttXzl3zDId 52vyKMbuX3TywiFpDvcFYu5Rq1TqN384plr0zreIXb16U71H/+g7O8YM/9Nz26QvpXsBrZbiklry 6/AQFYIKOw7xR6hlL1IIJw4y2RAQrjxsC3Tpuww9dNEhlSrosUGwouBhmTeDWq0rwJvzPzK/z0Oo B4tjLgCgS1QqqWykyG4Nw+jr2k9FgToSl9uSbakE5F0OmITcn0l77yXhx14Bsm+KuyC8CjlePkD6 JHOiQ+Q0EzvHu2ggGVLXAX+ooXLX/MXd2zeGhunM1kLzwm0L28QF+QXjQoZxj0898MasTStXjPjD /k+GrK8xoSnGh9Y90tm5XdANmsGsndo0r6xsGbvngYrgr7bMuG+oblTX5L5HN7lyHpTvaIBaeAfq u5gKU6dEk5JjuSCtKGALgvHQ8uDyEBvqwdFDDG9mSuFAtMARz/AME6LNXbS25LC+K/x66BgdhOJH h60U5VYCQtsOKRk/qZF8Ue9+Pc+lCYUoRqn3IYWvh77xMFVyhp9begxXUSq06ZDWLRDSjx9Og9mD ph7SWqNMRPgAyqYf0PwyKfSl/nKpuheOAciyTBF9RUCtvpy60AsDp5e8wJcVC6gY+CcJ70RuPogq KMKdHI/DcZsekRrizeneArT1aKALsxBH89YIrZTOf8iobkKF22b/wqpk9QtHcSCQmEnTkN7yEDTi tjHxT5TKPaZshUqhF78ZdcswNI3Nqj5LK180eMxdO1Insd5dXadQlL1gdqq4EbyKVihvUKg4pSMX 3UzvnSCNfxaTCsyFCnyOXQVafLOoaQ92Bmn36y7r62ZDD3KKaj2tY/P8akdhjp+UoGo9iFp1id3b 5SJdZzJ32Rn2zRJt1g857ys+KgznnfH20HkHTD8ALeUcoMLlpOkupXqBJi/1kvLrTRF4gsl+RFpQ rsoEEi5QwgXhAkHLFLuuIIGt4SBAivKnxuNxpigpuRpzB9+4Y+ay7oc21MwdVmgy6M6/dPAetZrR 9xxetVI9Ytnodz6Snrs6ZE2lFcUUlgdm7dx21+O+sO2Hne88ptGoLUOCWSN1PCMdLnafOXROOu5w bCGVOAgweQu60kkFqOmi1mIG05plsTFmPt/2ErhNE8WgfVChVBZSZGWpTaznTbU2/yO+kDqGRlEu ZDzcrUf6wgKIPpm6kJkREDbUQr9wXegwpdIzKjPFocHKUEwwAvnycg/avBB2uicDfnTD0pLqyd2H tq45seXdxa+iWe+2eAa5ZpxZuWvy9KXJG2dXR+g3lltcZ178fPvWLd+eRno07xN6dJ7q7itfLFx1 5jd33v9803ASXeLqaXwConMA694ogs9lTFCLXVYSmVGOTOV0Gt1vqlijVg4oBxlFla4g76NuGKEy kSaBR1MXqDqZPvuFVO9ATBANx6dHOhUJu5BFoBlezmAtwgNphUxa6f2Lymom33sI0W9tfXfhEelX nzXba+yL3lv2yyYIZsLMmjB9eJkVgjmPLLd9fQYm4/bPNUP9/N1XEb9ozclnb7/n+QnDSDSy2sAn YdrZqOIXKQ70BsVrQG8cNKoxlOG5I0rLSHtGeFSPSVVn5vX14sP0D0KkbTAIkaEZQYJPykpuyJBk auo1aYKo8Vf72HsBxXyq4SXKQs+ksuhvj2ixSHmwtwftOsIpMbLusfSgMaIOtRr8rnV6VZ2KVvl9 Gfz6LqdkVXnW+Y6zLgVc7AN20KE8dz4dEyhPGLhBnkBlOM9LGQSb1ROuYBc6nOaOP90tfS899CZ6 Ed22MbWWN/JavonTzPj1rItS33OPIeO8F/+PLRytifSgsX8G39RVFtRXhFs3Pp47Oij9WfpW+mz/ 02Q/P+Lqd1wW2wH+4H3xRr8L+SMVngrvJNek3Dnlc8RlJctKt0W2io9GHxJPuU8FThWcLD8pGstC oaUutzkUcbncoSVitVmMRMhDtVgthqpdETeXHQ9UNo+zvoRzwGFm018dUBmoHuwQS1TNTRGRpkIh F00Z3bYC2tBs9JlbrXkBbKTHxWnUTFU1to6vrsSUgqqzVV8BBW+rvnbwBpnR5BsBgCmi7uHH+ZPk ma1lxWVC8dYyRXHZG4RFKJjiFRlVY4oCS8BXjLCIBcYahyMVVB1K04qFJxhzQMhW+csSRF4+/QcI 13AWU+Z5OBuxWq9mVZwaIbWK01lWHup69uF1AYZFulmocy5CylvH3DgrUW8uGDrzkQNTnvpsk9M4 JnZgxJIbX+/ebOA5Ts9hhlZyOvOq7Ydu4puUPKvQlY37I1p16GuzllexTTw86QzXSQ03orXrfT4V nHO8wlg54b5nFv9Wul+v4ppolp/bt/duI6Y1ihHS+1vMOk7JN/Hkpoarf+WPQzYbkFm8YVnlssSW yi2Jj6o+GvS3yi+qvhikVFai4a31Ja1FWa0OQ6s+b6qHn8qyh5qpiV7P35tzJnojh5rLJnr1E1W6 Zr1vXnPRxDzxneb6iXk9Vx8UJ9iqEm5TTVXVEpvJbLOZHLFEYrHNAYeOmpgN1+c4HCaTnq4vKysq ohRVCWVVwoRFR0RtQ3fZztq+sGGbzcfGIqs8IZ/oo30jxUk1PVgUtarDbCsv8uN5mh85Qnj3PMzX vlSfcD5JOtUhj4rFwJS2hB1GLVg6+Er/JFlny4q3rj2xtcxOHsh1EuBW4TLZQ5NxIs+UzFxZTGRd LQIxDjwaKEPpaoDEIsp0rS4MZqPNheRU8/Bu2oFoDP3nx8BiAy/UVY/0YZ6mNZx73aqOrWsrqgrR ENR0x8r565dv9rIKhYp3rt+1fsPHg4bnqX7x9xnx+tHrpF9xuGDj7Nk7FE0MU7TqG+R+5M3lTq2g bMJ4/dpJqdn0XjSUZZsUrjHrpCcOSB1OvaBuUiiaaOzpAjkwRfq9pH53017E02/fkTr1x5YCrkkB GR979TvmLXYFNYjaKBpmO1HMGrMtzdrivC2L9c4F0e896mvwUbrSM8VwLJoNrdpmi46Oo+ZBrZWU wuNxBAt66IsHHDXxHpx9oHRusAeaVUFpe3DOYVGBFDXV8vyCTutLwQwjyZD1DmSg/0oKjFZiefDL yz/rN7AQtD+IYmnnIw8AMyPP6cD1QhPE5HV9NXaFoOFUSm3OiKrFt9Q2vzI7dHDPJOm73zurPAaT zerTz9pw24bocLUC86zOun3/qgroExWnd6D5e1AdMroBOwZzTP2dc479oODzvQ6Wu2vtXdt00qkP RkhrH7EZeLVS7hHP1e/YGPRIhJq532V6ia6jfOAPvhUFx5ksGx1EzeHWEKXI3QPiZtPBF7JR9qv0 borCWZSK/ooKYufBF4pQUQ+966jVtMc81xqLAkDA4qnkl6n+VPJyagCeKynZsLOxsFx0poqYQMLW 0eAnAnHG4yZUn/cTyWBhAAvUmqjNsXM8i9n6u2ZW6RXaFlqrRoNQESpEi9QmxQSlkneM/28zw3Aq k7b7gd0f8k0q1pZbjAxv/A516RWsyvHUa3cqdDphW8+vdWpGy/FlqWnSx1t0Sg2AABNzBKibP8DE LKPi1IOi+xENUsTU8VgwuNlojFn1zlxn0FnnHOdklXonUjh7sFEUrE96eaqFaeOQKrZSrXa+jFwg frxUGCtFrV43XkfrKvm5RgUdPEZfAch4UVeUFP1P+F/wv+Zn/IlK4YPzSWhtW3WvANOPQNVPfGhd ipiUpGxKZBsmuzCfRQYmEM9IiXiFT4YKeDoQD6b1EiktnkgJF0I6JKukOP7DmJqatiaV6v3K4nkd 42ajJB2IL81K5JQOoxF6ZGh56/Lt9Qx4hlzps33z6qPjJoyZgDGnvvMx7bpVD9aMr1seG6nVtRtK Swqm2o0Nq5eVr9s0bm2WYET3+SeNrhk+CWooBuhVA3p+apgIjUpzGqPGQn3NPenhNU9a1HojjXyo BSae7qDgK1D2YPV+e0DeFIBBIMOKRJ5KXfOcKI8QUt6A0IunRQCJmpRO2oGBEsCmCbxKe9OwedOP 3BttzTdYTUO2Df/of9xxj3nHpBvrq5dUGPLpthXG7LJVj739odFgDZV7PF+db9ySzBGmVjqNRuOv Se5nX+1jetj35CsDG8TsofnN+XRxnI6WOV1Rqqyg7IsC3thiabOZVNwxWkvxtP2AEkXJHXIudTnE ctTtCXloT4Lrwdxh+3tOigZyUYoa1XvG/W5tSEtrqxLCyfPJfpLqvstA5KB9U3WXU+lkp1N8zWyD qiVcnPZF5mvkC8ZzQEQCBjICtp8gqkUxXMqzOav+vsuponlIZvvqjqaRBg1b/2Ai/KtPSmumrF1a Xz67Irhy5JwFW29pWGXBj/7mSadJj0c4h9uf7P7x728VZ1mUEzhOM6s20mn55vTMpxrF1lLLl0OH PPCbA/sa6/8DkBoLeT4Aec6mCqgVoruALsB0nI7j4fRw3Ew3Y45CtM1Js05PTjK309RDs4fI5558 PVgQNTre+SSrBiPqQZ4erBeVaLdpuqHINiOnh/5mv6IQ3DkMub6+vmsFQTqgL3W5+me7CJ9toBZg HMkWQY+4YiQzKQIo6lDaquO1OaUjdic/+sHn2naw/ekP8NM3dH+o33dHYpGknDx5XCuaPKZirP/l nGmlpam++6aOmT3l6O8dERe793kPekqhCK5ZHJtGqqMRqsMDMWvA+YRE13LFcv3tmie4bg1r72R4 Q6dKbT7HZ2vPkVt+sgRZxQ6sv6ikKZqxMcSYIcEm25b07qtx4ZYfvr8gffPlf36NLPWxeUnAfX6y Hf2xf0XXZ5d+kC5KKC5dWdy6/U2kmdP4EPxLYqkfmLvgXxKm6qh1or5bh+oidHWF01ahrNZAc9EH 0OPVPVgrCqyGr/jCpnblt3jacvN0CXIbp36wqwcrDnMzlE66roe+IuqLppfkUe3TSlDJ+MFosCic TJ4nk02u0nQU6aUYjLbL/1ClplhFHQoT6DPxEa2Q3oWYIBNpuZBRmzEskzq63sPG9i1t1zF4V2TF s6ciwyc+nJMYXzq5hGH8Gx9d+vHkeYKKVTIcjVSsyogCpfNq52y+fW70lijOHyN48+zm/LYNhe/v n7R3dv0qg8dqlc4s8DXyfCNWclr7YakTdb3g0HLK1P5E1b4Tjz9FPsSEyP9iizGgF6MWHvEE823Z +TqA7Kj+8Wn5i/Lp/B56hGjKNvJB1BJpC1Eq95njLuQaGQTMDtqmmwsJYgYlpdu/XnmvcqcSK4Nx iH0AsxQgtfyDpL3vmhhIXu4f4O5runugtQl0QNNpIrMBgcuNLBO3PPNkorfM0mt4Nc1w2LX4d61z dIiJ1JbVJ9weJS61xUuqWzQKntHbNixqHztqBjeB5SH2xvtX/rXYYWHGmLL9Jl3d8vLRlV71zL1C ILe2wPV8qihbpeeA3OUdR9bVD/EFwKOcelYc4ncj7EFei9v9C67EXMKVWEpoN5frpbPcLE9zFOem s6is/Ih6IbUeKjESZgtKvJzbUsLnWoQSS4GgOYbupNQoeVTgHW1ZNs5HzvNpJXR5S6itjFIVqMEZ A0qXCOuluT4x8E1+IOHkB8lq4YOTA45m4HurUFx28uR1iqoOkbknlxegB3OgIp6Rq+BYCF1mZARH 1gVZN+SULG9/eHLZoOyGOVmGksHFo6fdemtxQUV1ZbToVPvmEYPmr8kNuQt3PNA81uPnJijMnoe3 9o0vRGL+KFO5e9E9Xb9h2UYuK3Rx51siU+eP5wZiV97skj96xKT+xjTi/aCcNoiORzQ7cmmlMhcp cjX2YMiDNZTGTtljhcdolgrQCjGPikU9uT6HTqPyccHyEoozOjDVgqy4jTXZMeKKjpb0YPt+nx6G Qx84vMuyw7seI9nlXbkgnMx0olxdZJcG/ZiBAErIFCer2kBab1q8splTIx2d5w0AdvI8VUPFMRfE SbuSeTNuTa7Nm1w3y5O/ozxXqxIWHPvNoOSC+vob7OqsQWOHtNz06RrBh6eS9mJMVtc30pcfIV+p xQCRM3yjntdbJalFWr5qetB7c5tySMu7dAUC106YU8G46SdZk7yFKNivoQYrkYEyUhz9I6WHIwuF keGA0mGHzKfOpzIXdK5fO3iuO94YbmgIwzf6KDy8oRwOWFNDONLQECHPpx9JTsZd7WPvYbdSxdTY o+ocVLQo4LEcSy8iDntUAmZxD9p1VKUM+LnMIkLJ+bWmUsq1ThvsDwsfGxKJy6lg8DRQ+Ok6YyKV Cp6WmRxZKQ/ZuPGcx00ZBMrjJquI9CKCt0Z84VxktcmXBNBtBhRGxrOvO5zmU9Jlaa00Hh1BXYj5 indrmzj1oqebv5UuqZfbUVI5X6lRVQ6efXQp/cxl6eWbbeHoIvQAaoT03JvUT+jfUTC2UOr7mOPY 0Rty2MVmguowcDh/AYdDfvXOnCORRQgpbN4eepCoCux0tFqbc2y0vofWHNRpWkvB4xxSKPL2eEG7 ixp3cJ2bbOmYyij1Coh3PfolZcUOyhTs7QcOO5s0JPqDl8nw6j3bX3cC/Iw8gcleKB5mCMdDCQ0w u0HIrA+gCdNI0ES2G6wRtyEKfAbahba/eQUJD3/6aenEcXkTn67O0kRu++UjL729aX51WGVlQJJ2 z5szSRevQAUj198yE+Mwfm/vHW8twZgP5jtvod3o+wjTBCyHrRufu8fnVPb8WKJHw2bclUDSf1hJ tkcBFlMBi0Kq5UXKDhiYs3fqWtXNRg3tQ80FrX5KYd9jg+CPCpaQhbYU+17B2ZQbYkeUGuccCYHN pvkimNq94RQR4SR6mcDl6Al1h2tp2cD9y2DNxow8G1XTaOA1Wu9tO+87+PvN7en4lOp7582daFCb /d3bd2zim9SWAuQ6gmrROI+iWQ5r7fMkrJPSsdul4mID38RfvTqwgaKt5DPucJ7ZYcB5iCIxD4fX Z4NfG0S1i87sRZWtVKx5UAXtM6lxabNQ1Oo3anCJwvQKJNYKgVIQqFNUj2MRxe5jabbGR17x0Bdh EJZix2GxHJWnTW1/OJUCCBaTR7JquhAmm6bq/vAVAALshAGoxYVtlkwN1CKjAcOhhyeWQyBAyK+w sVo6JqTXCdAx3OzboxgjrdG/wN6ydsgj72zLV/PrDU7pq+cwq8q7C1c+c2OFdG5znsB67/2vzbhh 4xesmy2QqoSPpVfnFOtVfBMQTROXjwLoR9TGI0XplD0dkum/vCqy+GnibDedpyd971E2KZWAVsb/ A1oRGb3MRhLO/fJ5xu3COfmYJ6aGXP2OzwE0A1QQ1P96sao00mmnVILKrQqpRNAfZl2zodWkpwtC nS49k8sEmTpmHMMyHtTsb/VSiqJ1Wa6CUruZ9RwDXMvor0R1ecU6nglFVDoW9QDCVHmonC4PJntt ibNkLUweoMp6+8Nnk9VEKwwcEXMM2t6db4jm+8roge0czWuQRWA8AwhzCN7gz8NmZIpi2eXRczYF OekZED43o1VYG1z58vbbXlkZ1GK0Ct0srZGe5YKbjAvWj9iNYuiZr4/Q0qc0/dnJ3/JNrHPJOYQu 9aEJXoEnqzZe8DTRvZekq+eWOFkAnkHDGLTmg6ekeS3SJTRjCGpSHnzl5dcIknFAdjm7FbWiz9m3 KOo4JVKUIKrJ7yYUtMT2MElDTK5n2VkD4vXkjgZqPujpevYxKgc8RJtoFK2ibby12TbXOM26xrjI qsh+CY8ntzvg8aIOelopuDrVfF6noAaFi0UT8p/TFrnPKTsFs9scMotmxhxM9vcLH/efTctuY6Lu ROpsSuZsGy0zlhtXeNzA2eQStEG+JE1mI/IahMylPXyioeDH4MRYmfSxthOF0Cmp/28PfDpvwsFn xCG3FjdLb729at7UmTezjzkkSclKDX+XQtL/SD+uQBwqQiwa2q3QSVZpv/T92zteufgnUle1UId5 +CBFfvFplJooFisjLXpvnXecd6qX8Xr1/k4Gt8H056wWU1tpp16Vf07p5EPnNBWFuSA1j1ipjmlO 5ISqOUGouf8scLNMzKdldpYvF8HwJ3PfR6YkS6w/5/mJn2OCn+VyyLiPRfO8mEjLAflde0hEK55+ QTr1ybqLkhQKr1TEnwNyhr+OK3f9oScS56rzZ224fV4enjqB49tnPFtj7Jy0dC/NEFq+M4n+Umb+ hXgD3n2fNL/pTJ0iOaVtirxr/Q4/gY/AXBolmhSGFpptK2qhuGxvS25bjkcFpp8+pJjLlWS/AjbR jpWUlyoCvzzeP81P+4NpAj57Se4MYjogyNMQHwmPXOfKI8o5ve+QVxwmszWzlKyFlMJrdT/q0dxb l+hUYxhUHNeE5wzK0iCW8XUfW1b514X5Ol3eIryPYThuyTP1s7QI0Yw+12Tpflq6UFYmlz5jnIa8 iJlmAnVMX/1ausI8ig9A9iqpJlFb3mlvy7a0ZFm5wk7vMUxTOqhFPUdpCtQVnZZ2I9UZ8JUSi6DM 7jBqcqvUnZpgvwBJ6+0/e7Y/2JsyJKhgdbC/n5ip8CV5pMKULEZeef8VJ2Qa9Wco0+Ll5MokagN5 iLePBvzFiMvjQIozLmTd/N2pR6d7ElltPt3EW6uKl1xIoFdm71nptK7RWRkH/nEcejXqYRTxuiX1 HobWjJSu2B+N5AuOxYv+sli3CvkRHulkwOpPqJL+LN0Df/fDL6C5rjOPPnqSw56I9ML3lMykstcH 8T9CnjtamDt/ALU7inpXtHOlRXxRXRXHVFRUlhaXRiuiFRXRusGyrxQqKyrDgysromG2KjCso3gw WYYIrKATHNkOo0C+eJYn76zR6QQzrxOMZlbjpjqyu1nEstnFgxm1OxDG5hZwaW0Oj7+0nLVwaFgV 1rTUjFS28dTwukGsWkVmVG84nL4ckj4ATRxCwSScnbUlgluF/q2K42ir8A55AI/2L54up5KEdGsQ hzNTzRT/aRdO2a5T0jqUg+QNg8zJNmOmAOmAxZzxbPSMzcJrveGR89vCwy/e+WpL+YIRgxpKCtGI IaYNVYvnT396g+lB5CppqKu/paT17TsvDg/fPGpKtbTbvqZq6U2LoQSrzm+4X9qlUDSxNSjrqb1j TFwjyw6VjoWWvhRjGhHDNjLRl5feim4AT8LqG44+JfXVkEskaNucDX8r4WEgkkwNhsy1y9s46MRc dYtG47MYWhw8Zjt96lw1qMNvDmSrzdCQosZiU5yzqbMx7S2gg1CwNpCAULDBfvnOCCCb00QBAtPE /YHMjRDFKBZxE1KRfVZF5maIjFRfYHIantg4/TZplB8pD7TO1IzRcTt/dfL95cc7e789/2wAQJ0y eeobTXv2tm77JD+2etro1RW3bLhrB/l3D7r6N1YLFVZMTRc9IQuyFAnYn9uC8tp8FI3dnNLQomuD 0exQGjooi9xtStzBlfo7bEVwdtT5Xm7HtGyUDWTSm0oAmwCnJHqJ7SSMQmokVV0NLio9GkhCoc2u 0zMxTGH58rpwXc4tBgrv3Pjl0tzs5biqY9qC59Zm0dIbH4xu0hgdq2oWzlrx5J06GLr7ISPYL/1W WlvEyLqEL/wdekByS1exVv3h4+hEKU7nr7Jbaqdp+Xo6RAvuqBh0/GIxAPFGK4Lufx9zeclA1GqI uiSbq/y3cQPtkMiJifnH2IVPTp/+38ZvAgPpJxtJK/v/AcWuYI7nwx/HzNiEtP9bVNDdDr2eL7L7 xk/wQj2IMEP/CBwcoe4XLZi2quss4yxPWFilWq0FBNUaLfmYntVsJqBYtGotaHm11sz6xuuRPhZy tlNW8orHW9DhA/fGhwpamNK2IM3hQk7v9LYYc9uyzAL2qDJqt7pafuwPhwEo4BGCGQzfE0mDzBqp rakTx7cKig9ZwhrXtg7/TAXXAJU9Uvgakuj9Dz+pbaivn18y6Wz3t6OiM+c2ir89r7kbVa+YefPz Ha7s5ah6wezVj693IKnnR6BnTlP/8lPShVq5xTV/WvpnMY0iE0ANaGkRnkAz8KaiE4CV7up/M8dl rEaJuQWdujajusWg4ezulpw2R64KsyvD6pJOdbvC3Z5HasZu7FBQlhgVzFRLL3hAueHlesnMqHh6 X3D9aPrHmjFEgwhmE9ky6MAK63QoUFa7tLZsIcykU7P3LM3NWsFULYVa2WTn6RGl6y0TGIZxTts8 NoLap2kHg1EeErfLs+jndRJBU19dFmLY0u2/PvvGlDQ7fM0+BREmqNliaUhfhBWUlW8xqdu0BgtW cFFfDkYtwTZvZVss34Upla9dqzcEy9gQ6RFRm2PtcA6Ktoc6edTBBNNqA35CanvTg6R3YJCkqtNb Ttv1GYxbTcbMVVHa8vOuMRk4DEP8J2AGkVRy8XbP12UfPrJkwuTYiwuy+Sy5Z27dAz2DnjzAl0qP m2/nK9pzf57N1VIZzCI9yb3j7TXX4GALb0Ag8BTSU9LqHKyQvpB2J5gM24PSZGnAZTC1SxTFljr3 OPdUN3a71SanvwQbWwphhgaKsYljqsIwQePKNjYRwWpVVdBfJ1+JOuNnz/g/BRHW7q0lUOWEizsu BlFwKON2hpw7nfucx53sced7TtrZ7qLIO1QaYwelR9OgzYLJxQSxS8nFZIEwcJhG9Bqg8hYLBCuo nv9Xg8hqNR6L/nRfws9rrQaR7coZ4Y6fGgZXLb556e47dbfMXtti2Lp76ZznluQOIH2HMG7LRvT6 6lcS/6JrgHFu5bhbH4j9c+2xla+s5okCymz+wbk0UtcjHaM6xarINUXIF3mxviWgaVMU5mGdys0H i0J8XdFO/oWiffxrRcf5M0Uq8uM9/tMipqhdlolqb3bHxVyUG+fbGRlRvaWDMqJpRmRMI9qbRrM3 ufgnLAeUo+y3/wnGf9ufUJsBL/ojZs23/wTcc3PoXdeDtdXM4fDQvUMNeLQtOP21TH1dB9o/osRU ocmvTR+OEAKkMlcmAKkJssseDQqkUT4fLu9pMDA5A8iRyW5iczoDbchb6OO0phahTWdUgU3Gh6nx RahIS8yBEsyBjfLAc96p+Sjf1IM5Ud1tQ2AUbffasC2YXNJ7Nil7afKQcQzVp8OX5DvC5eUMZ8Hm a/ctEAktBAZu4cwjd895yG2r+PvhKv3O6QYF1uQt/s9I7MLigBIrDFN2C8rhKt27KB8V/E6vonfd Y1HqvNJDn7dbGOIUcp/egthp+V6dwtb1YAevUvEdEHNmGwwxT0lvFiTMLWSPUmGqBhT0uhcpASyD 0vC4iWpY6eQrerBKdFBetY3BSn7wF2519Uqs9pe1FLcFSnV+CPmo+T111FbLeMnH08vaBXjqUDdg WQ/nhyguZ1TiRcCJS9uMfnn2A5f1DvgncnMdiDl4IDXjS186FCiwvrHowPVFbPnp6hQZXRG5btzE U8UcyD9wcREZrllH+vz9wUUHXkRr7xh9g86z/PO9WbzigeDsp89ILz93U2NgC6paVyddjM73aMfM WrKpe04TunHMrLl33TYreWdn4Wc7kQI11j7fXafDI2wN9tHSyI2dhb8/+lepq/qlz8saMatoxNYX nkBxdL7trV/8cjedL3lXHN/36POkpjLXKwDfm9LdKF1hi6CmKqnNYp0vQuGclgpvW360Eru4kk5T G2dtsajUmk5QS25fMBry1UV3+l6I7vO9Fj3uOxNVkR/v+T6NMjAU5BakOi5ihKt87QXyqTWng3Ki tAm/1pGkIQVwdFSwDpoxNdCaUHXXebb/2961wEVR7f+ZfbEsb2EBE2Vc5OmyzIK8UVlgwS1esbCS KbosA4wuu7AzC+ITMMlX6fWqPcxXlmbmoyS10qQ0K2+amb0sy9Iyb1nem5mlwv+cM7MPULzePp/6 3P/9XI+7+5szv/M7v9/3/M7v/M7MOEakQIgjhqPNaXKfEAcfHpcPT+VSLFgnFrTcFdqKtm1GQci8 X3uSTNsbhnkMaeEiW2eQWIivEkrknTC2CSen9xzueSITH/TYNrkQbOk8KsSD35iFPzDSEdR6nuo2 qkILjN34xFQY2QBOMjD3XgI4pWLPZ0/zCw0PVYWODS0KnRg6NbQ1dHWopzI4ONw3KgkXDjOkgKxz FCYMl3j6GbyrZL4y/6jwpGVR65LWR+1I2hl1IElKRCUkkVFj+1R2R72b5A2/jkd9kXQm6sekS1G9 SVI/4K+7kthA8hXgpZ4YDrxXnB7FxsHNxzD2LrAl5hbgxHMAUhvmlqdyqwWXpYLVNsDfOY/hYss9 DzoaH9V35QhC98D5pUP0UqPCzy/Cej5tZtecVNH8GS1TW5MiaQ7SmUO3310fF9li3z5E+IJeGDil 53rP55MD0cyWhmfhw8eXZtsfmDcJZCUQU/GIUn131gTbZAWIgdDvRvf+6qEBeOZge7JpuSImOUvs Y0iPHFQVFBGdkin2laiGzBJW5UgMmFi2TrEMbKsURMwOxfqYA4qdMe8qumOkfgosJlzhH0PI4amE 5LEKMqZEkR0zWVEa0y2HLO8mf6E4HvOj4kxMr+JSTGgymwgm/e6cLHZsDAufLdgVLmdD4bbaV+LD yhQsEU6Gl4YLw0EUOIlc9Qb3yyELPdW1R1aT4qgBfDMcd3fNflUhbmuyh2a76dow03bLUOSptmrT 5o5QiRDsg8Ais7nOsunBQDE8ksjnZ9nvq90KVxwP+OTe4EOznd7qkdizoduYD531/jS0DIvSe57m a6D7QiZhdM9LPUti4XuTIPKS2QD5MCwOK8Bs2bGxs8RibzzYMKQKC5H4+fpURczylmQkGlKr0pNk GqUhvypnpEyZyCbA93j4aTLYMbqoTzFP3BOfFg6X3V1+wf6BCecO3Th0DmQnyB3PJTqWE/4qFJcR 87dBkKslEQHwVki04zIbD2GgxP0aG94/u3HLGgXTZhPN+Fd/Pf3Gm/vhdbdW6Jh1Q4UemcMnz59h jxSMR6lNZlM1/SxAOKxZlM5WVwNnlUZtoXquT1qWKpE6rsRBKHvk47KX3S2dXKmnexLgij0OZ2L5 zYEri4TXXnNALBjJI6jLHnEr/GRRn4Z7JniOBYuw8maY/D+b5LgM+btgETTexvRZTOQdGFleD2eh FmQYbcLDWAyWkT3M33tWUFD00MGG4fAaR7RXQJhhaHiw9NOAcMGIOEECuql3Iwte13C7pnHUdU0j lUuXwN4X3VLm7sY7rm3Ay8Y2eFWjs3EuHliQPiJWoSRV9cUjpRuDZ04pqvUp9JWsfun0zz0Xv1uO Lm+0XxUKxGFq5QMCwZE5+sWnRyR/cK3ncs81TNB7HeBfC1KdGLBPm5cdtA4YEoEn4bm4HjfhDL4R 98DhrPaRybzIT30SIvHIabFoNYobGsLKvHyEHuvAepTs4RU7C8Mk8bP8g6pCDMGSoZEeBoWoCgf7 Hgl/WQxuZvkLxRfhXhbe3QuBG72sc5MSLoLN7CS4ifXEFehW+hg8NZD7d3Mht8y8A5Idl16DkwTN Pa/g0bphm+LHKr+9fmyd/0vD57hnku2DcY8c+ZIq2oBv7DHAVBEfmY7Hhr46c6GHoP82LwEn7j9t 9zAVlY13XnMUBwqi0DVHD+xh7CD/L0Az+dKK7b9FOYedw2W4Dl+G/yaYIcSEr4i0oi5YxEPE428q e/sWyTrJOo9HYZGq+dI1UPHUg/KCrED22s3FS+L1tNfT3vFu5ZhP1Z9QHv1f+V/5/1B8PQcoS0H5 1b344aB4ovKo33q/Z/x2+u30L7qpGFGhQYCvCNg3aPQgbeBdgc2BF4PmyIPk84MDgl8NPhyiD7k/ xBTyQcjp0PmhDw0ePvjtuzphGRI9ZMmQ80POh7WEzftvLiB2FggnON+4uw9zvDQZx7yxMp4WYCLs bZ4WYqGAi6NFWICTFgP+kzwtwfyxMzztgU3FLsG3MouEQI4vzvK0CIvBJyBaDOpl+BM8LcJG4B2I loB6Cd7N0yKMwDch2gM+O4Sf4WkRpsAPI1oK6r0FAp4WYVH4t4j2BMZMF/jyNI6FCl7gaSBHuJ6n hRgp7ORpINNJi7FQ4W6elmCE8BhPe2AnhT/wtBRLFL3O055YmugyT8sEv4mVPO2F1UqjeNobq5cu 4Wkfr2NSB78vNjGIkyODWMnTeBpgJR+GaC9QP0g+hadFmFKej2hvaIt8CU8D/eU2RPvC12vK9/K0 CIuTr0W0P5KzhKehHI4/EGIu/4qnAebytxAdBPUJFvA01IfDVg7qg4LjeFqEqYL9ER2M+Ct5GvAH j0H0YMTfxtOQvxbRQ6APBG/naeADwSsQPRT5wBmehj7AjXU44j/B05Cfs3EE9IHgKzwNfCD4M0TH Q/6QMJ4G/CHIFqkbzlI3nKVu+kvd9Pd24/d24/d2w9+bxz+PrqNZegZVQ9QYWSNhsja22ui6epYo r6eIIqvFyrY2UkSu1dZotRlZ2moh1Onp6njwlawiNGYzgbgZwkYxlK2ZqlEROVbrNEJjYekmu/FZ gmYII8HajDVUg9E2jbDWDiy4pZ421RMNxlaimgLy6miGpWxAMdpCmCgbawS/U+02mqmhTZCfUbn3 BLo11xAZSDsDZWOgwERVUjLk4VniIcufpx3YW1tBmYYRmAazYCxGY02YHTOC42KMwuowG/hmwfHA fCxmx31A3YXb8NQCKTW3OZ+PemEH5hAuEO4XHhIeAN/PY3mgvg584PkZSDIBPkakJ4Hepd4Islcb 4qoHtQRWDn4p8FsEzsH3F7HgfCOqyUVvXm9E30YkEXIQmBpLB0WNxfNUMqZCWplBIdxkM+iIAr8U +G1G2kDOASwZrgA1NGrFYQd7rQGtGsCvDfFbAVq/R+MW0IIG1tcDGkprBb/VqIUNjSTslUVacojR qJUJ1UDkuOOpQEsb4q1B0hzyGex2vgLPmJHUDDfsDEg249QwEchIAkg65PSVEu+U8t+I3c26lCPK iuaYEVD14FgJ6nWAz3SbFpDKQ21aUL914LgE2F2L+qSQ9RxKLqxsQA60y4Jw46TUov93gEKWGpH/ 1iAEIQ88bwEjUsP3A+vM/BzlxtSBNctjrUM4mEGfXC9lSIIR6cCgOtgXNzMoQBsBVgxqSaMZyula wyNNI37424x4YHuoXR2SyiJdHKMAsYP6GpGuFt4mTqqJ14YbS7vTShZoT6BxdciHfVsBvx3gxPXh qKURttzYc/XwiEJxAFrP9cDp75DI9dnqhk8D8jmKt8GKemGRt5gQbgTyZAbFFYsbvrAdg3qFyE/n ++dGjkF46tzwg5IYZBtnay34NaMWsHcCWWhCo815JtezGSEJ5SmRDMaJrfuYE8gSI0IEeh3jNi4m ZFEjkuTAD55nUE2jm6YMPxpw/FmELach7fQfE+qJ04Lz2VanPS5caF6WFXmnCvPBZCges6C3DCwB lBZUVAhB93mk4rVNQPwNoM8E8M0iNKDu8IjBJoO2cIxN/FipnNy/vxf3EYaIOmomI0Rr0Pi6+ilG b+XTgbVRB+KWBtEloBbO9nzwXYjqtaBGD75hrCxAb7XSgsgBa8sRJvDjigg3z31HPeeljShSNPJx rdWJ9p1FL5c/OEbHMce5udAK+O3OPiE+zW4x1c5jYHPTh/O8BrdxN/L+akJexvCzl8tTKKfvQW+7 j+8N+hI3y61AD0e0dsSBgZFhUI8sGF0jP3MpZFc9ryOcBzYUy2A8akWzjIuzt8LLyttlRfPfJaWF l3mr/hzREEaJajRfOK2r+ZGx8JJvMULEYGRVX6S4iHGzV9zcs2vlaEaz0o7eymfm0WaQNHZA74Do V4AaM+qRcRt511hw49R3ReWishFp1IiQpflV7U7GnOB90cKvH3Vu/cKoVcNnjK64557FKZ3cNje/ da1xt0eKi3u0c4Q4S1zyWtD4T0Oj6Z53OOKyi9PKr7aN4LgayWVQ75w9nF7u3u3IVjj8Xdmvw+Nu 5UO3s8jlHzpk+80j54jIMCej+NXayudDVn79tYHfvmNgw/pnzQ7J0D4rWgVqMC7fagZ8FNDIFQfu ZPQd8rg5SfErcU2fOeaQd/M4cmhxFrAoBrC3nMeOETP2w7r239LWhfLNPfTNWfpqxNkDPSjDKaEC xH8NqE3DRmGpIGdLBZl3GvglwTEJCoFm4z3gexQoMaAmFnCkgkw8FdSlYikgI09HH4fEfN7G/na4 R2NHpLej7K4Oo24xnxpRBDDyrZuRx9F83HDMCwrYSfD1FG8b8W+tqo5zCf30da2k0CYCfRfyO0YL +K5GaHJeakffXN5m5y0rRrNlBn+O4f2qntez1rlmwzZ65LEEympqeRkMH92gneORnQy/glB/iIXw U+pEthFFbS6njka6cp7b4BZ/GKz/nDXyc8nM51o1aEVzrOZQEpe1cXHJPZJRfdr1jw2unrhdG/Rl O8qvuBZK5B8UqKP5uhnOFgyKDSxfx2Fl42fxH40mt6dwZA4Un7cR/fCE69RP/F6EQ9LE7x24aGDl M4wLiJ9GGjJu5x1amNDuiUARxezG4/A891Z2FMOUfeYVhfBxIG9DaxDjXPUI3le5nct4fuZR/P73 j8GP4uOIK5LVoBnIeQXdzytY5BXcLoBw5gWOTItG52mnH95sv5HHgEYWWvidkzsOVreYY0SeFs3P Y66HGaBY/xA8fv+u4V/L/9fX8Dh0BuaDcZFb4bnZbr8NbwEaK0cOCDG93XW9C0C/adgVIBl6/8Cc BiRt4PPj0Hg1o7337fhK+T0JzJ44L2u9Q3xuY4coXDRGlCnKFaWI0kTZotGie0Tpt5FafgdXRO+B 9uBqUHs7HjjzG7Fpt8W4ENTXoMgh5G489VwGvnXrP/DVZgIsAINPkgrRnSkc3VsCnyD4f8vzb8cP 8iI7gjwknnGd4zp/8cE9BOs7Aq+SHYGXBTiu9iW9JVLujEAsxsgpEtlICS7CO1IFuGh9GVlKKt1q wp4c1haGZaFSgtZAK39VgcLGwEISfeWJ/BXyu1uueQ39MlN/uWeR37Wc9R1+Y8kOQTf4xAqCAhd2 vbfo282H9ie/ufqhBUfCj+gNfyF9nLrC+15k+1p1ODlUIqwQyQKDDZSN1tN1FqLcZmdYophiW6y2 aeoQUg4ZvAJ9HQxKQmcxqdRKMo47EeFqSTdQhJ41NjTSljpCT9maaRNFlFmtrHoUmchxjywuIQp1 mhxdoa78PkKTm6stLdfmKYkYU2x6KtG3D3JYiE96KpmsTiRTSfBnAjhMVycmqfnD/3wD2te5Y46L MWH7QwD3hYL2dux9FXGpfpYyXtUe9rzkhc1eewJ8xp/Sf2w/+3ZS3Asnr3jeP+qnC8t6PL2Pfzpk wktHz19Z8Pya7gcjv5td6c9Mnf63JvmNw5VXYrdWVq0S3YivDqhsDzvStOIDRWXCB+8EiR9IeXnF s11Fd1/4IVOxzfDYnOFPmDu77y54ZGrXppQPrnvGv9+VvlogBE7dzyWEQK+MgCfmi8ecuNB2beYH Wy4/13pdfH3l6KaILSNjvlgSSC3sUT6IL53wePWRgM1tl/e8GrTnPcNj06TV2sNPPn0qea5Y8bkt XtQp3jzLM/ivQbmXfgku+tDj4dX+5soeWfIjRxau+0LU+ETcbOPDr33r1fT4M2/WVueMXrlCkfio YuGi32qkI34+8Rvw36PgkyKQY/sDHj+Ve3H4tfzKBxYeyV+wLPKHoCn/fU78nDqajOQED7u9Gg5L vQa09Hep6MBHdhM+AaQfPOERKNVZWMpmoViyfc1NLr0YjMKD0KW3Gi92bXtoWcGyz7oCqujPZHOr l0nUR4/1LvhL/ke6jBUXTkrGrtn25PQJ3/963aQt2etlIX98MmVrvOcX/7BGb/W5d4o4uWTusfKS 43uUOR97HX9ob1Xv7rbjZ1d1zVXocvzN7z+6EzdsPPiual3G5bnPVG76SEF9vWTr9Cf2fVKQU39/ /OwbLwpw4S0cumHKtccmP0Xven9m48jqiGF5xL07IuRvsoJfdf+Mvmvic51NydKRV5Z+fubFVd8u 3nzPWeatcZ5rdp5afEq+/Ijwa89Ig+R88VMFT783Pv9kmuHn4UcPRmXGRyYeW/3VgeyCv3/cUND8 dTe50a/t2NyPM+es/3VlnHqk/Le3gi6e3nmhQtOYH6+cQ3Z4bgIfv/VCAS4Q+LfWrrLM23l8Nz7I sqa7i2py11gAHNp4C9QHHqEkUs0NeJzTI3KtDQ2UzUQbzYTeWsu2GG0UUWqvNtNMPWVjiFwNcsk0 cpQ6hSSdLgkPE5OS05PTJ5Ad+KQ/XAl1PpnHNRrd0tKiagYNGdBQZbI2JNioRitDs1Zba0JuqR72 YbU1qojqVqKMqlUpoV+rCsvzoC+nqMeQWZycZHT/G3SoyyNyzUaGIZKIeKKINtmsDFDBpYfBaKZr uDvBzYlqL9ITtpcECir06kAyAB5IA2XjjUw9mHqs1aL2J305KDzKqJoGq6VGPYwMgzXCILlLvNsN Zsd5rwHOA4CJ/rOoA+RCoF4q6MBxrGvZiahnar75Tn6wt2GmpkT2qzWu6ZgqVL8pMeXMyfovk2/o Bn286jr1rj6IeFX09oyf325sWPH9O7t2xJGPJ1bO2r1lWmTdY91ftfxd/PWPZ1f9ss1r8KbtWQ80 fnXVOrFkttWvTLtI/hH1WSYhPjt6g/mRDF+vyMCLw/9GPJw+o3qe+O2Iu66XrXluTeGqj7KKK0d3 zPzBM9nwYn13jvbJTPXGax+vvFbxpvKZjQdjS45d/uslYfjMf8gztlx9tnSeuKH60uLABWmfnA3z ZV6TZL8cc/C7o8ub3ny19oUN5YoPvepmXX2wdeFztbJn7/3thm349c5Jhy/f7ft9pTGi6PjzGTVn AtdWvTW/oTB4x2gPMJE3dohPkx3iT9DoDA0UCUiM9IKkn0gkFIjXk+0L4BEuam8j57T5z1x17r3c G/WP/pT2jiXzn14dG0x/wkTqEAu6QFZIDoeaiHC8VxRCBpEw83NldsFCgUcbBkYbsMhEEhIoL8km O0Qpbjwy2LRDFAGqw9fHtkXXs2wjk5GQ8C8mxoYO4d72DmFXeT3NoAcX6FraZGQpgkYTBjobxcBZ Y6NqKRtlMVFKwmipIWiWIewMBZ+YYFgbbWLNrTLGXj2VMrEEa1USbD1FuEBwyoXzpdRmNLFwQQRL E0s1UBaWiAGaxMqa+ec01CoSdNJspM3GajPUpK80lwGEkc2QDWRoJtRaG98AxAA+AvQQb6Oa7BTD Mtl9+aw2GWB1MPYdUyWRmJyeBIbRCFZITTMFKoqsdgt6vsNAUy1KMIRE+ihyVJKsQq8BfI7nZUBg Uaenp/QTR6BnZMq4Z2TKnM/I5GrLyjW6Ytl4TVmZprhcp9UTeTp9bqFGV6TNIzTFeW7rcKGuSAeW YZUMchfrigsyiPJxWqJCryVK8gGp0yNxunxdrqZcS4BDfXmZLre88D5CX5Fztza3nCgvgU1kBm2Z Tq8rKHbj15UUE6VlmtxyXa4WtAMCirTF5UBt2IVOr68A/RGaivJxJWVAF5lDSb3DAkJXVFqo43XW VpaWafV6wmUVAKE4t7AiD0px1cqA3kXastxx4NBhZUkZka8rL4bN8wGtIUo1QMfcikJNGVFaUVZa otcqUSfjdYWFRHFJuSxHi0Aq1KIGuSXFeu29FUB5naZQCZoU68p1Br6NQ9kSYFUZkacp0hRo9SpC r9XKoJ1wvYAy8rSAq1APkM61grlvAUNmre3vi84HfyxWC3SrWpqq0XMTQcOCmVFtBxNIRk0H7ZFz NxvNdopg6o3ADyxWFj49ZLKCUzVIiJEhjCaT3cbNwFqrrQHNGVkzt9wADuCpUAOdRiXbmNI26k6m uaPebK2zquroWrJ9B4wkhKh9M9lGtkm8pnSOwzuvanEPHAcVMRIpiCpiMYigwWEDygcgkdVOTgFp IOXB/eIhCZIV/K7RjspoBiFLu1ZiZ0whzLSxWkWYWTAX+maX3C6ZDHaLdENEUlICoh342y/vgZna ysInWytOsRMXR76+ibhk3rtrZv7MtetmvNwkGScfRL0zKfbqvZkLm56/HJQ2/dTS7V5tKcsmjXvk DSxNpj+Qndq7KDC6ASsY9cu4QpXtn4ffn3Mjz6pY+t7ydWdXXDzfi739+g+2sE+eEFp2v2aamTg9 L3Pt/EXXHuhMjVGd35SWOubl6z91RKg7RGkgBo8CppP2P2H9uEUy2GeTv779dXKwEyVPodp9YRGB HMN15KXut+yQ4a6GIvUgkf9zH8Zk7ZMOHXfiq7UX3/hiop2sdWP3VleShvWqNuUdPb1Uy12N3DCi TQF9jHexBkeqg3yMtdkp+OBdQr9ER9SBY5S97qesA62a9k0T7u/MXrt5atbYwIPbPg99pSdT8cbq RT8/9fzKpIym8df/llXAvFUdtP+drzc9ZLHItx0nmr5Zvv2nEMV3+mmmr833LP04rbMwd+e7r8SO HbUhefnUrVtC90fP6Tit++HMg99IimvHR+zacu+JVRue9Aqw9bRGfuaTPHFhws4Fl9l7s31yN226 8p48mj4qPXZl78O7jlWsffVclWDp+Ozfroomnuo9yNavvq8pe8Il30e+HMyeSB69dEFq/KETsy60 nFr94ecJWMac3rRzY57N275n9dNk8jo8fM3cx7OfEz9Uplr5Y0/DvvIDq9eFrT71yz0No4a8+I+M qa8oxrS/bjg/S7XnuPrMnA0d+HGQ673jGiGJugPfD6pegq7Xvvc/flc70Oa8r/veR4a6e6+X61IZ DpzXeUas9oMbErVanahOVqclpk64yXnnVL1zhNzx0YqMS/O/3z3pH4v7O1V7W/S+Rbs1bxXti5+7 77Gnu77bUdDw3t87Nxoziy4HfTP7cJdHyMFXk7vDgnMWm8Mqqt6/vrLs0FfiqNkVLduW7H9sa/CE PcdP7hQsj65gy0aHeSr+culAalC65uizmvVpNRusW8o/aZeuYMl5Z2N7r4lPHtr/yJdUSMDVI71E r2DJK4lXXl/e2oz9H8VqsFUNCmVuZHN0cmVhbQ0KZW5kb2JqDQoyNTIgMCBvYmoNClsgMFsgNzUw XSAgM1sgMjUwIDI3OF0gIDE1WyAyNTBdICAxN1sgMjUwIDI5NiA1MDAgNTAwIDUwMCA1MDAgNTAw IDUwMCA1MDBdICAyOFsgNTAwIDI1MF0gIDQ5NVsgNjYzXSAgNDk3WyA1NTZdICA1MDRbIDc3OF0g IDUwOVsgODMzIDYxMSA3MjIgNjY3XSAgNTE0WyA5MjFdICA1MjNbIDcyMV0gIDUyNlsgNTAwIDU3 MyA1NTkgNDU0IDU4OCA1MDAgODU5IDQ1OCA2NjEgNjYxIDYxMCA2MjQgNzM2IDY1NiA1NTYgNjU2 IDYxMSA0NDQgNTAzIDU1NiA4MzcgNTAwIDY1NiA2MjIgOTM2XSAgNTUzWyA4NDEgNTQ0IDQ3NF0g IDU1N1sgNTgyIDUwMF0gXSANCmVuZG9iag0KMjUzIDAgb2JqDQpbIDI1MCAwIDAgMCAwIDAgMCAw IDAgMCAwIDYwNiAyNTAgMzMzIDI1MCAyOTYgNTAwIDUwMCA1MDAgNTAwIDUwMCAwIDUwMCA1MDAg NTAwIDUwMCAyNTAgMCAwIDAgMCAwIDc0NyAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAw IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgNTAwIDAgNDQ0IDYxMSA1MDAgMzg5IDU1 NiA2MTEgMzMzIDAgMCAzMzMgODg5IDYxMSA1NTYgNjExIDAgMzg5IDQ0NCAzMzMgNjExIDAgODMz IDUwMCA1NTZdIA0KZW5kb2JqDQoyNTQgMCBvYmoNCjw8L0ZpbHRlci9GbGF0ZURlY29kZS9MZW5n dGggMjA4OTUvTGVuZ3RoMSA1MzM4OD4+DQpzdHJlYW0NCnic7J0JfBRF9vhfdc9M99xnZibnzDAk gdwkkAMDTMghEO4z4Uy4QTDRACYQEVFEAqxRERRdAV1ZBFYnkyATBEERV1cUXU+Cwroiqyt4giKS 6d+rmpAl/sdd9uNn/7/fz9+8pr9V3fXqevW6qmsmJEAAwISQgbNozODrD60YeivA/pkAlh5Dx44Z pLHY9gIIFwG4bSPGpGdudFftAiA7MNf48UXDyob+MGcUgOoRAOOGGQsrq8cdnTcZYFIu6jTMWLLI efrDd74GqBIBFNtnV89Z+FX+mb4Ak1/ECm+fU1lTDXZQYn1jsTzDnAV1s998JPN7gMVegISX5s5c WPvp6feHAsRkAAwQ586qnHmw8lO8Jimonz0Xb+hPKT7Ga2wvdJ+7cFHt9jQxEduKl/LvFlTNqHTl JlcBPFKL1/kLK2urxTIdbdvdqOC8sXLhrOjv99wJsK0FIGpFdVXNosD3cAu2pzdNr755VvW069do ASoHAWgPAbUVV755gvemz6bp8y9ANHYL5Ykhq1+loW/h/urAF+3DlGvFFNRVMn0qGAoz2p8DUB4P fBE4p1zbmXJFptI73G9hOvDsmgMDWOA6bPUCrJeVwe/m9oMc72yWZ+H1H4Ih+QpmcyYi42QCJ+fl PC/DzKuvLnpY1Y1V4MTjD/Jj7R/BNmEG53ACbDn1Hk1VdDSFu3LmwTI+B5bBvxDZcajiQDrL7QQV 5qvgpgbaseocPGPxjMczQ3ZFF+A6PIfimYpnHtUPVab8Eoz7V/X+VHAEBvy7ef6ZYPsG0ZBfD31k H8NsvB7Ox4JWVgN5eJ2O/e2sD+N5Qiz0w/t5mD4awz4sbyxEYP6RmG7De4n0nmIniFhWNOrJQtcc lrCEJSz/v4T7LWFy5Zp0Cvzjfpd16qeLVvDelUwsogcNjWtIKN2whOXfFB545l34YkM4dCq7/Kz6 EFwUJVz4lVI7vmOppMugAjVSDRqkBrRILeiQOtAj9YwGMEg/ghGMSBOjGUxIC5iRERCBtCIvgQ2s SDtjJNiQUWCXfoBoiETGMMZCFDIOoqWL4IBYpBMcSBc4kd2Q34MbuiG7M8aDG5kA3aXv8H0gHtkD EpE9GZOgh3QBkhlToCcyFZKQaZAsnYd0SEFmQCqyF6QhMyFd+hayGHtDBrIPZCKzobf0DeRAH2Qu ZCPzGPtCjvQ1vk3mSl9BPuQh+zH2h77Sl/g+k4/0QD9kAeNA6C99AYWMReBBFjOWQIF0Dq5nHARF yMGMQ6BYOguljEOhBDkMrkcOh0HS5zACBiNHwhDkKChFjoah0t9hDAxDjmUcB8OR42GE9BlMgJHI MsZyGI2ciPwUJsFY5GQYj5wCE5BTkX+DaVCGrIByZCVMQk5HnoEZMBk5E6YgZ8FU6ROYzTgHpiHn Ms6D6dJpmM94A8xALmBcCDOlj+FGmIWsgtnIasabYI70V7gZ5iFrYD5yEeNiuEH6CJbAjchboApZ C9XIOuRfYCncjFzGWA+LkLciT8FyWIy8jXEF3IK8HXkSVkIt8g6oQ94JS5GrYJn0IdwF9cjVjHfD rcg1sFz6ABrgNukErIUVyHVwO3I9sg1+A3cg72FshDuR98Jd0nG4D1Yj74c1yA3QgHwA+T5shLXI TbAO+SCsRz6EfA82w2+QDzM+Avcifwv3Se/Co4xb4H7kVsZt8ID0DjzG+DhsRP4ONiGfgIekt2E7 4+9hM3IH45PwsPQW7IRHkLtgC3I3bEX+AbZJf4anGJ+Gx5Fexib4nfQm+BibYTuyhXEP7JDegGcY 98KTSD/sRLbCLukY7GN8FnYj9zMegKel1+E5xoPgRR5ifB580mvwAuNhaEa+yHgEnpGOwkvQivwj 48uwD/kK8lX4E+xHvsp4FA5If4LXGLFs5DE4hHwDnpdegTcZ/wwvIN9ifBtelF6GdxjfhZeQ7zG+ Dy9Lf4TjyJegDV5BnmD8AP4kHYEP4VXkSTiKPAXHkH+BN6QX4SPGv8KfkR8znoa3pMPwCeMZeAf5 N3gX+Sm8J70AnzH+Hd5Hfg7HkWehTXoezsEJ5BeMX8IHyK/gpHQIvoZTyG8Yv4W/IM/DR9JBuAB/ RX7H+D18jLwIp6Xn4Ac4g7wEnyJ/hM+Ql5EHoB3+jgzA50gJziL/Z8/p34fn9PCcHp7TfzVzekt4 Tv9fO6df+l/6np4ZntP/T8/pJ8Jz+q90Tn/p/9CcDjjjArdVrRaBZ982BUXgZTyvoAIUwW+xxKs/ ylGH+HhHAXJBIVMIWIxMJSgEkMtlAohYSFjC8ktEo1FS/5Rfuab+Kfupfyq75AhRCvNPucD8Uy0I Hf6pQkcNS1h+iWi1KvRPWad/itQ/BSpAEfRPVZccIUoRQCEKcoF+syzTiIIIcoVMBPTU/2zjw/Kr F71eDTKZrHMhVsrkMplIBSiC636XJV0fohQRBKWoEJX0x1a0SlEJCkGuBK0ohtANS1iuXQwGTRf/ VKF/yn/qn12WdEOIUtA/VaJCqaL+qVMpVdQ/VeifyhC6YQnLtYvRqEX/lHcuxCqZQiZXUgGKoH92 WdKNIUpRgqhSCkoVurlCT/1TEBUq0CnD/hmWXyZmsw43M/LOhVgjV8gVKipAEXwv1XXJEaIUFYga laDWUP80atQa6p8aMKhC7fXDEpZrl4gIA/qnotM/tXJBrlBTAYqgfxq65AhRihqUWrWo0eI0LJi1 Gi2ISkELJnWovX5YwnLtYrebQKEQOnfoeoWoEDRUgCL4XmrqkiNEKRpQ6zVKrR7dXIzQa/WgVIt6 sGhC7fXDEpZrl+hoCwiC2LkQGwSlIOqoAEXwvdTSJUeIUnSgMerUeiO+byrtRr0R1BqlEay6UHv9 sITl2iU21kr9s3MhNgkqQamnAhRB/7R2yRGiFD1oTXq1wYTTsCrKZDCBWqsygV1v+I+2PSy/fnE6 7SCKys6F2CyqRaWBClAE30u7LOnOEKUYQGcxaEwWnIbVMRaTBTQ6tQWiDaYQumEJy7WLyxXZxT8t 6J8qIxWgCPpnZJccIUoxgt5i1Ab9M5b6p1ZP/dMY9s+w/DKJj48BpVLV+aJoVWqUajMVoAh+gBnT JUeIUsxgsJl1ETZ8TdC4bBE20Bk0NnCYQ+31wxKWa5ekJCeo1ZrOD90j1Tq1JoIKUAT3TY4uOUKU EgHmqAiDLUqHW6X4KFsUGMy6KHCjo4YlLL9E0tLcoNFoOxfiGI1eo7NRAYrgvqlblxwhSrGBJcZm iorBaVjfMyYqBkwWfQwkoKOGJSy/RDIzE0Cr1XV+ghSnNWr1kVSAIvhe2mVJzwxRSiRYHZHmGAdO w8YUR4wDzFajA5IiY0LohiUs1y7Z2T1Bp9N3foLk0pl0hmgqQBH8ZrNHlxwhSokGuys6Is6F07Ap wxXnggi7yQWp0XH/2caH5VcvffumgF5v6HxRdOvNemMsFaAI7puSu+QIUUosRLljbU63GbdKvd1O N9iizG7IiHX+R9sell+/FBZmgtFo7vxSqKfRarR0owIUwX1TlyW9MEQp3SCuZ7eo+J44DVvze8b3 hKg4a0/I7RZqrx+WsFy7lJbmgtkc0bkQp5ojzdYEKkAR/GGl3C45QpSSAK60hNiktEh8FS1MS0qD WFdkGvRPCLXXD0tYrl3GjOkPERG2zg/dMyNiIiKTqABF8APM/l1yhCglCeKzkpxpWbgfihmSlZYF zviYLChOCrXXD0tYrl0mTy4Gmy2qcyHOtTls0WlUgCL4XlrcJUeIUtKgZ25a96xcB4BjdG5WLnTv 6ciFYWlZ/9nGh+VXLzNnlkJkZEznDr1fpCsyLpMKUAS/2eyypM8MUUompPTLTMzth9Owq7xfbj9I THH1gzGZuSF0wxKWf0u4jl+IaQGexkgUnop//JZMcuVXKl8tmHjVf/rU6Q1Gk9kSYbVBZFR0TPAn nNxX62eEqLcISq4fNHhI6VCAESNHjR4D48ZPKIOJk0JN0P8dIoNqoD8bY0C7iLgF7A19wQPDoBLm YcpiqIM/SBLQH5hJhuyOlBmwAG6GW2iK9HGIY0bIXz7aIZ68vnm5Ob2zMntlpKelpiQn9eyRmBDf 3d3N5XTExcZER0XabdYIi9lkNOh1Wo1apRQFhVzGcwRSit0lFU5vQoVXluAeNCiVXrsr8UblVTcq vE68VdJVx+usYGrOrpoe1Jz9E01PUNPTqUkMznzIT01xFrud3teK3E4/mTiqDOPri9zlTu85Fh/G 4rIEdqHFC5cLcziL7XOLnF5S4Sz2Dloyt6G4ogjLa1KrCt2Fs1SpKdCkUmNUjTFvibu6iZT0JyzC lRT3beJA1GKrvEPcRcXewe4i2gQvH19cOdM7clRZcVG0y1WemuIlhTPc073gHujVJzMVKGTVeBWF XoFV45xHuwNrnU0phxrW+Q0wvSJZM9M9s3JymZevLKd1GJO917uLvNcvPW1PTfGT7WPLvMpCP4Gx Za0wRFrRNHhFUVE5rc1UWLb6avVovqHYPs9JLxsaVju9W0eVXZ3qoiwvx0JTU0pHl7mw1e7idU7a jdFlrAdYKLGnYyPpPdrNYIdnuYvpnYr5Tq/SPdA9t2F+BQ5WVIMXRte5fFFDPK3SX2BIsbNhbJnb 5R0Q7S6vLIppskDD6LrmwR7n4K4pqSlNBmPQ0k06fUdEo706MqszjcWYOo1hq6+YmtAWuQeji3id M5zYkjK3l4vPpZiVCw0zclENpZygReeh/SoaDH3pQMjjDW5nwwVAR3CfO9v1TmXHHUW84QLQKHWX TpfD9Ctxb3KyNymJeopQiEOLLevPrvukpizxlrqrDU5vKZoMRpZhpvK+6Whyl4uO8lq/B6bjhXfF qLLgtROmR/vAk55c7uUqaMqhKykR42jKiispndkr3OjOLeyxjvCKCZ3/9AaruXhuXy+x/pPkWcF0 fHyKnU0yeXzDyLKEyoa10QkVDevKcWhK8FFsaChxO0saKhoq/dKK6W6nwd3QVFraUF1ccaVLfmn3 2mjv2HXlcwka1ZsVtIbXXFjGR3PlwRgXzWOsdIy7dNTEMmdxQ0XHwHXcyWVX2MiWqRN2OKYd5Iez X+TfHwx4cvz1Pj7R4edLmrlEx1cFseSPmGrgR4ATzww8PXjKcEkY8f/cHYlnNZ5b8RT5oS3jX3bk pO/jhwDhB/lOdMdCi5qXxzkaC3rw2XhvAN8LX3YcfD73JA25b8kMdh3HR7MwtiOM6QijOsLIYMj1 4vqwaytv8xkd1Qd5G7Z0AG+BRjw5XuurnYlVaoKB2ncCA87ue9Tg2M9t4O6DLMwq+pqiMFEIBopg IKdBKw+c5MtypBfouRMwAE8O7XMCqvFcgWcjnjKoIrU+maOqQEVqpb/htZV7jNOipoOGPo6ztpLl JN/nkAUjHi3GVj+YowriADlHPgUlOGjosf1FeVUalJTgCJmMoqfAyb3O3QJNoOVmMo5jHM7Yj7EX o4GSBBhXM6Yyxu9t0i5q0t7QpC0o5BrQyFruNkryPuOfGF9kPMjYj9FCCS8z7mfcx/g04wZWzhoo Q1YxljOOpiQTGdMYezC6GPWMmr1l2iNl2mfLtAWTuLu4Osy2mNFDSU4wvs34EuPzjE8xzmWczTiV cTzjdYw9GSMYzZTwJeMrjC2MGxnnsxpTYTwyglHDyFOSBxgbGEcwDmUsZXR4TOO1b4/X3jFee9t4 7bjx2kf1oPRzc33LRzgOcBPgnuS18t7oDGN8bRscBQZuKLSptGQY3hkCbdwdMBZjgzGWDUMwltPc 5rNb/Vx2c9suG4YZzW13mjBMa26rN2LYs7ltlg5Dd3PbOI21IJ5zQjVRo4/FoTduxjAG6rFwBxcN 9Vitg4uEev1Z1gA71AsXUMfKWVHnMvweYxaMuaECY/rm+qf7Wv3kDR8+lejDL8NyWg45AnX2iTQX Oew7sdRRYCfPXekSOXAlxieQVlo7acWO0HAvhg64HnWeaW77zIHl7mluOx6Loa+57X4Lhrub29aZ Mdwe7Bj5XbBj5HEWFrjIb6HGfJlVsznYRbIx2DUyC+pYJTPhRCphGtOhrUcpi1VAGxHxFdRKJjPL FXQnY9ASw8h+vJUHdbJTcBfGsjsz9IE2+fNwEGNZ2OadUB6811FIN6jnnoCTGHM21797PT6lBmhT NLE76ua2fZHYYoENxT4ix+apfY5vT/i5zT7H121+InpsbutXbV85rWfbpmitHyyvcrzU9kKUtbXa L+/9jOOp6pOO3fWttHE+6656PxnVXGV9HPOp9zoeo43fUo96HoNjM3rOWsy8uG2h3npznV9haf69 9aaaAnXQQDjP9sEp1MgrwYzzmN43byPOXEoWkPK9J0yO9BNbTnB+7jvfvIM4733v0WA4r+2gY0bb 41ZrgZK/jpjY7Nk3GBLT3rZMR3rbljaulS/gPb5Mh/4A78EZ9UukxHv2cOnLtyzn9nNfc1+x6fer vXWYoW5LHdZS7asVsZYbfLVKDCp8tRoMpgWDqb5aLQaTg8FIX60Zg2G+2ggMSoPBIF9tDAaFvtpu GOT5akc4CtRcJtQq99NB5NKhlt/OnDfJV5OBKom+mlwMuvtqCnE27wY17DkwN9cHxuKDYmqu/3IE jtJbrFXkz8HgzWBwLBgcaq7VOwbsI/uAkBZf7V3Uy71QS58f8jTUMmfbieFZ5jtPYuwGqMLYE1BL HEC96DFf9Ux8uMkjUMOPYt6xCarFF9lzcx/6hY751b3BNpFKXy2uqmSKr3aOo0BHJnUWPSHYeDKu w+NHNdfvyMUMmdQmBVqSCNWsUQkdYXd0T6pv9NVaHftw84bZWxznqeF5VcvnMx2f16AH+RyfonOp PRrH8dpCx5/rn/dYD1ejk6JneWs8jifr/1Ro3VbT27GVuqVH6dhUe9CxqlaFZRh89XS95PaMn+k4 Np608sl8CjoD+DEgSkDPoX8nSOQC3GXmBu3cZUym43UZ0vEcgOc0PG/D8yB32aNUyLmZDhlHC+1G TebnLno0GE6rrqrmSpQlgp8vRK0Ixzi30q1s9HPLPQ6h8TOh8VWh8WGh8SGh8U6h8XahcaHQOEto nCw0ThL80qFmbVKfPAw9SmVSZp6H77jKUCdl5HmEpNS87mI30SnGiTFilGgXraJFNIkGUSdqRJUo igpRJnIibvWI18yXcqVjBpJS76EZUDrd6f1ujNtPVKMmeuXugcRrKoXSsQPt3tzkUr8Io705yaVe YeSksiZCfoOvh3ez3YGfRNLrVdF0Y9CKLpW5an00DaVV68vRDZJ/RuxXxUnpyLoCOq33AAHHdzhj X0auWXDcKjCt0jFUqZEpNTKlRqbUSJUaO5Tssd6NpWPKvDtjy72ZNCLFlmOzk8c4J5e1cm9wrxcX tXLHaFBe1opr6Ru4C8H7ZDZubkq9/ZgazoxvULU3aEDVLkEbVcN58hJT2xBUu4epwYkONdn7cA9T u0f2PlM7GFSr445RteU0QDXFj1DH1OoUP6IalHqNVK+pvr64qKm2nuo09apHjab6XqyY7H8k1wST HwsmP8aS7/pHcnV9sL2boJ7VUE82oQqpLvWTb8eU+UpcJcVri8pL/fzf6FUlu/ItryspnuvGjek/ VztxT4caLKJ2rklOnloztSZ50c+Nb1ep+dkUgkk1NYs6NWr+ufq/L7MG/uQGhG7Hz6t0SUpuXvHD zqN0d1rhLp6FZ4V37ZK5du+K6U5n084fOratCRXTZ8ylYeUs7w/uWUXene4iZ9OKoyGSj9LkFe6i JjhaPLas6ahnVpFvhWdFsbuyqLz5wVO3rOxS15rOum45FaKwU7SwW2hdD64MkbySJj9I61pJ61pJ 63rQ8yCrixTPo1PByLImEQaWF04Ohs2cWoUPdkW0q3yg1VDdnz3l17nsy6P3yejflVPjRlHjHujV 4kmTUgtSC2gSbpNoko5+KNGRZF9+nSt6H9nRkWTA20acZrpYt+Yqf6q5ygtqUGsRTa7BoVlUkyx/ BRTyRWCW3woq3gtW6QfpLJ6fSxelc+0/SmfkPnAHhuBWTQEgX41bvD5dfzvG1SL9jPzrj86CesQC QCw/qzQWRuMktRvkuHSehwdw4lXg9Ti0kAL24WrC4+KqABVI8Bt4RHoVVoIR+sACWIrr3TJohC38 j1hCC0nBEpQwHR7CV7c0+IZkSE/BeKIkHohA/X6wDi6RAdK9WK6NaKQt0hd4dzS+OeyGZngWXoTT hJB0LCEK3+NnwEJsyVPQzh8GO8RBLxgEw2EkpkzDtJthPdb7ADwM32OreMiBAty8LMTW7IAjXKKU If1ROoV9mI2tvA82wWE4Ah/AWXKEmyx5pRbpRdCDCcscBiOw9+NgJtTDWngZLpIIMoBfy2+UKjA/ thPb4oB4bGcOzIEb0Q71WPMj8DyW+Dq8Ce+g/niuilvNz5ZAUkkVmEeJlkqCXDxKscUjsLVz4Fa4 EzbgsYPl/CP8FT6Fb+BboiZW4iHjyFbyDTdcasSeaLBVHijG3o7AHk2GSrTnHOzZQqz7Duzx72A7 7IK9WPdxOI3HZ/AFfA3fEzNxkG6kB+lDSsh8LO8JTuRHy+Qyg+xpoVw6j9teHkdHAd2hJ45NBuRh LUOw79PgBrgJ7bkMVuC4roKdaHPaxsNYw3to3R9xq5lGckgllnqGm8vVcEu5t/l6/oCsQDZIdkSe Lh8sf0J+uv1i4FOpu1SCx1jpNYn+JUAl9iUOrUf/UmAPrDUdN/V9oRCKsG9DYCgeo2EMjud47Ods mI/tuJG1ZDEsxdbU43EHNGCPN8JmeALoG+YObN0f4Gnw4tECe9jxLDwHr8BR+AT+DhfxuEQEtKqa GNEidhJDnGiTJJKCRw4euSSPDCDFZAKZTCrITLKA3ERux+MetNgOsps8RQ6RI+QkCXBurjdXwL3E fcFd4HX8UH42fxu/iz/Mv8p/LHPKvpBb5HMUKoVdsF/+NPBs4C0pVlohNUo7pRPSKbQ2/cxazuwt 4OFGD0pAG/SAZLRBb+w/vrYw3xuFNqD+NxGm4qaPjvUMZosboRptUYt2uA3ugXvxuJ9ZYhN6/FZ4 HO2xG8fpaWiCZ6AVn9EDcAifnyNoidfQL1+HY/AOHifQ5z+AD/H19yM8PoEz6HXn8biA43oJLkN7 x9/a4ogcLaYjBrRYFNosFj0pnvTEI4WkotXy8SjCoxiPQWQkGU8mofXmkxpSR5ah7RrJZvIIs54f j0N4HCWvk/fIKfIF+Zp8SySOcCKn4fScmYtGy7q5BC4bj/7ccG4iN4Wbzs3iHuAe5HZxXm4fd4T7 gDvLneO+5zW8hbfxdj6K78Zn4BgM56fwU/mZ/I18Db+av5t/lN/K7+Cf41/gv+QDsmrZdtmTsuOy 42j4Svlq+Rr5A/JtCrUiSTFIMUVxq6AQkoSbhS9EtzgQvSOV/HS2fQ39dQ0+jTlcXWAA3E/2o09M BANu5x7CjfNuUJMlYIFdgZFkBG7G96KNYvGeDZ+Q+WhJDm4OxAcmw22yKNl42XryADlEf885DJLv gdWwDX35afgOGlDvMHpxT9zOLiA5cJfcwH2HT9r38Cre3YvefBBjXniCvwRr8EmYhjPnTWQD4bjx ZB25he9BlpA5WGc0fMPdTO6GG0kAfeUl9IXL8CbO8O1Ex0/Gsr8jj8ESfIK28YvIdeCQD5XfgBuj ieBHTxmNs8v76FtvoBetwn5z9CNR6qw4QwgwrEku85NVPlAIz5JV9Csp7sAengeVQu4ndz7D89wQ pSCjUQKDxeaL9uThhvP5wy7kDzd8lz/McCEfBuQb2vMv5GO0V4bL6DLGIwg+D5ed/KHLHjn8CE7Z ISx4mfQJeU6+EK1uh27NwCm0fu7EHrNabSUGjDVZIw3vtr9teBsGtJ8c0CuDZCl4BS8kJvAJidnm TGuEReHultCndzYZO5/r0T1pqNaaG0lq3AOnTBk4cOpU+cJNgcDfA0eSla+R9b66nB8/mFKItzGJ foe2jLdy++VrcBVwgKtJF+cnN3jUVgWv/Jovivza7MSal5y0n8O+tGMvCE/ryaJ1CjzWGv+Ta86S oejfK2OAkC5k9QpszFAMyOi44AeTkenuYaNGliakB7xZWWRkWo8hI0cOSkrDK9ypVYFfNl/WAmrI aQUZ6d+iIJsEeJb0xzVEQawtMuUmXuUn1j0wWDN7HbP1sPPYptOQzoJeGeY+LmOW0RXhMrqNVWTr s2RroOJZrjwYBqaRbUCks4Gt5DUSiWVGPyOTEUGjhlY+ESen9HZiOPnuybx+6XYsKTHblJOdY+ME hdY1uEy59eb423f3CWzttoLY62zp3QIfXYim3zeqyDJuGzcNtJC8VzNHJZ/D8wLuiD1qFYhD9GSw 7sZ7aUNPG85Aev6w9kzDGcMZVnqONSszx6YQEtzd7LoeUa2Llz2qi3dtv+Mussw8YakgWCYtpn88 tgL9YguJR5vEteJYnfAp1Dz1DOVgTUVj0AQ4MOdwWK52AgiO+xQS/49xJoH2wETuFL5p4fuKx6DV 6DgOHZjjOYPKsAf83KW9wgQV8JzZZHj9zeMw4MKAC0aTLS8tTZAbjufTkc/OwX+05TkKgeAUkhho zyjhMpNEjW6lbVyfgvZjvdW6VYHJU56Sz5kX2b2/SOZuubRhlTNPhl6WI33Cv4LvdtTLHB5D7GGZ POKwRhvZJroMbYBOds5wknaFdsZsMFGPMhkNHO0Sh9c2aq9soyERDabIqTn+wP37py954771Rysv 9s1J6j8t/brc5CXT5nPbcCpKf2BF4IvAmcCHgcMb1xEN+X3ghcDruUllC0hfctu++w6iXWOlH/hG +VJciUtbwcTFt1itervezxU222XdeD8ZvafHhHjQRBzgLgDHfYv2d5MZvshjMX7+uiZ1kuFk++l2 w7l2fCY+ac8fcM5oyktv75VhS+yTk80OUx/WUkGemJCY0x0HmjNabFab1UEiBJqwVKU6ZDeLWrmo kOmV5sA5ragVSe3FKK1WqzBG+jSa+v0D/YImX2NUicaYJ4nrFIl3mcTl4uBe+gWz9GsDzsCuz/Ki lDo16tBfFE/o39PgT6CFE2C1J20IVxo5yz43sk621HaLfVnkOvvdkY/YH4rUJBgSjNmGbKMMRz5a JNGg04HoJ5UtZnns+mg/2edRxj/vBk1kHMFJzrTX+qbzWLe4HoZ9nAq0nKVF9ybpkWh4/d3z7Thg +efP076jGc60nx5wDq2AV9RremXAFDLFhuYw9elNhwzdxZ2d05+wiYIjtiwnGiXCYqMPQPzrgQ21 c4ct1inix7rE4U3VL51pCcxRfE5kv1GrVOrDP+5TVb9ykciXLl1Z5NI//MqDw0re27kmcDZwD1pr fHJKf5WK9j8DPewQ9j8LFrcC4fOaZTHYIT53jy1xvX690c8ltahU6S4bdtZjcMllh9O12rhEwdK9 zfImPrSm5uQ+cWiA9R6lEmKIGDMhExfw9U3QGyfAvAtTp0xtz8NxZx2mXT7XMeynzxsunzbg6Jtz 4rB72ay/QvAJD17oCL3s6LtCiONwqqR+nZiQcX3uYwtuatxwe0axzmLtaalaUzXVc2P3HiMyjCMe neZ7YdbK2lsGvdX04cDb+pnJZNPG5Q/V128w6K6bLrt12tj5aWmL5bvuz07fvmr6vYW6IesnfvLw yrjYB9jPRaAvvIL+nQyZcNRjVirkinRO7CHvkZ6TsSR9SYY8w8/3bpEJFlkqRjwRGBNkgkyWwVnW c9qUPfr1mc9n7OPS0fnJHiuAU4kWWtOilCVQH+nu0Tufd8dpMjJAptTHEzHez43aAynHhLmp+/i+ OCuubNE6DXTpytkTNKafTGvRWnvLsgzvotucQ2uenWL4pP2j8/mnMY6GTOtwoq+pUfMvtJ85jcvm aZogpCUbSDLOP1NQkziFdJINdG5WCDxOoXpCfUiwBJ8ttLaeXHkKo4mCE6xZnDJw8rhMNYn0XDN7 s1Up11cNUeBrnqy8gugjNuKDuGbYf7H3JeBRVWf/99xt9n3Peid7JslkskySCVkmC4RAICEJCdsE JskEJnsyk0AEZFEEF4QqLqiAW7XUjVUiWvUTS13KYkXbUqv9qrHlr1RtAVs1w3fOuXeSoMLn1+fp //9/vqdc5857zz33nPNuv/d9z0zG/N9LJE/oosRSscr95Sz/dLCMiSw6Q0qe01j1W+8dP06puKJS sdj+jD5Cys4USUmxpEYsZSWWWNBGPtkQqttLIalPgxb4c2iBEUQy4XUrDHpYZkYaTLRelGB6HtaH OhjW9kFtEJFAHBkp0zHWYzJFwllRKnEUzCJigPbwdhVQpaZA9/KMfyzgIRQH5Pu8+jxAnoaNDyIy j8dC3IXGZAdOtRYCjQjbmykO+hZvf8lJoCaQXrRo+6HNq1/ddHLgReA72WSdFtN6atXDi7wBz7yO ohzylWFDzKnnPtyxedPfTwAV6Pw9OTteetulT/pGTj11yx1PN85A/lVz+e+0BFbwHLHHXcjSrISV mmibxCa1yWxym2I5TEPvofaSe6m9kufJ56nj1G/Ic9QlyiCmgGmr2UxHq7dySqBEECOPPUWsiKbZ /xDTcnqUrHVHSBTKKAlNmDlYjrlh+t8PS7DtMAWLM46SRrd8mbnfvN683Uyb46xIOufVxz0IZzIR BH9cOvbRuAfZSiZMAsCABxhIQsR7oTYSZJJxEH1YaBdIHPm0NZuWnAztLp+XklElXX7w2UPSNw/e x2mlGpW4XiRSgwTg3MoMLgvtGZe9KhbHPAoT/yJQqgZALjImPygRDexsXafRoAwxA+p7FOrbDCvJ LMLjTjKIDGK9Qq/UJ9gIG7CZZ4FZpNSSGJsWe4xl0o7pFIQ8Kk4ySjqejfrafladEzcKlh2g3kqB fnIAqgtydv7C+TDITGCMC9k+LDzDeRYrMqJv3BB8tE8sATzEQo1TShDWux2A+L7WS2/se65pcENB TejT3zz/URcYLS0Z7lja12eqKb+7x7sxv5s8WLi758kPf7J9wc0zc6Z77nwj9MWZR1fufi9reLp/ VVdjbSD0ufvm+jUP3drp9tcgG3ddPkG9Cnm2wDgzzy0hImgd9L6tRmTfWmzf0ogILXdMymgV2Kyj gdYtVabEn90OkwYcOjyIxY+JUhwwzqvHPwpbNuSTFfFJDJGTHQMMapIWJSMgLQGUAKYoaBjJ/f32 4kXbDgHy55tP9j0beuyP883F5v7TQw80QpNuaC/OJg8PGaFJvw8MN/71FMwFdnwor0gS3XYZiPpX H9970+1PN0xH3OD8ijoO47uJSHuOYGGGRYjkMMM6qJVRMB/43bMSQ7VZSLVgAlckZChT0y3dt1Kv ljKYelUIKRh1HGfg5eWe8aUTyRhJzL/8CfNjZgNRAavee9wpC1IWpA6lUpbkqrmp7QlHuCpHFVlV xSoLHlRSxGFH+1xj9JHauWDuKBlwK90PsjJL8uyM1AygdWaMAsatKoUVaWV9g/O5pVqgbZg9SskP vsQBbhTYDhU9J22oh0IfvwTFDkWPvMTDxzDBxi55xiHSjvHhzDP+0YTF5bAiJYiPSyCdudqEHA7Z HLpOSg4rCYc0U34OJeLhJh+ZIjRLGkY4LY20BrDKSHy3BDDGG4sKfJd3vB766dEXwcxXgO61p667 sHBajaI8uWhm5wMrT7RXNGq4Y3dRYrMutaShK3Tig32hc3t2geQD3kfuCj3jsmV2ryhKLVhbA7p6 XB3BF0HJsddA3UsH7/905/95pGbJgsi0R1YPvbVuRtXq8TNSszYqKm/GZz1HgOW+0Lm9j4X+9qBr kEybN3tZ6KK/umbLZYRqpZf/JHqZCRJVQO+uGSoYcm0q2OQ6W3h22rmCTwo/mSaRFIAZzZXpzbbI ZoumWRW/1CpayjCH5hML4qyfzY9eEJdzaL59QZxqgVQ5X5XYOd+2IN79+vzKBfGjl+9yN5gKXZyu uLBw0KTTm0w6i9PlGjBZIGkpdpqoymiLRadTkZV2u81GiAtdkkKXjnJbcmQmcKvpjOkTE2UyJTLO nBGrI9GdSCZWuxcWj1Jut0J6mGkWuUV1IlJUPVN98n0YS8fGx9Tve5CNWrAiB6CKTS4zxEdYhMKD P8OmzYw9bfPaVzfbzegNfbIDY4v6Ito5R+UJgU58nQKhFKZwJQAm3jCOJNthZEVahugDCB2iDDC1 YTV6rSkGmAwIcGFv0gJICmZ7SRT03/CN0qLqREpEknKWu34kuHltXmEqKAeNW1Z1rxu+IY4Ri6Wi iHUPr1v/3rQZ8dL7PmvNr5x9fegxlkrZ0NFxr7iRpm0jXwJu57HhCIVa0khR69YuHO8gnwQVDNMo jplzfWjPgVAwQqWWNYrFjSRl3QpD/5LQmyHZyY1PAhH5iy3jv3ynKYVtFEPfmwlR+23o83Yin7jL ze2UA7FTlu/MzLxBq3UaVRGxEZkRpRG1EYxEFQHEEaOU1q02PhQnIproFhZInatksogXQAwM4nFE NiVxK1TKOiWpLBCt0IrJzKPkJRgaRG6lDcaDPUnPJL2URCe5CtTvvu+BKjIVfYSc8OI4whFYO5SO o8TSgxNJnDrjzDnRgIuH5HzBz/LzEpNw4QNjWH4mH/chOuqR20EJAwH186m35xQXtzRKpW8VpHUG azuAh0zOD0S6ojOmkwDsrMhqHt5RScM8Lzb0x32dlbm1DXMaKIqV3bJLcf3IXcV1pcPOaoWyS5OR nrLUrK26bijr+o21ayPVWvCjpIWzi2cshP7ihNIrgtJLIqa7ocBJVq6VG4i/sg9ZRfKHDDKVlgSJ oIkYpZQH1YkpklFKtt+cjKs7mNShkI04Hx+fqBNAPDKs+HDCgtI6DDIIXfKFrDkWsJSuQSRVLJ7e 6X12W25zgsaoK795xtm/cflW/b0L51UWDeZpEsiWldoo+8iuX/xWqzE6sqzWL96v3+SJVi8tiNBq tY8jvO+4PEaPMqfxnvR6d1RFwvwEMi2fzLVHxOQS9hT7JykibZOhxaSTskdJBSEizQckIBd9NytG lgV5OcJZHVbS6mJHKfaw+XQEQaaNQhOQS09r93MKh4JUFLrUx9/3nEeqHrsIHRLmcOOlF8d5ZfMq niiQYDqCfIrPZfUTTgSLhUmE5SVgmhQRxFgqQ8REj3z2cISUFEFldl0XbKzWyJnKu1zZj/0+o3jJ 2kBlVkde5qrq5b2b/VUjBur+px6K0KmomREzzA9t/+azn6dFGiQNLCv3leSsMXx5ov2RendzhuHT ivI7nzqwr77yD1BSc6GeD0A9RxEpxEo3l0KmUGQ+mU/NIGdQ88n5FEsA0hRBMhHWaE/sGt0oyRxC f/GSOEqp3XKlKOIhRgaLByuwjlIqtwT8WOfV2Eyt0aPkl/vFqbCigmA1NjY2YRDIA8bGLxZdUT8m msK2AGEFpz4qwKYBXGYBKIpSwJdX1NrojJk/9pz9OjHm5oNdj75LPVqz/beqfVtc/SHJokW1zWDR nLy5SS9EL8vIGB/70dI5HUuOvGnJiWGefNoKHhGLM1cPOJehWKC4/BVlYE5BXNjklrhlVukK2ykx jLDNB5NPqRJeoCpgMnMHwVFyt84EckBTXksuIU2Jik6hMiIicp4ni2EemEFJDoik0P5Zt1F1SvKM CLg+EMGqpU+0TrQN1lgQCqB9DECvHxtHm4Pn38N5LK5+ikrHx/COwtjFiNcjshwC+DphwHWWUk7s ECgFNEEgQAYB/V7YRYLQjbYXsP0oSopjaTHZVrZMI40GOX13J7oXRRVxGllyepMtv0DR0dAsV0un 5d4Jncp8351btrANDMVV3HbsC4bJzRIzqpYBX/sWU6pMNnSD2JaaFfiHWl1YzoRqb5ytNrANLMp8 XeP/Sd8ErSMXJut1xCvuVIVZmayw6Wk9o9ZEpG3SbEq+Q3NH8h1p8iQxWcAWrCHYZWw/S7GqUeA5 VFdnTIe1dfOB7FbHKCDd5pI16aKqNUaVA5DTqJxpfjVVS22jKOoomUHMJqvdiqW6Ph2pq0+KIWVW 2ShleNZqrbQ4/alHwRyiksx3y5da+izrLNsstKV+Hk4xL54XQNXkQl540TN+Mmxs5y9+hG+efx8l QiY+2YmH1kXHxyUjLDUZrRhfCSuPvqU4+S6FwCsk4UjWUO6MfqLGZ3UCCJfwXh1PVz6mDP1jX1Se 3VKRCAbWLC0JvRL64uM/xqtbZs7LS7a6cgIdn77jr5s27b0KTeQ34wsbahqba2sWmRtz7r7Dv2NW jHHOKPlNlm30EB3J6R1SNq23+fXQ5w+tnekw5qWqnVnOOYbEtNTbOnf+3KBOBWJD0gN3X9c1uHaw 7ZsPSuqdy1aWB6vKMmK1yK4zL39Fv8i8Tkwnth6M5PIUoxTljlbu1hJ5qzhRmY2EeF2Z0VKemUYR 0kRvgmNX9lHyS8JGMW5OEpsAXHUJexJeSqASqowrLBKiDIi5MkcZWdZV6J02Sl5yS6StYkIZFFfN gKYNjRpmIudRrV6E8A/VruMfqS8SpaaiS9DgTUVQA1g5yL753TKdGuNgNrbuaMAaKNbEmzrMOa8A Rn5bDYpaZ5yw98xutZSRApIluf7ij6tjGBXMNMCNNoOzatfsWYyYSWxZvWzRUoU+JmVFybJEGkgY mbE7cP2z0JYlrNyyG/SDxC8Wx1Iz7TEKncicHXppaGd/vNgwd+7eULDTotLSECs1rzwPiOI5hbU9 oRMr9FJGhj2BhPnjV2SQeRRWEClE3XPQNzQH2CjLKEW6FRG7o0QJiqbklkS5FAZCzWEq+lRCF/72 m1ZuQRGkDqbrtlQECAgLxsbeHRdw4CIqka4sM3j/d+ZmQtDLBDhoaCZEA5rcixeXwde7A/GMmKIs +bO/eMCiFDGRw4fbnMyj+J67bPFXTQ203l76a0/tUGEkSc3RVuhfCt35dnqsFsYDaCkuyM0gjI+x RDHkBdzi1oHdNKHQNWlalFopc0rRJfGK0Hf1LFoEcQcsVo7XOVT52MTa0U48XKwJbXrGkCaUzTBC HknBRCY5yXX7o0sjVDSpsi73t1aE3pmVHU0xAEhpmZbJK9SlJBpD94+v33BjY6SaRhlKA01ae+4B RvDEMYuclSGbLr78lYiECOQlzrkN2YUA5rEWZ2x2QbaLiQG15shaGdJBkny3tqB2ldZKRoo8M8sz aGjq0x3kspaWqopsO0NIY4pn5+xyIo5SWjOOUiIikdzhTi5WVcVWZVaVVtVWMUur+qqeqTpV9UHV Z1XsZPvlKrYK9Z9NXjrClTvKyfKu4lHyDrdMy3kcnpc9pz20B31f2+xtxj5Ce1hCFmTbWqf4SNH4 eQ/8zzOg/gYmDGN4JxV6iYl3E1MR7Ic9RUgLYTKOTQD6ADQAROZkoyQwGvBRQXAYISuccBlh/3Uy GRc5+Q0Cvhk9MdG/eEU0LZaKS8pWPz1DKVJS5KO5nV3XW3+atWDXrFkkLWGjW9d6FnnlkbOXlrSo pCIqtv+G63etbYvTz6nMro9SAwqmapHLVm3LhjrTWbKOgA1cJCDnKJKjGIuOUyYkrE5uWLw5ec6c pxpu6d5mM+mgG7G6X5/420hJStSdob/7Mixi2NLgen98jdtuMzmSojYM/zRWP2mf9MtQ6+XEtoOm qFwF0nGUcnfuqiitqCQVAVlZeostoxQCWYKHs+9yICBL5YGMg0DG7eFe4iiuUuctNJESogRCWYmj hCzpciElyegWsZeFUMZWVghqGhvHUGa6GpYVnZ/AMt49hTopGwaNbKSK/G9n6yZDJsBqSQ7rJQxk rp4oiqVIljF2543NjYR5zf3RsemlnZtLKUYmjl66uvakLCI2pbOyXSVildrg06uqoPRMKb7L1y8u kIrF1Bx7jMQkiQputEjk1Ru2FNU+PFwRoZVLoPuwihdfC02rmZ6snh+62y9XCehVD/NhK5SnnIgg HO6YYfGw6ib5Hna7nDGvoUWaNVKZ/neiKMXv0NdrI9V45yb8IQ3h0eUKG5BoJwolICgY8p/Q1Pdt +vqrj0NffvrnvwJDpbPTAzPNbk8XeOf8yq1/vPB16PMQyA9dGmjecQzIl9ffDVfiHP+avhWuJJso Ja53q7YrQWkOWZQXYcqTFMkh1pAHwO6iUUrhVjNyUd4nJllMQpO1JTZe6UJ/MqEqixmlxIfZVkkE WYpUqbJ50+OJrmXpIL2uDJS51cc9GGRxXs5zwX90gzT4rbxc58TKg8mmwB+qcvkdex3MPXkX4iNX npMHNDC59Q9ztX2BLiVNPZyzcu8vc2YsuCfaVZexKJ2mkzbcH3hvUSeMVhKaJQEMWlqQnNFZsvyG m1bk+nOphDnquHizPqFlfepb+xc+2VE5orEajaFTvYn1IlE9JWEV5sOhNWDrMxYFKxnf7yrc9+ru R7KzERoaYOZKQek5ib5nrZkJpqgEJRTZEdXuZQn9CWTCKDnTrYMukgmaclochJQ79XIMiKnOhDI7 aPLqU5HENBJCuX+dZJvkQQklycyHvIdlBvPR8eF3PeYwwBed90zCkmlCEkIxI9g9X7qFM1UWGz82 dFzaGnwquUhG0iwVM/BG83IloHNK7JUuziqhMkz56UVNcrGIVpnW93fNndUK81MR5L3+jlV/SrMY 6Dm6qCSdsnQ4a3ZBnKz9SXVybElKzNPjtigptGooBSSPOli9lOD8dJ8705XkSp4vb1TQcikpViel kGlxxjg9hP9t5j3mZ8wvmWmVOdacaaYkKjMQm0cpk1sTu0YvQr8wzhGUBA4ohhZodMuZNXaZpcl8 ep0RGEdB3UFODMSjINMtT8sjmnJPZXsz40AcbDjiUNepSTX0BpSKei5eHIcW57noQXX/+Diq+IU3 z6TlTVif0SQYE4ISkt9lM6ENlWR+E0AQJIIUmLAmof2AQ4zYOFLX6o2PDzztL1ny1O071imZWlam shWWN3pstt09thnVoa8OF93RpJJToHSDKrWkrtxltVqSXP1zl9w+zzHviW5dtD5ytssZy0XrNTGB BXsPRUVqmp9H0jRdHiOfYdREBuF3q+6PAYzYTVgz1F6b3quFafxhqUfeCgVBVbiVllVxMkW03s1Y 2SqxHtXGKgLYVlBc0rakl5KopEw7ynaKLhadHC8aPgOrHPX7x/m9kAuw+rtYhFrOoIRcl5+UjAtj /EG5CH9SjsFyyiYBysZReRQnMm0iRVtGYoxie0bHPIlEJRrKT00mU2Ybc6I1Ra7EkojGgRyGyeGy qejm/ZtsRaYfXRAp2ISCTAnjmxPat0QqSaqYybKFSxY7fnlwBYn/0DgZYuPT1AmimLjRLd1J7qRI uyLbRDxPkYQZFr/mg5G0CAYguVueLUtqSm1JS5aypyWIZS0RdOeBvJJ0T6ap1ESauuwa1GyIPp20 X4hD23AkornSErQzhAILRKPzHlgVD8AQgx0NSeUizAH4jfEwKiFHQvaB6wxkEuFmjX4iI57YQYAC Cjvmg7e2aWlNVHVxVZeFpaWqkRPLOjWkRszI1L2BgSW1Eob2NFdNX7KljKREDAfBSGWLN037+N1b FmfPbfn9/hg1K2bnmGKTDJFPh/JvS9CIJChQa7O7Zi+KnbWyu8dXeiDepEPfuL/8FbuJehP63ip3 9UbFRh15p+JOHZmmA2kKcL8O3K8ACrXdkZbGoe9bxUKDg7JyJjkIe5pGLWIjOIpoim6mmpnIWJhN pGbYKYUuRUqUvv46Too++gjH3dfRNjVQn/GcwbudruLMLIdI7IH/CM+ADu9TGkS4mIuEDpJjhGcs MP4O+jyaRbuUJEVS8UkkkqR4zYu39JTlRsa3vjbd0ln564UVOmXf7bVNPXO1Cll0Z03No/0PPd31 47QDKolcRy2tZ9l6Cmh1sltD94Dn7q14PpQMZG8mmKQitp5h6impWJ8TOv3eOIgGC0K7Qn95lvRH a0Q4d428/FvqY4hOWcRed3kSBygriDNw3H1suj6dTTekkxwbG0dGcowIWiLLkZFEZEKOrI9YB+Nk TjaTkh7HcoZ0UaxBnW5IUcuPglsIGfAcUYssLZEmNhFdJ5AStwQ0OVrshDRFRpSiaHcB7ULxe2+u 8AudgPr4u54i9bvHwzAUfm1Wp9mPH0fGR3gwzpcCBEE4+KFUMxbw32MxKIEK4NRGgCnsrZE10enD Xfcssk+LqloeqUkvS5u9rKcnLSWvqCDX9suuG2ZO614d6+BS771z/lxrEtsg1lvv2TxWlwrcCbN0 WVz/7VufgnJkIx2fP/hzN12alB+b7Lx0bCv2TXr8HF1P7SdyiPVuy075vbGkRBILxLFyc6bDSskJ uZkwO1OPkgyRTIrd8YQz1xqbaFHKpYlsZlY6wWot0MiAkWphdGZoZLYj6aOUeX+iikA7MCb0jS1o ZFNlBIV08t1LH6uPT6A1dEr0ebRHsDVsarp89HWHZCf+tooBf+wokgElGR+XDGWHoUsG4yH9sXvh w5741h7P2vhFpT5rwr1ZsQqpuvfoU9M8vZWVNWZZ5LS55U2LP1itToSGBoM/rTPGfBn69CxIzDBo IOe0qF4lUhlDoabQ8AiMOm0tkvKmk2QecCQKP3o4TThGiJ995/gcmEAV6AFPgr+RHvL3VBsdA4+t jJHZznzJ5kw5/n61Q/TFDzvE2+HxmeRGSUh6p6xTbpavw8cZxSnlSuULqsXw+FB9i4bRPKR5SJut fVvX9u/j38e/j38f/68OiJ1V1KKJX0R5gQj/6AyAVXK9QJMETbwu0BRMB18QaJrQTNAM7H9GoFlY SvxBoEVEJ/E5+lUbmoLjKEFQoGkiBSzCNAPbpeABgaaJBLAR0yxsZ8HLAk0THHgM0yLYLgZ/EGia iAPHMY0+7ZSTpEDTRBL4M6ZRRbOKVAo0IMzkAYGG41APCjRFOKibBBqOOUEzhJl6VqBZgqNOCrSI OEP9RaDFRDb9ikBLiAL6gkBLya+YdIGWER3iJIGWEyvEtwm0QnZSHO6vJJbo+XGkSFaGAoGGsjLE YFoG27WGZQJNE+mGGZiWI14Mtwk0XL9hENNK9PMIhlGBpgmbYTem1Xic2wQajcP31yGZG/4o0FDm htcwrUfrMZICjdbDy9YA2/VGm0DThN2oxrQR918g0LC/sQTTFtx/vUCj/h2YjkQ2YHxaoKENGHdg OhrbwB8EGtkAr+tY3P9XAo368zwmIBswXhJoaAPG9zCdgfqbogQa9jdhXsRT5CyeImfxlPWLp6xf PqW/fEp/+RT5ywX5V/qX+4P+63ztXLs36OXa+vpHBv3LVwS5xhU+bk5fb19wpN/HVfQN9vcNeoP+ vl4uy+XKyoAnp50r6+7mcO8AN+gL+AaHfe12rryvr4sr6w36B4a8P+X8Ac7LBQe97b4e72AX19dx 9YFXrvC3reB6vCNcqw+Ot9wfCPoG4cL8vVybbzDohe+dQ4P+QLu/DfUP2KfOBKftbucK8eqafIMB NGC2PceJ+ghdMlCX/3urI8qJPnh0ERxRRvQSQcJPDBBDhBdezyV8xHJiEJ6D8Prq/YLEEFDAtnPX 6NMBR2m/xv0ZeJbg1XtQW6ifUa9SL8HzfqISti+HL3T/OjwyB19evE6OaIMj9MPsdRD3WgFbOaIR vvvg+xx4D/39WRDe78ctFfBqENLo7MUjoh4crLBc8MgiMgTKSdjxqrrhwU0ZO4CvfPDdB9+H8WpQ z6twYo2DLX78FC87NGs7fKoHvg/i/n1QWv/MilfCJ/yQ+xWQRqONwPdW/MQg1iSaNYhXyUvMj59q wy1B/Ctg6LoTrnIQ923Ho4XHDxDXshV0pxuPWjhFdk147MDECrPhGDlQkuFxrhwlY2KU/42y++5a GjHVh33MC6kV8DodtlfDfm3XeAJRlfiZlXje5fC6FvLdgef0Ye55KU3KahCOg/jqxXLjR+nAv+/m w5x6sf22YwmiPuh+L9RIuzAPausWfJTXaVjWQUHW1VgO3XBOfpZ6PIIXryGA29BcvGf4IO2Fsgrg J/3YQ/m1tguS9uP+6H0Y90HPo9Utx6MG8VrCWkCyQ+v14rX2Cjzxo7YJq+F1OTTBZRCunsN6DY+P 5u6D/YegnPg5wq1+LFte93w7uvJhHEDc8zPw6w+PyM85MkU+PdjmfAIPfXiWILaWNiw3DltyAONK 7xT5oucCeFYk+VXC/LzmAlie1VPkh0YKYN54Xjvgezd+As3OYQ7bsLZ5y+Rn7saSROOl4zECE7Kd qnMOc+LFEkFWF5iilzbMUT8eKSw/dD+AW/qnrDQgaAPpP4hly6/QP2E/bXgmfhW8zY5M8DMpF78w Vh+2TjuhIKQYj4NwtkIiEx4r8WHHEpzqR3ZhtZm4fw+cMxOeg1gaaO3oKkAshc8iHbcJurJP9P7n Z5mqYSTRcMtSLNF2rN/Jeebiv6quhrGxGuJWGaZrYSvy9hnwXIPbp8OWBnhGWFmF/ypxOkQO1NqI ZYJek4jwXd8Pt/NW2o+Rol/AtZEJaf8w9Jq0h7B2wj7O+8II7D80MSeSz/AUTB0SZDA4ZT285fVM 0btXsNc2bGUBwXv5PMU3YXvI2hYKsyFb4r28D64jjNZhHLi6ZAJ4xiDUrlfwXB/ma4WwRuQHgxjL EB6NYC/jcfb75NUn8NWH/X9ylJXCmN83XxgNEUq0Yn/hV90qaKZXGPl7NMRZMFdXSopHjO9axXdn nowcw9grh/BfVXcL0g7g0YJXtQ4k/fmwpRvPGJii+Uld8Hq6MqLyqOzFK+rHkvULUe2H6JwTbLFX iB/Lp8yLUKtdyBgncW9qFpc+0Xtwit1OxrhrS4rHPf+EhnhOJsdbifXfhbU5Ne8I4/Jkzz4h2qJf ZG3F4wbw7Dw//LqmWnc4W+HlP5n9hi3u+2zoWhxN2kc15v27mgsjMsrJfEK07hPyoT4h/g7C9yt1 MEh8O2sOj4z468NRoJ3g861h2M8HVzSJAz9E++HxeJ/0CZG4/QofC4/3XT3y0uI5CGIMCH6vH4c1 5v2WrDv+R6udlPJ3Z7gyZ7lyRTw/yIIKJ0aYD/G/DLYWELlEPszZ8mHmXQDfHfDaAQ8Oe+NseM6F RwpsSYU98mEmng/b8ok8mJG78Cs84gyBx2/zMRWNw0g/hLO75YTve/ypHyOAV3h6GFucX8CNsF/4 IJ+c0O4TeOP+R1E1fC/zW+udjKSIJw6fa4SKsReeW7E0eSsdwmc+bxsSOJuLveU64V5AsKsVwjo7 JmI2eqYBWyyHs5oOYYyAgG6Iz2bMZ0CIIL5/CYfoVTch2X6M2nxOnYzXyltuzxT8CRDf9lmv4Evd Qq7VjiNaOJqjkfisjcelqUjmu+K5b2PD5Ex81YZseQjnV/wT6dg+fLDNL7RdN/FEAGNDUGjjZTUo ePG/Wpp8TRHOHHxC3sZ9S54oTv1NqEV4SbYJtQOPBn1ChnEO9/fjFQam3A+vog1XTxxGlO4pfcKW N/WpIYxh6Vf4lQ/LJyz5QRyDAhNRjxNsla9cmgXP8wn1779Gfj4BRyaRrB17IG8V/m9ZRRBbBV8F cBN5QTjT8uP7/gk7/C7/XkEGfsxhr1A5TZVD3xTM8WJLSxb8mJ/hOnj0/Uvk8c9XDf/9+P/9Hh4v nav3Q7jIR3je24eu0bcK6yqcAyKZXmtf7xxcXxdxCY6MrP/qPZvwaFe/PxPraxjX3tfqVyfUJCh7 4q1s5AfK5xp80LF0CT2NrqDz6ALaTRfTs2nXNUZt/AE7orMRPyALtl6rD/L8fqLrmjKuge3tGDko /oOn0AVoW9//D/3yP0loCHD5Mu4N8IE/p9Kj/zeX8Otmepljo17ESmw3zbzpSwUQkQ9u1P3dsVF3 gQQgS+mQs2L+DskwhGMZK01jAQ025pOAfrDeUedIn9IS9XDM+iiiCB+1OAb2CbsKPqIEHQ7uyvFo dZxh1sqvZdH/Oa3hQugW1dflD25UlTo2ki/DVyqp19186K1b/vz4qz9z/uL+rVveiH2joelHDsXE WtHnXo4Nu7NiHdEsNZ+W6oxNvkF/g395L9c4OBQIcnN9wZV9g11ZJocBdZDplOEO6Vx1b5s9K91h 42/ETz7p7/FxDUFvT7+/dznX4Bsc9rf5uPq+vmBWriOb7502t5arqS4rr66pblzIlVVUTK9rnF6Z zqW0pbryuSvncMSYFK58hzMr25HvgP8WwUtXVnZOlnD5/z8DG/ZMlTlgCGrDVij3m8kNG4i37dzn K9akZ9g3RO1nDzwuO6JRNJ9t+M3Qh6/n2A6cuSRZnPu3c9tDEvnp30Uueu7Eny5t2b/r5c2Jn6xd oA50rnpzwDB+fMGl1CcWtNxNj2e0ahZsiHpjYMc7cQsy3/mlnrkx7+iOnx6aM+vcX6bFPdW083rr A903vTyr6p7OQ4/lvfONJOPtQ677SQoa9bdMgoLrKtQ8sIkp+dW59V+vfmfvhSdHvmG+uat4IH5v WsoHt+l8N4fSN4Nti+5rfUPz+PoLR17UH3mraWeXuHX68Yd/fNa5jol7fzCDvol5fI3EeKe+4vMv jXPeFd1+v7p7QUjqvOeNm/d8QPc/YFvrvf0//iwbuO8nv+hoLS++a0dc9r1xN9/yVbs44eKvvoL2 ewK+8kgD8TPNfWcrzlu/nrHgxpvfmLFle+Jf9Mv+9xnxk1nJjkR+4JhrLyPMqeyqnP5TSwzLR/od +WgcKnRDpBNX9wZ9g72+oGPDru+Y9K1QC5uRST/hPX/oqa3bq7a/d0jT4n9Puq51O5t14uTlLT+a 8evqwh3nzrClu556eNWiT//xTdv02lFZr+Ozh/OeyJB88EVf8hOKecsYZ+26k421p4+kl/9Gdnrr aMvlZ9ef/vDuQ+viqsvV3W/fuw80PXLslH1P4YV1P1nw2K/jfGO3PbHqgRd+W1W+YnHG2vHDJKC+ x6B7ln29c+mj/oNvr+5Pa42PqeTmPRNv+EWQ/Ef1X5Mjljx504BTnHZp2/t/OHz3n299fPaHgddm SnbtO3vrWcMdb1BjksQm9r+atfaoJq40TkKCmGx98VBbul5xFXEhzACB8LKMyQDT5oGZBNRVz4Yw kdgkA5kJiCiGWKliW7us4FpWBKm0Wp8rVdd3Ra22SNF6fJ3a9e2pr2J9UUXZO4kQYOvZ/rM9ew6c M/fO9333u9/9fY+b+W6oP05feyI77ZQs6+Ho483jkiLHRrfWXN6fmn7zrDW98NoBpGGws3XB2aTS up+rJqB/DHpyNPDOhS0/6LH8tMiIUsQ1sBH+D67z5fP4/CHFpmrbwi1t23nDbKsONFEFvTXmQ0Ab fsHqLz+hGAT1HPiEHkTIaauVshvNBgsgaRNbZLBTINORYzEzeZSdAXLMDUkZEovGIUgPJLlhdIw0 QZowDXHxZvzPlUDTEIWHKaWoqEhSCBkZyCgx0tYoO5VPM2aWthdHyTNJbg3ani8BOcVAS5kkERyu JUqdgsNyHDoRSfbIkbq/f8MFCQWQWwwMA2JAJFCZjXaagSp49cgyWMy5ni/BhdGoGBnI8fsF8PUk GoAM5Qb+AaJsA5MHXY+lbegQZJDHFAO0VK6VtuWiv0dCuBnfwCCv+F4fmLvfi1/yHhoY9PciF6yF 4Lw/38Xj+TR9eHLcp7nXbwU1d1lLMI3oZ3pCQatkBNkYHXfxVN4l6TNi2NnqTuobMhDsExyb+/BY vnX57ZZtmycgH0VPmbd93dtjZ608cLnopvDaj1eqH28Uj2zclPxO/uUOerpmPj1Yi1cEnaG+SwLC Kyn1lhWJg8RjA+6M/hp8kDA3Z6Hw2JhXO7WrNqxSVp9JVk9JcZXcHSjN+jzvwCR8TRLa8PRs1VP9 lxGfNjSHa1of/LXdd1TJvaDEdR3rMxcKrTntSwMWy85dCRnEfOGXumt8863jlQVf7jP9o14Xelo8 a17Hu8VLNphE6yc/eWYf3Vk+48iDNwfdnmIYo2rbmph7MaB25tFFVmXw5pQB0JEbXMILiEt4zn06 rwcI+IgPIuYeBwsEvnxhHVK2mBvxBGVOpNQ5pKT66gn5s7y/3Ze12JJ+Ervqjb+BI7mE/CZYFSKj OU0EPF6XYDgSiHCVn7eyC/blD3D6wNOGJCKBHwKV90tFXIK4XjQijtUlGAOnR9WFO8PyWDafSYyK +i+OUe/y3Vnm8m3S5ZkZd+OC2WQ2GlgKmN0Ow4GNYjivsVMmyk7ZjFQEMNhygZllgIOhuI4JhrWb jaylWMQ4cmZTRhawdARg8yjgNUKPXM5fMu0GI8slRJiaWMpK2VgwHmoSLip80aeBShC4SKHBbDHk WDhN+krzbgAY2ETRyzaaxGmNR1qhGEgH4AqRdqrAQTEsk9qXjraLIGk3Yd8zjQDR0oQYeIwGmCGx QgpOqGiHzd3fkWWmiiLgEYKEWCQ2RqQnMUjX3S8DAwuakBDXTxxw98hoPT0y2p4eGTmu1WGEWpSN abWYWkfgJFAQpFyJESpcATC1olceVhIqAqZhiYijVhPq9ESgy8CBnsSBJg0+EqRbHJFGyDEdDuCQ 1GkJuU45FZD6SW/ich3QaTgWURauJUgiXd2LntCoQaYWk+sIOQ75oAAVrtZBtbklCJLUw/UAptdl aLRQF1G3kmT3DgChylQSL3TGp2RqcZIE3l1BI6jlSr2Ck+KdFUG9VbhWngGH3bvUaEEaoVNz7Gnw GQOZGNRRrldiWpCp12ZqSDzCvUg2oVQCtUYnmoS7jaTE3QxyjZrEJ+uh8gSmjIAsakJHZL3g6VZW A3elBQpMhaXjpASQOC7i9snlC06GAodUShJaWk5D37fBI6NN/bHY0/hjo20crExmKpf0OALGQs/I cUAHElFzIL8b3IUGi4MCTJ4B4sBGs1z3kJGGr3LdQgwMMBiNDrvHA0203er2GVGhJ91ACohUTgMC k4ga4pyxv8bNu+ct9CxaMstsQso2c5EECMo+QZyI00/85/IMXnkHzhvA48GJ8X7+MKoIhTCCBoe8 VD40EpLTQ8lHspCg4H7xEIHFCu/VlO7JMMZtWbM3E/fEFGAxG3IkwMJCX+hbXXpuyUhwr0j3msAf 8YPRDv71q3u4Sq1KuaZYf56dvnTswUbQbtm5rSStpHb13F0FfhlBw6iWGeEdk5OWFGx9ECibc37Z JrEz7sMZGSsO+8hE5P7U+K6KgDCrT3rs4wylxP7TkW9Lnyno0GUnKldfWX7nRpfPsYN37SHn/u5r 2/6FsSR6jiKpdlHF03fK48dLbjTK4ifu6rzvGoO6BDIYg2Ph1hHHb5A/fqEY7HPJrys7iIzssdJA X7R3YhHAGsM7EqP90g4yyssoQIcJhmw4PT55j//rGScv1945/K/pDsTUi/x36BQkq07ijPhV3Usm z6+R9X9whnIYewExa3ep48YYa3dQXONdVL9CR+Di+VCOWfeT9xdjZY3T/lSeWvvJ7OQ3Apo3fj9i 9/Ok0MM1FQ8/3loVk1iQ3fl1cjpzNCdwb8u1xvdttqCNbaDgeuWm+8NDb5FvG69Z3lp2VlaulG/5 Znf4G7H10srZn60bsTes1HWBuHvx3et+alP2mG3rJp+srl8jHmp/Xjz2u1ek05dEbVn8gJ2c+oq8 sfHRiaAw83H/1kc7P9jWqq/dd3Umf1l26pMOwfTzXc1sXs3UgtRp7YNWXBrJnpSmLFscH3no5Lwf is7XnP4+yiextEt2deJ6xaYdNWsR6WreqFULPkrdIHxfK6n68bl1j25/zeqQmvOP37LGvvb5vcTZ u0Mnlh3MujFPsqMNvVha7+K1wVqvxXtCfqiLtxdO/ZODXtnO//tb7csu533hOxUZ0Ru9Yu9PZTwI 3p43QnQwdyFBUTQalaKy6Php/wHe0pktXyGbzyxPbF90e/uMe0v7g6rMGbanYjt2VLUncsGelWub bm1Ot564Wd5gSFI9CLw+/0jTgOHN+6QHQoInLbWE6Gd+21mlPXRZOG6+vmjje3tXfhY8bUfbqS38 yjA9q00JGRj6l/b98YEJ2PH1WJ0st55epztX5r+cRRZeCe96Kjx1aO+KS9TwoR1fdYEu/nu7ox8d rCwu9Pk3zxfMoQ0KZW5kc3RyZWFtDQplbmRvYmoNCjI1NSAwIG9iag0KWyAyNTBdIA0KZW5kb2Jq DQoyNTYgMCBvYmoNCjw8L0ZpbHRlci9GbGF0ZURlY29kZS9MZW5ndGggMTI4NDcvTGVuZ3RoMSA0 NTQ1Nj4+DQpzdHJlYW0NCnic7H0LXFNH9v+ZexOS8AyvAKLmYpQoDxEQAUUJCPjAt4hgqxIgvJSH BHzQl66rtehWtrW2dfuwXbd2a3cNwVpgtdp22+5ut8W+X7u6rY/WtrbdVtttK9z/mbk3kNhQS7fd z+/z/+Rc73fOzJyZOXPmzNyZmxCBAEAQggKEnMWzZswPTosCuLcBIESYU7B4Jq/g7wNQfQDAPTB/ cULSHXzdvQDkYSxVWJgzt6jmRes+AO8dAMr7ymrNDat3ztkDYN6FMsvK1jYJ55576xMA66sAXm9W NFTWnnnmnrcASj/DBv9aabY2QDhosL0SrE9buXpDRXnOQh6g5VGU56rKa9df+4h1GGbFASysqrKY y4/5vTkH68Y4TKIJAdu9NmG8HOOjq2qb1o98kV+DumJU+cHq+jLzfuFh1GWjDeMZteb1DaqbfFtR fhsKCHXmWss19+y8ALDlY4CwgoZ6a1PfV7AO9THR/IZGS8Py0F03AVQeAfDVAbUVV7xnnZcmZWVA xiWIVAOl3836PW0f7PWtm/s+7N2smaKejVENk6eEoaqs9wlM2tT3Yd+Hmin9OQ5aSlO4e2E6U512 QAsJMBWtdBu2y+rg20gbKLEfe5TJGO+UQvIZVHBBRMEpvDglr+R5BRa+2bnqufV19WCCKGhUvoQ6 XK86yGULAPefeoPmesmqcLI0lw4Pcf+B3TAEwrLbhyL/U5Lq12inn4kUp2HZjynHj0Nre8hDHvLQ /xni7iWEAHF+8lz5FLqCBskmP0TIQx76EeRwUF+4oBZBDd5iL+6jKHqDD6IP+CL6gh+iH+Jl8Ad/ xADQImoZBkKg+C2EQDBiKISI3+AeU4cYAeHi1zAMIhAjGQ6HSPE/oIfhiAKMEL+CUaBHNICAGA0G 8UswIl6CsTAacRxEI8YwjAWjeBHiIQ5xPMMEiBe/gAkME2E8YhIkICbDBPFzmMgwBRIRU2Gi+G9I g0mI6ZAqfgaTIU38FKZAOmIGTEacynAaTBE/gUzIQDTBVMQsmIaYDZniBdwtmhBzIAsxF/FjyINs xBkwHXEm5CDOQvwIZkMuYj7MQJwDsxHnIn4I8yAfcT7DBTBXPA8LYR7iIoaLYT5iASwQP4AlsAix kOFSWIxYBAXi+1AMSxCXMbwGChGvRTwHy6EIcQXDlbBMPAslDM2wArGUYRmsFM9AOUMLmBEroBSx EvE0VEEZYjVYEGugQnwPVjFcDZWItQzroFp8F+oZNkAN4hqGjbBa/BdYoRaxCeoQmxmuhQbxFO7w GxHXgxVxAzSJJ6GF4XWwFvF6hjfAevGfcCPDm6AFcSPDTXCd+A/4BcPNcAPiLxHfgS1wo/g2bGV4 M2xC3Ib4FtwCv0BsZbgdNiPugK3im/AruBnxVtiGuJNhG7SKb8CvYTvibbAD8XbE12EX3Ip4B8Pd sBPxTsTX4C5oQ7wbfo24B25D/A3cLr4K98AuxHvhDsT7YLf4CtzPcC/cifgA3I34IPxGfBl+C/cg 7mP4O7gf8SHEl2A/7EV8mOHv4QHER+BB8QQcgN8iPsrwD7BP7IE/wu8QD8J+RBvDdnhYfBHs8HvE DngE8RDDx+CA+AIchkcRH4c/IHaCTfw7dEE7YjfYEf8EHYhH4JD4PBxl+AQ8hngMOhGPQ5f4N3iS 4VPQjfg0HEH8MxwV/wrPMHwWnkB8DvEv8Bc4jvhXeBLxbwyfh6fE5+Dv8DTiC/AM4osMe+BZ8Vk4 Ac8hvgR/EZ+BlxH/DK/A84ivMnwNXkB8HfFpeAN6EN9k+Ba8hPg24lPwDryM+A+G/4RXEU/Ca+KT cIrhv+B1xHfhTfE4vAdvIZ5meAbeRjyLeAzOwT8Q34eTiB/AKcTziE/Ah/Au4kfwHuLHcFo8ChcY fgJnET9l+BmcE4/Av+F9xM8ZfgHnES8i/gkuwUeIXzL8Ci4g/gexG76GTxC/YfgtfC52wWWGvfAF Yh9DEb4UO9n6rMd9xF6NRoVnPp53Wrc5d4v5AGncJ3u5xBQ/+qnhIQ85kbdGDTzwzv7EDyrMyOOf HvrfkY/3UP3T232yyiXm8U8P/STk66MZon/6uE929U/lf6eVhzwkkZ+vNzqkwtmfruKfvu6T1S4x j3966Cchfz8ffBi7+OdVns1+7pNdt6Ve7oU85KGhUYA/809nf7qKf/q7T/b4p4d+BtIG+A7RPwPc J7semzz+6aGfhAK1fuiQyiH4p9Z9sqt/qtwLechDQ6OgQH88zCid/ekqZ5tA98mux3qPf3roJ6Hg oKH6Z5D7ZNdjvdq9kIc8NDQKCQ5Ah/Qagn8Gu0/2+KeHfgYKDdFS/3T2p6v4Z4j7ZNfXTh7/9NBP QrrQQDxsu/jnVc7eoe6TXf1zkA/pPeShoVGYjvmnsz9dxT917pNdX4t6/NNDPwmFhwWhQ6qG4J9h 7pNdX4t6/NNDPwlFDgsBFaid315e5d3QMPfJrq+dBvkSiYc8NDQaEamj/unsT1fxz0j3ya6vnTz+ 6aGfhISR4XjY1ji/HbrK2Xuk+2TXY/0gXyLxkIeGRlH6iCH6p959ssc/PfQz0BjDcPpHoc6n76uc bQzuk12PTYN8icRDHhoaxYwV6B8qa52SrrJ3HOs+2fXYNMiH9B7y0NBofJyB/gm9sz8N8gV5B8W5 Tx7uEhvkQ3oPeWholJQQjZtFf+cP1a+ydxzkJ6Bct6WDfAjqIQ8NjSYljwN/CHD2p0G+IO+gZPfJ rr8SNsiHoB7y0NBocmoc/UEc5w8tr3K2SXWf7HpsGuRDJg95aGg0PTMJDzPBEU5JVznbZLpPHucS G+RDJg95aGiUPyMNgiHU+XQzyBc8HTTDffJ4l9ggL/E95KGh0eL503CzGOZ8urnK3nG++2TXbann N2s99JPQtUtzcbM4bJRT0lX2jkvdJ6e5xEb/d1p5yEMSla/MhwgYPsYpKWJQYUYr3SdPdYkN8hLf Qx4aMnHy7yqHAE85gmcb4jXwY8uEg+/+5iLNdPnRkascqia4T3bdyy75Yfr+r0gBJqCfVqix9woY hTvsuVAOjaIIdP/SHxNPO64rf5/aNCVjyuT0tNSJyUmJExLGx8fFxowba4weM9owKkrQjxwxPHJY RHiYLjQkOChQG+Dv5+vjrVGrvJQKniMQl2vIKxFs0SU2RbRh5sx4GjeYMcHslFBiEzApz1XGJpQw McFV0oSSFVdImiRJU78k0QoZkBEfJ+QaBNsLOQahkyxbWIT8r3IMxYLtAuPnMl4RzSJ+GImKwhJC bnhVjmAjJUKubebaqtbckhysr93He7phusU7Pg7avX2Q9UHOlmdoaCd50whjuLzcye0cqP1QK9ts Q06ubZYhh6pg48fkmsttCxYW5eZERkUVx8fZyPQyQ6kNDNm2gFgmAtNZMzav6TYVa0aopt2B7UJ7 3PHWHZ1aKC2J9S03lJuvLbLx5mLaRmCsbYYhxzaj5Ux4fFwneaigyKaZ3kmgoKgLZosb22dtzMkp pq0FTS+62Vk8km/NDa8WaLS19WbBtndhkXNuFMXiYqw0Pi5/UVEUam3I3SHQbiwqYj3ASkl4AipJ 02g3pQ5bDLk0paRGsGkM2Yaq1poSHKxhrTZYtCHKPmy2qUv8F8zOFVoLigxRtsxIQ7E5Z3h7CLQu 2tAxyyTMcs2Jj2vXBkqWbvcPkBlfP2fG0p/HOCZOOdTaYWpCNTLMQhexCWUCalJksHFj0ihY0qC1 LA3FkIoJWrQa7VfSqp1MB0I5RmsQWi8BOoLhwseuKWY5xWuM9hJQlrpLv8thvoO3xcbaYmKop6im 49CiZtNYPCU+bq0t39CgFWz5aDJYUISFiicnoMmjougob+80QSlGbBsXFklxAUoj7WBKiC22cSU0 57gjJ3QJzdnoyOkvXmJAdz7EJnOoTR3d/y9AqwvOrZpsI7rvybZI+Th9coV2hXJM64KiaHPr9sjo ktYdxTg0eTgVW1vzDEJea0mruVPcWGoQtIbW9vz81obcEkeXOsXj2yNtph3FVQSNakuWrGELnl7E R3LFEsdF8sU/vL5urC9vR7FNW8KqZJMrb1FRZmRUINaSv9iQv3BZUZo09HJMyG0tkZwBu5qF+2O+ AhbwVdDAr4KNeN/PV4IS7ueC4CDex/DuwfsU3p/iLeKtAi1fincZ3uUgIC8gLyA/AfkJyE9A3oS8 CXkT8guQX4D8Ar7cpAlQcuV6Bd5Z3ryZX4obJz1fIocr+KUdEXpNQCe/1E7U+mOYnIn3Srx57h2y zJ6oh6xhvBFbMNKnl8yV4H0CbwVqNJDShrcNbyU/jh9rT9IHZA3nx+II70S8H++DeB/DuwfvU3h/ ireIt5o7x53H56aeH8GPxKeBnh9pV4XqsyL4cD6IxcN4fxZG8X4sDJRDrRwGSCFnsHeX64/y13Dv QSpG3+Xes6fqd3eS6+0q/e4sb3K9+BpaU8f9klzCp7Sehh0KXndNJ0nsSFCy0KRBxnZwtt52sJMc NfnO1jUdTNRIkBVAerhd+CzT05AkIafj7sUUDdaFoSnqlMZJfM/BWLUEkJcH9Ece1KYsf+4Q5w3F 4EfaGdYwLGFoOFTs98div6zpXCu3GPy4fIYaiuQjhnUMaxlWMrQw1FKElxieYPgkw06G97J6bkQT +XHLGaYzTGMYy5Aa3o+UMSxluNTkU+73QrnfU+V+peV+WddwjSQeBWsYLmOYx3AiQyPDEIrkOMOj DOsZmhlOYjiOYQBDf4Z+DH0owmcM32f4LsNXGb7C8GWGt7O2wqAQS33G8BOGtzKcx3A2w5GmoEK/ Y4V++wr9Nhf6LSn0eywANFnB3DhYr5yIozaaHGBhFJwfuQM5HaeHHk01OYJccEfPqRhdJ6fu6Nk2 DENVR88N4RgqO3oadRgqOnpqQzHkO3oqQzCEjp6lgbpOcrmjZ5EWw2/tzUn6TvINDbJCyNfQzF9P 5oKO/AeauUVwErmvoIb4oDtdwtAIWzHlYkfNxXos/Af72mScsWQ/nOf2oMRDDgXJHkkdcpfUPNnd 0XNtEIa3s2azRpCdUMO9yxpaCee9Y2lfyAo47xWJTenIMlxfYqESuYWoBq16AdRQG5A5HTVPF+uO kLFyk9EdPb/VY8VR9ppj+mO4me1R2JnWHPSQhzvm676p6SR5psBduq+pzhfWJ+k/Xl+i/3BXJ7fn sP5czzH92R5kH9efpIq9g8JH7Pq3azqVE01++r9TWz1OG/hDDQrZ9Y/WdHHziI/JR/fbmvcqdfev j9ff10UOkCOmLP0dGGntOROr29azOUJ3M+3v9vPl+hfx7sJ7Ld4nesjGHnKikZxYf6Kb29hINq7f 2M2dOE82nieN3eSA/qBy4mO6VWyEuCR7i5++k0uUghh7SyAGgr0lEoMR9hYvDIbbW8ZgEGlvicFg mBQE2VsKMNDaW7ZiECAFxL51Pw7zFx01r5SgtQ7aW/wx+oi9JRSDB+wtYzG4395SgsGd9q0n9UdJ G9T43MLG8hp7ywhML7a3VOqzgkkRtDDLF2J4K+xHgSXI+TLHWAxbmavMlR3E294SgEV5e8s4DMgh 1KW3uZOIHcd036KpH8LwX1vR1nb9qWY2IM/jKP4Ncxo69uuO17Ccw1jgiEmjvwd7sLPZqM/ScF+S RWDEZhaR+8CA4X2mwObh+ttaWvQ70Fi3oJ6/pON1SL9m6zHs/KemAPTuPMArYEmkJlLThjtAU4Sq 7YiqbaOqrUHVVqdqq1K1VajaVqralqvwkdzhF5OUgaFJo0HGxMuxCT40pkIYrR6lFtQj1cPVw9Th ap06RB2k1qr91b5qb7Va7aVWqDk1HieILZjP5/IXZ5N82/EyyC8VbF8uNqBhFi6zKQ3ZxBaUD/kF 2eG2tNj8TjUssqXG5ts0C64paifkVtysbGN71U4SQeNbIuk2tQsImbLlV5E0FLf8qrgYdLGDUHg/ R/IXbDiGS0g4Plr0ZARDdYdKv05Fc/MXY2Yby2xjmW00s03KDB9h252/uMj2yIhiWxJlxBHF+bbi xcK1qEoPdyg3pwsfFxgUF3Vhn3twA0zT1bivzredZGLkgKuYMoIcoGK4rkVQMRwrJscdluQek+UC irjDVI47HFDkLAfd3GMoB+tpQOU2QTdrtjtgE5NTEEluF5ZHufM0QLmwvbCLye0K24tykG+LoHLt NTW5Oe0tNVSmPaUGJdprUpj6aQPZW6XsFim7hWU7lW6WslOl7FTMJg35OOEWF9nzovJyt+egVvz7 NGZmMfv67rzcKgOenL5f7PyuHyLWjYvdAZAlYTB3GIxIbKy1yWptarI2DbXoFWTJHmqJK5QlUtAF tSS7/dBz9LhUYsi14F1i2762Kty2sVQQuuAQyZZPUtElpWVVNDRbOkm2wZJjO2TIEdprn/tuvu05 ml1ryGmH53ILitqfM1ly7LWm2lyDOae4Cw6SnPYte11avGWgxS0kx12LObTKLbTFg3vdtLiXZh+k Le6lLe6lLR40HWQtktxquiwsKGpXQ3bx9GulsIPz8cZJXhIZVZyt0zZMYzN+SlT4jZHdCvr/Y/rg EcYXz8R+eNOs+Kz4LJqlAJblT4/Lclb4jVOiIrvJw3KWFpMDcckhVxkNgl5gbWqOBesK6wppUKxg tQIoX8Z7G4Qofw0+/KMQIn4tfuy4e98Sz9L8vtm4//ZHuXvcvGVZhXetxIqDEMu77fte1chyR5E9 OqhQJkzGVWwT3I92mQLlZDyGd2NKFBwBL3gB7/tByY3C/fUMWAHb4RsyXLyH3AYV8BSEQhzuyv4I z8DzePy4Edr5TyEIwmEiSRHrseQ0LDMTVkIJrMOSO+H38CFXJj4L82EpbIFb4A7U6zzu4RV4YlLh 7nsK7mM2wbOY1oV78EjULAtyIFd8UTyL7fuCP2TDLNgNT8Nr4hLxcfEUJMA83Gpvht9g3UfIAm4d tjocorHVFfi8fQZOkz28SXwJTy0+2NN5cA22cB9qfAjeJjFkAemiP+OCGifAdCwzGwqwP0V4lcB1 qGEb9v2P8Bgchm60xjF4Et6Cc/ApfI373Gncm/w+cRLQnxaMgSTUfRqYULv5WLYCfgHb4F4s/QD8 Dh6GA9in1+AdAiSB7CC7ycOki9vIb1EoFF6KUX1Pim3iUdTQC3s8HOuaAlMhF3U1wxq022a8DmLr x6EHr9PYdjqZTArJBnIzuY3YyVPkAqfm0rl0fhhfwd/C38F38y8oDiq+Er3FUPEO0SZ+gCe9cRAL 8ZAMaVh7Jtp0JvbzWjwW1EMTrIUbcOy2o66PYm/b4XHowvF8DXt6Hj6Hr+BbosM9/iSyglSSG8iN ZCdpw+sy6eVu5G7mXuSb+RuUh5Xne0+LgC1GijFigXiD+An9gXAcs3D0jEgQ8IqBRNQgBdufjvuL mbCQWboYysCCvl4HG9Bqm3FvdBPsgF2wF/V5AMfwT3gdgSfQ+seA/o8/7+J1Gs7CR3hdwJOGjmSS bDKHzCcLSSlZRWxokyfJs+Q58jGn5EK5qdwR7l2e4yfxy/G4vJ2/lz/If6jIVPxaCcqJylnKzcrd yke8PldtVD2sDr6c0Vfad06MEwvFN8W3xYvYB+ofKvRGH9aXKNxEjcUrBq2ZBulsrPJgDiyARXgt wd4sQx9bjj5fCdV41aGF66EZ+3YdXI9W3oR9vBl9Yxv28Va8bsdrN3rvPeiV9HoQfguPoL/YWL// zK6/4Wg8D3/HufgSXq+jDd6Ef8H7eF2A/+D1DfSBSP/bNqLAyxt9M4BoSSAJIcNIJBlOoshoMoYY yRSSgVce2qqQLCXX4hmuiqwmdaQRr/WkBUd2M9lK7iR7yH14/Q4teYh0km5yDO35DHmFvE7eIWfJ B+QLIhKR4zgF58MJXAw3kZvETePmcAXcCq6cq+Qaue3c7dwu7k689nFd3GnuHPcZ9xX3NdeLJ/tw PoLP4DP5GfwSfiXfwm/lbbwdffbP/F8VQYpwhaAwKtIV5YoKxWFFp+KUcpgyU1mHY3Sn8rCXxivS K9VrqtcqrxdUEapq1eu4fhy7cm1TxEI3SVEE94WSy/ArPLV24PgUoT/poFa5CVcdPwhBnwtCq/vj HAgm5eSfENS3FwJgD/reGP6yMgp99AWc7Un4bAWwwzO4ir6Eq+JEXNmMKFMJHegBAfBvMhGPfPPB G7zJRaz/I1x1ZkIs0aBXvEWegkryJo7iJrgIevSBkViyE8d2MexjMywD/glcn4IfgavGJJyLL8II UPOr+EZcN2LBTnxxtbsTPSUfnxLrcIZU4UrzF3gDJpOROGNMsBG+xN2iD/YDD5NwAuvfj/O3Dkvd jR6YABUkF8ykHt5BbxqJp8A4XK//oTaQ47Cae4YUcNdxKTjzPyZ/U6hJK5dNErHNUSROcbNinyJZ MQ+99xfo0S1wFzzAaXB9qMf1lKMv+JT0x654nBUL2pWKTnKLHbxUfyK30I9MyMuP8Tx4eyk7ybbD PM/N1qhQYtshArPUn3SR6yA8dp72YsbcSxnztF9mzNVeyoDMDG1vxqUMZBMnRAVGBY5BILh0XBb4 45dNSvgWBMVx+lnLQ+JZcjuOoD8MgxEmf+BUAXeE+pAgv6A7wiO1r194Vvs6ZPaezEycQJJVXiqO Vxk5Y3RK6qTgJF1oiJdhVHTKxEkkfybHacaGp4VEBg8n84ZPyMmZkJiTo9zUOmJ+3/6+NRM1ZPOD l1aYxnzbkpM4ITcXM2nbu/lQrgyf1AE4kvFHwJ804bIwkjSZAnQ6Lz6iNVjTys8SVm9i3Zt74eQF 2q0L2guJE4J52mwyVUHFoxJjrogfHsEbh4+I5kbyUXqSM5JGjPwIPkrgTeT4uPC4hPHjw8b1mXBr 4RyjnzVtR3s04TPBByJMvrDDy4ffoZnl268DZGLrY5y7DnJnewZ6RiBBPKeqwL1KNplgmuoLTxu/ NKLhxhhfMfIKouSUvGJshCJCGekVGR1hHEOi+TGjx4x9yPi08YzxojFQFc0Zg4yjUFpp7CSLTBoe QvjRI9A7aEwfYwyJMcYYG1WKEIUxRqVQNRpHh4w2jh6tUMWAET2j1aSN5Ql/o4+RGI2gCphKpnZy 7x2C7uTxaciY/CBZSDYl88k54Et8u7n3QEUWHdJZIvSBNDs2ojZnulEF/GhFwhL9krilo5aOjhnP C5zvtDQ+aMmUpQFLA9On8n5qBa/BEckMyzhzpjdMCi9cCAwKSyfaF3t7M7RnenuXa08uRw6ZqYFB 6QnLwy8uR4l0/KdSaGNVary1Chaig61ZDmuWawjHG6J5EqjVTSGh0YZRqpTkpEmpk1ICJxrHk1iS oktOSg0KJsFBwZQLNYzyCg0McZYNVJ7ve2P/qrFjDvbtiW0Ys31p5pGs7Diln0aRPCflj/Hp1Rvu I6ovNu67IXnKnqwi47gV6dtv2nF39vwoha13d9++vst4dOLOXv627/NZmSpVZnTSjge5SS9kjxqN sb4v+o70niaXiIo0Yt7Uo71jLs6kUrnECz16mXhW8SDuQ8dBKtxpivfWJyfmJC42LE4sGVeSeIOw dlyrfus4n5hhXHI8xBuDC3UlIeHeyS0jfZSFXp18mClcDfE1RtWEtRqIIuqdUUQbJURxUWnh3eQ8 KPmAx2EYF9OlORDcyQeYfHf6E62/4G/y5/3Ttf9cvubjszgMF86hydesWL6iF30181IvQsbZXmbz sPTECbCcBE6MRjNOSg3zUvGqwJAwnV6y3aRUL5Xk1dNIKp1MYeMJtW4I2nkaSeELhycV2vcEqZQK zjsgZ8Z1KwJrVYolv1yS9fszRS2bygrSN5hy71i4ee/jmxdsncZvJjWZQobvNN+Ktr4vC3sP7A+O 1GimaDQ5N2SvG9732pYjS7ISRz4/e/axzj+9VnzrXXTWRIlf457iGdzNlDwOWsFXGVcY38n725Pu 0nZygslHqYqKLBxZIgz39usksw/53uCdGtnJBz4Oy1JCuoxCXCevPbzS+BkuUJPQHBfpEnjmY+3r l9ASGWf7MjIvfHmpV/sqmgJ9bVLqNJKcFKYLxUXNQPvpT0LRFGH9jpRKjZAy0UhtJdsjlFw/NiGt JCV1BO4GuPiwzLgpllE+Cm307Iy7b9nyi5LkSIUq2C+3wHzXFH+Nj5o7GT1t1iQ/Lz/vhbclxyxo e2X7SoMmdLJKNVmtGLmo7dl/x0RO9jFEqnylb7lNla/r8Ing/vrgv7nImaFc3ObBL1xaPJfn8lye 6//EhWtnAje5/xsxR8DxhSKCp8tFMs/hzvqvMs/j2fmIzCucZJTIvyHzXrgDdHzLRgU1QE/eRMFj Pb6kiPFK5LWkivFeLH0941Us/ZeMVzN+F+M1qNB6sk/mCYRzM2WeA39+kszzMIkfLvMKJxklhPOL ZN4LdHyNzKvgVX6jzKshSVEg8xpIU2yVeW/uG8UTMu8DFapOmfeFKvVImffzeVHtkMcTXIhUj7dT f31oX0JsjPd1SvenfMhxxmtpX0JOMD4Y+aCQk4wPcZIPZTaReJ1TegQr+xnjI1lbUp0jnGT0Tvxo Jt/H+HjKh/pSXu2ks9qpfl+ndF9Z/5zqyuqm6hZLuVBubjILZfUNGxqrK6uahIIqizC3vq6+aUOD RZhe39hQ32huqq6vExLT0xPjEVLGC1mrVwtM2io0WqyWxrWW8vFCdn39KiGrrql6TbP5EaHaKpiF pkZzuaXW3LhKqK8YvOJ1VdVlVUKteYNQasH6KqutTZZGVKy6TiizNDaZMaxpbqy2lleXUXnreOeW hEWWyubV5kZhMlOw0NJopXUmjU9OoWKy1P9ON5iH59pGPF2bYTV7B1UPpbCB+OEJuwbj59kbHEf+ YmjCsA7P6mZMK+f38O38Uf4Y3l18N/8o5OCZmb73acK7BWsoB4HJ0lIClGFNDdhCI5OqwlQBCjC0 YDgX8+rY27gNKENTprN2GxiaWY1UQoBESMcrEeJlLgXGY2oWarcaw4G6rSxmwdCC4VqmDZXMZm+k VrEydazeNdAM5qhRmFLNSlFdm1ir5ezNHO0rla+Hih+l8TosUY29r0Ke1rYBw1JWgupXyVptYlpK FqtmpcpYCrWcFK9BLRuZbDmrzVG/FXs1SJ8wvoi10Iy2ob0QYLKTBQtZC9Z+PZOwJvp+0lGba13/ P9rtu7oUMK4ea6e6NGDbGyAO02ehXNn3lKBcDiuzjrVbifH52O8K1qaF9V6y0oCtGrGeWjafhP76 KjBexmorRc4q90yyB82vQ78vl9uhaasxrUm2grXf1k2yrWcxO6zGNqVWFrEazEwHK0ujbUmzwoK8 GW1lZSWr2eyUdC2XLV3N5Gm4lslIK4GAfbUwj1gtl6xjeQ1MXzPTtU7uk1RrmayNNJbN/b1sQu0F Nq6O+gX2hr4MZWrlNhyp1cy20thL6TRmYWsA7b3UgqS/o0apzQ1O9qllPmeR+1DPWmli3lLG7CYw T7ayNaXOyb60nJW1Si2/Xm5fGjkrs+csJ/vRmqysb1JfK9h8pCXq2ZykPSxjoy15ptTyamZJWl8c q8Pab1vnMRdYT8zMItTrrE7jUsZ61MBqctiP5ltZSoOTplZ5NOj4NzHbShpW9/tPGWtJ0kLy2Q39 /RmwS7VcVz3zzvHgB95sLW7C1iZDAl7r2DWeWdB5Ho2XtU1g8rXYZgJiE7MG1Z3GrLASy9IxLpPH any/9I9vxXmEqUUdKSuZRcvZ+A60Mw9ndQHaLA/v6bgSFrBPvOax2Z6HOIel00+vFiPStXIGzrpc vOay1AJmE3oPrAjfnfuOdMlLG9hK0SCvaxv6rf3DVq8Bf3CMjmOOS3NhA/t8xtEmtc9apzW1WbZB o5M+kufVOo27WfbXMuZlVnn2VrJaLP2+R72tWG6N+pI0y+l+w7FaO9aBwS1jZS024eia5ZlrYf2q knWk86CRrWV0PdrAZpm0zrqzV73cr3o2/wdqWSfX6a49x2pIV4lSNl8krUvlkamTa3YzQkIE65Wr paQV47te8d2WB54ca9mspE/lUnnVNbMV3cJWHffeQa2/BFNWsxatTiM/MBbSOLk+UaVV2cw0amCW rZafaj9kzAXZF+vk50elU7t01SqXd4sD657zDi6uX7rRyW8HnnHfbylp3avuHyGpJwP1rWPjv4qN pvO+w7EuD0jWy0/bBoyXsnqtrHWpP5Jezt7t2K1I9h/Y+To8zp0PfV+PBvxjFuv7d0fOsSLTPZlF flrXy/uhevn524ih6xg0wpU7ZkfNtH/17ClQDtJ+ay3KWVCjgXXgh4y+oz5pTlrkJ3G5yxxz1Pfd cZSsJfWgia0BTW7nsWPEzFfYumJI2g5Y+bstuO5ZXDWS+kM9aHJ/DUtw/c/C1DSYCKm4Z0vF/XYa hhMwPgEvgc3GfMSJeI3FlHEokYr771RMS4VJuA9PZ7ejxjy5j1f2w3k1dqz0zWx3VwkWN/Opga0A Zrn0WuZx1fK64ZgXFuynIKdb5L4JQ3qqOvISrtB34ElK+yQwnCOfFusQS5k1JS9tZijt25rlns1j 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 gaHwJ3O88WfqXoc8HG6kjPz98yYx3LiV99uoNwZuhzto66+kjQUfZEE25JDuh3GQC3mkccMy8pGD 1CuAEIShEO4kL0I/UeYR470IimECTIQSmASTKTMFSmEqTIMymA530fYMmAl3wyzS7oFymA1zaPte 4rnM7z6Yx7znwwLk+4kXwgOwCB6k/mLADuKLqvFF1Sf8xrrMXGgsB/lb62Po63F4AlYwTm4Y9u+u ceMp5s7Zwz/FDWwhPqrWWE2Z56Ca8tZvsJVu5uueaI51l8AkKIWpgD3Hl1V6ThEne7DzHmy8hzTP HJgL98F8sxw/V46fq8TPVXqWkvYIVMCjvK8wx3tWm1M8zwH21fMKvAqvwxvwJqznNvQWvA3vAHbU s5V07B/+sTzxO6vnkDkFH1medIU4OYn9lTTIHI+/rMVf1ibdQBp7Br8ZTxpBfBPvI2GUWYkPrcSH VuJDK9Vvr2PMhUm30xb7J4n9k8T+4asxE59aLpL4QurGF1I3vpC6OfZCE/wAP2KVfhV9nE7RzamB wR29F75qH75qH77qC/UX0CrUP6f6b+LuPrzt8r73uKw8SAotBEooDZTwEB4MJEAMbdrGBadrEnCA OMThwQYMxAoYSvrgBALUlLou7raM4W4DMq89mT1tO+xk7tZ0oHXLZtnb3E2mbaiktHXbWFDTViQ0 FPOc+7ykiJ7sXOe6dl3n2jn7472frN9PP8n3/f5+vvctp2xKnk7J0yl5OlXN06kj8nSy8tftaOVv MVPvZIKanlLTk+pnslInjY5rPbcd7m3+p8z/lPl/3vw/b/6nzP+k+Z80/+Xv26cq8z7k8dfClHGf NO7l76mnjN+U8Zv0+0/5/Z/3+5f3WNutSPsrf6vv9anKa4lpn2rap5j2KaZ9gmnvNu3dpr3TtHea 9k7T3mHa3afdfdpdp91x2h2nI7Nrjgk/r1mN6l/7Z6wLvTOajWuNZyYqf3Utf38xVXk0VvM5r5lR /fvwdHmn7PnPVb/hKL9id+S4mmvtXq/HDWhBK26s7GhT1jbnWNucM7MtfG/mLbgVt2ED2nE77kBH +F7ls5V8tvJfxpeX/4b+zr9CqHyWf6y8e/k9X/J/7ZYr71zyziXvXPLOJe9c8s7lTzfinU/xzqd4 55J3LnnnkncueeeSdy5555J3LnnnUuVOB9zpgDsdcKcD7nTAnQ4c/hS/vtMBdzrgTgfc6YA7HXCn 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 b3HcGp5hybh1T6d1TwtbHmNLii11bJnHlnq2jLGl21qnwJhOxrQwZoe1Too1dayZx5p61oxb53Ra 57Sw5zH2pNhTx5557Klnz3rrnJXWOStZtDp+7KEfxY87tJdFLSyqY9F665yV1jkr2bSYTavj811z kmtOPlRkUwub6ti0nk31bKpn02I2rY6f6bqzXHe2tUat8+e6x3k43/lFzi92/gLnL3Sfi5xf4lwd Lnb+Euc/4PwHnV/q/Ie8z4e9T70Z/qhrLsVlXtPg3ssPPcOyrSyrZ9nq+AqvWem1qzx/+aHNLKu1 k/tblvVZ5zRZ56xkWzvbOtg2N77u0EG2zWZbH9ua2NbHtia21bOtnW0dbJsbv9l1bY63On+b8xvc p935pPMbPX+783eE2dY4BeZ1Mq+FeTuscVLsq2PfPPbVJzYzYou1yT3O32s9s9U64z7P3x+OYmIt E9czsZ6J9UxczMTVie5DP0p84dDeRM+hF5nYZo2z0hpnJSPrGbk88due3+b87xwqMrKPkU2MrGdk OyM7GDk38QeHDjJyLiN7rXGarHFWMrOdmcuZOTfx1UMvRJoZOc1GBkaOZ94U8yZZN8G6rYwbYlmJ ZQWWTbJsz+FsihzPril2TTJrgllb2TQhjyZYNMScEnMmZNCEDNrKmCGG7JE3k/Jmj7zZxIoSKybk zISc2cqCEgsm5MuEfNlq9ofM+IRMmTDTQ2Z6Qp5MyJIJWbJVjgyZ1ZJZnZAfE2Z0q9kcMnt7zN6k rNhj9jaZsZIZm5ARE2ZrqxkqmaGCGZo0Q3sq+bA5cryZKZmZSbMyYVa2moU98mBSHuyRB5uMfMnI T8iBCTmw1SjvMcqT6n6PUd5kZEtGdkK9T0R2GNVRdf6okX1UbRfU9pDaThnhHUZ4h9puN8qrjfLS WPlvGq8Z7cO1nVLbO6q1vcOotxj1eqO+VG0X1PaQ2k4Z/R1Gf4fabjcDq83AUrXdp7ZTajtlNjp0 iNVmZKnafsysNKntPrWdUtspM7TJDHXoFKvN0tLqtzSPmakmtd2ntneo7R1qu93MdZi55WauzszV qO0+tZ1S2ymzuMksdugYq83k0uq3NH1qO6W2U2Z1k1nt0DlWm9ml1W9pHjO7TWp7SG2n1HbKTHfr IE1me6naHqp2kA4zvlQHWW3Wl6rtZ9X2NjM/r/otTUptp1jQXe0kTUyoZ8JCtT3EhvbqtzQ71PYO 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 wGypMhVdFAo+0TflV6byKbaGfGT7O/+VJDmUrnkjPFrzpt/sLY8PeRz8dlHZMiNsjs50nOVoPxiN OZ4RvuF3/EZ0UeQcd52WUZ+KXhQ5XkblK/naIKc+LnNW+nmVd748UiejsrIpL5vKubu2mk3pSvZe 577X+7kVN7r2Jtzs+X+fSUPGMW0c09HNzm8JKVnUI6+fMKZpY/oNY/oNGZSVQVljmza2aWObljV5 WZOXNXlZk5c1eVmTlzV5WZOXNXlZk5c1eVmTlzV5WZOXNXlZk5c1eVmTlzV5WZOXNXlZk5c1eVmT lzV5WZI3h3XmsM4c1pnDOnNYZw7rzGGdOawzh3XmsE6W5M1jnXmsM4915rFOlmRlSVaWZGVJVpZk ZUlWlmRlSfY/IUOGZMiQDBmSIUMyZEiGDMmQIRkyJEOGZMiQDBmSIUMyZEiGDMmQIRkyJEOGZMiQ DBmSIUMyZEiGDMmQIQ6mOZjmYJqDaQ6mOZjmYJqDaSuefcx6Ds9jGq+y62TrD31dt9tb6asbVM1G 3I0HVIe+rnPs1Tn26hx7JVVRUhUlVVFSFSVVUVIVJVVRUhUlVVFSFSVVUVIVJVVRUhUlVVFSFSVV UVIVJVVRUhUlVVFSFSVVUVIVJVVRUhUlVVFSFSVVUVIVJVVRCuyVAnsjx3H5+F/X9Wa94v+ybq0T rVD83nsq1XJ5yKmOTKU61qnNmWrqaXUyqHfneZ6rOdUYnlQzGZ6pKeI5j5/HT8Oi8n9JzJieZExP Usnra16XRm/gLY/fdjzkDtGwSCWnVfIilZxWyYtUctoctJmDtkpqneVYTq4LfYaLVHV9aK2uOHZa ceyM2hmo6Eeqq44eFb25uurY6LN/ymf/ok+8s1rZ249YdSRVd6tVx04V/sgRq47N/1uFJyurjvbK v0NbHr29+m/ROhzvDI9H73L8BMorkU2On8SnPf8Zx85KFpdHKllZmXzWzw/ic97nofB47ANh369T 97ths4TYLCEelxCPS4jHYy84/wvsx+t2hG/gTbuQmegIrdKjVXq0So9W6dEqPVqlR6v0aJUerdKj VXq0So9W6dEqPVqlR6v0aJUerdKjVXq0So9W6dEqPVqlR6v0aJUerVYqO61Udlqp7LRS2WmlstNK ZcRKZaeVyk7p8kjVtCWHTbNj+tPIOUzbUDVtBdNWVFcqj1Rt21C17Xjpslm6bJYum6XLZumyWbr0 S5fN0mWzlcpGK5WN/wkpk5QySSmTlDJJKZOUMkkpk5QySSmTlDJJKZOUMkkpk5QySSmTlDJJKZOU Mkkpk5QySSmTlDJJKZP8L12pRMO+xAzMxCzMRgxxJDAHR+FdeDeOxjGYi2NxHN6D4zEPJ+C9OBHv w3ychJPxfpyCBTgVp+F0nIGFOBNn4Wycg1qci/NwPsqrKmsTK6slVlZLEhd5vAR1sKtMXOKoHqT2 41L7can9uNR+XGo/LrUfl9qPS+3HE5e65rLKv99qk31ten15D9WggstJsEp1X+HxVSp7jT1Bk+Na rPN4vaN1WLUi61RKn+roUB0dqqNDBfSxvoPtQ0wfYvo4s5exevJ/We3xO+vvnR4ftvkUNi9h7lCi 1m9yeP24wm+5wm+2JrJGRg7KxkHZOCgTB2XioIzLyrisdVBGxmWthcr/yqnHfi4p5x6xl0vK37zs ycmdnHzJVT75Pa7dKn8e8PPnPe62qhi2T37e8aeYwut4A2/q0DOxmqdXVlzNcTXH1RxXc1zNcTXH 1RxXc1zNcTXH1RxXc1zNcTXH1RxXc1zNcTXH1RxXc1zNcTXH1RxXc1zNcTXH1RxXc1zNcTXH1Vyi IWQTy/Ex/AasxBIrsBJmLXE5roAdcGI1rMzMcdYcZyMDOsrD5f/yo04yqotstiZ8RicZ1UU2WxM+ o5OkdJIOnSSlk3ToJCmdpEMH+bru8fUj1oR9lfXflWG04sU1nLnWDPz7Nd6oDlDQAQo6QCHaHlkQ vR0dKK/17nL8BDbhkyiv/T7j2InNkv3wGnAw+lk/P4jPobwW/EBkgbT/urT/urQflfajR64HYy84 /wvsjyz4T1i3jUrWUck6KllHJesoP0cl66hkHZWoBYlakKgFiVqQqAWJWpCoBYlakKgFiVqQqAWJ WpCoBYlakKgFiVpIRCMLEjMwE7MwGzHEkcAcHIV34d04GsdgLo7FcXgPjsc8nID34kS8D/NxEk7G +3EKFuBUnIbTcQYW4kychbNxDmpxLs7D+ViExbgAF+IiLEEdLsYlMDf/0XoxcalrLossiNyndnvU bo+67bEeGZY+mepO4imJU15nlHcPGeuL4cqO4TaPN6jnjbi7shZI/npH8HroUas9arVHrfbo68P6 +rC+PqyvD+vrw/r6sLQa1teH9fVhfX1Ycg1LrmHJNayvD+vrw/r6sL4+rK8P6+vD+vqwVBvW14f1 9WF9fVjCDTNpCZPu/nWS/aV0+5oU+49W+/8WMvpoRh/N6KMZfTSjj2b00Yw+mtFHM/poRh/N6KMZ fTSjj2b00Yw+mtFHM/poRh/N6KMZfTSjj2b00YxsSsqmpGxKyqakbErKpqRsSsqmpGxKyqakbErK pqRsSsqmpGxKyqakbErKpqRsSsqmpGxKyqakbErKpmS8/D3iW3gbhxBCUjYlZVOSIcvYsYwdyyq9 6E477M7QEzk2FuR7HCfiDJyPi9GEVrRHNiQ24V48hN/El/FY5PhEv+N/i5wSqYmW//t4NfImG5lh XZq1rsla12Stpy9jy1UyprxCtaaO3MWnwepuNRNt9OyV1qxrPNfk8VruXOP5dc5f67nr+Hd95Ruz eslVz7XtkisjuTKSK8O7Hp5t59l2Xg3yapBXg7wa5NUgrwZ5NcirQV4N8mqQV4O8GuTVIK8GeTXI q0FeDfJqkFeDvBrk1SCvBnk1yKtBXpW/taqXWPUSq15i1fOsnmf1Equea/Vcq5dY9dKqnnP10qqe d/W828677bzbzrvtvNvOu+2828677dIqI60y0iojrTLSKiOtMtIqI60y0iojrTLSKiOtMtIqI60y 0iojrTK87eFtD297eNvD2x7e9vC2h7c9vO3hbQ9ve3jbw9se3vbwtoe3Pbzt4W0Pb3t428PbHt72 8Lb8/8fw8siyyMcq3zI0VOYrb772maOS+clXvkG4ubKPyJuLvLnI/3/Z+f8V/hpfxy58A3+Dp/B0 ZU2cNyZ5Y5I3JnljkjcmeWOSNyb5ePlzfg855FHAXnwfP8APMYEf4cf4CfZhksUnMreNravY2l/d cfUzs5+Z/czsN6P9ZrTfjPab0X4z2m9G+81ovxntN6P9ZrTfjPab0X4z2m9G+81ovxntj8wu15T1 USm6GkfWVHkmss7mqzNRTuN8dSay/4eZyJqJrJnImomsmciaiayZyJqJrJnImomsmciaiayZyJqJ rJnImomsmciaiayZyJqJrJnImomsmciaiayZyP6XzsQMWVIqJ49ZOJxBh5/LV5/LR6LyJ1POn8gq IzdQub6hso/OGtedlZ62trL/zxjFR4ziQLWnPfJODzOKA0ZxwCgOGMUBozhgFAeM4oBRHDCKA0Zx wCgOGMUBozhgFAeM4oBRHDCKA0ZxwCgOGMUBozhgFAeM4oBRHDCKA/9hb0rbj/4t/s0+M4txPINv 4zv4LvbgWXwPOeRRwF58Hz/ADzGBH+HH+An2YTI8EplldDIV666qjGA5s7ORRM3+kK85gIN4ufJt Y/nsU+XxnfGhsHPGh43ueqObq35rMVVZ2ZfdvMa6dH1kWdXPXPQG58p7mltwK26rOJozujmjmzO6 OaObM7o5o5szujmjmzO6OaObM7o5o5szujmjmzO6OaObM7o5o5szujmjmzO6OaObM7o5o5uz05+y 05+y95my05+y/5my/5my05+y05+Kf9MK4e/w99iNf8A/YhgZjGAU/4R/xr9gDN/Cv+L/peM15dGs WJ39dR+dXflLW/mvbIf/gvZ09L7wqRnrwsOReZ6ZsIvK2EXtt4PK2EFl7J4ydk8Zu6eMnUrGTiVj p5KxU8nYqWTsVDJ2Khk7lYydSsZOJWOnkrFTydipZCLX2ePNscebY483xx5vjj3eHGu+VdZ8q6p/ rfqf1J0NfBTF/f9nZ293ub0AQSLgw08rVg2KD7UVIkqx2NKIVlFTlYCKbXzCGh8QTRVMjVbQphWw xjalbXyiGq2NNrY2KookGrQEBSJJ/6hwQQ7hCOHEiBEz//fMXZLLE8/2Ye/1uZ3dnZ35fr/znc98 Z/f2djGxXyazhcWJGejr8g7km8G+u9h3j3qW2cBiZgOLmQ3oeCiTeCiTeCiTeCiTeCiTeCiTeCiT eCiTeCiTeCiTeCiTeCiTeCiTeCiTeCiTeCiTeCiTeCiTeCiTeCiTeCiTeCiTeCiTeCizj77ztQN8 CVqBUpnEQ5nEQ5lEwouJhBcTCS8mEl5MJLyYSHgxkfBiIuHFwXPVs0G4ITgBEJcEsXrwQpAFfggu AheDS8BEkA0mgcngUnAZuBxMAVeAH4EfgxxwJbgKXA2uAdeCqfQf/W8FaxO/3FkrBpotCQLANdfi mrFtsz6KPZuxZTO2bMaWzejTjD7N6NOMPs3o04w+zejTjD7N+M615swl+EStOFz/L4LVKIZZW8Q3 rCaRZsXMHdJvWNtIb+fYDmZ4kpEsAFwwWKRRfy311zIDTDd3bO9StfYYkWZniWHIUosstchSiyy1 yFKLLLXIUosstchSiyy1yFIr0vGkKJ4UxZOieFIUT4riSRE8KYIHRfCYCN4RwTsieEcE74jgHRG8 I4J3RPCOCN4RwTsieEcE74jgHRG8I4J3RPCOCN4RwTsieEcE74jgHRG8I4J3RPCOCN4RwTsieEcE 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 neBeaD/sZrtX279zr3Wfsp9yn3Gftze6L7h/s7e6/3Bftj9xX3MX25+5b7hv2F+4S9wl9g53mfuO /aW7wl1pK7fOrQ9Y7gfuBwHbXeOuCQTc9e7mgONucbcG+rrN7ueBVHeHqwJpnvRkYIjneAMCB3kD vYGBo70DvUGBY7wh3sGBYd7h3omB4d5Ib3RgtPc9LzPwXe9s7+JApnepd1Xgh9413vWBy70bvBsC V3o3edMCV3m3encErvVmencGbvDu8e4N3OTd590fuMV7wJsbuNV72Xs18FNvkfd6YKZX7VUH8r0V 3orAz7xarzZwl7faWx0o8NZ4awJ3e2EvHLjHW+dFAj/3tvRJC9zXJ73PSYG/9Bnd5weBF/tc0acg sKTPo322BzYFZTDojA2ODP7AGR+8LjjNuSL41+BfnanBvwX/7lwX/EfwH871wZeCLzm5wVeCrzs3 BKuCbzjTg0uC/3RuC74TfNe5I7gi+IEzM9gQbHLuC24PbnceDqqgcn7jW77j/NYP+kHnD35fP9X5 o3+An+Y85g/yD3IW+If5hzul/lB/qPOMf5x/vPNn/yT/JKfMP9n/pvOcP9If6fzVH+OPccr97/jf cV7wz/TPdP7mf8/PdP7uj/fHOy/5P/DPdV72z/fPdxb6E/2Jzqv+FP/Hzmv+Vf5VTqV/nX+TU+VP 86c5//Sn+7c5S/2f+T9z3vHv9u9x3vXv9e91VviFfqGz0n/An+vU+r/2f+PU+b/zH3He9x/3n3LW +U/7zzgb/Wf9Z52oX+aXOZv95/3nnUb/Jf8lZ4v/ir/IafIr/TecT/0l/lvOdn+pv8xp8Vf6tc6X /gf+h47yG/wG1wqNCo1zZSgzdJbbP3Re6GJ3QGhiKNs9ODQ59CP30BCzJPfI0NWha9yjUhpSGtxj Uj5O2eSmp3ye8rl7XN8+fUPucCFHlsHOYlTWuABz34nif3xRr/acUlv53KCeJKVxTxzmaMY+1fdL 8Kse9leAZUnb8/jcosrU2MT2h7tV+vvtqXAc+76oKNgINu/xmXtYv3p7T2toX9L46MVPaI4d1Abw yd4Vp3XuLdWx56tfdm1B1ZxYd7R8PJWmU/HzVWQPqtTnRfmEk+vWe5Ll6d0G+rzO53Y6utV4U3M8 3bG3a6rjfJM/uj9sHi+pJ4l3Zef2ll/bviee0rZaa6wVVSvUB22236W909pq7snGia0tHG1WEfZu Fd0WjvVqE3W3ukh/m/Sm9r2dUprdetPyq1g6Wt1sTely9Ep1sDpd3WDSy9v8J55i3q1TzarG7F/b qRW0Fcp6qTI94cevqhUmb11cjoQf14DZXSVM2qo0OcriOfk+oWvO3bNWfEwx7PlWHPu+qErwTpzf 9uCsZmOt5qRdaT3mq+tIYTu2VNNeiRkvAy9Tf6bmN8DbyT291zOiezVuWXsl3n5e1L9Urf7+j8qw R70YlnlDLVZbvippeqm1dj+V804Pqfayda/rtvTo8/ssx3yhnyzsWNKp52TWJ3fLWdEllQ4TV6i/ mT0L1CP0klcTsWCl2ddja7J3nOmfdWqpWtq+t46SViTzIX2+LM5i3UooI7asUPN23deS+aBrSo1V f+Vb45w4zN5zdl7iLur7Pjivh/01nWVVqerrBgfvRpmb20fmc9RbWFlz8RTOnZI4flG3M7Ziu+b4 d6f98ehmvm5xsx1TrspRx6qpPc0KtE/E21EvrTviUF83xzYYjfaIw/+9S1ffUw142Ouq4d8sRX2X 7Z1E9F19WX2ie9au5wBqSXtqsUbnNt+7RZdpWnjlTnNF26LPRHwSIfJ4cQ9reiJ+5l4IeZiOrhL1 vwxei0cs6vWd1FbTnopLPEX7c7wnJUXtnVJdPOmgBPZ90aX4O5Gxf1zCLkfPV4fT9yeZdDtrJ1I6 2pxPrPl+p1MOo6YjTa75cYt1W9ITkcud8XIS35HE/KumnRV1Sb4ZhTqNRGp2uyRagrFtqcTRR7QO 6pEea+5x6W2us/dLR7v3eNTtsn073HyZut2k22YeaZ3mIKndymibW9Z1PdI1X1I/Ny0sRvLRRx7o knNFp62aZC00E/daw7aeU/DJNrWobQ6iquPY98X0udd62N/bLLqbhbrN/k0qMeatIPWKuSISVkUJ j4z2VLbxmg1m1vR+Ujlmq2O+yZj4HJ79uFrXPbKAvTrNTM38QePvPWvSi35N7akNe8ls3cvcKnZj 9tHtrDt1X1R3mnTH/LVTqmuMsL+XrtfdOkdCbdcH27dXmKhjhdjDRcX2Troey/p4p0e7jtLL1DPq T8nXPv8dS8eMIbG9Zid5u8impqvv6m+Tbh/fO6fUR+qjbuUos+p5BNnHxbR6WftWhqlFIz2+TZya kfDj2UT/lWZmMI9UmRm7pqpq9teY7fgVhkrDF7rUST3UVkMrTmB9D6PlBXoeQfoi8pepXzGvKIv3 GWKDjYmSKkTnGZKW4iJqPYf1bMM7yVdYOuXcSc+LX6dM9Gw9i90/M9neuGL3r0v0fP1YrTPrurbR eT9fo98vJX11y1fNk3u/JK5HN6tPuxzwe4ou/31L18jV7NP+dLru6/TBExJx5lTTV+m7xg8WdD+r UwnzTDR5i2i7xnBL0rGKXk7a56VzfyKO2tbbsX0pd6+W0t3IkZwnXdt/N87qXksb9mnZlcbdr+2r GJ99iKL2g413Xn5yxLiF2HI3Ze24tvI/u+QksM8LbbRTzzJe0cmPE16x1378VXtF94UZR7eY6t9a /x6PX/hy4z6x29pd59np+dHerngnxrxw23yw/UD6bpYbX0zp8bhyt5fT9yj3f8PS7Tr+//xS1OPe CUnp5eZ73D7X0oZ9WnqPbePz1h7uhh+2O/OszuW2XdX/zy37cxa+P5Zk7tLjRZfD2sa7vKPWfrUq 3h7J/DJ4H6Xr3SvMPLBtxqE+U9v3oZaypHTXGcKeltXrWND2m5ieYp/9OW/qKL8tZSKuF0zqBvWC ekin1S0qKz4voGd1u5+X+MVLJPHdUeK/VCWfp9XT7fkuVL9UuWqu+mm3MvS1hmXmukD89xT6DuJ3 Oq5nUe5nu6FNXceV7h7v9ybJ3CZ5p71btfy6lLZfqKgPGRM3gliXX0uInc/X1Vh1sPq6utKkH27/ DYtJmSssDxO91LTdDel8faDXO6bpIn6Xd3rHXQWkqkvcedG2u6KLFEkSm/lhhbqoPX/SnVIjx2zz O6HZbdsdR5Ik697n25av5ipW4spTIq7IMPyiGSN+FesiNQSd4hJrT6uJ50fLCjMnXkDrVaBvTdu1 /ri9Ta4pPdSm7aLvpM/HFwsSNp5nLKyvkK2IjwjqauMXbffpOs059FyavPPI/aQ52uUqFiVf1Dau dMSuSakt/wEbt10/jtt4Spcrhbdi4UsSElca7zNaG5umi/gV/jeNf0fiHNIWSYL8HmrTNWkbl+nf GyRsXIyN/6XKKUvflXikm4073d9Agt+Tc77+fYP5fWfSnfY4byVtv9VD6t98x9rUWdZVi15zdv1F iL7/V5Hg4wVqiXrP3B3a9ZVCYlRzn6ayw0PNL0Iqku5uNzEi6r7wWg9yLFBTOfcWsYs7ff/9S4Lt 6swVskq1auf3QTtiPsOVFXjmO8lHu95f2UXdUTMS1HFeWF8Hj9fPukpV7fS8ymRpdv8qXGKM7txf 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 4J/7E4NnlyzyWINvr2kuWaq/Tas5pnFyYK3mpWp2B7TPMLg2sEp/q655Rf9VgysL79HfKmrW1ezU 38prNuhvvWtW1Kz2qOvOZLfV34I1qwJ1n64Qn3oT3v3WMs4m9PWM9Hjan/wfrjOfo8/pK/0v3HOy Ve4fyF5sm+tTuu0/kGlrypW/XB301dn8Jd3/ubR/4/pX6v0P69NVX0HPyPYePm77dvrTUf/tor+1 a5+j/3bjU9A+wqdAp/bWH0/7cn114dO7/ZD2I9pXkUON/lun08rbp7ja6e8p/ZkMyl9DTQNr9MdD /rfqXG7VH7nHo++paj+r/Vw9tiO/OLHQemJBOcrTk3MLhZxPCHM+oYjzCRHOJxRzPiHK+YQSzieU cj6hF+cTenM+4WrOJ5RxPqEP5xP6cj6hH+cTyjmf0J/zCQM4nzCQ8wmDOJ8wmPMJQzifcA3nEyo4 nzCU8wnDOJ8wnPMJIzifcC3nEyq/GMX/L0bR6y3wzmfV3+Mp8niy7jFXmxr9t/Fz35tarxrzF94h fR39nMwJfZ3+7Ps/vCTPja1XY2s5fyfzaVmp1qvuc3TT36XXfVqfojZlrZ8B+lOhP5XgmDbj2sT0 p0zvx1PaTNdUhU6PtfLK9P5ciazwZ+trnv7M5lOpPxP1HZI+Uev7xa3/Se/Qp/9Jz+I/6dn2r+y9 niz+h56f/6GXx//Qu4r/oded/6EX4r/n9eC/5/Xkv+cV8t/zwv/P8vWqBptfk3o3aQvZ4z71t5dv tr7m6WthK+/QZ/y/l/1XLsnH1/A/yEkZr2i5JX/H39V6Cb3/s7rI3/+uD/X9N69/qe77/4U6/5M2 /01//ptlS///HW+qs47PfOeUU60/o5zl+ttZZ6lzj/6sdM7r7/rjeuTjzNRXteYv0jJLnW3InHdd t53b0eTidnFz3I6uy/1LtexmsardAlD+Gioi2Fqy/ri93d78dclRPqcE3fLPUFv51bo+97hDWj8j Wj9V5kO9Ra7aWad1/IYv3pf9D96X7XW8eq+Qt2YX8dbsCG/NLuat2VHeml3CW7NLeWt2L96a3Zu3 Zl/NW7PLeGt2H96a3Ze3ZvfjrdnlvDW7P2/NHsBbswfy1uxBvDV7MG/NHsJbs6/hrdkVvDV7KG/N HsZbs4fz1uwRvDX7Wt6aXclbs0fy1uzRvDW7irdmX8dbs8fw1uyxvDW7mrdm1/LW7Em8NftG3po9 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 Vterm9Qt6vPqDvVl9XX1LfVd9UMNU8PVSDVajVnjq/HXBGlCNKGaCM1YzWTNNI1LE6dJ1KRoFmnS NdmaVZpiTZlms2aHpkqzV1OrqdOc0DRrzmnaNJ2aq5ouzW3NPc0jLVPL1gq1cq1Wa9b6av21QdqB 2qHacO1o7URtlHaaNkaboE3RpmkztbnaQm2ZdrN2h7ZKu1dbq63TntA2a89p27Sd2qvaLu1t7T3t Ix1Tx9YJdXKdVmfW+er8dUG6gbqhugjdeF2UbrouVpeoW6BbrMvULdet1hXrynSbdTt0Vbq9ulpd ne6Erll3Ttem69Rd1XXpbuvu6R7pmXq2XqiX67V6s95X768P0g/UD9WH60frJ+qj9NP0Ln2cPlGf ol+kT9dn63P1+foSfbl+m75KX6M/oj+hP6M/r+/UX9V36W/r7+kfGZgGtkFokBu0BrPB1+BvCDIM NAw1hBtGGyYaogzTDC5DvCHZsMiQYVhuyDeUGjYbKg3VhlpDneGEodlwztBm6DRcNXQZbhvuGR4Z mUa2UWiUG7VGs9HX6G8MMg40DjWGG0cbJxqjjNOMLmOcMdGYYlxkTDdmG3ON+cYSY7lxi7HSuNtY YzxsPGZsNJ4xthrbjZeM14w3jHeM903E0cTENYlNSpPeZDX5mZymYFOIKdQUYRprmmSaYppuijHF m5JMC0xppgxTjmmVqdBUaqowbTPtMlWbak3HTE2mc6Z202VTl+mO6aGZaeaaxWalWW+2mv3MTnOw OcQcao4wjzVPMk8xTzfHmhPNC8yLzdnmVeZic7l5i7nSvNtcYz5sPmZuNJ8xt5rbzZfM18w3zHfM 9y004pDEtYgtSoveYrX4WZyWYEuIJdQSYRlvibJMt8RaEi0LLIst2ZZcS76lxFJu2WKptOy21FgO W45ZGi1nLK2WdsslyzXLDcsdy0Mrw+pt5VulVrXVaLVbe1kDrP2tQ6xh1lHW8dbJ1qnWaGusNcGa bF1oXWzNtC63rrYWW8usm607rFXWvdZaa531hLXZes7aZu20XrV2We9YH9qYNq5NatParLZetgBb f9sQW5htlG28bbJtqi3aFmdLsi20pdtybKttJbYK2zbbLlu17YDtiK3e1mRrsZ23ddqu2W7Z7tlp dm+70K606+1Wu5/daQ+2h9hD7RH2sfbJ9mn2GHuCPcWeZs+059rz7SX2cvsWe6V9t73Gfth+zN5o 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 Y07iP5vrtPdLePDhidBRbyhPNEcMiTxyf6f0QK+Ag+JxE08s/XFI4Fcv9F3tuzfP1WkYn3Gg7sWz 77Du3Xzz8HsN277YNTsxZoEj5trefTeX7T99Y8ev4s2cP5l79Pls6FeTmZqUj+e45oya9PWFv3R8 smFpw+KL74xm9Mv/+UiZ92R97MjTXx1Jmdrn7b02ZvXkV+K0Mx8vXhRy4wumbcyA+cler9ZNPZ/Z r9ebJ/nX9QN8FqU8Wh+fsLCza8jKorI3+H/2G6eMnh5Q1rJ0bE/z1NgR73X0yRCO3939sXpF/A3b Osm9U8Ivl/HvpKfMC64vWFjRNN2zi1WVGbjvXv4rGcMyopblJ1QZekU0zS0d3hl37R177uvu/Sad 7kvMiPVZO473/4xsR+jpQ50sZHQyhaH9bqOce23s80X7g3a+mLmytvR65aBhw+vPOFV/bSBlMLl6 Ni2S9iZxChlOG/Z0JvQ3adQzNqj8MaK+dYvGHxTlbpzhRecvTxyx4ua8SYee92H1flwzIXKZ9scB efs2TeZ0LN87SHP2QeXWk/s+mmDSzPWenfa6R4U5/Mf46jmLzDXhn2f8tEJw2Csn+OgPad8nvjpi w+qWpuYLuUe++cTv9KKuk7sCvsjaf2rmseCzStMnKR2DSvZo5pWZss9XV4snLb9TWjdrVImvvXR6 jmBQg2TWgoiDn32wdOC4quioDuf33w/Qffvu7bYBS7olpuWuxTM9mYW3SxjD+6SGZx94zPhqVveo jjaP5DV7WAncpvXtvjMWRfxFUSoy9Wdosyo9jxcG1FwZWh85+ND2dzuuxfRbccdcWNpUNX/ShIGt SWG7LXeJDWoHsUGt/mt6lN8b6ZHPvy49+puNAOmRs1/Ac8TWFNAXe1Sg+2Vf8qVzyZ7/jvTI4bS5 X+oThs9OjJ2VZAyLHGEcETl2YL9h/QN6B/fvP6z3gPABAX1tTot7TNqnx9Q7khyUMXJWUsrsmbP+ 4fZWsIRtDFVOWPhVwY/rfm3POvuAv1JyfUc/X3HKozHjd6YU+a0Z2bl98mzGlfy0Mcu+fueNm2/S vj44PP7B3Mo3bvU8u2h1c75i/cbjB7p/Sbsw45veTn2pvXfK81fDC3N3nX+33/mmmz999sqnD2M7 b7tWrrv2qbh70+GMh63vNbMGH6KnjHd43MvYJ89cMf3wqz16hXz2/q/FU57TjZMf6X9eP+P5wcF7 Jktl8wsGCe/TqtZcerXfTsfBmb0ipEte+jb++vaeBSuy+WmbaO/Pt3oV+yV61PhZV5V0HK8wv/jJ 6D95zp+UNLxqiOvCmgzvqL2Pvs96wSd4z557gdvTRle89U7An3rwyz7+uTOk7Pmu8EG/T6d+2xB8 C7I/YQz6oS3/wNvhgvun7qStf3z2qUzpmTvG/0umlDwvceaM/5RM6Ymn5Gdv1k/lf55HnrVb0W5U PrzUkh3T2OPbKftP09LTFFOPW/8kPrjtl9e/zHq04tTHKQaN+e4v3zRW7x9GV/f7IKJfYeL9psCt vstrOHuTJb779rz5jZ/PpffGXSx+vmhfkHjJdeEFXfsB12djxw8anfOr6oJt1xeFWddfPHblVvcw xav0H17Ofjtl4ZW5j7KMlWtKl5d88md1ucxp7axIm5Gn69Hj0xdWDRy+9N0bHV8svTCu13ODvhs2 jL6DxuXcbn1B0xy6IrXqp94rXu3xzeEV7+TJUqqnP5A6dswVzwz1jRqYM+i9oZf3HW9a/bI2fPLr K0+tHjOZRWu85xw6YuxFVfahn4W3Lqgv+uqrJ9ye32n/9qDPEnG7fuCZEX3TmWuJHauAQac7l2T9 C49sTx0kf/uoq3zJMfLp9H8GjTZOZkMe5HE0oL0IHrchnwGyrCiw1IBrZDEEJnX1acJHzW6er7rv ffE2n3zbSr7PUrcNUpC08BiGGYQs0GrQYPBlyGRIZihiyAcPxaUxlDAoMIQwVDIUAHnpQPFEICuD oXKhWoMKznRaUlmQn16UWJBRqY9WLrE0MTI01P8OqIyVPip/lLdlwc/P0ZUaDG0fbvHv2fUtd9OW d4+5ZfMy2sJbns/+bnbvfYb8dn/fHc9qXr7bLLJG4+TH/9tZZT0W3mze4fNX3CSy8ftKFfW7ipdP xkVa/Qz2N9J67XLq5yxlJ1G28y/WJzOK1so/W2UmMX36yytcu7Yx/Nt9fJ/dRZNXmw8H8Wzq/rAj b7a20IEfc1z0tig2/rg30SYrd4PG0gsh0fy7F16o3n56ZeGfb7n3rWp4dQ40fQlZ0sfrf6jb+Lzh BFst6/irW1XO92TP+5l5jvf/wmduk5R/7bWt1WN/bmNrkbrr07JlR2NLWAz/rlVa8XhHeUxAorDb Prej4u1Jb6bktnzJW9jEJG/QxCSNiCM2wyYmHqAQB90TI3oFiVJts0MT44JYAwnklMiNGPZlBNoJ l2E15AdWr6Ca1MAQWKcamUVhJMTC+XOzkt5c2Xvd7rCal9uGmliBoBq00gmURMLerruQL7dN4aHz lx9y3x66xRZ7m8tpPg8N0PfYedrn4dTmH57XPv9qvZT0dqt3xXQWvWuKO6R89leUffyzcfWZH0kM 4mpWUpO+Xpuf6Png1ITN0bNnpkfGen1RLgl17qxWmb3ifPn6xeIbvUNnarNWsfLwPEj6dMHhptBv v7t7J22w3MnppOy5OGTl382hDtnZl7dck94UkvvlpvbvZ497zBe/cdz4js3wx0LfR9smq2rapQUG r6lyZHR8u3m5r/6+j4/vleuJ7Psefbi6/4fkpwd7lqeW9qxfoef18WFAmJhrGY9p5eWkHWbrVmjt KvthyOY0QfNYwzH2acqnc8RsHS8++HD03XVWp6ulm34DALzY4TcNCmVuZHN0cmVhbQ0KZW5kb2Jq DQoyNTkgMCBvYmoNClsgMFsgNjU4XSAgM1sgMjIwXSAgNDg4WyAzMjhdICA1MjNbIDM5NiAzOTZd ICA2NjdbIDgxOCA2OTEgNjc1XSAgNzA3WyA1NzBdICA3MDlbIDU1MV0gIDcxMVsgNTU1IDQ5OV0g IDcxNFsgNTExIDU4NF0gIDcxN1sgNTc3IDU5NiA4MTEgNTg3IDU0MCA1ODUgNTcxIDQ1MiA4NjYg NTAwIDgwOCA0ODNdICA3MzFbIDg0Nl0gIDczNFsgNzkyXSAgNzM4WyA1NzddICA3NDVbIDQ5OV0g XSANCmVuZG9iag0KMjYwIDAgb2JqDQpbIDIyMF0gDQplbmRvYmoNCjI2MSAwIG9iag0KPDwvRmls dGVyL0ZsYXRlRGVjb2RlL0xlbmd0aCA5MjMzMy9MZW5ndGgxIDE5NTI0OD4+DQpzdHJlYW0NCnic 7H0LfFTVtfc+j5nJY5JMXiRkSDhhSIiZvEx4JDGGMS8ID+URaIKomcwMycBkJs5MeAoERcBIEa0i IlprKSqlfgdL+YBSSy23Ui9QpWp9oCJatBa81KtIrc3c/97nzGQGYqtf+/v63e/OXjl7/nvttdde e+211z4BRglHCElFJZKyhtnNk+5f+CMz4d+rJCRj6aSGxqb0R6QCQly7CdHMnTTjhtkd296bSYhX JNzAjkmz59Q1HlkwQPieJ8HbfMPs0vJZP99fQQi3H1rbbd3Wnpgt8S8RYhpBCH+zbbFfqnmzkidk 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 ekqop4RqSqilhGpKmEkJ9ZRQTwnVlFBLCVWUMJMS6imhnhKqKaGWEqopoZoS6imhnhKqKKGWEqoo oZoS6imhnhKqKaGWEqopoZoS6imhnhKqKKGWEqoooZoS6imhnhKqKaGWEqr5wgHRBJG7vRDRtjoz b7OPH7QPfyc0i2RzRLL+wl79I/v6HQiFqNUiajWJWgsLEavMHrI8dIpUrSJVs0g1R6TqE6GaRahW EapZhOoVoeaJUH0iU4fI1CwytYpMzSLTGJGpV2SaJzKtF5likSkWmbIiU5PI1CIyNYlMI0WmPhGp Q0RqFpFaRaRmEWmMiNQnEnWIRM0iUatI1CwSjRGJekWieSJRnwjULAK1ikDNIlCvCDRPBGoWgZpF oFYRqLnsDPd8QVmtsjPdU6fNs/V/jvJZyndGnl6RZ6HIs17kiUWeWOTJijwtIk+LyNNUjDx9Ik6H iNMi4rSKOM2FiHNViEWaWKQZjjItokyTKLNQZOkWWTpEllaRpVlkmS6yrBdZYpElFlmyIkuTyNIi sjSJLCNFlj4RpUNEaRZRWkWUZhFljIiyXkSJRZRYRMmKKC0iSouI0lSMKH0iSYdI0iyStIokzVE2 0Rhyw6f9wp5u5+k+VzjVL5YuDc9TSY99T5N9zxxqeZhastQymVpGU8tUaummlhZ7nV6KaaKYORSz yl4nSzWTqWY01Uylmh77nCb7nDnU8zD1ZKlnMvWMpp6p1DPbPme6fc50KppRtvuOjWV77PgTFc2h oslUNNs+Z7p9znRqmkRNM8rGqLOvOvvt2ERNc6hpMjXNpqap1DSVmiZR04yyQ9Q7VL3D7DUmKD9c G0fgM8onKp+k/Ejln9XOUcqPVjYZxyg/Vvlxyo9XPkX5Cfo5UT9TzfBJ6pyMU9xTre1pO56nsqVU NpXKZpTVuGe6e0+Xf8aORVQ2wUnuJ1TWZp9TZ58zndrmUVsjtY0sm7VjK7WlqK2N2uqorY3a6qht KrXNo7ZGahtZdpF6DdJLlF+qfK525im/TPnl8ucrXxBS9ji9lNdEeXMob5U9Tpb6JlPfaOqbWr6I Ihbbm9ygfIn9zFL7jGXybwyVlDiBEmdT4lRKnEqJkyhxRnnLjo3lt+/4U/kdO96ixAZ7nOn2ONMp cipFTiu/R36r8nt3bKLINoqso8ipFDmPIhspcmT5Qzu2UuRIiszY49TZ40ynzHmUOY0yR5Y/vuO1 qJ4ih6iRAqNRlNdPeXmq66O6pRTXQWUxlfVSWZ7K1u/0pmgUdfVTV56y+ihrKTX18aM+KuqgnJhy +nhQHw9aSjEdFLKe3+T5zXp+s5AqYqro4zN9fGYpFcRU0Mdf+vjLUrPfYcb7eEqfme4w0338pI+X 9PGSpXykw6zGZrWPf/SZ0aVms8PsrTd7eV6x3uwtNGOxGevjEX1ma6kZis1QrxnKm6H1BX9YFI0y M7GZyZuVPrOy1Cys5wd5frCeHyw08rGR7+MDfXxgqVFeb5Tz1v16o7zQyMZGts9674tWGdUu63yF kV1hbfda2x3WdtYIrzLCq6zteUZ5hlGekh7+m8a7Rnvn2s5a26uKa3uVUZ9j1Kca9SnWdq+13WFt Z43+KqO/ytqeZwZmmIEp1nabtZ21trNmo1GEmGFGpljbD5uVOmu7zdrOWttZM7TQDDWKFDPM0pTi V5qHzVSdtd1mba+ytldZ2/PMXKOZm2bmJpu5hLXdZm1nre2sWVxoFhtFjBlmckrxK02btZ21trNm daFZbRQ5ZpjZKcWvNA+b3Tpru8PazlrbWTPdIoLUme0p1nZHMYI0mvEpIsgMsz7F2n7R2m4186OL X2my1naWClqKkaSOEqZSwsHWdgc1zCt+pVllba+ytluoo5k66qhjMnWMLn6lyVrbWUppKUaUOmqZ Si0HF9d21tpeVVzbqyhnDuVMpZwpxbXdYW1ni2u71dqeR0VTqWiStd1mba+ytldZ2/OoqpGqplHV ZKpKWNvt1nbW2s5S2EIKaxRtZlDZFCpLFL+SrLK2V1nbLVTXTHV1VDeZ6kZb2x3WdtbazlJgCwU2 Wtt1VDglerLwf3vujDp/oMZp1NhVjDrtok4HZcaU2UaZGcpcW9yj1FHmpE/sUbKUGVNmG2VmKHMt ZfZQZh1lTqLMeZQZU2YbZWYoc21xz1JHmZOKe5ZWysxQZoYymyhzAmWOpsyW4t6llTIzlJmhzDmU 2USZEyhzdHEP01Lcwwx/P2ymzGbKnEOZzZQ5jjIrKXMMZbZSZoYyM5Q5hzKbKHMCZY4u7mVaKTND mRnKnEOZTZQ5gTJHF/c0LcU9zTrKzFBmpni6nkyZoykzR5mtlNlEmaMpcwJljqbMNZS5UNT5sKjM NsrMFE/X/5u584+Porr3/tnZsMkuAWKNgD8KoihERSUBjUiKYhtXixohVzEJGOu60KABJdFYhZTY vUSb56Lx3ojp9vWizRY19qarjV5dFTWT1NC6iUayPyyK2YUsyhriigEC5tz3TAYIgrV9nj7Pff54 O7MzszPnfL+f8znfs8Hdp1BmDsqcijKzDGU+gjJ9KLMaZa41Vte/QZlZKHMqyswxlFmLMquN1fVT KDMHZU5FmVkoM44ya1FmNcp8CWV2oMybUebFKPMuVPk8qqweUfsUosqLjdpH++xuLapciyoLUeVa VDkZVY5GlWcYn91Vo8pqVHmXocoMVHkaqrSgSh+qrEaVa41V9W9QZRaqnIoqcwxV1qLKakOVxagy B1WeJtxGDbQeNa5HfSHUFzLU50N9Zaiv2Pg0O4763CivA+V1GMrzobwSlFeof7ZjwROTYVh1PlRX huqKjU+tfaguhOpCqK4a1ZWhumJU9yaqK0N1PlQXQnUhVFeL6qpRXRmqK0Z1U1Hdm6iuDNW9hOo6 UF0Hqqs2PtMpQXWFqG4qqvOhuhCqC6G6WlRXjerKUF0xqpuK6nyoLoTqQqiuFtVVo7oyVFeM6qai ujdRXRmqC6G6EKoLobqXUF0Zqis2KuqnUF01qitGdWWorhjV7Ud1b+KH16K6VlQXQnUhVOc2PrUu Q3XFhuq2orq1huo6UF3HiM90SlBdofGpdSuqC6G6EKpzG59al6G6Yl1196CyUhhWnA/FlaC4Qv2z nPvxygeggur7QfzoZ9RED5H54c9xXkJxHSiuA8VVG5/jlKC4QhQ3FcX5UFwIxYVQXC2KewTFlaG4 YqPq1hTXgeI6RnyOU4LiCo1Pi1tRXAjFhVCcG8WtRHFlKK5YJJvGiUztGxiUV8SVSlw4zOeJmcmP in7t/1gR6SPOztTPJERmshSZKSkwEc6Fi2AW3AxFcJfItK6ECjHTuo7tY/AkuEWm+JFylnQqk+F8 cMgsZRmUwsOwQS5VVBlW2qAd3odtEIRe+EqGkw9KZ/IgHJLOlCSIkpmdsAt6IQa74VP4DPZAHD6H PtgL/fAFJOBLYDWR8hUMwH44AAdhEA7BYfgahkASUQGsLKwrpNNaBiG51BqWS20pMmyzwmSYBtMh A2bBbJgjw6kHYRAOwWEYkmGRduRbT0x7ZBPjP1+5VHqUTLlEuUpuUH6EJ/xY+pWF0qXcwvlb2b9f rlQq2P+Z3GDOl0+IU5SzhE2ZDOfDxbJHuUS+iovs4y5x5Ur5anILHBS25EE4JGwpSbBAvppyg3zV ukLYrGXa/x9j6hnqMe2EXbBXZJi+hAH298MB6TIdpg1nSTsZtONVfuVcOJ/9C9heTDsvlaqSRbty ZA5tb1Kuph/z4Vqwc/566VVu4B438vomuVDJQwU308eF8iFlEefz5b300U8fg8pizt/GfQq4tgiW iAxlKdzO+4s5fwf8BO7kOgcz+DLQZvAV8mkUNV+5j20FbXuI6x/m9Tpe/0K6kl+X/uQt0MX+NvhE Pp3cA1E4KO2oy4667KjLnrJYNqXcASXMLivgbrgHSmElrIJ7gZonhfVMShmUw/3wAFTAg8CaJoW6 J4XxnrIG1gLrmhTWNSnroAoekZ6UX4AL/hXWQzUz3aNsH4PfQoPISPGI3JTfsd0Mz7DaeFbkpTzH fiPb5+H37P8n1zax/YOYm+Jl+wK8KF0pf4RmeAlehv+CV+BV8MmFKa/B6zKY8gZsgTfhLXgbWkCF VmiDP8E70A5b4c/wF3iXe/ihAzrhPXgfuuAD2AbdEIAghCAMH8JfYTt8BB/DDvgEeiACUWrtnbAL eiEGu+FT+Az2QBw+hz7YC/3wBSTgS9gHX8EA7IcDcBAG4RAchq9hCCT1qAATzMDDLhHTrZfCLDHX erl82poNV8AcuBLmQg78AG6ULutNkAc3A+PXugjy4V/gFrgVFsNtUACFUARLYCmgdWsx3AE/gTvB AXeBE5bBcvgplMAKaceR7NYNssm6UTaJJJylB2fp0T3hfvmBmMaroOmgWGj6Wixk/EYZu1HOqkfH 1wrG0H16JRxkzMQZL1HGS5RxEmecxBkncUOHGSN0mIEOMwwdZqDDDF2HwxrMOKJBYhYnZnFiFidm cWIWJ2ZxYha3at8cYMFVYsoMGaJFr+Nfqt6KB2VQ1B/5liR8yGcalE+YDtGzw+wPsS/pnYK3mGW5 ksR2FFvWg0oy23Ply/TxZWWGmM5dB/Coe5WZIh2PCur+ejU+9SM851pe23nydSILj/LjTUG8SfPd hYY3+XTvXcx9b+N1ESzh2qVwO8eP9yQvcfQRR59Szvn75Wa8yIVfP01MfcT0ZWL6Mh7kx4P8xNZH bH3E1ofXBPGaIF4TxGuCeE0QrwniNUG8JojXBPGaIF4TxGuCeE0QrwniNUG8JojXBPGaIF4TxGuC eE0QrwniNUG8JojXBPGSIDnMIodZ5DCLHGaRwyxymEUOs8hhFjnMIodZeEmQPGaRxyzymEUes/AS P17ix0v8eIkfL/HjJX68xI+X+P8JHuLFQ7x4iBcP8eIhXjzEi4d48RAvHuLFQ7x4iBcP8eIhXjzE i4d48RAvHuLFQ7x4iBcP8eIhXjzEi4d40aAPDfrQoA8N+tCgDw360KAPDfqoeHpQ1k7YBQOwH3Wd Rf3BvM5sF9bnVQejZhmUwsOMDuZ1Zo4wM0eYmSOMU0VxqihOFcWpojhVFKeK4lRRnCqKU0VxqihO FcWpojhVFKeK4lRRnCqKU0VxqihOFcWpojhVFKeK4lRRnCqKU0VxqihOFcWpojhVFKeK4lRRXCCM C4TF99By+tFxXc5c8b85bqkTqVDo9wf6aLlOBhgdqj468hmbSYypVxknHubuIDoPmM4mhmeaIrLT FIWd7O+CXjlD+yYxYnomMT2TkXyL6SBuNAiH2f+a7RB3UOQMRrKPkTyDkexjJM9gJPvIQTE5KNZd 63y2mnNdShtmMqpzZJFRcTRRcTQprAwY0RuMqsPFiC43qo5ltP1e2v6vtLjJGNn1I6oOJ6O7iKqj iRG+YUTVUf6NEe7Uq4679H+HNl9ZbvxbtBK2K+RG5W6294BWiaxkuwru4/hqtmW6F2uRcuqVyRpe V8LPec46uTH5Mtlz1HW7ZDkOUY5DbMQhNuIQG5N3c34P9MFBVoSDcIhVSBKUyCLcowj3KMI9inCP ItyjCPcowj2KcI8i3KMI9yjCPYpwjyLcowj3KMI9inCPItyjCPcowj2KcI8i3KMI9yjCPYpwjyIq lSYqlSYqlSYqlSYqlSYqlVYqlSYqlSbcZYOhtMxhpbFiekZMR2kOQ2m5KC3XqFQ2GGpzGGpLx13K cZdy3KUcdynHXcpxFzfuUo67lFOpLKNSWfZPcBknLuPEZZy4jBOXceIyTlzGics4cRknLuPEZZy4 jBOXceIyTlzGics4cRknLuPEZZy4jBOXceIyTlzG+T9aqSiyx2qGJBgFFkiGFLCCDUZDKoyBsTAO 0uAU+B6cCulwGoyHCTARTocz4Ew4C74Pk2AynA1T4Bw4F6bCeXA+TIPpkAEXwIVwEWhVFbUJlVUm lVWmdSb7mZAFrCqts9kyHnDtjbj2Rlx7I669EdfeiGtvxLU34tobrfO45ir9328V433FzPXaGupq RrDmBHZG9/Xs38jIzmNNcDPbhZDP/i1sqcOMEZnFSKlldJQwOkoYHSWMgFpUX4LavSjdi9I7UPZc VB05pmr2j9TfTewPq3kSas5EuV5rBj0Zrh9z6WUuPcsTeXikB2/04I0ePNGDJ3rwOD8e56cOUvE4 P7WQ9q+cXKznnPjcBtZyTvw3iPcE8J0A/hLQW/4A1z6I/zzM6yr2H6GqaGGdvIttL8TgIAzCIWbo JFiATm/QtRpAqwG0GkCrAbQaQKsBtBpAqwG0GkCrAbQaQKsBtBpAqwG0GkCrAbQaQKsBtBpAqwG0 GkCrAbQaQKsBtBpAqwG0GkCrAbQaQKsBtBqwXi391vlwDfwQqMSsuXAtkDXrdXA9sAK2LgAqM3Ls J8d+0cCMsl775kdmkjZmkXJqwk5mkjZmkXJqwk5mks3MJCXMJJuZSUqYSTYzk5QwgzQzezSPqAlr 9frvBtmm62IRmrmVDBxf47UxA4SYAULMACHlLjFZWQ4loNV6d7O9B1bCKtBqv9Vsy6AcZx+uAT3K Gl5Xws9BqwUvE5Nx+2bcvhm3b8Pt20bWg8m7Ob8H+sTkf0Ld1oaztuGsbThrG87ahj7bcNY2nLUN Rw3hqCEcNYSjhnDUEI4awlFDOGoIRw3hqCEcNYSjhnDUEI4awlFDOGrIqojJVjMkwSiwQDKkgBVs MBpSYQyMhXGQBqfA9+BUSIfTYDxMgIlwOpwBZ8JZ8H2YBJPhbJgC58C5MBXOg/NhGkyHDLgALoSL YAZcDJfApTATMiELZsFsIDffVS9a53HNVWKy+Blj18XYdTFuXdQjLbiPaqwkXsFxtDpDWz2o1Bct +orhTvYdjOdlUKrXAs6jK4KD0sVYdTFWXYxVF/N6C/N6C/N6C/N6C/N6C/N6C27Vwrzewrzewrze gnO14FwtOFcL83oL83oL83oL83oL83oL83oL83oLrtbCvN7CvN7CvN6Cw7WgpEyUVHrUyf6Au72A i31Xtf+uVJlHVeZRlXlUZR5VmUdV5lGVeVRlHlWZR1XmUZV5VGUeVZlHVeZRlXlUZR5VmUdV5lGV eVRlHlWZR1XmURVvcuJNTrzJiTc58SYn3uTEm5x4kxNvcuJNTrzJiTc58SYn3uTEm5x4kxNvcuJN TrzJiTc58SYn3uTEm5x4kzNF+xzxMHwNQyClE29y4k1OFDIXdcxFHXP1uWgFK+wy6RKnJEv8PQUm wrlwEcyCm6EI7hIO60qogHXwGDwJT4l0q5vtJjFJmBTt+/FM+I1fmKlL/dQ1fuoaP/X0VajlRjxG q1CpqcXd6MljrFZV5cccvYGaNY9jN7O/EO0s4ng+52/l2GL0d5v+iVkOzpWD1upxLhXnUnEuFd25 0Fk9OqtHVx505UFXHnTlQVcedOVBVx505UFXHnTlQVcedOVBVx505UFXHnTlQVcedOVBVx505UFX HnTlQVcedOVBV9qnVjk4Vg6OlYNj5aCzHHSWg2PloLUctJaDY+XgVjloLge3ykF3OeiuHt3Vo7t6 dFeP7urRXT26q0d39biVilupuJWKW6m4lYpbqbiVilupuJWKW6m4lYpbqbiVilupuJWKW6no1oVu XejWhW5d6NaFbl3o1oVuXejWhW5d6NaFbl3o1oVuXejWhW5d6NaFbl3o1oVuXejWhW5d6Fb7HcPr xFxxjf4pw9V6voLkq4ccxclPUP8E4XZ9HREkF0FyEfx/svJ/Ef4IzfASvAz/Ba/Aq3pNHCQmQWIS JCZBYhIkJkFiEiQmwRStnd0QgCCEIAwfwl9hO3wEH8MO+AR6IIKKJ6LcYtRqR61uY8XlRplulOlG mW4y6iajbjLqJqNuMuomo24y6iajbjLqJqNuMuomo24y6iajbjLqJqNuYdHGFPVRXFkAI8eUlgk/ Z4NGJjQ3DhqZ8J8kE34y4ScTfjLhJxN+MuEnE34y4ScTfjLhJxN+MuEnE34y4ScTfjLhJxN+MuEn E34y4ScTfjLhJxN+MuEnE/7/0UyY8ZK45jxkYdiDho8FjWNBoeA/quY/wk7kGvTrr9bX0X7i2qTP aQv19b9KFDcQxQZjTttwZA4jig1EsYEoNhDFBqLYQBQbiGIDUWwgig1EsYEoNhDFBqLYQBQbiGID UWwgig1EsYEoNhDFBqLYQBQbiGIDUWwgig3fOTf5WI++Bu+yzvRDB3TCe/A+dMEHsA26IQBBCEEY PoS/wnb4CD6GHfAJ9EBEbhCjiI6qq+5GPYKaZ/uF1dQng6a9kIAv9U8btbOvaPE1XyGbzHOI7i1E N2B8ahHTK3tNm4uoS28Rcw19BpQCzmlrmjvgJ3CnrtEA0Q0Q3QDRDRDdANENEN0A0Q0Q3QDRDRDd ANENEN0A0Q0Q3QDRDRDdANENEN0A0Q0Q3QDRDRDdANENEN0AK/0YK/0Ya58YK/0Y658Y658YK/0Y K/1YyutUCG/AFngT3oK3oQVUaIU2+BO8A+2wFf4Mf4H/mxo3adHUVe0/Oo9a9L+0aX9lG/4L2qvK z+S95ny5XpzGkY9YRamsovpYQamsoFRWTyqrJ5XVk8pKRWWlorJSUVmpqKxUVFYqKisVlZWKykpF ZaWislJRWamorFRUsZg1no01no01no01no01no2az07NZzf+WqVS+9lZLajGCrRFeYj2PcyxdRz7 hWxiNaCyGlBZDWj1kJ16yE49ZKceslMP2amH7NRDduohO/WQnXrITj1kpx6yUw/ZqYfs1EN26iE7 9ZCdeshOPWSnHrJTD9mph+zUQ3bqIXuK9pevw/A1DIGUduohO/WQnUpYpRJWqYRVKmGVSlilElap hFUqYdV6o2yy4g3WPKAusRJ16yLIh3+BW+BWWAy3QQEUQhEsgaVwOxTDHfATuBMccBc4YRksh59C CeNH+7aCHuNf7vSIU/VXCiSBRf8sboDYDmhniecAsRwglgPEcoD+DNCfAfozQH8G6M8A/RmgPwP0 ZwDt/FR/51Y00S0ma9+LYOoTGaa9YqapX6SbEvpfSGea9rF/gHOHWeEpzGRJYIEJIp3nd/P8blaA 0/W/2K6T3eZ5It2cLzJoSzdt6aYt3bSlm7Z005Zu2tJNW7ppSzdt6aYt3WI6SoqjpDhKiqOkOEqK o6QYSoqhoBiKiaGOGOqIoY4Y6oihjhjqiKGOGOqIoY4Y6oihjhjqiKGOGOqIoY4Y6oihjhjqiKGO GOqIoY4Y6oihjhjqiKGOGOqIoY4Y6oihjhjqiKGOGOPtQdnJf5kDxVW0dj6tnU9rtW/SaKPF82nx fOKk/dVGy1EnceokTp3EyUpPKulJpZ6vUrZazirooTYaH+Y1uSNu1pH5o7eV9LaS3lbS20p6W0lv K+ltJb2tpLeV9LaS3lbS20p6W0lvK+ltJb2tpLeV9LaS3lbS20p6W0lvK+ltJb2tpLeV9LaS3lbS 20p6W0lvK+lt5XdqRxGj9R4ExA+IRZBYBIlFkDgEiYP2+U2E/kZQWIT+RlBZPe5Tr/2ti/5GcKB6 HKgeB6rHgepxoHr6G6G/Efobob8R+huhvxH6G6G/Efobob8R+huhvxH6G6G/Efobob8R+huhvxH6 G6G/Efobob8R+huhvxH6G6G/Efobob8R+huhvxH6G8H96nG/etyvHverx/3qcb963K8e96vH/epx v3rcrx73q8f96sUE/W92B/RP94P63+e0v81Z9L+NRclwlFExyXA9DxnW/sYYJbtRshslwlEiHCXC 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 RUwxU8KUMuWZsqabTDebbjE1MzU3tTAVm1qaWplam9qY7tGP6Ef1Y/pxvV4/8f/ftP5/5E1rK5JN zGQ2WU32f/I+I1/P8mH5iHxUPiYf/wnvk+HsBfn3bA1bzzaxrWw728MOsCPsOGtgjewcu8gus2ua rGmaXfNqYS2p5WtNtRZaK14llfKKqAevd/rxSmcIr2pG8QpmsjZDm8N3u6XaCm21tk7bqG3Rtmm7 tDrtsHZMO6Gd0s7w3e6SdsWMzIpZNzvNfnPUnDYXmAvNxebW5hJzmbnc3Mvcx9zfXGkeah5hHm2e YJ5qrjLPNS8y15hXmteY15s3mbeat5v3mA+Zj5rrzQ3mRvM580XzZfM1XdY13a579bCe1PP1pnoL vZXeVi/Vu+o99Aq9nz5IH6IP10fp4/TJ+gx9jr5AX6qv0Ffr6/SN+hZ9m75Lr9MP87vnhH5KP6Of 1y/pV3gVpvCay2nxW6KWtKXAUmgptrS2lFjKLOWWXpY+lv6WSstQywjLaMsEy1RLlWWuZZGlxrLS staywbLZUmvZadlnOWQ5aqm3NFgaLecsFy2XLdesslWz2q1ea9iatOZbm1pbWFtZ21pLrV2tPawV 1n7WQdYh1uHWUdZx1snWGdY51gXWpdYV1tXWddaN1i3WbdZd1jrrYesx6wnrKesZ63nrJesVG7Ip Nt3mtPltUVvaVmArtBXbWttKbGW2clsvWx9bf1ulbahthG20bYJtqq3KNte2yFZjW2lbY1tv22Tb attu22M7YDtiO247aTttO2u7YPvGdtUu2VW71e62B+1xe8bexN7c3tLext7e3tnezd7b3tc+0D7Y Psw+0j7WPsk+zT7bPt++2L7cvtq+zr7RvsW+zb7HfsB+xH7cftJ+2n7WfsF+2X7NITs0h93hdYQd SUe+o9BR7GjtKHGUOcodvRx9HP0dlY6hjhGO0Y4JjqmOKsdcxyJHjWOlY41jvWOzo9ax07HPcchx zHHCccpxxnHecclxxckDidPqdDuDzrgz42zibO5s6WzrLHV2dfZwVjj7OQc5hziHO0c5xzknO2c4 5zgXOJc6VzhXO9c5Nzq3OLc59zgPOI84jztPOhud55wXnZed11yyS3PZXX5X1JV2FbgKXcWu1q4S V5mrm6u3q69roGuwa5hrpGusa5Jrmmu2a75rsWu5a5VrrWuDa7Or1rXTVec64qp3nXKddV10XXZd c8tuzW13e91hd9Kd727qbuFu5W7rLnV3dfdwV7j7uQe5h7iHu0e7J7mnuee4F7iXule4V7vXuTe6 t7i3uXe569yH3cfdDe5G9zn3Rfdl9zWP7NE8do/XE/akPQWeQk+xp7Wnvaezp5unt6evZ6BnsGeY Z6RnrGeyp8oz37PUs8Kz2rPOs9Gz1bPds8dzwHPUc8Jz2nPWc8HzjeeqV/KqXqvX6416094Cb6G3 2NvaW+It85Z7e3n7ePt7K71DvSO8Y72TvVXe+d6l3pXeNd713k3erd7t3j3eA94j3uPek97T3rPe C95vvFd9kk/1WX1uX9AX92V8TX3Fvta+9r7Ovm6+3r6+voG+wb5hvpG+sb7JvirfXN8iX41vpW+N b71vk2+rb7tvj++A76iv3tfga/Sd813yXeFlk+LX/U6/3x/1p/0F/ub+Vv4Sf2d/N39vf1//QP8Q /3D/KP84/1T/bP98/2L/cv8q/1r/Bv9m/zb/Hv8B/xH/cf9J/2n/Wf8F/zf+qwEpoAasAXcgGIgH MoEmgeaBloE2gfaBroFegb6BQYGhgZGBsYFJgWmB2YH5gcWB5YFVgbWBDYHNgdrAzsC+wKHA0UB9 oCHQGDgXuBi4EpSCatAe9AbDwWQwP9g02CLYKtg2WBrsGuwR7BMcGBwcHBYcGRwbnBScFpwdnB9c HFweXB1cF9wY3BLcFtwTPBA8EjwePBk8HTwbvBD8Jng1JIf0kDsUDiVD+aGmoRah1qGSUFmoPNQ7 1C80KDQkNDw0KjQuNDk0IzQ3tDi0PLQqtDa0IbQ5VBvaGdoXOhQ6GqoPNYQaQ+dCF0OXQ9fCclgL 28PecDicDOeHm4ZbhFuF24ZLw13DPcIV4X7hyvCw8KjwhPC08JzwovDy8Krw2vCG8OZwbXhneF/4 UPhouD7cEG4MnwtfDF8OX4vIES1ij3gj4Ugykh9pGmkRaRVpGymLdItURPpHBkeGR0ZHJkWmRWZH 5kcWR5ZHVkXWRjZENkdqIzsj+yKHIkcj9ZGGSGPkXORi5HLkWlSOalF71BsNR5PR/GjTaItoq2jb aGm0a7RHtCLaLzooOiQ6PDoqOi46OTojOie6ILo0uiK6JrohuiW6Pbovejh6PNoQbYyei16MXo5e i8kxLWaPeWPhWDKWH2saaxFrFWsbK411jfWIVcT6xQbFhsZGxsbFpsZmxxbEamKrYutim2K1sZ2x fbFDsaOx+lhDrDF2LnYxdjl2LS7Htbg97o2H48l4frxpvEW8VbxtvDTeNd4jXhHvFx8UHxIfHh8V HxefHJ8RnxNfEF8aXxFfHV8X3xjfEt8W3xWvix+OH4ufiJ+Kn4mfj1+KX0nw0iShJ5wJfyKaSCcK EoWJ4kTrREmiLFGe6JXok+ifqEwMTYxIjE5MSExNVCXmJhYlahIrE2sS6xObErWJXYkDiaOJE4nT iXOJS4mrSTmpJ51JfzKaTCcLkoXJ4mTrZEmyLFme7JXsk+yfHJwcnhydnJSckZybXJxckVydXJfc mNyS3JbclaxLHk4eS55InkqeSZ5PXkpeSSFeJOkpZ8qfiqbSqYJUYao41TpVkipLdUtVpPqnBqeG p0anJqVmpOakFqSWplakVqfWpTamtqS2pXal6lKHU8dSJ1KnUmdS51OXUlfTUlpNW9PudDAdT2fS TdLN0y3TbdLt053T3dK9033TA9OD08PSI9Nj05PS09Kz0/PTi9PL06vSa9Mb0pvTtemd6X3pQ+mj 6fp0Q7oxfS59KX01T87T89x54bx0XpO85nkt89rktc/rnNctr3de37yBeUPyRuSNzZucV5U3P29p 3sq8NXnr8zblbc3bnrcn70DekbzjeQ15Z/Iu5F3OoIyasWf8mWgmnSnIFGaKM60zJZmyTHmmd6Zf pjIzLDMqMyEzLTMnsyCzNLMiszqzLrMxsyWzLbMrU5c5nDmWOZE5lTmTOZ+5lLkiisqsnnVm/dlo Np0tyBZmi7OtsyXZsmx5tle2T7Z/tjI7NDsiOzo7ITs1W5Wdm12UrcmuzK7Jrs9uym7Nbs/uyR7I Hskez57Mns6eFVkffgvwbcB3AHcC7gGsAzwEeET8PRpegwjdfEDFwHcA3wWsh98lF20VbKugo4KO asj3ANYBHgIUvTTQ0UCiGZKPOJpBroM1HazphmQn4B7AOsBDgKKvBXSsYMEGvWzQdkDbAZ44wIID 5E6w74SzTujrhLNOsO8E+06w78THOD4Mmh4D3wUUdrwg8YIFL8i9IPdB2wdtP4zlB00/aPphLD+M 5Yex/DCWn7MuUIwYhF5B6BWEXkHQD4M8DPIwyMMgj4AkAuNGgJMpeAPgJsAtgDsAdwPuBzwI+Hvx Nx143SZ0fwX4koFbAGsB3+c4HaxOh7PT4ex0ODsdrE4Hq9PB6nTQnwk6M0EyMyfhtZp4PiR83wvW 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 YrlozupBFQl/4fhXLr2FW923IpBCHAM4k6PwgYgjLUU4dSIyolXZw7WzWVMuPc5I+zz0wy++v9Zx wK686T/Un/7Wo/Bt71kfDJn3TtjZjK8MS5fbRlThXeuC/RcPfTJ+/lHO5imsE94zfLXnHv442uP2 3fH3AyPufNKjshp/eHBSxITkrVOTt2en7fRkyZrv7BucFNQce7h2xr0x83bnZN7Lrrg+dbGpb9m2 D0R1V071TZRcbQhoHP75j5w0Y1zQyW/HnNkdevffmnuNL220dj+sf4NtOzm5vHqnmJeR1U8oFBeU NUz01h4Qf9H14kxsuain9BNb9/qXBx6IjI/Z+GHj3s+iNp4rG/rdjc4PDtxHxwXpSvvof71jG2Q5 /CBvb65XgvLb5gFfZwdMCvDZtOJA08GsQV9UWvadrraz60Dld9xlLz5mZ+8HTXspINr2/M+vcdtb qrcE82j0H+5YFro2ztgAys47PKwztTzBMCwSi8bioiLHPAXlE7He/Q4vCJrx0o0N0nlXruxvDSpb xaxdHaOF0/aP5ZYcLEhZd2nCrOEvD6+qfOdMdf++Xuc25NVcnqjrsTlsmbzJphQZtx8em9bx6OiE SR/vGx7sfenTgqhH+6fP+GTvmFG19Z1vz18fIXulZCTrK+z9t/A1MsPamrJ8X7Kqsl99+o6QTQ+S e08MOL/Qs8+JcXEL7Jdfjfk6fHPYPx+AuPdf9OeSeQ0KZW5kc3RyZWFtDQplbmRvYmoNCjI2NCAw IG9iag0KWyAwWyA3NTBdICAzWyAyNTAgMzMzXSAgMTFbIDMzMyAzMzNdICAxNVsgMjUwXSAgMTdb IDI1MF0gIDQ5NVsgNjY2XSAgNDk3WyA1MzQgNzUxXSAgNTAwWyAxMTEzXSAgNTA0WyA3MjJdICA1 MDdbIDc3OF0gIDUwOVsgNzU4IDY2NyA2ODVdICA1MjNbIDY3N10gIDUyNlsgNTU2XSAgNTI4WyA1 MzIgNDMxIDU1NSA0NDRdICA1MzNbIDQwNCA1NTZdICA1MzZbIDU2NCA1MjAgNzA3IDU3MiA1NTYg NTU2IDU1NiA0NDQgODMzIDU1NiA4MjUgNTAwXSAgNTUwWyA4MDhdICA1NTNbIDc0OV0gIDU1N1sg NTQ4XSBdIA0KZW5kb2JqDQoyNjUgMCBvYmoNClsgMjUwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAy NTAgMzg5IDI1MCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDY2NyAwIDc3 OCAwIDU1NiAwIDAgMCAwIDAgMCAwIDAgODMzIDY2N10gDQplbmRvYmoNCjI2NiAwIG9iag0KPDwv RmlsdGVyL0ZsYXRlRGVjb2RlL0xlbmd0aCAxNDQyOS9MZW5ndGgxIDQ2MTA4Pj4NCnN0cmVhbQ0K eJzsfQl8U1X2/7nvJXnZl6ZN06ZtkqYL0H1fKG26pC1UdroBpS2UHWQVUWewgAgGlKK4oaKog+tI mgJNAYVRUXBFBVRc8DeiOIPIqICO0rzfebehpRJmZH7+Pv/5/Sfnku89997z7nLuuefeG9pXIAAQ hCACS9nYoRU/vLzlR4CHTwAE514zbmylSCJ6FID7CoDZMnJsSvo90+ZtBSBP4lM1NWXD66oMU+cA yNcB6DZOmds8f/eyXVg2YQDKrJiyZLHl3e7H1gPMiQEQfzVt/vS5Rx6AjwEmPosNLp/evGg+GEGG 7R3G+rTT59wwbcPq5+cDLFQCKMfNaJm79Ke43F0AERaAIumMqc0te6Wv1GDdiSifPQMzNCel5zHd gumYGXMXLy05xZzEvoLQ3px5U5pX/3DbhwDLmjBdMLd56XxuhGI0yq9BAcu1zXOn/vDRfTcBrHwQ 2wiZP2/RYu/p1uuxP9uF8vkLp86PeXJRPEBzKo7xLAi6Yuo3bdHVFDZqCs6BSQoC/aFqqkeI3XP3 3Ojd2F0pu01aAiwoqLxAGHNTul8AkH3k3eh1yW5jaqAFLqVaQYZ5CCrwOYEY0EIwDEYtTcZ2aR3s XcweEOM4Nokz+E/ggBBDOaOAaUwQETEijpGwYjkjwodXX1r18HnXzgMrWOCP4ve734RVXBNThOp8 +Pj7QqnE10nm4udpmC0CooNfQQzw97CREInPRf0a+V9L4how0L7l8d1CLFrEf3glWe52fheVfRpa xTX8md+yH6JFMPJfeQ51kv1b9iNAAQpQgP5nxDxEKPVmXMr3EaHhIutf4sqpAAXof0IssNRIxSxL GLQ+o/hrxT74UcqDFKR4GpCBDFEOCkQFKBGVoOIvgIqiGtSIGopa0CLqQMf/DEEQhKinGAx6xBDE n/CUEYwYCgZEI+LfIQxCEcMhDNFEMQLC+R8hEkyIURCBaIZIRAtE8T/guUrAaDAj2sDCn4cYsCHG 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 wr73/4CEkH4NCmVuZHN0cmVhbQ0KZW5kb2JqDQoyNjcgMCBvYmoNClsgMjc4IDAgMCAwIDAgMCAw IDAgMCAzMzMgMCAwIDI3OCAzMzMgMjc4IDAgNTU2IDU1NiA1NTYgNTU2IDAgNTU2IDU1NiA1NTYg NTU2IDU1NiAzMzMgMCAwIDAgMCAwIDk3NSAwIDAgMCA3MjIgMCAwIDc3OCAwIDI3OCAwIDAgNjEx IDgzMyAwIDc3OCA2NjcgMCA3MjIgNjY3IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgNTU2IDAg NTU2IDYxMSA1NTYgMzMzIDYxMSAwIDI3OCAwIDU1NiAyNzggODg5IDYxMSA2MTEgMCAwIDM4OSA1 NTYgMzMzIDYxMSAwIDAgNTU2IDU1Nl0gDQplbmRvYmoNCjI2OCAwIG9iag0KPDwvRmlsdGVyL0Zs YXRlRGVjb2RlL0xlbmd0aCA0Mjc+Pg0Kc3RyZWFtDQp4nH1TTW+CQBC98yv22B4M7LArmhgS8CPx 0I/U9tT0gDBakrKQFQ/++y4zVosmkACZ2ffevBkYf75erE3ZCv/V1vkGW7ErTWHxUB9tjmKL+9J4 IEVR5u05omdeZY3nO/LmdGixWptd7c1mwn9zh4fWnsRDUtRbfPT8F1ugLc1ePHzMNy7eHJvmBys0 rQi8OBYF7pzQU9Y8ZxUKn2ijdeHOy/Y0cpwr4v3UoACKJZvJ6wIPTZajzcwevVngrljMVu6KPTTF zTkwa7vLvzNL6NChgwCCmKIJR5q4Z5T841xLpAQL5oyenNF8Lu9KrBg2HxaVkmBywehlT1TfigI7 VZp8h9yF5i6UomgsOWLkmJGKzYx7ZuDOjGYzmnXHS+JqzUkWjGC47UnkYBAADLedTEktSWLx2b15 tGkafw2qp5LUZTjYB4RJJwcKupeSNB/g+YBacjLp9XH7hwCPQkFEXJ6BgvR/XXVXV0dUgkelYMFc NhPRUFXIZiLNSSIolXJyykkeiuKPppyT3lC637vbwsvu5Edr3drQqtK+dJtSGrxsc1M3Hau7fwGa myE5DQplbmRzdHJlYW0NCmVuZG9iag0KMjY5IDAgb2JqDQo8PC9GaWx0ZXIvRmxhdGVEZWNvZGUv TGVuZ3RoIDYwNzE3L0xlbmd0aDEgMjAxNDg0Pj4NCnN0cmVhbQ0KeJzsnQlgW8WZx7/3nqz7PixZ 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 Ezd4tGldUP3J3n3T85JSp5zrVO9pTOVx/j0P5LjGlt0yNn5g0/HX7Gsf3Jm1LSbz2GdzXNqPrnfU 9SOP6JSVyuM/+7LmO3Z0PjEuo6nPxPAl22Z1MCn0o7SLM01O0iPC5iVd6lXaXNFc/s9tml7SNofl FKSETu/yctCHrVLG+iGGvKqZ3W0Vx5SvZn/+S2zzdOf7kS+HvFznl/9zyLoytjgSqGJua2tja5XT Iid6YrPegwalh9er1zMjLaDf23UK6DmgX730j/sQt156xoDkwT0HDaznWEZaRSyijMoAKWKLV60y MYWwmEzmGFtrW8u3n23KxEbGAEOHDv2jAXpl/AvNg2xuZG91s2ZzfquSW/8hITlFSZmmHXJOVc59 L6KK81K/+lNS4+uusbVv+HBn1z73ep2M2d0h48nA6r9dH6/sHuz5SXyzlY/3r5hx+cCA+Eaf36x3 eHjIvZQzpxK3zFjYdeJs15y7Hevndv2t5ohq7d8/e6XfEHN1W1K53O9mLK6xseWNTk+i2+3e9HlN 1wXLrx2tdvvTtNWzeod7PHXbVX7j8PDsJue+6ZJ97OSVinOyMmLyTL/7qi/f95u7tvOh4QtvzQz/ OHDEmKels7tO/f5XsbFB9XlfZ9YOnRq2evVUj1UPbt4L2N4m4DtLyNinbt531reelb19/rguo3Mr 1Euo/YnL7NSwV7btvW4+a3Dpjs/9SdNWrm24wbQz98qrGdUraD7bFmr3vWQZuyfLWME7ZSy/bJ7z 1GMNF15EGc7/xzL26f9Isahmq6onvce77cm9vDv1Se0vtb5TyAKD7EFBwcHBDfRCZnd8tI0d979R yAxx/k/E/9vCdCsvYZF3qee1Rm4VI0bnPrg7ZFWtThHh5yM/Wzcj+NeuEd91rGCP++7o+qnLI5bV L6zb4X5IxXYP2w4/7zZkcr7/ow8Tlt8tPFN78PVKE2r+5enzutlNQv1cIl9ua7hlc8LgWRVj2xwI 3l0//+ndUcueNamQYO3lVbX+I/8tPi6ua1wXDPWZMH5k+82VsvKfLX4ztUib1y7n2X7nqldXXDOF tnhdL7PvWP5seciF2V0XvGxTUDrzfNgX5d5cOz180OTkwh67qgfUWb3AvUrpyht35vmuL91h6yXP WQmtln66YeP5Iy/SR9Qyjd9Up/bR7cuFKLxS5pO2r3MTqo2rfXfv7tb7btUcf3LUnmYuXzGxpn2v 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 xFHc0MjNi6d+yXtQNexr9upD9ZaHjh5e9GR2aZW8SAGs7ITN9hSnSrTYzK1gsnHO+dctKt6TbHF5 1mi53Za/DUlZp7gHuy8rKF1IdvMCe2w6Bnn6i/Sq5tJuFjeq7yZZTW6jp2/QdYpcgi8IvBOpM3Tf 8R44cK1uq13lEYzWU6Pl6qNy7HkNL7ViIjaxW8rqS5XEFIc/LnVSdObRZtLZFAE6G+brHnGBdDZh KLVhVZXnv5sL+PYbiTWaPACIrZUk/9c3K3Dox7+McILrP3XZQC1QSx0AwH1/UWRL8E6sdjA9cK7E zkEJBtaT5jIM/8TrFa0YwMPKQbNtj1wUVWetuyLP9UzLWA3VSEmVq6jY88dUOx+IW1rvHK9zW8Fb IFTB7gBNI+V9s1lNNcvv4Yjxumuno6ZFO4HFHJnXFri0MqZgqPC6jJZLAT8ZyM627/zo+Nx1YX6E nNfWJfaTZLZ+Hz1KjXXp4Pgmd1bibYwqMiyBk928MBUZptAgvkPlJ3SAVWGgLuXuGfwvewMtJJI4 PQ/QdO3c8lgnSJ1CUwjtjTrPs+aFHqvxP5q3+5Gi46aXgbxKwlyxncMUiyw217SklPLavfuQtt28 HKi0drtH503rMNDgv2hrxns6qF41gaR9rxdz76T0QftZaTr7chJS0tIJvy8e9i82SXY8DQplbmRz dHJlYW0NCmVuZG9iag0KMjcwIDAgb2JqDQpbIDBbIDc1MF0gIDNbIDI3OCAzMzNdICA4WyA4ODld ICAxMVsgMzMzIDMzM10gIDE1WyAyNzhdICAxN1sgMjc4IDI3OCA1NTYgNTU2IDU1NiA1NTYgNTU2 IDU1NiA1NTYgNTU2IDU1NiA1NTYgMzMzXSAgNDBbIDY2N10gIDUxWyA2NjddICA2OFsgNTU2XSAg NzJbIDU1Nl0gIDc5WyAyNzhdICA4MVsgNjExIDYxMSA2MTFdICA4NVsgMzg5IDU1NiAzMzMgNjEx XSAgMTM1WyAzNTBdICAxNjlbIDU1NiA1NTZdICAxNzdbIDU1Nl0gIDU3MFsgNzIyIDcxOSA3MjIg NTY3IDcxMiA2NjcgOTA0IDYyNiA3MTldICA1ODBbIDYxMCA3MDIgODMzIDcyMiA3NzggNzE5IDY2 NyA3MjIgNjExIDYyMiA4NTRdICA1OTNbIDcwM10gIDU5N1sgOTc5XSAgNTk5WyA3MTEgMTAzMV0g IDYwMlsgNTU2IDYxOCA2MTUgNDE3IDYzNSA1NTYgNzA5IDQ5NyA2MTUgNjE1IDUwMCA2MzUgNzQw IDYwNCA2MTEgNjA0IDYxMSA1NTYgNDkwIDU1NiA4NzUgNTU2IDYxNSA1ODEgODMzIDg0NF0gIDYy OVsgODU0IDYxNSA1NTJdICA2MzNbIDU4MyA1NTZdIF0gDQplbmRvYmoNCjI3MSAwIG9iag0KWyAy NzggMCAwIDAgMCA4ODkgMCAwIDMzMyAwIDAgMCAyNzggMzMzIDI3OCAwIDU1NiA1NTYgNTU2IDU1 NiA1NTYgNTU2IDU1NiA1NTYgNTU2IDU1Nl0gDQplbmRvYmoNCjI3MiAwIG9iag0KPDwvRmlsdGVy L0ZsYXRlRGVjb2RlL0xlbmd0aCAzODA+Pg0Kc3RyZWFtDQp4nH1TTW+CQBC98yv2aA8GdmGVJoQE UBMO/UhpT00PCIMlKQtZ8OC/7+6M1aqJJJK8N+/NjJOHm+WrXLUTc191XxUwsaZVtYax3+sK2BZ2 rXJ4yOq2mo4I31VXDo5rzMVhnKDLVdM7UcTcN1McJ31gs6Tut/DguC+6Bt2qHZt9ZIXBxX4YfqAD NTHPiWNWQ2MaPZXDc9kBc9E2z2tTb6fD3HjOivfDAEwg5rRM1dcwDmUFulQ7cCLPPDGLNuaJHVD1 VV2Qa9tU36VGtW/Unie8GFFISKL3qOJ/nvOIFGVeRurwqKY6vxmxIVl2vynnKOMrUq8vmsrrpoLU /hr39iUiKQjRv5ASUbg0SHiCaklKaPF/Gf9mmZTapwLV3Lde4SeWFAHWAo4nE0FA5JrI5O4thFyg 7PIWN+OFpElLgWqfJi0lkdQiSIl8JNIYPi2Ltw4kj7/u7hHiGTi/OIONi031KYvVXmsTQ4w+5s8m r1Vw+jqGfrAu+/sFrenyCw0KZW5kc3RyZWFtDQplbmRvYmoNCjI3MyAwIG9iag0KPDwvRmlsdGVy L0ZsYXRlRGVjb2RlL0xlbmd0aCA2MTkxOS9MZW5ndGgxIDIwNDUzNj4+DQpzdHJlYW0NCnic7J0J YBTV/cd/b2bv+8jem+xsNrshm4OQAAkhhM0FaESOBJooSgJEAUXQgFetRiuC8axVqtiK2stKrZug NKAtVK1aKmoVz3pwWMW2Fu2/1nox/9+b2VyEpJvabP7+eZ/lfd85b347+zL7fszMWyAA4EZRQHtN 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 0+kLGNQrEjziWvzT99aE9gBOO25hRuMA82ypMAmIMcQV4gghQLy3D7mdIf4QQYg5hAjxAVt4sN8e fOcCIVLEwkT/crP6E3288QR7Hxei7B/+VKhJUIiWNz7kqXEka6S9fZS273M1l4V7Uw5tYWzh6pLH 3rT79Xg6esSnjKAITqsx6eQ3BNaSBpWARjquGoZl//xfYfqAUIwNx9y4wbnQbKsAFd0aYuBZoHo4 MtE4wkYWutI0grxV7TGSVXaZ29F3HP5OiJ9IbXFBss/scheRU37T77zq/FoOP8XeWtDU8ohICd1y uoPu7GuOwcQhpa7TiewVa/jZ29I5Y+RoHkiA+o/GnuVP9z5++6goXFP3IAGqoOZbRQlfZLqnW6u6 yE2/y6ROSIa55/RP/YIH++k66NYLtcboeRxN8aFxMaOFWrU8Jp1mEqsR0kKcuLKhwzVNV4LG9q2/ 0KCQYBIACSb6dY1o0SQYJ9jFth2Vl75bFvDtJxI7YtIa4NkZkkxfn6xAwS//coUGvevTKRtaHi0v BwCAxZ8i8o2SSdhtSFFji21T8eLMhBe5KyLnD15vxcqT9Nu/RM2msYy05ro4ISOCrWwaLRt52fW9 nKKnyQbywYFq9dKOrXAj0/UU/iKJUplAd7Vc9tCNnhvB7c8M17A3mAf2pGE24JoXFQ4XkOROnD7a O8DyE+3SNcVVDdmZhOYTrX2arffDOfBZk+ZGad6ZFw+RwumU2SYCPJyYbNgUaX5YPvHgQ88NV03E PSvOumRGMaT14EDF9YgAMYKOobTtDNJC/+DTrFc9rjaVcF8pslU1TPqlp2plXNYiPhHnJSIwMhuN D1tXoDnk2dlPELVTZXqzZNPJ8eqj3cdUr2ttaOHu7m7JxqKUqt40opTtJVuIei/rS3h4eI3wpPOj DWfeZ2uQ/wCya7BbDQplbmRzdHJlYW0NCmVuZG9iag0KMjc0IDAgb2JqDQpbIDBbIDc1MF0gIDNb IDI3OCAyNzhdICA4WyA4ODldICAxMVsgMzMzIDMzM10gIDE1WyAyNzhdICAxN1sgMjc4IDI3OCA1 NTYgNTU2IDU1NiA1NTYgNTU2IDU1NiA1NTYgNTU2IDU1NiA1NTYgMjc4XSAgMzNbIDU4NF0gIDUz WyA3MjJdICA1NlsgNzIyXSAgMTM1WyAzNTBdICAxNzdbIDU1NiAxMDAwXSAgNTcwWyA2NjcgNjU2 IDY2NyA1NDIgNjc3IDY2NyA5MjMgNjA0XSAgNTgwWyA1ODMgNjU2IDgzMyA3MjIgNzc4IDcxOSA2 NjcgNzIyIDYxMSA2MzUgNzYwXSAgNTk4WyA2NTZdICA2MDJbIDU1NiA1NzMgNTMxIDM2NSA1ODMg NTU2IDY2OSA0NTggNTU5IDU1OSA0MzggNTgzIDY4OCA1NTIgNTU2IDU0MiA1NTYgNTAwIDQ1OCA1 MDAgODIzIDUwMCA1NzMgNTIxIDgwMl0gIDYyOVsgNzE5IDUyMV0gIDYzM1sgNTQyIDU1Nl0gIDY1 MVsgMTA3M10gXSANCmVuZG9iag0KMjc1IDAgb2JqDQpbIDI3OCAwIDAgMCAwIDAgMCAwIDAgMCAw IDAgMCAzMzMgMjc4IDAgMCA1NTYgNTU2IDU1NiA1NTYgNTU2IDAgNTU2IDAgNTU2XSANCmVuZG9i ag0KMjc2IDAgb2JqDQo8PC9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVuZ3RoIDMzND4+DQpzdHJlYW0N CnicfVLLboMwELzzFT6mhwhsQ5IDQspT4tCHSvsBxF5SS8VYxjnw97W9aZqmUi0BGs/Mzpp1uq13 tVaOpC92EA040iktLYzD2QogRzgpndCCSCXcBcW36FuTpN7cTKODvtbdkJQlSV89OTo7kdlaDkd4 SNJnK8EqfSKz923jcXM25hN60I5kSVURCZ0v9Niap7YHkkbbvJaeV26ae8+P4m0yQFjEFJsRg4TR tAJsq0+QlJlfFSkPflUJaHnH5+g6duKjtVHNvTrLWFYFRCmiPSLkOHKbwLGwGepeKtDvet/xjK+D ifFN+OQ0u6iR53fxjO9QxkMEyxmiFaIVov1tIPsTmMcklm+jmtHoLbCLAjf57y7ofRfFAWXF/0mL +HfYArvky5i0WOImHsSf5zYpDCDck+t0xdlaP9h4meJEwyyVhut9M4MJrvB8AYJEw9INCmVuZHN0 cmVhbQ0KZW5kb2JqDQoyNzcgMCBvYmoNCjw8L0ZpbHRlci9GbGF0ZURlY29kZS9MZW5ndGggMzk5 ODEvTGVuZ3RoMSAxNDYwMjg+Pg0Kc3RyZWFtDQp4nOydCXxTVdr/n3OX3GxNszRtutAkhJbSdKMt XaDQQBeQsi/aIoxFdgUpiwy4gStYUesyzuio4ICIipK2iAVUcEZHRwZcYNRxAxXRAYui4ILQ+z7n 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 WDEhTCqTQN7FEvv/WyKQlcFQuVCtQQVnZi2pLMhPL0osyKjUR6tUWJoYGTJWbn/yLm2vpn2GSunH 37O25Nj43b3xaqPghl/+wpuXSKv48Sc9Odd2drs4e9BMX/4za+Y3LzA1kmjIv3n5BNOvJ9tEZ8x0 52nY63uyWh/YeLKZv/3sau1HxvrbtlU8Ln593+iroMOKsHbB5Ld9zW8iCrOv8O+6OH1P3m+F5cwZ PFduR+85eaq68HXYra9XH2w+9iiXY0repDcpt02t9ffsdLF8EVZ/4xuTQMzttJ5M/kbVNd9an4Vr 2cyqYC2529p5974Ur2p33/P7rx5/PLmsv2BXbvnRqpR84cJws/71bklh03ZvMHhiIrMyeQfX7KhP rz2mrWeT2Bz6VD2A4Z6khMHMdU8cZi8TKj4r2rGwiUnDoIlJBRFHbIZNTKJAIUFwquwbsFYA9hkJ pDQZayCBnCS5ETMrjEDL4TKshvyQUTZDC0MLYwMDgyiMFDll6n7HNVJsKT4hDxg9Qw5NvXjTyRSt vAallRlNSg+jQ/q7lQ4F5GUdu5B22ORemeOGhV2NP8N35aQ936kQ6Hbk+Zt3Gw5sdFC7ebj81tup QWx3u3JWVyV9umvxpvJn/TSmN4c/PnQwPesX/3VSj6GKV+fW+7mGu8KXXF92Tu+NwL7O4uOTZu6Z 7H3E/j3LFv92+x/sT5yz7Gar6J19q+29+0zU/EAmY4MupzeOFsdaqz587kv9k7DtTZTf4Y9xnoHv ZsnNShXT/SOX8GXDrruXP5r/+nnxnEnUXc4cHxEv0wuFogo6p3NS78zaXFHjqztXdWFN0ooH88v6 P8l8N9VjDAnKvnQkyIf78/NOBp45nf82bznzR/nkCqv0datnvmuZe2Nie8rxvOcMAL0ieLUNCmVu ZHN0cmVhbQ0KZW5kb2JqDQoyNzggMCBvYmoNClsgMFsgNzUwXSAgM1sgMjc4IDI3OF0gIDE3WyAy NzhdICAxOVsgNTU2XSAgMTc3WyA1NTZdICA1NzBbIDY2NyA2NTFdICA1NzNbIDU0NF0gIDU3OFsg NzE1XSAgNTg0WyA3NzhdICA1ODdbIDcyMiA2MTFdICA2MDJbIDU1NiA1NjMgNTIyXSAgNjA3WyA1 NTZdICA2MDlbIDQ2NSA1NTZdICA2MTVbIDU1MCA1NTYgNTUwIDU1NiA1MDAgODMzIDUwMF0gXSAN CmVuZG9iag0KMjc5IDAgb2JqDQo8PC9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVuZ3RoIDMzNj4+DQpz dHJlYW0NCnicfVLbboMgGL7nKbjsLhoB7ewSY9K6NvFih8ztARR+O5OJBOmFbz8OXdt1mSRKPvgO oF9UlI+l7AyOXvXAKzC47aTQMA5HzQE3cOgkomssOm5OyL95XysUWXE1jQb6UrYDyjIcvdnN0egJ LzZiaOAORS9agO7kAS8+isri6qjUF/QgDSYoz7GA1ho91eq57gFHXrYshd3vzLS0mgvjfVKAmcc0 HIYPAkZVc9C1PADKiB05zvZ25AikuNlnQdW0/LPWnh1bNiGM5B6tA1p57YlFfzSXiK2nkSKw1yf2 fxH7QCt8BKUB7eYjaDgXDREx+RVBbyO2zpQ50ZwpizfOjSXMTQmdN2VJEmiba9P4j2lyH0x3ge1v yVYhKfW3SGL/dVm6CoupX0y28/HpQ6Dtr+PdH3XFO9eFH7W2TfHt9BVx5egknAusBuVU7vkGdsrf Ug0KZW5kc3RyZWFtDQplbmRvYmoNCjI4MCAwIG9iag0KPDwvRmlsdGVyL0ZsYXRlRGVjb2RlL0xl bmd0aCA2NjI5MS9MZW5ndGgxIDIwOTIyND4+DQpzdHJlYW0NCnic7J0JYFTVuce/O3f2fcksmUky M5lM9o2ENQSYrAQCgiRqQq0kBAQXSipg1WLBWluNWm31We0idIFalzJJ1Ab0Vbq6oAJqFa0VFFxQ W6mtbbWUef9zZpIMSg3Jc5q2nN9w/mf7zr1n7tx8OV/unQtJROSBKGljfcuc2csu975OsutCIu+L s+sbGpc5VpxGitPqiRS3z164oOXTxwa+QYqFh4h+9O7sljNqHzAudJHig31EvovmtrQ2rio8T43x 87DVrHmtLU0z779yKVH4z0Smcxa0lFU4Wi9Zj21p0d+xsG5ea/vTVxzE9o2oTz6zfn7baaGVXySq bCWy3dy1qrO76DljH0lX3Ugk27suXhs4Vv7SEZJuDxBpXji3e8WqX2zNlEi6+gdE6gkrOtd0k4d0 pJh/FNuzrrjw0nOvbBxYQtIW1C9Trly26pI/HzXMIqp/g6TIHSuXdy47dPToL4mk69j+V6LB/o4J +5LQRjkrV6295J63ba9jviuJQj0XLL/oM4cth7H9qgEi7eYLV3d17svb8XlSYDrkvX9V5yXdjnes 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 uU/fz336fu7T93Ofvp/79Je4T3+J+/SXxtGn35rw6c+Pyafv4z59H/fp+7hP38d9+j7u0/dxn76P +/TnuE9/jvv057hPf4779Oe4T3+W+/RnuU9/lvv0Z7lP/w336c9wn/4M9+nPcJ/+DPfpT3Of/jT3 6U9zn/409+lPcZ/+FPfpT3Gf/hT36Xu5T9/Lffpe7tOf4j59L/fpe7lP38t9+l7u0/dwn76H+/Q9 3Kfv4T59N/fpu7lP3819+m7u05/kPv1J7tOf5D79Se7Tn+Q+/Qnu05/gPv0J7tMf5z59F/fpu7hP 38V9+i7u03dxn76L+/Rd3Kc/zn36Lu7Td3Gfvov79F3cpz/Gffpj3Kc/xn36Y9ynP8p9+qPcpz/K ffqj3Kc/cgr59CLh04VPP2V8+m3/L5/+XIp8+jbh0/8FPp1dwibT2QaXjmRZqeIPr1Aq+V9qSD1E 4s83Wo2GNIlrznrU6EPXn1WkUqmGahimHCykgJRs9FRnLLcT4KxQazV6tRbnhl6rRRWS1K9S46xQ aZRq5Bp2NqlUapbDSIPThZ0wqn+27dShOHlTTepmccohGVzjPQWBQCAQCASCVGP0DMZW+o+JrXRs OZx4dqCRdCeKrdRJsZUmEVupUrI4FbFVCtCNZYxGi5dBrcPJYNTpUNXqkrejQjSlVmlV7ERiMRUC Kg2rwUiL04V9jv/esZW4f/2TQ2H0jPcUBAKBQCAQCFKNyatnsRXWuYaPia30I8RWasRTwyGPJrWx lbiakALGElvpWTClMWqSYyt9Uj/OCRZJqTQIrHQaoFZpWE2vJx1OLXbCjEOcLJ+8qYitPjkUJu94 T0EgEAgEAoEg1ViyjAip2A19JsRCKrb0VJJmiISVgS2HefjF7AxsIX7cYlxDw7Y8tlINFlKAWPGm AMNYxuj0eJm0BtKTyWBgVUPydjTa+D2D7ETSJ04oxFhaGOkRirOT4987ttKPbCI4SRSWrJGNBAKB QCAQCP6zsQY+FFsp8dIOkbAy6A1DsZWZjCeKrbTDcRSGidjqP4yxxlYGnRmxlYHMBqMBFUPyf3is 0WrV/J5BnUar12l1Wh5b6VhsZYh/gW88rkGK2GpcUFgD4z0FgUAgEAgEglRjyzYlYitz/NkTLLbS DZGwMrBLDex2QGAhI1tzfii2Sn6KgU6buB6hTUkYNJbb1wQjYBzDGETceqPeojMitrIYjUa9QWc8 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 pvCFvmsyzcdrZptPxdpfzVzz2Zr55gs1C81Xov5B9gc1xea7fP7G+hfqT2d+wOtWmB9F7Rz81ZjM TwlcblWWizX15nFOWyxXTQ2WG2SvJpvllqnVcs+0zjJmslse0zX386hvKoFPVNagr9LldN240Zfs p02ByT6i9yOWZ6YttexLuniRbe6eNre/zl9Nvy/LyLS9Vm3aVZuq8E2yNe2pzYiVVZSH6hf4IZKn 1RJPiK5rip0o95styTUdlnSODZbMGpdldux6WuOzzJ2y3sasszVhy/zp61vNZstCrgsFSjvbLAU8 3WnR1vRbimv2WXS8nxeg5oClgsB9mZJ3yGKKzmF5La0ZstTXHLVYY31azQlLMx/baUvHC9dlsr1z lg00XhpjzUWLK9rmVYsvVl41NyzhmluWzTX3LNtqxiw7ax5b+mueWfaZmOWASW05ZEq1DJkyLEdN WZYTU9YOZe7FpspaMt0Pvyidbl/V01Iln/z+7q+wpxetRdPXJNQ1Fcn2+lXlYtZTXi5mLnN7pXkH fSsp35tQ+nXj/EO+ltK98l5DSZV5Y5w2j6avf8p+BNem8qlpdG8jfnkcX1pvvym/8v3oWjl9XX3R /mO6PuW5Fe2PfBrk/YPTPzj3pb0t9TdQm2XKsZw25VrOmQZrc0yHa3On7BmpXQKNmdoars2LzmGS V+z+WJl/yj5E5sd0rDaf1gnTydrC6Lyn/DO1RTT/YuubzteWRPmb3jbaNV2qLed1r8XMrxj/pPii 6N6ZeB6trYrK4natRfHvpvu1DVG5yTybHtbapuyHZDmahVr7FB2TfShrItV7Uttqel67jp7iE/88 8VPGUhbxvyD0IOUBo7+qOe8/9v1KQhyb4O9Rmvh7lI/UJ9WfqXbyNyi7+RuUAf4G5RJ/g/JL/gbl H5OCybOEEv5e5Bp/L/Jz/l7kC/5e5Jf8vciv6b1IXDa9F4mbT+9F4t6i9yJx+fReJG4Rnmj3s4OT bw+0Raxca9E2aG3aVu06rV3rXnpXG9BGtFu027W7tHu0RdoBYFB7WDusLdce055cehclzmjPay9p r2lHtbe197UPtU+0z5cLyxOXpy2ftTxbW7J8zvJ5yxcsX7x8qbZq+YrlpcuNy6uXndaW8KMKRxE/ yvlBVyUcRAP0JiBxFX0/Oe3Z1guN+FkQT7WHcSzjz7la9hN2CU+yV3D8keofVOfYiviL8ZdZMb2v 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 Ca/HKjnvDegXJa3zY7HHRkmbJW2VtMP/zTyv5dslXINOZUzujNXP04l11OX32CVp35d9fdLY/LpY azJfnXBeUlsOSjqSwBff9jje2FdNbfiSLs07EKS633VxUvf7sKRjQaqROtxYo+tpj+QE2cRrk9rY Ival61uP1kFf1KU6PRnBOVtSR0mdYl+6NiWmHl39RAzV8Xol+De4lvboLalP43b36Ofb2+OKhDY3 SSrbo9Rvr7axx+AEncMa+6vHaEnlkiZImiRpiqRpkmZImi1pvqSFkh5vcu3IO8n5BH110vg81Tku cuJ4+qbXpK+0o+kYTjy3C/q7yflfmmvr5pKE85fGz8mu/193/pr2fGt7v+qaeSr9mte4/rq5qbR1 47ivO8eMxN1SScuFDklKCeqtTqjHDtosumLpsYYxnBZrvD6uG391a+PAnlibGNeJWGasYdwrP8cf f4nlY+cl2NdUt+iNdU7g1Y3HxPmpbi7KbbAh1r0hP3ZRw/weuzTBb4HNsXiTOAn8GCtr0seRhrFI uQGSSmIj9L0n/tq9+d9zr2nN1L+GblKsNNPbmNw5kh4xJmeBn3IXyXmxnJdIqpS0QtLzktZIWm9M 5gY5vxGkNwO+yGWubkhtp/hyyG7zZZWf+56kPQF/v6RDko5+i1Tt66lLdfrOsX37z4kEuiWdk9ZY tkm53rnpuW1yM3Nzcs/L7ZzbPfei3EvliOcOkN8lcgzIvVp4QzhG5Jbljsu9LfdOoQfkTs29L3dm 7pyzd529K/cRRT37VO4icMkZY9p2bNsxt1L0XZ0bP2N87go5ns9dk3BU6rueX37Tly88uHzboRXf cGjNNxza8vWGDL7b0J53fLN4x/e/+FZDF77S0JXvM3Tj+wzd+TJDjC8z9OSbDN/9j9dnWemW/9bs 8+Z8Y84uNeb09X46e7CkYZJGN/BOls4ulzThFOQmSZL4O3ua/zsn0iR/xtfrCNL5OXtzDjQ5Drcd XU8fS+Tn1NTRCRInPPSLcLzJbfiCh//tDo83uZN5kzuVb3e04XsdGXypoz3f6MjiWxzZfIUjly9v dORrG+fynY3z/r/ptUylWdHwDKjDbNM/u2urGv/IvkJSr/pfvbP7BBQSfk52v7r8uhKCpdml9Zyu ejTOr9NXp0s11ekJNAinda+6cnU1686hPUd8EbIX2i/ItP6y/arJtF+z95qzQreGbjXf19nTFDR7 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 7oAV8xusjCbuqO8+PpfrOrs5JFPjJX2hbmZ85HjWEEl5qet35Te9cziaEFFjYtb1aXHepdFhTwsz 1k2psPNrfp9T/+vQWTEGr0q3GlhSM5RiGh1VU9X4r7nnjOua3Goef3ox9+CjneVZVkcCGqZqDdbN 5joEr5w6ztNN/nhNTZV/4vntrt8X5GgsKFKgE566Dp6odL5IU+Oq2zOjZ3VvvS8ZN982X+Cna+it HTXuedirXQ82F16wTz+Rq5dFyb7M1qjfyj+lF3qoOsVxWUl2dG1aidyu+l+9Xg9O/7bcfMqBP9pG n1+p1ZhwolBlyeA4tqPJ/rGrj3RqPD5YdSG2dmYoanYxDapYV1U2c29N8YbpSnfWLpGbrmlmXi6e Vjx+pU598atFFzRudasGNm55OerhB1Z8+jLu3PPJ55+kPd+98QrP4LtUw/jI2/7DS25/NityMh2j OLlRbsc3Hp/DSJizm81i0Yzc/nfj5Z8/NvnzIXJx7lnBcE0YvxKQhwc+oWYq8GeKy5OiBx5VEAwG f5zI4TFQcpb3322eN3dJd63CB42gabVVdtlVdNyAUzAvjA4tNlygD/xBMogFmSCdPOROAFlAHYSC HJDBpBKZ/dGMlQRySnQXaP9DsWblZKQnZkZnJOWY/aVT4fBZIKjwyGZz6cV2n17buH2+rnrSNqJR redMS8njs7HFVfaVN4+mIW7E3Z3ce1nXXKVWX97svcO0RXeC7zfl3z9nnqzmT1G8c8cj6J2Dq+fk FrXNVlPyFi8xWWsnu337zVFsv1LztGPVaEzjjkdXXIv1Y79dnVBwuVXS9eTylKIj4fs/ip/R2rjw S1TtPtZmQ85h1w8j6zLMJvkHGWMnp6jjO9J12ldJvV8+/VR2y8p496G+M8tmiucX+ET+MlrfeN8Q VmbNOhfDN79f4emO+L3i1MqOD6EFbcP1l8cFdu7K4IdTrct283k3drk0qK73GtoyFb7box3oPiHb /CLIKju7sap9cuT7voZj8tkbSvhsfZrP1v6zjSgen63A7JIlUbnqfzYK+PkbiQExOYEeOjAkuX++ WWExFxcdQTzp/qdsPFuerQVN88b9XUT2BdVOSC24rFfkd33LerOeyRvs2lP+wmtBrHhFzbxYN3dF 4g51aJR1pP6a+9ztp4fvfN7VuuHyq7y89JttLSrS47pG1K8eQWdEKX+9Ff5R8lXZ4eaFSyVfZk7Z H2I0/1E3WBrg/1mcc+q657NGiXc1vSl/tEU/7HL3lLt7zpQ/37pB1YIdpnJ63suZvdfwwef3N+6e vvbSDHWbGjhbtn1mUfH9GcdTk34riXVu+624jgLhMqnKaO2pFw1Gpb3HPDivMw7c4O0tbjR6sf9b wpi6slav5uFDtMMlCy/pHlr4YWOt/on355BHw8OXDRwX9azht5XXDZf2OKdzd6TDb0Urx+yxTmgq /+VOoHhofZN15v2ws2pOx72r2D3+ke7Kv+++Xn23HPwfUDG+Jg0KZW5kc3RyZWFtDQplbmRvYmoN CjI4MSAwIG9iag0KWyAwWyA3NzhdICAzWyAyNTAgMzMzXSAgOFsgODMzXSAgMTFbIDMzMyAzMzNd ICAxNVsgMjUwXSAgMTdbIDI1MF0gIDE5WyA1MDAgNTAwIDUwMCA1MDAgNTAwIDUwMCA1MDAgNTAw IDUwMCA1MDBdICAxNzdbIDUwMF0gIDU3MFsgNzIyIDU3NCA2NjcgNTc4IDY4MiA2MTEgODk2IDUw MSA3MjJdICA1ODBbIDY2N10gIDU4MlsgODg5IDcyMiA3MjIgNzIyIDU1NiA2NjcgNjExIDcwOCA3 OTBdICA2MDJbIDQ0NCA1MDkgNDcyIDQxMCA1MDkgNDQ0IDY5MSAzOTUgNTM1IDUzNSA0ODYgNDk5 IDYzMyA1MzUgNTAwIDUzNSA1MDAgNDQ0IDQzNyA1MDAgNjQ4IDUwMCA1MzUgNTAzIDc3MCA3NzBd ICA2MjlbIDY3MiA0NTYgNDI5XSAgNjMzWyA0NjBdIF0gDQplbmRvYmoNCjI4MiAwIG9iag0KWyAy NTAgMCA0MDggMCAwIDgzMyAwIDAgMCAzMzMgMCAwIDAgMzMzIDI1MCAwIDUwMCA1MDAgNTAwIDUw MCA1MDAgNTAwIDUwMCA1MDAgNTAwIDUwMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDcyMiAwIDU1NiA3 MjIgMCAzMzMgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAg MCAwIDAgNDQ0IDAgMCAwIDI3OCAwIDAgMCAwIDAgMCAwIDAgMzMzIDAgMCAwIDUwMF0gDQplbmRv YmoNCjI4MyAwIG9iag0KPDwvRmlsdGVyL0ZsYXRlRGVjb2RlL0xlbmd0aCAzMzI+Pg0Kc3RyZWFt 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 g062vxNWoqcupsmbLp45LuZ0sR9d0PA3wNRLG8bYC9wSsvHn7UO6j/kWKv1rYqzjT+FULun41wlM UrxG64RDfKDRepEpLmu0QSRJ5RptFDmSTaMjRNugHJOYLPZqdKTYJD2h0dHyTnkkfe7zv6n6fRot iVj9BY2Whd4wU6N1YprBqtF6kWDI0miDiDIs0WijGGlYpdERYtagHJNIMkRodKS439Ch0dFSheEX kCzpdegrJiJTo/UiN8LEtAH15oglGq0X2RHTmDai3hixQaP1IiOilukIslvEHo2GrSI2MW1CfVTE qxqtFzkRe5mO1Oyv0qr9VVq1v0qr9ldp1f4qrdpfpVX7q7Rqf5VW7a/Sqv1VWrU/0WYe+3WNprG/ y7QF9fGmTI3WizyTapMo0s1UrdHQx1TIdAz9RUDTYxqtF5NNDqbjWE61RpMclX842dB0UKNhQ9Mu phNIH9M5jYY+psNMj0B9QmScRutFgekS0yOJP7JEo8Efmc50MvO3ajT4IxcxPYp8GrlHo+HTSNVH Y9inezSafKrWpzH/KY0m/n1Mp5NPI69rNHwaqdotm+xjztBo2MdsZHoiyTFXajTkmHOJNoXZ3xRm f1PYuExh44oK448K448K80vUgF9+IqwiDzNgiigAVSXsoh55hXALF0ARfuHhmvtRagVNuA71jcyR iydzMPccyBehbg3aK8LLpXrk9eBuA7aBswrPnVxrFZXI25nLjbo6SLLiKT2pAyjchw089KxVNKPO LRr+Q/rdyll4Rz3mgnag90KxhPX3arKsODfkwk5TQGVCbqNYjaduPCfdFJF1W36y7VCPan9DvS0U D4mJgz1WgPPLI6sapEp4bO2Q5oKlreIB9NvAetDTiYCH0I7kOlDj1+zUypYlqTmoWcL8CtdbRTnb lyztQp0VY5uJk1KeWIbnPpRJS5LjY1+SZ+yanxpYosIeo7KHx+7EUwWJPG4Vq7itovlsHs5F5Zgt atvWsCcetqMNvaxmiY1svXbuazXw7ftVy8S7GuP18ShszOsGtvFzD56oIyCr2LS+GjUJqzVZ6uhp Llu/NHI3W9PPPm+Ej608K1cN9nU7vVxfkv31rTQk3Tbo51aeOwprvnpwbt9+9GrvX9ZrVpgNaCTq WBTub2DVkHx1rDbUtPPI3bwSbz9S1dJ1N1m1nj3r1rA6KpX2oeRhbGVt2wZnriqHOB3g+Js++ok1 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 CGqwWcu3afAkYKcGRD+NNueQ79HKTwrJka3mLR8hf16DXsALgBdRfxH5Ea38ihAdrRp0CKljHfJH uTxC5IhCUSIqxVKxir/z2iC24sSyW/SIXpxXjolT4l2cVfolk9C1zG7JaylpmdEy34kzh+cjz8Wm K+5VoD72nG+65PaA+sDzrudDdyWoNz2nPGfdNaBOeI659zRRi8Oeg+5dntOgXvD0ure7M0Dt9fS4 N7sLQO3z7Havc8eD2uN50q24raB2eba6m1z9oLZ7Nrhr3VGgNnva3EtcH4Na53G4y13XQNnxdK7r IqgVeDrDdV7oPfs9z3ie8PR4dqCPXY7rqOnx1IJuwBOHs6cpCdyTPdlus2s3qAyPtX2048T/tllq 4O+BBH8DJBnXGb8lIvm7kGH8TcZwzKskKci/av4ifCBc8K8LvsQYhOsKfIazmOs6crMQbhzL3Djp YvQC9lHLSRrgvOxOB2RrMFnLp2lQBJirAdFlgEqNHoAqDaoBtYAGgEOjMWfaUjTAqbkth+mc5qLm uc1lzXM9K5orPbbmKqRqhlo8qW1uaHYgtSLvAF4HoORofhT0VqYoPcF8AN/lRpPvmq+/kb7dGwb7 X8Zx+or8qZDlz+ALPfvCyL6IYF9EwRczRbRh1qBH4uCRB0Wi8SH4ZRT7ZbSx2lgtUuGX50WaZS+8 kw7v3BD3Wvrho+z/iz1Jolgo7OtcnESFEyc553YATnBOnNTWfIgcpzUnTmdKoTA1FTYVr/EAlzaV rulV+Hwv/1X+KzS9Kl8VkqHQUChk4yLjIqHD3Fsm9MblmIEGy08tPxVGyxeWL0TEf6iNFNPH3wHY xOuSXjJLk6W5Uq3UKm2WXpfj5PnyZnmbvJ/Ti/IR+XWkj3RmnVWXi1SgW6Gz6/bqzuqu6gt0Zv18 vU3fpL9kWGGwG7YbdhkuG2cYG4wdulzjM8yfazxl/BDpk4hpER0RvaZ002xTmanN9JTpddNHkXJk QeT2yBPmueazFtlitWRYcizTLB7LTsvLlvejoqLmRtmiXFGbo/ZEnYi6Hm2KnhZdFd0ZvS/6cowp pjCmOGZ+jD1mW8wuWJzu/NKN35mAQkBRaL/0l9Dj0ueAfw89LkuAyNAZ2RzaL8eG9sNLdDM4ku8B 073gmf3X0G4M2pWIZShXA+g+74EQfV+iQ4tYPKFbvXQfOEJrV4L+StCuhNvVoO5AqIT5H7+J38C3 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 YjceDFWJqDDKsygvKqcOUpLV6ntVkPNU08NvXPpjzslFuzuSkBzIvwC50AV0DQplbmRzdHJlYW0N CmVuZG9iag0KMjg1IDAgb2JqDQpbIDBbIDc3OF0gIDNbIDI1MCAzMzMgNTU1XSAgMTFbIDMzMyAz MzNdICAxN1sgMjUwXSAgMTlbIDUwMCA1MDAgNTAwIDUwMCA1MDAgNTAwIDUwMCA1MDAgNTAwIDUw MF0gIDU3MFsgNzIyIDY2MSA2NjcgNjM2IDY4OCA2NjddICA1NzdbIDUyOCA3NzhdICA1ODBbIDcy NSA3NDUgOTQ0IDc3OCA3NzggNzc4IDYxMSA3MjIgNjY3IDczNF0gIDYwMVsgNzIyIDUwMCA1MDAg NTQwIDQ1NCA1MDYgNDQ0IDcyNSA0MDIgNTc2IDU3NiA1NzYgNTYxIDY4MSA1NzYgNTAwIDU3NiA1 NTYgNDQ0IDQ5MSA1MDAgNjkyXSAgNjI1WyA1NjRdICA2MjlbIDc4MSA1MjldICA2MzNbIDU0MV0g XSANCmVuZG9iag0KMjg2IDAgb2JqDQo8PC9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVuZ3RoIDQ2Nj4+ DQpzdHJlYW0NCnicfVTBbqMwEL3zFT62hwrb2JBIERKQVspht9WmPa32QMBJkTaAHHLI3689z9s2 iRoksOZ55r15mCGuVstV300sfrFDszYT23Z9a81hONrGsI3ZdX0kBWu7ZgoRPZt9PUaxK16fDpPZ r/rtEC0WLP7lNg+TPbG7oh025j6Kn21rbNfv2N1btXbx+jiOf83e9BPjUZ6z1mwd0Y96/FnvDYup 7GHVuv1uOj24ms+M19NomKRYoJlmaM1hrBtj635nogV3V84WT+7KI9O3F/uharNt3mtL2YnL5lxy yg548j/rkzSjND5DtsoJLAFWAGcECkGR0AAfA+838gKEif4qL6/knSCxpbQoQUoyNFMA1LeVJLpU 869K4kop4WgIr0Utz0iTS9IELrWkhhJ0ojOKFHpOxW1BFTzBTJqcCcpLQQWJNEjAU3rmaX4t8Yi+ 4CktqVaH1qGbwUExp6hwKr/9igMuy/yP3y1BUHpjkovKl0iYlsnSL0pwAuFdKg2wAJgBnAFcAkQ5 nCiJck2HIN1rJTC9ebJSp0irbn7CUpM3mQXSJ1LKNEBQqBLgDOAc4Pkn7GfKj/7HwDZHa92s0v+B htSPZ9ebj1/IOIy+yt//AC+IN/ANCmVuZHN0cmVhbQ0KZW5kb2JqDQoyODcgMCBvYmoNCjw8L0Zp bHRlci9GbGF0ZURlY29kZS9MZW5ndGggNTc3MTMvTGVuZ3RoMSAxNjg3MTI+Pg0Kc3RyZWFtDQp4 nOx9CXgbxf32u6vVfVqHJUuyJUW2Zcu27Nix4yROIl+JE+d2DjscsXNAAgRSEgK0KQFajroU0kJb oIXQAi1N2qLYlDpAS0ov7ptyQ7habugBbTmy/9/MKrJDCqZPHfJ9D/NK887125nZ0Xjm3dWODAmA n0jBhrauWTOf/PbaxyGfVgkEn5rZ1j7jjV+9uQ/SozcA0rszF8zv6r3jBRekx38KfOuZmV1LWrZf d6EK+YQLAOuVcxZ3dcyY2zoeCLUB5n3zu6pr/5q3vZGO/RfV0rugdc7ijXuaz6bytlC8YWnb3O4l E076DlBC9nmXrFrftyEzactmSKVnArqVqzZvii5ec+wxkJqoDEPmmA3Hrp+1vWompPIXAf37x/Zt 3AA3zFTeCVSe69gTTj/mrWe+ezWklpeB4wfWrl5/2hPfXjJEVT0GvHXd2jV9q/duv2KQ2sPrX0sJ jhr9nylO54fites3nfb8L0svBuRuIPDq8WtOPjH5Xv2PIN12CdX/wxNOWtV3yYNb7oX08+8DnnfX 9522wfl929/peCof0RP71q+pad55H6Q7qL0Oz4aTNm5Si/AotW8Oy99w8poN76/dm4RUvRewLQPr e31d3e9/vNO+wtn0jqnABIarF97awPz7TumreP/cDz60RkzF0LHzhAbyjdP2zUOrZcf75763yBpB DEaMgPwlZmN+D43Qo5aOleFCNZZQdbVUr0y5su5h+RbKNekv19ehSApxf7nuARwju0162WpUZFk2 y8peWFTgtFatXmDx3NYo1ReNFuof2rdQqjNOkwbSkG599p80iEr1u9mZQjFkGytPyrodOEN3l8TP S9mI5cZC3MRP5S9SA+WdJ+9Qe/ER0HHL5Unqj8n+q+T+Tm7L/jwKn/1R+0+C/o/qK/o/YhG523h8 KRYrL2CBYRJ+QWk9VNfMkfaGHeii9CMpf5Bsu7QysJzX/QLe3W9n/Abe/jT1U3uPzPpfouNPJ//U bFnp7LkuyubPpfAC6p9ZlLeU3BblBfUdlqcrRAvlV1F/XU7p24bLVh+idPt/0x8CvK+vI5ca1Y7G MjnjaHaHGvvHSC6+Az87XG0REBAQ+LyD64odOJJpC+UVHPFxdspr6NFvVZ/QjkEP0xU8vJTrjNtG agqe/ghplR2S2fgIeg5I3zG8BugfUf/EdIXyD9JHj+BspZ30wd/wRaYt9C+qdys+hJlO4M6BTuU9 9V79a1hAth2arsB8pi2YJuF6gzSE0UvlkJ7QV+B8ZQfuovRt++szUJuUPZpOMrxG4RvVx8akEwUE BAQEBAQEBAQEBAQE/r+A+T2jJEkFbpg+xIeGS1iSiYG8EVapVAqmsDHVQeEPU8UOpBADnLn8IHxh E8Ioh7utJpxIwFvtTwI1o96g/m9gys+FTJ9kx1AO5L5zEjhEiEkF2T72mxEuhiNKgwIF9gLwzi8I JgrsbskxPpl02YMFiXDCV5NK1Lg8bsqTII3p4BAQEBAQEBD4L6CDTmLQ63SSLEkI6F+37sG/TCoJ QJO6D2aYiS2crbAS22BTP4QddmIHZyccxC44ifOIP4AbecQeuNX34YWH2Mc5H15iP3zEAeSr76EA fgoHEaBwCEHiMOdChNR/o4hzBGHiKAqJY4gQjyP+F+KIEhcjRlyCccSlxP9EAnHiMpQQl6OUOEn8 LiqQIK5EGXEVyolTSBJXo5K4BlXE44nfQS1SxHWoVv+BCZzrUUPcgPHEE1FH3IgJ6t8xifNk1BNP QQNxEyYST+U8DZPUv2E6JhOnMUX9K5rRRNzCuRVTidswjbgdaeIZxG9jJpqJO9BCPAutxLPRpr6F Ts5zMIN4LmYSz0MH8XziN7EAs4gXYjbxInQSd2EO8WLMVd/AEswjXor5xMuwQH0d3Zx7sJB4ORYR H4HFxEdiCfFRnI/GUvU1rMAy4l50q6+ij/NKLCdehSOIV+NI4jU4ivgY4ldwLI4mXosVxOvQp76M 44hfwfFYSeETsIp4PVarf8GJWEN8EucNOIb4C1hLfDLWEW/kvAnHqX/GKTieeDNOID4V69WXcBpO JD4dJxF/ERuIv4QvEG8hfhFfxsnEZ2Aj8VacQnwmNhOfxflsnKq+gK/gNOKv4nT1eZzD+Vx8ifg8 bCE+H18m/hq2qs+hn/PXcSbxBTiL+Bs4W92LC/EV4ovwVeJtOIf4mziX+Fs4j/hi4mdxCc4n/jb6 ib+DrxN/l3gvLsUFFL4M3yC+HBeqz+B7uIj4+9hGfAW+SXwlvkW8HRcTX8X5B7hEfRo/xLcpfDW+ S+FrcCnxtZx/hMuIf4zLia/D99Qn8RPip7ADVxDvxJXEP8V24p/hKsr9Oefr8QPiDH5IvAvXqE9g gPMgriW+AT8i/gV+THwjrlMfxy85D2EH8W7sJL4JP1Ufw82cb8HPiH+FnxP/GtcT34pdxHuIH8Vv MEB8GwaJf4sbiH9H/Cf8Hr8g/gN+SfxHDKmP4HbsJr6D8524ifgu3Ex8N24hvge/Ir4Xv1Yfxn24 lfh+7CF+AL9RH8KDnB/Cb4kfxu+IH8Hviake9UE8ij8QP4Y/Ej+O24mfwJ3ETxI/gKdwF/HTuJv4 Gdyj3o9nOe/FvcTP4X7i5/EA8Qt4kPhFzi/hIfU+/BkPE/8Fj6j34mX8ifgVPEr8Kh4jfg2PE7+O J4jfIL4Hb+JJ4rfwNPHbeIb4r5z/hmfVu/F37CX+B55T78I7eJ74XbxA/E+8SPwvvET8b/yZ+D3O 7+MvxB/gZfVOfIhXiffhNfUOqJz/9zndJeb0wzqnz+Fz+tyPmdMX8jl9IZ/TF/E5vetj5vRlfE7v 5nN6D5/Tez5mTj+az+lH8zl9BZ/Te7Nz+isfmdNX8zl9DZ/Tj+Fz+jF8Tj/2oDn9OD6nH098Cp/N N9Nszub0E0fM6Rv4nP4FPqefzOf0k/mcvpHP6ZtGzOmn8jn9VD6nn8bn9NP5nP5FPqd/ccSc/mU+ p5+RndOf53P6859iTn+Oz+nPjZjT9/I5fS+f0/eKOV3M6Z/bOf3fYk7PzeltfE5v53N6+yfO6bP5 nN4p5nQxp4s5XczpH5nTQTMuzB9YrSbodDo9DOQrCr9XozMYDIBhxO0b9lWd0Wg26ShsNZlpLWD7 qay5fCMMRgOxAqNiMRqN0OsVMtAbMIYw5DaYGEYtV8k6gUMIGhXZj8RII8IMLWoysXHBvtqlgUDD wmRgHosYDRaDWU8MWIywjOngEBAQEBAQEPh0sNnMJPYUEm7WYe3H1NsBm+XNbGU3ms1c+5lJ+5lZ ti2XbwQ7xAgdjDor135Gpv0MY7od2PhfaD/WUKH9DjHMOe1HlwZmGiFmFjWbs9rPbOQwk/YzmrSI 1WilmFXTfod9r7iAgICAgMDnEXa7BYpygPZTlIO0n4VWdrPJwrWfzWxh2o8W9+Ef0iHdRzLARHLL pNjYTUK9QTGNVGtjgeHSRi9X3Pf7DGBhVwEcdGlgtsDEo2YzGxdmpv1IG9IVg4F5FrbNw2ijFzG7 eQyr0H4CAgICAgKHAU6nlcSenoSbHTq9niUpykG7Ma1WK630NivTfnarzQIrW9wduXwTX/fNXPs5 zCQUDSa9+dPsmvxvMFza6OUy3acfy8oFDgaNCrMWIuFntcHCo1Yr26Vr5Q8HmGlYWI1ms9FspVFh NjlMdkohbWg3wz6mg0NAQEBAQEDg08Hlsmnaz+wg7ce/S1UUpt5gHmFlo5XdarHZmJxy2GxW0EI/ 8pc42Pd9Zq79zIrDYiHtZ9Zb2C2gsWyqWWi//7dgs1otWshCI4JGiM3CU13g2s9mtpjpbTNZLCaL zULDwuQwOyiFrhkcFjjGdHAICAgICAgIfDrk5dmh1zPt54ROe45Orz9Y+7GV3WLn2s9ps2e1nyuX T7ovq/1MmvYzHlLtN3q5TPuJvQSHGDQq9ms/G2z2/drPlgf+LKjNbLWQ0rObaUBYufYj5eekRNJ+ Tgt7CwgICAgICHzm8HgcJPYMZlhdULS9GXo9+4p3xC5ewGF3wG5zOpikcjucdjjY4u7O5Vtp3WeC 0ACrwc2EoslqYE91WTGGGC7NMqpsMEBov0MOh92e3e5Dws/hhN1h46ke8GdBHTQmLDarw0IS0eag UWGzuq15lEja0GVlbwEBAQEBAYHPHD6fCwaDwQKbB3ptD4XBwNTbiF28gJNWdofd5WRyyu10OeBk i7s3l89u+9goyQCbwWu322GyGe3sFtBYNtWWEwuja0rWULGX4BDD6XRkt/vQpYHTBXZRwFJ94M8D OG12u5WuGKzMc9GosNu8Ng+pQNKGbht7CwgICAgICHzmCATc7PdZrLB7odeeozMamXobsYuXPRWY B5fTk8cklTfP42K/2wr4c/l22PnNQCPsRh8Tima7ycE2EY9lU4dLG11T8h+aG8vKBQ6GK8+VfeST hF+eh+Is6s4LEOdRwE5i0Gl32xwOm9NNo8Jp99m9dpeDtKHPwd4CAgICAgICnzlCQS9MJrMdzgAM Zv5dqsnkdDpH7uRg3wx74Hb5vExOBbw+NzzsYb+CXL6TVn8nJRnhNBa4XC5YnWYXuwU0lk0dLs0x qmzgPzQ3lpULHAwaFXlaiISf1wc3XRTQtYEnyPIo4MxzOfKcXoeLPK+LKcUCZ4ASSRv6XewtICAg ICAg8JmjMJxPYs/igCsIgyWr/Zh6G7GTg5Zxnxcet9/HtZ8v3wMfe9gvlMt3weV2UZIJLlPQ7XbD 6rK4+e2gMYQrV9rompI1VOwlOMTw+nzZRz7dXvjy4fGyqM8XZkxvl9vtpCsGJ/N8NCrcrqAr6PTk kTYsyGNvAQEBAQEBgc8c0UiA/ScGJ9xhGLXn6Mxmpt5G7OQA8v1++LwFfnYrLeQv8MHPbuwU5fLd tPq74YUZbnPY6/XC5rayp7rcGEMMlzasAj8O/IfmxrJygYNBoyL7yKc3H/4C+Pxsl4ffHwF/HsDv 9nryvO6Ay+NxeQMeGhbuML18HtKGIQ/CnsPZdgEBAQEBgc8rYtECpv1cn6z9AoEA8r3BAJNUhf5g PgJso0cklz9S+xUy7Wd3W72HTvvljXrLSGi/zwABf2C/9vMjEEQ+jwb8UXDtF3CT2iPtl+f15vkC Xqb9Cunl8xQCYS8KhfYTEBAQEBA4DCgpDsNisbnhi8Fk47spLBafz8e/tcshFAqhwF8YYl+jFoUK CxBii3s8l++Dz89uBlrgs0T9fj8cPpufff03lk0dLs0zqmzgPzQ3lpULHIxQMJTd7uOnEVGIAh4N BYuJgxTw+fO9fl/I4/d7/KF8Gha+qC/mC+THgGg+ewsICAgICAh85kiWR2GzObzwF8Ps4M/R2WxM vY3YxUt6r6gI4WCsiN1KKy6KhVHEFveyXL4f/qCfkmzw20qCwSBc+Y4g+/pvLJs6XNrompL/0NxY Vi5wMGhUBLVQsBBFMYR5NFJUDv48QMQfLMgP+iO+YNAXjBTQsPCX0CsUKKFBVMDeAgICAgICAp85 UlVx2O3OfAQTsGh7M+x2pt4QHGEVi8UQCRfH2H3BRKw4AlrogYpcfhDBcJCS7Ajay8LhMNwFTjIo CGIMEcyVNrqm5D80N5aVCxwMGhVhLRSOIlaMCI+Oi1WxPAoEw+GCcHCcPxz2F46jUREOlgXLC4pC pA0TIZSFPqlsAQEBAQEBgUOD2vGlcDjyAghXwqo9R+dwMPWG8Air4uJixCKJYiapksWJGIrZw37V ufwwwpEwJTkQdlRGIhF4wnlkEA5jDDFcWsGot4zYPT+xj/QQozhenH3kMzIOxQnEeLQ4Ph78eYDi cKQoFAmXBCORgkhJEQ2LcCW9ooWVdNlQhIrCw9l2AQEBAQGBzysa6svhdLqDKKqGTdtN4XSyr3hH 7OIFEokEimPJBLuVVplIFiPBbuzU5fKLUBQroiQnipw17Cahr8gdY18KjmVTh0sLjXrLiP/I8FhW LnAwEqV0FcARK0EiiWIeTZTWE5dSoCgWK4wVlYVjsdC4MhoVsaIaesUjNUAqiuro4Wu5gICAgIDA 5xeTJ1XC5fKEEa2B3cO3bbpc0WgUiI6wSiaTSMSrki4Kj09WJZBkN3Ym5vKjiMajlORC1DUhHo/D H/WQQXRkGf8zhksrHPWWEWuo2Ed6iJEsTxZroeIyJKtI/sV56iTicgpEi+OR4mhFUTxeWFxBoyIe nRCti5aMmwDUjmNvAQEBAQEBgc8crS218HjyoyhpgjOfb730eEpKSoCSEVY1NTWoKp9Qw26lTayZ UIUatrhPz+WXoKS8hJI8KHE3lZeXI1iSTwYlJRhDDJc2blTZwHSf2Ed6iFFTXVOuhcpTqJmAKh4d X90C/jzA+JLysuLykvHjysvHJWvLaFiUNJVMKalINAGTyjA5cTjbLiAgICAg8HlF56xG+HwFxUi2 Ia+A/SdWirLbfEiOsGpoaEBtanID2187tWFyLRqQAmbm8pNIppKU5EPS15pKpVCYLEix24Vj2dTh 0kpLR7NlDRX7SA8xGuobUlooNQENk1HLoxPrZxHXUyCZqipLJSeWplKl1ROraFgkW5MtyZrKViBd hebKw9l2AQEBAQGBzyu6Fk6D3x9OINUJd5g/R+f3M/WG1AirpqYmTKxrbmL7a1ubmieiiT3sNy+X n0KqLkVJfqT8s+vq6hBNhckglcIYYri00TUla+iYbjQROBhNU5qyj3zWTUJTMyby6NQpC4mnUCBV V1tZl5qarKtLTphaS8MiNTs1K9VQM5suG8ajY/zhbLuAgICAgMDnFUcub0cwGKlE3SL4Inw3RTDI 1NuInRxAS0sLpjZ2tLBfWZnb0jEVLWgEluXy61DXWEdJQdQFFzU2NqK4LkIGdXUYQwyXNrqm5D80 N5aVCxyMluaWRi00aTpaOjCVR1ublxM3U6BuUuP4SXVt1Y2N1ZPaaFQ01i2qW1g3pWERMH8iFjQc zrYLCAgICAh8XrF6ZSfC4Vg1GpcjP8a3bYbDTL2hcYRVR0cHWqfO62C30ro65rWCFnrg6Fx+Ixqn NlJSGI3hnqlTpyLRGCODxkaMIYZLq60dzZY1NDaWlQscjI6ZdBXAMbUdHfPQyqOzZq4Efx5gVuO0 pvppjbPrpk6tmza7iYZFY09jd2Pz5B5gyRQsnXI42y4gICAgIPA5hi7rwpBYVGqiGIXkFihSlBLa kIYeCsaBbeeoRT1aMQsLsAiLsQx9WINjsQ4bcApOx1XYiZul8fJjikcJKUXKOKVMqVQ6lDnK/Gih qoJtCWa/EJOiUprRjrm5UlbxUo7HyThtRCkuJagUKlGllEqpVjqVedGwqqovfIrXKnWf+pZ6zT5p X/Kjr73f1c70f4dkQK4oSZap0z5qQF2r6GE0wWLl/2Muz+3x+oDACJviklKUlScr2PNvNeNr66hr JgKTc/ltmDGzA7MxB/PmL1i4qAtLli7rBo44cmzOIYuf7OCDgGHwhlGtHyH3eDYsRskoSLcsTk+f NrVpyuRJjRMb6ifU1Y6vqU5VVVYky8sSpSXF8XGxaKSoMBwKFgT8+T6vx53ncjrsNqvFbDIa9IpO llDZHp/RG82U9maU0nhHRxWLx/sooW9EQm8mSkkzDrTJRHu5WfRAyzRZHvMRy7Rmmc5ZSq5oE5qq KqPt8WjmnrZ4dEhavrCbwt9oi/dEM2/w8FweVkp5xE6RWIyOiLYH1rZFM1JvtD0zY/Pa/vbeNipv l9XSGm9dY6mqxC6LlYJWCmX88Q27JP80iQdkf/vkXTJMdmpVJhhva88UxNtYEzK6kva+1ZkFC7vb 20KxWE9VZUZqXRVfmUG8JeOs4CZo5dVkDK0ZI68muo6dDr4e3VW5p/+CIRdW9lbYVsdX9x3ZndH1 9bA68iqo3raM/4svBoajVLi7tfu8kbkhXX97YF2URfv7z4tm9izsHpkbY9zTQ2XQsXLJjN7+GVT1 BawXA9XUENZ8diraSa2Jt7OU3uOiGXO8Jb62/7he+kCC/RksOj02EAymd6t7EWyP9i/ujscy00Px nr628C4v+hedPliQjhYcmFNVucuVp/XmLoczG7DZRwbW5PJ4iJuzUOeiXHdKrEXxWTQMMtFVUWpJ d5xOpJHRmkb0r2oMsR9qivVIdFRmNX0M6zLm1t5+12SWzo7P6Etc8Wj/O6CPPf7G6wem9GVTDCWu d8CCbHDkBhjl7w9nKioyySQbF8ZW+iCpjdN4vL6qcvOQvDS+wRUlj7oPC7rpsJ7J1dTnsRj7VL8+ lMZKimTOXNitxaNYGRpAurqiJyP3spw9+3N8S1jOmftzcof3xmn43sD/9n0ZU2nu7XTle9rXTs5I +Z+QvUbL7+yKdy5c3h1t7+/N9m3n4gNiWn5jLi8bkrQM6vCMUkI9NStOI27R8m6WQG99yYx4+7re DvoLozZmPK3dupDco4XkkI4XRcP2yFzJLNJtY2UpJQY+7FdndDRseYIUnZFx9XZo3GOJxT72mCGj acRBQ+rb7CjuDR+WPaXM5IoD41MOiB/QOlu/jtqrlMqdi5f391sOyJtBc1R//4x4dEZ/b3/fkHrm ynjUFe/frWvVtfZvaO/d/+kPqTd9PZSZcUEPncRaaTKNbBktu+LS+Qt3paXzu5Z373bRanL+4u4B WZJbe1t6dhVTXvduWrLSPFXOpbJYlMXQKdFfxYBs4lmh3WngTJ6r8AQeXzUkgaeZ9qdJWDUka2ku nkaowq7FNTfrFlJmWjd/YFJdekg3f9DlqyV/waDNzfy5g9V13B+YVsej7bO06AIeHViueWvqzmSZ oZB2jNur+VZ7rbPZp5uLreTeIqfDdOL55C4ip5JT4Mzmy7o5g9K4SO+vdJ0U7yS1ktbNGmxtrd16 q24WtpN7lpyOp9bwRs0arK/X/Orxmp9IaP64EqrYRubTyW0ld1/2cD0/3OyprW6O6WZT1myq5yLi W8ndR+5Zcm+R01O7ZqOa3HxyveS251Kf5UeldbMHyyez+mZnT3j2oNVVu6DZpeuggjvogA5qLmOJ DumgYjv4YR2DZlete7e6R35qIN1cqwUmNfHAM4NNzbUPNxfIz9BBNfJTSJNbQK6X3P3k9pJ7m5yR 5NxT2EbuKnIZKkGZuK15nHwXHbdNvp19pjyc5uEaHq7h4SgPR7M215I0vBab6ZhrqKRrIMvXpEtW 7DXsNcq3Gm41ytcbrjfK2w3bjfJ8w3yj7DQ4s2nO5qN0LdRBLdRBLXSWLfyjbKEeb8EKcteT20NO JWdAtdyAreRkOIkj5FjKdHLzyV1Ebju5W8mZcD2xxO3226zIHq2SM8Al11OsnpdVTzb11DH11NMs TeK508nNZ2m62fRq0bXIE+nVQK96uZ56+e6B2ATe3XftD9y5P3DH/sDtLDCk7hlcH2zi/ivBepYh HTFAAZawJetvzvq9WT+l+QPJCXXcq9O8Ws0br3k1mleteUnNK9e8Ms2LaZ5f8/I1z6d5Xs3zaJ5b 8+yaZ9M8K/MGk9nGJLTGJLTGJLTGJLTGJLTGJLTGJLTGJLTGJLTGJLTGJLTGJLTGJLTGJLTGJLTG JLTGJLTGJLTGJLTGJLI9FGM+fQrF9ZEh+gy4d6fm3aF5t6et5K8vboq8wuLSEekI+VvIbSbXSy5F LkkuQS7GbHTTBy4sJ2/aYDQeWdFs1k3FSeS2kruInKKbNBiNRSI0HzXSsG2kgdpIQ7eRhu124uvJ 3UpOl8uTdfU3UrkXTW+i+gtupKb8kzdlkLdQ2ql5SzVvieaF0vPIf4/cq+QeJHcquRPJLSM3h1wr uank6slNlODeK70tye4N0pnSNkknSTBLpC61/w/kzjOlb5bZjwKY5a8NrPNQ+b8YKDuWzkC6AWWK hIg0KK3gfgbruL8TCamE/B3kLyX/hwPJK+mw7TT6yLuCRhh5awbKCslbPVAWJW/VQFkNeX0DZc2s nwcSV0aazdIyJEyswKVISpeTv2Qg+TXKXqx5XQPJVvIiWglFA2UXR5qtUiHWyTvJNoQE9wuQlHcO RN5LDCnSQOTfiSF5542RfybnR15NDpmkGyOvJE+PPFI2JEtpZ+Th1D2RB2P3RH5bVh25bR1Zpq2R PevuifyazHcV8wIuT1JvU/JlycbIN5M0GFKUTPFT6dDNyZ2RDVQUVXdShFufGBuSLqfc9YmLI2uS Z0V6ExS/MbIimYwsSw1JJQORRVQNGc6h2NIbI51U+axsxTOTFZE2qryVtXMg0lzGS0xTCVI6FJka ezEyhdowMXVzpD45JTI+9WIknmyPjFtHBf0yssRutpsnbhuS4ukG47anjdtONm5bYtw2wbit2rit writ1LitxLityLit0Og1uU0uk8NkM1lMJpPBpJhkE0zeIXVvupJdnXsNLuYZFMYKD7tkxuxCnt0E kUwyXXq7Mx5dp9zZ1ZJprOgcMqqLMhMrOjOmBUd075KkC3tYambPKnSujGbe7YoPSRZSOvp4i5Rx d6JzcUsgI59PemFxN41ydsA5IXZxsRuSVHDON0JZv6entfsmmqPzIW3sQf7m6YHp7ml5k2a0/Qfq zXLFMAIjwhWdC07fTcPjukFjpMFI0S6KbmPRbSwaKMx8p7OrO7OjsCdTywJqYU9n5mtd0SO7d8sB Ob+9bbfsZ15P925lUA60L2LpymBbT08nfcTcjla3ANmhmHlk5zAhyuwQdZi4nbxTs4vQ9RzZlTGP 7ALXIsLtIoFruZ0iMbtd66LtbbvoopHZxIF13GZdHCNsdksrUExWxcWa1VXSCmYlrYhfxawyFbyg RIJMUgluIoWR4AUlpDA3qR82iWVNVuRMVnCTC4ZNkpqJbsd+E90OMqkYA6xpaV/X1SJ1LujeZUJL Dwlu7ue7NkzjI8NeMO3a0E14UPcarHR9YqELXGucFv7pgQpXk1R9FB0wsFWSjurhobdYyGDLGMjM SI6VMCUWOCN0kwLpOl6CjZLt2ayq5qpmlkVjnmU52NVzNitwxpRY6CbpumyWi5LzqN7/dAobN26q 2Dgy4T9afTog0L6uTXsHso6KP4W7TRs3MWxsb6P3JnRmkl2dmUa6sthlNLbTpWpbD6Wl9qfpdDxt l9lMfl9bz8YsKjadsokqot5Kj0+TakiTZEiTXkiTWEiTUkiTTEjTAp6m1TtNS3ea1u00LdppWrGv arZwPXcV13PbeXg7LZ91UppURZokRZoW9DSt5mmSCWlandOkL9K0rKdJYKSThaSgE5xidQd0Em/Y CPSggs6YZWwiT8s6pULauD85h00V0N+EEHc/QkgpRQhQX9rv9h2vvsTy9p2gviT/heaxsOay+CL+ JCWkAN6R3LielpQ7cQMek5LYgnuk1ciHHx/IxYhKehKCASzGDtwpGdGDQfUVXIdleJ3WwW9ir1SJ pbhbctB6vgRXYJ7kU3fiNUlW91IJk7GAJhyvfrP+Mels6CWdfI5aDTsd+RV4MQ3fx0PSFvMv1Ecw Eb9S5qh/xaVSQE7CgQ34M96m9lXJjfJR6nr0YSt+Ixl0rfqL1UqciA9056pXU0uM6KJ6V+AMfJdq nSbtka/Xr0YY08HulR6F9fgRfiYfo3+bT+alOIHa/ke8LP1MelL3su7fikk5WrlAX7JvOtU5Duyh 1WVU2kpsxAW4FL+WIEWkRdJl+toPz6I+iVIJ48nmTJyNr2GQch1SnuSTlkpXyGfI98lvKj/RP6be R1YTSOmfQWf5G/wer+FvkkFKSTXS2dJu6QG6Aj1dfk8XVaHegjLMxCIciVNxFrbhMgzgFurN38hz 6Qr3VF1GeU15f9/vYMNyatOXMIg78Ah9bm4pLJfKr+tiunN0V+vu1r1DZ+JRvkK2e+ksaqiNc+jV Ree/kT7n83AhfoCduBE3UXvuxwN4Ei9Rqxul46Ut0pXSzdK70ntyTB4nN8knyd+WM/JN8vO6fN1C 3WLdF3Tf0V2u+4PuISVPaVE6lSuUG5UnDFWGl419+67d94I6T+1Wz1K/pd6s3qY+pL4JM+zUgjgq sY76+gt0XlupJ3+OX9PrdjyKx/EEnsJLNOog2aSQVC/NlrqkJdIJ0snShdJF0iXSpdLvpXtli5wn ++T58gL5WPlc+Xb5Pt0k3RTdkFKm1CrtynLleGWTcq6+ll5z9Rfor9Pv0O/Uv63/wOA27KCV/e4P kx8+s2/tvs37nlYtqkMtUmvUdeo7dFVZRJ9eH46lPvke9ck1NDp+ij34He6mXnmYWvcUnsYzeJZa +Hd8IHmlfClAr5BUSWNrnnScdJp0Fn2Kl0rfk66WbpSGpFuk30r3SPdLD0gPSo9Jz0nPS69Kb0pv yzq5QI7IcblCXiGvlbfS61z5Yvky+XL5Thon98n3y3+SX5bf0Ll043Skg+nVpGumC6h+3U7d/cr/ 8fUlgFEUWf/1qqqv6Tl6jsyVSWYmCcmQAAk5GYymVW6EREViWCJx10VUFCZ4oquIaFBXYdVPFF3D eqys6xESwCGgZD3wlqyuKKgLKggeUVwDKpDJ92omeO3//yXpqp7qObre8Xu/96qSZHEfSrueX8YX o8T/ynv4P/g/+ScSkQzJLRVII6Sp0q1Sj/RSes522S8XypfIN8jL5EfkpMIVr1KtLFVuVu5T/qL8 S/Wo+eoadTPOIgYB+MU/2oSzYRsy8tOgCdpgBtjgFmgiHlpC/sITdAq/n66gSC3FM+U47xA9+xu5 nQF18JXsT3AX2YBM+gSyDE4iV8AdqOltsBCtawRZzbayFJ0AYhHpYRhDDrPtiEnvoLQqYTRMJFPo y/xN6aXZbbSAngM7+TmyxreRO+lm3sKrOKBsr0LetZzdRqrJV2wR24tecTFfiR55DXByIj2B9GO/ A23IgGF0FKmDySwADWwuBHGe4rXvIEpcQNfROvIC3EUvYjG4GsrJIZIiXdLz5F7pDP7O4HS+YTCC I4vTwngM3wfnCH9kLXz4YGPqO2hjfvoPVkhPhP/wc+kFqSehHirpPjYaFtFL4ShmBTG0oFfpNHoy BDGnt+H7f4k2dIx8Qzr5ney2wX+zv6dOp1tIgTSbvIWIJpPTaTd8S95GPH0WrUJFzH2CV5MN7BJy kLXQJB2A7+h35AHyJKLwU7QI3qcm6ZPn8D2wb4EdctlcxDRKHkFU/i37ipw8+BEyvEsHtw9uhWz0 l27EpW+k5+kCcgfixbOIKNcijp2L1jyfWOEq9AA7fneh7f8H8cGH6pEQQy9BP12NeNmNePEOosYB vP4BOYy+ey95nwJpkO/HOz9InsP5HQGVbCLlGDPs6Et7Bw/zt1B268nNDMjzils+id9EnpG2KieR xwZrENcvIcPJ3WQj7OJr8X6oqJiiHYu1RoXUrqfwtKwk6SHTTyT+NCMWhT8NJKDK0tOUdWhb/41U 53DtQO10o7922kAtqcNz4xg2o8uizqhzGDbI2MmxCOs5ZkrkKInwHrH+di02b2P0kxCR1ptZxCwP 1IFoFCM7XCmLRkkOvtzlyqqUsTdL8YTrS5znVRO0qIg+SerQe/ReXUFWLimqyqmsaYw4MBxQBwAk WbFpkTlOQp6sWchmFsFkEuD0Lo0vZEnaYzrUyUQztIjGtMOWp7rFNJr7+vuMvcZeUjdQW1drHE40 17ZJfzBesL/QJhm19hdGl0Gi+TiJgny3O8ogyqLw4AOzJsHIaalyCI1N7YXL6JfQlLrt2JupL8jg IFSzddyOMy0kFrRdhVhgPop45AYCaFzDSQmsk+mpM87O7gJUYRLuNB2TihSm8DJWpi20LbHJzcg4 UBuzBqv4/fJwEhUrbrDcvCgrb7gWyZ5g/VvsheDnPsXitnisPtswrvoL5WHKsFjh8Ap5rH9MfsXw RltT7jx9Qdm9ymp1tW+1f3Vgdd7q/Pd8WWpAzZsQnlLM/cNdDjmfDA/HXP5AODY8EnESWXHk5Uej BtvIn4En8Faj8BcynO4wreGsjQ4vtHvB+/v8brqDOOmKDQ4pFrY5k3D/0/XGHGO3wYzN9H2ccgTu N60kakTN6Jro7qgUfYbuwvifRd8l3sEe015eVeqt8/Z6v/YOeiVvki7YEBlRNoKOSNJ3TRcJGaGy UENoZWhNqCPUE1JDSTjNtLSUQVlpYV0hLXwG38ZCGLac7jSdDZYWS4cFrdSwlFlMC7dsoe+RUtJP ewkquL+5GRXc12w0o6qb+5tL+oyB5j4c7iN1JXXky4GB5sReo2+vMbBXEQqvlfCorf35eYnTFXfG XfidNgaSaJYKC4tqvD53YWFVZXV1ha+mQvF6fUphEfN6szwkX0E7KZSzPG5WXV1VWQhPrEhaB9yt s9vvvOzdlirXCu/199sOu+rP7Lwv9fGBYSs+P+2sxLYZiavHWPL3PW57vBK6J3x45fzXEjDz/Ehy hW3BiFTrpHdv6Ul928HPRXpw8dSFqcWpBdriGTUN6Evdg/+QP5feRj4SIDmkmNSAbFYpKmJfthpS c5RCRzweiuecRy9Q54Xm5ZwXuaCwJb4ouCh7ceiqnBuDN2avCvomhyAnGEzSf5v27JAnOzsUzA7l 8PgYI0k/7LS8hCr60NRZTijEIDs4PlYphqMvjcJuY0yP+3zBgiT9wHQ7RpeN7hndO5q3jF44umM0 G91RIsZtRm5HLiW5S3JpbocsRnxlbnC4oczd4+51sxb3Qjdm8e4Om7hmRY8RJfvAmKd+5y9BjEk0 Txs43JxItIo2fUwf//txn5K6aX0DqEnhtrUGnoLT5Yu3jSpB700ryl3pqihHfchyfl5hjcdbUS6U kZ8ny+58qID/79XuNzddu+r8zkuuufftEYWTzh01rPjUE87ez7d9OvDwj1feGlGUuVLLvt0K0TUr Lv9qwf0LKkp3XjVi9PhXjv5Vdh11bYU8HP/6EjH+3lUjcRzBCJGBPpjGwN+aJ3g5cMa5QzGIGzzM 4IYUYcMQBSr5DN7GulgX75KeY8/xt7lH4oxRBYFvFyXKfsS6iKmJOkhA3nEgLabmaf39iGJxFEPc V44SaG4Gd01UYVAtVUF51Ty2Dpzff5/6Gl/UljqdXYM2Y5CpZo6OrumzlJJGulyTNQNTj6V22M8t R4gGWhKGmTZ7I+EGn4P3GnAu24RsZegD+/oTQ+BZJz4P8gtpVaWrprqmQqY0y+OCL54/o/6GtrO2 7Nq6fe7I1Olboe2h1+G+d5a/swdpYNm/707txSkMtmA0Pit9Nw2mw0ZDNELYEhdoLjAQXH6LFrHU bjni0CA8dENW2G9vrEMuRnnQlYSN66aIGzqMN7S3v1nc0qeZO0IbqPC6sjxUkZX8aperqpJ+k76j mZt3Pbt97gjp7WdTVz74eur3O/COYDn8c/cqyBZCnYVNB2QhAg8zfWQys9C1yGXWRpDGb8XBJ/mE RengsXdABI7RZRgVondlIkEWRgCc06OD+9l4nBMjU8wsAww6DsZRTgX3stDvF4poBe+bVva9SUyv v3I7fmgSVnfyyIub4ByUbzCAOFUS9PelkQptXAhYQbNtojteHigJSF8e8YiYumxwP79D6kH+EMFP clq4KnNdth3wfu+Vh1PITkKoU5JQSCHTY7X5LyCqoVI1mOe4gASiW1alFTmtLyM8UtdX1ze6jDQD +k6Ni1SUC9mR/Dw6TPhHTbU74yKKzORlU2dDpKNz36OpvZ2d+yF4Wm3DSWeaFdNqTzuhsa4aPvzw E0xm7KnU4Y9SeuoQ0O7LW6b8DvL3t11y7uQLU4dE6ov8h3Av8j6N/I+ZPZVM0+aQOTBHk0ZgXlEt Vcsz2Q+azCUpCXOQkKCnKgrpppcQYD5EI4ZXZKsiG+xkHR4kHOYShd6GCW0HkellGGkTptMQhcI6 Uk9akI8ELLIvyTzrvvWXpM03MW3v4b7+gb4SozYtYaN/IN4mHcePZtLsdhfUVEDULcvfVsOi155K vZba/c6sL9gUIA++e+RE9v3YFnz/a3AWf0INhGGKORvnYiE6YrGNuOWrPLDaDa5SR6kx0jfWV++o N+o99Vn13kb3Xe6H3F3ubv+GcI+lR+9xv+3e6d/j3ufd5+t3H/Ie8gUdTofL4XZ4eJndtPfYe+3c noQLTacTcohDjHWkRyUcPWej4bTOwTvppq0kB/XNJaObJoiDrjBtwQtWKIMKQoahUOR0xRuj5IKI sD66oMtwgrMbppMICmVV2p7R2IxD6EH9wqz3NiOxa65FOAEMoBnGssHKnR5uJyIkuuJNaR87VdQS bYN7OjFEJge/73TGNbHq4YxbMp2e6ayZzpbp7JnOjS9YZ40jI/qp0tKM7wnDMK6m4VmRuayge51E EVeqhzCa5qT25/2w+Y3PJ51xQqq/MQbHqo/daP/dXS/eVTShsvHUcXPZN8Wv7/z33xufahn3w28q UkfmP7928+0l01tHTZl9PkpqKXpNu/RXZDfUPNVt6nEPHkJPtY4TjGmOacY5jlnGAvte9XDWYa81 AhEeM2KeSOREo85Z51ll3ONc7Tng/MS1L3goy+HJykrCU6bXcHoMw2k4sqx+0gAtsBD2AIdueJLI ENoQti1wgCNJV3TtsYI1CbNMw++OeOo89Z6tnu2e3R7Zg6rscjm5lqQ3d2ZvdCVpYgNxG27qPtkK qzB/99CdyKEKkPA+hvTrNmIg/dHhAoeIAnlDvpxAUN7bN7BXgFO/QA7UYOlAM+oSI2c8zWTa7KNK pB+NvKTEPQypyk/xTykSaKYMyZ9yDI9LwQe/mTz30XOmj7lg9Je76UfVqcCpxTOGr31vVar/zs3f wMMBj2Xu3OcfnzuvsspF+1JHPna7P372ntTOB/5D6OBnmF38DmOe4MFec8ZuDRDBI9aF1l3sX5zX W6/iW6291oNWqZAV85g2k8203MNXWRRNI9bJZKo8RTWtMlE1BSyaRiVZzlM0j6JoGBHzqOahVEOR NXVy1SKWzuwYZZmEuYGiUKYi3Vhq6hHlOoU2KLvRBzYjrGvIHptMS5iW0oV0D8Jykm40HUQztYVa r8ZFjkC1LZiZ6rSTPo1oHBBwcbjZ35c+8Qu5Iumoq3XFS0Xu0zcEG22j/KJTjNrathdqMx5jGprp DFRqMc1aWY/xS+IiQAu5Z7ynOQGtJJHOKaIoeAbcM7C5I/UqOxHqv0p9PPOs1AMwLrVF6j4ygY6h 0wc6RV5wBkr0SZSoi+SSGBkwT4oUw0wD1sKj4TXFPcX8POsq+VHSW8wb3Y3hFv1gMS/Ri6xlxcwd C+fqniJd9Yt/6ksAYwh43EJsvqLtMYhFYrtjtDRWH+uI9cR4LJyTi9cwIaSR9LLkSBdRgRj+WESF UnUBRpLXCmJmMRC7YY/Yy+wt9nb7VrtiP2dhMRTndtM7SJgWmM4e0ktoGTFJA9577XDi66aP0UaU q8CcBBorkvPWPhG6M1gsUrGBWme8OVGawJMh6ablhoci1aajIX4JrECELvflUgEVgn3LPJ+hLQtj LirMz2fRzHl+9AwMnoceOnn+3dOX35647u7U9/u2f3rf8nHmCdFrP38T8p/+w9T516bukbotjll3 /2Zx16hw+3nL+uaxC0ecFx8zySofKyqdXzt5johbzw1+Kn2HsT2bdJqj6kk9mHbTwRWfz1eilVhK PJOkesdEzxR/E53FZlnv1mzon/Z6xxwHdXRjUuWir5kWnZViYDJRHmIogENjuUZiC2Ar0HqYA+3A 4HpHTAiW2l8zc2BPDkRyzJyGnJYcnuONmUqD0qKw47i+uisUL09DONKfRHMrAjlmPn0ZFB/oT3t+ xt9Bkkl+hDgrXQUV5dyHqYzA0wwA8MVQ1pS6/+vUt6l/vgbz/vUVFAZTu/03t/5h59K/XXvZ89QY 9V3qKIyDyiPQ/sHgB6Eli+5JPfOXjp57UCoz0CZfRJvUyQGzpFFrZ+1Ku86rNZOarJFzFSKWiF5D uKRqnGvakPHJkrArh6KWqvVqh9qjclVjfMjoLOjXL2/U0zandNNTiIxBo7pKFqc6PWUDZoUWahFm xugpprsB6RU10KkbKG/HlwdtfAte0xAygY77tRlaiS9JH1s3f8gKkcoJFtTcOg055N7+kr2/MsXS nwxROW5/aHoiNKWPGVDO6yqOfT2BflcxoM1mZ1VK3YdSXYdSrYeEzTSgdG5E6WhkgxlQoZE3qu9q XJW49itZbFDUIQmYFpyDlpl8kp6ysVeGDhlw8qemp+tZmZluD2U0GNGhQQedb0EVa7Tp/zVfS9rt 8IN+PmGBaukZJ/Yep0Fitv892Z+m2gAVnFYOjJhCt1UMjF0qZrnm0MBKnOOGwf3yZPSLKMzYRCKo Knc8imHeTLjjAYZ5IpvMztbbclflPpy7JqxtpV25VKEgU5kJgmwwX9DINcJGZAQtso3KHR4eK49x jDHi4QaY7ZhttEN77gPh9sjD5FH6d76D7ggfgVxnlisSDudRwCgA4QiVQpGnEEjTWyggkpY7EFco if6lSdocF+CPS3hclhixM5oXA2rg808xs5AmQgNpJ7vJoGCL4ddWYOBP0oINDWQFUBDPyXHFTCcQ Jwjq9Eh+IGZqDVqLxjIRA91wYx710TxLfBN9Mi3n2iGXPNQsWFXzQHN/GtX2pq/0pN0zUTcgzKt5 iGu5fozPZMhnIUESzaL6FGUIbpGiQmdlTTX5L+etqYmyZXTlsktTTz2VOvinbWfNhStTKagoT+0f 9sgf7ui/Ze2D574+ZWTqFuYYuHXqvKvXQt2OF74E/uXHkWuuvSf13JZN62oKdwlbbSJEzk178m5z 1ExLg42qvJE2yo0KJ2idOhqqRDWLJayrHl1XJUrDjHuQkBMQgg8ochnaKbfoOgZgTUUjp6rOmaE+ S8fhm3JsRRbUZHrm6Nv13TrbrQPR2/FsUOd6EuavN21gw6DcZLp7WC+jZcxkDYyxWqvuY2mvXSzW 1DOiRaxLtKbTUBRq2obToRkb1y+89mfBWRyZBDkddhkGXojyiQOv3Jx6C6PEyMtpzRUwMvVm6i26 YiAhdQ+8SquPTEDJTMSU61GUDCO9m4g02NN16sRKSezpqTMzfe2Jmb6iMtOXlqV78+SikZUrJVBB pabUSBukFuk6aY30Et1P90gHJashzZHapQ6pV5JMCShjQ5CACMDSCECfEVJDz46kfTuykKwka0gH 4cK/WwjDTGcPgRYco+Qj/gtoQ/G0BvYGB9Ie7hcu/lOW04qxIsO70cFhoph86k3BNYQdnEmIouBs rXROhstsJAqAzvQkvb7LIlOGvemUuIXbbdaIZqukolGSg71IegKV1KogD0Pz0IGrQi11taJCg58l Inm8tGKgoqK0D09LKypGl2WbH9tlTdHU8WQ8m2C5RL1cvpHcAsvkg5pV5Du9duZQNGsRHWGdokyw XqesVLZatYAWtIbthaRYG2GN2BWmM+un5HP1gPWgXZaJDg6qSpoiq8yivEi2qy9ZtukvW6VVlvus 68lmdYP2tFVebvmj9c8yBiv1Xk2+WrvGukK+TVmh3qzJ86wt9qvIdfJ1ytWqPFmdaD1bO9u6QJ6v yHFtjLVePk3hVjpXVZQosaKyrOgSeboVXcIqcZ7HKLoEohKzohsYDiWMgfoZuozgE+lSBOlx6+0+ X9AiZBibg7ZPr0Pzpw4dvhZ9uw4rdLgOZ6AvEKNhvR4F3w1I/6DT9NYhRdgNzAHXAYo3DCtgEHON Z/AyI1LaUq43S1fwrXyQszJu8ga+gF/H27nMAzbhQzYbt1rRrylqB42Sq2PQo0id+BIKwZ/jOXKf SCUSranDzekvUYZLl9+mpcuqaZcT6mz7uY+1ceyHUozLSwOlMLVDP/3sLrtm4+L5TdD84xcSktZE UxSJr+C/aINRYO2pj6s+Sx2EcnhyJPRDV+qNVB/65ytHa6TuowOcHZkg1hOAzEacCoqYSkeYj4AS xESAULQ6TQtCFvVJQUV1jaDn0QuVu+lq5SvloKLspjCMDIcYUumJbLLcoM+D89nldLFyE12urCL3 wt30Hmm1spb8lT+urFXXalvIJmWT2q29RF6Gl9hL/FVpm7wLvpC/I4fpMaVwiQ4aIXmgegBUGfMR Lnk4l5Q/E/pnCaFPlihmKUBUFSRukCTqrhjMhiowJ02uBLO2agVszyiyFDXKxDklSP52p/WZhIvX YxzT047m7uG9nGaUyXitBXw87eU3/AoKhT8f/jUUGn2/TlIyHr2JKIhO2rCiSmpiowis0nKj+Agb fLTG1AxXJW3BJnPNasdr2OCjJaZL1yvpedg4KFHoID2oUNKc+NmuidFlZGpH4Ew8Tp+V/qw319Hy MWPEvpBhOFr0X6Nit8ioodHudXRCZrQcR8t/OSoK8a2Z0oMyeND06XHq98TB8MQl7KWIEafVRhzv 8tV1RhyOb4NpEgw4iiYm7Mwd5QdS+1OXvpnaj6YWhNveAD/beaxI6j5Wwt5BHO0a/FSekK5L5pBL zYDX7fcGgr6cGC+0zvO+wrfpmsYlnXrELk6bli1IxgiZ+WOCDezRmBY0wy3hNWEWdsbEv7eka0Rh u0Gg9R5yEN9f0PbcDG1vTSSa+6YbiZ+V4dIV7JpqpOnI1tN5eEGmDlftSifqpKuo4p9w0mtgQP2u 1C1fvpH6/FIoTt69+KM7u1d+mPqC1i1d+Q8IPZJ6MvXZgdT0z7vBfceq1/8CE+974sXUeaJ2iPgu PYD+4yBBss4cqVGvFHM3OprcjcEFoZ3u3aHP3JaqYG+IxoNg4JOChISBoqVTpyGYqt3hgEBQhPww Ah3B2AZGVkykJA3KHoUr15eGzFBLiIWCgpYSDF40TUuhF2gZmNCAOU5tNqSt+LxfsFIhhv+LjzYj gqAao+Ui47NTRc7PrxlK+jDng+tFGKcz2jfNn/mHlYsnPv+P8uav18wuPevO96TuqU9cueCta092 Wr6tXVZfNS6McpiFcvgK5eBF5nqiebVKZaTlXinsCBs5TsVlMaxOq7s42KVJxbbC4An6ibYxzniw 3jLZNtloJI2A3MjaGL1B+6NzhWu17V7jUdsmyyZ9k22T8Yr+mu0V433bLmOnc5/la/dnwR+Mo8F8 ry8q/vzFkDD9EV+Zz/StFP6cJs0okFc3ZHm9EEkTWRsKF0Wdka9DsKJwhx3s94RiEaVH6c0kgVsV prxm5kMkH/Kj/4e48/5L3EZCwIaoM5f8BBlDQi9p/lUaAAmxT8sImq54AA8/Hj480nun0Ll+1Anm 4j6vO1rI0kn4kG7wNArL07q5de3mRXs+GVvx+2tSW4paT5pQctHVo9Z82z7r5NiNqfVS9/jkDZu/ zak86/HUtmtAuX10zgdjrxnXEPML1D+M2npcVJMgaJ6zUAMHc3C7ZJd3KgeovJP28l6JdSmv0JcV 9hB9SFlPWTtvlx4l7GZ6q3IPZVeQZeRGYKZ8Pjkf2ESYROs5q2N1fCJhyo9KIQLOhfQ1ZK8od2kT F8oZV8UynZTpZAGK/nFVRDZkGpEXymtkRuQeeY98UOZykp6/PqJhhBBKywO+yWBQxtYwSthCtgcJ rcmArQFQUDt7UDtJOmG9qoHvpk3gJ2lY/7Q5AfFEKcL6XoTwBCoqvRj9s+T0ZxXrH78gIRRRg9ka fQvFTVJnVPAbKlJn8xcPHUIJHiREvVXwOugyl1ppiAqarmtW5tqh7LLQRcpbCi2VSu1VpIrV2cez KWq9fSabI82R5yjnqHPs88jF0sXyxcplbClZxm5V/yxtINvIPraH94u/7CIj2dJVYn2L9CI3slBB ApEjZfiQKM4xrlp1BE8MjxgfrUm6dAPRF+oUeeX6LsutQlyzuuBWiknwLNPOpLA8K6ysUGhYAQVD omlVw2yFEOIchhwULu5UP8Hc69P1BrLlmzaxHBRdaXNfH6ZWgsEgT/nK6Mef/lZRtzOGvjNnbT+m Wr74UIWblllslRYksV1aOuj1dmJPSo7X60iCHA87ezp1UePuxY4mBw902kS8GeoObrTGdT96Bp52 ukTxW9THJXHBFVcNV5yJEae4frwz7UZcxcCl+h14eOPwUyAd2sE5FL7SOxDcabokbUttjw58nnql Bops8B1MzINPoICXHe1FqpTi9JjGvkOEmz24n4/jdSSfjIZHzYuvjN0UXJp9Y+iWmOTiTI6QCqa7 JgTHZU8uWh68uWhT8JXg+8H3iw4X6t4AlFbsYAdKD5TtqThWcqj0UJlaEBjranJd4JoXuDqwiTwd 3EXf8e8IHAh+XvRFzH52AEYXhFiuXcE8OTpYAAVJ8JrBUBmGgoWh3tCekBSK2h0WNtI9kh4cCSNF llQeqEv3MU+mz3elezOU66gbWeTRxR+KpA5sSsgcsoD0ogUrJMkKzOFRsX0kauILoya+KmriKxxR GETzL+aKMi6cC0ZuJJfmJul4M2g9w1lB8Al0oaMHKYvDcEQcZY5Bh4SoWmdaKkTBoCC9kwSf7S8e 5zPrqub4QKDzdt9uxOdA+SmvZtY+EyXp1c9mcdra33csIYxrIEN+RE7fJ06wT5eO+hJiEUUk9764 WF/D8EVaE0NYCqYlTvAAU8NeG8JS8oslkCyPL1pYlF6qrqqsFgshmVo94DVlqHpfXQP7UwfKvn7x jRecFcX+1GdOXvfwmcsef+bbN8a7pkye1gQQLHnvlNJJJ5y8KO6lP/hvX/PIFWXzP332tHFnjj1p wtQnlt+z0e301xaMOqkutUWRg+UFJ5aPr/vdBSiUq9F+lqH9ZJON5pjsbCi2NtEmdhG9iF1Nr2aL pYU5y7OfIn+jj7HHg3/L7oQN9GlnR467xDKGTqIMAsTucqBX55l6oIjrYQdsTa+F5Jl1riJdIQVQ BwvEHh4E30FAKlwH9ZjStMNWkMExLlNdZvZgjrdAxLoIMnmu7AsNn5nZwZNZvYwL7luaKXm2YpNZ osqk+a0gyTwtPFH19A4VToYExzAmjk/9p/O1r1ZC3hNb9thTX1uaJp25ctrs8eOXwMqR3c/9519P QOW6F9bkNM245rv558xNs6erBvdLTWn2FCJvmauGZdezU631nin+KaErQ8oJlrH+sdlnZzXkLsn9 K3nM+xLZTw7YvyPfsh8s9mJLLOsK18JcnsXQNm0UwG4L6tQtUZ+N2YE4HBE7eOx4BhZ3kaQHUUh2 B4qBnAErASIgfmMGA0cHUAWQJkAZBncJco0CsbwbUQ9iQrcvB3zD38iE+T5XXFQBSvtK0pQK6WXd z4rqvvjQcl6b3ajNbJ1Iw0zNkL2RinKfOwoZI0vbHeVFqYP+6avmPPIGRPp2XLQIwsdqFs2Y3nb6 Nadf++CiqSd/9MEg3P8YHXb0cOuSiz74/aLbUwdQYlegFS1EK/KRCLxn/mm565Yw9YXBdau23LbM 3qdxt2poXgsLqUFLWPc7A1nusCvSpKq3GG3hZ7SN9te197VPVEVXLK5MxdDgomI4Ljw+Yplpm2tb rFzpujJ8s/I/kYe0R2xblK3qdnWn2mvZpX+mfK0eUX5Q/+M5GuoPe0ucy120MXx++EELi6j+rRHI 1Pq+Nn1iq1kD0AYhZgDZlVPkVrTXVQFLw2KVojezArmVDSrUq5ARdy8KXFKTdKJZ4ZKLrLp6jfZ6 jv82P83xg38c8RreiJd5l+RFCm7AtyzI4M5BB3fsix43YUzesG1NiCW7gXR4kTO4KAhG10hfpkeY k4fwUfSdCHaZuCBACHGnrk8gSiBHgGKOia/KEciYI5Axx/zxyaIC2Yrkrrm1FoYcpDkh8nDEpPRH G4Pfd1oyi7iWuJrp0o+0zCMt88iefrTOHj++cz4dniCacasaSZgPqcIUJipQbNjx5UU+e6AMrmpc gRKeevT+Han+qx6B8uc/TR2BC5uabgtAt1O7cOldJffdB47dux779Jud82a7LZdfftMN4tdHU6fz o2hBw0glTDVvjVRDm++GUlqdP902NW96MS/0xcpGkwrgAUch0Im+l7IPVrNbSpdUPzFqbSlvqL4i trB6WW5bTBo7amL2hNxJI872S0UlsVFj3GMC8RJppHt4OfUjNwmARKx+60g/C+jB7OyIHvDgYLY+ 3B4MyGXFWcrwIrvFIBHxu0iiY6SbFaQLgijvdMHPjuKWiqMOvSoW0I3gZpqH4BmgU8xI9slEL9VX 6syhR/QenTHdjScN+hp9q35QV/QkvGhmV6OZ3F5YQJyG83/Z+hL4qMqr72e5+zL33pk7WybJ3Eky mSSTZAIJCZEIFxQSNgmoBMQYRMS1hVAloihRkE2FuBRw+YS+VdyqILKJr4X2B4JbSe2LiNoCn2HT puRtEauQm+957kyAtl+WuctkYJ7znOec8/+fc56xjB6DMY4PkoPyIOnxiouscvc5WspG/E6a+Uzq u4f1ZnwPXd+UYutnktOLvPbyNZ5hX8i803AxyJoBt8KDfNekV72XOp9gTQx70obz8vVPfM5VMJV7 1RXTaoqz9LD0y3Uv7F92rv3OTQOKoLqjbGjj/RtuPnYCXv+zSWOfGHt/4/iHS6zBpeWpWEH20MSi gQu+/p/34OD1c2797wuPHdx292jruXd8KDR/4dzPZrSuuH/hDCLUScTA/trlWUnIZ6+wxAbcIa4X O8UekQsQlI40pGFErBwbYkLsq/xGcT+zj9vHH+K6UTc+xaj5TD6bEqu5an4y28S1i6u51fzL3Mv8 KawKSMBAxJvQJrwb7cadqBOfQWewQBPLEJOgASAWcpgh/zXHWTww6Z0OErVvIgE7XX3BcBXegeO2 h4EAMORVvES8EokZ1mzmJhEvt8bWeBI4dPBwAnn3KwWeIK53386Y4tZkV+/FVAstOE22Xp7fpFNU e4miTtdCkGmCc90UMU3BwMUwWu0cy4XRvzjH2J3OhY7zLms/nryZbylrD8/ZvxNYlgsxWMGalC1G JcbbAEfjBma08DPmCWapzNfjevFWrg0/jX/JbcBb8F58EH8pfil9g0+KP4k/STqHRVGUrsJz8SP4 K/ErSfDjF0QUBwkun88XUmo1N4AfIIziruKHC014sjSLncXdyd8uLOHa1dX4Wf5Z4RXwKnyVe0Xa jnfw+/B+fr9wCHwJv0CH8WHmEHuQ4LXDwudyp3oKnsTHudP8aeEH9gfuR+Gc+INURUL/efZUKltR EgWJlSSWwAYkSyKZGUZAsmylCXLMYMTUsJLJsuQPRUmweI7MGEerRkSZZiuAxDIcgrR9UJhEIMQ6 iiJQg+2NsnAV28ciWsC/kd3FMiwJ+7ZNUI+oiCYf1tiSPGkCedlKBQR3wnfh1ZnMGc1Xu1HfxXz1 sDTJBo1aEskbbhGRQJk2tjx06aQfZvBCnVC3VND3CHtgSO/OoA7RkmNVLiaQYhRtTHWztXNb04j7 XYAJPvAqRDX0Wob8CrpGjloaIwA3XKQpOuzSWpjH42EljK6H8+C9zvXfOMee+v1V7M5eFt7mPNR7 I/zuN87vMjlJ9Ct3lT1g+wBrsR3seraTpQkJfhMLXTt25VWDUmwTbicSSlOgX8BD+BT8AcsIY6s/ SQFokkLHkzaBo2StAOiKjWYh4CXFn5uJPi5HrDA5l+bvicOthLmZxAMEowmG/Aex8knE295qfhRf H8YCEFTBFCzGS5HB5hGDXIDQN2xQY9n0MlQovKW86X8t9rXyhXbI5FNl9O7usqNlbFyLe+OReE5h cWGyBtTy1Vq1tyZSXTxSrtfqvfWR+tzJcpPWFFmKHpWXW+1lr4FXlQ3aBu9r/g2R161XkhvLtsrv qNu0bZFtuZvK9oMPlX36h/4Psj/I+TC2r2Rfkvx/+mHfl/5D2V9aX8UOlZwCJ/XT/pPZ31mnYydL fgT/VIYvgQfK0OwySGB2cUkJ9Gi6rvq8hmHy+ShRjEugquuWYZrkTiQ728rJNXNycmFJiZUEJplc 3TCyc3JKklKwRJLyCaqBgDON3ByQ1HVbmpQy+gx0wIDGDvS+LWdPSuX05aADOTDnPfQ+wUsQNWwu oVZpjG1WJOH0JJyQ7Eii5MpSI5gTTLqm6SO3QdWdI8oHpdkgV7czLPKw7jq921VxCpkv0cieft32 XHQyrofZs+fig7DnsgDD7fJ7F2gEJOu15g73oKYPWRQn67URctiq11qhi6RtJqjgXXeUQUQ8gb/9 pYiXzjnOvYIJ6Im8+NZ9j3hr/jB74crsZc6xZeFBg+667srkrc6xJcHagamZYyNKZJZzjCl8+LmZ UxrvXjanZmlvG1p+v15a2TrxD04uemR2rKR68IzxBQudENHIycS2vkc0MgzvsrdIPCTayPG8oDFe gbMijQIOI/iW/jVPrJjOnAKntG91/JG+L7Av9JXObFG2q/v5fTKzwb9Z2CZtkZnq4Chug7RBZeLB GqlGrTaZOCiQClX8hXRIPuzBr2vwN/xr4msePJ9/QJuv41FSvdokYRQMhQhUUBRNlGTBD0MCsYOK ZpIbMBSywsAMh4GsKKGw5C1hqaJoCgjr8iTFRdP1gzoUeEbpU5ClHFCQpqSUYQq2lIUKJWEG2kpo 0oQwDK/MUoJhVzHGZ1ILVB1aSYTZnbyoEMP+P6rg5oE8l01+3b+wUplkj6sCgjvb2o6+L8hBSs89 0YSefrL+4qz/+4Rn5rgK6tmz3p6xaE3sQefYQ9nDrxj2XKlVNI1O6YopY1cvGPxC7yto2tKsmmF3 Ng3d5YwjMcUCgj4+JnOogCzwll01OtyZfT78YxbzcfijLFSMEkKRNxGu944ON2bPYu4LLwv3ZMs6 jaR1GkTrCcwHM1wFPdoV5GYwIcpqAWeXVFRxdv0gzh45aCN3gEMt3CpuI9fHMZQWtLhGrodjuR0k Yg1Y2TDbLHDLUi3QQ8zm8UjxeBcCNHdT9p+G8UmaAUgm6a9rI+e2+nQQGwj85DGvsBBWXcKuNdUL 4HiofQcFZ5vz3epTc/HAtpuaOxoX3DSvcS5xWQnY4vR+5TjOsvu+hmNnPfCLr26cu+TWVQD1fe/c xXxBpKGDXHDefmK82uAdFRiZPcvLVhHL2GjN8s6x1oLntef1V8EGbZv2jvdDsM+zTz+p6Y9rj+uo QCoIIIHEUZpvltFpscjwaBBFoMdUPAbCOiQYVgemTofKRYgymgQYEeATKthIQBkSqMxWCX0CahHo DZxGUo3CHIqk4NjtlgXbCSRzoyotHVXpQIedBPfplt5OoF84ugOufntyho6ZO56aLlrO0tqadIm+ f4O5l6HcPa5itqYVsl/HdJ7EvQn8LziXBIQJqAeb1ja98vHG1Z/+6e5fOMfgkfmT6hc3zZ0yaekY pvBnDUNPdDnHPnjtjd7D+IYFy287M6tt4b3fUO86AgBM9U0Dx+zmOIpLVeI+/JXyV4WbhIkB4ZSg EgeFasqoUcfyTXKLMZufwy2F+8E+dZ92SD2pelUcQM/zazzM9fxqHhH3oXogh0QGqdDjsTRgahrw aJK4A75li65fINDSZaQ9Vw5q5KDOQZeX5iidZVg8nM6384hfuZF4C4/rE7ZP0KC2UteCO9G7MJCJ b7q63Xq8LlcZLy73fkHWunKkUhQyBQRgbsY+B/m0FSZCtKCSXL1xaP3PE6Vjnp1cMoouzD+cjH7n mfPex847RDplZDXeSaRTCje/C/JJcCMSwBSyyEOc1hCLtfnkYD8u1+rlVnlFuV3eWM5KHqG4Wq5X 2vK/Ug/GT6kCn8/GA/m+eEF8lDQynyeyyeosx1Z5VV51fGRefdwubwbTPNf5GwOTgk0F1xW2lDaW tyWXJJ/zvO5fn1xfuqn8Y//Hgd3JPaU/ZkXSu/pZsbz8gnihapYABgajIaiFoqGW0GyCMyjh6PVm l5gk2Ie0wHc93E2TtDjb1rxMSYkcujoVHBac4Jao3LhVKOhMwASdjYQ8CCT0hJWoSNgJNrGyPHq1 DgtSAFIyEzWCjeAAOAMYlyBTJpClo3fqyCKavgO+9E7ZiDRF0Jqpc6FEQbI13RaQZgqYtFViMkwB k2EK3HwFQf5pPpHMZjrS3MJAEyLQPNV9tW1mUxOXTcmCbGrnsu2LLyH/n1sw7JKWsJlWIcG57lO+ eBot0pROoiBRmAH5QZZme/IoWxmg336TQskyGIj/vGXGkGJ/4GbnwtCbb1oE0aefZTs/+FP2DTdM KAov+6x+pnPyxHlYXDpldGluMicYsCYPvOahh6YtXN1efkVOoi5RlKUXXTnk2nvX/OU1ojvP9Z3E FruaeONP7H9MwKvwEUx+YJCBTwnPyF8x+AHmUWax8GiYgVDjqxms4hfxfvwBcxh3MVwRXohX0MoM nmFpHz3PiVwogAKswRkkvA4Yp4Sj+rfhHs44EjkKu5hjHHOEQJUjxuEws4fbo/8Jfs4w24Vdxh64 j2FeEl4WN4ReCm+C7/Fcu9EeeZpZLawW1zPclNB94vxQO9fOt+tcXngkUy9OwVPEqX4uTygULb3A KPMXhjhiGbDFWGyMi5F3IstMKBDAYRwAvMDIgGcZmax5HIDkOcYjeQzdhyl6KWYYmcGyFcAEuWNe A7CPSCbBQY5YyR6iOwmfbHyyiSoRqrdV7hOe4NE+Hm4i6Oc9dCOIAIEYBVGGn6wjr6sMUxPhlws6 ApsCuwM4zVntDpwNsIGdaBzIgn4ax7tVBl1n53bpXffr/yTqGEqdPdvaRdwVZbp7mwmU9aShDwil KAFbS3vnajXytdSNFT3/lqhqplw4CS1c7slXU1kTx5V8Ps44Nz7NRNT4nit9PB+OHr+xdFNzuKTG N65szDVrV8Sn4okHX//A6TjoXDXfiMX5g9q9tw94G75B9wAj1uUsU0je9xj7PiTotUPEK83x4njz JZb1SYaMhFAIhENFoChkZTeE5mSvz+7MlkA2lIAEBU3Qwyikh7PiStwYnNWQdb3nOmOWOssz02hD 93ruMZYYe9j9+gfBz9GRwKGsnmxiO3xen+nVMMNi3cf7fR7Na/y27yfgIb9M3z9AqK/HHmEQ16V5 idX2QoaxQsAM0YQmWe6c4ZX4Er8cihRpXhDSjbaF3gNeFPUO807wYvLnlneh94wXe3fAL+wYUwBC sCO0PrQptDvUGWKtUEUIhURvMBQMRaSJk9MMUTJJs4YwHbqlAze34rA7A1b7uaFMOQikH/5EJ8v1 ksFaClCJo8wEINTEu/WH7sS4rRi0SSBDFdXAchhdFLp6UOGYa4ZGfIE7KTVxNnfTgUWr85jC3sda s8tH5AwZN7T8dvjT+S87Xlv9UM1LtEfqTySqPkFmSUbV9mHvdWTeVErq+jgfb6mN6nRVkDDLynKF aqs3ghtgizBFnCxLdbgBN3CzwG14BVgHnsNPc2IxLmPK2EK+QCiTLLUaVeNqoVqsUMeC0bABXYPH MmPZ8VwDf404FUzDU8W7wB1wBp7OzORuke9l7hPvl9rkZWARXCquA8/AteJa6QW5Qz2BSzFHFh9m SNTJ8ugiG0HzmDKAMiOKEnnXMnHnlJeAAs+zLMNJsgxp8XIXt1iC0k50AxlhvS3R7FIXXuyml27Y ghYLUKAJTmU6v57fxO/mj/IsvwMltnGn8WKCvv+bvI5BYwCGH9t5UQQ1FEUtCEeRRQ6z0UK0Cm1E u9ABdASdQTLaSXRXySxTSgt2ne1u1nuJm2im3a+9zfSyP/+ZfnS5CD1NRtQJD+5xOYn0xZ6l/QVC W4GtB6vcoEIkJ6BI1OjVF5vJEWRqfNxY3W1joB7FkGl2k/wyNj36asmfd26Ta4HlZkt7thm1WDBo KjST+Py/m9006d/JlUD+Zfo8gX8u+yBptXJII9fa5dlQWgubBgkwBtNVYzCGhjj/dNbD75y/wwHP QxU2Oz6oOAdgifM5kRjn/BGmeg87kEZmqjOR+YHonQn/Ym8pxNALAqOER4WjgR6BjZp2AJ3ynWPP cj/IzHF0HB9nTsjMB+xe7hA6iA8y7DZ2K/cB2ov3MuzL+HV+K9qCtzDs0/gpZg33pPBrxLbjJexK 36Pm04idh+bhNna+bylipwqNZGHcKc422ZHMWN9kNBFP4dlBeLBQK45CV2OWOAKmUByEmGHiUl8H gzmW4RFmGCi26ZpXFbvaGci0mUQBSYDcYid4xuR58jQJ/PKAaQJgEvUjAZ83oWpapU1iZDTHNf/X 2iFTGN7OQ4uv4GnfQAdRuKN8Dy/wNO1ZyoBJ7j5s8B7mdIVpm+1mh8no5KHTPGoyJIY3LXO6uZtc cuZO9DfgR/vefjOjZVTBXMLALSYBl+FC4XJuAISGdbfSUs+BsNv1BHtoFN5fgkZTHbKaLpgV1So3 cJHU/pw7pbYu+8oASM5Nq/NEibZ5a9kijaYkjm7Vas1+UoxCSF/MFwhSUwU9iAT3NdSpvAFzGyJ4 8AwHVvTOmdi86MZpc8NVAxZfTwzVmU8m/XorPHR+7pP3jLA+1/bTLN+roJ7Zif8IWLLgH7QnNuEm 8Rh3VDwqE8MEBYE/Slb4T/IT3BzaPdROu4coSY3Ec4D5iX0CjMb8Z0CwhXYBC2/BzzoRRJtXYajj FJ6D2zGDd2DuHfX10rRvPdvae46IkrY1U0/b290MUkScqXTpDayEvvz0IxoOHz3rvLjwD73r4Av/ 66xZ/CEqhq86I5wqeAy+5lztDKTvvZy8dzvz3lfZd6RUGn80qnSDgU/hJ+gTvFuVKJOxil8lMB9g SMfDyvxnmjCBILS3MgPTxAniKvGIyBwRz4h9dOsEAD9Dm3F6fDYZRSfGIFOhvUeZcIvbdd/q9mb3 j0MnwyJDoYPpJ7VhPsSV6Uf0ivPAWXjzQ39ANzu39MA7Hv0I9jhNcBf82LGcyfB9+Cnd7Q3gNuZh 9mMgAT+YZxv38ks8S7yYFzgRjJbk0f73cAIYQMIJ28O9z7LG+zrQxCgty4cTt0ivEk+wAwa3yZoZ NZFJ7tmq/1V5TocClXBg172Zjubes13N+rnes2ebASW9ek/o58h8UL/oTkGsprqahCUcX3nZKcM4 R1IlWzuyG67xL+7tcv5SUbKFXpiLcdvxfS/jR41JTc53/WdkJDyexSxjd7oj+ZV9hc9rGoauKn6B F2lBDJTIezdJGKcvlUdr/jN+5CcDEgHxCUvBaE06IyGJrsr0KBS/MocMJN2B8B6cSPtPYdBW4Ggy 5kxyage03nHH6LYsn9DJGAnI6yLa1dzd1Vynd/cf3f6DTBoifUKGHaOjpKPNv/x0MYxVFG9NjxPl wLyKkq2rIg0TzMXsTneo+rWTYaD/jFpdmtOZQKwuBnPs6gqXae5hGcAmkMVSehfWIMoys3EQhykW Q4QsDEyqWkii0BbTFMuYzSgDXDHEKxns0lQVGdx6KbFyeVEUiS/dMv8KN2HCFKazJW8ybxEM0QkU MMsuFsWQUqzUKqPld4UPhc/R58q3wmnxgnBBJAtEElEnWeTvHyGmdgfWt9EsEf8+RxvTDeYt6SR8 3y3uBGH1qYtaFO46ETrnelvqgPs70an5qXST6m8+Fhw/pO2axcU7Wu9dy3ZOtJ9csfbJvr7+TkkU AAWAruAbM7VuKgiBA3blHcxyZpkfc8IspUPBTdJUucmDK7IapAYDC3JIHqRgGPIA4PFEJdmUJBm5 DRlqKGQHYWMQBoOSCmjlpiKjIs1DnxssSkKRsk6FUXWVijaqUFV9RRyQPbKkp7gWjgQ9u6VOCdGt NRolLNWFpSCnKjjLCFa6NmtgihaBw4FGpd5dSUPOyiSBAqCOPtL+SAIK9P/snKIRA650SwUBrVXj Yexi+SZaNbz7m+MPOJ85X/YOhEMY/+ALY2HpokdmjH9w4d+Yvc7+cR8vO+ScZnd+fyGZf0/jqJvp 5xJkOiKJ5OLu9pDTyPV+d5+FebYvBOpxE7FODBNlgUlQH0qX9hVBgBgWFREMX2fnTEftqAMdRT2I pU1klHAhoFzfTRQVUd+0XfFUsXUcG0zSrF3SHTMZfXMXGeowMmAy6MtTGzGeFhk/w1QNvPC985Pz OXm/54eku2vYF8g7i4Lv7V/5vYP5YbHl3Ap+qfyI/iSzNvy69rr+uvFq8NXQdnabfpjrjJ3m/sr/ xJ3nvzfO+UJYMzSfjot4GKGfSRCKmP5AMOhDObm50BcMRskNchPm5kajwCS/Xm8OKkLTc2BOTrRI gmTA0dzcUFEoKBCk0y51SD0S1qVh0nRpjsRIEhluFFZE7WhjFEfrrGgwnbOsg2Rqm1uJQifT8SMg aIJOLqhMpkCYnPWnuPq5YLqBSp1LBKfpYFgOytOkG1mMA6trhqJKgvQoneuWigYJnChMFFL+7SmY XHz9TbfcMbfjqcYRA2qGFLatvG71AIwXOx89gGJFDy+noux9qv6NrcuHfl0w6qu1/oovFNmphB8I U65HvYsosviy71v2SyJjH+i268NKWF3LrGHXGmt9XIMwFawBayAzEtTDUUw9y4wGoxlEUDETBlhl NQVL8GJDE8txUQMQ8wxocnD/diI+jIQijVZ8S6JK+xAVdLVdYEAGYRZwhlnEYGDoLfhAhpQAeB05 9FFPD++2vX5gQAMHjaBhSqpiQuw3KivJj4vYUsQsU9Itg9WoftFvnXbjdyfTtdD/BtvAZVVONJNP VS6GL0U71TXwNP5f50PnfyB27tiQe/Pz7ZN/UT1BW1BM3u/On0Yxey/8c8WROwPnlUOKCsg6yvR+ kXWUBPQ6UwNPrge615macXJd6V5nemHJdaF7nanOJdc17jqc5NzFhd1esr/ZDavFDQK6XrhOfIZf LTA0dU/byhji9GhNKM/HJJFYLZFKPS1/OhMyMGUZsCTSJdIvEsQiHtHFO7JIkgVyydP0LnlGxkqR KBHpy7ou9VEXSUKSVXgTkTzdMwpVyLbcKGO5TpGCOCgHsUJwnNovelfNU82p5kzSi4qfyj4zBcnM +ibKTg2b/q+5j0sHRHO76clITwWsxPkk/HwMJp3zqAbyBI6cX/TY903nu9id54cwe88P6Z0Hfwkg 7SLhWCKnIDhvNy7XoaTDNegHD2pQmvh5PBZ1IYgCVlZOlZ8+mPQBufoJg4EAGbOmKbqXRAGQyC4A THJPJV5AU0zyhJd2JlSJIs0cUSFqHqFIVTwaOQ0GQkUgoGh6MNiiHdCOaPgIua2tI2d9GqNRnZXD gaBG/k5StXC/uFw+cmAqebmo0nLKYEtATMLFhhNPphsIZNob9T11vEfPWIc9STfNQWvOWqlt6K9n pFF7zNdPMDwCi69F2Df75288thwWOx84hx765snOP+WwO50HeG1c5diWBrTgp1Fo+FWvr7ppcdrK CqVuNcQge8Zt+DauDbdxS/BSdgm3lhGamCZ2MtckMfV8vUR0EDMjcT0xBiM5Rlcr1HqEeYL8QyAE M8p5mSJeVE7aAckLBIQJaY20JZk2O6Y1VS+iRAHDYaqaPNFNIDNY4PV/00Xai8UHMa9IIp9Rxrr+ uu+xm25vnGLnYCyLLfwB/giPjxB8x+t8H48r+HX0Bv8uvBuoBOBTs2HUpqZeUt9LkzLQnZf+uuf/ 7Ij8T929pL7p7ydhqXMBroAMUWMHroIcTDj7f7y1X4WZvbRf0K3aYe9x17offGqXz2eXs4j2Rjwr /pfIVATrUb1CAr0QGOzBhQLyE11UlIxUsStBzV/kbzShacp0qasKvVfornO6qt3OknVk0BAo/yrG gJz2U2SkKbeN4eJ6HeZqYjMRyCXvvJSmf0JXzbezGB8b9xZ6RJ34ToY8aIKaCwzOzIX9FMPDMJMl uhSsxGMD+/tMnoDJe7pPfdvq7He6SKhyCyw98fCY+x/9G/FPf7p2z2PHnHM9z1x79c1RgPo+J+t7 oLtjQwTW2rdNk+En8gHljHxGYehHC0wQJolMH9fH9wn4z8Ix8RvptMy8y+/nv+T+zDP3+Zap28F2 yDQZTb7b1ftUpsHnNp5gJiEOxoN9DYBJCEXyLeIvREbhNF4TggLD6cKOvm/tuByQ8kU9ghHyERsb TdtYYnKiyGeSe4oSYVa78ZAvy4rYERSJAEEksRFxdOmtIYq9ZDaADyLFh/RgUcrdyUBrcaknfIR2 oa8jZ310Hw149+YcFHQBILEP7lzA2oxlAL3peaHBgzspvV3/Ejn0m4mlxD64dCQYTA1Da3N/5yGc S9meBAkaiE5W19Dd10CMdRMOgcoYN9DZ63yxKG/xUzc7Tzsr4LP337DmKfKHQbjwrz+8MvM3MOnu oXELHNvqTIF/XhnJ+vDh96D/+5tvH3kH9VyZGnniua4G6Z2VTrFD2fMgAhLgTfu2uDgvRlYy7CyG jcU9xSihJwKJIBYtrjBsBQoZUY6LedlErCrBaYkwiCdoQz4XTRgyJXnzCjzZBaaHpj09dv0gjz1y UItnlWejp8/DpOubGz097nY+Y21PsW5CYFpmj4nN40XEGDRTg0DtQjcNsitTlGhp7h7W3VqZquvf FqO/zoJY0UoP4slPOncOYrQK0+ulu+e4yc10+xjHzN/L2g++8dyK+QM7On7f7exz/nzC+f63/3v4 0K1lvQOXXffwprm3LX+DPf/gAwMwKmibM9M5eMJ5AGqdB+GnkB3BIvP82fb5EL14++LzdE+SR/pO EXgylGDwCInBl9jXv6K/YqBZ8qzInMTrdEdrr5fIRwv4vN54dnY0nFD4aIKT8wqmZ2rrcKBAyy4Q qffZpWFNi4otIqLMA9JFCESL4Nvjhel+ZqJaaVE0u91yvbRZKSMKKg2qVhla0m1GihEnQlPo9Dx+ caMbHOjf9AY/P3Pm352+HgfWwysOv9nW+/hX62dPnLT8pWL0s1+23DT7ahSM3jt50e+//xJ64Pw3 Zt+ypGzcuME1i5zPFi6pqxs+jmZ7yeijZPSF4L/shmFFb4AN4ss+Zqm0NPqKiGui9dG2KE7Kxbko Oyc3armfHybhIIyCFDhDP90tXoJ5E/hafMjnM0qCss9nmnk78KCt9GPsoIec2d4snWukgGxYFmxx f7JcxkypylqQSs5tbQ5VUrFQ/bioJeRObfrR6O89aCbYJOF1hcFz7EV3y/Z3F1xqL4D7L0yBI/72 8U03OT++XVFxy8TdZdBTeuGbr//Y9OTeP5aXjxmzFv1YCsObFyweM+bKkkikZoD9fOn65/YuuG5h w4DKrPDQ0iRdSfeTlQTJSgqAPPCKPdDmZnLz1Jc55nZ9vv53HtNd1a5QGwvaC1iTD4RK1BUqI+VC wxOEtEwiCwR2wJfs4RAFEx4+JyHIinWNtdLCu6xPrT9b2LKMNjargHjmdoLUsM5WsI3k9AhLvnS6 sYAl9xAncTyfqg5RnFaiOb306PZZUncI3R70VGYRZeoCaiotr0ErLgrSqhN0ZeLLS++2QNcQqquc BpuOOr9zfnXQ+SucBpnrnx6Gn9hib/j9PdP+z56fsSV/dC44x53xvbu++wuU4KKamiEFT93hDHcO v3D3vbBh3Q23ULuTqYondqeBRsx9nxBPcQ1TCKrgenvm7dETFppVPI+dx93vY+xqYvO1pjAz1piQ aBjQUMXUBiujlXnjWKYwXJhtRfPzmATM8yMpEKpaC57z/ZjH4ii2+NhjYHkVi8JZWbAqm9h3j8ka Pn9RfACOxCRqcrQJIpwtrhcPiFgUJX8ZvRepKLVLUWlZqQWziGcAJnlhPI4MIzs7vAONs42qFKKf rGhNL4Udpevd/TvH2Z4yCiXbJdwhrSdROL11gyiWQcAVxSyLgNYs4uRNye8nJi4rolsFFrIsoPdF YDRSEbk6ckfkwcgTES4SiWkm3EXtIOWfW0zG1GIQxKzYrhiORYKmJOLq2CDiWoKVNNNF4Sl1Ks0U l6ea05FPqh+wAjcoGlZXR866qQY0044c6oLqqK0wLnkhEjVVhlLNXeRA/tUuumpcPuyyolzY75Ey ULa6+nIoS4EssSgxX55bCFFN/VSiMN0ESYBuIIhZGJle31xXP3f+grxEqrR8wK3Xt5bOdP4xOVw9 YoZzckaqqqzH2QdxffOIwXFJjVZWx2aMXpjrq6tiCp26ax98ZvqLqRm33RTMft55AV5xwyCnBn6Y P4Kc3zWzgamZNPGWihcbf9t2BUusUnbfKXyaWKV8cMTOHSLC6fEN6sv6eZGx4zeId9K5HhaBEdtj VEVo8YGvj9iULNqMDvpoafuVeTCPmhiPXkVsUcI2MG9oXuj1TiBBGn2VSVsmCjVZ5KJkYr1Uf8mX 4fVqBtxEkK7BBQvWK5sURAI9asKyWriFHEpxE7hVXAeJtd06qU63PIpSR65BpzEc8WvkQB9rU65F J/i3NW3L0kd39sh5OG3oSbScMWmZTaDyLRzvt+41/eU88Fd/nQ3H7nrv8anX3nXigrN0LFQr1469 efrPQzMnj7i2bjYmQY+6fsFtj5neJdc99BEsjjw9dfjooRuNxuqasWSlZrLKZKVOcbGue812omp6 DYPgMJxIJJBrG9CK74ofiGOyXKBmQxh/l/wN3fY32Uw/pGksAMRT0k8G+Ke9YTvaHkZL2dXss77n A2uD7J3G9Jw2dq6H+X/sfXt8VNW979pr7z2PPTOZIY+ZJAQYSAIhPBISCG8ICCFABIwhvPImExLy mMkwM4SJp3CtD4pW0INAqQettVatV21OCtZaa60FH9B6bSko6rECvuoDrcf6InO/67d3wgTRex7/ 3Pu5ZH3Wb//22r/1W7/HWmvvtX9rduYOK8FQb3EqVjVVTUwYI+2R1IVDfM6fmZ62P+14MuFpp9lN Ixp3Cm+KOzklxZ0uSV42NJmxoUPSOM9Lk2rT/Gl3pj2dpqSlMZcm4bnPKomRKEYhBqG20/qilQes 23BrtaYkJbuTR6UsT3khRU7B2GQu11BpObrHLRlD6fE6qL/yyqsu1AcXvGTEE8fRCyHhsSHTyXmJ 07+2SxQPdf1vgPSRU/RNI0eaIKXXrSid0bnt9iVjMsePyayum9EysbHv45Xps8sa+94Wo0Ca2vRs 9dMjp+1d7Ez6sRgGNXl908Xs+Qfca1yw7RD2anHlIdNh6Yh6xPS5S11kamZ7pUPSIVWdOmRu0iJp kaJMkYqUqSY5VVnN3lZku5pgo3c/3oF3P8YONkUdA6PJXMtJGGO12R+VtOLpd+Lhzma89XElirc+ LpdTBHa8co28Vd4pq/JO111iG89qV4trq0txyR6Xx5WoGW96qmGni1/0YN76T7zpEV+tkcVNm970 FE2VbpB3vNF3tqdvT2TUfXsWBSbMyFs8yyved8sl5//X3d9P/dBRt9v4EtVXsJBd+n5xj2yR4Htz qvka8zXa98w3a/vMz5s/NGsWbkG/08xpUipPV9PNWUqW+QfKPnW3/V52n/le+xHTs+bD9r/K75jf tLxr9WxL+KH5kYTfs+cUNWK7Qb7ZfK3lepvqs/nsAfka8yaLul5uM/sszdYWTV2llGs+qZEri8SH XpSl5nkWdbJcZJ5sKdSUfFO+eZY2x6Z4TZmWXK2IKeYJ2gRuxp3ELLMc8TFQuajYpn8NVMNTlE2c L7azZLtd/Pcoi6yqdpf45AY81v8j4xyTqilm1aTZ7GYTs7tU1anvjPOa5mI+Uk0222i7ZDd57B7h msI86sPGp030V0D9NxJ6+8n0Tm98bjh+g/84FElpeXl5bNo04/N/NoVjlaUVWxMmcxHYtFNgs3rN oH0wFD8XgWw5M0nKlOVMqUCq7pAekFae/uj2vo5zjfs+VEafH8Vf+/JlfvD8Ev6787PhSTwvKO+L /ROSuzh4xPYZ+0yWn5GfQYc/YlUwr5gOWZ9hyl7pdnWvZa9VqbSsstY69jKlRF1kXSVVqkqRKrZJ LGJKlpptGW2FtbPZaIk7Hanyww5ZxmpREd95ksRQ0MPNmEK8+ordYhV7ykfmYFmpmsQH2RWTTdPM ZpOWIzHNhlPFjFU7fTXEs0j8GuZD8SFSp3mumYvPMT6ChbzYdKwtx0i6xW72YA2vf4K0U993qAcV jLWjq/9DJmIY5MW/a7/UZ53i7s9ikFCWcqWMCummCinjjb4ztX2h2r6zmEg2S9/78mXpib75Yj43 dghjfi+nd5fLYV+xi8jMflw8O1udqnKLOhoGGq0oIl5lUeTBs4XxWyFZRtfU5wzxLXoXL5f7jSBL H8oxmTvluTIqbtV/UiR2XpvK9d8KibdBX9t5Hbfx+vysizdeD/z2v19ZaZL8O6j4SF/oEaGiGP5f PRaL9e/4hXZX093L+E0vzkvo3PjVBc5X0LmxSwLn4r9ZY33XV2eW1T8xLG3ZJCmz+JFs20xbgack 9XvZakS5UXlw5LlCJcfsLZycvzh1RaFqtr9QyNNGpuVyU5aS785y5yjSaBuGaao3weFIsyUMs0qp ciaz272OtGSUpDGWkzdGzhzjRtcYO8Y6bIzLZrU57Ak547NM6VlJLM3uKMhJczq8jiscHzq+dKgO R5LrP7b72muSaAN2UqErSWJJ3qRzSXLS2QKHx1FAM7Kxxtb3X4s3adX9E7NYZ4r729y5QAiMG4gv sv5fbNE7TT3QoXujU49w6TuLGW0s1t9luujXtNKF761yNR4fsWn9nr1H+l44sas70PdW29bI3sPS xBfu6Qiev3tVWcP++tnV9/D9AqudW/UT9U99cvNHR/v6+lpuPf+WdKbq3FEsM3bdwjO//Fvb7vM/ 2/ZPfefuWL/n/M+6r+37CD3A2G8Fj66j/r2975DSh/49EoZZdm/aM2k8jWHCt6Xafyr/1PmTlHvc hz1nnVrEcdD5+5TDbqVSfOfEUZepTHXkZ5bwEsdeu5plHe2YqslWTL5jJNk6QhrhSh82WXks9nc2 Inau+Lo0zWV3OLx6OBLPKEvdnmQ8BIsNcHqAKs2ckXh7ck6yxy52TTGTR8tJceeYczNsyZ4Ut93m 0CSmzBsxwq2NyrFpHjcb4XrY/Uf3h27Z5V7urnXLbqcm3aL9RvtQBLK8Wq0ma/kQA6SeER7NPWKU cPAsfUOcWCWINcKFt6RPSq73+1+Uimn+ff0Vv/EWe4gIb50ZcuGbfDde9K5qXOJ0adq0cRcWBfSu 0PhhudgjZ6yuMa8P/H5/qjROGnrTkDlzNvzcG5CG7ksYv9JcGHh7xZOe9b9ed+tNKZjpQ8uypk17 Yg9PP583zzMyg5//d2mxvP2q8js7J9cLzz0PT/4WnnOzZ4vnp1rfsv/D9g+7YrE+y57lz7qVE/aT 7nf4O27lp+q9iUfsJ7lSnLqGrZHqUhUrxp5mZQlml00MPA0DTzM/Kk8tnu9y2TGBCxc47BpMbXfI XJKTU9xM0RwuxZuXFEq6H6MmyeWQKh0Rx10O2esocpQ4ZIYRyR0Oj3isqQ4ar2AlT6Gn4BtjAvQ0 M11EAWZdeKK58OZfHnjzP1VKkLwT3VVVV5fXSemY19bdsOvWB5MVZfSfW7Lnzx8lPY35+6e5B/7H 4jXip2h4Jn/bPAWWGSNtKP7b9qRtY/dp+1IUj6fFyncrksuZIOZqzMoXOqUnNdV4fFbE43M22GSn jzCPwlrNbvTJtFQtJzE3w5w7ypZhS09OzZqcJkB2clLq5PS01JQRDs3lcaemGL01O0XLgQHdKSx7 pdaqhbUbtP2amq0VaSXonFq2qynlmpQbUvakHE5RR6csS6lMkS0pQ1K8KUUp51LUXSmSM2VbCk+Z ml2Z3ZQdyb4xe0+2aUx2fja3ZKdme7N/lK3sypa2ZUvZmifFk+3RUrJzLvTxziBsqUOK0FbH9/WC C119nP48KT7Hx/qntQtRAn2PP3yVEPd0Ex/I8UynXeHB6kv297jtoRd6fZGUcbtzcsGV9+eEpeH/ 7JyVt+xH3mvE7fjzYfc91nhjQvkvN1yzawh6f2lJmrdo16/4qPMrFnrGTtu5ny/48uXr/6Vt8dp1 3/2nohX6949NH9FekgTmweN4A92PTSKimJd2u+cQP8FPON/ibzntizzilckeaa+yVzVNYeKRv8iz kC2UTIt4SUKJUzZLrrRsliVlK9kek8njdKoXdp6o4kMMSnJCgmI2PSrPLnbmuD0ergd4TDkupyib npCDISWL1UFSliYCxKriZLKS4BL/keRh4XCnCAO75Ltws1+eICXckip7EjxyGnwg7jt42JxuxB0H Ir7v0yOPCLK7zg9EHNk3P/non2aqvvBBS1oKZ47sf9mZqR6XMk73nfnqCmlYjVT68MOnXjzvk644 etdm/4/2i2cEPAqVXnfdnUd6SxcvmCbe2S3CDLNTEf+/JokdKE5P5VOVRYq8yCbxJAwJm82rMQwe EbeBDbTEpCSxRyfHbiOT5OChMceZhYdsG4wwt/9hWzbN1aRV2l7tXu2gdkT7h2YarU3VlmknNEW7 JVnzmFJgEroL64sj/fZ7USzn4i/TUtDwa/riae9SisYryVl57G3TMWUOfUX75eLbmzTpxuF7pUeZ /L3kmzzXp8vdns3Dd9i2JyiblS22roSuZGWVq8XWJctFrMi1yFXpUHLlXCXbNcajaB7Rh2S7bMey SeauIZKc5JSGDPEmsuTEROZ0LRVfSBuSqLEcyZQxBsvdMXZbUrkzLcsqYa2a6GLOgAiqJPb/f6K7 xGsWj9Ur7kDoIonT47bZuPRPxM2l39MOMgn9Am/wz+704FWR+Niz/gOyMZnGj5z0OACXCqX0VScL pVHHj0mWvof63j98Tn2zqu8tuau24rY969Zt+wns1vD83/7tVN+nfR0fH+1bK/2gqkuacsDn63uf 8dhJ9JTn0VMSWYaUXLw2z5xr5we1Q/bDdnm/7Q77/bb77coarZHVDd+iKSO1kbYppoUmrO+85pGW 4uGKLUPWg1Cy3ePEOsKrR6VMFovXaku2Wm2a2YZHOavYKjm7OGVoztDaDH8Gz8gwglSaCFLhysxE 9L/ULKfVKSJVSdy10ynlOZc7/yhCCV5exBfxrfxOfhc30V7qPLGXGisRsc3HQ1vlqwuNXhc3Bqnb xYesaDzSwu+iuZGiMGlicUI7X6SJ/T4Qj4Ejk8RLDvPIJD1oVTTSk5lA75ELlec/6jtdvXxm1VU/ 77v3w/mrZl3/hDTuH8+3LFy07u7vioEp3TUz8O/S1FV55uuDN57pVZMq82cupf+MVmik+9hRdlR6 jf8C6TMsLLYPpPvlV5WZygG1SyRT3jekk+a9llFIP7dmamZtt834s69z3OT4MmFrwlZnJdI/RHKd +3pKdCHtTypMrkiuSClFeiPlDfeXnkWpu9KCaZ+nP5D+wNDpGauGNQ+fKdKIzd7v/1+b/jay/Gvp 0KiC/3baYqSnL6fL6f/pdDSzPrMl82B8ymrOVpEc2SlIw7KzsycY6bejW8ZkGunnIuVcm7Nj7Kix P8rNy30i9/C498b/8/gfjj80wTfh04mn8r6bd1Pex3lf5PN8LT8x/+/5X046WeArXC3SZOvk7snd U4ZPeelyupwup8vpcrqcLqfL6XK6nC6ny+lyupz+f0j03k9izHSASVKqiTEL28VklhXrZcksOdbM spgMPItNJXxGbCcby4bEhgFmAS+kq4VsSN9ngFmgmQLKU4AzAKeCshkwi2ABlSwA/VRWQrCUYBmV lxO+kvBKwlcTXgV8BvGZQS3OAIdTgKUEy2IfAJYTvpLgaoJVgCtRayerAuzlM/hClgZYGtsPuJRg WWwS4FWEr6Wr62LHAGsJNhNsJdhOsANwJp8R6wEU3GaC21nApQTLqPwqwtcQpY9o2qlkC/BZVHcW ah0DXEqwLLYVcA3hgnIW9xPsBOVsSL6Vz0atfYALUT6bWpwNegHXEqyiqzWE10KX2bxB1OU+gk3g PJtvINhMVzcS3k4wTDBCsIvgFsAF1MoC0msBL4PkC/hVrAmwFjwX8HqiaSa8laCQfCHZcCFvBywl TUtJ5lLULQQUOpbyJroqrLEE2jHAB1C+BPRbARcSLiy5hOiXkF5L0K6AzYBLQXkMUNAsBec0wLXg v5TXEV5PsBOUZeDfw8tIkjLSqAy2EngtwQaCjeBWBlsJ2ESwmcpbiH4jlbRSSTvhfoJhuhoh2EVw C+AKkqSSJKxEiz2ASwmWxUT5VYSvAVxLfWMt2W0t+XodrwO+DrYV0EewiaBodx21u44oq8jvVdRX q2AfAWsJ1lF5PcEmKmkm2EqwjcrbiUMHlXSiP1SR5NWwFSBxrgbPHkDBs5p8XU3cqolbNXGrplo1 1FYt+b2WryNYQ7COyn2ENxNsJdhO5R2E+wnvBLc64lBHHOqo/9SRB+uho4A1BGsJ1hNsIthMsJWg 0Kseeglc6NVIPBuJZyMkKQRsJ1xw9hFnH/H0ER8f8fGRhD7i4yPZmqjFZuLWTHo1k0eaySPN1NZG Kt9IlBvJdxtJwo2gfB5QUG4kylaibCXKVmqrldpqJWu0kn/byBdtpHUbSdhGtdrIF23Ev434t5Hk bSR5G0nVTn2+nbRupxHRTiOinfsJinHXQZQd1JafPO4na/jJ436SzU++9pOv/dRb/GSNANEHaAQF iDJA4yVAYyRAGkXQ044BdqLPdxHnLtKli3Tpgi7HAH2ENxFsJthKsI1gB0E/UXbGttI96mr5Xdoz Jv42EpTpzqWJ/5ZOOGdutt3AZdZEVAJX2KgBGpWlshcM3IT72dsGbmYNkt3ALSyfJRi4le2QOgzc wR+QPhP3Svqbotxt4BJTldcNnDOb8qaBy6xQOWHgChsyQKMyu6oZuIklqm4DN7NJao6BW1iqcr+B W9lCdY2BO6SV6gFwlhQZbQ03xQxcYbmmvxOuojzdPNbAFTbaPIxwE8qTzcsNXGFe8xWEm4XdzH4D h63M6wm3EJ9bDVzwuZ5wq2F/Hdftr+O6/XVct7+O6/bXcd3+Oq7bX8d1++u4bn8d1+2v47r9Ba4J 3c2HDBy6m39GuA3lWea/GrjC8s3HCbcLXSxDDBy6WFTCE6h8qoGL8nGEi29vjLJUG7jCJlquIjxJ 6Gi5ycChl2Ur4ckoz7D8TwNXWI7lR4SnCHksxw0c8lieJdwt5LeqBg75LZ8TnibateYZONq1ZhI+ VMhprTZwyGnV5RkmfGr9roHDp9bNhIv/QJZq/bGBKyzLupfwLCGn9YiBQ07rrwjPJfoPDVzQnyZ8 gtBXSzJw6KuZBW6Js78lzv6WOL0scXrZ4+jtcfT2OL/Y+/1yP/OyAvSASWwysArWzHw4Xsn8rAM5 xLawAJVcgbMgcAHrUd5CFBNxZR5rQ/KycpRtQP0Q20RnPhx9oI4ANoLyYp4zUDOIOvVUez6utIHO yxaDQpS1sPWgiRCPTUZ7XjzpToSsRcBywFHQBHFlE3IT6o1llZegF/pdaGvCQFvxLV0J3ePlaSEt 6pFDpHEj+LbjGGStKBOt/Ves9XXKigFsAdFuBm0H7Ohly9FGE8kmrk4gm/pZA133smV0pZk0qYes 41G2gtoK0pUWkv1qwDDoGw2reGG76WwaLLIGNcM4FzptwTFM3hLaNhu6N5GsISrzAzZSeYDa20K2 6SB/BahFnXK9UcdnnNcTpwC13g6qEF0TtRqIR8iwYJuhZ8eAFHqNfjmCcbQB8ngjJF5Pbej22Exy C4tcWgf9XNCuR2thskgj9d+LLSFqtBGWA/qxOArPNxhyX5p3x39D9wvcGwd8H6TR0+/L/v5zKQ36 W/+6XDPjfCQ00XUJUXv9PVPw13VtRMlm0txPvf3bekL9IK/7yDt+A+pa6XgYZwGCXpI2MtCbdT6C sg0U39aHJt7vLcifNNlb0ezzXunv8Ie2BHzeK/zBgD9YH2rxd0z0zmtr85a3bGgObfKW+zb5ghFf 48R+yhnzgi31bd75/rZG7+JQfVvL+hkRX3AT6nmnTJxU5M25smV90L/J3xQaWzlQXpBPtSaIWnql Kyt0Pi2bvPXeULC+0ddeH2z1+pu+WayBwgoBFgTrN7d0bPAub2pqWe/zTvCW+xtaOrzLWtY3+9vq N433rqgPBVvWt9R7r64PdzRCFO+k6dMK1vjD3vb6Ld7wJp831IzWm/wdIW/I721s2RRow4X6jkZv INiCwvW44sOxfpM34Au2t4RCvkZvwxZU83mhga9DsMAFwSNIpYGgvzG8PuSFHJubIUhcCzi2dKxv CzfClN5+IfwdbVu8OS1jvb72BvCOo+741taJvFFoH/RtEloK+1xoQFQf4DWTNMppQSshX7swZrAF rTb6N3e0+esbBxuhXlfdF/RCIz+aAgyHAuGQt9EXEWYGTbOvLTDYQhMHTfPL0M020HALUbdej+6q 3z4iOI+nDLGw5ECXfAd4K1FF2ftfo2oyBmVrHJ/46yXUkujmSy9NIW+Xfy0/Lf8G8Oc4u0v+lfyg /K/yL3F2KblbDLmv+Ea5y4A1A49gWAnq8EVti9J4+kU0MWwadCPuBL3vIj3ewbGVfQoO79Bwb5Su Qknokrw2GVr7B26N/W3HU1cSVbwuPtgznqKUjhGy8rfYEDdCP1knTLdLMZ3Ux/lkCya6+m+0pt/Q /K/GTWmQjOIDAcpM5QqlSJmmFCuzlaXKdJSmo6RYmYeygkF8K4w+89dv7TMl/wdtloqjNElM81L+ gE9aL6IRfTiAUj9Np36pnibcjots3EGPaC3sXf1GIw1hb8iZuCEM7jF+uhV5Sa4o3UTqaU0W+wR5 DDvBLv0nM7GKsTEpRuskxq7kvynm05XRTCoW3/JiV3qN+VjMxl6vN4Y/NjfWN6+8bEl+vsyKjbej DGtDKUsaT1/AZPxmJvHv8x8wme/n+4H/kP8Q+B38DuD/wrE+43fKZibJFtnCZNkqO4AnyFjTyE45 G/hoeQzwHBmrPXmsjLWanCs/DvzX8q+BP6G8jOftU8opJiuvKH8D/p66mXG1S+1hsvqvai+T1F+o vwX+lPoU8N+pLwL/kymLSaZsUy6TTeNMtwDfacKKxPSQZS6exostWO1ZFlhqgNdaWoBvtPwb8Nct bwA/bZWY+NEmntytJivsZbVbIa1V7HyVrC6rC/gQayNwn7UZeIv1YeCPWB8F/kvr57CQYtiJs5Gk ta6vrqmhI+TfDml3qN8HfosKCdVd6m7ge1VYUr1DvRfwQfVhwEegqdDxEOCjKlpRf6n+Evhj6uPA f63+BviTZIHD0F1onWPoyKFdPfAGiw96NVmaSC8ZcipWheQXJRusG1DSDF2EFr8APGg9iJJDVrRo fVToZeijsaDUwJT1W4JtLH1D0NfKcpt9DUE2o60+1IGBIvRm1LvEGt8ady5hrasNnIuvTWLNX1ZR 6sUqWafgWPXaDFz0VDtztPqCHWwFwUqCVQQbxN2dNRPsIHgdwfsIPt7e2t7KXiB4kuDrBN82dLg0 5PRmQRzF2wP6aj1k0Jj48qQD628njkNYIktiySwFMnuwck9j6Wyo+H+8oNRrxte7VJkYffZvPGZj aFewKgxuMVFfw65jN7Pd7A52D3uQ9bLH2dPsKPsze4WdYR+jgyZIGWIMSpOlJVK5FJSi0rXSDuk2 ab90t/QAOKJ9qUnvia4F+jHrCf2YvUs/jv5AP445qh+nHNSPRQf049Rr9eOc15kCA0lzNzITDCZd OYuZ4GJp+T24DlGuqiFtpfICnGOkl9fo5eVdxvED/VjxF6JTKj9YxVe5V+XqZ6vuXfXYqj+sekM/ W33P6kdXH139un62pmpNYM11a/bp9deu1Y/rSvRjlZeoLFVfVCdUZ1XPqF5R3VR9TfVtujQ1XXR0 1Byo6ak5XPNyzQe1vNZdm1s7p7a8tqk2WnuLoGJS3QydW918/Vg/UT823K0f15/U6Xzif9yIY4Vx jrHjeIQs1MxeZl9JHB7JlRZIlVKj9ID0OnfzCl7D23gEaRu/ge/jD/EX+Gv8Pf4FZoV0eYG8TN4n H5Zflw/zF5ThymRlhvKkOkodL66olepd6l9Mqab5pgpTDeogmW427UG6w/SuebK5w3zU/Jr5PUui ZRZmry7LDkuv5QvreOttmlcr0Rq1jVpI+472iPac9rr2sS3VVmnbZrvB1mt7zvaZPdG2zZ5vX2Jv s++wP25/2X7GoTmyHBMd0xw1jt2Oe/kXsJyIec2KnZI+ivVKnyN/GevlErIWO8WdsVOwgIiHmSji JaJh00VMKrYTdZrZQRxl5owNo9iYiFMJulMG3c44umbYT3Bw9n1GUTMRG5MpZiYiZmgfo86JMhdq iKjXMOThIvaGLCJoIn4momcidiYiZyJuJiJfImYmYl9rcRQxMwe4LACXXnBZAC694NJLXBYM1O4d qC1qipiZw2i712i7v9ZOirqJmJuIuIl4W3wtJ+mqt9dstLcTNXdesr2rkStI2l62Bpmzxah9ELOB sOBOitodZKLv9Z8JTEiEOx/7BaBuwUrUWoVaB4GrfEIsjRfFGC/D8arYVl4RK4RPnbERqDdC+kzS 4NNl8Oky+HQZT4dPx7DvMhmlR+Dhh+DhhwbObsXZrbiLu0GVhZKbY6/iWiEbxkcjj2PDMDuIaxm4 1n9dEzJJ42M3SRNiN3EV2RpbAF4KeAnq3/PhyFmx3zM+0F6iNBF18pAnIRci63IugZxbIOdODk/w ROQk5FTkdOShyPAM9yJDBz4W+tvIIuiF/yEJTIasx0F1PJ6KOVHajvrtkOwlSPYSJHsJkr0EynZI 8xL3IKchj0D2Io9GHos8LvYSZn5n3xfo1V9Ah2bo0AwdcI+VCmJ/ZCMv1avR2im0dmrADvmDbJFm 8LkHfO6BBKe4A1nYRMR03bFnYZNT5MthyMMNm2SS13p5Nq4L++TgHDbiuegvqZCixOilJf299D/l BTcs9m2e4LDIY7DGY0wD3xPgewR8T4DvCfA5Adu9CvoToDoB+hOgPEH9IBOUB0GZCWsdAXUmqDPR ag9aPIIWe1DzOFrtQas90PUIuGSCSya4ZIJLJnrhEeYApx5w6gGnHnDpAZce+EzU7oHPelCrh49C Ho08FnlcrIe5UOs0ap1GrdOodRq1TvNk8vZp1DqNWqdR6zRsKzx+GjYVXj8NmwrPnyZdj4PDcXA4 Dg7HweE4ah9H7eOofRy1j6PGcaZAv1cHjSw+gNkuKYcnrn3RtmhXtClmhUL4sRCzwkHAJMAmPoeV 8XnQS0ToRbR/sYgX4yii/VdiXliGLGL+q5BFVE/EUUXkS0S8RLyLomOxYyyRIsdzQFEcOwuOZw2O ZykuLuLPV4JyWex5vhznIu5fQVyPUeRaxD5FNGwLnpkSiFMxSueJGDjJc4wi/7o8PeDQg9pbqaao JaKBnfCLBxpupV0AYg/AHOJwVo+qI4tdABQLxjURYRPRfxHVFpF/EbHdQFrtpyi20EpE+0WsX0T6 t0BDBW2fpeg8xQjFXo4BPVsht5XO+jW+CnatEFFrEb0VcVBkyMo00uyCVsIuPeB8jDgLjYRssAez XbAeeAi9xa4CEUusJ0l7KIoo9N8M6WSSbi1JlgZZRfvGmYjhol3yD2iKhbdxFNZcHteu2Gsg7C/u p0zsNsB4P4vxfpb2HIgdB3PILz16f4mTXvijX3JDV2anuP68QVRnaQdCv99F9F/EXOsNCdPQbg9F ZMn/uFpi9CCh2SrgYj+C0F94TexEEPsQmgxbiB0IG6lP9pD3RDR0E3nxLO08EPsOtqCVTLTShFaa oN0xaCc0ayLN4vuKsPYqo8/QzgHIXI2yGur9+ynCXG9Ish5lujTx/WgrJDpmSLSfpAkgBw2p+vuU 1fDKMbKn0Le/n+teEb3zLDPzeXFjSfSVVWRl8j7W0LAkZgVhT9EruRjdwh9YMRyMlZEf+kdTCenX Q/ssxC4L8j/pKjzYw0xGD9GphUzLaYT24Imhf1SWYfwYvkQ/6x+5Ij6+GdJYDducpZh1E/V63RuC IoS6gspJI3Ed9Rl9Pumv1RQ3t7RR7R6KqIv9ACHYRfhQgw/PUtxfcKmhXnGMRkV87S1kG/DESKKZ C1nst6jTxxfttGg1pBd7LPRZ5Bg07ac2xg4P0WhcR23pPbze0E2M6tYBKc8aUu6HHft5+MgrOp/N 4GMmPrWD6p416h4z6tUNstp+spjlEnZ9fhCFeYCin6MxL0Ii0Rf6bdavg059bIDfBXmO0YxiHhiP tNPEGKl+Y5bgRCdmXavhy7OGF84OeED32zGSzkRU+ux1Nn72AifjfgKsjWoUgue6QVL29wtdQl23 Y8wxyCd1l9Cl7QK12BlBein9eg3Mb+LOeAwlkEDM6vR2IhlJYllMxIDHMrE/IA9Jod/7qmwKkolN RTKz6WwGnpxnIWlsMZKNrUSyszVsLdYHVUhO9gs8obuwPn8azy7jpAksScqT8phbKsBTskf6SPqI pUn/Ln3K0qXPpc9ZhvSl9CWenMW/XBnOVa4yLzdzBxsp/uk6y+Ee7mFj+VCewXL5CD6SjedZPIvl 8dF43s7nY/lYNomPw3N3AZ/IJ6L/TeZT2GQ+A7NIEV+AWWYOL+WlbB5fwlew+fxq3KcW80q+mi3l a+HjZbwR94JK3owRsoZv5AG2lm/im1g9VqldrAHr1BuYj2/n23E3upnfzDYwKfGDpHJYyC49wdoY a5iFPB+5FHkZ490f41iBvBa5DrkJWdAFkbuQv4N8HfIOI+8yaPYg32Hku5kU2c74+scHZdZwH45P IT8Tl/+A/Gfkl5FfN8reRH4P+WMjf2bkPp2+UdEz8QJto0b0rOEhI/ciP4b8JPJhXHcZR2WgXdZw FPlFouONbuQM4Cf/C/k15DPI7xr5HPKnyF8xXrN7UGbreRxuQU6grJ8nf2PWr6eLI3+144vQK9ES PwsURMtWpofeiJb7TcGu6Gq/3X80WuM3hd6ONvoTUbLRnwoY8A8PfRCN+LM2PRW9hkpK/LmhT0CZ GPoieq0/NcxQkkjlJnDY7s8Hfgtx2+23o5XtfgZ8PyhN4GYP26O7VxaEE6N3Ubv3UknAXxROBc9Z 4eHrDvjnhz5Zd2DlkuAe4KWBAoGHs6Jl/mUrE6IPrlwRzo32+CsEjX9t5+7aHn9d5+7oo/4mKmkL 56MkGC6KPuHvCs9CyXfCs6DddeH50R7ULY0+7d8RXgaaXeGK6HP+PeG10Rf8d4Tng/LucB1K7kPd vwCfH33Ff3dwR/QN/0Phpujb/t5wG3R8LByMlpDdPvA/Ge6Cjr3h70Q/8R8OXweL9YZ3AJ8fPiq0 GARf7IcBLkqEdt0sYAmfjK6+BEwIvxZ9MJAcPhN90D88/C7BcyhJD3+Kq97wV98M/U0RjrYIBryE lxKsCH/aDQ+Fd0W/gC/2RK8NjI5Yuu2w7afwgmmzu/uw/8XwHdDxZPhuwNfC94GmIJLcPTwwLZLe nRUYDw6JgTkRLzz1ZPgh0JwhC+i13gX+if8cwU83HYDMBgz3ChhyA/YKnoPgV+HHQP9V+EmCwAML /A9158K/r0CjJf5l0HpFZHQ0ELBExkdfCVSCf02gClZ6jvrbaqEX+saT4cMoJwn9pkgCep3QNzXQ ECmAFumRad35geaQhv4z3n+0u8j/Hdh/VqAjMgferIwsgK1CAg9EBb6yEpzLAtsiS6BdBXnthsiK 7vmBm4M7uksDt0Hy1YF96L1l1IdrAgcild3LAjdHqrorAvdEGqK70aKw/wORZlA+EumAFgc7PwD+ +MrxAscIgnYBC2xyBvb8BJ6F3/1fAd8deCoSwtVnIlExpiLbUK7T/CFyQ21P4M+Evxx+V+Dhru61 K7dFbu6uC7weeqO7KfBm5LbutsB7sFJZ4OPIvugLK71E/1nkAOTpEzj6xj3rDnQqwpKdWuSB6HOE 36vjK9Mjj0Cjg5GD3cGVCcFdkOFJ9IfdsL/oRSfBoRwcQsC/ijweLUc58E5X5CnhI+rnZ4Dv1nFI O4B3uiPR7i7RJ7tL/b3g8wT5pRQtPtP9nc6MyIHu0s5RwgKdOZE/RFd3Tow8g5mhIvJn4JNDJdEH O2dEXgYsjrwucDEuOksibwKWidHRCVm6r/OvDVR1X9e5OvJe9JrOssjH3Ts6a8B/l79i5ZzuPZgH xEyCGay7orMRlHeIVrrv7twY+UxIImanzo3huu77OgOQZGNnhLS7hvBrI33Atwe7und13hIs7X5I 7/+BgzTGc0V/6Ny9Wenu7dxPNj9I9AEDF9YTWn/yv8n7/rCosivBW6+KsoCS0AWNWFYxFRr5CGEZ qhawmji2X1H1qprxR1GAIcbYxjjEuK4UVaX1g6LiGJd1HWMIoWljjGOIMcYYw7I2axjWJsS4xI8l LKFd1iaMMcZ1WT4/wrIM47C455x6D15VY7fTk80/893vnHveufeee+4955573+PxquHC4QXgX6J+ rx62QF9d/qTGnoYb/lSwTh+uL5ilxcY+d4oHxuW5HDgIpbcCntCs51ogQDTEHM915Ndoid/jPwbz XwCa99VrvEOhYw03/ToYaab/BvR409MCvWf6xhu3efoOZzV66hdgfbV5bgeOg7en+LsaLRhjwS4L /q7Qbs9g4CSuKaDRpjBjDXygJdztGQm0h7vr97h3hXvr99Qghmgf7oe2G9GmQA94xgLnQls8E4eV jR01Ts/J8BCsdCVoOBbowPVyZCA8Wh8IXG5knh6M/J6HgQ6RdhfA+mL1E0FVqM3bij7jPRpMCXd7 zwTTod/bQS2s0Hlc7w21QZhJ73mka7T+7NAsRNSTYVV9tT+vcU/DLfCcAw13YG+qrQn5C2G27/iL wYuG/WXg4Sn+zY2DDXf9fMjVMO7fAnFeCZyd9Rq/K3Ssxuyvhfimhpq1DQ/AOiM1Bf7dxNmH+6P/ QONYw2O/G2b4jv8IeOwTfxg8ORqpKrw7wA9nwRZtDU/9J8D/K/ynga/yqD973sP8bbArZYLdJzzK w/kwYxr/2RDvUfsvANb4L+Hq81+F9cX8J8ArTvi7Dk7XpNC+HDlcDRIygb7UsMXdDb7xqMbZ+LA+ H8YIO2N9ZuMk0o3boHdX6EBN+mF14zTIvwnRz+C/0TgHMecBWDYLZngBdvkHYc59HyKho74O9ay/ FsyF9fLgcH7TVe/FYEFTl/dK0NR0w9sZNDfd9HZ7u5tueXuDm5ruePu9/U28dyBohdKhYEXTsHfU O9oEO6b/aaPyLx4HnU3j3v4jqqYH9RqIJDdxv4axZAR3hG567+F6r78Otmvz3g/ugn41Hk9jBP2n Sed9FNzbGAF/m2vS1U8H9zc9dquChxr7vFNBX9MT70wwBFrNg1az3kXQ6qlPAf5wTIgh5uBR2H9h R4iwGlXQ0DgIEXUEZmY62ByNP+jPS3Ste0fwVOOgLwn9x5eKNPYLdWC3iigbyoLp0Z0L6cMT4HvX oa8DDU+DrbiKka6vDraC76mCZ8C3dwbPR9TQ1xnYL7YBrQGZF0OzvgySeR1piBJI5wdPRTLhxDIe yap3wHps9+ncuZEciDC9TadBqyuwHs0QYbY1XHCbwJ+VtA+C7SL5vmzPyUiRLw9XB44inFKv9j1o 2oIrN6yNagX8BRhRYbAz5K45enikkcEabIGa5/y3QrWeHDg71dYzsIgSPSGc3nAV/GFPTQj60sLa OdaobHjgv0N4GOrk+++GDZ4swLlUP7f+HOACT5F/PGyC+pvBsjf9DxB7ToJ/lh7OD5trnP7HobPo S42X69HPldhjeJO7oqYCotnGml0ihlXDYL201bOwFXfDMFz7nzQ6PBb/bOgm4rBTwCinHfVvbAfd nsLavHk4H3q0BBjUdASUjYEarbcf4tiugDq8o76uXhneUbPLownv8mwLaMJ7CVcgfqPLU13jC+/H 6ASR5IGnBWagIpAZPlTfXq8O+zw76zPDIc+e+m24pgJZ4aNgr6Rwc3074KMwugdgI2cgB2byHM5e /Tl3LmhSF8iHs0TIowbOcdBzT/01KN2IOHwKolNLuFXAUCe8vwHP4Xfcu+o1sO4OBDJhrorgVHYA NCkCvwJ9Qnc8BwOl4DPR02ldjRY06YCafZ78wMZQ2K0FezncqhpTaBj2i1Go7wlYwnAuCTjC5z0R 73z4IswPnIQ9xwPbYPZOBqqBbgnsDF/xtAf24AkwUAen8ZD/RLjTcw5izp6aFPDJDvCoLOhlErzi HpwrZsETpt2mxlLPnG82fL8+H/iP8AQenvIswK63r+EpntK9HMT/R0iHNxE94zYAPY87ZnjRrXWb mhTIx5gD0vq8HMQfC5y0c8L3id4Wpd078B7Eq8LTfv11GGMAvDof4rAB+mrzpsDZaQutEUvDMd9s U5I3nfhakd+USvwMSR1Fg8v3JGzywJ1CeC/uU9H6uPfhWsOxQAxBugVpiD8McHbDvsNF4V6vAeg8 b25NQVMh8fOIvzdKewuQ9pr8bU3FXnPgWuhmQzhwnegeiPaaQF9jxLspcLupzJuO+wLEpRzU03+s aTNYNqeJJ5pWMYwR6OheHD7UoAjA/RTEDdhbvVak6+uQ9vSQ/hXgz92oc5PL6wxommqj+iMdNkHb Eaizw9Me7qwpCIw0wb0V0Ie8u4Dv9u71qEN3pDTWb9yG9RsveyYDY7B+4VzctA/8fwwiQ1ZgoukA 0k1uoo8gDR6LdBh03tzkgji/B+Mw0MeW6cZtRLfDWQLOJ9794L17YF87Fh71HoIVZ27owjtBOM88 hLWz6bCm6YTXF3jYdAzOA6xxp3e/2wy+F0urIU4WAM3ceEo/0ZDkNsM66q4fbGrzhoA/R/RZpJsu uLUeddMl79HAZON1b3NgOnQXzjZzcN4YDCyEU7yngly4+8vcl1WRBd8FrzPc7TvrdUauw8o6AV6x ByLSUTgNbmwsdVc0jIeGPR2B0sYIrHTAvuJgd6TUVxbsjWz0bT58LmLx8cH+iMO3JTgQ2Ra9R/a5 Dgci1XSn2YV3kZGdvtrgkHiHG723jd7Vxtyx0r1q9C7Vtzs4unyvGrwH96p0N+rbF7zfWOQ7EHwU 2eNzB6cidb4jwZnIQV84OB/xIIZWJMd3LLgYCfhOhBSRCPYbOY79AoZ+IyeFu+k64sO9c6QFNYls RE2As6QJ8KOjoAhJd8pdeI8caY+OC+/cI8ej99cYl4AGH46cwx2ksQh3kEYNcTrwnj3S4jvtaY9c FqRBfIsc97WFkiLXfJdCqZGe6NOJ6BMD31XfeKSvXo33Wb6uUEbktvAsgu76fTdCushg/blQdmRE eOYQvbuPPlWg+3ffcKgsMik8tYg+H4jS0ecV0Kop1XczlNfk9t0KFUbGfKdDxZEJ3x1PS+Qh41gq vbPFJO9scfTOliIhkHCaJdB7Wjp6T+vj9J5WTsLVhC72p/QWWim9g1VO72A5VW+o6lh1IpeoYLvo XbE36C2xL0AfJpbD/owxZmWfY1q2l/0lK2b/DlI1a2FfZzXsAvsO+zS7BOkz7CrrZDvZT1gPe4Pd Zu+yz7P77Hesgf0PNsX8bI49Y00yTpbP/q3spOwU65S1y95l/0H2a9lD9r+5RbmM/YPcLP8UeyZ3 ymtkcvke+RdlifKw/Muyl+Qn5W/JXpbfkP9E9oq8Tz4jWy+fk/+drFb+9/K/l+2ULypWyT6rWK3Y KPsLxWuKrbI3FVWKatlFxacVb8suKd9W9nIJyneUA9xq5X9RDnNrlL9SPuDWKX+3inGfXJW4KpWz r0pbVcBtX2VcVcF9SfWa6jXuKyqrysYdVzlUW7lm1d8lMu5U4kuJr3HtiW2J3+F+ntiT2MP9KrE3 sZ8bTfxF4i+49xIHEwe5cSaDeTkAWM2y8H0bixbAAJALUMC0FoMl11JgMVnMlk0Wq6XC4rTssOyy 7LXsh3TI4gMcshy1NFtOWVotZyznoe5+fDeLbMsSgglBxiUcTThKb6FpuAKugDHOzJmZjCvjyhjH vca9xuSchStnCnq2quS2clvZKq6Gq2Eq7tPcTpbIvcG9wVZze7kvsBR6tprK/Wv8D0TuMHcYZPq5 EEujZ6trYL5vsEzFKsUqthbGNMYmaGQafBfN5mB7bQ7bNlu1badtj63OdtDmsQVsEdtx20lbi63d ds7WAXDZds123dZj67PdhnzQNmIbs03YHtombdO2OdsCz/EqPoVP57W8gc/lC3gTb+Y38Va+gnfy O/hd/F5+P38I2iyn6Wjie/l+SgNLaUhIPtsEH+JH+aP8qG2Mb+ZP8SbbmKXPesNy0tLHd/Ot/Bmo cZ6/yF/hO/H9KMV79D9wUj/H/yEoZm7w2jIWBJ+3kJ//Ofh3J9sKHv4Ttg38+122nU1CctIcVSo+ o/gscyk+p/gcq1F8XvF5tkPxBcU+9mlFnaKOfUZxUHGQ7VS4FW72WYVH4WG7FE2KCPuc4uuKVvaG ok3RButFxs7BSsJZzmYJ4DO9AP0AAwBDAKNso2XW8rQcFm65ulxTngk4qzynPL+8CLCyvLR8I+SW ckf5tvJqwDvLHZbZ8j3ldeUHyz2QAuWR8uPlJ8tbytsBnyvvKL8MvGvAu17eUx6xPCnvK78N0GcZ tzyxPAb8wHLLcscybLmL75QlfD/hh/QWYFLMbAUhFbNfQiphv4VUCqv+d2wDewzJrGhWNLNXFX+l +CtWpjirOMs+xWTq2dX4v2Vqls9WMbYdVsf2AiarXIDcBAD+7ILeXCq5abuhcjoGcivnthdULmw3 uTi6NrtU2ze5UohGvtWVTjSWY12xnthOpCtcWspFPsqIz50uA9EI2I/YF+Y7XLlLZSLschXEtEMa +8ccYa/LtH0/9L9fMhakD0EdzMV6LwKiPiLE6/JB4HOZSS9xDChP1At1wXKcH+SLOoYkOcJR6FMK 2E4EUdZ+wT7i/GE7lNkM1zgXos1EvmgLlCG2yRXKDML8iPMk2jK+7JRr09LcIk/ap6hLq8tK+RlX BbVBWszFvvEa7SnmohwsQ/s2P6e9ODYxP+9yUruLrh3vG4OYx+sq5qIuYm6S6NYsjF/qmyIcjbsW /cUg8TGxnSjjimtXTB9ibnjO+MXxGuLGL16j/6AMsR30VcmivPh8qU6na+/2btd+p8J1xZnk6nzu fK2QVypfrDymXvx8v0BO7cXr+Hk2xdnrg/Lm5etKdXTcz8vFeYmf60pNdJ4+LH+uf4nzII5D6vuY 97oOLdm83+XbPgA+jLSYizFZXINDrtDSGh4FQPqe6+iSP913NW9/5Dq1NF9iW9FHp1ytS2PE+jOu M9vnXee3L7ouEk+M11DXmerqdma4epdirZA7da5+lOHMdg0s6Y7rUIx9wKvMqTpLeX7VhcqiqkuV pVVXKzdWdVVaqm5UOly5ldugrLrqJsZBvKa6OyEmYryMt7HoU/F8sK/zbFUZ+f2e5T6WbF5Xdavy YNWdmPix6QN882jc2o73qfh4FR+XhDmq9FQNVwaq7i7FELBlZaRqHGFpruLjktiHqIs4r5I5jeEh DTZz5rkqnIWuIWexa9RZ5ron3U+dm133yY6861GMrLhY5tzimqLc5Zqh+RdBlFPrmqd8t2vRua9K 4TxQlUTjfw443VWpCNT3kaoMBNTLGa7SkX6iHx2rynaeqMqT7uHO01WFOD/OtqpitC3BharNIoh1 nZdczTheHKPzahXv7KraQu1vVLlItlgf/Mt5s6rWeatqt/NO1T7ncNUB590qt3O86ojzQVXY+bjq mPNJ1QnnbNXpmFgojbOGFfxnpfL4PN6/cuNyyb5ZmQlzEh8bpP02ryBfuhchiOskfs8W66KMo5Kz gpBXZsF5Duwt5nS+w/zDxvmcWBvjy9JcXDeGuHUUv//lvn8viNkTmpdj0Yr58/TdHzefcf0t7ZXx +2p8Lp47ClbIsX/peRTme//TLzHRVpXHqx5Unqx6XNlS9aSyvWrW+bSqDaHyXNXTyo5qFhPvpWsd 5FderlZK40zM+Vhcf+LZWNCn8lq1uvJ6taaypzpTeo7FdYfrLyZu9VVnrXj2FuRW3q7OiTlnx+m4 FItw7Qv7Da39gmicrhyszo+5x8iVxDqMP7ivSM9Dol3GhLkVfRb54hzhWLHOSHUR3sUn/Czh54yp voj/x5eYkIj/b8Wx3D/y85W32DN6jvIGPUf5vHxO/veyNnqCcoaeoHTQE5QReoLyG3qC8lvl26sq OAs9Fxmj5yL/nZ6LvEfPRX5Dz0X+Fz4XkWvxuYg8D5+LyD+Bz0XkRfhcRG6EO9qL7Mry0wPjeeYw 3jPeNz4yThlnjPPGRZPClGRKNWUA1pkUxvOmbIA8U6Gp2HjROGQqg5LNJt60xXjFtMXkAqg19gK9 27TPdMDkNh0xheHqmOmE6TSUtRk7jZ2ms6YLpkumq8ZuSr3GfuOA8TykIZQIV+eBizAKtYeMvfgk IOFr9B9usfe2IbBIE/sy3NVeg/Qq3eeWsf/KRuBOdhTSn8l+IbvDNsn3yb/INuPzKmgpY7Vst2S8 Aywbeh+CvpZHfS9m3DpTdnS8MNbNgHkaZy0kF6TdUCvJtI90PAs6rqE3Ahl4Ty7w8iBxcC+dz+Ss AJKCFbI/ZQnMyExwf13CzCwRdLKy1YyHlMIckD7GKiClsi2QXmLb2HbQFIIMSwefq2UZ9G/WWnYE 0joWgaRjRyHp8RdGWBaM/VfsT2QpshT2cSZTBpSR5bFam+Uma7P1lLHF2mo9UzRrPW+9aLxdWmy9 Yu20dlt7rf3AG7AOGa+VlRpbzAPWUeu9shzrfeNYaaH1kbGlNM/Ybp0ydkCtGcLzxg7zlHXRprAl WVtLZoxj5hlbqi3DprNlQz/NtjzrGZRqbDGOLSdbcWleNBXNRhNKEdNSrTJbobXfttk8ZbuFsoDm bVtsOtCnGaQinDHejiZrPyboBRJo1QkSr8EI74MWrWYYgU0HdRZhtFPG2zaXrRjG/0iAZuip1rbb 2opzYttnO2A9U5qHEpag19hB0A8jHYJxAqB0m9t2pKwUxoxjA6DeAGxh2zHrRZQr9kISRQAdEGwn IL8IUgGMt0FfAWynbW1gjxnrFVuqscV21nbBdgnq37Ndpf6jOnRh/9K+EWw3bDeto7ZUHC1oDZQI yMGWUKsDbFKGur0fVuLbyvh8vihGfwlgGerMl0LK4TcuaSiBlfjIs43zFkHzDikgn3eglaNA8wh9 CPqPgXc+Ki203TEulBZGATlgjTJrr23Ydtc4Yj2FlraNW+dxRm0P0E9tj21PoFwBPjRre1qyaF3k WVkR2pxX8mqcSV5j7Swt5DOhR7Ahn8XnvKowD5Qx66JD4UhypDoyHDpHtiPPUegoflXhKLNtFi1p vWLscGx28Ah8ln3UOhNtgWWOLQ4X+Y44o8LMidaW2DTqV4ItHbWO3Y59jgPoHQ63LdtxpKwI/R5K wvxDbEE+PWlssVvtVnO/vcLuhPXaD3OTjcm+w74LNJuy77Xvtz6yHzJ22H3iWitz2EP2o/Zm+ykb rDt7q3XAfM943X6GHzROGCfs5+0X7VdsSaVJxgXzlL0T5nKx7KC9295rh/Vlnip6DH0OADVjH7Ke t4/ydeCFI0bGZ1n7SwtBk73GBdsRPsfcb1OUbi7bab9nv29/ZJ+yz1i77fN28Hn7IlioGax2CuZ7 G1/N7+T3WKf4OrLGQbD+Tt7DByCP8MfF+QKvcPAn+Rbgt8PMtdO8w9zw+RTBOmDNDdsu8ef4Dv4y zSvYBFcQf42/zveAtXvAQ/v42/wgPwJxbn4JwDb8GD8BfV4Hmz+M91SQtIgQtQ/mIGuSn8b1B/rV YS7S5EUb+Tl+wc7ZVbYj9hR7ul1rN9hzeYdoV/OAeYavthfgqrSbQPt7tgwE8nT0ux7jmN1s38Rf L8E4qjOOFc1+ZkfR7OuZjmOOE47TjjZ7q33ecRY8uZkiS2dZKcz8VGkqrIQWmJd5WA+LtqRoNIZ4 NOW44LjkuEoxctHR5bhhUzhu2kPAv+W44xh23ATuXcc4X+p44HhsP+pwO544ZgE/RV96nb2ufF39 usbY8XoW7hmgL9gCo9PrOY4nOCeoN/QiRsoh41jZTuPI6/m0F37rn9EJaj9z0zNz/Foby89iMoD0 fC0kA6RcSAWQTJDM+c35m/JP5VvzrZ84+YmT+RWQrPmt+U5IOyDtgrQX0n5IhyD5IIUgHc0/it8C SHgzoR36SGA2/O0/9jr7czhXbIXTgZJVwewlwzx/jqUxmfqxeoY0or91FY8w2YZtkI9BXi03FQ9u cMTACMAYwIRw/RBgUqCRPy3QE0Ldibh2Ij0n5CJ/coV8QaDHhH7EviAv4SRlApSo4tpNCv1PRqEk ZYWxiLoOLtd7IXgYB2MvDiXp0T6XxiDOn6ALlc8JfFFHaT6yQv8TEpCOUdTtodBOmN+luRiT8KW2 jW8zGJePrcCDvEQr0XMytk9RlxKDkOdKdBiM63tQsKeYS+UsfEB7cWxCXlIg2N60sr4xOsbnE3E6 TcT1JebxtogH0V+kPjYm4aGu5uf3teL443WIz+c2LK9BsX+RF58LdUo2AVgBWgHOfMB8/aHy5837 i+YrrYGV5vBD8qVxf0geP8fiPH1Y/lz9B+PGEedfJRXLNi9xAuwQ6B2SetK1t2vD0hou2RulS/Yv j7XkEIBP0p+0f7R/SDJGrH8UoBng1IblOCH6ynmAixuWY624Jq8IunRKdBfWoxjrSk8LeRvAWYAL AJcArgJ0AdwAuBmNg3hN/aUL8XKltbjSWgUozYuOTdqHWF56C+BOnE0/yDc/zNfi49UKcQnnqHQY 4K7ExmDL0vEoxMTlleKQeD0pkTm2Am8yarOSboBegH6AgQ0x+2nJkFBvNE5W3DhL7gn5/ej8i7Ak 55GQTwHMAMxHx/9cWIwC2V8RBZqXJEE/QcfSVIAMyfixvi46P6XZUdsSFC6DWLe0ODpeHGNpGcBm oT0vyBbqk39tAXAB1ALsBtgHcADADXAEIAxwLM4/nhd3P6xcmr9ojBPX1vP2nufl8f76vBgs1n1e Pi3YOz7/sP4/LPaOxOUrrJ8V9/8Xna/n5R/VPs/ZM1fqX3r+iIl/oh0lZ8jKLcs2Kn0A8BjgCcAs wAkBnm5wbGAbYuO9dK2D/A1KCW8hbo2qYs/Goj4b1AAagEyJn4xF1x2uP6m8DVnLOsfLRv6GnOVx kfx4HcVYtLhhab+htS/E6Q35kvFJ9pmlPq/E+YlQvqFU4qui3cQ5WhDqFG1w4HtP9I069s/nXlPW gl9RY2pZCn5KMWcW4Clj62Hg65UAagANQCZAFkAOQD5AEUApwEYAiwAOoQ7cGa6vFmAnwB6AOgEO AngAAgARAY4DnBT4LR8B2gHOAXQIcBngGsB1gB6APoDbAgx+AIywzTl3c8ZzHuQ8znmSM5vzdD3M w3olgHopadZnAgeprJwn63PW5wNVBKkUWjyFFhshWQhjHqUcwlUR1Hmyftv60vXVANvW74RUtH6P JNXhu57vf9OXvsuooC8yvkxfXsygLy+upW8u6uhri3p6x9dA7/j+C/rCopG+rVhMX1Usoa8qltL3 FM30PcVX6UuKr/3R+5PJNLLoW7M97JOMvbII/qaIgySAVAlkAOgAsgHyBF4hQDFAmQCbBeCF+lsE SBLquoT6tQJflL0bYB9jWeMfCp98pfeV/rg0QHhoRf6o5Hr0fTWWElgghd7kZvTdzegXNxPoTe4k epN7NX1xM5O+sqmj72vq6cuaBvqCZjZ9OzOXvpeZR9/I/AR9HTP//5tcGbvGri//DUg3wbYafIaQ /orhqL7bcMXQrD+lH9CfMpwytBrOYA4QgpLzhvP6bv0QpAEquwj1sOyKAet2Q2oVko+SKLETJC7J MwiySJIgBySEDK3AOaXHtthG6NlwEZ8ccviES8ld4P4ThPWfcj9nWdx/5h6xV+TvyN9h5Rg9mVX1 31QTzEbfBM0E0Ahf4dQvtVdA+4vQ/hLXwxK4XpClpTY6qJFBWJyPO0yGgN+ZRYzfdmVmtmm5xtoW plnbDunc2o61I4Avr722dhBSy9rra4bW9gD0rWlde5tknME3cLnvc9+Hvn/E/Qg4P+Z+zDiui+ti cu5t7m3Q7G9AmwQY0wBT0WiSQLP3WLLq16BfKqy4E7IBenbnYi8xts4NOj6E/ADkk0I+DTAXpel6 YZkXD9pDbOvLOfrClyf0xbpefZlWp9/8slqfp83T8+tK9VuQxnK8xjprF/UuXb++Vjeg360b0u9D vjZJfwDpdRv1bt2o/gjCyx59GEF3T39Md19/QvdIf0G7WX9aN6VvEwHb6hb1NwlQJsK8vlav0N9d giT9JRGwf+0WfRf1A3JRF9QXdUEdsJzGAXLSZ/VniTenv0PjwzFgXWhH+SOQnaof12fob+h1+qv6 bP0tbap+GIHGXwa6wJhQDuk/oz+LNPUNOpId8SvEjL4hLFO2KL/BOOWbynamVJ5VnmUq5Tnlt1mi 8q+Vf82Sld9Tfo+plZeVP2CrlVeVP2Ife2EflsmuyubJ3kfg3MJ05jjYBGCV0BWSsh0vAE4J7ABf 72TsUyfY1nUz2sG03Wsm18zptqybT7uTlro2L+10pinTnFaL9No87aBmKtO0bnHNpE6xZm7Ngub+ 2rw102vzNPO6JKhnykzXpWrmtYOZKpCyAHghbVjn0l7WuXQZaanaEV2tTpdp0PZor6+ZzuREwD7W Ler2IaBMBJ0OQZe9BIXLSTuGOq7NWDefqQINU3XFoHFZ2h3URVecmS7oNxnVT9uj25yZvjYvU7tm EjXTDq6ZTLuj7UF9IF/QZWt7MgvSTqcdyFTpdusUOshhFqbTdtOIezT308ZhfFBrbR7oTxxoPZ6p yszV3EcrcV/l3gSbvsW9xRK5b3IQnZVfU34NPKBN2QYe8E3lN8EDLigvshTl95XfZ2n0Pej0RHWi mq1JTElMYZn09ee1/6gYVwfgBAhTlMui/zHZD/FBxjYKkS+L6p2gNw7wP12W621mPvzO6lI9DuKQ 1K9/BN7KEZe0ob6zqG/8zRsV+T0jv1eQ3yvJ71eR3yeS3yeR3yeD319lq0kSjojRiBJoROtJu3Zh FFdJkz8h3jEag4z1SXhDwiik9XpoDDLmFngcS/4nWQJtkPncUStJEiNJMpLEkSQ5SVKRDPx1poT3 60C9JJP8lOfOBceOs7M0G1GrGGiMzcJcuJd4HNsl2FRazyfMhUPgfVQrvbgXPG8U7eyGZBQfJ14P uyjxyyjvkGBTKa9VsKnI+0NZ9EVs8k+x+UpzIWPdbJBODFr8Mlh69hJsTdema19aTDek56YXADbB dQHy0s2Eo7QWSrXpmyCZ0q10jbRWSDsgadN3CaBdlvjS1EtTQE8Rb2+MJKmcTZRjSQX174xe41iU bynfgjFfUl6CMf9Q+UPygRfct1gXWVD4q6cG7gzSFGxrGktjL5kQpynFnDATaPUSrYEEWOPWbHmp AJOkZpbGTSBcC5LUlC9LUC9JisopTp0U6uemMc0JTaHmRFpmWiZiDa4jTvkt5fmPPMKrAF1sq+aa 5rqmR9Onua0Z1IwAxnxMM6F5SPSkZhpwn2ZOs5DGaSbSuDRVWkpaepqWUi7UHEsrgJQSTdTmtigx zZRmRgx1NqUVAGWFMpAEcioEObma62mbkIMlaelQehv6wBIDjfCM8so/Ym/h4N7gLsXa6DrMxm/b yUwyM+uH6zMx3DxZIcXkYzHcLFkORfaDMdx0mZbhX6x3xHCTZKn0P5ibY7jgerRj5Uu4HJujM3j6 Em95bB++wjVcB/ddqPE97hKcvX/A/QBO3Ve5q9Cyk+uEubnB3WCrYG5+ylTcLZihRO6X3DDEnxHu V2w19y73LvsYN8aNsVTuHnePvcTd5+6DzN9yv4WYM6YaY+mq9+DE/jKc2H/NMujc/3XCXyX8zffR X5fQrRK6TUK/KdA49mx6azCDfhcAR/8Klim/Q7hDuMdB3IW1ZQZZLpwixd+LyCFepiwLrqZjeKky 1HU8hqeSpcDVQAwP7SEDv5Dw2DxbhKsLMbxpsJGMnYrhPWZP4CoQw7vP8Pcb98Xwov+x6ozhDZMn bozhDcTsHFFeH7st8YwcuttDL2AUwWUUwTF2d9BuGWMD5YX32aBVwv8G0WckdJvETl+V2Onry7RQ 501J2zclMt9ctt2SjUU6iSXASTBpyaIxu4h6CGAU4B7bqh5JHk4+kTysHks+m3xXPYa5egKuH6on 1ZNAT0M+p15Qj63mVnNQ/nC1anWKegLT6txoDmkMuAWrVdieZNyF9mPq6eTh1abks6vNIA/qJJ8Q yqFs9abV6VgWbU0S0jGpJ1drIdeuNjz3JPGidz8psmoaswdmgql3xwF4jfqAhHZLyi7EwSUhvyrQ XQBHJIDXYbY1YTFpMmka8Jw6Q61L5pK5hBl1dnJKwiImoLSU5yVNJhuS5pINybnJBqi9gCk5XZ2t zsZy4FOKthIlJpuhDpdsTk5HeepClAW8yWU56mKQm5I0qRyGkgLl1YRHyabkgoRHIOXRH+wM9KL7 2wOKCGp685ip5gAWGHQbzYlWAaQIebpQBvUStQIY2FbVlGpGNa9aTFQkJoEGGZB0idmqReBDAlpH eYZqBp81As5LLMRrTJBnQ10sL4ymaCuJxC1SeSgrKmlJThLUXYQrlFWcWAZpcyKfWAZXZR/xZPyR PFe1DaAaYCfAHoA6ANgTVR4AiIeqCMBxod507GwvzXJ6tAxnVnUSoCUKeP3Ju2yr3KoqUpUC3qiy QHJAsqi2qarlVkyqnao9lDugVh3UqVMdVNXRNaaI6rjqOJXXRZPQKlaiBWqRPJRFkpblWOCqGsAB tEc+Iy9QBSDHXxop+KN7Lv4qy9OlM0H0fkhG1sAdcuCZWYi6HJUoF93/96GYPni/WBxVwo74TEm4 U/EOYXyO96NVlwF/l3CvEqRyPyX8hPA95MvXEd2GWN5H9DDRvyScj1g2q/gZ8HMJv06cfqKHEcsm if4p4dcIr6Y6i4gXO+Swjyi2JBwC3Im/WiX/V3I4D8gPK7SA64j+BtEdiKEO1nwHayqGovUJnyaO Fkvlj6mOT+AgjhDnO0jL9FRfTfyv0O9keYk2U50dJKGP6APIX7WGSlsJf4LaropqhTS3l2SmoW6y 3aSnOkqT5J9RzRDh41GMpdwXFf8S6vgV/wB1NlCrV6PjpdKHiJ+dewZnDO78MzgtyDOe/R5thOcD uQHp6PmG+y6WcrVEv0t0F+GTVP81gf97tBFxighbCWsWd4lnJyjFM8kI1c8lCbnUapKwn+os0unk N0RHT2Y/Q/zsHTgHyeQuOCGB57Av4Rip9BFJe7LYjTNAnB8/g1OY3I10whUai4vqGxbxBHgzOiJm Qv8RSrGv+4gVqVR6m/ghbMW+R9LqSIdzsh2EWwB/heivyO4BHuLepq+VFOHpD6TKZAXydaRnO0rm 8JT5HmL5OuDB/CDN9RL9b+QOtCbRTwj/LXK47xK/GDkyPWK5ATF7KjegfOLkU/1hsuYTwpeJ80XC 96jOHaJrSU6LDCIAt416/yThMtJNQXQu0bsV+P2QR0iz3xAnE3uUu6jOa4RrqXSaSmcJLxL/bxE/ M9PvzXUn9NCK2IKrSfErwD34K+Wwpm4A9iNOSFf8AjHSshBieReVfos4/z7hb6B0nGrKCPMKuItS 9CNOWE10SPGAVhyWHiKchnhVBcn5LeGoZBeti18Ka+TbwH8Vf9lNvgs5nCvhDtAPFXC/IP+PyJEV KKKzgVYrJboF6ys1JOGx/IeAv030KOGfYR3uywo9WkoBMVT2fxQl+Dt6JOEbiBO8RNcRPkf1/yfx x1GC0kP9HqLSDpI5Sf1+SpFH+gBO+D1i+QhiBXG4k0T/P+q+O6yKJHu7b9/ue8kGEB0EBEFQJDRJ ggFUQFRABURUREkCiiQRQR0DYhgUBxWVQWXAiBlzQl3jmAZzWLOAihkdDKDCV/V2e8ednU1/7G+f b+Z53nvuqVOnTr116nR1N6CfnOxi2WxYhsNmDzychbwZ+jzWjdgPZwNpdmEFGXY6rbpsDuTdwGqa P2T/yeR20lrn0EqF7K1Crzk0/5kGjj6tOg2cQ1HWBnIxRTYU8kPgYUmznKAhRVkesA4aNYrEG9X4 QSNAtgaeB+6DPp8i4ZbK5cAE4HTYhIs+m8hdMpsOTAEmUiT6MzSGpsvAMUBRM5dgNGz2AfPQivtH Mk9aDdQgh0MWIO8TqxmqDe7OZNZozQdeFOsnZPHevgE2UyCfxnV1PvAx8DKwGPiQoiwO8h3I/em/ usiwXBU4KaFZBx5qgNnAQIqcAdiwgGYP8AJwLFpPAJdRJPtuOXYllTPA2zHItdBjFeQFwGSKTbsp JwTPAC8DCW+NPaieYTC7fqiQTyBvECu8WI2hd6VzaepNkVRqKhsAVyBDulGUOyGSOOAazOUiYriK 2HwQyRgp62jOIHLmDnAjEPETn1ReCpwPTIR+JnAUNNFABv4xIjucVhKGaboDrKTcNu2nPDSV0RwD vqJI9LRC7qIos6bIGaC1HOgFDEXrA7SWoVcg0ASoBb0f5BqgkiLvA8+n0bcO2AY4BT5zIOfBPhmW /cGwOhiuAL4Qr1NYhUKsQg69BrHukkwxEpgC1EausrB/Bk057F9Bcx2tSui9gEXQdwHWAy9BH6qg //aoB0XZMWAhsA5oDdwAzIPlK6A7MAf6cMgWwEhoGiGnALWBCdA/g1xOUc5C9oK+HjgF2AV4HXgJ NqeAAnopIRehVRe7XpfmNsHLwLk005DzK2iWsjiHsLcw3/bA2eBZAb0pcDowXTwLgbcekPGGXeYJ nAHUkZ6/LMVOp5rzwNvAX4BrgD/DMgS52g2IncsMBBoDxX3xBPIwoAN20GzgA7Reodh4gyfn/i+l CnKFanyt0CT4kiLZLxvpjubovq5QGFPE6b2COwf8heBNbhrBQZLlRugTaQZKmt10f8knUhlYwR2A Z2O0roLmOGUVrSvotZtoMqgs30arAT01ET04pycQ0lqGvtMwOxG3Qk/lE9wo4DpgBZD0baykdxNf qpUJdI7KImiKKNuKVCB9Zsco3SHjXZ/CGtiV8qZ0pgiZUVwC7oN9AmRP4Dwy1gFeD3J7yA2Q18BS DTLeNip6A2eQeISmqagqS4F/BdKrrUPTMsijgFeAi4EVwJnAAmAunXtTGGRT4BngDGAZ8AQZy/DL RyqLiLM38yWd4mea7QP5YoJB/FFSbX5RcyIYQpGroqhwo8gCufHQbKSozIVelI0oyoEcQ1ENyD+H vjPwGvr2gn4T8Aw0OyGPBH6CJhwyPCuGwGclNOaQP2DEDGBfYFe03gO+QC+08ntgvx9xPoTeA/oD iOcqWltBEwZ5MfAksAK9siEfh40AD5eAW4DN0IpR2AWQfYAfgQeBiei7CHIXIAt8DwQncnAiL8Rc plFURySKWbBZBnkvUFwRZ/jsh1ZvYBY0a+GnAZpaihrgUB1rqoa+6lhZpSFsUmHjjlZfeIAfrgjY CRotjBgMz9ArYMnpwk8JcCUsYS93QmsP6GHDX4TeAngfGvTiZBSbhtPcI3iUZiOYnEZldgrVsxH0 dC1bz7vRzKQ7jg+hyFVRVLhRZIHceGg2UlTmQi/KRhTlQA57lmR4AbK6gGap6JPKLDQk5wto3qJX Z+A1eO4Fy03AM9DshDwS+AmacMgYVzEEI1ZCYw75A+LJAPYFdkXrPeAL9EIrvwf2+zGLh9B7QH8A 8VxFaytowiAvBp4EVqBXNuTjsBHg4RJwC7AZWjEKuwCyD/Aj8CAwEX0XQe4CZIHvgeBEDk7khZjL NIrqiEQxCzbLIO8FiuvlDJ/90OoNzIJmrbhq4H88VmcnMAPrshEyUN6AXrUUNaBRR1aowb86ckNp CJtU2LijlaGWGlgXNV+MiHG5ImAnaLQQYTBmBL0ClpwufJYAV8IS9nIntPaAHjb8RegtgPehQS9O RrFpOD09Ng1uIrnd5IczQFWjP8FNwBSKckOKMiDrBs1g4CnoRXkBZCDLUOSA7DvolwCfwdIU+mvA amiGQt4G/AKNHbAzNIuAk6EpB64BroT+NfA9NN0g3waGYcRk6NtBcxeoAdwK7AuMBMbCvhfkCGAB +sYBQ4BK6IfDsg9kM+AU4AigC/AMsC1QBhyDXiXAX+HtCFiCpVwctz9k+JeLzBtAvxbYHtgTeBl+ wBWbQZHHKnBYOw59OawgbwTZHJZHgQOAesDZGMUK3i5AFi3VIV8EVkCTD5tCyOBT/gPkGugXA8W1 QC8muuk9fX6Cs6UT8moHnlkZQIN/YZ2zBZ6A5iqegBlD4woN3lXLV0FThlYNyObQ34PPUvEuoDGZ 3kM1TiI2xeJ9LtXITaDHG075Z6CveEdA9exH8V6gcQHZU+KZ9gGV5Xgbzg+jqMDzPYWGeIdIW3mm MZveVQFrKLI7KJK+yfQOiCLnJ0U1CdzSfzu8ltowDbB3h+YyRXLuxFmdnnxk1hh9NDxvhs/r9Bmg /AMiXyA9OaSRp2OUSug3IVo8+eR9oLcFjmm8Su8g4HkN9UP2Mu17V7y3glwqWsJPAX1WySRiFnVg b48062T4SUbkyZjXVeivYkdT+0boW0JfTmdB9hTVH4N+E0Z3A0aiNR0MHMYTztMU+QxpLYgHrpd4 70Zl5jF8hmIdNyLaqYj2rfisA3GysNwFPC3FSWMLR19DKeYw6MNQ30Q2VmHtaJyzKfI+YkahlxpF uRs01RgxG2vRAnnSBrIW5EbqU66PUV7hBNsAuQg+D4u5hDjvIf73UqbRuQ/EvGoRQzBWKhyyJ316 LPOEh0Tx7kximKAC97k8+irx9IZbJO4vMKkHy91Uo46dpYZ8VmL3KROkvpPo9YuiGnaEwhp7ZzBF xQMxH5Cr1RTJ3QjdUxlSJvgiWl88MVBQhvHMuQZz1JeyK5u+a6DxyPZR5EaBbUP68358LWz20mfR JBOIJb8UmqPAr6MnYy9Qfu6ITEK+LK04jSQBsi9YHQX5LDAZHBbCvhjIiLsS8nw6R9lW8LAL9qPE u2AFfT6Zgrc5OcDVeJtjAvka3s60h/wJmI5WJeRQepcqe433OKbQtIR9HmQvyEZAXWgsIOvAgxN6 qeGtUCPklpBTgfuA3uilDfk2bE5BzqMoN8G7qmtKL5qBeD81liJXhl73oWGBgZIlxXPiGy6KMm+0 KqExpXeasjpEGAfk4McdKIiciDFTmfODZg80q3HveRqxWcO+lN7PsjkY5RgscTKRtcdpxArYDDat xbdskAshu8BnOTSe/GuCm6E/DE0oRdkAxByKOAeg1RmjDMeIop9TkNdATqDINEGeDn2UtIIZdEfD Wz70t6EvR4S+0FvQ+2v2N8iTRQ4xriVm1AayN10FWTg8eIqt0qypfTVGfy7yKa0dXbXOsHGDjQda d6DvFDAZLjFDT8WR4ltIYGfaSk5xtNdTcXXA2H1xdkAPvglZOo/GzyMbMa4b1cj3wOYj0BAxLBbZ gE22uAvgM0dB34SfhxyAqB6Iqwysp8g8R69AoBL6NdDXQt6AuTeIrMKPF59F70qohtcDLpR2Rxta TzA7PzES8T0pzUzS9zxtRYYbAB3BwA6gnvS+dQpyeArycAr2IMVXiijkLZXTYT8LIwYBi6ApBfNb xbxSkrHYi5BTJKTrqwtUB2NDsHfCxBXE6PnIhxnwE465vxbfF5NqTWSsoxwaubhesJkoorSaNPI8 yM40M0kFyMAqEFQbTfXKIupBgaxWY8HeO8QQCM12tF6H/o5UkTIwo1JkXQKYod6caKsygY6uiAPb TsjeOth/lDKfxrABERaK64tZ4K5NLr77XoG5XFPMB8/Uvg57NgV+8hUuRHNPXEdeSWsLr0XwJfeK rOBRasM8ozLJaor9gCKfbanM3EEuPRT5pB7YTbRikzgFMvog+H9NZcKVQFcNNgzt2+QqH01zBvWq EjgVqzMRkZ8FV6jGHGo7zwBtRGagXwbLVZj7BWSmASKZAssG6DE7ThPoCk1b4ARYHuN/I/JLaN6I uU2f0ZGoPFGrMzC6J/aCJ2IgqMT1iM/A6DWw8aNIbKhsAG7LJXuqjwbaoJqt4tELeAF7fzUv1gTU E2A5Rc4cNvcga/LIKx67kqJyL3hoTWPmB2PcCvifwIuxIRLIPtDvgbd6yPVg7xKQxay3QH8WkRtC /syLe5/66YSoLsLDYsih4K0tRc4VEYag9Sp6FYOZ0WBpMJisBAODMWIf0T/yv1r0LDFGx5oJ2R3e PmNdXsKmMx1L+SP83MGIafA2Ewwcxoj3gNhl3ApgJ8Tgglw6D7kj7BtEGTZ3RT/ARbAEP3wW5J8V Iod6WFk9vAug+i7Qz4e8FfJ4eI6GrAE8jtah6BsCnh2BlZjXSuwjQ2g6Ae8C+2DXe4rXEcg68Iy9 xsYCv8DDX0Q/8F8G+/fQFMDeR7xGUFTOgp96MQbEthE2C6F5ARlVmjBMW3HVUOJqxR+Gz1W8JTLW ElexIKyRJfLTEvlsiX20iIyijrFwhVUEQ8ZJSdEGY1Ug2iPAF8iBvhi9WDxBYcRi0RvwLxgxFvau NJdIvaWYIOW5J1aH7tlp1IPGMCqrL6KyGk5xilTaV90W+wXnJeVq9BqIzDSAvFHa7xRlUoYT1BgP e9RSLkbKZIoKXswrT+wCKveHvg/id6CyAnmluIXZRSFvu/LkysVF8FdIr0fiTyJhB03jPIhGk6PX TS0uh/QaAWbcqMwNAX4EdqEoN6X23HjKDH+b1ljOn1tNr8hUQyo89TlePFHQSvtFoG+j5CZ4T50C WR9yDrAcWAS9G+RrFGXtgXXQB0KfD1kL8itgOjQXIK+GvTVkiy/0DUUGRXk2NB5UZi1gcwy9WkCP 2GQP0Cp6voZeSipzjtCofaF3JV7oFSZGBXsvitxUWBpQZO7AXhutObQX8Uz7rgaGAsuBgcAdYmxS hPQKGw68TVvlY0Xe4MebItMfvV4BPaDZBvka0AKW1sA89N0jRUs1E2FzUZw1NO0xihtkXeAUtB5F r0bYy6EJgJwAuS+wJdALem36loes1Ew6R7zxaYC3erQaQh4Kn8EYMVCMB5o8zOI5NLcl9qhmKbAW +nCgPVpDm8zp6FTDbwTzlZCPUz1nIMVDPRthRR5iRH1xpk0L6YxgUwQsFWckykD3xh4004CGwB2i Hugs8g99JDAFmkiRH8R8A2MNEbMF+lPAziL/wFuYkTrkfMgbxOxt1KJzpJ5lXYCesLkv5oPYFzHH Qs5BDGpAgSLzmOrVCqiNEmutNKSouE6RH0xbFZZgTA9ojDgnwWcQ4o+GBxZ91RAVhwgtwWct8Lm0 +ulYHYrHRAbwnESO5yQ18JyN3WRCV4fsenPMLgw7l8patFVWiFEOYjf9CBkxsyOAYk6GwtIaqIv9 JQBTRGy0ovUKcltp74Nz9M0VKw9YqgI6g9tjkMWacwrjnsB78xf0p/Jl7Smyo9A6iqsm8T/gAui5 FKfcUXiCehTvhjozjPQ+XIOJZsoZLiozNYExiE2NGcuYx8VEpjJCQkRaItOD/j1GhmlqIvBVkn0j k4MpQ38vQOYX7GtCf68d7azUJmfIcS4qalwyYwEUgK7AXtEJ8bGMX0JSVAJDfxZQjnjoz0RQn/zf aH6XZAze/hONOqPHGDLmjDXjxHRjvBg/JphRyGibLyP+BONl8VPRAxHLlPcQq0xZzdDfF5GpF4nf NQjSfhp60veO0nj0t+nbo68SvyHgx/iTidN/dYv9v/+7FvwYwklzWXvWSe7DhZKZuzO9mH6EuWFM JDOGSWUmMVnMXCaPKWCKmVKmjNnDHGZOMRXMdeYeU828YOqYz+RCrcW9YOTkNFXFvcRnNbna0c9H 3Gt8PuZqyWcVkd7gs4p7i89q7jd8PuLq8PmYe0d/Oop7T75VE+sP+KziPuKzmqvH5yOuAZ+PuU/E upr7TL49ItZf8FnFNeKzmmvC5yOy6PTzMU9/8uoRT/KH9Kzk5fis4jl8VvM8Ph/xCnw+JvdHLPf4 D4zQv3CawUz/dxjh1TDzSl5dZIbXEJnhNUVmyP0dmOG1yTiVvI7ID99M5IVvLvLCtxB54VuKjPC6 IiPkpANG+FYiI7y+yAjfmjLCtxEZ4b8TGeENREb4thIjhhIjRmDEWGKkncSIicSIqcRIe4kRs3/B yFKmiFnHbP2HjJhLjHSQGLGQGLGUGOkoMdIJjFhJjHQWM4a3lpixkZixlZixoxnDCxI/9hI/DhIv jhIvThIjzhIjXSRGXCRGXCVG3MCIu8RIV4mRbhIj3SVGekiMePwHjJxgzjNXmTuEkWfMW6ZBxso0 eE+JkZ4SI70kRnpLjHhJjHiDER+JkT4SI74SI30lRvpJjPQHI34SI/4SIwFSxgyQmBkoMTMIGRMo 8RMk8RMs8TNY4mU4nSkfIvEyROIlVOJlqMTLMJGX/5iRFypGwiRGRkiMhEuMjJQYGSUxEgFGIiVG oiRGoiVGYiRGRkuMxIKROImReImRMRIjYyVGEiRGxoGRRImRJImRZImRFCljUiVmxiNj0iRmJkjM pEvMTBSZoX+ji8aNtxuLyJVAi0mkPzhBrgaGjAUjEL68mAAmVD2NVPpMfo7cQn2CJFmqp0OaS3QT JclSPYNIk2GXKUmW6pMgUbvJkmSJ36IzZ2wZV7IefkwIM4pU9TRmKjNXfYpqpO9VI01VjTRNNdJ0 1UgzVCNlqUaa+XUk9flE+p7PJLpcSbJUXwBpMtH9KEn/LKJsVUSzVBHNVkU0RxXRXFVEP6giylFF NE8VUZ4qooWqiBapIlqsiohcEWS2MltyRDBgDciJxow1w7VYjVzN6c9x4W8NyPKZ7/4+ZqaQWUOy eR85FdxhPpIM1pLpy0xkVjInWQ+Zr4zcIzKc2gOGxW87cmoPVVLlV4n9lUgFkCpU0gWVdFElXYLE klOGFnuZymwVwaVou6KyuqqSrkGSk1noMHrsdfQ4RjCXPU5wCWxufGOjz56g/tiTjJxYLmVvqjz9 VSXdUkm3VdIdlXRXJd1TSfdV0gNISob+hpMJyXlbpgvTjT1DRltJxjuDUVeyvxCrlexZ8q2IfD8L bRF7mmiL2IcqX5USF0p2AZtH1q2YXUcsS9nNjAa7ld3KNGPL2O1Mc3Ynu4tpye5hD5BTnRxnQD2y 1+hvXtPzl5r0F5JKSMMmdhPxuYvYy9lD7CFyZiMZwObjd7no73XSfFDi5EnPtmbEqpAtZIzYFewK xpj4OMK0w+9meeB3szylc54aon1CPG2mecQW4y/cyJlrat5qXn93+pORiklOY+R0aE248ZTW+hzi OK9as2oiLYf0SCU9/irJj1Drfzov8YQuE0+vDGNAf0ZVD1rG4IiQZXBQoW4123f2B22Zki3OMthM VKUsuenUFNQVfGcdOWvAM0KEQqOzglzUs1xYGVccJAwSrL/RGK4ynm5Ijs/0/wHkAjCeSWISmBiy ZWLI0Z/8L5h+44zT6+/5bM3QFUPP77x2wlPtvsuivfa+3YqzWmUJWdxxIUu+qVjOylhW15GE6FdS 439+V9rkrgjYT9BWRSsjJzhhIsKUD+YUuuzgIHtdoQX9oqarMSRifFx8YmxaUqJ9c0GHKpW6ysCY 6HFJidH2xoIh1WjotvKPj0pNGp80Os2kd1JqclJqRFo86WEqtKPtct02v7cHx4+LsQlKixiXbDKw d0/BuLW2vaM9+c/BwZ4Iw8hXZ8FB9VWYsfO/Epm2oEnbNXU5/wEDA+0thQ7iV+PE3vHJcTGpJl5B 3ibeQQHuvQUfJxtHwbWLjZe3j6t9B8FMnJHhn84oKCY1PT4qRsiStf+WYRk5I2fJmjFEr8Fmkdub 7Tcb2io6Tyytzh8xpdnjSesWvcoJNlpTnz1h1rLz58KWXrwxweavap+GX35l0+GUS493m6YaBD0a cnhszZGzSzXu+LwZZtyDvbzjgcUCJnry4W6LP4Y6ZM65bDDCrHzFoBPNmjdwobv10xNflJ96dPjz ls1He97eWJH5znDHTz3XT+rQuWlThnao+/bwgfei/R6cbWV1f93TxjWj7YY3V1e3ML3qoW037vLH iXnyhHt6LdfOf9KlXd2ctWU9WydV+aeNPvZlVYqP86DzY1sPimpolb+ocGT/jgce63v3fWq9u3He nG2f147rfWed0NCp4+vl2tZhM++1zB2z63bK6zC9YVZmHZtmJA95M19ZqHvTKoilf7ZhdZZMnTDC C0aEUiMdTp/T26+9Zad/3a2fDXZYWgzWNvG6WVBZhxwyMuPaCPrT9cycPv410CdZ46Xnp/RPOzuX HXfe2UwIpgbtOH+hv9C3uE+x9+zecWlpye52dlGpCbbjvq6TbVTSOLvksfFUa5ecmhQ9ISptvJ1q GekqYhFJVtoSEyFUoUY2Js8rZTLOT+gn+H79LrCzu0kDTJw48c8GiEn9J57TBF0abwdOS9D46lKu 9ocNKadZop4ToNhW8zLrgpFy6g2r9eaaNtsKh5tPy0/RGjzX3CCwVVRlnj/fr6Dfik8P14+LG5y1 v9Oz+A07rlVp3bp0fVIHl4xYQ61PtzsNM1jmauUW4vPJecb+6u4+wxZUf57gEjq077yA291arRwf 2P/5ZC33YzZHdy4PtHngfHL/0SE7a7qXdPN6a6ZvrLFxqIvlxSWB4aXTPIJrZzy8U3go5lrG+w9+ bgfvPrjuorOwcM788U9SogM/9JDfPPVr6j4np4Lh86+8U1v3POPUoGJtnaS6sd08DUbpW29QBK40 1M2rSGKNn01esfP9x2Wj3sZcutRujvvRCbW9cie9nJ+6Y/In65xdC/sEV9rGn9cPNhhKytgLUsau flPGylps05h3sevPd1GGy/5YxjL/K8XCTDAVN73Bt+3RMSZB8bGJxOvvhUywd3BycHB0dHSjhcxJ cFJ9FWbM/L8oZJK5/B+Y/8vCVLMtbJWJ9seOU8r5ydO2vHqevrljkIf7bc/vdy5wfDzEY+2gVk7B ay/smrfBo9Tloc3Al876Aa/9J93WTZ9bZl07NGzD84c3Ok2objvLcvlvH22KenbprOn56XDXA/vD JizWD+x/1vGkS9lvz6eWvuvZKkwtxsjUpdb6QHvN5tubr5zYflb2lAH72+aVvVvdOK9OqzCg+N0Z DdPKjVWyLn2+2GWNmSF/t8H5Tv6QlZ/6X9XJuu36Y8vGquuT0uZGP4w80cHWauvKNu10jPcc22a+ S2dg+T3DxWF912Xu3nO7oj55ckdZ9j6rTheObOD5hw+apfh/2RJmNrPT819O9jtdY5l9Zeqp3ppL GH77gJiUk18L0yjCSNifbVT5N9VqaMq6YY7+twqU05uyjQ/PqU916PlWGESbW3CkXqzxEbz+uD4k Q+hXXtfK0d7Zzbmz0+iI0UKki71NRLSji41TRISjTUQX8tWlS2SU4Ozg6OQUEf03BfBci5qzl3fp h8rOuNg66uvv9yvUaCeEiAVwgEBKYDEpgbO9/6MCSHKZZDJJ4pGCq42jvY2DYC+gBA77pgQGCKQI flMCe/x7JfAf+E77s3pnfyPRquUQxxnXVp56Xu9+1ctfrehV+P0xw/dmXmBXlKfHFeWVrNA8Pm3V /Df+B5a4fdJ+8HB53QjzZm1z57Zyn3J7S8XOMwkH3Ky9vzdvEWwhaGs39XkmVz6qHj3CevJKow3N GwzL0t4OiB9btME8+9bLpcX3x695PcZgc//IojdT/qI3zfdX/x1e9bXdFo/rdbNmyuPWxcvj4tQ7 1rPLXreQH4gN3HL06c7x6y5H/dqvskf1bwFfmkoeHGR1u44wuTfYY/XWPE971wkdw7kNPuMev5uU 6Xmo3a813te2Vo7o8W7CL49HR406f60we06uufDhtdPFKKPtvWL76fQ/4q7zes8S9/Wu1R0Wqa2b O5oc2/hyUu/WiPVOI8LRwgCnNfs/lrmRqB4a6ossflj81jpa9p2+nBBv/53Q+m+U6qp1sbcROot1 wfz3uhCYlESKA1mo+NHxURFpMSY9J6TFJaXGp2WimAmCqyM9hrk5OpBi5iB9daBf/5d19l9VsB2p Q8O+E6KPGBWOMjHp9VN6UEKPtteTzp9782xs4zL95g/uu6fNNNhrV+zwounesV4BZtdSmdvOQzR+ OLvVpG9dbdxm//65aw9l9k9Z3kd560uH+ysnzL2wcbzXtBszbv926G2XNWfCvO9s29L9Qce4ZQbr 16aOD3nTOr/6i3N+avH19JHGE71nznLVvzh+OE9SJnftjni7W99pNi5K61SZbhd8V08Y+vFybuSX c2dG+tgP3G+pW+0pXEjt1Lxj+19cAroXO3TP+7XEVTErLCAkq6MV77C3/40BUU8u20S+8e7+ZLMa 896npOjS8PkWQTWTNvZ763PBpZtr0a6JYWtbF+Wea/FjSLejm9VHyq98rWDhhJFhQjNaGXRlsiaO F+Tk45vq9aeVhBYro2YcRzJwttBSoS7dmrSScTwck+OvSsdSL18u2QdcschZ8rBgVNdS+6R13cpv 2gjfqYz0WE7LWIMJYiaQ25neTM+/qWU6m7NGeYZYLnvUQfez1UONoCVDq9cIA8Va1lfoI3gX9y7u Odvj369lquZUktq0BKGKBX9TxXwFUpS/qWKu/8lBjm6Y3qLXv69frIwZ6tZjmoXPtudJntsddo95 rmOXWNr3w/ORE176dbW50XuLZuO5pzb2q83OTxlYMN10xObudn4HVpWGrKhKPrhv18fM3X1TP/R4 1nPa2YdarePPrV1hYtOgOfBEyK82Vf0ulyc/KdVeJV8b8mBfTv8hb5f0WvHmt9evqma3c+q2L6Sw NshsltWaLMPFlflKo7eVAR/nl5yt0V27MOB028s/pi6xShm33OCjYW3Q9djz7ZvCjH5dNf+Q5Y7M qBCvVYN+rX+6OjTk7nLW28tuZN2trVezHBI/r1miW/08/smGVdaHT3durhOz4Kfb71Y1tLRQj3HN fzOpXb+Dlx6G1FzMWNom7Iyz/si7i436LrA5vMXJy/BV81YGzIi7zsNNKwp+UX81S2f+gHE6ugHd p3TyXZF66beEs0dfJK8esmjI9/m5xW195cM+XFgdq5G2tstLG7vWpx+nurSsS9reLTarPnBHrqN+ jLFOzt3m96Lrkip8rl5p/TTzBLfryifr++1yijZrfNK19NxSXf9wwzSfg8pRfWJGeQaU9XoR8HJn euZNDSf1cYbT7dtV6gTffVTy6VGf5luiC5oG6ttOOcKbTqpc0tMy/vjiH5ecyb253HSrdtiK2lVb Z8fN1BpjczB9LGO0dMtb/cnv9Wea7597YUxpH3u7wjtVKd1vMFMj+1yqmHtmX5sGndTco6u7b2M9 xzTFL19a2by0+S6XgWrXj3cXshRKUr9ff63f+nFOqN+G/4v6LbgITgKp2M6OAj2MOtjjq6NAv/7v bvf/VfX+uSRh+/3bvouspoy1/e7hocqqkz8NMhu4peJumwDzZq8urb/ktyVNMGnxXHkteEmrvvlt ey3aWhAmWNxixtZMPvTiB2WzDzpcQe0P59udczSfs/JtXayh9efJT+YaPXsSsLrkqFnQ2dwG7wvq F8O3XSzrxa2qX5ewOPZGxzs+QWWzLz7q6GNruXn2gMGBWtVy609j8vKExDm/DRVWNky9vmxnjemy qR8v6/6mtjdoXOAu77yffZl+fUa3sOw0unRZ9RXFjH6r6rPXt+ijp571c/bLwRmNskKjgWqzmOaC z8u998x8Dp6wCf55m3FGT/uJ55ff7zpzcUkEu9tIe/vnD8t3yCra9w9uquePHzPR/Fq9NxFG1v+z 6v2nN8J/U72bf1u9iYYRZhSIxXdGnjAj98/Lb0nUmoj/enpmNc/col/Sr3jtFr/xoXVKXduY/2+q /r916064br4s53iY3KvL3ae7tky8XZE5yF+23TYtZfg4Ld1NFYcn/7jP9mrLVfPHRe4bwp4LMNEd +NPdSZ6VQw5uCy00fGgkm735YMbbeRdfdJW9qjz8owZ/Ote3sjao1d0BmxZVP8kdc2360cf5bxV2 s+RPF1qZt0/+9P5zdcZPttoflJXJ5W0CVi4Yq5G6ZF+J24pYm5ODdJ5FhnnoF8wz8ahUGjjUn7fv l27fvXOq5ulnyd2bZmno3j+mEbGg9sa+1s8D5k076dw5fPWR5+Xfa/aafDUo1fSVcPZgRkzYcFlr DT2dy7f0Ct512z86dKeN3ZP6WbPPDwqpWZmcn7DZze/q+8wjG9tMiuz0etXyTk6KiQaRZ7obj2uX Vav5i/XBC713Pqp/8f3uqjWlac77Ak6mmLW0SNfsFjg/ZZhPb73ynTvL/GNP/9yraXqm6fSiVsLo ml4tww1OF7U3vdj7aeenB+t8z1tfvekw3c/Cytd85LBnIa/X3ftp5Vn3pEMzLNMULV6lmx5ZnnXU MnjP9jHdfyhJj9iVWKK77sjGPrUtk77kOCTsaLw/6PR8szOjD600mtMymu1us23oj/uqTR/tLjsb tSsjmL/a03bg5vyytRmbdhYvnWDw10VzdCe0t3MoVUssHj6/w5Hi19lnTa8/Nx5wpvBV3wcfZDFJ P2h+fzr+9OPEZ+uXVdh3atI5OTzspn/bkpsNdkUetoP1x57RXf3FPosjW5hbz8pkAtlu/7vz8p8/ Nvn9IXLxjBP0uCblr7rcXuvbJ9QkgN+/adrrCN+2tqKHwa8dOXtSlBR3jM3lCR5Xr5m8GHQt8sjY LKMLh4Tob7po2YcIwcVW0zsy/kw8E8WkMkl4yD2aSWNMmGAmk0km32KJPoJIcUxmicV083+4WdMy k5NiUyOS4zLt/nBR4bJkjPv4oiPpDitONaTeqks+6GxiwN6y5E4URHIxDkNaq60eaGhksyfAamn0 d3ybC427t/QsGHXuxvPcY0OtY6d/igqtHHQmOXVm/2wLq6yqQP8RPzRsjW07IMvWz2trjlnP0H3Z ybtSB4zYE3iuYMZc5p1mwDD+omxFeEbsA524VTMqy1yN2lYsqW4x4+7YhYb71rWX735vlfXUw0xb 07Fz3cyJ808c27Mobn6r1MaWLnuz7XcvfLV17K2le1cPfv7UaWtR4tojzW18956acymm59gvyz+6 X3a0MP1LsxuPPIbptfVeKBTnrjE0mZjxXWxpRN85c/7y/3bt/8ZmT3NXxkPyihlHc+YKaeU/9r13 rclAa2ETk4ZBE5MKIo7YDJuYRIFCguBU2TdgrQDsMxJIaTLWQAI5SXIjZlYYgZbDZVgN+SGjbIYW hhbGBgaGURgpMv2nnGvk+aI3YUWnJjL8mhfV7PDlK1p5DUor7eHSU2dfP3wwwDWwweDCtWlf5vv/ a88+edBRyeXA+waG9Np93QaxrTbb3sy00ro3+f8n68cXvL68zjl6NuHN0qz6z5mXy1ZI/U/PbbA9 LzzniTKrgkXVfs3z2m+Yyovqd7jVrbywImn6uZwYRr7Y1jvdu898OHW77FBRpe8PtkZ/p0jX3Soa gh6LC840vZJ+MtXsCn/Alclz7xb6ewe/ad13YPbKVbOOFvQcFEwquPlyttbx762HzEPNtx8t/afQ wHGnNdCkbH2s0oRNfFLXL838yX1t1UQjzYCUw8sPBShHPkrQmLykdO352+tzDrkwHmFY+rZ3Y91L /slMp5QZrqRtD9u18LQ9e6t7Q02YFwMA9FUBdA0KZW5kc3RyZWFtDQplbmRvYmoNCjI4OCAwIG9i ag0KWyAwWyA3NTBdICAzWyAyNzggMzMzXSAgN1sgNTU2IDg4OV0gIDExWyAzMzMgMzMzXSAgMTdb IDI3OCAyNzggNTU2IDU1NiA1NTZdICAyNFsgNTU2XSAgMzZbIDcyMiA3MjIgNzIyXSAgNDBbIDY2 NyA2MTEgNzc4XSAgNDRbIDI3OF0gIDQ4WyA4MzMgNzIyIDc3OCA2NjddICA1M1sgNzIyXSAgNThb IDk0NF0gIDY4WyA1NTZdICA3MFsgNTU2IDYxMSA1NTZdICA3NFsgNjExXSAgNzZbIDI3OF0gIDc4 WyA1NTYgMjc4IDg4OSA2MTEgNjExIDYxMV0gIDg1WyAzODkgNTU2IDMzMyA2MTFdICAxNjlbIDU1 NiA1NTZdICAxNzlbIDUwMCA1MDBdICA1NzBbIDcyMiA3MDggNzIyIDYxNF0gIDU4MFsgNjE1IDY4 N10gIDU4M1sgNzIyIDc3OF0gIDU4NlsgNjY3IDcyMiA2MTFdICA1OTJbIDcyOSA3MDggOTc5XSAg NTk4WyA3MDhdICA2MDFbIDcyOSA1NTYgNjE5IDYwNCA1MzQgNjE4IDU1NiA3MzYgNTEwIDYxMSA2 MTEgNTA3IDYyMiA3NDAgNjA0IDYxMSA2MTEgNjExIDU1NiA4ODkgNTU2IDg4NSA1NTYgNjQ2IDU4 MyA4ODldICA2MjlbIDg1NCA1OTRdICA2MzJbIDg2NSA1ODldIF0gDQplbmRvYmoNCjI4OSAwIG9i ag0KWyAyNzggMCAwIDAgMCAwIDAgMCAwIDMzMyAwIDAgMCAzMzMgMjc4IDAgMCAwIDAgMCA1NTYg MCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgNzIyIDcyMiA3MjIgMCAwIDYxMSAwIDAgMCAwIDAgMCAw IDAgNzc4XSANCmVuZG9iag0KMjkwIDAgb2JqDQo8PC9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVuZ3Ro IDI5OD4+DQpzdHJlYW0NCnicXZFNa8MwDIbv/hU6doeSxE0HhWBIuxZy2AfLdho7pLbSGRbHOO4h /362XLIxg20eS68kS9mheWiM9pC9uFG26KHXRjmcxquTCGe8aMMKDkpLfyM65dBZlgVxO08eh8b0 I6sqyF6DcfJuhlWtxjPesezZKXTaXGD1fmgDt1drv3FA4yFnQoDCPgR67OxTNyBkJFs3Kti1n9dB 8+vxNlsETlykYuSocLKdRNeZC7IqD0tAdQpLMDTqn32TVOdefnWOvDfBO895LohOiQ5ERZHoSJFu miXCkrDekVtdC/iI955wvxefwco3dURe8niVBeXhZZkej+mxviVIIfm/Gvn2ntxSVXy7S3T6W1X8 aRzI0kZ5dS50kKZGrYtN0waXwdrRRlXcP9AUmr8NCmVuZHN0cmVhbQ0KZW5kb2JqDQoyOTEgMCBv YmoNCjw8L0ZpbHRlci9GbGF0ZURlY29kZS9MZW5ndGggNDQ4MDUvTGVuZ3RoMSAxNTIxMTY+Pg0K c3RyZWFtDQp4nOxdCXxTVbr/zrk3e9KkSdN0v0mTNqXpRvcNmtIFsJQdaWVr2RERBFxAHXADrDju C+qIy6iM6JAGhLAJ7hsVddwVQcVtRtBRREeh933nNoDp61Pfe3bq/Dz/2/s/y/ede9Z7znfPTVIg AOBAEmFB7Zihg2fP3NYMtKQJIOHdwbV19cvvvmQhkGvvACB/HTxyxJj8SeP3Abl+GMCaFwePGTdo xVxtBtCsJABD+bCxY4bcPf+sRzDtAQDdoRFjcvO/ib/4KKb9DnNpGVkzbOyDk1WVeL3pGC4+vbax adTEuZsBPC8BRN84bV7rgp0fPG0D4lkNQC+ddt5ip2b9u0YgxV8CaO6ZuWDWPDLz9muAeC0Aqo5Z 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 NzggNjExIDY2NyA2MTEgNjk2IDg1MF0gIDU5OFsgNjM0XSAgNjAxWyA2ODldIF0gDQplbmRvYmoN CjI5MyAwIG9iag0KWyAyNTAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMzMzXSANCmVuZG9iag0K Mjk0IDAgb2JqDQo8PC9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVuZ3RoIDUxNz4+DQpzdHJlYW0NCnic hVRNj5swEL3zK3zcHlaYGZMQKUICEqQc+qGmPVU9EHBSpAYQYQ/59zXz2G2zqQhSgp49M+/5mRk/ 2212TT0o/0vflns7qGPdVL29tC99adXBnurGo0hVdTlMSP7Lc9F5vkveXy+DPe+aY+ut18r/6jYv Q39VT0nVHuwHz//cV7avm5N6+p7tHd6/dN1ve7bNoLQXx6qyR1foY9F9Ks5W+ZL2vKvcfj1cn13O 34hv184qEhxATNlW9tIVpe2L5mS9tXZPrNa5e2LPNtW7fUbW4Vj+KnqJZhetNel4RLQQZBZAOdBK Kk059FrhlZASM4ZRshxfJpBKlCRYTLFophL/V0GpRlgkuekCKAGKgNJ/VQR3KlIQphNhdkMY3BFu ELZ9UFQcoCxAdD5/iky8NESie4Mk2gAZoHzWS9bZGMYa8li8ZC0qOIBJTDcq6J0KDsDERnIDeMnh PG8QgcK9frjwMIh/yvIKyxmKLOaZCSdmuTcmuMHz98YUCgVNOrMHFPgYeAuKBCh/QAFTCaYafUMR 3lHkCJNbZMaZDAPBWwNvGZrRLcwroGheDEMMT2LSeTFmos+FIgzRrBlQBAQvFhkQIpejUNIBz1/7 citilmh0kvbjLRTmIGM920kGx9Z084GNg2ecj29TrXzpezfQZIjKJBtnWN3Ytznbtd2YNf7+AHno jfENCmVuZHN0cmVhbQ0KZW5kb2JqDQoyOTUgMCBvYmoNCjw8L0ZpbHRlci9GbGF0ZURlY29kZS9M ZW5ndGggOTE2MzAvTGVuZ3RoMSAxOTIwNzI+Pg0Kc3RyZWFtDQp4nOx8B2BUxdr2zDnbkt1NdpPd tE2ymywpkECABAhFsqRRQoCQLCbUhIQqJTTpxY5BbGDBiopYQN0sILGjYi9Y8Oq1e/WqV0WxX9Ek /zPn3QkBy6f3fv/nd/8/kzzneeadcuadMzPnDdnAOGPMiYuOjSuuHDk8bth7bUx5eR5jCW+WFBZX vaS/ZSNj7zgYs64rKRxdNK3nBh9jf93LmL52eHFJ6UePfsOZcmgNY+rnw8eNrZzTMPhMxj7byvg1 luGV/kJV7f4DUzZuZ6z09bGVOX1/ePO1RMb4a7hrbf38usYzL7z6AcYyf0J/vvrTl3oCVx98ibFJ s5FPnNk4a/5335VbGOs1hLGwhFl1SxpZIvPi/jvQ3jZr3sqZN7/69ip0dTZjxfmzZ9Q1HF2+6Qn0 Pxnl/WfDYL3DiLHxrch3mz1/6YrGCu9KxpR8xtIPnjZj8YK7y/a+wdijuEdY/3kL6+tuunffasZ2 3M9Y8rj5dSsaUwalZaN9C9p7FtTNn5Gwe9E6xp4txnwMbVy4ZGm7i52L8ZwtyhsXz2g87S6ljbEB 1bidjYm51d/7XmniQfu0yCHfsngTE+m+T9c8K/jQ0rA3fjzWuinsM+PdyIYxhVFCOwNrY/xg+PYf jx3bHvaZ1lOnpBssLJEZ7GymZzMBhdlYDpvBmP1i3FdFqarL4hejxKTfps9Fl8nE6gvsXIWZmBKp VxRFpyq6d5nS7mO72+m+jJVXejwMz9hTTGMwXqekexi/XpSp+/URwlP0HnF8NPwQRnSDeC5/LOkm st26Ylb3e+qqH7Pdv6veHb9cT/fTcbui+319/ZFkePXX+9SPZvV/pC9d6h8fn/ohi/yjbbpSV/p3 k/oKm/wvtZvOJv6eero8VntCux/ZlH/lfl3p30+6/N/3zDrq57FtUitPH9f/ryf1epb6Z4/hz0xq tz97BF3p/7ck4k9dObtDxJRq4/H4SZ/B1F+KHfW/EmPpqsmuex9RNKO4TsaOMo7T/QBb6vHY9V+N vXTTj7/LdItY5b/Sx39KEnGCrqhDb1MOnvg+0C1nsVpZ6P0uWH8WG4o4oUxXybYBK37W593Uh87J YgTr57BpuuEhW+hdpesRyuNdJGMONZ6Fa9zpnNa1sQqN/cfHpT/cSVeh/SMnjll9huWfkF/wc7+V q3n4b81L58TbWY+Odnp2xe9t93uSGnvyz5Anlf/U/t3v6UeZz84BVv33jOpXxtKPbfq/2f//ZMLP yaeFePyfPI4RwJ3AYmAW0BuYIcYH1Ivx/ZljVK49cS/92/01t5f9u33oW9iI/46xdKWu1JW6Ulfq Sl2pK3WlrtSVulJX6kpdqSt1pa7UlbpSV/ofT2oIifTbEd6ifXaOqTuYjl8DQyHzaZ+uY8zKUlka 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 qJGiWopTpZgghV+KKikqpRgvRYUU46QYK8UYKcqlGC1FmRSjpBgpxQgphktRKkWJFMVSFElRKMUw KXxSFEgxVIpTpBgixWApBkkxUIp8KQZI0V+KflLkSZErRV8p+kjRW4ocKXpJ0VOKbCmypOghRXcp MqXIkCJdijQpuknhlSJVihQpPFK4pUiWIkmKRClcUiRIES9FnBSxUsRI4ZTCIUW0FFFS2KWwSREp RYQUViksUpilCJciTAqTFEYpDFLopdBJoUqhSMGlYCHB26Vok6JVip+k+FGKY1L8IMU/pfheiu+k +FaKb6T4WoqvpPhSiqNSfCHF51IckeIzKT6V4hMp/iHFx1J8JMWHUvxdig+keF+Kv0nxnhTvSvGO FG9L8ZYUb0rxhhSvS/FXKV6T4lUp/iLFK1IcluJlKV6S4kUpXpDikBTPS/GcFM9K8YwUT0vxlBRP SvGEFI9L8ZgUB6V4VIpHpHhYigNSPCTFg1I8IMX9Utwnxb1S3CNFixT7pbhbin1S7JVijxRBKZql CEhxlxR3SnGHFLul2CXF7VLcJsWtUtwixU4pbpZihxQ3SXGjFDdIsV2K66W4ToprpbhGiquluEqK bVJcKcUVUlwuxWVSbJViixSXSnGJFBdLcZEUF0qxWYoLpNgkRZMU50uxUYrzpDhXinOkkGEPl2EP l2EPl2EPl2EPl2EPl2EPl2EPl2EPl2EPl2EPl2EPl2EPl2EPl2EPl2EPl2EPl2EPXyyFjH+4jH+4 jH+4jH+4jH+4jH+4jH+4jH+4jH+4jH+4jH+4jH+4jH+4jH+4jH+4jH+4jH+4jH+4jH+4jH+4jH+4 jH+4jH+4jH+4jH+4jH+4jH+4jH+4jH+4jH+4jH+4jH+4DHu4DHu4DHu4jHa4jHa4jHa4jHa4jHa4 jHa4jHa4jHa4jHZ40R4hEDUHk4e6ETMHk52gMyl3RjB5EGgD5dYTrQsmW0BrKbeGaDXRKqKVwaRh oBXBpCLQcqLTiZZR2VLKLSFaTMZFwaRCUCPRQqIFVGU+0Tyi04KJJaC5RHOIZhPNIpoZTCwGzaBc A1E90XSiOqJaomlEU6ndFMpNJppENJGohqia6FSiCUR+oiqiSqLxRBVE44jGEo0hKicaTVRGNCro GgkaSTQi6BoFGk5UGnSVgUqCrtGgYqIiokIqG0btfEQF1G4o0SlEQ6jmYKJB1HwgUT7RAKL+RP2o szyiXOqlL1Efot7UWQ5RL2rXkyibKIuoB1F3okyiDOo6nSiN+uxG5CVKpa5TiDzUzk2UTJRElEjk IkoIJowBxRPFBRPGgmKJYsjoJHKQMZooishOZTaiSDJGEFmJLFRmJgonCqMyE5GRyBCMHwfSB+Mr QDoilYwK5TgR04i3E7VpVXgr5X4i+pHoGJX9QLl/En1P9B3Rt8G4KtA3wbhK0NeU+4roS6KjVPYF 5T4nOkL0GZV9SvQJGf9B9DHRR0QfUpW/U+4Dyr1Pub8RvUf0LpW9Q/Q2Gd8iepPoDaLXqcpfKfca 0avB2FNBfwnGTgC9QnSYjC8TvUT0ItELVOUQ0fNkfI7oWaJniJ6mKk8RPUnGJ4geJ3qM6CDRo1Tz Eco9THSA6CEqe5DoATLeT3Qf0b1E9xC1UM39lLubaB/RXqI9wZgCUDAYMwnUTBQguovoTqI7iHYT 7SK6PRiD85rfRr3cSnQLle0kuploB9FNRDcS3UC0neh66uw66uVaomuo7Gqiq4i2EV1JDa6g3OVE lxFtpbIt1MulRJdQ2cVEFxFdSLSZ6AKquYlyTUTnE20kOo/o3KCzDnRO0DkddDbRWUHnTNCZRGcE nX7QhqAThzFfH3T2B60jWkvN11C71USrgs4G0EpqvoJoOdHpRMuIlhItoa4XU/NFRI1BZz1oIXW2 gGrOJ5pHdBrRXKI51G420Swa2UxqPoOogWrWE00nqiOqJZpGNJWcnkIjm0w0iZyeSF3X0I2qiU6l 4U6gG/mplyqiSqLxRBVBhw80LugQdxgbdIjlPSboOAtUHnT0BI2mKmVEo4IOxAV8JOVGEA0nY2nQ sQ5UEnScByoOOtaDioKODaDCYFQpaBiRj6iAaGgwCu93fgrlhgTtNaDBRIOCdrE0BhLlB+3DQQOC 9mpQ/6B9IqgfleUR5Qbt2aC+VLNP0C4c6x20i72ZQ9SLmvekO2QTZVFnPYi6U2eZRBlE6URpQbuY pW5EXuozlfpMoc481IubKJnaJRElErmIEojig7YpoLigbSooNmibBoohchI5iKKJoqiBnRrYyBhJ FEFkJbJQTTPVDCdjGJGJyEhkoJp6qqkjo0qkEHEi5muPnO4WaIusd7dGNrh/gv4ROAb8ANs/Yfse +A74FvgG9q+Br1D2JfJHgS+Az4EjsH8GfIqyT5D/B/Ax8BHwYcQs998jZrs/AN4H/ga8B9u74HeA t4G3kH8T/AbwOvBX4DXrae5XrX3cfwG/Yp3nPmxNd78MvAT9ojXL/QJwCHge5c/B9qx1vvsZ6Keh n4J+0jrX/YR1jvtx62z3Y9ZZ7oNo+yj6ewR4GPC1H8D1IeBB4AHLIvf9lsXu+yxL3PdalrrvAVqA /bDfDexD2V6U7YEtCDQDAeAu80r3neZV7jvMa9y7zWvdu8zr3LcDtwG3ArcAO4GbzT3dO8A3ATei zQ3g7ebT3NdDXwd9LXAN9NXo6yr0tQ19XQnbFcDlwGXAVmALcCnaXYL+Lg4f474ofKz7wvBZ7s3h N7svCL/FfY6a5j5bzXefxfPdZ/o3+M/YtcG/3r/Wv27XWr95LTevda0tW7t67a61b6z1RRnC1/hX +VfvWuVf6V/uX7Fruf9e5Vw2UznHN8R/+q5lft0yx7Kly9RvlvFdy3jxMt57GVfYMtsyzzLVstS/ 2L9k12I/Wzxu8YbFgcW6wYHF7y5W2GIe3tJ+YM9iV3Ip2LdmsdVWusi/0N+4a6F/wcz5/rkY4Jz8 Wf7Zu2b5Z+Y3+GfsavDX50/31+XX+qflT/FP3TXFPzl/on/Sron+mvxq/6moPyG/yu/fVeWvzK/w j99V4R+bP8Y/Bvby/DL/6F1l/lH5I/wjd43wD88v9ZfAeZZoS/QkqjYxgDGJGAlz8cLeLp/rXddR l465Aq4DLjUqMsGdoHSPjOdFY+P5wvj18RfFq5Fxh+IUX1z37NLI2EOx78R+EauL9sV271XKYmwx nhjVKXyLKa8q1bigmLhPP83X8hhvemmkk0c63U6lxO3kzP6u/ahddT5kO2RTIiN5ZGR7pOKLRPXI CHeEIi7tEaovos+A0kir26qIS7tVjfFZYRE9ZljGVZVGmt1mxV9gHmtWfOaColKfuWfvUqZyD+fi I1cerprEKLjTXYp9vSeG6zne581VlVlZZS0mNr4sYBo3KcA3BtIqxdVXMTFg2Bhg/omTqps5v7Cm mStFVQGH+I2tlj9n82ZWmFQWSKqsDmxPqikLbIDwCdEOwZKaY1hhTdbUJcuWZGUtnYrL1CVLs7Rv 5PgykcsSRvG9ZCny4muZlmdZv5moGmjaEqSl0rj0t1v9b0/8zx7Af35qZuJDBsPalbNZg3IWcCZw BrABWA+sA9YCa4DVwCpgJbACWA6cDiwDlgJLgEVAI7AQWADMB+YBpwFzgTnAbGAWMBOYATQA9cB0 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 a+qmOk331IP1WD1Nz9XZZg9KW3E2ZnWnIq/7Fnk9vcjrGT957RUpD8w2P6Iizk9eF2t4++sSi2+v H712u//4nre/LqNu918mvsjrakXs2xd53avI6yLjKXPs9tdlqxd53bnI6zG39z9x0e3llTbc/rpq 7SKv6/7ktdl/VesXKZ/Ma9fkh9J2hPd2tr+r25F7JubKmlxVLdTuDX8fC3+fDn9f/q+sazYMfzcP f7cPf3e7vRc1p90+ylqNbn9dN3a7fb0et79uUGQVUlKKvG5Y5PXeIq/3F3l9scjrvNtfp5b+SZQZ oVF8kdeNbrdv1LjI66LlaUVedyzyutPtq9gkzTBqZqafM1sNdOaRbfuaf8rs1FnK8Uv5d3GtKK2C Eh2i20q0j26JfhHdbDSB853znbG77FxWjnPFuaJc5wfnB6WjLaMtlRd9KPqQuW5KPLi6jZb1ct3S bhmjkb8gikp/dElTs655XdacRkaoeWqbylU3nXjThzjTq/gSXZRbon2JroYdSjxqKKMrZXJykjkt 1DdnnmbRc0q7pUyf/snv/8Xed0BZUWxr76rqPnVOd589AzMDwxAk53AGySBIzhkkKChhyEgaGAyA IAgiKpJzkqQgOQgKEiSIJJGcc8458+/e0yBcue/53/vuW//6l1Nranc6fXp/tXt/X1X36V6P1NOS UTR/ge163A2S5vZSvR73U72RfHUjNAbS41E61lW09hjb9Xic7BqaP8F2/XNbnvS2POVtedrb8oy3 5dPjrczHW4WPtyof79M11XhNdV5T4/k1uImPcDMf4VY+wqdrtvOaHbxmJ6+RoCUVOs1s6d65HS7D CdUoQlU55ZzyhPoqXAU+OqY1hJQCl/GF4hEm+s9Kn+9DXvWh2TARBr1EjEgNH/H7LPuKhuIt6Cfa ifYwgN9hOVB0EvHwmRgoBsKXYpQYDYPFNXENhojb4jYMFQ/EAxjmhgYMlz7pgxHSkQ6MlElkEhgl k8lkMFqmlClhjMwgM8BYmU1mg3EyJGvAeBkvu8JKmSATYBVl//dhtewhe8Ia2Vf2hZ9lf9kf1slh chislyPlSNggp8o9sFEFKWoeqnwqHzxWpVQZeKIqqopCqvFqvFBGvDFZGGYzs5nIa8aZceJVs6XZ UuQzW5utRX6zi9lFFDC7ml1FQTPBTBCFzN99A0Rhq7bVRFyx+ttCPHbCnbLyPedNZ4KcG2webCNv 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 iQhWIoKViGAlIliJCFYigpWIYCUiWIkIViKClYhgJSJYiQhWIoKViGAlIliJCFYigpWIYCUiWIkI ViKClYhgJSJYiQhWIoKViGAlIliJCFYigpWIYCUiWIkIViKClYhgJSJYiQhWIoKViGAlIliJCFYi gpWIYCUiWIkIViKClYhgJSJYiQhWIoKViGAlIliJCFYigpWIYCUiWIkIViKClYhgJfL0+SDPnhYS s4FsJC+FmJ9CfWJ+8AWyf1LhkztBoeWkPjGzadFMKUSsHQr4zByoZIwJoSY+K4dPGKJPQSmMSbVD NUM5n1uSakqaj1Lx5ZxiUB2aQhfoQEk0DuLp3728UzyU7rmdGZEFqzw2Iqb07tyu7QdlGx649vZx tazlpD5RfUJ9jLWhPmrWJCWFlBGv0iFWmXy26uZF8R8U5QOuEgo+O1ph0nEl8GGquoYvQtatHRsR SuLO+COsek26tGr9bsv4Du/GhofQXagjdK245u07vNs8Nk0olbvEioiq2rpZ5w5dOrSIT1u6Q+eO HTo3iW9Nn0gXesVdryKi/1hfp3X7uFy145u075i2RumSoTTJg7GvxtJf3ryxNNGQZvOH8j6bDfVe +B85smDIdtfbEUbV6jVqxWYJZUqcTfNu6dYdW8V1Tlumdtm0ZWtXK1I6VC5frldDhQrkKlO2XKHY TKEMiR6leqlHteM6d2vdLC7UR6R/HmH3pVN9KEvRckv2EQLm772f0pcjYebJYY0+DDv9/vQhlwfW ST31Xt+u/UZu/vWtEdv3dM21z//gzR2Xc2VaX7D4rVk9Y2qfqrey7dmfNo2wDpa71jBNcbljwdHM X0DzD1YWG3q3ft73+u+IaZThx3E1fw4Lv2/UX5ys27sXf1x/auXD72avLnng263v3Uq1YHTJGe9n yvFkVvdg/SLzG9c43LzK0U1R2Y9MP/d4aos8b4YHApnT7SwRzNN+x92Eward4cik0wadKfDKzf7T 5pVM3uFE1fgWax5N6VQuf83NbZPXbHY/atiQMW9Xzrr8dLKyFc/lXPz4s/5zH05rX/rg9ND9bFmv jA3mfOvjw0k/b7PoQKcrb0U2zJ4h65PeHetdG6THROzNXlsqOo++7iMChIgZSk2QpkaS45HLgt8t rHpz/8SYBVky1w2mLbN31PGbHEOpMxjRoWQfRWbId3dfrXIdrUuvP+j2YGGOeWvzLwwL1XE3eMWo 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 UkWrHvxTRjb5vXap9E4S4DMalGvoRDk7Vrgof+f1Rq5EpFEeX6WTV9dTLVcSqrmdUBTxCVomsrY8 mtio2dDvHMMvOiDFD5APHO92JWY//c2saNLX3be08Y40YYR9LLwFHKqYZyRu/Xtn+fPrO0R+ceqp 2SYb3Vc2Sj4l0xUzopZayuD8ziZSsvcDr9I4ec5zJ3S/WHfNce538541CEPKo6DnQuZidckrGYIj 6b5k5nWcRUM6/whjGJTFJT5siVyTcz/vgxZvpLPtr2rdtCIz6SZq1uwhdzQQMg0c+oF3PkZiHrjL xrlc4OdcNk8/22Bw+wlSGVPhYpy2M9KIZHORfGJi8dgU+6Kk24VcGdfyK5ZNBnVrrUR3Ro4LodBb WslOwhaQfwFuwT9dDQplbmRzdHJlYW0NCmVuZG9iag0KMjk2IDAgb2JqDQpbIDBbIDUwN10gIDNb IDIyNl0gIDM4WyA0NTldICA0N1sgMjUyXSAgNjc2WyA1NzkgNTM4IDU0NCA0MzBdICA2ODJbIDY0 NCA0ODhdICA2ODhbIDY0Ml0gIDY5NFsgNTQzXSAgNjk2WyA2MTFdICA2OThbIDg1NSA2MjNdICA3 MDFbIDY2Ml0gIDcwM1sgNjIyIDUxNyA1MzNdICA3MDdbIDQ4N10gIDcyMVsgNTQ4XSAgNzI0WyA1 NTVdICA3ODBbIDQ3OSA1MzNdICA3ODNbIDQ3OSAzNDZdICA3ODhbIDU1OF0gIDc5MFsgNDk4XSAg NzkyWyA0OTggNjg5IDQyMyA1NDEgNTQxXSAgODAxWyA0NjRdICA4MDNbIDUxMF0gIDgwNVsgNjc2 IDUzNV0gIDgwOFsgNTI3XSAgODEwWyA1MjFdICA4MTJbIDUyNSA0MjNdICA4MTVbIDM4N10gIDgx N1sgNDUzXSAgODIwWyA2MjRdICA4MjJbIDU0Ml0gIDgyNVsgNzI5XSAgODI4WyA2NjYgNDcwXSAg ODMzWyA0NzRdICA4NDJbIDMyNl0gIDg1M1sgMjUwXSAgODU2WyAyNTJdICA4NzZbIDM4Nl0gIDg4 NFsgNDk4XSAgODk0WyAzMDMgMzAzXSAgMTAwNFsgNTA3IDUwNyA1MDcgNTA3IDUwNyA1MDcgNTA3 IDUwNyA1MDcgNTA3XSAgMTA4MVsgNzE1XSBdIA0KZW5kb2JqDQoyOTcgMCBvYmoNCjw8L1R5cGUv WFJlZi9TaXplIDI5Ny9XWyAxIDQgMl0gL1Jvb3QgMSAwIFIvSW5mbyAxMDcgMCBSL0lEWzw5QzQ1 NTMyREQxRjdBRDRGODI1ODI4QjExMkE1RDg5QT48OUM0NTUzMkREMUY3QUQ0RjgyNTgyOEIxMTJB NUQ4OUE+XSAvRmlsdGVyL0ZsYXRlRGVjb2RlL0xlbmd0aCA3NTU+Pg0Kc3RyZWFtDQp4nDXVWVCN YRzH8XNOUp3qtCoVKtnXLGUn7ZvotCJSsqVsKVsqhZAGw4zBDFmz7wyDGeOCMePCPsMFg3HBjH0s Nybn/X3zXryfeZ55n+f9P+/ye0wmx9HWZnacfUwmgxr4KCx1IjgCHoiQmyKhSST6QSQ8F0lhIjkA 7ooUxqUuEWkl8FOkM0v6bTHJKjJ84b6Y/EhMqReZq4WdK+194KnI6iayQ4HOnGcitwy2iLxx0Cjy d4up2WIaBU73gO+ioAJ2iBmDYKWYycIKqbrwh5i1GJpFUU+gs7hYlASKqoeipUUcTBGHhsFVYCmH KeLwLXHkujgaB0XimAtkila7OO4ELOXEOjggTqbCLnFqrzgdDhPgrTgzQJxt54U4d0+cLwBezoX+ UCkubhCXYsTl8eLKdvGY4U/SoVQ8dYcc8SxRPG8Qn5PEl30GZkuucNJTMgcMFoHVIrJWDNFjNUc7 3orF8XkvM62GNVANq6D9krWOASPe/2+ZwQJO0AGcoSO4gCu4gRXcwQM8wQZe4A0+4At+4A+doAYC IBA6QxAEQwh0ga7QDUIhDMKhO0RAD6iFntAL6qA39IG+0A/6wwAYCINgMETCEBgK62AYDIcoiIYR MBJGwWgYA2NhHIyHCRAD9TARYiEO4iEBEiEJkiEFUiEN0mESZMBkmAKZYIcGyIJsyIFcyIN8mArT YDoUwAyYCYUwC4qgGGZDCcyBuTAP5sMCKIWFUAblsAgWwxJYCuthGVTAcqiEKlgBKx3/Xyy/dpzi ybJZmWxpumPg9ClffKkTX9VyDm+A1yJis9ionHdu3CQ27Rcv98AVg46eMcKmXcZl60jR3AtiDVx/ KZ5c/5gN3DKVZ272ayIrXjT9Fc3aety2af+zVreIGuW1tbavqPtm4F4xUCz/ICqV+u5V7ww8/MqF vzo9Or038AyKEsGq2jPklOiq8LfZioXXDeGjaLb9aBU/34hfmtP2W3fwak0Qx62gZXqd3Gng4/3K ZPoHodX5eg0KZW5kc3RyZWFtDQplbmRvYmoNCnhyZWYNCjAgMjk4DQowMDAwMDAwMTA4IDY1NTM1 IGYNCjAwMDAwMDAwMTcgMDAwMDAgbg0KMDAwMDAwMDEyNiAwMDAwMCBuDQowMDAwMDAwMjM0IDAw MDAwIG4NCjAwMDAwMDA2NDAgMDAwMDAgbg0KMDAwMDAwNjY5MSAwMDAwMCBuDQowMDAwMDA2ODYw IDAwMDAwIG4NCjAwMDAwMDcxMDAgMDAwMDAgbg0KMDAwMDAxNzgwMyAwMDAwMCBuDQowMDAwMDE3 OTM5IDAwMDAwIG4NCjAwMDAwMTc5NjggMDAwMDAgbg0KMDAwMDAxODEzNCAwMDAwMCBuDQowMDAw MDE4MjA4IDAwMDAwIG4NCjAwMDAwMTg0NTQgMDAwMDAgbg0KMDAwMDAxODYzMCAwMDAwMCBuDQow MDAwMDE4ODc2IDAwMDAwIG4NCjAwMDAwMTkwNTYgMDAwMDAgbg0KMDAwMDAxOTMwMCAwMDAwMCBu DQowMDAwMDE5NDQ1IDAwMDAwIG4NCjAwMDAwMTk0NzUgMDAwMDAgbg0KMDAwMDAxOTY0OCAwMDAw MCBuDQowMDAwMDE5NzIyIDAwMDAwIG4NCjAwMDAwMTk5ODYgMDAwMDAgbg0KMDAwMDAyMDE2OSAw MDAwMCBuDQowMDAwMDIwNDMzIDAwMDAwIG4NCjAwMDAwMjA2MTAgMDAwMDAgbg0KMDAwMDAyMDg1 OCAwMDAwMCBuDQowMDAwMDIxMDAyIDAwMDAwIG4NCjAwMDAwMjEwMzIgMDAwMDAgbg0KMDAwMDAy MTIwNCAwMDAwMCBuDQowMDAwMDIxMjc4IDAwMDAwIG4NCjAwMDAwMjE1MzUgMDAwMDAgbg0KMDAw MDAyMTcxNiAwMDAwMCBuDQowMDAwMDIxOTczIDAwMDAwIG4NCjAwMDAwMjIxMjQgMDAwMDAgbg0K MDAwMDAyMjE1NCAwMDAwMCBuDQowMDAwMDIyMzMzIDAwMDAwIG4NCjAwMDAwMjI0MDcgMDAwMDAg bg0KMDAwMDAyMjY3OSAwMDAwMCBuDQowMDAwMDIyODY4IDAwMDAwIG4NCjAwMDAwMjMxNDAgMDAw MDAgbg0KMDAwMDAyMzMwOCAwMDAwMCBuDQowMDAwMDIzNTM4IDAwMDAwIG4NCjAwMDAwMjM2Njcg MDAwMDAgbg0KMDAwMDAyMzY5NyAwMDAwMCBuDQowMDAwMDIzODU0IDAwMDAwIG4NCjAwMDAwMjM5 MjggMDAwMDAgbg0KMDAwMDAyNDE3NiAwMDAwMCBuDQowMDAwMDI0MzM4IDAwMDAwIG4NCjAwMDAw MjQ1NjMgMDAwMDAgbg0KMDAwMDAyNDY4NyAwMDAwMCBuDQowMDAwMDI0NzE3IDAwMDAwIG4NCjAw MDAwMjQ4NjkgMDAwMDAgbg0KMDAwMDAyNDk0MyAwMDAwMCBuDQowMDAwMDI1MTg2IDAwMDAwIG4N CjAwMDAwMjU2MjMgMDAwMDAgbg0KMDAwMDAzMDQxNiAwMDAwMCBuDQowMDAwMDQxMTIwIDAwMDAw IG4NCjAwMDAwNDEyODkgMDAwMDAgbg0KMDAwMDA0MTUyMyAwMDAwMCBuDQowMDAwMDQxNjU0IDAw MDAwIG4NCjAwMDAwNDE2ODQgMDAwMDAgbg0KMDAwMDA0MTg0MyAwMDAwMCBuDQowMDAwMDQxOTE3 IDAwMDAwIG4NCjAwMDAwNDIxNjkgMDAwMDAgbg0KMDAwMDA0MjMwNyAwMDAwMCBuDQowMDAwMDQy MzM3IDAwMDAwIG4NCjAwMDAwNDI1MDMgMDAwMDAgbg0KMDAwMDA0MjU3NyAwMDAwMCBuDQowMDAw MDQyODM0IDAwMDAwIG4NCjAwMDAwNDMwMTEgMDAwMDAgbg0KMDAwMDA0MzI1MCAwMDAwMCBuDQow MDAwMDQzMzkzIDAwMDAwIG4NCjAwMDAwNDM0MjMgMDAwMDAgbg0KMDAwMDA0MzU5NCAwMDAwMCBu DQowMDAwMDQzNjY4IDAwMDAwIG4NCjAwMDAwNDM5MzAgMDAwMDAgbg0KMDAwMDA0NDA2NSAwMDAw MCBuDQowMDAwMDQ0MDk1IDAwMDAwIG4NCjAwMDAwNDQyNTggMDAwMDAgbg0KMDAwMDA0NDMzMiAw MDAwMCBuDQowMDAwMDQ0NTg4IDAwMDAwIG4NCjAwMDAwNDQ3NjEgMDAwMDAgbg0KMDAwMDA0NDk5 OSAwMDAwMCBuDQowMDAwMDQ1MTQ4IDAwMDAwIG4NCjAwMDAwNDUxNzggMDAwMDAgbg0KMDAwMDA0 NTM1NSAwMDAwMCBuDQowMDAwMDQ1NDI5IDAwMDAwIG4NCjAwMDAwNDU3MDEgMDAwMDAgbg0KMDAw MDA0NTg4OCAwMDAwMCBuDQowMDAwMDQ2MTQyIDAwMDAwIG4NCjAwMDAwNDY0ODAgMDAwMDAgbg0K MDAwMDA1Mzk1OSAwMDAwMCBuDQowMDAwMDU0MDkyIDAwMDAwIG4NCjAwMDAwNTQxMjIgMDAwMDAg bg0KMDAwMDA1NDI4MyAwMDAwMCBuDQowMDAwMDU0MzU3IDAwMDAwIG4NCjAwMDAwNTQ1OTggMDAw MDAgbg0KMDAwMDA1NDkxNSAwMDAwMCBuDQowMDAwMDYwOTk5IDAwMDAwIG4NCjAwMDAwNjEzMzkg MDAwMDAgbg0KMDAwMDA2NjEzNCAwMDAwMCBuDQowMDAwMDY2NDg2IDAwMDAwIG4NCjAwMDAwNzEy MTUgMDAwMDAgbg0KMDAwMDA3MTU0OCAwMDAwMCBuDQowMDAwMDc3OTUxIDAwMDAwIG4NCjAwMDAw NzgyNDAgMDAwMDAgbg0KMDAwMDA3OTYwMyAwMDAwMCBuDQowMDAwMDAwMTA5IDY1NTM1IGYNCjAw MDAwMDAxMTAgNjU1MzUgZg0KMDAwMDAwMDExMSA2NTUzNSBmDQowMDAwMDAwMTEyIDY1NTM1IGYN CjAwMDAwMDAxMTMgNjU1MzUgZg0KMDAwMDAwMDExNCA2NTUzNSBmDQowMDAwMDAwMTE1IDY1NTM1 IGYNCjAwMDAwMDAxMTYgNjU1MzUgZg0KMDAwMDAwMDExNyA2NTUzNSBmDQowMDAwMDAwMTE4IDY1 NTM1IGYNCjAwMDAwMDAxMTkgNjU1MzUgZg0KMDAwMDAwMDEyMCA2NTUzNSBmDQowMDAwMDAwMTIx IDY1NTM1IGYNCjAwMDAwMDAxMjIgNjU1MzUgZg0KMDAwMDAwMDEyMyA2NTUzNSBmDQowMDAwMDAw MTI0IDY1NTM1IGYNCjAwMDAwMDAxMjUgNjU1MzUgZg0KMDAwMDAwMDEyNiA2NTUzNSBmDQowMDAw MDAwMTI3IDY1NTM1IGYNCjAwMDAwMDAxMjggNjU1MzUgZg0KMDAwMDAwMDEyOSA2NTUzNSBmDQow MDAwMDAwMTMwIDY1NTM1IGYNCjAwMDAwMDAxMzEgNjU1MzUgZg0KMDAwMDAwMDEzMiA2NTUzNSBm DQowMDAwMDAwMTMzIDY1NTM1IGYNCjAwMDAwMDAxMzQgNjU1MzUgZg0KMDAwMDAwMDEzNSA2NTUz NSBmDQowMDAwMDAwMTM2IDY1NTM1IGYNCjAwMDAwMDAxMzcgNjU1MzUgZg0KMDAwMDAwMDEzOCA2 NTUzNSBmDQowMDAwMDAwMTM5IDY1NTM1IGYNCjAwMDAwMDAxNDAgNjU1MzUgZg0KMDAwMDAwMDE0 MSA2NTUzNSBmDQowMDAwMDAwMTQyIDY1NTM1IGYNCjAwMDAwMDAxNDMgNjU1MzUgZg0KMDAwMDAw MDE0NCA2NTUzNSBmDQowMDAwMDAwMTQ1IDY1NTM1IGYNCjAwMDAwMDAxNDYgNjU1MzUgZg0KMDAw MDAwMDE0NyA2NTUzNSBmDQowMDAwMDAwMTQ4IDY1NTM1IGYNCjAwMDAwMDAxNDkgNjU1MzUgZg0K MDAwMDAwMDE1MCA2NTUzNSBmDQowMDAwMDAwMTUxIDY1NTM1IGYNCjAwMDAwMDAxNTIgNjU1MzUg Zg0KMDAwMDAwMDE1MyA2NTUzNSBmDQowMDAwMDAwMTU0IDY1NTM1IGYNCjAwMDAwMDAxNTUgNjU1 MzUgZg0KMDAwMDAwMDE1NiA2NTUzNSBmDQowMDAwMDAwMTU3IDY1NTM1IGYNCjAwMDAwMDAxNTgg NjU1MzUgZg0KMDAwMDAwMDE1OSA2NTUzNSBmDQowMDAwMDAwMTYwIDY1NTM1IGYNCjAwMDAwMDAx NjEgNjU1MzUgZg0KMDAwMDAwMDE2MiA2NTUzNSBmDQowMDAwMDAwMTYzIDY1NTM1IGYNCjAwMDAw MDAxNjQgNjU1MzUgZg0KMDAwMDAwMDE2NSA2NTUzNSBmDQowMDAwMDAwMTY2IDY1NTM1IGYNCjAw MDAwMDAxNjcgNjU1MzUgZg0KMDAwMDAwMDE2OCA2NTUzNSBmDQowMDAwMDAwMTY5IDY1NTM1IGYN CjAwMDAwMDAxNzAgNjU1MzUgZg0KMDAwMDAwMDE3MSA2NTUzNSBmDQowMDAwMDAwMTcyIDY1NTM1 IGYNCjAwMDAwMDAxNzMgNjU1MzUgZg0KMDAwMDAwMDE3NCA2NTUzNSBmDQowMDAwMDAwMTc1IDY1 NTM1IGYNCjAwMDAwMDAxNzYgNjU1MzUgZg0KMDAwMDAwMDE3NyA2NTUzNSBmDQowMDAwMDAwMTc4 IDY1NTM1IGYNCjAwMDAwMDAxNzkgNjU1MzUgZg0KMDAwMDAwMDE4MCA2NTUzNSBmDQowMDAwMDAw MTgxIDY1NTM1IGYNCjAwMDAwMDAxODIgNjU1MzUgZg0KMDAwMDAwMDE4MyA2NTUzNSBmDQowMDAw MDAwMTg0IDY1NTM1IGYNCjAwMDAwMDAxODUgNjU1MzUgZg0KMDAwMDAwMDE4NiA2NTUzNSBmDQow MDAwMDAwMTg3IDY1NTM1IGYNCjAwMDAwMDAxODggNjU1MzUgZg0KMDAwMDAwMDE4OSA2NTUzNSBm DQowMDAwMDAwMTkwIDY1NTM1IGYNCjAwMDAwMDAxOTEgNjU1MzUgZg0KMDAwMDAwMDE5MiA2NTUz NSBmDQowMDAwMDAwMTkzIDY1NTM1IGYNCjAwMDAwMDAxOTQgNjU1MzUgZg0KMDAwMDAwMDE5NSA2 NTUzNSBmDQowMDAwMDAwMTk2IDY1NTM1IGYNCjAwMDAwMDAxOTcgNjU1MzUgZg0KMDAwMDAwMDE5 OCA2NTUzNSBmDQowMDAwMDAwMTk5IDY1NTM1IGYNCjAwMDAwMDAyMDAgNjU1MzUgZg0KMDAwMDAw MDIwMSA2NTUzNSBmDQowMDAwMDAwMjAyIDY1NTM1IGYNCjAwMDAwMDAyMDMgNjU1MzUgZg0KMDAw MDAwMDIwNCA2NTUzNSBmDQowMDAwMDAwMjA1IDY1NTM1IGYNCjAwMDAwMDAyMDYgNjU1MzUgZg0K MDAwMDAwMDIwNyA2NTUzNSBmDQowMDAwMDAwMjA4IDY1NTM1IGYNCjAwMDAwMDAyMDkgNjU1MzUg Zg0KMDAwMDAwMDIxMCA2NTUzNSBmDQowMDAwMDAwMjExIDY1NTM1IGYNCjAwMDAwMDAyMTIgNjU1 MzUgZg0KMDAwMDAwMDIxMyA2NTUzNSBmDQowMDAwMDAwMjE0IDY1NTM1IGYNCjAwMDAwMDAyMTUg NjU1MzUgZg0KMDAwMDAwMDIxNiA2NTUzNSBmDQowMDAwMDAwMjE3IDY1NTM1IGYNCjAwMDAwMDAy MTggNjU1MzUgZg0KMDAwMDAwMDIxOSA2NTUzNSBmDQowMDAwMDAwMjIwIDY1NTM1IGYNCjAwMDAw MDAyMjEgNjU1MzUgZg0KMDAwMDAwMDIyMiA2NTUzNSBmDQowMDAwMDAwMjIzIDY1NTM1IGYNCjAw MDAwMDAyMjQgNjU1MzUgZg0KMDAwMDAwMDIyNSA2NTUzNSBmDQowMDAwMDAwMjI2IDY1NTM1IGYN CjAwMDAwMDAyMjcgNjU1MzUgZg0KMDAwMDAwMDIyOCA2NTUzNSBmDQowMDAwMDAwMjI5IDY1NTM1 IGYNCjAwMDAwMDAyMzAgNjU1MzUgZg0KMDAwMDAwMDIzMSA2NTUzNSBmDQowMDAwMDAwMjMyIDY1 NTM1IGYNCjAwMDAwMDAyMzMgNjU1MzUgZg0KMDAwMDAwMDIzNCA2NTUzNSBmDQowMDAwMDAwMjM1 IDY1NTM1IGYNCjAwMDAwMDAyMzYgNjU1MzUgZg0KMDAwMDAwMDIzNyA2NTUzNSBmDQowMDAwMDAw MjM4IDY1NTM1IGYNCjAwMDAwMDAyMzkgNjU1MzUgZg0KMDAwMDAwMDI0MCA2NTUzNSBmDQowMDAw MDAwMjQxIDY1NTM1IGYNCjAwMDAwMDAwMDAgNjU1MzUgZg0KMDAwMDA4MjUxOCAwMDAwMCBuDQow MDAwMDgyNzYyIDAwMDAwIG4NCjAwMDAxNjYyNDQgMDAwMDAgbg0KMDAwMDE2Njg1MCAwMDAwMCBu DQowMDAwMjU3MzY4IDAwMDAwIG4NCjAwMDAyNTc5MjAgMDAwMDAgbg0KMDAwMDI1ODEzNiAwMDAw MCBuDQowMDAwMzM2MjU5IDAwMDAwIG4NCjAwMDAzMzYzNTEgMDAwMDAgbg0KMDAwMDMzNjc3NyAw MDAwMCBuDQowMDAwMzYyMDQ1IDAwMDAwIG4NCjAwMDAzNjIzNzYgMDAwMDAgbg0KMDAwMDM2MjY1 NCAwMDAwMCBuDQowMDAwMzgzNjQxIDAwMDAwIG4NCjAwMDAzODM2NjkgMDAwMDAgbg0KMDAwMDM5 NjYwOCAwMDAwMCBuDQowMDAwMzk3MDA5IDAwMDAwIG4NCjAwMDA0OTQ2NDggMDAwMDAgbg0KMDAw MDQ5NDg4NiAwMDAwMCBuDQowMDAwNDk0OTE0IDAwMDAwIG4NCjAwMDA1ODczNDAgMDAwMDAgbg0K MDAwMDU4Nzc3NyAwMDAwMCBuDQowMDAwNjEwNjkzIDAwMDAwIG4NCjAwMDA2MTEwMDAgMDAwMDAg bg0KMDAwMDYxMTE0MCAwMDAwMCBuDQowMDAwNjI1NjYxIDAwMDAwIG4NCjAwMDA2MjU5NTEgMDAw MDAgbg0KMDAwMDYyNjQ1NCAwMDAwMCBuDQowMDAwNjg3MjY0IDAwMDAwIG4NCjAwMDA2ODc4MDUg MDAwMDAgbg0KMDAwMDY4NzkxMyAwMDAwMCBuDQowMDAwNjg4MzY5IDAwMDAwIG4NCjAwMDA3NTAz ODEgMDAwMDAgbg0KMDAwMDc1MDgyNSAwMDAwMCBuDQowMDAwNzUwOTIxIDAwMDAwIG4NCjAwMDA3 NTEzMzEgMDAwMDAgbg0KMDAwMDc5MTQwNSAwMDAwMCBuDQowMDAwNzkxNjI1IDAwMDAwIG4NCjAw MDA3OTIwMzcgMDAwMDAgbg0KMDAwMDg1ODQyMSAwMDAwMCBuDQowMDAwODU4ODA1IDAwMDAwIG4N CjAwMDA4NTkwNTEgMDAwMDAgbg0KMDAwMDg1OTQ1OSAwMDAwMCBuDQowMDAwOTIxMTg2IDAwMDAw IG4NCjAwMDA5MjE1MzEgMDAwMDAgbg0KMDAwMDkyMjA3MyAwMDAwMCBuDQowMDAwOTc5ODc5IDAw MDAwIG4NCjAwMDA5ODA0NDkgMDAwMDAgbg0KMDAwMDk4MDU4OSAwMDAwMCBuDQowMDAwOTgwOTYz IDAwMDAwIG4NCjAwMDEwMjU4NjEgMDAwMDAgbg0KMDAwMTAyNjA1OCAwMDAwMCBuDQowMDAxMDI2 MTE0IDAwMDAwIG4NCjAwMDEwMjY3MDcgMDAwMDAgbg0KMDAwMTExODQzMCAwMDAwMCBuDQowMDAx MTE5MDA1IDAwMDAwIG4NCnRyYWlsZXINCjw8L1NpemUgMjk4L1Jvb3QgMSAwIFIvSW5mbyAxMDcg MCBSL0lEWzw5QzQ1NTMyREQxRjdBRDRGODI1ODI4QjExMkE1RDg5QT48OUM0NTUzMkREMUY3QUQ0 RjgyNTgyOEIxMTJBNUQ4OUE+XSA+Pg0Kc3RhcnR4cmVmDQoxMTE5OTY0DQolJUVPRg0KeHJlZg0K MCAwDQp0cmFpbGVyDQo8PC9TaXplIDI5OC9Sb290IDEgMCBSL0luZm8gMTA3IDAgUi9JRFs8OUM0 NTUzMkREMUY3QUQ0RjgyNTgyOEIxMTJBNUQ4OUE+PDlDNDU1MzJERDFGN0FENEY4MjU4MjhCMTEy QTVEODlBPl0gL1ByZXYgMTExOTk2NC9YUmVmU3RtIDExMTkwMDU+Pg0Kc3RhcnR4cmVmDQoxMTI2 MDg2DQolJUVPRg== --1XmTJMNGXzXxUECqr=_fLDDp5FC8IM6PQ5-- From debbugs@buxtehude.debian.org Fri Nov 6 10:33:15 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 4A0877F74 for ; Fri, 6 Nov 2015 10:33:15 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 37AB48F8049 for ; Fri, 6 Nov 2015 08:33:15 -0800 (PST) X-ASG-Debug-ID: 1446827588-04cb6c296d82e30001-NocioJ Received: from buxtehude.debian.org (buxtehude.debian.org [140.211.166.26]) by cuda.sgi.com with ESMTP id 21BzK2i9WAocQGUB (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Fri, 06 Nov 2015 08:33:09 -0800 (PST) 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.84) (envelope-from ) id 1Zujwo-0002Qi-9A; Fri, 06 Nov 2015 16:33:06 +0000 X-Loop: owner@bugs.debian.org Subject: Bug#804255: Please update initramfs in postinst Reply-To: Steve McIntyre , 804255@bugs.debian.org X-ASG-Orig-Subj: Bug#804255: Please update initramfs in postinst Resent-From: Steve McIntyre Resent-To: debian-bugs-dist@lists.debian.org Resent-CC: XFS Development Team X-Loop: owner@bugs.debian.org Resent-Date: Fri, 06 Nov 2015 16:33:02 +0000 Resent-Message-ID: X-Debian-PR-Message: report 804255 X-Debian-PR-Package: xfsprogs X-Debian-PR-Keywords: d-i X-Debian-PR-Source: xfsprogs Received: via spool by submit@bugs.debian.org id=B.14468268164138 (code B); Fri, 06 Nov 2015 16:33:02 +0000 Received: (at submit) by bugs.debian.org; 6 Nov 2015 16:20:16 +0000 Received: from cheddar.halon.org.uk ([93.93.131.118]) by buxtehude.debian.org with esmtps (TLS1.2:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.84) (envelope-from ) id 1ZujkO-00012i-4b for submit@bugs.debian.org; Fri, 06 Nov 2015 16:20:16 +0000 Received: from bsmtp by cheddar.halon.org.uk with local-bsmtp (Exim 4.80) (envelope-from ) id 1ZujkI-0005Ac-LY; Fri, 06 Nov 2015 16:20:10 +0000 Received: from steve by tack.local with local (Exim 4.84) (envelope-from ) id 1Zujjp-0007iW-HU; Fri, 06 Nov 2015 16:19:41 +0000 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Steve McIntyre To: Debian Bug Tracking System Message-ID: <20151106161941.15248.86048.reportbug@tack.local> X-Mailer: reportbug 6.6.3 Date: Fri, 06 Nov 2015 16:19:41 +0000 Delivered-To: submit@bugs.debian.org X-Barracuda-Connect: buxtehude.debian.org[140.211.166.26] X-Barracuda-Start-Time: 1446827589 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24165 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Package: xfsprogs Version: 3.2.1 Severity: important Tags: d-i Hi! Since the move to systemd as the default init system, the initramfs will attempt to fsck and mount both / and /usr (where applicable). To aid this, initramfs-tools will copy necessary filesystem tools into the initramfs when it is generated. To make this work well, all filesystem tools packages for filesystems that are likely to be used for / and/or /usr should call "update-initramfs -u" in their postinst. This will (a) ensure that necesssary fsck tools are included in the initramfs generated by debian-installer (see #801961 for an example failure here); and (b) ensure that bug fixes to fsck tools get included immediately in the initramfs I've checked your package and I don't see any update-initramfs calls. Please add one. If you'd like help doing that postinst work, I can supply a patch - just ask! -- System Information: Debian Release: 8.2 APT prefers stable APT policy: (500, 'stable') Architecture: amd64 (x86_64) Foreign Architectures: i386 Kernel: Linux 3.16.0-4-amd64 (SMP w/4 CPU cores) Locale: LANG=en_GB.UTF-8, LC_CTYPE=en_GB.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Init: systemd (via /run/systemd/system) Versions of packages xfsprogs depends on: ii libblkid1 2.25.2-6 ii libc6 2.19-18+deb8u1 ii libreadline5 5.2+dfsg-2 ii libuuid1 2.25.2-6 xfsprogs recommends no packages. Versions of packages xfsprogs suggests: ii acl 2.2.52-2 ii attr 1:2.4.47-2 pn quota pn xfsdump -- no debconf information From sandeen@sandeen.net Fri Nov 6 10:54:17 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 63A687F75 for ; Fri, 6 Nov 2015 10:54:17 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id D4E1DAC005 for ; Fri, 6 Nov 2015 08:54:16 -0800 (PST) X-ASG-Debug-ID: 1446828851-04cbb024228c290001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id WhFdhqQ8eCWuILDH for ; Fri, 06 Nov 2015 08:54:12 -0800 (PST) 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 B89E06372A80 for ; Fri, 6 Nov 2015 10:54:11 -0600 (CST) Subject: Re: Several bugs in xfs-progs when parsing invalid input To: xfs@oss.sgi.com X-ASG-Orig-Subj: Re: Several bugs in xfs-progs when parsing invalid input References: <20151105174732.2378bc35@pc1> From: Eric Sandeen Message-ID: <563CDB33.5010704@sandeen.net> Date: Fri, 6 Nov 2015 10:54:11 -0600 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <20151105174732.2378bc35@pc1> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 8bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1446828852 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24166 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 11/5/15 10:47 AM, Hanno Böck wrote: > Hi, > > A while ago I reported a couple of bugs into your bugtracker about > issues in xfs_repair that I found through fuzzing (with the tool > american fuzzy lop). > > http://oss.sgi.com/bugzilla/show_bug.cgi?id=1119 > null pointer access > > http://oss.sgi.com/bugzilla/show_bug.cgi?id=1120 > out of bounds heap read access > > http://oss.sgi.com/bugzilla/show_bug.cgi?id=1121 > http://oss.sgi.com/bugzilla/show_bug.cgi?id=1122 > 2x assert > > When opening these bugs I got an error message. I then contacted your > support and almost two months(!) later I got a reply telling me that I > should not use bugzilla, instead I should report bugs to this mailing > list. > > Your webpage however clearly states that I should use bugzilla: > http://oss.sgi.com/projects/xfs/ oss.sgi.com infrastructure is not well maintained, I'm sorry about that, but it's up to SGI to fix anything that needs fixing, I'm afraid. Which is a pity, because a well-maintained bug tracker would be pretty useful. That said, reporting to the list is also probably a good idea. > This is all a bit ridiculous. If you don't want people to use your > bugzilla don't say so on your webpage and preferrably disable the > creation of new bugs. > > Anyway: Please have a look at the bugs I reported (and once they're > fixed I'll happily re-test the code to see if there are more issues > that can be found via fuzzing). You didn't say what version of xfsprogs you tested, but there have been a few independent fuzz-related fixes recently; you might just retest against what's currently in the git tree, and see if we got lucky. ;) Thanks, - -Eric -----BEGIN PGP SIGNATURE----- Version: GnuPG/MacGPG2 v2.0.17 (Darwin) Comment: GPGTools - http://gpgtools.org iQIcBAEBAgAGBQJWPNsyAAoJECCuFpLhPd7gcIcP/26oNtf4LctRnyNwAQfqdp99 SCoJoCBnJLY8B8CI4ut1LkUzaCmGw3tC/sB5i+JxV9kU2U1IZ3D06mw3HMFrf2zB /AXxTyZPejpNGmWsfn8XevaC0t2/qGqZp6cEyE7IeK7CCDfKl/ulmTg0np3uexTo /FRTBkFJtM9TOgByvbuk0CAeW4zC9VUCBubV5KxXFgJgQIigHDZhdVPl6gFfPuov +AZu8jNAK+zKcmlziUxZHr+xL/8T+IVGkao91pqxXYDW/p0OYC4XlOm8NCQ+Z7HQ zuCWDyL8Y1lCwqJonkO+slFQ1YtF2K2zBmyT8HBzmqd294/9SP8pJcyZkm9JKbvC on2AipTqrob90xHnMyyIrU9stbfa2vlFo2CDUzDwklY6M3dfViPoMrkAu+IRxjC0 aenoezYSYJ6H4blAfvWeSHwmfSUp9qtS+QR0ETPLqw+w1WARrbxjqcARw+ln4dOY +0AgUJfc6UFmgGkulX2qQqFX8zNth9uE09TIU5q2Gy9/uY2hkK7mgQ4sVNQMVt7f M2vooAh8vF59PrJt6fTOHeSMrTcScl1fi1N0sQgnWfDUWlh81gSCRBy3drg02JGB nh3wcAJo4D726fyucRh7XSj+3k2CUas/Y87kDevX5A8xBBNNiT/S4ueYlg7BEPT4 5Y20B/KyIe0jQiLFLOMU =Vuhf -----END PGP SIGNATURE----- From bfoster@redhat.com Fri Nov 6 10:55:14 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 E91177F76 for ; Fri, 6 Nov 2015 10:55:14 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id CACD68F8049 for ; Fri, 6 Nov 2015 08:55:14 -0800 (PST) X-ASG-Debug-ID: 1446828913-04bdf03f05876b0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id FLglxDufyxiEJ1VA (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 06 Nov 2015 08:55:13 -0800 (PST) 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 (Postfix) with ESMTPS id 61892E7076 for ; Fri, 6 Nov 2015 16:55:13 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-67.bos.redhat.com [10.18.41.67]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA6GtDZ3023088 for ; Fri, 6 Nov 2015 11:55:13 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id E7616125010; Fri, 6 Nov 2015 11:55:11 -0500 (EST) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH] xfs: fix log recovery op header validation assert Date: Fri, 6 Nov 2015 11:55:11 -0500 X-ASG-Orig-Subj: [PATCH] xfs: fix log recovery op header validation assert Message-Id: <1446828911-11314-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: 1446828913 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Commit 89cebc84 ("xfs: validate transaction header length on log recovery") added additional validation of the on-disk op header length to protect from buffer overflow during log recovery. It accounts for the fact that the transaction header can be split across multiple op headers. It added an assert for when this occurs that verifies the length of the second part of a split transaction header is less than a full transaction header. In other words, it expects that the first op header of a split transaction header includes at least some portion of the transaction header. This expectation is not always valid as a zero-length op header can exist for the first op header of a split transaction header (see xlog_recover_add_to_trans() for details). This means that the second op header can have a valid, full length transaction header and thus the full header is copied in xlog_recover_add_to_cont_trans(). Fix the assert in xlog_recover_add_to_cont_trans() to handle this case correctly and require that the op header length is less than or equal to a full transaction header. Signed-off-by: Brian Foster --- fs/xfs/xfs_log_recover.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index f8f1363..c5ecaac 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -3431,7 +3431,7 @@ xlog_recover_add_to_cont_trans( * previous record. Copy the rest of the header. */ if (list_empty(&trans->r_itemq)) { - ASSERT(len < sizeof(struct xfs_trans_header)); + ASSERT(len <= sizeof(struct xfs_trans_header)); if (len > sizeof(struct xfs_trans_header)) { xfs_warn(log->l_mp, "%s: bad header length", __func__); return -EIO; -- 2.1.0 From brian.boylston@hpe.com Fri Nov 6 12:14:00 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 DAB7E7F7B for ; Fri, 6 Nov 2015 12:14:00 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id CB2B6304051 for ; Fri, 6 Nov 2015 10:13:57 -0800 (PST) X-ASG-Debug-ID: 1446833635-04cb6c296d8a210001-NocioJ Received: from g1t5425.austin.hp.com (g1t5425.austin.hp.com [15.216.225.55]) by cuda.sgi.com with ESMTP id 7sJAw8SuWAp3wxwv (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 06 Nov 2015 10:13:56 -0800 (PST) X-Barracuda-Envelope-From: brian.boylston@hpe.com X-Barracuda-Apparent-Source-IP: 15.216.225.55 Received: from G2W4316.americas.hpqcorp.net (g2w4316.austin.hp.com [16.197.9.73]) (using TLSv1 with cipher AES128-SHA (128/128 bits)) (No client certificate requested) by g1t5425.austin.hp.com (Postfix) with ESMTPS id 861055A; Fri, 6 Nov 2015 18:13:55 +0000 (UTC) Received: from G1W5784.americas.hpqcorp.net (16.193.26.2) by G2W4316.americas.hpqcorp.net (16.197.9.73) with Microsoft SMTP Server (TLS) id 14.3.169.1; Fri, 6 Nov 2015 18:12:51 +0000 Received: from G1W3650.americas.hpqcorp.net ([169.254.8.95]) by G1W5784.americas.hpqcorp.net ([16.193.26.2]) with mapi id 14.03.0169.001; Fri, 6 Nov 2015 18:12:51 +0000 From: "Boylston, Brian" To: Dave Chinner , "xfs@oss.sgi.com" CC: "ross.zwisler@linux.intel.com" , "jack@suse.cz" Subject: RE: [PATCH 0/6 V2] xfs: upfront block zeroing for DAX Thread-Topic: [PATCH 0/6 V2] xfs: upfront block zeroing for DAX X-ASG-Orig-Subj: RE: [PATCH 0/6 V2] xfs: upfront block zeroing for DAX Thread-Index: AQHq71+Fq3vnJ+w8E4b07LUyLp82+Z5bm5Eg Date: Fri, 6 Nov 2015 18:12:51 +0000 Message-ID: <80B02B5F638F054B8B1358323FECDE0A5EA64CFA@G1W3650.americas.hpqcorp.net> References: <1445225238-30413-1-git-send-email-david@fromorbit.com> In-Reply-To: <1445225238-30413-1-git-send-email-david@fromorbit.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [16.193.232.23] Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-Barracuda-Connect: g1t5425.austin.hp.com[15.216.225.55] X-Barracuda-Start-Time: 1446833636 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/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 Hi, I wrote a test tool that exercises page faults on hole-y portions of an mmapped file. The file is created, sized using various methods, mmapped, and then two threads race to write a marker to different offsets within each mapped page. Once the threads have finished marking each page, the pages are checked for the presence of the markers. The test easily exposes corruption on pmem-backed, DAX-mounted xfs and ext4 file systems. With 4.3 and this patch set, the data corruption is no longer seen. The test code was posted to linux-ext4: http://marc.info/?l=3Dlinux-ext4&m=3D144683276225574&w=3D2 For the series: Tested-by: Brian Boylston -----Original Message----- From: Dave Chinner [mailto:david@fromorbit.com]=20 Sent: Sunday, October 18, 2015 11:27 PM Subject: [PATCH 0/6 V2] xfs: upfront block zeroing for DAX Hi folks, This is an updated patch set that was first posted here: http://oss.sgi.com/archives/xfs/2015-10/msg00006.html I've dropped the DAX locking revert patch from it; that's on it's way to Linus via other channels and is essentially independent to this set of XFS changes. The only real change in the XFS code between the two versions is the addition of XFS_TRANS_RESERVE in the DAX path in xfs_iomap_write_direct() to allow it to dip into the reserve block pool for unwritten extent conversion rather than reporting ENOSPC. Patches are against 4.3-rc5 + XFS for-next branch. -Dave. From adilger@dilger.ca Fri Nov 6 14:40:33 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 A8DF57F75 for ; Fri, 6 Nov 2015 14:40:33 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 971808F8035 for ; Fri, 6 Nov 2015 12:40:30 -0800 (PST) X-ASG-Debug-ID: 1446842427-04cbb0242595d30001-NocioJ Received: from mail-pa0-f43.google.com (mail-pa0-f43.google.com [209.85.220.43]) by cuda.sgi.com with ESMTP id VCQ3aYi1mb7JVsjv (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Fri, 06 Nov 2015 12:40:27 -0800 (PST) X-Barracuda-Envelope-From: adilger@dilger.ca X-Barracuda-RBL-Trusted-Forwarder: 209.85.220.43 Received: by pabfh17 with SMTP id fh17so132962785pab.0 for ; Fri, 06 Nov 2015 12:40:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=dilger_ca.20150623.gappssmtp.com; s=20150623; h=subject:mime-version:content-type:from:in-reply-to:date:cc :message-id:references:to; bh=tpPwAXA0x8LtAhMB28yqDxo4iTd62Z9QjWnD/Xjl8Gs=; b=ceAHNH7z5fTx2hlmcWnDM4NzdOUMQFSGk2ZFKzsMzcuUbLptJMq/W49hPcOR+9TKbR LsN9QT7nBa2JqJNCRMLrsLGJsAv/N/2jiP+qQ7ATJZbPqDeANVT8kim4bRQl8/nsnPah yzAlnbXn58wKLJlg4vsVOXote/AVmGAP0rWHtBi2Yi1E8LWLvHmo1OIrS0AnGgaPWYr4 bx5haErTTnG2wc0K6OgmKHrOHlPY/n+AKr6YkcP1yka2XjtwY1KM2etlEjhKRgl+eDBt ZzccmC0V+dy7diiNHaK5cylQv1XMR+JPan3w51hmbmDiB1ZsDdqOtB1nEdZSdRvmLRFM ehjQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:subject:mime-version:content-type:from :in-reply-to:date:cc:message-id:references:to; bh=tpPwAXA0x8LtAhMB28yqDxo4iTd62Z9QjWnD/Xjl8Gs=; b=Mqg8euQOKSW5GAsi5CJFUwFc5059gGMurKn6pvGBpN9b4QRI2SQu3bqtD5EVkxsTHz S8/ByDobamvBVTik2mCMXcQWoa5cS7cC7tSxBlPHCySNxzYAGwo/fO0ewdWv0Qs3Z+P9 6JKT0x2CCScRUuwt3eZ9UgKGQivhQIOp2Zb5sAoQ2zB0v0syHTiA7Tx6Bq/wudQ2quyi VwI2SABiKxflRduUHD9OYQxft+d3PZy9UGrWsVml1mGUVSWPEFNatA5U2fdrflXNbjT1 xQMKoUkq7Nh1lw0EK9VOqrJX5z/HajnxWQQ7BoGLFEFKet1x+c1JNaUIB9Ygzoq0ToR8 Ayvg== X-Gm-Message-State: ALoCoQmBSNjJLbAd540IrAM7RgHpVF+qcAFMgMx9e+qdElVcoMDAvhZED/rk0NEIh1jGB1I7YCjn X-Received: by 10.68.175.66 with SMTP id by2mr20343963pbc.3.1446842426971; Fri, 06 Nov 2015 12:40:26 -0800 (PST) Received: from cabot-wlan.adilger.int (S0106002191d9348b.cg.shawcable.net. [96.51.76.157]) by smtp.gmail.com with ESMTPSA id v13sm1669461pbs.51.2015.11.06.12.40.24 (version=TLS1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 06 Nov 2015 12:40:26 -0800 (PST) Subject: Re: [PATCH v14 01/22] vfs: Add IS_ACL() and IS_RICHACL() tests X-Barracuda-Apparent-Source-IP: 96.51.76.157 X-Barracuda-BBL-IP: 96.51.76.157 Mime-Version: 1.0 (Mac OS X Mail 8.2 \(2104\)) X-ASG-Orig-Subj: Re: [PATCH v14 01/22] vfs: Add IS_ACL() and IS_RICHACL() tests Content-Type: multipart/signed; boundary="Apple-Mail=_6590A0FC-D328-440C-B3C9-4B91CB6E915B"; protocol="application/pgp-signature"; micalg=pgp-sha256 X-Pgp-Agent: GPGMail 2.5.2 From: Andreas Dilger In-Reply-To: <1446723580-3747-2-git-send-email-agruenba@redhat.com> Date: Fri, 6 Nov 2015 13:40:19 -0700 Cc: Alexander Viro , Theodore Ts'o , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4 , XFS Developers , LKML , linux-fsdevel , Linux NFS Mailing List , linux-cifs@vger.kernel.org, Linux API Message-Id: References: <1446723580-3747-1-git-send-email-agruenba@redhat.com> <1446723580-3747-2-git-send-email-agruenba@redhat.com> To: Andreas Gruenbacher X-Mailer: Apple Mail (2.2104) X-Barracuda-Connect: mail-pa0-f43.google.com[209.85.220.43] X-Barracuda-Start-Time: 1446842427 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24172 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 --Apple-Mail=_6590A0FC-D328-440C-B3C9-4B91CB6E915B Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii On Nov 5, 2015, at 4:39 AM, Andreas Gruenbacher = wrote: >=20 > The vfs does not apply the umask for file systems that support acls. = The > test used for this used to be called IS_POSIXACL(). Switch to a new > IS_ACL() test to check for either posix acls or richacls instead. Add = a new > MS_RICHACL flag and IS_RICHACL() test for richacls alone. The = IS_POSIXACL() > test is still needed by nfsd. >=20 > Signed-off-by: Andreas Gruenbacher > Reviewed-by: J. Bruce Fields Looks good to me. Reviewed-by: Andreas Dilger > --- > fs/Kconfig | 3 +++ > fs/namei.c | 8 ++++---- > include/linux/fs.h | 12 ++++++++++++ > include/uapi/linux/fs.h | 3 ++- > 4 files changed, 21 insertions(+), 5 deletions(-) >=20 > diff --git a/fs/Kconfig b/fs/Kconfig > index da3f32f..bff2879 100644 > --- a/fs/Kconfig > +++ b/fs/Kconfig > @@ -56,6 +56,9 @@ endif # BLOCK > config FS_POSIX_ACL > def_bool n >=20 > +config FS_RICHACL > + def_bool n > + > config EXPORTFS > tristate >=20 > diff --git a/fs/namei.c b/fs/namei.c > index 33e9495..224ecf1 100644 > --- a/fs/namei.c > +++ b/fs/namei.c > @@ -2798,7 +2798,7 @@ static int atomic_open(struct nameidata *nd, = struct dentry *dentry, > } >=20 > mode =3D op->mode; > - if ((open_flag & O_CREAT) && !IS_POSIXACL(dir)) > + if ((open_flag & O_CREAT) && !IS_ACL(dir)) > mode &=3D ~current_umask(); >=20 > excl =3D (open_flag & (O_EXCL | O_CREAT)) =3D=3D (O_EXCL | = O_CREAT); > @@ -2982,7 +2982,7 @@ static int lookup_open(struct nameidata *nd, = struct path *path, > /* Negative dentry, just create the file */ > if (!dentry->d_inode && (op->open_flag & O_CREAT)) { > umode_t mode =3D op->mode; > - if (!IS_POSIXACL(dir->d_inode)) > + if (!IS_ACL(dir->d_inode)) > mode &=3D ~current_umask(); > /* > * This write is needed to ensure that a > @@ -3553,7 +3553,7 @@ retry: > if (IS_ERR(dentry)) > return PTR_ERR(dentry); >=20 > - if (!IS_POSIXACL(path.dentry->d_inode)) > + if (!IS_ACL(path.dentry->d_inode)) > mode &=3D ~current_umask(); > error =3D security_path_mknod(&path, dentry, mode, dev); > if (error) > @@ -3622,7 +3622,7 @@ retry: > if (IS_ERR(dentry)) > return PTR_ERR(dentry); >=20 > - if (!IS_POSIXACL(path.dentry->d_inode)) > + if (!IS_ACL(path.dentry->d_inode)) > mode &=3D ~current_umask(); > error =3D security_path_mkdir(&path, dentry, mode); > if (!error) > diff --git a/include/linux/fs.h b/include/linux/fs.h > index 72d8a84..4efa435 100644 > --- a/include/linux/fs.h > +++ b/include/linux/fs.h > @@ -1781,6 +1781,12 @@ struct super_operations { > #define IS_IMMUTABLE(inode) ((inode)->i_flags & S_IMMUTABLE) > #define IS_POSIXACL(inode) __IS_FLG(inode, MS_POSIXACL) >=20 > +#ifdef CONFIG_FS_RICHACL > +#define IS_RICHACL(inode) __IS_FLG(inode, MS_RICHACL) > +#else > +#define IS_RICHACL(inode) 0 > +#endif > + > #define IS_DEADDIR(inode) ((inode)->i_flags & S_DEAD) > #define IS_NOCMTIME(inode) ((inode)->i_flags & S_NOCMTIME) > #define IS_SWAPFILE(inode) ((inode)->i_flags & S_SWAPFILE) > @@ -1794,6 +1800,12 @@ struct super_operations { > (inode)->i_rdev =3D=3D WHITEOUT_DEV) >=20 > /* > + * IS_ACL() tells the VFS to not apply the umask > + * and use check_acl for acl permission checks when defined. > + */ > +#define IS_ACL(inode) __IS_FLG(inode, MS_POSIXACL | = MS_RICHACL) > + > +/* > * Inode state bits. Protected by inode->i_lock > * > * Three bits determine the dirty state of the inode, I_DIRTY_SYNC, > diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h > index 9b964a5..6ac6bc9 100644 > --- a/include/uapi/linux/fs.h > +++ b/include/uapi/linux/fs.h > @@ -81,7 +81,7 @@ struct inodes_stat_t { > #define MS_VERBOSE 32768 /* War is peace. Verbosity is silence. > MS_VERBOSE is deprecated. */ > #define MS_SILENT 32768 > -#define MS_POSIXACL (1<<16) /* VFS does not apply the umask */ > +#define MS_POSIXACL (1<<16) /* Supports POSIX ACLs */ > #define MS_UNBINDABLE (1<<17) /* change to unbindable */ > #define MS_PRIVATE (1<<18) /* change to private */ > #define MS_SLAVE (1<<19) /* change to slave */ > @@ -91,6 +91,7 @@ struct inodes_stat_t { > #define MS_I_VERSION (1<<23) /* Update inode I_version field */ > #define MS_STRICTATIME (1<<24) /* Always perform atime updates = */ > #define MS_LAZYTIME (1<<25) /* Update the on-disk [acm]times lazily = */ > +#define MS_RICHACL (1<<26) /* Supports richacls */ >=20 > /* These sb flags are internal to the kernel */ > #define MS_NOSEC (1<<28) > -- > 2.5.0 >=20 Cheers, Andreas --Apple-Mail=_6590A0FC-D328-440C-B3C9-4B91CB6E915B Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename=signature.asc Content-Type: application/pgp-signature; name=signature.asc Content-Description: Message signed with OpenPGP using GPGMail -----BEGIN PGP SIGNATURE----- Comment: GPGTools - http://gpgtools.org iQIVAwUBVj0QNHKl2rkXzB/gAQgu9BAApe7t8JVkJBussiJ9KKn3HcKnbRMd0Ceb yHLcspAiOUXHfjYzZdKOrdXC2PIGV0Yn9ka6dMHKjktKAy95hTtkGdyKZFTtS5eu TvyEtTo0OX0I1XhuSQWBljBlO98BdgggT4mDUY52rmb34E8wEEiuCA3vESEQtVJm TblPjsT9xHFwMsApvbLRM+SD8PQl5x6n8lyzUtc4rcRBnpSlYO1AapJ5CKbKUXRR J1J4a8cU5hEGshwKqmd/vs+Gz8QsR6pXCuGxmG+d4OjjtoQa2y60b+e8BHL8yYHp qmaDKEXsJVl93H29IC+Pfah5DTsFpBPi3kcZMT86UGnIE5dcQocB9zhloiY3l14Y M+uV9MDmzgI8y/+vyytmwtECYlaXfFcMbYYolxfBqDi/p4OPS1nRsDUHJL/Ph+g8 jqyALbYkqGdJIBj9Yumh7ZSFtCMeQzlFZI1SctRddOk7DYgvuKoTqC+8zo3ttIbP Fa3sL2RtPd5HsNP6ksNsye5qblhV2CfLpq+hox8XxEW2GUF8+uO/cI+s6ugChNsi hMCc5Yn1ANjicj2jmJH7e1f2WZxM1hnDNv3Jw34CoUkb4mWPgiw9Y3IBDBvq4Br3 2rvRPo4XkvZy4Y37dKb1latxRllqsbDU6Dhs2HZpCuTBHklw2BpWTjMxr2F8rXxV 5rtthkKehAA= =qMGN -----END PGP SIGNATURE----- --Apple-Mail=_6590A0FC-D328-440C-B3C9-4B91CB6E915B-- From adilger@dilger.ca Fri Nov 6 14:58:53 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 171CD7F76 for ; Fri, 6 Nov 2015 14:58:53 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id D9F0A8F8040 for ; Fri, 6 Nov 2015 12:58:52 -0800 (PST) X-ASG-Debug-ID: 1446843530-04bdf03f0290490001-NocioJ Received: from mail-pa0-f47.google.com (mail-pa0-f47.google.com [209.85.220.47]) by cuda.sgi.com with ESMTP id DSCHHbDgLz9o8xir (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Fri, 06 Nov 2015 12:58:50 -0800 (PST) X-Barracuda-Envelope-From: adilger@dilger.ca X-Barracuda-RBL-Trusted-Forwarder: 209.85.220.47 Received: by pasz6 with SMTP id z6so137560979pas.2 for ; Fri, 06 Nov 2015 12:58:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=dilger_ca.20150623.gappssmtp.com; s=20150623; h=subject:mime-version:content-type:from:in-reply-to:date:cc :message-id:references:to; bh=YDARGOGBVvAnsgvy77qqaqDlN59HCPbl0RcNrapH/9M=; b=nxI2h/kfrCJb+mWNUdPfB502U3m5r1eMEhjd1hS861w4uqvl/YeubTGlEUmz7szXkA FKUo9pBX9VQoLxjhkNeJDFMC4U+87DRHzKPJifVj2Hl4rM3z3u4jmBI5KF3kWMsTG04q pxnn3MDQzMzMH78neZdFrIKO5V+vqO3g6IuXsNTXeO7ZPRWL87zzFlcLMxvEv5w87eLJ DO52VjXD2nlOeeZoxd4yqV5TS41Ef+prfbF2vANXjlUPBB+HcTXdtt4Y9GCXiME59a/+ ZUjERrLP8uS1pUh+bNqgXEhtfDOY1B7PDO9wKaZrYwpEGNbFvp5r4nTH+DQgXvW6Y+jo aSvw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:subject:mime-version:content-type:from :in-reply-to:date:cc:message-id:references:to; bh=YDARGOGBVvAnsgvy77qqaqDlN59HCPbl0RcNrapH/9M=; b=ck/bJbc4P4Ynfqd7WSBjSZoXIni9HNcJtCmMHTEDTUxQWv5yduolty2fQlLvUrXGA1 4d+0WzO+nNw8gupDDeH6cDrwI1pYthn1+c3a/bR2yQwqwtnG593SHWrj74d87YGXG+ai OR18XLFLyGsUYt12Pha+xvGJKSn4/lkIdHr5N2BIH+vQqjyrWD4VW8/8oYjdRURau1hW QsNaauNItHokkEMpTcMXE/4gLLiyXiwIe0ghxKMs5BQgQ10D26xaz940N9Jjzmq7hofX C5XJa3pSqhxZ1OGkQY0hUyK3TB22wDiuJEVwnG+1YRUk4tBfYq8GupjdSqAwk89rA/nu o1EQ== X-Gm-Message-State: ALoCoQl2kMKS1+6f0PQxoGu0uTJjTHbT7/QSwH/eI792nvOvtbyQhKh5fkRoSoJ8LhK+vWXifyZe X-Received: by 10.66.249.37 with SMTP id yr5mr10547931pac.24.1446843529686; Fri, 06 Nov 2015 12:58:49 -0800 (PST) Received: from cabot-wlan.adilger.int (S0106002191d9348b.cg.shawcable.net. [96.51.76.157]) by smtp.gmail.com with ESMTPSA id wq1sm1716133pbc.49.2015.11.06.12.58.47 (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 06 Nov 2015 12:58:48 -0800 (PST) Subject: Re: [PATCH v14 02/22] vfs: Add MAY_CREATE_FILE and MAY_CREATE_DIR permission flags X-Barracuda-Apparent-Source-IP: 96.51.76.157 X-Barracuda-BBL-IP: 96.51.76.157 Mime-Version: 1.0 (Mac OS X Mail 8.2 \(2104\)) X-ASG-Orig-Subj: Re: [PATCH v14 02/22] vfs: Add MAY_CREATE_FILE and MAY_CREATE_DIR permission flags Content-Type: multipart/signed; boundary="Apple-Mail=_CF1F0347-94B9-4516-BCFE-FD637F708057"; protocol="application/pgp-signature"; micalg=pgp-sha256 X-Pgp-Agent: GPGMail 2.5.2 From: Andreas Dilger In-Reply-To: <1446723580-3747-3-git-send-email-agruenba@redhat.com> Date: Fri, 6 Nov 2015 13:58:42 -0700 Cc: Alexander Viro , Theodore Ts'o , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Message-Id: References: <1446723580-3747-1-git-send-email-agruenba@redhat.com> <1446723580-3747-3-git-send-email-agruenba@redhat.com> To: Andreas Gruenbacher X-Mailer: Apple Mail (2.2104) X-Barracuda-Connect: mail-pa0-f47.google.com[209.85.220.47] X-Barracuda-Start-Time: 1446843530 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24174 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 --Apple-Mail=_CF1F0347-94B9-4516-BCFE-FD637F708057 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii On Nov 5, 2015, at 4:39 AM, Andreas Gruenbacher = wrote: >=20 > Richacls distinguish between creating non-directories and directories. = To > support that, add an isdir parameter to may_create(). When checking > inode_permission() for create permission, pass in an additional > MAY_CREATE_FILE or MAY_CREATE_DIR mask flag. >=20 > To allow checking for delete *and* create access when replacing an = existing > file via vfs_rename(), add a replace parameter to may_delete(). I thought you proposed adding an enum for these parameters, and possibly making them a single parameter flag, to make the code in the caller more readable. Flags like below for example, though I'm not stuck on = "MAY_IS" as a prefix, just my first thought: enum may_flags { MAY_IS_FILE =3D 0x0, /* Essentially !MAY_IS_DIR */ MAY_IS_DIR =3D 0x1, /* Operation only allowed on = directory */ MAY_IS_REPLACE =3D 0x2, /* Operation only }; would make it immediately clear what is being passed to the function. Some examples inline below. If Al hates it, fine, but having functions with multiple "true, false" or "false, true" arguments is ugly and error prone, IMHO. > Signed-off-by: Andreas Gruenbacher > Reviewed-by: J. Bruce Fields > --- > fs/namei.c | 43 +++++++++++++++++++++++++------------------ > include/linux/fs.h | 2 ++ > 2 files changed, 27 insertions(+), 18 deletions(-) >=20 > diff --git a/fs/namei.c b/fs/namei.c > index 224ecf1..0259392 100644 > --- a/fs/namei.c > +++ b/fs/namei.c > @@ -453,7 +453,9 @@ static int sb_permission(struct super_block *sb, = struct inode *inode, int mask) > * this, letting us set arbitrary permissions for filesystem access = without > * changing the "normal" UIDs which are used for other things. > * > - * When checking for MAY_APPEND, MAY_WRITE must also be set in @mask. > + * MAY_WRITE must be set in @mask whenever MAY_APPEND, = MAY_CREATE_FILE, or > + * MAY_CREATE_DIR are set. That way, file systems that don't support = these > + * permissions will check for MAY_WRITE instead. > */ > int inode_permission(struct inode *inode, int mask) > { > @@ -2549,10 +2551,11 @@ EXPORT_SYMBOL(__check_sticky); > * 10. We don't allow removal of NFS sillyrenamed files; it's handled = by > * nfs_async_unlink(). > */ > -static int may_delete(struct inode *dir, struct dentry *victim, bool = isdir) > +static int may_delete(struct inode *dir, struct dentry *victim, > + bool isdir, bool replace) > { > struct inode *inode =3D d_backing_inode(victim); > - int error; > + int error, mask =3D MAY_WRITE | MAY_EXEC; >=20 > if (d_is_negative(victim)) > return -ENOENT; > @@ -2561,7 +2564,9 @@ static int may_delete(struct inode *dir, struct = dentry *victim, bool isdir) > BUG_ON(victim->d_parent->d_inode !=3D dir); > audit_inode_child(dir, victim, AUDIT_TYPE_CHILD_DELETE); >=20 > - error =3D inode_permission(dir, MAY_WRITE | MAY_EXEC); > + if (replace) > + mask |=3D isdir ? MAY_CREATE_DIR : MAY_CREATE_FILE; > + error =3D inode_permission(dir, mask); > if (error) > return error; > if (IS_APPEND(dir)) > @@ -2592,14 +2597,16 @@ static int may_delete(struct inode *dir, = struct dentry *victim, bool isdir) > * 3. We should have write and exec permissions on dir > * 4. We can't do it if dir is immutable (done in permission()) > */ > -static inline int may_create(struct inode *dir, struct dentry *child) > +static inline int may_create(struct inode *dir, struct dentry *child, = bool isdir) > { > + int mask =3D isdir ? MAY_CREATE_DIR : MAY_CREATE_FILE; > + > audit_inode_child(dir, child, AUDIT_TYPE_CHILD_CREATE); > if (child->d_inode) > return -EEXIST; > if (IS_DEADDIR(dir)) > return -ENOENT; > - return inode_permission(dir, MAY_WRITE | MAY_EXEC); > + return inode_permission(dir, MAY_WRITE | MAY_EXEC | mask); > } >=20 > /* > @@ -2649,7 +2656,7 @@ EXPORT_SYMBOL(unlock_rename); > int vfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, > bool want_excl) > { > - int error =3D may_create(dir, dentry); > + int error =3D may_create(dir, dentry, false); int error =3D may_create(dir, dentry, MAY_IS_FILE); > if (error) > return error; >=20 > @@ -3494,7 +3501,7 @@ EXPORT_SYMBOL(user_path_create); >=20 > int vfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, = dev_t dev) > { > - int error =3D may_create(dir, dentry); > + int error =3D may_create(dir, dentry, false); >=20 > if (error) > return error; > @@ -3586,7 +3593,7 @@ SYSCALL_DEFINE3(mknod, const char __user *, = filename, umode_t, mode, unsigned, d >=20 > int vfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) > { > - int error =3D may_create(dir, dentry); > + int error =3D may_create(dir, dentry, true); int error =3D may_create(dir, dentry, MAY_IS_DIR); > unsigned max_links =3D dir->i_sb->s_max_links; >=20 > if (error) > @@ -3667,7 +3674,7 @@ EXPORT_SYMBOL(dentry_unhash); >=20 > int vfs_rmdir(struct inode *dir, struct dentry *dentry) > { > - int error =3D may_delete(dir, dentry, 1); > + int error =3D may_delete(dir, dentry, true, false); The cases where there are multiple parameters is where it makes the most improvement, since the code is more readable: int error =3D may_delete(dir, dentry, MAY_IS_DIR); > if (error) > return error; > @@ -3789,7 +3796,7 @@ SYSCALL_DEFINE1(rmdir, const char __user *, = pathname) > int vfs_unlink(struct inode *dir, struct dentry *dentry, struct inode = **delegated_inode) > { > struct inode *target =3D dentry->d_inode; > - int error =3D may_delete(dir, dentry, 0); > + int error =3D may_delete(dir, dentry, false, false); int error =3D may_delete(dir, dentry, MAY_IS_FILE); Cheers, Andreas > if (error) > return error; > @@ -3923,7 +3930,7 @@ SYSCALL_DEFINE1(unlink, const char __user *, = pathname) >=20 > int vfs_symlink(struct inode *dir, struct dentry *dentry, const char = *oldname) > { > - int error =3D may_create(dir, dentry); > + int error =3D may_create(dir, dentry, false); >=20 > if (error) > return error; > @@ -4006,7 +4013,7 @@ int vfs_link(struct dentry *old_dentry, struct = inode *dir, struct dentry *new_de > if (!inode) > return -ENOENT; >=20 > - error =3D may_create(dir, new_dentry); > + error =3D may_create(dir, new_dentry, false); > if (error) > return error; >=20 > @@ -4194,19 +4201,19 @@ int vfs_rename(struct inode *old_dir, struct = dentry *old_dentry, > if (source =3D=3D target) > return 0; >=20 > - error =3D may_delete(old_dir, old_dentry, is_dir); > + error =3D may_delete(old_dir, old_dentry, is_dir, false); > if (error) > return error; >=20 > if (!target) { > - error =3D may_create(new_dir, new_dentry); > + error =3D may_create(new_dir, new_dentry, is_dir); > } else { > new_is_dir =3D d_is_dir(new_dentry); >=20 > if (!(flags & RENAME_EXCHANGE)) > - error =3D may_delete(new_dir, new_dentry, = is_dir); > + error =3D may_delete(new_dir, new_dentry, = is_dir, true); > else > - error =3D may_delete(new_dir, new_dentry, = new_is_dir); > + error =3D may_delete(new_dir, new_dentry, = new_is_dir, true); > } > if (error) > return error; > @@ -4469,7 +4476,7 @@ SYSCALL_DEFINE2(rename, const char __user *, = oldname, const char __user *, newna >=20 > int vfs_whiteout(struct inode *dir, struct dentry *dentry) > { > - int error =3D may_create(dir, dentry); > + int error =3D may_create(dir, dentry, false); > if (error) > return error; >=20 > diff --git a/include/linux/fs.h b/include/linux/fs.h > index 4efa435..d6e2330 100644 > --- a/include/linux/fs.h > +++ b/include/linux/fs.h > @@ -82,6 +82,8 @@ typedef void (dax_iodone_t)(struct buffer_head = *bh_map, int uptodate); > #define MAY_CHDIR 0x00000040 > /* called from RCU mode, don't block */ > #define MAY_NOT_BLOCK 0x00000080 > +#define MAY_CREATE_FILE 0x00000100 > +#define MAY_CREATE_DIR 0x00000200 >=20 > /* > * flags in file.f_mode. Note that FMODE_READ and FMODE_WRITE must = correspond > -- > 2.5.0 >=20 Cheers, Andreas --Apple-Mail=_CF1F0347-94B9-4516-BCFE-FD637F708057 Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename=signature.asc Content-Type: application/pgp-signature; name=signature.asc Content-Description: Message signed with OpenPGP using GPGMail -----BEGIN PGP SIGNATURE----- Comment: GPGTools - http://gpgtools.org iQIVAwUBVj0UgnKl2rkXzB/gAQj0pQ//S0x5zpIJIIlg0ZToZKnQtKv6YKa2Qsbu 60fY9fT901YO7DeSsO3F8e+qx8RYRDOTjtfedLalum7CxEd8BAmeY6EK17KVR0Fn m1lgacRF7bbplLEtiCtSkn1a26TbZPuMF0Z3YApvGWyBxZ0+0zaYKKOiPyZ8Ybz8 2NrltLToKzMxDzoMvsPE2+L4g1sxRwtiPhHiMs9/2oLJ64ML7ppNrzJn2dnGksDS XP1g4iv2sWf82jms2RFiZ0/2rECUkFZfWhcVbjSinHmM7H1+furXJ9H1pnMji0/j WyypBGlC4z0ovaOYXsJfrSv0jnS5XnoWXK3nQR+rGA6NvyujCPs5NjjpI8mrU+Yt Yv+ORJdhyOmVwtSZo4C4Nx1PDlki74WFoXiYkF5L5OorztgCxcdF4xtTxr7BY9J7 HwtIpXrxYUNHAfaSyPdj5zVSk1cED3Pgs0pdxkiSEgkX26ZZ/jZMzV1UYmvOsOvC UY0rgVHcHKtX5tWZ8mXUtIhVV0kugt3loj6JYiEhYPsUMcpq5xk9KqTQTfjYA2q+ U9EUjHjtZIKFH7Bw8XpXHdSF8Tww7wY2T/Dx5equgoiHn71wxqrXdfsqhhM90WSM 2B3ghmZaNdfnwSdQf3nR5A1Pfqoupq39BT+Gdx+VouIWNbGXFLxmDjCKxEeaKy9x Jgfoz+qXk6Y= =TK5q -----END PGP SIGNATURE----- --Apple-Mail=_CF1F0347-94B9-4516-BCFE-FD637F708057-- From adilger@dilger.ca Fri Nov 6 15:04:21 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 1882B7F76 for ; Fri, 6 Nov 2015 15:04:21 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 04AD78F8033 for ; Fri, 6 Nov 2015 13:04:17 -0800 (PST) X-ASG-Debug-ID: 1446843852-04cb6c296b8e110001-NocioJ Received: from mail-pa0-f53.google.com (mail-pa0-f53.google.com [209.85.220.53]) by cuda.sgi.com with ESMTP id p1kxy2VAtI5cXwkG (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Fri, 06 Nov 2015 13:04:13 -0800 (PST) X-Barracuda-Envelope-From: adilger@dilger.ca X-Barracuda-RBL-Trusted-Forwarder: 209.85.220.53 Received: by pabfh17 with SMTP id fh17so133462618pab.0 for ; Fri, 06 Nov 2015 13:04:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=dilger_ca.20150623.gappssmtp.com; s=20150623; h=subject:mime-version:content-type:from:in-reply-to:date:cc :message-id:references:to; bh=manz7KPaObuZ9L4QKC/42CcUOC8b0o782EuYEUxn4Zo=; b=hfOSnhFjc1bX//TvJTpHIV0DpMr57D0C7ZtMUgWuUsVsigWR5s7mBHb5oxplCXdqHI Riouw+9MgBEGCgbZJDb/TuEg1VVRuNGVfWCZanY0JOTXHXSbWCMQ9ZTdTSFvDZ1cn13z Sg6kUEgWxfBR6zx8Woaa+5clFf887+GJe80XkbbzFlVfawIdOsgsqDMywWxl7nr5uhiC bDEDWs9NpTNxpc0633FUJNKkRaHZLPheCtKhIfpAffjH2sk4ysv0IxDuD5NCRnBneNcc 7KKitXuoz6TYjcc1BwDQRKv5NcKzXx8hwvZv6EZlbkoNoJdyPdM4+0QL9T/Of9clxjYQ ctpA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:subject:mime-version:content-type:from :in-reply-to:date:cc:message-id:references:to; bh=manz7KPaObuZ9L4QKC/42CcUOC8b0o782EuYEUxn4Zo=; b=Gl576t2kHOfvV3lSK3R8DKiyoT3t6+qj0VgpI6R1UUcCYivO8x5YVgEN8hbFuQDWzx 8N/flN4ELS1nn91rcHY2h1x/x9bkm8XSGRfPtKmUsxzC9ixRVUg0WBu4FMe+7Lx6J6lV VBjsIawYz9dMGl7WhTNC0Egpx5jrlUhZanvhxPNrJEmZOuGv7yGyumqrvBHa4FxJnjL9 BdG+G9XBXwfaOZ5sBLHlTHE2Cx0UcheztO1dk1t0r1UlRa0IDSg8TpUl1JhyMxnDnVxg ezavbzgbbpputceFxStT2KwkNhcMKU7eKlNdx5p/0srMJmZHyN1O7hBY0/ouBxx3uPmD VmXw== X-Gm-Message-State: ALoCoQlXFqiU3IK25SNTmQctFpQI/Cr0Ps3YlC0wc5cDmIGfDidBSVuuJ56u5ZFyUSN1cZthyNaT X-Received: by 10.68.103.227 with SMTP id fz3mr20534989pbb.159.1446843852538; Fri, 06 Nov 2015 13:04:12 -0800 (PST) Received: from cabot-wlan.adilger.int (S0106002191d9348b.cg.shawcable.net. [96.51.76.157]) by smtp.gmail.com with ESMTPSA id ux3sm1739493pac.18.2015.11.06.13.04.10 (version=TLS1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 06 Nov 2015 13:04:11 -0800 (PST) Subject: Re: [PATCH v14 04/22] vfs: Make the inode passed to inode_change_ok non-const X-Barracuda-Apparent-Source-IP: 96.51.76.157 X-Barracuda-BBL-IP: 96.51.76.157 Mime-Version: 1.0 (Mac OS X Mail 8.2 \(2104\)) X-ASG-Orig-Subj: Re: [PATCH v14 04/22] vfs: Make the inode passed to inode_change_ok non-const Content-Type: multipart/signed; boundary="Apple-Mail=_C50AB9E3-D3AC-4D52-99DF-74EAB42E7D8D"; protocol="application/pgp-signature"; micalg=pgp-sha256 X-Pgp-Agent: GPGMail 2.5.2 From: Andreas Dilger In-Reply-To: <1446723580-3747-5-git-send-email-agruenba@redhat.com> Date: Fri, 6 Nov 2015 14:04:07 -0700 Cc: Alexander Viro , Theodore Ts'o , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Message-Id: References: <1446723580-3747-1-git-send-email-agruenba@redhat.com> <1446723580-3747-5-git-send-email-agruenba@redhat.com> To: Andreas Gruenbacher X-Mailer: Apple Mail (2.2104) X-Barracuda-Connect: mail-pa0-f53.google.com[209.85.220.53] X-Barracuda-Start-Time: 1446843853 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24173 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 --Apple-Mail=_C50AB9E3-D3AC-4D52-99DF-74EAB42E7D8D Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii > On Nov 5, 2015, at 4:39 AM, Andreas Gruenbacher = wrote: >=20 > We will need to call iop->permission and iop->get_acl from > inode_change_ok() for additional permission checks, and both take a > non-const inode. Seems unfortunate that those functions cannot themselves be changed to take a const struct inode, but it doesn't look possible. Reviewed-by: Andreas Dilger > Signed-off-by: Andreas Gruenbacher > Reviewed-by: J. Bruce Fields > --- > fs/attr.c | 2 +- > include/linux/fs.h | 2 +- > 2 files changed, 2 insertions(+), 2 deletions(-) >=20 > diff --git a/fs/attr.c b/fs/attr.c > index 6530ced..328be71 100644 > --- a/fs/attr.c > +++ b/fs/attr.c > @@ -28,7 +28,7 @@ > * Should be called as the first thing in ->setattr implementations, > * possibly after taking additional locks. > */ > -int inode_change_ok(const struct inode *inode, struct iattr *attr) > +int inode_change_ok(struct inode *inode, struct iattr *attr) > { > unsigned int ia_valid =3D attr->ia_valid; >=20 > diff --git a/include/linux/fs.h b/include/linux/fs.h > index 402acd7..aab32c8 100644 > --- a/include/linux/fs.h > +++ b/include/linux/fs.h > @@ -2871,7 +2871,7 @@ extern int buffer_migrate_page(struct = address_space *, > #define buffer_migrate_page NULL > #endif >=20 > -extern int inode_change_ok(const struct inode *, struct iattr *); > +extern int inode_change_ok(struct inode *, struct iattr *); > extern int inode_newsize_ok(const struct inode *, loff_t offset); > extern void setattr_copy(struct inode *inode, const struct iattr = *attr); >=20 > -- > 2.5.0 >=20 Cheers, Andreas --Apple-Mail=_C50AB9E3-D3AC-4D52-99DF-74EAB42E7D8D Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename=signature.asc Content-Type: application/pgp-signature; name=signature.asc Content-Description: Message signed with OpenPGP using GPGMail -----BEGIN PGP SIGNATURE----- Comment: GPGTools - http://gpgtools.org iQIVAwUBVj0Vx3Kl2rkXzB/gAQjYHQ/+L9LDlXVXWGi/GhDrCiBpnUWSkDNUm3a+ Vwxf/j2ZpsEZpgjz/sjgi+c189DNa1ZhpRe6M9kUYIQqofiHfYS+Yx3GpDvyCzUo qmXtDGSPMRzsOjMNlx9NPoQULPutHRWJcKvHTXypQHGl3qbezEFvbUfP47l0trqQ xir5U2N4z13p2ipJTq2Y7FstNqOgNU/xiF+BUeFlFDS5S8K6gXQVsAwhOHBpzRMp A5v60jIbYtP5MmRiKDSbrEQLQte1g4rIlKklWIsjAmTbK98CRc8f3eb4V+DXYzNp rjoTsY8H2XoJJeYmFe9/+CxVI/ICOoaCSRRZ9aV9hkff1gz2CifXM5kGy4WWO3Md puhLHUJIUNhmSqWJEsDCJOegOS7XlrnrFLscv4VkCpse7UM9kMtn/ZtJABzQItfk 5DQ4OCoR9u2tXJlyVG8XWHiKzpNYL0ehDeYlIagguHgir0bM5lj4cji3vmoCGDZS lU5vGydGX6nR8zeaTuPgGULObDEPOEi1jlDcyuSQz9VIhqTfuNgNPoZibZDhSYoH zb6T3pNiV4peHzRZ1E8Pi/pZ7yVEdtuKQWSP34QyDjspnANm1panb7MtIEo09TIk GPwEePLgLRlsrnD1bl1BhuZ4eby+yLYJp2c/AZnovrI4d7Wp1IQc4k9LFR5qB0ai 2AwZOWhuDpg= =SiKg -----END PGP SIGNATURE----- --Apple-Mail=_C50AB9E3-D3AC-4D52-99DF-74EAB42E7D8D-- From adilger@dilger.ca Fri Nov 6 15:26:55 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 558A57F84 for ; Fri, 6 Nov 2015 15:26:55 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 32FF8304039 for ; Fri, 6 Nov 2015 13:26:55 -0800 (PST) X-ASG-Debug-ID: 1446845212-04cbb02424969e0001-NocioJ Received: from mail-pa0-f44.google.com (mail-pa0-f44.google.com [209.85.220.44]) by cuda.sgi.com with ESMTP id n3dGgEkcmgmmvbdW (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Fri, 06 Nov 2015 13:26:53 -0800 (PST) X-Barracuda-Envelope-From: adilger@dilger.ca X-Barracuda-RBL-Trusted-Forwarder: 209.85.220.44 Received: by pabfh17 with SMTP id fh17so133929814pab.0 for ; Fri, 06 Nov 2015 13:26:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=dilger_ca.20150623.gappssmtp.com; s=20150623; h=subject:mime-version:content-type:from:in-reply-to:date:cc :message-id:references:to; bh=JvHMdQlbQAOdZ4EPzseOVQaIWunRi0hCA8/C1mDWubM=; b=WINoaDlwhnU5kYPV7Y0/Gl8sUhe0RzOcPngaRp/puyw/iRZPk5D9AEk6/LjmkHz2vi svSNVrIw2QfiSL61dnHRHqHwPssAycp4j5raXegnwPF+VEqgou2+HUp5QTOAbNp9BP+x LCBqxxTI3xlRMeZKpUT0ArMHurkb+j/h/Rcc9V403AAVWeEvFt1fOE9sD1D63xjC5FyE k+i9OfuTV7Rk5G6PYZ6FetFfJFqZwJL8TGzR0RlodpnuMoLrClzlaWVr4RWPvX/prSeX rRZeZns3l68Euozmcxyvzrol0n0v26kzA/10CKq6D93IbATi80iTOt93PEN6lPvrBIDW PWCw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:subject:mime-version:content-type:from :in-reply-to:date:cc:message-id:references:to; bh=JvHMdQlbQAOdZ4EPzseOVQaIWunRi0hCA8/C1mDWubM=; b=TsQwiQJej54WgxewsLct6iO+J9C0vm7a4X6axvn74j+fssytwsI1OdX/duNrcT6sda h9WdKrYH23JdNUIbAOZ48K+MKvjMOpRB6WyJ78LR2CrVUzOczlMdgK1BmHgOsSMQcFYc 7uG3Fw/1aGb8Ct3aQ1ZHZ7GMKuleN6erw+lzhroyojJv1T033XCRWaM9Q786rUX3HGUV g0qM11xh/1PbAWM8WYPIUsfeMOaTIgBV2JlmIW36Ql2fZkC+a4k/0dEoTsCX3AOmSr2s l289EiCI1srRypXgUmngv6zvwjj1PGZbhK8SoTAVXqxvxvqHfJ7UNSDxw5/P2iALNCFB zJYA== X-Gm-Message-State: ALoCoQnLxEdbWIQKgQnbDhiv3HJHZ0/wEsL9Ca2rvQBQJOyDrNPmf5AMU7p0qA8jIAW4pl+4W3Fc X-Received: by 10.66.227.1 with SMTP id rw1mr20584458pac.35.1446845212452; Fri, 06 Nov 2015 13:26:52 -0800 (PST) Received: from cabot-wlan.adilger.int (S0106002191d9348b.cg.shawcable.net. [96.51.76.157]) by smtp.gmail.com with ESMTPSA id ph8sm1823278pbc.8.2015.11.06.13.26.50 (version=TLS1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 06 Nov 2015 13:26:51 -0800 (PST) Subject: Re: [PATCH v14 03/22] vfs: Add MAY_DELETE_SELF and MAY_DELETE_CHILD permission flags X-Barracuda-Apparent-Source-IP: 96.51.76.157 X-Barracuda-BBL-IP: 96.51.76.157 Mime-Version: 1.0 (Mac OS X Mail 8.2 \(2104\)) X-ASG-Orig-Subj: Re: [PATCH v14 03/22] vfs: Add MAY_DELETE_SELF and MAY_DELETE_CHILD permission flags Content-Type: multipart/signed; boundary="Apple-Mail=_686D8F26-4634-4110-89A3-CE8E4878A295"; protocol="application/pgp-signature"; micalg=pgp-sha256 X-Pgp-Agent: GPGMail 2.5.2 From: Andreas Dilger In-Reply-To: <1446723580-3747-4-git-send-email-agruenba@redhat.com> Date: Fri, 6 Nov 2015 14:26:45 -0700 Cc: Alexander Viro , Theodore Ts'o , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Message-Id: <8C966D9B-A46D-47EC-BD4B-20E2F9B42555@dilger.ca> References: <1446723580-3747-1-git-send-email-agruenba@redhat.com> <1446723580-3747-4-git-send-email-agruenba@redhat.com> To: Andreas Gruenbacher X-Mailer: Apple Mail (2.2104) X-Barracuda-Connect: mail-pa0-f44.google.com[209.85.220.44] X-Barracuda-Start-Time: 1446845213 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24174 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 --Apple-Mail=_686D8F26-4634-4110-89A3-CE8E4878A295 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii On Nov 5, 2015, at 4:39 AM, Andreas Gruenbacher = wrote: >=20 > Normally, deleting a file requires MAY_WRITE access to the parent > directory. With richacls, a file may be deleted with MAY_DELETE_CHILD = access > to the parent directory or with MAY_DELETE_SELF access to the file. >=20 > To support that, pass the MAY_DELETE_CHILD mask flag to = inode_permission() > when checking for delete access inside a directory, and = MAY_DELETE_SELF > when checking for delete access to a file itelf. >=20 > The MAY_DELETE_SELF permission overrides the sticky directory check. >=20 > Signed-off-by: Andreas Gruenbacher > Reviewed-by: J. Bruce Fields > --- > fs/namei.c | 21 ++++++++++++--------- > include/linux/fs.h | 2 ++ > 2 files changed, 14 insertions(+), 9 deletions(-) >=20 > diff --git a/fs/namei.c b/fs/namei.c > index 0259392..2eab19e 100644 > --- a/fs/namei.c > +++ b/fs/namei.c > @@ -453,9 +453,9 @@ static int sb_permission(struct super_block *sb, = struct inode *inode, int mask) > * this, letting us set arbitrary permissions for filesystem access = without > * changing the "normal" UIDs which are used for other things. > * > - * MAY_WRITE must be set in @mask whenever MAY_APPEND, = MAY_CREATE_FILE, or > - * MAY_CREATE_DIR are set. That way, file systems that don't support = these > - * permissions will check for MAY_WRITE instead. > + * MAY_WRITE must be set in @mask whenever MAY_APPEND, = MAY_CREATE_FILE, > + * MAY_CREATE_DIR, or MAY_DELETE_CHILD are set. That way, file = systems that > + * don't support these permissions will check for MAY_WRITE instead. > */ > int inode_permission(struct inode *inode, int mask) > { > @@ -2555,7 +2555,7 @@ static int may_delete(struct inode *dir, struct = dentry *victim, > bool isdir, bool replace) > { > struct inode *inode =3D d_backing_inode(victim); > - int error, mask =3D MAY_WRITE | MAY_EXEC; > + int error, mask =3D MAY_EXEC; >=20 > if (d_is_negative(victim)) > return -ENOENT; > @@ -2565,15 +2565,18 @@ static int may_delete(struct inode *dir, = struct dentry *victim, > audit_inode_child(dir, victim, AUDIT_TYPE_CHILD_DELETE); >=20 > if (replace) > - mask |=3D isdir ? MAY_CREATE_DIR : MAY_CREATE_FILE; > - error =3D inode_permission(dir, mask); > + mask |=3D MAY_WRITE | (isdir ? MAY_CREATE_DIR : = MAY_CREATE_FILE); > + error =3D inode_permission(dir, mask | MAY_WRITE | = MAY_DELETE_CHILD); > + if (!error && check_sticky(dir, inode)) > + error =3D -EPERM; > + if (error && IS_RICHACL(inode) && > + inode_permission(inode, MAY_DELETE_SELF) =3D=3D 0) > + error =3D 0; This looks like a serious bug, as it is overriding other errors returned from inode_permission() such as -EROFS from sb_permission() or even from generic_permission->acl_permission_check(). Clearing the error returned by an earlier check doesn't seem safe, only new errors should be added. The call to inode_permission(inode) is also duplicating the = sb_permission() check from inode_permission(dir), so at most should be = __inode_permission(). It looks like this would be correct if you check MAY_DELETE_SELF = together with check_sticky(): if (!error && check_sticky(dir, inode) && !__inode_permission(inode, MAY_DELETE_SELF)) error =3D -EPERM; I ommitted the IS_RICHACL() check here, since that should probably be in __inode_permission() when MAY_DELETE_SELF is passed? Cheers, Andreas > if (error) > return error; > if (IS_APPEND(dir)) > return -EPERM; > - > - if (check_sticky(dir, inode) || IS_APPEND(inode) || > - IS_IMMUTABLE(inode) || IS_SWAPFILE(inode)) > + if (IS_APPEND(inode) || IS_IMMUTABLE(inode) || = IS_SWAPFILE(inode)) > return -EPERM; > if (isdir) { > if (!d_is_dir(victim)) > diff --git a/include/linux/fs.h b/include/linux/fs.h > index d6e2330..402acd7 100644 > --- a/include/linux/fs.h > +++ b/include/linux/fs.h > @@ -84,6 +84,8 @@ typedef void (dax_iodone_t)(struct buffer_head = *bh_map, int uptodate); > #define MAY_NOT_BLOCK 0x00000080 > #define MAY_CREATE_FILE 0x00000100 > #define MAY_CREATE_DIR 0x00000200 > +#define MAY_DELETE_CHILD 0x00000400 > +#define MAY_DELETE_SELF 0x00000800 >=20 > /* > * flags in file.f_mode. Note that FMODE_READ and FMODE_WRITE must = correspond > -- > 2.5.0 >=20 Cheers, Andreas --Apple-Mail=_686D8F26-4634-4110-89A3-CE8E4878A295 Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename=signature.asc Content-Type: application/pgp-signature; name=signature.asc Content-Description: Message signed with OpenPGP using GPGMail -----BEGIN PGP SIGNATURE----- Comment: GPGTools - http://gpgtools.org iQIVAwUBVj0bFXKl2rkXzB/gAQgVMw/9HRWeCdxHmVddBJ/NJ4cEapoGKeJnXALg cLCr0ABLWmBJr3IH+IUcb717xKy9DtCjIMB5WIRCi6xhaNqfm+4ytLpQ34zLq006 EXkyLU/RMK2/x1OI/VsPHZ6LX8SAHqIwq5pJ8ZDd8ZuwA74DRwY6txYEyRHOptdT xffUViiy+5tEJChnqJgi4gMSaGXamyoUjJ/YfF1/TftgMq7Iil8DC6JtcfUtEuTu NhXsPhpGl4Dfz+jOyZd09CmaKDdeXHoE9o/0vEjZz6A20yS1zC5fbjQ0UwqMUDT9 WDyxa9WbLArpUalW/L0tRE1l34n/rfIqIBz0gSF0Uw/cjE6mPb40Vc+W4AWkUEZl K3LWTq6aXdSn9oXmPDW5/4y3lVVeJ0DLRHCMkgkKGyx0U2zcHyHkA+iEIYM7+0FL 2nJ7KBig+DX2O/qXvsygIfYiaOsLJTnkz+8s6hOh041lbNSOK9Ul9E1IjAGd4VV3 Ft7+qLEtN0LT464Lj2SxfSRh3B+Ug+ylVgNiC496XILMSGAga7ORSNeoKDhMbO1h b+KHBY8hHgQL446CHtIiMEveBtXEgKK7DH0zdl2kpTtGwTMmwOHsZ/6IVUeBKZGh V4dD1jpUZtmqgNsxysAMs2bCH7R+w+1syXB09lP4+KTaGlQeSATGtlFkZ4Ow2i1l rxiI67P1K2g= =Vb9Z -----END PGP SIGNATURE----- --Apple-Mail=_686D8F26-4634-4110-89A3-CE8E4878A295-- From adilger@dilger.ca Fri Nov 6 15:27:27 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 7E9477F87 for ; Fri, 6 Nov 2015 15:27:27 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 6B6878F8033 for ; Fri, 6 Nov 2015 13:27:27 -0800 (PST) X-ASG-Debug-ID: 1446845244-04cb6c296c8e6b0001-NocioJ Received: from mail-pa0-f42.google.com (mail-pa0-f42.google.com [209.85.220.42]) by cuda.sgi.com with ESMTP id MK3asVQELXuLRjJI (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Fri, 06 Nov 2015 13:27:25 -0800 (PST) X-Barracuda-Envelope-From: adilger@dilger.ca X-Barracuda-RBL-Trusted-Forwarder: 209.85.220.42 Received: by pabfh17 with SMTP id fh17so133940976pab.0 for ; Fri, 06 Nov 2015 13:27:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=dilger_ca.20150623.gappssmtp.com; s=20150623; h=subject:mime-version:content-type:from:in-reply-to:date:cc :message-id:references:to; bh=omLVCI/9skm3KbLDDNifEhsAAATeZRiE8R5CGlB97hM=; b=J3LBtTzji7rjK5s9kn0jWLMiyTcnJPIBuTCcs1lgBk0HVzp2hpvONsKhUCX6GqzIUR /r5F5qDlglv7dVUavBn8/Ta15/bhmycxsFb1W4eBThU0MrIocAch8MMSrp6WdcWtER5z fC9Dhd9nRwLTC2HTkImmNhLJR1qb9C8lxnVeLf/SEP1VbFLTQfLD0THyJwWtVR3MG0oV S5mEz0gRRzUnpS8j1gvYeOLLw7jtziBAWH/wQOq8Ruw1yChHGuyBMQyphbPbthVRY8tM mwqbvl06F+DL1IgUTJEZFsSrKzaDn3gjt3iRCOagwNwnFlkgpgScDCjD452Lnh+ERA5+ M4KQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:subject:mime-version:content-type:from :in-reply-to:date:cc:message-id:references:to; bh=omLVCI/9skm3KbLDDNifEhsAAATeZRiE8R5CGlB97hM=; b=CInCNmiz7Fl1EZRTBiL7jtao4XKF9vqESamFk5KZQyfMF2/F5BBh8I8zRbCE5sQCFs pru3vlwqQYW9GMrH8s8H8ZNL/AakuTBPiDXgGS4l/DqZkDe+jmUfkvFUDkwy85+Re9Vi QciMIeG6Y51QoJ9nt21y9r5YExmkRsNcqDMoAJju+ekZRWO6hSiyB30tP4NNNZpK+E6q LJSBU6Xn0jCaWF3GMMnbrknLZVIQoLRhaj2hDoliqZUO3oKl6/bq7uTxkRmLz/5pWf4c 537Cd01GqYpmzUZAH5SdM3OYqjbqBCx9mTq8xjHrcXZ4kjbNPn83sIFefRLMytjhKrhY hfJA== X-Gm-Message-State: ALoCoQlFLp8/b15g1+3uhoG19ZUPHCIsT3qLB3nPwHnQtV7XekmMGcooMzlS9Kb5WcffYOnHW6t0 X-Received: by 10.68.139.225 with SMTP id rb1mr20474905pbb.33.1446845244820; Fri, 06 Nov 2015 13:27:24 -0800 (PST) Received: from cabot-wlan.adilger.int (S0106002191d9348b.cg.shawcable.net. [96.51.76.157]) by smtp.gmail.com with ESMTPSA id ph8sm1823278pbc.8.2015.11.06.13.27.22 (version=TLS1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 06 Nov 2015 13:27:23 -0800 (PST) Subject: Re: [PATCH v14 03/22] vfs: Add MAY_DELETE_SELF and MAY_DELETE_CHILD permission flags X-Barracuda-Apparent-Source-IP: 96.51.76.157 X-Barracuda-BBL-IP: 96.51.76.157 Mime-Version: 1.0 (Mac OS X Mail 8.2 \(2104\)) X-ASG-Orig-Subj: Re: [PATCH v14 03/22] vfs: Add MAY_DELETE_SELF and MAY_DELETE_CHILD permission flags Content-Type: multipart/signed; boundary="Apple-Mail=_2915270B-23EA-4C7B-BE26-9213A7A0F9C4"; protocol="application/pgp-signature"; micalg=pgp-sha256 X-Pgp-Agent: GPGMail 2.5.2 From: Andreas Dilger In-Reply-To: <1446723580-3747-4-git-send-email-agruenba@redhat.com> Date: Fri, 6 Nov 2015 14:26:45 -0700 Cc: Alexander Viro , Theodore Ts'o , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Message-Id: <88120453-8E06-481C-90C7-5D7E7B279C4E@dilger.ca> References: <1446723580-3747-1-git-send-email-agruenba@redhat.com> <1446723580-3747-4-git-send-email-agruenba@redhat.com> To: Andreas Gruenbacher X-Mailer: Apple Mail (2.2104) X-Barracuda-Connect: mail-pa0-f42.google.com[209.85.220.42] X-Barracuda-Start-Time: 1446845245 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24174 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 --Apple-Mail=_2915270B-23EA-4C7B-BE26-9213A7A0F9C4 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii On Nov 5, 2015, at 4:39 AM, Andreas Gruenbacher = wrote: >=20 > Normally, deleting a file requires MAY_WRITE access to the parent > directory. With richacls, a file may be deleted with MAY_DELETE_CHILD = access > to the parent directory or with MAY_DELETE_SELF access to the file. >=20 > To support that, pass the MAY_DELETE_CHILD mask flag to = inode_permission() > when checking for delete access inside a directory, and = MAY_DELETE_SELF > when checking for delete access to a file itelf. >=20 > The MAY_DELETE_SELF permission overrides the sticky directory check. >=20 > Signed-off-by: Andreas Gruenbacher > Reviewed-by: J. Bruce Fields > --- > fs/namei.c | 21 ++++++++++++--------- > include/linux/fs.h | 2 ++ > 2 files changed, 14 insertions(+), 9 deletions(-) >=20 > diff --git a/fs/namei.c b/fs/namei.c > index 0259392..2eab19e 100644 > --- a/fs/namei.c > +++ b/fs/namei.c > @@ -453,9 +453,9 @@ static int sb_permission(struct super_block *sb, = struct inode *inode, int mask) > * this, letting us set arbitrary permissions for filesystem access = without > * changing the "normal" UIDs which are used for other things. > * > - * MAY_WRITE must be set in @mask whenever MAY_APPEND, = MAY_CREATE_FILE, or > - * MAY_CREATE_DIR are set. That way, file systems that don't support = these > - * permissions will check for MAY_WRITE instead. > + * MAY_WRITE must be set in @mask whenever MAY_APPEND, = MAY_CREATE_FILE, > + * MAY_CREATE_DIR, or MAY_DELETE_CHILD are set. That way, file = systems that > + * don't support these permissions will check for MAY_WRITE instead. > */ > int inode_permission(struct inode *inode, int mask) > { > @@ -2555,7 +2555,7 @@ static int may_delete(struct inode *dir, struct = dentry *victim, > bool isdir, bool replace) > { > struct inode *inode =3D d_backing_inode(victim); > - int error, mask =3D MAY_WRITE | MAY_EXEC; > + int error, mask =3D MAY_EXEC; >=20 > if (d_is_negative(victim)) > return -ENOENT; > @@ -2565,15 +2565,18 @@ static int may_delete(struct inode *dir, = struct dentry *victim, > audit_inode_child(dir, victim, AUDIT_TYPE_CHILD_DELETE); >=20 > if (replace) > - mask |=3D isdir ? MAY_CREATE_DIR : MAY_CREATE_FILE; > - error =3D inode_permission(dir, mask); > + mask |=3D MAY_WRITE | (isdir ? MAY_CREATE_DIR : = MAY_CREATE_FILE); > + error =3D inode_permission(dir, mask | MAY_WRITE | = MAY_DELETE_CHILD); > + if (!error && check_sticky(dir, inode)) > + error =3D -EPERM; > + if (error && IS_RICHACL(inode) && > + inode_permission(inode, MAY_DELETE_SELF) =3D=3D 0) > + error =3D 0; This looks like a serious bug, as it is overriding other errors returned from inode_permission() such as -EROFS from sb_permission() or even from generic_permission->acl_permission_check(). Clearing the error returned by an earlier check doesn't seem safe, only new errors should be added. The call to inode_permission(inode) is also duplicating the = sb_permission() check from inode_permission(dir), so at most should be = __inode_permission(). It looks like this would be correct if you check MAY_DELETE_SELF = together with check_sticky(): if (!error && check_sticky(dir, inode) && !__inode_permission(inode, MAY_DELETE_SELF)) error =3D -EPERM; I ommitted the IS_RICHACL() check here, since that should probably be in __inode_permission() when MAY_DELETE_SELF is passed? Cheers, Andreas > if (error) > return error; > if (IS_APPEND(dir)) > return -EPERM; > - > - if (check_sticky(dir, inode) || IS_APPEND(inode) || > - IS_IMMUTABLE(inode) || IS_SWAPFILE(inode)) > + if (IS_APPEND(inode) || IS_IMMUTABLE(inode) || = IS_SWAPFILE(inode)) > return -EPERM; > if (isdir) { > if (!d_is_dir(victim)) > diff --git a/include/linux/fs.h b/include/linux/fs.h > index d6e2330..402acd7 100644 > --- a/include/linux/fs.h > +++ b/include/linux/fs.h > @@ -84,6 +84,8 @@ typedef void (dax_iodone_t)(struct buffer_head = *bh_map, int uptodate); > #define MAY_NOT_BLOCK 0x00000080 > #define MAY_CREATE_FILE 0x00000100 > #define MAY_CREATE_DIR 0x00000200 > +#define MAY_DELETE_CHILD 0x00000400 > +#define MAY_DELETE_SELF 0x00000800 >=20 > /* > * flags in file.f_mode. Note that FMODE_READ and FMODE_WRITE must = correspond > -- > 2.5.0 >=20 Cheers, Andreas --Apple-Mail=_2915270B-23EA-4C7B-BE26-9213A7A0F9C4 Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename=signature.asc Content-Type: application/pgp-signature; name=signature.asc Content-Description: Message signed with OpenPGP using GPGMail -----BEGIN PGP SIGNATURE----- Comment: GPGTools - http://gpgtools.org iQIVAwUBVj0bFXKl2rkXzB/gAQgVMw/9HRWeCdxHmVddBJ/NJ4cEapoGKeJnXALg cLCr0ABLWmBJr3IH+IUcb717xKy9DtCjIMB5WIRCi6xhaNqfm+4ytLpQ34zLq006 EXkyLU/RMK2/x1OI/VsPHZ6LX8SAHqIwq5pJ8ZDd8ZuwA74DRwY6txYEyRHOptdT xffUViiy+5tEJChnqJgi4gMSaGXamyoUjJ/YfF1/TftgMq7Iil8DC6JtcfUtEuTu NhXsPhpGl4Dfz+jOyZd09CmaKDdeXHoE9o/0vEjZz6A20yS1zC5fbjQ0UwqMUDT9 WDyxa9WbLArpUalW/L0tRE1l34n/rfIqIBz0gSF0Uw/cjE6mPb40Vc+W4AWkUEZl K3LWTq6aXdSn9oXmPDW5/4y3lVVeJ0DLRHCMkgkKGyx0U2zcHyHkA+iEIYM7+0FL 2nJ7KBig+DX2O/qXvsygIfYiaOsLJTnkz+8s6hOh041lbNSOK9Ul9E1IjAGd4VV3 Ft7+qLEtN0LT464Lj2SxfSRh3B+Ug+ylVgNiC496XILMSGAga7ORSNeoKDhMbO1h b+KHBY8hHgQL446CHtIiMEveBtXEgKK7DH0zdl2kpTtGwTMmwOHsZ/6IVUeBKZGh V4dD1jpUZtmqgNsxysAMs2bCH7R+w+1syXB09lP4+KTaGlQeSATGtlFkZ4Ow2i1l rxiI67P1K2g= =Vb9Z -----END PGP SIGNATURE----- --Apple-Mail=_2915270B-23EA-4C7B-BE26-9213A7A0F9C4-- From david@fromorbit.com Fri Nov 6 16:32:46 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 9A7747F58 for ; Fri, 6 Nov 2015 16:32:46 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 87E5E304039 for ; Fri, 6 Nov 2015 14:32:43 -0800 (PST) X-ASG-Debug-ID: 1446849159-04cbb0242597bd0001-NocioJ Received: from ipmail06.adl2.internode.on.net (ipmail06.adl2.internode.on.net [150.101.137.129]) by cuda.sgi.com with ESMTP id srRk4THSzkHowi81 for ; Fri, 06 Nov 2015 14:32:40 -0800 (PST) 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: A2CZBwCEKT1WPBB4LHleKAECgxBTb4JeqEoBAQEBAQEGizCFKoQJIYVpBAICgTpNAQEBAQEBBwEBAQFBP4Q2AQEEOhwjEAgDGAklDwUlAwcaE4gtDsEHAQshGYV0hUWCcYZIBZZIhR2IAJxMhHsqNAGFEwEBAQ Received: from ppp121-44-120-16.lns20.syd4.internode.on.net (HELO dastard) ([121.44.120.16]) by ipmail06.adl2.internode.on.net with ESMTP; 07 Nov 2015 09:02:39 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZupYk-0008Uc-7J; Sat, 07 Nov 2015 09:32:38 +1100 Date: Sat, 7 Nov 2015 09:32:38 +1100 From: Dave Chinner To: Ross Zwisler Cc: xfs@oss.sgi.com, jack@suse.cz Subject: Re: [PATCH 0/6 V2] xfs: upfront block zeroing for DAX Message-ID: <20151106223238.GT10656@dastard> X-ASG-Orig-Subj: Re: [PATCH 0/6 V2] xfs: upfront block zeroing for DAX References: <1445225238-30413-1-git-send-email-david@fromorbit.com> <20151105234827.GA5771@linux.intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151105234827.GA5771@linux.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: 1446849160 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24175 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Thu, Nov 05, 2015 at 04:48:27PM -0700, Ross Zwisler wrote: > On Mon, Oct 19, 2015 at 02:27:12PM +1100, Dave Chinner wrote: > > Hi folks, > > > > This is an updated patch set that was first posted here: > > > > http://oss.sgi.com/archives/xfs/2015-10/msg00006.html > > > > I've dropped the DAX locking revert patch from it; that's on it's > > way to Linus via other channels and is essentially independent to > > this set of XFS changes. > > > > The only real change in the XFS code between the two versions is the > > addition of XFS_TRANS_RESERVE in the DAX path in > > xfs_iomap_write_direct() to allow it to dip into the reserve block > > pool for unwritten extent conversion rather than reporting ENOSPC. > > > > Patches are against 4.3-rc5 + XFS for-next branch. > > > > -Dave. > > Hey Dave, > > I was going to start testing these, but I'm having trouble finding a baseline > where they apply cleanly. It looks like xfs/for-next already contains v1 of > the series, and they don't seem to apply cleanly to the current > xfs/xfs-misc-fixes-for-4.4-2 nor to v4.3. The xfs repo I'm looking at is > git://git.kernel.org/pub/scm/linux/kernel/git/dgc/linux-xfs.git The xfs-dax-updates branch of that kernel contains the v3 version of the patches I posted a few days ago. i.e. just pull the for-next branch of the XFS tree, because that already contains all the patches integrated into the rest of the XFS for-next tree... Cheers, Dave. -- Dave Chinner david@fromorbit.com From vskytta@gmail.com Sat Nov 7 04:05:49 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 974F17F75 for ; Sat, 7 Nov 2015 04:05:49 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 779388F8033 for ; Sat, 7 Nov 2015 02:05:46 -0800 (PST) X-ASG-Debug-ID: 1446890742-04cbb02422a1df0001-NocioJ Received: from mail-lf0-f44.google.com (mail-lf0-f44.google.com [209.85.215.44]) by cuda.sgi.com with ESMTP id NvYWR1FnoF3GrAY9 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Sat, 07 Nov 2015 02:05:43 -0800 (PST) X-Barracuda-Envelope-From: vskytta@gmail.com X-Barracuda-Apparent-Source-IP: 209.85.215.44 Received: by lfs39 with SMTP id 39so51612614lfs.3 for ; Sat, 07 Nov 2015 02:05:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:subject:date:message-id:mime-version:content-type :content-transfer-encoding; bh=A3VRmkprpw/XaS2tnD+7tX7Tweho8d92H5Ext1bpmWc=; b=fnSG8nfpucF7/LgV7ZTnmFI1laZ5X1CCjQbo4ClyqNbaUKGVPHzivAIBPwAXj7di9/ lppHP1VZxyhtA0zpxK2ASfmFCGyZI2KRTxAx3OgLEtRlosUQ+HpRMp9UK6qHQtcV1GLR /eqFoa+rTLCgqvRiwIz5RaAIEaweBC9IcSXli56urE7GumRAHjj2F/3SlUhi9BowobID ImnTTmBXbkeKbHTLkwe9CPlh4hhrSDOT03EN9ksDn7E+/hJRqw0cTr2J3iw9KQOBPk0I UNj3BPTt5budUnWqIGajoyoAOylMQqkQ/pYJJFEzy3RsnRndvAKw8jlGEr2Utt5VBUbD IFMg== X-Received: by 10.25.87.82 with SMTP id l79mr5662126lfb.64.1446890742085; Sat, 07 Nov 2015 02:05:42 -0800 (PST) Received: from viper.bobcat.mine.nu (62-78-200-229.bb.dnainternet.fi. [62.78.200.229]) by smtp.gmail.com with ESMTPSA id br10sm714794lbb.4.2015.11.07.02.05.41 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 07 Nov 2015 02:05:41 -0800 (PST) Sender: =?UTF-8?Q?Ville_Skytt=C3=A4?= From: =?UTF-8?q?Ville=20Skytt=C3=A4?= To: xfs@oss.sgi.com Subject: [PATCH 1/2] xfs_db.8: Remove stray backslash near bmap Date: Sat, 7 Nov 2015 12:05:39 +0200 X-ASG-Orig-Subj: [PATCH 1/2] xfs_db.8: Remove stray backslash near bmap Message-Id: <1446890740-25659-1-git-send-email-ville.skytta@iki.fi> X-Mailer: git-send-email 2.4.3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Barracuda-Connect: mail-lf0-f44.google.com[209.85.215.44] X-Barracuda-Start-Time: 1446890743 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24189 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 Signed-off-by: Ville Skyttä --- man/man8/xfs_db.8 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/man8/xfs_db.8 b/man/man8/xfs_db.8 index 681efc4..5745b22 100644 --- a/man/man8/xfs_db.8 +++ b/man/man8/xfs_db.8 @@ -315,7 +315,7 @@ command must have also specified the option. .RE .TP -.BI "bmap [\-a\] [\-d] [" block " [" len ]] +.BI "bmap [\-a] [\-d] [" block " [" len ]] Show the block map for the current inode. The map display can be restricted to an area of the file with the .I block -- 2.4.3 From vskytta@gmail.com Sat Nov 7 04:05:50 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 2CF087F87 for ; Sat, 7 Nov 2015 04:05:50 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id AB985AC002 for ; Sat, 7 Nov 2015 02:05:46 -0800 (PST) X-ASG-Debug-ID: 1446890743-04cbb02425a1e00001-NocioJ Received: from mail-lf0-f53.google.com (mail-lf0-f53.google.com [209.85.215.53]) by cuda.sgi.com with ESMTP id hVGXtun5CKi7ePsl (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Sat, 07 Nov 2015 02:05:44 -0800 (PST) X-Barracuda-Envelope-From: vskytta@gmail.com X-Barracuda-Apparent-Source-IP: 209.85.215.53 Received: by lfs39 with SMTP id 39so51612722lfs.3 for ; Sat, 07 Nov 2015 02:05:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:subject:date:message-id:in-reply-to:references :mime-version:content-type:content-transfer-encoding; bh=6P1UayA94mHQj58ZksENPdv6oPmG3wET/K8lRRWQ0Mw=; b=pz4jn3o7Qwpcq6YgyxesWv9PV23wYyKBFL6ZKZkJB+PrPEh0theq0wJbJz+6swyi9a XTGx/5hJn1Pb/QsbZjGyzF3BMnU36IMPlZgtq91eFF/J1FnOqbOdRDLY6iRHC52b0+Um rPxQug/jL0e/EzdDEt/vwqDhXw2YzBRg0GFMDyevjxv0dK0qm38LuIP6GvXTHtNL/w5x OAjc5Gz50LabCuo2/Xyw/jGwcFjWAiQzJN3SsOCbz3mpULc8cQWa2pJP/6QcspRITEi9 a4EvoykkVPtToZvRWP9eYgAzFbcce50lw/DJ3UcarckCNgxRLXVl9Ii62gzQjX8imc3L P1rw== X-Received: by 10.25.131.200 with SMTP id f191mr1857276lfd.65.1446890743354; Sat, 07 Nov 2015 02:05:43 -0800 (PST) Received: from viper.bobcat.mine.nu (62-78-200-229.bb.dnainternet.fi. [62.78.200.229]) by smtp.gmail.com with ESMTPSA id br10sm714794lbb.4.2015.11.07.02.05.42 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 07 Nov 2015 02:05:42 -0800 (PST) Sender: =?UTF-8?Q?Ville_Skytt=C3=A4?= From: =?UTF-8?q?Ville=20Skytt=C3=A4?= To: xfs@oss.sgi.com Subject: [PATCH 2/2] mkfs.xfs.8: Spelling fix Date: Sat, 7 Nov 2015 12:05:40 +0200 X-ASG-Orig-Subj: [PATCH 2/2] mkfs.xfs.8: Spelling fix Message-Id: <1446890740-25659-2-git-send-email-ville.skytta@iki.fi> X-Mailer: git-send-email 2.4.3 In-Reply-To: <1446890740-25659-1-git-send-email-ville.skytta@iki.fi> References: <1446890740-25659-1-git-send-email-ville.skytta@iki.fi> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Barracuda-Connect: mail-lf0-f53.google.com[209.85.215.53] X-Barracuda-Start-Time: 1446890744 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24189 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 Signed-off-by: Ville Skyttä --- man/man8/mkfs.xfs.8 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/man8/mkfs.xfs.8 b/man/man8/mkfs.xfs.8 index e98b94d..1fe510b 100644 --- a/man/man8/mkfs.xfs.8 +++ b/man/man8/mkfs.xfs.8 @@ -146,7 +146,7 @@ changes also improves crash recovery algorithms and the ability of various tools to validate and repair metadata corruptions when they are found. The CRC algorithm used is CRC32c, so the overhead is dependent on CPU architecture as some CPUs have hardware acceleration of this algorithm. Typically the overhead -of calculating and checking the CRCs is not noticable in normal operation. +of calculating and checking the CRCs is not noticeable in normal operation. .IP By default, .B mkfs.xfs -- 2.4.3 From agruenba@redhat.com Sat Nov 7 11:44:45 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 2B8127F5D for ; Sat, 7 Nov 2015 11:44:45 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 185FA304032 for ; Sat, 7 Nov 2015 09:44:41 -0800 (PST) X-ASG-Debug-ID: 1446918279-04cb6c296da1030001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id XWqhhEpME9iLPssJ (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sat, 07 Nov 2015 09:44:40 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 25AACC02C6B6; Sat, 7 Nov 2015 17:44:38 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-75.ams2.redhat.com [10.36.7.75]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA7HiTOU019263; Sat, 7 Nov 2015 12:44:30 -0500 From: Andreas Gruenbacher To: Andreas Dilger Cc: Andreas Gruenbacher , Alexander Viro , "Theodore Ts'o" , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Subject: Re: [PATCH v14 02/22] vfs: Add MAY_CREATE_FILE and MAY_CREATE_DIR permission flags Date: Sat, 7 Nov 2015 18:44:28 +0100 X-ASG-Orig-Subj: Re: [PATCH v14 02/22] vfs: Add MAY_CREATE_FILE and MAY_CREATE_DIR permission flags Message-Id: <1446918268-858-1-git-send-email-agruenba@redhat.com> References: <1446723580-3747-1-git-send-email-agruenba@redhat.com> <1446723580-3747-3-git-send-email-agruenba@redhat.com> In-Reply-To: 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: 1446918280 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Fri, Nov 6, 2015 at 9:58 PM, Andreas Dilger wrote: > I thought you proposed adding an enum for these parameters, and possibly > making them a single parameter flag, to make the code in the caller more > readable. No, the result would just be different but not any better; vfs_rename would become messy. I've played with this patch some more, and I find the approach below which splits may_delete into may_delete and may_replace much better. What do you think? Thanks, Andreas ---------- 8< ---------- Richacls distinguish between creating non-directories and directories. To support that, add an isdir parameter to may_create(). When checking inode_permission() for create permission, pass in an additional MAY_CREATE_FILE or MAY_CREATE_DIR mask flag. Add may_replace() to allow checking for delete and create access when replacing an existing file in vfs_rename(). Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/namei.c | 49 +++++++++++++++++++++++++++++++++---------------- include/linux/fs.h | 2 ++ 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 224ecf1..4e5dc2f 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -453,7 +453,9 @@ static int sb_permission(struct super_block *sb, struct inode *inode, int mask) * this, letting us set arbitrary permissions for filesystem access without * changing the "normal" UIDs which are used for other things. * - * When checking for MAY_APPEND, MAY_WRITE must also be set in @mask. + * MAY_WRITE must be set in @mask whenever MAY_APPEND, MAY_CREATE_FILE, or + * MAY_CREATE_DIR are set. That way, file systems that don't support these + * permissions will check for MAY_WRITE instead. */ int inode_permission(struct inode *inode, int mask) { @@ -2549,7 +2551,8 @@ EXPORT_SYMBOL(__check_sticky); * 10. We don't allow removal of NFS sillyrenamed files; it's handled by * nfs_async_unlink(). */ -static int may_delete(struct inode *dir, struct dentry *victim, bool isdir) +static int may_delete_replace(struct inode *dir, struct dentry *victim, + bool isdir, int mask) { struct inode *inode = d_backing_inode(victim); int error; @@ -2561,7 +2564,7 @@ static int may_delete(struct inode *dir, struct dentry *victim, bool isdir) BUG_ON(victim->d_parent->d_inode != dir); audit_inode_child(dir, victim, AUDIT_TYPE_CHILD_DELETE); - error = inode_permission(dir, MAY_WRITE | MAY_EXEC); + error = inode_permission(dir, mask | MAY_WRITE | MAY_EXEC); if (error) return error; if (IS_APPEND(dir)) @@ -2584,6 +2587,18 @@ static int may_delete(struct inode *dir, struct dentry *victim, bool isdir) return 0; } +static int may_delete(struct inode *dir, struct dentry *victim, bool isdir) +{ + return may_delete_replace(dir, victim, isdir, 0); +} + +static int may_replace(struct inode *dir, struct dentry *victim, bool isdir) +{ + int mask = isdir ? MAY_CREATE_DIR : MAY_CREATE_FILE; + + return may_delete_replace(dir, victim, isdir, mask); +} + /* Check whether we can create an object with dentry child in directory * dir. * 1. We can't do it if child already exists (open has special treatment for @@ -2592,14 +2607,16 @@ static int may_delete(struct inode *dir, struct dentry *victim, bool isdir) * 3. We should have write and exec permissions on dir * 4. We can't do it if dir is immutable (done in permission()) */ -static inline int may_create(struct inode *dir, struct dentry *child) +static inline int may_create(struct inode *dir, struct dentry *child, bool isdir) { + int mask = isdir ? MAY_CREATE_DIR : MAY_CREATE_FILE; + audit_inode_child(dir, child, AUDIT_TYPE_CHILD_CREATE); if (child->d_inode) return -EEXIST; if (IS_DEADDIR(dir)) return -ENOENT; - return inode_permission(dir, MAY_WRITE | MAY_EXEC); + return inode_permission(dir, MAY_WRITE | MAY_EXEC | mask); } /* @@ -2649,7 +2666,7 @@ EXPORT_SYMBOL(unlock_rename); int vfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool want_excl) { - int error = may_create(dir, dentry); + int error = may_create(dir, dentry, false); if (error) return error; @@ -3494,7 +3511,7 @@ EXPORT_SYMBOL(user_path_create); int vfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev) { - int error = may_create(dir, dentry); + int error = may_create(dir, dentry, false); if (error) return error; @@ -3586,7 +3603,7 @@ SYSCALL_DEFINE3(mknod, const char __user *, filename, umode_t, mode, unsigned, d int vfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) { - int error = may_create(dir, dentry); + int error = may_create(dir, dentry, true); unsigned max_links = dir->i_sb->s_max_links; if (error) @@ -3667,7 +3684,7 @@ EXPORT_SYMBOL(dentry_unhash); int vfs_rmdir(struct inode *dir, struct dentry *dentry) { - int error = may_delete(dir, dentry, 1); + int error = may_delete(dir, dentry, true); if (error) return error; @@ -3789,7 +3806,7 @@ SYSCALL_DEFINE1(rmdir, const char __user *, pathname) int vfs_unlink(struct inode *dir, struct dentry *dentry, struct inode **delegated_inode) { struct inode *target = dentry->d_inode; - int error = may_delete(dir, dentry, 0); + int error = may_delete(dir, dentry, false); if (error) return error; @@ -3923,7 +3940,7 @@ SYSCALL_DEFINE1(unlink, const char __user *, pathname) int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname) { - int error = may_create(dir, dentry); + int error = may_create(dir, dentry, false); if (error) return error; @@ -4006,7 +4023,7 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de if (!inode) return -ENOENT; - error = may_create(dir, new_dentry); + error = may_create(dir, new_dentry, false); if (error) return error; @@ -4199,14 +4216,14 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, return error; if (!target) { - error = may_create(new_dir, new_dentry); + error = may_create(new_dir, new_dentry, is_dir); } else { new_is_dir = d_is_dir(new_dentry); if (!(flags & RENAME_EXCHANGE)) - error = may_delete(new_dir, new_dentry, is_dir); + error = may_replace(new_dir, new_dentry, is_dir); else - error = may_delete(new_dir, new_dentry, new_is_dir); + error = may_replace(new_dir, new_dentry, new_is_dir); } if (error) return error; @@ -4469,7 +4486,7 @@ SYSCALL_DEFINE2(rename, const char __user *, oldname, const char __user *, newna int vfs_whiteout(struct inode *dir, struct dentry *dentry) { - int error = may_create(dir, dentry); + int error = may_create(dir, dentry, false); if (error) return error; diff --git a/include/linux/fs.h b/include/linux/fs.h index 4efa435..d6e2330 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -82,6 +82,8 @@ typedef void (dax_iodone_t)(struct buffer_head *bh_map, int uptodate); #define MAY_CHDIR 0x00000040 /* called from RCU mode, don't block */ #define MAY_NOT_BLOCK 0x00000080 +#define MAY_CREATE_FILE 0x00000100 +#define MAY_CREATE_DIR 0x00000200 /* * flags in file.f_mode. Note that FMODE_READ and FMODE_WRITE must correspond -- 2.5.0 From agruenba@redhat.com Sat Nov 7 14:47:36 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 8E3D67F5D for ; Sat, 7 Nov 2015 14:47:36 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 5E4EF8F8049 for ; Sat, 7 Nov 2015 12:47:36 -0800 (PST) X-ASG-Debug-ID: 1446929249-04bdf03f02a8700001-NocioJ Received: from mail-lb0-f173.google.com (mail-lb0-f173.google.com [209.85.217.173]) by cuda.sgi.com with ESMTP id zwVqcq7MNW7PrYBo (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Sat, 07 Nov 2015 12:47:30 -0800 (PST) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.85.217.173 Received: by lbbkw15 with SMTP id kw15so71622945lbb.0 for ; Sat, 07 Nov 2015 12:47:29 -0800 (PST) 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=W4yZ2r8YybAP8OxVpeIh0jnUV0rSLWkcuNHo2CZWomo=; b=bszYzKe4tR7rgAl16MI1ZDfS09ppolC7nUbKjGGgAM24jCGjrnJOMpae2PSHgCJjAm tNls+yw6ig8j9oMqtU/CBhQ3XAqWSCQ8GNTSRhSDy508jvnWR1eMgWBQMagbxhWTn1xE +ZK/s5Bv1/tVl7rgWaxbgZ+SZc24H6RfYkcOlWjJKS6zQuTTDpmQVoKLefQgWU0GArUI dIVGoUnxD90+3UjY/8JgWJiPvj3vts0Q7sFKDmPTsqyTi2N9YMMCk8KCv8+Jlniz3PB8 k77tRbxmkDCf7wvZ/g5vdq0lTFPQZB8jckzHNdNkege67+vIpESUi7kIex1xVQ/AGAJ9 7aLg== X-Gm-Message-State: ALoCoQlzls2lPuMG1AvA7mWvCB9Rac5U0qol5CyPjzXNS/sEkTTOcOC9R7f6rMKB+ur+ZqBtIpCt MIME-Version: 1.0 X-Received: by 10.112.16.162 with SMTP id h2mr10598196lbd.89.1446929248996; Sat, 07 Nov 2015 12:47:28 -0800 (PST) Received: by 10.112.53.42 with HTTP; Sat, 7 Nov 2015 12:47:28 -0800 (PST) In-Reply-To: <8C966D9B-A46D-47EC-BD4B-20E2F9B42555@dilger.ca> References: <1446723580-3747-1-git-send-email-agruenba@redhat.com> <1446723580-3747-4-git-send-email-agruenba@redhat.com> <8C966D9B-A46D-47EC-BD4B-20E2F9B42555@dilger.ca> Date: Sat, 7 Nov 2015 21:47:28 +0100 Message-ID: Subject: Re: [PATCH v14 03/22] vfs: Add MAY_DELETE_SELF and MAY_DELETE_CHILD permission flags From: Andreas Gruenbacher X-ASG-Orig-Subj: Re: [PATCH v14 03/22] vfs: Add MAY_DELETE_SELF and MAY_DELETE_CHILD permission flags To: Andreas Dilger Cc: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4 , XFS Developers , LKML , linux-fsdevel , Linux NFS Mailing List , linux-cifs@vger.kernel.org, Linux API Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-lb0-f173.google.com[209.85.217.173] X-Barracuda-Start-Time: 1446929250 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24199 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri, Nov 6, 2015 at 10:26 PM, Andreas Dilger wrote: > On Nov 5, 2015, at 4:39 AM, Andreas Gruenbacher wrote: >> >> Normally, deleting a file requires MAY_WRITE access to the parent >> directory. With richacls, a file may be deleted with MAY_DELETE_CHILD access >> to the parent directory or with MAY_DELETE_SELF access to the file. >> >> To support that, pass the MAY_DELETE_CHILD mask flag to inode_permission() >> when checking for delete access inside a directory, and MAY_DELETE_SELF >> when checking for delete access to a file itelf. >> >> The MAY_DELETE_SELF permission overrides the sticky directory check. >> >> Signed-off-by: Andreas Gruenbacher >> Reviewed-by: J. Bruce Fields >> --- >> fs/namei.c | 21 ++++++++++++--------- >> include/linux/fs.h | 2 ++ >> 2 files changed, 14 insertions(+), 9 deletions(-) >> >> diff --git a/fs/namei.c b/fs/namei.c >> index 0259392..2eab19e 100644 >> --- a/fs/namei.c >> +++ b/fs/namei.c >> @@ -453,9 +453,9 @@ static int sb_permission(struct super_block *sb, struct inode *inode, int mask) >> * this, letting us set arbitrary permissions for filesystem access without >> * changing the "normal" UIDs which are used for other things. >> * >> - * MAY_WRITE must be set in @mask whenever MAY_APPEND, MAY_CREATE_FILE, or >> - * MAY_CREATE_DIR are set. That way, file systems that don't support these >> - * permissions will check for MAY_WRITE instead. >> + * MAY_WRITE must be set in @mask whenever MAY_APPEND, MAY_CREATE_FILE, >> + * MAY_CREATE_DIR, or MAY_DELETE_CHILD are set. That way, file systems that >> + * don't support these permissions will check for MAY_WRITE instead. >> */ >> int inode_permission(struct inode *inode, int mask) >> { >> @@ -2555,7 +2555,7 @@ static int may_delete(struct inode *dir, struct dentry *victim, >> bool isdir, bool replace) >> { >> struct inode *inode = d_backing_inode(victim); >> - int error, mask = MAY_WRITE | MAY_EXEC; >> + int error, mask = MAY_EXEC; >> >> if (d_is_negative(victim)) >> return -ENOENT; >> @@ -2565,15 +2565,18 @@ static int may_delete(struct inode *dir, struct dentry *victim, >> audit_inode_child(dir, victim, AUDIT_TYPE_CHILD_DELETE); >> >> if (replace) >> - mask |= isdir ? MAY_CREATE_DIR : MAY_CREATE_FILE; >> - error = inode_permission(dir, mask); >> + mask |= MAY_WRITE | (isdir ? MAY_CREATE_DIR : MAY_CREATE_FILE); >> + error = inode_permission(dir, mask | MAY_WRITE | MAY_DELETE_CHILD); >> + if (!error && check_sticky(dir, inode)) >> + error = -EPERM; >> + if (error && IS_RICHACL(inode) && >> + inode_permission(inode, MAY_DELETE_SELF) == 0) >> + error = 0; > > This looks like a serious bug, as it is overriding other errors returned > from inode_permission() such as -EROFS from sb_permission() or even from > generic_permission->acl_permission_check(). Clearing the error returned > by an earlier check doesn't seem safe, only new errors should be added. See further below ... > The call to inode_permission(inode) is also duplicating the sb_permission() > check from inode_permission(dir), so at most should be __inode_permission(). This could be optimized, but that would make the code harder to read. I don't think it really matters: this only affects file with the MAY_DELETE_SELF permission, and sb_permissions is really cheap anyway. > It looks like this would be correct if you check MAY_DELETE_SELF together > with check_sticky(): > > if (!error && check_sticky(dir, inode) && > !__inode_permission(inode, MAY_DELETE_SELF)) > error = -EPERM; Nope, this version would deny users with MAY_DELETE_SELF access to a file and MAY_EXEC access to the directory the right to delete the file because @error would already be set then. You are right that the check for MAY_DELETE_SELF overrides too much here though; we need an additional inode_permission(dir, ...) check in there. I've pushed a fixed version here that I will do some more testing on before reposting: git://git.kernel.org/pub/scm/linux/kernel/git/agruen/linux-richacl.git richacl-wip > I ommitted the IS_RICHACL() check here, since that should probably be in > __inode_permission() when MAY_DELETE_SELF is passed? The IS_RICHACL() check is indeed done in inode_permission -> __inode_permission -> do_inode_permission -> generic_permission -> acl_permission_check. I've duplicated that check here to avoid slowing down may_delete in the common case where the filesystem doesn't support richacls. Thanks, Andreas From adilger@dilger.ca Sun Nov 8 02:04:49 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 29EA47F5A for ; Sun, 8 Nov 2015 02:04:49 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 03924304039 for ; Sun, 8 Nov 2015 00:04:48 -0800 (PST) X-ASG-Debug-ID: 1446969882-04cb6c296db22e0001-NocioJ Received: from mail-pa0-f54.google.com (mail-pa0-f54.google.com [209.85.220.54]) by cuda.sgi.com with ESMTP id CAf5jJcLU0aeA6Xk (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Sun, 08 Nov 2015 00:04:42 -0800 (PST) X-Barracuda-Envelope-From: adilger@dilger.ca X-Barracuda-RBL-Trusted-Forwarder: 209.85.220.54 Received: by pacdm15 with SMTP id dm15so142099855pac.3 for ; Sun, 08 Nov 2015 00:04:41 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=dilger_ca.20150623.gappssmtp.com; s=20150623; h=subject:mime-version:content-type:from:in-reply-to:date:cc :message-id:references:to; bh=zLTDpGH+5C23d8lO3JA42MIIm3xR9ISAemqGNnKJSYM=; b=qDKvGA1orzmfBH/HBlav8VuAMSu0uuu+GkxG1iDeLHk4/zoxJKNQrdosjHyXo82919 67hF9bQLhjbcfU/KyuLTDEYAsGmsRsnCax3wGN1eI8FRMjqy9I5tCG5/bR8AcGBoiNL0 c8L0qGGYCNzmNkD/kiKvEop//a5kw5w1PbFTAv72f07GKEgi1a5psIQ1EApc0PMxN8Ul /31hbfxodE16sfeuK358r2sFdJZFogp+XZ0JHeyEdW+L+XLqnl8lFLzXe4brK4weZ/rg PD5tAwye1KwOyA8m2U4S7uB+e2Kk/PgkbPoatvrLVd2ydZX5o4LDI0sOtsM1JU9HLHsu 1q5g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:subject:mime-version:content-type:from :in-reply-to:date:cc:message-id:references:to; bh=zLTDpGH+5C23d8lO3JA42MIIm3xR9ISAemqGNnKJSYM=; b=dxYk+X5BMGOqAxHyyMpp1ITzrkxZwrdsS7FsKjNI0nguQjSaehft+6MRRrR5Sje1Yx giS5FEVQnW8BOVIj8EVxPWJjHqK4znk4E84gfgzK3XqCjVAOrg57r9irDEilq4f+0YtE izDoPSpTtuN3qrc9jCPKJwz005UyHcn/wPAn8G5GK9sYYuZT28JDeZMWId2nxD2DkltH QjAKKTxrsFLUTxQSXxdzvPJ5JD7UJkbcMKVDZG8Iv74ewM850bTSR0WK78OP3sxO4S6r +tnyLP9R4B+v+xfhCdLQiXxv17mc/0bu9y05qFRaIZKWQnteUWBQa4nqwqT6VqFfQoxy 8hIA== X-Gm-Message-State: ALoCoQlQYF6zEOEnO8+OTprOFHxavMIMwB+GAYHIHYNYKlXjAGneMHA3TbKnedtZLVbnA1yT1VyC X-Received: by 10.66.158.234 with SMTP id wx10mr30937148pab.72.1446969881841; Sun, 08 Nov 2015 00:04:41 -0800 (PST) Received: from cabot-wlan.adilger.int (S0106002191d9348b.cg.shawcable.net. [96.51.76.157]) by smtp.gmail.com with ESMTPSA id ia3sm9537736pbb.5.2015.11.08.00.04.39 (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Sun, 08 Nov 2015 00:04:40 -0800 (PST) Subject: Re: [PATCH v14 11/22] vfs: Cache base_acl objects in inodes X-Barracuda-Apparent-Source-IP: 96.51.76.157 X-Barracuda-BBL-IP: 96.51.76.157 Mime-Version: 1.0 (Mac OS X Mail 8.2 \(2104\)) X-ASG-Orig-Subj: Re: [PATCH v14 11/22] vfs: Cache base_acl objects in inodes Content-Type: multipart/signed; boundary="Apple-Mail=_65082315-236F-444B-A9A2-6BE991F8EF14"; protocol="application/pgp-signature"; micalg=pgp-sha256 X-Pgp-Agent: GPGMail 2.5.2 From: Andreas Dilger In-Reply-To: <1446723580-3747-12-git-send-email-agruenba@redhat.com> Date: Sun, 8 Nov 2015 01:06:00 -0700 Cc: Alexander Viro , Theodore Ts'o , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Message-Id: References: <1446723580-3747-1-git-send-email-agruenba@redhat.com> <1446723580-3747-12-git-send-email-agruenba@redhat.com> To: Andreas Gruenbacher X-Mailer: Apple Mail (2.2104) X-Barracuda-Connect: mail-pa0-f54.google.com[209.85.220.54] X-Barracuda-Start-Time: 1446969882 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24211 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 --Apple-Mail=_65082315-236F-444B-A9A2-6BE991F8EF14 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii On Nov 5, 2015, at 4:39 AM, Andreas Gruenbacher = wrote: >=20 > POSIX ACLs and richacls are both objects allocated by kmalloc() with a > reference count which are freed by kfree_rcu(). An inode can either > cache an access and a default POSIX ACL, or a richacl (richacls do not > have default acls). To allow an inode to cache either of the two = kinds > of acls, introduce a new base_acl type and convert i_acl and > i_default_acl to that type. In most cases, the vfs then doesn't care = which > kind of acl an inode caches (if any). >=20 > Signed-off-by: Andreas Gruenbacher Reviewed-by: Andreas Dilger > --- > drivers/staging/lustre/lustre/llite/llite_lib.c | 2 +- > fs/f2fs/acl.c | 4 +-- > fs/inode.c | 4 +-- > fs/jffs2/acl.c | 10 ++++-- > fs/posix_acl.c | 41 = +++++++++++++------------ > fs/richacl_base.c | 4 +-- > include/linux/fs.h | 34 = ++++++++++++++++++-- > include/linux/posix_acl.h | 12 +++----- > include/linux/richacl.h | 9 +++--- > 9 files changed, 75 insertions(+), 45 deletions(-) >=20 > diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c = b/drivers/staging/lustre/lustre/llite/llite_lib.c > index b4ed6c8..46912c2 100644 > --- a/drivers/staging/lustre/lustre/llite/llite_lib.c > +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c > @@ -1118,7 +1118,7 @@ void ll_clear_inode(struct inode *inode) > } > #ifdef CONFIG_FS_POSIX_ACL > else if (lli->lli_posix_acl) { > - LASSERT(atomic_read(&lli->lli_posix_acl->a_refcount) =3D=3D= 1); > + LASSERT(base_acl_refcount(&lli->lli_posix_acl->a_base) = =3D=3D 1); > LASSERT(lli->lli_remote_perms =3D=3D NULL); > posix_acl_release(lli->lli_posix_acl); > lli->lli_posix_acl =3D NULL; > diff --git a/fs/f2fs/acl.c b/fs/f2fs/acl.c > index c8f25f7..9646197 100644 > --- a/fs/f2fs/acl.c > +++ b/fs/f2fs/acl.c > @@ -270,7 +270,7 @@ static struct posix_acl *f2fs_acl_clone(const = struct posix_acl *acl, > sizeof(struct posix_acl_entry); > clone =3D kmemdup(acl, size, flags); > if (clone) > - atomic_set(&clone->a_refcount, 1); > + base_acl_init(&clone->a_base); > } > return clone; > } > @@ -282,7 +282,7 @@ static int f2fs_acl_create_masq(struct posix_acl = *acl, umode_t *mode_p) > umode_t mode =3D *mode_p; > int not_equiv =3D 0; >=20 > - /* assert(atomic_read(acl->a_refcount) =3D=3D 1); */ > + /* assert(base_acl_refcount(&acl->a_base) =3D=3D 1); */ >=20 > FOREACH_ACL_ENTRY(pa, acl, pe) { > switch(pa->e_tag) { > diff --git a/fs/inode.c b/fs/inode.c > index 78a17b8..5c46ae5 100644 > --- a/fs/inode.c > +++ b/fs/inode.c > @@ -233,9 +233,9 @@ void __destroy_inode(struct inode *inode) >=20 > #ifdef CONFIG_FS_POSIX_ACL > if (inode->i_acl && inode->i_acl !=3D ACL_NOT_CACHED) > - posix_acl_release(inode->i_acl); > + base_acl_put(inode->i_acl); > if (inode->i_default_acl && inode->i_default_acl !=3D = ACL_NOT_CACHED) > - posix_acl_release(inode->i_default_acl); > + base_acl_put(inode->i_default_acl); > #endif > this_cpu_dec(nr_inodes); > } > diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c > index 2f7a3c0..569cb1b 100644 > --- a/fs/jffs2/acl.c > +++ b/fs/jffs2/acl.c > @@ -294,13 +294,19 @@ int jffs2_init_acl_post(struct inode *inode) > int rc; >=20 > if (inode->i_default_acl) { > - rc =3D __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_DEFAULT, = inode->i_default_acl); > + struct posix_acl *default_acl =3D container_of( > + inode->i_default_acl, struct posix_acl, a_base); > + > + rc =3D __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_DEFAULT, = default_acl); > if (rc) > return rc; > } >=20 > if (inode->i_acl) { > - rc =3D __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_ACCESS, = inode->i_acl); > + struct posix_acl *acl =3D container_of( > + inode->i_acl, struct posix_acl, a_base); > + > + rc =3D __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_ACCESS, = acl); > if (rc) > return rc; > } > diff --git a/fs/posix_acl.c b/fs/posix_acl.c > index aacfb58..4573315 100644 > --- a/fs/posix_acl.c > +++ b/fs/posix_acl.c > @@ -21,7 +21,7 @@ > #include > #include >=20 > -static struct posix_acl **acl_by_type(struct inode *inode, int type) > +static struct base_acl **acl_by_type(struct inode *inode, int type) > { > switch (type) { > case ACL_TYPE_ACCESS: > @@ -35,63 +35,64 @@ static struct posix_acl **acl_by_type(struct inode = *inode, int type) >=20 > struct posix_acl *get_cached_acl(struct inode *inode, int type) > { > - struct posix_acl **p =3D acl_by_type(inode, type); > - struct posix_acl *acl =3D ACCESS_ONCE(*p); > + struct base_acl **p =3D acl_by_type(inode, type); > + struct base_acl *acl =3D ACCESS_ONCE(*p); > if (acl) { > spin_lock(&inode->i_lock); > acl =3D *p; > if (acl !=3D ACL_NOT_CACHED) > - acl =3D posix_acl_dup(acl); > + base_acl_get(acl); > spin_unlock(&inode->i_lock); > } > - return acl; > + return container_of(acl, struct posix_acl, a_base); > } > EXPORT_SYMBOL(get_cached_acl); >=20 > struct posix_acl *get_cached_acl_rcu(struct inode *inode, int type) > { > - return rcu_dereference(*acl_by_type(inode, type)); > + struct base_acl *acl =3D rcu_dereference(*acl_by_type(inode, = type)); > + return container_of(acl, struct posix_acl, a_base); > } > EXPORT_SYMBOL(get_cached_acl_rcu); >=20 > void set_cached_acl(struct inode *inode, int type, struct posix_acl = *acl) > { > - struct posix_acl **p =3D acl_by_type(inode, type); > - struct posix_acl *old; > + struct base_acl **p =3D acl_by_type(inode, type); > + struct base_acl *old; > spin_lock(&inode->i_lock); > old =3D *p; > - rcu_assign_pointer(*p, posix_acl_dup(acl)); > + rcu_assign_pointer(*p, &posix_acl_dup(acl)->a_base); > spin_unlock(&inode->i_lock); > if (old !=3D ACL_NOT_CACHED) > - posix_acl_release(old); > + base_acl_put(old); > } > EXPORT_SYMBOL(set_cached_acl); >=20 > void forget_cached_acl(struct inode *inode, int type) > { > - struct posix_acl **p =3D acl_by_type(inode, type); > - struct posix_acl *old; > + struct base_acl **p =3D acl_by_type(inode, type); > + struct base_acl *old; > spin_lock(&inode->i_lock); > old =3D *p; > *p =3D ACL_NOT_CACHED; > spin_unlock(&inode->i_lock); > if (old !=3D ACL_NOT_CACHED) > - posix_acl_release(old); > + base_acl_put(old); > } > EXPORT_SYMBOL(forget_cached_acl); >=20 > void forget_all_cached_acls(struct inode *inode) > { > - struct posix_acl *old_access, *old_default; > + struct base_acl *old_access, *old_default; > spin_lock(&inode->i_lock); > old_access =3D inode->i_acl; > old_default =3D inode->i_default_acl; > inode->i_acl =3D inode->i_default_acl =3D ACL_NOT_CACHED; > spin_unlock(&inode->i_lock); > if (old_access !=3D ACL_NOT_CACHED) > - posix_acl_release(old_access); > + base_acl_put(old_access); > if (old_default !=3D ACL_NOT_CACHED) > - posix_acl_release(old_default); > + base_acl_put(old_default); > } > EXPORT_SYMBOL(forget_all_cached_acls); >=20 > @@ -128,7 +129,7 @@ EXPORT_SYMBOL(get_acl); > void > posix_acl_init(struct posix_acl *acl, int count) > { > - atomic_set(&acl->a_refcount, 1); > + base_acl_init(&acl->a_base); > acl->a_count =3D count; > } > EXPORT_SYMBOL(posix_acl_init); > @@ -161,7 +162,7 @@ posix_acl_clone(const struct posix_acl *acl, gfp_t = flags) > sizeof(struct posix_acl_entry); > clone =3D kmemdup(acl, size, flags); > if (clone) > - atomic_set(&clone->a_refcount, 1); > + base_acl_init(&clone->a_base); > } > return clone; > } > @@ -383,7 +384,7 @@ static int posix_acl_create_masq(struct posix_acl = *acl, umode_t *mode_p) > umode_t mode =3D *mode_p; > int not_equiv =3D 0; >=20 > - /* assert(atomic_read(acl->a_refcount) =3D=3D 1); */ > + /* assert(base_acl_refcount(&acl->a_base) =3D=3D 1); */ >=20 > FOREACH_ACL_ENTRY(pa, acl, pe) { > switch(pa->e_tag) { > @@ -438,7 +439,7 @@ static int __posix_acl_chmod_masq(struct posix_acl = *acl, umode_t mode) > struct posix_acl_entry *group_obj =3D NULL, *mask_obj =3D NULL; > struct posix_acl_entry *pa, *pe; >=20 > - /* assert(atomic_read(acl->a_refcount) =3D=3D 1); */ > + /* assert(base_acl_refcount(&acl->a_base) =3D=3D 1); */ >=20 > FOREACH_ACL_ENTRY(pa, acl, pe) { > switch(pa->e_tag) { > diff --git a/fs/richacl_base.c b/fs/richacl_base.c > index 69b806c..5826842 100644 > --- a/fs/richacl_base.c > +++ b/fs/richacl_base.c > @@ -33,7 +33,7 @@ richacl_alloc(int count, gfp_t gfp) > struct richacl *acl =3D kzalloc(size, gfp); >=20 > if (acl) { > - atomic_set(&acl->a_refcount, 1); > + base_acl_init(&acl->a_base); > acl->a_count =3D count; > } > return acl; > @@ -52,7 +52,7 @@ richacl_clone(const struct richacl *acl, gfp_t gfp) >=20 > if (dup) { > memcpy(dup, acl, size); > - atomic_set(&dup->a_refcount, 1); > + base_acl_init(&dup->a_base); > } > return dup; > } > diff --git a/include/linux/fs.h b/include/linux/fs.h > index ba91a89..2fd840e 100644 > --- a/include/linux/fs.h > +++ b/include/linux/fs.h > @@ -576,6 +576,12 @@ static inline void mapping_allow_writable(struct = address_space *mapping) > #define i_size_ordered_init(inode) do { } while (0) > #endif >=20 > +struct base_acl { > + union { > + atomic_t ba_refcount; > + struct rcu_head ba_rcu; > + }; > +}; > struct posix_acl; > #define ACL_NOT_CACHED ((void *)(-1)) >=20 > @@ -595,9 +601,9 @@ struct inode { > kgid_t i_gid; > unsigned int i_flags; >=20 > -#ifdef CONFIG_FS_POSIX_ACL > - struct posix_acl *i_acl; > - struct posix_acl *i_default_acl; > +#if defined(CONFIG_FS_POSIX_ACL) > + struct base_acl *i_acl; > + struct base_acl *i_default_acl; > #endif >=20 > const struct inode_operations *i_op; > @@ -3059,4 +3065,26 @@ static inline bool dir_relax(struct inode = *inode) >=20 > extern bool path_noexec(const struct path *path); >=20 > +static inline void base_acl_get(struct base_acl *acl) > +{ > + if (acl) > + atomic_inc(&acl->ba_refcount); > +} > + > +static inline void base_acl_put(struct base_acl *acl) > +{ > + if (acl && atomic_dec_and_test(&acl->ba_refcount)) > + kfree_rcu(acl, ba_rcu); > +} > + > +static inline void base_acl_init(struct base_acl *acl) > +{ > + atomic_set(&acl->ba_refcount, 1); > +} > + > +static inline int base_acl_refcount(struct base_acl *acl) > +{ > + return atomic_read(&acl->ba_refcount); > +} > + > #endif /* _LINUX_FS_H */ > diff --git a/include/linux/posix_acl.h b/include/linux/posix_acl.h > index 5b5a80c..cef5428 100644 > --- a/include/linux/posix_acl.h > +++ b/include/linux/posix_acl.h > @@ -43,10 +43,7 @@ struct posix_acl_entry { > }; >=20 > struct posix_acl { > - union { > - atomic_t a_refcount; > - struct rcu_head a_rcu; > - }; > + struct base_acl a_base; /* must be first, see = posix_acl_release() */ > unsigned int a_count; > struct posix_acl_entry a_entries[0]; > }; > @@ -61,8 +58,7 @@ struct posix_acl { > static inline struct posix_acl * > posix_acl_dup(struct posix_acl *acl) > { > - if (acl) > - atomic_inc(&acl->a_refcount); > + base_acl_get(&acl->a_base); > return acl; > } >=20 > @@ -72,8 +68,8 @@ posix_acl_dup(struct posix_acl *acl) > static inline void > posix_acl_release(struct posix_acl *acl) > { > - if (acl && atomic_dec_and_test(&acl->a_refcount)) > - kfree_rcu(acl, a_rcu); > + BUILD_BUG_ON(offsetof(struct posix_acl, a_base) !=3D 0); > + base_acl_put(&acl->a_base); > } >=20 >=20 > diff --git a/include/linux/richacl.h b/include/linux/richacl.h > index 1d9f5f7..7628fad 100644 > --- a/include/linux/richacl.h > +++ b/include/linux/richacl.h > @@ -31,7 +31,7 @@ struct richace { > }; >=20 > struct richacl { > - atomic_t a_refcount; > + struct base_acl a_base; /* must be first, see richacl_put() */ > unsigned int a_owner_mask; > unsigned int a_group_mask; > unsigned int a_other_mask; > @@ -56,8 +56,7 @@ struct richacl { > static inline struct richacl * > richacl_get(struct richacl *acl) > { > - if (acl) > - atomic_inc(&acl->a_refcount); > + base_acl_get(&acl->a_base); > return acl; > } >=20 > @@ -67,8 +66,8 @@ richacl_get(struct richacl *acl) > static inline void > richacl_put(struct richacl *acl) > { > - if (acl && atomic_dec_and_test(&acl->a_refcount)) > - kfree(acl); > + BUILD_BUG_ON(offsetof(struct richacl, a_base) !=3D 0); > + base_acl_put(&acl->a_base); > } >=20 > /** > -- > 2.5.0 >=20 Cheers, Andreas --Apple-Mail=_65082315-236F-444B-A9A2-6BE991F8EF14 Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename=signature.asc Content-Type: application/pgp-signature; name=signature.asc Content-Description: Message signed with OpenPGP using GPGMail -----BEGIN PGP SIGNATURE----- Comment: GPGTools - http://gpgtools.org iQIVAwUBVj8CaXKl2rkXzB/gAQicpA/+OeitqZLCsqV1MSaRUFodjrabv/0fPIYu oFqw7xAGQIO7PJr0x+GMswKFvz98QU3OUtXASkL1WfYNN/tl4ClCkhdzMblNS4u7 DjtovBMWWUZZTYQtHZm1CdCUmUDHODq6V3xGrn7jgQEK7WDtBu4CNn8TZHupqDb7 0IRcEuIcw9IDc04Fn2rDtYQ5REovfnX9/ar3MC8Gqi9JAtJTfsjN5XaJ0QD20lfq zHpaToBgGAP3w5vVhL5EW0Y187PlvKoeMFXqK+iKNJ2Rbg39fBIWw1BWxAFhYQzU 8GaNwQLs2ZRuczy2P0xgixm40CMt04rD4Y2e5+XP04s0wHLtGAW2vWZ4wUjo/tyy iZDlqEXwa1ngL5o2hkXmy3ouzkVGCzUN7OC0E7qe0Qn5MOmy57Ssye6xi9hsjGv9 f08sYGkZYAKVfITOHqD/WYzX4AFpkjidiLCYkoMkWGYHvOO4dE94MMuCl+RnOPTz mAWIOg0rSvI3rYenfQt9xlnHJ2TpGeLrWu0EUmFw34r4YoqpsB9nbwf4uns/4F9i X4KUKHCvvVDCks9SCLAjdo64YRT3grLtKcP+WF8L8UkJ8uCo8OZ7ksUAkoT75q8/ 5utTjtJppag2yusjXBH5glH2tRo+GSzD9wQnYWYv4mVbImNkkQ7vSjUUSiX7v6Sq gge7QatOl+4= =vmAg -----END PGP SIGNATURE----- --Apple-Mail=_65082315-236F-444B-A9A2-6BE991F8EF14-- From adilger@dilger.ca Sun Nov 8 02:11:35 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 137367F67 for ; Sun, 8 Nov 2015 02:11:35 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 82538AC002 for ; Sun, 8 Nov 2015 00:11:34 -0800 (PST) X-ASG-Debug-ID: 1446970288-04cbb02423b5c20001-NocioJ Received: from mail-pa0-f45.google.com (mail-pa0-f45.google.com [209.85.220.45]) by cuda.sgi.com with ESMTP id Rw2f2l4hP90gJG5M (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Sun, 08 Nov 2015 00:11:29 -0800 (PST) X-Barracuda-Envelope-From: adilger@dilger.ca X-Barracuda-RBL-Trusted-Forwarder: 209.85.220.45 Received: by pacdm15 with SMTP id dm15so142189870pac.3 for ; Sun, 08 Nov 2015 00:11:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=dilger_ca.20150623.gappssmtp.com; s=20150623; h=subject:mime-version:content-type:from:in-reply-to:date:cc :message-id:references:to; bh=B/kVToMHvaqgzDo/231vh+syNA6c8GbXKur1V8Qk9VI=; b=NT5JW3524tNtCas4XmG4ckyR3JmCYQSZzGLZuWfDpZua9X0dV61EEBy4cQSlcSHtrm e9Jg+QiE5W6igM0VnRRmuNSwfX1g41i/8FBOz2n8fvBIHC7/JSAd0wsFxlQ2KL9MaAJy U8f90xx1WLSUChzA0U1zYUKIAYW0vDfhWvAIlu7BaTr1R5ATkt6qCUArJh5nExBhhwSx qUp+BjhO08R1xBV0jHlMNZM05WFKPcQfnCsp91t0fJmEYwL/i4DBibT6mKQnYDnYJUYP f8gp+X1lA+FEjMLfOx2PEke6xWrdXSRaso1gcT5e0598VfSiHY3ujGuES7epN6alq2O2 ljgw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:subject:mime-version:content-type:from :in-reply-to:date:cc:message-id:references:to; bh=B/kVToMHvaqgzDo/231vh+syNA6c8GbXKur1V8Qk9VI=; b=lZ7szS7xgwqZdN9rlaIievtHPlqEXjDPFHomEJyt1StMX5aM1HGNlWE530v1E7KYuX 7cZ2qvu9HXSdJhkpcZhnL/HSMJv5aFRv6RhB3YjZ7M4Z4jAIQY0YnjIJmIiFmZU7eTG/ 89j48OF8dNrjXZcaBGw4ZAZ1kewLSWeeewateLD6yPCMP6BPSYb5w+hSBnxURD2rL50j r4YLOSiQY0eaUjdyn7nkG0IM02q72Nw/cH5+sUi6mQyvu3nXheMMQGdMV6kJtjOLYuQd wfUGjNTf5+1dQWi0skBggeBCNZtesiVMPcFuBjh0Gw9RPB2kF457zBR/GZrGKenporhT vCxQ== X-Gm-Message-State: ALoCoQmXJ1FqFBYqmFO9CvY+0qRG6KPvU3DkWndPoGF4Hy0fJlASkxF9dZKLL0vKdm2QF1DsdzzU X-Received: by 10.68.253.73 with SMTP id zy9mr3466788pbc.97.1446970288610; Sun, 08 Nov 2015 00:11:28 -0800 (PST) Received: from cabot-wlan.adilger.int (S0106002191d9348b.cg.shawcable.net. [96.51.76.157]) by smtp.gmail.com with ESMTPSA id bs3sm9481446pbd.89.2015.11.08.00.11.26 (version=TLS1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 08 Nov 2015 00:11:27 -0800 (PST) Subject: Re: [PATCH v14 22/22] ext4: Add richacl feature flag X-Barracuda-Apparent-Source-IP: 96.51.76.157 X-Barracuda-BBL-IP: 96.51.76.157 Mime-Version: 1.0 (Mac OS X Mail 8.2 \(2104\)) X-ASG-Orig-Subj: Re: [PATCH v14 22/22] ext4: Add richacl feature flag Content-Type: multipart/signed; boundary="Apple-Mail=_0BCACE90-E476-493B-B86E-BCA15FCFDC21"; protocol="application/pgp-signature"; micalg=pgp-sha256 X-Pgp-Agent: GPGMail 2.5.2 From: Andreas Dilger In-Reply-To: <1446723580-3747-23-git-send-email-agruenba@redhat.com> Date: Sun, 8 Nov 2015 01:12:48 -0700 Cc: Alexander Viro , Theodore Ts'o , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4 , XFS Developers , LKML , linux-fsdevel , Linux NFS Mailing List , linux-cifs@vger.kernel.org, Linux API , "Aneesh Kumar K.V" Message-Id: References: <1446723580-3747-1-git-send-email-agruenba@redhat.com> <1446723580-3747-23-git-send-email-agruenba@redhat.com> To: Andreas Gruenbacher X-Mailer: Apple Mail (2.2104) X-Barracuda-Connect: mail-pa0-f45.google.com[209.85.220.45] X-Barracuda-Start-Time: 1446970289 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24211 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 --Apple-Mail=_0BCACE90-E476-493B-B86E-BCA15FCFDC21 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii On Nov 5, 2015, at 4:39 AM, Andreas Gruenbacher = wrote: >=20 > From: "Aneesh Kumar K.V" >=20 > This feature flag selects richacl instead of POSIX ACL support on the > filesystem. When this feature is off, the "acl" and "noacl" mount = options > control whether POSIX ACLs are enabled. When it is on, richacls are > automatically enabled and using the "noacl" mount option leads to an = error. >=20 > Signed-off-by: Aneesh Kumar K.V > Signed-off-by: Andreas Gruenbacher Reviewed-by: Andreas Dilger > --- > fs/ext4/ext4.h | 6 ++++-- > fs/ext4/super.c | 49 ++++++++++++++++++++++++++++++++++++++++--------- > 2 files changed, 44 insertions(+), 11 deletions(-) >=20 > diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h > index fd1f28b..b97a3b1 100644 > --- a/fs/ext4/ext4.h > +++ b/fs/ext4/ext4.h > @@ -991,7 +991,7 @@ struct ext4_inode_info { > #define EXT4_MOUNT_UPDATE_JOURNAL 0x01000 /* Update the journal = format */ > #define EXT4_MOUNT_NO_UID32 0x02000 /* Disable 32-bit UIDs = */ > #define EXT4_MOUNT_XATTR_USER 0x04000 /* Extended user = attributes */ > -#define EXT4_MOUNT_POSIX_ACL 0x08000 /* POSIX Access Control = Lists */ > +#define EXT4_MOUNT_ACL 0x08000 /* Access = Control Lists */ > #define EXT4_MOUNT_NO_AUTO_DA_ALLOC 0x10000 /* No auto delalloc = mapping */ > #define EXT4_MOUNT_BARRIER 0x20000 /* Use block barriers */ > #define EXT4_MOUNT_QUOTA 0x80000 /* Some quota option set = */ > @@ -1582,6 +1582,7 @@ static inline int ext4_encrypted_inode(struct = inode *inode) > #define EXT4_FEATURE_INCOMPAT_LARGEDIR 0x4000 /* >2GB = or 3-lvl htree */ > #define EXT4_FEATURE_INCOMPAT_INLINE_DATA 0x8000 /* data in inode = */ > #define EXT4_FEATURE_INCOMPAT_ENCRYPT 0x10000 > +#define EXT4_FEATURE_INCOMPAT_RICHACL 0x20000 >=20 > #define EXT2_FEATURE_COMPAT_SUPP EXT4_FEATURE_COMPAT_EXT_ATTR > #define EXT2_FEATURE_INCOMPAT_SUPP (EXT4_FEATURE_INCOMPAT_FILETYPE| = \ > @@ -1607,7 +1608,8 @@ static inline int ext4_encrypted_inode(struct = inode *inode) > EXT4_FEATURE_INCOMPAT_FLEX_BG| = \ > EXT4_FEATURE_INCOMPAT_MMP | \ > = EXT4_FEATURE_INCOMPAT_INLINE_DATA | \ > - EXT4_FEATURE_INCOMPAT_ENCRYPT) > + EXT4_FEATURE_INCOMPAT_ENCRYPT | = \ > + EXT4_FEATURE_INCOMPAT_RICHACL) > #define EXT4_FEATURE_RO_COMPAT_SUPP = (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER| \ > = EXT4_FEATURE_RO_COMPAT_LARGE_FILE| \ > = EXT4_FEATURE_RO_COMPAT_GDT_CSUM| \ > diff --git a/fs/ext4/super.c b/fs/ext4/super.c > index a63c7b0..7457ea8 100644 > --- a/fs/ext4/super.c > +++ b/fs/ext4/super.c > @@ -1270,6 +1270,28 @@ static ext4_fsblk_t get_sb_block(void **data) > return sb_block; > } >=20 > +static int enable_acl(struct super_block *sb) > +{ > + sb->s_flags &=3D ~(MS_POSIXACL | MS_RICHACL); > + if (test_opt(sb, ACL)) { > + if (EXT4_HAS_INCOMPAT_FEATURE(sb, > + = EXT4_FEATURE_INCOMPAT_RICHACL)) { > +#ifdef CONFIG_EXT4_FS_RICHACL > + sb->s_flags |=3D MS_RICHACL; > +#else > + return -EOPNOTSUPP; > +#endif > + } else { > +#ifdef CONFIG_EXT4_FS_POSIX_ACL > + sb->s_flags |=3D MS_POSIXACL; > +#else > + return -EOPNOTSUPP; > +#endif > + } > + } > + return 0; > +} > + > #define DEFAULT_JOURNAL_IOPRIO (IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 3)) > static char deprecated_msg[] =3D "Mount option \"%s\" will be removed = by %s\n" > "Contact linux-ext4@vger.kernel.org if you think we should keep = it.\n"; > @@ -1416,9 +1438,9 @@ static const struct mount_opts { > MOPT_NO_EXT2 | MOPT_DATAJ}, > {Opt_user_xattr, EXT4_MOUNT_XATTR_USER, MOPT_SET}, > {Opt_nouser_xattr, EXT4_MOUNT_XATTR_USER, MOPT_CLEAR}, > -#ifdef CONFIG_EXT4_FS_POSIX_ACL > - {Opt_acl, EXT4_MOUNT_POSIX_ACL, MOPT_SET}, > - {Opt_noacl, EXT4_MOUNT_POSIX_ACL, MOPT_CLEAR}, > +#if defined(CONFIG_EXT4_FS_POSIX_ACL) || = defined(CONFIG_EXT4_FS_RICHACL) > + {Opt_acl, EXT4_MOUNT_ACL, MOPT_SET}, > + {Opt_noacl, EXT4_MOUNT_ACL, MOPT_CLEAR}, > #else > {Opt_acl, 0, MOPT_NOSUPPORT}, > {Opt_noacl, 0, MOPT_NOSUPPORT}, > @@ -1466,6 +1488,13 @@ static int handle_mount_opt(struct super_block = *sb, char *opt, int token, > #endif > switch (token) { > case Opt_noacl: > +#ifdef CONFIG_EXT4_FS_RICHACL > + if (EXT4_HAS_INCOMPAT_FEATURE(sb, = EXT4_FEATURE_INCOMPAT_RICHACL)) { > + ext4_msg(sb, KERN_ERR, "Mount option \"%s\" incompatible = " > + "with richacl feature", opt); > + return -1; > + } > +#endif > case Opt_nouser_xattr: > ext4_msg(sb, KERN_WARNING, deprecated_msg, opt, "3.5"); > break; > @@ -3576,8 +3605,8 @@ static int ext4_fill_super(struct super_block = *sb, void *data, int silent) > set_opt(sb, NO_UID32); > /* xattr user namespace & acls are now defaulted on */ > set_opt(sb, XATTR_USER); > -#ifdef CONFIG_EXT4_FS_POSIX_ACL > - set_opt(sb, POSIX_ACL); > +#if defined(CONFIG_EXT4_FS_POSIX_ACL) || = defined(CONFIG_EXT4_FS_RICHACL) > + set_opt(sb, ACL); > #endif > /* don't forget to enable journal_csum when metadata_csum is = enabled. */ > if (ext4_has_metadata_csum(sb)) > @@ -3660,8 +3689,9 @@ static int ext4_fill_super(struct super_block = *sb, void *data, int silent) > sb->s_iflags |=3D SB_I_CGROUPWB; > } >=20 > - sb->s_flags =3D (sb->s_flags & ~MS_POSIXACL) | > - (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0); > + err =3D enable_acl(sb); > + if (err) > + goto failed_mount; >=20 > if (le32_to_cpu(es->s_rev_level) =3D=3D EXT4_GOOD_OLD_REV && > (EXT4_HAS_COMPAT_FEATURE(sb, ~0U) || > @@ -4981,8 +5011,9 @@ static int ext4_remount(struct super_block *sb, = int *flags, char *data) > if (sbi->s_mount_flags & EXT4_MF_FS_ABORTED) > ext4_abort(sb, "Abort forced by user"); >=20 > - sb->s_flags =3D (sb->s_flags & ~MS_POSIXACL) | > - (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0); > + err =3D enable_acl(sb); > + if (err) > + goto restore_opts; >=20 > es =3D sbi->s_es; >=20 > -- > 2.5.0 >=20 Cheers, Andreas --Apple-Mail=_0BCACE90-E476-493B-B86E-BCA15FCFDC21 Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename=signature.asc Content-Type: application/pgp-signature; name=signature.asc Content-Description: Message signed with OpenPGP using GPGMail -----BEGIN PGP SIGNATURE----- Comment: GPGTools - http://gpgtools.org iQIVAwUBVj8EAXKl2rkXzB/gAQgbOxAAgr/EeWdcnvF/SjAMimIladAt5mlkUjW9 UTtWj5C3xO7NTPmH28K3HG42mKT0WsP+ltiCDeB9VFhodLaRkykv4LhrWY0bbnZV tgmMthacKyWL+CUES9Ol1OzE2flm8KrSgSXWslTTbUsBN0dHuMPc1CJNrcs3MP0C wqaEZEzUdOBxkhZJXJco3oBMMfuoaQRi5XbcgF0ItXLY3w7z+3kXkGMaYslMW/FN NO6O+ycxbRTTQgWBI61vGFV8dOC6lGZE+1j7+ZrESmhJDGfY+dLw3IALwEMQSPCa ZT/6fX4f5fla78+hFLUM1Vkjxa8qPSjw/4en8zbNV+Kkv9j3fTRyGTjbT5e5UkUm o5hnBWKO5eESGRdTi9Nji8I06iy/1DhnazQnROmGhUrNBTUjT6OWuxWGIJ0l8iJR mVS98xlZbPZ8VCWpRBW0TwMkcs7Odo0TYry94vMjbvhBY/DrqiGFx0Rk7Pv7leHt iKnXMuEKGTZFBmApFDaTYlJYhc6eHxC1grEfUujriw0z9r6CLVr5tp+oggPP7wwv 4APOthWXoDIQV6kuujVlLaoQPP0pct/Yt6LCFIFqEUgsTfQlyQBguUnqefkH5nzS fWWdIs69SI8fcVPDg9KFZ7HdTvMWcutN1ijyhvZS3bEAFp6SgmI5+F55A5fTxTjH jpvgOQxlT9Y= =0MG+ -----END PGP SIGNATURE----- --Apple-Mail=_0BCACE90-E476-493B-B86E-BCA15FCFDC21-- From adilger@dilger.ca Sun Nov 8 02:17:37 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 D1B927F6D for ; Sun, 8 Nov 2015 02:17:37 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id BF412304039 for ; Sun, 8 Nov 2015 00:17:37 -0800 (PST) X-ASG-Debug-ID: 1446970655-04cbb02424b5de0001-NocioJ Received: from mail-pa0-f52.google.com (mail-pa0-f52.google.com [209.85.220.52]) by cuda.sgi.com with ESMTP id 7O5ZixC1qv49svhA (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Sun, 08 Nov 2015 00:17:35 -0800 (PST) X-Barracuda-Envelope-From: adilger@dilger.ca X-Barracuda-RBL-Trusted-Forwarder: 209.85.220.52 Received: by pasz6 with SMTP id z6so170931539pas.2 for ; Sun, 08 Nov 2015 00:17:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=dilger_ca.20150623.gappssmtp.com; s=20150623; h=subject:mime-version:content-type:from:in-reply-to:date:cc :message-id:references:to; bh=D/ev0JQ+xUSeRQEvsbdrqVitl9+5FXHH58Sgf27tYWQ=; b=hsZdnz4yRDAi+P2pjkO2j2RF73lbIVRnjW9sUzCJrZmDlI5ktd+/oh4KQTBWFn83e5 fR0FbZ/PLTYAWyr6nu4WwG6G+Cy2WlxOayx+bZKp9WNj2rC6Wz4GxXmv2Fh+6UKkULR1 clQ7dUZGXodKpKyluhnjol9lVsmr6JlLqBK55MzDjOJlzwduqpMaXdzLaQHPUXH00DUt pjNDsjON6Pcs0TU25FV2aB5upAuQSiXBrbw8kGtbBnCipGpge7yeHCFDSH5WrLZMepJc gOfGLZGCbLjlMu4eQZrm5kIr0mpE3D7RfoCI0F/hofLmJuS4Uu/mnKagT94M4pqPnUow P4yQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:subject:mime-version:content-type:from :in-reply-to:date:cc:message-id:references:to; bh=D/ev0JQ+xUSeRQEvsbdrqVitl9+5FXHH58Sgf27tYWQ=; b=LKjfrx84I4KocM/huj4c9hQK5WSqkMAnm/o27/HqBNf14g+Mo1TurO5DKTzW39GrEg xsGt2fnlkjCF/FmyDFXWMn+DOnd8R93qN9CwCJfw03Zl2bzqZEj8mKZlo9Qf+wtJQ7A6 G2tfWfjYl/Un2LxHdSps5VyHXmQgRyeyNsbTAziwscZysNSoCdtgF19QKT+bmcs2wtvS Lxfbrg/7OwSwBW66hhTE0pnoWbeZ3ZRWWXqIWHno9CXw7zQFjvbJiAAw5aT1POS94AlX mRqvwoyH4ijdVlG2t+Vg5dc0/Jtj9xNFn/Y8TdEI1/P2LPPq/u1tjJe4A/FxHG0j/sAY WXYg== X-Gm-Message-State: ALoCoQl8GmUMFjJ3XkOctNzeB2vheBLbev6EYDEg3cc4KNra5CEH9J30pLEil3Esdkpmh12oz17u X-Received: by 10.68.69.39 with SMTP id b7mr2694359pbu.48.1446970655151; Sun, 08 Nov 2015 00:17:35 -0800 (PST) Received: from cabot-wlan.adilger.int (S0106002191d9348b.cg.shawcable.net. [96.51.76.157]) by smtp.gmail.com with ESMTPSA id cn4sm9504986pbc.94.2015.11.08.00.17.33 (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Sun, 08 Nov 2015 00:17:34 -0800 (PST) Subject: Re: [PATCH v14 02/22] vfs: Add MAY_CREATE_FILE and MAY_CREATE_DIR permission flags X-Barracuda-Apparent-Source-IP: 96.51.76.157 X-Barracuda-BBL-IP: 96.51.76.157 Mime-Version: 1.0 (Mac OS X Mail 8.2 \(2104\)) X-ASG-Orig-Subj: Re: [PATCH v14 02/22] vfs: Add MAY_CREATE_FILE and MAY_CREATE_DIR permission flags Content-Type: multipart/signed; boundary="Apple-Mail=_28C5425C-AF5E-40F9-B6EB-6C6221836E29"; protocol="application/pgp-signature"; micalg=pgp-sha256 X-Pgp-Agent: GPGMail 2.5.2 From: Andreas Dilger In-Reply-To: <1446918268-858-1-git-send-email-agruenba@redhat.com> Date: Sun, 8 Nov 2015 01:18:55 -0700 Cc: Alexander Viro , Theodore Ts'o , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Message-Id: <0B5A4519-9506-41AA-9AA9-A67EA070E6F8@dilger.ca> References: <1446723580-3747-1-git-send-email-agruenba@redhat.com> <1446723580-3747-3-git-send-email-agruenba@redhat.com> <1446918268-858-1-git-send-email-agruenba@redhat.com> To: Andreas Gruenbacher X-Mailer: Apple Mail (2.2104) X-Barracuda-Connect: mail-pa0-f52.google.com[209.85.220.52] X-Barracuda-Start-Time: 1446970655 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24211 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 --Apple-Mail=_28C5425C-AF5E-40F9-B6EB-6C6221836E29 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii On Nov 7, 2015, at 10:44 AM, Andreas Gruenbacher = wrote: >=20 > On Fri, Nov 6, 2015 at 9:58 PM, Andreas Dilger = wrote: >> I thought you proposed adding an enum for these parameters, and = possibly >> making them a single parameter flag, to make the code in the caller = more >> readable. >=20 > No, the result would just be different but not any better; vfs_rename = would > become messy. I've played with this patch some more, and I find the = approach > below which splits may_delete into may_delete and may_replace much = better. > What do you think? This is definitely better than the previous patch. You can add: Reviewed-by: Andreas Dilger Cheers, Andreas > ---------- 8< ---------- >=20 > Richacls distinguish between creating non-directories and directories. = To > support that, add an isdir parameter to may_create(). When checking > inode_permission() for create permission, pass in an additional > MAY_CREATE_FILE or MAY_CREATE_DIR mask flag. >=20 > Add may_replace() to allow checking for delete and create access when > replacing an existing file in vfs_rename(). >=20 > Signed-off-by: Andreas Gruenbacher > Reviewed-by: J. Bruce Fields > --- > fs/namei.c | 49 = +++++++++++++++++++++++++++++++++---------------- > include/linux/fs.h | 2 ++ > 2 files changed, 35 insertions(+), 16 deletions(-) >=20 > diff --git a/fs/namei.c b/fs/namei.c > index 224ecf1..4e5dc2f 100644 > --- a/fs/namei.c > +++ b/fs/namei.c > @@ -453,7 +453,9 @@ static int sb_permission(struct super_block *sb, = struct inode *inode, int mask) > * this, letting us set arbitrary permissions for filesystem access = without > * changing the "normal" UIDs which are used for other things. > * > - * When checking for MAY_APPEND, MAY_WRITE must also be set in @mask. > + * MAY_WRITE must be set in @mask whenever MAY_APPEND, = MAY_CREATE_FILE, or > + * MAY_CREATE_DIR are set. That way, file systems that don't support = these > + * permissions will check for MAY_WRITE instead. > */ > int inode_permission(struct inode *inode, int mask) > { > @@ -2549,7 +2551,8 @@ EXPORT_SYMBOL(__check_sticky); > * 10. We don't allow removal of NFS sillyrenamed files; it's handled = by > * nfs_async_unlink(). > */ > -static int may_delete(struct inode *dir, struct dentry *victim, bool = isdir) > +static int may_delete_replace(struct inode *dir, struct dentry = *victim, > + bool isdir, int mask) > { > struct inode *inode =3D d_backing_inode(victim); > int error; > @@ -2561,7 +2564,7 @@ static int may_delete(struct inode *dir, struct = dentry *victim, bool isdir) > BUG_ON(victim->d_parent->d_inode !=3D dir); > audit_inode_child(dir, victim, AUDIT_TYPE_CHILD_DELETE); >=20 > - error =3D inode_permission(dir, MAY_WRITE | MAY_EXEC); > + error =3D inode_permission(dir, mask | MAY_WRITE | MAY_EXEC); > if (error) > return error; > if (IS_APPEND(dir)) > @@ -2584,6 +2587,18 @@ static int may_delete(struct inode *dir, struct = dentry *victim, bool isdir) > return 0; > } >=20 > +static int may_delete(struct inode *dir, struct dentry *victim, bool = isdir) > +{ > + return may_delete_replace(dir, victim, isdir, 0); > +} > + > +static int may_replace(struct inode *dir, struct dentry *victim, bool = isdir) > +{ > + int mask =3D isdir ? MAY_CREATE_DIR : MAY_CREATE_FILE; > + > + return may_delete_replace(dir, victim, isdir, mask); > +} > + > /* Check whether we can create an object with dentry child in = directory > * dir. > * 1. We can't do it if child already exists (open has special = treatment for > @@ -2592,14 +2607,16 @@ static int may_delete(struct inode *dir, = struct dentry *victim, bool isdir) > * 3. We should have write and exec permissions on dir > * 4. We can't do it if dir is immutable (done in permission()) > */ > -static inline int may_create(struct inode *dir, struct dentry *child) > +static inline int may_create(struct inode *dir, struct dentry *child, = bool isdir) > { > + int mask =3D isdir ? MAY_CREATE_DIR : MAY_CREATE_FILE; > + > audit_inode_child(dir, child, AUDIT_TYPE_CHILD_CREATE); > if (child->d_inode) > return -EEXIST; > if (IS_DEADDIR(dir)) > return -ENOENT; > - return inode_permission(dir, MAY_WRITE | MAY_EXEC); > + return inode_permission(dir, MAY_WRITE | MAY_EXEC | mask); > } >=20 > /* > @@ -2649,7 +2666,7 @@ EXPORT_SYMBOL(unlock_rename); > int vfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, > bool want_excl) > { > - int error =3D may_create(dir, dentry); > + int error =3D may_create(dir, dentry, false); > if (error) > return error; >=20 > @@ -3494,7 +3511,7 @@ EXPORT_SYMBOL(user_path_create); >=20 > int vfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, = dev_t dev) > { > - int error =3D may_create(dir, dentry); > + int error =3D may_create(dir, dentry, false); >=20 > if (error) > return error; > @@ -3586,7 +3603,7 @@ SYSCALL_DEFINE3(mknod, const char __user *, = filename, umode_t, mode, unsigned, d >=20 > int vfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) > { > - int error =3D may_create(dir, dentry); > + int error =3D may_create(dir, dentry, true); > unsigned max_links =3D dir->i_sb->s_max_links; >=20 > if (error) > @@ -3667,7 +3684,7 @@ EXPORT_SYMBOL(dentry_unhash); >=20 > int vfs_rmdir(struct inode *dir, struct dentry *dentry) > { > - int error =3D may_delete(dir, dentry, 1); > + int error =3D may_delete(dir, dentry, true); >=20 > if (error) > return error; > @@ -3789,7 +3806,7 @@ SYSCALL_DEFINE1(rmdir, const char __user *, = pathname) > int vfs_unlink(struct inode *dir, struct dentry *dentry, struct inode = **delegated_inode) > { > struct inode *target =3D dentry->d_inode; > - int error =3D may_delete(dir, dentry, 0); > + int error =3D may_delete(dir, dentry, false); >=20 > if (error) > return error; > @@ -3923,7 +3940,7 @@ SYSCALL_DEFINE1(unlink, const char __user *, = pathname) >=20 > int vfs_symlink(struct inode *dir, struct dentry *dentry, const char = *oldname) > { > - int error =3D may_create(dir, dentry); > + int error =3D may_create(dir, dentry, false); >=20 > if (error) > return error; > @@ -4006,7 +4023,7 @@ int vfs_link(struct dentry *old_dentry, struct = inode *dir, struct dentry *new_de > if (!inode) > return -ENOENT; >=20 > - error =3D may_create(dir, new_dentry); > + error =3D may_create(dir, new_dentry, false); > if (error) > return error; >=20 > @@ -4199,14 +4216,14 @@ int vfs_rename(struct inode *old_dir, struct = dentry *old_dentry, > return error; >=20 > if (!target) { > - error =3D may_create(new_dir, new_dentry); > + error =3D may_create(new_dir, new_dentry, is_dir); > } else { > new_is_dir =3D d_is_dir(new_dentry); >=20 > if (!(flags & RENAME_EXCHANGE)) > - error =3D may_delete(new_dir, new_dentry, = is_dir); > + error =3D may_replace(new_dir, new_dentry, = is_dir); > else > - error =3D may_delete(new_dir, new_dentry, = new_is_dir); > + error =3D may_replace(new_dir, new_dentry, = new_is_dir); > } > if (error) > return error; > @@ -4469,7 +4486,7 @@ SYSCALL_DEFINE2(rename, const char __user *, = oldname, const char __user *, newna >=20 > int vfs_whiteout(struct inode *dir, struct dentry *dentry) > { > - int error =3D may_create(dir, dentry); > + int error =3D may_create(dir, dentry, false); > if (error) > return error; >=20 > diff --git a/include/linux/fs.h b/include/linux/fs.h > index 4efa435..d6e2330 100644 > --- a/include/linux/fs.h > +++ b/include/linux/fs.h > @@ -82,6 +82,8 @@ typedef void (dax_iodone_t)(struct buffer_head = *bh_map, int uptodate); > #define MAY_CHDIR 0x00000040 > /* called from RCU mode, don't block */ > #define MAY_NOT_BLOCK 0x00000080 > +#define MAY_CREATE_FILE 0x00000100 > +#define MAY_CREATE_DIR 0x00000200 >=20 > /* > * flags in file.f_mode. Note that FMODE_READ and FMODE_WRITE must = correspond > -- > 2.5.0 >=20 Cheers, Andreas --Apple-Mail=_28C5425C-AF5E-40F9-B6EB-6C6221836E29 Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename=signature.asc Content-Type: application/pgp-signature; name=signature.asc Content-Description: Message signed with OpenPGP using GPGMail -----BEGIN PGP SIGNATURE----- Comment: GPGTools - http://gpgtools.org iQIVAwUBVj8Fb3Kl2rkXzB/gAQjlFw//aWzy9SPFugHLc3t+sSL41Y1t+7aX4X8N dd6d5FXGYH1PL+H1Z0iic/7Cmartf5YyNuILYboa89rUAEU7drzG4AkzLQ0TZ8OO xac09BSBQ1XXO9SUB/ph4WvXwwSZRYGISqFi6+GZ4W5MIn/cKkB1zyFgwAwmWn6Z v8QoR9t/Tipy0LjCdyMPfQx6hBYVaix3oUP5BNQvKcjkjzaPYig6QFcnXjUL6CTD DhnQV8adxJLaWQfbt5IFg3pLABtGqnrKfqEDPPyD8waiu6Qt8amRXz01bKHuOgBv VFOjgG8NBFJsFWFVsmmkSijeQNn8AzxQ8MNQAjdZgbzVIkFYVPGf/ZJxOhgt5dKb ocNJsfF2Lrwksa729XLD6GAIIjRtk+HHGE+L5K/HQz0uv1WxUb9/AVSrusmsgyYB tDbaiQENZm0V9pvxb0SM+jqI0lo93P9gl0ie8XcxRGQrMGxx9V4tm6aqhD8cQhsO zDAaN90AWoTQme/ZkeqH3H2xePtNvXaCatMA9dlKvJkpL02vuxEC97BP5oVkLxHF 5n1mb6s9Pt6a6g091sZET5Mn7sqNDuRsCub5iOIlJyK69jXPPah9x5HnfUbNurP6 EhbUhSqw/zFBj9JbLxyMSa30bBFIpLApzukXgSbxlpd1Lcs6h1a7zqJ+qS/6JEuc fDrfsrLN9zM= =YAtC -----END PGP SIGNATURE----- --Apple-Mail=_28C5425C-AF5E-40F9-B6EB-6C6221836E29-- From BATV+e6d75f8cb5da29cb3d45+4459+infradead.org+hch@bombadil.srs.infradead.org Sun Nov 8 10:49:47 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 8ECBF7F50 for ; Sun, 8 Nov 2015 10:49:47 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 6BF24304032 for ; Sun, 8 Nov 2015 08:49:46 -0800 (PST) X-ASG-Debug-ID: 1447001383-04cb6c296dba950001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id K03yLopBaX7ss2FI (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Sun, 08 Nov 2015 08:49:43 -0800 (PST) X-Barracuda-Envelope-From: BATV+e6d75f8cb5da29cb3d45+4459+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 1ZvT9x-0007l3-T7; Sun, 08 Nov 2015 16:49:41 +0000 Date: Sun, 8 Nov 2015 08:49:41 -0800 From: Christoph Hellwig To: David Madore Cc: Linux Kernel mailing-list , xfs@oss.sgi.com Subject: Re: XFS freeze (xfsaild blocked) with 4.2.5 (also 4.3) Message-ID: <20151108164941.GA26354@infradead.org> X-ASG-Orig-Subj: Re: XFS freeze (xfsaild blocked) with 4.2.5 (also 4.3) References: <20151108114917.GA5620@achernar.madore.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151108114917.GA5620@achernar.madore.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: 1447001383 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/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_SA717, BSF_SC7_SA_HREF_FROM_MISMATCH_TEXT_URIx1_HL, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24220 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS 0.00 BSF_SC0_SA717 Custom Rule BSF_SC0_SA717 2.50 BSF_SC7_SA_HREF_FROM_MISMATCH_TEXT_URIx1_HL Custom Rule HREF_FROM_MISMATCH_TEXT_URIx1_HL Hi David, can you try the patch at: http://article.gmane.org/gmane.comp.file-systems.xfs.general/70984 The symptoms sound surprisingly similar. From david@fromorbit.com Sun Nov 8 15:16:57 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 D924B7F51 for ; Sun, 8 Nov 2015 15:16:57 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id CBD21304039 for ; Sun, 8 Nov 2015 13:16:54 -0800 (PST) X-ASG-Debug-ID: 1447017410-04cbb02424c3c00001-NocioJ Received: from ipmail06.adl6.internode.on.net (ipmail06.adl6.internode.on.net [150.101.137.145]) by cuda.sgi.com with ESMTP id 24lbLq8HFyLutt8h for ; Sun, 08 Nov 2015 13:16:51 -0800 (PST) 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: A2BcCADxuj9WPGfGLHleKAECgxCBQoZcpFEGizKFLIQJhgoEAgKBG00BAQEBAQEHAQEBAUE/hDUBAQEDATocIwULCAMOCgklDwUlAwcaE4gmB79rASwZhXSFRYk5AQSWSI0fjzSNGYR7KjSFZgEBAQ Received: from ppp121-44-198-103.lns20.syd7.internode.on.net (HELO dastard) ([121.44.198.103]) by ipmail06.adl6.internode.on.net with ESMTP; 09 Nov 2015 07:46:49 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZvXKS-0003ij-HQ; Mon, 09 Nov 2015 08:16:48 +1100 Date: Mon, 9 Nov 2015 08:16:48 +1100 From: Dave Chinner To: Chris Mason Cc: xfs@oss.sgi.com, Tejun Heo Subject: Re: [PATCH RFC] use WQ_MEM_RECLAIM for m_log_workqueue Message-ID: <20151108211648.GV10656@dastard> X-ASG-Orig-Subj: Re: [PATCH RFC] use WQ_MEM_RECLAIM for m_log_workqueue References: <20151104185103.GC5458@ret.masoncoding.com> <20151105121059.GJ5458@ret.masoncoding.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151105121059.GJ5458@ret.masoncoding.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: 1447017410 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24224 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Thu, Nov 05, 2015 at 07:10:59AM -0500, Chris Mason wrote: > On Wed, Nov 04, 2015 at 01:51:03PM -0500, Chris Mason wrote: > > I think we should be using WQ_MEM_RECLAIM to make sure this thread pool > > makes progress when we're not able to allocate new workers. > > Thinking harder, it's probably best to just flag them all > WQ_MEM_RECLAIM. This is what btrfs does, and it saves you from painful > discoveries about how different queues depend on each other. Makes sense, we missed this one because the original use of the workqueue was just for a periodic, non-critical function. Then we move the log IO completion to it in 3.19 in commit b29c70f ("xfs: split metadata and log buffer completion to separate workqueues"). > I'll start testing and send a v2. Seems like a no-brainer to me... Cheers, Dave. -- Dave Chinner david@fromorbit.com From david+bounce@madore.org Sun Nov 8 15:52:47 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 3D85B7F52 for ; Sun, 8 Nov 2015 15:52:47 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id C37C8AC001 for ; Sun, 8 Nov 2015 13:52:46 -0800 (PST) X-ASG-Debug-ID: 1447019562-04cbb02424c41f0001-NocioJ Received: from achernar.gro-tsen.net (achernar.gro-tsen.net [195.154.91.68]) by cuda.sgi.com with ESMTP id ND5kWfl57FFko8fQ (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 08 Nov 2015 13:52:43 -0800 (PST) X-Barracuda-Envelope-From: david+bounce@madore.org X-Barracuda-Apparent-Source-IP: 195.154.91.68 Received: by achernar.gro-tsen.net (Postfix, from userid 500) id DA8D22402B4; Sun, 8 Nov 2015 22:52:41 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=madore.org; s=achernar; t=1447019561; bh=1rtRRL961G1PS9vDn1Egqjyc2mf9LDD+IaGRL9S0/6Y=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=lbaAeG+fstye0kKy1hgGjNIvEW/6x4Ylsl2k/916ERwiNrcv4L8jKicnJ7dlhabHR C+rUtQL5ySYqsV1jmHdf/RlPiD5Q4TLShoehs+WaRbkop+mZBuAhoUvW21NON94qaQ DX0kX0hGO5pknksD5H7RYsAQLXnQzELq3wOCnYag= Date: Sun, 8 Nov 2015 22:52:41 +0100 From: David Madore To: Christoph Hellwig Cc: Linux Kernel mailing-list , xfs@oss.sgi.com Subject: Re: XFS freeze (xfsaild blocked) with 4.2.5 (also 4.3) Message-ID: <20151108215241.GA10569@achernar.madore.org> X-ASG-Orig-Subj: Re: XFS freeze (xfsaild blocked) with 4.2.5 (also 4.3) References: <20151108114917.GA5620@achernar.madore.org> <20151108164941.GA26354@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151108164941.GA26354@infradead.org> User-Agent: Mutt/1.5.23 (2014-03-12) X-Barracuda-Connect: achernar.gro-tsen.net[195.154.91.68] X-Barracuda-Start-Time: 1447019563 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24225 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 Sun, Nov 08, 2015 at 08:49:41AM -0800, Christoph Hellwig wrote: > can you try the patch at: > > http://article.gmane.org/gmane.comp.file-systems.xfs.general/70984 > > The symptoms sound surprisingly similar. Thanks for the pointer. I'm running with the patch now, and will follow-up if the problem reoccurs. -- David A. Madore ( http://www.madore.org/~david/ ) From agruenba@redhat.com Sun Nov 8 16:19:43 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 2B7BE7F54 for ; Sun, 8 Nov 2015 16:19:43 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 0F2DA8F8035 for ; Sun, 8 Nov 2015 14:19:39 -0800 (PST) X-ASG-Debug-ID: 1447021175-04cbb02423c4860001-NocioJ Received: from mail-lb0-f178.google.com (mail-lb0-f178.google.com [209.85.217.178]) by cuda.sgi.com with ESMTP id JaK6UYmdkZ9g6Vls (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Sun, 08 Nov 2015 14:19:36 -0800 (PST) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.85.217.178 Received: by lbces9 with SMTP id es9so17520912lbc.2 for ; Sun, 08 Nov 2015 14:19:35 -0800 (PST) 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=+Gr09NqzDPnCm/Zh3amgUrB7Ojapnm39jF9YnIAHuLc=; b=kFTaVcFhJorEAKFKRzI+hBT5K8ODGejJ0mCG4t8YuBa5tbcJ5thrpLBR2BDzntI0Dq Yr09O9TE5I8fxran4QGOZ5nP4JP6X4/wcLl5rA9ghp7FqbEg40tcpi/ITF/Ueo5R9sLF 5xS1r9r7cYZRT2KPBovA08xKSXG2IZbiYW0rleVhsPGG3kWEygQsJzVWAMVQaHh7/8QH 1/tHTI3NvXi3p2ot6xHitGBzT9rNK13b/GNbjdBjh7WeaM6hS0sI556jslaPlmEa+Lxf cK18D01nNUlOQYkRXfXUwCA+wkdV4TjHUadMjFC48qb08hv0DmBfKzt+8A9N//StnfMW 2b8w== X-Gm-Message-State: ALoCoQkzQ8cJ/qIu9EuIZ7puM1ocOjP+yXqe3mHrIU+ybgzsqQg557ZUQaPXMbkXJoTwPb7d6v3f MIME-Version: 1.0 X-Received: by 10.112.236.8 with SMTP id uq8mr13088457lbc.116.1447021175294; Sun, 08 Nov 2015 14:19:35 -0800 (PST) Received: by 10.112.53.42 with HTTP; Sun, 8 Nov 2015 14:19:35 -0800 (PST) In-Reply-To: References: <1446563847-14005-1-git-send-email-agruenba@redhat.com> <1446563847-14005-46-git-send-email-agruenba@redhat.com> Date: Sun, 8 Nov 2015 23:19:35 +0100 Message-ID: Subject: Re: [PATCH v13 45/51] sunrpc: Allow to demand-allocate pages to encode into From: Andreas Gruenbacher X-ASG-Orig-Subj: Re: [PATCH v13 45/51] sunrpc: Allow to demand-allocate pages to encode into To: Trond Myklebust Cc: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Anna Schumaker , Dave Chinner , linux-ext4 , XFS Developers , Linux Kernel Mailing List , Linux FS-devel Mailing List , Linux NFS Mailing List , linux-cifs@vger.kernel.org, Linux API Mailing List Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-lb0-f178.google.com[209.85.217.178] X-Barracuda-Start-Time: 1447021176 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24225 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Thu, Nov 5, 2015 at 4:57 PM, Trond Myklebust wrote: > On Thu, Nov 5, 2015 at 6:07 AM, Andreas Gruenbacher wrote: >> Trond, >> >> On Tue, Nov 3, 2015 at 5:25 PM, Trond Myklebust >> wrote: >>> On Tue, Nov 3, 2015 at 10:17 AM, Andreas Gruenbacher >>> wrote: >>>> When encoding large, variable-length objects such as acls into xdr_bufs, >>>> it is easier to allocate buffer pages on demand rather than precomputing >>>> the required buffer size. >>> >>> NACK. We're not doing allocations from inside the XDR encoders. This >>> can and should be done before calling into the SUNRPC layer. >> >> an XDR-encoded ACL can be up to 64k (16 pages) in size. In practice, >> large ACLs like that will almost never occur and almost all ACLs will >> fit into a single page though. >> >> The XDR-encoded ACL contains strings for the user and group names >> which need to be looked up when the idmapper is used. Those lookups >> are somewhat expensive; in addition, the lookup results can change >> over time. When precomputing the size, allocating space, and then >> encoding the ACL, we could run out of space when encoding. >> >> So we could always allocate the maximum 16 pages, encode the acl, and >> free the unused pages. This would be rather wasteful though. >> >> Given how simple it is to allocate pages as we go, this seems the >> better choice here. This doesn't break any existing code either; NULL >> page pointers would have oopsed in xdr_get_next_encode_buffer before. >> >> From the memory management point of view, there is no difference in >> preallocating GFP_NOFS pages and allocating them on demand; the pages >> are allocated in the same task and locking context in both cases. >> >> So could you please explain why you object to this change? > > Allocating memory deep in the bowels of the RPC code with the > expectation that it will be freed by the caller of the RPC request is > a layering violation of the ugliest sort. Ah, there we have it, Godwin's Law for software discussions. What happens here is the following: the caller sets up an xdr_stream that contains an array of NULL page pointers (__nfs4_proc_set_acl -> nfs4_encode_acl -> xdr_init_encode_pages). It does so on purpose to tell the XDR layer to allocate pages for it as needed, and it knows it is responsible for later freeing those pages. Without this patch, the XDR layer would immediately Oops when hitting a NULL page pointer. This tells us that the XDR layer is so far not prepared to handle NULL page pointers, and that we can assign a meaning to NULL page pointers without affecting existing callers. Using the existing XDR layer for XDR-encoding ACLs makes sense because the XDR layer already knows how to align things, encode into multiple pages, handle strings that wrap across pages, etc. I really don't want to duplicate all that for ACLs. > How is anyone who is > unfamiliar with the code going to be able to understand what is going > on without tracing through 1000 lines of code to spot where the > allocation is happening? Somebody unfamiliar with the existing code will not understand it without putting some effort in, either. What do you expect? Besides, the caller doesn't care where the allocation is happening, it just cares that it is happening when it should. > Aside from that, we do not want any non-critical blocking while > holding the RPC socket lock. Your allocation request will block all > further traffic to the server until it is satisfied. That includes > blocking page writeback, which might actually free up memory to > satisfy the allocation. > > As I said above, there is no reason whatsoever to have to do all this > inside encode_setacl(). The entire ACL encoding into pages can be done > before even calling into the RPC layer, just like we do today. You have pointed that out before, and as a consequence, it was fixed in the July 22 snapshot (https://lwn.net/Articles/652058/): * Changes to the nfs patches: acls are now encoded above the sunrpc layer. This means we can no longer encode small acls directly into the scratch area of an xdr_buf, we always have to allocate extra memory. But we also don't need to touch the nfs sunrpc code, which Trond objected to. Since then, the ACL encoding happens in __nfs4_proc_set_acl, before calling into the RPC layer. Thanks, Andreas From debbugs@buxtehude.debian.org Sun Nov 8 18:03:18 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 AAE107F56 for ; Sun, 8 Nov 2015 18:03:18 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 8A8368F8033 for ; Sun, 8 Nov 2015 16:03:15 -0800 (PST) X-ASG-Debug-ID: 1447027388-04cbb02424c5af0001-NocioJ Received: from buxtehude.debian.org (buxtehude.debian.org [140.211.166.26]) by cuda.sgi.com with ESMTP id hswb3qaUXFjQldzB (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Sun, 08 Nov 2015 16:03:08 -0800 (PST) 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.84) (envelope-from ) id 1ZvZvN-0003mj-Ur; Mon, 09 Nov 2015 00:03:05 +0000 X-Loop: owner@bugs.debian.org Subject: Bug#804255: Please update initramfs in postinst Reply-To: Nathan Scott , 804255@bugs.debian.org X-ASG-Orig-Subj: Bug#804255: Please update initramfs in postinst Resent-From: Nathan Scott Resent-To: debian-bugs-dist@lists.debian.org Resent-CC: XFS Development Team X-Loop: owner@bugs.debian.org Resent-Date: Mon, 09 Nov 2015 00:03:04 +0000 Resent-Message-ID: X-Debian-PR-Message: followup 804255 X-Debian-PR-Package: xfsprogs X-Debian-PR-Keywords: d-i X-Debian-PR-Source: xfsprogs Received: via spool by 804255-submit@bugs.debian.org id=B804255.144702722713128 (code B ref 804255); Mon, 09 Nov 2015 00:03:04 +0000 Received: (at 804255) by bugs.debian.org; 9 Nov 2015 00:00:27 +0000 Received: from mx4-phx2.redhat.com ([209.132.183.25]) by buxtehude.debian.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.84) (envelope-from ) id 1ZvZso-0003PK-Oy for 804255@bugs.debian.org; Mon, 09 Nov 2015 00:00:26 +0000 Received: from zmail20.collab.prod.int.phx2.redhat.com (zmail20.collab.prod.int.phx2.redhat.com [10.5.83.23]) by mx4-phx2.redhat.com (8.13.8/8.13.8) with ESMTP id tA900K6i021867; Sun, 8 Nov 2015 19:00:20 -0500 Date: Sun, 8 Nov 2015 19:00:20 -0500 (EST) From: Nathan Scott To: Steve McIntyre , 804255@bugs.debian.org Message-ID: <1822095565.6959319.1447027220334.JavaMail.zimbra@redhat.com> In-Reply-To: <20151106161941.15248.86048.reportbug@tack.local> References: <20151106161941.15248.86048.reportbug@tack.local> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-Originating-IP: [10.64.51.93] X-Mailer: Zimbra 8.0.6_GA_5922 (ZimbraWebClient - FF37 (Linux)/8.0.6_GA_5922) Thread-Topic: Bug#804255: Please update initramfs in postinst Thread-Index: 9o4atQ/2S8PqjPGj2/mFHCWYGyr2xA== X-Barracuda-Connect: buxtehude.debian.org[140.211.166.26] X-Barracuda-Start-Time: 1447027388 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/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.24227 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.01 THREAD_INDEX thread-index: AcO7Y8iR61tzADqsRmmc5wNiFHEOig== 0.01 THREAD_TOPIC Thread-Topic: ...(Japanese Subject)... Hi Steve, ----- Original Message ----- > Package: xfsprogs > Version: 3.2.1 > Severity: important > Tags: d-i > > To make this work well, all filesystem tools packages for filesystems > that are likely to be used for / and/or /usr should call > "update-initramfs -u" in their postinst. This will OK. > I've checked your package and I don't see any update-initramfs > calls. (yep, xfsprogs has no postinst at all IIRC) > Please add one. If you'd like help doing that postinst work, I > can supply a patch - just ask! That would be great, if you don't mind Steve? Many thanks! cheers. -- Nathan From ts10@a.shengjumuduan.com Sun Nov 8 23:32:43 2015 Return-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, UNPARSEABLE_RELAY 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 921CE7F37 for ; Sun, 8 Nov 2015 23:32:43 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 404FAAC002 for ; Sun, 8 Nov 2015 21:32:39 -0800 (PST) X-ASG-Debug-ID: 1447047153-04bdf03f05c5d50001-NocioJ Received: from a.shengjumuduan.com ([112.195.153.83]) by cuda.sgi.com with SMTP id hNlmhGPVs0bZ8TYb for ; Sun, 08 Nov 2015 21:32:34 -0800 (PST) X-Barracuda-Envelope-From: ts10@a.shengjumuduan.com X-Barracuda-Apparent-Source-IP: 112.195.153.83 Received: from 121.15.41.131 (HELO LQSUVW); Mon, 9 Nov 2015 13:30:53 +0800 Date: Mon, 9 Nov 2015 13:36:13 +0800 From: "Michelle Tang" Reply-To: sales@sz-tecom.com To: "xfs" Subject: Factory for CNC precision parts Message-ID: <201511091336132907890@a.shengjumuduan.com> X-ASG-Orig-Subj: Factory for CNC precision parts X-Mailer: Foxmail 6, 10, 201, 20 [cn] MIME-Version: 1.0 Content-Type: text/plain; charset="GB2312" Content-Transfer-Encoding: base64 X-Barracuda-Connect: UNKNOWN[112.195.153.83] X-Barracuda-Start-Time: 1447047153 X-Barracuda-URL: https://192.48.157.11:443/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, UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24232 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS RGVhciBTaXIsDQoNCkhvcGUgeW91IGhhdmUgYSBmYWJ1bG91cyBkYXkhDQoNCk91ciBjb21wYW55 IG1haW5seSBkZWFscyBpbiBtYWNoaW5pbmcgQ05DIHByZWNpc2lvbiBwYXJ0cyBhcHBsaWNhdGlv bnMuICBPdXIgY29tcGFueSBwcm9kdWNlIHBhcnRzIGFzIHBlciBjdXN0b21lciBkcmF3aW5nLCBm cm9tIHByb2R1Y3Rpb24gdG8gYWxsIGtpbmRzIG9mIHN1cmZhY2UgdHJlYXRtZW50IGFuZCBkaWZm ZXJlbnQgdGVjaG5vbG9neSwgc3VjaCBhcyB0byB0aGUgY3VzdG9tZXJzIHdpdGggY29tcGxldGUg Y29uZmlkZW5jZSBndWFyYW50ZWUNCg0KUGxlYXNlIGhhdmUgYSBsb29rIGF0IGZvbGxvd2luZyBz ZXJ2aWNlc6Gtoa2hraGtDQoNCqGkICAgICAgY25jIG1hY2hpbmVkIHBhcnRzLCBjbmMgdHVybmlu ZywgY25jIG1pbGxpbmcgY2VudGVyLCBjbmMgc21hbGwgZGlhbWV0ZXIgbWFjaGluaW5nDQoNCqGk ICAgICAgICBBdXRvbW90aXZlIHBhcnRzIG1hY2hpbmluZw0KDQqhpCAgICAgICAgRWxlY3Rvcm5p Y3MgcGFydCBtYWNoaW5pbmcNCg0KoaQgICAgICAgIFJGIGNvbm5lY3RvciBhY2NlcnNzb3JpZXMN Cg0KoaQgICAgICAgIE1lZGljYWwgJiBGaWJlcm9wdGljIHBhcnRzDQoNCqGkICAgICAgICBFbGVj dHJvbmljIGxpZ2h0Zml0dGluZ3MNCg0KV2Ugd2lsbCBiZSBoYXBweSB0byBwcm92aWRlIHlvdSBv dXIgcXVpY2sgYXNzaXN0YW5jZS5Nb3JlIGRldGFpbCBwbGVhc2UgeW91ciBoZWxwIHRvIHJlZmVy IHRvIG91ciB3ZWJzaXRlIHd3dy5zei10ZWNvbS5jb20gDQoNCkJlc3QgcmVnYXJkcyENCk1pY2hl bGxlIFRhbmcNCg0KVGVjb20gUHJlY2lzaW9uIE1hY2hpbmluZyhzaGVuemhlbilDby4sTFREDQpB ZGQ6IDN0aCBGbG9vcixBMiBCbG9jayxaaG9uZ1BlbmdDaGVuZyBJbmR1c3RyaWFsIFBhcmssIA0K ICAgICAgICBDaHVhbmdDaHVuIFNvdXRoIFJvYWQsR29uZ01pbmcgVG93bixTaGVuWmhlbixDaGlu YQ0KQ2VsbDogMDA4Ni0xMzQgMTA1MyA1ODgwDQpUZWwgOiAwMDg2LTc1NS0yNzE1IDUxMzANCkZh eDogMDA4Ni03NTUtMjcxNSA1MTMwDQpFbWFpbDogTWljaGVsbGVAc3otdGVjb20uY29tDQpXZWI6 IHd3dy5zei10ZWNvbS5jb20= From anthoniocasova@gmail.com Mon Nov 9 00:56:42 2015 Return-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_REPLY, HTML_MESSAGE,LOTS_OF_MONEY 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 25A3C7F50 for ; Mon, 9 Nov 2015 00:56:42 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id AC199AC002 for ; Sun, 8 Nov 2015 22:56:41 -0800 (PST) X-ASG-Debug-ID: 1447052195-04bdf03f02c79b0001-NocioJ Received: from vps-8295 (vps-8295.fhnet.fr [93.115.97.125]) by cuda.sgi.com with SMTP id aD3w1KjqeYjct8qP for ; Sun, 08 Nov 2015 22:56:36 -0800 (PST) X-Barracuda-Envelope-From: anthoniocasova@gmail.com X-Barracuda-Apparent-Source-IP: 93.115.97.125 Received: from vps-8295 ([127.0.0.0]) by vps-8295 ([127.0.0.0]) with SMTPSVC; Mon, 09 Nov 2015 07:57:03 +0100 Message-ID: From: To: Subject: =?utf-8?B?0JrRgNC10LTQuNGC0L3Ri9C1INC/0YDQtdC00LvQvtC20LXQvdC40Y+=?= =?utf-8?B?OyDQpNC40L3QsNC90YHQuNGA0L7QstCw0L3QuNC1INCS0LDRiNC40YW=?= =?utf-8?B?INC/0YDQvtC10LrRgtC+0LK=?= Date: Mon, 09 Nov 2015 07:57:02 +0100 X-ASG-Orig-Subj: =?utf-8?B?0JrRgNC10LTQuNGC0L3Ri9C1INC/0YDQtdC00LvQvtC20LXQvdC40Y+=?= =?utf-8?B?OyDQpNC40L3QsNC90YHQuNGA0L7QstCw0L3QuNC1INCS0LDRiNC40YW=?= =?utf-8?B?INC/0YDQvtC10LrRgtC+0LK=?= MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="----=MailPart0000_0010_7C1244E8" X-Barracuda-Connect: vps-8295.fhnet.fr[93.115.97.125] X-Barracuda-Start-Time: 1447052195 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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, NO_REAL_NAME X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24234 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 NO_REAL_NAME From: does not include a real name 0.00 HTML_MESSAGE BODY: HTML included in message This is a multi-part message in MIME format. ------=MailPart0000_0010_7C1244E8 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable =D0=94=D0=B0=D0=BC=D1=8B =D0=B8 = =D0=B3=D0=BE=D1=81=D0=BF=D0=BE=D0=B4=D0=B0 = =D0=97=D0=B4=D1=80=D0=B0=D0=B2=D1=81=D1=82=D0=B2=D1=83=D0=B9=D1=82=D0=B5 =D0=92=D1=8B =D0=BD=D0=B0=D1=85=D0=BE=D0=B4=D0=B8=D1=82=D0=B5=D1=81=D1=8C = =D0=B2 =D0=BF=D0=BE=D0=B8=D1=81=D0=BA=D0=B0=D1=85 = =D1=84=D0=B8=D0=BD=D0=B0=D0=BD=D1=81=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0= =B8=D1=8F =D0=B4=D0=BB=D1=8F =D0=BB=D0=B8=D0=B1=D0=BE = =D0=BF=D0=B5=D1=80=D0=B5=D0=B7=D0=B0=D0=BF=D1=83=D1=81=D1=82=D0=B8=D1=82=D0= =B5=D0=BC=D0=B5=D1=80=D0=BE=D0=BF=D1=80=D0=B8=D1=8F=D1=82=D0=B8=D1=8F = =D0=B4=D0=BB=D1=8F =D0=BB=D1=8E=D0=B1=D0=BE=D0=B9 = =D0=BF=D1=80=D0=BE=D0=B5=D0=BA=D1=82 =D0=B8=D0=BB=D0=B8 = =D0=BA=D1=83=D0=BF=D0=B8=D1=82=D1=8C =D1=82=D0=B5=D0=B1=D0=B5 = =D0=BA=D0=B2=D0=B0=D1=80=D1=82=D0=B8=D1=80=D0=B0, =D1=8F = =D0=BF=D1=80=D0=B5=D0=B4=D0=BE=D1=81=D1=82=D0=B0=D0=B2=D0=BB=D1=8F=D1=82=D1= =8C =D0=BA=D1=80=D0=B5=D0=B4=D0=B8=D1=82=D1=8B = =D0=B4=D0=B5=D0=BD=D0=B5=D0=B6=D0=BD=D1=8B=D1=85 =D1=81=D1=83=D0=BC=D0=BC = =D0=BE=D1=82 $ 3000 =D0=B4=D0=BE $ 1000.000, =D0=BA=D1=82=D0=BE =D0=B2 = =D1=81=D0=BE=D1=81=D1=82=D0=BE=D1=8F=D0=BD=D0=B8=D0=B8 = =D0=BF=D0=BE=D0=B3=D0=B0=D1=81=D0=B8=D1=82=D1=8C =D0=B5=D0=B3=D0=BE =D1=81 = =D0=BF=D1=80=D0=BE=D1=86=D0=B5=D0=BD=D1=82=D0=BD=D0=BE=D0=B9 = =D1=81=D1=82=D0=B0=D0=B2=D0=BA=D0=BE=D0=B9 =D0=B2 = =D1=80=D0=B0=D0=B7=D0=BC=D0=B5=D1=80=D0=B5 3% =D0=B2 =D0=B3=D0=BE=D0=B4, = =D0=B8 =D0=B2=D1=80=D0=B5=D0=BC=D1=8F, = =D0=BD=D0=B0=D1=87=D0=B8=D0=BD=D0=B0=D1=8F =D0=BE=D1=82 1-25 = =D0=BB=D0=B5=D1=82, =D0=B2 = =D0=B7=D0=B0=D0=B2=D0=B8=D1=81=D0=B8=D0=BC=D0=BE=D1=81=D1=82=D0=B8 = =D0=BE=D1=82 =D0=BA=D0=BE=D0=BB=D0=B8=D1=87=D0=B5=D1=81=D1=82=D0=B2=D0=B0 = =D0=BF=D1=80=D0=BE=D1=81=D0=B8=D0=BB , =D0=AF = =D0=B4=D0=B5=D0=BB=D0=B0=D1=8E =D1=8D=D1=82=D0=BE =D0=B2 = =D1=81=D0=BB=D0=B5=D0=B4=D1=83=D1=8E=D1=89=D0=B8=D1=85 = =D0=BE=D0=B1=D0=BB=D0=B0=D1=81=D1=82=D1=8F=D1=85: - = =D1=84=D0=B8=D0=BD=D0=B0=D0=BD=D1=81=D0=BE=D0=B2=D0=BE-=D0=93=D0=BE=D1=82= =D0=BE=D0=B2 =D0=93=D0=BE=D1=82=D0=BE=D0=B2 = =D0=93=D0=BE=D1=82=D0=BE=D0=B2=D0=BD=D0=B5 = =D0=B4=D0=B2=D0=B8=D0=B6=D0=B8=D0=BC=D0=BE=D1=81=D1=82=D1=8C- = =D0=98=D0=BD=D0=B2=D0=B5=D1=81=D1=82=D0=B8=D1=86=D0=B8=D0=B8 = =D0=B0=D0=B2=D1=82=D0=BE=D0=BC=D0=BE=D0=B1=D0=B8=D0=BB=D0=B5- = =D0=B7=D0=B0=D0=B9=D0=BC=D0=B0 = =D0=B7=D0=B0=D0=B4=D0=BE=D0=BB=D0=B6=D0=B5=D0=BD=D0=BD=D0=BE=D1=81=D1=82=D0= =B8 =D0=92=D1=8B=D0=BA=D1=83=D0=BF = =D0=BA=D1=80=D0=B5=D0=B4=D0=B8=D1=82=D0=BD=D1=8B=D1=85 = =D0=BA=D0=BE=D0=BD=D1=81=D0=BE=D0=BB=D0=B8=D0=B4=D0=B0=D1=86=D0=B8=D1=8F- = =D0=93=D0=BE=D1=82=D0=BE=D0=B2 =D0=BB=D0=B8=D1=87=D0=BD=D0=BE =D0=B2=D1=8B = =D0=B7=D0=B0=D1=81=D1=82=D1=80=D1=8F=D0=BB=D0=B8. =D0=95=D1=81=D0=BB=D0=B8 = =D0=B2=D1=8B = =D0=B4=D0=B5=D0=B9=D1=81=D1=82=D0=B2=D0=B8=D1=82=D0=B5=D0=BB=D1=8C=D0=BD=D0= =BE =D0=B2 =D0=BD=D0=B5=D0=B9 = =D0=BD=D1=83=D0=B6=D0=B4=D0=B0=D0=B5=D1=82=D1=81=D1=8F, = =D0=BF=D0=BE=D0=B6=D0=B0=D0=BB=D1=83=D0=B9=D1=81=D1=82=D0=B0, = =D1=81=D0=B2=D1=8F=D0=B6=D0=B8=D1=82=D0=B5=D1=81=D1=8C =D1=81=D0=BE = =D0=BC=D0=BD=D0=BE=D0=B9 =D0=B4=D0=BB=D1=8F = =D0=BF=D0=BE=D0=BB=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D1=8F = =D0=B4=D0=BE=D0=BF=D0=BE=D0=BB=D0=BD=D0=B8=D1=82=D0=B5=D0=BB=D1=8C=D0=BD=D0= =BE=D0=B9 =D0=B8=D0=BD=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=86=D0=B8=D0=B8 . = =D0=9F=D0=BE=D0=B6=D0=B0=D0=BB=D1=83=D0=B9=D1=81=D1=82=D0=B0, = =D1=81=D0=B2=D1=8F=D0=B6=D0=B8=D1=82=D0=B5=D1=81=D1=8C =D1=81=D0=BE = =D0=BC=D0=BD=D0=BE=D0=B9 =D1=87=D0=B5=D1=80=D0=B5=D0=B7 E-MAIL: = (anthoniocasova@gmail.com) =D0=B8=D0=BB=D0=B8 =D0=BD=D0=B0 = =D0=BC=D0=BE=D0=B5=D0=BC =D1=81=D0=BA=D0=B0=D0=B9=D0=BF=D0=B5 = (anthonio.casova@gmail.com) ------=MailPart0000_0010_7C1244E8 Content-Type: text/html; charset="utf-8" Content-Transfer-Encoding: quoted-printable =D0=9A=D1=80=D0=B5=D0=B4=D0=B8=D1=82=D0=BD=D1=8B=D0=B5 = =D0=BF=D1=80=D0=B5=D0=B4=D0=BB=D0=BE=D0=B6=D0=B5=D0=BD=D0=B8=D1=8F; = =D0=A4=D0=B8=D0=BD=D0=B0=D0=BD=D1=81=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0= =B8=D0=B5 =D0=92=D0=B0=D1=88=D0=B8=D1=85 = =D0=BF=D1=80=D0=BE=D0=B5=D0=BA=D1=82=D0=BE=D0=B2

 =D0=94=D0=B0=D0=BC=D1=8B =D0=B8 = =D0=B3=D0=BE=D1=81=D0=BF=D0=BE=D0=B4=D0=B0 = =D0=97=D0=B4=D1=80=D0=B0=D0=B2=D1=81=D1=82=D0=B2=D1=83=D0=B9=D1=82=D0=B5

=D0=92=D1=8B = =D0=BD=D0=B0=D1=85=D0=BE=D0=B4=D0=B8=D1=82=D0=B5=D1=81=D1=8C =D0=B2 = =D0=BF=D0=BE=D0=B8=D1=81=D0=BA=D0=B0=D1=85 = =D1=84=D0=B8=D0=BD=D0=B0=D0=BD=D1=81=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0= =B8=D1=8F =D0=B4=D0=BB=D1=8F =D0=BB=D0=B8=D0=B1=D0=BE = =D0=BF=D0=B5=D1=80=D0=B5=D0=B7=D0=B0=D0=BF=D1=83=D1=81=D1=82=D0=B8=D1=82=D0= =B5
=D0=BC=D0=B5=D1=80=D0=BE=D0=BF=D1=80=D0=B8=D1=8F=D1=82=D0=B8=D1=8F = =D0=B4=D0=BB=D1=8F =D0=BB=D1=8E=D0=B1=D0=BE=D0=B9 = =D0=BF=D1=80=D0=BE=D0=B5=D0=BA=D1=82 =D0=B8=D0=BB=D0=B8 = =D0=BA=D1=83=D0=BF=D0=B8=D1=82=D1=8C =D1=82=D0=B5=D0=B1=D0=B5 = =D0=BA=D0=B2=D0=B0=D1=80=D1=82=D0=B8=D1=80=D0=B0, =D1=8F = =D0=BF=D1=80=D0=B5=D0=B4=D0=BE=D1=81=D1=82=D0=B0=D0=B2=D0=BB=D1=8F=D1=82=D1= =8C =D0=BA=D1=80=D0=B5=D0=B4=D0=B8=D1=82=D1=8B = =D0=B4=D0=B5=D0=BD=D0=B5=D0=B6=D0=BD=D1=8B=D1=85 =D1=81=D1=83=D0=BC=D0=BC = =D0=BE=D1=82 $ 3000 =D0=B4=D0=BE $ 1000.000, =D0=BA=D1=82=D0=BE =D0=B2 = =D1=81=D0=BE=D1=81=D1=82=D0=BE=D1=8F=D0=BD=D0=B8=D0=B8 = =D0=BF=D0=BE=D0=B3=D0=B0=D1=81=D0=B8=D1=82=D1=8C =D0=B5=D0=B3=D0=BE =D1=81 = =D0=BF=D1=80=D0=BE=D1=86=D0=B5=D0=BD=D1=82=D0=BD=D0=BE=D0=B9 = =D1=81=D1=82=D0=B0=D0=B2=D0=BA=D0=BE=D0=B9 =D0=B2 = =D1=80=D0=B0=D0=B7=D0=BC=D0=B5=D1=80=D0=B5 3% =D0=B2 =D0=B3=D0=BE=D0=B4, = =D0=B8 =D0=B2=D1=80=D0=B5=D0=BC=D1=8F, = =D0=BD=D0=B0=D1=87=D0=B8=D0=BD=D0=B0=D1=8F =D0=BE=D1=82 1-25 = =D0=BB=D0=B5=D1=82, =D0=B2 = =D0=B7=D0=B0=D0=B2=D0=B8=D1=81=D0=B8=D0=BC=D0=BE=D1=81=D1=82=D0=B8 = =D0=BE=D1=82 =D0=BA=D0=BE=D0=BB=D0=B8=D1=87=D0=B5=D1=81=D1=82=D0=B2=D0=B0 = =D0=BF=D1=80=D0=BE=D1=81=D0=B8=D0=BB , =D0=AF = =D0=B4=D0=B5=D0=BB=D0=B0=D1=8E =D1=8D=D1=82=D0=BE =D0=B2 = =D1=81=D0=BB=D0=B5=D0=B4=D1=83=D1=8E=D1=89=D0=B8=D1=85 = =D0=BE=D0=B1=D0=BB=D0=B0=D1=81=D1=82=D1=8F=D1=85:
- = =D1=84=D0=B8=D0=BD=D0=B0=D0=BD=D1=81=D0=BE=D0=B2=D0=BE-=D0=93=D0=BE=D1=82= =D0=BE=D0=B2 =D0=93=D0=BE=D1=82=D0=BE=D0=B2 = =D0=93=D0=BE=D1=82=D0=BE=D0=B2=D0=BD=D0=B5 = =D0=B4=D0=B2=D0=B8=D0=B6=D0=B8=D0=BC=D0=BE=D1=81=D1=82=D1=8C- = =D0=98=D0=BD=D0=B2=D0=B5=D1=81=D1=82=D0=B8=D1=86=D0=B8=D0=B8 = =D0=B0=D0=B2=D1=82=D0=BE=D0=BC=D0=BE=D0=B1=D0=B8=D0=BB=D0=B5- = =D0=B7=D0=B0=D0=B9=D0=BC=D0=B0 = =D0=B7=D0=B0=D0=B4=D0=BE=D0=BB=D0=B6=D0=B5=D0=BD=D0=BD=D0=BE=D1=81=D1=82=D0= =B8 =D0=92=D1=8B=D0=BA=D1=83=D0=BF = =D0=BA=D1=80=D0=B5=D0=B4=D0=B8=D1=82=D0=BD=D1=8B=D1=85 = =D0=BA=D0=BE=D0=BD=D1=81=D0=BE=D0=BB=D0=B8=D0=B4=D0=B0=D1=86=D0=B8=D1=8F- = =D0=93=D0=BE=D1=82=D0=BE=D0=B2 =D0=BB=D0=B8=D1=87=D0=BD=D0=BE =D0=B2=D1=8B = =D0=B7=D0=B0=D1=81=D1=82=D1=80=D1=8F=D0=BB=D0=B8. =D0=95=D1=81=D0=BB=D0=B8 = =D0=B2=D1=8B = =D0=B4=D0=B5=D0=B9=D1=81=D1=82=D0=B2=D0=B8=D1=82=D0=B5=D0=BB=D1=8C=D0=BD=D0= =BE =D0=B2 =D0=BD=D0=B5=D0=B9 = =D0=BD=D1=83=D0=B6=D0=B4=D0=B0=D0=B5=D1=82=D1=81=D1=8F, = =D0=BF=D0=BE=D0=B6=D0=B0=D0=BB=D1=83=D0=B9=D1=81=D1=82=D0=B0, = =D1=81=D0=B2=D1=8F=D0=B6=D0=B8=D1=82=D0=B5=D1=81=D1=8C =D1=81=D0=BE = =D0=BC=D0=BD=D0=BE=D0=B9 =D0=B4=D0=BB=D1=8F = =D0=BF=D0=BE=D0=BB=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D1=8F = =D0=B4=D0=BE=D0=BF=D0=BE=D0=BB=D0=BD=D0=B8=D1=82=D0=B5=D0=BB=D1=8C=D0=BD=D0= =BE=D0=B9 =D0=B8=D0=BD=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=86=D0=B8=D0=B8 . = =D0=9F=D0=BE=D0=B6=D0=B0=D0=BB=D1=83=D0=B9=D1=81=D1=82=D0=B0, = =D1=81=D0=B2=D1=8F=D0=B6=D0=B8=D1=82=D0=B5=D1=81=D1=8C =D1=81=D0=BE = =D0=BC=D0=BD=D0=BE=D0=B9 =D1=87=D0=B5=D1=80=D0=B5=D0=B7 E-MAIL: = (
anthoniocasova@gmail.com) =D0=B8=D0=BB=D0=B8 =D0=BD=D0=B0 = =D0=BC=D0=BE=D0=B5=D0=BC =D1=81=D0=BA=D0=B0=D0=B9=D0=BF=D0=B5 (anthonio.casova@gmail.com= )

------=MailPart0000_0010_7C1244E8-- From BATV+de400beb68979b2c477c+4460+infradead.org+hch@bombadil.srs.infradead.org Mon Nov 9 01:54:42 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 2FA297F37 for ; Mon, 9 Nov 2015 01:54:42 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 8EFB6AC004 for ; Sun, 8 Nov 2015 23:54:41 -0800 (PST) X-ASG-Debug-ID: 1447055679-04bdf03f02c8a30001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id AvqCXFfFklREoZtP (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Sun, 08 Nov 2015 23:54:39 -0800 (PST) X-Barracuda-Envelope-From: BATV+de400beb68979b2c477c+4460+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 1ZvhHi-0005Yf-VI; Mon, 09 Nov 2015 07:54:38 +0000 Date: Sun, 8 Nov 2015 23:54:38 -0800 From: Christoph Hellwig To: "Darrick J. Wong" Cc: david@fromorbit.com, xfs@oss.sgi.com Subject: Re: [PATCH v2 03/51] xfs_io: support reflink and dedupe of file ranges Message-ID: <20151109075438.GA17974@infradead.org> X-ASG-Orig-Subj: Re: [PATCH v2 03/51] xfs_io: support reflink and dedupe of file ranges References: <20151007050513.1504.28089.stgit@birch.djwong.org> <20151007050533.1504.66249.stgit@birch.djwong.org> <20151014053656.GJ10397@birch.djwong.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151014053656.GJ10397@birch.djwong.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: 1447055679 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/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_MISMATCH_TO, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24235 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS Any reason why the dedup command is called 'dedupe'? Is this a revenge for the missing 'e' in the creat syscall? :) Either way it would be good to get this support in ASAP so we can have the command ready for xfstests and we can merge the test. They are useful for btrfs and NFS already, so I'd love to fast track them. From BATV+de400beb68979b2c477c+4460+infradead.org+hch@bombadil.srs.infradead.org Mon Nov 9 01:59:45 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 4CD787F37 for ; Mon, 9 Nov 2015 01:59:45 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 2D6CA8F8033 for ; Sun, 8 Nov 2015 23:59:42 -0800 (PST) X-ASG-Debug-ID: 1447055973-04bdf03f04c8b40001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id AGrnRdgNH3sWJaRj (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Sun, 08 Nov 2015 23:59:33 -0800 (PST) X-Barracuda-Envelope-From: BATV+de400beb68979b2c477c+4460+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 1ZvhMM-000791-3o; Mon, 09 Nov 2015 07:59:26 +0000 Date: Sun, 8 Nov 2015 23:59:26 -0800 From: Christoph Hellwig To: "Darrick J. Wong" Cc: david@fromorbit.com, fstests@vger.kernel.org, linux-ext4@vger.kernel.org, Anna.Schumaker@netapp.com, linux-btrfs@vger.kernel.org, xfs@oss.sgi.com Subject: Re: [RFCv3 00/12] xfstests: test the btrfs/xfs reflink/dedupe ioctls Message-ID: <20151109075926.GB17974@infradead.org> X-ASG-Orig-Subj: Re: [RFCv3 00/12] xfstests: test the btrfs/xfs reflink/dedupe ioctls References: <20151007051257.3260.73072.stgit@birch.djwong.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151007051257.3260.73072.stgit@birch.djwong.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: 1447055973 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/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_MISMATCH_TO, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24235 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS On Tue, Oct 06, 2015 at 10:12:57PM -0700, Darrick J. Wong wrote: > * I don't have any interesting NFS/CIFS setups for test. :( I have a banrch with client and server support for NFSv4.2 CLONE support: http://git.infradead.org/users/hch/pnfs.git/shortlog/refs/heads/reflink+clone For now you want to use btrfs on the server, as using reflinks on XFS seems to be a little unstable over NFS. > If you're going to start using this mess, you probably ought to just > pull from my github trees for kernel[1], xfsprogs[2], and xfstests[3]. > They should just work with the btrfs that's in 4.3. > > Comments and questions are, as always, welcome. Any reason the groups are called clone? I don't really have an opinion on clone vs reflink but given that the xfs_io command is reflink I'd rather be consistent. Otherwise I'd say get it merged ASAP, we can still fix up various details later. From agruenba@redhat.com Mon Nov 9 05:09:18 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 761D87CBF for ; Mon, 9 Nov 2015 05:09:18 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 4A5A8304032 for ; Mon, 9 Nov 2015 03:09:15 -0800 (PST) X-ASG-Debug-ID: 1447067353-04bdf03f05cdb40001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id n1v64CWNGZ8VVJl2 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 09 Nov 2015 03:09:14 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id AC88B3DD42; Mon, 9 Nov 2015 11:09:12 +0000 (UTC) Received: from nux.redhat.com (vpn1-6-118.ams2.redhat.com [10.36.6.118]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA9B94CJ028578; Mon, 9 Nov 2015 06:09:05 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v15 00/22] Richacls (Core and Ext4) Date: Mon, 9 Nov 2015 12:08:41 +0100 X-ASG-Orig-Subj: [PATCH v15 00/22] Richacls (Core and Ext4) Message-Id: <1447067343-31479-1-git-send-email-agruenba@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: 1447067353 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Here is another update to the richacl patch queue. This posting contains the patches ready to be merged; the patches later in the queue still need some more review. Changes since the last posting (http://thread.gmane.org/gmane.linux.kernel.cifs/11221): * Replacing an existing file or directory requires to be able to delete and recreate it. A new function may_replace was added to test for replace access vs. delete access (may_delete); this simplifies the code and makes it more readable. Without richacls, deleting and creating requires the same permissions, and making that distinction wasn't useful. * The DELETE permission on a file was accidentally allowing to replace the file without also requiring the ADD_FILE permission on the containing directory. This was fixed and a regression test was added to the test suite. * A comment as to how pages for XDR-encoded ACLs are alocated was added to __nfs4_proc_set_acl. (See the complete patch queue for that.) The complete patch queue is available in git form here: git://git.kernel.org/pub/scm/linux/kernel/git/agruen/linux-richacl.git \ richacl-2015-11-09 The richacl user-space utilitites, man pages, and test suite are available here: https://github.com/andreas-gruenbacher/richacl Changes to other user-space packages for richacl are available here: https://github.com/andreas-gruenbacher/coreutils https://github.com/andreas-gruenbacher/e2fsprogs https://github.com/andreas-gruenbacher/xfsprogs-dev https://github.com/andreas-gruenbacher/nfs-utils Please see the richacl homepage for more information: http://www.bestbits.at/richacl/ Thanks, Andreas Andreas Gruenbacher (20): vfs: Add IS_ACL() and IS_RICHACL() tests vfs: Add MAY_CREATE_FILE and MAY_CREATE_DIR permission flags vfs: Add MAY_DELETE_SELF and MAY_DELETE_CHILD permission flags vfs: Make the inode passed to inode_change_ok non-const vfs: Add permission flags for setting file attributes richacl: In-memory representation and helper functions richacl: Permission mapping functions richacl: Compute maximum file masks from an acl richacl: Permission check algorithm posix_acl: Unexport acl_by_type and make it static vfs: Cache base_acl objects in inodes vfs: Add get_richacl and set_richacl inode operations vfs: Cache richacl in struct inode richacl: Update the file masks in chmod() richacl: Check if an acl is equivalent to a file mode richacl: Create-time inheritance richacl: Automatic Inheritance richacl: xattr mapping functions richacl: Add richacl xattr handler vfs: Add richacl permission checking Aneesh Kumar K.V (2): ext4: Add richacl support ext4: Add richacl feature flag drivers/staging/lustre/lustre/llite/llite_lib.c | 2 +- fs/Kconfig | 3 + fs/Makefile | 2 + fs/attr.c | 81 +++- fs/ext4/Kconfig | 11 + fs/ext4/Makefile | 1 + fs/ext4/ext4.h | 6 +- fs/ext4/file.c | 3 + fs/ext4/ialloc.c | 11 +- fs/ext4/inode.c | 12 +- fs/ext4/namei.c | 5 + fs/ext4/richacl.c | 142 ++++++ fs/ext4/richacl.h | 40 ++ fs/ext4/super.c | 49 +- fs/ext4/xattr.c | 7 + fs/f2fs/acl.c | 4 +- fs/inode.c | 15 +- fs/jffs2/acl.c | 10 +- fs/namei.c | 118 +++-- fs/posix_acl.c | 50 +-- fs/richacl_base.c | 564 ++++++++++++++++++++++++ fs/richacl_inode.c | 333 ++++++++++++++ fs/richacl_xattr.c | 298 +++++++++++++ fs/xattr.c | 34 +- include/linux/fs.h | 60 ++- include/linux/posix_acl.h | 13 +- include/linux/richacl.h | 208 +++++++++ include/linux/richacl_xattr.h | 44 ++ include/uapi/linux/Kbuild | 2 + include/uapi/linux/fs.h | 3 +- include/uapi/linux/richacl.h | 152 +++++++ include/uapi/linux/richacl_xattr.h | 44 ++ include/uapi/linux/xattr.h | 2 + 33 files changed, 2222 insertions(+), 107 deletions(-) create mode 100644 fs/ext4/richacl.c create mode 100644 fs/ext4/richacl.h create mode 100644 fs/richacl_base.c create mode 100644 fs/richacl_inode.c create mode 100644 fs/richacl_xattr.c create mode 100644 include/linux/richacl.h create mode 100644 include/linux/richacl_xattr.h create mode 100644 include/uapi/linux/richacl.h create mode 100644 include/uapi/linux/richacl_xattr.h -- 2.5.0 From agruenba@redhat.com Mon Nov 9 05:09:21 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 C6C607F50 for ; Mon, 9 Nov 2015 05:09:21 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id B6308304032 for ; Mon, 9 Nov 2015 03:09:21 -0800 (PST) X-ASG-Debug-ID: 1447067359-04cb6c296acc790001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id nm0YVDBxmIWGdWQy (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 09 Nov 2015 03:09:20 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 8FB6BC00354D; Mon, 9 Nov 2015 11:09:19 +0000 (UTC) Received: from nux.redhat.com (vpn1-6-118.ams2.redhat.com [10.36.6.118]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA9B94CK028578; Mon, 9 Nov 2015 06:09:13 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v15 01/22] vfs: Add IS_ACL() and IS_RICHACL() tests Date: Mon, 9 Nov 2015 12:08:42 +0100 X-ASG-Orig-Subj: [PATCH v15 01/22] vfs: Add IS_ACL() and IS_RICHACL() tests Message-Id: <1447067343-31479-2-git-send-email-agruenba@redhat.com> In-Reply-To: <1447067343-31479-1-git-send-email-agruenba@redhat.com> References: <1447067343-31479-1-git-send-email-agruenba@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: 1447067360 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 The vfs does not apply the umask for file systems that support acls. The test used for this used to be called IS_POSIXACL(). Switch to a new IS_ACL() test to check for either posix acls or richacls instead. Add a new MS_RICHACL flag and IS_RICHACL() test for richacls alone. The IS_POSIXACL() test is still needed by nfsd. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields Reviewed-by: Andreas Dilger --- fs/Kconfig | 3 +++ fs/namei.c | 8 ++++---- include/linux/fs.h | 12 ++++++++++++ include/uapi/linux/fs.h | 3 ++- 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/fs/Kconfig b/fs/Kconfig index da3f32f..bff2879 100644 --- a/fs/Kconfig +++ b/fs/Kconfig @@ -56,6 +56,9 @@ endif # BLOCK config FS_POSIX_ACL def_bool n +config FS_RICHACL + def_bool n + config EXPORTFS tristate diff --git a/fs/namei.c b/fs/namei.c index 33e9495..224ecf1 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -2798,7 +2798,7 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry, } mode = op->mode; - if ((open_flag & O_CREAT) && !IS_POSIXACL(dir)) + if ((open_flag & O_CREAT) && !IS_ACL(dir)) mode &= ~current_umask(); excl = (open_flag & (O_EXCL | O_CREAT)) == (O_EXCL | O_CREAT); @@ -2982,7 +2982,7 @@ static int lookup_open(struct nameidata *nd, struct path *path, /* Negative dentry, just create the file */ if (!dentry->d_inode && (op->open_flag & O_CREAT)) { umode_t mode = op->mode; - if (!IS_POSIXACL(dir->d_inode)) + if (!IS_ACL(dir->d_inode)) mode &= ~current_umask(); /* * This write is needed to ensure that a @@ -3553,7 +3553,7 @@ retry: if (IS_ERR(dentry)) return PTR_ERR(dentry); - if (!IS_POSIXACL(path.dentry->d_inode)) + if (!IS_ACL(path.dentry->d_inode)) mode &= ~current_umask(); error = security_path_mknod(&path, dentry, mode, dev); if (error) @@ -3622,7 +3622,7 @@ retry: if (IS_ERR(dentry)) return PTR_ERR(dentry); - if (!IS_POSIXACL(path.dentry->d_inode)) + if (!IS_ACL(path.dentry->d_inode)) mode &= ~current_umask(); error = security_path_mkdir(&path, dentry, mode); if (!error) diff --git a/include/linux/fs.h b/include/linux/fs.h index 72d8a84..4efa435 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1781,6 +1781,12 @@ struct super_operations { #define IS_IMMUTABLE(inode) ((inode)->i_flags & S_IMMUTABLE) #define IS_POSIXACL(inode) __IS_FLG(inode, MS_POSIXACL) +#ifdef CONFIG_FS_RICHACL +#define IS_RICHACL(inode) __IS_FLG(inode, MS_RICHACL) +#else +#define IS_RICHACL(inode) 0 +#endif + #define IS_DEADDIR(inode) ((inode)->i_flags & S_DEAD) #define IS_NOCMTIME(inode) ((inode)->i_flags & S_NOCMTIME) #define IS_SWAPFILE(inode) ((inode)->i_flags & S_SWAPFILE) @@ -1794,6 +1800,12 @@ struct super_operations { (inode)->i_rdev == WHITEOUT_DEV) /* + * IS_ACL() tells the VFS to not apply the umask + * and use check_acl for acl permission checks when defined. + */ +#define IS_ACL(inode) __IS_FLG(inode, MS_POSIXACL | MS_RICHACL) + +/* * Inode state bits. Protected by inode->i_lock * * Three bits determine the dirty state of the inode, I_DIRTY_SYNC, diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h index 9b964a5..6ac6bc9 100644 --- a/include/uapi/linux/fs.h +++ b/include/uapi/linux/fs.h @@ -81,7 +81,7 @@ struct inodes_stat_t { #define MS_VERBOSE 32768 /* War is peace. Verbosity is silence. MS_VERBOSE is deprecated. */ #define MS_SILENT 32768 -#define MS_POSIXACL (1<<16) /* VFS does not apply the umask */ +#define MS_POSIXACL (1<<16) /* Supports POSIX ACLs */ #define MS_UNBINDABLE (1<<17) /* change to unbindable */ #define MS_PRIVATE (1<<18) /* change to private */ #define MS_SLAVE (1<<19) /* change to slave */ @@ -91,6 +91,7 @@ struct inodes_stat_t { #define MS_I_VERSION (1<<23) /* Update inode I_version field */ #define MS_STRICTATIME (1<<24) /* Always perform atime updates */ #define MS_LAZYTIME (1<<25) /* Update the on-disk [acm]times lazily */ +#define MS_RICHACL (1<<26) /* Supports richacls */ /* These sb flags are internal to the kernel */ #define MS_NOSEC (1<<28) -- 2.5.0 From agruenba@redhat.com Mon Nov 9 05:09:31 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 3DFFD7CBF for ; Mon, 9 Nov 2015 05:09:31 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 12A1A8F8049 for ; Mon, 9 Nov 2015 03:09:28 -0800 (PST) X-ASG-Debug-ID: 1447067366-04bdf03f04cdb50001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id cD3W2utBT3YOMJml (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 09 Nov 2015 03:09:26 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 73AADE7066; Mon, 9 Nov 2015 11:09:26 +0000 (UTC) Received: from nux.redhat.com (vpn1-6-118.ams2.redhat.com [10.36.6.118]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA9B94CL028578; Mon, 9 Nov 2015 06:09:20 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v15 02/22] vfs: Add MAY_CREATE_FILE and MAY_CREATE_DIR permission flags Date: Mon, 9 Nov 2015 12:08:43 +0100 X-ASG-Orig-Subj: [PATCH v15 02/22] vfs: Add MAY_CREATE_FILE and MAY_CREATE_DIR permission flags Message-Id: <1447067343-31479-3-git-send-email-agruenba@redhat.com> In-Reply-To: <1447067343-31479-1-git-send-email-agruenba@redhat.com> References: <1447067343-31479-1-git-send-email-agruenba@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: 1447067366 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Richacls distinguish between creating non-directories and directories. To support that, add an isdir parameter to may_create(). When checking inode_permission() for create permission, pass in an additional MAY_CREATE_FILE or MAY_CREATE_DIR mask flag. Add may_replace() to allow checking for delete and create access when replacing an existing file in vfs_rename(). Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields Reviewed-by: Andreas Dilger --- fs/namei.c | 49 +++++++++++++++++++++++++++++++++---------------- include/linux/fs.h | 2 ++ 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 224ecf1..24a98f9 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -453,7 +453,9 @@ static int sb_permission(struct super_block *sb, struct inode *inode, int mask) * this, letting us set arbitrary permissions for filesystem access without * changing the "normal" UIDs which are used for other things. * - * When checking for MAY_APPEND, MAY_WRITE must also be set in @mask. + * MAY_WRITE must be set in @mask whenever MAY_APPEND, MAY_CREATE_FILE, or + * MAY_CREATE_DIR are set. That way, file systems that don't support these + * permissions will check for MAY_WRITE instead. */ int inode_permission(struct inode *inode, int mask) { @@ -2549,7 +2551,8 @@ EXPORT_SYMBOL(__check_sticky); * 10. We don't allow removal of NFS sillyrenamed files; it's handled by * nfs_async_unlink(). */ -static int may_delete(struct inode *dir, struct dentry *victim, bool isdir) +static int may_delete_or_replace(struct inode *dir, struct dentry *victim, + bool isdir, int mask) { struct inode *inode = d_backing_inode(victim); int error; @@ -2561,7 +2564,7 @@ static int may_delete(struct inode *dir, struct dentry *victim, bool isdir) BUG_ON(victim->d_parent->d_inode != dir); audit_inode_child(dir, victim, AUDIT_TYPE_CHILD_DELETE); - error = inode_permission(dir, MAY_WRITE | MAY_EXEC); + error = inode_permission(dir, mask); if (error) return error; if (IS_APPEND(dir)) @@ -2584,6 +2587,18 @@ static int may_delete(struct inode *dir, struct dentry *victim, bool isdir) return 0; } +static int may_delete(struct inode *dir, struct dentry *victim, bool isdir) +{ + return may_delete_or_replace(dir, victim, isdir, MAY_WRITE | MAY_EXEC); +} + +static int may_replace(struct inode *dir, struct dentry *victim, bool isdir) +{ + int mask = isdir ? MAY_CREATE_DIR : MAY_CREATE_FILE; + + return may_delete_or_replace(dir, victim, isdir, mask | MAY_WRITE | MAY_EXEC); +} + /* Check whether we can create an object with dentry child in directory * dir. * 1. We can't do it if child already exists (open has special treatment for @@ -2592,14 +2607,16 @@ static int may_delete(struct inode *dir, struct dentry *victim, bool isdir) * 3. We should have write and exec permissions on dir * 4. We can't do it if dir is immutable (done in permission()) */ -static inline int may_create(struct inode *dir, struct dentry *child) +static inline int may_create(struct inode *dir, struct dentry *child, bool isdir) { + int mask = isdir ? MAY_CREATE_DIR : MAY_CREATE_FILE; + audit_inode_child(dir, child, AUDIT_TYPE_CHILD_CREATE); if (child->d_inode) return -EEXIST; if (IS_DEADDIR(dir)) return -ENOENT; - return inode_permission(dir, MAY_WRITE | MAY_EXEC); + return inode_permission(dir, MAY_WRITE | MAY_EXEC | mask); } /* @@ -2649,7 +2666,7 @@ EXPORT_SYMBOL(unlock_rename); int vfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool want_excl) { - int error = may_create(dir, dentry); + int error = may_create(dir, dentry, false); if (error) return error; @@ -3494,7 +3511,7 @@ EXPORT_SYMBOL(user_path_create); int vfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev) { - int error = may_create(dir, dentry); + int error = may_create(dir, dentry, false); if (error) return error; @@ -3586,7 +3603,7 @@ SYSCALL_DEFINE3(mknod, const char __user *, filename, umode_t, mode, unsigned, d int vfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) { - int error = may_create(dir, dentry); + int error = may_create(dir, dentry, true); unsigned max_links = dir->i_sb->s_max_links; if (error) @@ -3667,7 +3684,7 @@ EXPORT_SYMBOL(dentry_unhash); int vfs_rmdir(struct inode *dir, struct dentry *dentry) { - int error = may_delete(dir, dentry, 1); + int error = may_delete(dir, dentry, true); if (error) return error; @@ -3789,7 +3806,7 @@ SYSCALL_DEFINE1(rmdir, const char __user *, pathname) int vfs_unlink(struct inode *dir, struct dentry *dentry, struct inode **delegated_inode) { struct inode *target = dentry->d_inode; - int error = may_delete(dir, dentry, 0); + int error = may_delete(dir, dentry, false); if (error) return error; @@ -3923,7 +3940,7 @@ SYSCALL_DEFINE1(unlink, const char __user *, pathname) int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname) { - int error = may_create(dir, dentry); + int error = may_create(dir, dentry, false); if (error) return error; @@ -4006,7 +4023,7 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de if (!inode) return -ENOENT; - error = may_create(dir, new_dentry); + error = may_create(dir, new_dentry, false); if (error) return error; @@ -4199,14 +4216,14 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, return error; if (!target) { - error = may_create(new_dir, new_dentry); + error = may_create(new_dir, new_dentry, is_dir); } else { new_is_dir = d_is_dir(new_dentry); if (!(flags & RENAME_EXCHANGE)) - error = may_delete(new_dir, new_dentry, is_dir); + error = may_replace(new_dir, new_dentry, is_dir); else - error = may_delete(new_dir, new_dentry, new_is_dir); + error = may_replace(new_dir, new_dentry, new_is_dir); } if (error) return error; @@ -4469,7 +4486,7 @@ SYSCALL_DEFINE2(rename, const char __user *, oldname, const char __user *, newna int vfs_whiteout(struct inode *dir, struct dentry *dentry) { - int error = may_create(dir, dentry); + int error = may_create(dir, dentry, false); if (error) return error; diff --git a/include/linux/fs.h b/include/linux/fs.h index 4efa435..d6e2330 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -82,6 +82,8 @@ typedef void (dax_iodone_t)(struct buffer_head *bh_map, int uptodate); #define MAY_CHDIR 0x00000040 /* called from RCU mode, don't block */ #define MAY_NOT_BLOCK 0x00000080 +#define MAY_CREATE_FILE 0x00000100 +#define MAY_CREATE_DIR 0x00000200 /* * flags in file.f_mode. Note that FMODE_READ and FMODE_WRITE must correspond -- 2.5.0 From agruenba@redhat.com Mon Nov 9 05:09:38 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 2AF817CBF for ; Mon, 9 Nov 2015 05:09:38 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id C8148AC003 for ; Mon, 9 Nov 2015 03:09:34 -0800 (PST) X-ASG-Debug-ID: 1447067373-04bdf03f04cdb60001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 6GpHuNEL4iULX0hh (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 09 Nov 2015 03:09:33 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 594D68E22D; Mon, 9 Nov 2015 11:09:33 +0000 (UTC) Received: from nux.redhat.com (vpn1-6-118.ams2.redhat.com [10.36.6.118]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA9B94CM028578; Mon, 9 Nov 2015 06:09:27 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v15 03/22] vfs: Add MAY_DELETE_SELF and MAY_DELETE_CHILD permission flags Date: Mon, 9 Nov 2015 12:08:44 +0100 X-ASG-Orig-Subj: [PATCH v15 03/22] vfs: Add MAY_DELETE_SELF and MAY_DELETE_CHILD permission flags Message-Id: <1447067343-31479-4-git-send-email-agruenba@redhat.com> In-Reply-To: <1447067343-31479-1-git-send-email-agruenba@redhat.com> References: <1447067343-31479-1-git-send-email-agruenba@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: 1447067373 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Normally, deleting a file requires MAY_WRITE access to the parent directory. With richacls, a file may be deleted with MAY_DELETE_CHILD access to the parent directory or with MAY_DELETE_SELF access to the file. To support that, pass the MAY_DELETE_CHILD mask flag to inode_permission() when checking for delete access inside a directory, and MAY_DELETE_SELF when checking for delete access to a file itelf. The MAY_DELETE_SELF permission overrides the sticky directory check. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/namei.c | 20 ++++++++++++-------- include/linux/fs.h | 2 ++ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 24a98f9..7f21554 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -453,9 +453,9 @@ static int sb_permission(struct super_block *sb, struct inode *inode, int mask) * this, letting us set arbitrary permissions for filesystem access without * changing the "normal" UIDs which are used for other things. * - * MAY_WRITE must be set in @mask whenever MAY_APPEND, MAY_CREATE_FILE, or - * MAY_CREATE_DIR are set. That way, file systems that don't support these - * permissions will check for MAY_WRITE instead. + * MAY_WRITE must be set in @mask whenever MAY_APPEND, MAY_CREATE_FILE, + * MAY_CREATE_DIR, or MAY_DELETE_CHILD are set. That way, file systems that + * don't support these permissions will check for MAY_WRITE instead. */ int inode_permission(struct inode *inode, int mask) { @@ -2564,14 +2564,18 @@ static int may_delete_or_replace(struct inode *dir, struct dentry *victim, BUG_ON(victim->d_parent->d_inode != dir); audit_inode_child(dir, victim, AUDIT_TYPE_CHILD_DELETE); - error = inode_permission(dir, mask); + error = inode_permission(dir, mask | MAY_WRITE | MAY_DELETE_CHILD); + if (!error && check_sticky(dir, inode)) + error = -EPERM; + if (error && IS_RICHACL(inode) && + inode_permission(inode, MAY_DELETE_SELF) == 0 && + inode_permission(dir, mask) == 0) + error = 0; if (error) return error; if (IS_APPEND(dir)) return -EPERM; - - if (check_sticky(dir, inode) || IS_APPEND(inode) || - IS_IMMUTABLE(inode) || IS_SWAPFILE(inode)) + if (IS_APPEND(inode) || IS_IMMUTABLE(inode) || IS_SWAPFILE(inode)) return -EPERM; if (isdir) { if (!d_is_dir(victim)) @@ -2589,7 +2593,7 @@ static int may_delete_or_replace(struct inode *dir, struct dentry *victim, static int may_delete(struct inode *dir, struct dentry *victim, bool isdir) { - return may_delete_or_replace(dir, victim, isdir, MAY_WRITE | MAY_EXEC); + return may_delete_or_replace(dir, victim, isdir, MAY_EXEC); } static int may_replace(struct inode *dir, struct dentry *victim, bool isdir) diff --git a/include/linux/fs.h b/include/linux/fs.h index d6e2330..402acd7 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -84,6 +84,8 @@ typedef void (dax_iodone_t)(struct buffer_head *bh_map, int uptodate); #define MAY_NOT_BLOCK 0x00000080 #define MAY_CREATE_FILE 0x00000100 #define MAY_CREATE_DIR 0x00000200 +#define MAY_DELETE_CHILD 0x00000400 +#define MAY_DELETE_SELF 0x00000800 /* * flags in file.f_mode. Note that FMODE_READ and FMODE_WRITE must correspond -- 2.5.0 From agruenba@redhat.com Mon Nov 9 05:09:41 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 7E5597F5F for ; Mon, 9 Nov 2015 05:09:41 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 604CD8F804B for ; Mon, 9 Nov 2015 03:09:41 -0800 (PST) X-ASG-Debug-ID: 1447067380-04bdf03f05cdb70001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id XXqkvCcGkBRWRNOU (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 09 Nov 2015 03:09:40 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 2BDC4C0B60EA; Mon, 9 Nov 2015 11:09:40 +0000 (UTC) Received: from nux.redhat.com (vpn1-6-118.ams2.redhat.com [10.36.6.118]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA9B94CN028578; Mon, 9 Nov 2015 06:09:33 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v15 04/22] vfs: Make the inode passed to inode_change_ok non-const Date: Mon, 9 Nov 2015 12:08:45 +0100 X-ASG-Orig-Subj: [PATCH v15 04/22] vfs: Make the inode passed to inode_change_ok non-const Message-Id: <1447067343-31479-5-git-send-email-agruenba@redhat.com> In-Reply-To: <1447067343-31479-1-git-send-email-agruenba@redhat.com> References: <1447067343-31479-1-git-send-email-agruenba@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: 1447067380 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 We will need to call iop->permission and iop->get_acl from inode_change_ok() for additional permission checks, and both take a non-const inode. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields Reviewed-by: Andreas Dilger --- fs/attr.c | 2 +- include/linux/fs.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/attr.c b/fs/attr.c index 6530ced..328be71 100644 --- a/fs/attr.c +++ b/fs/attr.c @@ -28,7 +28,7 @@ * Should be called as the first thing in ->setattr implementations, * possibly after taking additional locks. */ -int inode_change_ok(const struct inode *inode, struct iattr *attr) +int inode_change_ok(struct inode *inode, struct iattr *attr) { unsigned int ia_valid = attr->ia_valid; diff --git a/include/linux/fs.h b/include/linux/fs.h index 402acd7..aab32c8 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2871,7 +2871,7 @@ extern int buffer_migrate_page(struct address_space *, #define buffer_migrate_page NULL #endif -extern int inode_change_ok(const struct inode *, struct iattr *); +extern int inode_change_ok(struct inode *, struct iattr *); extern int inode_newsize_ok(const struct inode *, loff_t offset); extern void setattr_copy(struct inode *inode, const struct iattr *attr); -- 2.5.0 From agruenba@redhat.com Mon Nov 9 05:09:49 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 6C77E7CBF for ; Mon, 9 Nov 2015 05:09:49 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id E1EE6AC007 for ; Mon, 9 Nov 2015 03:09:48 -0800 (PST) X-ASG-Debug-ID: 1447067387-04cb6c296dcc7c0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id Ykm2KRPj8xJDTRih (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 09 Nov 2015 03:09:47 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 067E096C2; Mon, 9 Nov 2015 11:09:47 +0000 (UTC) Received: from nux.redhat.com (vpn1-6-118.ams2.redhat.com [10.36.6.118]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA9B94CO028578; Mon, 9 Nov 2015 06:09:40 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v15 05/22] vfs: Add permission flags for setting file attributes Date: Mon, 9 Nov 2015 12:08:46 +0100 X-ASG-Orig-Subj: [PATCH v15 05/22] vfs: Add permission flags for setting file attributes Message-Id: <1447067343-31479-6-git-send-email-agruenba@redhat.com> In-Reply-To: <1447067343-31479-1-git-send-email-agruenba@redhat.com> References: <1447067343-31479-1-git-send-email-agruenba@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: 1447067387 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Richacls support permissions that allow to take ownership of a file, change the file permissions, and set the file timestamps. Support that by introducing new permission mask flags and by checking for those mask flags in inode_change_ok(). Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/attr.c | 79 +++++++++++++++++++++++++++++++++++++++++++++--------- include/linux/fs.h | 3 +++ 2 files changed, 70 insertions(+), 12 deletions(-) diff --git a/fs/attr.c b/fs/attr.c index 328be71..85483e0 100644 --- a/fs/attr.c +++ b/fs/attr.c @@ -17,6 +17,65 @@ #include /** + * inode_extended_permission - permissions beyond read/write/execute + * + * Check for permissions that only richacls can currently grant. + */ +static int inode_extended_permission(struct inode *inode, int mask) +{ + if (!IS_RICHACL(inode)) + return -EPERM; + return inode_permission(inode, mask); +} + +static bool inode_uid_change_ok(struct inode *inode, kuid_t ia_uid) +{ + if (uid_eq(current_fsuid(), inode->i_uid) && + uid_eq(ia_uid, inode->i_uid)) + return true; + if (uid_eq(current_fsuid(), ia_uid) && + inode_extended_permission(inode, MAY_TAKE_OWNERSHIP) == 0) + return true; + if (capable_wrt_inode_uidgid(inode, CAP_CHOWN)) + return true; + return false; +} + +static bool inode_gid_change_ok(struct inode *inode, kgid_t ia_gid) +{ + int in_group = in_group_p(ia_gid); + if (uid_eq(current_fsuid(), inode->i_uid) && + (in_group || gid_eq(ia_gid, inode->i_gid))) + return true; + if (in_group && inode_extended_permission(inode, MAY_TAKE_OWNERSHIP) == 0) + return true; + if (capable_wrt_inode_uidgid(inode, CAP_CHOWN)) + return true; + return false; +} + +/** + * inode_owner_permitted_or_capable + * + * Check for permissions implicitly granted to the owner, like MAY_CHMOD or + * MAY_SET_TIMES. Equivalent to inode_owner_or_capable for file systems + * without support for those permissions. + */ +static bool inode_owner_permitted_or_capable(struct inode *inode, int mask) +{ + struct user_namespace *ns; + + if (uid_eq(current_fsuid(), inode->i_uid)) + return true; + if (inode_extended_permission(inode, mask) == 0) + return true; + ns = current_user_ns(); + if (ns_capable(ns, CAP_FOWNER) && kuid_has_mapping(ns, inode->i_uid)) + return true; + return false; +} + +/** * inode_change_ok - check if attribute changes to an inode are allowed * @inode: inode to check * @attr: attributes to change @@ -47,22 +106,18 @@ int inode_change_ok(struct inode *inode, struct iattr *attr) return 0; /* Make sure a caller can chown. */ - if ((ia_valid & ATTR_UID) && - (!uid_eq(current_fsuid(), inode->i_uid) || - !uid_eq(attr->ia_uid, inode->i_uid)) && - !capable_wrt_inode_uidgid(inode, CAP_CHOWN)) - return -EPERM; + if (ia_valid & ATTR_UID) + if (!inode_uid_change_ok(inode, attr->ia_uid)) + return -EPERM; /* Make sure caller can chgrp. */ - if ((ia_valid & ATTR_GID) && - (!uid_eq(current_fsuid(), inode->i_uid) || - (!in_group_p(attr->ia_gid) && !gid_eq(attr->ia_gid, inode->i_gid))) && - !capable_wrt_inode_uidgid(inode, CAP_CHOWN)) - return -EPERM; + if (ia_valid & ATTR_GID) + if (!inode_gid_change_ok(inode, attr->ia_gid)) + return -EPERM; /* Make sure a caller can chmod. */ if (ia_valid & ATTR_MODE) { - if (!inode_owner_or_capable(inode)) + if (!inode_owner_permitted_or_capable(inode, MAY_CHMOD)) return -EPERM; /* Also check the setgid bit! */ if (!in_group_p((ia_valid & ATTR_GID) ? attr->ia_gid : @@ -73,7 +128,7 @@ int inode_change_ok(struct inode *inode, struct iattr *attr) /* Check for setting the inode time. */ if (ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET | ATTR_TIMES_SET)) { - if (!inode_owner_or_capable(inode)) + if (!inode_owner_permitted_or_capable(inode, MAY_SET_TIMES)) return -EPERM; } diff --git a/include/linux/fs.h b/include/linux/fs.h index aab32c8..ba91a89 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -86,6 +86,9 @@ typedef void (dax_iodone_t)(struct buffer_head *bh_map, int uptodate); #define MAY_CREATE_DIR 0x00000200 #define MAY_DELETE_CHILD 0x00000400 #define MAY_DELETE_SELF 0x00000800 +#define MAY_TAKE_OWNERSHIP 0x00001000 +#define MAY_CHMOD 0x00002000 +#define MAY_SET_TIMES 0x00004000 /* * flags in file.f_mode. Note that FMODE_READ and FMODE_WRITE must correspond -- 2.5.0 From agruenba@redhat.com Mon Nov 9 05:09:56 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 78FEB7CBF for ; Mon, 9 Nov 2015 05:09:56 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 35CB38F804B for ; Mon, 9 Nov 2015 03:09:56 -0800 (PST) X-ASG-Debug-ID: 1447067394-04bdf03f04cdb80001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id I8YZcqTXlG782R4O (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 09 Nov 2015 03:09:54 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id DE11DC00354D; Mon, 9 Nov 2015 11:09:53 +0000 (UTC) Received: from nux.redhat.com (vpn1-6-118.ams2.redhat.com [10.36.6.118]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA9B94CP028578; Mon, 9 Nov 2015 06:09:47 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v15 06/22] richacl: In-memory representation and helper functions Date: Mon, 9 Nov 2015 12:08:47 +0100 X-ASG-Orig-Subj: [PATCH v15 06/22] richacl: In-memory representation and helper functions Message-Id: <1447067343-31479-7-git-send-email-agruenba@redhat.com> In-Reply-To: <1447067343-31479-1-git-send-email-agruenba@redhat.com> References: <1447067343-31479-1-git-send-email-agruenba@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: 1447067394 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 A richacl consists of an NFSv4 acl and an owner, group, and other mask. These three masks correspond to the owner, group, and other file permission bits, but they contain NFSv4 permissions instead of POSIX permissions. Each entry in the NFSv4 acl applies to the file owner (OWNER@), the owning group (GROUP@), everyone (EVERYONE@), or to a specific uid or gid. As in the standard POSIX file permission model, each process is the owner, group, or other file class. A richacl grants a requested access only if the NFSv4 acl in the richacl grants the access (according to the NFSv4 permission check algorithm), and the file mask that applies to the process includes the requested permissions. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/Makefile | 2 + fs/richacl_base.c | 67 ++++++++++++++++ include/linux/richacl.h | 179 +++++++++++++++++++++++++++++++++++++++++++ include/uapi/linux/Kbuild | 1 + include/uapi/linux/richacl.h | 99 ++++++++++++++++++++++++ 5 files changed, 348 insertions(+) create mode 100644 fs/richacl_base.c create mode 100644 include/linux/richacl.h create mode 100644 include/uapi/linux/richacl.h diff --git a/fs/Makefile b/fs/Makefile index f79cf40..fe3e9dd 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -48,6 +48,8 @@ obj-$(CONFIG_COREDUMP) += coredump.o obj-$(CONFIG_SYSCTL) += drop_caches.o obj-$(CONFIG_FHANDLE) += fhandle.o +obj-$(CONFIG_FS_RICHACL) += richacl.o +richacl-y := richacl_base.o obj-y += quota/ diff --git a/fs/richacl_base.c b/fs/richacl_base.c new file mode 100644 index 0000000..c3ec928 --- /dev/null +++ b/fs/richacl_base.c @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2006, 2010 Novell, Inc. + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * 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; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include +#include +#include +#include +#include + +MODULE_LICENSE("GPL"); + +/** + * richacl_alloc - allocate a richacl + * @count: number of entries + */ +struct richacl * +richacl_alloc(int count, gfp_t gfp) +{ + size_t size = sizeof(struct richacl) + count * sizeof(struct richace); + struct richacl *acl = kzalloc(size, gfp); + + if (acl) { + atomic_set(&acl->a_refcount, 1); + acl->a_count = count; + } + return acl; +} +EXPORT_SYMBOL_GPL(richacl_alloc); + +/** + * richacl_clone - create a copy of a richacl + */ +struct richacl * +richacl_clone(const struct richacl *acl, gfp_t gfp) +{ + int count = acl->a_count; + size_t size = sizeof(struct richacl) + count * sizeof(struct richace); + struct richacl *dup = kmalloc(size, gfp); + + if (dup) { + memcpy(dup, acl, size); + atomic_set(&dup->a_refcount, 1); + } + return dup; +} + +/** + * richace_copy - copy an acl entry + */ +void +richace_copy(struct richace *to, const struct richace *from) +{ + memcpy(to, from, sizeof(struct richace)); +} diff --git a/include/linux/richacl.h b/include/linux/richacl.h new file mode 100644 index 0000000..edb8480 --- /dev/null +++ b/include/linux/richacl.h @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2006, 2010 Novell, Inc. + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * 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; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#ifndef __RICHACL_H +#define __RICHACL_H + +#include + +struct richace { + unsigned short e_type; + unsigned short e_flags; + unsigned int e_mask; + union { + kuid_t uid; + kgid_t gid; + unsigned int special; + } e_id; +}; + +struct richacl { + atomic_t a_refcount; + unsigned int a_owner_mask; + unsigned int a_group_mask; + unsigned int a_other_mask; + unsigned short a_count; + unsigned short a_flags; + struct richace a_entries[0]; +}; + +#define richacl_for_each_entry(_ace, _acl) \ + for (_ace = (_acl)->a_entries; \ + _ace != (_acl)->a_entries + (_acl)->a_count; \ + _ace++) + +#define richacl_for_each_entry_reverse(_ace, _acl) \ + for (_ace = (_acl)->a_entries + (_acl)->a_count - 1; \ + _ace != (_acl)->a_entries - 1; \ + _ace--) + +/** + * richacl_get - grab another reference to a richacl handle + */ +static inline struct richacl * +richacl_get(struct richacl *acl) +{ + if (acl) + atomic_inc(&acl->a_refcount); + return acl; +} + +/** + * richacl_put - free a richacl handle + */ +static inline void +richacl_put(struct richacl *acl) +{ + if (acl && atomic_dec_and_test(&acl->a_refcount)) + kfree(acl); +} + +/** + * richace_is_owner - check if @ace is an OWNER@ entry + */ +static inline bool +richace_is_owner(const struct richace *ace) +{ + return (ace->e_flags & RICHACE_SPECIAL_WHO) && + ace->e_id.special == RICHACE_OWNER_SPECIAL_ID; +} + +/** + * richace_is_group - check if @ace is a GROUP@ entry + */ +static inline bool +richace_is_group(const struct richace *ace) +{ + return (ace->e_flags & RICHACE_SPECIAL_WHO) && + ace->e_id.special == RICHACE_GROUP_SPECIAL_ID; +} + +/** + * richace_is_everyone - check if @ace is an EVERYONE@ entry + */ +static inline bool +richace_is_everyone(const struct richace *ace) +{ + return (ace->e_flags & RICHACE_SPECIAL_WHO) && + ace->e_id.special == RICHACE_EVERYONE_SPECIAL_ID; +} + +/** + * richace_is_unix_user - check if @ace applies to a specific user + */ +static inline bool +richace_is_unix_user(const struct richace *ace) +{ + return !(ace->e_flags & RICHACE_SPECIAL_WHO) && + !(ace->e_flags & RICHACE_IDENTIFIER_GROUP); +} + +/** + * richace_is_unix_group - check if @ace applies to a specific group + */ +static inline bool +richace_is_unix_group(const struct richace *ace) +{ + return !(ace->e_flags & RICHACE_SPECIAL_WHO) && + (ace->e_flags & RICHACE_IDENTIFIER_GROUP); +} + +/** + * richace_is_inherit_only - check if @ace is for inheritance only + * + * ACEs with the %RICHACE_INHERIT_ONLY_ACE flag set have no effect during + * permission checking. + */ +static inline bool +richace_is_inherit_only(const struct richace *ace) +{ + return ace->e_flags & RICHACE_INHERIT_ONLY_ACE; +} + +/** + * richace_is_inheritable - check if @ace is inheritable + */ +static inline bool +richace_is_inheritable(const struct richace *ace) +{ + return ace->e_flags & (RICHACE_FILE_INHERIT_ACE | + RICHACE_DIRECTORY_INHERIT_ACE); +} + +/** + * richace_is_allow - check if @ace is an %ALLOW type entry + */ +static inline bool +richace_is_allow(const struct richace *ace) +{ + return ace->e_type == RICHACE_ACCESS_ALLOWED_ACE_TYPE; +} + +/** + * richace_is_deny - check if @ace is a %DENY type entry + */ +static inline bool +richace_is_deny(const struct richace *ace) +{ + return ace->e_type == RICHACE_ACCESS_DENIED_ACE_TYPE; +} + +/** + * richace_is_same_identifier - are both identifiers the same? + */ +static inline bool +richace_is_same_identifier(const struct richace *a, const struct richace *b) +{ + return !((a->e_flags ^ b->e_flags) & + (RICHACE_SPECIAL_WHO | RICHACE_IDENTIFIER_GROUP)) && + !memcmp(&a->e_id, &b->e_id, sizeof(a->e_id)); +} + +extern struct richacl *richacl_alloc(int, gfp_t); +extern struct richacl *richacl_clone(const struct richacl *, gfp_t); +extern void richace_copy(struct richace *, const struct richace *); + +#endif /* __RICHACL_H */ diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild index f7b2db4..8c82010 100644 --- a/include/uapi/linux/Kbuild +++ b/include/uapi/linux/Kbuild @@ -348,6 +348,7 @@ header-y += reboot.h header-y += reiserfs_fs.h header-y += reiserfs_xattr.h header-y += resource.h +header-y += richacl.h header-y += rfkill.h header-y += romfs_fs.h header-y += rose.h diff --git a/include/uapi/linux/richacl.h b/include/uapi/linux/richacl.h new file mode 100644 index 0000000..08856f8 --- /dev/null +++ b/include/uapi/linux/richacl.h @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2006, 2010 Novell, Inc. + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ + +#ifndef __UAPI_RICHACL_H +#define __UAPI_RICHACL_H + +/* a_flags values */ +#define RICHACL_WRITE_THROUGH 0x40 +#define RICHACL_MASKED 0x80 + +/* e_type values */ +#define RICHACE_ACCESS_ALLOWED_ACE_TYPE 0x0000 +#define RICHACE_ACCESS_DENIED_ACE_TYPE 0x0001 + +/* e_flags bitflags */ +#define RICHACE_FILE_INHERIT_ACE 0x0001 +#define RICHACE_DIRECTORY_INHERIT_ACE 0x0002 +#define RICHACE_NO_PROPAGATE_INHERIT_ACE 0x0004 +#define RICHACE_INHERIT_ONLY_ACE 0x0008 +#define RICHACE_IDENTIFIER_GROUP 0x0040 +#define RICHACE_SPECIAL_WHO 0x4000 + +/* e_mask bitflags */ +#define RICHACE_READ_DATA 0x00000001 +#define RICHACE_LIST_DIRECTORY 0x00000001 +#define RICHACE_WRITE_DATA 0x00000002 +#define RICHACE_ADD_FILE 0x00000002 +#define RICHACE_APPEND_DATA 0x00000004 +#define RICHACE_ADD_SUBDIRECTORY 0x00000004 +#define RICHACE_READ_NAMED_ATTRS 0x00000008 +#define RICHACE_WRITE_NAMED_ATTRS 0x00000010 +#define RICHACE_EXECUTE 0x00000020 +#define RICHACE_DELETE_CHILD 0x00000040 +#define RICHACE_READ_ATTRIBUTES 0x00000080 +#define RICHACE_WRITE_ATTRIBUTES 0x00000100 +#define RICHACE_WRITE_RETENTION 0x00000200 +#define RICHACE_WRITE_RETENTION_HOLD 0x00000400 +#define RICHACE_DELETE 0x00010000 +#define RICHACE_READ_ACL 0x00020000 +#define RICHACE_WRITE_ACL 0x00040000 +#define RICHACE_WRITE_OWNER 0x00080000 +#define RICHACE_SYNCHRONIZE 0x00100000 + +/* e_id values */ +#define RICHACE_OWNER_SPECIAL_ID 0 +#define RICHACE_GROUP_SPECIAL_ID 1 +#define RICHACE_EVERYONE_SPECIAL_ID 2 + +#define RICHACL_VALID_FLAGS ( \ + RICHACL_WRITE_THROUGH | \ + RICHACL_MASKED ) + +#define RICHACE_VALID_FLAGS ( \ + RICHACE_FILE_INHERIT_ACE | \ + RICHACE_DIRECTORY_INHERIT_ACE | \ + RICHACE_NO_PROPAGATE_INHERIT_ACE | \ + RICHACE_INHERIT_ONLY_ACE | \ + RICHACE_IDENTIFIER_GROUP | \ + RICHACE_SPECIAL_WHO ) + +#define RICHACE_INHERITANCE_FLAGS ( \ + RICHACE_FILE_INHERIT_ACE | \ + RICHACE_DIRECTORY_INHERIT_ACE | \ + RICHACE_NO_PROPAGATE_INHERIT_ACE | \ + RICHACE_INHERIT_ONLY_ACE ) + +/* Valid RICHACE_* flags for directories and non-directories */ +#define RICHACE_VALID_MASK ( \ + RICHACE_READ_DATA | RICHACE_LIST_DIRECTORY | \ + RICHACE_WRITE_DATA | RICHACE_ADD_FILE | \ + RICHACE_APPEND_DATA | RICHACE_ADD_SUBDIRECTORY | \ + RICHACE_READ_NAMED_ATTRS | \ + RICHACE_WRITE_NAMED_ATTRS | \ + RICHACE_EXECUTE | \ + RICHACE_DELETE_CHILD | \ + RICHACE_READ_ATTRIBUTES | \ + RICHACE_WRITE_ATTRIBUTES | \ + RICHACE_WRITE_RETENTION | \ + RICHACE_WRITE_RETENTION_HOLD | \ + RICHACE_DELETE | \ + RICHACE_READ_ACL | \ + RICHACE_WRITE_ACL | \ + RICHACE_WRITE_OWNER | \ + RICHACE_SYNCHRONIZE ) + +#endif /* __UAPI_RICHACL_H */ -- 2.5.0 From agruenba@redhat.com Mon Nov 9 05:10:03 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 189A67F6B for ; Mon, 9 Nov 2015 05:10:03 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 09464304039 for ; Mon, 9 Nov 2015 03:10:02 -0800 (PST) X-ASG-Debug-ID: 1447067401-04cb6c296dcc7d0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id DHIxjQT28KKOMdT3 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 09 Nov 2015 03:10:01 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id C64D0A452E; Mon, 9 Nov 2015 11:10:00 +0000 (UTC) Received: from nux.redhat.com (vpn1-6-118.ams2.redhat.com [10.36.6.118]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA9B94CQ028578; Mon, 9 Nov 2015 06:09:54 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v15 07/22] richacl: Permission mapping functions Date: Mon, 9 Nov 2015 12:08:48 +0100 X-ASG-Orig-Subj: [PATCH v15 07/22] richacl: Permission mapping functions Message-Id: <1447067343-31479-8-git-send-email-agruenba@redhat.com> In-Reply-To: <1447067343-31479-1-git-send-email-agruenba@redhat.com> References: <1447067343-31479-1-git-send-email-agruenba@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: 1447067401 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 We need to map from POSIX permissions to NFSv4 permissions when a chmod() is done, from NFSv4 permissions to POSIX permissions when an acl is set (which implicitly sets the file permission bits), and from the MAY_READ/MAY_WRITE/MAY_EXEC/MAY_APPEND flags to NFSv4 permissions when doing an access check in a richacl. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_base.c | 118 +++++++++++++++++++++++++++++++++++++++++++ include/linux/richacl.h | 3 ++ include/uapi/linux/richacl.h | 44 ++++++++++++++++ 3 files changed, 165 insertions(+) diff --git a/fs/richacl_base.c b/fs/richacl_base.c index c3ec928..a393001 100644 --- a/fs/richacl_base.c +++ b/fs/richacl_base.c @@ -65,3 +65,121 @@ richace_copy(struct richace *to, const struct richace *from) { memcpy(to, from, sizeof(struct richace)); } + +/* + * richacl_mask_to_mode - compute the file permission bits from mask + * @mask: %RICHACE_* permission mask + * + * Compute the file permission bits corresponding to a particular set of + * richacl permissions. + * + * See richacl_masks_to_mode(). + */ +static int +richacl_mask_to_mode(unsigned int mask) +{ + int mode = 0; + + if (mask & RICHACE_POSIX_MODE_READ) + mode |= S_IROTH; + if (mask & RICHACE_POSIX_MODE_WRITE) + mode |= S_IWOTH; + if (mask & RICHACE_POSIX_MODE_EXEC) + mode |= S_IXOTH; + + return mode; +} + +/** + * richacl_masks_to_mode - compute file permission bits from file masks + * + * When setting a richacl, we set the file permission bits to indicate maximum + * permissions: for example, we set the Write permission when a mask contains + * RICHACE_APPEND_DATA even if it does not also contain RICHACE_WRITE_DATA. + * + * Permissions which are not in RICHACE_POSIX_MODE_READ, + * RICHACE_POSIX_MODE_WRITE, or RICHACE_POSIX_MODE_EXEC cannot be represented + * in the file permission bits. Such permissions can still be effective, but + * not for new files or after a chmod(); they must be explicitly enabled in the + * richacl. + */ +int +richacl_masks_to_mode(const struct richacl *acl) +{ + return richacl_mask_to_mode(acl->a_owner_mask) << 6 | + richacl_mask_to_mode(acl->a_group_mask) << 3 | + richacl_mask_to_mode(acl->a_other_mask); +} +EXPORT_SYMBOL_GPL(richacl_masks_to_mode); + +/** + * richacl_mode_to_mask - compute a file mask from the lowest three mode bits + * @mode: mode to convert to richacl permissions + * + * When the file permission bits of a file are set with chmod(), this specifies + * the maximum permissions that processes will get. All permissions beyond + * that will be removed from the file masks, and become ineffective. + */ +unsigned int +richacl_mode_to_mask(umode_t mode) +{ + unsigned int mask = 0; + + if (mode & S_IROTH) + mask |= RICHACE_POSIX_MODE_READ; + if (mode & S_IWOTH) + mask |= RICHACE_POSIX_MODE_WRITE; + if (mode & S_IXOTH) + mask |= RICHACE_POSIX_MODE_EXEC; + + return mask; +} + +/** + * richacl_want_to_mask - convert the iop->permission want argument to a mask + * @want: @want argument of the permission inode operation + * + * When checking for append, @want is (MAY_WRITE | MAY_APPEND). + * + * Richacls use the iop->may_create and iop->may_delete hooks which are used + * for checking if creating and deleting files is allowed. These hooks do not + * use richacl_want_to_mask(), so we do not have to deal with mapping MAY_WRITE + * to RICHACE_ADD_FILE, RICHACE_ADD_SUBDIRECTORY, and RICHACE_DELETE_CHILD + * here. + */ +unsigned int +richacl_want_to_mask(unsigned int want) +{ + unsigned int mask = 0; + + if (want & MAY_READ) + mask |= RICHACE_READ_DATA; + if (want & MAY_DELETE_SELF) + mask |= RICHACE_DELETE; + if (want & MAY_TAKE_OWNERSHIP) + mask |= RICHACE_WRITE_OWNER; + if (want & MAY_CHMOD) + mask |= RICHACE_WRITE_ACL; + if (want & MAY_SET_TIMES) + mask |= RICHACE_WRITE_ATTRIBUTES; + if (want & MAY_EXEC) + mask |= RICHACE_EXECUTE; + /* + * differentiate MAY_WRITE from these request + */ + if (want & (MAY_APPEND | + MAY_CREATE_FILE | MAY_CREATE_DIR | + MAY_DELETE_CHILD)) { + if (want & MAY_APPEND) + mask |= RICHACE_APPEND_DATA; + if (want & MAY_CREATE_FILE) + mask |= RICHACE_ADD_FILE; + if (want & MAY_CREATE_DIR) + mask |= RICHACE_ADD_SUBDIRECTORY; + if (want & MAY_DELETE_CHILD) + mask |= RICHACE_DELETE_CHILD; + } else if (want & MAY_WRITE) + mask |= RICHACE_WRITE_DATA; + return mask; +} +EXPORT_SYMBOL_GPL(richacl_want_to_mask); diff --git a/include/linux/richacl.h b/include/linux/richacl.h index edb8480..9102ef0 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -175,5 +175,8 @@ richace_is_same_identifier(const struct richace *a, const struct richace *b) extern struct richacl *richacl_alloc(int, gfp_t); extern struct richacl *richacl_clone(const struct richacl *, gfp_t); extern void richace_copy(struct richace *, const struct richace *); +extern int richacl_masks_to_mode(const struct richacl *); +extern unsigned int richacl_mode_to_mask(umode_t); +extern unsigned int richacl_want_to_mask(unsigned int); #endif /* __RICHACL_H */ diff --git a/include/uapi/linux/richacl.h b/include/uapi/linux/richacl.h index 08856f8..1ed48ac 100644 --- a/include/uapi/linux/richacl.h +++ b/include/uapi/linux/richacl.h @@ -96,4 +96,48 @@ RICHACE_WRITE_OWNER | \ RICHACE_SYNCHRONIZE ) +/* + * The POSIX permissions are supersets of the following richacl permissions: + * + * - MAY_READ maps to READ_DATA or LIST_DIRECTORY, depending on the type + * of the file system object. + * + * - MAY_WRITE maps to WRITE_DATA or RICHACE_APPEND_DATA for files, and to + * ADD_FILE, RICHACE_ADD_SUBDIRECTORY, or RICHACE_DELETE_CHILD for directories. + * + * - MAY_EXECUTE maps to RICHACE_EXECUTE. + * + * (Some of these richacl permissions have the same bit values.) + */ +#define RICHACE_POSIX_MODE_READ ( \ + RICHACE_READ_DATA | \ + RICHACE_LIST_DIRECTORY) +#define RICHACE_POSIX_MODE_WRITE ( \ + RICHACE_WRITE_DATA | \ + RICHACE_ADD_FILE | \ + RICHACE_APPEND_DATA | \ + RICHACE_ADD_SUBDIRECTORY | \ + RICHACE_DELETE_CHILD) +#define RICHACE_POSIX_MODE_EXEC RICHACE_EXECUTE +#define RICHACE_POSIX_MODE_ALL ( \ + RICHACE_POSIX_MODE_READ | \ + RICHACE_POSIX_MODE_WRITE | \ + RICHACE_POSIX_MODE_EXEC) + +/* + * These permissions are always allowed no matter what the acl says. + */ +#define RICHACE_POSIX_ALWAYS_ALLOWED ( \ + RICHACE_SYNCHRONIZE | \ + RICHACE_READ_ATTRIBUTES | \ + RICHACE_READ_ACL) + +/* + * The owner is implicitly granted these permissions under POSIX. + */ +#define RICHACE_POSIX_OWNER_ALLOWED ( \ + RICHACE_WRITE_ATTRIBUTES | \ + RICHACE_WRITE_OWNER | \ + RICHACE_WRITE_ACL) + #endif /* __UAPI_RICHACL_H */ -- 2.5.0 From agruenba@redhat.com Mon Nov 9 05:10:09 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 D51427F5D for ; Mon, 9 Nov 2015 05:10:09 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id C4E89304032 for ; Mon, 9 Nov 2015 03:10:09 -0800 (PST) X-ASG-Debug-ID: 1447067407-04cbb02425d1590001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id viP4W74QwbCREIgO (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 09 Nov 2015 03:10:08 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id AE86E96A2; Mon, 9 Nov 2015 11:10:07 +0000 (UTC) Received: from nux.redhat.com (vpn1-6-118.ams2.redhat.com [10.36.6.118]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA9B94CR028578; Mon, 9 Nov 2015 06:10:01 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v15 08/22] richacl: Compute maximum file masks from an acl Date: Mon, 9 Nov 2015 12:08:49 +0100 X-ASG-Orig-Subj: [PATCH v15 08/22] richacl: Compute maximum file masks from an acl Message-Id: <1447067343-31479-9-git-send-email-agruenba@redhat.com> In-Reply-To: <1447067343-31479-1-git-send-email-agruenba@redhat.com> References: <1447067343-31479-1-git-send-email-agruenba@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: 1447067408 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Compute upper bound owner, group, and other file masks with as few permissions as possible without denying any permissions that the NFSv4 acl in a richacl grants. This algorithm is used when a file inherits an acl at create time and when an acl is set via a mechanism that does not provide file masks (such as setting an acl via nfsd). When user-space sets an acl via setxattr, the extended attribute already includes the file masks. Setting an acl also sets the file mode permission bits: they are determined by the file masks; see richacl_masks_to_mode(). Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_base.c | 157 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/richacl.h | 1 + 2 files changed, 158 insertions(+) diff --git a/fs/richacl_base.c b/fs/richacl_base.c index a393001..69b806c 100644 --- a/fs/richacl_base.c +++ b/fs/richacl_base.c @@ -183,3 +183,160 @@ richacl_want_to_mask(unsigned int want) return mask; } EXPORT_SYMBOL_GPL(richacl_want_to_mask); + +/* + * Note: functions like richacl_allowed_to_who(), richacl_group_class_allowed(), + * and richacl_compute_max_masks() iterate through the entire acl in reverse + * order as an optimization. + * + * In the standard algorithm, aces are considered in forward order. When a + * process matches an ace, the permissions in the ace are either allowed or + * denied depending on the ace type. Once a permission has been allowed or + * denied, it is no longer considered in further aces. + * + * By iterating through the acl in reverse order, we can compute the same + * result without having to keep track of which permissions have been allowed + * and denied already. + */ + +/** + * richacl_allowed_to_who - permissions allowed to a specific who value + * + * Compute the maximum mask values allowed to a specific who value, taking + * everyone@ aces into account. + */ +static unsigned int richacl_allowed_to_who(struct richacl *acl, + struct richace *who) +{ + struct richace *ace; + unsigned int allowed = 0; + + richacl_for_each_entry_reverse(ace, acl) { + if (richace_is_inherit_only(ace)) + continue; + if (richace_is_same_identifier(ace, who) || + richace_is_everyone(ace)) { + if (richace_is_allow(ace)) + allowed |= ace->e_mask; + else if (richace_is_deny(ace)) + allowed &= ~ace->e_mask; + } + } + return allowed; +} + +/** + * richacl_group_class_allowed - maximum permissions of the group class + * + * Compute the maximum mask values allowed to a process in the group class + * (i.e., a process which is not the owner but is in the owning group or + * matches a user or group acl entry). This includes permissions granted or + * denied by everyone@ aces. + * + * See richacl_compute_max_masks(). + */ +static unsigned int richacl_group_class_allowed(struct richacl *acl) +{ + struct richace *ace; + unsigned int everyone_allowed = 0, group_class_allowed = 0; + int had_group_ace = 0; + + richacl_for_each_entry_reverse(ace, acl) { + if (richace_is_inherit_only(ace) || + richace_is_owner(ace)) + continue; + + if (richace_is_everyone(ace)) { + if (richace_is_allow(ace)) + everyone_allowed |= ace->e_mask; + else if (richace_is_deny(ace)) + everyone_allowed &= ~ace->e_mask; + } else { + group_class_allowed |= + richacl_allowed_to_who(acl, ace); + + if (richace_is_group(ace)) + had_group_ace = 1; + } + } + /* + * If the acl doesn't contain any group@ aces, richacl_allowed_to_who() + * wasn't called for the owning group. We could make that call now, but + * we already know the result (everyone_allowed). + */ + if (!had_group_ace) + group_class_allowed |= everyone_allowed; + return group_class_allowed; +} + +/** + * richacl_compute_max_masks - compute upper bound masks + * + * Computes upper bound owner, group, and other masks so that none of the + * permissions allowed by the acl are disabled. + * + * We don't make assumptions about who the owner is so that the owner can + * change with no effect on the file masks or file mode permission bits; this + * means that we must assume that all entries can match the owner. + */ +void richacl_compute_max_masks(struct richacl *acl) +{ + unsigned int gmask = ~0; + struct richace *ace; + + /* + * @gmask contains all permissions which the group class is ever + * allowed. We use it to avoid adding permissions to the group mask + * from everyone@ allow aces which the group class is always denied + * through other aces. For example, the following acl would otherwise + * result in a group mask of rw: + * + * group@:w::deny + * everyone@:rw::allow + * + * Avoid computing @gmask for acls which do not include any group class + * deny aces: in such acls, the group class is never denied any + * permissions from everyone@ allow aces, and the group class cannot + * have fewer permissions than the other class. + */ + +restart: + acl->a_owner_mask = 0; + acl->a_group_mask = 0; + acl->a_other_mask = 0; + + richacl_for_each_entry_reverse(ace, acl) { + if (richace_is_inherit_only(ace)) + continue; + + if (richace_is_owner(ace)) { + if (richace_is_allow(ace)) + acl->a_owner_mask |= ace->e_mask; + else if (richace_is_deny(ace)) + acl->a_owner_mask &= ~ace->e_mask; + } else if (richace_is_everyone(ace)) { + if (richace_is_allow(ace)) { + acl->a_owner_mask |= ace->e_mask; + acl->a_group_mask |= ace->e_mask & gmask; + acl->a_other_mask |= ace->e_mask; + } else if (richace_is_deny(ace)) { + acl->a_owner_mask &= ~ace->e_mask; + acl->a_group_mask &= ~ace->e_mask; + acl->a_other_mask &= ~ace->e_mask; + } + } else { + if (richace_is_allow(ace)) { + acl->a_owner_mask |= ace->e_mask & gmask; + acl->a_group_mask |= ace->e_mask & gmask; + } else if (richace_is_deny(ace) && gmask == ~0) { + gmask = richacl_group_class_allowed(acl); + if (likely(gmask != ~0)) + /* should always be true */ + goto restart; + } + } + } + + acl->a_flags &= ~(RICHACL_WRITE_THROUGH | RICHACL_MASKED); +} +EXPORT_SYMBOL_GPL(richacl_compute_max_masks); diff --git a/include/linux/richacl.h b/include/linux/richacl.h index 9102ef0..3559b2c 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -178,5 +178,6 @@ extern void richace_copy(struct richace *, const struct richace *); extern int richacl_masks_to_mode(const struct richacl *); extern unsigned int richacl_mode_to_mask(umode_t); extern unsigned int richacl_want_to_mask(unsigned int); +extern void richacl_compute_max_masks(struct richacl *); #endif /* __RICHACL_H */ -- 2.5.0 From agruenba@redhat.com Mon Nov 9 05:10:17 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 3C3DB7F37 for ; Mon, 9 Nov 2015 05:10:17 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id C095CAC006 for ; Mon, 9 Nov 2015 03:10:16 -0800 (PST) X-ASG-Debug-ID: 1447067414-04cb6c296dcc7f0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id TXT7WCr7Tmg657Gt (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 09 Nov 2015 03:10:15 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 967DFC0AED5C; Mon, 9 Nov 2015 11:10:14 +0000 (UTC) Received: from nux.redhat.com (vpn1-6-118.ams2.redhat.com [10.36.6.118]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA9B94CS028578; Mon, 9 Nov 2015 06:10:08 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v15 09/22] richacl: Permission check algorithm Date: Mon, 9 Nov 2015 12:08:50 +0100 X-ASG-Orig-Subj: [PATCH v15 09/22] richacl: Permission check algorithm Message-Id: <1447067343-31479-10-git-send-email-agruenba@redhat.com> In-Reply-To: <1447067343-31479-1-git-send-email-agruenba@redhat.com> References: <1447067343-31479-1-git-send-email-agruenba@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: 1447067415 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 A richacl roughly grants a requested access if the NFSv4 acl in the richacl grants the requested permissions according to the NFSv4 permission check algorithm and the file mask that applies to the process includes the requested permissions. Signed-off-by: Andreas Gruenbacher Reviewed-by: "J. Bruce Fields" --- fs/Makefile | 2 +- fs/richacl_inode.c | 149 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/richacl.h | 3 + 3 files changed, 153 insertions(+), 1 deletion(-) create mode 100644 fs/richacl_inode.c diff --git a/fs/Makefile b/fs/Makefile index fe3e9dd..ec665fd 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -49,7 +49,7 @@ obj-$(CONFIG_SYSCTL) += drop_caches.o obj-$(CONFIG_FHANDLE) += fhandle.o obj-$(CONFIG_FS_RICHACL) += richacl.o -richacl-y := richacl_base.o +richacl-y := richacl_base.o richacl_inode.o obj-y += quota/ diff --git a/fs/richacl_inode.c b/fs/richacl_inode.c new file mode 100644 index 0000000..99b3c93 --- /dev/null +++ b/fs/richacl_inode.c @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2010 Novell, Inc. + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * 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; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include +#include +#include +#include +#include + +/** + * richacl_permission - richacl permission check algorithm + * @inode: inode to check + * @acl: rich acl of the inode + * @want: requested access (MAY_* flags) + * + * Checks if the current process is granted @mask flags in @acl. + */ +int +richacl_permission(struct inode *inode, const struct richacl *acl, + int want) +{ + const struct richace *ace; + unsigned int mask = richacl_want_to_mask(want); + unsigned int requested = mask, denied = 0; + int in_owning_group = in_group_p(inode->i_gid); + int in_owner_or_group_class = in_owning_group; + + /* + * A process is + * - in the owner file class if it owns the file, + * - in the group file class if it is in the file's owning group or + * it matches any of the user or group entries, and + * - in the other file class otherwise. + * The file class is only relevant for determining which file mask to + * apply, which only happens for masked acls. + */ + if (acl->a_flags & RICHACL_MASKED) { + if ((acl->a_flags & RICHACL_WRITE_THROUGH) && + uid_eq(current_fsuid(), inode->i_uid)) { + denied = requested & ~acl->a_owner_mask; + goto out; + } + } else { + /* + * When the acl is not masked, there is no need to determine if + * the process is in the group class and we can break out + * earlier of the loop below. + */ + in_owner_or_group_class = 1; + } + + /* + * Check if the acl grants the requested access and determine which + * file class the process is in. + */ + richacl_for_each_entry(ace, acl) { + unsigned int ace_mask = ace->e_mask; + + if (richace_is_inherit_only(ace)) + continue; + if (richace_is_owner(ace)) { + if (!uid_eq(current_fsuid(), inode->i_uid)) + continue; + goto entry_matches_owner; + } else if (richace_is_group(ace)) { + if (!in_owning_group) + continue; + } else if (richace_is_unix_user(ace)) { + if (!uid_eq(current_fsuid(), ace->e_id.uid)) + continue; + if (uid_eq(current_fsuid(), inode->i_uid)) + goto entry_matches_owner; + } else if (richace_is_unix_group(ace)) { + if (!in_group_p(ace->e_id.gid)) + continue; + } else + goto entry_matches_everyone; + + /* + * Apply the group file mask to entries other than owner@ and + * everyone@ or user entries matching the owner. This ensures + * that we grant the same permissions as the acl computed by + * richacl_apply_masks(). + * + * Without this restriction, the following richacl would grant + * rw access to processes which are both the owner and in the + * owning group, but not to other users in the owning group, + * which could not be represented without masks: + * + * owner:rw::mask + * group@:rw::allow + */ + if ((acl->a_flags & RICHACL_MASKED) && richace_is_allow(ace)) + ace_mask &= acl->a_group_mask; + +entry_matches_owner: + /* The process is in the owner or group file class. */ + in_owner_or_group_class = 1; + +entry_matches_everyone: + /* Check which mask flags the ACE allows or denies. */ + if (richace_is_deny(ace)) + denied |= ace_mask & mask; + mask &= ~ace_mask; + + /* + * Keep going until we know which file class + * the process is in. + */ + if (!mask && in_owner_or_group_class) + break; + } + denied |= mask; + + if (acl->a_flags & RICHACL_MASKED) { + /* + * The file class a process is in determines which file mask + * applies. Check if that file mask also grants the requested + * access. + */ + if (uid_eq(current_fsuid(), inode->i_uid)) + denied |= requested & ~acl->a_owner_mask; + else if (in_owner_or_group_class) + denied |= requested & ~acl->a_group_mask; + else { + if (acl->a_flags & RICHACL_WRITE_THROUGH) + denied = requested & ~acl->a_other_mask; + else + denied |= requested & ~acl->a_other_mask; + } + } + +out: + return denied ? -EACCES : 0; +} +EXPORT_SYMBOL_GPL(richacl_permission); diff --git a/include/linux/richacl.h b/include/linux/richacl.h index 3559b2c..1d9f5f7 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -180,4 +180,7 @@ extern unsigned int richacl_mode_to_mask(umode_t); extern unsigned int richacl_want_to_mask(unsigned int); extern void richacl_compute_max_masks(struct richacl *); +/* richacl_inode.c */ +extern int richacl_permission(struct inode *, const struct richacl *, int); + #endif /* __RICHACL_H */ -- 2.5.0 From agruenba@redhat.com Mon Nov 9 05:10:23 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 A99017F37 for ; Mon, 9 Nov 2015 05:10:23 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 8BCAF304039 for ; Mon, 9 Nov 2015 03:10:23 -0800 (PST) X-ASG-Debug-ID: 1447067422-04cb6c296bcc7f0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id Uy1CTWFBTQ8H9vjQ (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 09 Nov 2015 03:10:22 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 0C52F8E374; Mon, 9 Nov 2015 11:10:22 +0000 (UTC) Received: from nux.redhat.com (vpn1-6-118.ams2.redhat.com [10.36.6.118]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA9B94CT028578; Mon, 9 Nov 2015 06:10:15 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v15 10/22] posix_acl: Unexport acl_by_type and make it static Date: Mon, 9 Nov 2015 12:08:51 +0100 X-ASG-Orig-Subj: [PATCH v15 10/22] posix_acl: Unexport acl_by_type and make it static Message-Id: <1447067343-31479-11-git-send-email-agruenba@redhat.com> In-Reply-To: <1447067343-31479-1-git-send-email-agruenba@redhat.com> References: <1447067343-31479-1-git-send-email-agruenba@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: 1447067422 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 acl_by_type(inode, type) returns a pointer to either inode->i_acl or inode->i_default_acl depending on type. This is useful in fs/posix_acl.c, but should never have been visible outside that file. Signed-off-by: Andreas Gruenbacher --- fs/posix_acl.c | 3 +-- include/linux/posix_acl.h | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/fs/posix_acl.c b/fs/posix_acl.c index 4fb17de..aacfb58 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c @@ -21,7 +21,7 @@ #include #include -struct posix_acl **acl_by_type(struct inode *inode, int type) +static struct posix_acl **acl_by_type(struct inode *inode, int type) { switch (type) { case ACL_TYPE_ACCESS: @@ -32,7 +32,6 @@ struct posix_acl **acl_by_type(struct inode *inode, int type) BUG(); } } -EXPORT_SYMBOL(acl_by_type); struct posix_acl *get_cached_acl(struct inode *inode, int type) { diff --git a/include/linux/posix_acl.h b/include/linux/posix_acl.h index 3e96a6a..5b5a80c 100644 --- a/include/linux/posix_acl.h +++ b/include/linux/posix_acl.h @@ -99,7 +99,6 @@ extern int posix_acl_create(struct inode *, umode_t *, struct posix_acl **, extern int simple_set_acl(struct inode *, struct posix_acl *, int); extern int simple_acl_create(struct inode *, struct inode *); -struct posix_acl **acl_by_type(struct inode *inode, int type); struct posix_acl *get_cached_acl(struct inode *inode, int type); struct posix_acl *get_cached_acl_rcu(struct inode *inode, int type); void set_cached_acl(struct inode *inode, int type, struct posix_acl *acl); -- 2.5.0 From agruenba@redhat.com Mon Nov 9 05:10:31 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 5B0D57F37 for ; Mon, 9 Nov 2015 05:10:31 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id D0AB9AC004 for ; Mon, 9 Nov 2015 03:10:30 -0800 (PST) X-ASG-Debug-ID: 1447067428-04cbb02423d15b0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id ZJhSUmWMAmmluYKl (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 09 Nov 2015 03:10:28 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 44AF38A4BC; Mon, 9 Nov 2015 11:10:28 +0000 (UTC) Received: from nux.redhat.com (vpn1-6-118.ams2.redhat.com [10.36.6.118]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA9B94CU028578; Mon, 9 Nov 2015 06:10:22 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v15 11/22] vfs: Cache base_acl objects in inodes Date: Mon, 9 Nov 2015 12:08:52 +0100 X-ASG-Orig-Subj: [PATCH v15 11/22] vfs: Cache base_acl objects in inodes Message-Id: <1447067343-31479-12-git-send-email-agruenba@redhat.com> In-Reply-To: <1447067343-31479-1-git-send-email-agruenba@redhat.com> References: <1447067343-31479-1-git-send-email-agruenba@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: 1447067428 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 POSIX ACLs and richacls are both objects allocated by kmalloc() with a reference count which are freed by kfree_rcu(). An inode can either cache an access and a default POSIX ACL, or a richacl (richacls do not have default acls). To allow an inode to cache either of the two kinds of acls, introduce a new base_acl type and convert i_acl and i_default_acl to that type. In most cases, the vfs then doesn't care which kind of acl an inode caches (if any). Signed-off-by: Andreas Gruenbacher Reviewed-by: Andreas Dilger --- drivers/staging/lustre/lustre/llite/llite_lib.c | 2 +- fs/f2fs/acl.c | 4 +-- fs/inode.c | 4 +-- fs/jffs2/acl.c | 10 ++++-- fs/posix_acl.c | 41 +++++++++++++------------ fs/richacl_base.c | 4 +-- include/linux/fs.h | 34 ++++++++++++++++++-- include/linux/posix_acl.h | 12 +++----- include/linux/richacl.h | 9 +++--- 9 files changed, 75 insertions(+), 45 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c index b4ed6c8..46912c2 100644 --- a/drivers/staging/lustre/lustre/llite/llite_lib.c +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c @@ -1118,7 +1118,7 @@ void ll_clear_inode(struct inode *inode) } #ifdef CONFIG_FS_POSIX_ACL else if (lli->lli_posix_acl) { - LASSERT(atomic_read(&lli->lli_posix_acl->a_refcount) == 1); + LASSERT(base_acl_refcount(&lli->lli_posix_acl->a_base) == 1); LASSERT(lli->lli_remote_perms == NULL); posix_acl_release(lli->lli_posix_acl); lli->lli_posix_acl = NULL; diff --git a/fs/f2fs/acl.c b/fs/f2fs/acl.c index c8f25f7..9646197 100644 --- a/fs/f2fs/acl.c +++ b/fs/f2fs/acl.c @@ -270,7 +270,7 @@ static struct posix_acl *f2fs_acl_clone(const struct posix_acl *acl, sizeof(struct posix_acl_entry); clone = kmemdup(acl, size, flags); if (clone) - atomic_set(&clone->a_refcount, 1); + base_acl_init(&clone->a_base); } return clone; } @@ -282,7 +282,7 @@ static int f2fs_acl_create_masq(struct posix_acl *acl, umode_t *mode_p) umode_t mode = *mode_p; int not_equiv = 0; - /* assert(atomic_read(acl->a_refcount) == 1); */ + /* assert(base_acl_refcount(&acl->a_base) == 1); */ FOREACH_ACL_ENTRY(pa, acl, pe) { switch(pa->e_tag) { diff --git a/fs/inode.c b/fs/inode.c index 78a17b8..5c46ae5 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -233,9 +233,9 @@ void __destroy_inode(struct inode *inode) #ifdef CONFIG_FS_POSIX_ACL if (inode->i_acl && inode->i_acl != ACL_NOT_CACHED) - posix_acl_release(inode->i_acl); + base_acl_put(inode->i_acl); if (inode->i_default_acl && inode->i_default_acl != ACL_NOT_CACHED) - posix_acl_release(inode->i_default_acl); + base_acl_put(inode->i_default_acl); #endif this_cpu_dec(nr_inodes); } diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c index 2f7a3c0..569cb1b 100644 --- a/fs/jffs2/acl.c +++ b/fs/jffs2/acl.c @@ -294,13 +294,19 @@ int jffs2_init_acl_post(struct inode *inode) int rc; if (inode->i_default_acl) { - rc = __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_DEFAULT, inode->i_default_acl); + struct posix_acl *default_acl = container_of( + inode->i_default_acl, struct posix_acl, a_base); + + rc = __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_DEFAULT, default_acl); if (rc) return rc; } if (inode->i_acl) { - rc = __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_ACCESS, inode->i_acl); + struct posix_acl *acl = container_of( + inode->i_acl, struct posix_acl, a_base); + + rc = __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_ACCESS, acl); if (rc) return rc; } diff --git a/fs/posix_acl.c b/fs/posix_acl.c index aacfb58..4573315 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c @@ -21,7 +21,7 @@ #include #include -static struct posix_acl **acl_by_type(struct inode *inode, int type) +static struct base_acl **acl_by_type(struct inode *inode, int type) { switch (type) { case ACL_TYPE_ACCESS: @@ -35,63 +35,64 @@ static struct posix_acl **acl_by_type(struct inode *inode, int type) struct posix_acl *get_cached_acl(struct inode *inode, int type) { - struct posix_acl **p = acl_by_type(inode, type); - struct posix_acl *acl = ACCESS_ONCE(*p); + struct base_acl **p = acl_by_type(inode, type); + struct base_acl *acl = ACCESS_ONCE(*p); if (acl) { spin_lock(&inode->i_lock); acl = *p; if (acl != ACL_NOT_CACHED) - acl = posix_acl_dup(acl); + base_acl_get(acl); spin_unlock(&inode->i_lock); } - return acl; + return container_of(acl, struct posix_acl, a_base); } EXPORT_SYMBOL(get_cached_acl); struct posix_acl *get_cached_acl_rcu(struct inode *inode, int type) { - return rcu_dereference(*acl_by_type(inode, type)); + struct base_acl *acl = rcu_dereference(*acl_by_type(inode, type)); + return container_of(acl, struct posix_acl, a_base); } EXPORT_SYMBOL(get_cached_acl_rcu); void set_cached_acl(struct inode *inode, int type, struct posix_acl *acl) { - struct posix_acl **p = acl_by_type(inode, type); - struct posix_acl *old; + struct base_acl **p = acl_by_type(inode, type); + struct base_acl *old; spin_lock(&inode->i_lock); old = *p; - rcu_assign_pointer(*p, posix_acl_dup(acl)); + rcu_assign_pointer(*p, &posix_acl_dup(acl)->a_base); spin_unlock(&inode->i_lock); if (old != ACL_NOT_CACHED) - posix_acl_release(old); + base_acl_put(old); } EXPORT_SYMBOL(set_cached_acl); void forget_cached_acl(struct inode *inode, int type) { - struct posix_acl **p = acl_by_type(inode, type); - struct posix_acl *old; + struct base_acl **p = acl_by_type(inode, type); + struct base_acl *old; spin_lock(&inode->i_lock); old = *p; *p = ACL_NOT_CACHED; spin_unlock(&inode->i_lock); if (old != ACL_NOT_CACHED) - posix_acl_release(old); + base_acl_put(old); } EXPORT_SYMBOL(forget_cached_acl); void forget_all_cached_acls(struct inode *inode) { - struct posix_acl *old_access, *old_default; + struct base_acl *old_access, *old_default; spin_lock(&inode->i_lock); old_access = inode->i_acl; old_default = inode->i_default_acl; inode->i_acl = inode->i_default_acl = ACL_NOT_CACHED; spin_unlock(&inode->i_lock); if (old_access != ACL_NOT_CACHED) - posix_acl_release(old_access); + base_acl_put(old_access); if (old_default != ACL_NOT_CACHED) - posix_acl_release(old_default); + base_acl_put(old_default); } EXPORT_SYMBOL(forget_all_cached_acls); @@ -128,7 +129,7 @@ EXPORT_SYMBOL(get_acl); void posix_acl_init(struct posix_acl *acl, int count) { - atomic_set(&acl->a_refcount, 1); + base_acl_init(&acl->a_base); acl->a_count = count; } EXPORT_SYMBOL(posix_acl_init); @@ -161,7 +162,7 @@ posix_acl_clone(const struct posix_acl *acl, gfp_t flags) sizeof(struct posix_acl_entry); clone = kmemdup(acl, size, flags); if (clone) - atomic_set(&clone->a_refcount, 1); + base_acl_init(&clone->a_base); } return clone; } @@ -383,7 +384,7 @@ static int posix_acl_create_masq(struct posix_acl *acl, umode_t *mode_p) umode_t mode = *mode_p; int not_equiv = 0; - /* assert(atomic_read(acl->a_refcount) == 1); */ + /* assert(base_acl_refcount(&acl->a_base) == 1); */ FOREACH_ACL_ENTRY(pa, acl, pe) { switch(pa->e_tag) { @@ -438,7 +439,7 @@ static int __posix_acl_chmod_masq(struct posix_acl *acl, umode_t mode) struct posix_acl_entry *group_obj = NULL, *mask_obj = NULL; struct posix_acl_entry *pa, *pe; - /* assert(atomic_read(acl->a_refcount) == 1); */ + /* assert(base_acl_refcount(&acl->a_base) == 1); */ FOREACH_ACL_ENTRY(pa, acl, pe) { switch(pa->e_tag) { diff --git a/fs/richacl_base.c b/fs/richacl_base.c index 69b806c..5826842 100644 --- a/fs/richacl_base.c +++ b/fs/richacl_base.c @@ -33,7 +33,7 @@ richacl_alloc(int count, gfp_t gfp) struct richacl *acl = kzalloc(size, gfp); if (acl) { - atomic_set(&acl->a_refcount, 1); + base_acl_init(&acl->a_base); acl->a_count = count; } return acl; @@ -52,7 +52,7 @@ richacl_clone(const struct richacl *acl, gfp_t gfp) if (dup) { memcpy(dup, acl, size); - atomic_set(&dup->a_refcount, 1); + base_acl_init(&dup->a_base); } return dup; } diff --git a/include/linux/fs.h b/include/linux/fs.h index ba91a89..2fd840e 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -576,6 +576,12 @@ static inline void mapping_allow_writable(struct address_space *mapping) #define i_size_ordered_init(inode) do { } while (0) #endif +struct base_acl { + union { + atomic_t ba_refcount; + struct rcu_head ba_rcu; + }; +}; struct posix_acl; #define ACL_NOT_CACHED ((void *)(-1)) @@ -595,9 +601,9 @@ struct inode { kgid_t i_gid; unsigned int i_flags; -#ifdef CONFIG_FS_POSIX_ACL - struct posix_acl *i_acl; - struct posix_acl *i_default_acl; +#if defined(CONFIG_FS_POSIX_ACL) + struct base_acl *i_acl; + struct base_acl *i_default_acl; #endif const struct inode_operations *i_op; @@ -3059,4 +3065,26 @@ static inline bool dir_relax(struct inode *inode) extern bool path_noexec(const struct path *path); +static inline void base_acl_get(struct base_acl *acl) +{ + if (acl) + atomic_inc(&acl->ba_refcount); +} + +static inline void base_acl_put(struct base_acl *acl) +{ + if (acl && atomic_dec_and_test(&acl->ba_refcount)) + kfree_rcu(acl, ba_rcu); +} + +static inline void base_acl_init(struct base_acl *acl) +{ + atomic_set(&acl->ba_refcount, 1); +} + +static inline int base_acl_refcount(struct base_acl *acl) +{ + return atomic_read(&acl->ba_refcount); +} + #endif /* _LINUX_FS_H */ diff --git a/include/linux/posix_acl.h b/include/linux/posix_acl.h index 5b5a80c..cef5428 100644 --- a/include/linux/posix_acl.h +++ b/include/linux/posix_acl.h @@ -43,10 +43,7 @@ struct posix_acl_entry { }; struct posix_acl { - union { - atomic_t a_refcount; - struct rcu_head a_rcu; - }; + struct base_acl a_base; /* must be first, see posix_acl_release() */ unsigned int a_count; struct posix_acl_entry a_entries[0]; }; @@ -61,8 +58,7 @@ struct posix_acl { static inline struct posix_acl * posix_acl_dup(struct posix_acl *acl) { - if (acl) - atomic_inc(&acl->a_refcount); + base_acl_get(&acl->a_base); return acl; } @@ -72,8 +68,8 @@ posix_acl_dup(struct posix_acl *acl) static inline void posix_acl_release(struct posix_acl *acl) { - if (acl && atomic_dec_and_test(&acl->a_refcount)) - kfree_rcu(acl, a_rcu); + BUILD_BUG_ON(offsetof(struct posix_acl, a_base) != 0); + base_acl_put(&acl->a_base); } diff --git a/include/linux/richacl.h b/include/linux/richacl.h index 1d9f5f7..7628fad 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -31,7 +31,7 @@ struct richace { }; struct richacl { - atomic_t a_refcount; + struct base_acl a_base; /* must be first, see richacl_put() */ unsigned int a_owner_mask; unsigned int a_group_mask; unsigned int a_other_mask; @@ -56,8 +56,7 @@ struct richacl { static inline struct richacl * richacl_get(struct richacl *acl) { - if (acl) - atomic_inc(&acl->a_refcount); + base_acl_get(&acl->a_base); return acl; } @@ -67,8 +66,8 @@ richacl_get(struct richacl *acl) static inline void richacl_put(struct richacl *acl) { - if (acl && atomic_dec_and_test(&acl->a_refcount)) - kfree(acl); + BUILD_BUG_ON(offsetof(struct richacl, a_base) != 0); + base_acl_put(&acl->a_base); } /** -- 2.5.0 From agruenba@redhat.com Mon Nov 9 05:10:36 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 C2F357F3F for ; Mon, 9 Nov 2015 05:10:36 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id A47988F8049 for ; Mon, 9 Nov 2015 03:10:36 -0800 (PST) X-ASG-Debug-ID: 1447067435-04cb6c296bcc800001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id nAvlo8EbqORjAGJ7 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 09 Nov 2015 03:10:35 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 2909519EF33; Mon, 9 Nov 2015 11:10:35 +0000 (UTC) Received: from nux.redhat.com (vpn1-6-118.ams2.redhat.com [10.36.6.118]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA9B94CV028578; Mon, 9 Nov 2015 06:10:28 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v15 12/22] vfs: Add get_richacl and set_richacl inode operations Date: Mon, 9 Nov 2015 12:08:53 +0100 X-ASG-Orig-Subj: [PATCH v15 12/22] vfs: Add get_richacl and set_richacl inode operations Message-Id: <1447067343-31479-13-git-send-email-agruenba@redhat.com> In-Reply-To: <1447067343-31479-1-git-send-email-agruenba@redhat.com> References: <1447067343-31479-1-git-send-email-agruenba@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: 1447067435 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 These operations are similar to the get_acl and set_acl operations for POSIX ACLs. The distinction between access and default ACLs doesn't exist for richacls. Signed-off-by: Andreas Gruenbacher --- include/linux/fs.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/fs.h b/include/linux/fs.h index 2fd840e..3c36c72 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1662,6 +1662,7 @@ struct inode_operations { const char * (*follow_link) (struct dentry *, void **); int (*permission) (struct inode *, int); struct posix_acl * (*get_acl)(struct inode *, int); + struct richacl * (*get_richacl)(struct inode *); int (*readlink) (struct dentry *, char __user *,int); void (*put_link) (struct inode *, void *); @@ -1691,6 +1692,7 @@ struct inode_operations { umode_t create_mode, int *opened); int (*tmpfile) (struct inode *, struct dentry *, umode_t); int (*set_acl)(struct inode *, struct posix_acl *, int); + int (*set_richacl)(struct inode *, struct richacl *); /* WARNING: probably going away soon, do not use! */ } ____cacheline_aligned; -- 2.5.0 From agruenba@redhat.com Mon Nov 9 05:10:44 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 046DB7F3F for ; Mon, 9 Nov 2015 05:10:44 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id C99E0304039 for ; Mon, 9 Nov 2015 03:10:43 -0800 (PST) X-ASG-Debug-ID: 1447067442-04bdf03f03cdbe0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id Xehx38ncMnmVfRs1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 09 Nov 2015 03:10:42 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 0EAFBA2C00; Mon, 9 Nov 2015 11:10:42 +0000 (UTC) Received: from nux.redhat.com (vpn1-6-118.ams2.redhat.com [10.36.6.118]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA9B94CW028578; Mon, 9 Nov 2015 06:10:35 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v15 13/22] vfs: Cache richacl in struct inode Date: Mon, 9 Nov 2015 12:08:54 +0100 X-ASG-Orig-Subj: [PATCH v15 13/22] vfs: Cache richacl in struct inode Message-Id: <1447067343-31479-14-git-send-email-agruenba@redhat.com> In-Reply-To: <1447067343-31479-1-git-send-email-agruenba@redhat.com> References: <1447067343-31479-1-git-send-email-agruenba@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: 1447067442 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Cache richacls in struct inode so that this doesn't have to be done individually in each filesystem. This is similar to POSIX ACLs. Signed-off-by: Andreas Gruenbacher --- fs/inode.c | 11 +++++-- fs/posix_acl.c | 2 +- fs/richacl_inode.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/fs.h | 5 +++- include/linux/richacl.h | 6 ++++ 5 files changed, 96 insertions(+), 5 deletions(-) diff --git a/fs/inode.c b/fs/inode.c index 5c46ae5..5e8710c 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -174,8 +174,11 @@ int inode_init_always(struct super_block *sb, struct inode *inode) inode->i_private = NULL; inode->i_mapping = mapping; INIT_HLIST_HEAD(&inode->i_dentry); /* buggered by rcu freeing */ -#ifdef CONFIG_FS_POSIX_ACL - inode->i_acl = inode->i_default_acl = ACL_NOT_CACHED; +#if defined(CONFIG_FS_POSIX_ACL) || defined(CONFIG_FS_RICHACL) + inode->i_acl = ACL_NOT_CACHED; +# if defined(CONFIG_FS_POSIX_ACL) + inode->i_default_acl = ACL_NOT_CACHED; +# endif #endif #ifdef CONFIG_FSNOTIFY @@ -231,11 +234,13 @@ void __destroy_inode(struct inode *inode) atomic_long_dec(&inode->i_sb->s_remove_count); } -#ifdef CONFIG_FS_POSIX_ACL +#if defined(CONFIG_FS_POSIX_ACL) || defined(CONFIG_FS_RICHACL) if (inode->i_acl && inode->i_acl != ACL_NOT_CACHED) base_acl_put(inode->i_acl); +# if defined(CONFIG_FS_POSIX_ACL) if (inode->i_default_acl && inode->i_default_acl != ACL_NOT_CACHED) base_acl_put(inode->i_default_acl); +# endif #endif this_cpu_dec(nr_inodes); } diff --git a/fs/posix_acl.c b/fs/posix_acl.c index 4573315..b0eb1dc 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c @@ -37,7 +37,7 @@ struct posix_acl *get_cached_acl(struct inode *inode, int type) { struct base_acl **p = acl_by_type(inode, type); struct base_acl *acl = ACCESS_ONCE(*p); - if (acl) { + if (acl && IS_POSIXACL(inode)) { spin_lock(&inode->i_lock); acl = *p; if (acl != ACL_NOT_CACHED) diff --git a/fs/richacl_inode.c b/fs/richacl_inode.c index 99b3c93..52c1595 100644 --- a/fs/richacl_inode.c +++ b/fs/richacl_inode.c @@ -20,6 +20,83 @@ #include #include +struct richacl *get_cached_richacl(struct inode *inode) +{ + struct base_acl *acl; + + acl = ACCESS_ONCE(inode->i_acl); + if (acl && IS_RICHACL(inode)) { + spin_lock(&inode->i_lock); + acl = inode->i_acl; + if (acl != ACL_NOT_CACHED) + base_acl_get(acl); + spin_unlock(&inode->i_lock); + } + return container_of(acl, struct richacl, a_base); +} +EXPORT_SYMBOL_GPL(get_cached_richacl); + +struct richacl *get_cached_richacl_rcu(struct inode *inode) +{ + struct base_acl *acl = rcu_dereference(inode->i_acl); + + return container_of(acl, struct richacl, a_base); +} +EXPORT_SYMBOL_GPL(get_cached_richacl_rcu); + +void set_cached_richacl(struct inode *inode, struct richacl *acl) +{ + struct base_acl *old = NULL; + + spin_lock(&inode->i_lock); + old = inode->i_acl; + rcu_assign_pointer(inode->i_acl, &richacl_get(acl)->a_base); + spin_unlock(&inode->i_lock); + if (old != ACL_NOT_CACHED) + base_acl_put(old); +} +EXPORT_SYMBOL_GPL(set_cached_richacl); + +void forget_cached_richacl(struct inode *inode) +{ + struct base_acl *old = NULL; + + spin_lock(&inode->i_lock); + old = inode->i_acl; + inode->i_acl = ACL_NOT_CACHED; + spin_unlock(&inode->i_lock); + if (old != ACL_NOT_CACHED) + base_acl_put(old); +} +EXPORT_SYMBOL_GPL(forget_cached_richacl); + +struct richacl *get_richacl(struct inode *inode) +{ + struct richacl *acl; + + acl = get_cached_richacl(inode); + if (acl != ACL_NOT_CACHED) + return acl; + + if (!IS_RICHACL(inode)) + return NULL; + + /* + * A filesystem can force a ACL callback by just never filling the + * ACL cache. But normally you'd fill the cache either at inode + * instantiation time, or on the first ->get_richacl call. + * + * If the filesystem doesn't have a get_richacl() function at all, + * we'll just create the negative cache entry. + */ + if (!inode->i_op->get_richacl) { + set_cached_richacl(inode, NULL); + return NULL; + } + return inode->i_op->get_richacl(inode); +} +EXPORT_SYMBOL_GPL(get_richacl); + /** * richacl_permission - richacl permission check algorithm * @inode: inode to check diff --git a/include/linux/fs.h b/include/linux/fs.h index 3c36c72..05fb943 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -583,6 +583,7 @@ struct base_acl { }; }; struct posix_acl; +struct richacl; #define ACL_NOT_CACHED ((void *)(-1)) #define IOP_FASTPERM 0x0001 @@ -601,9 +602,11 @@ struct inode { kgid_t i_gid; unsigned int i_flags; -#if defined(CONFIG_FS_POSIX_ACL) +#if defined(CONFIG_FS_POSIX_ACL) || defined(CONFIG_FS_RICHACL) struct base_acl *i_acl; +# if defined(CONFIG_FS_POSIX_ACL) struct base_acl *i_default_acl; +# endif #endif const struct inode_operations *i_op; diff --git a/include/linux/richacl.h b/include/linux/richacl.h index 7628fad..7bf912b6 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -70,6 +70,12 @@ richacl_put(struct richacl *acl) base_acl_put(&acl->a_base); } +extern struct richacl *get_cached_richacl(struct inode *); +extern struct richacl *get_cached_richacl_rcu(struct inode *); +extern void set_cached_richacl(struct inode *, struct richacl *); +extern void forget_cached_richacl(struct inode *); +extern struct richacl *get_richacl(struct inode *); + /** * richace_is_owner - check if @ace is an OWNER@ entry */ -- 2.5.0 From agruenba@redhat.com Mon Nov 9 05:10:50 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 B072C7F8B for ; Mon, 9 Nov 2015 05:10:50 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 78DAD304043 for ; Mon, 9 Nov 2015 03:10:50 -0800 (PST) X-ASG-Debug-ID: 1447067449-04bdf03f04cdc00001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 8laqK9xp8PjlzijA (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 09 Nov 2015 03:10:49 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id EB7518F265; Mon, 9 Nov 2015 11:10:48 +0000 (UTC) Received: from nux.redhat.com (vpn1-6-118.ams2.redhat.com [10.36.6.118]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA9B94CX028578; Mon, 9 Nov 2015 06:10:42 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v15 14/22] richacl: Update the file masks in chmod() Date: Mon, 9 Nov 2015 12:08:55 +0100 X-ASG-Orig-Subj: [PATCH v15 14/22] richacl: Update the file masks in chmod() Message-Id: <1447067343-31479-15-git-send-email-agruenba@redhat.com> In-Reply-To: <1447067343-31479-1-git-send-email-agruenba@redhat.com> References: <1447067343-31479-1-git-send-email-agruenba@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: 1447067449 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Doing a chmod() sets the file mode, which includes the file permission bits. When a file has a richacl, the permissions that the richacl grants need to be limited to what the new file permission bits allow. This is done by setting the file masks in the richacl to what the file permission bits map to. The richacl access check algorithm takes the file masks into account, which ensures that the richacl cannot grant too many permissions. It is possible to explicitly add permissions to the file masks which go beyond what the file permission bits can grant (like the RICHACE_WRITE_ACL permission). The POSIX.1 standard calls this an alternate file access control mechanism. A subsequent chmod() would ensure that those permissions are disabled again. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_base.c | 42 ++++++++++++++++++++++++++++++++++++++++++ fs/richacl_inode.c | 30 ++++++++++++++++++++++++++++++ include/linux/richacl.h | 2 ++ 3 files changed, 74 insertions(+) diff --git a/fs/richacl_base.c b/fs/richacl_base.c index 5826842..e4dd779 100644 --- a/fs/richacl_base.c +++ b/fs/richacl_base.c @@ -340,3 +340,45 @@ restart: acl->a_flags &= ~(RICHACL_WRITE_THROUGH | RICHACL_MASKED); } EXPORT_SYMBOL_GPL(richacl_compute_max_masks); + +/** + * __richacl_chmod - update the file masks to reflect the new mode + * @acl: access control list + * @mode: new file permission bits including the file type + * + * Return a copy of @acl where the file masks have been replaced by the file + * masks corresponding to the file permission bits in @mode, or returns @acl + * itself if the file masks are already up to date. Takes over a reference + * to @acl. + */ +struct richacl * +__richacl_chmod(struct richacl *acl, umode_t mode) +{ + unsigned int x = S_ISDIR(mode) ? 0 : RICHACE_DELETE_CHILD; + unsigned int owner_mask, group_mask, other_mask; + struct richacl *clone; + + owner_mask = richacl_mode_to_mask(mode >> 6) & ~x; + group_mask = richacl_mode_to_mask(mode >> 3) & ~x; + other_mask = richacl_mode_to_mask(mode) & ~x; + + if (acl->a_owner_mask == owner_mask && + acl->a_group_mask == group_mask && + acl->a_other_mask == other_mask && + (acl->a_flags & RICHACL_MASKED) && + (acl->a_flags & RICHACL_WRITE_THROUGH)) + return acl; + + clone = richacl_clone(acl, GFP_KERNEL); + richacl_put(acl); + if (!clone) + return ERR_PTR(-ENOMEM); + + clone->a_flags |= (RICHACL_WRITE_THROUGH | RICHACL_MASKED); + clone->a_owner_mask = owner_mask; + clone->a_group_mask = group_mask; + clone->a_other_mask = other_mask; + + return clone; +} +EXPORT_SYMBOL_GPL(__richacl_chmod); diff --git a/fs/richacl_inode.c b/fs/richacl_inode.c index 52c1595..e329826 100644 --- a/fs/richacl_inode.c +++ b/fs/richacl_inode.c @@ -224,3 +224,33 @@ out: return denied ? -EACCES : 0; } EXPORT_SYMBOL_GPL(richacl_permission); + +/** + * richacl_chmod - filesystem chmod helper + * @inode: inode whose file permission bits to change + * @mode: new file permission bits including the file type + * + * Helper for filesystems to use to perform a chmod on the richacl of an inode. + */ +int +richacl_chmod(struct inode *inode, umode_t mode) +{ + struct richacl *acl; + int retval; + + if (S_ISLNK(mode)) + return -EOPNOTSUPP; + if (!inode->i_op->set_richacl) + return -EOPNOTSUPP; + acl = get_richacl(inode); + if (IS_ERR_OR_NULL(acl)) + return PTR_ERR(acl); + acl = __richacl_chmod(acl, mode); + if (IS_ERR(acl)) + return PTR_ERR(acl); + retval = inode->i_op->set_richacl(inode, acl); + richacl_put(acl); + + return retval; +} +EXPORT_SYMBOL(richacl_chmod); diff --git a/include/linux/richacl.h b/include/linux/richacl.h index 7bf912b6..a2d5600 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -184,8 +184,10 @@ extern int richacl_masks_to_mode(const struct richacl *); extern unsigned int richacl_mode_to_mask(umode_t); extern unsigned int richacl_want_to_mask(unsigned int); extern void richacl_compute_max_masks(struct richacl *); +extern struct richacl *__richacl_chmod(struct richacl *, umode_t); /* richacl_inode.c */ extern int richacl_permission(struct inode *, const struct richacl *, int); +extern int richacl_chmod(struct inode *, umode_t); #endif /* __RICHACL_H */ -- 2.5.0 From agruenba@redhat.com Mon Nov 9 05:10:57 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 92D7F7F60 for ; Mon, 9 Nov 2015 05:10:57 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 56B858F8049 for ; Mon, 9 Nov 2015 03:10:57 -0800 (PST) X-ASG-Debug-ID: 1447067455-04bdf03f03cdc00001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id xzdiaSE5S4nbc9OB (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 09 Nov 2015 03:10:56 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id C864EA4519; Mon, 9 Nov 2015 11:10:55 +0000 (UTC) Received: from nux.redhat.com (vpn1-6-118.ams2.redhat.com [10.36.6.118]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA9B94CY028578; Mon, 9 Nov 2015 06:10:49 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v15 15/22] richacl: Check if an acl is equivalent to a file mode Date: Mon, 9 Nov 2015 12:08:56 +0100 X-ASG-Orig-Subj: [PATCH v15 15/22] richacl: Check if an acl is equivalent to a file mode Message-Id: <1447067343-31479-16-git-send-email-agruenba@redhat.com> In-Reply-To: <1447067343-31479-1-git-send-email-agruenba@redhat.com> References: <1447067343-31479-1-git-send-email-agruenba@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: 1447067456 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 ACLs are considered equivalent to file modes if they only consist of owner@, group@, and everyone@ entries, the owner@ permissions do not depend on whether the owner is a member in the owning group, and no inheritance flags are set. This test is used to avoid storing richacls if the acl can be computed from the file permission bits. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_base.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/richacl.h | 1 + 2 files changed, 105 insertions(+) diff --git a/fs/richacl_base.c b/fs/richacl_base.c index e4dd779..74e5cb5 100644 --- a/fs/richacl_base.c +++ b/fs/richacl_base.c @@ -382,3 +382,107 @@ __richacl_chmod(struct richacl *acl, umode_t mode) return clone; } EXPORT_SYMBOL_GPL(__richacl_chmod); + +/** + * richacl_equiv_mode - compute the mode equivalent of @acl + * + * An acl is considered equivalent to a file mode if it only consists of + * owner@, group@, and everyone@ entries and the owner@ permissions do not + * depend on whether the owner is a member in the owning group. + */ +int +richacl_equiv_mode(const struct richacl *acl, umode_t *mode_p) +{ + umode_t mode = *mode_p; + + /* + * The RICHACE_DELETE_CHILD flag is meaningless for non-directories, so + * we ignore it. + */ + unsigned int x = S_ISDIR(mode) ? 0 : RICHACE_DELETE_CHILD; + struct { + unsigned int allowed; + unsigned int defined; /* allowed or denied */ + } owner = { + .defined = RICHACE_POSIX_ALWAYS_ALLOWED | + RICHACE_POSIX_OWNER_ALLOWED | x, + }, group = { + .defined = RICHACE_POSIX_ALWAYS_ALLOWED | x, + }, everyone = { + .defined = RICHACE_POSIX_ALWAYS_ALLOWED | x, + }; + const struct richace *ace; + + if (acl->a_flags & ~(RICHACL_WRITE_THROUGH | RICHACL_MASKED)) + return -1; + + richacl_for_each_entry(ace, acl) { + if (ace->e_flags & ~RICHACE_SPECIAL_WHO) + return -1; + + if (richace_is_owner(ace) || richace_is_everyone(ace)) { + x = ace->e_mask & ~owner.defined; + if (richace_is_allow(ace)) { + unsigned int group_denied = + group.defined & ~group.allowed; + + if (x & group_denied) + return -1; + owner.allowed |= x; + } else /* if (richace_is_deny(ace)) */ { + if (x & group.allowed) + return -1; + } + owner.defined |= x; + + if (richace_is_everyone(ace)) { + x = ace->e_mask; + if (richace_is_allow(ace)) { + group.allowed |= + x & ~group.defined; + everyone.allowed |= + x & ~everyone.defined; + } + group.defined |= x; + everyone.defined |= x; + } + } else if (richace_is_group(ace)) { + x = ace->e_mask & ~group.defined; + if (richace_is_allow(ace)) + group.allowed |= x; + group.defined |= x; + } else + return -1; + } + + if (group.allowed & ~owner.defined) + return -1; + + if (acl->a_flags & RICHACL_MASKED) { + if (acl->a_flags & RICHACL_WRITE_THROUGH) { + owner.allowed = acl->a_owner_mask; + everyone.allowed = acl->a_other_mask; + } else { + owner.allowed &= acl->a_owner_mask; + everyone.allowed &= acl->a_other_mask; + } + group.allowed &= acl->a_group_mask; + } + + mode = (mode & ~S_IRWXUGO) | + (richacl_mask_to_mode(owner.allowed) << 6) | + (richacl_mask_to_mode(group.allowed) << 3) | + richacl_mask_to_mode(everyone.allowed); + + /* Mask flags we can ignore */ + x = S_ISDIR(mode) ? 0 : RICHACE_DELETE_CHILD; + + if (((richacl_mode_to_mask(mode >> 6) ^ owner.allowed) & ~x) || + ((richacl_mode_to_mask(mode >> 3) ^ group.allowed) & ~x) || + ((richacl_mode_to_mask(mode) ^ everyone.allowed) & ~x)) + return -1; + + *mode_p = mode; + return 0; +} +EXPORT_SYMBOL_GPL(richacl_equiv_mode); diff --git a/include/linux/richacl.h b/include/linux/richacl.h index a2d5600..b7128bf 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -185,6 +185,7 @@ extern unsigned int richacl_mode_to_mask(umode_t); extern unsigned int richacl_want_to_mask(unsigned int); extern void richacl_compute_max_masks(struct richacl *); extern struct richacl *__richacl_chmod(struct richacl *, umode_t); +extern int richacl_equiv_mode(const struct richacl *, umode_t *); /* richacl_inode.c */ extern int richacl_permission(struct inode *, const struct richacl *, int); -- 2.5.0 From agruenba@redhat.com Mon Nov 9 05:11:05 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 60EDF7F6D for ; Mon, 9 Nov 2015 05:11:05 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id D47E9AC004 for ; Mon, 9 Nov 2015 03:11:04 -0800 (PST) X-ASG-Debug-ID: 1447067462-04cbb02424d15f0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id shaPAWWHSHkKEwjL (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 09 Nov 2015 03:11:03 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id B74878F4FD; Mon, 9 Nov 2015 11:11:02 +0000 (UTC) Received: from nux.redhat.com (vpn1-6-118.ams2.redhat.com [10.36.6.118]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA9B94CZ028578; Mon, 9 Nov 2015 06:10:56 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v15 16/22] richacl: Create-time inheritance Date: Mon, 9 Nov 2015 12:08:57 +0100 X-ASG-Orig-Subj: [PATCH v15 16/22] richacl: Create-time inheritance Message-Id: <1447067343-31479-17-git-send-email-agruenba@redhat.com> In-Reply-To: <1447067343-31479-1-git-send-email-agruenba@redhat.com> References: <1447067343-31479-1-git-send-email-agruenba@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: 1447067463 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 When a new file is created, it can inherit an acl from its parent directory; this is similar to how default acls work in POSIX (draft) ACLs. As with POSIX ACLs, if a file inherits an acl from its parent directory, the intersection between the create mode and the permissions granted by the inherited acl determines the file masks and file permission bits, and the umask is ignored. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_base.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++ fs/richacl_inode.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/richacl.h | 2 ++ 3 files changed, 140 insertions(+) diff --git a/fs/richacl_base.c b/fs/richacl_base.c index 74e5cb5..3753216 100644 --- a/fs/richacl_base.c +++ b/fs/richacl_base.c @@ -486,3 +486,71 @@ richacl_equiv_mode(const struct richacl *acl, umode_t *mode_p) return 0; } EXPORT_SYMBOL_GPL(richacl_equiv_mode); + +/** + * richacl_inherit - compute the inherited acl of a new file + * @dir_acl: acl of the containing directory + * @isdir: inherit by a directory or non-directory? + * + * A directory can have acl entries which files and/or directories created + * inside the directory will inherit. This function computes the acl for such + * a new file. If there is no inheritable acl, it will return %NULL. + */ +struct richacl * +richacl_inherit(const struct richacl *dir_acl, int isdir) +{ + const struct richace *dir_ace; + struct richacl *acl = NULL; + struct richace *ace; + int count = 0; + + if (isdir) { + richacl_for_each_entry(dir_ace, dir_acl) { + if (!richace_is_inheritable(dir_ace)) + continue; + count++; + } + if (!count) + return NULL; + acl = richacl_alloc(count, GFP_KERNEL); + if (!acl) + return ERR_PTR(-ENOMEM); + ace = acl->a_entries; + richacl_for_each_entry(dir_ace, dir_acl) { + if (!richace_is_inheritable(dir_ace)) + continue; + richace_copy(ace, dir_ace); + if (dir_ace->e_flags & RICHACE_NO_PROPAGATE_INHERIT_ACE) + ace->e_flags &= ~RICHACE_INHERITANCE_FLAGS; + else if (!(dir_ace->e_flags & RICHACE_DIRECTORY_INHERIT_ACE)) + ace->e_flags |= RICHACE_INHERIT_ONLY_ACE; + ace++; + } + } else { + richacl_for_each_entry(dir_ace, dir_acl) { + if (!(dir_ace->e_flags & RICHACE_FILE_INHERIT_ACE)) + continue; + count++; + } + if (!count) + return NULL; + acl = richacl_alloc(count, GFP_KERNEL); + if (!acl) + return ERR_PTR(-ENOMEM); + ace = acl->a_entries; + richacl_for_each_entry(dir_ace, dir_acl) { + if (!(dir_ace->e_flags & RICHACE_FILE_INHERIT_ACE)) + continue; + richace_copy(ace, dir_ace); + ace->e_flags &= ~RICHACE_INHERITANCE_FLAGS; + /* + * RICHACE_DELETE_CHILD is meaningless for + * non-directories, so clear it. + */ + ace->e_mask &= ~RICHACE_DELETE_CHILD; + ace++; + } + } + + return acl; +} diff --git a/fs/richacl_inode.c b/fs/richacl_inode.c index e329826..ec3d2c8 100644 --- a/fs/richacl_inode.c +++ b/fs/richacl_inode.c @@ -254,3 +254,73 @@ richacl_chmod(struct inode *inode, umode_t mode) return retval; } EXPORT_SYMBOL(richacl_chmod); + +/* + * richacl_inherit_inode - compute inherited acl and file mode + * @dir_acl: acl of the containing directory + * @mode_p: mode of the new inode + * + * The file permission bits in @mode_p must be set to the create mode by the + * caller. + * + * If there is an inheritable acl, the maximum permissions that the acl grants + * are computed and the file masks of the new acl are set accordingly. + */ +static struct richacl * +richacl_inherit_inode(const struct richacl *dir_acl, umode_t *mode_p) +{ + struct richacl *acl; + umode_t mode = *mode_p; + + acl = richacl_inherit(dir_acl, S_ISDIR(mode)); + if (acl) { + if (richacl_equiv_mode(acl, &mode) == 0) { + *mode_p &= mode; + richacl_put(acl); + acl = NULL; + } else { + richacl_compute_max_masks(acl); + /* + * Ensure that the acl will not grant any permissions + * beyond the create mode. + */ + acl->a_flags |= RICHACL_MASKED; + acl->a_owner_mask &= + richacl_mode_to_mask(mode >> 6); + acl->a_group_mask &= + richacl_mode_to_mask(mode >> 3); + acl->a_other_mask &= + richacl_mode_to_mask(mode); + } + } else + *mode_p &= ~current_umask(); + + return acl; +} + +/** + * richacl_create - filesystem create helper + * @mode_p: mode of the new inode + * @dir: containing directory + * + * Compute the inherited acl for a new inode. If there is no acl to inherit, + * apply the umask. Use when creating a new inode on a richacl enabled file + * system. + */ +struct richacl *richacl_create(umode_t *mode_p, struct inode *dir) +{ + struct richacl *dir_acl, *acl = NULL; + + if (S_ISLNK(*mode_p)) + return NULL; + dir_acl = get_richacl(dir); + if (dir_acl) { + if (IS_ERR(dir_acl)) + return dir_acl; + acl = richacl_inherit_inode(dir_acl, mode_p); + richacl_put(dir_acl); + } else + *mode_p &= ~current_umask(); + return acl; +} +EXPORT_SYMBOL_GPL(richacl_create); diff --git a/include/linux/richacl.h b/include/linux/richacl.h index b7128bf..c8fae91a 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -186,9 +186,11 @@ extern unsigned int richacl_want_to_mask(unsigned int); extern void richacl_compute_max_masks(struct richacl *); extern struct richacl *__richacl_chmod(struct richacl *, umode_t); extern int richacl_equiv_mode(const struct richacl *, umode_t *); +extern struct richacl *richacl_inherit(const struct richacl *, int); /* richacl_inode.c */ extern int richacl_permission(struct inode *, const struct richacl *, int); extern int richacl_chmod(struct inode *, umode_t); +extern struct richacl *richacl_create(umode_t *, struct inode *); #endif /* __RICHACL_H */ -- 2.5.0 From agruenba@redhat.com Mon Nov 9 05:11:12 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 27FF47F60 for ; Mon, 9 Nov 2015 05:11:12 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id DF8C38F804B for ; Mon, 9 Nov 2015 03:11:11 -0800 (PST) X-ASG-Debug-ID: 1447067469-04bdf03f04cdc10001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id kye28OYYFyK4Fo3C (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 09 Nov 2015 03:11:09 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 948B78F277; Mon, 9 Nov 2015 11:11:09 +0000 (UTC) Received: from nux.redhat.com (vpn1-6-118.ams2.redhat.com [10.36.6.118]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA9B94Ca028578; Mon, 9 Nov 2015 06:11:03 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v15 17/22] richacl: Automatic Inheritance Date: Mon, 9 Nov 2015 12:08:58 +0100 X-ASG-Orig-Subj: [PATCH v15 17/22] richacl: Automatic Inheritance Message-Id: <1447067343-31479-18-git-send-email-agruenba@redhat.com> In-Reply-To: <1447067343-31479-1-git-send-email-agruenba@redhat.com> References: <1447067343-31479-1-git-send-email-agruenba@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: 1447067469 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Automatic Inheritance (AI) allows changes to the acl of a directory to propagate down to children. This is mostly implemented in user space: when a process changes the permissions of a directory and Automatic Inheritance is enabled for that directory, the process must propagate those changes to all children, recursively. The kernel enables this by keeping track of which permissions have been inherited at create time. In addition, it makes sure that permission propagation is turned off when the permissions are set explicitly (for example, upon create or chmod). Automatic Inheritance works as follows: - When the RICHACL_AUTO_INHERIT flag in the acl of a file or directory is not set, the file or directory is not affected by AI. - When the RICHACL_AUTO_INHERIT flag in the acl of a directory is set and a file or subdirectory is created in that directory, the inherited acl will have the RICHACL_AUTO_INHERIT flag set, and all inherited aces will have the RICHACE_INHERITED_ACE flag set. This allows user space to distinguish between aces which have been inherited and aces which have been explicitly added. - When the RICHACL_PROTECTED acl flag in the acl of a file or directory is set, AI will not modify the acl. This does not affect propagation of permissions from the file to its children (if the file is a directory). Linux does not have a way of creating files or directories without setting the file permission bits, so all files created inside a directory with RICHACL_AUTO_INHERIT set will have the RICHACL_PROTECTED flag set. This effectively disables Automatic Inheritance. Protocols which support creating files without specifying permissions can explicitly clear the RICHACL_PROTECTED flag after creating a file and reset the file masks to "undo" applying the create mode; see richacl_compute_max_masks(). They should set the RICHACL_DEFAULTED flag. (A mechanism that would allow to indicate to the kernel to ignore the create mode in the first place when there are inherited permissions would be nice to have.) Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_base.c | 10 +++++++++- fs/richacl_inode.c | 7 +++++++ include/linux/richacl.h | 12 ++++++++++++ include/uapi/linux/richacl.h | 11 ++++++++++- 4 files changed, 38 insertions(+), 2 deletions(-) diff --git a/fs/richacl_base.c b/fs/richacl_base.c index 3753216..b67280d 100644 --- a/fs/richacl_base.c +++ b/fs/richacl_base.c @@ -366,7 +366,8 @@ __richacl_chmod(struct richacl *acl, umode_t mode) acl->a_group_mask == group_mask && acl->a_other_mask == other_mask && (acl->a_flags & RICHACL_MASKED) && - (acl->a_flags & RICHACL_WRITE_THROUGH)) + (acl->a_flags & RICHACL_WRITE_THROUGH) && + (!richacl_is_auto_inherit(acl) || richacl_is_protected(acl))) return acl; clone = richacl_clone(acl, GFP_KERNEL); @@ -378,6 +379,8 @@ __richacl_chmod(struct richacl *acl, umode_t mode) clone->a_owner_mask = owner_mask; clone->a_group_mask = group_mask; clone->a_other_mask = other_mask; + if (richacl_is_auto_inherit(clone)) + clone->a_flags |= RICHACL_PROTECTED; return clone; } @@ -551,6 +554,11 @@ richacl_inherit(const struct richacl *dir_acl, int isdir) ace++; } } + if (richacl_is_auto_inherit(dir_acl)) { + acl->a_flags = RICHACL_AUTO_INHERIT; + richacl_for_each_entry(ace, acl) + ace->e_flags |= RICHACE_INHERITED_ACE; + } return acl; } diff --git a/fs/richacl_inode.c b/fs/richacl_inode.c index ec3d2c8..99a1ab6 100644 --- a/fs/richacl_inode.c +++ b/fs/richacl_inode.c @@ -279,6 +279,13 @@ richacl_inherit_inode(const struct richacl *dir_acl, umode_t *mode_p) richacl_put(acl); acl = NULL; } else { + /* + * We need to set RICHACL_PROTECTED because we are + * doing an implicit chmod + */ + if (richacl_is_auto_inherit(acl)) + acl->a_flags |= RICHACL_PROTECTED; + richacl_compute_max_masks(acl); /* * Ensure that the acl will not grant any permissions diff --git a/include/linux/richacl.h b/include/linux/richacl.h index c8fae91a..c524a4b 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -76,6 +76,18 @@ extern void set_cached_richacl(struct inode *, struct richacl *); extern void forget_cached_richacl(struct inode *); extern struct richacl *get_richacl(struct inode *); +static inline int +richacl_is_auto_inherit(const struct richacl *acl) +{ + return acl->a_flags & RICHACL_AUTO_INHERIT; +} + +static inline int +richacl_is_protected(const struct richacl *acl) +{ + return acl->a_flags & RICHACL_PROTECTED; +} + /** * richace_is_owner - check if @ace is an OWNER@ entry */ diff --git a/include/uapi/linux/richacl.h b/include/uapi/linux/richacl.h index 1ed48ac..8849a53 100644 --- a/include/uapi/linux/richacl.h +++ b/include/uapi/linux/richacl.h @@ -18,6 +18,9 @@ #define __UAPI_RICHACL_H /* a_flags values */ +#define RICHACL_AUTO_INHERIT 0x01 +#define RICHACL_PROTECTED 0x02 +#define RICHACL_DEFAULTED 0x04 #define RICHACL_WRITE_THROUGH 0x40 #define RICHACL_MASKED 0x80 @@ -31,6 +34,7 @@ #define RICHACE_NO_PROPAGATE_INHERIT_ACE 0x0004 #define RICHACE_INHERIT_ONLY_ACE 0x0008 #define RICHACE_IDENTIFIER_GROUP 0x0040 +#define RICHACE_INHERITED_ACE 0x0080 #define RICHACE_SPECIAL_WHO 0x4000 /* e_mask bitflags */ @@ -60,6 +64,9 @@ #define RICHACE_EVERYONE_SPECIAL_ID 2 #define RICHACL_VALID_FLAGS ( \ + RICHACL_AUTO_INHERIT | \ + RICHACL_PROTECTED | \ + RICHACL_DEFAULTED | \ RICHACL_WRITE_THROUGH | \ RICHACL_MASKED ) @@ -69,13 +76,15 @@ RICHACE_NO_PROPAGATE_INHERIT_ACE | \ RICHACE_INHERIT_ONLY_ACE | \ RICHACE_IDENTIFIER_GROUP | \ + RICHACE_INHERITED_ACE | \ RICHACE_SPECIAL_WHO ) #define RICHACE_INHERITANCE_FLAGS ( \ RICHACE_FILE_INHERIT_ACE | \ RICHACE_DIRECTORY_INHERIT_ACE | \ RICHACE_NO_PROPAGATE_INHERIT_ACE | \ - RICHACE_INHERIT_ONLY_ACE ) + RICHACE_INHERIT_ONLY_ACE | \ + RICHACE_INHERITED_ACE ) /* Valid RICHACE_* flags for directories and non-directories */ #define RICHACE_VALID_MASK ( \ -- 2.5.0 From agruenba@redhat.com Mon Nov 9 05:11:19 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 400D87F3F for ; Mon, 9 Nov 2015 05:11:19 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 21238304032 for ; Mon, 9 Nov 2015 03:11:19 -0800 (PST) X-ASG-Debug-ID: 1447067476-04cb6c296acc830001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id JQshDxHezDYZ2GdP (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 09 Nov 2015 03:11:17 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 7EBCF19F236; Mon, 9 Nov 2015 11:11:16 +0000 (UTC) Received: from nux.redhat.com (vpn1-6-118.ams2.redhat.com [10.36.6.118]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA9B94Cb028578; Mon, 9 Nov 2015 06:11:10 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v15 18/22] richacl: xattr mapping functions Date: Mon, 9 Nov 2015 12:08:59 +0100 X-ASG-Orig-Subj: [PATCH v15 18/22] richacl: xattr mapping functions Message-Id: <1447067343-31479-19-git-send-email-agruenba@redhat.com> In-Reply-To: <1447067343-31479-1-git-send-email-agruenba@redhat.com> References: <1447067343-31479-1-git-send-email-agruenba@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: 1447067477 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Map between "system.richacl" xattrs and the in-kernel representation. Signed-off-by: Andreas Gruenbacher --- fs/Makefile | 2 +- fs/richacl_xattr.c | 220 +++++++++++++++++++++++++++++++++++++ fs/xattr.c | 34 +++++- include/linux/richacl_xattr.h | 42 +++++++ include/uapi/linux/Kbuild | 1 + include/uapi/linux/richacl_xattr.h | 44 ++++++++ include/uapi/linux/xattr.h | 2 + 7 files changed, 338 insertions(+), 7 deletions(-) create mode 100644 fs/richacl_xattr.c create mode 100644 include/linux/richacl_xattr.h create mode 100644 include/uapi/linux/richacl_xattr.h diff --git a/fs/Makefile b/fs/Makefile index ec665fd..35e640d 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -49,7 +49,7 @@ obj-$(CONFIG_SYSCTL) += drop_caches.o obj-$(CONFIG_FHANDLE) += fhandle.o obj-$(CONFIG_FS_RICHACL) += richacl.o -richacl-y := richacl_base.o richacl_inode.o +richacl-y := richacl_base.o richacl_inode.o richacl_xattr.o obj-y += quota/ diff --git a/fs/richacl_xattr.c b/fs/richacl_xattr.c new file mode 100644 index 0000000..38473b6 --- /dev/null +++ b/fs/richacl_xattr.c @@ -0,0 +1,220 @@ +/* + * Copyright (C) 2006, 2010 Novell, Inc. + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * 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; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include +#include +#include +#include +#include + +MODULE_LICENSE("GPL"); + +/** + * richacl_from_xattr - convert a richacl xattr into the in-memory representation + */ +struct richacl * +richacl_from_xattr(struct user_namespace *user_ns, + const void *value, size_t size) +{ + const struct richacl_xattr *xattr_acl = value; + const struct richace_xattr *xattr_ace = (void *)(xattr_acl + 1); + struct richacl *acl; + struct richace *ace; + int count; + + if (size < sizeof(*xattr_acl) || + xattr_acl->a_version != RICHACL_XATTR_VERSION || + (xattr_acl->a_flags & ~RICHACL_VALID_FLAGS)) + return ERR_PTR(-EINVAL); + size -= sizeof(*xattr_acl); + count = le16_to_cpu(xattr_acl->a_count); + if (count > RICHACL_XATTR_MAX_COUNT) + return ERR_PTR(-EINVAL); + if (size != count * sizeof(*xattr_ace)) + return ERR_PTR(-EINVAL); + + acl = richacl_alloc(count, GFP_NOFS); + if (!acl) + return ERR_PTR(-ENOMEM); + + acl->a_flags = xattr_acl->a_flags; + acl->a_owner_mask = le32_to_cpu(xattr_acl->a_owner_mask); + if (acl->a_owner_mask & ~RICHACE_VALID_MASK) + goto fail_einval; + acl->a_group_mask = le32_to_cpu(xattr_acl->a_group_mask); + if (acl->a_group_mask & ~RICHACE_VALID_MASK) + goto fail_einval; + acl->a_other_mask = le32_to_cpu(xattr_acl->a_other_mask); + if (acl->a_other_mask & ~RICHACE_VALID_MASK) + goto fail_einval; + + richacl_for_each_entry(ace, acl) { + ace->e_type = le16_to_cpu(xattr_ace->e_type); + ace->e_flags = le16_to_cpu(xattr_ace->e_flags); + ace->e_mask = le32_to_cpu(xattr_ace->e_mask); + + if (ace->e_flags & ~RICHACE_VALID_FLAGS) + goto fail_einval; + if (ace->e_flags & RICHACE_SPECIAL_WHO) { + ace->e_id.special = le32_to_cpu(xattr_ace->e_id); + if (ace->e_id.special > RICHACE_EVERYONE_SPECIAL_ID) + goto fail_einval; + } else if (ace->e_flags & RICHACE_IDENTIFIER_GROUP) { + u32 id = le32_to_cpu(xattr_ace->e_id); + + ace->e_id.gid = make_kgid(user_ns, id); + if (!gid_valid(ace->e_id.gid)) + goto fail_einval; + } else { + u32 id = le32_to_cpu(xattr_ace->e_id); + + ace->e_id.uid = make_kuid(user_ns, id); + if (!uid_valid(ace->e_id.uid)) + goto fail_einval; + } + if (ace->e_type > RICHACE_ACCESS_DENIED_ACE_TYPE || + (ace->e_mask & ~RICHACE_VALID_MASK)) + goto fail_einval; + + xattr_ace++; + } + + return acl; + +fail_einval: + richacl_put(acl); + return ERR_PTR(-EINVAL); +} +EXPORT_SYMBOL_GPL(richacl_from_xattr); + +/** + * richacl_xattr_size - compute the size of the xattr representation of @acl + */ +size_t +richacl_xattr_size(const struct richacl *acl) +{ + size_t size = sizeof(struct richacl_xattr); + + size += sizeof(struct richace_xattr) * acl->a_count; + return size; +} +EXPORT_SYMBOL_GPL(richacl_xattr_size); + +/** + * richacl_to_xattr - convert @acl into its xattr representation + * @acl: the richacl to convert + * @buffer: buffer for the result + * @size: size of @buffer + */ +int +richacl_to_xattr(struct user_namespace *user_ns, + const struct richacl *acl, void *buffer, size_t size) +{ + struct richacl_xattr *xattr_acl = buffer; + struct richace_xattr *xattr_ace; + const struct richace *ace; + size_t real_size; + + real_size = richacl_xattr_size(acl); + if (!buffer) + return real_size; + if (real_size > size) + return -ERANGE; + + xattr_acl->a_version = RICHACL_XATTR_VERSION; + xattr_acl->a_flags = acl->a_flags; + xattr_acl->a_count = cpu_to_le16(acl->a_count); + + xattr_acl->a_owner_mask = cpu_to_le32(acl->a_owner_mask); + xattr_acl->a_group_mask = cpu_to_le32(acl->a_group_mask); + xattr_acl->a_other_mask = cpu_to_le32(acl->a_other_mask); + + xattr_ace = (void *)(xattr_acl + 1); + richacl_for_each_entry(ace, acl) { + xattr_ace->e_type = cpu_to_le16(ace->e_type); + xattr_ace->e_flags = cpu_to_le16(ace->e_flags); + xattr_ace->e_mask = cpu_to_le32(ace->e_mask); + if (ace->e_flags & RICHACE_SPECIAL_WHO) + xattr_ace->e_id = cpu_to_le32(ace->e_id.special); + else if (ace->e_flags & RICHACE_IDENTIFIER_GROUP) + xattr_ace->e_id = + cpu_to_le32(from_kgid(user_ns, ace->e_id.gid)); + else + xattr_ace->e_id = + cpu_to_le32(from_kuid(user_ns, ace->e_id.uid)); + xattr_ace++; + } + return real_size; +} +EXPORT_SYMBOL_GPL(richacl_to_xattr); + +/* + * Fix up the uids and gids in richacl extended attributes in place. + */ +static void richacl_fix_xattr_userns( + struct user_namespace *to, struct user_namespace *from, + void *value, size_t size) +{ + struct richacl_xattr *xattr_acl = value; + struct richace_xattr *xattr_ace = + (struct richace_xattr *)(xattr_acl + 1); + unsigned int count; + + if (!value) + return; + if (size < sizeof(*xattr_acl)) + return; + if (xattr_acl->a_version != cpu_to_le32(RICHACL_XATTR_VERSION)) + return; + size -= sizeof(*xattr_acl); + if (size % sizeof(*xattr_ace)) + return; + count = size / sizeof(*xattr_ace); + for (; count; count--, xattr_ace++) { + if (xattr_ace->e_flags & cpu_to_le16(RICHACE_SPECIAL_WHO)) + continue; + if (xattr_ace->e_flags & + cpu_to_le16(RICHACE_IDENTIFIER_GROUP)) { + u32 id = le32_to_cpu(xattr_ace->e_id); + kgid_t gid = make_kgid(from, id); + + xattr_ace->e_id = cpu_to_le32(from_kgid(to, gid)); + } else { + u32 id = le32_to_cpu(xattr_ace->e_id); + kuid_t uid = make_kuid(from, id); + + xattr_ace->e_id = cpu_to_le32(from_kuid(to, uid)); + } + } +} + +void richacl_fix_xattr_from_user(void *value, size_t size) +{ + struct user_namespace *user_ns = current_user_ns(); + + if (user_ns == &init_user_ns) + return; + richacl_fix_xattr_userns(&init_user_ns, user_ns, value, size); +} + +void richacl_fix_xattr_to_user(void *value, size_t size) +{ + struct user_namespace *user_ns = current_user_ns(); + + if (user_ns == &init_user_ns) + return; + richacl_fix_xattr_userns(user_ns, &init_user_ns, value, size); +} diff --git a/fs/xattr.c b/fs/xattr.c index 072fee1..f2313c6 100644 --- a/fs/xattr.c +++ b/fs/xattr.c @@ -21,6 +21,7 @@ #include #include #include +#include #include @@ -314,6 +315,18 @@ out: } EXPORT_SYMBOL_GPL(vfs_removexattr); +static void +fix_xattr_from_user(const char *kname, void *kvalue, size_t size) +{ + if (strncmp(kname, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) + return; + kname += XATTR_SYSTEM_PREFIX_LEN; + if (!strcmp(kname, XATTR_POSIX_ACL_ACCESS) || + !strcmp(kname, XATTR_POSIX_ACL_DEFAULT)) + posix_acl_fix_xattr_from_user(kvalue, size); + else if (!strcmp(kname, XATTR_RICHACL)) + richacl_fix_xattr_from_user(kvalue, size); +} /* * Extended attribute SET operations @@ -350,9 +363,7 @@ setxattr(struct dentry *d, const char __user *name, const void __user *value, error = -EFAULT; goto out; } - if ((strcmp(kname, XATTR_NAME_POSIX_ACL_ACCESS) == 0) || - (strcmp(kname, XATTR_NAME_POSIX_ACL_DEFAULT) == 0)) - posix_acl_fix_xattr_from_user(kvalue, size); + fix_xattr_from_user(kname, kvalue, size); } error = vfs_setxattr(d, kname, kvalue, size, flags); @@ -419,6 +430,19 @@ SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name, return error; } +static void +fix_xattr_to_user(const char *kname, void *kvalue, size_t size) +{ + if (strncmp(kname, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) + return; + kname += XATTR_SYSTEM_PREFIX_LEN; + if (!strcmp(kname, XATTR_POSIX_ACL_ACCESS) || + !strcmp(kname, XATTR_POSIX_ACL_DEFAULT)) + posix_acl_fix_xattr_to_user(kvalue, size); + else if (!strcmp(kname, XATTR_RICHACL)) + richacl_fix_xattr_to_user(kvalue, size); +} + /* * Extended attribute GET operations */ @@ -451,9 +475,7 @@ getxattr(struct dentry *d, const char __user *name, void __user *value, error = vfs_getxattr(d, kname, kvalue, size); if (error > 0) { - if ((strcmp(kname, XATTR_NAME_POSIX_ACL_ACCESS) == 0) || - (strcmp(kname, XATTR_NAME_POSIX_ACL_DEFAULT) == 0)) - posix_acl_fix_xattr_to_user(kvalue, size); + fix_xattr_to_user(kname, kvalue, size); if (size && copy_to_user(value, kvalue, error)) error = -EFAULT; } else if (error == -ERANGE && size >= XATTR_SIZE_MAX) { diff --git a/include/linux/richacl_xattr.h b/include/linux/richacl_xattr.h new file mode 100644 index 0000000..7fc5ca8 --- /dev/null +++ b/include/linux/richacl_xattr.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2006, 2010 Novell, Inc. + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * 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; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#ifndef __RICHACL_XATTR_H +#define __RICHACL_XATTR_H + +#include +#include + +extern struct richacl *richacl_from_xattr(struct user_namespace *, const void *, + size_t); +extern size_t richacl_xattr_size(const struct richacl *); +extern int richacl_to_xattr(struct user_namespace *, const struct richacl *, + void *, size_t); + +#ifdef CONFIG_FS_RICHACL +extern void richacl_fix_xattr_from_user(void *, size_t); +extern void richacl_fix_xattr_to_user(void *, size_t); +#else +static inline void richacl_fix_xattr_from_user(void *value, size_t size) +{ +} + +static inline void richacl_fix_xattr_to_user(void *value, size_t size) +{ +} +#endif + +#endif /* __RICHACL_XATTR_H */ diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild index 8c82010..18ad070 100644 --- a/include/uapi/linux/Kbuild +++ b/include/uapi/linux/Kbuild @@ -349,6 +349,7 @@ header-y += reiserfs_fs.h header-y += reiserfs_xattr.h header-y += resource.h header-y += richacl.h +header-y += richacl_xattr.h header-y += rfkill.h header-y += romfs_fs.h header-y += rose.h diff --git a/include/uapi/linux/richacl_xattr.h b/include/uapi/linux/richacl_xattr.h new file mode 100644 index 0000000..5178ca6 --- /dev/null +++ b/include/uapi/linux/richacl_xattr.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2006, 2010 Novell, Inc. + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ + +#ifndef __UAPI_RICHACL_XATTR_H +#define __UAPI_RICHACL_XATTR_H + +#include +#include + +struct richace_xattr { + __le16 e_type; + __le16 e_flags; + __le32 e_mask; + __le32 e_id; +}; + +struct richacl_xattr { + unsigned char a_version; + unsigned char a_flags; + __le16 a_count; + __le32 a_owner_mask; + __le32 a_group_mask; + __le32 a_other_mask; +}; + +#define RICHACL_XATTR_VERSION 0 +#define RICHACL_XATTR_MAX_COUNT \ + ((XATTR_SIZE_MAX - sizeof(struct richacl_xattr)) / \ + sizeof(struct richace_xattr)) + +#endif /* __UAPI_RICHACL_XATTR_H */ diff --git a/include/uapi/linux/xattr.h b/include/uapi/linux/xattr.h index 1590c49..1996903 100644 --- a/include/uapi/linux/xattr.h +++ b/include/uapi/linux/xattr.h @@ -73,5 +73,7 @@ #define XATTR_POSIX_ACL_DEFAULT "posix_acl_default" #define XATTR_NAME_POSIX_ACL_DEFAULT XATTR_SYSTEM_PREFIX XATTR_POSIX_ACL_DEFAULT +#define XATTR_RICHACL "richacl" +#define XATTR_NAME_RICHACL XATTR_SYSTEM_PREFIX XATTR_RICHACL #endif /* _UAPI_LINUX_XATTR_H */ -- 2.5.0 From agruenba@redhat.com Mon Nov 9 05:11:25 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 536BC7F94 for ; Mon, 9 Nov 2015 05:11:25 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 408648F8040 for ; Mon, 9 Nov 2015 03:11:25 -0800 (PST) X-ASG-Debug-ID: 1447067483-04cbb02425d1620001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id wO4H7blkkg1v2lIy (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 09 Nov 2015 03:11:24 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 75660C0B60EA; Mon, 9 Nov 2015 11:11:23 +0000 (UTC) Received: from nux.redhat.com (vpn1-6-118.ams2.redhat.com [10.36.6.118]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA9B94Cc028578; Mon, 9 Nov 2015 06:11:17 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v15 19/22] richacl: Add richacl xattr handler Date: Mon, 9 Nov 2015 12:09:00 +0100 X-ASG-Orig-Subj: [PATCH v15 19/22] richacl: Add richacl xattr handler Message-Id: <1447067343-31479-20-git-send-email-agruenba@redhat.com> In-Reply-To: <1447067343-31479-1-git-send-email-agruenba@redhat.com> References: <1447067343-31479-1-git-send-email-agruenba@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: 1447067484 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Add richacl xattr handler implementing the xattr operations based on the get_richacl and set_richacl inode operations. Signed-off-by: Andreas Gruenbacher --- fs/richacl_xattr.c | 78 +++++++++++++++++++++++++++++++++++++++++++ include/linux/richacl_xattr.h | 2 ++ 2 files changed, 80 insertions(+) diff --git a/fs/richacl_xattr.c b/fs/richacl_xattr.c index 38473b6..767c1f7 100644 --- a/fs/richacl_xattr.c +++ b/fs/richacl_xattr.c @@ -18,7 +18,9 @@ #include #include #include +#include #include +#include MODULE_LICENSE("GPL"); @@ -161,6 +163,82 @@ richacl_to_xattr(struct user_namespace *user_ns, } EXPORT_SYMBOL_GPL(richacl_to_xattr); +static size_t +richacl_xattr_list(struct dentry *dentry, char *list, size_t list_len, + const char *name, size_t name_len, int handler_flags) +{ + const size_t size = sizeof(XATTR_NAME_RICHACL); + + if (!IS_RICHACL(d_backing_inode(dentry))) + return 0; + if (list && size <= list_len) + memcpy(list, XATTR_NAME_RICHACL, size); + return size; +} + +static int +richacl_xattr_get(struct dentry *dentry, const char *name, void *buffer, + size_t buffer_size, int handler_flags) +{ + struct inode *inode = d_backing_inode(dentry); + struct richacl *acl; + int error; + + if (strcmp(name, "") != 0) + return -EINVAL; + if (!IS_RICHACL(inode)) + return EOPNOTSUPP; + if (S_ISLNK(inode->i_mode)) + return -EOPNOTSUPP; + acl = get_richacl(inode); + if (IS_ERR(acl)) + return PTR_ERR(acl); + if (acl == NULL) + return -ENODATA; + error = richacl_to_xattr(&init_user_ns, acl, buffer, buffer_size); + richacl_put(acl); + return error; +} + +static int +richacl_xattr_set(struct dentry *dentry, const char *name, + const void *value, size_t size, int flags, int handler_flags) +{ + struct inode *inode = d_backing_inode(dentry); + struct richacl *acl = NULL; + int ret; + + if (strcmp(name, "") != 0) + return -EINVAL; + if (!IS_RICHACL(inode)) + return -EOPNOTSUPP; + if (!inode->i_op->set_richacl) + return -EOPNOTSUPP; + + if (!uid_eq(current_fsuid(), inode->i_uid) && + inode_permission(inode, MAY_CHMOD) && + !capable(CAP_FOWNER)) + return -EPERM; + + if (value) { + acl = richacl_from_xattr(&init_user_ns, value, size); + if (IS_ERR(acl)) + return PTR_ERR(acl); + } + + ret = inode->i_op->set_richacl(inode, acl); + richacl_put(acl); + return ret; +} + +struct xattr_handler richacl_xattr_handler = { + .prefix = XATTR_NAME_RICHACL, + .list = richacl_xattr_list, + .get = richacl_xattr_get, + .set = richacl_xattr_set, +}; +EXPORT_SYMBOL(richacl_xattr_handler); + /* * Fix up the uids and gids in richacl extended attributes in place. */ diff --git a/include/linux/richacl_xattr.h b/include/linux/richacl_xattr.h index 7fc5ca8..45ec27a 100644 --- a/include/linux/richacl_xattr.h +++ b/include/linux/richacl_xattr.h @@ -39,4 +39,6 @@ static inline void richacl_fix_xattr_to_user(void *value, size_t size) } #endif +extern struct xattr_handler richacl_xattr_handler; + #endif /* __RICHACL_XATTR_H */ -- 2.5.0 From agruenba@redhat.com Mon Nov 9 05:11:32 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 A5EEF7F3F for ; Mon, 9 Nov 2015 05:11:32 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 27583AC004 for ; Mon, 9 Nov 2015 03:11:32 -0800 (PST) X-ASG-Debug-ID: 1447067490-04cbb02424d1620001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 9NJqoSDMHvWz7BPu (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 09 Nov 2015 03:11:30 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 4D902C100450; Mon, 9 Nov 2015 11:11:30 +0000 (UTC) Received: from nux.redhat.com (vpn1-6-118.ams2.redhat.com [10.36.6.118]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA9B94Cd028578; Mon, 9 Nov 2015 06:11:24 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v15 20/22] vfs: Add richacl permission checking Date: Mon, 9 Nov 2015 12:09:01 +0100 X-ASG-Orig-Subj: [PATCH v15 20/22] vfs: Add richacl permission checking Message-Id: <1447067343-31479-21-git-send-email-agruenba@redhat.com> In-Reply-To: <1447067343-31479-1-git-send-email-agruenba@redhat.com> References: <1447067343-31479-1-git-send-email-agruenba@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: 1447067490 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Hook the richacl permission checking function into the vfs. Signed-off-by: Andreas Gruenbacher --- fs/namei.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++-- fs/posix_acl.c | 6 +++--- 2 files changed, 52 insertions(+), 5 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 7f21554..2d32d103 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include "internal.h" @@ -255,7 +256,40 @@ void putname(struct filename *name) __putname(name); } -static int check_acl(struct inode *inode, int mask) +static int check_richacl(struct inode *inode, int mask) +{ +#ifdef CONFIG_FS_RICHACL + struct richacl *acl; + + if (mask & MAY_NOT_BLOCK) { + acl = get_cached_richacl_rcu(inode); + if (!acl) + goto no_acl; + /* no ->get_richacl() calls in RCU mode... */ + if (acl == ACL_NOT_CACHED) + return -ECHILD; + return richacl_permission(inode, acl, mask & ~MAY_NOT_BLOCK); + } + + acl = get_richacl(inode); + if (IS_ERR(acl)) + return PTR_ERR(acl); + if (acl) { + int error = richacl_permission(inode, acl, mask); + richacl_put(acl); + return error; + } +no_acl: +#endif + if (mask & (MAY_DELETE_SELF | MAY_TAKE_OWNERSHIP | + MAY_CHMOD | MAY_SET_TIMES)) { + /* File permission bits cannot grant this. */ + return -EACCES; + } + return -EAGAIN; +} + +static int check_posix_acl(struct inode *inode, int mask) { #ifdef CONFIG_FS_POSIX_ACL struct posix_acl *acl; @@ -290,11 +324,24 @@ static int acl_permission_check(struct inode *inode, int mask) { unsigned int mode = inode->i_mode; + /* + * With POSIX ACLs, the (mode & S_IRWXU) bits exactly match the owner + * permissions, and we can skip checking posix acls for the owner. + * With richacls, the owner may be granted fewer permissions than the + * mode bits seem to suggest (for example, append but not write), and + * we always need to check the richacl. + */ + + if (IS_RICHACL(inode)) { + int error = check_richacl(inode, mask); + if (error != -EAGAIN) + return error; + } if (likely(uid_eq(current_fsuid(), inode->i_uid))) mode >>= 6; else { if (IS_POSIXACL(inode) && (mode & S_IRWXG)) { - int error = check_acl(inode, mask); + int error = check_posix_acl(inode, mask); if (error != -EAGAIN) return error; } diff --git a/fs/posix_acl.c b/fs/posix_acl.c index b0eb1dc..6dbddb6 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c @@ -100,13 +100,13 @@ struct posix_acl *get_acl(struct inode *inode, int type) { struct posix_acl *acl; + if (!IS_POSIXACL(inode)) + return NULL; + acl = get_cached_acl(inode, type); if (acl != ACL_NOT_CACHED) return acl; - if (!IS_POSIXACL(inode)) - return NULL; - /* * A filesystem can force a ACL callback by just never filling the * ACL cache. But normally you'd fill the cache either at inode -- 2.5.0 From agruenba@redhat.com Mon Nov 9 05:11:40 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 05AFA7FAF for ; Mon, 9 Nov 2015 05:11:40 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id CDDF0304043 for ; Mon, 9 Nov 2015 03:11:39 -0800 (PST) X-ASG-Debug-ID: 1447067497-04bdf03f03cdc40001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id soCkpms1RqVIZlZc (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 09 Nov 2015 03:11:37 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 8935CC10047C; Mon, 9 Nov 2015 11:11:37 +0000 (UTC) Received: from nux.redhat.com (vpn1-6-118.ams2.redhat.com [10.36.6.118]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA9B94Ce028578; Mon, 9 Nov 2015 06:11:30 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: "Aneesh Kumar K.V" , Andreas Gruenbacher Subject: [PATCH v15 21/22] ext4: Add richacl support Date: Mon, 9 Nov 2015 12:09:02 +0100 X-ASG-Orig-Subj: [PATCH v15 21/22] ext4: Add richacl support Message-Id: <1447067343-31479-22-git-send-email-agruenba@redhat.com> In-Reply-To: <1447067343-31479-1-git-send-email-agruenba@redhat.com> References: <1447067343-31479-1-git-send-email-agruenba@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: 1447067497 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: "Aneesh Kumar K.V" Support the richacl permission model in ext4. The richacls are stored in "system.richacl" xattrs. Richacls need to be enabled by tune2fs or at file system create time. Signed-off-by: Aneesh Kumar K.V Signed-off-by: Andreas Gruenbacher Reviewed-by: Andreas Dilger --- fs/ext4/Kconfig | 11 +++++ fs/ext4/Makefile | 1 + fs/ext4/file.c | 3 ++ fs/ext4/ialloc.c | 11 ++++- fs/ext4/inode.c | 12 ++++- fs/ext4/namei.c | 5 ++ fs/ext4/richacl.c | 142 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ fs/ext4/richacl.h | 40 +++++++++++++++ fs/ext4/xattr.c | 7 +++ 9 files changed, 229 insertions(+), 3 deletions(-) create mode 100644 fs/ext4/richacl.c create mode 100644 fs/ext4/richacl.h diff --git a/fs/ext4/Kconfig b/fs/ext4/Kconfig index b46e9fc..65c5230 100644 --- a/fs/ext4/Kconfig +++ b/fs/ext4/Kconfig @@ -22,6 +22,17 @@ config EXT3_FS_POSIX_ACL This config option is here only for backward compatibility. ext3 filesystem is now handled by the ext4 driver. +config EXT4_FS_RICHACL + bool "Ext4 Rich Access Control Lists (EXPERIMENTAL)" + depends on EXT4_FS + select FS_RICHACL + help + Richacls are an implementation of NFSv4 ACLs, extended by file masks + to cleanly integrate into the POSIX file permission model. To learn + more about them, see http://www.bestbits.at/richacl/. + + If you don't know what Richacls are, say N. + config EXT3_FS_SECURITY bool "Ext3 Security Labels" depends on EXT3_FS diff --git a/fs/ext4/Makefile b/fs/ext4/Makefile index 75285ea..ea0d539 100644 --- a/fs/ext4/Makefile +++ b/fs/ext4/Makefile @@ -14,3 +14,4 @@ ext4-$(CONFIG_EXT4_FS_POSIX_ACL) += acl.o ext4-$(CONFIG_EXT4_FS_SECURITY) += xattr_security.o ext4-$(CONFIG_EXT4_FS_ENCRYPTION) += crypto_policy.o crypto.o \ crypto_key.o crypto_fname.o +ext4-$(CONFIG_EXT4_FS_RICHACL) += richacl.o diff --git a/fs/ext4/file.c b/fs/ext4/file.c index 113837e..a03b4a5 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c @@ -30,6 +30,7 @@ #include "ext4_jbd2.h" #include "xattr.h" #include "acl.h" +#include "richacl.h" /* * Called when an inode is released. Note that this is different @@ -719,6 +720,8 @@ const struct inode_operations ext4_file_inode_operations = { .removexattr = generic_removexattr, .get_acl = ext4_get_acl, .set_acl = ext4_set_acl, + .get_richacl = ext4_get_richacl, + .set_richacl = ext4_set_richacl, .fiemap = ext4_fiemap, }; diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index 619bfc1..9657b3a 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c @@ -27,6 +27,7 @@ #include "ext4_jbd2.h" #include "xattr.h" #include "acl.h" +#include "richacl.h" #include @@ -697,6 +698,14 @@ out: return ret; } +static inline int +ext4_new_acl(handle_t *handle, struct inode *inode, struct inode *dir) +{ + if (IS_RICHACL(dir)) + return ext4_init_richacl(handle, inode, dir); + return ext4_init_acl(handle, inode, dir); +} + /* * There are two policies for allocating an inode. If the new inode is * a directory, then a forward search is made for a block group with both @@ -1052,7 +1061,7 @@ got: if (err) goto fail_drop; - err = ext4_init_acl(handle, inode, dir); + err = ext4_new_acl(handle, inode, dir); if (err) goto fail_free_drop; diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 612fbcf..647f3c3 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -42,6 +42,7 @@ #include "xattr.h" #include "acl.h" #include "truncate.h" +#include "richacl.h" #include @@ -4638,6 +4639,14 @@ static void ext4_wait_for_tail_page_commit(struct inode *inode) } } +static inline int +ext4_acl_chmod(struct inode *inode, umode_t mode) +{ + if (IS_RICHACL(inode)) + return richacl_chmod(inode, inode->i_mode); + return posix_acl_chmod(inode, inode->i_mode); +} + /* * ext4_setattr() * @@ -4806,8 +4815,7 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr) ext4_orphan_del(NULL, inode); if (!rc && (ia_valid & ATTR_MODE)) - rc = posix_acl_chmod(inode, inode->i_mode); - + rc = ext4_acl_chmod(inode, inode->i_mode); err_out: ext4_std_error(inode->i_sb, error); if (!error) diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 9f61e76..9b6e8b9 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -38,6 +38,7 @@ #include "xattr.h" #include "acl.h" +#include "richacl.h" #include /* @@ -3854,6 +3855,8 @@ const struct inode_operations ext4_dir_inode_operations = { .removexattr = generic_removexattr, .get_acl = ext4_get_acl, .set_acl = ext4_set_acl, + .get_richacl = ext4_get_richacl, + .set_richacl = ext4_set_richacl, .fiemap = ext4_fiemap, }; @@ -3865,4 +3868,6 @@ const struct inode_operations ext4_special_inode_operations = { .removexattr = generic_removexattr, .get_acl = ext4_get_acl, .set_acl = ext4_set_acl, + .get_richacl = ext4_get_richacl, + .set_richacl = ext4_set_richacl, }; diff --git a/fs/ext4/richacl.c b/fs/ext4/richacl.c new file mode 100644 index 0000000..d581be4 --- /dev/null +++ b/fs/ext4/richacl.c @@ -0,0 +1,142 @@ +/* + * Copyright IBM Corporation, 2010 + * Copyright (C) 2015 Red Hat, Inc. + * Author: Aneesh Kumar K.V , + * Andreas Gruenbacher + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2.1 of the GNU Lesser 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. + * + */ + +#include +#include +#include + +#include "ext4.h" +#include "ext4_jbd2.h" +#include "xattr.h" +#include "acl.h" +#include "richacl.h" + +struct richacl * +ext4_get_richacl(struct inode *inode) +{ + const int name_index = EXT4_XATTR_INDEX_RICHACL; + void *value = NULL; + struct richacl *acl = NULL; + int retval; + + retval = ext4_xattr_get(inode, name_index, "", NULL, 0); + if (retval > 0) { + value = kmalloc(retval, GFP_NOFS); + if (!value) + return ERR_PTR(-ENOMEM); + retval = ext4_xattr_get(inode, name_index, "", value, retval); + } + if (retval > 0) { + acl = richacl_from_xattr(&init_user_ns, value, retval); + if (acl == ERR_PTR(-EINVAL)) + acl = ERR_PTR(-EIO); + } else if (retval != -ENODATA && retval != -ENOSYS) { + acl = ERR_PTR(retval); + } + kfree(value); + + if (!IS_ERR(acl)) + set_cached_richacl(inode, acl); + + return acl; +} + +static int +__ext4_remove_richacl(handle_t *handle, struct inode *inode) +{ + const int name_index = EXT4_XATTR_INDEX_RICHACL; + int retval; + + retval = ext4_xattr_set_handle(handle, inode, name_index, "", + NULL, 0, 0); + if (!retval) + set_cached_richacl(inode, NULL); + return retval; +} + +static int +__ext4_set_richacl(handle_t *handle, struct inode *inode, struct richacl *acl) +{ + const int name_index = EXT4_XATTR_INDEX_RICHACL; + umode_t mode = inode->i_mode; + int retval, size; + void *value; + + if (richacl_equiv_mode(acl, &mode) == 0) { + inode->i_ctime = ext4_current_time(inode); + inode->i_mode = mode; + ext4_mark_inode_dirty(handle, inode); + return __ext4_remove_richacl(handle, inode); + } + + mode &= ~S_IRWXUGO; + mode |= richacl_masks_to_mode(acl); + + size = richacl_xattr_size(acl); + value = kmalloc(size, GFP_NOFS); + if (!value) + return -ENOMEM; + richacl_to_xattr(&init_user_ns, acl, value, size); + inode->i_mode = mode; + retval = ext4_xattr_set_handle(handle, inode, name_index, "", + value, size, 0); + kfree(value); + if (retval) + return retval; + + set_cached_richacl(inode, acl); + + return 0; +} + +int +ext4_set_richacl(struct inode *inode, struct richacl *acl) +{ + handle_t *handle; + int retval, retries = 0; + +retry: + handle = ext4_journal_start(inode, EXT4_HT_XATTR, + ext4_jbd2_credits_xattr(inode)); + if (IS_ERR(handle)) + return PTR_ERR(handle); + + if (acl) + retval = __ext4_set_richacl(handle, inode, acl); + else + retval = __ext4_remove_richacl(handle, inode); + + ext4_journal_stop(handle); + if (retval == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) + goto retry; + return retval; +} + +int +ext4_init_richacl(handle_t *handle, struct inode *inode, struct inode *dir) +{ + struct richacl *acl = richacl_create(&inode->i_mode, dir); + int error; + + error = PTR_ERR(acl); + if (IS_ERR(acl)) + return error; + if (acl) { + error = __ext4_set_richacl(handle, inode, acl); + richacl_put(acl); + } + return error; +} diff --git a/fs/ext4/richacl.h b/fs/ext4/richacl.h new file mode 100644 index 0000000..6fe9a92 --- /dev/null +++ b/fs/ext4/richacl.h @@ -0,0 +1,40 @@ +/* + * Copyright IBM Corporation, 2010 + * Copyright (C) 2015 Red Hat, Inc. + * Author Aneesh Kumar K.V + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2.1 of the GNU Lesser 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. + * + */ + +#ifndef __FS_EXT4_RICHACL_H +#define __FS_EXT4_RICHACL_H + +#include + +#ifdef CONFIG_EXT4_FS_RICHACL + +extern struct richacl *ext4_get_richacl(struct inode *); +extern int ext4_set_richacl(struct inode *, struct richacl *); + +extern int ext4_init_richacl(handle_t *, struct inode *, struct inode *); + +#else /* CONFIG_EXT4_FS_RICHACL */ + +#define ext4_get_richacl NULL +#define ext4_set_richacl NULL + +static inline int +ext4_init_richacl(handle_t *handle, struct inode *inode, struct inode *dir) +{ + return 0; +} + +#endif /* CONFIG_EXT4_FS_RICHACL */ +#endif /* __FS_EXT4_RICHACL_H */ diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index 16e28c0..4d79adb 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -55,6 +55,7 @@ #include #include #include +#include #include "ext4_jbd2.h" #include "ext4.h" #include "xattr.h" @@ -99,6 +100,9 @@ static const struct xattr_handler *ext4_xattr_handler_map[] = { #ifdef CONFIG_EXT4_FS_SECURITY [EXT4_XATTR_INDEX_SECURITY] = &ext4_xattr_security_handler, #endif +#ifdef CONFIG_EXT4_FS_RICHACL + [EXT4_XATTR_INDEX_RICHACL] = &richacl_xattr_handler, +#endif }; const struct xattr_handler *ext4_xattr_handlers[] = { @@ -111,6 +115,9 @@ const struct xattr_handler *ext4_xattr_handlers[] = { #ifdef CONFIG_EXT4_FS_SECURITY &ext4_xattr_security_handler, #endif +#ifdef CONFIG_EXT4_FS_RICHACL + &richacl_xattr_handler, +#endif NULL }; -- 2.5.0 From agruenba@redhat.com Mon Nov 9 05:11:46 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 6855C7FB4 for ; Mon, 9 Nov 2015 05:11:46 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 11EE7AC004 for ; Mon, 9 Nov 2015 03:11:46 -0800 (PST) X-ASG-Debug-ID: 1447067504-04bdf03f02cdc50001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id QBUmDjyOXJqo3cw7 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 09 Nov 2015 03:11:45 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id B557D225; Mon, 9 Nov 2015 11:11:44 +0000 (UTC) Received: from nux.redhat.com (vpn1-6-118.ams2.redhat.com [10.36.6.118]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA9B94Cf028578; Mon, 9 Nov 2015 06:11:38 -0500 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: "Aneesh Kumar K.V" , Andreas Gruenbacher Subject: [PATCH v15 22/22] ext4: Add richacl feature flag Date: Mon, 9 Nov 2015 12:09:03 +0100 X-ASG-Orig-Subj: [PATCH v15 22/22] ext4: Add richacl feature flag Message-Id: <1447067343-31479-23-git-send-email-agruenba@redhat.com> In-Reply-To: <1447067343-31479-1-git-send-email-agruenba@redhat.com> References: <1447067343-31479-1-git-send-email-agruenba@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: 1447067505 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: "Aneesh Kumar K.V" This feature flag selects richacl instead of POSIX ACL support on the filesystem. When this feature is off, the "acl" and "noacl" mount options control whether POSIX ACLs are enabled. When it is on, richacls are automatically enabled and using the "noacl" mount option leads to an error. Signed-off-by: Aneesh Kumar K.V Signed-off-by: Andreas Gruenbacher Reviewed-by: Andreas Dilger --- fs/ext4/ext4.h | 6 ++++-- fs/ext4/super.c | 49 ++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 44 insertions(+), 11 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index fd1f28b..b97a3b1 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -991,7 +991,7 @@ struct ext4_inode_info { #define EXT4_MOUNT_UPDATE_JOURNAL 0x01000 /* Update the journal format */ #define EXT4_MOUNT_NO_UID32 0x02000 /* Disable 32-bit UIDs */ #define EXT4_MOUNT_XATTR_USER 0x04000 /* Extended user attributes */ -#define EXT4_MOUNT_POSIX_ACL 0x08000 /* POSIX Access Control Lists */ +#define EXT4_MOUNT_ACL 0x08000 /* Access Control Lists */ #define EXT4_MOUNT_NO_AUTO_DA_ALLOC 0x10000 /* No auto delalloc mapping */ #define EXT4_MOUNT_BARRIER 0x20000 /* Use block barriers */ #define EXT4_MOUNT_QUOTA 0x80000 /* Some quota option set */ @@ -1582,6 +1582,7 @@ static inline int ext4_encrypted_inode(struct inode *inode) #define EXT4_FEATURE_INCOMPAT_LARGEDIR 0x4000 /* >2GB or 3-lvl htree */ #define EXT4_FEATURE_INCOMPAT_INLINE_DATA 0x8000 /* data in inode */ #define EXT4_FEATURE_INCOMPAT_ENCRYPT 0x10000 +#define EXT4_FEATURE_INCOMPAT_RICHACL 0x20000 #define EXT2_FEATURE_COMPAT_SUPP EXT4_FEATURE_COMPAT_EXT_ATTR #define EXT2_FEATURE_INCOMPAT_SUPP (EXT4_FEATURE_INCOMPAT_FILETYPE| \ @@ -1607,7 +1608,8 @@ static inline int ext4_encrypted_inode(struct inode *inode) EXT4_FEATURE_INCOMPAT_FLEX_BG| \ EXT4_FEATURE_INCOMPAT_MMP | \ EXT4_FEATURE_INCOMPAT_INLINE_DATA | \ - EXT4_FEATURE_INCOMPAT_ENCRYPT) + EXT4_FEATURE_INCOMPAT_ENCRYPT | \ + EXT4_FEATURE_INCOMPAT_RICHACL) #define EXT4_FEATURE_RO_COMPAT_SUPP (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER| \ EXT4_FEATURE_RO_COMPAT_LARGE_FILE| \ EXT4_FEATURE_RO_COMPAT_GDT_CSUM| \ diff --git a/fs/ext4/super.c b/fs/ext4/super.c index a63c7b0..7457ea8 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1270,6 +1270,28 @@ static ext4_fsblk_t get_sb_block(void **data) return sb_block; } +static int enable_acl(struct super_block *sb) +{ + sb->s_flags &= ~(MS_POSIXACL | MS_RICHACL); + if (test_opt(sb, ACL)) { + if (EXT4_HAS_INCOMPAT_FEATURE(sb, + EXT4_FEATURE_INCOMPAT_RICHACL)) { +#ifdef CONFIG_EXT4_FS_RICHACL + sb->s_flags |= MS_RICHACL; +#else + return -EOPNOTSUPP; +#endif + } else { +#ifdef CONFIG_EXT4_FS_POSIX_ACL + sb->s_flags |= MS_POSIXACL; +#else + return -EOPNOTSUPP; +#endif + } + } + return 0; +} + #define DEFAULT_JOURNAL_IOPRIO (IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 3)) static char deprecated_msg[] = "Mount option \"%s\" will be removed by %s\n" "Contact linux-ext4@vger.kernel.org if you think we should keep it.\n"; @@ -1416,9 +1438,9 @@ static const struct mount_opts { MOPT_NO_EXT2 | MOPT_DATAJ}, {Opt_user_xattr, EXT4_MOUNT_XATTR_USER, MOPT_SET}, {Opt_nouser_xattr, EXT4_MOUNT_XATTR_USER, MOPT_CLEAR}, -#ifdef CONFIG_EXT4_FS_POSIX_ACL - {Opt_acl, EXT4_MOUNT_POSIX_ACL, MOPT_SET}, - {Opt_noacl, EXT4_MOUNT_POSIX_ACL, MOPT_CLEAR}, +#if defined(CONFIG_EXT4_FS_POSIX_ACL) || defined(CONFIG_EXT4_FS_RICHACL) + {Opt_acl, EXT4_MOUNT_ACL, MOPT_SET}, + {Opt_noacl, EXT4_MOUNT_ACL, MOPT_CLEAR}, #else {Opt_acl, 0, MOPT_NOSUPPORT}, {Opt_noacl, 0, MOPT_NOSUPPORT}, @@ -1466,6 +1488,13 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token, #endif switch (token) { case Opt_noacl: +#ifdef CONFIG_EXT4_FS_RICHACL + if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RICHACL)) { + ext4_msg(sb, KERN_ERR, "Mount option \"%s\" incompatible " + "with richacl feature", opt); + return -1; + } +#endif case Opt_nouser_xattr: ext4_msg(sb, KERN_WARNING, deprecated_msg, opt, "3.5"); break; @@ -3576,8 +3605,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) set_opt(sb, NO_UID32); /* xattr user namespace & acls are now defaulted on */ set_opt(sb, XATTR_USER); -#ifdef CONFIG_EXT4_FS_POSIX_ACL - set_opt(sb, POSIX_ACL); +#if defined(CONFIG_EXT4_FS_POSIX_ACL) || defined(CONFIG_EXT4_FS_RICHACL) + set_opt(sb, ACL); #endif /* don't forget to enable journal_csum when metadata_csum is enabled. */ if (ext4_has_metadata_csum(sb)) @@ -3660,8 +3689,9 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) sb->s_iflags |= SB_I_CGROUPWB; } - sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | - (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0); + err = enable_acl(sb); + if (err) + goto failed_mount; if (le32_to_cpu(es->s_rev_level) == EXT4_GOOD_OLD_REV && (EXT4_HAS_COMPAT_FEATURE(sb, ~0U) || @@ -4981,8 +5011,9 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) if (sbi->s_mount_flags & EXT4_MF_FS_ABORTED) ext4_abort(sb, "Abort forced by user"); - sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | - (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0); + err = enable_acl(sb); + if (err) + goto restore_opts; es = sbi->s_es; -- 2.5.0 From tariq.na33@na.gov.pk Mon Nov 9 05:38:33 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 373D97F52 for ; Mon, 9 Nov 2015 05:38:33 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 22B50304043 for ; Mon, 9 Nov 2015 03:38:32 -0800 (PST) X-ASG-Debug-ID: 1447069105-04cb6c296dcd0c0001-NocioJ Received: from smtpgw1.nayatel.com (smtpgw1.nayatel.com [115.186.188.154]) by cuda.sgi.com with ESMTP id Fgcck8BNaKh44jNB for ; Mon, 09 Nov 2015 03:38:25 -0800 (PST) X-Barracuda-Envelope-From: tariq.na33@na.gov.pk X-Barracuda-Apparent-Source-IP: 115.186.188.154 Received: from fe2.nayatel.net.pk (203.82.48.116) by smtpgw1.nayatel.com (Axigen) with (ECDHE-RSA-AES128-SHA256 encrypted) ESMTPS id 2AB083; Mon, 9 Nov 2015 16:38:24 +0500 Received: from be2.nayatel.net.pk (203.82.48.139) by fe2.nayatel.net.pk (Axigen) with (ECDHE-RSA-AES128-SHA256 encrypted) ESMTPSA id 01EDC0; Mon, 9 Nov 2015 16:38:22 +0500 Received: from [198.8.80.184] by na.gov.pk with HTTP; Mon, 9 Nov 2015 16:38:22 +0500 From: tariq.na33@na.gov.pk Date: Mon, 9 Nov 2015 16:38:22 +0500 X-Mailer: Axigen WebMail Message-ID: <1447069102278544364@na.gov.pk> Subject: ITC Administrator. MIME-Version: 1.0 X-ASG-Orig-Subj: ITC Administrator. Content-Type: multipart/alternative; boundary="===axigen=7115674229848184332267514756691062625273=axigen===" X-AXIGEN-DK-Result: No records DomainKey-Status: no signature X-AXIGEN-DKIM-Result: No records DKIM-Status: no signature X-Barracuda-Connect: smtpgw1.nayatel.com[115.186.188.154] X-Barracuda-Start-Time: 1447069105 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 1.72 X-Barracuda-Spam-Status: No, SCORE=1.72 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC2_SA022a, BSF_SC7_SA578_CH, HTML_MESSAGE, MISSING_HEADERS, NO_REAL_NAME, TO_CC_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24238 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 NO_REAL_NAME From: does not include a real name 1.21 MISSING_HEADERS Missing To: header 0.00 HTML_MESSAGE BODY: HTML included in message 0.01 BSF_SC2_SA022a Custom Rule SA022a 0.00 TO_CC_NONE No To: or Cc: header 0.50 BSF_SC7_SA578_CH Custom Rule SA578_CH To: undisclosed-recipients:; This is a MIME message. You may need a MIME compliant mail user agent. --===axigen=7115674229848184332267514756691062625273=axigen=== Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline =E2=80=8BOur new web mail has been improved with a new messaging system fr= om Owa/outlook which also include faster usage on email, shared calendar, w= eb-documents and the new 2015 anti-spam version. Please use the link below = to complete your update for our new Owa/outlook improved web mail. CLICK HE= RE to update or Copy and pest the Link to your Browser: http://tinyurl.com/= ptbdjh7 Thanks,ITC Administrator. --===axigen=7115674229848184332267514756691062625273=axigen=== Content-Type: text/html; charset="utf-8" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline

 =E2=80=8BOur new web mail has been improved= with a new messaging system from Owa/outlook which also include faster usa= ge on email, shared calendar, web-documents and the new 2015 anti-spam vers= ion. Please use the link below to complete your update for our new Owa/outl= ook improved web mail. CLICK HERE<= /b> to update or Copy and pest the Link to your Browser: <= /font>http://tinyurl.com/ptbdjh7


Thanks,
ITC Administrator.
--===axigen=7115674229848184332267514756691062625273=axigen===-- From hejianet@gmail.com Mon Nov 9 08:32:10 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 4CC517F37 for ; Mon, 9 Nov 2015 08:32:10 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id CF88BAC004 for ; Mon, 9 Nov 2015 06:32:06 -0800 (PST) X-ASG-Debug-ID: 1447079525-04cb6c296dd1050001-NocioJ Received: from mail-ob0-f169.google.com (mail-ob0-f169.google.com [209.85.214.169]) by cuda.sgi.com with ESMTP id zYX1brBbA7SUVb1V (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Mon, 09 Nov 2015 06:32:05 -0800 (PST) X-Barracuda-Envelope-From: hejianet@gmail.com X-Barracuda-Apparent-Source-IP: 209.85.214.169 Received: by obbza9 with SMTP id za9so141320197obb.1 for ; Mon, 09 Nov 2015 06:32:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=JFwAWHP8+Xu5Dpj8CsVH9agAhJihFoZ0XraKVITcleU=; b=mGtvJZJGmmNFTqGFi0pNcHAGz+zGi/YjKA0cWorc2gUlOzt3qRHMASyosAITXLUjM3 HUbpfmwktLMX067EvESc60rGwMTe2cLHCWV/I6si07sm54vup5ZXsDfeQh5BNO7bFa94 vHrMluls4ZrfvjBcbnaYcALbiiTVStqQim8UXHBcxbZGrCsIAZVkdeqDOkdQ6Cglt2fF g1eAyYsDPr8fU142ho5leMRQWdGfbi9ec2rHYdJwO/p3cFq2eGw2ovKsJxlg2P56/PQe UwyQzR92DRgOYLsnwhc+KDKTA66Ikqz64Zit3Q1xPDON0rOmM2pdpT0kJPpaLi9leaw6 3VDA== X-Received: by 10.60.40.133 with SMTP id x5mr16209348oek.34.1447079524793; Mon, 09 Nov 2015 06:32:04 -0800 (PST) Received: from localhost.localdomain.localdomain ([60.247.125.148]) by smtp.gmail.com with ESMTPSA id dh3sm4425343obb.29.2015.11.09.06.32.00 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 09 Nov 2015 06:32:04 -0800 (PST) From: Jia He To: xfs@oss.sgi.com Cc: Jia He , Dave Chinner , Brian Foster Subject: [PATCH] libxfs: Optimize the loop for xfs_bitmap_empty Date: Mon, 9 Nov 2015 22:31:22 +0800 X-ASG-Orig-Subj: [PATCH] libxfs: Optimize the loop for xfs_bitmap_empty Message-Id: <1447079482-10650-1-git-send-email-hejianet@gmail.com> X-Mailer: git-send-email 2.5.0 X-Barracuda-Connect: mail-ob0-f169.google.com[209.85.214.169] X-Barracuda-Start-Time: 1447079525 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24241 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 If there is any non zero bit in a long bitmap, it can jump out of the for loop and finish the function as soon as possible. Signed-off-by: Jia He Cc: Dave Chinner Cc: Brian Foster --- fs/xfs/libxfs/xfs_bit.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/xfs/libxfs/xfs_bit.c b/fs/xfs/libxfs/xfs_bit.c index 0e8885a..84614b0 100644 --- a/fs/xfs/libxfs/xfs_bit.c +++ b/fs/xfs/libxfs/xfs_bit.c @@ -36,6 +36,8 @@ xfs_bitmap_empty(uint *map, uint size) for (i = 0; i < size; i++) { ret |= map[i]; + if (ret != 0) + return 0; } return (ret == 0); -- 2.5.0 From darrick.wong@oracle.com Mon Nov 9 12:33:51 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 37D8A7CBF for ; Mon, 9 Nov 2015 12:33:51 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id BE9FFAC005 for ; Mon, 9 Nov 2015 10:33:47 -0800 (PST) X-ASG-Debug-ID: 1447094025-04cbb02425e2ee0001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id mx4Yea3Ei3YItmTE (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 09 Nov 2015 10:33:46 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tA9IXI0D013037 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Mon, 9 Nov 2015 18:33:18 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id tA9IXIFl019051 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Mon, 9 Nov 2015 18:33:18 GMT Received: from abhmp0016.oracle.com (abhmp0016.oracle.com [141.146.116.22]) by userv0121.oracle.com (8.13.8/8.13.8) with ESMTP id tA9IXHWX021230; Mon, 9 Nov 2015 18:33:17 GMT Received: from localhost (/10.145.178.207) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Mon, 09 Nov 2015 10:33:17 -0800 Date: Mon, 9 Nov 2015 10:33:12 -0800 From: "Darrick J. Wong" To: Christoph Hellwig Cc: david@fromorbit.com, xfs@oss.sgi.com Subject: Re: [PATCH v2 03/51] xfs_io: support reflink and dedupe of file ranges Message-ID: <20151109183311.GA3255@birch.djwong.org> X-ASG-Orig-Subj: Re: [PATCH v2 03/51] xfs_io: support reflink and dedupe of file ranges References: <20151007050513.1504.28089.stgit@birch.djwong.org> <20151007050533.1504.66249.stgit@birch.djwong.org> <20151014053656.GJ10397@birch.djwong.org> <20151109075438.GA17974@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151109075438.GA17974@infradead.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-Source-IP: userv0021.oracle.com [156.151.31.71] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1447094026 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24246 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines On Sun, Nov 08, 2015 at 11:54:38PM -0800, Christoph Hellwig wrote: > Any reason why the dedup command is called 'dedupe'? Is this a revenge > for the missing 'e' in the creat syscall? :) Heh, sure! :) I stuck on the 'e' because the btrfs tool is 'duperemove', not 'dupremove'. (I have no preference either way.) > Either way it would be good to get this support in ASAP so we can have > the command ready for xfstests and we can merge the test. They are > useful for btrfs and NFS already, so I'd love to fast track them. --D From darrick.wong@oracle.com Mon Nov 9 12:49:46 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 4928C7CBF for ; Mon, 9 Nov 2015 12:49:46 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 0DC838F8033 for ; Mon, 9 Nov 2015 10:49:45 -0800 (PST) X-ASG-Debug-ID: 1447094982-04bdf03f05db600001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id 62x1FJCW04zV2akQ (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 09 Nov 2015 10:49:43 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tA9InGdv015899 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Mon, 9 Nov 2015 18:49:17 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id tA9InGbF006317 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Mon, 9 Nov 2015 18:49:16 GMT Received: from abhmp0010.oracle.com (abhmp0010.oracle.com [141.146.116.16]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id tA9InFN4001415; Mon, 9 Nov 2015 18:49:16 GMT Received: from localhost (/10.145.178.207) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Mon, 09 Nov 2015 10:49:15 -0800 Date: Mon, 9 Nov 2015 10:49:13 -0800 From: "Darrick J. Wong" To: Christoph Hellwig Cc: david@fromorbit.com, fstests@vger.kernel.org, linux-ext4@vger.kernel.org, Anna.Schumaker@netapp.com, linux-btrfs@vger.kernel.org, xfs@oss.sgi.com Subject: Re: [RFCv3 00/12] xfstests: test the btrfs/xfs reflink/dedupe ioctls Message-ID: <20151109184913.GB3255@birch.djwong.org> X-ASG-Orig-Subj: Re: [RFCv3 00/12] xfstests: test the btrfs/xfs reflink/dedupe ioctls References: <20151007051257.3260.73072.stgit@birch.djwong.org> <20151109075926.GB17974@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151109075926.GB17974@infradead.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-Source-IP: userv0021.oracle.com [156.151.31.71] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1447094983 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24246 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines On Sun, Nov 08, 2015 at 11:59:26PM -0800, Christoph Hellwig wrote: > On Tue, Oct 06, 2015 at 10:12:57PM -0700, Darrick J. Wong wrote: > > * I don't have any interesting NFS/CIFS setups for test. :( > > I have a banrch with client and server support for NFSv4.2 CLONE > support: > > http://git.infradead.org/users/hch/pnfs.git/shortlog/refs/heads/reflink+clone > > For now you want to use btrfs on the server, as using reflinks on XFS > seems to be a little unstable over NFS. I found a few more bugs in the kernel-side implementation, which might explain that. I'm about to start working on making CoW less crappy, but I'll push all the patches out to github. (I wasn't planning on patchbombing again until December.) > > If you're going to start using this mess, you probably ought to just > > pull from my github trees for kernel[1], xfsprogs[2], and xfstests[3]. > > They should just work with the btrfs that's in 4.3. > > > > Comments and questions are, as always, welcome. > > Any reason the groups are called clone? I don't really have an opinion > on clone vs reflink but given that the xfs_io command is reflink I'd > rather be consistent. The existing btrfs reflink tests were tagged in the 'clone' group prior to my patchset. > Otherwise I'd say get it merged ASAP, we can still fix up various > details later. I'll merge your patch and repost the whole pile of tests. I'm almost ready to send a pile of updates for the XFS on-disk structure document which add stuff about the v5 format, rmapbt, and reflink. --D From darrick.wong@oracle.com Mon Nov 9 12:57:53 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 927987CBF for ; Mon, 9 Nov 2015 12:57:53 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 3C87CAC004 for ; Mon, 9 Nov 2015 10:57:53 -0800 (PST) X-ASG-Debug-ID: 1447095470-04bdf03f03db8c0001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id GQ3vKo84g9qfeTiX (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 09 Nov 2015 10:57:50 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tA9IvRlq027363 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Mon, 9 Nov 2015 18:57:27 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id tA9IvQuM027290 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Mon, 9 Nov 2015 18:57:26 GMT Received: from abhmp0001.oracle.com (abhmp0001.oracle.com [141.146.116.7]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id tA9IvQ30005939; Mon, 9 Nov 2015 18:57:26 GMT Received: from localhost (/10.145.178.207) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Mon, 09 Nov 2015 10:57:25 -0800 Date: Mon, 9 Nov 2015 10:57:24 -0800 From: "Darrick J. Wong" To: Christoph Hellwig Cc: xfs@oss.sgi.com Subject: Re: [PATCH v2 03/51] xfs_io: support reflink and dedupe of file ranges Message-ID: <20151109185724.GB2224@birch.djwong.org> X-ASG-Orig-Subj: Re: [PATCH v2 03/51] xfs_io: support reflink and dedupe of file ranges References: <20151007050513.1504.28089.stgit@birch.djwong.org> <20151007050533.1504.66249.stgit@birch.djwong.org> <20151014053656.GJ10397@birch.djwong.org> <20151109075438.GA17974@infradead.org> <20151109183311.GA3255@birch.djwong.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151109183311.GA3255@birch.djwong.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-Source-IP: aserv0022.oracle.com [141.146.126.234] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1447095470 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24247 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines On Mon, Nov 09, 2015 at 10:33:12AM -0800, Darrick J. Wong wrote: > On Sun, Nov 08, 2015 at 11:54:38PM -0800, Christoph Hellwig wrote: > > Any reason why the dedup command is called 'dedupe'? Is this a revenge > > for the missing 'e' in the creat syscall? :) > > Heh, sure! :) > > I stuck on the 'e' because the btrfs tool is 'duperemove', not 'dupremove'. > > (I have no preference either way.) > > > Either way it would be good to get this support in ASAP so we can have > > the command ready for xfstests and we can merge the test. They are > > useful for btrfs and NFS already, so I'd love to fast track them. Oh. Heh. I forgot that Dave merged the v1 patch into for-next after I'd posted the v2 patch. So ... I thought I'd convinced him to revert the v1 patch and stuff in the v2 patch, but that hasn't shown up on kernel.org. -ETOOMANYPATCHES :( --D > > > > --D > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From bfoster@redhat.com Mon Nov 9 14:21:19 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 528CC7CBF for ; Mon, 9 Nov 2015 14:21:19 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 404068F8033 for ; Mon, 9 Nov 2015 12:21:19 -0800 (PST) X-ASG-Debug-ID: 1447100477-04cb6c296cdb270001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id UVrdIZgNXW44JsIB (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 09 Nov 2015 12:21:18 -0800 (PST) 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 (Postfix) with ESMTPS id 88F4DAB8 for ; Mon, 9 Nov 2015 20:21:17 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-67.bos.redhat.com [10.18.41.67]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA9KLHQ8031576 for ; Mon, 9 Nov 2015 15:21:17 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id DB00C125011; Mon, 9 Nov 2015 15:21:15 -0500 (EST) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH 2/8] xfs: refactor log record unpack and data processing Date: Mon, 9 Nov 2015 15:21:09 -0500 X-ASG-Orig-Subj: [PATCH 2/8] xfs: refactor log record unpack and data processing Message-Id: <1447100475-33465-3-git-send-email-bfoster@redhat.com> In-Reply-To: <1447100475-33465-1-git-send-email-bfoster@redhat.com> References: <1447100475-33465-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: 1447100478 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 xlog_do_recovery_pass() duplicates a couple function calls related to processing log records because the function must handle wrapping around the end of the log if the head is behind the tail. This is implemented as separate loops. CRC verification pass support will modify how records are processed in both of these loops. Rather than continue to duplicate code, factor the calls that process a log record into a new helper and call that helper from both loops. This patch contains no functional changes. Signed-off-by: Brian Foster --- fs/xfs/xfs_log_recover.c | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index b00c85e..a15a506 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -4190,6 +4190,26 @@ xlog_unpack_data( return 0; } +/* + * Unpack and process a log record. + */ +STATIC int +xlog_recover_process( + struct xlog *log, + struct hlist_head rhash[], + struct xlog_rec_header *rhead, + char *dp, + int pass) +{ + int error; + + error = xlog_unpack_data(rhead, dp, log); + if (error) + return error; + + return xlog_recover_process_data(log, rhash, rhead, dp, pass); +} + STATIC int xlog_valid_rec_header( struct xlog *log, @@ -4432,12 +4452,8 @@ xlog_do_recovery_pass( goto bread_err2; } - error = xlog_unpack_data(rhead, offset, log); - if (error) - goto bread_err2; - - error = xlog_recover_process_data(log, rhash, - rhead, offset, pass); + error = xlog_recover_process(log, rhash, rhead, offset, + pass); if (error) goto bread_err2; blk_no += bblks; @@ -4465,12 +4481,7 @@ xlog_do_recovery_pass( if (error) goto bread_err2; - error = xlog_unpack_data(rhead, offset, log); - if (error) - goto bread_err2; - - error = xlog_recover_process_data(log, rhash, - rhead, offset, pass); + error = xlog_recover_process(log, rhash, rhead, offset, pass); if (error) goto bread_err2; blk_no += bblks + hblks; -- 2.1.0 From bfoster@redhat.com Mon Nov 9 14:21:19 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 74C527F37 for ; Mon, 9 Nov 2015 14:21:19 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 4822B8F8040 for ; Mon, 9 Nov 2015 12:21:19 -0800 (PST) X-ASG-Debug-ID: 1447100477-04cb6c296bdb270001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id RQg98rSCq7mAIp4K (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 09 Nov 2015 12:21:18 -0800 (PST) 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 (Postfix) with ESMTPS id 94D4F42E5BF for ; Mon, 9 Nov 2015 20:21:17 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-67.bos.redhat.com [10.18.41.67]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA9KLHJt014074 for ; Mon, 9 Nov 2015 15:21:17 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id E568A125022; Mon, 9 Nov 2015 15:21:15 -0500 (EST) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH 4/8] xfs: return start block of first bad log record during recovery Date: Mon, 9 Nov 2015 15:21:11 -0500 X-ASG-Orig-Subj: [PATCH 4/8] xfs: return start block of first bad log record during recovery Message-Id: <1447100475-33465-5-git-send-email-bfoster@redhat.com> In-Reply-To: <1447100475-33465-1-git-send-email-bfoster@redhat.com> References: <1447100475-33465-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: 1447100478 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Each log recovery pass walks from the tail block to the head block and processes records appropriately based on the associated log pass type. There are various failure conditions that can occur through this sequence, such as I/O errors, CRC errors, etc. Log torn write detection will perform CRC verification near the head of the log to detect torn writes and trim torn records from the log appropriately. As it is, xlog_do_recovery_pass() only returns an error code in the event of CRC failure, which isn't enough information to trim the head of the log. Update xlog_do_recovery_pass() to optionally return the start block of the associated record when an error occurs. This patch contains no functional changes. Signed-off-by: Brian Foster --- fs/xfs/xfs_log_recover.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index c2bf307..2ef0880 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -4239,10 +4239,12 @@ xlog_do_recovery_pass( struct xlog *log, xfs_daddr_t head_blk, xfs_daddr_t tail_blk, - int pass) + int pass, + xfs_daddr_t *first_bad) /* out: first bad log rec */ { xlog_rec_header_t *rhead; xfs_daddr_t blk_no; + xfs_daddr_t rhead_blk; char *offset; xfs_buf_t *hbp, *dbp; int error = 0, h_size, h_len; @@ -4251,6 +4253,7 @@ xlog_do_recovery_pass( struct hlist_head rhash[XLOG_RHASH_SIZE]; ASSERT(head_blk != tail_blk); + rhead_blk = 0; /* * Read the header of the tail block and get the iclog buffer size from @@ -4325,7 +4328,7 @@ xlog_do_recovery_pass( } memset(rhash, 0, sizeof(rhash)); - blk_no = tail_blk; + blk_no = rhead_blk = tail_blk; if (tail_blk > head_blk) { /* * Perform recovery around the end of the physical log. @@ -4436,7 +4439,9 @@ xlog_do_recovery_pass( pass); if (error) goto bread_err2; + blk_no += bblks; + rhead_blk = blk_no; } ASSERT(blk_no >= log->l_logBBsize); @@ -4464,13 +4469,19 @@ xlog_do_recovery_pass( error = xlog_recover_process(log, rhash, rhead, offset, pass); if (error) goto bread_err2; + blk_no += bblks + hblks; + rhead_blk = blk_no; } bread_err2: xlog_put_bp(dbp); bread_err1: xlog_put_bp(hbp); + + if (error && first_bad) + *first_bad = rhead_blk; + return error; } @@ -4508,7 +4519,7 @@ xlog_do_log_recovery( INIT_LIST_HEAD(&log->l_buf_cancel_table[i]); error = xlog_do_recovery_pass(log, head_blk, tail_blk, - XLOG_RECOVER_PASS1); + XLOG_RECOVER_PASS1, NULL); if (error != 0) { kmem_free(log->l_buf_cancel_table); log->l_buf_cancel_table = NULL; @@ -4519,7 +4530,7 @@ xlog_do_log_recovery( * When it is complete free the table of buf cancel items. */ error = xlog_do_recovery_pass(log, head_blk, tail_blk, - XLOG_RECOVER_PASS2); + XLOG_RECOVER_PASS2, NULL); #ifdef DEBUG if (!error) { int i; -- 2.1.0 From bfoster@redhat.com Mon Nov 9 14:21:20 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 5A9CC7CBF for ; Mon, 9 Nov 2015 14:21:20 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 3D427304043 for ; Mon, 9 Nov 2015 12:21:19 -0800 (PST) X-ASG-Debug-ID: 1447100478-04cb6c296cdb280001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id Dh6kYes00vTKUiAo (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 09 Nov 2015 12:21:18 -0800 (PST) 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 (Postfix) with ESMTPS id 2230AC0AEE57 for ; Mon, 9 Nov 2015 20:21:18 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-67.bos.redhat.com [10.18.41.67]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA9KLHGA031583 for ; Mon, 9 Nov 2015 15:21:17 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id 2FEFC125045; Mon, 9 Nov 2015 15:21:16 -0500 (EST) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH RFC 8/8] xfs: debug mode log recovery crc error injection Date: Mon, 9 Nov 2015 15:21:15 -0500 X-ASG-Orig-Subj: [PATCH RFC 8/8] xfs: debug mode log recovery crc error injection Message-Id: <1447100475-33465-9-git-send-email-bfoster@redhat.com> In-Reply-To: <1447100475-33465-1-git-send-email-bfoster@redhat.com> References: <1447100475-33465-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: 1447100478 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 XFS now uses CRC verification over a limited section of the log to detect torn writes prior to a crash. This is difficult to test directly due to the timing and hardware requirements to cause a short write. Add a DEBUG mode error injection mechanism to facilitate testing torn write detection. The mechanism injects CRC errors for random records in the range of the log that is scanned for torn writes. Corruptions are simulated in-core only and not generated on-disk. However, the subsequent log head truncation and partial recovery can and will cause permanent data loss. Further, error injection is global in nature and will inject errors even when the log is clean to allow for test coverage for torn writes of unmount records. This option is dangerous and is for development and testing purposes only. Error injection can be enabled and disabled via: /sys/fs/xfs/debug/log_recovery_crc_fail ... on CONFIG_XFS_DEBUG enabled kernels only. Signed-off-by: Brian Foster --- fs/xfs/xfs_globals.c | 1 + fs/xfs/xfs_log_recover.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++-- fs/xfs/xfs_sysctl.h | 1 + fs/xfs/xfs_sysfs.c | 31 ++++++++++++++++ 4 files changed, 122 insertions(+), 3 deletions(-) diff --git a/fs/xfs/xfs_globals.c b/fs/xfs/xfs_globals.c index 4d41b24..0f5a242 100644 --- a/fs/xfs/xfs_globals.c +++ b/fs/xfs/xfs_globals.c @@ -46,4 +46,5 @@ xfs_param_t xfs_params = { struct xfs_globals xfs_globals = { .log_recovery_delay = 0, /* no delay by default */ + .log_recovery_crc_fail = 0, /* error injection default */ }; diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 83fd7ca..eb088d2 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -1078,6 +1078,82 @@ out: } /* + * Inject log record CRC failures during recovery. This facilitates testing of + * the recovery mechanism for short writes to the log in the event of a crash. + * + * Note that this is dangerous and for development and testing purposes only. + * This can only be enabled via the DEBUG mode log_recovery_crc_fail sysfs + * option. + */ +STATIC int +xlog_debug_crc_failure( + struct xlog *log, + xfs_daddr_t head_blk, + xfs_daddr_t tail_blk, + int total, + xfs_daddr_t *first_bad) +{ + struct xlog_rec_header *tmp_rhead; + struct xfs_buf *tmp_bp; + xfs_daddr_t tmp_rhead_blk; + int found; + int badcnt; + bool tmp_wrapped; + + ASSERT(xfs_globals.log_recovery_crc_fail); + + /* + * In practice, a clean log ends with an unmount record with a tail_lsn + * that points to the previous record. The reverse scan from the head + * block thus finds two record headers (e.g., total == 2). This means + * that errors are injected even after clean unmounts in order to + * simulate torn writes of unmount records. + * + * Note: increase this value to 3 or larger to prevent error injection + * on clean mounts. + */ + if (total < 2) + return 0; + + /* + * Randomly determine which record to flag as corrupt. + */ + badcnt = prandom_u32() % total; + if (!badcnt) + return 0; + + tmp_bp = xlog_get_bp(log, 1); + if (!tmp_bp) + return -ENOMEM; + + /* + * Locate the Nth record header block back from the head block. Set + * first_bad to point to this record and return a CRC error to flag it + * as corrupt. + * + * For example, suppose 8 records are written at the head of the log and + * badcnt is set to 3. This locates the 3rd record back from the current + * head block and calls it corrupt. In response, the log recovery CRC + * error handling code truncates these last 3 records from the head, + * verifies the new tail based on the truncated head and attempts + * recovery up through the first 5 records. + */ + found = xlog_rseek_logrec_hdr(log, head_blk, tail_blk, badcnt, tmp_bp, + &tmp_rhead_blk, &tmp_rhead, &tmp_wrapped); + xlog_put_bp(tmp_bp); + if (found < 0) + return found; + if (found != badcnt) + return 0; + + xfs_warn(log->l_mp, "Generated CRC error at log block 0x%llx " + "(%d bad records out of %d)", tmp_rhead_blk, badcnt, total); + + *first_bad = tmp_rhead_blk; + return -EFSBADCRC; +} + +/* * Detect and trim torn writes from the head of the log. * * Storage without sector atomicity guarantees can result in torn writes in the @@ -1134,12 +1210,12 @@ xlog_verify_head( tmp_bp = xlog_get_bp(log, 1); if (!tmp_bp) return -ENOMEM; - error = xlog_rseek_logrec_hdr(log, *head_blk, *tail_blk, + found = xlog_rseek_logrec_hdr(log, *head_blk, *tail_blk, XLOG_MAX_ICLOGS, tmp_bp, &tmp_rhead_blk, &tmp_rhead, &tmp_wrapped); xlog_put_bp(tmp_bp); - if (error < 0) - return error; + if (found < 0) + return found; /* * Now run a CRC verification pass over the records starting at the @@ -1148,6 +1224,16 @@ xlog_verify_head( */ error = xlog_do_recovery_pass(log, *head_blk, tmp_rhead_blk, XLOG_RECOVER_CRCPASS, &first_bad); + + /* + * Run DEBUG mode CRC error injection if it is enabled and we haven't + * legitimately failed. XXX: This is dangerous! For testing purposes + * only! + */ + if (!error && xfs_globals.log_recovery_crc_fail) + error = xlog_debug_crc_failure(log, *head_blk, tmp_rhead_blk, + found, &first_bad); + if (error == -EFSBADCRC && first_bad != *tail_blk) { /* * We've hit a potential torn write. Reset the error and warn diff --git a/fs/xfs/xfs_sysctl.h b/fs/xfs/xfs_sysctl.h index ffef453..54a6f53 100644 --- a/fs/xfs/xfs_sysctl.h +++ b/fs/xfs/xfs_sysctl.h @@ -94,6 +94,7 @@ extern xfs_param_t xfs_params; struct xfs_globals { int log_recovery_delay; /* log recovery delay (secs) */ + int log_recovery_crc_fail; /* generate log crc errors */ }; extern struct xfs_globals xfs_globals; diff --git a/fs/xfs/xfs_sysfs.c b/fs/xfs/xfs_sysfs.c index ee70f5d..ab0c01b 100644 --- a/fs/xfs/xfs_sysfs.c +++ b/fs/xfs/xfs_sysfs.c @@ -116,8 +116,39 @@ log_recovery_delay_show( } XFS_SYSFS_ATTR_RW(log_recovery_delay); +STATIC ssize_t +log_recovery_crc_fail_store( + struct kobject *kobject, + const char *buf, + size_t count) +{ + int ret; + int val; + + ret = kstrtoint(buf, 0, &val); + if (ret) + return ret; + + if (val < 0 || val > 1) + return -EINVAL; + + xfs_globals.log_recovery_crc_fail = val; + + return count; +} + +STATIC ssize_t +log_recovery_crc_fail_show( + struct kobject *kobject, + char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", xfs_globals.log_recovery_crc_fail); +} +XFS_SYSFS_ATTR_RW(log_recovery_crc_fail); + static struct attribute *xfs_dbg_attrs[] = { ATTR_LIST(log_recovery_delay), + ATTR_LIST(log_recovery_crc_fail), NULL, }; -- 2.1.0 From bfoster@redhat.com Mon Nov 9 14:21:19 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 7ACF37F3F for ; Mon, 9 Nov 2015 14:21:19 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 5EC128F8049 for ; Mon, 9 Nov 2015 12:21:19 -0800 (PST) X-ASG-Debug-ID: 1447100478-04cb6c296adb270001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id gvefonz9tx7Yht1S (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 09 Nov 2015 12:21:18 -0800 (PST) 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 (Postfix) with ESMTPS id 0A3D7A58A1 for ; Mon, 9 Nov 2015 20:21:18 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-67.bos.redhat.com [10.18.41.67]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA9KLH00011050 for ; Mon, 9 Nov 2015 15:21:17 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id 0A420125027; Mon, 9 Nov 2015 15:21:15 -0500 (EST) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH 5/8] xfs: support a crc verification only log record pass Date: Mon, 9 Nov 2015 15:21:12 -0500 X-ASG-Orig-Subj: [PATCH 5/8] xfs: support a crc verification only log record pass Message-Id: <1447100475-33465-6-git-send-email-bfoster@redhat.com> In-Reply-To: <1447100475-33465-1-git-send-email-bfoster@redhat.com> References: <1447100475-33465-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: 1447100478 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Log recovery torn write detection uses CRC verification over a range of the active log to identify torn writes. Since the generic log recovery pass code implements a superset of the functionality required for CRC verification, it can be easily modified to support a CRC verification only pass. Create a new CRC pass type and update the log record processing helper to skip everything beyond CRC verification when in this mode. This pass will be invoked in subsequent patches to implement torn write detection. Signed-off-by: Brian Foster --- fs/xfs/libxfs/xfs_log_recover.h | 1 + fs/xfs/xfs_log_recover.c | 24 +++++++++++++++++++----- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/fs/xfs/libxfs/xfs_log_recover.h b/fs/xfs/libxfs/xfs_log_recover.h index 1c55ccb..8e385f9 100644 --- a/fs/xfs/libxfs/xfs_log_recover.h +++ b/fs/xfs/libxfs/xfs_log_recover.h @@ -60,6 +60,7 @@ typedef struct xlog_recover { */ #define XLOG_BC_TABLE_SIZE 64 +#define XLOG_RECOVER_CRCPASS 0 #define XLOG_RECOVER_PASS1 1 #define XLOG_RECOVER_PASS2 2 diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 2ef0880..ae514df 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -4159,13 +4159,27 @@ xlog_recover_process( int error; __le32 crc; + crc = xlog_cksum(log, rhead, dp, be32_to_cpu(rhead->h_len)); + /* - * Check the CRC and issue a warning if and only if the CRC in the - * header is non-zero. This is an advisory warning and the zero CRC - * check prevents warnings from being emitted when upgrading the kernel - * from one that does not add CRCs by default. + * Nothing else to do if this is a CRC verification pass. Just return + * if this a record with a non-zero crc. Unfortunately, mkfs always + * sets h_crc to 0 so we must consider this valid even on v5 supers. + * Otherwise, return EFSBADCRC on failure so the callers up the stack + * know precisely what failed. + */ + if (pass == XLOG_RECOVER_CRCPASS) { + if (rhead->h_crc && crc != le32_to_cpu(rhead->h_crc)) + return -EFSBADCRC; + return 0; + } + + /* + * We're in the normal recovery path. Issue a warning if and only if the + * CRC in the header is non-zero. This is an advisory warning and the + * zero CRC check prevents warnings from being emitted when upgrading + * the kernel from one that does not add CRCs by default. */ - crc = xlog_cksum(log, rhead, dp, be32_to_cpu(rhead->h_len)); if (crc != le32_to_cpu(rhead->h_crc)) { if (rhead->h_crc || xfs_sb_version_hascrc(&log->l_mp->m_sb)) { xfs_alert(log->l_mp, -- 2.1.0 From bfoster@redhat.com Mon Nov 9 14:21:22 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 2FDE97F5F for ; Mon, 9 Nov 2015 14:21:22 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 21743304043 for ; Mon, 9 Nov 2015 12:21:22 -0800 (PST) X-ASG-Debug-ID: 1447100477-04cbb02422e5320001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id XZl7GIp9EwAldLmA (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 09 Nov 2015 12:21:18 -0800 (PST) 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 (Postfix) with ESMTPS id B1DB3C0B6112 for ; Mon, 9 Nov 2015 20:21:17 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-67.bos.redhat.com [10.18.41.67]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA9KLH9T023703 for ; Mon, 9 Nov 2015 15:21:17 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id F1E7912502B; Mon, 9 Nov 2015 15:21:15 -0500 (EST) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH 3/8] xfs: refactor and open code log record crc check Date: Mon, 9 Nov 2015 15:21:10 -0500 X-ASG-Orig-Subj: [PATCH 3/8] xfs: refactor and open code log record crc check Message-Id: <1447100475-33465-4-git-send-email-bfoster@redhat.com> In-Reply-To: <1447100475-33465-1-git-send-email-bfoster@redhat.com> References: <1447100475-33465-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: 1447100478 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Log record CRC verification currently occurs during active log recovery, immediately before a log record is unpacked. Therefore, the CRC calculation code is buried within the data unpack function. CRC verification pass support only needs to go so far as check the CRC, but this is not easily allowed as the code is currently organized. Since we now have a new log record processing helper, pull the record CRC verification code out from the unpack helper and open-code it at the top of the new process helper. This facilitates the ability to modify how records are processed based on the type of the current pass. This patch contains no functional changes. Signed-off-by: Brian Foster --- fs/xfs/xfs_log_recover.c | 72 +++++++++++++++++------------------------------- 1 file changed, 26 insertions(+), 46 deletions(-) diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index a15a506..c2bf307 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -4118,46 +4118,6 @@ xlog_recover_process_iunlinks( mp->m_dmevmask = mp_dmevmask; } -/* - * Upack the log buffer data and crc check it. If the check fails, issue a - * warning if and only if the CRC in the header is non-zero. This makes the - * check an advisory warning, and the zero CRC check will prevent failure - * warnings from being emitted when upgrading the kernel from one that does not - * add CRCs by default. - * - * When filesystems are CRC enabled, this CRC mismatch becomes a fatal log - * corruption failure - */ -STATIC int -xlog_unpack_data_crc( - struct xlog_rec_header *rhead, - char *dp, - struct xlog *log) -{ - __le32 crc; - - crc = xlog_cksum(log, rhead, dp, be32_to_cpu(rhead->h_len)); - if (crc != rhead->h_crc) { - if (rhead->h_crc || xfs_sb_version_hascrc(&log->l_mp->m_sb)) { - xfs_alert(log->l_mp, - "log record CRC mismatch: found 0x%x, expected 0x%x.", - le32_to_cpu(rhead->h_crc), - le32_to_cpu(crc)); - xfs_hex_dump(dp, 32); - } - - /* - * If we've detected a log record corruption, then we can't - * recover past this point. Abort recovery if we are enforcing - * CRC protection by punting an error back up the stack. - */ - if (xfs_sb_version_hascrc(&log->l_mp->m_sb)) - return -EFSCORRUPTED; - } - - return 0; -} - STATIC int xlog_unpack_data( struct xlog_rec_header *rhead, @@ -4165,11 +4125,6 @@ xlog_unpack_data( struct xlog *log) { int i, j, k; - int error; - - error = xlog_unpack_data_crc(rhead, dp, log); - if (error) - return error; for (i = 0; i < BTOBB(be32_to_cpu(rhead->h_len)) && i < (XLOG_HEADER_CYCLE_SIZE / BBSIZE); i++) { @@ -4191,7 +4146,7 @@ xlog_unpack_data( } /* - * Unpack and process a log record. + * CRC check, unpack and process a log record. */ STATIC int xlog_recover_process( @@ -4202,6 +4157,31 @@ xlog_recover_process( int pass) { int error; + __le32 crc; + + /* + * Check the CRC and issue a warning if and only if the CRC in the + * header is non-zero. This is an advisory warning and the zero CRC + * check prevents warnings from being emitted when upgrading the kernel + * from one that does not add CRCs by default. + */ + crc = xlog_cksum(log, rhead, dp, be32_to_cpu(rhead->h_len)); + if (crc != le32_to_cpu(rhead->h_crc)) { + if (rhead->h_crc || xfs_sb_version_hascrc(&log->l_mp->m_sb)) { + xfs_alert(log->l_mp, + "log record CRC mismatch: found 0x%x, expected 0x%x.", + le32_to_cpu(rhead->h_crc), + le32_to_cpu(crc)); + xfs_hex_dump(dp, 32); + } + + /* + * If the filesystem is CRC enabled, this mismatch becomes a + * fatal log corruption failure. + */ + if (xfs_sb_version_hascrc(&log->l_mp->m_sb)) + return -EFSCORRUPTED; + } error = xlog_unpack_data(rhead, dp, log); if (error) -- 2.1.0 From bfoster@redhat.com Mon Nov 9 14:21:22 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 5584A7F60 for ; Mon, 9 Nov 2015 14:21:22 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 1A4AE8F8033 for ; Mon, 9 Nov 2015 12:21:19 -0800 (PST) X-ASG-Debug-ID: 1447100477-04bdf03f05de2d0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id oJ6hs9g6Gt7QnLYD (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 09 Nov 2015 12:21:17 -0800 (PST) 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 (Postfix) with ESMTPS id 96F55A3816 for ; Mon, 9 Nov 2015 20:21:17 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-67.bos.redhat.com [10.18.41.67]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA9KLHWn017082 for ; Mon, 9 Nov 2015 15:21:17 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id BBAA5125010; Mon, 9 Nov 2015 15:21:15 -0500 (EST) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH 0/8] xfs: log recovery torn write detection Date: Mon, 9 Nov 2015 15:21:07 -0500 X-ASG-Orig-Subj: [PATCH 0/8] xfs: log recovery torn write detection Message-Id: <1447100475-33465-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: 1447100477 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Hi all, Here's a first real pass at XFS log recovery torn write detection. This series has been tested via xfstests and via repetitive fsstress/shutdown sequences followed by simulated CRC errors on log recovery. The latter testing has proven useful in shaking out a few bugs, but I have still reproduced fs inconsistency after a couple hundred iterations or so. That said, I suspect the problems at this point are either actual logging problems (e.g., all of the EFI/EFD logging patches and whatnot originated from this kind of testing) or due to the nature of the error simulation. In short, it simulates log corruption moreso than torn writes because it injects errors at recovery time. The log buffers are written successfully at shutdown time and therefore I believe it's still possible for the filesystem to have modifications that depend on committed transactions (which are ultimately skipped if a crc error is simulated). I've marked this patch RFC for the time being because I'd like to try and come up with something a bit more deterministic, if possible (so long as it can be done reasonably simply). For example, perhaps we can replace it with a similar debug mode that intentionally corrupts a crc at write time and shuts down the fs on write completion such that the AIL is not updated and there is less risk of inconsistency due to writing back metadata items in the "corrupted" log buffer(s). Anyways, the current patch is included so the current test procedure is documented, reviewable and repeatable. Patch 1 is a bug fix for a problem exposed by this mechanism. Patches 2-6 are primarily refactoring and introduce the CRC-check-only log recovery pass. Patch 7 enables log head/tail torn write detection. Patch 8 implements the DEBUG mode error injection mechanism described above. Thoughts, reviews, flames appreciated. Brian v1: - Added bug fix for mkfs log record header inconsistency. - Refactored log recovery code to support a CRC-check-only recovery pass. - CRC verify the last 8 records behind the head to account for concurrent log writes. - Verify the tail of the log as well when the head is torn. - Added (rfc) crc error injection patch for testing purposes. rfc: http://oss.sgi.com/pipermail/xfs/2015-July/042415.html Brian Foster (8): xfs: detect and handle invalid iclog size set by mkfs xfs: refactor log record unpack and data processing xfs: refactor and open code log record crc check xfs: return start block of first bad log record during recovery xfs: support a crc verification only log record pass xfs: refactor log record start detection into a new helper xfs: detect and trim torn writes during log recovery xfs: debug mode log recovery crc error injection fs/xfs/libxfs/xfs_log_recover.h | 1 + fs/xfs/xfs_globals.c | 1 + fs/xfs/xfs_log_recover.c | 646 +++++++++++++++++++++++++++++++++------- fs/xfs/xfs_sysctl.h | 1 + fs/xfs/xfs_sysfs.c | 31 ++ 5 files changed, 574 insertions(+), 106 deletions(-) -- 2.1.0 From bfoster@redhat.com Mon Nov 9 14:21:22 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 D7A937F5F for ; Mon, 9 Nov 2015 14:21:22 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id BA2D5304043 for ; Mon, 9 Nov 2015 12:21:19 -0800 (PST) X-ASG-Debug-ID: 1447100478-04cb6c296ddb280001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id AtxGpm2DWQaRFMhh (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 09 Nov 2015 12:21:18 -0800 (PST) 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 (Postfix) with ESMTPS id 1D9FCC0032F3 for ; Mon, 9 Nov 2015 20:21:18 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-67.bos.redhat.com [10.18.41.67]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA9KLHZx017094 for ; Mon, 9 Nov 2015 15:21:17 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id 16CBC12503C; Mon, 9 Nov 2015 15:21:16 -0500 (EST) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH 6/8] xfs: refactor log record start detection into a new helper Date: Mon, 9 Nov 2015 15:21:13 -0500 X-ASG-Orig-Subj: [PATCH 6/8] xfs: refactor log record start detection into a new helper Message-Id: <1447100475-33465-7-git-send-email-bfoster@redhat.com> In-Reply-To: <1447100475-33465-1-git-send-email-bfoster@redhat.com> References: <1447100475-33465-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: 1447100478 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 As part of the head/tail discovery process, log recovery locates the head block and then reverse seeks to find the start of the last active record in the log. This is non-trivial as the record itself could have wrapped around the end of the physical log. Log recovery torn write detection potentially needs to walk further behind the last record in the log, as multiple log I/Os can be in-flight at one time during a crash event. Therefore, refactor the reverse log record header search mechanism into a new helper that supports the ability to seek past an arbitrary number of log records (or until the tail is hit). Update the head/tail search mechanism to call the new helper, but otherwise there is no change in log recovery behavior. Signed-off-by: Brian Foster --- fs/xfs/xfs_log_recover.c | 118 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 83 insertions(+), 35 deletions(-) diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index ae514df..1b3f8fe 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -868,6 +868,79 @@ validate_head: } /* + * Seek backwards in the log for log record headers. + * + * Given a starting log block, walk backwards until we find the provided number + * of records or hit the provided tail block. The return value is the number of + * records encountered or a negative error code. The log block and buffer + * pointer of the last record seen are returned in rblk and rhead respectively. + */ +STATIC int +xlog_rseek_logrec_hdr( + struct xlog *log, + xfs_daddr_t head_blk, + xfs_daddr_t tail_blk, + int count, + struct xfs_buf *bp, + xfs_daddr_t *rblk, + struct xlog_rec_header **rhead, + bool *wrapped) +{ + int i; + int error; + int found = 0; + char *offset = NULL; + xfs_daddr_t end_blk; + + *wrapped = false; + + /* + * Walk backwards from the head block until we hit the tail or the first + * block in the log. + */ + end_blk = head_blk > tail_blk ? tail_blk : 0; + for (i = (int) head_blk - 1; i >= end_blk; i--) { + error = xlog_bread(log, i, 1, bp, &offset); + if (error) + goto out_error; + + if (*(__be32 *) offset == cpu_to_be32(XLOG_HEADER_MAGIC_NUM)) { + *rblk = i; + *rhead = (struct xlog_rec_header *) offset; + if (++found == count) + break; + } + } + + /* + * If we haven't hit the tail block or the log record header count, + * start looking again from the end of the physical log. Note that + * callers can pass head == tail if the tail is not yet known. + */ + if (tail_blk >= head_blk && found != count) { + for (i = log->l_logBBsize - 1; i >= (int) tail_blk; i--) { + error = xlog_bread(log, i, 1, bp, &offset); + if (error) + goto out_error; + + if (*(__be32 *)offset == + cpu_to_be32(XLOG_HEADER_MAGIC_NUM)) { + *wrapped = true; + *rblk = i; + *rhead = (struct xlog_rec_header *) offset; + if (++found == count) + break; + } + } + } + + return found; + +out_error: + return error; +} + +/* * Find the sync block number or the tail of the log. * * This will be the block number of the last record to have its @@ -898,8 +971,7 @@ xlog_find_tail( xfs_daddr_t after_umount_blk; xfs_lsn_t tail_lsn; int hblks; - - found = 0; + bool wrapped = false; /* * Find previous log record @@ -923,37 +995,16 @@ xlog_find_tail( } /* - * Search backwards looking for log record header block + * Search backwards through the log looking for the log record header + * block. This wraps all the way back around to the head so something is + * seriously wrong if we can't find it. */ ASSERT(*head_blk < INT_MAX); - for (i = (int)(*head_blk) - 1; i >= 0; i--) { - error = xlog_bread(log, i, 1, bp, &offset); - if (error) - goto done; - - if (*(__be32 *)offset == cpu_to_be32(XLOG_HEADER_MAGIC_NUM)) { - found = 1; - break; - } - } - /* - * If we haven't found the log record header block, start looking - * again from the end of the physical log. XXXmiken: There should be - * a check here to make sure we didn't search more than N blocks in - * the previous code. - */ - if (!found) { - for (i = log->l_logBBsize - 1; i >= (int)(*head_blk); i--) { - error = xlog_bread(log, i, 1, bp, &offset); - if (error) - goto done; - - if (*(__be32 *)offset == - cpu_to_be32(XLOG_HEADER_MAGIC_NUM)) { - found = 2; - break; - } - } + found = xlog_rseek_logrec_hdr(log, *head_blk, *head_blk, 1, bp, &i, + &rhead, &wrapped); + if (found < 0) { + error = found; + goto done; } if (!found) { xfs_warn(log->l_mp, "%s: couldn't find sync record", __func__); @@ -961,9 +1012,6 @@ xlog_find_tail( ASSERT(0); return -EIO; } - - /* find blk_no of tail of log */ - rhead = (xlog_rec_header_t *)offset; *tail_blk = BLOCK_LSN(be64_to_cpu(rhead->h_tail_lsn)); /* @@ -979,7 +1027,7 @@ xlog_find_tail( log->l_prev_block = i; log->l_curr_block = (int)*head_blk; log->l_curr_cycle = be32_to_cpu(rhead->h_cycle); - if (found == 2) + if (wrapped) log->l_curr_cycle++; atomic64_set(&log->l_tail_lsn, be64_to_cpu(rhead->h_tail_lsn)); atomic64_set(&log->l_last_sync_lsn, be64_to_cpu(rhead->h_lsn)); -- 2.1.0 From bfoster@redhat.com Mon Nov 9 14:21:22 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 F2A137F60 for ; Mon, 9 Nov 2015 14:21:22 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id E3F088F8033 for ; Mon, 9 Nov 2015 12:21:22 -0800 (PST) X-ASG-Debug-ID: 1447100478-04cbb02425e5330001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 21YG5caSiQcYtT8F (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 09 Nov 2015 12:21:18 -0800 (PST) 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 (Postfix) with ESMTPS id 3504DAA5 for ; Mon, 9 Nov 2015 20:21:18 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-67.bos.redhat.com [10.18.41.67]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA9KLH4A014078 for ; Mon, 9 Nov 2015 15:21:17 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id 25410125041; Mon, 9 Nov 2015 15:21:16 -0500 (EST) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH 7/8] xfs: detect and trim torn writes during log recovery Date: Mon, 9 Nov 2015 15:21:14 -0500 X-ASG-Orig-Subj: [PATCH 7/8] xfs: detect and trim torn writes during log recovery Message-Id: <1447100475-33465-8-git-send-email-bfoster@redhat.com> In-Reply-To: <1447100475-33465-1-git-send-email-bfoster@redhat.com> References: <1447100475-33465-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: 1447100478 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Certain types of storage, such as persistent memory, do not provide sector atomicity for writes. This means that if a crash occurs while XFS is writing log records, only part of those records might make it to the storage. This is problematic because log recovery uses the cycle value packed at the top of each log block to locate the head/tail of the log. This can lead to CRC verification failures during log recovery and an unmountable fs for a filesystem that is otherwise consistent. Update log recovery to incorporate log record CRC verification as part of the head/tail discovery process. Once the head is located via the traditional algorithm, run a CRC-only pass over the records up to the head of the log. If CRC verification fails, assume that the records are torn as a matter of policy and trim the head block back to the start of the first bad record. Signed-off-by: Brian Foster --- fs/xfs/xfs_log_recover.c | 298 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 279 insertions(+), 19 deletions(-) diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 1b3f8fe..83fd7ca 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -61,6 +61,9 @@ xlog_recover_check_summary( #else #define xlog_recover_check_summary(log) #endif +STATIC int +xlog_do_recovery_pass( + struct xlog *, xfs_daddr_t, xfs_daddr_t, int, xfs_daddr_t *); /* * This structure is used during recovery to record the buf log items which @@ -941,6 +944,270 @@ out_error: } /* + * Seek forward in the log for log record headers. + * + * Given head and tail blocks, walk forward from the tail block until we find + * the provided number of records or hit the head block. The return value is the + * number of records encountered or a negative error code. The log block and + * buffer pointer of the last record seen are returned in rblk and rhead + * respectively. + */ +STATIC int +xlog_seek_logrec_hdr( + struct xlog *log, + xfs_daddr_t head_blk, + xfs_daddr_t tail_blk, + int count, + struct xfs_buf *bp, + xfs_daddr_t *rblk, + struct xlog_rec_header **rhead, + bool *wrapped) +{ + int i; + int error; + int found = 0; + char *offset = NULL; + xfs_daddr_t end_blk; + + *wrapped = false; + + /* + * Walk forward from the tail block until we hit the head or the last + * block in the log. + */ + end_blk = head_blk > tail_blk ? head_blk : log->l_logBBsize - 1; + for (i = (int) tail_blk; i <= end_blk; i++) { + error = xlog_bread(log, i, 1, bp, &offset); + if (error) + goto out_error; + + if (*(__be32 *) offset == cpu_to_be32(XLOG_HEADER_MAGIC_NUM)) { + *rblk = i; + *rhead = (struct xlog_rec_header *) offset; + if (++found == count) + break; + } + } + + /* + * If we haven't hit the head block or the log record header count, + * start looking again from the start of the physical log. + */ + if (tail_blk > head_blk && found != count) { + for (i = 0; i < (int) head_blk; i++) { + error = xlog_bread(log, i, 1, bp, &offset); + if (error) + goto out_error; + + if (*(__be32 *)offset == + cpu_to_be32(XLOG_HEADER_MAGIC_NUM)) { + *wrapped = true; + *rblk = i; + *rhead = (struct xlog_rec_header *) offset; + if (++found == count) + break; + } + } + } + + return found; + +out_error: + return error; +} + +/* + * Check the log tail for torn writes. This is required when torn writes are + * detected at the head and the head had to be walked back to a previous record. + * The tail of the previous record must now be verified to ensure the torn + * writes didn't corrupt the previous tail. + * + * Return an error if CRC verification fails as recovery cannot proceed. + */ +STATIC int +xlog_verify_tail( + struct xlog *log, + xfs_daddr_t head_blk, + xfs_daddr_t tail_blk) +{ + struct xlog_rec_header *thead; + struct xfs_buf *bp; + xfs_daddr_t first_bad; + int count; + int error = 0; + bool wrapped; + xfs_daddr_t tmp_head; + + bp = xlog_get_bp(log, 1); + if (!bp) + return -ENOMEM; + + /* + * Seek XLOG_MAX_ICLOGS + 1 records past the current tail record to get + * a temporary head block that points after the last possible + * concurrently written record of the tail. + */ + count = xlog_seek_logrec_hdr(log, head_blk, tail_blk, + XLOG_MAX_ICLOGS + 1, bp, &tmp_head, &thead, + &wrapped); + if (count < 0) { + error = count; + goto out; + } + + /* + * If the call above didn't find XLOG_MAX_ICLOGS + 1 records, we ran + * into the actual log head. tmp_head points to the start of the record + * so update it to the actual head block. + */ + if (count < XLOG_MAX_ICLOGS + 1) + tmp_head = head_blk; + + /* + * We now have a tail and temporary head block that covers at least + * XLOG_MAX_ICLOGS records from the tail. We need to verify that these + * records were completely written. Run a CRC verification pass from + * tail to head and return the result. + */ + error = xlog_do_recovery_pass(log, tmp_head, tail_blk, + XLOG_RECOVER_CRCPASS, &first_bad); + +out: + xlog_put_bp(bp); + return error; +} + +/* + * Detect and trim torn writes from the head of the log. + * + * Storage without sector atomicity guarantees can result in torn writes in the + * log in the event of a crash. Our only means to detect this scenario is via + * CRC verification. While we can't always be certain that CRC verification + * failure is due to a torn write vs. an unrelated corruption, we do know that + * only a certain number (XLOG_MAX_ICLOGS) of log records can be written out at + * one time. Therefore, CRC verify up to XLOG_MAX_ICLOGS records at the head of + * the log and treat failures in this range as torn writes as a matter of + * policy. In the event of CRC failure, the head is walked back to the last good + * record in the log and the tail is updated from that record and verified. + */ +STATIC int +xlog_verify_head( + struct xlog *log, + xfs_daddr_t *head_blk, /* in/out: unverified head */ + xfs_daddr_t *tail_blk, /* out: tail block */ + struct xfs_buf *bp, + xfs_daddr_t *rhead_blk, /* start blk of last record */ + struct xlog_rec_header **rhead, /* ptr to last record */ + bool *wrapped) /* last rec. wraps phys. log */ +{ + struct xlog_rec_header *tmp_rhead; + struct xfs_buf *tmp_bp; + xfs_daddr_t first_bad; + xfs_daddr_t tmp_rhead_blk; + int found; + int error; + bool tmp_wrapped; + + /* + * Search backwards through the log looking for the log record header + * block. This wraps all the way back around to the head so something is + * seriously wrong if we can't find it. + */ + found = xlog_rseek_logrec_hdr(log, *head_blk, *head_blk, 1, bp, rhead_blk, + rhead, wrapped); + if (found < 0) + return found; + if (!found) { + xfs_warn(log->l_mp, "%s: couldn't find sync record", __func__); + return -EIO; + } + + *tail_blk = BLOCK_LSN(be64_to_cpu((*rhead)->h_tail_lsn)); + + /* + * Now that we have a tail block, check the head of the log for torn + * writes. Search again until we hit the tail or the maximum number of + * log record I/Os that could have been in flight at one time. Use a + * temporary buffer so we don't trash the rhead/bp pointer from the + * call above. + */ + tmp_bp = xlog_get_bp(log, 1); + if (!tmp_bp) + return -ENOMEM; + error = xlog_rseek_logrec_hdr(log, *head_blk, *tail_blk, + XLOG_MAX_ICLOGS, tmp_bp, &tmp_rhead_blk, + &tmp_rhead, &tmp_wrapped); + xlog_put_bp(tmp_bp); + if (error < 0) + return error; + + /* + * Now run a CRC verification pass over the records starting at the + * block found above to the current head. If a CRC failure occurs, the + * log block of the first bad record is saved in first_bad. + */ + error = xlog_do_recovery_pass(log, *head_blk, tmp_rhead_blk, + XLOG_RECOVER_CRCPASS, &first_bad); + if (error == -EFSBADCRC && first_bad != *tail_blk) { + /* + * We've hit a potential torn write. Reset the error and warn + * about it. + */ + error = 0; + xfs_warn(log->l_mp, +"WARNING: torn write (CRC failure) detected at block 0x%llx, recovery truncated", + first_bad); + + /* + * Get the header block and buffer pointer for the last good + * record before the bad record. + * + * Note that xlog_find_tail() clears the blocks at the new head + * (i.e., the records with invalid CRC) if the cycle number + * matches the the current cycle. + */ + found = xlog_rseek_logrec_hdr(log, first_bad, *tail_blk, 1, bp, + rhead_blk, rhead, wrapped); + if (found < 0) + return found; + if (found == 0) /* XXX: right thing to do here? */ + return -EIO; + + /* + * Reset the head block to the starting block of the first bad + * log record and set the tail block based on the last good + * record. + */ + *head_blk = first_bad; + *tail_blk = BLOCK_LSN(be64_to_cpu((*rhead)->h_tail_lsn)); + + /* + * Now verify the tail based on the updated head. This is + * required because the torn writes trimmed from the head could + * have been written over the tail of a previous record. Return + * any errors since recovery cannot proceed if the tail is + * corrupt. + * + * XXX: This leaves a gap in truly robust protection from torn + * writes in the log. If the head is behind the tail, the tail + * pushes forward to create some space and then a crash occurs + * causing the writes into the previous record's tail region to + * tear, log recovery isn't able to recover. + * + * How likely is this to occur? If possible, can we do something + * more intelligent here? Is it safe to push the tail forward if + * we can determine that the tail is within the range of the + * torn write (e.g., the kernel can only overwrite the tail if + * it has actually been pushed forward)? Alternatively, could we + * somehow prevent this condition at runtime? + */ + error = xlog_verify_tail(log, *head_blk, *tail_blk); + } + + return error; +} + +/* * Find the sync block number or the tail of the log. * * This will be the block number of the last record to have its @@ -966,9 +1233,10 @@ xlog_find_tail( xlog_op_header_t *op_head; char *offset = NULL; xfs_buf_t *bp; - int error, i, found; + int error; xfs_daddr_t umount_data_blk; xfs_daddr_t after_umount_blk; + xfs_daddr_t rhead_blk; xfs_lsn_t tail_lsn; int hblks; bool wrapped = false; @@ -995,24 +1263,16 @@ xlog_find_tail( } /* - * Search backwards through the log looking for the log record header - * block. This wraps all the way back around to the head so something is - * seriously wrong if we can't find it. + * Trim the head block back to skip over torn records. We can have + * multiple log I/Os in flight at any time, so we assume CRC failures + * back through the previous several records are torn writes and skip + * them. */ ASSERT(*head_blk < INT_MAX); - found = xlog_rseek_logrec_hdr(log, *head_blk, *head_blk, 1, bp, &i, - &rhead, &wrapped); - if (found < 0) { - error = found; + error = xlog_verify_head(log, head_blk, tail_blk, bp, &rhead_blk, + &rhead, &wrapped); + if (error) goto done; - } - if (!found) { - xfs_warn(log->l_mp, "%s: couldn't find sync record", __func__); - xlog_put_bp(bp); - ASSERT(0); - return -EIO; - } - *tail_blk = BLOCK_LSN(be64_to_cpu(rhead->h_tail_lsn)); /* * Reset log values according to the state of the log when we @@ -1024,7 +1284,7 @@ xlog_find_tail( * written was complete and ended exactly on the end boundary * of the physical log. */ - log->l_prev_block = i; + log->l_prev_block = rhead_blk; log->l_curr_block = (int)*head_blk; log->l_curr_cycle = be32_to_cpu(rhead->h_cycle); if (wrapped) @@ -1062,12 +1322,12 @@ xlog_find_tail( } else { hblks = 1; } - after_umount_blk = (i + hblks + (int) + after_umount_blk = (rhead_blk + hblks + (int) BTOBB(be32_to_cpu(rhead->h_len))) % log->l_logBBsize; tail_lsn = atomic64_read(&log->l_tail_lsn); if (*head_blk == after_umount_blk && be32_to_cpu(rhead->h_num_logops) == 1) { - umount_data_blk = (i + hblks) % log->l_logBBsize; + umount_data_blk = (rhead_blk + hblks) % log->l_logBBsize; error = xlog_bread(log, umount_data_blk, 1, bp, &offset); if (error) goto done; -- 2.1.0 From bfoster@redhat.com Mon Nov 9 14:21:23 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 7EB4C7F5F for ; Mon, 9 Nov 2015 14:21:23 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id ED309AC005 for ; Mon, 9 Nov 2015 12:21:22 -0800 (PST) X-ASG-Debug-ID: 1447100477-04cbb02423e5320001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id Y9ajW1GL5dx9BJwo (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 09 Nov 2015 12:21:18 -0800 (PST) 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 (Postfix) with ESMTPS id 86AB2A3259 for ; Mon, 9 Nov 2015 20:21:17 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-67.bos.redhat.com [10.18.41.67]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA9KLHw7017084 for ; Mon, 9 Nov 2015 15:21:17 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id CE80812500F; Mon, 9 Nov 2015 15:21:15 -0500 (EST) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH 1/8] xfs: detect and handle invalid iclog size set by mkfs Date: Mon, 9 Nov 2015 15:21:08 -0500 X-ASG-Orig-Subj: [PATCH 1/8] xfs: detect and handle invalid iclog size set by mkfs Message-Id: <1447100475-33465-2-git-send-email-bfoster@redhat.com> In-Reply-To: <1447100475-33465-1-git-send-email-bfoster@redhat.com> References: <1447100475-33465-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: 1447100477 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 XFS log records have separate fields for the record size and the iclog size used to write the record. mkfs.xfs zeroes the log and writes an unmount record to generate a clean log for the subsequent mount. The userspace record logging code has a bug where the iclog size (h_size) field of the log record is hardcoded to 32k, even if a log stripe unit is specified. The log record length is correctly extended to the stripe unit. Since the kernel log recovery code uses the h_size field to determine the log buffer size, this means that the kernel can attempt to read/process records larger than the buffer size and overrun the buffer. This has historically not been a problem because the kernel doesn't actually run through log recovery in the clean unmount case. Instead, the kernel detects that a single unmount record exists between the head and tail and pushes the tail forward such that the log is viewed as clean (head == tail). Once CRC verification is enabled, however, all records at the head of the log are verified for CRC errors and thus we are susceptible to overrun problems if the iclog field is not correct. While the core problem must be fixed in userspace, this is historical behavior that must be detected in the kernel to avoid severe side effects such as memory corruption and crashes. Update the log buffer size calculation code to detect this condition, warn the user and resize the log buffer based on the log stripe unit. Return a corruption error in cases where this does not look like a clean filesystem (i.e., the log record header indicates more than one operation). Signed-off-by: Brian Foster --- fs/xfs/xfs_log_recover.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index f8f1363..b00c85e 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -4245,7 +4245,7 @@ xlog_do_recovery_pass( xfs_daddr_t blk_no; char *offset; xfs_buf_t *hbp, *dbp; - int error = 0, h_size; + int error = 0, h_size, h_len; int bblks, split_bblks; int hblks, split_hblks, wrapped_hblks; struct hlist_head rhash[XLOG_RHASH_SIZE]; @@ -4274,7 +4274,31 @@ xlog_do_recovery_pass( error = xlog_valid_rec_header(log, rhead, tail_blk); if (error) goto bread_err1; + + /* + * xfsprogs has a bug where record length is based on lsunit but + * h_size (iclog size) is hardcoded to 32k. Now that we + * unconditionally CRC verify the unmount record, this means the + * log buffer can be too small for the record and cause an + * overrun. + * + * Detect this condition here. Use lsunit for the buffer size as + * long as this looks like the mkfs case. Otherwise, return an + * error to avoid a buffer overrun. + */ h_size = be32_to_cpu(rhead->h_size); + h_len = be32_to_cpu(rhead->h_len); + if (h_len > h_size) { + if (h_len <= log->l_mp->m_logbsize && + be32_to_cpu(rhead->h_num_logops) == 1) { + xfs_warn(log->l_mp, + "invalid iclog size (%d bytes), using lsunit (%d bytes)", + h_size, log->l_mp->m_logbsize); + h_size = log->l_mp->m_logbsize; + } else + return -EFSCORRUPTED; + } + if ((be32_to_cpu(rhead->h_version) & XLOG_VERSION_2) && (h_size > XLOG_HEADER_CYCLE_SIZE)) { hblks = h_size / XLOG_HEADER_CYCLE_SIZE; -- 2.1.0 From david@fromorbit.com Mon Nov 9 15:36:23 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 078587CBF for ; Mon, 9 Nov 2015 15:36:23 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id DC24A304051 for ; Mon, 9 Nov 2015 13:36:19 -0800 (PST) X-ASG-Debug-ID: 1447104973-04cb6c296bdccb0001-NocioJ Received: from ipmail06.adl6.internode.on.net (ipmail06.adl6.internode.on.net [150.101.137.145]) by cuda.sgi.com with ESMTP id Rdo213LmUdqwScx2 for ; Mon, 09 Nov 2015 13:36:14 -0800 (PST) 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: A2CPBwBmEEFWPGfGLHleKAECgxBTb4ZcpF4DAQEBBosyhSyCfYEOGYVxBAICgURNAQEBAQEBBwEBAQFBP4Q2AQEEOhwjEAgDGAklDwUlAwcaE4gtwXwBAQEHAgEgGYV0hUWIJIEVBZZIhR6IAYIsjQiNGYR7KjSFZgEBAQ Received: from ppp121-44-198-103.lns20.syd7.internode.on.net (HELO dastard) ([121.44.198.103]) by ipmail06.adl6.internode.on.net with ESMTP; 10 Nov 2015 08:05:21 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1Zvu5w-0006OK-5V; Tue, 10 Nov 2015 08:35:20 +1100 Date: Tue, 10 Nov 2015 08:35:20 +1100 From: Dave Chinner To: "Darrick J. Wong" Cc: Christoph Hellwig , xfs@oss.sgi.com Subject: Re: [PATCH v2 03/51] xfs_io: support reflink and dedupe of file ranges Message-ID: <20151109213520.GB14311@dastard> X-ASG-Orig-Subj: Re: [PATCH v2 03/51] xfs_io: support reflink and dedupe of file ranges References: <20151007050513.1504.28089.stgit@birch.djwong.org> <20151007050533.1504.66249.stgit@birch.djwong.org> <20151014053656.GJ10397@birch.djwong.org> <20151109075438.GA17974@infradead.org> <20151109183311.GA3255@birch.djwong.org> <20151109185724.GB2224@birch.djwong.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151109185724.GB2224@birch.djwong.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: 1447104973 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24250 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header On Mon, Nov 09, 2015 at 10:57:24AM -0800, Darrick J. Wong wrote: > On Mon, Nov 09, 2015 at 10:33:12AM -0800, Darrick J. Wong wrote: > > On Sun, Nov 08, 2015 at 11:54:38PM -0800, Christoph Hellwig wrote: > > > Any reason why the dedup command is called 'dedupe'? Is this a revenge > > > for the missing 'e' in the creat syscall? :) > > > > Heh, sure! :) > > > > I stuck on the 'e' because the btrfs tool is 'duperemove', not 'dupremove'. > > > > (I have no preference either way.) > > > > > Either way it would be good to get this support in ASAP so we can have > > > the command ready for xfstests and we can merge the test. They are > > > useful for btrfs and NFS already, so I'd love to fast track them. > > Oh. Heh. I forgot that Dave merged the v1 patch into for-next after I'd posted > the v2 patch. So ... I thought I'd convinced him to revert the v1 patch and > stuff in the v2 patch, but that hasn't shown up on kernel.org. > > -ETOOMANYPATCHES :( Need to push it out - I have an updated branch here, just been delayed in testing and pushing out progs-4.3-rc2. Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Mon Nov 9 18:16:09 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 B1BF27CBF for ; Mon, 9 Nov 2015 18:16:09 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 9B2AC304043 for ; Mon, 9 Nov 2015 16:16:06 -0800 (PST) X-ASG-Debug-ID: 1447114562-04cb6c296ddfc90001-NocioJ Received: from ipmail06.adl6.internode.on.net (ipmail06.adl6.internode.on.net [150.101.137.145]) by cuda.sgi.com with ESMTP id Ex7njdqqJv3zanON for ; Mon, 09 Nov 2015 16:16:02 -0800 (PST) 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: A2DyCADwNUFWPGfGLHleKAECgxAjMG+GXKRHAhYBAQEBAQEGgQ2KJYUsgn2BDhcChXEEgURNAQEBAQEBBwEBAQFAAT+FEjskNAUlAwctiC2hPqBoCRmFdIpsghQMQRyBFQWWSIUeiAGOb41egi0MgkIqNINmJYEjAQEB Received: from ppp121-44-198-103.lns20.syd7.internode.on.net (HELO dastard) ([121.44.198.103]) by ipmail06.adl6.internode.on.net with ESMTP; 10 Nov 2015 10:46:01 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZvwbQ-0006eZ-TC for xfs@oss.sgi.com; Tue, 10 Nov 2015 11:16:00 +1100 Date: Tue, 10 Nov 2015 11:16:00 +1100 From: Dave Chinner To: xfs@oss.sgi.com Subject: [ANNOUNCE] xfs: for-next branch updated to 4e14e49 Message-ID: <20151110001600.GC14311@dastard> X-ASG-Orig-Subj: [ANNOUNCE] xfs: for-next branch updated to 4e14e49 MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="x+6KMIRAuhnl3hBn" Content-Disposition: inline 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: 1447114562 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24255 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- --x+6KMIRAuhnl3hBn Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Hi folks, The for-next branch of the xfs kernel repository at git://git.kernel.org/pub/scm/linux/kernel/git/dgc/linux-xfs.git has just been updated. it contains the couple of outstanding fixes for the 4.4 merge window. This is essentially what I'll ask linus to pull in the next couple of days. -Dave. The new head of the for-next branch is commit: 4e14e49 Merge branch 'xfs-misc-fixes-for-4.4-3' into for-next New Commits: Andreas Gruenbacher (1): [edfb8eb] xfs: Fix error path in xfs_get_acl Brian Foster (1): [848ccfc] xfs: fix log recovery op header validation assert Chris Mason (1): [7a29ac4] xfs: give all workqueues rescuer threads Dave Chinner (1): [4e14e49] Merge branch 'xfs-misc-fixes-for-4.4-3' into for-next Code Diffstat: fs/xfs/xfs_acl.c | 1 + fs/xfs/xfs_acl.h | 1 - fs/xfs/xfs_log_recover.c | 2 +- fs/xfs/xfs_super.c | 7 ++++--- 4 files changed, 6 insertions(+), 5 deletions(-) --=20 Dave Chinner david@fromorbit.com --x+6KMIRAuhnl3hBn Content-Type: application/pgp-signature; name="signature.asc" Content-Description: Digital signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQIcBAEBAgAGBQJWQTdAAAoJEK3oKUf0dfod6zIQAIb00jj80mY//9XAIaNi4uJr n9O0eyUhdBkR6dNTw8TR/HZRK5Huhf7cCnPfQTT2TWTOtYBDo91rP3EEtgkMwqaB vgCqXHREX2lhwqeaNZjqInZYVi3GiKpCSLAsEYHbgfVjzyZMBQhk/ZSkjAAFX53v 9kAJL7lDOlEtKoSJv2rX71HJNJLzQLpQytHFFsWE9bLR7WOOU5CiuG863hfX/tPW IhKa0BglVxBEfT3T9rIlI8Gsl+Nu4CFVF4Hkh9ptT7IY1rZEJ51nvTFus162P4oE OX9pHPTSbRqUEwSeg8ZkfDqN8HE4zja0GYckXSJRjCeQYZefQSlAOOo7JMB8VNIk vUYC2wh5AGkgChQw4h5ALyrGkWXR5554xqh3R23SQIWnoxswnVHxq/3SaqaZcOD8 /fLRM8G5j6r481dkjPu8DNt0BhIedympklzZ9C4ku8EzL75iTji0gDexdbKMZCGa UiPK3nYDs2Bjn+GNZe4ZtIx1XiH7iUQVMFLjvIyelePZdBjndRBMKBBN/3v7Oo3O 2gGo/boLgLCsM/leV+eAHne4cFHoOXluFsVB2wBPjghAC8iZpkarHUlR9imdEvZ+ BqkLguMeHxX2/S+VhADtGeIUFcI6fruxnO6T7sB91KF+0JqZALBRYy1uQEe+HamN VFjnM6R4uqkH/xgv4Va0 =US5V -----END PGP SIGNATURE----- --x+6KMIRAuhnl3hBn-- From david@fromorbit.com Mon Nov 9 23:14:22 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 F26447CBF for ; Mon, 9 Nov 2015 23:14:21 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 747E6AC005 for ; Mon, 9 Nov 2015 21:14:18 -0800 (PST) X-ASG-Debug-ID: 1447132453-04cb6c296be4f20001-NocioJ Received: from ipmail06.adl6.internode.on.net (ipmail06.adl6.internode.on.net [150.101.137.145]) by cuda.sgi.com with ESMTP id qcivuGx5WO6YexbV for ; Mon, 09 Nov 2015 21:14:13 -0800 (PST) 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: A2C9CADDe0FWPGfGLHleKAECgxAjMG+CXoN+pEkCHAaBDYolIYULgn2BDhcGhW0EgUZNAQEBAQEBBwEBAQFAAT+FEjskNAUlAwctiC2hR6BuCRmFdIpsghQMQRyBFQWHRI8EhR6IAYFjSYN3iEyFCohUgjmCQio0hS4BAQE Received: from ppp121-44-198-103.lns20.syd7.internode.on.net (HELO dastard) ([121.44.198.103]) by ipmail06.adl6.internode.on.net with ESMTP; 10 Nov 2015 15:43:56 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1Zw1Fj-0007BD-SV for xfs@oss.sgi.com; Tue, 10 Nov 2015 16:13:55 +1100 Date: Tue, 10 Nov 2015 16:13:55 +1100 From: Dave Chinner To: xfs@oss.sgi.com Subject: [ANNOUNCE] xfsprogs: v4.3.0-rc2 released Message-ID: <20151110051355.GD14311@dastard> X-ASG-Orig-Subj: [ANNOUNCE] xfsprogs: v4.3.0-rc2 released MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="neYutvxvOLaeuPCA" Content-Disposition: inline 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: 1447132453 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24264 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- --neYutvxvOLaeuPCA Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Hi folks, The xfsprogs repository at: git://git.kernel.org/pub/scm/fs/xfs/xfsprogs-dev.git has just been updated. This contains the few fixes and cleanups that were pending from the 4.3.0-rc1 release as well as a couple of new fixes that have been posted since. Please test, I'm planning on a 4.3.0 release early next week if no problems are reported in the next few days... -Dave. The new head of the master branch is commit: af37ed4 xfsprogs: Release v4.3.0-rc2 New Commits: Darrick J. Wong (2): [a9b61ce] libxcmd: provide a common function to report command runtim= es [2afac83] io: update reflink/dedupe ioctl definitions Dave Chinner (2): [5cfd2d5] headers: remove definition of ASSERT from xfs.h [af37ed4] xfsprogs: Release v4.3.0-rc2 Jan Tulak (1): [7141fc5] xfsprogs: make fsr use mntinfo when there is no mntent Ville Skytt=E4 (2): [2e53a4f] xfs_db.8: Remove stray backslash near bmap [6222418] mkfs.xfs.8: Spelling fix Code Diffstat: VERSION | 2 +- configure.ac | 2 +- doc/CHANGES | 8 ++ fsr/Makefile | 8 ++ fsr/xfs_fsr.c | 113 ++++++++++-------- include/command.h | 6 + include/darwin.h | 62 ++++++++++ include/freebsd.h | 29 +++++ include/gnukfreebsd.h | 28 +++++ include/irix.h | 29 +++++ include/linux.h | 28 +++++ include/platform_defs.h.in | 6 + include/xfs.h | 6 - io/Makefile | 2 +- io/dedupe.c | 190 ----------------------------- io/init.c | 1 - io/io.h | 1 - io/pread.c | 16 +-- io/pwrite.c | 17 +-- io/reflink.c | 289 ++++++++++++++++++++++++++++++++++-------= ---- io/sendfile.c | 16 +-- libxcmd/command.c | 27 +++++ libxfs/xfs_fs.h | 25 ++-- man/man8/mkfs.xfs.8 | 2 +- man/man8/xfs_db.8 | 2 +- man/man8/xfs_io.8 | 29 ++--- 26 files changed, 544 insertions(+), 400 deletions(-) delete mode 100644 io/dedupe.c --=20 Dave Chinner david@fromorbit.com --neYutvxvOLaeuPCA Content-Type: application/pgp-signature; name="signature.asc" Content-Description: Digital signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQIcBAEBAgAGBQJWQX0TAAoJEK3oKUf0dfodZiUQAL0kSok4voiuiE1YEqGDIYUC 5TApAKGHXoHNlHEwr9pEPVM/seVsM8kZH69nKt/Y2tOkDSbmfq3crfLJM2hnuc3Z f7kpqBg+Nj31l2+mIKNJHw6cvo4bqE/xHS31d6dbUyPPm4qVxTx3EicXZOs6aHVA jWBXKjwVFpGrSQ8vJcI7+98SF/O8QV+csER10tHgk0P8qX+C99q9SGxeaxl2nwju RhQ2Db9s/JJ/EPJnRRaozkRAMGBxqhi/m9eE+fFtGhz4Ea0Nk7aiEPRu9RE75qYw UMEsFylHwwZIrYsVO+lel1aIl4aoashEy+W190MWS0KQqht9W0WYkmMBokvCpS8V 2U8OnsNrGH/MIuEROlpwbs+ovhRJxDQ3mtlk8xIrv42kJpHiEaK2PzxlChw2WCji 2v+VYgipDkn7XxIWaWndF5C8A/ozLGOn1h6VfA+vvl37Ao7ofMl0bvMVVPTZ+v8t 5U9NjLzaQaFJZQRoeXW0S4Z1NvzBe0UH8XlzO/YWkTkdrBfaLMHqpFx5ZxsVBw/h taygi2eyvKzdyV4/Mz0aDZAAZIrqQR7gtuoo7fmCE20gePveyFh7GUG5YCAvQxKv M6igJUcrl/SlGHi+x6Ne4EU+Evdtd0fEI3MW6w/pOdqli/qig61v65ewwguzh6Hn 3Y1cabbfapxfCb7p6gwu =pfQn -----END PGP SIGNATURE----- --neYutvxvOLaeuPCA-- From darrick.wong@oracle.com Tue Nov 10 00:28:25 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 D51C27CBF for ; Tue, 10 Nov 2015 00:28:25 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id B40938F8033 for ; Mon, 9 Nov 2015 22:28:25 -0800 (PST) X-ASG-Debug-ID: 1447136903-04cbb02425f5ab0001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id qFq4vRCSHHSTrux0 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 09 Nov 2015 22:28:23 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tAA6Rx22021952 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Tue, 10 Nov 2015 06:28:00 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id tAA6RxUb012023 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Tue, 10 Nov 2015 06:27:59 GMT Received: from abhmp0017.oracle.com (abhmp0017.oracle.com [141.146.116.23]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id tAA6RxQH019814; Tue, 10 Nov 2015 06:27:59 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Mon, 09 Nov 2015 22:27:59 -0800 Date: Mon, 9 Nov 2015 22:27:58 -0800 From: "Darrick J. Wong" To: Dave Chinner Cc: Christoph Hellwig , xfs@oss.sgi.com Subject: Re: [PATCH v2 03/51] xfs_io: support reflink and dedupe of file ranges Message-ID: <20151110062758.GG3255@birch.djwong.org> X-ASG-Orig-Subj: Re: [PATCH v2 03/51] xfs_io: support reflink and dedupe of file ranges References: <20151007050513.1504.28089.stgit@birch.djwong.org> <20151007050533.1504.66249.stgit@birch.djwong.org> <20151014053656.GJ10397@birch.djwong.org> <20151109075438.GA17974@infradead.org> <20151109183311.GA3255@birch.djwong.org> <20151109185724.GB2224@birch.djwong.org> <20151109213520.GB14311@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151109213520.GB14311@dastard> User-Agent: Mutt/1.5.21 (2010-09-15) X-Source-IP: aserv0022.oracle.com [141.146.126.234] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1447136903 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24265 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines On Tue, Nov 10, 2015 at 08:35:20AM +1100, Dave Chinner wrote: > On Mon, Nov 09, 2015 at 10:57:24AM -0800, Darrick J. Wong wrote: > > On Mon, Nov 09, 2015 at 10:33:12AM -0800, Darrick J. Wong wrote: > > > On Sun, Nov 08, 2015 at 11:54:38PM -0800, Christoph Hellwig wrote: > > > > Any reason why the dedup command is called 'dedupe'? Is this a revenge > > > > for the missing 'e' in the creat syscall? :) > > > > > > Heh, sure! :) > > > > > > I stuck on the 'e' because the btrfs tool is 'duperemove', not 'dupremove'. > > > > > > (I have no preference either way.) > > > > > > > Either way it would be good to get this support in ASAP so we can have > > > > the command ready for xfstests and we can merge the test. They are > > > > useful for btrfs and NFS already, so I'd love to fast track them. > > > > Oh. Heh. I forgot that Dave merged the v1 patch into for-next after I'd posted > > the v2 patch. So ... I thought I'd convinced him to revert the v1 patch and > > stuff in the v2 patch, but that hasn't shown up on kernel.org. > > > > -ETOOMANYPATCHES :( > > Need to push it out - I have an updated branch here, just been > delayed in testing and pushing out progs-4.3-rc2. Ok, thanks, I'll rebase and give the tests a spin in the morning. --D > > Cheers, > > Dave. > -- > Dave Chinner > david@fromorbit.com From david@fromorbit.com Tue Nov 10 00:30:56 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 BF72E7F37 for ; Tue, 10 Nov 2015 00:30:56 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id A54C38F8033 for ; Mon, 9 Nov 2015 22:30:56 -0800 (PST) X-ASG-Debug-ID: 1447137051-04cbb02422f6030001-NocioJ Received: from ipmail06.adl6.internode.on.net (ipmail06.adl6.internode.on.net [150.101.137.145]) by cuda.sgi.com with ESMTP id YR13hsAChCmANwsA for ; Mon, 09 Nov 2015 22:30:51 -0800 (PST) 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: A2C+CACNjkFWPGfGLHleKAECgxAjMG+CXoN+pEoCHAaBDYolIYULgn2BDhcChXEEgTpNAQEBAQEBBwEBAQFAAT+Edhw7JDQFJQMHLR6ID6FGoHsZhXSINoRKDEEcgRUFh0SPBIUeiAGBY0mMQ4UKiFSCLQw7HYFqKjQBAQEBhSoBAQE Received: from ppp121-44-198-103.lns20.syd7.internode.on.net (HELO dastard) ([121.44.198.103]) by ipmail06.adl6.internode.on.net with ESMTP; 10 Nov 2015 17:00:21 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1Zw2RJ-0007Js-MZ for xfs@oss.sgi.com; Tue, 10 Nov 2015 17:29:57 +1100 Date: Tue, 10 Nov 2015 17:29:57 +1100 From: Dave Chinner To: xfs@oss.sgi.com Subject: [ANNOUNCE] xfsdump: v3.1.6 released Message-ID: <20151110062957.GE14311@dastard> X-ASG-Orig-Subj: [ANNOUNCE] xfsdump: v3.1.6 released 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: ipmail06.adl6.internode.on.net[150.101.137.145] X-Barracuda-Start-Time: 1447137051 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24265 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Hi folks, The xfsdump repositories have just been updated and tagged with the v3.1.6 release tag. This is an update to fix the building of the xfsdump package on systems that have xfsprogs 4.2.0 or later installed on them. The source code can be found in these git repositories: git://oss.sgi.com/xfs/cmds/xfsdump v3.1.6 git://git.kernel.org/pub/scm/fs/xfs/xfsdump-dev.git v3.1.6 A signed gzipped-tar archive of the source code is available here: ftp://oss.sgi.com/projects/xfs/cmd_tars/xfsdump-3.1.6.tar.gz ftp://oss.sgi.com/projects/xfs/cmd_tars/xfsdump-3.1.6.tar.gz.sign The archive is signed with my gpg key (the same one that this release announcement is signed with). -Dave. The new head of the master branch is commit: f2a518a xfsdump: Release v3.1.6 New Commits: Dave Chinner (9): [9d8bde8] cleanup: get rid of ASSERT [ff46015] build: don't rely on xfs/xfs.h to include necessary headers [3518475] cleanup: kill intgen_t [508ae35] cleanup: kill u_int*_t types [86252eb] cleanup: define a local xfs_ino_t [6fad1f8] cleanup: use system uuid.h headers [2f529f0] cleanup: move fold_t out of util.h [65c91e1] cleanup: Kill unnecessary xfs includes [f2a518a] xfsdump: Release v3.1.6 Code Diffstat: VERSION | 2 +- common/arch_xlate.c | 8 +- common/arch_xlate.h | 4 +- common/cldmgr.c | 24 +- common/cldmgr.h | 2 +- common/cleanup.c | 7 +- common/content.h | 8 +- common/content_common.c | 23 +- common/content_inode.h | 78 +++--- common/dlog.c | 27 +- common/dlog.h | 2 +- common/drive.c | 33 +-- common/drive.h | 48 ++-- common/drive_minrmt.c | 654 +++++++++++++++++++++++------------------------ common/drive_scsitape.c | 662 ++++++++++++++++++++++++------------------------ common/drive_simple.c | 246 +++++++++--------- common/exit.h | 2 +- common/fs.c | 43 ++-- common/fs.h | 8 +- common/global.c | 49 ++-- common/global.h | 10 +- common/hsmapi.c | 26 +- common/hsmapi.h | 16 +- common/inventory.c | 42 +-- common/inventory.h | 6 +- common/lock.c | 7 +- common/main.c | 183 ++++++------- common/media.c | 28 +- common/media.h | 10 +- common/mlog.c | 113 ++++++--- common/mlog.h | 22 +- common/openutil.c | 39 +-- common/openutil.h | 14 +- common/path.c | 32 ++- common/qlock.c | 51 ++-- common/rec_hdr.h | 4 +- common/ring.c | 74 +++--- common/ring.h | 4 +- common/stream.c | 31 +-- common/stream.h | 6 +- common/types.h | 35 ++- common/util.c | 147 ++++------- common/util.h | 53 ++-- configure.ac | 2 +- debian/changelog | 6 + doc/CHANGES | 5 + dump/content.c | 414 +++++++++++++++--------------- dump/inomap.c | 216 ++++++++-------- dump/inomap.h | 19 +- dump/var.c | 13 +- include/config.h.in | 49 +++- inventory/inv_api.c | 51 ++-- inventory/inv_core.c | 30 ++- inventory/inv_files.c | 15 +- inventory/inv_fstab.c | 17 +- inventory/inv_idx.c | 48 ++-- inventory/inv_mgr.c | 25 +- inventory/inv_oref.c | 83 +++--- inventory/inv_oref.h | 34 +-- inventory/inv_priv.h | 102 ++++---- inventory/inv_stobj.c | 95 +++---- inventory/inventory.h | 14 +- inventory/testmain.c | 40 +-- invutil/cmenu.c | 4 + invutil/fstab.c | 4 + invutil/invidx.c | 13 +- invutil/invutil.c | 5 + invutil/list.c | 4 +- invutil/menu.c | 4 +- invutil/screen.c | 4 + invutil/stobj.c | 5 + librmt/rmtabort.c | 1 + librmt/rmtclose.c | 1 + librmt/rmtcommand.c | 2 + librmt/rmtfstat.c | 2 + librmt/rmtioctl.c | 11 +- librmt/rmtlib.h | 3 - librmt/rmtlseek.c | 2 + librmt/rmtmsg.c | 5 + librmt/rmtopen.c | 4 +- librmt/rmtread.c | 2 + librmt/rmtstatus.c | 2 + librmt/rmtwrite.c | 2 + restore/bag.c | 24 +- restore/content.c | 466 +++++++++++++++++----------------- restore/dirattr.c | 202 ++++++++------- restore/dirattr.h | 12 +- restore/inomap.c | 102 ++++---- restore/inomap.h | 8 +- restore/mmap.c | 1 - restore/namreg.c | 56 ++-- restore/namreg.h | 4 +- restore/node.c | 97 +++---- restore/node.h | 4 +- restore/tree.c | 295 ++++++++++----------- restore/tree.h | 4 +- restore/win.c | 76 +++--- restore/win.h | 4 +- 98 files changed, 2942 insertions(+), 2654 deletions(-) -- Dave Chinner david@fromorbit.com From conatct@bluetrade195.eu Tue Nov 10 04:05:01 2015 Return-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.6 required=5.0 tests=HTML_IMAGE_RATIO_04, HTML_MESSAGE,LOTS_OF_MONEY,SUBJECT_NEEDS_ENCODING,T_DKIM_INVALID, T_REMOTE_IMAGE 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 685217F37 for ; Tue, 10 Nov 2015 04:05:01 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id E08B48F8035 for ; Tue, 10 Nov 2015 02:04:57 -0800 (PST) X-ASG-Debug-ID: 1447149892-04bdf03f04f02c0001-NocioJ Received: from vps.hero1005.eu (vps.hero1005.eu [188.213.25.58]) by cuda.sgi.com with ESMTP id XlXV3Gy3adK9xtdL (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 10 Nov 2015 02:04:53 -0800 (PST) X-Barracuda-Envelope-From: conatct@bluetrade195.eu X-Barracuda-Apparent-Source-IP: 188.213.25.58 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=bluetrade195.eu; s=bluetrade195.eu; t=1447149891; bh=chyBrOeO9/ywqmWFf17AO29gS/oi4M96Kd/H6U+rgMQ=; h=Date:From:To:Reply-to:Subject:From; b=dOyK/I01+iWphf8Y76TUygHl1ahMo8IwyFhXyA/RPUIPIhst/Dh29U0fS6gBFJBBB 0EF4nI4sugA5GgKL6jK8lw1mfR2n6ePQlw2iFJ5bFmpDefTPhfGIT2leTzYQnIgZ0t N70P4n+Yii59onkzdRYOHFBkTyXL8Yr65pZ0KiD8= Date: Tue, 10 Nov 2015 11:04:45 +0000 From: Lendopolis To: xfs@oss.sgi.com Reply-to: Lendopolis User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; Trident/6.0; Microsoft Outlook 15.0.4420) MIME-Version: 1.0 Subject: Empruntez jusqu'à 200 000 euros en 30 jours maximum ! Content-Type: multipart/alternative; boundary="------------030701010808070405050509" X-ASG-Orig-Subj: Empruntez jusqu'à 200 000 euros en 30 jours maximum ! X-Barracuda-Connect: vps.hero1005.eu[188.213.25.58] X-Barracuda-Start-Time: 1447149893 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 1.59 X-Barracuda-Spam-Status: No, SCORE=1.59 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_04, HTML_MESSAGE, MISSING_MID, NO_REAL_NAME, SUBJECT_NEEDS_ENCODING X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24269 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.14 MISSING_MID Missing Message-Id: header 0.00 NO_REAL_NAME From: does not include a real name -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature 0.17 HTML_IMAGE_RATIO_04 BODY: HTML has a low ratio of text to image area 0.00 HTML_MESSAGE BODY: HTML included in message 1.28 SUBJECT_NEEDS_ENCODING SUBJECT_NEEDS_ENCODING Message-Id: <20151110100457.7C0A1A420A4@cuda.sgi.com> This is a multi-part message in MIME format. --------------030701010808070405050509 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Si vous ne visualisez pas correctement ce message suivez ce lien LENDOPOLIS Entreprises, vous recherchez un crédit professionnel ? Financez vos projets de développement grâce à LENDOPOLIS en empruntant directement auprès de particuliers. En savoir plus Image RAPIDITÉ Déposez votre dossier en 20 minutes Image FLEXIBILITÉ Empruntez entre 10k€ et 200k€ en 30 jours maximum Image SIMPLICITÉ Sans caution ni garantie Image COMMUNICATION Menez une campagne intense auprès du grand public Prêter présente un risque de non remboursement et nécessite une immobilisation de son épargne. Crédits amortissables à mensualités constantes, composées des intérêts courus et d'une part de principal. LENDOPOLIS se rémunère sous forme d'une commission de 3% à 4% prélevée auprès de l'emprunteur sur le montant prêté. L'ouverture et la gestion d'un compte prêteur sont gratuites. LENDOPOLIS ? RCS Paris 804 606 796 ? 35 rue Jouffroy d'Abbans 75017 Paris. Société immatriculée en tant qu'intermédiaire en Financement Participatif auprès de l'ORIAS sous le n°14006007. LENDOPOLIS est mandatée en tant qu'agent par Ingenico Financial Solution SA-NV, Prestataire en Service de Paiement supervisé par la Banque Nationale de Belgique. LENDOPOLIS ® Tous droits réservés. Pour retirer votre adresse email,c'est la --------------030701010808070405050509 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit
Si vous ne visualisez pas correctement ce message suivez ce lien
LENDOPOLIS
Entreprises, vous recherchez un crédit professionnel ?
Financez vos projets de développement grâce à LENDOPOLIS en empruntant directement auprès de particuliers.
En savoir plus
Image
RAPIDITÉ
Déposez votre dossier en 20 minutes
Image
FLEXIBILITÉ
Empruntez entre 10k€ et 200k€ en 30 jours maximum
Image
SIMPLICITÉ
Sans caution ni garantie
Image
COMMUNICATION
Menez une campagne intense auprès du grand public

Prêter présente un risque de non remboursement et nécessite une immobilisation de son épargne. Crédits amortissables à mensualités constantes, composées des intérêts courus et d'une part de principal. LENDOPOLIS se rémunère sous forme d'une commission de 3% à 4% prélevée auprès de l'emprunteur sur le montant prêté. L'ouverture et la gestion d'un compte prêteur sont gratuites. LENDOPOLIS ? RCS Paris 804 606 796 ? 35 rue Jouffroy d'Abbans 75017 Paris. Société immatriculée en tant qu'intermédiaire en Financement Participatif auprès de l'ORIAS sous le n°14006007. LENDOPOLIS est mandatée en tant qu'agent par Ingenico Financial Solution SA-NV, Prestataire en Service de Paiement supervisé par la Banque Nationale de Belgique. LENDOPOLIS ® Tous droits réservés.

 

 

Pour retirer votre adresse email,c'est la

--------------030701010808070405050509-- From BATV+25f5049bfd0fd9a4203a+4461+infradead.org+hch@bombadil.srs.infradead.org Tue Nov 10 05:29:59 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 709887F37 for ; Tue, 10 Nov 2015 05:29:59 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 5C94630404E for ; Tue, 10 Nov 2015 03:29:55 -0800 (PST) X-ASG-Debug-ID: 1447154993-04cbb02423fd020001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id BiED0EmQKGE1b9or (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 10 Nov 2015 03:29:53 -0800 (PST) X-Barracuda-Envelope-From: BATV+25f5049bfd0fd9a4203a+4461+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 1Zw77P-0004ed-LP; Tue, 10 Nov 2015 11:29:43 +0000 Date: Tue, 10 Nov 2015 03:29:43 -0800 From: Christoph Hellwig To: Andreas Gruenbacher Cc: Alexander Viro , Theodore Ts'o , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Subject: Re: [PATCH v15 00/22] Richacls (Core and Ext4) Message-ID: <20151110112943.GA17038@infradead.org> X-ASG-Orig-Subj: Re: [PATCH v15 00/22] Richacls (Core and Ext4) References: <1447067343-31479-1-git-send-email-agruenba@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1447067343-31479-1-git-send-email-agruenba@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: 1447154993 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/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.24270 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS On Mon, Nov 09, 2015 at 12:08:41PM +0100, Andreas Gruenbacher wrote: > Here is another update to the richacl patch queue. This posting contains > the patches ready to be merged; the patches later in the queue still need > some more review. It still has the same crappy fs interfaces with lots of boilerplate code and still abuses xattrs instead of a proper syscall interface. That's far from being ready to merge. From agruenba@redhat.com Tue Nov 10 06:40:01 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 4B7147F37 for ; Tue, 10 Nov 2015 06:40:01 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id BC8EBAC006 for ; Tue, 10 Nov 2015 04:39:57 -0800 (PST) X-ASG-Debug-ID: 1447159193-04cb6c296cfa5a0001-NocioJ Received: from mail-lb0-f171.google.com (mail-lb0-f171.google.com [209.85.217.171]) by cuda.sgi.com with ESMTP id YIE75fD44v0P69LQ (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 10 Nov 2015 04:39:54 -0800 (PST) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.85.217.171 Received: by lbbkw15 with SMTP id kw15so113136693lbb.0 for ; Tue, 10 Nov 2015 04:39:53 -0800 (PST) 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=QQXuSTpPTtmPHjtL2SUT+49LlIAWIF4h/tQb/bgPpu4=; b=iWphnu7U0Ju4nfsEYiEZg7Ha9bDAHwKYckdnW2055fuiO/CdhvMFYAEFK6YWsebttU kKwF0fAdaIQyXud6VSTpwq+qK2XNq5ExUrqdzFdwfTfAFSlBrCfouVXzoFcxbe3uwwYd Yd/VIZSCTZi6RuE2tjphaTEb3LMRXL+UyLDwtr4+6/SLsRsaTltJ3/NUhhfGfh0d9726 S7fj6+3Gi5lB4xrnl+/pnQ51Is42k4YlJvSde5fVmkkE1Xb6xOdkd9XsSfJxKlKRYQEU nFQevk/jKGVZYYW0noIH2IPd4XVptcEIoz8rUie7a8l8dSljWWRb9S6CjhifvM5NHqfJ AriQ== X-Gm-Message-State: ALoCoQmrm6hjvO+dx72ZkBM6nrLNrZ7xkMNXuFSBRBSgYiAgueD++P+C/Ho38Jc58IAEco56HzeV MIME-Version: 1.0 X-Received: by 10.112.16.162 with SMTP id h2mr1583279lbd.89.1447159192959; Tue, 10 Nov 2015 04:39:52 -0800 (PST) Received: by 10.112.53.42 with HTTP; Tue, 10 Nov 2015 04:39:52 -0800 (PST) In-Reply-To: <20151110112943.GA17038@infradead.org> References: <1447067343-31479-1-git-send-email-agruenba@redhat.com> <20151110112943.GA17038@infradead.org> Date: Tue, 10 Nov 2015 13:39:52 +0100 Message-ID: Subject: Re: [PATCH v15 00/22] Richacls (Core and Ext4) From: Andreas Gruenbacher X-ASG-Orig-Subj: Re: [PATCH v15 00/22] Richacls (Core and Ext4) To: Christoph Hellwig Cc: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4 , XFS Developers , LKML , linux-fsdevel , Linux NFS Mailing List , linux-cifs@vger.kernel.org, Linux API Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-lb0-f171.google.com[209.85.217.171] X-Barracuda-Start-Time: 1447159194 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24271 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Tue, Nov 10, 2015 at 12:29 PM, Christoph Hellwig wrote: > On Mon, Nov 09, 2015 at 12:08:41PM +0100, Andreas Gruenbacher wrote: >> Here is another update to the richacl patch queue. This posting contains >> the patches ready to be merged; the patches later in the queue still need >> some more review. > > It still has the same crappy fs interfaces with lots of boilerplate > code Could you please be more specific so that I can trace this complaint to some actual code? > and still abuses xattrs instead of a proper syscall interface. > That's far from being ready to merge. The xattr syscall interface is what's used for very similar kinds of things today; using it for richacls as well sure does not count as abuse. Things could be improved in the xattr interface and in its implementation, but we need more substantial reasons than that for reimplementing the wheel once again. [The recently discussed xattr fixes (http://permalink.gmane.org/gmane.linux.file-systems/101502) and two small POSIX ACL fixes (http://permalink.gmane.org/gmane.linux.file-systems/101499) are currently stuck waiting for Al, by the way.] Thanks, Andreas From bfoster@redhat.com Tue Nov 10 06:54:09 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 831157F37 for ; Tue, 10 Nov 2015 06:54:09 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 718B58F8033 for ; Tue, 10 Nov 2015 04:54:06 -0800 (PST) X-ASG-Debug-ID: 1447160044-04cb6c296cfaba0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id o8DdPx4ELZdoYJM3 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 10 Nov 2015 04:54:05 -0800 (PST) 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 (Postfix) with ESMTPS id 9EFB6A4514; Tue, 10 Nov 2015 12:54:04 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-67.bos.redhat.com [10.18.41.67]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAACs4iG019750; Tue, 10 Nov 2015 07:54:04 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id 6FE38125010; Tue, 10 Nov 2015 07:54:03 -0500 (EST) Date: Tue, 10 Nov 2015 07:54:03 -0500 From: Brian Foster To: Jia He Cc: xfs@oss.sgi.com Subject: Re: [PATCH] libxfs: Optimize the loop for xfs_bitmap_empty Message-ID: <20151110125403.GC21670@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH] libxfs: Optimize the loop for xfs_bitmap_empty References: <1447079482-10650-1-git-send-email-hejianet@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1447079482-10650-1-git-send-email-hejianet@gmail.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: 1447160045 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Mon, Nov 09, 2015 at 10:31:22PM +0800, Jia He wrote: > If there is any non zero bit in a long bitmap, it can jump out of the for > loop and finish the function as soon as possible. > > Signed-off-by: Jia He > Cc: Dave Chinner > Cc: Brian Foster > --- > fs/xfs/libxfs/xfs_bit.c | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/fs/xfs/libxfs/xfs_bit.c b/fs/xfs/libxfs/xfs_bit.c > index 0e8885a..84614b0 100644 > --- a/fs/xfs/libxfs/xfs_bit.c > +++ b/fs/xfs/libxfs/xfs_bit.c > @@ -36,6 +36,8 @@ xfs_bitmap_empty(uint *map, uint size) > > for (i = 0; i < size; i++) { > ret |= map[i]; > + if (ret != 0) > + return 0; > } > Seems Ok to me, but if we're going to do this, why not just kill ret entirely? For example, check 'if (map[i] != 0) return 0;' in the loop and unconditionally return 1 if we make it to the end. Brian > return (ret == 0); > -- > 2.5.0 > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From bfoster@redhat.com Tue Nov 10 07:45:25 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 550C97F37 for ; Tue, 10 Nov 2015 07:45:25 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id E1525AC004 for ; Tue, 10 Nov 2015 05:45:21 -0800 (PST) X-ASG-Debug-ID: 1447163120-04bdf03f03f6970001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id Sn4SmNAyDyavnEqO (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 10 Nov 2015 05:45:20 -0800 (PST) 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 (Postfix) with ESMTPS id 0F385A381D for ; Tue, 10 Nov 2015 13:45:20 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-67.bos.redhat.com [10.18.41.67]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAADjJS5020459 for ; Tue, 10 Nov 2015 08:45:19 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id 9D802125010; Tue, 10 Nov 2015 08:45:18 -0500 (EST) Date: Tue, 10 Nov 2015 08:45:18 -0500 From: Brian Foster To: xfs@oss.sgi.com Subject: Re: [PATCH 7/8] xfs: detect and trim torn writes during log recovery Message-ID: <20151110134518.GD21670@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH 7/8] xfs: detect and trim torn writes during log recovery References: <1447100475-33465-1-git-send-email-bfoster@redhat.com> <1447100475-33465-8-git-send-email-bfoster@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1447100475-33465-8-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: 1447163120 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Mon, Nov 09, 2015 at 03:21:14PM -0500, Brian Foster wrote: > Certain types of storage, such as persistent memory, do not provide > sector atomicity for writes. This means that if a crash occurs while XFS > is writing log records, only part of those records might make it to the > storage. This is problematic because log recovery uses the cycle value > packed at the top of each log block to locate the head/tail of the log. > This can lead to CRC verification failures during log recovery and an > unmountable fs for a filesystem that is otherwise consistent. > > Update log recovery to incorporate log record CRC verification as part > of the head/tail discovery process. Once the head is located via the > traditional algorithm, run a CRC-only pass over the records up to the > head of the log. If CRC verification fails, assume that the records are > torn as a matter of policy and trim the head block back to the start of > the first bad record. > > Signed-off-by: Brian Foster > --- > fs/xfs/xfs_log_recover.c | 298 ++++++++++++++++++++++++++++++++++++++++++++--- > 1 file changed, 279 insertions(+), 19 deletions(-) > > diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c > index 1b3f8fe..83fd7ca 100644 > --- a/fs/xfs/xfs_log_recover.c > +++ b/fs/xfs/xfs_log_recover.c ... > +STATIC int > +xlog_verify_head( > + struct xlog *log, > + xfs_daddr_t *head_blk, /* in/out: unverified head */ > + xfs_daddr_t *tail_blk, /* out: tail block */ > + struct xfs_buf *bp, > + xfs_daddr_t *rhead_blk, /* start blk of last record */ > + struct xlog_rec_header **rhead, /* ptr to last record */ > + bool *wrapped) /* last rec. wraps phys. log */ > +{ > + struct xlog_rec_header *tmp_rhead; > + struct xfs_buf *tmp_bp; > + xfs_daddr_t first_bad; > + xfs_daddr_t tmp_rhead_blk; > + int found; > + int error; > + bool tmp_wrapped; > + > + /* > + * Search backwards through the log looking for the log record header > + * block. This wraps all the way back around to the head so something is > + * seriously wrong if we can't find it. > + */ > + found = xlog_rseek_logrec_hdr(log, *head_blk, *head_blk, 1, bp, rhead_blk, > + rhead, wrapped); > + if (found < 0) > + return found; > + if (!found) { > + xfs_warn(log->l_mp, "%s: couldn't find sync record", __func__); > + return -EIO; > + } > + > + *tail_blk = BLOCK_LSN(be64_to_cpu((*rhead)->h_tail_lsn)); > + > + /* > + * Now that we have a tail block, check the head of the log for torn > + * writes. Search again until we hit the tail or the maximum number of > + * log record I/Os that could have been in flight at one time. Use a > + * temporary buffer so we don't trash the rhead/bp pointer from the > + * call above. > + */ > + tmp_bp = xlog_get_bp(log, 1); > + if (!tmp_bp) > + return -ENOMEM; > + error = xlog_rseek_logrec_hdr(log, *head_blk, *tail_blk, > + XLOG_MAX_ICLOGS, tmp_bp, &tmp_rhead_blk, > + &tmp_rhead, &tmp_wrapped); > + xlog_put_bp(tmp_bp); > + if (error < 0) > + return error; > + > + /* > + * Now run a CRC verification pass over the records starting at the > + * block found above to the current head. If a CRC failure occurs, the > + * log block of the first bad record is saved in first_bad. > + */ > + error = xlog_do_recovery_pass(log, *head_blk, tmp_rhead_blk, > + XLOG_RECOVER_CRCPASS, &first_bad); > + if (error == -EFSBADCRC && first_bad != *tail_blk) { I started playing around with an alternate error injection mechanism that actually writes out an invalid crc record, aborts on log write completion and shuts down the fs. With that, I hit an interesting problem with the first_bad != *tail_blk check in that we don't fix up the head if the first record written after a covered log is torn and points to itself as the tail. We end up failing the mount (which is what would happen currently, anyways), but this should probably be fixed up. Unfortunately I didn't sufficiently document why I had that check there. I suspect it is a remnant of an old version that didn't update the tail when the head was truncated back (before I fully grokked what was necessary here), and then ran into issues further along when the head == tail. This version obviously updates and verifies the tail once it finds a valid head so I can probably just kill the check. Perhaps I'll replace it with a head == tail check after the head/tail update to simply bail out and let normal recovery try to run. Brian > + /* > + * We've hit a potential torn write. Reset the error and warn > + * about it. > + */ > + error = 0; > + xfs_warn(log->l_mp, > +"WARNING: torn write (CRC failure) detected at block 0x%llx, recovery truncated", > + first_bad); > + > + /* > + * Get the header block and buffer pointer for the last good > + * record before the bad record. > + * > + * Note that xlog_find_tail() clears the blocks at the new head > + * (i.e., the records with invalid CRC) if the cycle number > + * matches the the current cycle. > + */ > + found = xlog_rseek_logrec_hdr(log, first_bad, *tail_blk, 1, bp, > + rhead_blk, rhead, wrapped); > + if (found < 0) > + return found; > + if (found == 0) /* XXX: right thing to do here? */ > + return -EIO; > + > + /* > + * Reset the head block to the starting block of the first bad > + * log record and set the tail block based on the last good > + * record. > + */ > + *head_blk = first_bad; > + *tail_blk = BLOCK_LSN(be64_to_cpu((*rhead)->h_tail_lsn)); > + > + /* > + * Now verify the tail based on the updated head. This is > + * required because the torn writes trimmed from the head could > + * have been written over the tail of a previous record. Return > + * any errors since recovery cannot proceed if the tail is > + * corrupt. > + * > + * XXX: This leaves a gap in truly robust protection from torn > + * writes in the log. If the head is behind the tail, the tail > + * pushes forward to create some space and then a crash occurs > + * causing the writes into the previous record's tail region to > + * tear, log recovery isn't able to recover. > + * > + * How likely is this to occur? If possible, can we do something > + * more intelligent here? Is it safe to push the tail forward if > + * we can determine that the tail is within the range of the > + * torn write (e.g., the kernel can only overwrite the tail if > + * it has actually been pushed forward)? Alternatively, could we > + * somehow prevent this condition at runtime? > + */ > + error = xlog_verify_tail(log, *head_blk, *tail_blk); > + } > + > + return error; > +} > + > +/* > * Find the sync block number or the tail of the log. > * > * This will be the block number of the last record to have its > @@ -966,9 +1233,10 @@ xlog_find_tail( > xlog_op_header_t *op_head; > char *offset = NULL; > xfs_buf_t *bp; > - int error, i, found; > + int error; > xfs_daddr_t umount_data_blk; > xfs_daddr_t after_umount_blk; > + xfs_daddr_t rhead_blk; > xfs_lsn_t tail_lsn; > int hblks; > bool wrapped = false; > @@ -995,24 +1263,16 @@ xlog_find_tail( > } > > /* > - * Search backwards through the log looking for the log record header > - * block. This wraps all the way back around to the head so something is > - * seriously wrong if we can't find it. > + * Trim the head block back to skip over torn records. We can have > + * multiple log I/Os in flight at any time, so we assume CRC failures > + * back through the previous several records are torn writes and skip > + * them. > */ > ASSERT(*head_blk < INT_MAX); > - found = xlog_rseek_logrec_hdr(log, *head_blk, *head_blk, 1, bp, &i, > - &rhead, &wrapped); > - if (found < 0) { > - error = found; > + error = xlog_verify_head(log, head_blk, tail_blk, bp, &rhead_blk, > + &rhead, &wrapped); > + if (error) > goto done; > - } > - if (!found) { > - xfs_warn(log->l_mp, "%s: couldn't find sync record", __func__); > - xlog_put_bp(bp); > - ASSERT(0); > - return -EIO; > - } > - *tail_blk = BLOCK_LSN(be64_to_cpu(rhead->h_tail_lsn)); > > /* > * Reset log values according to the state of the log when we > @@ -1024,7 +1284,7 @@ xlog_find_tail( > * written was complete and ended exactly on the end boundary > * of the physical log. > */ > - log->l_prev_block = i; > + log->l_prev_block = rhead_blk; > log->l_curr_block = (int)*head_blk; > log->l_curr_cycle = be32_to_cpu(rhead->h_cycle); > if (wrapped) > @@ -1062,12 +1322,12 @@ xlog_find_tail( > } else { > hblks = 1; > } > - after_umount_blk = (i + hblks + (int) > + after_umount_blk = (rhead_blk + hblks + (int) > BTOBB(be32_to_cpu(rhead->h_len))) % log->l_logBBsize; > tail_lsn = atomic64_read(&log->l_tail_lsn); > if (*head_blk == after_umount_blk && > be32_to_cpu(rhead->h_num_logops) == 1) { > - umount_data_blk = (i + hblks) % log->l_logBBsize; > + umount_data_blk = (rhead_blk + hblks) % log->l_logBBsize; > error = xlog_bread(log, umount_data_blk, 1, bp, &offset); > if (error) > goto done; > -- > 2.1.0 > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From bfoster@redhat.com Tue Nov 10 09:42:19 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 F06237F37 for ; Tue, 10 Nov 2015 09:42:19 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id DCDBC8F8040 for ; Tue, 10 Nov 2015 07:42:19 -0800 (PST) X-ASG-Debug-ID: 1447170138-04cbb02423103a10001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id fsbVRZsGNRX82HVB (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 10 Nov 2015 07:42:18 -0800 (PST) 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 (Postfix) with ESMTPS id 57051C0AEE5E for ; Tue, 10 Nov 2015 15:42:18 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-67.bos.redhat.com [10.18.41.67]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAAFgHTm013564 for ; Tue, 10 Nov 2015 10:42:18 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id E3E83125010; Tue, 10 Nov 2015 10:42:16 -0500 (EST) Date: Tue, 10 Nov 2015 10:42:16 -0500 From: Brian Foster To: xfs@oss.sgi.com Subject: Re: [PATCH 4/8] xfs: return start block of first bad log record during recovery Message-ID: <20151110154216.GE21670@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH 4/8] xfs: return start block of first bad log record during recovery References: <1447100475-33465-1-git-send-email-bfoster@redhat.com> <1447100475-33465-5-git-send-email-bfoster@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1447100475-33465-5-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.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1447170138 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Mon, Nov 09, 2015 at 03:21:11PM -0500, Brian Foster wrote: > Each log recovery pass walks from the tail block to the head block and > processes records appropriately based on the associated log pass type. > There are various failure conditions that can occur through this > sequence, such as I/O errors, CRC errors, etc. Log torn write detection > will perform CRC verification near the head of the log to detect torn > writes and trim torn records from the log appropriately. > > As it is, xlog_do_recovery_pass() only returns an error code in the > event of CRC failure, which isn't enough information to trim the head of > the log. Update xlog_do_recovery_pass() to optionally return the start > block of the associated record when an error occurs. This patch contains > no functional changes. > > Signed-off-by: Brian Foster > --- > fs/xfs/xfs_log_recover.c | 19 +++++++++++++++---- > 1 file changed, 15 insertions(+), 4 deletions(-) > > diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c > index c2bf307..2ef0880 100644 > --- a/fs/xfs/xfs_log_recover.c > +++ b/fs/xfs/xfs_log_recover.c > @@ -4239,10 +4239,12 @@ xlog_do_recovery_pass( > struct xlog *log, > xfs_daddr_t head_blk, > xfs_daddr_t tail_blk, > - int pass) > + int pass, > + xfs_daddr_t *first_bad) /* out: first bad log rec */ > { > xlog_rec_header_t *rhead; > xfs_daddr_t blk_no; > + xfs_daddr_t rhead_blk; > char *offset; > xfs_buf_t *hbp, *dbp; > int error = 0, h_size, h_len; > @@ -4251,6 +4253,7 @@ xlog_do_recovery_pass( > struct hlist_head rhash[XLOG_RHASH_SIZE]; > > ASSERT(head_blk != tail_blk); > + rhead_blk = 0; > > /* > * Read the header of the tail block and get the iclog buffer size from > @@ -4325,7 +4328,7 @@ xlog_do_recovery_pass( > } > > memset(rhash, 0, sizeof(rhash)); > - blk_no = tail_blk; > + blk_no = rhead_blk = tail_blk; > if (tail_blk > head_blk) { > /* > * Perform recovery around the end of the physical log. > @@ -4436,7 +4439,9 @@ xlog_do_recovery_pass( > pass); > if (error) > goto bread_err2; > + > blk_no += bblks; > + rhead_blk = blk_no; > } > > ASSERT(blk_no >= log->l_logBBsize); There's a rewind of blk_no (not shown in this patch) between the above loop and the subsequent loop to handle wrapping around the end of the log. We need to update rhead_blk there as well. Otherwise, if the first record processed in the following loop is bad, rhead_blk can still point beyond the end of the log and thus throw off all of the recovery bits that follow. Brian > @@ -4464,13 +4469,19 @@ xlog_do_recovery_pass( > error = xlog_recover_process(log, rhash, rhead, offset, pass); > if (error) > goto bread_err2; > + > blk_no += bblks + hblks; > + rhead_blk = blk_no; > } > > bread_err2: > xlog_put_bp(dbp); > bread_err1: > xlog_put_bp(hbp); > + > + if (error && first_bad) > + *first_bad = rhead_blk; > + > return error; > } > > @@ -4508,7 +4519,7 @@ xlog_do_log_recovery( > INIT_LIST_HEAD(&log->l_buf_cancel_table[i]); > > error = xlog_do_recovery_pass(log, head_blk, tail_blk, > - XLOG_RECOVER_PASS1); > + XLOG_RECOVER_PASS1, NULL); > if (error != 0) { > kmem_free(log->l_buf_cancel_table); > log->l_buf_cancel_table = NULL; > @@ -4519,7 +4530,7 @@ xlog_do_log_recovery( > * When it is complete free the table of buf cancel items. > */ > error = xlog_do_recovery_pass(log, head_blk, tail_blk, > - XLOG_RECOVER_PASS2); > + XLOG_RECOVER_PASS2, NULL); > #ifdef DEBUG > if (!error) { > int i; > -- > 2.1.0 > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From smfrench@gmail.com Tue Nov 10 10:44:09 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 EDD667F37 for ; Tue, 10 Nov 2015 10:44:09 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id DCFD4304032 for ; Tue, 10 Nov 2015 08:44:06 -0800 (PST) X-ASG-Debug-ID: 1447173845-04cb6c296d1011b0001-NocioJ Received: from mail-ig0-f181.google.com (mail-ig0-f181.google.com [209.85.213.181]) by cuda.sgi.com with ESMTP id 7FqBOFkQsde6YNQk (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 10 Nov 2015 08:44:05 -0800 (PST) X-Barracuda-Envelope-From: smfrench@gmail.com X-Barracuda-RBL-Trusted-Forwarder: 209.85.213.181 Received: by igl9 with SMTP id 9so57452570igl.0 for ; Tue, 10 Nov 2015 08:44:05 -0800 (PST) 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=SxjVrZPsF0ZqDYE//hZLdZ83d381gAqLq6th42j1qZs=; b=BeX8T6nMyIG8mgdKxiOOoTGvl1ROPaLJqYxoKtSoMRKmISxSu7D3HBxk243SwsT+q3 s/NsP80zdtin/UFmRKTqIWCmKJzrHluKJfCjUJzx0Ttpwj3QyfmMz/tzsorEYwoRV6xZ 7K2LtUSAGrekDfZ42lqbPZv+m2uJumMTJIg7rIy43NTw3RrweR43OdXEFIaen1nxQ6rx 2PuxC3UO0EudMasQTHp7CTOpFStnumEAz267XN47xv0WuaNLwv7ulal9IP5JaUQddgdl cN1q96TcPUbh8+NFE0vqYgmel7erSYmCiu7ZMlRWsvlerD4OqQAj3SUNiNuG1Q9ImNdf AJsQ== X-Received: by 10.50.20.167 with SMTP id o7mr4680725ige.44.1447173845598; Tue, 10 Nov 2015 08:44:05 -0800 (PST) MIME-Version: 1.0 Received: by 10.79.116.213 with HTTP; Tue, 10 Nov 2015 08:43:46 -0800 (PST) In-Reply-To: References: <1447067343-31479-1-git-send-email-agruenba@redhat.com> <20151110112943.GA17038@infradead.org> From: Steve French Date: Tue, 10 Nov 2015 10:43:46 -0600 Message-ID: Subject: Re: [PATCH v15 00/22] Richacls (Core and Ext4) To: Andreas Gruenbacher X-ASG-Orig-Subj: Re: [PATCH v15 00/22] Richacls (Core and Ext4) Cc: Christoph Hellwig , Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4 , XFS Developers , LKML , linux-fsdevel , Linux NFS Mailing List , "linux-cifs@vger.kernel.org" , Linux API Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-ig0-f181.google.com[209.85.213.181] X-Barracuda-Start-Time: 1447173845 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24275 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 Tue, Nov 10, 2015 at 6:39 AM, Andreas Gruenbacher wrote: > On Tue, Nov 10, 2015 at 12:29 PM, Christoph Hellwig wrote: >> On Mon, Nov 09, 2015 at 12:08:41PM +0100, Andreas Gruenbacher wrote: >>> Here is another update to the richacl patch queue. This posting contains >>> the patches ready to be merged; the patches later in the queue still need >>> some more review. >> and still abuses xattrs instead of a proper syscall interface. >> That's far from being ready to merge. > > The xattr syscall interface is what's used for very similar kinds of > things today; using it for richacls as well sure does not count as > abuse. Things could be improved in the xattr interface and in its > implementation, but we need more substantial reasons than that for > reimplementing the wheel once again. I don't have strong disagreement with using pseudo-xattrs to store/retrieve ACLs (we already do this) but retrieving/setting an ACL all at once can be awkward when ACLs are quite large e.g. when it encodes to over 1MB (not all administrators think about the size of ACLs when they add hundreds of users or groups or apps to ACLs). The bigger problem is that when ACLs are created -- after -- the file is created there is a potential race (harder to deal with in cluster and network file systems). Ideally we should be able to optionally pass all the security information needed to create a file in the create call itself. For apps which don't care they can continue to use the old syscalls. In the meantime, I don't mind the approach of staging this in via a pseudo-xattr, Samba can deal with that (and it will make some of the backup and data movement tools easier for the cifs.ko client which currently rely on a cifs specific xattr). In cifs.ko I still need to enable the SMB3 ACL helper functions (currently only enabled for the older cifs dialect) since that will make it easier, and figure out a way to allow helper tools to view "claims based ACLs" (DAC), not just traditional CIFS/NTFS/SMB3/RichACLs. -- Thanks, Steve From debbugs@buxtehude.debian.org Tue Nov 10 10:45:10 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 3542A7F50 for ; Tue, 10 Nov 2015 10:45:10 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id C5ECEAC009 for ; Tue, 10 Nov 2015 08:45:09 -0800 (PST) X-ASG-Debug-ID: 1447173907-04bdf03f04fb440001-NocioJ Received: from buxtehude.debian.org (buxtehude.debian.org [140.211.166.26]) by cuda.sgi.com with ESMTP id kx4XKeDCqL35zZFR (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 10 Nov 2015 08:45:07 -0800 (PST) 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.84) (envelope-from ) id 1ZwC2b-0005YH-6j; Tue, 10 Nov 2015 16:45:05 +0000 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-Mailer: MIME-tools 5.505 (Entity 5.505) Content-Type: text/plain; charset=utf-8 From: owner@bugs.debian.org (Debian Bug Tracking System) To: Steve McIntyre CC: xfs@oss.sgi.com Subject: Processed: Re: Bug#804255: Please update initramfs in postinst Message-ID: X-ASG-Orig-Subj: Processed: Re: Bug#804255: Please update initramfs in postinst References: <20151110164115.GG13015@einval.com> <20151106161941.15248.86048.reportbug@tack.local> X-Debian-PR-Package: xfsprogs X-Debian-PR-Source: xfsprogs X-Debian-PR-Message: transcript X-Loop: owner@bugs.debian.org Date: Tue, 10 Nov 2015 16:45:05 +0000 X-Barracuda-Connect: buxtehude.debian.org[140.211.166.26] X-Barracuda-Start-Time: 1447173907 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24275 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Processing control commands: > tag -1 +patch Bug #804255 [xfsprogs] Please update initramfs in postinst Added tag(s) patch. --=20 804255: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=3D804255 Debian Bug Tracking System Contact owner@bugs.debian.org with problems From debbugs@buxtehude.debian.org Tue Nov 10 10:45:11 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 60EAF7F50 for ; Tue, 10 Nov 2015 10:45:11 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id CE33FAC009 for ; Tue, 10 Nov 2015 08:45:10 -0800 (PST) X-ASG-Debug-ID: 1447173906-04cb6c296c101260001-NocioJ Received: from buxtehude.debian.org (buxtehude.debian.org [140.211.166.26]) by cuda.sgi.com with ESMTP id 3FFotjZeRqqoEmWI (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 10 Nov 2015 08:45:07 -0800 (PST) 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.84) (envelope-from ) id 1ZwC2a-0005Y3-8F; Tue, 10 Nov 2015 16:45:04 +0000 X-Loop: owner@bugs.debian.org Subject: Bug#804255: Please update initramfs in postinst Reply-To: Steve McIntyre , 804255@bugs.debian.org X-ASG-Orig-Subj: Bug#804255: Please update initramfs in postinst Resent-From: Steve McIntyre Resent-To: debian-bugs-dist@lists.debian.org Resent-CC: XFS Development Team X-Loop: owner@bugs.debian.org Resent-Date: Tue, 10 Nov 2015 16:45:02 +0000 Resent-Message-ID: X-Debian-PR-Message: followup 804255 X-Debian-PR-Package: xfsprogs X-Debian-PR-Keywords: d-i X-Debian-PR-Source: xfsprogs Received: via spool by 804255-submit@bugs.debian.org id=B804255.144717373620517 (code B ref 804255); Tue, 10 Nov 2015 16:45:02 +0000 Received: (at 804255) by bugs.debian.org; 10 Nov 2015 16:42:16 +0000 Received: from cheddar.halon.org.uk ([93.93.131.118]) by buxtehude.debian.org with esmtps (TLS1.2:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.84) (envelope-from ) id 1ZwBzs-0005KR-3X for 804255@bugs.debian.org; Tue, 10 Nov 2015 16:42:16 +0000 Received: from bsmtp by cheddar.halon.org.uk with local-bsmtp (Exim 4.80) (envelope-from ) id 1ZwBzm-0001o4-NH; Tue, 10 Nov 2015 16:42:10 +0000 Received: from steve by tack.local with local (Exim 4.84) (envelope-from ) id 1ZwByt-0004w3-OK; Tue, 10 Nov 2015 16:41:15 +0000 Date: Tue, 10 Nov 2015 16:41:15 +0000 From: Steve McIntyre To: Nathan Scott Cc: 804255@bugs.debian.org Message-ID: <20151110164115.GG13015@einval.com> References: <20151106161941.15248.86048.reportbug@tack.local> <1822095565.6959319.1447027220334.JavaMail.zimbra@redhat.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="2fHTh5uZTiUOsy+g" Content-Disposition: inline In-Reply-To: <1822095565.6959319.1447027220334.JavaMail.zimbra@redhat.com> X-attached: unknown User-Agent: Mutt/1.5.23 (2014-03-12) X-Barracuda-Connect: buxtehude.debian.org[140.211.166.26] X-Barracuda-Start-Time: 1447173907 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.75 X-Barracuda-Spam-Status: No, SCORE=0.75 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_RULE_7580D X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24275 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.75 BSF_RULE_7580D Custom Rule 7580D --2fHTh5uZTiUOsy+g Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Control: tag -1 +patch On Sun, Nov 08, 2015 at 07:00:20PM -0500, Nathan Scott wrote: >Hi Steve, > >----- Original Message ----- >> Package: xfsprogs >> Version: 3.2.1 >> Severity: important >> Tags: d-i >> >> To make this work well, all filesystem tools packages for filesystems >> that are likely to be used for / and/or /usr should call >> "update-initramfs -u" in their postinst. This will > >OK. > >> I've checked your package and I don't see any update-initramfs >> calls. > >(yep, xfsprogs has no postinst at all IIRC) > >> Please add one. If you'd like help doing that postinst work, I >> can supply a patch - just ask! > >That would be great, if you don't mind Steve? Many thanks! Here's a debdiff of what I've just built. Ignore the NMU version in the changelog... -- Steve McIntyre, Cambridge, UK. steve@einval.com The two hard things in computing: * naming things * cache invalidation * off-by-one errors -- Stig Sandbeck Mathisen --2fHTh5uZTiUOsy+g Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="xfsprogs_4.2.0.1.debdiff" diff -Nru xfsprogs-4.2.0/debian/changelog xfsprogs-4.2.0.1/debian/changelog --- xfsprogs-4.2.0/debian/changelog 2015-09-11 01:51:36.000000000 +0000 +++ xfsprogs-4.2.0.1/debian/changelog 2015-11-10 16:35:45.000000000 +0000 @@ -1,3 +1,11 @@ +xfsprogs (4.2.0.1) unstable; urgency=low + + * NMU + * * Add a postinst to update the initramfs on install/upgrade. + (Closes: #804255) + + -- Steve McIntyre <93sam@debian.org> Tue, 10 Nov 2015 16:33:59 +0000 + xfsprogs (4.2.0) unstable; urgency=low * New upstream release diff -Nru xfsprogs-4.2.0/debian/postinst xfsprogs-4.2.0.1/debian/postinst --- xfsprogs-4.2.0/debian/postinst 1970-01-01 00:00:00.000000000 +0000 +++ xfsprogs-4.2.0.1/debian/postinst 2015-11-10 16:35:20.000000000 +0000 @@ -0,0 +1,25 @@ +#!/bin/sh + +set -e + +case "${1}" in + configure) + if [ -x /usr/sbin/update-initramfs ] && [ -e /etc/initramfs-tools/initramfs.conf ] + then + update-initramfs -u + fi + ;; + + abort-upgrade|abort-remove|abort-deconfigure) + + ;; + + *) + echo "postinst called with unknown argument \`${1}'" >&2 + exit 1 + ;; +esac + +#DEBHELPER# + +exit 0 --2fHTh5uZTiUOsy+g-- From bfields@fieldses.org Tue Nov 10 11:07:09 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 D795E7F3F for ; Tue, 10 Nov 2015 11:07:09 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id C6E2A8F8033 for ; Tue, 10 Nov 2015 09:07:06 -0800 (PST) X-ASG-Debug-ID: 1447175224-04cb6c296a101b60001-NocioJ Received: from fieldses.org (fieldses.org [173.255.197.46]) by cuda.sgi.com with ESMTP id ccqVrreBGDBRRPZ7 for ; Tue, 10 Nov 2015 09:07:04 -0800 (PST) X-Barracuda-Envelope-From: bfields@fieldses.org X-Barracuda-Apparent-Source-IP: 173.255.197.46 Received: by fieldses.org (Postfix, from userid 2815) id 47C953675; Tue, 10 Nov 2015 12:07:03 -0500 (EST) Date: Tue, 10 Nov 2015 12:07:03 -0500 From: "J. Bruce Fields" To: Steve French Cc: Andreas Gruenbacher , Christoph Hellwig , Alexander Viro , Theodore Ts'o , Andreas Dilger , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4 , XFS Developers , LKML , linux-fsdevel , Linux NFS Mailing List , "linux-cifs@vger.kernel.org" , Linux API Subject: Re: [PATCH v15 00/22] Richacls (Core and Ext4) Message-ID: <20151110170703.GB17530@fieldses.org> X-ASG-Orig-Subj: Re: [PATCH v15 00/22] Richacls (Core and Ext4) References: <1447067343-31479-1-git-send-email-agruenba@redhat.com> <20151110112943.GA17038@infradead.org> 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: fieldses.org[173.255.197.46] X-Barracuda-Start-Time: 1447175224 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24276 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC5_SA210e Custom Rule SA210e On Tue, Nov 10, 2015 at 10:43:46AM -0600, Steve French wrote: > On Tue, Nov 10, 2015 at 6:39 AM, Andreas Gruenbacher > wrote: > > On Tue, Nov 10, 2015 at 12:29 PM, Christoph Hellwig wrote: > >> On Mon, Nov 09, 2015 at 12:08:41PM +0100, Andreas Gruenbacher wrote: > >>> Here is another update to the richacl patch queue. This posting contains > >>> the patches ready to be merged; the patches later in the queue still need > >>> some more review. > > >> and still abuses xattrs instead of a proper syscall interface. > >> That's far from being ready to merge. > > > > The xattr syscall interface is what's used for very similar kinds of > > things today; using it for richacls as well sure does not count as > > abuse. Things could be improved in the xattr interface and in its > > implementation, but we need more substantial reasons than that for > > reimplementing the wheel once again. > > I don't have strong disagreement with using pseudo-xattrs to > store/retrieve ACLs (we already do this) but retrieving/setting an ACL > all at once can be awkward when ACLs are quite large e.g. when it > encodes to over 1MB At least in the NFS case, that's also a limitation of the protocol. If we really wanted to support massive ACLs then we'd need both syscall and NFS interfaces to allow incrementally reading and writing ACLs, and I don't even know what those would look like. So this is a fine limitation as far as I'm concerned. > (not all administrators think about the size of > ACLs when they add hundreds of users or groups or apps to ACLs). > > The bigger problem is that when ACLs are created -- after -- the file > is created there is a potential race (harder to deal with in cluster > and network file systems). Ideally we should be able to optionally > pass all the security information needed to create a file in the > create call itself. For apps which don't care they can continue to > use the old syscalls. That would be most of them, I'd think. But I suppose windows apps (via Samba or Wine?) could use this. Definitely a project for another day, in any case. --b. > In cifs.ko I still need to enable the SMB3 ACL helper functions > (currently only enabled for the older cifs dialect) since that will > make it easier, and figure out a way to allow helper tools to view > "claims based ACLs" (DAC), not just traditional > CIFS/NTFS/SMB3/RichACLs. > -- > Thanks, > > Steve From agruenba@redhat.com Tue Nov 10 11:58:23 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 3BF427F3F for ; Tue, 10 Nov 2015 11:58:23 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 1ACB18F8033 for ; Tue, 10 Nov 2015 09:58:22 -0800 (PST) X-ASG-Debug-ID: 1447178300-04cb6c296d102ee0001-NocioJ Received: from mail-lb0-f174.google.com (mail-lb0-f174.google.com [209.85.217.174]) by cuda.sgi.com with ESMTP id 0cYAavlD9o7kZJcz (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 10 Nov 2015 09:58:21 -0800 (PST) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.85.217.174 Received: by lbbcs9 with SMTP id cs9so2808182lbb.1 for ; Tue, 10 Nov 2015 09:58:19 -0800 (PST) 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=0ZmcQWAGoeLVMQhM3YbEjW32MEAbvnfytSNDtUxK3Ps=; b=hRXi+XP6V8+JJaftzWv58vmw6A46susMMj+BtZwCsvFCxlT0m61vl4yWqX1s/gffkB N4c5xdMiBMxiiin0amUXaDJgSRd6h23EcbzMESkqs0IAvBI07+n6TMzfNYpvjr4hAQP/ LYULIiaM/D9lu6cJe3xoRVKNaAPD1IzYaFb6NNVUUMhnwrt3YvLOka2l4YAYPffPFsQF gzYBxzBN2/7dzL/Syk/KZUGkJN2ApIZ1xSVR/ZX26acqBnbEUqlbC21OJF1DcK9RSgkC 2yyCJhA6M9UbxrmwzQiSHYSWxbO3+1cTHDAvsJQNalBpgj3Iyrq1OkjJFEjnipVgwFkN e4/A== X-Gm-Message-State: ALoCoQmxuEUd/riLxhwPLLk+P4lRN25qkhSDmO4+nMTa/55ITJbei8K5KsMHCxXa12VJTP0v0AEi MIME-Version: 1.0 X-Received: by 10.112.205.194 with SMTP id li2mr2289257lbc.75.1447178299815; Tue, 10 Nov 2015 09:58:19 -0800 (PST) Received: by 10.112.53.42 with HTTP; Tue, 10 Nov 2015 09:58:19 -0800 (PST) In-Reply-To: <20151110170703.GB17530@fieldses.org> References: <1447067343-31479-1-git-send-email-agruenba@redhat.com> <20151110112943.GA17038@infradead.org> <20151110170703.GB17530@fieldses.org> Date: Tue, 10 Nov 2015 18:58:19 +0100 Message-ID: Subject: Re: [PATCH v15 00/22] Richacls (Core and Ext4) From: Andreas Gruenbacher X-ASG-Orig-Subj: Re: [PATCH v15 00/22] Richacls (Core and Ext4) To: "J. Bruce Fields" Cc: Steve French , Christoph Hellwig , Alexander Viro , "Theodore Ts'o" , Andreas Dilger , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4 , XFS Developers , LKML , linux-fsdevel , Linux NFS Mailing List , "linux-cifs@vger.kernel.org" , Linux API Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-lb0-f174.google.com[209.85.217.174] X-Barracuda-Start-Time: 1447178300 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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, BSF_SC5_SA210e X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24277 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.00 BSF_SC5_SA210e Custom Rule SA210e On Tue, Nov 10, 2015 at 6:07 PM, J. Bruce Fields wrote: > On Tue, Nov 10, 2015 at 10:43:46AM -0600, Steve French wrote: >> On Tue, Nov 10, 2015 at 6:39 AM, Andreas Gruenbacher >> wrote: >> > On Tue, Nov 10, 2015 at 12:29 PM, Christoph Hellwig wrote: >> >> On Mon, Nov 09, 2015 at 12:08:41PM +0100, Andreas Gruenbacher wrote: >> >>> Here is another update to the richacl patch queue. This posting contains >> >>> the patches ready to be merged; the patches later in the queue still need >> >>> some more review. >> >> >> and still abuses xattrs instead of a proper syscall interface. >> >> That's far from being ready to merge. >> > >> > The xattr syscall interface is what's used for very similar kinds of >> > things today; using it for richacls as well sure does not count as >> > abuse. Things could be improved in the xattr interface and in its >> > implementation, but we need more substantial reasons than that for >> > reimplementing the wheel once again. >> >> I don't have strong disagreement with using pseudo-xattrs to >> store/retrieve ACLs (we already do this) but retrieving/setting an ACL >> all at once can be awkward when ACLs are quite large e.g. when it >> encodes to over 1MB > > At least in the NFS case, that's also a limitation of the protocol. I couldn't find a limit in the NFSv4 specification, but the client and server implementations both define arbitrary ACL size limits. In addition, the xattr syscalls allow attributes to be up to 64k long. > If > we really wanted to support massive ACLs then we'd need both syscall and > NFS interfaces to allow incrementally reading and writing ACLs, and I > don't even know what those would look like. > > So this is a fine limitation as far as I'm concerned. The bigger problem would be incrementally setting ACLs. To prevent processes from racing with each other, we would need a locking mechanism. In addition, the memory overhead would be prohibitive and access decisions would become extremely slow; we would have to come up with mechanisms to avoid those problems. Thanks, Andreas From prvs=8756a6f0b1=clm@fb.com Tue Nov 10 12:02:04 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 DBCCC7F4E for ; Tue, 10 Nov 2015 12:02:03 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 77569AC006 for ; Tue, 10 Nov 2015 10:02:00 -0800 (PST) X-ASG-Debug-ID: 1447178518-04bdf03f04fd3a0001-NocioJ Received: from mx0b-00082601.pphosted.com (mx0b-00082601.pphosted.com [67.231.153.30]) by cuda.sgi.com with ESMTP id gBqhFIighi6gVFoO (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 10 Nov 2015 10:01:58 -0800 (PST) X-Barracuda-Envelope-From: prvs=8756a6f0b1=clm@fb.com X-Barracuda-Apparent-Source-IP: 67.231.153.30 X-ASG-Whitelist: EmailCat (corporate) Received: from pps.filterd (m0001255.ppops.net [127.0.0.1]) by mx0b-00082601.pphosted.com (8.15.0.59/8.15.0.59) with SMTP id tAAHuk45026623; Tue, 10 Nov 2015 10:01:56 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=fb.com; h=date : from : to : subject : message-id : references : mime-version : content-type : in-reply-to; s=facebook; bh=Sbm9nkqSKGUa2+qxdsswbemhonXdzhT1aS/v4x2SY4A=; b=oYnsM1ZXyjyyl7EH6Zlw8ngRwoRNYxpbp9wPE/Wn9r7XoobSqDjw9yWth9crX/ESZbLc ywUmaiWRy1aaWbLnU4cpjlL27llHSmkU3KfBOap9XxOa5kXxeA1nPtf8BZQq+VXKSIxE FVRKldbjn6Ltm/ow3nIFVye0CdRtc2KsKdQ= Received: from mail.thefacebook.com ([199.201.64.23]) by mx0b-00082601.pphosted.com with ESMTP id 1y1e06jnpx-2 (version=TLSv1/SSLv3 cipher=AES128-SHA bits=128 verify=NOT); Tue, 10 Nov 2015 10:01:56 -0800 Received: from localhost (192.168.52.123) by mail.thefacebook.com (192.168.16.24) with Microsoft SMTP Server (TLS) id 14.3.248.2; Tue, 10 Nov 2015 10:01:51 -0800 Date: Tue, 10 Nov 2015 13:01:50 -0500 From: Chris Mason To: Dave Chinner , , Tejun Heo Subject: [PATCH v2] xfs: use WQ_MEM_RECLAIM for m_log_workqueue Message-ID: <20151110180150.GD26661@ret.masoncoding.com> X-ASG-Orig-Subj: [PATCH v2] xfs: use WQ_MEM_RECLAIM for m_log_workqueue References: <20151104185103.GC5458@ret.masoncoding.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Disposition: inline In-Reply-To: <20151104185103.GC5458@ret.masoncoding.com> User-Agent: Mutt/1.5.23.1 (2014-03-12) X-Originating-IP: [192.168.52.123] X-Proofpoint-Spam-Reason: safe X-FB-Internal: Safe X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:,, definitions=2015-11-10_13:,, signatures=0 X-Barracuda-Connect: mx0b-00082601.pphosted.com[67.231.153.30] X-Barracuda-Start-Time: 1447178518 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 We're consistently hitting deadlocks here with XFS on recent kernels. After some digging through the crash files, it looks like everyone in the system is waiting for XFS to reclaim memory. Something like this: PID: 2733434 TASK: ffff8808cd242800 CPU: 19 COMMAND: "java" 0 [ffff88082d093368] __schedule at ffffffff818c4df2 1 [ffff88082d0933b8] schedule at ffffffff818c5517 2 [ffff88082d0933d8] schedule_timeout at ffffffff818c7c6c 3 [ffff88082d093478] wait_for_completion at ffffffff818c6125 4 [ffff88082d0934d8] flush_work at ffffffff8106867c 5 [ffff88082d093548] xlog_cil_force_lsn at ffffffff81317b00 6 [ffff88082d0935f8] _xfs_log_force_lsn at ffffffff81316249 7 [ffff88082d093688] xfs_log_force_lsn at ffffffff813164fb 8 [ffff88082d0936b8] xfs_iunpin_wait at ffffffff8130835e 9 [ffff88082d093728] xfs_reclaim_inode at ffffffff812fd453 10 [ffff88082d093778] xfs_reclaim_inodes_ag at ffffffff812fd8c7 11 [ffff88082d093928] xfs_reclaim_inodes_nr at ffffffff812fe433 12 [ffff88082d093958] xfs_fs_free_cached_objects at ffffffff8130d3b9 13 [ffff88082d093968] super_cache_scan at ffffffff811a6f73 14 [ffff88082d0939c8] shrink_slab at ffffffff811460e6 15 [ffff88082d093aa8] shrink_zone at ffffffff8114a53f 16 [ffff88082d093b48] do_try_to_free_pages at ffffffff8114a8ba 17 [ffff88082d093be8] try_to_free_pages at ffffffff8114ad5a 18 [ffff88082d093c78] __alloc_pages_nodemask at ffffffff8113e1b8 19 [ffff88082d093d88] alloc_kmem_pages_node at ffffffff8113e671 20 [ffff88082d093dd8] copy_process at ffffffff8104f781 21 [ffff88082d093ec8] do_fork at ffffffff8105129c 22 [ffff88082d093f38] sys_clone at ffffffff810515b6 23 [ffff88082d093f48] stub_clone at ffffffff818c8e4d xfs_log_force_lsn is waiting for logs to get cleaned, which is waiting for IO, which is waiting for workers to complete the IO which is waiting for worker threads that don't exist yet: PID: 2752451 TASK: ffff880bd6bdda00 CPU: 37 COMMAND: "kworker/37:1" 0 [ffff88000394fbb0] __schedule at ffffffff818c4df2 1 [ffff88000394fc00] schedule at ffffffff818c5517 2 [ffff88000394fc20] schedule_timeout at ffffffff818c7c6c 3 [ffff88000394fcc0] wait_for_completion_killable at ffffffff818c6495 4 [ffff88000394fd30] kthread_create_on_node at ffffffff8106ec82 5 [ffff88000394fdf0] create_worker at ffffffff8106752f 6 [ffff88000394fe40] worker_thread at ffffffff810699be 7 [ffff88000394fec0] kthread at ffffffff8106ef59 8 [ffff88000394ff50] ret_from_fork at ffffffff818c8ac8 I think we should be using WQ_MEM_RECLAIM to make sure this thread pool makes progress when we're not able to allocate new workers. While we are here, just assume that everything in the FS will eventually wait on one of these workqueues, and flag them all for reclaim. Signed-off-by: Chris Mason --- v1 -> v2 add WQ_MEM_RECLAIM to xfs-reclaim and xfs-eofblocks too, fix commit text so git commit doesn't eat the stack traces fs/xfs/xfs_super.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 904f637..d74d7e1 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -838,17 +838,18 @@ xfs_init_mount_workqueues( goto out_destroy_unwritten; mp->m_reclaim_workqueue = alloc_workqueue("xfs-reclaim/%s", - WQ_FREEZABLE, 0, mp->m_fsname); + WQ_MEM_RECLAIM|WQ_FREEZABLE, 0, mp->m_fsname); if (!mp->m_reclaim_workqueue) goto out_destroy_cil; mp->m_log_workqueue = alloc_workqueue("xfs-log/%s", - WQ_FREEZABLE|WQ_HIGHPRI, 0, mp->m_fsname); + WQ_MEM_RECLAIM|WQ_FREEZABLE|WQ_HIGHPRI, + 0, mp->m_fsname); if (!mp->m_log_workqueue) goto out_destroy_reclaim; mp->m_eofblocks_workqueue = alloc_workqueue("xfs-eofblocks/%s", - WQ_FREEZABLE, 0, mp->m_fsname); + WQ_MEM_RECLAIM|WQ_FREEZABLE, 0, mp->m_fsname); if (!mp->m_eofblocks_workqueue) goto out_destroy_log; -- 2.4.6 From sandeen@redhat.com Tue Nov 10 12:21:13 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 8FC237F4E for ; Tue, 10 Nov 2015 12:21:13 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 63EEC8F8035 for ; Tue, 10 Nov 2015 10:21:13 -0800 (PST) X-ASG-Debug-ID: 1447179672-04cbb02423107d10001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id CfpM2E90YbOJMSFT (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 10 Nov 2015 10:21:12 -0800 (PST) X-Barracuda-Envelope-From: sandeen@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 (Postfix) with ESMTPS id 085D41361 for ; Tue, 10 Nov 2015 18:21:12 +0000 (UTC) Received: from liberator.sandeen.net (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAAILADM021973 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 10 Nov 2015 13:21:11 -0500 To: xfs@oss.sgi.com Cc: jtulak@redhat.com From: Eric Sandeen Subject: [PATCH] xfsprogs: fix cut & paste error in xfs_fsr.c X-Enigmail-Draft-Status: N1110 X-ASG-Orig-Subj: [PATCH] xfsprogs: fix cut & paste error in xfs_fsr.c Message-ID: <56423596.3030300@redhat.com> Date: Tue, 10 Nov 2015 12:21:10 -0600 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit 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: 1447179672 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Commit: 7141fc xfsprogs: make fsr use mntinfo when there is no mntent added an inadvertent "break;" to initallfs() after the call to find_mountpoint_check(); this is likely a cut & paste error from the call in find_mountpoint(), where we really *do* want to stop after the first one we find. Fix that by removing the break, and fix the declaration-after-code. Addresses-Coverity-Id: 1338431 Signed-off-by: Eric Sandeen --- I'll probably follow this with some other cleanups, but this is the functional fix AFAICT. diff --git a/fsr/xfs_fsr.c b/fsr/xfs_fsr.c index b902acc..9332c57 100644 --- a/fsr/xfs_fsr.c +++ b/fsr/xfs_fsr.c @@ -433,12 +433,11 @@ initallfs(char *mtab) } while ( (mp = platform_mntent_next(&cursor)) != NULL) { + int rw = 0; + mntp = find_mountpoint_check(&sb, mp, &ms); if (mntp == NULL) continue; - break; - - int rw = 0; if (strcmp(mp->mnt_type, MNTTYPE_XFS ) != 0 || stat64(mp->mnt_fsname, &sb) == -1 || From sandeen@sandeen.net Tue Nov 10 12:45:35 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 086597F3F for ; Tue, 10 Nov 2015 12:45:35 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id CD1878F8035 for ; Tue, 10 Nov 2015 10:45:34 -0800 (PST) X-ASG-Debug-ID: 1447181128-04bdf03f05fe4f0001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id jmVeBe4b2KHlwmUe for ; Tue, 10 Nov 2015 10:45:28 -0800 (PST) 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 DDEFB6372A81 for ; Tue, 10 Nov 2015 12:45:27 -0600 (CST) Subject: Re: [PATCH] xfsprogs: fix cut & paste error in xfs_fsr.c To: xfs@oss.sgi.com X-ASG-Orig-Subj: Re: [PATCH] xfsprogs: fix cut & paste error in xfs_fsr.c References: <56423596.3030300@redhat.com> From: Eric Sandeen X-Enigmail-Draft-Status: N1110 Message-ID: <56423B47.4060306@sandeen.net> Date: Tue, 10 Nov 2015 12:45:27 -0600 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <56423596.3030300@redhat.com> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 8bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1447181128 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24277 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 11/10/15 12:21 PM, Eric Sandeen wrote: > Commit: > > 7141fc xfsprogs: make fsr use mntinfo when there is no mntent > > added an inadvertent "break;" to initallfs() after the call > to find_mountpoint_check(); this is likely a cut & paste error > from the call in find_mountpoint(), where we really *do* want to > stop after the first one we find. > > Fix that by removing the break, and fix the declaration-after-code. > > Addresses-Coverity-Id: 1338431 > Signed-off-by: Eric Sandeen > --- Actually, unless Jan's commit fixes something important for this release (and I don't think it does?) I'd just revert it; it's pretty chock full of outright errors and other weirdness. For example: initallfs(mtab); struct stat64 sb; mntp = find_mountpoint_check(&sb, mp, &ms); and find_mounpoint_check() does: if (S_ISDIR(sb->st_mode)) { so "sb" is never initialized on that path. Weird that Coverity didn't see it. (I'm also not a fan of using "sb" and "mp" for things that aren't superblocks and xfs_mount_t's, but that's just style I guess...) ((and every caller passes an ms stat buffer into the function, which can be local to the function, as no caller uses it ...)) (((and there's whitespace damage))) Jan said this patch "fell under the sofa" - I think it might need a bit more dusting off before it's ready to go... ;) -Eric From bfields@fieldses.org Tue Nov 10 13:17:52 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 AC4D47F3F for ; Tue, 10 Nov 2015 13:17:52 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 9D8F0304032 for ; Tue, 10 Nov 2015 11:17:49 -0800 (PST) X-ASG-Debug-ID: 1447183065-04cbb02424109280001-NocioJ Received: from fieldses.org (fieldses.org [173.255.197.46]) by cuda.sgi.com with ESMTP id SlYCD3la5JJL1XH6 for ; Tue, 10 Nov 2015 11:17:46 -0800 (PST) X-Barracuda-Envelope-From: bfields@fieldses.org X-Barracuda-Apparent-Source-IP: 173.255.197.46 Received: by fieldses.org (Postfix, from userid 2815) id 68A1EC4F; Tue, 10 Nov 2015 14:17:45 -0500 (EST) Date: Tue, 10 Nov 2015 14:17:45 -0500 From: "J. Bruce Fields" To: Andreas Gruenbacher Cc: Steve French , Christoph Hellwig , Alexander Viro , Theodore Ts'o , Andreas Dilger , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4 , XFS Developers , LKML , linux-fsdevel , Linux NFS Mailing List , "linux-cifs@vger.kernel.org" , Linux API Subject: Re: [PATCH v15 00/22] Richacls (Core and Ext4) Message-ID: <20151110191745.GA19379@fieldses.org> X-ASG-Orig-Subj: Re: [PATCH v15 00/22] Richacls (Core and Ext4) References: <1447067343-31479-1-git-send-email-agruenba@redhat.com> <20151110112943.GA17038@infradead.org> <20151110170703.GB17530@fieldses.org> 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: fieldses.org[173.255.197.46] X-Barracuda-Start-Time: 1447183066 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24278 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Tue, Nov 10, 2015 at 06:58:19PM +0100, Andreas Gruenbacher wrote: > On Tue, Nov 10, 2015 at 6:07 PM, J. Bruce Fields wrote: > > On Tue, Nov 10, 2015 at 10:43:46AM -0600, Steve French wrote: > >> I don't have strong disagreement with using pseudo-xattrs to > >> store/retrieve ACLs (we already do this) but retrieving/setting an ACL > >> all at once can be awkward when ACLs are quite large e.g. when it > >> encodes to over 1MB > > > > At least in the NFS case, that's also a limitation of the protocol. > > I couldn't find a limit in the NFSv4 specification, but the client and > server implementations both define arbitrary ACL size limits. In > addition, the xattr syscalls allow attributes to be up to 64k long. I don't recall 4.0 specifying any limit, 4.1 does include negotiation of maximum rpc calls and replies, and that effectively limits ACL sizes since they have to fit in a single rpc. > The bigger problem would be incrementally setting ACLs. To prevent > processes from racing with each other, we would need a locking > mechanism. In addition, the memory overhead would be prohibitive and > access decisions would become extremely slow; we would have to come up > with mechanisms to avoid those problems. Right. Anyway, not worth the trouble, I think. (Though what might be worth thinking about at some point is just making sure we fail in helpful ways.) --b. From david@fromorbit.com Tue Nov 10 14:28:14 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 AE6A57F47 for ; Tue, 10 Nov 2015 14:28:14 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 3408BAC004 for ; Tue, 10 Nov 2015 12:28:11 -0800 (PST) X-ASG-Debug-ID: 1447187287-04cb6c296b106a80001-NocioJ Received: from ipmail06.adl6.internode.on.net (ipmail06.adl6.internode.on.net [150.101.137.145]) by cuda.sgi.com with ESMTP id b9Xn7N5h8Qz9BXJt for ; Tue, 10 Nov 2015 12:28:08 -0800 (PST) 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: A2ATCQBGUkJWPGfGLHleKAECgxCBQoJfg36kaQEBAQEBAQaLMoUshA2GCgICAQECgUpNAQEBAQEBBwEBAQFAAT+ENAEBAQQnExwjEAgDFQMJJQ8FJQMHGhOILcNwAQEBBwIBIBmFdIVFiTkFh0SPBI0ejzSNGYJ0HYFqKjSFLgEBAQ Received: from ppp121-44-198-103.lns20.syd7.internode.on.net (HELO dastard) ([121.44.198.103]) by ipmail06.adl6.internode.on.net with ESMTP; 11 Nov 2015 06:58:07 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZwFWQ-0000P3-Hl; Wed, 11 Nov 2015 07:28:06 +1100 Date: Wed, 11 Nov 2015 07:28:06 +1100 From: Dave Chinner To: Eric Sandeen Cc: xfs@oss.sgi.com, jtulak@redhat.com Subject: Re: [PATCH] xfsprogs: fix cut & paste error in xfs_fsr.c Message-ID: <20151110202806.GG14311@dastard> X-ASG-Orig-Subj: Re: [PATCH] xfsprogs: fix cut & paste error in xfs_fsr.c References: <56423596.3030300@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <56423596.3030300@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: 1447187287 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24280 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Tue, Nov 10, 2015 at 12:21:10PM -0600, Eric Sandeen wrote: > Commit: > > 7141fc xfsprogs: make fsr use mntinfo when there is no mntent > > added an inadvertent "break;" to initallfs() after the call > to find_mountpoint_check(); this is likely a cut & paste error > from the call in find_mountpoint(), where we really *do* want to > stop after the first one we find. > > Fix that by removing the break, and fix the declaration-after-code. That's not the right fix - the find_mountpoint_check() shoul dnot be there at all. Patch to clean it all up is below. -Dave. -- Dave Chinner david@fromorbit.com fsr: clean up mountpoint checks From: Dave Chinner Fix up a stray hunk of code from commit 7141fc5 ("xfsprogs: make fsr use mntinfo when there is no mntent") that coverity reported. Also clean up a couple of whitespace issues introduced with that commit, too. Addresses-Coverity-Id: 1338431 Signed-off-by: Dave Chinner --- fsr/xfs_fsr.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/fsr/xfs_fsr.c b/fsr/xfs_fsr.c index b902acc..2887ceb 100644 --- a/fsr/xfs_fsr.c +++ b/fsr/xfs_fsr.c @@ -176,7 +176,6 @@ aborter(int unused) * here - the code that handles defragmentation of invidual files takes care * of that. */ - static char * find_mountpoint_check(struct stat64 *sb, struct mntent *t, struct stat64 *ms) { @@ -200,9 +199,9 @@ find_mountpoint_check(struct stat64 *sb, struct mntent *t, struct stat64 *ms) return NULL; /* - * Make sure the mountpoint given by mtab is accessible - * before using it. - */ + * Make sure the mountpoint given by mtab is accessible + * before using it. + */ if (stat64(t->mnt_dir, &sb2) < 0) return NULL; } @@ -224,7 +223,7 @@ find_mountpoint(char *mtab, char *argname, struct stat64 *sb) exit(1); } - while ( (t = platform_mntent_next(&cursor)) != NULL) { + while ((t = platform_mntent_next(&cursor)) != NULL) { mntp = find_mountpoint_check(sb, t, &ms); if (mntp == NULL) continue; @@ -409,12 +408,10 @@ static void initallfs(char *mtab) { struct mntent_cursor cursor; - char *mntp = NULL; struct mntent *mp = NULL; int mi; char *cp; struct stat64 sb; - struct stat64 ms; /* malloc a number of descriptors, increased later if needed */ if (!(fsbase = (fsdesc_t *)malloc(fsbufsize * sizeof(fsdesc_t)))) { @@ -432,12 +429,7 @@ initallfs(char *mtab) exit(1); } - while ( (mp = platform_mntent_next(&cursor)) != NULL) { - mntp = find_mountpoint_check(&sb, mp, &ms); - if (mntp == NULL) - continue; - break; - + while ((mp = platform_mntent_next(&cursor)) != NULL) { int rw = 0; if (strcmp(mp->mnt_type, MNTTYPE_XFS ) != 0 || From sandeen@redhat.com Tue Nov 10 14:35:33 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 D7B987F50 for ; Tue, 10 Nov 2015 14:35:32 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 6A545AC008 for ; Tue, 10 Nov 2015 12:35:32 -0800 (PST) X-ASG-Debug-ID: 1447187727-04cbb0242510be10001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id OBOzLaGEaXT1yf6d (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 10 Nov 2015 12:35:28 -0800 (PST) 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 (Postfix) with ESMTPS id 93742C0B8407; Tue, 10 Nov 2015 20:35:27 +0000 (UTC) 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 tAAKZOn6022638 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 10 Nov 2015 15:35:26 -0500 Subject: Re: [PATCH] xfsprogs: fix cut & paste error in xfs_fsr.c To: Dave Chinner X-ASG-Orig-Subj: Re: [PATCH] xfsprogs: fix cut & paste error in xfs_fsr.c References: <56423596.3030300@redhat.com> <20151110202806.GG14311@dastard> Cc: xfs@oss.sgi.com, jtulak@redhat.com From: Eric Sandeen X-Enigmail-Draft-Status: N1110 Message-ID: <5642550C.4040603@redhat.com> Date: Tue, 10 Nov 2015 14:35:24 -0600 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <20151110202806.GG14311@dastard> Content-Type: text/plain; charset=windows-1252 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: 1447187728 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 > On Tue, Nov 10, 2015 at 12:21:10PM -0600, Eric Sandeen wrote: >> Commit: >> >> 7141fc xfsprogs: make fsr use mntinfo when there is no mntent >> >> added an inadvertent "break;" to initallfs() after the call >> to find_mountpoint_check(); this is likely a cut & paste error >> from the call in find_mountpoint(), where we really *do* want to >> stop after the first one we find. >> >> Fix that by removing the break, and fix the declaration-after-code. > > That's not the right fix - the find_mountpoint_check() shoul dnot be > there at all. Patch to clean it all up is below. > > -Dave. > -- > Dave Chinner > david@fromorbit.com > > fsr: clean up mountpoint checks > > From: Dave Chinner > > Fix up a stray hunk of code from commit 7141fc5 ("xfsprogs: make fsr > use mntinfo when there is no mntent") that coverity reported. Also > clean up a couple of whitespace issues introduced with that commit, > too. Um, ok, well it wasn't your misapplication, it was there in the original patch, and I wasn't sure of Jan's intent, having gone so far as to add local vars to support that placement. ;) This seems fine, I guess I'll send another patch to make *ms local to find_mountpoint_check(), and rename some vars ("sb" and "mp" have their own expected meanings in xfsprogs) Reviewed-by: Eric Sandeen -Eric > Addresses-Coverity-Id: 1338431 > Signed-off-by: Dave Chinner > --- > fsr/xfs_fsr.c | 18 +++++------------- > 1 file changed, 5 insertions(+), 13 deletions(-) > > diff --git a/fsr/xfs_fsr.c b/fsr/xfs_fsr.c > index b902acc..2887ceb 100644 > --- a/fsr/xfs_fsr.c > +++ b/fsr/xfs_fsr.c > @@ -176,7 +176,6 @@ aborter(int unused) > * here - the code that handles defragmentation of invidual files takes care > * of that. > */ > - > static char * > find_mountpoint_check(struct stat64 *sb, struct mntent *t, struct stat64 *ms) > { > @@ -200,9 +199,9 @@ find_mountpoint_check(struct stat64 *sb, struct mntent *t, struct stat64 *ms) > return NULL; > > /* > - * Make sure the mountpoint given by mtab is accessible > - * before using it. > - */ > + * Make sure the mountpoint given by mtab is accessible > + * before using it. > + */ > if (stat64(t->mnt_dir, &sb2) < 0) > return NULL; > } > @@ -224,7 +223,7 @@ find_mountpoint(char *mtab, char *argname, struct stat64 *sb) > exit(1); > } > > - while ( (t = platform_mntent_next(&cursor)) != NULL) { > + while ((t = platform_mntent_next(&cursor)) != NULL) { > mntp = find_mountpoint_check(sb, t, &ms); > if (mntp == NULL) > continue; > @@ -409,12 +408,10 @@ static void > initallfs(char *mtab) > { > struct mntent_cursor cursor; > - char *mntp = NULL; > struct mntent *mp = NULL; > int mi; > char *cp; > struct stat64 sb; > - struct stat64 ms; > > /* malloc a number of descriptors, increased later if needed */ > if (!(fsbase = (fsdesc_t *)malloc(fsbufsize * sizeof(fsdesc_t)))) { > @@ -432,12 +429,7 @@ initallfs(char *mtab) > exit(1); > } > > - while ( (mp = platform_mntent_next(&cursor)) != NULL) { > - mntp = find_mountpoint_check(&sb, mp, &ms); > - if (mntp == NULL) > - continue; > - break; > - > + while ((mp = platform_mntent_next(&cursor)) != NULL) { > int rw = 0; > > if (strcmp(mp->mnt_type, MNTTYPE_XFS ) != 0 || > From sandeen@sandeen.net Tue Nov 10 14:45:53 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 A94D77F47 for ; Tue, 10 Nov 2015 14:45:53 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 9C8CA304032 for ; Tue, 10 Nov 2015 12:45:50 -0800 (PST) X-ASG-Debug-ID: 1447188347-04cb6c296d107170001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id WTAwerSubci5rbpy for ; Tue, 10 Nov 2015 12:45:47 -0800 (PST) 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 4327265BD16C for ; Tue, 10 Nov 2015 14:45:47 -0600 (CST) Subject: [PATCH] xfsprogs: tidy up xfs_fsr.c To: xfs@oss.sgi.com X-ASG-Orig-Subj: [PATCH] xfsprogs: tidy up xfs_fsr.c References: <56423596.3030300@redhat.com> <20151110202806.GG14311@dastard> From: Eric Sandeen Message-ID: <5642577A.8000206@sandeen.net> Date: Tue, 10 Nov 2015 14:45:46 -0600 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <20151110202806.GG14311@dastard> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1447188347 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24280 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Make the mountpoint stat structure "ms" local to find_mountpoint_check(), no caller uses it. And remove 3rd "sb2" statbuf in that same function, we can just re-use ms. rename "struct mntent *mp" to "struct mntent *mnt" - "mp" has its own common meaning in xfsprogs. And a couple more minor whitespace removals. Signed-off-by: Eric Sandeen --- diff --git a/fsr/xfs_fsr.c b/fsr/xfs_fsr.c index 2887ceb..d5962f7 100644 --- a/fsr/xfs_fsr.c +++ b/fsr/xfs_fsr.c @@ -177,44 +177,41 @@ aborter(int unused) * of that. */ static char * -find_mountpoint_check(struct stat64 *sb, struct mntent *t, struct stat64 *ms) +find_mountpoint_check(struct stat64 *sb, struct mntent *t) { + struct stat64 ms; + if (S_ISDIR(sb->st_mode)) { /* mount point */ - if (stat64(t->mnt_dir, ms) < 0) + if (stat64(t->mnt_dir, &ms) < 0) return NULL; - if (sb->st_ino != ms->st_ino) + if (sb->st_ino != ms.st_ino) return NULL; - if (sb->st_dev != ms->st_dev) + if (sb->st_dev != ms.st_dev) return NULL; if (strcmp(t->mnt_type, MNTTYPE_XFS) != 0) return NULL; } else { /* device */ - struct stat64 sb2; - - if (stat64(t->mnt_fsname, ms) < 0) + if (stat64(t->mnt_fsname, &ms) < 0) return NULL; - if (sb->st_rdev != ms->st_rdev) + if (sb->st_rdev != ms.st_rdev) return NULL; if (strcmp(t->mnt_type, MNTTYPE_XFS) != 0) return NULL; - /* * Make sure the mountpoint given by mtab is accessible * before using it. */ - if (stat64(t->mnt_dir, &sb2) < 0) + if (stat64(t->mnt_dir, &ms) < 0) return NULL; } return t->mnt_dir; - } static char * find_mountpoint(char *mtab, char *argname, struct stat64 *sb) { struct mntent_cursor cursor; - struct stat64 ms; struct mntent *t = NULL; char *mntp = NULL; @@ -224,7 +221,7 @@ find_mountpoint(char *mtab, char *argname, struct stat64 *sb) } while ((t = platform_mntent_next(&cursor)) != NULL) { - mntp = find_mountpoint_check(sb, t, &ms); + mntp = find_mountpoint_check(sb, t); if (mntp == NULL) continue; break; @@ -408,7 +405,7 @@ static void initallfs(char *mtab) { struct mntent_cursor cursor; - struct mntent *mp = NULL; + struct mntent *mnt= NULL; int mi; char *cp; struct stat64 sb; @@ -429,15 +426,15 @@ initallfs(char *mtab) exit(1); } - while ((mp = platform_mntent_next(&cursor)) != NULL) { + while ((mnt = platform_mntent_next(&cursor)) != NULL) { int rw = 0; - if (strcmp(mp->mnt_type, MNTTYPE_XFS ) != 0 || - stat64(mp->mnt_fsname, &sb) == -1 || + if (strcmp(mnt->mnt_type, MNTTYPE_XFS ) != 0 || + stat64(mnt->mnt_fsname, &sb) == -1 || !S_ISBLK(sb.st_mode)) continue; - cp = strtok(mp->mnt_opts,","); + cp = strtok(mnt->mnt_opts,","); do { if (strcmp("rw", cp) == 0) rw++; @@ -445,7 +442,7 @@ initallfs(char *mtab) if (rw == 0) { if (dflag) fsrprintf(_("Skipping %s: not mounted rw\n"), - mp->mnt_fsname); + mnt->mnt_fsname); continue; } @@ -465,15 +462,15 @@ initallfs(char *mtab) fs = (fsbase + mi); /* Needed ? */ } - fs->dev = strdup(mp->mnt_fsname); - fs->mnt = strdup(mp->mnt_dir); + fs->dev = strdup(mnt->mnt_fsname); + fs->mnt = strdup(mnt->mnt_dir); if (fs->dev == NULL) { - fsrprintf(_("strdup(%s) failed\n"), mp->mnt_fsname); + fsrprintf(_("strdup(%s) failed\n"), mnt->mnt_fsname); exit(1); } if (fs->mnt == NULL) { - fsrprintf(_("strdup(%s) failed\n"), mp->mnt_dir); + fsrprintf(_("strdup(%s) failed\n"), mnt->mnt_dir); exit(1); } mi++; From debbugs@buxtehude.debian.org Tue Nov 10 15:54:09 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 F0AE27F56 for ; Tue, 10 Nov 2015 15:54:08 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 8A39FAC008 for ; Tue, 10 Nov 2015 13:54:08 -0800 (PST) X-ASG-Debug-ID: 1447192446-04bdf03f021024d0001-NocioJ Received: from buxtehude.debian.org (buxtehude.debian.org [140.211.166.26]) by cuda.sgi.com with ESMTP id vi2wAXewztQOmmL8 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 10 Nov 2015 13:54:07 -0800 (PST) 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.84) (envelope-from ) id 1ZwGrc-0001tC-CG; Tue, 10 Nov 2015 21:54:04 +0000 X-Loop: owner@bugs.debian.org Subject: Bug#804255: Please update initramfs in postinst Reply-To: Nathan Scott , 804255@bugs.debian.org X-ASG-Orig-Subj: Bug#804255: Please update initramfs in postinst Resent-From: Nathan Scott Resent-To: debian-bugs-dist@lists.debian.org Resent-CC: XFS Development Team X-Loop: owner@bugs.debian.org Resent-Date: Tue, 10 Nov 2015 21:54:02 +0000 Resent-Message-ID: X-Debian-PR-Message: followup 804255 X-Debian-PR-Package: xfsprogs X-Debian-PR-Keywords: d-i patch X-Debian-PR-Source: xfsprogs Received: via spool by 804255-submit@bugs.debian.org id=B804255.14471922356455 (code B ref 804255); Tue, 10 Nov 2015 21:54:02 +0000 Received: (at 804255) by bugs.debian.org; 10 Nov 2015 21:50:35 +0000 Received: from mx6-phx2.redhat.com ([209.132.183.39]) by buxtehude.debian.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84) (envelope-from ) id 1ZwGoF-0001fs-BF for 804255@bugs.debian.org; Tue, 10 Nov 2015 21:50:35 +0000 Received: from zmail20.collab.prod.int.phx2.redhat.com (zmail20.collab.prod.int.phx2.redhat.com [10.5.83.23]) by mx6-phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAALoW3P019730; Tue, 10 Nov 2015 16:50:33 -0500 Date: Tue, 10 Nov 2015 16:50:31 -0500 (EST) From: Nathan Scott To: Steve McIntyre , 804255@bugs.debian.org Message-ID: <557726867.9104603.1447192231975.JavaMail.zimbra@redhat.com> In-Reply-To: <20151110164115.GG13015@einval.com> References: <20151106161941.15248.86048.reportbug@tack.local> <1822095565.6959319.1447027220334.JavaMail.zimbra@redhat.com> <20151110164115.GG13015@einval.com> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-Originating-IP: [10.64.51.139] X-Mailer: Zimbra 8.0.6_GA_5922 (ZimbraWebClient - FF37 (Linux)/8.0.6_GA_5922) Thread-Topic: Bug#804255: Please update initramfs in postinst Thread-Index: tlNqo2V1BFTwQffbVpWhgSsmcEqnQQ== X-Barracuda-Connect: buxtehude.debian.org[140.211.166.26] X-Barracuda-Start-Time: 1447192447 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/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.24283 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.01 THREAD_INDEX thread-index: AcO7Y8iR61tzADqsRmmc5wNiFHEOig== 0.01 THREAD_TOPIC Thread-Topic: ...(Japanese Subject)... ----- Original Message ----- > >[...] > >That would be great, if you don't mind Steve? Many thanks! > > Here's a debdiff of what I've just built. Ignore the NMU version in > the changelog... Thanks Steve - I believe there's an upstream xfsprogs release pending, so we'll get this uploaded shortly. cheers. -- Nathan From arekm@maven.pl Tue Nov 10 16:13:49 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 476627F4E for ; Tue, 10 Nov 2015 16:13:49 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 297DC30405F for ; Tue, 10 Nov 2015 14:13:45 -0800 (PST) X-ASG-Debug-ID: 1447193618-04cbb0242410dc70001-NocioJ Received: from mail-lf0-f54.google.com (mail-lf0-f54.google.com [209.85.215.54]) by cuda.sgi.com with ESMTP id jTddF4HGH2HYFKoK (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 10 Nov 2015 14:13:39 -0800 (PST) X-Barracuda-Envelope-From: arekm@maven.pl X-Barracuda-Apparent-Source-IP: 209.85.215.54 Received: by lffu14 with SMTP id u14so6588168lff.1 for ; Tue, 10 Nov 2015 14:13:38 -0800 (PST) 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=8/IcmuJpOC3lJRaN8uk/KsEYF0q+YNE6sSeffXOxzQA=; b=YBP3/VWSsEICuzSBqQfQtNMT8C25pDITMzQaf2nMZS7cEhCMY7zQFRsIwfVmDAgBgv /d1+VBu+ZzZQOXCDW9JS34bXwuwLhO54D2q4lxuXRwlZi39/tOhXwuUAdXPJxFvq5ECf Dit1A6lzzxqt+RD/1Ws3JPCalKUHJm0wbrM+Q= 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=8/IcmuJpOC3lJRaN8uk/KsEYF0q+YNE6sSeffXOxzQA=; b=Fw4vHThtRiExIXZoEyTAozfdzwAgeeW6ooe9IZPXD6uCWBW36AE4L3zQiljGsFr00A SzeGiX/ZtKYt/FxKy9wyTsooGnRr38zxRLLNPB1PODQ0U8TuRH796eVcAvK1PPUhWuU4 e0JtscFay6FS6bv2ueP/cUnLNcFWaM5Id9YsPsiVIZr1oS/huuWcmytkArclOe2vc8eR XsYEU2tIhbmB7wsD+BfoU2irF+rD0Wuj5mpCOGceP3GskNG9HpOEtEZANN3FXQzcCDDm cC9X+LD2j6oXkAzJ0xAx+ZcWLkUYApMtswaLogqeTlFjHv9baBFSWXcnvlNeoc9M/4Wn pQtw== X-Gm-Message-State: ALoCoQlbz5+TW4jv0M9dwazLL9eEBrAbS/atVoxgzfHKAyvb2+tOMs5wK6JXuKHllBsNjh6uujFU X-Received: by 10.25.20.160 with SMTP id 32mr2922056lfu.28.1447193618126; Tue, 10 Nov 2015 14:13:38 -0800 (PST) Received: from xps.localnet (85-222-71-204.dynamic.chello.pl. [85.222.71.204]) by smtp.gmail.com with ESMTPSA id a2sm884811lbc.20.2015.11.10.14.13.37 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 10 Nov 2015 14:13:37 -0800 (PST) From: Arkadiusz =?utf-8?q?Mi=C5=9Bkiewicz?= To: linux-mm@kvack.org, xfs@oss.sgi.com Subject: memory reclaim problems on fs usage Date: Tue, 10 Nov 2015 23:13:36 +0100 X-ASG-Orig-Subj: memory reclaim problems on fs usage User-Agent: KMail/1.13.7 (Linux/4.3.0-09269-gce5c2d2; KDE/4.14.13; x86_64; ; ) MIME-Version: 1.0 Content-Type: Text/Plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <201511102313.36685.arekm@maven.pl> X-Barracuda-Connect: mail-lf0-f54.google.com[209.85.215.54] X-Barracuda-Start-Time: 1447193619 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24283 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. I have a x86_64 system running 4.1.12 kernel on top of software raid array = (raid 1 and 6) on top of adaptec HBA card (ASR71605E) that provides connectivity to 16 sata rotational disks. fs is XFS. System has 8GB of ram and 111GB of swap on ssd disk (swap is barely used: ~7,4MB in use). Usage scenario on this machine is 5-10 (sometimes more) rsnapshot/rsync pro= cesses doing hardlinks and copying tons of files. The usual (repeatable) problem is like this: full dmesg: http://sprunge.us/VEiE (more in it then in partial log below) partial log: 122365.832373] swapper/3: page allocation failure: order:0, mode:0x20 [122365.832382] CPU: 3 PID: 0 Comm: swapper/3 Not tainted 4.1.12-3 #1 [122365.832384] Hardware name: Supermicro X8SIL/X8SIL, BIOS 1.2a 06/2= 7/2012 [122365.832386] 0000000000000000 ab5d50b5f2ae9872 ffff88023fcc3b18 fffffff= f8164b37a [122365.832390] 0000000000000000 0000000000000020 ffff88023fcc3ba8 fffffff= f8118f02e [122365.832392] 0000000000000000 0000000000000001 ffff880200000030 ffff880= 0ba984400 [122365.832395] Call Trace: [122365.832398] [] dump_stack+0x45/0x57 [122365.832409] [] warn_alloc_failed+0xfe/0x150 [122365.832415] [] ? raid5_align_endio+0x148/0x160 [raid= 456] [122365.832418] [] __alloc_pages_nodemask+0x322/0xa90 [122365.832423] [] __alloc_page_frag+0x12c/0x150 [122365.832426] [] __alloc_rx_skb+0x66/0x100 [122365.832430] [] ? __blk_mq_complete_request+0x7c/0x110 [122365.832433] [] __napi_alloc_skb+0x22/0x50 [122365.832440] [] e1000_clean_rx_irq+0x33e/0x3f0 [e1000= e] [122365.832444] [] ? timer_cpu_notify+0x160/0x160 [122365.832449] [] e1000e_poll+0xbc/0x2f0 [e1000e] [122365.832457] [] ? aac_src_intr_message+0xaf/0x3e0 [aa= craid] [122365.832461] [] net_rx_action+0x212/0x340 [122365.832465] [] __do_softirq+0x103/0x280 [122365.832467] [] irq_exit+0xad/0xb0 [122365.832471] [] do_IRQ+0x58/0xf0 [122365.832474] [] common_interrupt+0x6e/0x6e [122365.832476] [] ? mwait_idle+0x8c/0x150 [122365.832482] [] arch_cpu_idle+0xf/0x20 [122365.832485] [] cpu_startup_entry+0x380/0x400 [122365.832488] [] start_secondary+0x17d/0x1a0 [122365.832491] Mem-Info: [122365.832496] active_anon:28246 inactive_anon:31593 isolated_anon:0 active_file:6641 inactive_file:1616279 isolated_file:0 unevictable:0 dirty:136960 writeback:0 unstable:0 slab_reclaimable:191482 slab_unreclaimable:34061 mapped:3744 shmem:0 pagetables:1015 bounce:0 free:5700 free_pcp:551 free_cma:0 [122365.832500] Node 0 DMA free:15884kB min:20kB low:24kB high:28kB active_= anon:0kB inactive_anon:0kB active_file:0kB inactive_file:0kB unevictable:0k= B isolated(anon):0kB isolated(file):0kB present:15968kB managed:15884kB=20 mlocked:0kB dirty:0kB writeback:0kB mapped:0kB shmem:0kB slab_reclaimable:0= kB slab_unreclaimable:0kB kernel_stack:0kB pagetables:0kB unstable:0kB boun= ce:0kB free_pcp:0kB local_pcp:0kB free_cma:0kB writeback_tmp:0kB=20 pages_scanned:0 all_unreclaimable? yes [122365.832505] lowmem_reserve[]: 0 2968 7958 7958 [122365.832508] Node 0 DMA32 free:6916kB min:4224kB low:5280kB high:6336kB = active_anon:34904kB inactive_anon:44024kB active_file:9076kB inactive_file:= 2313600kB unevictable:0kB isolated(anon):0kB isolated(file):0kB=20 present:3120704kB managed:3043796kB mlocked:0kB dirty:199004kB writeback:0k= B mapped:5488kB shmem:0kB slab_reclaimable:441924kB slab_unreclaimable:3844= 0kB kernel_stack:960kB pagetables:1084kB unstable:0kB=20 bounce:0kB free_pcp:1132kB local_pcp:184kB free_cma:0kB writeback_tmp:0kB p= ages_scanned:0 all_unreclaimable? no [122365.832514] lowmem_reserve[]: 0 0 4990 4990 [122365.832517] Node 0 Normal free:0kB min:7104kB low:8880kB high:10656kB a= ctive_anon:78080kB inactive_anon:82348kB active_file:17488kB inactive_file:= 4151516kB unevictable:0kB isolated(anon):0kB isolated(file):0kB=20 present:5242880kB managed:5109980kB mlocked:0kB dirty:348836kB writeback:0k= B mapped:9488kB shmem:0kB slab_reclaimable:324004kB slab_unreclaimable:9780= 4kB kernel_stack:1760kB pagetables:2976kB unstable:0kB=20 bounce:0kB free_pcp:1072kB local_pcp:120kB free_cma:0kB writeback_tmp:0kB p= ages_scanned:0 all_unreclaimable? no [122365.832522] lowmem_reserve[]: 0 0 0 0 [122365.832525] Node 0 DMA: 1*4kB (U) 1*8kB (U) 0*16kB 0*32kB 2*64kB (U) 1*= 128kB (U) 1*256kB (U) 0*512kB 1*1024kB (U) 1*2048kB (R) 3*4096kB (M) =3D 15= 884kB [122365.832536] Node 0 DMA32: 1487*4kB (UE) 0*8kB 7*16kB (R) 9*32kB (R) 5*6= 4kB (R) 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB =3D 6668kB [122365.832544] Node 0 Normal: 0*4kB 0*8kB 0*16kB 0*32kB 0*64kB 0*128kB 0*2= 56kB 0*512kB 0*1024kB 0*2048kB 0*4096kB =3D 0kB [122365.832552] Node 0 hugepages_total=3D0 hugepages_free=3D0 hugepages_sur= p=3D0 hugepages_size=3D2048kB [122365.832554] 1623035 total pagecache pages [122365.832556] 96 pages in swap cache [122365.832558] Swap cache stats: add 1941, delete 1845, find 1489/1529 [122365.832559] Free swap =3D 117213444kB [122365.832561] Total swap =3D 117220820kB [122365.832562] 2094888 pages RAM [122365.832564] 0 pages HighMem/MovableOnly [122365.832565] 48377 pages reserved [122365.832567] 4096 pages cma reserved [122365.832568] 0 pages hwpoisoned [122377.888271] XFS: possible memory allocation deadlock in xfs_buf_allocat= e_memory (mode:0x250) [122379.889804] XFS: possible memory allocation deadlock in xfs_buf_allocat= e_memory (mode:0x250) [122381.891337] XFS: possible memory allocation deadlock in xfs_buf_allocat= e_memory (mode:0x250) [122383.892871] XFS: possible memory allocation deadlock in xfs_buf_allocat= e_memory (mode:0x250) Tried to ask on #xfs@freenode and #mm@oftc and did a bit of irc relay betwe= en channels and people. Essential parts of discussion: #xfs 22:00 < dchinner__> arekm: so teh machine has 8GB ram, and it has almost 6G= B of inactive file pages? 22:01 < dchinner__> it seems like there is a lot of reclaimable memory in t= hat machine when it starts having problems... 22:04 < dchinner__> indeed, the ethernet driver is having problems with an = order 0 allocation, when there appears to be lots of reclaimable memory.... 22:04 < arekm> dchinner__: 8GB of ram, 111GB of swap (ssd; looks unused - o= nly ~7.4MB in use), 5x rsync, 1xmysqldump, raid1 and raid6 on sata disks 22:04 < dchinner__> ah: 22:05 < dchinner__> Node 0 Normal: 0*4kB 0*8kB 0*16kB 0*32kB 0*64kB 0*128kB= 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB =3D 0kB 22:05 < dchinner__> looks like there's a problem with a zone imbalance 22:05 < dchinner__> Node 0 DMA32: 1487*4kB (UE) 0*8kB 7*16kB (R) 9*32kB (R)= 5*64kB (R) 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB =3D 6668kB 22:07 < dchinner__> given that the zones have heaps of clean, inactive file= pages, the DMA32 and NORMAL zones are not marked as "all unreclaimable", a= nd there's the free pages in ZONE_NORMAL have been completely drained 22:07 < dchinner__> I'd be asking the mm folks what is going on 22:08 < dchinner__> I'd say XFS is backed up on the same issue so normal zone is drained to 0 #mm 22:15 < arekmx> hi. I'm running backup system on 4.1.12 kernel. Machine mos= tly does rsnapshot/rsyncs (5-10 in parallel). Unfortunately it hits memory = problems often -> http://sprunge.us/VEiE . I've asked XFS people and the conc= lusion was that this is most likely mm problem -> http://sprunge.us/ggVG An= y ideas what could be going on ? (like normal zone is completly drained for examp= le) 22:29 < sasha_> Wild guess: your xfs is on a rather slow storage device (ne= twork?) 22:33 < arekmx> sasha_: raid6 on local rotational sata disks... so could be= slow, especially when 10x rsyncs start and hdd heads need to jump like cra= zy 22:33 < sasha_> Hm, shouldn't be *that* slow though 22:34 < sasha_> The scenario I see is that xfs can't run reclaim fast enoug= h, so the system runs out of memory and it appears to have a lot of "unused= cache" it should have freed 22:34 < sasha_> Look at all those cpus stuck in xfs reclaim, while one of t= hem is waiting for IO 22:38 < sasha_> I suppose the easiest one is just not caching on that files= ystem I don't think there is a way to do that. 22:41 < sasha_> Or maybe your RAID box/disks are dying? Nope, good condition according to smart logs (but started long tests to ret= est) #xfs: 22:40 < dchinner__> arekm: XFs is waiting on slab cache reclaim 22:41 < dchinner__> because there are already as many slab reclaimers as th= ere are AGs, and reclaim can't progress any faster than that 22:41 < dchinner__> but slab reclaim does not prevent clean pages from bein= g reclaimed by direct reclaim during memory allocation 22:41 < dchinner__> it's a completely different part of memory reclaim 22:42 < dchinner__> the fact that XFs is repeatedly saying "memory allocati= on failed" means it is not getting backed up on slab cache reclaim 22:42 < dchinner__> especially as it's a GFP_NOFS allocation which means th= e slab shrinkers are being skipped. 22:43 < dchinner__> direct page cache reclaim should be occurring on GFP_NO= =46S allocation because there are clean pages available to be reclaimed 22:44 < dchinner__> but that is not happening - the processes blocked in th= e shrinkers are not relevant to the XFS allocations that=20 Overall I was asked to post this to both mailing list to get better coverag= e and possibly solution to the problem. kernel config: http://sprunge.us/SRUi # cat /proc/mdstat Personalities : [raid1] [raid6] [raid5] [raid4] md4 : active raid6 sdg[0] sdi[5] sdh[4] sdd[3] sdf[2] sde[1] 11720540160 blocks super 1.2 level 6, 512k chunk, algorithm 2 [6/6] [= UUUUUU] bitmap: 1/22 pages [4KB], 65536KB chunk md3 : active raid6 sdj[9] sdq[7] sdp[6] sdo[10] sdn[4] sdm[8] sdl[2] sdk[1] 5859781632 blocks super 1.2 level 6, 512k chunk, algorithm 2 [8/8] [U= UUUUUUU] bitmap: 3/8 pages [12KB], 65536KB chunk md1 : active raid1 sdb1[0] sdc1[1] 524224 blocks [2/2] [UU] md2 : active raid1 sdb2[0] sdc2[1] 731918016 blocks super 1.2 [2/2] [UU] rsync/rsnapshot processes operate on md3 and md4 =2D-=20 Arkadiusz Mi=C5=9Bkiewicz, arekm / ( maven.pl | pld-linux.org ) From sfr@canb.auug.org.au Tue Nov 10 17:22:03 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 BF58A7F47 for ; Tue, 10 Nov 2015 17:22:03 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 9F320304062 for ; Tue, 10 Nov 2015 15:22:00 -0800 (PST) X-ASG-Debug-ID: 1447197715-04bdf03f03103f40001-NocioJ Received: from ozlabs.org (ozlabs.org [103.22.144.67]) by cuda.sgi.com with ESMTP id nctyzgmBHProZLZA (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 10 Nov 2015 15:21:57 -0800 (PST) X-Barracuda-Envelope-From: sfr@canb.auug.org.au X-Barracuda-Apparent-Source-IP: 103.22.144.67 Received: from authenticated.ozlabs.org (localhost [127.0.0.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPSA id F0221140D97; Wed, 11 Nov 2015 10:21:54 +1100 (AEDT) Date: Wed, 11 Nov 2015 10:21:54 +1100 From: Stephen Rothwell To: Al Viro , Ben Myers , David Chinner , xfs@oss.sgi.com Cc: linux-next@vger.kernel.org, linux-kernel@vger.kernel.org, Andreas Gruenbacher , Brian Foster Subject: linux-next: manual merge of the vfs tree with the xfs tree Message-ID: <20151111102154.507e2a67@canb.auug.org.au> X-ASG-Orig-Subj: linux-next: manual merge of the vfs tree with the xfs tree X-Mailer: Claws Mail 3.13.0 (GTK+ 2.24.28; x86_64-pc-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-Barracuda-Connect: ozlabs.org[103.22.144.67] X-Barracuda-Start-Time: 1447197716 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24286 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Hi Al, Today's linux-next merge of the vfs tree got a conflict in: fs/xfs/xfs_xattr.c between commit: 67d8e04e345e ("xfs: invalidate cached acl if set directly via xattr") from the xfs tree and commit: 64669c648bc0 ("xattr handlers: Pass handler to operations instead of flags") from the vfs tree. I fixed it up (see below) and can carry the fix as necessary (no action is required). -- Cheers, Stephen Rothwell sfr@canb.auug.org.au diff --cc fs/xfs/xfs_xattr.c index 8294f86441bf,b1850e1489ef..000000000000 --- a/fs/xfs/xfs_xattr.c +++ b/fs/xfs/xfs_xattr.c @@@ -53,34 -54,12 +54,35 @@@ xfs_xattr_get(const struct xattr_handle return asize; } +void +xfs_forget_acl( + struct inode *inode, + const char *name, + int xflags) +{ + /* + * Invalidate any cached ACLs if the user has bypassed the ACL + * interface. We don't validate the content whatsoever so it is caller + * responsibility to provide data in valid format and ensure i_mode is + * consistent. + */ + if (xflags & ATTR_ROOT) { +#ifdef CONFIG_XFS_POSIX_ACL + if (!strcmp(name, SGI_ACL_FILE)) + forget_cached_acl(inode, ACL_TYPE_ACCESS); + else if (!strcmp(name, SGI_ACL_DEFAULT)) + forget_cached_acl(inode, ACL_TYPE_DEFAULT); +#endif + } +} + static int - xfs_xattr_set(struct dentry *dentry, const char *name, const void *value, - size_t size, int flags, int xflags) + xfs_xattr_set(const struct xattr_handler *handler, struct dentry *dentry, + const char *name, const void *value, size_t size, int flags) { - int xflags = handler->flags; - struct xfs_inode *ip = XFS_I(d_inode(dentry)); + struct xfs_inode *ip = XFS_I(d_inode(dentry)); + int error; ++ int xflags = handler->flags; if (strcmp(name, "") == 0) return -EINVAL; From david@fromorbit.com Tue Nov 10 17:26:31 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 8D44D7F47 for ; Tue, 10 Nov 2015 17:26:31 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 16F06AC008 for ; Tue, 10 Nov 2015 15:26:30 -0800 (PST) X-ASG-Debug-ID: 1447197987-04cbb0242310f810001-NocioJ Received: from ipmail06.adl6.internode.on.net (ipmail06.adl6.internode.on.net [150.101.137.145]) by cuda.sgi.com with ESMTP id xJLKGrjRvsrJnKSo for ; Tue, 10 Nov 2015 15:26:28 -0800 (PST) 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: A2BzCQCffEJWPGfGLHleKAECgxCBQoJfg36kagEBAQEBAQaLMoUsgn2BEIYKBAICgUNNAQEBAQEBBwEBAQFBP4Q0AQEBAwE6HCMQCAMOCgklDwUlAwcaE4gmB8QRAQEIAiEZhXSFRYk5BZZIjR6cTYJ0HYFqKjSFVgEBAQ Received: from ppp121-44-198-103.lns20.syd7.internode.on.net (HELO dastard) ([121.44.198.103]) by ipmail06.adl6.internode.on.net with ESMTP; 11 Nov 2015 09:55:43 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZwIIJ-0000lw-7Z; Wed, 11 Nov 2015 10:25:43 +1100 Date: Wed, 11 Nov 2015 10:25:43 +1100 From: Dave Chinner To: Christoph Hellwig Cc: Brian Foster , xfs@oss.sgi.com Subject: Re: [PATCH 2/4] xfs: Introduce writeback context for writepages Message-ID: <20151110232543.GH14311@dastard> X-ASG-Orig-Subj: Re: [PATCH 2/4] xfs: Introduce writeback context for writepages References: <1440479153-1584-1-git-send-email-david@fromorbit.com> <1440479153-1584-3-git-send-email-david@fromorbit.com> <20150831180221.GA16371@bfoster.bfoster> <20150831185612.GB349@infradead.org> <20150831221743.GI26895@dastard> <20150901074103.GA27231@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20150901074103.GA27231@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: 1447197987 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24285 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- [ finally getting back to this :/ ] On Tue, Sep 01, 2015 at 12:41:03AM -0700, Christoph Hellwig wrote: > On Tue, Sep 01, 2015 at 08:17:43AM +1000, Dave Chinner wrote: > > The patch changes the bio allocation patterns - it allocates them on > > the fly and holds them, so we could potentially exhaust the bio > > mempool with this submission technique. > > I've spend time to look over the patch again, and still don't see > a change. Ah, it's in the next patch that I haven't posted that "goes straight to bios". Ignore it for now... > > The ioend allocation pattern > > is different, too, because we only used to have 1 per buffer on a > > writepage call and the last one was used for the write clustering. > > .. that we now build up way bigger ioend chains. > > So back to Brians concern: we can now have fairly large piles of > ioends built up while potentially getting scheduled out, and this > does look like a potential real issue to me. I wonder if we should > (ab-)use the blk_plug_cb infrastructure so that we can flush the > pending ioends out on a context switch? Possibly, but I'm thinking that we should just end up building bios directly and submitting them once they are reach size limits of boundaries rather than building ioend chains for later submission. Did the work for arbitrarily sized bios ever get merged? I can't find any evidence that it did.... Cheers, Dave. -- Dave Chinner david@fromorbit.com From agruenba@redhat.com Tue Nov 10 19:16:40 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 A56587F4E for ; Tue, 10 Nov 2015 19:16:40 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 835C4304059 for ; Tue, 10 Nov 2015 17:16:37 -0800 (PST) X-ASG-Debug-ID: 1447204594-04cbb024251116f0001-NocioJ Received: from mail-lb0-f178.google.com (mail-lb0-f178.google.com [209.85.217.178]) by cuda.sgi.com with ESMTP id 4nhfbIM7HhBBVJzg (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 10 Nov 2015 17:16:35 -0800 (PST) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.85.217.178 Received: by lbbkw15 with SMTP id kw15so8750398lbb.0 for ; Tue, 10 Nov 2015 17:16:33 -0800 (PST) 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=TBjVjmwNQXKZxgZYPTMJPEhzmERUaLLU5C2LpvD2CBU=; b=MGgMq9DgvzhFD5i41PlzOaGCu3M8kC3XQu/jveMfv5JrZnmhN3FlVF1a0679ePf2O4 +OB8VvLHG1QWrBuok0oEn89zL+OxIYpDvZjv4Vq923okPAKMiYAp6mjy5V0U0yLLd9B1 W3tj/MAX6L9/1gD1Q2fpBLjflEzq6C9PTrzeukT9nu+6I5hn+H5o70VNbbHTEkJ47Sf2 L3M84AInKXdA1KmxkbacJ1rM5Xu/YhlYYTD3ZZdIPZQE+40Q5x0TYYy8aKKTNaRufm8h +SEFhPtaoZPow2D5gqFBShkfVqCH+6ULBvlj2Eu+ZGK6L8KsFnxR1KOyuZlch0mly2Jt 29Xw== X-Gm-Message-State: ALoCoQlMr2w08M66odplZX32sxtc73VbkfX5fNSHF/sBvXggtbYRyjNPWpz9wf9wI15b9/eaUMHp MIME-Version: 1.0 X-Received: by 10.112.63.100 with SMTP id f4mr3133199lbs.85.1447204593826; Tue, 10 Nov 2015 17:16:33 -0800 (PST) Received: by 10.112.53.42 with HTTP; Tue, 10 Nov 2015 17:16:33 -0800 (PST) In-Reply-To: <1447067343-31479-20-git-send-email-agruenba@redhat.com> References: <1447067343-31479-1-git-send-email-agruenba@redhat.com> <1447067343-31479-20-git-send-email-agruenba@redhat.com> Date: Wed, 11 Nov 2015 02:16:33 +0100 Message-ID: Subject: Re: [PATCH v15 19/22] richacl: Add richacl xattr handler From: Andreas Gruenbacher X-ASG-Orig-Subj: Re: [PATCH v15 19/22] richacl: Add richacl xattr handler To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4 , XFS Developers , LKML , linux-fsdevel , Linux NFS Mailing List , linux-cifs@vger.kernel.org, Linux API Cc: Andreas Gruenbacher Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-lb0-f178.google.com[209.85.217.178] X-Barracuda-Start-Time: 1447204594 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24288 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Mon, Nov 9, 2015 at 12:09 PM, Andreas Gruenbacher wrote: > Add richacl xattr handler implementing the xattr operations based on the > get_richacl and set_richacl inode operations. > > Signed-off-by: Andreas Gruenbacher > --- > fs/richacl_xattr.c | 78 +++++++++++++++++++++++++++++++++++++++++++ > include/linux/richacl_xattr.h | 2 ++ > 2 files changed, 80 insertions(+) > > diff --git a/fs/richacl_xattr.c b/fs/richacl_xattr.c > index 38473b6..767c1f7 100644 > --- a/fs/richacl_xattr.c > +++ b/fs/richacl_xattr.c > @@ -18,7 +18,9 @@ > #include > #include > #include > +#include > #include > +#include > > MODULE_LICENSE("GPL"); > > @@ -161,6 +163,82 @@ richacl_to_xattr(struct user_namespace *user_ns, > } > EXPORT_SYMBOL_GPL(richacl_to_xattr); > > +static size_t > +richacl_xattr_list(struct dentry *dentry, char *list, size_t list_len, > + const char *name, size_t name_len, int handler_flags) > +{ > + const size_t size = sizeof(XATTR_NAME_RICHACL); > + > + if (!IS_RICHACL(d_backing_inode(dentry))) > + return 0; > + if (list && size <= list_len) > + memcpy(list, XATTR_NAME_RICHACL, size); > + return size; > +} > + > +static int > +richacl_xattr_get(struct dentry *dentry, const char *name, void *buffer, > + size_t buffer_size, int handler_flags) > +{ > + struct inode *inode = d_backing_inode(dentry); > + struct richacl *acl; > + int error; > + > + if (strcmp(name, "") != 0) > + return -EINVAL; > + if (!IS_RICHACL(inode)) > + return EOPNOTSUPP; This should have been -EOPNOTSUPP instead. > + if (S_ISLNK(inode->i_mode)) > + return -EOPNOTSUPP; > + acl = get_richacl(inode); > + if (IS_ERR(acl)) > + return PTR_ERR(acl); > + if (acl == NULL) > + return -ENODATA; > + error = richacl_to_xattr(&init_user_ns, acl, buffer, buffer_size); > + richacl_put(acl); > + return error; > +} > + > +static int > +richacl_xattr_set(struct dentry *dentry, const char *name, > + const void *value, size_t size, int flags, int handler_flags) > +{ > + struct inode *inode = d_backing_inode(dentry); > + struct richacl *acl = NULL; > + int ret; > + > + if (strcmp(name, "") != 0) > + return -EINVAL; > + if (!IS_RICHACL(inode)) > + return -EOPNOTSUPP; > + if (!inode->i_op->set_richacl) > + return -EOPNOTSUPP; > + > + if (!uid_eq(current_fsuid(), inode->i_uid) && > + inode_permission(inode, MAY_CHMOD) && > + !capable(CAP_FOWNER)) > + return -EPERM; > + > + if (value) { > + acl = richacl_from_xattr(&init_user_ns, value, size); > + if (IS_ERR(acl)) > + return PTR_ERR(acl); > + } > + > + ret = inode->i_op->set_richacl(inode, acl); > + richacl_put(acl); > + return ret; > +} > + > +struct xattr_handler richacl_xattr_handler = { > + .prefix = XATTR_NAME_RICHACL, > + .list = richacl_xattr_list, > + .get = richacl_xattr_get, > + .set = richacl_xattr_set, > +}; > +EXPORT_SYMBOL(richacl_xattr_handler); > + > /* > * Fix up the uids and gids in richacl extended attributes in place. > */ > diff --git a/include/linux/richacl_xattr.h b/include/linux/richacl_xattr.h > index 7fc5ca8..45ec27a 100644 > --- a/include/linux/richacl_xattr.h > +++ b/include/linux/richacl_xattr.h > @@ -39,4 +39,6 @@ static inline void richacl_fix_xattr_to_user(void *value, size_t size) > } > #endif > > +extern struct xattr_handler richacl_xattr_handler; > + > #endif /* __RICHACL_XATTR_H */ > -- > 2.5.0 > From seminars@info.ve10.com Tue Nov 10 22:38:15 2015 Return-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_FONT_SIZE_HUGE, HTML_MESSAGE,MIME_HTML_ONLY,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 8D46E7F37 for ; Tue, 10 Nov 2015 22:38:15 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 6F4DF8F8033 for ; Tue, 10 Nov 2015 20:38:12 -0800 (PST) X-ASG-Debug-ID: 1447216688-04cbb02425114f50001-NocioJ Received: from 114-19.m057.com (114-19.m057.com [216.39.114.19]) by cuda.sgi.com with ESMTP id plhw1W5N011nTc81 for ; Tue, 10 Nov 2015 20:38:08 -0800 (PST) X-Barracuda-Envelope-From: seminars@info.ve10.com X-Barracuda-Apparent-Source-IP: 216.39.114.19 DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; s=ig; d=info.ve10.com; h=From:Reply-To:To:Subject:MIME-Version:Content-Type:Message-ID:Date; i=seminars@info.ve10.com; bh=B8azcEbyvr5GW1iIlX8fZKWJwco=; b=hQizJoKCigukB9kQO62Eflf5pXpy9lu/Wf7SlNSAm86SmGEkqUQTDXxmE2PbIF5Ns54PUuVKbKe/ 0ZXddH23RpzYYaHOhqepNu4pYqfQV9drl7Ceo+Z0J5I3SKCO5Lc1jwWh/uC8zxjJdIHau63W8Fuh PFFM9+/ajILZUZ9oaiI= DomainKey-Signature: a=rsa-sha1; c=nofws; q=dns; s=ig; d=info.ve10.com; b=Mu3aGoKY3VSWO3tUPRa1xZZPtJ911Vr4jHYdtuWMRK+QUsMkX7TbrePWfbva+4s2aEw3oaQ4R8Vf eTKyuPT/P/N9etGE+sQXNb2pRfjDQJgk1+pa23qjg+A1oYup1VpDZxbmZwdRyr315hrHKR/2AiCG hYDgA0yTsQMD1DJ9g3w=; Received: by 114-19.m057.com (PowerMTA(TM) v3.5r15) id h8b33a0qrhgo for ; Tue, 10 Nov 2015 20:37:57 -0800 (envelope-from ) From: The Professional Development Workshop Reply-To: The Professional Development Workshop To: xfs@oss.sgi.com Subject: Communication Skills for Women X-RID: phqx X-ASG-Orig-Subj: Communication Skills for Women X-PMG-Userid: IG25 X-PMG-Msgid: 57 X-PMG-Recipient: xfs@oss.sgi.com X-PID: 4947901010 X-XID: 6948397 X-CID: 57 MIME-Version: 1.0 Content-Type: text/html; charset=us-ascii Message-ID: <0.0.68.B71.1D11C3ABD0DD9DC.0@114-19.m057.com> Date: Tue, 10 Nov 2015 20:37:57 -0800 X-Barracuda-Connect: 114-19.m057.com[216.39.114.19] X-Barracuda-Start-Time: 1447216688 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 1.05 X-Barracuda-Spam-Status: No, SCORE=1.05 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED, HTML_FONT_SIZE_HUGE, HTML_MESSAGE, INTERRUPTUS, INTERRUPTUS_2, MIME_HTML_ONLY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24294 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.39 HTML_FONT_SIZE_HUGE BODY: HTML font size is huge 0.00 MIME_HTML_ONLY BODY: Message only has text/html MIME parts 0.00 HTML_MESSAGE BODY: HTML included in message 0.01 INTERRUPTUS RAW: Message looks to contain HTML-interrupted text 0.65 INTERRUPTUS_2 Message looks to contain HTML-interrupted text Communication Skills for Women
FRED PRYOR SEMINARS & CAREERTRACK
divisions of PARK University Enterprises, Inc.

VIP 2309822881820
Special Offer Code 467423*
Hurry — offer expires December 11, 2015

A one day seminar from CareerTrack
Communication Skills for Women

Nearly all work involves interaction and communication with others. Clear, effective communication — between individuals, within teams and among departments — is a vital part of any successful organization.

Communication Skills for Women

 

INDIANAPOLIS, IN

1/15/2016

Event # 176959

Register Now


CLARKSVILLE, IN

1/14/2016

Event # 176958

Register Now


The top 10 communication hurdles to overcome

Our researchers asked women across the country to describe their toughest communication situations. We analyzed over 800 circumstances and compiled these top 10:
Confronting others, delivering criticism
Controlling emotions
Being more assertive
Receiving constructive criticism
Using confidence not uncertainty
Getting cooperation
Dealing with the anger of others
Setting limits
Improving presentation skills
Taking charge
With this powerful day of training, you'll build the skills needed to handle these situations and turn it into the results you deserve, and much more.

Attend Communication Skills for Women for

Only $49

Group discounts with 5 or more

Register Online
with the following special offer code

VIP 2309822881820
Special Offer Code 467423*
Offer expires December 11, 2015

Learn More

Your Location Your convenience Private team training for groups of 15 or more. Let us come
to your location with customized on-site training. Learn More

This course qualifies for 0.6 CEU and 6 CPE Credits.
*To receive your special $49 ENROLLMENT FEE, you must register for the seminar online at www.CareerTrack.com and provide your Special Offer Code 467423 during checkout. This offer is available only for online registrations for the seminar, Communication Skills for Women. This offer cannot be combined with any other offer and is valid only on new registrations for December - January 2015 seminars. Offer expires December 11, 2015. If you have questions, please contact our customer service team at 1-800-780-8469.
VIP#: 2309822881820
ID#: 467423
Hurry — offer expires December 11, 2015
Copyright 2015
CareerTrack
5700 Broadmoor, Suite 300, Mission, KS 66202
1-800-780-8469
www.CareerTrack.com
To remove your name from future offers and promotions, please click here.
From hejianet@gmail.com Wed Nov 11 00:37:58 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 55C257F37 for ; Wed, 11 Nov 2015 00:37:58 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 36AC0304053 for ; Tue, 10 Nov 2015 22:37:58 -0800 (PST) X-ASG-Debug-ID: 1447223873-04cbb024251173d0001-NocioJ Received: from mail-oi0-f48.google.com (mail-oi0-f48.google.com [209.85.218.48]) by cuda.sgi.com with ESMTP id vmK2vQlu0lj26RAm (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 10 Nov 2015 22:37:53 -0800 (PST) X-Barracuda-Envelope-From: hejianet@gmail.com X-Barracuda-Apparent-Source-IP: 209.85.218.48 Received: by oiad129 with SMTP id d129so11380165oia.0 for ; Tue, 10 Nov 2015 22:37:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=subject:to:references:cc:from:message-id:date:user-agent :mime-version:in-reply-to:content-type:content-transfer-encoding; bh=w4xwi+wTj6m5mLUy1zkilI7s2t/xElK4vfxbCkurYCc=; b=IafeHGn0kNuHOD3US8IppGbeiN/NeTSfPZd0O7OLTQ5b4Zb4+mZoysSJjVUKC+OpNY Xy0KVawR+kzUdsj93jqR8d3fPZWziyXQkU7r2boXiKlTBL8UB7N8IYXRyEEAqwEF/nDL SMNMtVl55yheoDSSt5/7j650auVdRW3HlxGh70/rxi+6x4NQ12XPmnyegcr70r4dMmzb kg6jBwAS/Ujlz1yI3ALveB7aB4wDrD4/4JgGH+cxRLCPnjoRd5E+VXlwK5rQrI3i1HbS 74saoyskQS7p2s73RefxXa3m+MDj3sazbMRRT4yQHrQq1nU1zpRmVTYoAZpISdrL48wK kvoQ== X-Received: by 10.202.81.195 with SMTP id f186mr3967692oib.12.1447223873066; Tue, 10 Nov 2015 22:37:53 -0800 (PST) Received: from justin.cn.ibm.com (pok1.bluebird.ibm.com. [129.42.208.177]) by smtp.gmail.com with ESMTPSA id xh10sm1345488oeb.16.2015.11.10.22.37.50 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 10 Nov 2015 22:37:52 -0800 (PST) Subject: Re: [PATCH] libxfs: Optimize the loop for xfs_bitmap_empty To: Brian Foster X-ASG-Orig-Subj: Re: [PATCH] libxfs: Optimize the loop for xfs_bitmap_empty References: <1447079482-10650-1-git-send-email-hejianet@gmail.com> <20151110125403.GC21670@bfoster.bfoster> Cc: xfs@oss.sgi.com From: hejianet Message-ID: <5642E23F.6050009@gmail.com> Date: Wed, 11 Nov 2015 14:37:51 +0800 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <20151110125403.GC21670@bfoster.bfoster> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit X-Barracuda-Connect: mail-oi0-f48.google.com[209.85.218.48] X-Barracuda-Start-Time: 1447223873 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24296 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 Brian Thanks, I will resend the patch V2 B.R. Justin 在 11/10/15 8:54 PM, Brian Foster 写é“: > On Mon, Nov 09, 2015 at 10:31:22PM +0800, Jia He wrote: >> If there is any non zero bit in a long bitmap, it can jump out of the for >> loop and finish the function as soon as possible. >> >> Signed-off-by: Jia He >> Cc: Dave Chinner >> Cc: Brian Foster >> --- >> fs/xfs/libxfs/xfs_bit.c | 2 ++ >> 1 file changed, 2 insertions(+) >> >> diff --git a/fs/xfs/libxfs/xfs_bit.c b/fs/xfs/libxfs/xfs_bit.c >> index 0e8885a..84614b0 100644 >> --- a/fs/xfs/libxfs/xfs_bit.c >> +++ b/fs/xfs/libxfs/xfs_bit.c >> @@ -36,6 +36,8 @@ xfs_bitmap_empty(uint *map, uint size) >> >> for (i = 0; i < size; i++) { >> ret |= map[i]; >> + if (ret != 0) >> + return 0; >> } >> > Seems Ok to me, but if we're going to do this, why not just kill ret > entirely? For example, check 'if (map[i] != 0) return 0;' in the loop > and unconditionally return 1 if we make it to the end. > > Brian > >> return (ret == 0); >> -- >> 2.5.0 >> >> _______________________________________________ >> 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 liruilong0128@gmail.com Wed Nov 11 00:38:30 2015 Return-Path: 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 25D137F37 for ; Wed, 11 Nov 2015 00:38:30 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 088348F8035 for ; Tue, 10 Nov 2015 22:38:26 -0800 (PST) X-ASG-Debug-ID: 1447223904-04bdf03f0410ba10001-NocioJ Received: from mail-qg0-f67.google.com (mail-qg0-f67.google.com [209.85.192.67]) by cuda.sgi.com with ESMTP id CMcnMja3Mctr1VyS (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 10 Nov 2015 22:38:25 -0800 (PST) X-Barracuda-Envelope-From: liruilong0128@gmail.com X-Barracuda-Apparent-Source-IP: 209.85.192.67 Received: by qgad10 with SMTP id d10so1912575qga.0 for ; Tue, 10 Nov 2015 22:38:24 -0800 (PST) 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=ed0C7IjxTAZpsVBSj6XyCjc1tA9njF74Eu8srKIiUzc=; b=tGzXB5pSVz65Znx122Eud22DtexQ/O2IxXNdsa5TVvHXgyaOMFV8+8r5RexuPfd09K aC+UpXjeIL557m3aWAXIy/BaX7Fj7j1BLbpaG8DHgsE8GYfmlnZqvsYBPnDXSOYp7aG+ aaF4BX9p5RKB2VFHB9mHOudujtd/29t37lIZiXbeQKPSRu/TXUI+lLdujkdNlvPpjLKc su/kQwGPaDToy6CwMWg6BpDqGxBhbKqmuZZ0kwLIkdMioCk+AGuK/cIlDDQi8uJr5Vk2 EAYt/vo1JQUaQeBoZIb692vZvKpN+HK0qdU6a9Xad8BOKOmsUEwxxL80ZjiFOT0JzFak eF5g== MIME-Version: 1.0 X-Received: by 10.140.155.75 with SMTP id b72mr9145679qhb.29.1447223904455; Tue, 10 Nov 2015 22:38:24 -0800 (PST) Received: by 10.140.81.175 with HTTP; Tue, 10 Nov 2015 22:38:24 -0800 (PST) Date: Wed, 11 Nov 2015 14:38:24 +0800 Message-ID: Subject: xfsprogs install From: rui li X-ASG-Orig-Subj: xfsprogs install To: xfs@oss.sgi.com Content-Type: multipart/alternative; boundary=001a113991eabc52bd05243e125a X-Barracuda-Connect: mail-qg0-f67.google.com[209.85.192.67] X-Barracuda-Start-Time: 1447223905 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/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=BSF_SC0_SA148d, DKIM_SIGNED, DKIM_VERIFIED, HTML_MESSAGE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24296 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 0.20 BSF_SC0_SA148d Custom Rule SA148d --001a113991eabc52bd05243e125a Content-Type: text/plain; charset=UTF-8 hello when i install xfsprogs i hava follwing problems FATAL ERROR: could not find a valid BLKID header Install the Block device ID development package could you give me some help? thanks --001a113991eabc52bd05243e125a Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
hello=C2=A0
when i install xfsprogs i hava follwing pr= oblems

FATAL ERROR: could not find a valid BLKID h= eader
Install the Block device ID development package
<= br>
could you give me some help?

thanks<= /div>
--001a113991eabc52bd05243e125a-- From hejianet@gmail.com Wed Nov 11 01:49:17 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 D63697F4E for ; Wed, 11 Nov 2015 01:49:17 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 76871AC007 for ; Tue, 10 Nov 2015 23:49:14 -0800 (PST) X-ASG-Debug-ID: 1447228152-04bdf03f0310cf30001-NocioJ Received: from mail-ob0-f175.google.com (mail-ob0-f175.google.com [209.85.214.175]) by cuda.sgi.com with ESMTP id wfNn9m5up1SWRMHL (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 10 Nov 2015 23:49:13 -0800 (PST) X-Barracuda-Envelope-From: hejianet@gmail.com X-Barracuda-Apparent-Source-IP: 209.85.214.175 Received: by obbnk6 with SMTP id nk6so16723901obb.2 for ; Tue, 10 Nov 2015 23:49:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=nqwfne499QA+5j2nO94JT01Zoubr4ZPQtT7lgU8ckdE=; b=LVM/ySvT/NoOL7yDc8Udo25MX5Ikttb2JOFMUBWHZEpp2kN10b3ztKrOOKhKj8staV GfR8mTAXBV/LahCv9lBsE/piE/VG74MCRyT6AS8D9kPrHGzMBZq333KkSf4uaLtzkmsK PKQWAfWkTMFjh2Fmls91xbC13ZIKH+RqEMW+6/O1vwSAHIBsdBDfRoCKK7jxs+lETyLI 8mrDkatAJQjGsieE6OTxMtMJdcGyQmynXBP46zYDHvWb8hZFPRURcTOkbWLGxr70BAxc Bu75yariWWHrbVsqkdGmIdkNQ6uwbpAdePHryWn27sXIjRlpmdgW3rkZN5aDDt9Zokhs m8Nw== X-Received: by 10.182.153.101 with SMTP id vf5mr4160410obb.81.1447228152619; Tue, 10 Nov 2015 23:49:12 -0800 (PST) Received: from localhost.localdomain.localdomain ([60.247.125.148]) by smtp.gmail.com with ESMTPSA id ta5sm1495670obc.13.2015.11.10.23.49.10 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 10 Nov 2015 23:49:11 -0800 (PST) From: Jia He To: xfs@oss.sgi.com Cc: Jia He , Dave Chinner , Brian Foster Subject: [PATCH v2] libxfs: Optimize the loop for xfs_bitmap_empty Date: Wed, 11 Nov 2015 15:49:01 +0800 X-ASG-Orig-Subj: [PATCH v2] libxfs: Optimize the loop for xfs_bitmap_empty Message-Id: <1447228141-17408-1-git-send-email-hejianet@gmail.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <20151110125403.GC21670@bfoster.bfoster> References: <20151110125403.GC21670@bfoster.bfoster> X-Barracuda-Connect: mail-ob0-f175.google.com[209.85.214.175] X-Barracuda-Start-Time: 1447228153 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24297 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 If there is any non zero bit in a long bitmap, it can jump out of the loop and finish the function as soon as possible. Signed-off-by: Jia He Cc: Dave Chinner Cc: Brian Foster --- fs/xfs/libxfs/xfs_bit.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/xfs/libxfs/xfs_bit.c b/fs/xfs/libxfs/xfs_bit.c index 0e8885a..0a94cce 100644 --- a/fs/xfs/libxfs/xfs_bit.c +++ b/fs/xfs/libxfs/xfs_bit.c @@ -32,13 +32,13 @@ int xfs_bitmap_empty(uint *map, uint size) { uint i; - uint ret = 0; for (i = 0; i < size; i++) { - ret |= map[i]; + if (map[i] != 0) + return 0; } - return (ret == 0); + return 1; } /* -- 2.5.0 From BATV+66af426afb9dea266a66+4462+infradead.org+hch@bombadil.srs.infradead.org Wed Nov 11 01:57:21 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 BA0D57F52 for ; Wed, 11 Nov 2015 01:57:21 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 4537FAC005 for ; Tue, 10 Nov 2015 23:57:21 -0800 (PST) X-ASG-Debug-ID: 1447228639-04cbb02424118b10001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id ImsxWAXcUrpjTCPw (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 10 Nov 2015 23:57:19 -0800 (PST) X-Barracuda-Envelope-From: BATV+66af426afb9dea266a66+4462+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 1ZwQHD-0007uE-S6; Wed, 11 Nov 2015 07:57:07 +0000 Date: Tue, 10 Nov 2015 23:57:07 -0800 From: Christoph Hellwig To: Andreas Gruenbacher Cc: Christoph Hellwig , Alexander Viro , Theodore Ts'o , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4 , XFS Developers , LKML , linux-fsdevel , Linux NFS Mailing List , linux-cifs@vger.kernel.org, Linux API Subject: Re: [PATCH v15 00/22] Richacls (Core and Ext4) Message-ID: <20151111075707.GA23752@infradead.org> X-ASG-Orig-Subj: Re: [PATCH v15 00/22] Richacls (Core and Ext4) References: <1447067343-31479-1-git-send-email-agruenba@redhat.com> <20151110112943.GA17038@infradead.org> 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-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: 1447228639 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/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.24297 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS On Tue, Nov 10, 2015 at 01:39:52PM +0100, Andreas Gruenbacher wrote: > > It still has the same crappy fs interfaces with lots of boilerplate > > code > > Could you please be more specific so that I can trace this complaint > to some actual code? if (IS_RICHACL()) richacl_foo() else posix_acl_foo() for every call from the filesystem is the major one that came to mind. > > and still abuses xattrs instead of a proper syscall interface. > > That's far from being ready to merge. > > The xattr syscall interface is what's used for very similar kinds of > things today; using it for richacls as well sure does not count as > abuse. Things could be improved in the xattr interface and in its > implementation, but we need more substantial reasons than that for > reimplementing the wheel once again. And it's a horrible interface. Look at all the pain for example in XFS which has a different ACL format, or in fact everyone who just uses a different xattr name or even none at all. And all the mess of people trying to shoe horn crazy interfaces into xattrs. It was an experiment worth trying with Posix ACLs, but it failed, so do not repeat it. From BATV+66af426afb9dea266a66+4462+infradead.org+hch@bombadil.srs.infradead.org Wed Nov 11 05:32:47 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 3A2E27F52 for ; Wed, 11 Nov 2015 05:32:47 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 07DAB30405F for ; Wed, 11 Nov 2015 03:32:44 -0800 (PST) X-ASG-Debug-ID: 1447241562-04bdf03f04114190001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id XHzfppW7vbz6RzCU (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Wed, 11 Nov 2015 03:32:42 -0800 (PST) X-Barracuda-Envelope-From: BATV+66af426afb9dea266a66+4462+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 1ZwTdp-0001rF-45; Wed, 11 Nov 2015 11:32:41 +0000 Date: Wed, 11 Nov 2015 03:32:41 -0800 From: Christoph Hellwig To: Dave Chinner Cc: Brian Foster , xfs@oss.sgi.com Subject: Re: [PATCH 2/4] xfs: Introduce writeback context for writepages Message-ID: <20151111113241.GA7083@infradead.org> X-ASG-Orig-Subj: Re: [PATCH 2/4] xfs: Introduce writeback context for writepages References: <1440479153-1584-1-git-send-email-david@fromorbit.com> <1440479153-1584-3-git-send-email-david@fromorbit.com> <20150831180221.GA16371@bfoster.bfoster> <20150831185612.GB349@infradead.org> <20150831221743.GI26895@dastard> <20150901074103.GA27231@infradead.org> <20151110232543.GH14311@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151110232543.GH14311@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: 1447241562 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/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.24301 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS On Wed, Nov 11, 2015 at 10:25:43AM +1100, Dave Chinner wrote: > Did the work for arbitrarily sized bios ever get merged? I can't > find any evidence that it did.... Yes, it landed in 4.3. From robin.listas@gmail.com Wed Nov 11 06:26:02 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 9ED0D7F56 for ; Wed, 11 Nov 2015 06:26:02 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 65A3C30404E for ; Wed, 11 Nov 2015 04:25:59 -0800 (PST) X-ASG-Debug-ID: 1447244756-04bdf03f041158f0001-NocioJ Received: from mail-wm0-f49.google.com (mail-wm0-f49.google.com [74.125.82.49]) by cuda.sgi.com with ESMTP id SCuYeDFT365H3GYI (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Wed, 11 Nov 2015 04:25:57 -0800 (PST) X-Barracuda-Envelope-From: robin.listas@gmail.com X-Barracuda-Apparent-Source-IP: 74.125.82.49 Received: by wmec201 with SMTP id c201so44353379wme.1 for ; Wed, 11 Nov 2015 04:25:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:subject:to:references:from:message-id:date:user-agent :mime-version:in-reply-to:content-type:content-transfer-encoding; bh=XlLKUEdtu4/xftnifWcpvm4eSh37n8PNqTfgFeDXqro=; b=YAZY0eXQ0iBr6m0kiHWeTELaZjCqdO/KbSnTVektJJkoF3gHY6yNTxrPzT11hfGhHF s2Z/XiGSOdPv2m7JgzJBa+AvUfvSU/iMQ7C28sd7fMqfASISB0+4urslsKIj/HrjazjD gPloSni5Y39KMq9Fr9NU2VyReCmEsVWbZaUWsx+ifn5IfKga2eaDjcvrzmJaUaxYAk9C rA9AHrfAPxeKtEZ9gJHzC8CIQxpjfAc/fDeVO9ZQS13OzF2uMqtKpyf4XKO0Au8JOZXF hQH9TevKT/fo2NzmFcsd7RUtk2ONaZ4MMegxijW9Dx243vP+17L5sjWVxh6zTfzLhS/8 bHIQ== X-Received: by 10.194.203.106 with SMTP id kp10mr10030735wjc.86.1447244755693; Wed, 11 Nov 2015 04:25:55 -0800 (PST) Received: from Telcontar.valinor (248.Red-81-36-103.dynamicIP.rima-tde.net. [81.36.103.248]) by smtp.gmail.com with ESMTPSA id an7sm8739044wjc.44.2015.11.11.04.25.54 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 11 Nov 2015 04:25:54 -0800 (PST) Sender: Carlos Robinson Received: from localhost (localhost [127.0.0.1]) by Telcontar.valinor (Postfix) with ESMTP id 7A3A960ECD for ; Wed, 11 Nov 2015 13:25:53 +0100 (CET) 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 CBhHyj5S5Seq for ; Wed, 11 Nov 2015 13:25:53 +0100 (CET) Received: from [127.0.0.1] (localhost [127.0.0.1]) by Telcontar.valinor (Postfix) with ESMTP id 56E86606D8 for ; Wed, 11 Nov 2015 13:25:53 +0100 (CET) Subject: Re: xfsprogs install To: XFS mail list X-ASG-Orig-Subj: Re: xfsprogs install References: From: "Carlos E. R." Message-ID: <564333D1.8070900@opensuse.org> Date: Wed, 11 Nov 2015 13:25:53 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mail-wm0-f49.google.com[74.125.82.49] X-Barracuda-Start-Time: 1447244757 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24302 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 2015-11-11 07:38, rui li wrote: > hello when i install xfsprogs i hava follwing problems Maybe you have to say what distribution you are using - -- Cheers / Saludos, Carlos E. R. (from 13.1 x86_64 "Bottle" at Telcontar) -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iEYEARECAAYFAlZDM88ACgkQtTMYHG2NR9VMNACfak0n0p0Z8t6SQY1gYxgWHdzL 1/YAoIqUyEHuY8T4QUKMVXTBi7uTpkE3 =qo1N -----END PGP SIGNATURE----- From bfoster@redhat.com Wed Nov 11 06:48:39 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 E92137F50 for ; Wed, 11 Nov 2015 06:48:39 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id CC11D8F8049 for ; Wed, 11 Nov 2015 04:48:36 -0800 (PST) X-ASG-Debug-ID: 1447246115-04bdf03f021162a0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id TyWt0zaiq9DVYXgX (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 11 Nov 2015 04:48:35 -0800 (PST) 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 (Postfix) with ESMTPS id 3D3FEC0BA188; Wed, 11 Nov 2015 12:48:35 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-67.bos.redhat.com [10.18.41.67]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tABCmYK0029523; Wed, 11 Nov 2015 07:48:35 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id 1F9AE123AAD; Wed, 11 Nov 2015 07:48:34 -0500 (EST) Date: Wed, 11 Nov 2015 07:48:34 -0500 From: Brian Foster To: Jia He Cc: xfs@oss.sgi.com Subject: Re: [PATCH v2] libxfs: Optimize the loop for xfs_bitmap_empty Message-ID: <20151111124833.GB52153@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH v2] libxfs: Optimize the loop for xfs_bitmap_empty References: <20151110125403.GC21670@bfoster.bfoster> <1447228141-17408-1-git-send-email-hejianet@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1447228141-17408-1-git-send-email-hejianet@gmail.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: 1447246115 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Wed, Nov 11, 2015 at 03:49:01PM +0800, Jia He wrote: > If there is any non zero bit in a long bitmap, it can jump out of the > loop and finish the function as soon as possible. > > Signed-off-by: Jia He > Cc: Dave Chinner > Cc: Brian Foster > --- Looks good to me: Reviewed-by: Brian Foster > fs/xfs/libxfs/xfs_bit.c | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > > diff --git a/fs/xfs/libxfs/xfs_bit.c b/fs/xfs/libxfs/xfs_bit.c > index 0e8885a..0a94cce 100644 > --- a/fs/xfs/libxfs/xfs_bit.c > +++ b/fs/xfs/libxfs/xfs_bit.c > @@ -32,13 +32,13 @@ int > xfs_bitmap_empty(uint *map, uint size) > { > uint i; > - uint ret = 0; > > for (i = 0; i < size; i++) { > - ret |= map[i]; > + if (map[i] != 0) > + return 0; > } > > - return (ret == 0); > + return 1; > } > > /* > -- > 2.5.0 > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From cmaiolino@redhat.com Wed Nov 11 06:50:30 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 0C0AD7F5E for ; Wed, 11 Nov 2015 06:50:30 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id DFA6B8F804B for ; Wed, 11 Nov 2015 04:50:29 -0800 (PST) X-ASG-Debug-ID: 1447246225-04bdf03f03116350001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id CB2kkshCrc0zH7HU (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 11 Nov 2015 04:50:25 -0800 (PST) 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 (Postfix) with ESMTPS id 7CC02935D4; Wed, 11 Nov 2015 12:50:25 +0000 (UTC) Received: from redhat.com (dhcp-26-103.brq.redhat.com [10.34.26.103]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tABCoM5h018707 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Wed, 11 Nov 2015 07:50:24 -0500 Date: Wed, 11 Nov 2015 13:50:22 +0100 From: Carlos Maiolino To: rui li Cc: xfs@oss.sgi.com Subject: Re: xfsprogs install Message-ID: <20151111125021.GA28745@redhat.com> X-ASG-Orig-Subj: Re: xfsprogs install Mail-Followup-To: rui li , xfs@oss.sgi.com References: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.24 (2015-08-30) 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: 1447246225 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Wed, Nov 11, 2015 at 02:38:24PM +0800, rui li wrote: > hello > when i install xfsprogs i hava follwing problems > FATAL ERROR: could not find a valid BLKID header > Install the Block device ID development package > could you give me some help? > thanks install libblkid-devel package in your distribution, or any similar package that your distribution provides with libblkid headers. > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs -- Carlos From jtulak@redhat.com Wed Nov 11 07:13:51 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 B989C7F61 for ; Wed, 11 Nov 2015 07:13:51 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 32126AC002 for ; Wed, 11 Nov 2015 05:13:48 -0800 (PST) X-ASG-Debug-ID: 1447247623-04cb6c296d11af40001-NocioJ Received: from mail-io0-f174.google.com (mail-io0-f174.google.com [209.85.223.174]) by cuda.sgi.com with ESMTP id gVE3r7PoKASZumvb (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Wed, 11 Nov 2015 05:13:43 -0800 (PST) X-Barracuda-Envelope-From: jtulak@redhat.com X-Barracuda-RBL-Trusted-Forwarder: 209.85.223.174 Received: by iouu10 with SMTP id u10so24762311iou.0 for ; Wed, 11 Nov 2015 05:13:43 -0800 (PST) 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:from:date :message-id:subject:to:cc:content-type; bh=9lOKPuhVMOpWTShrQLjNBhQlMd606R77BagQmivW+LY=; b=H3/GZ0YMwgIJLj2qyIfVODZY5N3iLsUaOx+uWt3vN7Ys7H0vvi003OvLhzzSI4Y3v1 8955Rpct6l1MqzaIxzRsj1rgp/kR40DPo2qElFTseJNgD0fslArdZgTWeUMHn+5VJ5F9 p4F2IshUE/hZF1G3RfhkXXDa2/RLmb8YZUAO4+o0V1VT+DGJR/zadSrMr0tGYKTczm1w hU8OKxaGnFnN64XmcQj7aECYzLkeBKBu0t6qCSpYBekEnFSGkn7grZc8V/cUILqswlzK 6/vRFwkKwVQpB5muJ5vZAVdllT0PvlUswXCHQ99/KLQVt3TJA8mcjK6Dp4KhQZCd9Ynl 9viA== X-Gm-Message-State: ALoCoQlRkqclCH82CmTiZlcL3VJae3udnhAvpm30mx2Yma49ic3A/yecyXG4W3RmKxxhjOksLq2R X-Received: by 10.107.150.12 with SMTP id y12mr10583692iod.52.1447247622813; Wed, 11 Nov 2015 05:13:42 -0800 (PST) MIME-Version: 1.0 Received: by 10.36.84.6 with HTTP; Wed, 11 Nov 2015 05:13:23 -0800 (PST) In-Reply-To: <5642550C.4040603@redhat.com> References: <56423596.3030300@redhat.com> <20151110202806.GG14311@dastard> <5642550C.4040603@redhat.com> From: Jan Tulak Date: Wed, 11 Nov 2015 14:13:23 +0100 Message-ID: Subject: Re: [PATCH] xfsprogs: fix cut & paste error in xfs_fsr.c To: Eric Sandeen X-ASG-Orig-Subj: Re: [PATCH] xfsprogs: fix cut & paste error in xfs_fsr.c Cc: Dave Chinner , xfs-oss Content-Type: multipart/alternative; boundary=001a114032fc761b9405244398e3 X-Barracuda-Connect: mail-io0-f174.google.com[209.85.223.174] X-Barracuda-Start-Time: 1447247623 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/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_SC0_SA_TO_FROM_DOMAIN_MATCH, HTML_MESSAGE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24302 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 HTML_MESSAGE BODY: HTML included in message 0.01 BSF_SC0_SA_TO_FROM_DOMAIN_MATCH Sender Domain Matches Recipient Domain --001a114032fc761b9405244398e3 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable On Tue, Nov 10, 2015 at 9:35 PM, Eric Sandeen wrote: > > On Tue, Nov 10, 2015 at 12:21:10PM -0600, Eric Sandeen wrote: > >> Commit: > >> > >> 7141fc xfsprogs: make fsr use mntinfo when there is no mntent > >> > >> added an inadvertent "break;" to initallfs() after the call > >> to find_mountpoint_check(); this is likely a cut & paste error > >> from the call in find_mountpoint(), where we really *do* want to > >> stop after the first one we find. > >> > >> Fix that by removing the break, and fix the declaration-after-code. > > > > That's not the right fix - the find_mountpoint_check() shoul dnot be > > there at all. Patch to clean it all up is below. > > > > -Dave. > > -- > > Dave Chinner > > david@fromorbit.com > > > > fsr: clean up mountpoint checks > > > > From: Dave Chinner > > > > Fix up a stray hunk of code from commit 7141fc5 ("xfsprogs: make fsr > > use mntinfo when there is no mntent") that coverity reported. Also > > clean up a couple of whitespace issues introduced with that commit, > > too. > > Um, ok, well it wasn't your misapplication, it was there in the original > patch, > and I wasn't sure of Jan's intent, having gone so far as to add local var= s > to support that placement. ;) > > This seems fine, I guess I'll send another patch to make *ms local to > find_mountpoint_check(), and rename some vars ("sb" and "mp" have their > own expected meanings in xfsprogs) > =E2=80=8BHmmm, sorry about the mess... :-( I will look on the patch again t= oo. Speaking about Coverity, is there a way I can get to it and use it myself? (Maybe it may be b=E2=80=8Better to continue this off list - from what I he= ard, Coverity guys don't like to be talk about publicly...) Cheers, Jan --=20 Jan Tulak jtulak@redhat.com / jan@tulak.me --001a114032fc761b9405244398e3 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
On Tue, No= v 10, 2015 at 9:35 PM, Eric Sandeen <sandeen@redhat.com> wrote:
> On Tue, Nov 10, 20= 15 at 12:21:10PM -0600, Eric Sandeen wrote:
>> Commit:
>>
>> 7141fc xfsprogs: make fsr use mntinfo when there is no mntent
>>
>> added an inadvertent "break;" to initallfs() after the c= all
>> to find_mountpoint_check(); this is likely a cut & paste error=
>> from the call in find_mountpoint(), where we really *do* want to >> stop after the first one we find.
>>
>> Fix that by removing the break, and fix the declaration-after-code= .
>
> That's not the right fix - the find_mountpoint_check() shoul dnot = be
> there at all. Patch to clean it all up is below.
>
> -Dave.
> --
> Dave Chinner
> david@fromorbit.com
>
> fsr: clean up mountpoint checks
>
> From: Dave Chinner <dchinner= @redhat.com>
>
> Fix up a stray hunk of code from commit 7141fc5 ("xfsprogs: make = fsr
> use mntinfo when there is no mntent") that coverity reported. Als= o
> clean up a couple of whitespace issues introduced with that=C2=A0 comm= it,
> too.

Um, ok, well it wasn't your misapplication, it was there in the = original patch,
and I wasn't sure of Jan's intent, having gone so far as to add loc= al vars
to support that placement.=C2=A0 ;)

This seems fine, I guess I'll send another patch to make *ms local to find_mountpoint_check(), and rename some vars ("sb" and "mp&= quot; have their
own expected meanings in xfsprogs)

=E2=80=8BHmmm, sorry about the mess... :-( I will loo= k on the patch again too.
Speaking about =C2=A0Coverity, is there a= way I can get to it and use it myself? (Maybe it may be b=E2=80=8Better to= continue this off list - from what I heard, Coverity guys don't like t= o be talk about publicly...)

Cheers,
Jan

--
--001a114032fc761b9405244398e3-- From BATV+66af426afb9dea266a66+4462+infradead.org+hch@bombadil.srs.infradead.org Wed Nov 11 07:56:50 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 CD80E7F63 for ; Wed, 11 Nov 2015 07:56:50 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id AEA60304032 for ; Wed, 11 Nov 2015 05:56:47 -0800 (PST) X-ASG-Debug-ID: 1447250206-04cb6c296b11bd10001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id EbYpAtXC1otHajzO (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Wed, 11 Nov 2015 05:56:46 -0800 (PST) X-Barracuda-Envelope-From: BATV+66af426afb9dea266a66+4462+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 1ZwVt9-0001WP-3h; Wed, 11 Nov 2015 13:56:39 +0000 Date: Wed, 11 Nov 2015 05:56:39 -0800 From: Christoph Hellwig To: "Darrick J. Wong" Cc: Christoph Hellwig , david@fromorbit.com, fstests@vger.kernel.org, linux-ext4@vger.kernel.org, Anna.Schumaker@netapp.com, linux-btrfs@vger.kernel.org, xfs@oss.sgi.com Subject: Re: [RFCv3 00/12] xfstests: test the btrfs/xfs reflink/dedupe ioctls Message-ID: <20151111135639.GA4760@infradead.org> X-ASG-Orig-Subj: Re: [RFCv3 00/12] xfstests: test the btrfs/xfs reflink/dedupe ioctls References: <20151007051257.3260.73072.stgit@birch.djwong.org> <20151109075926.GB17974@infradead.org> <20151109184913.GB3255@birch.djwong.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151109184913.GB3255@birch.djwong.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: 1447250206 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/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_MISMATCH_TO, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24303 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS On Mon, Nov 09, 2015 at 10:49:13AM -0800, Darrick J. Wong wrote: > I found a few more bugs in the kernel-side implementation, which might explain > that. I'm about to start working on making CoW less crappy, but I'll push all > the patches out to github. (I wasn't planning on patchbombing again until > December.) Yes, please push your WIP code out as often as possible! Btw, here is another additional fixup, as two tests were wrongly tagged as needing reflink instead of dedupe: diff --git a/tests/generic/827 b/tests/generic/827 index cc1bc52..c8ce7cf 100755 --- a/tests/generic/827 +++ b/tests/generic/827 @@ -47,7 +47,7 @@ _supported_fs generic _supported_os Linux _require_scratch -_require_xfs_io_command "reflink" +_require_xfs_io_command "dedupe" echo "Format and mount" _scratch_mkfs > $seqres.full 2>&1 diff --git a/tests/generic/828 b/tests/generic/828 index 1757985..f5b7298 100755 --- a/tests/generic/828 +++ b/tests/generic/828 @@ -47,7 +47,7 @@ _supported_fs generic _supported_os Linux _require_scratch -_require_xfs_io_command "reflink" +_require_xfs_io_command "dedupe" echo "Format and mount" _scratch_mkfs > $seqres.full 2>&1 From agruenba@redhat.com Wed Nov 11 07:59:35 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 6D7737F67 for ; Wed, 11 Nov 2015 07:59:35 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 3B23E8F8035 for ; Wed, 11 Nov 2015 05:59:35 -0800 (PST) X-ASG-Debug-ID: 1447250371-04bdf03f03117b80001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id ZtQVfjACQJmjLp0C (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 11 Nov 2015 05:59:31 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id C864719D054; Wed, 11 Nov 2015 13:59:30 +0000 (UTC) Received: from nux.redhat.com (vpn1-6-232.ams2.redhat.com [10.36.6.232]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tABDxMYC020889; Wed, 11 Nov 2015 08:59:23 -0500 From: Andreas Gruenbacher To: Christoph Hellwig Cc: Andreas Gruenbacher , Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4 , XFS Developers , LKML , linux-fsdevel , Linux NFS Mailing List , linux-cifs@vger.kernel.org, Linux API Subject: Re: [PATCH v15 00/22] Richacls (Core and Ext4) Date: Wed, 11 Nov 2015 14:59:21 +0100 X-ASG-Orig-Subj: Re: [PATCH v15 00/22] Richacls (Core and Ext4) Message-Id: <1447250361-5561-1-git-send-email-agruenba@redhat.com> References: <1447067343-31479-1-git-send-email-agruenba@redhat.com> <20151110112943.GA17038@infradead.org> <20151111075707.GA23752@infradead.org> In-Reply-To: <20151111075707.GA23752@infradead.org> 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: 1447250371 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Wed, Nov 11, 2015 at 8:57 AM, Christoph Hellwig wrote: > On Tue, Nov 10, 2015 at 01:39:52PM +0100, Andreas Gruenbacher wrote: >> > It still has the same crappy fs interfaces with lots of boilerplate >> > code >> >> Could you please be more specific so that I can trace this complaint >> to some actual code? > > if (IS_RICHACL()) > richacl_foo() > else > posix_acl_foo() > > for every call from the filesystem is the major one that came to mind. There are two such places in ext4, ext4_new_acl and ext4_acl_chmod. Those could be replaced by function pointers as below, I'm not sure we seriously want to consider that. In xfs, we have xfs_acl_chmod which is similar. xfs_generic_create doesn't quite follow this pattern. This seems to be about it though. Thanks, Andreas --- fs/ext4/ext4.h | 10 ++++++++++ fs/ext4/ialloc.c | 11 +---------- fs/ext4/inode.c | 11 +---------- fs/ext4/super.c | 30 ++++++++++++++++++++++++++++++ include/linux/fs.h | 1 + 5 files changed, 43 insertions(+), 20 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index b97a3b1..5ff4556 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -3049,6 +3049,16 @@ extern struct mutex ext4__aio_mutex[EXT4_WQ_HASH_SZ]; extern int ext4_resize_begin(struct super_block *sb); extern void ext4_resize_end(struct super_block *sb); +struct ext4_acl_ops { + int (*chmod)(struct inode *, umode_t); + int (*init_acl)(handle_t *, struct inode *, struct inode *); +}; + +static inline const struct ext4_acl_ops *ACL_OPS(struct inode *inode) +{ + return inode->i_sb->s_private; +} + #endif /* __KERNEL__ */ #endif /* _EXT4_H */ diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index 9657b3a..e33646f 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c @@ -27,7 +27,6 @@ #include "ext4_jbd2.h" #include "xattr.h" #include "acl.h" -#include "richacl.h" #include @@ -698,14 +697,6 @@ out: return ret; } -static inline int -ext4_new_acl(handle_t *handle, struct inode *inode, struct inode *dir) -{ - if (IS_RICHACL(dir)) - return ext4_init_richacl(handle, inode, dir); - return ext4_init_acl(handle, inode, dir); -} - /* * There are two policies for allocating an inode. If the new inode is * a directory, then a forward search is made for a block group with both @@ -1061,7 +1052,7 @@ got: if (err) goto fail_drop; - err = ext4_new_acl(handle, inode, dir); + err = ACL_OPS(inode)->init_acl(handle, inode, dir); if (err) goto fail_free_drop; diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 647f3c3..9f179ee 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -42,7 +42,6 @@ #include "xattr.h" #include "acl.h" #include "truncate.h" -#include "richacl.h" #include @@ -4639,14 +4638,6 @@ static void ext4_wait_for_tail_page_commit(struct inode *inode) } } -static inline int -ext4_acl_chmod(struct inode *inode, umode_t mode) -{ - if (IS_RICHACL(inode)) - return richacl_chmod(inode, inode->i_mode); - return posix_acl_chmod(inode, inode->i_mode); -} - /* * ext4_setattr() * @@ -4815,7 +4806,7 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr) ext4_orphan_del(NULL, inode); if (!rc && (ia_valid & ATTR_MODE)) - rc = ext4_acl_chmod(inode, inode->i_mode); + rc = ACL_OPS(inode)->chmod(inode, inode->i_mode); err_out: ext4_std_error(inode->i_sb, error); if (!error) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 7457ea8..879bc2c 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -49,6 +49,7 @@ #include "ext4_jbd2.h" #include "xattr.h" #include "acl.h" +#include "richacl.h" #include "mballoc.h" #define CREATE_TRACE_POINTS @@ -1270,25 +1271,54 @@ static ext4_fsblk_t get_sb_block(void **data) return sb_block; } +static int no_chmod_acl(struct inode *inode, umode_t mode) +{ + return 0; +} + +static int no_init_acl(handle_t *handle, struct inode *inode, struct inode *dir) +{ + return 0; +} + +struct ext4_acl_ops no_acl_ops = { + .chmod = no_chmod_acl, + .init_acl = no_init_acl, +}; + +struct ext4_acl_ops ext4_posix_acl_ops = { + .chmod = posix_acl_chmod, + .init_acl = ext4_init_acl, +}; + +struct ext4_acl_ops ext4_richacl_ops = { + .chmod = richacl_chmod, + .init_acl = ext4_init_richacl, +}; + static int enable_acl(struct super_block *sb) { sb->s_flags &= ~(MS_POSIXACL | MS_RICHACL); + sb->s_private = &no_acl_ops; if (test_opt(sb, ACL)) { if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RICHACL)) { #ifdef CONFIG_EXT4_FS_RICHACL sb->s_flags |= MS_RICHACL; + sb->s_private = &ext4_richacl_ops; #else return -EOPNOTSUPP; #endif } else { #ifdef CONFIG_EXT4_FS_POSIX_ACL sb->s_flags |= MS_POSIXACL; + sb->s_private = &ext4_posix_acl_ops; #else return -EOPNOTSUPP; #endif } } + return 0; } diff --git a/include/linux/fs.h b/include/linux/fs.h index 05fb943..5803bf6 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1324,6 +1324,7 @@ struct super_block { void *s_security; #endif const struct xattr_handler **s_xattr; + const void *s_private; struct hlist_bl_head s_anon; /* anonymous dentries for (nfs) exporting */ struct list_head s_mounts; /* list of mounts; _not_ for fs use */ -- 2.5.0 From sandeen@sandeen.net Wed Nov 11 09:41:27 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 5B2547F5A for ; Wed, 11 Nov 2015 09:41:27 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 23E498F8035 for ; Wed, 11 Nov 2015 07:41:26 -0800 (PST) X-ASG-Debug-ID: 1447256484-04bdf03f0211a510001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id tdmQVKE33vsYPBZe for ; Wed, 11 Nov 2015 07:41:24 -0800 (PST) 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 67ED8612961A; Wed, 11 Nov 2015 09:41:24 -0600 (CST) Subject: Re: [PATCH] xfsprogs: fix cut & paste error in xfs_fsr.c To: Jan Tulak X-ASG-Orig-Subj: Re: [PATCH] xfsprogs: fix cut & paste error in xfs_fsr.c References: <56423596.3030300@redhat.com> <20151110202806.GG14311@dastard> <5642550C.4040603@redhat.com> Cc: xfs@oss.sgi.com From: Eric Sandeen Message-ID: <564361A1.8050502@sandeen.net> Date: Wed, 11 Nov 2015 09:41:21 -0600 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1447256484 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24305 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 11/11/15 7:13 AM, Jan Tulak wrote: > ​Hmmm, sorry about the mess... :-( I will look on the patch again > too. Speaking about Coverity, is there a way I can get to it and use > it myself? (Maybe it may be b​etter to continue this off list - from > what I heard, Coverity guys don't like to be talk about publicly...) > > Cheers, Jan So, we have xfsprogs & xfsdump in the upstream "Coverity Scan" project, which is free for open source projects. Nah, it's not secret, although access to the defect database is controlled, out of security concerns I guess - I sent you an invite. Thanks, -Eric From penguin-kernel@I-love.SAKURA.ne.jp Wed Nov 11 09:58:22 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 33C0D7F77 for ; Wed, 11 Nov 2015 09:58:22 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 1FB288F8049 for ; Wed, 11 Nov 2015 07:58:21 -0800 (PST) X-ASG-Debug-ID: 1447257496-04cb6c296c11f360001-NocioJ Received: from www262.sakura.ne.jp (www262.sakura.ne.jp [202.181.97.72]) by cuda.sgi.com with ESMTP id ChCr4rzAkhtfTQc4 (version=TLSv1 cipher=DHE-RSA-CAMELLIA256-SHA bits=256 verify=NO) for ; Wed, 11 Nov 2015 07:58:17 -0800 (PST) X-Barracuda-Envelope-From: penguin-kernel@I-love.SAKURA.ne.jp X-Barracuda-Apparent-Source-IP: 202.181.97.72 Received: from fsav402.sakura.ne.jp (fsav402.sakura.ne.jp [133.242.250.101]) by www262.sakura.ne.jp (8.14.5/8.14.5) with ESMTP id tABFw8Tc005589; Thu, 12 Nov 2015 00:58:09 +0900 (JST) (envelope-from penguin-kernel@I-love.SAKURA.ne.jp) Received: from www262.sakura.ne.jp (202.181.97.72) by fsav402.sakura.ne.jp (F-Secure/fsigk_smtp/522/fsav402.sakura.ne.jp); Thu, 12 Nov 2015 00:58:08 +0900 (JST) X-Virus-Status: clean(F-Secure/fsigk_smtp/522/fsav402.sakura.ne.jp) Received: from [192.168.1.8] (softbank126094077227.bbtec.net [126.94.77.227]) (authenticated bits=0) by www262.sakura.ne.jp (8.14.5/8.14.5) with ESMTP id tABFw8PA005586 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Thu, 12 Nov 2015 00:58:08 +0900 (JST) (envelope-from penguin-kernel@I-love.SAKURA.ne.jp) Subject: Re: memory reclaim problems on fs usage To: =?UTF-8?Q?Arkadiusz_Mi=c5=9bkiewicz?= , linux-mm@kvack.org, xfs@oss.sgi.com X-ASG-Orig-Subj: Re: memory reclaim problems on fs usage References: <201511102313.36685.arekm@maven.pl> Newsgroups: gmane.linux.kernel.mm From: Tetsuo Handa Message-ID: <5643658B.9090206@I-love.SAKURA.ne.jp> Date: Thu, 12 Nov 2015 00:58:03 +0900 User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <201511102313.36685.arekm@maven.pl> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit X-Barracuda-Connect: www262.sakura.ne.jp[202.181.97.72] X-Barracuda-Start-Time: 1447257497 X-Barracuda-Encrypted: DHE-RSA-CAMELLIA256-SHA X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24305 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 2015/11/11 7:13, Arkadiusz Miśkiewicz wrote: > The usual (repeatable) problem is like this: > > full dmesg: http://sprunge.us/VEiE (more in it then in partial log below) Maybe somebody doing GFP_NOIO allocation which XFS driver doing GFP_NOFS allocation is waiting for is stalling inside memory allocator. I think that checking tasks which are stalling inside memory allocator would help. Please try reproducing this problem with a debug printk() patch shown below applied. This is a patch which I used for debugging silent lockup problem. When memory allocation got stuck, lines with MemAlloc keyword will be printed. --- fs/xfs/kmem.c | 10 ++- fs/xfs/xfs_buf.c | 3 +- include/linux/mmzone.h | 1 + include/linux/vmstat.h | 1 + mm/page_alloc.c | 217 +++++++++++++++++++++++++++++++++++++++++++++++++ mm/vmscan.c | 22 +++++ 6 files changed, 249 insertions(+), 5 deletions(-) diff --git a/fs/xfs/kmem.c b/fs/xfs/kmem.c index a7a3a63..535c136 100644 --- a/fs/xfs/kmem.c +++ b/fs/xfs/kmem.c @@ -55,8 +55,9 @@ kmem_alloc(size_t size, xfs_km_flags_t flags) return ptr; if (!(++retries % 100)) xfs_err(NULL, - "possible memory allocation deadlock in %s (mode:0x%x)", - __func__, lflags); + "%s(%u) possible memory allocation deadlock in %s (mode:0x%x)", + current->comm, current->pid, + __func__, lflags); congestion_wait(BLK_RW_ASYNC, HZ/50); } while (1); } @@ -120,8 +121,9 @@ kmem_zone_alloc(kmem_zone_t *zone, xfs_km_flags_t flags) return ptr; if (!(++retries % 100)) xfs_err(NULL, - "possible memory allocation deadlock in %s (mode:0x%x)", - __func__, lflags); + "%s(%u) possible memory allocation deadlock in %s (mode:0x%x)", + current->comm, current->pid, + __func__, lflags); congestion_wait(BLK_RW_ASYNC, HZ/50); } while (1); } diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index 1790b00..16322cb 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c @@ -354,7 +354,8 @@ retry: */ if (!(++retries % 100)) xfs_err(NULL, - "possible memory allocation deadlock in %s (mode:0x%x)", + "%s(%u) possible memory allocation deadlock in %s (mode:0x%x)", + current->comm, current->pid, __func__, gfp_mask); XFS_STATS_INC(xb_page_retries); diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 54d74f6..932a6d6 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -527,6 +527,7 @@ struct zone { ZONE_PADDING(_pad3_) /* Zone statistics */ atomic_long_t vm_stat[NR_VM_ZONE_STAT_ITEMS]; + unsigned long stat_last_updated[NR_VM_ZONE_STAT_ITEMS]; } ____cacheline_internodealigned_in_smp; enum zone_flags { diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h index 82e7db7..2488925 100644 --- a/include/linux/vmstat.h +++ b/include/linux/vmstat.h @@ -115,6 +115,7 @@ static inline void zone_page_state_add(long x, struct zone *zone, { atomic_long_add(x, &zone->vm_stat[item]); atomic_long_add(x, &vm_stat[item]); + zone->stat_last_updated[item] = jiffies; } static inline unsigned long global_page_state(enum zone_stat_item item) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 18490f3..35a46b4 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -61,6 +61,8 @@ #include #include #include +#include +#include #include #include @@ -2496,6 +2498,8 @@ __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order, } #endif /* CONFIG_COMPACTION */ +pid_t dump_target_pid; + /* Perform direct synchronous page reclaim */ static int __perform_reclaim(gfp_t gfp_mask, unsigned int order, @@ -2645,6 +2649,208 @@ bool gfp_pfmemalloc_allowed(gfp_t gfp_mask) return !!(gfp_to_alloc_flags(gfp_mask) & ALLOC_NO_WATERMARKS); } +static unsigned long kmallocwd_timeout = 10 * HZ; /* Scan interval. */ +static u8 memalloc_counter_active_index; /* Either 0 or 1. */ +static int memalloc_counter[2]; /* Number of tasks doing memory allocation. */ + +struct memalloc { + struct list_head list; /* Connected to memalloc_list. */ + struct task_struct *task; /* Iniatilized to current. */ + unsigned long start; /* Initialized to jiffies. */ + unsigned int order; + gfp_t gfp; + u8 index; /* Initialized to memalloc_counter_active_index. */ + u8 dumped; +}; + +static LIST_HEAD(memalloc_list); /* List of "struct memalloc".*/ +static DEFINE_SPINLOCK(memalloc_list_lock); /* Lock for memalloc_list. */ + +/* + * kmallocwd - A kernel thread for monitoring memory allocation stalls. + * + * @unused: Not used. + * + * This kernel thread does not terminate. + */ +static int kmallocwd(void *unused) +{ + struct memalloc *m; + struct task_struct *g, *p; + unsigned long now; + unsigned int sigkill_pending; + unsigned int memdie_pending; + unsigned int stalling_tasks; + u8 index; + pid_t pid; + + not_stalling: /* Healty case. */ + /* Switch active counter and wait for timeout duration. */ + index = memalloc_counter_active_index; + spin_lock(&memalloc_list_lock); + memalloc_counter_active_index ^= 1; + spin_unlock(&memalloc_list_lock); + schedule_timeout_interruptible(kmallocwd_timeout); + /* + * If memory allocations are working, the counter should remain 0 + * because tasks will be able to call both start_memalloc_timer() + * and stop_memalloc_timer() within timeout duration. + */ + if (likely(!memalloc_counter[index])) + goto not_stalling; + maybe_stalling: /* Maybe something is wrong. Let's check. */ + now = jiffies; + /* Count stalling tasks, dying and victim tasks. */ + sigkill_pending = 0; + memdie_pending = 0; + stalling_tasks = 0; + pid = 0; + spin_lock(&memalloc_list_lock); + list_for_each_entry(m, &memalloc_list, list) { + if (time_after(now - m->start, kmallocwd_timeout)) + stalling_tasks++; + } + spin_unlock(&memalloc_list_lock); + preempt_disable(); + rcu_read_lock(); + for_each_process_thread(g, p) { + if (test_tsk_thread_flag(p, TIF_MEMDIE)) + memdie_pending++; + if (fatal_signal_pending(p)) + sigkill_pending++; + } + rcu_read_unlock(); + preempt_enable(); + cond_resched(); + pr_warn("MemAlloc-Info: %u stalling task, %u dying task, %u victim task.\n", + stalling_tasks, sigkill_pending, memdie_pending); + /* Report stalling tasks, dying and victim tasks. */ + spin_lock(&memalloc_list_lock); + list_for_each_entry(m, &memalloc_list, list) { + if (time_before(now - m->start, kmallocwd_timeout)) + continue; + p = m->task; + pr_warn("MemAlloc: %s(%u) gfp=0x%x order=%u delay=%lu\n", + p->comm, p->pid, m->gfp, m->order, now - m->start); + } + spin_unlock(&memalloc_list_lock); + preempt_disable(); + rcu_read_lock(); + for_each_process_thread(g, p) { + u8 type = 0; + + if (test_tsk_thread_flag(p, TIF_MEMDIE)) + type |= 1; + if (fatal_signal_pending(p)) + type |= 2; + if (likely(!type)) + continue; + if (p->state & TASK_UNINTERRUPTIBLE) + type |= 4; + pr_warn("MemAlloc: %s(%u)%s%s%s\n", p->comm, p->pid, + (type & 4) ? " uninterruptible" : "", + (type & 2) ? " dying" : "", + (type & 1) ? " victim" : ""); + } + rcu_read_unlock(); + preempt_enable(); + cond_resched(); + /* + * Show traces of newly reported (or too long) stalling tasks. + * + * Show traces only once per 256 timeouts because their traces + * will likely be the same (e.g. cond_sched() or congestion_wait()) + * when they are stalling inside __alloc_pages_slowpath(). + */ + spin_lock(&memalloc_list_lock); + list_for_each_entry(m, &memalloc_list, list) { + if (time_before(now - m->start, kmallocwd_timeout) || + m->dumped++) + continue; + p = m->task; + sched_show_task(p); + debug_show_held_locks(p); + touch_nmi_watchdog(); + if (!pid) + pid = p->pid; + } + spin_unlock(&memalloc_list_lock); + /* + * Show traces of dying tasks (including victim tasks). + * + * Only dying tasks which are in trouble (e.g. blocked at unkillable + * locks held by memory allocating tasks) will be repeatedly shown. + * Therefore, we need to pay attention to tasks repeatedly shown here. + */ + preempt_disable(); + rcu_read_lock(); + for_each_process_thread(g, p) { + if (likely(!fatal_signal_pending(p))) + continue; + sched_show_task(p); + debug_show_held_locks(p); + touch_nmi_watchdog(); + } + rcu_read_unlock(); + preempt_enable(); + show_workqueue_state(); + if (!dump_target_pid) + dump_target_pid = -pid; + /* Wait until next timeout duration. */ + schedule_timeout_interruptible(kmallocwd_timeout); + if (memalloc_counter[index]) + goto maybe_stalling; + goto not_stalling; + return 0; /* To suppress "no return statement" compiler warning. */ +} + +static int __init start_kmallocwd(void) +{ + if (kmallocwd_timeout) { + struct task_struct *task = kthread_run(kmallocwd, NULL, + "kmallocwd"); + BUG_ON(IS_ERR(task)); + } + return 0; +} +late_initcall(start_kmallocwd); + +static int __init kmallocwd_config(char *str) +{ + if (kstrtoul(str, 10, &kmallocwd_timeout) == 0) + kmallocwd_timeout = min(kmallocwd_timeout * HZ, + (unsigned long) LONG_MAX); + return 0; +} +__setup("kmallocwd=", kmallocwd_config); + +static void start_memalloc_timer(struct memalloc *m, const gfp_t gfp_mask, + const int order) +{ + if (!kmallocwd_timeout || m->task) + return; + m->task = current; + m->start = jiffies; + m->gfp = gfp_mask; + m->order = order; + m->dumped = 0; + spin_lock(&memalloc_list_lock); + m->index = memalloc_counter_active_index; + memalloc_counter[m->index]++; + list_add_tail(&m->list, &memalloc_list); + spin_unlock(&memalloc_list_lock); +} + +static void stop_memalloc_timer(struct memalloc *m) +{ + if (!m->task) + return; + spin_lock(&memalloc_list_lock); + memalloc_counter[m->index]--; + list_del(&m->list); + spin_unlock(&memalloc_list_lock); +} + static inline struct page * __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order, struct alloc_context *ac) @@ -2657,6 +2863,7 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order, enum migrate_mode migration_mode = MIGRATE_ASYNC; bool deferred_compaction = false; int contended_compaction = COMPACT_CONTENDED_NONE; + struct memalloc m = { .task = NULL }; /* * In the slowpath, we sanity check order to avoid ever trying to @@ -2678,6 +2885,9 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order, goto nopage; retry: + if (dump_target_pid == -current->pid) + dump_target_pid = -dump_target_pid; + if (!(gfp_mask & __GFP_NO_KSWAPD)) wake_all_kswapds(order, ac); @@ -2740,6 +2950,8 @@ retry: if (test_thread_flag(TIF_MEMDIE) && !(gfp_mask & __GFP_NOFAIL)) goto nopage; + start_memalloc_timer(&m, gfp_mask, order); + /* * Try direct compaction. The first pass is asynchronous. Subsequent * attempts after direct reclaim are synchronous @@ -2798,6 +3010,10 @@ retry: goto got_pg; /* Check if we should retry the allocation */ + if (dump_target_pid == current->pid) { + printk(KERN_INFO "did_some_progress=%lu\n", did_some_progress); + dump_target_pid = 0; + } pages_reclaimed += did_some_progress; if (should_alloc_retry(gfp_mask, order, did_some_progress, pages_reclaimed)) { @@ -2834,6 +3050,7 @@ retry: nopage: warn_alloc_failed(gfp_mask, order, NULL); got_pg: + stop_memalloc_timer(&m); return page; } diff --git a/mm/vmscan.c b/mm/vmscan.c index 1a17bd7..c449371 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -2432,6 +2432,8 @@ static inline bool compaction_ready(struct zone *zone, int order) return watermark_ok; } +extern pid_t dump_target_pid; + /* * This is the direct reclaim path, for page-allocating processes. We only * try to reclaim pages from zones which will satisfy the caller's allocation @@ -2533,7 +2535,27 @@ static bool shrink_zones(struct zonelist *zonelist, struct scan_control *sc) if (global_reclaim(sc) && !reclaimable && zone_reclaimable(zone)) + { + if (dump_target_pid == current->pid) { + unsigned long rec = zone_reclaimable_pages(zone); + unsigned long free = zone_page_state(zone, NR_FREE_PAGES); + unsigned long min = min_wmark_pages(zone); + unsigned long scanned = zone_page_state(zone, NR_PAGES_SCANNED); + unsigned long now = jiffies; + unsigned long rec2 = zone_page_state_snapshot(zone, NR_ACTIVE_FILE) + + zone_page_state_snapshot(zone, NR_INACTIVE_FILE); + unsigned long free2 = zone_page_state_snapshot(zone, NR_FREE_PAGES); + unsigned long scanned2 = zone_page_state_snapshot(zone, NR_PAGES_SCANNED); + + printk(KERN_INFO "%s zone_reclaimable: reclaim:%lu(%lu,%lu,%ld) free:%lu(%lu,%ld) min:%lu pages_scanned:%lu(%lu,%ld) prio:%d\n", + zone->name, rec, now - zone->stat_last_updated[NR_ACTIVE_FILE], + now - zone->stat_last_updated[NR_INACTIVE_FILE], rec - rec2, + free, now - zone->stat_last_updated[NR_FREE_PAGES], free - free2, + min, scanned, now - zone->stat_last_updated[NR_PAGES_SCANNED], + scanned - scanned2, sc->priority); + } reclaimable = true; + } } /* -- 1.8.3.1 From arekm@maven.pl Wed Nov 11 10:19:58 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 5C83C7F80 for ; Wed, 11 Nov 2015 10:19:58 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 4AA5B304032 for ; Wed, 11 Nov 2015 08:19:55 -0800 (PST) X-ASG-Debug-ID: 1447258787-04cb6c296a120420001-NocioJ Received: from mail-lb0-f177.google.com (mail-lb0-f177.google.com [209.85.217.177]) by cuda.sgi.com with ESMTP id 6FMJMRH4tgiRhFjA (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Wed, 11 Nov 2015 08:19:48 -0800 (PST) X-Barracuda-Envelope-From: arekm@maven.pl X-Barracuda-Apparent-Source-IP: 209.85.217.177 Received: by lbbkw15 with SMTP id kw15so19645836lbb.0 for ; Wed, 11 Nov 2015 08:19:47 -0800 (PST) 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=5Dk7Mhf7CIVcwpAC672GQ3bcRhzWv/re5bdfNWlsbRY=; b=Ds4YmlqjSp5koGe+AJ/yVDXaRuz4Xbay52NDfsMxqELUfhskVjW2mGmMpefTx8sc6K ViTigYaIRGdvNqOwYrRjbZIDDMHBVAHCowtkeuOZJ5xMnI6ttaNYozsb+ghMgd1AKtCc QClhAUQ+OmBW7oez3jdCbKZ6sqWyYDqmprA4E= 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=5Dk7Mhf7CIVcwpAC672GQ3bcRhzWv/re5bdfNWlsbRY=; b=SstG/UtagGNwKX3neR9J1RVovuKCUviqRjl0GRmNw0T6XZTXKpM/nGUE3RwEJCtWGY AKsVTJbNNcGgKPLEEN2LIkCBU72SqovRjvqvlKEz8+aFePBDz1nfNyf0m/5NlOb8yxg2 viIzNZ3NsQ8Dph7tWk1nyv9gthK1grjsZQhdP+0kB14UL3vivDDWPGeMoPAYQIVBfNmQ X6h1aJ8cQyo0mmzeFanqbn02HGP6aNW2mbzuojvRtWtP0WJSVD6X7CmpVQKMmBc0jB3c Gmi4RanYv8nOvA/SCQSo0EBvqyI7DNohoddw+FJol4PPfTqm//FkTGEJnKG1ZibmhbIq w39g== X-Gm-Message-State: ALoCoQlp+L2Q7vgKwT9s8PYvujB3Gkf5tleMikB0cHBPooscazPv7tWW+Z4gfuW2E8RIuyxvYnMN X-Received: by 10.112.180.131 with SMTP id do3mr4847377lbc.123.1447258786591; Wed, 11 Nov 2015 08:19:46 -0800 (PST) Received: from xps.localnet (85-222-71-204.dynamic.chello.pl. [85.222.71.204]) by smtp.gmail.com with ESMTPSA id l8sm1564264lbj.7.2015.11.11.08.19.45 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 11 Nov 2015 08:19:45 -0800 (PST) From: Arkadiusz =?utf-8?q?Mi=C5=9Bkiewicz?= To: Tetsuo Handa Subject: Re: memory reclaim problems on fs usage Date: Wed, 11 Nov 2015 17:19:42 +0100 X-ASG-Orig-Subj: Re: memory reclaim problems on fs usage User-Agent: KMail/1.13.7 (Linux/4.3.0; KDE/4.14.13; x86_64; ; ) Cc: linux-mm@kvack.org, xfs@oss.sgi.com References: <201511102313.36685.arekm@maven.pl> <5643658B.9090206@I-love.SAKURA.ne.jp> In-Reply-To: <5643658B.9090206@I-love.SAKURA.ne.jp> MIME-Version: 1.0 Content-Type: Text/Plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <201511111719.44035.arekm@maven.pl> X-Barracuda-Connect: mail-lb0-f177.google.com[209.85.217.177] X-Barracuda-Start-Time: 1447258787 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24305 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 11 of November 2015, Tetsuo Handa wrote: > On 2015/11/11 7:13, Arkadiusz Mi=C5=9Bkiewicz wrote: > > The usual (repeatable) problem is like this: > >=20 > > full dmesg: http://sprunge.us/VEiE (more in it then in partial log belo= w) >=20 > Maybe somebody doing GFP_NOIO allocation which XFS driver doing GFP_NOFS > allocation is waiting for is stalling inside memory allocator. I think th= at > checking tasks which are stalling inside memory allocator would help. >=20 > Please try reproducing this problem with a debug printk() patch shown bel= ow > applied. This is a patch which I used for debugging silent lockup problem. > When memory allocation got stuck, lines with MemAlloc keyword will be > printed. >=20 > --- > fs/xfs/kmem.c | 10 ++- > fs/xfs/xfs_buf.c | 3 +- > include/linux/mmzone.h | 1 + > include/linux/vmstat.h | 1 + > mm/page_alloc.c | 217 > +++++++++++++++++++++++++++++++++++++++++++++++++ mm/vmscan.c | > 22 +++++ > 6 files changed, 249 insertions(+), 5 deletions(-) This patch is against which tree? (tried 4.1, 4.2 and 4.3) =2D-=20 Arkadiusz Mi=C5=9Bkiewicz, arekm / ( maven.pl | pld-linux.org ) From darrick.wong@oracle.com Wed Nov 11 12:55:45 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 523DF7F54 for ; Wed, 11 Nov 2015 12:55:45 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 117CF30404E for ; Wed, 11 Nov 2015 10:55:44 -0800 (PST) X-ASG-Debug-ID: 1447268139-04bdf03f051208e0001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id b9NkDQChxnt5UlOf (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 11 Nov 2015 10:55:39 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tABItEk5021267 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 11 Nov 2015 18:55:15 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id tABItEJZ000568 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 11 Nov 2015 18:55:14 GMT Received: from abhmp0002.oracle.com (abhmp0002.oracle.com [141.146.116.8]) by userv0121.oracle.com (8.13.8/8.13.8) with ESMTP id tABItBWN030475; Wed, 11 Nov 2015 18:55:13 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 11 Nov 2015 10:55:11 -0800 Date: Wed, 11 Nov 2015 10:55:10 -0800 From: "Darrick J. Wong" To: david@fromorbit.com, hch@infradead.org Cc: linux-fsdevel , xfs Subject: RFCv3+ WIP rollup of XFS reverse-mapping, reflink, and dedupe support Message-ID: <20151111185510.GC2224@birch.djwong.org> X-ASG-Orig-Subj: RFCv3+ WIP rollup of XFS reverse-mapping, reflink, and dedupe support MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) X-Source-IP: aserv0022.oracle.com [141.146.126.234] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1447268139 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24309 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Hi all, Today I've uploaded the latest WIP patches for XFS reverse mapping, reflink, and dedupe support to github: https://github.com/djwong/linux/tree/for-dave https://github.com/djwong/xfsprogs/tree/for-dave https://github.com/djwong/xfstests/tree/for-dave https://github.com/djwong/xfs-documentation/tree/for-dave I've cleaned things up so now you can pull the for-dave branch in any of the four repositories. I updated the XFS on-disk format documentation to fix numerous omissions in the second edition and to reflect v5 XFS and the rmap/reflink additions to the filesystem. Since RFCv3, I restructured how bmbt updates get reflected in the rmapbt -- now they're deferred until xfs_bmap_finish time, so that the rmap btree updates obey AG locking order rules to avoid deadlocks. I also fixed numerous minor bookkeeping bugs in the rmapbt and refcountbt code. Lastly, I pulled in Anna Schumaker and Peng Tao's patches hoisting the reflink ioctls into the VFS, added patches to do the same with the dedupe ioctl, and wired up XFS to both of the new VFS operations. The tests have been reworked (I hope) to play more nicely with NFS reflink -- now we simply test the xfs_io reflink or dedupe commands on the test or scratch FS to decide if we're going to run the test, instead of inferring it from FS type. The fiemap checks are gone, replaced with umount, mount, and verifying file contents. xfsprogs hasn't changed much, other than porting kernel-side changes. I will post the xfstests and xfs-documentation patches on the list shortly. I'm holding off on reposting the kernel and xfsprogs patches because I'm still working on fixing CoW and don't really want to blast the mailing lists again until I'm done with that. --D From darrick.wong@oracle.com Wed Nov 11 13:22:51 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 0CD387F5F for ; Wed, 11 Nov 2015 13:22:51 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id DEBDD304032 for ; Wed, 11 Nov 2015 11:22:47 -0800 (PST) X-ASG-Debug-ID: 1447269766-04cb6c296d124fa0001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id LQARVjRN6Ha4YYmv (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 11 Nov 2015 11:22:46 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tABJML5D024565 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 11 Nov 2015 19:22:21 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id tABJMLjf028376 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 11 Nov 2015 19:22:21 GMT Received: from abhmp0012.oracle.com (abhmp0012.oracle.com [141.146.116.18]) by userv0121.oracle.com (8.13.8/8.13.8) with ESMTP id tABJMKQB012603; Wed, 11 Nov 2015 19:22:20 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 11 Nov 2015 11:22:20 -0800 Subject: [RFCv3.1 00/21] xfs-documentation: massive cleanups and add v5 format, reverse-mapping, reflink, and dedupe support From: "Darrick J. Wong" X-ASG-Orig-Subj: [RFCv3.1 00/21] xfs-documentation: massive cleanups and add v5 format, reverse-mapping, reflink, and dedupe support To: hch@infradead.org, david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Wed, 11 Nov 2015 11:22:19 -0800 Message-ID: <20151111192218.14235.13928.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0022.oracle.com [141.146.126.234] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1447269766 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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, UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24309 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines 0.00 BSF_SC5_SA210e Custom Rule SA210e Hi all, This is part of the third revision of an RFC for adding support to XFS for tracking reverse-mappings of physical blocks to file and metadata; and support for mapping multiple file logical blocks to the same physical block, more commonly known as reflinking. This is the first time I've posted patches against the documentation, but they fit with the pending RFCv3 code patches, so they're now a part of the full suite. This patch set does the following: * Cleans up leftover artifacts of the XML -> asciidoc conversion. * Fixes the formatting of quoted text and structure field definitions. * Fixes a lot of the strange wording in the existing documentation. * Replaces the screen dump PNGs with (much smaller) text sections. There's a huge 1.2MB patch to remove the image files as well, but I'll probably just send that privately to Dave later on. * Fills in the missing xfs_db examples and structure field definitions. * Fills in the missing realtime and journal sections. * Covers the new header formats for v5 filesystems. * Adds a magic number index. * Adds a brief overview of what is XFS, prior to jumping into the disk format. * Covers sparse inodes, reverse mapping btrees, reference count btrees and reflink. * Switches the xattr and directory chapters since the directory chapter introduces the btrees that xattrs can use. The patch set is based on the current master branch. As specified eleswhere, I have git trees for the kernel[1], xfsprogs[2], xfstests[3], and xfs-docs[4]. Comments and questions are, as always, welcome. --D [1] https://github.com/djwong/linux/tree/for-dave [2] https://github.com/djwong/xfsprogs/tree/for-dave [3] https://github.com/djwong/xfstests/tree/for-dave [4] https://github.com/djwong/xfs-documentation/tree/for-dave From darrick.wong@oracle.com Wed Nov 11 13:23:00 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 184277F6A for ; Wed, 11 Nov 2015 13:23:00 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id EE3C38F8033 for ; Wed, 11 Nov 2015 11:22:56 -0800 (PST) X-ASG-Debug-ID: 1447269770-04bdf03f02121250001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id gstlzc6Ev3wjzegx (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 11 Nov 2015 11:22:50 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tABJMR0J024699 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 11 Nov 2015 19:22:27 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id tABJMRPE020707 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 11 Nov 2015 19:22:27 GMT Received: from abhmp0007.oracle.com (abhmp0007.oracle.com [141.146.116.13]) by userv0121.oracle.com (8.13.8/8.13.8) with ESMTP id tABJMQdU012652; Wed, 11 Nov 2015 19:22:26 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 11 Nov 2015 11:22:26 -0800 Subject: [PATCH 01/21] xfsdocs: fix asciidoc confusion w.r.t. include file newline at EOF From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 01/21] xfsdocs: fix asciidoc confusion w.r.t. include file newline at EOF To: hch@infradead.org, david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Wed, 11 Nov 2015 11:22:25 -0800 Message-ID: <20151111192225.14235.36980.stgit@birch.djwong.org> In-Reply-To: <20151111192218.14235.13928.stgit@birch.djwong.org> References: <20151111192218.14235.13928.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1447269770 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24309 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Space each include one line apart so that asciidoc knows that each section has ended at included file's EOF. This prevents it from spewing horribly confused XML that blows up xmllint if each included file doesn't itself end with a blank line. Signed-off-by: Darrick J. Wong --- .../xfs_filesystem_structure.asciidoc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/design/XFS_Filesystem_Structure/xfs_filesystem_structure.asciidoc b/design/XFS_Filesystem_Structure/xfs_filesystem_structure.asciidoc index 226bb25..560e549 100644 --- a/design/XFS_Filesystem_Structure/xfs_filesystem_structure.asciidoc +++ b/design/XFS_Filesystem_Structure/xfs_filesystem_structure.asciidoc @@ -36,18 +36,28 @@ Global Structures ================= :leveloffset: 1 + include::allocation_groups.asciidoc[] + include::journaling_log.asciidoc[] + include::internal_inodes.asciidoc[] + :leveloffset: 0 Dynamically Allocated Structures ================================ :leveloffset: 1 + include::ondisk_inode.asciidoc[] + include::data_extents.asciidoc[] + include::extended_attributes.asciidoc[] + include::directories.asciidoc[] + include::symbolic_links.asciidoc[] + :leveloffset: 0 From darrick.wong@oracle.com Wed Nov 11 13:23:06 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 4E9457F5F for ; Wed, 11 Nov 2015 13:23:06 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 3FF358F8035 for ; Wed, 11 Nov 2015 11:23:06 -0800 (PST) X-ASG-Debug-ID: 1447269778-04cb6c296d124fd0001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id mhixg7N0q02FQSsR (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 11 Nov 2015 11:23:00 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tABJMXGA023596 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 11 Nov 2015 19:22:33 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id tABJMXGK016002 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 11 Nov 2015 19:22:33 GMT Received: from abhmp0004.oracle.com (abhmp0004.oracle.com [141.146.116.10]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id tABJMXST013736; Wed, 11 Nov 2015 19:22:33 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 11 Nov 2015 11:22:32 -0800 Subject: [PATCH 02/21] xfsdocs: update book subtitles and headings From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 02/21] xfsdocs: update book subtitles and headings To: hch@infradead.org, david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Wed, 11 Nov 2015 11:22:31 -0800 Message-ID: <20151111192231.14235.80898.stgit@birch.djwong.org> In-Reply-To: <20151111192218.14235.13928.stgit@birch.djwong.org> References: <20151111192218.14235.13928.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1447269779 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24309 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines The current subtitle is redundant and since this is the third edition (the second ed. came out in 2006) we might as well note that. Update some of the headings to make it clear that we're talking about disk format and not much else. Signed-off-by: Darrick J. Wong --- design/XFS_Filesystem_Structure/docinfo.xml | 2 +- .../xfs_filesystem_structure.asciidoc | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/design/XFS_Filesystem_Structure/docinfo.xml b/design/XFS_Filesystem_Structure/docinfo.xml index d56aaed..cb5ffe7 100644 --- a/design/XFS_Filesystem_Structure/docinfo.xml +++ b/design/XFS_Filesystem_Structure/docinfo.xml @@ -1,4 +1,4 @@ -Documentation of the XFS filesystem on-disk structures +3rd Edition This book documents the XFS Filesystem Structure diff --git a/design/XFS_Filesystem_Structure/xfs_filesystem_structure.asciidoc b/design/XFS_Filesystem_Structure/xfs_filesystem_structure.asciidoc index 560e549..a78f3b9 100644 --- a/design/XFS_Filesystem_Structure/xfs_filesystem_structure.asciidoc +++ b/design/XFS_Filesystem_Structure/xfs_filesystem_structure.asciidoc @@ -6,13 +6,13 @@ // and we really need an area to set up various docbook sections like copyright // and legal notice sections. // -XFS Filesystem Structure -======================== +XFS Filesystem Disk Structures +============================== :doctype: book :docinfo1: -Introduction -============ +High Level Design +================= [partintro] -- From darrick.wong@oracle.com Wed Nov 11 13:23:10 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 0AAEC7F78 for ; Wed, 11 Nov 2015 13:23:10 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id A5D2F8F8035 for ; Wed, 11 Nov 2015 11:23:09 -0800 (PST) X-ASG-Debug-ID: 1447269781-04bdf03f03121270001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id Wsf33AhLyf4rJpZi (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 11 Nov 2015 11:23:02 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tABJMdCb024844 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 11 Nov 2015 19:22:40 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id tABJMdVv029070 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 11 Nov 2015 19:22:39 GMT Received: from abhmp0003.oracle.com (abhmp0003.oracle.com [141.146.116.9]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id tABJMd91032243; Wed, 11 Nov 2015 19:22:39 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 11 Nov 2015 11:22:39 -0800 Subject: [PATCH 03/21] xfsdocs: restore the old rendering of structure field definitions From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 03/21] xfsdocs: restore the old rendering of structure field definitions To: hch@infradead.org, david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Wed, 11 Nov 2015 11:22:38 -0800 Message-ID: <20151111192238.14235.56734.stgit@birch.djwong.org> In-Reply-To: <20151111192218.14235.13928.stgit@birch.djwong.org> References: <20151111192218.14235.13928.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0022.oracle.com [141.146.126.234] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1447269782 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24309 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Restore the rendering of the on-disk struct fields to resemble that of the old SGI book, with bold field names on one line and the description indented below. This is a lot more readable than letting the whole field and description run together as one long line. Signed-off-by: Darrick J. Wong --- .../allocation_groups.asciidoc | 136 ++++++++++---------- .../XFS_Filesystem_Structure/common_types.asciidoc | 28 ++-- .../internal_inodes.asciidoc | 38 +++--- .../XFS_Filesystem_Structure/ondisk_inode.asciidoc | 50 ++++--- 4 files changed, 126 insertions(+), 126 deletions(-) diff --git a/design/XFS_Filesystem_Structure/allocation_groups.asciidoc b/design/XFS_Filesystem_Structure/allocation_groups.asciidoc index a3721c2..afbbb67 100644 --- a/design/XFS_Filesystem_Structure/allocation_groups.asciidoc +++ b/design/XFS_Filesystem_Structure/allocation_groups.asciidoc @@ -92,59 +92,59 @@ struct xfs_sb __uint32_t sb_features2; }; ---- -.sb_magicnum +*sb_magicnum*:: Identifies the filesystem. It's value is +XFS_SB_MAGIC = 0x58465342 "XFSB"+. -.sb_blocksize +*sb_blocksize*:: The size of a basic unit of space allocation in bytes. Typically, this is 4096 (4KB) but can range from 512 to 65536 bytes. -.sb_dblocks +*sb_dblocks*:: Total number of blocks available for data and metadata on the filesystem. -.sb_rblocks +*sb_rblocks*:: Number blocks in the real-time disk device. Refer to xref:Real-time_Devices[real-time sub-volumes] for more information. -.sb_rextents +*sb_rextents*:: Number of extents on the real-time device. -.sb_uuid +*sb_uuid*:: UUID (Universally Unique ID) for the filesystem. Filesystems can be mounted by the UUID instead of device name. -.sb_logstart +*sb_logstart*:: First block number for the journaling log if the log is internal (ie. not on a separate disk device). For an external log device, this will be zero (the log will also start on the first block on the log device). -.sb_rootino +*sb_rootino*:: Root inode number for the filesystem. Typically, this is 128 when using a 4KB block size. -.sb_rbmino +*sb_rbmino*:: Bitmap inode for real-time extents. -.sb_rsumino +*sb_rsumino*:: Summary inode for real-time bitmap. -.sb_rextsize +*sb_rextsize*:: Realtime extent size in blocks. -.sb_agblocks +*sb_agblocks*:: Size of each AG in blocks. For the actual size of the last AG, refer to the xref:AG_Free_Space_Management[free space] +agf_length+ value. -.sb_agcount +*sb_agcount*:: Number of AGs in the filesystem. -.sb_rbmblocks +*sb_rbmblocks*:: Number of real-time bitmap blocks. -.sb_logblocks +*sb_logblocks*:: Number of blocks for the journaling log. -.sb_versionnum +*sb_versionnum*:: Filesystem version number. This is a bitmask specifying the features enabled when creating the filesystem. Any disk checking tools or drivers that do not recognize any set bits must not operate upon the filesystem. Most of the flagsi @@ -174,72 +174,72 @@ Version 2 directories are used. This is always set. Set if the sb_features2 field in the superblock contains more flags. |===== -.sb_sectsize +*sb_sectsize*:: Specifies the underlying disk sector size in bytes. Majority of the time, this is 512 bytes. This determines the minimum I/O alignment including Direct I/O. -.sb_inodesize +*sb_inodesize*:: Size of the inode in bytes. The default is 256 (2 inodes per standard sector) but can be made as large as 2048 bytes when creating the filesystem. -.sb_inopblock +*sb_inopblock*:: Number of inodes per block. This is equivalent to +sb_blocksize / sb_inodesize+. -.sb_fname[12] +*sb_fname[12]*:: Name for the filesystem. This value can be used in the mount command. -.sb_blocklog +*sb_blocklog*:: log~2~ value of +sb_blocksize+. In other terms, +sb_blocksize = 2^sb_blocklog^+. -.sb_sectlog +*sb_sectlog*:: log~2~ value of +sb_sectsize+. -.sb_inodelog +*sb_inodelog*:: log~2~ value of +sb_inodesize+. -.sb_inopblog +*sb_inopblog*:: log~2~ value of +sb_inopblock+. -.sb_agblklog +*sb_agblklog*:: log~2~ value of +sb_agblocks+ (rounded up). This value is used to generate inode numbers and absolute block numbers defined in extent maps. -.sb_rextslog +*sb_rextslog*:: log~2~ value of +sb_rextents+. -.sb_inprogress +*sb_inprogress*:: Flag specifying that the filesystem is being created. -.sb_imax_pct +*sb_imax_pct*:: Maximum percentage of filesystem space that can be used for inodes. The default value is 5%. -.sb_icount +*sb_icount*:: Global count for number inodes allocated on the filesystem. This is only maintained in the first superblock. -.sb_ifree +*sb_ifree*:: Global count of free inodes on the filesystem. This is only maintained in the first superblock. -.sb_fdblocks +*sb_fdblocks*:: Global count of free data blocks on the filesystem. This is only maintained in the first superblock. -.sb_frextents +*sb_frextents*:: Global count of free real-time extents on the filesystem. This is only maintained in the first superblock. -.sb_uquotino +*sb_uquotino*:: Inode for user quotas. This and the following two quota fields only apply if +XFS_SB_VERSION_QUOTABIT+ flag is set in +sb_versionnum+. Refer to xref:Quota_Inodes[quota inodes] for more information -.sb_gquotino +*sb_gquotino*:: Inode for group or project quotas. Group and Project quotas cannot be used at the same time. -.sb_qflags +*sb_qflags*:: Quota flags. It can be a combination of the following flags: .Superblock quota flags @@ -255,37 +255,37 @@ Quota flags. It can be a combination of the following flags: | +XFS_GQUOTA_ACCT+ | Group quota accounting is enabled. |===== -.sb_flags +*sb_flags*:: Miscellaneous flags. -.sb_shared_vn +*sb_shared_vn*:: Reserved and must be zero ("vn" stands for version number). -.sb_inoalignmt +*sb_inoalignmt*:: Inode chunk alignment in fsblocks. -.sb_unit +*sb_unit*:: Underlying stripe or raid unit in blocks. -.sb_width +*sb_width*:: Underlying stripe or raid width in blocks. -.sb_dirblklog +*sb_dirblklog*:: log~2~ multiplier that determines the granularity of directory block allocations in fsblocks. -.sb_logsectlog +*sb_logsectlog*:: log~2~ value of the log subvolume's sector size. This is only used if the journaling log is on a separate disk device (i.e. not internal). -.sb_logsectsize +*sb_logsectsize*:: The log's sector size in bytes if the filesystem uses an external log device. -.sb_logsunit +*sb_logsunit*:: The log device's stripe or raid unit size. This only applies to version 2 logs +XFS_SB_VERSION_LOGV2BIT+ is set in +sb_versionnum+. -.sb_features2 +*sb_features2*:: Additional version flags if +XFS_SB_VERSION_MOREBITSBIT+ is set in +sb_versionnum+. The currently defined additional features include: @@ -417,45 +417,45 @@ struct xfs_agf { The rest of the bytes in the sector are zeroed. +XFS_BTNUM_AGF+ is set to 2, index 0 for the count B+tree and index 1 for the size B+tree. -.agf_magicnum +*agf_magicnum*:: Specifies the magic number for the AGF sector: "XAGF" (0x58414746). -.agf_versionnum +*agf_versionnum*:: Set to +XFS_AGF_VERSION+ which is currently 1. -.agf_seqno +*agf_seqno*:: Specifies the AG number for the sector. -.agf_length +*agf_length*:: Specifies the size of the AG in filesystem blocks. For all AGs except the last, This must be equal to the superblock's +sb_agblocks+ value. For the last AG, this could be less than the +sb_agblocks+ value. It is this value that should be used to determine the size of the AG. -.agf_roots +*agf_roots*:: Specifies the block number for the root of the two free space B+trees. -.agf_levels +*agf_levels*:: Specifies the level or depth of the two free space B+trees. For a fresh AG, this will be one, and the "roots" will point to a single leaf of level 0. -.agf_flfirst +*agf_flfirst*:: Specifies the index of the first "free list" block. Free lists are covered in more detail later on. -.agf_fllast +*agf_fllast*:: Specifies the index of the last "free list" block. -.agf_flcount +*agf_flcount*:: Specifies the number of blocks in the "free list". -.agf_freeblks +*agf_freeblks*:: Specifies the current number of free blocks in the AG. -.agf_longest +*agf_longest*:: Specifies the number of blocks of longest contiguous free space in the AG. -.agf_btreeblks +*agf_btreeblks*:: Specifies the number of blocks used for the free space B+trees. This is only used if the +XFS_SB_VERSION2_LAZYSBCOUNTBIT+ bit is set in +sb_features2+. @@ -688,37 +688,37 @@ struct xfs_agi { __be32 agi_unlinked[64]; } ---- -.agi_magicnum +*agi_magicnum*:: Specifies the magic number for the AGI sector: "XAGI" (0x58414749). -.agi_versionnum +*agi_versionnum*:: Set to +XFS_AGI_VERSION+ which is currently 1. -.agi_seqno +*agi_seqno*:: Specifies the AG number for the sector. -.agi_length +*agi_length*:: Specifies the size of the AG in filesystem blocks. -.agi_count +*agi_count*:: Specifies the number of inodes allocated for the AG. -.agi_root +*agi_root*:: Specifies the block number in the AG containing the root of the inode B+tree. -.agi_level +*agi_level*:: Specifies the number of levels in the inode B+tree. -.agi_freecount +*agi_freecount*:: Specifies the number of free inodes in the AG. -.agi_newino +*agi_newino*:: Specifies AG relative inode number most recently allocated. -.agi_dirino +*agi_dirino*:: Deprecated and not used, it's always set to NULL (-1). -.agi_unlinked[64] +*agi_unlinked[64]*:: Hash table of unlinked (deleted) inodes that are still being referenced. Refer to xref:Unlinked_Pointer[unlinked list pointers] for more information. diff --git a/design/XFS_Filesystem_Structure/common_types.asciidoc b/design/XFS_Filesystem_Structure/common_types.asciidoc index 5b52271..ea2d21f 100644 --- a/design/XFS_Filesystem_Structure/common_types.asciidoc +++ b/design/XFS_Filesystem_Structure/common_types.asciidoc @@ -3,47 +3,47 @@ All the following XFS types can be found in xfs_types.h. NULL values are always -1 on disk (ie. all bits for the value set to one). -.xfs_ino_t +*xfs_ino_t*:: Unsigned 64 bit absolute xref:Inode_Numbers[inode number]. -.xfs_off_t +*xfs_off_t*:: Signed 64 bit file offset. -.xfs_daddr_t +*xfs_daddr_t*:: Signed 64 bit disk address. -.xfs_agnumber_t +*xfs_agnumber_t*:: Unsigned 32 bit xref:Allocation_Groups[AG number]. -.xfs_agblock_t +*xfs_agblock_t*:: Unsigned 32 bit AG relative block number. -.xfs_extlen_t +*xfs_extlen_t*:: Unsigned 32 bit xref:Data_Extents[extent] length in blocks. -.xfs_extnum_t +*xfs_extnum_t*:: Signed 32 bit number of extents in a file. -.xfs_dablk_t +*xfs_dablk_t*:: Unsigned 32 bit block number for xref:Directories[directories] and xref:Extended_Attributes[extended attributes]. -.xfs_dahash_t +*xfs_dahash_t*:: Unsigned 32 bit hash of a directory file name or extended attribute name. -.xfs_dfsbno_t +*xfs_dfsbno_t*:: Unsigned 64 bit filesystem block number combining xref:Allocation_Groups[AG number] and block offset into the AG. -.xfs_drfsbno_t +*xfs_drfsbno_t*:: Unsigned 64 bit raw filesystem block number. -.xfs_drtbno_t +*xfs_drtbno_t*:: Unsigned 64 bit extent number in the xref:Real-time_Devices[real-time] sub-volume. -.xfs_dfiloff_t +*xfs_dfiloff_t*:: Unsigned 64 bit block offset into a file. -.xfs_dfilblks_t +*xfs_dfilblks_t*:: Unsigned 64 bit block count for a file. diff --git a/design/XFS_Filesystem_Structure/internal_inodes.asciidoc b/design/XFS_Filesystem_Structure/internal_inodes.asciidoc index c3a3510..b69bea2 100644 --- a/design/XFS_Filesystem_Structure/internal_inodes.asciidoc +++ b/design/XFS_Filesystem_Structure/internal_inodes.asciidoc @@ -62,14 +62,14 @@ struct xfs_dqblk { }; ---- -.d_magic +*d_magic*:: Specifies the signature where these two bytes are 0x4451 (+XFS_DQUOT_MAGIC+), or "DQ" in ASCII. -.d_version +*d_version*:: Specifies the structure version, currently this is one (+XFS_DQUOT_VERSION+). -.d_flags +*d_flags*:: Specifies which type of ID the structure applies to: [source, c] @@ -79,71 +79,71 @@ Specifies which type of ID the structure applies to: #define XFS_DQ_GROUP 0x0004 ---- -.d_id +*d_id*:: The ID for the quota structure. This will be a uid, gid or projid based on the value of +d_flags+. -.d_blk_hardlimit +*d_blk_hardlimit*:: Specifies the hard limit for the number of filesystem blocks the ID can own. The ID will not be able to use more space than this limit. If it is attempted, +ENOSPC+ will be returned. -.d_blk_softlimit +*d_blk_softlimit*:: Specifies the soft limit for the number of filesystem blocks the ID can own. The ID can temporarily use more space than by +d_blk_softlimit+ up to +d_blk_hardlimit+. If the space is not freed by the time limit specified by ID zero's +d_btimer+ value, the ID will be denied more space until the total blocks owned goes below +d_blk_softlimit+. -.d_ino_hardlimit +*d_ino_hardlimit*:: Specifies the hard limit for the number of inodes the ID can own. The ID will not be able to create or own any more inodes if +d_icount+ reaches this value. -.d_ino_softlimit +*d_ino_softlimit*:: Specifies the soft limit for the number of inodes the ID can own. The ID can temporarily create or own more inodes than specified by d_ino_softlimit up to d_ino_hardlimit. If the inode count is not reduced by the time limit specified by ID zero's d_itimer value, the ID will be denied from creating or owning more inodes until the count goes below d_ino_softlimit. -.d_bcount +*d_bcount*:: Specifies how many filesystem blocks are actually owned by the ID. -.d_icount +*d_icount*:: Specifies how many inodes are actually owned by the ID. -.d_itimer +*d_itimer*:: Specifies the time when the ID's +d_icount+ exceeded +d_ino_softlimit+. The soft limit will turn into a hard limit after the elapsed time exceeds ID zero's +d_itimer+ value. When d_icount goes back below +d_ino_softlimit+, +d_itimer+ is reset back to zero. -.d_btimer +*d_btimer*:: Specifies the time when the ID's +d_bcount+ exceeded +d_blk_softlimit+. The soft limit will turn into a hard limit after the elapsed time exceeds ID zero's +d_btimer+ value. When d_bcount goes back below +d_blk_softlimit+, +d_btimer+ is reset back to zero. -.d_iwarns -.d_bwarns -.d_rtbwarns +*d_iwarns*:: +*d_bwarns*:: +*d_rtbwarns*:: Specifies how many times a warning has been issued. Currently not used. -.d_rtb_hardlimit +*d_rtb_hardlimit*:: Specifies the hard limit for the number of real-time blocks the ID can own. The ID cannot own more space on the real-time subvolume beyond this limit. -.d_rtb_softlimit +*d_rtb_softlimit*:: Specifies the soft limit for the number of real-time blocks the ID can own. The ID can temporarily own more space than specified by +d_rtb_softlimit+ up to +d_rtb_hardlimit+. If +d_rtbcount+ is not reduced by the time limit specified by ID zero's +d_rtbtimer value+, the ID will be denied from owning more space until the count goes below +d_rtb_softlimit+. -.d_rtbcount +*d_rtbcount*:: Specifies how many real-time blocks are currently owned by the ID. -.d_rtbtimer +*d_rtbtimer*:: Specifies the time when the ID's +d_rtbcount+ exceeded +d_rtb_softlimit+. The soft limit will turn into a hard limit after the elapsed time exceeds ID zero's +d_rtbtimer+ value. When +d_rtbcount+ goes back below +d_rtb_softlimit+, diff --git a/design/XFS_Filesystem_Structure/ondisk_inode.asciidoc b/design/XFS_Filesystem_Structure/ondisk_inode.asciidoc index 017f607..dfdcc32 100644 --- a/design/XFS_Filesystem_Structure/ondisk_inode.asciidoc +++ b/design/XFS_Filesystem_Structure/ondisk_inode.asciidoc @@ -101,20 +101,20 @@ struct xfs_dinode_core { }; ---- -.di_magic +*di_magic*:: The inode signature where these two bytes are 0x494e, or "IN" in ASCII. -.di_mode +*di_mode*:: Specifies the mode access bits and type of file using the standard S_Ixxx values defined in stat.h. -.di_version +*di_version*:: Specifies the inode version which currently can only be 1 or 2. The inode version specifies the usage of the +di_onlink+, +di_nlink+ and +di_projid+ values in the inode core. Initially, inodes are created as v1 but can be converted on the fly to v2 when required. -.di_format +*di_format*:: Specifies the format of the data fork in conjunction with the +di_mode+ type. This can be one of several values. For directories and links, it can be "local" @@ -137,34 +137,34 @@ typedef enum xfs_dinode_fmt { } xfs_dinode_fmt_t; ---- -.di_onlink +*di_onlink*:: In v1 inodes, this specifies the number of links to the inode from directories. When the number exceeds 65535, the inode is converted to v2 and the link count is stored in +di_nlink+. -.di_uid +*di_uid*:: Specifies the owner's UID of the inode. -.di_gid +*di_gid*:: Specifies the owner's GID of the inode. -.di_nlink +*di_nlink*:: Specifies the number of links to the inode from directories. This is maintained for both inode versions for current versions of XFS. Old versions of XFS did not support v2 inodes, and therefore this value was never updated and was classed as reserved space (part of +di_pad+). -.di_projid +*di_projid*:: Specifies the owner's project ID in v2 inodes. An inode is converted to v2 if the project ID is set. This value must be zero for v1 inodes. -.di_pad[8] +*di_pad[8]*:: Reserved, must be zero. -.di_flushiter +*di_flushiter*:: Incremented on flush. -.di_atime +*di_atime*:: Specifies the last access time of the files using UNIX time conventions the following structure. This value maybe undefined if the filesystem is mounted @@ -178,24 +178,24 @@ struct xfs_timestamp { }; ---- -.di_mtime +*di_mtime*:: Specifies the last time the file was modified. -.di_ctime +*di_ctime*:: Specifies when the inode's status was last changed. -.di_size +*di_size*:: Specifies the EOF of the inode in bytes. This can be larger or smaller than the extent space (therefore actual disk space) used for the inode. For regular files, this is the filesize in bytes, directories, the space taken by directory entries and for links, the length of the symlink. -.di_nblocks +*di_nblocks*:: Specifies the number of filesystem blocks used to store the inode's data including relevant metadata like B+trees. This does not include blocks used for extended attributes. -.di_extsize +*di_extsize*:: Specifies the extent size for filesystems with real-time devices and an extent size hint for standard filesystems. For normal filesystems, and with directories, the +XFS_DIFLAG_EXTSZINHERIT+ flag must be set in +di_flags+ if @@ -204,13 +204,13 @@ di_extsize value and have +XFS_DIFLAG_EXTSIZE+ set in their +di_flags+. When a file is written to beyond allocated space, XFS will attempt to allocate additional disk space based on this value. -.di_nextents +*di_nextents*:: Specifies the number of data extents associated with this inode. -.di_anextents +*di_anextents*:: Specifies the number of extended attribute extents associated with this inode. -.di_forkoff +*di_forkoff*:: Specifies the offset into the inode's literal area where the extended attribute fork starts. This is an 8-bit value that is multiplied by 8 to determine the actual offset in bytes (ie. attribute data is 64-bit aligned). This also limits @@ -220,19 +220,19 @@ an extended attribute is created. When in attribute is added, the nature of Refer to xref:Extended_Attribute_Versions[Extended Attribute Versions] for more details. -.di_aformat +*di_aformat*:: Specifies the format of the attribute fork. This uses the same values as +di_format+, but restricted to "local", "extents" and "btree" formats for extended attribute data. -.di_dmevmask +*di_dmevmask*:: DMAPI event mask. -.di_dmstate +*di_dmstate*:: DMAPI state. -.di_flags +*di_flags*:: Specifies flags associated with the inode. This can be a combination of the following values: @@ -271,7 +271,7 @@ Specifies the inode is to be ignored when defragmenting the filesystem. |===== -.di_gen +*di_gen*:: A generation number used for inode identification. This is used by tools that do inode scanning such as backup tools and xfsdump. An inode's generation number can change by unlinking and creating a new file that reuses the inode. From darrick.wong@oracle.com Wed Nov 11 13:23:13 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id C40D47F81 for ; Wed, 11 Nov 2015 13:23:13 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 42F47AC001 for ; Wed, 11 Nov 2015 11:23:10 -0800 (PST) X-ASG-Debug-ID: 1447269788-04cbb0242212cc40001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id hCLLZeQQ93m54DDS (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 11 Nov 2015 11:23:08 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tABJMkSm023827 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 11 Nov 2015 19:22:46 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id tABJMk5Q010463 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 11 Nov 2015 19:22:46 GMT Received: from abhmp0017.oracle.com (abhmp0017.oracle.com [141.146.116.23]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id tABJMjQ6032325; Wed, 11 Nov 2015 19:22:46 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 11 Nov 2015 11:22:45 -0800 Subject: [PATCH 04/21] xfsdocs: convert html entities to regular characters From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 04/21] xfsdocs: convert html entities to regular characters To: hch@infradead.org, david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Wed, 11 Nov 2015 11:22:44 -0800 Message-ID: <20151111192244.14235.27865.stgit@birch.djwong.org> In-Reply-To: <20151111192218.14235.13928.stgit@birch.djwong.org> References: <20151111192218.14235.13928.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0021.oracle.com [156.151.31.71] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1447269788 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24309 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Convert HTML entities back to regular characters, since this is now ASCII. Signed-off-by: Darrick J. Wong --- .../XFS_Filesystem_Structure/directories.asciidoc | 20 ++++++++++---------- .../extended_attributes.asciidoc | 14 +++++++------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/design/XFS_Filesystem_Structure/directories.asciidoc b/design/XFS_Filesystem_Structure/directories.asciidoc index 98143f7..76d5df7 100644 --- a/design/XFS_Filesystem_Structure/directories.asciidoc +++ b/design/XFS_Filesystem_Structure/directories.asciidoc @@ -321,8 +321,8 @@ blocksize = 4096 ... dirblklog = 0 ... -xfs_db> inode <inode#> -xfs_db> p +xfs_db> inode +xfs_db> p core.magic = 0x494e core.mode = 040755 core.version = 1 @@ -694,9 +694,9 @@ And the last data block: ---- -xfs_db> dblock 2 -xfs_db> type dir2 -xfs_db> p +xfs_db> dblock 2 +xfs_db> type dir2 +xfs_db> p dhdr.magic = 0x58443244 dhdr.bestfree[0].offset = 0x70 dhdr.bestfree[0].length = 0xf90 @@ -892,8 +892,8 @@ blocksize = 4096 ... dirblklog = 2 ... -xfs_db> inode <inode#> -xfs_db> p +xfs_db> inode +xfs_db> p core.magic = 0x494e core.mode = 040755 core.version = 1 @@ -1101,9 +1101,9 @@ u.bmbt.level = 1 u.bmbt.numrecs = 1 u.bmbt.keys[1] = [startoff] 1:[0] u.bmbt.ptrs[1] = 1:89 -xfs_db> fsblock 89 -xfs_db> type bmapbtd -xfs_db> p +xfs_db> fsblock 89 +xfs_db> type bmapbtd +xfs_db> p magic = 0x424d4150 level = 0 numrecs = 234 diff --git a/design/XFS_Filesystem_Structure/extended_attributes.asciidoc b/design/XFS_Filesystem_Structure/extended_attributes.asciidoc index 9887332..8b32bdf 100644 --- a/design/XFS_Filesystem_Structure/extended_attributes.asciidoc +++ b/design/XFS_Filesystem_Structure/extended_attributes.asciidoc @@ -355,8 +355,8 @@ core.aformat = 2 (extents) ... a.bmx[0] = [startoff,startblock,blockcount,extentflag] 0:[0,37535,9,0] -xfs_db> ablock 0 -xfs_db> p +xfs_db> ablock 0 +xfs_db> p hdr.info.forw = 0 hdr.info.back = 0 hdr.info.magic = 0xfbee @@ -580,9 +580,9 @@ rightsib = 109968 recs[1-127] = [startoff,startblock,blockcount,extentflag] 1:[0,81870,1,0] ... -xfs_db> fsblock 109968 -xfs_db> type bmapbtd -xfs_db> p +xfs_db> fsblock 109968 +xfs_db> type bmapbtd +xfs_db> p magic = 0x424d4150 level = 0 numrecs = 147 @@ -591,8 +591,8 @@ rightsib = null recs[1-147] = [startoff,startblock,blockcount,extentflag] ... (which is fsblock 81870) -xfs_db> ablock 0 -xfs_db> p +xfs_db> ablock 0 +xfs_db> p hdr.info.forw = 0 hdr.info.back = 0 hdr.info.magic = 0xfebe From darrick.wong@oracle.com Wed Nov 11 13:23:20 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id DFF9F7F8B for ; Wed, 11 Nov 2015 13:23:19 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 47BB3AC001 for ; Wed, 11 Nov 2015 11:23:19 -0800 (PST) X-ASG-Debug-ID: 1447269796-04cb6c296d125000001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id mWHzVD2w8puBaAs6 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 11 Nov 2015 11:23:16 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tABJMrjF025068 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 11 Nov 2015 19:22:53 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id tABJMqmo021765 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 11 Nov 2015 19:22:52 GMT Received: from abhmp0006.oracle.com (abhmp0006.oracle.com [141.146.116.12]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id tABJMqEj017900; Wed, 11 Nov 2015 19:22:52 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 11 Nov 2015 11:22:52 -0800 Subject: [PATCH 05/21] xfsdocs: convert images to text From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 05/21] xfsdocs: convert images to text To: hch@infradead.org, david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Wed, 11 Nov 2015 11:22:51 -0800 Message-ID: <20151111192250.14235.57607.stgit@birch.djwong.org> In-Reply-To: <20151111192218.14235.13928.stgit@birch.djwong.org> References: <20151111192218.14235.13928.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1447269796 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24309 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Convert images that are purely screenshots of xfs_db sessions to text, to reduce the document size and format better. Signed-off-by: Darrick J. Wong --- .../XFS_Filesystem_Structure/data_extents.asciidoc | 37 ++++- .../XFS_Filesystem_Structure/directories.asciidoc | 65 +++++++- .../extended_attributes.asciidoc | 161 ++++++++++++++++++-- .../symbolic_links.asciidoc | 15 ++ 4 files changed, 251 insertions(+), 27 deletions(-) diff --git a/design/XFS_Filesystem_Structure/data_extents.asciidoc b/design/XFS_Filesystem_Structure/data_extents.asciidoc index d7f51e4..b71bc52 100644 --- a/design/XFS_Filesystem_Structure/data_extents.asciidoc +++ b/design/XFS_Filesystem_Structure/data_extents.asciidoc @@ -132,14 +132,43 @@ u.bmx[0-2] = [startoff,startblock,blockcount,extentflag] Raw disk version of the inode with the third extent highlighted (+di_u+ always starts at offset 0x64): -.Raw inode contents with extents -image::images/code/33a.png[] +[subs="quotes"] +---- +xfs_db> type text +xfs_db> p +00: 49 4e 81 a4 01 02 00 01 00 00 00 00 00 00 00 00 IN.............. +10: 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 01 ................ +20: 44 b6 88 dd 2f 8a ed d0 44 b6 88 f7 10 8c 5b de D.......D....... +30: 44 b6 88 f7 10 8c 5b d0 00 00 00 00 01 7b b0 00 D............... +40: 00 00 00 00 00 00 17 bb 00 00 00 00 00 00 00 03 ................ +50: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 00 ................ +60: ff ff ff ff 00 00 00 00 00 00 00 00 00 00 00 0d ................ +70: 5e a0 07 e9 00 00 00 00 00 0f d2 00 00 00 00 0f ................ +80: 58 e0 07 e9 *00 00 00 00 00 1f a4 00 00 00 00 11 X............... +90: 53 20 07 e9* 00 00 00 00 00 00 00 00 00 00 00 00 S............... +a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +be: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +co: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +do: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +fo: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +---- We can expand the highlighted section into the following bit array from MSB to LSB with the file offset and the block count highlighted: -.Encoded extent -image::images/code/33b.png[] +[subs="quotes"] +---- +127-96: 0**000 0000 0000 0000 0000 0000 0000 0000** + 95-64: **0000 0000 0001 1111 1010 010**0 0000 0000 + 63-32: 0000 0000 0000 0000 0000 0000 0000 1111 + 31-0 : 0101 1000 111**0 0000 0000 0111 1110 1001** + +Grouping by highlights we get: + file offset = 0x0fd2 (4050) + start block = 0x7ac7 (31431) + block count = 0x07e9 (2025) +---- A 4MB file with two extents and a hole in the middle, the first extent containing 64KB of data, the second about 4MB in containing 32KB (+write+ 64KB, diff --git a/design/XFS_Filesystem_Structure/directories.asciidoc b/design/XFS_Filesystem_Structure/directories.asciidoc index 76d5df7..beabe20 100644 --- a/design/XFS_Filesystem_Structure/directories.asciidoc +++ b/design/XFS_Filesystem_Structure/directories.asciidoc @@ -149,8 +149,24 @@ u.sfdir2.list[3].inumber.i4 = 25165956 The raw data on disk with the first entry highlighted. The six byte header precedes the first entry: -.Shortform Directory entry detail -image::images/code/40.png[] +[subs="quotes"] +---- +xfs_db> type text +xfs_db> p +00: 49 4e 41 ed 01 01 00 02 00 00 00 00 00 00 00 00 INA............. +10: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 02 ................ +20: 44 ad 3a 83 1d a9 4a d0 44 ad 3a ab 0b c7 a7 d0 D.....J.D....... +30: 44 ad 3a ab 0b c7 a7 d0 00 00 00 00 00 00 00 5e D............... +40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +50: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 00 ................ +60: ff ff ff ff 04 00 00 00 00 80 *0f 00 30 66 72 61* ............0fra +70: *6d 65 30 30 30 30 30 30 2e 74 73 74 01 80 00 81* me000000.tst.... +80: 0f 00 50 66 72 61 6d 65 30 30 30 30 30 31 2e 74 ..Pframe000001.t +90: 73 74 01 80 00 82 0f 00 70 66 72 61 6d 65 30 30 st......pframe00 +a0: 30 30 30 32 2e 74 73 74 01 80 00 83 0f 00 90 66 0002.tst........ +b0: 72 61 6d 65 30 30 30 30 30 33 2e 74 73 74 01 80 rame000003.tst.. +cO: 00 84 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +---- Next, an entry is deleted (frame000001.tst), and any entries after the deleted entry are moved or compacted to "cover" the hole: @@ -479,8 +495,21 @@ and the length of the space. The tag remains intact at the +offset+length - sizeof(tag)+. The address for the hash is also cleared. The affected areas are highlighted below: -.Block directory free entry detail -image::images/code/46.png[] +[subs="quotes"] +---- +090: 00 00 00 00 02 00 00 84 0f 66 72 61 6d 65 30 30 ..........frame00 +0a0: 30 30 30 33 2e 74 73 74 00 00 00 00 00 00 00 90 0003.tst......... +0b0: *ff ff 00 20* 02 00 00 85 0f 66 72 61 6d 65 30 30 ..........frame00 +0c0: 30 30 30 34 2e 74 73 74 00 00 00 00 *00 00 00 b0* 0004.tst......... +0d0: 00 00 00 00 02 00 00 86 0f 66 72 61 6d 65 30 30 ..........frame00 +0e0: 30 30 30 35 2e 74 73 74 00 00 00 00 00 00 00 0d 0005.tst......... +... +fb0: 00 00 17 2e 00 00 00 04 83 a0 40 b4 00 00 00 0e ................. +fc0: 93 a0 40 b4 00 00 00 12 a3 a0 40 b4 00 00 00 06 ................. +fd0: b3 a0 40 b4 00 00 00 0a c3 a0 40 b4 00 00 00 1e ................. +fe0: d3 a0 40 b4 00 00 00 22 e3 a0 40 b4 *00 00 00 00* ................. +ff0: f3 a0 40 b4 00 00 00 1a 00 00 00 0a *00 00 00 01* ................. +---- @@ -1049,8 +1078,13 @@ block's +bestfree[0].length+ value. The raw disk layout, old data is not cleared after the array. The fbests array is highlighted: -.Node directory freespace detail -image::images/code/57.png[] +[subs="quotes"] +---- +xfs_db> type text +xfs_db> p +000: 58 44 32 46 00 00 00 00 00 00 00 05 00 00 00 05 XD2F............ +010: *00 10 00 10 00 10 00 10 3f 50* 00 00 1f 01 ff ff .........P...... +---- TODO: Example with a hole in the middle @@ -1188,6 +1222,21 @@ The leaves at each the end of a node always point to the end leaves in adjacent nodes. Directory block 8388928 forward pointer is to block 8388919, and vice versa as highlighted in the following example: -.B+tree directory pointer detail -image::images/code/60.png[] +[subs="quotes"] +---- +xfs_db> dblock 8388928 +xfs_db> type dir2 +xfs_db> p +lhdr.info.forw = *8388919* +lhdr.info.back = 8388937 +lhdr.info.magic = 0xd2ff +... +xfs_db> dblock 8388919 +xfs_db> type dir2 +xfs_db> p +lhdr.info.forw = 8388706 +lhdr.info.back = *8388928* +lhdr.info.magic = 0xd2ff +... +---- diff --git a/design/XFS_Filesystem_Structure/extended_attributes.asciidoc b/design/XFS_Filesystem_Structure/extended_attributes.asciidoc index 8b32bdf..51f7ff7 100644 --- a/design/XFS_Filesystem_Structure/extended_attributes.asciidoc +++ b/design/XFS_Filesystem_Structure/extended_attributes.asciidoc @@ -128,8 +128,27 @@ a.sfattr.list[1].value = "val1" We can determine the actual inode offset to be 220 (15 x 8 + 100) or +0xdc+. Examining the raw dump, the second attribute is highlighted: -.Shortform Attribute detail -image::images/code/65.png[] +[subs="quotes"] +---- +xfs_db> type text +xfs_db> p +09: 49 4e 81 a4 01 02 00 01 00 00 00 00 00 00 00 00 IN.............. +10: 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 02 ................ +20: 44 be 19 be 38 d1 26 98 44 be 1a be 38 d1 26 98 D...8...D...8... +30: 44 be 1a e1 3a 9a ea 18 00 00 00 00 00 00 00 04 D............... +40: 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 01 ................ +50: 00 00 0f 01 00 00 00 00 00 00 00 00 00 00 00 00 ................ +60: ff ff ff ff 00 00 00 00 00 00 00 00 00 00 00 12 ................ +70: 53 a0 00 01 00 00 00 00 00 00 00 00 00 00 00 00 ................ +80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +d0: 00 00 00 00 00 00 00 00 00 00 00 00 *00 18* 02 00 ................ <-- hdr.totsize = 0x18 +e0: 05 00 00 65 6d 70 74 79 *05 04 02 74 72 75 73 74* ...empty...trust +f0: *76 61 6c 31* 00 00 00 00 00 00 00 00 00 00 00 00 val1............ +---- Adding another attribute with attr1, the format is converted to extents and +di_forkoff+ remains unchanged (and all those zeros in the dump above remain @@ -192,8 +211,34 @@ a.sfattr.list[1].value = "val1" Another attribute is added: -.Shortform Multiple Attribute detail -image::images/code/66.png[] +[subs="quotes"] +---- +xfs_db> p +... +core.naextents = 0 +*core.forkoff = 13* +core.aformat = 1 (local) +... +a.sfattr.hdr.totsize = 52 +a.sfattr.hdr.count = 3 +a.sfattr.list[0].namelen = 10 +a.sfattr.list[0].valuelen = 0 +a.sfattr.list[0].root = 0 +a.sfattr.list[0].secure = 0 +a.sfattr.list[0].name = "empty_attr" +a.sfattr.list[1].namelen = 7 +a.sfattr.list[1].valuelen = 4 +a.sfattr.list[1].root = 1 +a.sfattr.list[1].secure = 0 +a.sfattr.list[1].name = "trust_a" +a.sfattr.list[1].value = "val1" +a.sfattr.list[2].namelen = 6 +a.sfattr.list[2].valuelen = 12 +a.sfattr.list[2].root = 0 +a.sfattr.list[2].secure = 0 +a.sfattr.list[2].name = "second" +a.sfattr.list[2].value = "second_value" +---- One more is added: @@ -233,8 +278,27 @@ a.sfattr.list[3].value = "contents" A raw dump is shown to compare with the attr1 dump on a prior page, the header is highlighted: -.Shortform attribute header detail -image::images/code/67.png[] +[subs="quotes"] +---- +xfs_db> type text +xfs_db> p +00: 49 4e 81 a4 01 02 00 01 00 00 00 00 00 00 00 00 IN.............. +10: 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 05 ................ +20: 44 be 24 cd 0f b0 96 18 44 be 24 cd 0f b0 96 18 D.......D....... +30: 44 be 2d f5 01 62 7a 18 00 00 00 00 00 00 00 04 D....bz......... +40: 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 01 ................ +50: 00 00 0a 01 00 00 00 00 00 00 00 00 00 00 00 00 ................ +60: ff ff ff ff 00 00 00 00 00 00 00 00 00 00 00 01 ................ +70: 41 c0 00 01 00 00 00 00 00 00 00 00 00 00 00 00 A............... +80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +b0: 00 00 00 00 *00 45 04 00* 0a 00 00 65 6d 70 74 79 .....E.....empty +c0: 5f 61 74 74 72 07 04 02 74 72 75 73 74 5f 61 76 .attr...trust.av +d0: 61 6c 31 06 0c 00 73 65 63 6f 6e 64 73 65 63 6f all...secondseco +e0: 6e 64 5f 76 61 6c 75 65 06 08 04 70 6f 6c 69 63 nd.value...polic +f0: 79 63 6f 6e 74 65 6e 74 73 64 5f 76 61 6c 75 65 ycontentsd.value +---- It can be clearly seen that attr2 allows many more attributes to be stored in an inode before they are moved to another filesystem block. @@ -444,9 +508,19 @@ flag set and the values are printed. A raw disk dump shows the attributes. The last attribute added is highlighted (offset 4044 or 0xfcc): -.Leaf Attribute detail -image::images/code/71.png[] - +[subs="quotes"] +---- +000: 00 00 00 00 00 00 00 00 fb ee 00 00 00 03 00 34 ...............4 +010: 0f cc 00 00 00 38 0f 94 00 00 00 00 00 00 00 00 .....8.......... +020: 1e 9d 39 34 0f cc 01 00 1e 9d 39 37 0f dc 01 00 ..94......97.... +030: fc f8 9d 4f 0f ec 00 00 00 00 00 00 00 00 00 00 ...0............ +040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00................. +... +fc0: 00 00 00 00 00 00 00 00 00 00 00 00 *00 06 05 61* ...............a +fd0: *74 74 72 32 76 61 6c 75 65 32* 00 00 00 06 05 61 ttr2value2.....a +fe0: 74 74 72 31 76 61 6c 75 65 31 00 00 00 00 00 01 ttr1value1...... +ff0: 00 00 77 e4 08 62 69 67 5f 61 74 74 72 00 00 00 ..w..big.attr... +---- [[Node_Attributes]] == Node Attributes @@ -522,16 +596,77 @@ xfs_db> hash attribute_267 In the root btree node, this falls between +0x3437922e+ and +0x3437d22a+, therefore leaf 11 or attribute block 5 will contain the entry. -.Node Attribute lookup detail -image::images/code/73-74.png[] +[subs="quotes"] +---- +xfs_db> ablock 5 +xfs_db> p +hdr.info.forw = 4 +hdr.info.back = 3 +hdr.info.magic = 0xfbee +hdr.count = 96 +hdr.usedbytes = 2688 +hdr.firstused = 1408 +hdr.holes = 0 +hdr.freemap[0-2] = [base,size] 0:[800,608] 1:[0,0] 2:[0,0] +entries[0.95] = [hashval,nameidx,incomplete,root,secure,local] + 0:[0x3437922f,4068,0,0,0,1] + 1:[0x343792a6,4040,0,0,0,1] + 2:[0x343792a7,4012,0,0,0,1] + 3:[0x343792a8,3984,0,0,0,1] + ... + 82:[0x3437d1a7,2892,0,0,0,1] + *83:[0x3437d1a8,2864,0,0,0,1]* + 84:[0x3437d1a9,2836,0,0,0,1] + ... + 95:[0x3437d22a,2528,0,0,0,1] +nvlist[0].valuelen = 10 +nvlist[0].namelen = 13 +nvlist[0].name = "attribute_310" +nvlist[0].value = "value_316\d" +nvlist[1].valuelen = 16 +nvlist[1].namelen = 13 +nvlist[1].name = "attribute_309" +nvlist[1].value = "value_309\d" +nvlist[2].valuelen = 10 +nvlist[2].namelen = 13 +nvlist[2].name = "attribute_308" +nvlist[2].value = "value_308\d" +nvlist[3].valuelen = 10 +nvlist[3].namelen = 13 +nvlist[3].name = "attribute_307" +nvlist[3].value = "value_307\d" +... +nvlist[82].valuelen = 10 +nvlist[82].namelen = 13 +nvlist[82].name = "attribute_268" +nvlist[82].value = "value_268\d" +nvlist[83].valuelen = 10 +nvlist[83].namelen = 13 +nvlist[83].name = "attribute_267" +nvlist[83].value = "value_267\d" +nvlist[84].valuelen = 10 +nvlist[84].namelen = 13 +nvlist[84].name = "attribute_266" +nvlist[84].value = "value_266\d" +... +---- Each of the hash entries has +XFS_ATTR_LOCAL+ flag set (1), which means the attribute's value follows immediately after the name. Raw disk of the name/value pair at offset 2864 (0xb30), highlighted with "value_267\d" following immediately after the name: -.Node Attribute value detail -image::images/code/74.png[] +[subs="quotes"] +---- +b00: 62 75 74 65 5f 32 36 35 76 61 6c 75 65 5f 32 36 bute.265value.26 +b10: 35 0a 00 00 00 0a 0d 61 74 74 72 69 62 75 74 65 5......attribute +b20: 51 32 36 36 76 61 6c 75 65 5f 32 36 36 0a 00 00 .266value.266... +b30: *00 0a 0d 61 74 74 72 69 62 75 74 65 5f 32 36 37* ...attribute.267 +b40: *76 61 6c 75 65 5f 32 36 37 0a* 00 00 00 0a 0d 61 value.267......a +b50: 74 74 72 69 62 75 74 65 5f 32 36 38 76 61 6c 75 ttribute.268va1u +b60: 65 5f 32 36 38 0a 00 00 00 0a 0d 61 74 74 72 69 e.268......attri +b70: 62 75 74 65 5f 32 36 39 76 61 6c 75 65 5f 32 36 bute.269value.26 +---- Each entry starts on a 32-bit (4 byte) boundary, therefore the highlighted entry has 2 unused bytes after it. diff --git a/design/XFS_Filesystem_Structure/symbolic_links.asciidoc b/design/XFS_Filesystem_Structure/symbolic_links.asciidoc index 9c9ca30..af88a1c 100644 --- a/design/XFS_Filesystem_Structure/symbolic_links.asciidoc +++ b/design/XFS_Filesystem_Structure/symbolic_links.asciidoc @@ -38,8 +38,19 @@ u.symlink = "small_target" Raw on-disk data with the link contents highlighted: -.Shortform symbolic link format -image::images/code/61.png[] +[subs="quotes"] +---- +xfs_db> type text +xfs_db> p +00: 49 4e a1 ff 01 01 00 01 00 00 00 00 00 00 00 00 IN.............. +10: 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 01 ................ +20: 44 be e1 c7 03 c4 d4 18 44 be el c7 03 c4 d4 18 D.......D....... +30: 44 be e1 c7 03 c4 d4 18 00 00 00 00 00 00 00 Oc D............... +40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +50: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 00 ................ +60: ff ff ff ff *73 6d 61 6c 6c 5f 74 61 72 67 65 74* ....small.target +70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +---- [[Extent_Symbolic_Links]] From darrick.wong@oracle.com Wed Nov 11 13:23:24 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 6FE387F91 for ; Wed, 11 Nov 2015 13:23:24 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 1B0B7AC001 for ; Wed, 11 Nov 2015 11:23:23 -0800 (PST) X-ASG-Debug-ID: 1447269801-04bdf03f04121290001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id HNL60GV0pELdCiuf (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 11 Nov 2015 11:23:21 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tABJMxfU025178 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 11 Nov 2015 19:23:00 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id tABJMxZK017138 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 11 Nov 2015 19:22:59 GMT Received: from abhmp0015.oracle.com (abhmp0015.oracle.com [141.146.116.21]) by userv0121.oracle.com (8.13.8/8.13.8) with ESMTP id tABJMwh5012827; Wed, 11 Nov 2015 19:22:59 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 11 Nov 2015 11:22:58 -0800 Subject: [PATCH 06/21] xfsdocs: update types From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 06/21] xfsdocs: update types To: hch@infradead.org, david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Wed, 11 Nov 2015 11:22:57 -0800 Message-ID: <20151111192257.14235.17490.stgit@birch.djwong.org> In-Reply-To: <20151111192218.14235.13928.stgit@birch.djwong.org> References: <20151111192218.14235.13928.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1447269801 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24309 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Update the common data types to reflect modern XFS source. Signed-off-by: Darrick J. Wong --- .../allocation_groups.asciidoc | 8 +++---- .../XFS_Filesystem_Structure/common_types.asciidoc | 23 ++++++++++++++------ .../XFS_Filesystem_Structure/data_extents.asciidoc | 4 ++- .../XFS_Filesystem_Structure/ondisk_inode.asciidoc | 2 +- 4 files changed, 23 insertions(+), 14 deletions(-) diff --git a/design/XFS_Filesystem_Structure/allocation_groups.asciidoc b/design/XFS_Filesystem_Structure/allocation_groups.asciidoc index afbbb67..b511324 100644 --- a/design/XFS_Filesystem_Structure/allocation_groups.asciidoc +++ b/design/XFS_Filesystem_Structure/allocation_groups.asciidoc @@ -47,11 +47,11 @@ struct xfs_sb { __uint32_t sb_magicnum; __uint32_t sb_blocksize; - xfs_drfsbno_t sb_dblocks; - xfs_drfsbno_t sb_rblocks; - xfs_drtbno_t sb_rextents; + xfs_rfsblock_t sb_dblocks; + xfs_rfsblock_t sb_rblocks; + xfs_rtblock_t sb_rextents; uuid_t sb_uuid; - xfs_dfsbno_t sb_logstart; + xfs_fsblock_t sb_logstart; xfs_ino_t sb_rootino; xfs_ino_t sb_rbmino; xfs_ino_t sb_rsumino; diff --git a/design/XFS_Filesystem_Structure/common_types.asciidoc b/design/XFS_Filesystem_Structure/common_types.asciidoc index ea2d21f..51909be 100644 --- a/design/XFS_Filesystem_Structure/common_types.asciidoc +++ b/design/XFS_Filesystem_Structure/common_types.asciidoc @@ -10,7 +10,7 @@ Unsigned 64 bit absolute xref:Inode_Numbers[inode number]. Signed 64 bit file offset. *xfs_daddr_t*:: -Signed 64 bit disk address. +Signed 64 bit disk address (sectors). *xfs_agnumber_t*:: Unsigned 32 bit xref:Allocation_Groups[AG number]. @@ -22,7 +22,10 @@ Unsigned 32 bit AG relative block number. Unsigned 32 bit xref:Data_Extents[extent] length in blocks. *xfs_extnum_t*:: -Signed 32 bit number of extents in a file. +Signed 32 bit number of extents in a data fork. + +*xfs_aextnum_t*:: +Signed 16 bit number of extents in an attribute fork. *xfs_dablk_t*:: Unsigned 32 bit block number for xref:Directories[directories] and @@ -31,19 +34,25 @@ xref:Extended_Attributes[extended attributes]. *xfs_dahash_t*:: Unsigned 32 bit hash of a directory file name or extended attribute name. -*xfs_dfsbno_t*:: +*xfs_fsblock_t*:: Unsigned 64 bit filesystem block number combining xref:Allocation_Groups[AG number] and block offset into the AG. -*xfs_drfsbno_t*:: +*xfs_rfsblock_t*:: Unsigned 64 bit raw filesystem block number. -*xfs_drtbno_t*:: +*xfs_rtblock_t*:: Unsigned 64 bit extent number in the xref:Real-time_Devices[real-time] sub-volume. -*xfs_dfiloff_t*:: +*xfs_fileoff_t*:: Unsigned 64 bit block offset into a file. -*xfs_dfilblks_t*:: +*xfs_filblks_t*:: Unsigned 64 bit block count for a file. + +*uuid_t*:: +16-byte universally unique identifier (UUID). + +*xfs_fsize_t*:: +Signed 64 bit byte size of a file. diff --git a/design/XFS_Filesystem_Structure/data_extents.asciidoc b/design/XFS_Filesystem_Structure/data_extents.asciidoc index b71bc52..8b09fee 100644 --- a/design/XFS_Filesystem_Structure/data_extents.asciidoc +++ b/design/XFS_Filesystem_Structure/data_extents.asciidoc @@ -217,9 +217,9 @@ struct xfs_bmdr_block { __be16 bb_numrecs; }; struct xfs_bmbt_key { - xfs_dfiloff_t br_startoff; + xfs_fileoff_t br_startoff; }; -typedef xfs_dfsbno_t xfs_bmbt_ptr_t, xfs_bmdr_ptr_t; +typedef xfs_fsblock_t xfs_bmbt_ptr_t, xfs_bmdr_ptr_t; ---- * On disk, the B+tree node starts with the +xfs_bmbr_block_t+ header followed by diff --git a/design/XFS_Filesystem_Structure/ondisk_inode.asciidoc b/design/XFS_Filesystem_Structure/ondisk_inode.asciidoc index dfdcc32..7262178 100644 --- a/design/XFS_Filesystem_Structure/ondisk_inode.asciidoc +++ b/design/XFS_Filesystem_Structure/ondisk_inode.asciidoc @@ -88,7 +88,7 @@ struct xfs_dinode_core { xfs_timestamp_t di_mtime; xfs_timestamp_t di_ctime; xfs_fsize_t di_size; - xfs_drfsbno_t di_nblocks; + xfs_rfsblock_t di_nblocks; xfs_extlen_t di_extsize; xfs_extnum_t di_nextents; xfs_aextnum_t di_anextents; From darrick.wong@oracle.com Wed Nov 11 13:23:32 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 27D3E7F8B for ; Wed, 11 Nov 2015 13:23:32 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id E22A98F8040 for ; Wed, 11 Nov 2015 11:23:31 -0800 (PST) X-ASG-Debug-ID: 1447269809-04bdf03f051212a0001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id pG66NlIBsratYcwV (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 11 Nov 2015 11:23:29 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tABJN5eo024356 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 11 Nov 2015 19:23:06 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id tABJN5Nr022369 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 11 Nov 2015 19:23:05 GMT Received: from abhmp0017.oracle.com (abhmp0017.oracle.com [141.146.116.23]) by userv0121.oracle.com (8.13.8/8.13.8) with ESMTP id tABJN5bq012942; Wed, 11 Nov 2015 19:23:05 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 11 Nov 2015 11:23:05 -0800 Subject: [PATCH 07/21] xfsdocs: make example section titles consistent From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 07/21] xfsdocs: make example section titles consistent To: hch@infradead.org, david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Wed, 11 Nov 2015 11:23:03 -0800 Message-ID: <20151111192303.14235.77696.stgit@birch.djwong.org> In-Reply-To: <20151111192218.14235.13928.stgit@birch.djwong.org> References: <20151111192218.14235.13928.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1447269809 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24309 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Make the section titles of the examples consistently formatted. Signed-off-by: Darrick J. Wong --- .../allocation_groups.asciidoc | 6 +++--- .../XFS_Filesystem_Structure/data_extents.asciidoc | 6 +++--- .../XFS_Filesystem_Structure/directories.asciidoc | 16 ++++++++-------- .../extended_attributes.asciidoc | 16 ++++++++-------- .../symbolic_links.asciidoc | 8 ++++---- 5 files changed, 26 insertions(+), 26 deletions(-) diff --git a/design/XFS_Filesystem_Structure/allocation_groups.asciidoc b/design/XFS_Filesystem_Structure/allocation_groups.asciidoc index b511324..a86274c 100644 --- a/design/XFS_Filesystem_Structure/allocation_groups.asciidoc +++ b/design/XFS_Filesystem_Structure/allocation_groups.asciidoc @@ -308,7 +308,7 @@ its parent inode. The primary purpose for this information is in backup systems. |===== -=== xfs_db superblock example +=== xfs_db Superblock Example A filesystem is made on a single SATA disk with the following command: @@ -548,7 +548,7 @@ image::images/16.png[] The presence of these reserved block guarantees that the free space B+trees can be updated if any blocks are freed by extent changes in a full AG. -==== xfs_db AGF Examples +==== xfs_db AGF Example These examples are derived from an AG that has been deliberately fragmented. The AGF: @@ -772,7 +772,7 @@ And a 2-level inode B+tree: image::images/20b.png[] -==== xfs_db AGI examples +==== xfs_db AGI Example TODO [[Real-time_Devices]] diff --git a/design/XFS_Filesystem_Structure/data_extents.asciidoc b/design/XFS_Filesystem_Structure/data_extents.asciidoc index 8b09fee..7850165 100644 --- a/design/XFS_Filesystem_Structure/data_extents.asciidoc +++ b/design/XFS_Filesystem_Structure/data_extents.asciidoc @@ -88,7 +88,7 @@ The number of extents that can fit in the inode depends on the inode size and can up to 19 extents with this format. Beyond this, extents have to use the B+tree format. -=== xfs_db: Inode data fork extents +=== xfs_db Inode Data Fork Extents Example An 8MB file with one extent: @@ -268,9 +268,9 @@ bits in size. .Single level extent B+tree image::images/35.png[] -.Multi-level extent B+tree +.Multiple level extent B+tree image::images/36.png[] -=== BMBT xfs_db Example +=== xfs_db bmbt Example TODO diff --git a/design/XFS_Filesystem_Structure/directories.asciidoc b/design/XFS_Filesystem_Structure/directories.asciidoc index beabe20..7d84117 100644 --- a/design/XFS_Filesystem_Structure/directories.asciidoc +++ b/design/XFS_Filesystem_Structure/directories.asciidoc @@ -47,7 +47,7 @@ typedef __uint32_t xfs_dir2_dataptr_t; [[Shortform_Directories]] -== Shortform Directories +== Short Form Directories * Directory entries are stored within the inode. @@ -86,7 +86,7 @@ typedef struct xfs_dir2_sf_entry { } xfs_dir2_sf_entry_t; ---- -.Shortform Directory layout +.Short form directory layout image::images/39.png[] * Inode numbers are stored using 4 or 8 bytes depending on whether all the inode @@ -107,7 +107,7 @@ typedef union { } xfs_dir2_inou_t; ---- -=== Shortform Directory xfs_db Example +=== xfs_db Short Form Directory Example A directory is created with 4 files, all inode numbers fitting within 4 bytes: @@ -325,7 +325,7 @@ lookup speed for large directories. If they were not stored, the hashes have to be calculated for all entries each time a lookup occurs in a directory. -=== Block Directory xfs_db Example +=== xfs_db Block Directory Example A directory is created with 8 entries, directory block size = filesystem block size: @@ -585,7 +585,7 @@ block's +bestfree[0].length+ value. .Leaf directory free entry detail image::images/48.png[] -=== Leaf Directory xfs_db Example +=== xfs_db Leaf Directory Example For this example, a directory was created with 256 entries (frame000000.tst to frame000255.tst) and then deleted some files (frame00005*, frame00018* and @@ -905,10 +905,10 @@ less than or equal to +hdr.nused. hdr.nused+ should be the same as the index of the last data directory block plus one (i.e. when the last data block is freed, +nused+ and +nvalid+ are decremented). -.Node Directory Layout +.Node directory layout image::images/54.png[] -=== Node Directory xfs_db Example +=== xfs_db Node Directory Example With the node directory examples, we are using a filesystems with 4KB block size, and a 16KB directory size. The directory has over 2000 entries: @@ -1111,7 +1111,7 @@ that B+trees can handle: required hundreds of thousand files with quite long file names (or millions with shorter names) to get a second freeindex block. -=== B+tree Directory xfs_db Example +=== xfs_db B+tree Directory Example A directory has been created with 200,000 entries with each entry being 100 characters long. The filesystem block size and directory block size are 4KB: diff --git a/design/XFS_Filesystem_Structure/extended_attributes.asciidoc b/design/XFS_Filesystem_Structure/extended_attributes.asciidoc index 51f7ff7..747217c 100644 --- a/design/XFS_Filesystem_Structure/extended_attributes.asciidoc +++ b/design/XFS_Filesystem_Structure/extended_attributes.asciidoc @@ -41,7 +41,7 @@ The following four sections describe each of the on-disk formats. [[Shortform_Attributes]] -== Shortform Attributes +== Short Form Attributes When the all extended attributes can fit within the inode's attribute fork, the inode's +di_aformat+ is set to "local" and the attributes are stored in the @@ -67,7 +67,7 @@ typedef struct xfs_attr_sf_hdr xfs_attr_sf_hdr_t; typedef struct xfs_attr_sf_entry xfs_attr_sf_entry_t; ---- -.Shortform attribute layout +.Short form attribute layout image::images/64.png[] @@ -89,7 +89,7 @@ immediately follows the name in the array. | +XFS_ATTR_SECURE+ | The attribute's namespace is "secure". |===== -=== Shortform attribute xfs_db example +=== xfs_db Short Form Attribute Example A file is created and two attributes are set: @@ -387,7 +387,7 @@ using the +xfs_attr_leaf_name_local_t+ structure. For large attribute values that cannot be stored within the leaf, separate filesystem blocks are allocated to store the value. They use the +xfs_attr_leaf_name_remote_t+ structure. -.Leaf Attribute layout +.Leaf attribute layout image::images/69.png[] Both local and remote entries can be interleaved as they are only addressed by @@ -403,7 +403,7 @@ crash during the time that the bit is set. The bit is cleared when attribute has finished being setup. This is done because some large attributes cannot be created inside a single transaction. -=== Leaf Attribute xfs_db Example +=== xfs_db Leaf Attribute Example A single 30KB extended attribute is added to an inode: @@ -538,10 +538,10 @@ to lookup, you read the node's btree array and first +hashval+ in the array that exceeds the given hash and it can then be found in the block pointed to by the +before+ value. -.Node Attribute layout +.Node attribute layout image::images/72.png[] -=== Node Attribute xfs_db Example +=== xfs_db Node Attribute Example An inode with 1000 small attributes with the naming "attribute_n" where 'n' is a number: @@ -685,7 +685,7 @@ Attributes. Refer to the previous section on B+tree Data Extents for more information on XFS B+tree extents. -=== B+tree Attribute xfs_db Example +=== xfs_db B+tree Attribute Example Added 2000 attributes with 729 byte values to a file: diff --git a/design/XFS_Filesystem_Structure/symbolic_links.asciidoc b/design/XFS_Filesystem_Structure/symbolic_links.asciidoc index af88a1c..939c440 100644 --- a/design/XFS_Filesystem_Structure/symbolic_links.asciidoc +++ b/design/XFS_Filesystem_Structure/symbolic_links.asciidoc @@ -7,16 +7,16 @@ Symbolic links to a file can be stored in one of two formats: "local" and [[Shortform_Symbolic_Links]] -== Shortform Symbolic Links +== Short Form Symbolic Links Symbolic links are stored with the "local" +di_format+ if the symbolic link can fit within the inode's data fork. The link data is an array of characters (+di_symlink+ array in the data fork union). -.Symbolic link shortform layout +.Symbolic link short form layout image::images/61.png[] -=== Shortform symbolic link xfs_db example +=== xfs_db Short Form Symbolic Link Example A short symbolic link to a file is created: @@ -66,7 +66,7 @@ characters. .Symbolic link extent layout image::images/62.png[] -=== Symbolic link extent xfs_db example +=== xfs_db Symbolic Link Extent Example A longer link is created (greater than 156 bytes): From darrick.wong@oracle.com Wed Nov 11 13:23:45 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 129B17FA5 for ; Wed, 11 Nov 2015 13:23:45 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 7D892AC002 for ; Wed, 11 Nov 2015 11:23:44 -0800 (PST) X-ASG-Debug-ID: 1447269821-04cb6c296a125020001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id QdUdnHsYuJ2URIK9 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 11 Nov 2015 11:23:41 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tABJNIW0024598 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 11 Nov 2015 19:23:19 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id tABJNIO6030500 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 11 Nov 2015 19:23:18 GMT Received: from abhmp0017.oracle.com (abhmp0017.oracle.com [141.146.116.23]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id tABJNI80032654; Wed, 11 Nov 2015 19:23:18 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 11 Nov 2015 11:23:18 -0800 Subject: [PATCH 09/21] xfsdocs: add missing structure field definitions From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 09/21] xfsdocs: add missing structure field definitions To: hch@infradead.org, david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Wed, 11 Nov 2015 11:23:16 -0800 Message-ID: <20151111192316.14235.12293.stgit@birch.djwong.org> In-Reply-To: <20151111192218.14235.13928.stgit@birch.djwong.org> References: <20151111192218.14235.13928.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0022.oracle.com [141.146.126.234] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1447269821 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24309 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Add missing field definitions for various data structures. Signed-off-by: Darrick J. Wong --- .../allocation_groups.asciidoc | 32 +++ .../XFS_Filesystem_Structure/data_extents.asciidoc | 27 ++ .../XFS_Filesystem_Structure/directories.asciidoc | 240 ++++++++++++++++++++ design/XFS_Filesystem_Structure/docinfo.xml | 1 .../extended_attributes.asciidoc | 86 +++++++ 5 files changed, 386 insertions(+) diff --git a/design/XFS_Filesystem_Structure/allocation_groups.asciidoc b/design/XFS_Filesystem_Structure/allocation_groups.asciidoc index 680f90c..e958039 100644 --- a/design/XFS_Filesystem_Structure/allocation_groups.asciidoc +++ b/design/XFS_Filesystem_Structure/allocation_groups.asciidoc @@ -501,6 +501,23 @@ struct xfs_btree_sblock { }; ---- +*bb_magic*:: +Specifies the magic number for the per-AG B+tree block. + +*bb_level*:: +The level of the tree in which this block is found. If this value is 0, this +is a leaf block and contains records; otherwise, it is a node block and +contains keys and pointers. + +*bb_numrecs*:: +Number of records in this block. + +*bb_leftsib*:: +AG block number of the left sibling of this B+tree node. + +*bb_rightsib*:: +AG block number of the right sibling of this B+tree node. + [[AG_Free_Space_Btrees]] === AG Free Space B+trees @@ -519,6 +536,12 @@ struct xfs_alloc_rec { }; ---- +*ar_startblock*:: +AG block number of the start of the free space. + +*ar_blockcount*:: +Length of the free space. + Node pointers are an AG relative block pointer: [source, c] @@ -776,6 +799,15 @@ struct xfs_inobt_rec { }; ---- +*ir_startino*:: +The lowest-numbered inode in this chunk. + +*ir_freecount*:: +Number of free inodes in this chunk. + +*ir_free*:: +A 64 element bitmap showing which inodes in this chunk are free. + Nodes contain key/pointer pairs using the following types: [source,c] diff --git a/design/XFS_Filesystem_Structure/data_extents.asciidoc b/design/XFS_Filesystem_Structure/data_extents.asciidoc index a09fcc2..d1617f1 100644 --- a/design/XFS_Filesystem_Structure/data_extents.asciidoc +++ b/design/XFS_Filesystem_Structure/data_extents.asciidoc @@ -33,8 +33,16 @@ struct xfs_bmbt_irec { }; ---- +*br_startoff*:: +Logical block offset of this mapping. +*br_startblock*:: +Filesystem block of this mapping. +*br_blockcount*:: +The length of this mapping. + +*br_state*:: The extent +br_state+ field uses the following enum declaration: [source, c] @@ -250,6 +258,25 @@ struct xfs_btree_lblock { }; ---- +*bb_magic*:: +Specifies the magic number for the BMBT block: "BMAP" (0x424d4150). + +*bb_level*:: +The level of the tree in which this block is found. If this value is 0, this +is a leaf block and contains records; otherwise, it is a node block and +contains keys and pointers. + +*bb_numrecs*:: +Number of records in this block. + +*bb_leftsib*:: +FS block number of the left sibling of this B+tree node. + +*bb_rightsib*:: +FS block number of the right sibling of this B+tree node. + +// force-split the lists + * For intermediate nodes, the data following +xfs_btree_lblock+ is the same as the root node: array of +xfs_bmbt_key+ value followed by an array of +xfs_bmbt_ptr_t+ values that starts halfway through the block (offset 0x808 for diff --git a/design/XFS_Filesystem_Structure/directories.asciidoc b/design/XFS_Filesystem_Structure/directories.asciidoc index 3521749..2df118e 100644 --- a/design/XFS_Filesystem_Structure/directories.asciidoc +++ b/design/XFS_Filesystem_Structure/directories.asciidoc @@ -75,11 +75,35 @@ typedef struct xfs_dir2_sf { xfs_dir2_sf_hdr_t hdr; xfs_dir2_sf_entry_t list[1]; } xfs_dir2_sf_t; +---- + +*hdr*:: +Short form directory header. + +*list*:: +An array of variable-length directory entry records. + +[source, c] +---- typedef struct xfs_dir2_sf_hdr { __uint8_t count; __uint8_t i8count; xfs_dir2_inou_t parent; } xfs_dir2_sf_hdr_t; +---- + +*count*:: +Number of directory entries. + +*i8count*:: +Number of directory entries requiring 64-bit entries, if any inode numbers +require 64-bits. Zero otherwise. + +*parent*:: +The absolute inode number of this directory's parent. + +[source, c] +---- typedef struct xfs_dir2_sf_entry { __uint8_t namelen; xfs_dir2_sf_off_t offset; @@ -89,6 +113,25 @@ typedef struct xfs_dir2_sf_entry { } xfs_dir2_sf_entry_t; ---- +*namelen*:: +Length of the name, in bytes. + +*offset*:: +Offset tag used to assist with directory iteration. + +*name*:: +The name of the directory entry. The entry is not NULL-terminated. + +*ftype*:: +The type of the inode. This is used to avoid reading the inode while iterating +a directory. The +XFS_SB_VERSION2_FTYPE+ feature must be set, or this field +will not be present. + +*inumber*:: +The inode number that this entry points to. The length is either 32 or 64 +bits, depending on whether +icount+ or +i8count+, respectively, are set in the +header. + .Short form directory layout image::images/39.png[] @@ -259,18 +302,67 @@ typedef struct xfs_dir2_block { xfs_dir2_leaf_entry_t leaf[1]; xfs_dir2_block_tail_t tail; } xfs_dir2_block_t; +---- + +*hdr*:: +Directory block header. + +*u*:: +Union of directory and unused entries. + +*leaf*:: +Hash values of the entries in this block. + +*tail*:: +Bookkeeping for the leaf entries. + +[source, c] +---- typedef struct xfs_dir2_data_hdr { __uint32_t magic; xfs_dir2_data_free_t bestfree[XFS_DIR2_DATA_FD_COUNT]; } xfs_dir2_data_hdr_t; +---- + +*magic*:: +Magic number for this directory block. + +*bestfree*:: +An array pointing to free regions in the directory block. + +[source, c] +---- typedef struct xfs_dir2_data_free { xfs_dir2_data_off_t offset; xfs_dir2_data_off_t length; } xfs_dir2_data_free_t; +---- + +*offset*:: +Block offset of a free block, in bytes. + +*length*:: +Length of the free block, in bytes. + +Space inside the directory block can be used for directory entries or unused +entries. This is signified via a union of the two types: + +[source, c] +----- typedef union { xfs_dir2_data_entry_t entry; xfs_dir2_data_unused_t unused; } xfs_dir2_data_union_t; +---- + +*entry*:: +A directory entry. + +*unused*:: +An unused entry. + +[source, c] +----- typedef struct xfs_dir2_data_entry { xfs_ino_t inumber; __uint8_t namelen; @@ -278,21 +370,74 @@ typedef struct xfs_dir2_data_entry { __uint8_t ftype; xfs_dir2_data_off_t tag; } xfs_dir2_data_entry_t; +---- + +*inumber*:: +The inode number that this entry points to. + +*namelen*:: +Length of the name, in bytes. + +*name*:: +The name associated with this entry. + +*ftype*:: +The type of the inode. This is used to avoid reading the inode while iterating +a directory. The +XFS_SB_VERSION2_FTYPE+ feature must be set, or this field +will not be present. + +*tag*:: +Starting offset of the entry, in bytes. This is used for directory iteration. + +[source, c] +----- typedef struct xfs_dir2_data_unused { __uint16_t freetag; /* 0xffff */ xfs_dir2_data_off_t length; xfs_dir2_data_off_t tag; } xfs_dir2_data_unused_t; +---- + +*freetag*:: +Magic number signifying that this is an unused entry. Must be 0xFFFF. + +*length*:: +Length of this unused entry, in bytes. + +*tag*:: +Starting offset of the entry, in bytes. + +[source, c] +----- typedef struct xfs_dir2_leaf_entry { xfs_dahash_t hashval; xfs_dir2_dataptr_t address; } xfs_dir2_leaf_entry_t; +---- + +*hashval*:: +Hash value of the name of the directory entry. This is used to speed up entry +lookups. + +*address*:: +Block offset of the entry, in eight byte units. + +[source, c] +----- typedef struct xfs_dir2_block_tail { __uint32_t count; __uint32_t stale; } xfs_dir2_block_tail_t; ---- +*count*:: +Number of leaf entries. + +*stale*:: +Number of free leaf entries. + +Following is a diagram of how these pieces fit together for a block directory. + .Block directory layout image::images/43.png[] @@ -550,6 +695,14 @@ typedef struct xfs_dir2_data { } xfs_dir2_data_t; ---- +*hdr*:: +Data block header. + +*u*:: +Union of directory and unused entries, exactly the same as in a block directory. + +// split lists + * The "leaf" extent uses the following structures: [source, c] @@ -560,16 +713,48 @@ typedef struct xfs_dir2_leaf { xfs_dir2_data_off_t bests[1]; xfs_dir2_leaf_tail_t tail; } xfs_dir2_leaf_t; +---- + +*hdr*:: +Directory leaf header. + +*ents*:: +Hash values of the entries in this block. + +*bests*:: +An array pointing to free regions in the directory block. + +*tail*:: +Bookkeeping for the leaf entries. + +[source, c] +---- typedef struct xfs_dir2_leaf_hdr { xfs_da_blkinfo_t info; __uint16_t count; __uint16_t stale; } xfs_dir2_leaf_hdr_t; +---- + +*info*:: +Leaf btree block header. + +*count*:: +Number of leaf entries. + +*stale*:: +Number of stale/zeroed leaf entries. + +[source, c] +---- typedef struct xfs_dir2_leaf_tail { __uint32_t bestcount; } xfs_dir2_leaf_tail_t; ---- +*bestcount*:: +Number of best free entries. + [[Directory_Attribute_Block_Header]] === Directory and Attribute Block Headers @@ -587,6 +772,20 @@ typedef struct xfs_da_blkinfo { } xfs_da_blkinfo_t; ---- +*forw*:: +Logical block offset of the previous B+tree block at this level. + +*back*:: +Logical block offset of the next B+tree block at this level. + +*magic*:: +Magic number for this directory/attribute block. + +*pad*:: +Padding to maintain alignment. + +// split lists + * The magic number of the leaf block is +XFS_DIR2_LEAF1_MAGIC+ (0xd2f1). * The size of the +ents+ array is specified by +hdr.count+. @@ -879,12 +1078,36 @@ typedef struct xfs_dir2_free_hdr { __int32_t nvalid; __int32_t nused; } xfs_dir2_free_hdr_t; +---- + +*magic*:: +The magic number of the free block, "XD2F" (0x0x58443246). + +*firstdb*:: +The starting directory block number for the bests array. + +*nvalid*:: +Number of elements in the bests array. + +*nused*:: +Number of valid elements in the bests array. + +[source, c] +---- typedef struct xfs_dir2_free { xfs_dir2_free_hdr_t hdr; xfs_dir2_data_off_t bests[1]; } xfs_dir2_free_t; ---- +*hdr*:: +Free block header. + +*bests*:: +An array specifying the best free counts in each directory data block. + +// split lists + * The location of the leaf blocks can be in any order, the only way to determine the appropriate is by the node block hash/before values. Given a hash to look up, you read the node's +btree+ array and first +hashval+ in the array that exceeds @@ -912,6 +1135,23 @@ typedef struct xfs_da_intnode { } xfs_da_intnode_t; ---- +*info*:: +Directory/attribute block info. The magic number is +XFS_DA_NODE_MAGIC+ +(0xfebe). + +*count*:: +Number of node entries in this block. + +*level*:: +The level of this block in the B+tree. + +*hashval*:: +The hash value of a particular record. + +*before*:: +The directory/attribute logical block containing all entries up to the +corresponding hash value. + * The freeindex's +bests+ array starts from the end of the block and grows to the start of the block. diff --git a/design/XFS_Filesystem_Structure/docinfo.xml b/design/XFS_Filesystem_Structure/docinfo.xml index 856c01d..32a502d 100644 --- a/design/XFS_Filesystem_Structure/docinfo.xml +++ b/design/XFS_Filesystem_Structure/docinfo.xml @@ -82,6 +82,7 @@ Miscellaneous fixes. + Add missing field definitions. diff --git a/design/XFS_Filesystem_Structure/extended_attributes.asciidoc b/design/XFS_Filesystem_Structure/extended_attributes.asciidoc index 18a4568..2499f12 100644 --- a/design/XFS_Filesystem_Structure/extended_attributes.asciidoc +++ b/design/XFS_Filesystem_Structure/extended_attributes.asciidoc @@ -334,7 +334,16 @@ typedef struct xfs_attr_leaf_map { __be16 base; __be16 size; } xfs_attr_leaf_map_t; +---- + +*base*:: +Block offset of the free area, in bytes. + +*size*:: +Size of the free area, in bytes. +[source, c] +---- typedef struct xfs_attr_leaf_hdr { xfs_da_blkinfo_t info; __be16 count; @@ -344,27 +353,90 @@ typedef struct xfs_attr_leaf_hdr { __u8 pad1; xfs_attr_leaf_map_t freemap[3]; } xfs_attr_leaf_hdr_t; +---- + +*info*:: +Directory/attribute block header. + +*count*:: +Number of entries. + +*usedbytes*:: +Number of bytes used in the leaf block. +*firstused*:: +Block offset of the first entry in use, in bytes. + +*holes*:: +Set to 1 if block compaction is necessary. + +*pad1*:: +Padding to maintain alignment to 64-bit boundaries. + +[source, c] +----- typedef struct xfs_attr_leaf_entry { __be32 hashval; __be16 nameidx; __u8 flags; __u8 pad2; } xfs_attr_leaf_entry_t; +---- + +*hashval*:: +Hash value of the attribute name. + +*nameidx*:: +Block offset of the name entry, in bytes. + +*flags*:: +Attribute flags, as specified xref:Attribute_Flags[above]. + +*pad2*:: +Pads the structure to 64-bit boundaries. +[source, c] +---- typedef struct xfs_attr_leaf_name_local { __be16 valuelen; __u8 namelen; __u8 nameval[1]; } xfs_attr_leaf_name_local_t; +---- + +*valuelen*:: +Length of the value, in bytes. + +*namelen*:: +Length of the name, in bytes. +*nameval*:: +The name and the value. String values are not zero-terminated. + +[source, c] +---- typedef struct xfs_attr_leaf_name_remote { __be32 valueblk; __be32 valuelen; __u8 namelen; __u8 name[1]; } xfs_attr_leaf_name_remote_t; +---- + +*valueblk*:: +The logical block in the attribute map where the value is located. +*valuelen*:: +Length of the value, in bytes. + +*namelen*:: +Length of the name, in bytes. + +*nameval*:: +The name. String values are not zero-terminated. + +[source, c] +---- typedef struct xfs_attr_leafblock { xfs_attr_leaf_hdr_t hdr; xfs_attr_leaf_entry_t entries[1]; @@ -373,6 +445,20 @@ typedef struct xfs_attr_leafblock { } xfs_attr_leafblock_t; ---- +*hdr*:: +Attribute block header. + +*entries*:: +A variable-length array of attribute entries. + +*namelist*:: +A variable-length array of descriptors of local attributes. The location and +size of these entries is determined dynamically. + +*valuelist*:: +A variable-length array of descriptors of remote attributes. The location and +size of these entries is determined dynamically. + Each leaf header uses the magic number +XFS_ATTR_LEAF_MAGIC+ (0xfbee). The hash/index elements in the +entries[]+ array are packed from the top of the From darrick.wong@oracle.com Wed Nov 11 13:23:46 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 6067F7F86 for ; Wed, 11 Nov 2015 13:23:46 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 51964304032 for ; Wed, 11 Nov 2015 11:23:46 -0800 (PST) X-ASG-Debug-ID: 1447269820-04cbb0242312cc90001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id jJKNN6qU6o3hcqO9 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 11 Nov 2015 11:23:40 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tABJNC34025625 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 11 Nov 2015 19:23:13 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id tABJNCBi022638 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 11 Nov 2015 19:23:12 GMT Received: from abhmp0014.oracle.com (abhmp0014.oracle.com [141.146.116.20]) by userv0121.oracle.com (8.13.8/8.13.8) with ESMTP id tABJNB7V012981; Wed, 11 Nov 2015 19:23:12 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 11 Nov 2015 11:23:11 -0800 Subject: [PATCH 08/21] xfsdocs: fix various errors and missing bits in the text From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 08/21] xfsdocs: fix various errors and missing bits in the text To: hch@infradead.org, david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Wed, 11 Nov 2015 11:23:10 -0800 Message-ID: <20151111192310.14235.61423.stgit@birch.djwong.org> In-Reply-To: <20151111192218.14235.13928.stgit@birch.djwong.org> References: <20151111192218.14235.13928.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 8bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1447269820 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/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=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24309 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Fix typos and grammatical errors in the text. Signed-off-by: Darrick J. Wong --- .../allocation_groups.asciidoc | 128 +++++++++++-------- .../XFS_Filesystem_Structure/data_extents.asciidoc | 64 +++++---- .../XFS_Filesystem_Structure/directories.asciidoc | 136 ++++++++++++-------- design/XFS_Filesystem_Structure/docinfo.xml | 16 ++ .../extended_attributes.asciidoc | 96 ++++++++------ .../internal_inodes.asciidoc | 33 +++-- .../XFS_Filesystem_Structure/ondisk_inode.asciidoc | 83 +++++++----- 7 files changed, 319 insertions(+), 237 deletions(-) diff --git a/design/XFS_Filesystem_Structure/allocation_groups.asciidoc b/design/XFS_Filesystem_Structure/allocation_groups.asciidoc index a86274c..680f90c 100644 --- a/design/XFS_Filesystem_Structure/allocation_groups.asciidoc +++ b/design/XFS_Filesystem_Structure/allocation_groups.asciidoc @@ -3,9 +3,8 @@ XFS filesystems are divided into a number of equally sized chunks called Allocation Groups. Each AG can almost be thought of as an individual filesystem -that maintains it's own space usage. Each AG can be up to one terabyte in size -(512 bytes * 2^31^), regardless of the underlying -device's sector size. +that maintains its own space usage. Each AG can be up to one terabyte in size +(512 bytes × 2^31^), regardless of the underlying device's sector size. Each AG has the following characteristics: @@ -14,15 +13,15 @@ Each AG has the following characteristics: * Inode allocation and tracking Having multiple AGs allows XFS to handle most operations in parallel without -degrading performance as the number of concurrent accessing increases. +degrading performance as the number of concurrent accesses increases. -The only global information maintained by the first AG (primary) is free spac e +The only global information maintained by the first AG (primary) is free space across the filesystem and total inode counts. If the +XFS_SB_VERSION2_LAZYSBCOUNTBIT+ flag is set in the superblock, these are only updated on-disk when the filesystem is cleanly unmounted (umount or shutdown). -Immediately after a mkfs.xfs, the primary AG has the following disk layout the -subsequent AGs do not have any inodes allocated: +Immediately after a +mkfs.xfs+, the primary AG has the following disk layout; +the subsequent AGs do not have any inodes allocated: .Allocation group layout image::images/6.png[] @@ -32,9 +31,10 @@ Each of these structures are expanded upon in the following sections. [[Superblocks]] == Superblocks -Each AG starts with a superblock. The first one is the primary superblock that -stores aggregate AG information. Secondary superblocks are only used by -xfs_repair when the primary superblock has been corrupted. +Each AG starts with a superblock. The first one, in AG 0, is the primary +superblock which stores aggregate AG information. Secondary superblocks are +only used by xfs_repair when the primary superblock has been corrupted. A +superblock is one sector in length. The superblock is defined by the following structure. The description of each field follows. @@ -93,7 +93,7 @@ struct xfs_sb }; ---- *sb_magicnum*:: -Identifies the filesystem. It's value is +XFS_SB_MAGIC = 0x58465342 "XFSB"+. +Identifies the filesystem. Its value is +XFS_SB_MAGIC = 0x58465342 "XFSB"+. *sb_blocksize*:: The size of a basic unit of space allocation in bytes. Typically, this is 4096 @@ -116,11 +116,14 @@ the UUID instead of device name. *sb_logstart*:: First block number for the journaling log if the log is internal (ie. not on a separate disk device). For an external log device, this will be zero (the log -will also start on the first block on the log device). +will also start on the first block on the log device). The identity of the log +devices is not recorded in the filesystem, but the UUIDs of the filesystem and +the log device are compared to prevent corruption. *sb_rootino*:: -Root inode number for the filesystem. Typically, this is 128 when using a -4KB block size. +Root inode number for the filesystem. Normally, the root inode is at the +start of the first possible inode chunk in AG 0. This is 128 when using a 4KB +block size. *sb_rbmino*:: Bitmap inode for real-time extents. @@ -147,9 +150,9 @@ Number of blocks for the journaling log. *sb_versionnum*:: Filesystem version number. This is a bitmask specifying the features enabled when creating the filesystem. Any disk checking tools or drivers that do not -recognize any set bits must not operate upon the filesystem. Most of the flagsi -indicate features introduced over time. The value must be 4 including the -following flags: +recognize any set bits must not operate upon the filesystem. Most of the flags +indicate features introduced over time. If the value of the lower nibble is 4, +the higher bits indicate feature flags as follows: .Version 4 Superblock version flags [options="header"] @@ -175,8 +178,8 @@ Set if the sb_features2 field in the superblock contains more flags. |===== *sb_sectsize*:: -Specifies the underlying disk sector size in bytes. Majority of the time, this -is 512 bytes. This determines the minimum I/O alignment including Direct I/O. +Specifies the underlying disk sector size in bytes. Typically this is 512 or +4096 bytes. This determines the minimum I/O alignment, especially for direct I/O. *sb_inodesize*:: Size of the inode in bytes. The default is 256 (2 inodes per standard sector) @@ -258,6 +261,13 @@ Quota flags. It can be a combination of the following flags: *sb_flags*:: Miscellaneous flags. +.Superblock flags +[options="header"] +|===== +| Flag | Description +| +XFS_SBF_READONLY+ | Only read-only mounts allowed. +|===== + *sb_shared_vn*:: Reserved and must be zero ("vn" stands for version number). @@ -300,17 +310,29 @@ primary superblock when the filesystem is cleanly unmounted. | +XFS_SB_VERSION2_ATTR2BIT+ | Extended attributes version 2. Making a filesystem with this optimises the inode -layout of extended attributes. +layout of extended attributes. See the section about +xref:Extended_Attribute_Versions[extended attribute versions] for more +information. | +XFS_SB_VERSION2_PARENTBIT+ | Parent pointers. All inodes must have an extended attribute that points back to its parent inode. The primary purpose for this information is in backup systems. + +| +XFS_SB_VERSION2_PROJID32BIT+ | +32-bit Project ID. Inodes can be associated with a project ID number, which +can be used to enforce disk space usage quotas for a particular group of +directories. This flag indicates that project IDs can be 32 bits in size. + +| +XFS_SB_VERSION2_FTYPE+ | +Directory file type. Each directory entry records the type of the inode to +which the entry points. This speeds up directory iteration by removing the +need to load every inode into memory. |===== === xfs_db Superblock Example -A filesystem is made on a single SATA disk with the following command: +A filesystem is made on a single disk with the following command: ---- # mkfs.xfs -i attr=2 -n size=16384 -f /dev/sda7 @@ -385,7 +407,7 @@ One B+tree tracks space by block number, the second by the size of the free space block. This scheme allows XFS to quickly find free space near a given block or of a given size. -All block numbers, indexes and counts are AG relative. +All block numbers, indexes, and counts are AG relative. [[AG_Free_Space_Block]] === AG Free Space Block @@ -414,8 +436,9 @@ struct xfs_agf { }; ---- -The rest of the bytes in the sector are zeroed. +XFS_BTNUM_AGF+ is set to 2, -index 0 for the count B+tree and index 1 for the size B+tree. +The rest of the bytes in the sector are zeroed. +XFS_BTNUM_AGF+ is set to 2: +index 0 for the free space B+tree indexed by block number; and index 1 for the +free space B+tree indexed by extent size. *agf_magicnum*:: Specifies the magic number for the AGF sector: "XAGF" (0x58414746). @@ -428,7 +451,7 @@ Specifies the AG number for the sector. *agf_length*:: Specifies the size of the AG in filesystem blocks. For all AGs except the last, -This must be equal to the superblock's +sb_agblocks+ value. For the last AG, +this must be equal to the superblock's +sb_agblocks+ value. For the last AG, this could be less than the +sb_agblocks+ value. It is this value that should be used to determine the size of the AG. @@ -459,14 +482,13 @@ Specifies the number of blocks of longest contiguous free space in the AG. Specifies the number of blocks used for the free space B+trees. This is only used if the +XFS_SB_VERSION2_LAZYSBCOUNTBIT+ bit is set in +sb_features2+. -[[AG_Free_Space_Btrees]] -=== AG Free Space B+trees +[[Short_Format_Btrees]] +=== Short Format B+trees -The two Free Space B+trees store a sorted array of block offset and block -counts in the leaves of the B+tree. The first B+tree is sorted by the offset, -the second by the count or size. - -The trees use the following header: +Each allocation group uses a ``short format'' B+tree to index various +information about the allocation group. The structure is called short format +because all block pointers are AG block numbers. The trees use the following +header: [source, c] ---- @@ -479,6 +501,13 @@ struct xfs_btree_sblock { }; ---- +[[AG_Free_Space_Btrees]] +=== AG Free Space B+trees + +The two Free Space B+trees store a sorted array of block offset and block +counts in the leaves of the B+tree. The first B+tree is sorted by the offset, +the second by the count or size. + Leaf nodes contain a sorted array of offset/count pairs which are also used for node keys: @@ -531,7 +560,7 @@ including inodes, data, directories and extended attributes. With a freshly made filesystem, 4 blocks are reserved immediately after the free space B+tree root blocks (blocks 4 to 7). As they are used up as the free space fragments, additional blocks will be reserved from the AG and added to the free -list array. +list array. This size may increase as features are added. As the free list array is located within a single sector, a typical device will have space for 128 elements in the array (512 bytes per sector, 4 bytes per AG @@ -545,8 +574,8 @@ values. The array is managed as a circular list. .AG Free List layout image::images/16.png[] -The presence of these reserved block guarantees that the free space B+trees can -be updated if any blocks are freed by extent changes in a full AG. +The presence of these reserved blocks guarantees that the free space B+trees +can be updated if any blocks are freed by extent changes in a full AG. ==== xfs_db AGF Example @@ -584,8 +613,8 @@ bno[0-127] = 0:4 1:5 2:6 3:7 4:83342 5:83343 6:83344 7:83345 8:83346 9:83347 26:80205 27:83344 ---- -The free space B+tree sorted by block offset, the root block is from the AGF's -+bnoroot+ value: +The root block of the free space B+tree sorted by block offset is found in the +AGF's +bnoroot+ value: ---- xfs_db> fsblock 7 @@ -602,11 +631,11 @@ ptrs[1-4] = 1:2 2:83347 3:6 4:4 ---- Blocks 2, 83347, 6 and 4 contain the leaves for the free space B+tree by -starting block. Block 2 would contain offsets 16 up to but not including 184586 +starting block. Block 2 would contain offsets 12 up to but not including 184586 while block 4 would have all offsets from 511629 to the end of the AG. -The free space B+tree sorted by block count, the root block is from the AGF's -+cntroot+ value: +The root block of the free space B+tree sorted by block count is found in the +AGF's +cntroot+ value: ---- xfs_db> fsblock 83343 @@ -642,7 +671,7 @@ recs[1-344] = [startblock,blockcount] 342:[513712,755] 343:[230317,258229] 344:[538795,3384327] ---- -The longest block count must be the same as the AGF's +longest+ value. +The longest block count (3384327) must be the same as the AGF's +longest+ value. [[AG_Inode_Management]] == AG Inode Management @@ -659,7 +688,7 @@ structures. Absolute inode numbers include the AG number in the high bits, above the bits used for the AG relative inode number. Absolute inode numbers are found in -xref:Directories[directory] entries. +xref:Directories[directory] entries and the superblock. .Inode number formats image::images/18.png[] @@ -713,10 +742,10 @@ Specifies the number of levels in the inode B+tree. Specifies the number of free inodes in the AG. *agi_newino*:: -Specifies AG relative inode number most recently allocated. +Specifies AG-relative inode number of the most recently allocated chunk. *agi_dirino*:: -Deprecated and not used, it's always set to NULL (-1). +Deprecated and not used, this is always set to NULL (-1). *agi_unlinked[64]*:: Hash table of unlinked (deleted) inodes that are still being referenced. Refer @@ -734,6 +763,8 @@ The B+tree header for the nodes and leaves use the +xfs_btree_sblock+ structure which is the same as the header used in the xref:AG_Free_Space_Btrees[AGF B+trees]. +The magic number of the inode B+tree is ``IABT'' (0x49414254). + Leaves contain an array of the following structure: [source,c] @@ -755,20 +786,15 @@ struct xfs_inobt_key { typedef __be32 xfs_inobt_ptr_t; ---- -For the leaf entries, +ir_startino+ specifies the starting inode number for the -chunk, +ir_freecount+ specifies the number of free entries in the chuck, and the -+ir_free+ is a 64 element bit array specifying which entries are free in the -chunk. - The following diagram illustrates a single level inode B+tree: -.Single Level inode b+tree +.Single Level inode B+tree image::images/20a.png[] And a 2-level inode B+tree: -.Multi-Level inode b+tree +.Multi-Level inode B+tree image::images/20b.png[] diff --git a/design/XFS_Filesystem_Structure/data_extents.asciidoc b/design/XFS_Filesystem_Structure/data_extents.asciidoc index 7850165..a09fcc2 100644 --- a/design/XFS_Filesystem_Structure/data_extents.asciidoc +++ b/design/XFS_Filesystem_Structure/data_extents.asciidoc @@ -1,18 +1,18 @@ [[Data_Extents]] = Data Extents -XFS allocates space for a file using extents: starting location and length. XFS -extents also specify the file's logical starting offset for a file. This allows -a files extent map to automatically support sparse files (i.e. "holes" in the -file). A flag is also used to specify if the extent has been preallocated and -not yet been written to (unwritten extent). +XFS manages space using extents, which are defined as a starting location and +length. A fork in an XFS inode maps a logical offset to a space extent. This +enables a file's extent map to support sparse files (i.e. "holes" in the file). +A flag is also used to specify if the extent has been preallocated but has not +yet been written (unwritten extent). A file can have more than one extent if one chunk of contiguous disk space is not available for the file. As a file grows, the XFS space allocator will -attempt to keep space contiguous and merge extents. If more than one file is +attempt to keep space contiguous and to merge extents. If more than one file is being allocated space in the same AG at the same time, multiple extents for the -files will occur as the extents get interleaved. The effect of this can vary -depending on the extent allocator used in the XFS driver. +files will occur as the extent allocations interleave. The effect of this can +vary depending on the extent allocator used in the XFS driver. An extent is 128 bits in size and uses the following packed layout: @@ -48,15 +48,16 @@ typedef enum { Some other points about extents: -* The +xfs_bmbt_rec_32_t+ and +xfs_bmbt_rec_64_t+ structures are effectively +* The +xfs_bmbt_rec_32_t+ and +xfs_bmbt_rec_64_t+ structures were effectively the same as +xfs_bmbt_rec_t+, just different representations of the same 128 -bits in on-disk big endian format. +bits in on-disk big endian format. +xfs_bmbt_rec_32_t+ was removed and ++xfs_bmbt_rec_64_t+ renamed to +xfs_bmbt_rec_t+ some time ago. * When a file is created and written to, XFS will endeavour to keep the extents within the same AG as the inode. It may use a different AG if the AG is busy or there is no space left in it. -* If a file is zero bytes long, it will have no extents, +di_nblocks+ and +* If a file is zero bytes long, it will have no extents and +di_nblocks+ and +di_nexents+ will be zero. Any file with data will have at least one extent, and each extent can use from 1 to over 2 million blocks (2^21^) on the filesystem. For a default 4KB block size filesystem, a single extent can be up to 8GB in @@ -72,20 +73,20 @@ efficiently. [[Extent_List]] == Extent List -Local extents are where the entire extent array is stored within the inode's -data fork itself. This is the most optimal in terms of speed and resource -consumption. The trade-off is the file can only have a few extents before the -inode runs out of space. +If the entire extent list is short enough to fit within the inode's fork +region, we say that the fork is in ``extent list'' format. This is the most +optimal in terms of speed and resource consumption. The trade-off is the file +can only have a few extents before the inode runs out of space. -The "data fork" of the inode contains an array of extents, the size of the array -determined by the inode's +di_nextents+ value. +The data fork of the inode contains an array of extents; the size of the array +is determined by the inode's +di_nextents+ value. .Inode data fork extent layout image::images/32.png[] The number of extents that can fit in the inode depends on the inode size and +di_forkoff+. For a default 256 byte inode with no extended attributes, a file -can up to 19 extents with this format. Beyond this, extents have to use the +can have up to 9 extents with this format. Beyond this, extents have to use the B+tree format. === xfs_db Inode Data Fork Extents Example @@ -129,7 +130,7 @@ u.bmx[0-2] = [startoff,startblock,blockcount,extentflag] 2:[4050,35481,2025,0] ---- -Raw disk version of the inode with the third extent highlighted (+di_u+ always +Raw disk version of the inode with the third extent highlighted (+di_u+ starts at offset 0x64): [subs="quotes"] @@ -193,9 +194,9 @@ u.bmx[0-1] = [startoff,startblock,blockcount,extentflag] [[Btree_Extent_List]] == B+tree Extent List -Beyond the simple extent array, to efficiently manage large extent maps, XFS -uses B+trees. The root node of the B+tree is stored in the inode's data fork. -All block pointers for extent B+trees are 64-bit absolute block numbers. +To manage extent maps that cannot fit in the inode fork area, XFS uses long +format B+trees. The root node of the B+tree is stored in the inode's data +fork. All block pointers for extent B+trees are 64-bit absolute block numbers. For a single level B+tree, the root node points to the B+tree's leaves. Each leaf occupies one filesystem block and contains a header and an array of extents @@ -204,11 +205,12 @@ forward) block pointers to adjacent leaves. For a standard 4KB filesystem block, a leaf can contain up to 254 extents before a B+tree rebalance is triggered. For a multi-level B+tree, the root node points to other B+tree nodes which -eventually point to the extent leaves. B+tree keys are based on the file's -offset. The nodes at each level in the B+tree point to the adjacent nodes. +eventually point to the extent leaves. B+tree keys are based on the file's +offset and have pointers to the next level down. Nodes at each level in the +B+tree also have pointers to the adjacent nodes. The base B+tree node is used for extents, directories and extended attributes. -The structures used for inode's B+tree root are: +The structures used for an inode's B+tree root are: [source, c] ---- @@ -222,15 +224,18 @@ struct xfs_bmbt_key { typedef xfs_fsblock_t xfs_bmbt_ptr_t, xfs_bmdr_ptr_t; ---- -* On disk, the B+tree node starts with the +xfs_bmbr_block_t+ header followed by +* On disk, the B+tree node starts with the +xfs_bmdr_block_t+ header followed by an array of +xfs_bmbt_key_t+ values and then an array of +xfs_bmbt_ptr_t+ values. The size of both arrays is specified by the header's +bb_numrecs+ value. -* The root node in the inode can only contain up to 19 key/pointer pairs for a +* The root node in the inode can only contain up to 9 key/pointer pairs for a standard 256 byte inode before a new level of nodes is added between the root and the leaves. This will be less if +di_forkoff+ is not zero (i.e. attributes are in use on the inode). +[[Long_Format_Btrees]] +== Long Format B+trees + The subsequent nodes and leaves of the B+tree use the +xfs_btree_lblock+ declaration: @@ -253,10 +258,7 @@ a 4096 byte filesystem block). * For leaves, an array of +xfs_bmbt_rec+ extents follow the +xfs_btree_lblock+ header. -* Nodes and leaves use the same value for +bb_magic+: - -[source, c] -#define XFS_BMAP_MAGIC 0x424d4150 /* 'BMAP' */ +* Nodes and leaves use the same value for +bb_magic+. * The +bb_level+ value determines if the node is an intermediate node or a leaf. Leaves have a +bb_level+ of zero, nodes are one or greater. diff --git a/design/XFS_Filesystem_Structure/directories.asciidoc b/design/XFS_Filesystem_Structure/directories.asciidoc index 7d84117..3521749 100644 --- a/design/XFS_Filesystem_Structure/directories.asciidoc +++ b/design/XFS_Filesystem_Structure/directories.asciidoc @@ -9,17 +9,18 @@ The term "block" in this section will refer to directory blocks, not filesystem blocks unless otherwise specified. The size of a "directory block" is defined by the xref:Superblocks[superblock's] -+sb_dirblklog+ value. The size in bytes = +sb_blocksize+ * 2^sb_dirblklog^. ++sb_dirblklog+ value. The size in bytes = +sb_blocksize+ × 2^sb_dirblklog^. For example, if +sb_blocksize+ = 4096 and +sb_dirblklog+ = 2, the directory block size is 16384 bytes. Directory blocks are always allocated in multiples based on +sb_dirblklog+. Directory blocks cannot be more that 65536 bytes in size. All directory entries contain the following "data": -* Entry's name (counted string consisting of a single byte +namelen+ followed by -+name+ consisting of an array of 8-bit chars without a NULL terminator). +* The entry's name (counted string consisting of a single byte +namelen+ +followed by +name+ consisting of an array of 8-bit chars without a NULL +terminator). -* Entry's absolute inode number (), which are +* The entry's absolute xref:Inode_Numbers[inode number], which are always 64 bits (8 bytes) in size except a special case for shortform directories. @@ -51,18 +52,19 @@ typedef __uint32_t xfs_dir2_dataptr_t; * Directory entries are stored within the inode. -* Only data stored is the name, inode # and offset, no "leaf" or "freespace index" -information is required as an inode can only store a few entries. +* The only data stored is the name, inode number, and offset. No "leaf" or +"freespace index" information is required as an inode can only store a few +entries. * "." is not stored (as it's in the inode itself), and ".." is a dedicated +parent+ field in the header. -* The number of directories that can be stored in an inode depends on the inode -size (), the number of entries, the length of the -entry names and extended attribute data. +* The number of directories that can be stored in an inode depends on the +xref:On-disk_Inode[inode] size, the number of entries, the length of the entry +names, and extended attribute data. -* Once the number of entries exceed the space available in the inode, the format -is converted to a "Block Directory". +* Once the number of entries exceeds the space available in the inode, the +format is converted to a xref:Block_Directories[block directory]. * Shortform directory data is packed as tightly as possible on the disk with the remaining space zeroed: @@ -82,6 +84,7 @@ typedef struct xfs_dir2_sf_entry { __uint8_t namelen; xfs_dir2_sf_off_t offset; __uint8_t name[1]; + __uint8_t ftype; xfs_dir2_inou_t inumber; } xfs_dir2_sf_entry_t; ---- @@ -94,8 +97,9 @@ numbers for the directory fit in 4 bytes (32 bits) or not. If all inode numbers fit in 4 bytes, the header's +count+ value specifies the number of entries in the directory and +i8count+ will be zero. If any inode number exceeds 4 bytes, all inode numbers will be 8 bytes in size and the header's +i8count+ value -specifies the number of entries and count will be zero. The following union -covers the shortform inode number structure: +specifies the number of entries requiring larger inodes. +i4count+ is still +the number of entries. The following union covers the shortform inode number +structure: [source, c] ---- @@ -222,7 +226,7 @@ b0: 72 61 6d 65 30 30 30 30 30 33 2e 74 73 74 01 80 rame000003.tst.. c0: 00 84 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ ---- -TODO: 8-byte inode number example +TODO: 8-byte inode number example [[Block_Directories]] @@ -233,12 +237,10 @@ data is moved into a new single directory block outside the inode. The inode's format is changed from "local" to "extent". Following is a list of points about block directories. - - * All directory data is stored within the one directory block, including "." and ".." entries which are mandatory. -* The block also contains "leaf" and "freespace index " information. +* The block also contains "leaf" and "freespace index" information. * The location of the block is defined by the inode's in-core xref:Extent_List[extent list]: the +di_u.u_bmx[0]+ value. The file offset in @@ -273,6 +275,7 @@ typedef struct xfs_dir2_data_entry { xfs_ino_t inumber; __uint8_t namelen; __uint8_t name[1]; + __uint8_t ftype; xfs_dir2_data_off_t tag; } xfs_dir2_data_entry_t; typedef struct xfs_dir2_data_unused { @@ -293,10 +296,12 @@ typedef struct xfs_dir2_block_tail { .Block directory layout image::images/43.png[] +* The magic number in the header is "XD2B" (0x58443242). + * The +tag+ in the +xfs_dir2_data_entry_t+ structure stores its offset from the start of the block. -* Start of a free space region is marked with the +xfs_dir2_data_unused_t+ +* The start of a free space region is marked with the +xfs_dir2_data_unused_t+ structure where the +freetag+ is +0xffff+. The +freetag+ and +length+ overwrites the +inumber+ for an entry. The +tag+ is located at +length - sizeof(tag)+ from the start of the +unused+ entry on-disk. @@ -321,8 +326,8 @@ structure, contains an array of hash/address pairs for quickly looking up a name by a hash value. Hash values are covered by the introduction to directories. The +address+ on-disk is the offset into the block divided by 8 (+XFS_DIR2_DATA_ALIGN+). Hash/address pairs are stored on disk to optimise -lookup speed for large directories. If they were not stored, the hashes have to -be calculated for all entries each time a lookup occurs in a directory. +lookup speed for large directories. If they were not stored, the hashes would +have to be calculated for all entries each time a lookup occurs in a directory. === xfs_db Block Directory Example @@ -529,9 +534,12 @@ allocate a new block for the leaf and freespace index information. * The "leaf" block has a special offset defined by +XFS_DIR2_LEAF_OFFSET+. Currently, this is 32GB and in the extent view, a block offset of -32GB/sb_blocksize. On a 4KB block filesystem, this is 0x800000 (8388608 +32GB / +sb_blocksize+. On a 4KB block filesystem, this is 0x800000 (8388608 decimal). +* Blocks with directory entries ("data" extents) have the magic number "X2D2" +(0x58443244). + * The "data" extents have a new header (no "leaf" data): [source, c] @@ -562,9 +570,12 @@ typedef struct xfs_dir2_leaf_tail { } xfs_dir2_leaf_tail_t; ---- -* The leaves use the +xfs_da_blkinfo_t+ filesystem block header. This header is -used for directory and xref:Extended_Attributes[extended attribute] leaves and -B+tree nodes: +[[Directory_Attribute_Block_Header]] +=== Directory and Attribute Block Headers + +* Leaf nodes in directories and xref:Extended_Attributes[extended attributes] +use the +xfs_da_blkinfo_t+ filesystem block header. The structure appears as +follows: [source, c] ---- @@ -576,11 +587,13 @@ typedef struct xfs_da_blkinfo { } xfs_da_blkinfo_t; ---- +* The magic number of the leaf block is +XFS_DIR2_LEAF1_MAGIC+ (0xd2f1). + * The size of the +ents+ array is specified by +hdr.count+. -* The size of the bests array is specified by the tail.bestcount which is also the -number of "data" blocks for  the directory. The bests array maintains each data -block's +bestfree[0].length+ value. +* The size of the +bests+ array is specified by the +tail.bestcount+, which is +also the number of "data" blocks for  the directory. The bests array maintains +each data block's +bestfree[0].length+ value. .Leaf directory free entry detail image::images/48.png[] @@ -588,7 +601,7 @@ image::images/48.png[] === xfs_db Leaf Directory Example For this example, a directory was created with 256 entries (frame000000.tst to -frame000255.tst) and then deleted some files (frame00005*, frame00018* and +frame000255.tst). Some files were deleted (frame00005*, frame00018* and frame000240.tst) to show free list characteristics. ---- @@ -840,15 +853,19 @@ each "data" block. This is not possible with more than one leaf. * The "data" blocks stay the same as leaf directories. -* The "leaf" blocks eventually change into a B+tree with the generic B+tree header -pointing to directory "leaves" as described in Leaf Directories. The top-level -blocks are called "nodes". It can exist in a state where there is still a single -leaf block before it's split. Interpretation of the node vs. leaf blocks has to -be performed by inspecting the magic value in the header. The combined -leaf/freeindex blocks has a magic value of +XFS_DIR2_LEAF1_MAGIC (0xd2f1)+, a -node directory's leaf/leaves have a magic value of +XFS_DIR2_LEAFN_MAGIC -(0xd2ff)+ and intermediate nodes have a magic value of +XFS_DA_NODE_MAGIC -(0xfebe)+. +* After the "freeindex" data moves to its own block, it is possible for the +leaf data to fit within a single leaf block. This single leaf block has a +magic number of +XFS_DIR2_LEAFN_MAGIC+ (0xd2ff). + +* The "leaf" blocks eventually change into a B+tree with the generic B+tree +header pointing to directory "leaves" as described in +xref:Leaf_Directories[Leaf Directories]. Blocks with leaf data still have the ++LEAFN_MAGIC+ magic number as outlined above. The top-level tree blocks are +called "nodes" and have a magic number of +XFS_DA_NODE_MAGIC+ (0xfebe). + +* Distinguishing between a combined leaf/freeindex block (+LEAF1_MAGIC+), a +leaf-only block (+LEAFN_MAGIC+), and a btree node block (+NODE_MAGIC+) can only +be done by examining the magic number. * The new "freeindex" block(s) only contains the bests for each data block. @@ -869,11 +886,17 @@ typedef struct xfs_dir2_free { ---- * The location of the leaf blocks can be in any order, the only way to determine -the appropriate is by the node block hash/before values. Given a hash to lookup, +the appropriate is by the node block hash/before values. Given a hash to look up, you read the node's +btree+ array and first +hashval+ in the array that exceeds the given hash and it can then be found in the block pointed to by the +before+ value. +[[Directory_Attribute_Internal_Node]] +=== Directory and Attribute Internal Nodes + +The hashing B+tree of a directory or an extended attribute fork uses nodes with +the following format: + [source, c] ---- typedef struct xfs_da_intnode { @@ -901,9 +924,9 @@ directory to have a hole at the start. * The freeindex's +hdr.nvalid+ should always be the same as the number of allocated data directory blocks containing name/inode data and will always be -less than or equal to +hdr.nused. hdr.nused+ should be the same as the index of -the last data directory block plus one (i.e. when the last data block is freed, -+nused+ and +nvalid+ are decremented). +less than or equal to +hdr.nused+. The value of +hdr.nused+ should be the same +as the index of the last data directory block plus one (i.e. when the last data +block is freed, +nused+ and +nvalid+ are decremented). .Node directory layout image::images/54.png[] @@ -940,9 +963,10 @@ u.bmx[0-7] = [startoff,startblock,blockcount,extentflag] 0:[0,7368,4,0] As can already be observed, all extents are allocated is multiples of 4 blocks. -Blocks 0 to 19 (16+4-1) are used for the data. Looking at blocks 16-19, it can -seen that it's the same as the single-leaf format, except the +length+ values -are a lot larger to accommodate the increased directory block size: +Blocks 0 to 19 (16+4-1) are used for directory data blocks. Looking at blocks +16-19, we can seen that it's the same as the single-leaf format, except the ++length+ values are a lot larger to accommodate the increased directory block +size: ---- xfs_db> dblock 16 @@ -994,11 +1018,11 @@ nhdr.level = 1 nbtree[0-1] = [hashval,before] 0:[0xa3a440ac,8388616] 1:[0xf3a440bc,8388612] ---- -The following leaf blocks have been allocated once as XFS knows it needs at two -blocks when allocating a B+tree, so the length is 8 fsblocks. For all hashes -< 0xa3a440ac, they are located in the directory offset 8388616 and hashes -below 0xf3a440bc are in offset 8388612. Hashes above f3a440bc don't exist in -this directory. +The two following leaf blocks were allocated as part of the directory's +conversion to node format. All hashes less than 0xa3a440ac are located at +directory offset 8,388,616, and hashes less than 0xf3a440bc are located at +directory offset 8,388,612. Hashes greater or equal to 0xf3a440bc don't exist +in this directory. ---- xfs_db> dblock 8388616 @@ -1075,8 +1099,7 @@ fbests[0-4] = 0:0x10 1:0x10 2:0x10 3:0x10 4:0x3f50 Like the Leaf Directory, each of the +fbests+ values correspond to each data block's +bestfree[0].length+ value. -The raw disk layout, old data is not cleared after the array. The fbests array -is highlighted: +The +fbests+ array is highlighted in a raw block dump: [subs="quotes"] ---- @@ -1095,15 +1118,13 @@ TODO: Example with a hole in the middle When the extent map in an inode grows beyond the inode's space, the inode format is changed to a "btree". The inode contains a filesystem block point to the B+tree extent map for the directory's blocks. The B+tree extents contain the -extent map for the "data", "node", "leaf" and "freeindex" information as +extent map for the "data", "node", "leaf", and "freeindex" information as described in Node Directories. Refer to the previous section on B+tree xref:Btree_Extent_List[Data Extents] for more information on XFS B+tree extents. -The following situations and changes can apply over Node Directories, and apply -here as inode extents generally cannot contain the number of directory blocks -that B+trees can handle: +The following properties apply to both node and B+tree directories: * The node/leaf trees can be more than one level deep. @@ -1219,8 +1240,9 @@ nbtree[0-318] = [hashval,before] 0:[0x70b14711,8388919] ... ---- The leaves at each the end of a node always point to the end leaves in adjacent -nodes. Directory block 8388928 forward pointer is to block 8388919, and vice -versa as highlighted in the following example: +nodes. Directory block 8388928 has a forward pointer to block 8388919 and block +8388919 has a previous pointer to block 8388928, as highlighted in the +following example: [subs="quotes"] ---- diff --git a/design/XFS_Filesystem_Structure/docinfo.xml b/design/XFS_Filesystem_Structure/docinfo.xml index cb5ffe7..856c01d 100644 --- a/design/XFS_Filesystem_Structure/docinfo.xml +++ b/design/XFS_Filesystem_Structure/docinfo.xml @@ -1,7 +1,9 @@ 3rd Edition + @@ -69,4 +71,18 @@ + + 3 + October 2015 + + Darrick + Wong + + + + + Miscellaneous fixes. + + + diff --git a/design/XFS_Filesystem_Structure/extended_attributes.asciidoc b/design/XFS_Filesystem_Structure/extended_attributes.asciidoc index 747217c..18a4568 100644 --- a/design/XFS_Filesystem_Structure/extended_attributes.asciidoc +++ b/design/XFS_Filesystem_Structure/extended_attributes.asciidoc @@ -1,20 +1,20 @@ [[Extended_Attributes]] = Extended Attributes -Extended attributes implement the ability for a user to attach name:value pairs -to inodes within the XFS filesystem. They could be used to store +Extended attributes enable users and administrators to attach (name: value) +pairs to inodes within the XFS filesystem. They could be used to store meta-information about the file. -The attribute names can be up to 256 bytes in length, terminated by the first 0 +Attribute names can be up to 256 bytes in length, terminated by the first 0 byte. The intent is that they be printable ASCII (or other character set) names -for the attribute. The values can be up to 64KB of arbitrary binary data. Some -XFS internal attributes (eg. parent pointers) use non-printable names for the -attribute. +for the attribute. The values can contain up to 64KB of arbitrary binary data. +Some XFS internal attributes (eg. parent pointers) use non-printable names for +the attribute. Access Control Lists (ACLs) and Data Migration Facility (DMF) use extended attributes to store their associated metadata with an inode. -XFS uses two disjoint attribute name spaces associated with every inode. They +XFS uses two disjoint attribute name spaces associated with every inode. These are the root and user address spaces. The root address space is accessible only to the superuser, and then only by specifying a flag argument to the function call. Other users will not see or be able to modify attributes in the root @@ -27,15 +27,10 @@ To set or delete extended attributes, use the +setfattr+ command. ACLs control should use the +getfacl+ and +setfacl+ commands. XFS attributes supports three namespaces: "user", "trusted" (or "root" using -IRIX terminology) and "secure". +IRIX terminology), and "secure". -The location of the attribute fork in the inode's literal area is specified by -the +di_forkoff+ value in the inode's core. If this value is zero, the inode -does not contain any extended attributes. Non-zero, the byte offset into the -literal area = +di_forkoff * 8+, which also determines the 2048 byte maximum -size for an inode. Attributes must be allocated on a 64-bit boundary on the disk -except shortform attributes (they are tightly packed). To determine the offset -into the inode itself, add 100 (0x64) to +di_forkoff * 8+. +See the section about xref:Extended_Attribute_Versions[extended attributes] in +the inode for instructions on how to calculate the location of the attributes. The following four sections describe each of the on-disk formats. @@ -45,7 +40,7 @@ The following four sections describe each of the on-disk formats. When the all extended attributes can fit within the inode's attribute fork, the inode's +di_aformat+ is set to "local" and the attributes are stored in the -inode's literal area starting at offset +di_forkoff * 8+. +inode's literal area starting at offset +di_forkoff × 8+. Shortform attributes use the following structures: @@ -67,28 +62,39 @@ typedef struct xfs_attr_sf_hdr xfs_attr_sf_hdr_t; typedef struct xfs_attr_sf_entry xfs_attr_sf_entry_t; ---- -.Short form attribute layout -image::images/64.png[] - +*totsize*:: +Total size of the attribute structure in bytes. -* +namelen+ and +valuelen+ specify the size of the two byte arrays containing the -name and value pairs. +valuelen+ is zero for extended attributes with no value. +*count*:: +The number of entries that can be found in this structure. -* +nameval[]+ is a single array where it's size is the sum of +namelen+ and -+valuelen+. The names and values are not null terminated on-disk. The value -immediately follows the name in the array. +*namelen* and *valuelen*:: +These values specify the size of the two byte arrays containing the name and +value pairs. +valuelen+ is zero for extended attributes with no value. -* +flags+ specifies the namespace for the attribute (0 = "user"): +*nameval[]*:: +A single array whose size is the sum of +namelen+ and +valuelen+. The names and +values are not null terminated on-disk. The value immediately follows the name +in the array. +[[Attribute_Flags]] +*flags*:: +A combination of the following: .Attribute Namespaces [options="header"] |===== | Flag | Description +| 0 | The attribute's namespace is "user". | +XFS_ATTR_ROOT+ | The attribute's namespace is "trusted". | +XFS_ATTR_SECURE+ | The attribute's namespace is "secure". +| +XFS_ATTR_INCOMPLETE+ | This attribute is being modified. +| +XFS_ATTR_LOCAL+ | The attribute value is contained within this block. |===== +.Short form attribute layout +image::images/64.png[] + === xfs_db Short Form Attribute Example A file is created and two attributes are set: @@ -315,8 +321,9 @@ The first part of the "leaf" contains an array of fixed size hash/index pairs with the flags stored as well. The remaining part of the leaf block contains the array name/value pairs, where each element varies in length. -Each leaf is based on the +xfs_da_blkinfo_t+ block header declared in Leaf -Directories. The structure encapsulating all other structures in the +Each leaf is based on the +xfs_da_blkinfo_t+ block header declared in the +section about xref:Directory_Attribute_Block_Header[directories]. The structure +encapsulating all other structures in the attribute block is +xfs_attr_leafblock_t+. The structures involved are: @@ -365,18 +372,14 @@ typedef struct xfs_attr_leafblock { xfs_attr_leaf_name_remote_t valuelist; } xfs_attr_leafblock_t; ---- - - - Each leaf header uses the following magic number: -[source, c] -#define XFS_ATTR_LEAF_MAGIC 0xfbee +Each leaf header uses the magic number +XFS_ATTR_LEAF_MAGIC+ (0xfbee). The hash/index elements in the +entries[]+ array are packed from the top of the block. Name/values grow from the bottom but are not packed. The freemap contains run-length-encoded entries for the free bytes after the +entries[]+ array, but only the three largest runs are stored (smaller runs are dropped). When the -+freemap+ doesn't show enough space for an allocation, name/value area is ++freemap+ doesn't show enough space for an allocation, the name/value area is compacted and allocation is tried again. If there still isn't enough space, then the block is split. The name/value structures (both local and remote versions) must be 32-bit aligned. @@ -400,7 +403,7 @@ lookup, the actual name string must be compared. An "incomplete" bit is also used for attribute flags. It shows that an attribute is in the middle of being created and should not be shown to the user if we crash during the time that the bit is set. The bit is cleared when attribute -has finished being setup. This is done because some large attributes cannot +has finished being set up. This is done because some large attributes cannot be created inside a single transaction. === xfs_db Leaf Attribute Example @@ -529,15 +532,18 @@ When the number of attributes exceeds the space that can fit in one filesystem block (ie. hash, flag, name and local values), the first attribute block becomes the root of a B+tree where the leaves contain the hash/name/value information that was stored in a single leaf block. The inode's attribute format itself -remains extent based. The nodes use the +xfs_da_intnode_t+ structure introduced -in Node Directories. - -The location of the attribute leaf blocks can be in any order, the only way to -determine the appropriate is by the node block hash/before values. Given a hash -to lookup, you read the node's btree array and first +hashval+ in the array that -exceeds the given hash and it can then be found in the block pointed to by the +remains extent based. The nodes use the +xfs_da_intnode_t+ or ++xfs_da3_intnode_t+ structures introduced in the section about +xref:Directory_Attribute_Internal_Node[directories]. + +The location of the attribute leaf blocks can be in any order. The only way to +find an attribute is by walking the node block hash/before values. Given a hash +to look up, search the node's btree array for the first +hashval+ in the array +that exceeds the given hash. The entry is in the block pointed to by the +before+ value. +Each attribute node block has a magic number of +XFS_DA_NODE_MAGIC+ (0xfebe). + .Node attribute layout image::images/72.png[] @@ -679,11 +685,11 @@ When the attribute's extent map in an inode grows beyond the available space, the inode's attribute format is changed to a "btree". The inode contains root node of the extent B+tree which then address the leaves that contains the extent arrays for the attribute data. The attribute data itself in the allocated -filesystem blocks use the same layout and structures as described in Node -Attributes. +filesystem blocks use the same layout and structures as described in +xref:Node_Attributes[Node Attributes]. -Refer to the previous section on B+tree Data Extents for more information on XFS -B+tree extents. +Refer to the previous section on xref:Btree_Extent_List[B+tree Data Extents] for +more information on XFS B+tree extents. === xfs_db B+tree Attribute Example diff --git a/design/XFS_Filesystem_Structure/internal_inodes.asciidoc b/design/XFS_Filesystem_Structure/internal_inodes.asciidoc index b69bea2..a926857 100644 --- a/design/XFS_Filesystem_Structure/internal_inodes.asciidoc +++ b/design/XFS_Filesystem_Structure/internal_inodes.asciidoc @@ -28,8 +28,9 @@ multiplied by the size of +xfs_dqblk_t+ (136 bytes). .Quota inode layout image::images/76.png[] -Quota information stored in the two inodes (in data extents) are an array of the -+xfs_dqblk+ structure where there is one instance for each ID in the system: +Quota information is stored in the data extents of the two reserved quota +inodes as an array of the +xfs_dqblk+ structures, where there is one array +element for each ID in the system: [source, c] ---- @@ -67,7 +68,7 @@ Specifies the signature where these two bytes are 0x4451 (+XFS_DQUOT_MAGIC+), or "DQ" in ASCII. *d_version*:: -Specifies the structure version, currently this is one (+XFS_DQUOT_VERSION+). +The structure version, currently this is 1 (+XFS_DQUOT_VERSION+). *d_flags*:: Specifies which type of ID the structure applies to: @@ -84,33 +85,33 @@ The ID for the quota structure. This will be a uid, gid or projid based on the value of +d_flags+. *d_blk_hardlimit*:: -Specifies the hard limit for the number of filesystem blocks the ID can own. The +The hard limit for the number of filesystem blocks the ID can own. The ID will not be able to use more space than this limit. If it is attempted, +ENOSPC+ will be returned. *d_blk_softlimit*:: -Specifies the soft limit for the number of filesystem blocks the ID can own. +The soft limit for the number of filesystem blocks the ID can own. The ID can temporarily use more space than by +d_blk_softlimit+ up to +d_blk_hardlimit+. If the space is not freed by the time limit specified by ID zero's +d_btimer+ value, the ID will be denied more space until the total blocks owned goes below +d_blk_softlimit+. *d_ino_hardlimit*:: -Specifies the hard limit for the number of inodes the ID can own. The ID will +The hard limit for the number of inodes the ID can own. The ID will not be able to create or own any more inodes if +d_icount+ reaches this value. *d_ino_softlimit*:: -Specifies the soft limit for the number of inodes the ID can own. The ID can -temporarily create or own more inodes than specified by d_ino_softlimit up to -d_ino_hardlimit. If the inode count is not reduced by the time limit specified -by ID zero's d_itimer value, the ID will be denied from creating or owning more -inodes until the count goes below d_ino_softlimit. +The soft limit for the number of inodes the ID can own. The ID can +temporarily create or own more inodes than specified by +d_ino_softlimit+ up to ++d_ino_hardlimit+. If the inode count is not reduced by the time limit specified +by ID zero's +d_itimer+ value, the ID will be denied from creating or owning more +inodes until the count goes below +d_ino_softlimit+. *d_bcount*:: -Specifies how many filesystem blocks are actually owned by the ID. +How many filesystem blocks are actually owned by the ID. *d_icount*:: -Specifies how many inodes are actually owned by the ID. +How many inodes are actually owned by the ID. *d_itimer*:: Specifies the time when the ID's +d_icount+ exceeded +d_ino_softlimit+. The soft @@ -130,18 +131,18 @@ is reset back to zero. Specifies how many times a warning has been issued. Currently not used. *d_rtb_hardlimit*:: -Specifies the hard limit for the number of real-time blocks the ID can own. The +The hard limit for the number of real-time blocks the ID can own. The ID cannot own more space on the real-time subvolume beyond this limit. *d_rtb_softlimit*:: -Specifies the soft limit for the number of real-time blocks the ID can own. The +The soft limit for the number of real-time blocks the ID can own. The ID can temporarily own more space than specified by +d_rtb_softlimit+ up to +d_rtb_hardlimit+. If +d_rtbcount+ is not reduced by the time limit specified by ID zero's +d_rtbtimer value+, the ID will be denied from owning more space until the count goes below +d_rtb_softlimit+. *d_rtbcount*:: -Specifies how many real-time blocks are currently owned by the ID. +How many real-time blocks are currently owned by the ID. *d_rtbtimer*:: Specifies the time when the ID's +d_rtbcount+ exceeded +d_rtb_softlimit+. The diff --git a/design/XFS_Filesystem_Structure/ondisk_inode.asciidoc b/design/XFS_Filesystem_Structure/ondisk_inode.asciidoc index 7262178..a887f8e 100644 --- a/design/XFS_Filesystem_Structure/ondisk_inode.asciidoc +++ b/design/XFS_Filesystem_Structure/ondisk_inode.asciidoc @@ -1,8 +1,8 @@ [[On-disk_Inode]] = On-disk Inode -All files, directories and links are stored on disk with inodes and descend from -the root inode with it's number defined in the xref:Superblocks[superblock]. The +All files, directories, and links are stored on disk with inodes and descend from +the root inode with its number defined in the xref:Superblocks[superblock]. The previous section on xref:AG_Inode_Management[AG Inode Management] describes the allocation and management of inodes on disk. This section describes the contents of inodes themselves. @@ -12,10 +12,10 @@ An inode is divided into 3 parts: .On-disk inode sections image::images/23.png[] -* The core contains what the inode represents, stat data and information +* The core contains what the inode represents, stat data, and information describing the data and attribute forks. -* The +di_u+ "data fork" contains normal data related to the inode. It's contents +* The +di_u+ "data fork" contains normal data related to the inode. Its contents depends on the file type specified by +di_core.di_mode+ (eg. regular file, directory, link, etc) and how much information is contained in the file which determined by +di_core.di_format+. The following union to represent this data is @@ -34,7 +34,7 @@ union { } di_u; ---- -* The di_a "attribute fork" contains extended attributes. Its layout is +* The +di_a+ "attribute fork" contains extended attributes. Its layout is determined by the +di_core.di_aformat+ value. Its representation is declared as follows: @@ -82,7 +82,8 @@ struct xfs_dinode_core { __uint32_t di_gid; __uint32_t di_nlink; __uint16_t di_projid; - __uint8_t di_pad[8]; + __uint16_t di_projid_hi; + __uint8_t di_pad[6]; __uint16_t di_flushiter; xfs_timestamp_t di_atime; xfs_timestamp_t di_mtime; @@ -102,7 +103,7 @@ struct xfs_dinode_core { ---- *di_magic*:: -The inode signature where these two bytes are 0x494e, or "IN" in ASCII. +The inode signature; these two bytes are 0x494e, or "IN" in ASCII. *di_mode*:: Specifies the mode access bits and type of file using the standard S_Ixxx values @@ -115,12 +116,11 @@ values in the inode core. Initially, inodes are created as v1 but can be converted on the fly to v2 when required. *di_format*:: - Specifies the format of the data fork in conjunction with the +di_mode+ type. This can be one of several values. For directories and links, it can be "local" -where all metadata associated with the file is within the inode, "extents" where +where all metadata associated with the file is within the inode; "extents" where the inode contains an array of extents to other filesystem blocks which contain -the associated metadata or data or "btree" where the inode contains a B+tree +the associated metadata or data; or "btree" where the inode contains a B+tree root node which points to filesystem blocks containing the metadata or data. Migration between the formats depends on the amount of metadata associated with the inode. "dev" is used for character and block devices while "uuid" is @@ -150,15 +150,18 @@ Specifies the owner's GID of the inode. *di_nlink*:: Specifies the number of links to the inode from directories. This is maintained -for both inode versions for current versions of XFS. Old versions of XFS did not -support v2 inodes, and therefore this value was never updated and was classed as -reserved space (part of +di_pad+). +for both inode versions for current versions of XFS. Prior to v2 inodes, this +field was part of +di_pad+. *di_projid*:: Specifies the owner's project ID in v2 inodes. An inode is converted to v2 if the project ID is set. This value must be zero for v1 inodes. -*di_pad[8]*:: +*di_projid_hi*:: +Specifies the high 16 bits of the owner's project ID in v2 inodes, if the ++XFS_SB_VERSION2_PROJID32BIT+ feature is set; and zero otherwise. + +*di_pad[6]*:: Reserved, must be zero. *di_flushiter*:: @@ -167,8 +170,8 @@ Incremented on flush. *di_atime*:: Specifies the last access time of the files using UNIX time conventions the -following structure. This value maybe undefined if the filesystem is mounted -with the "noatime" option. +following structure. This value may be undefined if the filesystem is mounted +with the "noatime" option. XFS supports timestamps with nanosecond resolution: [source, c] ---- @@ -240,7 +243,6 @@ following values: [options="header"] |===== | Flag | Description -| +XFS_SB_VERSION_ATTRBIT+ | Set if any inode have extended attributes. | +XFS_DIFLAG_REALTIME+ | The inode's data is located on the real-time device. | +XFS_DIFLAG_PREALLOC+ | The inode's extents have been preallocated. | +XFS_DIFLAG_NEWRTBM+ | @@ -269,6 +271,12 @@ For directory inodes, new inodes inherit the +di_extsize+ value. | +XFS_DIFLAG_NODEFRAG+ | Specifies the inode is to be ignored when defragmenting the filesystem. +| +XFS_DIFLAG_FILESTREAMS+ | +Use the filestream allocator. The filestreams allocator allows a directory to +reserve an entire allocation group for exclusive use by files created in that +directory. Files in other directories cannot use AGs reserved by other +directories. + |===== *di_gen*:: @@ -280,16 +288,15 @@ can change by unlinking and creating a new file that reuses the inode. [[Unlinked_Pointer]] == Unlinked Pointer -The +di_next_unlinked+ value in the inode is used to track inodes that have been -unlinked (deleted) but which are still referenced. When an inode is unlinked and -there is still an outstanding reference, the inode is added to one of the -xref:AG_Inode_Management[AGI's] +agi_unlinked+ hash buckets. The AGI unlinked -bucket points to an inode and the +di_next_unlinked+ value points to the next -inode in the chain. The last inode in the chain has +di_next_unlinked+ set to -NULL (-1). +The +di_next_unlinked+ value in the inode is used to track inodes that have +been unlinked (deleted) but are still open by a program. When an inode is +in this state, the inode is added to one of the xref:AG_Inode_Management[AGI's] ++agi_unlinked+ hash buckets. The AGI unlinked bucket points to an inode and the ++di_next_unlinked+ value points to the next inode in the chain. The last inode +in the chain has +di_next_unlinked+ set to NULL (-1). Once the last reference is released, the inode is removed from the unlinked hash -chain, and +di_next_unlinked+ is set to NULL. In the case of a system crash, XFS +chain and +di_next_unlinked+ is set to NULL. In the case of a system crash, XFS recovery will complete the unlink process for any inodes found in these lists. The only time the unlinked fields can be seen to be used on disk is either on an @@ -372,8 +379,8 @@ This is accessed by casting the return value from +XFS_DFORK_DPTR+ to +char*+. block, the inode contains the extents to these filesystem blocks (+xfs_bmbt_rec_t*+). -Details for symbolic links is covered in the xref:Symbolic_Links[Symbolic Links] -later on. +Details for symbolic links is covered in the section about +xref:Symbolic_Links[Symbolic Links]. [[Other_File_Types]] === Other File Types @@ -390,16 +397,16 @@ For character and block devices (+S_IFCHR+ and +S_IFBLK+), cast the value from The attribute fork in the inode always contains the location of the extended attributes associated with the inode. -The location of the attribute fork in the inode's literal area (offset 100 to -the end of the inode) is specified by the +di_forkoff+ value in the inode's -core. If this value is zero, the inode does not contain any extended attributes. -Non-zero, the byte offset into the literal area = +di_forkoff+ * 8, which also -determines the 2048 byte maximum size for an inode. Attributes must be allocated -on a 64-bit boundary on the disk. To access the extended attributes in code, use -the +XFS_DFORK_PTR+ macro specifying +XFS_ATTR_FORK+ for the "which" parameter. -Alternatively, the +XFS_DFORK_APTR+ macro can be used. +The location of the attribute fork in the inode's literal area is specified by +the +di_forkoff+ value in the inode's core. If this value is zero, the inode +does not contain any extended attributes. If non-zero, the attribute fork's +byte offset into the literal area can be computed from +di_forkoff × 8+. +Attributes must be allocated on a 64-bit boundary on the disk. To access the +extended attributes in code, use the +XFS_DFORK_PTR+ macro specifying ++XFS_ATTR_FORK+ for the "which" parameter. Alternatively, the +XFS_DFORK_APTR+ +macro can be used. -Which structure in the attribute fork is used depends on the +di_aformat+ value +The structure of the attribute fork depends on the +di_aformat+ value in the inode. It can be one of the following values: * +XFS_DINODE_FMT_LOCAL+: The extended attributes are contained entirely within @@ -431,7 +438,7 @@ space is split between +di_u+ and +di_a+ forks which also determines how the With "attr1" attributes, the +di_forkoff+ is set to somewhere in the middle of the space between the core and end of the inode and never changes (which has the effect of artificially limiting the space for data information). As the data -fork grows, when it gets to +di_forkoff+, it will move the data to the level +fork grows, when it gets to +di_forkoff+, it will move the data to the next format level (ie. local < extent < btree). If very little space is used for either attributes or data, then a good portion of the available inode space is wasted with this version. @@ -446,3 +453,5 @@ The following diagram compares the two versions: .Extended attribute layouts image::images/30.png[] +Note that because +di_forkoff+ is an 8-bit value measuring units of 8 bytes, +the maximum size of an inode is 2^8^ × 2^3^ = 2^11^ = 2048 bytes. From darrick.wong@oracle.com Wed Nov 11 13:23:56 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 A17777F6B for ; Wed, 11 Nov 2015 13:23:56 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 93D7B8F8033 for ; Wed, 11 Nov 2015 11:23:56 -0800 (PST) X-ASG-Debug-ID: 1447269834-04cbb0242512ccc0001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id Gy2AIS1Ntz4xJ1xI (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 11 Nov 2015 11:23:54 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tABJNXJf024782 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 11 Nov 2015 19:23:33 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id tABJNWJO023465 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 11 Nov 2015 19:23:33 GMT Received: from abhmp0011.oracle.com (abhmp0011.oracle.com [141.146.116.17]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id tABJNWFH032729; Wed, 11 Nov 2015 19:23:32 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 11 Nov 2015 11:23:32 -0800 Subject: [PATCH 10/21] xfsdocs: add missing xfs_db examples From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 10/21] xfsdocs: add missing xfs_db examples To: hch@infradead.org, david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Wed, 11 Nov 2015 11:23:23 -0800 Message-ID: <20151111192323.14235.4359.stgit@birch.djwong.org> In-Reply-To: <20151111192218.14235.13928.stgit@birch.djwong.org> References: <20151111192218.14235.13928.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1447269834 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24309 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Fix some of the more egregious missing xfs_db examples so that the reader can appreciate what the data structures look like. Signed-off-by: Darrick J. Wong --- .../allocation_groups.asciidoc | 74 ++++++++++++++++++++ .../XFS_Filesystem_Structure/data_extents.asciidoc | 41 +++++++++++ .../XFS_Filesystem_Structure/directories.asciidoc | 55 +++++++++++++++ design/XFS_Filesystem_Structure/docinfo.xml | 1 4 files changed, 168 insertions(+), 3 deletions(-) diff --git a/design/XFS_Filesystem_Structure/allocation_groups.asciidoc b/design/XFS_Filesystem_Structure/allocation_groups.asciidoc index e958039..7d4c11b 100644 --- a/design/XFS_Filesystem_Structure/allocation_groups.asciidoc +++ b/design/XFS_Filesystem_Structure/allocation_groups.asciidoc @@ -831,7 +831,79 @@ image::images/20b.png[] ==== xfs_db AGI Example -TODO + +This is an AGI of a freshly populated filesystem: + +---- +xfs_db> agi 0 +xfs_db> p +magicnum = 0x58414749 +versionnum = 1 +seqno = 0 +length = 825457 +count = 5440 +root = 3 +level = 1 +freecount = 9 +newino = 5792 +dirino = null +unlinked[0-63] = +uuid = 3dfa1e5c-5a5f-4ca2-829a-000e453600fe +lsn = 0x1000032c2 +crc = 0x14cb7e5c (correct) +free_root = 4 +free_level = 1 +---- + +From this example, we see that the inode B+tree is rooted at AG block 3 and +that the free inode B+tree is rooted at AG block 4. Let's look at the +inode B+tree: + +---- +xfs_db> addr root +xfs_db> p +magic = 0x49414233 +level = 0 +numrecs = 85 +leftsib = null +rightsib = null +bno = 24 +lsn = 0x1000032c2 +uuid = 3dfa1e5c-5a5f-4ca2-829a-000e453600fe +owner = 0 +crc = 0x768f9592 (correct) +recs[1-85] = [startino,freecount,free] + 1:[96,0,0] 2:[160,0,0] 3:[224,0,0] 4:[288,0,0] + 5:[352,0,0] 6:[416,0,0] 7:[480,0,0] 8:[544,0,0] + 9:[608,0,0] 10:[672,0,0] 11:[736,0,0] 12:[800,0,0] + ... + 85:[5792,9,0xff80000000000000] +---- + +Most of the inode chunks on this filesystem are totally full, since the +free+ +value is zero. This means that we ought to expect inode 160 to be linked +somewhere in the directory structure. However, notice that 0xff80000000000000 +in record 85 -- this means that we would expect inode 5856 to be free. Moving +on to the free inode B+tree, we see that this is indeed the case: + +---- +xfs_db> addr free_root +xfs_db> p +magic = 0x46494233 +level = 0 +numrecs = 1 +leftsib = null +rightsib = null +bno = 32 +lsn = 0x1000032c2 +uuid = 3dfa1e5c-5a5f-4ca2-829a-000e453600fe +owner = 0 +crc = 0x338af88a (correct) +recs[1] = [startino,freecount,free] 1:[5792,9,0xff80000000000000] +---- + +Observe also that the AGI's +agi_newino+ points to this chunk, which has never +been fully allocated. [[Real-time_Devices]] == Real-time Devices diff --git a/design/XFS_Filesystem_Structure/data_extents.asciidoc b/design/XFS_Filesystem_Structure/data_extents.asciidoc index d1617f1..5df6623 100644 --- a/design/XFS_Filesystem_Structure/data_extents.asciidoc +++ b/design/XFS_Filesystem_Structure/data_extents.asciidoc @@ -302,4 +302,43 @@ image::images/36.png[] === xfs_db bmbt Example -TODO +In this example, we dissect the data fork of a VM image that is sufficiently +sparse and interleaved to have become a B+tree. + +---- +xfs_db> inode 132 +xfs_db> p +core.magic = 0x494e +core.mode = 0100600 +core.version = 3 +core.format = 3 (btree) +... +u3.bmbt.level = 1 +u3.bmbt.numrecs = 3 +u3.bmbt.keys[1-3] = [startoff] 1:[0] 2:[9072] 3:[13136] +u3.bmbt.ptrs[1-3] = 1:8568 2:8569 3:8570 +---- + +As you can see, the block map B+tree is rooted in the inode. This tree has two +levels, so let's go down a level to look at the records: + +---- +xfs_db> addr u3.bmbt.ptrs[1] +xfs_db> p +magic = 0x424d4133 +level = 0 +numrecs = 251 +leftsib = null +rightsib = 8569 +bno = 68544 +lsn = 0x100000006 +uuid = 9579903c-333f-4673-a7d4-3254c05816ea +owner = 132 +crc = 0xc61513dc (correct) +recs[1-251] = [startoff,startblock,blockcount,extentflag] + 1:[0,8520,48,0] 2:[48,4421,16,0] 3:[80,9136,16,0] 4:[96,8569,16,0] + 5:[144,8601,32,0] 6:[192,8637,16,0] 7:[240,8680,16,0] 8:[288,9870,16,0] + 9:[320,9920,16,0] 10:[336,9950,16,0] 11:[384,4004,32,0] + 12:[432,6771,16,0] 13:[480,2702,16,0] 14:[528,8420,16,0] + ... +---- diff --git a/design/XFS_Filesystem_Structure/directories.asciidoc b/design/XFS_Filesystem_Structure/directories.asciidoc index 2df118e..73ede11 100644 --- a/design/XFS_Filesystem_Structure/directories.asciidoc +++ b/design/XFS_Filesystem_Structure/directories.asciidoc @@ -269,8 +269,61 @@ b0: 72 61 6d 65 30 30 30 30 30 33 2e 74 73 74 01 80 rame000003.tst.. c0: 00 84 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ ---- -TODO: 8-byte inode number example +This is an example of mixed 4-byte and 8-byte inodes in a directory: +---- +xfs_db> inode 1024 +xfs_db> p +core.magic = 0x494e +core.mode = 040755 +core.version = 3 +core.format = 1 (local) +core.nlinkv2 = 9 +... +core.size = 125 +core.nblocks = 0 +core.extsize = 0 +core.nextents = 0 +... +u3.sfdir3.hdr.count = 7 +u3.sfdir3.hdr.i8count = 4 +u3.sfdir3.hdr.parent.i8 = 1024 +u3.sfdir3.list[0].namelen = 3 +u3.sfdir3.list[0].offset = 0x60 +u3.sfdir3.list[0].name = "git" +u3.sfdir3.list[0].inumber.i8 = 1027 +u3.sfdir3.list[0].filetype = 2 +u3.sfdir3.list[1].namelen = 4 +u3.sfdir3.list[1].offset = 0x70 +u3.sfdir3.list[1].name = "home" +u3.sfdir3.list[1].inumber.i8 = 13422826546 +u3.sfdir3.list[1].filetype = 2 +u3.sfdir3.list[2].namelen = 10 +u3.sfdir3.list[2].offset = 0x80 +u3.sfdir3.list[2].name = "mike" +u3.sfdir3.list[2].inumber.i8 = 4299308032 +u3.sfdir3.list[2].filetype = 2 +u3.sfdir3.list[3].namelen = 3 +u3.sfdir3.list[3].offset = 0x98 +u3.sfdir3.list[3].name = "mtr" +u3.sfdir3.list[3].inumber.i8 = 13433252916 +u3.sfdir3.list[3].filetype = 2 +u3.sfdir3.list[4].namelen = 3 +u3.sfdir3.list[4].offset = 0xa8 +u3.sfdir3.list[4].name = "vms" +u3.sfdir3.list[4].inumber.i8 = 16647516355 +u3.sfdir3.list[4].filetype = 2 +u3.sfdir3.list[5].namelen = 5 +u3.sfdir3.list[5].offset = 0xb8 +u3.sfdir3.list[5].name = "rsync" +u3.sfdir3.list[5].inumber.i8 = 3494912 +u3.sfdir3.list[5].filetype = 2 +u3.sfdir3.list[6].namelen = 3 +u3.sfdir3.list[6].offset = 0xd0 +u3.sfdir3.list[6].name = "tmp" +u3.sfdir3.list[6].inumber.i8 = 1593379 +u3.sfdir3.list[6].filetype = 2 +---- [[Block_Directories]] == Block Directories diff --git a/design/XFS_Filesystem_Structure/docinfo.xml b/design/XFS_Filesystem_Structure/docinfo.xml index 32a502d..85ccda5 100644 --- a/design/XFS_Filesystem_Structure/docinfo.xml +++ b/design/XFS_Filesystem_Structure/docinfo.xml @@ -83,6 +83,7 @@ Miscellaneous fixes. Add missing field definitions. + Add some missing xfs_db examples. From darrick.wong@oracle.com Wed Nov 11 13:24:11 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 EC7E67FA5 for ; Wed, 11 Nov 2015 13:24:11 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id DFB258F804B for ; Wed, 11 Nov 2015 11:24:11 -0800 (PST) X-ASG-Debug-ID: 1447269850-04cbb0242512ccd0001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id TEbMVNjBOTMOyeHY (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 11 Nov 2015 11:24:10 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tABJNkxH026095 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 11 Nov 2015 19:23:47 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id tABJNkU8013055 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 11 Nov 2015 19:23:46 GMT Received: from abhmp0010.oracle.com (abhmp0010.oracle.com [141.146.116.16]) by userv0121.oracle.com (8.13.8/8.13.8) with ESMTP id tABJNjfE013236; Wed, 11 Nov 2015 19:23:46 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 11 Nov 2015 11:23:45 -0800 Subject: [PATCH 12/21] xfsdocs: introduce XFS at a high level From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 12/21] xfsdocs: introduce XFS at a high level To: hch@infradead.org, david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Wed, 11 Nov 2015 11:23:44 -0800 Message-ID: <20151111192344.14235.83160.stgit@birch.djwong.org> In-Reply-To: <20151111192218.14235.13928.stgit@birch.djwong.org> References: <20151111192218.14235.13928.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 8bit X-Source-IP: userv0021.oracle.com [156.151.31.71] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1447269850 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24309 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Provide a quick overview of the history and design goals of XFS, and specify what exactly this documentation aims to do. Signed-off-by: Darrick J. Wong --- .../allocation_groups.asciidoc | 9 +++-- design/XFS_Filesystem_Structure/docinfo.xml | 3 +- design/XFS_Filesystem_Structure/overview.asciidoc | 38 ++++++++++++++++++++ .../xfs_filesystem_structure.asciidoc | 31 +++++++++++++--- 4 files changed, 70 insertions(+), 11 deletions(-) create mode 100644 design/XFS_Filesystem_Structure/overview.asciidoc diff --git a/design/XFS_Filesystem_Structure/allocation_groups.asciidoc b/design/XFS_Filesystem_Structure/allocation_groups.asciidoc index 0527ecc..346f1b2 100644 --- a/design/XFS_Filesystem_Structure/allocation_groups.asciidoc +++ b/design/XFS_Filesystem_Structure/allocation_groups.asciidoc @@ -1,10 +1,11 @@ [[Allocation_Groups]] = Allocation Groups -XFS filesystems are divided into a number of equally sized chunks called -Allocation Groups. Each AG can almost be thought of as an individual filesystem -that maintains its own space usage. Each AG can be up to one terabyte in size -(512 bytes × 2^31^), regardless of the underlying device's sector size. +As mentioned earlier, XFS filesystems are divided into a number of equally +sized chunks called Allocation Groups. Each AG can almost be thought of as an +individual filesystem that maintains its own space usage. Each AG can be up to +one terabyte in size (512 bytes × 2^31^), regardless of the underlying device's +sector size. Each AG has the following characteristics: diff --git a/design/XFS_Filesystem_Structure/docinfo.xml b/design/XFS_Filesystem_Structure/docinfo.xml index 85ccda5..6620acf 100644 --- a/design/XFS_Filesystem_Structure/docinfo.xml +++ b/design/XFS_Filesystem_Structure/docinfo.xml @@ -1,7 +1,7 @@ 3rd Edition @@ -84,6 +84,7 @@ Miscellaneous fixes. Add missing field definitions. Add some missing xfs_db examples. + Add an overview of XFS. diff --git a/design/XFS_Filesystem_Structure/overview.asciidoc b/design/XFS_Filesystem_Structure/overview.asciidoc new file mode 100644 index 0000000..d15b50a --- /dev/null +++ b/design/XFS_Filesystem_Structure/overview.asciidoc @@ -0,0 +1,38 @@ += Overview + +XFS presents to users a standard Unix filesystem interface: a rooted +tree of directories, files, symbolic links, and devices. All five of those +entities are represented inside the filesystem by an index node, or ``inode''; +each node is uniquely referenced by an inode number. Directories consist of +(name, inode number) tuples and it is possible for multiple tuples to contain +the same inode number. Data blocks are associated with files by means of a +block map in each index node. It is also possible to attach (key, value) +tuples to any index node; these are known as ``extended attributes'', which +extend beyond the standard Unix file attributes. + +Internally, XFS filesystems are divided into a number of equally sized chunks +called Allocation Groups. Each AG can almost be thought of as an individual +filesystem that maintains its own space usage, index nodes, and other secondary +metadata. Having multiple AGs allows XFS to handle most operations in parallel +without degrading performance as the number of concurrent accesses increases. +Each allocation group uses multiple B+trees to maintain bookkeeping records +such as the locations of free blocks, the locations of allocated inodes, and +the locations of free inodes. + +Files, symbolic links, and directories can have up to two block maps, or +``forks'', which associate filesystems blocks with a particular file or +directory. The ``attribute fork'' tracks blocks used to store and index +extended attributes, whereas the ``data fork'' tracks file data blocks, +symbolic link targets, or directory blocks, depending on the type of the inode +record. Both forks associate a logical offset with an extent of physical +blocks, which makes sparse files and directories possible. Directory entries +and extended attributes are contained inside a second-level data structure +within the blocks that are mapped by the forks. This structure consists of +variable-length directory or attribute records and possible a second B+tree to +index these records. + +XFS employs a journalling log in which metadata changes are collected so that +filesystem operations can be carried out atomically in the case of a crash. +Furthermore, there is the concept of a real-time device wherein allocations are +tracked more simply and in larger chunks to reduce jitter in allocation +latency. diff --git a/design/XFS_Filesystem_Structure/xfs_filesystem_structure.asciidoc b/design/XFS_Filesystem_Structure/xfs_filesystem_structure.asciidoc index a78f3b9..9f4c096 100644 --- a/design/XFS_Filesystem_Structure/xfs_filesystem_structure.asciidoc +++ b/design/XFS_Filesystem_Structure/xfs_filesystem_structure.asciidoc @@ -16,17 +16,36 @@ High Level Design [partintro] -- -This document describes the layout of an XFS filesystem. - -It shows how to manually inspect it by showing examples using the xfs_db -user-space tool supplied with the XFS filesystem driver. - -TODO: More description. +XFS is a high performance filesystem which was designed to maximize parallel +throughput and to scale up to extremely large 64-bit storage systems. +Originally developed by SGI in October 1993 for IRIX, XFS can handle large +files, large filesystems, many inodes, large directories, large file +attributes, and large allocations. Filesystems are optimized for parallel +access by splitting the storage device into semi-autonomous allocation groups. +XFS employs branching trees (B+ trees) to facilitate fast searches of large +lists; it also uses delayed extent-based allocation to improve data contiguity +and IO performance. + +This document describes the on-disk layout of an XFS filesystem and how to use +the debugging tools +xfs_db+ and +xfs_logprint+ to inspect the metadata +structures. It also describes how on-disk metadata relates to the higher level +design goals. + +The information contained in this document derives from the XFS source code in +the Linux kernel as of v4.3. This book's source code is available at ++git://git.kernel.org/pub/scm/fs/xfs/xfs-documentation.git+. Feedback should +be sent to the XFS mailing list, currently at +xfs@oss.sgi.com+. + +[NOTE] +All fields in XFS metadata structures are in big-endian byte order except for +log items which are formatted in host order. -- // Push titles down one level :leveloffset: 1 +include::overview.asciidoc[] + include::common_types.asciidoc[] // return titles to normal From darrick.wong@oracle.com Wed Nov 11 13:24:11 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 4E6737F96 for ; Wed, 11 Nov 2015 13:24:11 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id E2F31AC004 for ; Wed, 11 Nov 2015 11:24:10 -0800 (PST) X-ASG-Debug-ID: 1447269846-04bdf03f031212e0001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id qHM22kKDFV3Ssgke (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 11 Nov 2015 11:24:06 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tABJNhII024962 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 11 Nov 2015 19:23:43 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id tABJNglv019139 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 11 Nov 2015 19:23:43 GMT Received: from abhmp0002.oracle.com (abhmp0002.oracle.com [141.146.116.8]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id tABJNd0E018303; Wed, 11 Nov 2015 19:23:39 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 11 Nov 2015 11:23:38 -0800 Subject: [PATCH 11/21] xfsdocs: fix quoted text markings From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 11/21] xfsdocs: fix quoted text markings To: hch@infradead.org, david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Wed, 11 Nov 2015 11:23:37 -0800 Message-ID: <20151111192337.14235.60760.stgit@birch.djwong.org> In-Reply-To: <20151111192218.14235.13928.stgit@birch.djwong.org> References: <20151111192218.14235.13928.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 8bit X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1447269846 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24309 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Use asciidoc quotes for quoted strings. Signed-off-by: Darrick J. Wong --- .../allocation_groups.asciidoc | 24 ++--- .../XFS_Filesystem_Structure/data_extents.asciidoc | 4 - .../XFS_Filesystem_Structure/directories.asciidoc | 98 ++++++++++---------- .../extended_attributes.asciidoc | 26 +++-- .../internal_inodes.asciidoc | 2 .../XFS_Filesystem_Structure/ondisk_inode.asciidoc | 32 +++---- .../symbolic_links.asciidoc | 8 +- 7 files changed, 97 insertions(+), 97 deletions(-) diff --git a/design/XFS_Filesystem_Structure/allocation_groups.asciidoc b/design/XFS_Filesystem_Structure/allocation_groups.asciidoc index 7d4c11b..0527ecc 100644 --- a/design/XFS_Filesystem_Structure/allocation_groups.asciidoc +++ b/design/XFS_Filesystem_Structure/allocation_groups.asciidoc @@ -93,7 +93,7 @@ struct xfs_sb }; ---- *sb_magicnum*:: -Identifies the filesystem. Its value is +XFS_SB_MAGIC = 0x58465342 "XFSB"+. +Identifies the filesystem. Its value is +XFS_SB_MAGIC+ ``XFSB'' (0x58465342). *sb_blocksize*:: The size of a basic unit of space allocation in bytes. Typically, this is 4096 @@ -269,7 +269,7 @@ Miscellaneous flags. |===== *sb_shared_vn*:: -Reserved and must be zero ("vn" stands for version number). +Reserved and must be zero (``vn'' stands for version number). *sb_inoalignmt*:: Inode chunk alignment in fsblocks. @@ -413,8 +413,8 @@ All block numbers, indexes, and counts are AG relative. === AG Free Space Block The second sector in an AG contains the information about the two free space -B+trees and associated free space information for the AG. The "AG Free Space -Block", also knows as the +AGF+, uses the following structure: +B+trees and associated free space information for the AG. The ``AG Free Space +Block'' also knows as the +AGF+, uses the following structure: [source, c] ---- @@ -441,7 +441,7 @@ index 0 for the free space B+tree indexed by block number; and index 1 for the free space B+tree indexed by extent size. *agf_magicnum*:: -Specifies the magic number for the AGF sector: "XAGF" (0x58414746). +Specifies the magic number for the AGF sector: ``XAGF'' (0x58414746). *agf_versionnum*:: Set to +XFS_AGF_VERSION+ which is currently 1. @@ -460,17 +460,17 @@ Specifies the block number for the root of the two free space B+trees. *agf_levels*:: Specifies the level or depth of the two free space B+trees. For a fresh AG, this -will be one, and the "roots" will point to a single leaf of level 0. +will be one, and the ``roots'' will point to a single leaf of level 0. *agf_flfirst*:: -Specifies the index of the first "free list" block. Free lists are covered in +Specifies the index of the first ``free list'' block. Free lists are covered in more detail later on. *agf_fllast*:: -Specifies the index of the last "free list" block. +Specifies the index of the last ``free list'' block. *agf_flcount*:: -Specifies the number of blocks in the "free list". +Specifies the number of blocks in the ``free list''. *agf_freeblks*:: Specifies the current number of free blocks in the AG. @@ -551,8 +551,8 @@ typedef __be32 xfs_alloc_ptr_t; * As the free space tracking is AG relative, all the block numbers are only 32-bits. -* The +bb_magic+ value depends on the B+tree: "ABTB" (0x41425442) for the block -offset B+tree, "ABTC" (0x41425443) for the block count B+tree. +* The +bb_magic+ value depends on the B+tree: ``ABTB'' (0x41425442) for the block +offset B+tree, ``ABTC'' (0x41425443) for the block count B+tree. * The +xfs_btree_sblock_t+ header is used for intermediate B+tree node as well as the leaves. * For a typical 4KB filesystem block size, the offset for the +xfs_alloc_ptr_t+ @@ -741,7 +741,7 @@ struct xfs_agi { } ---- *agi_magicnum*:: -Specifies the magic number for the AGI sector: "XAGI" (0x58414749). +Specifies the magic number for the AGI sector: ``XAGI'' (0x58414749). *agi_versionnum*:: Set to +XFS_AGI_VERSION+ which is currently 1. diff --git a/design/XFS_Filesystem_Structure/data_extents.asciidoc b/design/XFS_Filesystem_Structure/data_extents.asciidoc index 5df6623..af9ba44 100644 --- a/design/XFS_Filesystem_Structure/data_extents.asciidoc +++ b/design/XFS_Filesystem_Structure/data_extents.asciidoc @@ -3,7 +3,7 @@ XFS manages space using extents, which are defined as a starting location and length. A fork in an XFS inode maps a logical offset to a space extent. This -enables a file's extent map to support sparse files (i.e. "holes" in the file). +enables a file's extent map to support sparse files (i.e. ``holes'' in the file). A flag is also used to specify if the extent has been preallocated but has not yet been written (unwritten extent). @@ -259,7 +259,7 @@ struct xfs_btree_lblock { ---- *bb_magic*:: -Specifies the magic number for the BMBT block: "BMAP" (0x424d4150). +Specifies the magic number for the BMBT block: ``BMAP'' (0x424d4150). *bb_level*:: The level of the tree in which this block is found. If this value is 0, this diff --git a/design/XFS_Filesystem_Structure/directories.asciidoc b/design/XFS_Filesystem_Structure/directories.asciidoc index 73ede11..b539535 100644 --- a/design/XFS_Filesystem_Structure/directories.asciidoc +++ b/design/XFS_Filesystem_Structure/directories.asciidoc @@ -5,16 +5,16 @@ Only v2 directories covered here. v1 directories are obsolete. [NOTE] -The term "block" in this section will refer to directory blocks, not filesystem +The term ``block'' in this section will refer to directory blocks, not filesystem blocks unless otherwise specified. -The size of a "directory block" is defined by the xref:Superblocks[superblock's] +The size of a ``directory block'' is defined by the xref:Superblocks[superblock's] +sb_dirblklog+ value. The size in bytes = +sb_blocksize+ × 2^sb_dirblklog^. For example, if +sb_blocksize+ = 4096 and +sb_dirblklog+ = 2, the directory block size is 16384 bytes. Directory blocks are always allocated in multiples based on +sb_dirblklog+. Directory blocks cannot be more that 65536 bytes in size. -All directory entries contain the following "data": +All directory entries contain the following ``data'': * The entry's name (counted string consisting of a single byte +namelen+ followed by +name+ consisting of an array of 8-bit chars without a NULL @@ -26,17 +26,17 @@ directories. * An +offset+ or +tag+ used for iterative readdir calls. -All non-shortform directories also contain two additional structures: "leaves" -and "freespace indexes". +All non-shortform directories also contain two additional structures: ``leaves'' +and ``freespace indexes''. * Leaves contain the sorted hashed name value (+xfs_da_hashname()+ in -xfs_da_btree.c) and associated "address" which points to the effective offset +xfs_da_btree.c) and associated ``address'' which points to the effective offset into the directory's data structures. Leaves are used to optimise lookup operations. * Freespace indexes contain free space/empty entry tracking for quickly finding an appropriately sized location for new entries. They maintain the largest free -space for each "data" block. +space for each ``data'' block. A few common types are used for the directory structures: @@ -52,11 +52,11 @@ typedef __uint32_t xfs_dir2_dataptr_t; * Directory entries are stored within the inode. -* The only data stored is the name, inode number, and offset. No "leaf" or -"freespace index" information is required as an inode can only store a few +* The only data stored is the name, inode number, and offset. No ``leaf'' or +``freespace index'' information is required as an inode can only store a few entries. -* "." is not stored (as it's in the inode itself), and ".." is a dedicated +* ``.'' is not stored (as it's in the inode itself), and ``..'' is a dedicated +parent+ field in the header. * The number of directories that can be stored in an inode depends on the @@ -216,7 +216,7 @@ cO: 00 84 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ ---- Next, an entry is deleted (frame000001.tst), and any entries after the deleted -entry are moved or compacted to "cover" the hole: +entry are moved or compacted to ``cover'' the hole: ---- xfs_db> inode @@ -330,13 +330,13 @@ u3.sfdir3.list[6].filetype = 2 When the shortform directory space exceeds the space in an inode, the directory data is moved into a new single directory block outside the inode. The inode's -format is changed from "local" to "extent". Following is a list of points about +format is changed from ``local'' to ``extent'' Following is a list of points about block directories. -* All directory data is stored within the one directory block, including "." and -".." entries which are mandatory. +* All directory data is stored within the one directory block, including ``.'' and +``..'' entries which are mandatory. -* The block also contains "leaf" and "freespace index" information. +* The block also contains ``leaf'' and ``freespace index'' information. * The location of the block is defined by the inode's in-core xref:Extent_List[extent list]: the +di_u.u_bmx[0]+ value. The file offset in @@ -494,7 +494,7 @@ Following is a diagram of how these pieces fit together for a block directory. .Block directory layout image::images/43.png[] -* The magic number in the header is "XD2B" (0x58443242). +* The magic number in the header is ``XD2B'' (0x58443242). * The +tag+ in the +xfs_dir2_data_entry_t+ structure stores its offset from the start of the block. @@ -556,7 +556,7 @@ core.nextents = 1 u.bmx[0] = [startoff,startblock,blockcount,extentflag] 0:[0,2097164,1,0] ---- -Go to the "startblock" and show the raw disk data: +Go to the ``startblock'' and show the raw disk data: ---- xfs_db> dblock 0 @@ -584,7 +584,7 @@ xfs_db> p 130: ff ff 0e 78 00 00 00 00 00 00 00 00 00 00 00 00 ...x............ ---- -The "leaf" and "tail" structures are stored at the end of the block, so as the +The ``leaf'' and ``tail'' structures are stored at the end of the block, so as the directory grows, the middle is filled in: ---- @@ -652,7 +652,7 @@ btail.stale = 0 ---- [NOTE] -For block directories, all xfs_db fields are preceded with "b". +For block directories, all xfs_db fields are preceded with ``b''. For a simple lookup example, the hash of frame000000.tst is 0xb3a040b4. Looking up that value, we get an address of 0x6. Multiply that by 8, it becomes offset @@ -692,7 +692,7 @@ btail.count = 10 btail.stale = 1 ---- -A new "bestfree" value is added for the entry, the start of the entry is marked +A new ``bestfree'' value is added for the entry, the start of the entry is marked as unused with 0xffff (which overwrites the inode number for an actual entry), and the length of the space. The tag remains intact at the +offset+length - sizeof(tag)+. The address for the hash is also cleared. The affected areas are @@ -721,24 +721,24 @@ ff0: f3 a0 40 b4 00 00 00 1a 00 00 00 0a *00 00 00 01* ................. Once a Block Directory has filled the block, the directory data is changed into a new format. It still uses xref:Data_Extents[extents] and the same basic -structures, but the "data" and "leaf" are split up into their own extents. The -"leaf" information only occupies one extent. As "leaf" information is more -compact than "data" information, more than one "data" extent is common. +structures, but the ``data'' and ``leaf'' are split up into their own extents. The +``leaf'' information only occupies one extent. As ``leaf'' information is more +compact than ``data'' information, more than one ``data'' extent is common. * Block to Leaf conversions retain the existing block for the data entries and allocate a new block for the leaf and freespace index information. * As with all directories, data blocks must start at logical offset zero. -* The "leaf" block has a special offset defined by +XFS_DIR2_LEAF_OFFSET+. +* The ``leaf'' block has a special offset defined by +XFS_DIR2_LEAF_OFFSET+. Currently, this is 32GB and in the extent view, a block offset of 32GB / +sb_blocksize+. On a 4KB block filesystem, this is 0x800000 (8388608 decimal). -* Blocks with directory entries ("data" extents) have the magic number "X2D2" +* Blocks with directory entries (``data'' extents) have the magic number ``X2D2'' (0x58443244). -* The "data" extents have a new header (no "leaf" data): +* The ``data'' extents have a new header (no ``leaf'' data): [source, c] ---- @@ -756,7 +756,7 @@ Union of directory and unused entries, exactly the same as in a block directory. // split lists -* The "leaf" extent uses the following structures: +* The ``leaf'' extent uses the following structures: [source, c] ---- @@ -844,7 +844,7 @@ Padding to maintain alignment. * The size of the +ents+ array is specified by +hdr.count+. * The size of the +bests+ array is specified by the +tail.bestcount+, which is -also the number of "data" blocks for  the directory. The bests array maintains +also the number of ``data'' blocks for  the directory. The bests array maintains each data block's +bestfree[0].length+ value. .Leaf directory free entry detail @@ -876,8 +876,8 @@ u.bmx[0-2] = [startoff,startblock,blockcount,extentflag] 2:[8388608,4718605,1,0] ---- -As can be seen in this example, three blocks are used for "data" in two extents, -and the "leaf" extent has a logical offset of 8388608 blocks (32GB). +As can be seen in this example, three blocks are used for ``data'' in two extents, +and the ``leaf'' extent has a logical offset of 8388608 blocks (32GB). Examining the first block: @@ -931,9 +931,9 @@ du[119].tag = 0xff0 ---- [NOTE] -The xfs_db field output is preceded by a "d" for "data". +The xfs_db field output is preceded by a ``d'' for ``data''. -The next "data" block: +The next ``data'' block: ---- xfs_db> dblock 1 @@ -1015,7 +1015,7 @@ du[3].length = 0xf90 du[3].tag = 0x70 ---- -Examining the "leaf" block (with the fields preceded by an "l" for "leaf"): +Examining the ``leaf'' block (with the fields preceded by an ``l'' for ``leaf''): ---- xfs_db> dblock 8388608 @@ -1040,7 +1040,7 @@ ltail.bestcount = 3 ---- Note how the +lbests+ array correspond with the +bestfree[0].length+ values in -the "data" blocks: +the ``data'' blocks: ---- xfs_db> dblock 0 @@ -1098,28 +1098,28 @@ spaces. [[Node_Directories]] == Node Directories -When the "leaf" information fills a block, the extents undergo another -separation. All "freeindex" information moves into its own extent. Like Leaf -Directories, the "leaf" block maintained the best free space information for -each "data" block. This is not possible with more than one leaf. +When the ``leaf'' information fills a block, the extents undergo another +separation. All ``freeindex'' information moves into its own extent. Like Leaf +Directories, the ``leaf'' block maintained the best free space information for +each ``data'' block. This is not possible with more than one leaf. -* The "data" blocks stay the same as leaf directories. +* The ``data'' blocks stay the same as leaf directories. -* After the "freeindex" data moves to its own block, it is possible for the +* After the ``freeindex'' data moves to its own block, it is possible for the leaf data to fit within a single leaf block. This single leaf block has a magic number of +XFS_DIR2_LEAFN_MAGIC+ (0xd2ff). -* The "leaf" blocks eventually change into a B+tree with the generic B+tree -header pointing to directory "leaves" as described in +* The ``leaf'' blocks eventually change into a B+tree with the generic B+tree +header pointing to directory ``leaves'' as described in xref:Leaf_Directories[Leaf Directories]. Blocks with leaf data still have the +LEAFN_MAGIC+ magic number as outlined above. The top-level tree blocks are -called "nodes" and have a magic number of +XFS_DA_NODE_MAGIC+ (0xfebe). +called ``nodes'' and have a magic number of +XFS_DA_NODE_MAGIC+ (0xfebe). * Distinguishing between a combined leaf/freeindex block (+LEAF1_MAGIC+), a leaf-only block (+LEAFN_MAGIC+), and a btree node block (+NODE_MAGIC+) can only be done by examining the magic number. -* The new "freeindex" block(s) only contains the bests for each data block. +* The new ``freeindex'' block(s) only contains the bests for each data block. * The freeindex block uses the following structures: @@ -1134,7 +1134,7 @@ typedef struct xfs_dir2_free_hdr { ---- *magic*:: -The magic number of the free block, "XD2F" (0x0x58443246). +The magic number of the free block, ``XD2F'' (0x0x58443246). *firstdb*:: The starting directory block number for the bests array. @@ -1212,7 +1212,7 @@ start of the block. block is freed, the data extents contain a hole, and the freeindex's +hdr.nused+ value is decremented and the associated +bests[]+ entry is set to 0xffff. -* As the first data block always contains "." and "..", it's invalid for the +* As the first data block always contains ``.'' and ``..'', it's invalid for the directory to have a hole at the start. * The freeindex's +hdr.nvalid+ should always be the same as the number of @@ -1297,7 +1297,7 @@ du[5].length = 0x3f50 du[5].tag = 0 ---- -Next, the "node" block, the fields are preceded with 'n' for node blocks: +Next, the ``node'' block, the fields are preceded with 'n' for node blocks: ---- xfs_db> dblock 8388608 @@ -1409,9 +1409,9 @@ TODO: Example with a hole in the middle == B+tree Directories When the extent map in an inode grows beyond the inode's space, the inode format -is changed to a "btree". The inode contains a filesystem block point to the +is changed to a ``btree''. The inode contains a filesystem block point to the B+tree extent map for the directory's blocks. The B+tree extents contain the -extent map for the "data", "node", "leaf", and "freeindex" information as +extent map for the ``data'', ``node'', ``leaf'', and ``freeindex'' information as described in Node Directories. Refer to the previous section on B+tree xref:Btree_Extent_List[Data Extents] for diff --git a/design/XFS_Filesystem_Structure/extended_attributes.asciidoc b/design/XFS_Filesystem_Structure/extended_attributes.asciidoc index 2499f12..f268d66 100644 --- a/design/XFS_Filesystem_Structure/extended_attributes.asciidoc +++ b/design/XFS_Filesystem_Structure/extended_attributes.asciidoc @@ -26,8 +26,8 @@ To view extended attributes from the command line, use the +getfattr+ command. To set or delete extended attributes, use the +setfattr+ command. ACLs control should use the +getfacl+ and +setfacl+ commands. -XFS attributes supports three namespaces: "user", "trusted" (or "root" using -IRIX terminology), and "secure". +XFS attributes supports three namespaces: ``user'', ``trusted'' (or ``root'' using +IRIX terminology), and ``secure''. See the section about xref:Extended_Attribute_Versions[extended attributes] in the inode for instructions on how to calculate the location of the attributes. @@ -39,7 +39,7 @@ The following four sections describe each of the on-disk formats. == Short Form Attributes When the all extended attributes can fit within the inode's attribute fork, the -inode's +di_aformat+ is set to "local" and the attributes are stored in the +inode's +di_aformat+ is set to ``local'' and the attributes are stored in the inode's literal area starting at offset +di_forkoff × 8+. Shortform attributes use the following structures: @@ -85,9 +85,9 @@ A combination of the following: [options="header"] |===== | Flag | Description -| 0 | The attribute's namespace is "user". -| +XFS_ATTR_ROOT+ | The attribute's namespace is "trusted". -| +XFS_ATTR_SECURE+ | The attribute's namespace is "secure". +| 0 | The attribute's namespace is ``user''. +| +XFS_ATTR_ROOT+ | The attribute's namespace is ``trusted''. +| +XFS_ATTR_SECURE+ | The attribute's namespace is ``secure''. | +XFS_ATTR_INCOMPLETE+ | This attribute is being modified. | +XFS_ATTR_LOCAL+ | The attribute value is contained within this block. |===== @@ -314,10 +314,10 @@ an inode before they are moved to another filesystem block. == Leaf Attributes When an inode's attribute fork space is used up with shortform attributes and -more are added, the attribute format is migrated to "extents". +more are added, the attribute format is migrated to ``extents''. Extent based attributes use hash/index pairs to speed up an attribute lookup. -The first part of the "leaf" contains an array of fixed size hash/index pairs +The first part of the ``leaf'' contains an array of fixed size hash/index pairs with the flags stored as well. The remaining part of the leaf block contains the array name/value pairs, where each element varies in length. @@ -486,7 +486,7 @@ appropriate structure can be used. Since duplicate hash keys are possible, for each hash that matches during a lookup, the actual name string must be compared. -An "incomplete" bit is also used for attribute flags. It shows that an attribute +An ``incomplete'' bit is also used for attribute flags. It shows that an attribute is in the middle of being created and should not be shown to the user if we crash during the time that the bit is set. The bit is cleared when attribute has finished being set up. This is done because some large attributes cannot @@ -635,7 +635,7 @@ image::images/72.png[] === xfs_db Node Attribute Example -An inode with 1000 small attributes with the naming "attribute_n" where 'n' is a +An inode with 1000 small attributes with the naming ``attribute_n'' where 'n' is a number: ---- @@ -677,7 +677,7 @@ The hashes are in ascending order in the btree array, and if the hash for the attribute we are looking up is before the entry, we go to the addressed attribute block. -For example, to lookup attribute "attribute_267": +For example, to lookup attribute ``attribute_267'': ---- xfs_db> hash attribute_267 @@ -745,7 +745,7 @@ nvlist[84].value = "value_266\d" Each of the hash entries has +XFS_ATTR_LOCAL+ flag set (1), which means the attribute's value follows immediately after the name. Raw disk of the name/value -pair at offset 2864 (0xb30), highlighted with "value_267\d" following +pair at offset 2864 (0xb30), highlighted with ``value_267'' following immediately after the name: [subs="quotes"] @@ -768,7 +768,7 @@ has 2 unused bytes after it. == B+tree Attributes When the attribute's extent map in an inode grows beyond the available space, -the inode's attribute format is changed to a "btree". The inode contains root +the inode's attribute format is changed to a ``btree''. The inode contains root node of the extent B+tree which then address the leaves that contains the extent arrays for the attribute data. The attribute data itself in the allocated filesystem blocks use the same layout and structures as described in diff --git a/design/XFS_Filesystem_Structure/internal_inodes.asciidoc b/design/XFS_Filesystem_Structure/internal_inodes.asciidoc index a926857..837f025 100644 --- a/design/XFS_Filesystem_Structure/internal_inodes.asciidoc +++ b/design/XFS_Filesystem_Structure/internal_inodes.asciidoc @@ -65,7 +65,7 @@ struct xfs_dqblk { *d_magic*:: Specifies the signature where these two bytes are 0x4451 (+XFS_DQUOT_MAGIC+), -or "DQ" in ASCII. +or ``DQ'' in ASCII. *d_version*:: The structure version, currently this is 1 (+XFS_DQUOT_VERSION+). diff --git a/design/XFS_Filesystem_Structure/ondisk_inode.asciidoc b/design/XFS_Filesystem_Structure/ondisk_inode.asciidoc index a887f8e..da6281b 100644 --- a/design/XFS_Filesystem_Structure/ondisk_inode.asciidoc +++ b/design/XFS_Filesystem_Structure/ondisk_inode.asciidoc @@ -15,7 +15,7 @@ image::images/23.png[] * The core contains what the inode represents, stat data, and information describing the data and attribute forks. -* The +di_u+ "data fork" contains normal data related to the inode. Its contents +* The +di_u+ ``data fork'' contains normal data related to the inode. Its contents depends on the file type specified by +di_core.di_mode+ (eg. regular file, directory, link, etc) and how much information is contained in the file which determined by +di_core.di_format+. The following union to represent this data is @@ -34,7 +34,7 @@ union { } di_u; ---- -* The +di_a+ "attribute fork" contains extended attributes. Its layout is +* The +di_a+ ``attribute fork'' contains extended attributes. Its layout is determined by the +di_core.di_aformat+ value. Its representation is declared as follows: @@ -54,7 +54,7 @@ within the union are directly cast depending on the +di_mode/di_format+ and explain the various structures in use within the inode. The remaining space in the inode after +di_next_unlinked+ where the two forks -are located is called the inode's "literal area". This starts at offset 100 +are located is called the inode's ``literal area''. This starts at offset 100 (0x64) in the inode. The space for each of the two forks in the literal area is determined by the @@ -103,7 +103,7 @@ struct xfs_dinode_core { ---- *di_magic*:: -The inode signature; these two bytes are 0x494e, or "IN" in ASCII. +The inode signature; these two bytes are ``IN'' (0x494e). *di_mode*:: Specifies the mode access bits and type of file using the standard S_Ixxx values @@ -117,13 +117,13 @@ converted on the fly to v2 when required. *di_format*:: Specifies the format of the data fork in conjunction with the +di_mode+ type. -This can be one of several values. For directories and links, it can be "local" -where all metadata associated with the file is within the inode; "extents" where +This can be one of several values. For directories and links, it can be ``local'' +where all metadata associated with the file is within the inode; ``extents'' where the inode contains an array of extents to other filesystem blocks which contain -the associated metadata or data; or "btree" where the inode contains a B+tree +the associated metadata or data; or ``btree'' where the inode contains a B+tree root node which points to filesystem blocks containing the metadata or data. Migration between the formats depends on the amount of metadata associated with -the inode. "dev" is used for character and block devices while "uuid" is +the inode. ``dev'' is used for character and block devices while ``uuid'' is currently not used. [source, c] @@ -171,7 +171,7 @@ Incremented on flush. Specifies the last access time of the files using UNIX time conventions the following structure. This value may be undefined if the filesystem is mounted -with the "noatime" option. XFS supports timestamps with nanosecond resolution: +with the ``noatime'' option. XFS supports timestamps with nanosecond resolution: [source, c] ---- @@ -226,7 +226,7 @@ details. *di_aformat*:: Specifies the format of the attribute fork. This uses the same values as -+di_format+, but restricted to "local", "extents" and "btree" formats for ++di_format+, but restricted to ``local'', ``extents'' and ``btree'' formats for extended attribute data. *di_dmevmask*:: @@ -312,10 +312,10 @@ image::images/28.png[] The structure of the inode's data fork based is on the inode's type and +di_format+. It always starts at offset 100 (0x64) in the inode's space which is -the start of the inode's "literal area". The size of the data fork is determined +the start of the inode's ``literal area''. The size of the data fork is determined by the type and format. The maximum size is determined by the inode size and +di_forkoff+. In code, use the +XFS_DFORK_PTR+ macro specifying +XFS_DATA_FORK+ -for the "which" parameter. Alternatively, the +XFS_DFORK_DPTR+ macro can be +for the ``which'' parameter. Alternatively, the +XFS_DFORK_DPTR+ macro can be used. Each of the following sub-sections summarises the contents of the data fork @@ -403,7 +403,7 @@ does not contain any extended attributes. If non-zero, the attribute fork's byte offset into the literal area can be computed from +di_forkoff × 8+. Attributes must be allocated on a 64-bit boundary on the disk. To access the extended attributes in code, use the +XFS_DFORK_PTR+ macro specifying -+XFS_ATTR_FORK+ for the "which" parameter. Alternatively, the +XFS_DFORK_APTR+ ++XFS_ATTR_FORK+ for the ``which'' parameter. Alternatively, the +XFS_DFORK_APTR+ macro can be used. The structure of the attribute fork depends on the +di_aformat+ value @@ -429,13 +429,13 @@ xref:Extended_Attributes[Extended Attributes] in this document. [[Extended_Attribute_Versions]] === Extended Attribute Versions -Extended attributes come in two versions: "attr1" or "attr2". The attribute +Extended attributes come in two versions: ``attr1'' or ``attr2''. The attribute version is specified by the +XFS_SB_VERSION2_ATTR2BIT+  flag in the +sb_features2+ field in the superblock. It determines how the inode's extra space is split between +di_u+ and +di_a+ forks which also determines how the +di_forkoff+ value is maintained in the inode's core. -With "attr1" attributes, the +di_forkoff+ is set to somewhere in the middle of +With ``attr1'' attributes, the +di_forkoff+ is set to somewhere in the middle of the space between the core and end of the inode and never changes (which has the effect of artificially limiting the space for data information). As the data fork grows, when it gets to +di_forkoff+, it will move the data to the next @@ -443,7 +443,7 @@ format level (ie. local < extent < btree). If very little space is used for either attributes or data, then a good portion of the available inode space is wasted with this version. -"Attr2" was introduced to maximum the utilisation of the inode's literal area. +``attr2'' was introduced to maximum the utilisation of the inode's literal area. The +di_forkoff+ starts at the end of the inode and works its way to the data fork as attributes are added. Attr2 is highly recommended if extended attributes are used. diff --git a/design/XFS_Filesystem_Structure/symbolic_links.asciidoc b/design/XFS_Filesystem_Structure/symbolic_links.asciidoc index 939c440..5d2c4e8 100644 --- a/design/XFS_Filesystem_Structure/symbolic_links.asciidoc +++ b/design/XFS_Filesystem_Structure/symbolic_links.asciidoc @@ -1,15 +1,15 @@ [[Symbolic_Links]] = Symbolic Links -Symbolic links to a file can be stored in one of two formats: "local" and -"extents". The length of the symlink contents is always specified by the inode's +Symbolic links to a file can be stored in one of two formats: ``local'' and +``extents''. The length of the symlink contents is always specified by the inode's +di_size+ value. [[Shortform_Symbolic_Links]] == Short Form Symbolic Links -Symbolic links are stored with the "local" +di_format+ if the symbolic link can +Symbolic links are stored with the ``local'' +di_format+ if the symbolic link can fit within the inode's data fork. The link data is an array of characters (+di_symlink+ array in the data fork union). @@ -58,7 +58,7 @@ xfs_db> p If the length of the symbolic link exceeds the space available in the inode's data fork, the link is moved to a new filesystem block and the inode's -+di_format+ is changed to "extents". The location of the block(s) is specified ++di_format+ is changed to ``extents''. The location of the block(s) is specified by the data fork's +di_bmx[]+ array. In the significant majority of cases, this will be in one filesystem block as a symlink cannot be longer than 1024 characters. From darrick.wong@oracle.com Wed Nov 11 13:24:21 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 40A5F7F74 for ; Wed, 11 Nov 2015 13:24:21 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 332FF8F8035 for ; Wed, 11 Nov 2015 11:24:21 -0800 (PST) X-ASG-Debug-ID: 1447269857-04cb6c296c125060001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id hQwRsE5yzZcFInz8 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 11 Nov 2015 11:24:17 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tABJNrIP026236 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 11 Nov 2015 19:23:53 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id tABJNqZu019474 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 11 Nov 2015 19:23:53 GMT Received: from abhmp0005.oracle.com (abhmp0005.oracle.com [141.146.116.11]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id tABJNqSD018370; Wed, 11 Nov 2015 19:23:52 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 11 Nov 2015 11:23:51 -0800 Subject: [PATCH 13/21] xfsdocs: document the xfs log format From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 13/21] xfsdocs: document the xfs log format To: hch@infradead.org, david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Wed, 11 Nov 2015 11:23:50 -0800 Message-ID: <20151111192350.14235.44655.stgit@birch.djwong.org> In-Reply-To: <20151111192218.14235.13928.stgit@birch.djwong.org> References: <20151111192218.14235.13928.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1447269857 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24309 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Discuss the on-disk log format and provide an example of walking through the log with xfs_logprint. Signed-off-by: Darrick J. Wong --- design/XFS_Filesystem_Structure/docinfo.xml | 1 .../journaling_log.asciidoc | 836 ++++++++++++++++++++ 2 files changed, 836 insertions(+), 1 deletion(-) diff --git a/design/XFS_Filesystem_Structure/docinfo.xml b/design/XFS_Filesystem_Structure/docinfo.xml index 6620acf..a6a992b 100644 --- a/design/XFS_Filesystem_Structure/docinfo.xml +++ b/design/XFS_Filesystem_Structure/docinfo.xml @@ -85,6 +85,7 @@ Add missing field definitions. Add some missing xfs_db examples. Add an overview of XFS. + Document the journal format. diff --git a/design/XFS_Filesystem_Structure/journaling_log.asciidoc b/design/XFS_Filesystem_Structure/journaling_log.asciidoc index 77c4430..798e3d4 100644 --- a/design/XFS_Filesystem_Structure/journaling_log.asciidoc +++ b/design/XFS_Filesystem_Structure/journaling_log.asciidoc @@ -1,3 +1,837 @@ +[[Journaling_Log]] = Journaling Log - TODO: +[NOTE] +Only v2 log format is covered here. + +The XFS journal exists on disk as a reserved extent of blocks within the +filesystem, or as a separate journal device. The journal itself can be thought +of as a series of log records; each log record contains a part of or a whole +transaction. A transaction consists of a series of log operation headers +(``log items''), formatting structures, and raw data. The first operation in a +transaction establishes the transaction ID and the last operation is a commit +record. The operations recorded between the start and commit operations +represent the metadata changes made by the transaction. If the commit +operation is missing, the transaction is incomplete and cannot be recovered. + +[[Log_Records]] +== Log Records + +The XFS log is split into a series of log records. Log records seem to +correspond to an in-core log buffer, which can be up to 256KiB in size. Each +record has a log sequence number, which is the same LSN recorded in the v5 +metadata integrity fields. + +Log sequence numbers are a 64-bit quantity consisting of two 32-bit quantities. +The upper 32 bits are the ``cycle number'', which increments every time XFS +cycles through the log. The lower 32 bits are the ``block number'', which is +assigned when a transaction is committed, and should correspond to the block +offset within the log. + +A log record begins with the following header, which occupies 512 bytes on +disk: + +[source, c] +---- +typedef struct xlog_rec_header { + __be32 h_magicno; + __be32 h_cycle; + __be32 h_version; + __be32 h_len; + __be64 h_lsn; + __be64 h_tail_lsn; + __le32 h_crc; + __be32 h_prev_block; + __be32 h_num_logops; + __be32 h_cycle_data[XLOG_HEADER_CYCLE_SIZE / BBSIZE]; + /* new fields */ + __be32 h_fmt; + uuid_t h_fs_uuid; + __be32 h_size; +} xlog_rec_header_t; +---- + +*h_magicno*:: +The magic number of log records, 0xfeedbabe. + +*h_cycle*:: +Cycle number of this log record. + +*h_version*:: +Log record version, currently 2. + +*h_len*:: +Length of the log record, in bytes. Must be aligned to a 64-bit boundary. + +*h_lsn*:: +Log sequence number of this record. + +*h_tail_lsn*:: +Log sequence number of the first log record with uncommitted buffers. + +*h_crc*:: +Checksum of the log record header, the cycle data, and the log records +themselves. + +*h_prev_block*:: +Block number of the previous log record. + +*h_num_logops*:: +The number of log operations in this record. + +*h_cycle_data*:: +The first u32 of each log sector must contain the cycle number. Since log +item buffers are formatted without regard to this requirement, the original +contents of the first four bytes of each sector in the log are copied into the +corresponding element of this array. After that, the first four bytes of those +sectors are stamped with the cycle number. This process is reversed at +recovery time. If there are more sectors in this log record than there are +slots in this array, the cycle data continues for as many sectors are needed; +each sector is formatted as type +xlog_rec_ext_header+. + +*h_fmt*:: +Format of the log record. This is one of the following values: + +.Log record formats +[options="header"] +|===== +| Format value | Log format +| +XLOG_FMT_UNKNOWN+ | Unknown. Perhaps this log is corrupt. +| +XLOG_FMT_LINUX_LE+ | Little-endian Linux. +| +XLOG_FMT_LINUX_BE+ | Big-endian Linux. +| +XLOG_FMT_IRIX_BE+ | Big-endian Irix. +|===== + +*h_fs_uuid*:: +Filesystem UUID. + +*h_size*:: +In-core log record size. This is somewhere between 16 and 256KiB, with 32KiB +being the default. + +As mentioned earlier, if this log record is longer than 256 sectors, the cycle +data overflows into the next sector(s) in the log. Each of those sectors is +formatted as follows: + +[source, c] +---- +typedef struct xlog_rec_ext_header { + __be32 xh_cycle; + __be32 xh_cycle_data[XLOG_HEADER_CYCLE_SIZE / BBSIZE]; +} xlog_rec_ext_header_t; +---- + +*xh_cycle*:: +Cycle number of this log record. Should match +h_cycle+. + +*xh_cycle_data*:: +Overflow cycle data. + +[[Log_Operations]] +== Log Operations + +Within a log record, log operations are recorded as a series consisting of an +operation header immediately followed by a data region. The operation header +has the following format: + +[source, c] +---- +typedef struct xlog_op_header { + __be32 oh_tid; + __be32 oh_len; + __u8 oh_clientid; + __u8 oh_flags; + __u16 oh_res2; +} xlog_op_header_t; +---- + +*oh_tid*:: +Transaction ID of this operation. + +*oh_len*:: +Number of bytes in the data region. + +*oh_clientid*:: +The originator of this operation. This can be one of the following: + +.Log Operation Client ID +[options="header"] +|===== +| Client ID | Originator +| +XFS_TRANSACTION+ | Operation came from a transaction. +| +XFS_VOLUME+ | ??? +| +XFS_LOG+ | ??? +|===== + +*oh_flags*:: +Specifies flags associated with this operation. This can be a combination of +the following values (though most likely only one will be set at a time): + +.Log Operation Flags +[options="header"] +|===== +| Flag | Description +| +XLOG_START_TRANS+ | Start a new transaction. The next operation header should describe a transaction header. +| +XLOG_COMMIT_TRANS+ | Commit this transaction. +| +XLOG_CONTINUE_TRANS+ | Continue this trans into new log record. +| +XLOG_WAS_CONT_TRANS+ | This transaction started in a previous log record. +| +XLOG_END_TRANS+ | End of a continued transaction. +| +XLOG_UNMOUNT_TRANS+ | Transaction to unmount a filesystem. +|===== + +*oh_res2*:: +Padding. + +The data region follows immediately after the operation header and is exactly ++oh_len+ bytes long. These payloads are in host-endian order, which means that +one cannot replay the log from an unclean XFS filesystem on a system with a +different byte order. + +[[Log_Items]] +== Log Items + +Following are the types of log item payloads that can follow an ++xlog_op_header+. Except for buffer data and inode cores, all log items have a +magic number to distinguish themselves. Buffer data items only appear after ++xfs_buf_log_format+ items; and inode core items only appear after ++xfs_inode_log_format+ items. + +.Log Operation Magic Numbers +[options="header"] +|===== +| Magic | Hexadecimal | Operation Type +| +XFS_TRANS_HEADER_MAGIC+ | 0x5452414e | xref:Log_Transaction_Headers[Log Transaction Header] +| +XFS_LI_EFI+ | 0x1236 | xref:EFI_Log_Item[Extent Freeing Intent] +| +XFS_LI_EFD+ | 0x1237 | xref:EFD_Log_Item[Extent Freeing Done] +| +XFS_LI_IUNLINK+ | 0x1238 | Unknown? +| +XFS_LI_INODE+ | 0x123b | xref:Inode_Log_Item[Inode Updates] +| +XFS_LI_BUF+ | 0x123c | xref:Buffer_Log_Item[Buffer Writes] +| +XFS_LI_DQUOT+ | 0x123d | xref:Quota_Update_Log_Item[Update Quota] +| +XFS_LI_QUOTAOFF+ | 0x123e | xref:Quota_Off_Log_Item[Quota Off] +| +XFS_LI_ICREATE+ | 0x123f | xref:Inode_Create_Log_Item[Inode Creation] +|===== + +[[Log_Transaction_Headers]] +=== Transaction Headers + +A transaction header is an operation payload that starts a transaction. + +[source, c] +---- +typedef struct xfs_trans_header { + uint th_magic; + uint th_type; + __int32_t th_tid; + uint th_num_items; +} xfs_trans_header_t; +---- + +*th_magic*:: +The signature of a transaction header, ``TRAN'' (0x5452414e). Note that this +value is in host-endian order, not big-endian like the rest of XFS. + +*th_type*:: +Transaction type. This is one of the following values: + +[options="header"] +|===== +| Type | Description +| +XFS_TRANS_SETATTR_NOT_SIZE+ | Set an inode attribute that isn't the inode's size. +| +XFS_TRANS_SETATTR_SIZE+ | Setting the size attribute of an inode. +| +XFS_TRANS_INACTIVE+ | Freeing blocks from an unlinked inode. +| +XFS_TRANS_CREATE+ | Create a file. +| +XFS_TRANS_CREATE_TRUNC+ | Unused? +| +XFS_TRANS_TRUNCATE_FILE+ | Truncate a quota file. +| +XFS_TRANS_REMOVE+ | Remove a file. +| +XFS_TRANS_LINK+ | Link an inode into a directory. +| +XFS_TRANS_RENAME+ | Rename a path. +| +XFS_TRANS_MKDIR+ | Create a directory. +| +XFS_TRANS_RMDIR+ | Remove a directory. +| +XFS_TRANS_SYMLINK+ | Create a symbolic link. +| +XFS_TRANS_SET_DMATTRS+ | Set the DMAPI attributes of an inode. +| +XFS_TRANS_GROWFS+ | Expand the filesystem. +| +XFS_TRANS_STRAT_WRITE+ | Convert an unwritten extent or delayed-allocate some blocks to handle a write. +| +XFS_TRANS_DIOSTRAT+ | Allocate some blocks to handle a direct I/O write. +| +XFS_TRANS_WRITEID+ | Update an inode's preallocation flag. +| +XFS_TRANS_ADDAFORK+ | Add an attribute fork to an inode. +| +XFS_TRANS_ATTRINVAL+ | Erase the attribute fork of an inode. +| +XFS_TRANS_ATRUNCATE+ | Unused? +| +XFS_TRANS_ATTR_SET+ | Set an extended attribute. +| +XFS_TRANS_ATTR_RM+ | Remove an extended attribute. +| +XFS_TRANS_ATTR_FLAG+ | Unused? +| +XFS_TRANS_CLEAR_AGI_BUCKET+ | Clear a bad inode pointer in the AGI unlinked inode hash bucket. +| +XFS_TRANS_SB_CHANGE+ | Write the superblock to disk. +| +XFS_TRANS_QM_QUOTAOFF+ | Start disabling quotas. +| +XFS_TRANS_QM_DQALLOC+ | Allocate a disk quota structure. +| +XFS_TRANS_QM_SETQLIM+ | Adjust quota limits. +| +XFS_TRANS_QM_DQCLUSTER+ | Unused? +| +XFS_TRANS_QM_QINOCREATE+ | Create a (quota) inode with reference taken. +| +XFS_TRANS_QM_QUOTAOFF_END+ | Finish disabling quotas. +| +XFS_TRANS_FSYNC_TS+ | Update only inode timestamps. +| +XFS_TRANS_GROWFSRT_ALLOC+ | Grow the realtime bitmap and summary data for growfs. +| +XFS_TRANS_GROWFSRT_ZERO+ | Zero space in the realtime bitmap and summary data. +| +XFS_TRANS_GROWFSRT_FREE+ | Free space in the realtime bitmap and summary data. +| +XFS_TRANS_SWAPEXT+ | Swap data fork of two inodes. +| +XFS_TRANS_CHECKPOINT+ | Checkpoint the log. +| +XFS_TRANS_ICREATE+ | Unknown? +| +XFS_TRANS_CREATE_TMPFILE+ | Create a temporary file. +|===== + +*th_tid*:: +Transaction ID. + +*th_num_items*:: +The number of operations appearing after this operation, not including the +commit operation. In effect, this tracks the number of metadata change +operations in this transaction. + +[[EFI_Log_Item]] +=== Intent to Free an Extent + +The next two operation types work together to handle the freeing of filesystem +blocks. Naturally, the ranges of blocks to be freed can be expressed in terms +of extents: + +[source, c] +---- +typedef struct xfs_extent_32 { + __uint64_t ext_start; + __uint32_t ext_len; +} __attribute__((packed)) xfs_extent_32_t; + +typedef struct xfs_extent_64 { + __uint64_t ext_start; + __uint32_t ext_len; + __uint32_t ext_pad; +} xfs_extent_64_t; +---- + +*ext_start*:: +Start block of this extent. + +*ext_len*:: +Length of this extent. + +The ``extent freeing intent'' operation comes first; it tells the log that XFS +wants to free some extents. This record is crucial for correct log recovery +because it prevents the log from replaying blocks that are subsequently freed. +If the log lacks a corresponding ``extent freeing done'' operation, the +recovery process will free the extents. + +[source, c] +---- +typedef struct xfs_efi_log_format { + __uint16_t efi_type; + __uint16_t efi_size; + __uint32_t efi_nextents; + __uint64_t efi_id; + xfs_extent_t efi_extents[1]; +} xfs_efi_log_format_t; +---- + +*efi_type*:: +The signature of an EFI operation, 0x1236. This value is in host-endian order, +not big-endian like the rest of XFS. + +*efi_size*:: +Size of this log item. Should be 1. + +*efi_nextents*:: +Number of extents to free. + +*efi_id*:: +A 64-bit number that binds the corresponding EFD log item to this EFI log item. + +*efi_extents*:: +Variable-length array of extents to be freed. The array length is given by ++efi_nextents+. The record type will be either +xfs_extent_64_t+ or ++xfs_extent_32_t+; this can be determined from the log item size (+oh_len+) and +the number of extents (+efi_nextents+). + +[[EFD_Log_Item]] +=== Completion of Intent to Free an Extent + +The ``extent freeing done'' operation complements the ``extent freeing intent'' +operation. This second operation indicates that the block freeing actually +happened, so that log recovery needn't try to free the blocks. Typically, the +operations to update the free space B+trees follow immediately after the EFD. + +[source, c] +---- +typedef struct xfs_efd_log_format { + __uint16_t efd_type; + __uint16_t efd_size; + __uint32_t efd_nextents; + __uint64_t efd_efi_id; + xfs_extent_t efd_extents[1]; +} xfs_efd_log_format_t; +---- + +*efd_type*:: +The signature of an EFI operation, 0x1236. This value is in host-endian order, +not big-endian like the rest of XFS. + +*efd_size*:: +Size of this log item. Should be 1. + +*efd_nextents*:: +Number of extents to free. + +*efd_id*:: +A 64-bit number that binds the corresponding EFI log item to this EFD log item. + +*efd_extents*:: +Variable-length array of extents to be freed. The array length is given by ++efi_nextents+. The record type will be either +xfs_extent_64_t+ or ++xfs_extent_32_t+; this can be determined from the log item size (+oh_len+) and +the number of extents (+efi_nextents+). + +[[Inode_Log_Item]] +=== Inode Updates + +This operation records changes to an inode record. There are several types of +inode updates, each corresponding to different parts of the inode record. +Allowing updates to proceed at a sub-inode granularity reduces contention for +the inode, since different parts of the inode can be updated simultaneously. + +The actual buffer data are stored in subsequent log items. + +The inode log format header is as follows: + +[source, c] +---- +typedef struct xfs_inode_log_format_64 { + __uint16_t ilf_type; + __uint16_t ilf_size; + __uint32_t ilf_fields; + __uint16_t ilf_asize; + __uint16_t ilf_dsize; + __uint32_t ilf_pad; + __uint64_t ilf_ino; + union { + __uint32_t ilfu_rdev; + uuid_t ilfu_uuid; + } ilf_u; + __int64_t ilf_blkno; + __int32_t ilf_len; + __int32_t ilf_boffset; +} xfs_inode_log_format_64_t; +---- + +*ilf_type*:: +The signature of an inode update operation, 0x123b. This value is in +host-endian order, not big-endian like the rest of XFS. + +*ilf_size*:: +Number of operations involved in this update, including this format operation. + +*ilf_fields*:: +Specifies which parts of the inode are being updated. This can be certain +combinations of the following: + +[options="header"] +|===== +| Flag | Inode changes to log include: +| +XFS_ILOG_CORE+ | The standard inode fields. +| +XFS_ILOG_DDATA+ | Data fork's local data. +| +XFS_ILOG_DEXT+ | Data fork's extent list. +| +XFS_ILOG_DBROOT+ | Data fork's B+tree root. +| +XFS_ILOG_DEV+ | Data fork's device number. +| +XFS_ILOG_UUID+ | Data fork's UUID contents. +| +XFS_ILOG_ADATA+ | Attribute fork's local data. +| +XFS_ILOG_AEXT+ | Attribute fork's extent list. +| +XFS_ILOG_ABROOT+ | Attribute fork's B+tree root. +| +XFS_ILOG_DOWNER+ | Change the data fork owner on replay. +| +XFS_ILOG_AOWNER+ | Change the attr fork owner on replay. +| +XFS_ILOG_TIMESTAMP+ | Timestamps are dirty, but not necessarily anything else. Should never appear on disk. +| +XFS_ILOG_NONCORE+ | ( +XFS_ILOG_DDATA+ \| +XFS_ILOG_DEXT+ \| +XFS_ILOG_DBROOT+ \| +XFS_ILOG_DEV+ \| +XFS_ILOG_UUID+ \| +XFS_ILOG_ADATA+ \| +XFS_ILOG_AEXT+ \| +XFS_ILOG_ABROOT+ \| +XFS_ILOG_DOWNER+ \| +XFS_ILOG_AOWNER+ ) +| +XFS_ILOG_DFORK+ | ( +XFS_ILOG_DDATA+ \| +XFS_ILOG_DEXT+ \| +XFS_ILOG_DBROOT+ ) +| +XFS_ILOG_AFORK+ | ( +XFS_ILOG_ADATA+ \| +XFS_ILOG_AEXT+ \| +XFS_ILOG_ABROOT+ ) +| +XFS_ILOG_ALL+ | ( +XFS_ILOG_CORE+ \| +XFS_ILOG_DDATA+ \| +XFS_ILOG_DEXT+ \| +XFS_ILOG_DBROOT+ \| +XFS_ILOG_DEV+ \| +XFS_ILOG_UUID+ \| +XFS_ILOG_ADATA+ \| +XFS_ILOG_AEXT+ \| +XFS_ILOG_ABROOT+ \| +XFS_ILOG_TIMESTAMP+ \| +XFS_ILOG_DOWNER+ \| +XFS_ILOG_AOWNER+ ) +|===== + +*ilf_asize*:: +Size of the attribute fork, in bytes. + +*ilf_dsize*:: +Size of the data fork, in bytes. + +*ilf_ino*:: +Absolute node number. + +*ilfu_rdev*:: +Device number information, for a device file update. + +*ilfu_uuid*:: +UUID, for a UUID update? + +*ilf_blkno*:: +Block number of the inode buffer, in sectors. + +*ilf_len*:: +Length of inode buffer, in sectors. + +*ilf_boffset*:: +Byte offset of the inode in the buffer. + +Be aware that there is a nearly identical +xfs_inode_log_format_32+ which may +appear on disk. It is the same as +xfs_inode_log_format_64+, except that it is +missing the +ilf_pad+ field and is 52 bytes long as opposed to 56 bytes. + +[[Inode_Data_Log_Item]] +=== Inode Data Log Item + +This region contains the new contents of a part of an inode, as described in +the xref:Inode_Log_Item[previous section]. There are no magic numbers. + +If +XFS_ILOG_CORE+ is set in +ilf_fields+, the correpsonding data buffer must +be in the format +struct xfs_icdinode+, which has the same format as the first +96 bytes of an xref:On-disk_Inode[inode], but is recorded in host byte order. + +[[Buffer_Log_Item]] +=== Buffer Log Item + +This operation writes parts of a buffer to disk. The regions to write are +tracked in the data map; the actual buffer data are stored in subsequent log +items. + +[source, c] +---- +typedef struct xfs_buf_log_format { + unsigned short blf_type; + unsigned short blf_size; + ushort blf_flags; + ushort blf_len; + __int64_t blf_blkno; + unsigned int blf_map_size; + unsigned int blf_data_map[XFS_BLF_DATAMAP_SIZE]; +} xfs_buf_log_format_t; +---- + +*blf_type*:: +Magic number to specify a buffer log item, 0x123c. + +*blf_size*:: +Number of buffer data items following this item. + +*blf_flags*:: +Specifies flags associated with the buffer item. This can be any of the +following: + +[options="header"] +|===== +| Flag | Description +| +XFS_BLF_INODE_BUF+ | Inode buffer. These must be recovered before replaying items that change this buffer. +| +XFS_BLF_CANCEL+ | Don't recover this buffer, blocks are being freed. +| +XFS_BLF_UDQUOT_BUF+ | User quota buffer, don't recover if there's a subsequent quotaoff. +| +XFS_BLF_PDQUOT_BUF+ | Project quota buffer, don't recover if there's a subsequent quotaoff. +| +XFS_BLF_GDQUOT_BUF+ | Group quota buffer, don't recover if there's a subsequent quotaoff. +|===== + +*blf_len*:: +Number of sectors affected by this buffer. + +*blf_blkno*:: +Block number to write, in sectors. + +*blf_map_size*:: +The size of +blf_data_map+, in 32-bit words. + +*blf_data_map*:: +This variable-sized array acts as a dirty bitmap for the logged buffer. Each +1 bit represents a dirty region in the buffer, and each run of 1 bits +corresponds to a subsequent log item containing the new contents of the buffer +area. Each bit represents +(blf_len * 512) / (blf_map_size * NBBY)+ bytes. + +[[Buffer_Data_Log_Item]] +=== Buffer Data Log Item + +This region contains the new contents of a part of a buffer, as described in +the xref:Buffer_Log_Item[previous section]. There are no magic numbers. + +[[Quota_Update_Log_Item]] +=== Update Quota File + +This updates a block in a quota file. The buffer data must be in the next log +item. + +[source, c] +---- +typedef struct xfs_dq_logformat { + __uint16_t qlf_type; + __uint16_t qlf_size; + xfs_dqid_t qlf_id; + __int64_t qlf_blkno; + __int32_t qlf_len; + __uint32_t qlf_boffset; +} xfs_dq_logformat_t; +---- + +*qlf_type*:: +The signature of an inode create operation, 0x123e. This value is in +host-endian order, not big-endian like the rest of XFS. + +*qlf_size*:: +Size of this log item. Should be 2. + +*qlf_id*:: +The user/group/project ID to alter. + +*qlf_blkno*:: +Block number of the quota buffer, in sectors. + +*qlf_len*:: +Length of the quota buffer, in sectors. + +*qlf_boffset*:: +Buffer offset of the quota data to update, in bytes. + +[[Quota_Update_Data_Log_Item]] +=== Quota Update Data Log Item + +This region contains the new contents of a part of a buffer, as described in +the xref:Quota_Update_Log_Item[previous section]. There are no magic numbers. + +[[Quota_Off_Log_Item]] +=== Disable Quota Log Item + +A request to disable quota controls has the following format: + +[source, c] +---- +typedef struct xfs_qoff_logformat { + unsigned short qf_type; + unsigned short qf_size; + unsigned int qf_flags; + char qf_pad[12]; +} xfs_qoff_logformat_t; +---- + +*qf_type*:: +The signature of an inode create operation, 0x123d. This value is in +host-endian order, not big-endian like the rest of XFS. + +*qf_size*:: +Size of this log item. Should be 1. + +*qf_flags*:: +Specifies which quotas are being turned off. Can be a combination of the +following: + +[options="header"] +|===== +| Flag | Quota type to disable +| +XFS_UQUOTA_ACCT+ | User quotas. +| +XFS_PQUOTA_ACCT+ | Project quotas. +| +XFS_GQUOTA_ACCT+ | Group quotas. +|===== + +[[Inode_Create_Log_Item]] +=== Inode Creation Log Item + +This log item is created when inodes are allocated in-core. When replaying +this item, the specified inode records will be zeroed and some of the inode +fields populated with default values. + +[source, c] +---- +struct xfs_icreate_log { + __uint16_t icl_type; + __uint16_t icl_size; + __be32 icl_ag; + __be32 icl_agbno; + __be32 icl_count; + __be32 icl_isize; + __be32 icl_length; + __be32 icl_gen; +}; +---- + +*icl_type*:: +The signature of an inode create operation, 0x123f. This value is in +host-endian order, not big-endian like the rest of XFS. + +*icl_size*:: +Size of this log item. Should be 1. + +*icl_ag*:: +AG number of the inode chunk to create. + +*icl_agbno*:: +AG block number of the inode chunk. + +*icl_count*:: +Number of inodes to initialize. + +*icl_isize*:: +Size of each inode, in bytes. + +*icl_length*:: +Length of the extent being initialized, in blocks. + +*icl_gen*:: +Inode generation number to write into the new inodes. + +== xfs_logprint Example + +Here's an example of dumping the XFS log contents with +xfs_logprint+: + +---- +# xfs_logprint /dev/sda +xfs_logprint: /dev/sda contains a mounted and writable filesystem +xfs_logprint: + data device: 0xfc03 + log device: 0xfc03 daddr: 900931640 length: 879816 + +cycle: 48 version: 2 lsn: 48,0 tail_lsn: 47,879760 +length of Log Record: 19968 prev offset: 879808 num ops: 53 +uuid: 24afeec2-f418-46a2-a573-10091f5e200e format: little endian linux +h_size: 32768 +---- + +This is the log record header. + +---- +Oper (0): tid: 30483aec len: 0 clientid: TRANS flags: START +---- + +This operation indicates that we're starting a transaction, so the next +operation should record the transaction header. + +---- +Oper (1): tid: 30483aec len: 16 clientid: TRANS flags: none +TRAN: type: CHECKPOINT tid: 30483aec num_items: 50 +---- + +This operation records a transaction header. There should be fifty operations +in this transaction and the transaction ID is 0x30483aec. + +---- +Oper (2): tid: 30483aec len: 24 clientid: TRANS flags: none +BUF: #regs: 2 start blkno: 145400496 (0x8aaa2b0) len: 8 bmap size: 1 flags: 0x2000 +Oper (3): tid: 30483aec len: 3712 clientid: TRANS flags: none +BUF DATA +... +Oper (4): tid: 30483aec len: 24 clientid: TRANS flags: none +BUF: #regs: 3 start blkno: 59116912 (0x3860d70) len: 8 bmap size: 1 flags: 0x2000 +Oper (5): tid: 30483aec len: 128 clientid: TRANS flags: none +BUF DATA + 0 43544241 49010000 fa347000 2c357000 3a40b200 13000000 2343c200 13000000 + 8 3296d700 13000000 375deb00 13000000 8a551501 13000000 56be1601 13000000 +10 af081901 13000000 ec741c01 13000000 9e911c01 13000000 69073501 13000000 +18 4e539501 13000000 6549501 13000000 5d0e7f00 14000000 c6908200 14000000 + +Oper (6): tid: 30483aec len: 640 clientid: TRANS flags: none +BUF DATA + 0 7f47c800 21000000 23c0e400 21000000 2d0dfe00 21000000 e7060c01 21000000 + 8 34b91801 21000000 9cca9100 22000000 26e69800 22000000 4c969900 22000000 +... +90 1cf69900 27000000 42f79c00 27000000 6a99e00 27000000 6a99e00 27000000 +98 6a99e00 27000000 6a99e00 27000000 6a99e00 27000000 6a99e00 27000000 +---- + +Operations 4-6 describe two updates to a single dirty buffer at disk address +59,116,912. The first chunk of dirty data is 128 bytes long. Notice how the +first four bytes of the first chunk is 0x43544241? Remembering that log items +are in host byte order, reverse that to 0x41425443, which is the magic number +for the free space B+tree ordered by size. + +The second chunk is 640 bytes. There are more buffer changes, so we'll skip +ahead a few operations: + +---- +Oper (19): tid: 30483aec len: 56 clientid: TRANS flags: none +INODE: #regs: 2 ino: 0x63a73b4e flags: 0x1 dsize: 40 + blkno: 1412688704 len: 16 boff: 7168 +Oper (20): tid: 30483aec len: 96 clientid: TRANS flags: none +INODE CORE +magic 0x494e mode 0100600 version 2 format 3 +nlink 1 uid 1000 gid 1000 +atime 0x5633d58d mtime 0x563a391b ctime 0x563a391b +size 0x109dc8 nblocks 0x111 extsize 0x0 nextents 0x1b +naextents 0x0 forkoff 0 dmevmask 0x0 dmstate 0x0 +flags 0x0 gen 0x389071be +---- + +This is an update to the core of inode 0x63a73b4e. There were similar inode +core updates after this, so we'll skip ahead a bit: + +---- +Oper (32): tid: 30483aec len: 56 clientid: TRANS flags: none +INODE: #regs: 3 ino: 0x4bde428 flags: 0x5 dsize: 16 + blkno: 79553568 len: 16 boff: 4096 +Oper (33): tid: 30483aec len: 96 clientid: TRANS flags: none +INODE CORE +magic 0x494e mode 0100644 version 2 format 2 +nlink 1 uid 1000 gid 1000 +atime 0x563a3924 mtime 0x563a3931 ctime 0x563a3931 +size 0x1210 nblocks 0x2 extsize 0x0 nextents 0x1 +naextents 0x0 forkoff 0 dmevmask 0x0 dmstate 0x0 +flags 0x0 gen 0x2829c6f9 +Oper (34): tid: 30483aec len: 16 clientid: TRANS flags: none +EXTENTS inode data +---- + +This inode update changes both the core and also the data fork. Since we're +changing the block map, it's unsurprising that one of the subsequent operations +is an EFI: + +---- +Oper (37): tid: 30483aec len: 32 clientid: TRANS flags: none +EFI: #regs: 1 num_extents: 1 id: 0xffff8801147b5c20 +(s: 0x720daf, l: 1) +\---------------------------------------------------------------------------- +Oper (38): tid: 30483aec len: 32 clientid: TRANS flags: none +EFD: #regs: 1 num_extents: 1 id: 0xffff8801147b5c20 +\---------------------------------------------------------------------------- +Oper (39): tid: 30483aec len: 24 clientid: TRANS flags: none +BUF: #regs: 2 start blkno: 8 (0x8) len: 8 bmap size: 1 flags: 0x2800 +Oper (40): tid: 30483aec len: 128 clientid: TRANS flags: none +AGF Buffer: XAGF +ver: 1 seq#: 0 len: 56308224 +root BNO: 18174905 CNT: 18175030 +level BNO: 2 CNT: 2 +1st: 41 last: 46 cnt: 6 freeblks: 35790503 longest: 19343245 +\---------------------------------------------------------------------------- +Oper (41): tid: 30483aec len: 24 clientid: TRANS flags: none +BUF: #regs: 3 start blkno: 145398760 (0x8aa9be8) len: 8 bmap size: 1 flags: 0x2000 +Oper (42): tid: 30483aec len: 128 clientid: TRANS flags: none +BUF DATA +Oper (43): tid: 30483aec len: 128 clientid: TRANS flags: none +BUF DATA +\---------------------------------------------------------------------------- +Oper (44): tid: 30483aec len: 24 clientid: TRANS flags: none +BUF: #regs: 3 start blkno: 145400224 (0x8aaa1a0) len: 8 bmap size: 1 flags: 0x2000 +Oper (45): tid: 30483aec len: 128 clientid: TRANS flags: none +BUF DATA +Oper (46): tid: 30483aec len: 3584 clientid: TRANS flags: none +BUF DATA +\---------------------------------------------------------------------------- +Oper (47): tid: 30483aec len: 24 clientid: TRANS flags: none +BUF: #regs: 3 start blkno: 59066216 (0x3854768) len: 8 bmap size: 1 flags: 0x2000 +Oper (48): tid: 30483aec len: 128 clientid: TRANS flags: none +BUF DATA +Oper (49): tid: 30483aec len: 768 clientid: TRANS flags: none +BUF DATA +---- + +Here we see an EFI, followed by an EFD, followed by updates to the AGF and the +free space btrees. Most probably, we just unmapped a few blocks from a file. + +---- +Oper (50): tid: 30483aec len: 56 clientid: TRANS flags: none +INODE: #regs: 2 ino: 0x3906f20 flags: 0x1 dsize: 16 + blkno: 59797280 len: 16 boff: 0 +Oper (51): tid: 30483aec len: 96 clientid: TRANS flags: none +INODE CORE +magic 0x494e mode 0100644 version 2 format 2 +nlink 1 uid 1000 gid 1000 +atime 0x563a3938 mtime 0x563a3938 ctime 0x563a3938 +size 0x0 nblocks 0x0 extsize 0x0 nextents 0x0 +naextents 0x0 forkoff 0 dmevmask 0x0 dmstate 0x0 +flags 0x0 gen 0x35ed661 +\---------------------------------------------------------------------------- +Oper (52): tid: 30483aec len: 0 clientid: TRANS flags: COMMIT +---- + +One more inode core update and this transaction commits. From darrick.wong@oracle.com Wed Nov 11 13:24:26 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 3724729E06 for ; Wed, 11 Nov 2015 13:24:26 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 0EA438F8035 for ; Wed, 11 Nov 2015 11:24:26 -0800 (PST) X-ASG-Debug-ID: 1447269864-04bdf03f02121300001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id hENX9foAFlX9stZa (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 11 Nov 2015 11:24:24 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tABJO2BG025548 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 11 Nov 2015 19:24:03 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id tABJO2BV020193 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 11 Nov 2015 19:24:02 GMT Received: from abhmp0007.oracle.com (abhmp0007.oracle.com [141.146.116.13]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id tABJO2gT014494; Wed, 11 Nov 2015 19:24:02 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 11 Nov 2015 11:24:02 -0800 Subject: [PATCH 14/21] xfsdocs: document the operation of the realtime device and inodes From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 14/21] xfsdocs: document the operation of the realtime device and inodes To: hch@infradead.org, david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Wed, 11 Nov 2015 11:23:57 -0800 Message-ID: <20151111192357.14235.4600.stgit@birch.djwong.org> In-Reply-To: <20151111192218.14235.13928.stgit@birch.djwong.org> References: <20151111192218.14235.13928.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 8bit X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1447269864 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24309 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Signed-off-by: Darrick J. Wong --- .../allocation_groups.asciidoc | 17 +++++++++- design/XFS_Filesystem_Structure/docinfo.xml | 1 + .../internal_inodes.asciidoc | 35 +++++++++++--------- 3 files changed, 36 insertions(+), 17 deletions(-) diff --git a/design/XFS_Filesystem_Structure/allocation_groups.asciidoc b/design/XFS_Filesystem_Structure/allocation_groups.asciidoc index 346f1b2..9ba26c2 100644 --- a/design/XFS_Filesystem_Structure/allocation_groups.asciidoc +++ b/design/XFS_Filesystem_Structure/allocation_groups.asciidoc @@ -909,5 +909,18 @@ been fully allocated. [[Real-time_Devices]] == Real-time Devices -TODO - +The performance of the standard XFS allocator varies depending on the internal +state of the various metadata indices enabled on the filesystem. For +applications which need to minimize the jitter of allocation latency, XFS +supports the notion of a ``real-time device''. This is a special device +separate from the regular filesystem where extent allocations are tracked with +a bitmap and free space is indexed with a two-dimensional array. If an inode +is flagged with +XFS_DIFLAG_REALTIME+, its data will live on the real time +device. The metadata for real time devices is discussed in the section about +xref:Real-time_Inodes[real time inodes]. + +By placing the real time device (and the journal) on separate high-performance +storage devices, it is possible to reduce most of the unpredictability in I/O +response times that come from metadata operations. + +None of the XFS per-AG B+trees are involved with real time files. diff --git a/design/XFS_Filesystem_Structure/docinfo.xml b/design/XFS_Filesystem_Structure/docinfo.xml index a6a992b..9bcecad 100644 --- a/design/XFS_Filesystem_Structure/docinfo.xml +++ b/design/XFS_Filesystem_Structure/docinfo.xml @@ -86,6 +86,7 @@ Add some missing xfs_db examples. Add an overview of XFS. Document the journal format. + Document the realtime device. diff --git a/design/XFS_Filesystem_Structure/internal_inodes.asciidoc b/design/XFS_Filesystem_Structure/internal_inodes.asciidoc index 837f025..c21f8b4 100644 --- a/design/XFS_Filesystem_Structure/internal_inodes.asciidoc +++ b/design/XFS_Filesystem_Structure/internal_inodes.asciidoc @@ -160,24 +160,29 @@ Bitmap Inode and the Summary Inode. [[Real-Time_Bitmap_Inode]] === Real-Time Bitmap Inode -The Bitmap Inode tracks the used/free space in the real-time device using an -old-style bitmap. One bit is allocated per real-time extent. The size of an -extent is specified by the superblock's +sb_rextsize+ value. +The real time bitmap inode, +sb_rbmino+, tracks the used/free space in the +real-time device using an old-style bitmap. One bit is allocated per real-time +extent. The size of an extent is specified by the superblock's +sb_rextsize+ +value. The number of blocks used by the bitmap inode is equal to the number of -real-time extents (+sb_rextents+) divided by the block size (+sb_blocksize+) and -bits per byte. This value is stored in +sb_rbmblocks+. The nblocks and extent -array for the inode should match this. - -[source, c] - xfs_ino_t sb_rbmino; +real-time extents (+sb_rextents+) divided by the block size (+sb_blocksize+) +and bits per byte. This value is stored in +sb_rbmblocks+. The nblocks and +extent array for the inode should match this. Each real time block gets its +own bit in the bitmap. [[Real-Time_Summary_Inode]] === Real-Time Summary Inode -The Summary Inode keeps the used/free space accounting information for the -real-time device. - -[source, c] - xfs_ino_t sb_rsumino; - +The real time summary inode, +sb_rsumino+, tracks the used and free space +accounting information for the real-time device. This file indexes the +approximate location of each free extent on the real-time device first by +log2(extent size) and then by the real-time bitmap block number. The size of +the summary inode file is equal to +sb_rbmblocks+ × log2(realtime device size) +× sizeof(+xfs_suminfo_t+). The entry for a given log2(extent size) and +rtbitmap block number is 0 if there is no free extents of that size at that +rtbitmap location, and positive if there are any. + +This data structure is not particularly space efficient, however it is a very +fast way to provide the same data as the two free space B+trees for regular +files since the space is preallocated and metadata maintenance is minimal. From darrick.wong@oracle.com Wed Nov 11 13:24:37 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 30F6729DFC for ; Wed, 11 Nov 2015 13:24:37 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id D3CE9AC005 for ; Wed, 11 Nov 2015 11:24:36 -0800 (PST) X-ASG-Debug-ID: 1447269871-04bdf03f03121310001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id BD7fCrCr8NHfIUU7 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 11 Nov 2015 11:24:32 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tABJOAsk025734 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 11 Nov 2015 19:24:10 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id tABJO9qY020425 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 11 Nov 2015 19:24:10 GMT Received: from abhmp0004.oracle.com (abhmp0004.oracle.com [141.146.116.10]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id tABJO9q2018572; Wed, 11 Nov 2015 19:24:09 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 11 Nov 2015 11:24:08 -0800 Subject: [PATCH 15/21] xfsdocs: add documentation of v5 fields From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 15/21] xfsdocs: add documentation of v5 fields To: hch@infradead.org, david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Wed, 11 Nov 2015 11:24:07 -0800 Message-ID: <20151111192407.14235.89932.stgit@birch.djwong.org> In-Reply-To: <20151111192218.14235.13928.stgit@birch.djwong.org> References: <20151111192218.14235.13928.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1447269872 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/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=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24309 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Document the new fields and data structures added in XFS v5 filesystems. Signed-off-by: Darrick J. Wong --- .../allocation_groups.asciidoc | 223 +++++++++++++++++++ .../XFS_Filesystem_Structure/data_extents.asciidoc | 35 +++ .../XFS_Filesystem_Structure/directories.asciidoc | 230 +++++++++++++++++++- design/XFS_Filesystem_Structure/docinfo.xml | 16 + .../extended_attributes.asciidoc | 81 +++++++ .../internal_inodes.asciidoc | 15 + .../XFS_Filesystem_Structure/ondisk_inode.asciidoc | 62 +++++ .../symbolic_links.asciidoc | 45 ++++ 8 files changed, 675 insertions(+), 32 deletions(-) diff --git a/design/XFS_Filesystem_Structure/allocation_groups.asciidoc b/design/XFS_Filesystem_Structure/allocation_groups.asciidoc index 9ba26c2..845b359 100644 --- a/design/XFS_Filesystem_Structure/allocation_groups.asciidoc +++ b/design/XFS_Filesystem_Structure/allocation_groups.asciidoc @@ -40,8 +40,6 @@ superblock is one sector in length. The superblock is defined by the following structure. The description of each field follows. -TODO: update for v5 formats. - [source, c] ---- struct xfs_sb @@ -91,6 +89,20 @@ struct xfs_sb __uint16_t sb_logsectsize; __uint32_t sb_logsunit; __uint32_t sb_features2; + __uint32_t sb_bad_features2; + + /* version 5 superblock fields start here */ + __uint32_t sb_features_compat; + __uint32_t sb_features_ro_compat; + __uint32_t sb_features_incompat; + __uint32_t sb_features_log_incompat; + + __uint32_t sb_crc; + xfs_extlen_t sb_spino_align; + + xfs_ino_t sb_pquotino; + xfs_lsn_t sb_lsn; + uuid_t sb_meta_uuid; }; ---- *sb_magicnum*:: @@ -152,8 +164,8 @@ Number of blocks for the journaling log. Filesystem version number. This is a bitmask specifying the features enabled when creating the filesystem. Any disk checking tools or drivers that do not recognize any set bits must not operate upon the filesystem. Most of the flags -indicate features introduced over time. If the value of the lower nibble is 4, -the higher bits indicate feature flags as follows: +indicate features introduced over time. If the value of the lower nibble is >= +4, the higher bits indicate feature flags as follows: .Version 4 Superblock version flags [options="header"] @@ -178,13 +190,17 @@ Version 2 directories are used. This is always set. Set if the sb_features2 field in the superblock contains more flags. |===== +If the lower nibble of this value is 5, then this is a v5 filesystem; the ++XFS_SB_VERSION2_CRCBIT+ feature must be set in +sb_features2+. + *sb_sectsize*:: Specifies the underlying disk sector size in bytes. Typically this is 512 or 4096 bytes. This determines the minimum I/O alignment, especially for direct I/O. *sb_inodesize*:: Size of the inode in bytes. The default is 256 (2 inodes per standard sector) -but can be made as large as 2048 bytes when creating the filesystem. +but can be made as large as 2048 bytes when creating the filesystem. On a v5 +filesystem, the default inode size is 512 bytes. *sb_inopblock*:: Number of inodes per block. This is equivalent to +sb_blocksize / sb_inodesize+. @@ -324,12 +340,81 @@ its parent inode. The primary purpose for this information is in backup systems. can be used to enforce disk space usage quotas for a particular group of directories. This flag indicates that project IDs can be 32 bits in size. +| +XFS_SB_VERSION2_CRCBIT+ | +Metadata checksumming. All metadata blocks have an extended header containing +the block checksum, a copy of the metadata UUID, the log sequence number of the +last update to prevent stale replays, and a back pointer to the owner of the +block. This feature must be and can only be set if the lowest nibble of ++sb_versionnum+ is set to 5. + | +XFS_SB_VERSION2_FTYPE+ | Directory file type. Each directory entry records the type of the inode to which the entry points. This speeds up directory iteration by removing the need to load every inode into memory. |===== +*sb_bad_features2*:: +This field mirrors +sb_features2+, due to past 64-bit alignment errors. + +*sb_features_compat*:: +Read-write compatible feature flags. The kernel can still read and write this +FS even if it doesn't understand the flag. Currently, there are no valid +flags. + +*sb_features_ro_compat*:: +Read-only compatible feature flags. The kernel can still read this FS even if +it doesn't understand the flag. + +.Extended Version 5 Superblock Read-Only compatibility flags +[options="header"] +|===== +| Flag | Description +| +XFS_SB_FEAT_RO_COMPAT_FINOBT+ | +Free inode B+tree. Each allocation group contains a B+tree to track inode chunks +containing free inodes. This is a performance optimization to reduce the time +required to allocate inodes. +|===== + +*sb_features_incompat*:: +Read-write incompatible feature flags. The kernel cannot read or write this +FS if it doesn't understand the flag. + +.Extended Version 5 Superblock Read-Write incompatibility flags +[options="header"] +|===== +| Flag | Description +| +XFS_SB_FEAT_INCOMPAT_FTYPE+ | +Directory file type. Each directory entry tracks the type of the inode to +which the entry points. This is a performance optimization to remove the need +to load every inode into memory to iterate a directory. + +| +XFS_SB_FEAT_INCOMPAT_META_UUID+ | +Metadata UUID. The UUID stamped into each metadata block must match the value +in +sb_meta_uuid+. This enables the administrator to change +sb_uuid+ at will +without having to rewrite the entire filesystem. +|===== + +*sb_features_log_incompat*:: +Read-write incompatible feature flags for the log. The kernel cannot read or +write this FS log if it doesn't understand the flag. Currently, no flags are +defined. + +*sb_crc*:: +Superblock checksum. + +*sb_spino_align*:: +Sparse inode alignment. + +*sb_pquotino*:: +Project quota inode. + +*sb_lsn*:: +Log sequence number of the last superblock update. + +*sb_meta_uuid*:: +If the +XFS_SB_FEAT_INCOMPAT_META_UUID+ feature is set, then the UUID field in +all metadata blocks must match this UUID. If not, the block header UUID field +must match +sb_uuid+. === xfs_db Superblock Example @@ -405,7 +490,7 @@ features2 = 8 The XFS filesystem tracks free space in an allocation group using two B+trees. One B+tree tracks space by block number, the second by the size of the free -space block. This scheme allows XFS to quickly find free space near a given +space block. This scheme allows XFS to find quickly free space near a given block or of a given size. All block numbers, indexes, and counts are AG relative. @@ -434,6 +519,15 @@ struct xfs_agf { __be32 agf_freeblks; __be32 agf_longest; __be32 agf_btreeblks; + + /* version 5 filesystem fields start here */ + uuid_t agf_uuid; + __be64 agf_spare64[16]; + + /* unlogged fields, written during buffer writeback. */ + __be64 agf_lsn; + __be32 agf_crc; + __be32 agf_spare2; }; ---- @@ -483,6 +577,22 @@ Specifies the number of blocks of longest contiguous free space in the AG. Specifies the number of blocks used for the free space B+trees. This is only used if the +XFS_SB_VERSION2_LAZYSBCOUNTBIT+ bit is set in +sb_features2+. +*agf_uuid*:: +The UUID of this block, which must match either +sb_uuid+ or +sb_meta_uuid+ +depending on which features are set. + +*agf_spare64*:: +Empty space in the logged part of the AGF sector, for use for future features. + +*agf_lsn*:: +Log sequence number of the last AGF write. + +*agf_crc*:: +Checksum of the AGF sector. + +*agf_spare2*:: +Empty space in the unlogged part of the AGF sector. + [[Short_Format_Btrees]] === Short Format B+trees @@ -499,6 +609,13 @@ struct xfs_btree_sblock { __be16 bb_numrecs; __be32 bb_leftsib; __be32 bb_rightsib; + + /* version 5 filesystem fields start here */ + __be64 bb_blkno; + __be64 bb_lsn; + uuid_t bb_uuid; + __be32 bb_owner; + __le32 bb_crc; }; ---- @@ -519,6 +636,22 @@ AG block number of the left sibling of this B+tree node. *bb_rightsib*:: AG block number of the right sibling of this B+tree node. +*bb_blkno*:: +FS block number of this B+tree block. + +*bb_lsn*:: +Log sequence number of the last write to this block. + +*bb_uuid*:: +The UUID of this block, which must match either +sb_uuid+ or +sb_meta_uuid+ +depending on which features are set. + +*bb_owner*:: +The AG number that this B+tree block ought to be in. + +*bb_crc*:: +Checksum of the B+tree block. + [[AG_Free_Space_Btrees]] === AG Free Space B+trees @@ -553,7 +686,9 @@ typedef __be32 xfs_alloc_ptr_t; * As the free space tracking is AG relative, all the block numbers are only 32-bits. * The +bb_magic+ value depends on the B+tree: ``ABTB'' (0x41425442) for the block -offset B+tree, ``ABTC'' (0x41425443) for the block count B+tree. +offset B+tree, ``ABTC'' (0x41425443) for the block count B+tree. On a v5 +filesystem, these are ``AB3B'' (0x41423342) and ``AB3C'' (0x41423343), +respectively. * The +xfs_btree_sblock_t+ header is used for intermediate B+tree node as well as the leaves. * For a typical 4KB filesystem block size, the offset for the +xfs_alloc_ptr_t+ @@ -595,6 +730,38 @@ Active elements in the array are specified by the xref:AG_Free_Space_Block[AGF's] +agf_flfirst+, +agf_fllast+ and +agf_flcount+ values. The array is managed as a circular list. +On a v5 filesystem, the following header precedes the free list entries: + +[source, c] +---- +struct xfs_agfl { + __be32 agfl_magicnum; + __be32 agfl_seqno; + uuid_t agfl_uuid; + __be64 agfl_lsn; + __be32 agfl_crc; +}; +---- + +*agfl_magicnum*:: +Specifies the magic number for the AGFL sector: "XAFL" (0x5841464c). + +*agfl_seqno*:: +Specifies the AG number for the sector. + +*agfl_uuid*:: +The UUID of this block, which must match either +sb_uuid+ or +sb_meta_uuid+ +depending on which features are set. + +*agfl_lsn*:: +Log sequence number of the last AGFL write. + +*agfl_crc*:: +Checksum of the AGFL sector. + +On a v4 filesystem there is no header; the array of free block numbers begins +at the beginning of the sector. + .AG Free List layout image::images/16.png[] @@ -739,6 +906,18 @@ struct xfs_agi { __be32 agi_newino; __be32 agi_dirino; __be32 agi_unlinked[64]; + + /* + * v5 filesystem fields start here; this marks the end of logging region 1 + * and start of logging region 2. + */ + uuid_t agi_uuid; + __be32 agi_crc; + __be32 agi_pad32; + __be64 agi_lsn; + + __be32 agi_free_root; + __be32 agi_free_level; } ---- *agi_magicnum*:: @@ -775,19 +954,45 @@ Deprecated and not used, this is always set to NULL (-1). Hash table of unlinked (deleted) inodes that are still being referenced. Refer to xref:Unlinked_Pointer[unlinked list pointers] for more information. +*agi_uuid*:: +The UUID of this block, which must match either +sb_uuid+ or +sb_meta_uuid+ +depending on which features are set. + +*agi_crc*:: +Checksum of the AGI sector. + +*agi_pad32*:: +Padding field, otherwise unused. + +*agi_lsn*:: +Log sequence number of the last write to this block. + +*agi_free_root*:: +Specifies the block number in the AG containing the root of the free inode +B+tree. + +*agi_free_level*:: +Specifies the number of levels in the free inode B+tree. [[Inode_Btrees]] == Inode B+trees Inodes are allocated in chunks of 64, and a B+tree is used to track these chunks of inodes as they are allocated and freed. The block containing root of the -B+tree is defined by the AGI's +agi_root+ value. +B+tree is defined by the AGI's +agi_root+ value. If the ++XFS_SB_FEAT_RO_COMPAT_FINOBT+ feature is enabled, a second B+tree is used to +track the chunks containing free inodes; this is an optimization to speed up +inode allocation. The B+tree header for the nodes and leaves use the +xfs_btree_sblock+ structure which is the same as the header used in the xref:AG_Free_Space_Btrees[AGF B+trees]. -The magic number of the inode B+tree is ``IABT'' (0x49414254). +The magic number of the inode B+tree is ``IABT'' (0x49414254). On a v5 +filesystem, the magic number is ``IAB3'' (0x49414233). + +The magic number of the free inode B+tree is ``FIBT'' (0x46494254). On a v5 +filesystem, the magic number is ``FIB3'' (0x46494254). Leaves contain an array of the following structure: diff --git a/design/XFS_Filesystem_Structure/data_extents.asciidoc b/design/XFS_Filesystem_Structure/data_extents.asciidoc index af9ba44..a39045d 100644 --- a/design/XFS_Filesystem_Structure/data_extents.asciidoc +++ b/design/XFS_Filesystem_Structure/data_extents.asciidoc @@ -94,8 +94,9 @@ image::images/32.png[] The number of extents that can fit in the inode depends on the inode size and +di_forkoff+. For a default 256 byte inode with no extended attributes, a file -can have up to 9 extents with this format. Beyond this, extents have to use the -B+tree format. +can have up to 9 extents with this format. On a default v5 filesystem with 512 +byte inodes, a file can have up to 21 extents with this format. Beyond that, +extents have to use the B+tree format. === xfs_db Inode Data Fork Extents Example @@ -242,7 +243,7 @@ and the leaves. This will be less if +di_forkoff+ is not zero (i.e. attributes are in use on the inode). [[Long_Format_Btrees]] -== Long Format B+trees +=== Long Format B+trees The subsequent nodes and leaves of the B+tree use the +xfs_btree_lblock+ declaration: @@ -255,11 +256,20 @@ struct xfs_btree_lblock { __be16 bb_numrecs; __be64 bb_leftsib; __be64 bb_rightsib; + + /* version 5 filesystem fields start here */ + __be64 bb_blkno; + __be64 bb_lsn; + uuid_t bb_uuid; + __be64 bb_owner; + __le32 bb_crc; + __be32 bb_pad; }; ---- *bb_magic*:: Specifies the magic number for the BMBT block: ``BMAP'' (0x424d4150). +On a v5 filesystem, this is ``BMA3'' (0x424d4133). *bb_level*:: The level of the tree in which this block is found. If this value is 0, this @@ -275,6 +285,25 @@ FS block number of the left sibling of this B+tree node. *bb_rightsib*:: FS block number of the right sibling of this B+tree node. +*bb_blkno*:: +FS block number of this B+tree block. + +*bb_lsn*:: +Log sequence number of the last write to this block. + +*bb_uuid*:: +The UUID of this block, which must match either +sb_uuid+ or +sb_meta_uuid+ +depending on which features are set. + +*bb_owner*:: +The AG number that this B+tree block ought to be in. + +*bb_crc*:: +Checksum of the B+tree block. + +*bb_pad*:: +Pads the structure to 64 bytes. + // force-split the lists * For intermediate nodes, the data following +xfs_btree_lblock+ is the same as diff --git a/design/XFS_Filesystem_Structure/directories.asciidoc b/design/XFS_Filesystem_Structure/directories.asciidoc index b539535..bccf912 100644 --- a/design/XFS_Filesystem_Structure/directories.asciidoc +++ b/design/XFS_Filesystem_Structure/directories.asciidoc @@ -358,7 +358,7 @@ typedef struct xfs_dir2_block { ---- *hdr*:: -Directory block header. +Directory block header. On a v5 filesystem this is +xfs_dir3_data_hdr_t+. *u*:: Union of directory and unused entries. @@ -383,8 +383,62 @@ Magic number for this directory block. *bestfree*:: An array pointing to free regions in the directory block. +On a v5 filesystem, directory and attribute blocks are formatted with v3 +headers, which contain extra data: + [source, c] ---- +struct xfs_dir3_blk_hdr { + __be32 magic; + __be32 crc; + __be64 blkno; + __be64 lsn; + uuid_t uuid; + __be64 owner; +}; +---- + +*magic*:: +Magic number for this directory block. + +*crc*:: +Checksum of the directory block. + +*blkno*:: +Block number of this directory block. + +*lsn*:: +Log sequence number of the last write to this block. + +*uuid*:: +The UUID of this block, which must match either +sb_uuid+ or +sb_meta_uuid+ +depending on which features are set. + +*owner*:: +The inode number that this directory block belongs to. + +[source, c] +---- +struct xfs_dir3_data_hdr { + struct xfs_dir3_blk_hdr hdr; + xfs_dir2_data_free_t best_free[XFS_DIR2_DATA_FD_COUNT]; + __be32 pad; +}; +---- + +*hdr*:: +The v5 directory/attribute block header. + +*best_free*:: +An array pointing to free regions in the directory block. + +*pad*:: +Padding to maintain a 64-bit alignment. + +Within the block, data structures are as follows: + +[source, c] +----- typedef struct xfs_dir2_data_free { xfs_dir2_data_off_t offset; xfs_dir2_data_off_t length; @@ -494,7 +548,8 @@ Following is a diagram of how these pieces fit together for a block directory. .Block directory layout image::images/43.png[] -* The magic number in the header is ``XD2B'' (0x58443242). +* The magic number in the header is ``XD2B'' (0x58443242), or ``XDB3'' (0x58444233) +on a v5 filesystem. * The +tag+ in the +xfs_dir2_data_entry_t+ structure stores its offset from the start of the block. @@ -736,7 +791,7 @@ Currently, this is 32GB and in the extent view, a block offset of decimal). * Blocks with directory entries (``data'' extents) have the magic number ``X2D2'' -(0x58443244). +(0x58443244), or ``XDD3'' (0x58444433) on a v5 filesystem. * The ``data'' extents have a new header (no ``leaf'' data): @@ -749,7 +804,7 @@ typedef struct xfs_dir2_data { ---- *hdr*:: -Data block header. +Data block header. On a v5 filesystem, this field is +struct xfs_dir3_data_hdr+. *u*:: Union of directory and unused entries, exactly the same as in a block directory. @@ -769,7 +824,8 @@ typedef struct xfs_dir2_leaf { ---- *hdr*:: -Directory leaf header. +Directory leaf header. On a v5 filesystem this is +struct +xfs_dir3_leaf_hdr_t+. *ents*:: Hash values of the entries in this block. @@ -800,6 +856,28 @@ Number of stale/zeroed leaf entries. [source, c] ---- +struct xfs_dir3_leaf_hdr { + struct xfs_da3_blkinfo info; + __uint16_t count; + __uint16_t stale; + __be32 pad; +}; +---- + +*info*:: +Leaf B+tree block header. + +*count*:: +Number of leaf entries. + +*stale*:: +Number of stale/zeroed leaf entries. + +*pad*:: +Padding to maintain alignment rules. + +[source, c] +---- typedef struct xfs_dir2_leaf_tail { __uint32_t bestcount; } xfs_dir2_leaf_tail_t; @@ -839,7 +917,58 @@ Padding to maintain alignment. // split lists -* The magic number of the leaf block is +XFS_DIR2_LEAF1_MAGIC+ (0xd2f1). +* On a v5 filesystem, the leaves use the +struct xfs_da3_blkinfo_t+ filesystem +block header. This header is used in the same place as +xfs_da_blkinfo_t+: + +[source, c] +---- +struct xfs_da3_blkinfo { + /* these values are inside xfs_da_blkinfo */ + __be32 forw; + __be32 back; + __be16 magic; + __be16 pad; + + __be32 crc; + __be64 blkno; + __be64 lsn; + uuid_t uuid; + __be64 owner; +}; +---- + +*forw*:: +Logical block offset of the previous B+tree block at this level. + +*back*:: +Logical block offset of the next B+tree block at this level. + +*magic*:: +Magic number for this directory/attribute block. + +*pad*:: +Padding to maintain alignment. + +*crc*:: +Checksum of the directory/attribute block. + +*blkno*:: +Block number of this directory/attribute block. + +*lsn*:: +Log sequence number of the last write to this block. + +*uuid*:: +The UUID of this block, which must match either +sb_uuid+ or +sb_meta_uuid+ +depending on which features are set. + +*owner*:: +The inode number that this directory/attribute block belongs to. + +// split lists + +* The magic number of the leaf block is +XFS_DIR2_LEAF1_MAGIC+ (0xd2f1); on a +v5 filesystem it is +XFS_DIR3_LEAF1_MAGIC+ (0x3df1). * The size of the +ents+ array is specified by +hdr.count+. @@ -1107,13 +1236,15 @@ each ``data'' block. This is not possible with more than one leaf. * After the ``freeindex'' data moves to its own block, it is possible for the leaf data to fit within a single leaf block. This single leaf block has a -magic number of +XFS_DIR2_LEAFN_MAGIC+ (0xd2ff). +magic number of +XFS_DIR2_LEAFN_MAGIC+ (0xd2ff) or on a v5 filesystem, ++XFS_DIR3_LEAFN_MAGIC+ (0x3dff). * The ``leaf'' blocks eventually change into a B+tree with the generic B+tree header pointing to directory ``leaves'' as described in xref:Leaf_Directories[Leaf Directories]. Blocks with leaf data still have the +LEAFN_MAGIC+ magic number as outlined above. The top-level tree blocks are -called ``nodes'' and have a magic number of +XFS_DA_NODE_MAGIC+ (0xfebe). +called ``nodes'' and have a magic number of +XFS_DA_NODE_MAGIC+ (0xfebe), or on +a v5 filesystem, +XFS_DA3_NODE_MAGIC+ (0x3ebe). * Distinguishing between a combined leaf/freeindex block (+LEAF1_MAGIC+), a leaf-only block (+LEAFN_MAGIC+), and a btree node block (+NODE_MAGIC+) can only @@ -1161,6 +1292,50 @@ An array specifying the best free counts in each directory data block. // split lists +* On a v5 filesystem, the freeindex block uses the following structures: + +[source, c] +---- +struct xfs_dir3_free_hdr { + struct xfs_dir3_blk_hdr hdr; + __int32_t firstdb; + __int32_t nvalid; + __int32_t nused; + __int32_t pad; +}; +---- + +*hdr*:: +v3 directory block header. The magic number is "XDF3" (0x0x58444633). + +*firstdb*:: +The starting directory block number for the bests array. + +*nvalid*:: +Number of elements in the bests array. + +*nused*:: +Number of valid elements in the bests array. + +*pad*:: +Padding to maintain alignment. + +[source, c] +---- +struct xfs_dir3_free { + xfs_dir3_free_hdr_t hdr; + __be16 bests[1]; +}; +---- + +*hdr*:: +Free block header. + +*bests*:: +An array specifying the best free counts in each directory data block. + +// split lists + * The location of the leaf blocks can be in any order, the only way to determine the appropriate is by the node block hash/before values. Given a hash to look up, you read the node's +btree+ array and first +hashval+ in the array that exceeds @@ -1205,6 +1380,45 @@ The hash value of a particular record. The directory/attribute logical block containing all entries up to the corresponding hash value. +* On a v5 filesystem, the directory/attribute node blocks have the following +structure: + +[source, c] +---- +struct xfs_da3_intnode { + struct xfs_da3_node_hdr { + struct xfs_da3_blkinfo info; + __uint16_t count; + __uint16_t level; + __uint32_t pad32; + } hdr; + struct xfs_da_node_entry { + xfs_dahash_t hashval; + xfs_dablk_t before; + } btree[1]; +}; +---- + +*info*:: +Directory/attribute block info. The magic number is +XFS_DA3_NODE_MAGIC+ +(0x3ebe). + +*count*:: +Number of node entries in this block. + +*level*:: +The level of this block in the B+tree. + +*pad32*:: +Padding to maintain alignment. + +*hashval*:: +The hash value of a particular record. + +*before*:: +The directory/attribute logical block containing all entries up to the +corresponding hash value. + * The freeindex's +bests+ array starts from the end of the block and grows to the start of the block. diff --git a/design/XFS_Filesystem_Structure/docinfo.xml b/design/XFS_Filesystem_Structure/docinfo.xml index 9bcecad..8ed38d9 100644 --- a/design/XFS_Filesystem_Structure/docinfo.xml +++ b/design/XFS_Filesystem_Structure/docinfo.xml @@ -90,4 +90,20 @@ + + 3.1 + October 2015 + + Darrick + Wong + + + + + Add v5 fields. + Discuss metadata integrity. + Document the free inode B+tree. + + + diff --git a/design/XFS_Filesystem_Structure/extended_attributes.asciidoc b/design/XFS_Filesystem_Structure/extended_attributes.asciidoc index f268d66..bb773d5 100644 --- a/design/XFS_Filesystem_Structure/extended_attributes.asciidoc +++ b/design/XFS_Filesystem_Structure/extended_attributes.asciidoc @@ -322,7 +322,8 @@ with the flags stored as well. The remaining part of the leaf block contains the array name/value pairs, where each element varies in length. Each leaf is based on the +xfs_da_blkinfo_t+ block header declared in the -section about xref:Directory_Attribute_Block_Header[directories]. The structure +section about xref:Directory_Attribute_Block_Header[directories]. On a v5 +filesystem, the block header is +xfs_da3_blkinfo_t+. The structure encapsulating all other structures in the attribute block is +xfs_attr_leafblock_t+. @@ -459,7 +460,32 @@ size of these entries is determined dynamically. A variable-length array of descriptors of remote attributes. The location and size of these entries is determined dynamically. -Each leaf header uses the magic number +XFS_ATTR_LEAF_MAGIC+ (0xfbee). +On a v5 filesystem, the header becomes +xfs_da3_blkinfo_t+ to accomodate the +extra metadata integrity fields: + +[source, c] +---- +typedef struct xfs_attr3_leaf_hdr { + xfs_da3_blkinfo_t info; + __be16 count; + __be16 usedbytes; + __be16 firstused; + __u8 holes; + __u8 pad1; + xfs_attr_leaf_map_t freemap[3]; +} xfs_attr3_leaf_hdr_t; + + +typedef struct xfs_attr3_leafblock { + xfs_attr3_leaf_hdr_t hdr; + xfs_attr_leaf_entry_t entries[1]; + xfs_attr_leaf_name_local_t namelist; + xfs_attr_leaf_name_remote_t valuelist; +} xfs_attr3_leafblock_t; +---- + +Each leaf header uses the magic number +XFS_ATTR_LEAF_MAGIC+ (0xfbee). On a +v5 filesystem, the magic number is +XFS_ATTR3_LEAF_MAGIC+ (0x3bee). The hash/index elements in the +entries[]+ array are packed from the top of the block. Name/values grow from the bottom but are not packed. The freemap contains @@ -474,7 +500,8 @@ For attributes with small values (ie. the value can be stored within the leaf), the +XFS_ATTR_LOCAL+ flag is set for the attribute. The entry details are stored using the +xfs_attr_leaf_name_local_t+ structure. For large attribute values that cannot be stored within the leaf, separate filesystem blocks are allocated -to store the value. They use the +xfs_attr_leaf_name_remote_t+ structure. +to store the value. They use the +xfs_attr_leaf_name_remote_t+ structure. See +xref:Remote_Values[Remote Values] for more information. .Leaf attribute layout image::images/69.png[] @@ -629,6 +656,7 @@ that exceeds the given hash. The entry is in the block pointed to by the +before+ value. Each attribute node block has a magic number of +XFS_DA_NODE_MAGIC+ (0xfebe). +On a v5 filesystem this is +XFS_DA3_NODE_MAGIC+ (0x3ebe). .Node attribute layout image::images/72.png[] @@ -834,3 +862,50 @@ is two levels deep. The two blocks at offset 513 and 512 (ie. access using the +ablock+ command) are intermediate +xfs_da_intnode_t+ nodes that index all the attribute leaves. +[[Remote_Values]] +== Remote Attribute Values + +On a v5 filesystem, all remote value blocks start with this header: + +[source, c] +---- +struct xfs_attr3_rmt_hdr { + __be32 rm_magic; + __be32 rm_offset; + __be32 rm_bytes; + __be32 rm_crc; + uuid_t rm_uuid; + __be64 rm_owner; + __be64 rm_blkno; + __be64 rm_lsn; +}; +---- + + +*rm_magic*:: +Specifies the magic number for the remote value block: "XARM" (0x5841524d). + +*rm_offset*:: +Offset of the remote value data, in bytes. + +*rm_bytes*:: +Number of bytes used to contain the remote value data. + +*rm_crc*:: +Checksum of the remote value block. + +*rm_uuid*:: +The UUID of this block, which must match either +sb_uuid+ or +sb_meta_uuid+ +depending on which features are set. + +*rm_owner*:: +The inode number that this remote value block belongs to. + +*rm_blkno*:: +Disk block number of this remote value block. + +*rm_lsn*:: +Log sequence number of the last write to this block. + +Filesystems formatted prior to v5 do not have this header in the remote block. +Value data begins immediately at offset zero. diff --git a/design/XFS_Filesystem_Structure/internal_inodes.asciidoc b/design/XFS_Filesystem_Structure/internal_inodes.asciidoc index c21f8b4..9ace3ea 100644 --- a/design/XFS_Filesystem_Structure/internal_inodes.asciidoc +++ b/design/XFS_Filesystem_Structure/internal_inodes.asciidoc @@ -60,6 +60,11 @@ struct xfs_disk_dquot { struct xfs_dqblk { struct xfs_disk_dquot dd_diskdq; char dd_fill[32]; + + /* version 5 filesystem fields begin here */ + __be32 dd_crc; + __be64 dd_lsn; + uuid_t dd_uuid; }; ---- @@ -150,6 +155,16 @@ soft limit will turn into a hard limit after the elapsed time exceeds ID zero's +d_rtbtimer+ value. When +d_rtbcount+ goes back below +d_rtb_softlimit+, +d_rtbtimer+ is reset back to zero. +*dd_uuid*:: +The UUID of this block, which must match either +sb_uuid+ or +sb_meta_uuid+ +depending on which features are set. + +*dd_lsn*:: +Log sequence number of the last DQ block write. + +*dd_crc*:: +Checksum of the DQ block. + [[Real-time_Inodes]] == Real-time Inodes diff --git a/design/XFS_Filesystem_Structure/ondisk_inode.asciidoc b/design/XFS_Filesystem_Structure/ondisk_inode.asciidoc index da6281b..4aabc55 100644 --- a/design/XFS_Filesystem_Structure/ondisk_inode.asciidoc +++ b/design/XFS_Filesystem_Structure/ondisk_inode.asciidoc @@ -55,7 +55,7 @@ explain the various structures in use within the inode. The remaining space in the inode after +di_next_unlinked+ where the two forks are located is called the inode's ``literal area''. This starts at offset 100 -(0x64) in the inode. +(0x64) in a version 1 or 2 inode, and offset 176 (0xb0) in a version 3 inode. The space for each of the two forks in the literal area is determined by the inode size, and +di_core.di_forkoff+. The data fork is located between the start @@ -99,6 +99,20 @@ struct xfs_dinode_core { __uint16_t di_dmstate; __uint16_t di_flags; __uint32_t di_gen; + + /* di_next_unlinked is the only non-core field in the old dinode */ + __be32 di_next_unlinked; + + /* version 5 filesystem (inode version 3) fields start here */ + __le32 di_crc; + __be64 di_changecount; + __be64 di_lsn; + __be64 di_flags2; + __u8 di_pad2[16]; + xfs_timestamp_t di_crtime; + __be64 di_ino; + uuid_t di_uuid; + }; ---- @@ -110,10 +124,11 @@ Specifies the mode access bits and type of file using the standard S_Ixxx values defined in stat.h. *di_version*:: -Specifies the inode version which currently can only be 1 or 2. The inode +Specifies the inode version which currently can only be 1, 2, or 3. The inode version specifies the usage of the +di_onlink+, +di_nlink+ and +di_projid+ values in the inode core. Initially, inodes are created as v1 but can be -converted on the fly to v2 when required. +converted on the fly to v2 when required. v3 inodes are created only for v5 +filesystems. *di_format*:: Specifies the format of the data fork in conjunction with the +di_mode+ type. @@ -284,6 +299,35 @@ A generation number used for inode identification. This is used by tools that do inode scanning such as backup tools and xfsdump. An inode's generation number can change by unlinking and creating a new file that reuses the inode. +*di_next_unlinked*:: +See the section on xref:Unlinked_Pointer[unlinked inode pointers] for more +information. + +*di_crc*:: +Checksum of the inode. + +*di_changecount*:: +Counts the number of changes made to the attributes in this inode. + +*di_lsn*:: +Log sequence number of the last inode write. + +*di_flags2*:: +Specifies extended flags associated with a v3 inode. There are no flags defined +currently. + +*di_pad2*:: +Padding for future expansion of the inode. + +*di_crtime*:: +Specifies the time when this inode was created. + +*di_ino*:: +The full inode number of this inode. + +*di_uuid*:: +The UUID of this inode, which must match either +sb_uuid+ or +sb_meta_uuid+ +depending on which features are set. [[Unlinked_Pointer]] == Unlinked Pointer @@ -311,12 +355,12 @@ image::images/28.png[] == Data Fork The structure of the inode's data fork based is on the inode's type and -+di_format+. It always starts at offset 100 (0x64) in the inode's space which is -the start of the inode's ``literal area''. The size of the data fork is determined -by the type and format. The maximum size is determined by the inode size and -+di_forkoff+. In code, use the +XFS_DFORK_PTR+ macro specifying +XFS_DATA_FORK+ -for the ``which'' parameter. Alternatively, the +XFS_DFORK_DPTR+ macro can be -used. ++di_format+. The data fork begins at the start of the inode's ``literal area''. +This area starts at offset 100 (0x64), or offset 176 (0xb0) in a v3 inode. The +size of the data fork is determined by the type and format. The maximum size is +determined by the inode size and +di_forkoff+. In code, use the +XFS_DFORK_PTR+ +macro specifying +XFS_DATA_FORK+ for the ``which'' parameter. Alternatively, +the +XFS_DFORK_DPTR+ macro can be used. Each of the following sub-sections summarises the contents of the data fork based on the inode type. diff --git a/design/XFS_Filesystem_Structure/symbolic_links.asciidoc b/design/XFS_Filesystem_Structure/symbolic_links.asciidoc index 5d2c4e8..bfe5eb9 100644 --- a/design/XFS_Filesystem_Structure/symbolic_links.asciidoc +++ b/design/XFS_Filesystem_Structure/symbolic_links.asciidoc @@ -63,6 +63,51 @@ by the data fork's +di_bmx[]+ array. In the significant majority of cases, this will be in one filesystem block as a symlink cannot be longer than 1024 characters. +On a v5 filesystem, the first block of each extent starts with the following +header structure: + +[source, c] +---- +struct xfs_dsymlink_hdr { + __be32 sl_magic; + __be32 sl_offset; + __be32 sl_bytes; + __be32 sl_crc; + uuid_t sl_uuid; + __be64 sl_owner; + __be64 sl_blkno; + __be64 sl_lsn; +}; +----- + +*sl_magic*:: +Specifies the magic number for the symlink block: "XSLM" (0x58534c4d). + +*sl_offset*:: +Offset of the symbolic link target data, in bytes. + +*sl_bytes*:: +Number of bytes used to contain the link target data. + +*sl_crc*:: +Checksum of the symlink block. + +*sl_uuid*:: +The UUID of this block, which must match either +sb_uuid+ or +sb_meta_uuid+ +depending on which features are set. + +*sl_owner*:: +The inode number that this symlink block belongs to. + +*sl_blkno*:: +Disk block number of this symlink. + +*sl_lsn*:: +Log sequence number of the last write to this block. + +Filesystems formatted prior to v5 do not have this header in the remote block. +Symlink data begins immediately at offset zero. + .Symbolic link extent layout image::images/62.png[] From darrick.wong@oracle.com Wed Nov 11 13:24:41 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 7440C29E08 for ; Wed, 11 Nov 2015 13:24:41 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 67AA28F8035 for ; Wed, 11 Nov 2015 11:24:41 -0800 (PST) X-ASG-Debug-ID: 1447269879-04cbb0242212ccf0001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id MJPrWARNadZLwmkT (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 11 Nov 2015 11:24:40 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tABJOGfH025787 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 11 Nov 2015 19:24:16 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id tABJOGRU014735 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 11 Nov 2015 19:24:16 GMT Received: from abhmp0015.oracle.com (abhmp0015.oracle.com [141.146.116.21]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id tABJOFim018612; Wed, 11 Nov 2015 19:24:15 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 11 Nov 2015 11:24:15 -0800 Subject: [PATCH 16/21] xfsdocs: add a chapter discussing v5 disk format From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 16/21] xfsdocs: add a chapter discussing v5 disk format To: hch@infradead.org, david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Wed, 11 Nov 2015 11:24:14 -0800 Message-ID: <20151111192414.14235.39676.stgit@birch.djwong.org> In-Reply-To: <20151111192218.14235.13928.stgit@birch.djwong.org> References: <20151111192218.14235.13928.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0021.oracle.com [156.151.31.71] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1447269880 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24309 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Add a chapter to give an overview of the enhanced metadata integrity fields present on a v5 filesystem. Signed-off-by: Darrick J. Wong --- .../metadata_integrity.asciidoc | 36 ++++++++++++++++++++ .../xfs_filesystem_structure.asciidoc | 2 + 2 files changed, 38 insertions(+) create mode 100644 design/XFS_Filesystem_Structure/metadata_integrity.asciidoc diff --git a/design/XFS_Filesystem_Structure/metadata_integrity.asciidoc b/design/XFS_Filesystem_Structure/metadata_integrity.asciidoc new file mode 100644 index 0000000..f948d5e --- /dev/null +++ b/design/XFS_Filesystem_Structure/metadata_integrity.asciidoc @@ -0,0 +1,36 @@ += Metadata Integrity + +Prior to version 5, most XFS metadata blocks contained a magic number that +could provide a minimal sanity check that a block read off the disk contained +the same type of data that the code thought it was reading off the disk. +However, this was insufficient -- given a correct type code, it was still +impossible to tell if the block was from a previous filesystem, or happened to +be owned by something else, or had been written to the wrong location on disk. +Furthermore, not all metadata blocks had magic numbers -- remote extended +attributes and extent symbolic links had no protection at all. + +Therefore, the version 5 disk format introduced larger headers for all metadata +types, which enable the filesystem to check information being read from the +disk more rigorously. Metadata integrity fields now include: + +* *Magic* numbers, to classify all types of metadata. This is unchanged from v4. +* A copy of the filesystem *UUID*, to confirm that a given disk block is connected to the superblock. +* The *owner*, to avoid accessing a piece of metadata which belongs to some other part of the filesystem. +* The filesystem *block number*, to detect misplaced writes. +* The *log serial number* of the last write to this block, to avoid replaying obsolete log entries. +* A CRC32c *checksum* of the entire block, to detect minor corruption. + +Metadata integrity coverage has been extended to all metadata blocks in the +filesystem, with the following notes: + +* Inodes can have multiple ``owners'' in the directory tree; therefore the record contains the inode number instead of an owner or a block number. +* Superblocks have no owners. +* The disk quota file has no owner or block numbers. +* Metadata owned by files list the inode number as the owner. +* Per-AG data and B+tree blocks list the AG number as the owner. +* Per-AG header sectors don't list owners or block numbers, since they have fixed locations. +* Remote attribute blocks are not logged and therefore the LSN must be -1. + +This functionality enables XFS to decide that a block contents are so +unexpected that it should stop immediately. Unfortunately checksums do not +allow for automatic correction. Please keep regular backups, as always. diff --git a/design/XFS_Filesystem_Structure/xfs_filesystem_structure.asciidoc b/design/XFS_Filesystem_Structure/xfs_filesystem_structure.asciidoc index 9f4c096..8aacbb7 100644 --- a/design/XFS_Filesystem_Structure/xfs_filesystem_structure.asciidoc +++ b/design/XFS_Filesystem_Structure/xfs_filesystem_structure.asciidoc @@ -46,6 +46,8 @@ log items which are formatted in host order. include::overview.asciidoc[] +include::metadata_integrity.asciidoc[] + include::common_types.asciidoc[] // return titles to normal From darrick.wong@oracle.com Wed Nov 11 13:24:51 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 7D68429DFC for ; Wed, 11 Nov 2015 13:24:51 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 5FE5D304032 for ; Wed, 11 Nov 2015 11:24:51 -0800 (PST) X-ASG-Debug-ID: 1447269889-04cb6c296d125080001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id 3CPGBHEr8btjz7Yt (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 11 Nov 2015 11:24:49 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tABJOUI4025912 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 11 Nov 2015 19:24:31 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id tABJOUNB000971 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 11 Nov 2015 19:24:30 GMT Received: from abhmp0009.oracle.com (abhmp0009.oracle.com [141.146.116.15]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id tABJOUW6000772; Wed, 11 Nov 2015 19:24:30 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 11 Nov 2015 11:24:29 -0800 Subject: [PATCH 18/21] xfsdocs: document the sparse inodes feature From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 18/21] xfsdocs: document the sparse inodes feature To: hch@infradead.org, david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Wed, 11 Nov 2015 11:24:28 -0800 Message-ID: <20151111192428.14235.3249.stgit@birch.djwong.org> In-Reply-To: <20151111192218.14235.13928.stgit@birch.djwong.org> References: <20151111192218.14235.13928.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0022.oracle.com [141.146.126.234] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1447269889 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24309 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Document the new sparse inodes feature and how it affects the inobt records. Signed-off-by: Darrick J. Wong --- .../allocation_groups.asciidoc | 157 ++++++++++++++++++++ design/XFS_Filesystem_Structure/docinfo.xml | 1 2 files changed, 155 insertions(+), 3 deletions(-) diff --git a/design/XFS_Filesystem_Structure/allocation_groups.asciidoc b/design/XFS_Filesystem_Structure/allocation_groups.asciidoc index 845b359..ca3210c 100644 --- a/design/XFS_Filesystem_Structure/allocation_groups.asciidoc +++ b/design/XFS_Filesystem_Structure/allocation_groups.asciidoc @@ -388,6 +388,18 @@ Directory file type. Each directory entry tracks the type of the inode to which the entry points. This is a performance optimization to remove the need to load every inode into memory to iterate a directory. +| +XFS_SB_FEAT_INCOMPAT_SPINODES+ | +Sparse inodes. This feature relaxes the requirement to allocate inodes in +chunks of 64. When the free space is heavily fragmented, there might exist +plenty of free space but not enough contiguous free space to allocate a new +inode chunk. With this feature, the user can continue to create files until +all free space is exhausted. + +Unused space in the inode B+tree records are used to track which parts of the +inode chunk are not inodes. + +See the chapter on xref:Sparse_Inodes[Sparse Inodes] for more information. + | +XFS_SB_FEAT_INCOMPAT_META_UUID+ | Metadata UUID. The UUID stamped into each metadata block must match the value in +sb_meta_uuid+. This enables the administrator to change +sb_uuid+ at will @@ -977,9 +989,9 @@ Specifies the number of levels in the free inode B+tree. [[Inode_Btrees]] == Inode B+trees -Inodes are allocated in chunks of 64, and a B+tree is used to track these chunks -of inodes as they are allocated and freed. The block containing root of the -B+tree is defined by the AGI's +agi_root+ value. If the +Inodes are traditionally allocated in chunks of 64, and a B+tree is used to +track these chunks of inodes as they are allocated and freed. The block +containing root of the B+tree is defined by the AGI's +agi_root+ value. If the +XFS_SB_FEAT_RO_COMPAT_FINOBT+ feature is enabled, a second B+tree is used to track the chunks containing free inodes; this is an optimization to speed up inode allocation. @@ -1111,6 +1123,145 @@ recs[1] = [startino,freecount,free] 1:[5792,9,0xff80000000000000] Observe also that the AGI's +agi_newino+ points to this chunk, which has never been fully allocated. +[[Sparse_Inodes]] +== Sparse Inodes + +As mentioned in the previous section, XFS allocates inodes in chunks of 64. If +there are no free extents large enough to hold a full chunk of 64 inodes, the +inode allocation fails and XFS claims to have run out of space. On a +filesystem with highly fragmented free space, this can lead to out of space +errors long before the filesystem runs out of free blocks. + +The sparse inode feature tracks inode chunks in the inode B+tree as if they +were full chunks but uses some previously unused bits in the freecount field to +track which parts of the inode chunk are not allocated for use as inodes. This +allows XFS to allocate inodes one block at a time if absolutely necessary. + +The inode and free inode B+trees operate in the same manner as they do without +the sparse inode feature; the B+tree header for the nodes and leaves use the ++xfs_btree_sblock+ structure which is the same as the header used in the +xref:AG_Free_Space_Btrees[AGF B+trees]. + +Leaves contain an array of the following structure: + +[source,c] +---- +struct xfs_inobt_rec { + __be32 ir_startino; + __be16 ir_holemask; + __u8 ir_count; + __u8 ir_freecount; + __be64 ir_free; +}; +---- + +*ir_startino*:: +The lowest-numbered inode in this chunk, rounded down to the nearest multiple +of 64, even if the start of this chunk is sparse. + +*ir_holemask*:: +A 16 element bitmap showing which parts of the chunk are not allocated to +inodes. Each bit represents four inodes; if a bit is marked here, the +corresponding bits in ir_free must also be marked. + +*ir_count*:: +Number of inodes allocated to this chunk. + +*ir_freecount*:: +Number of free inodes in this chunk. + +*ir_free*:: +A 64 element bitmap showing which inodes in this chunk are not available for +allocation. + +==== xfs_db Sparse Inode AGI Example + +This example derives from an AG that has been deliberately fragmented. The +inode B+tree: + +---- +xfs_db> agi 0 +xfs_db> p +magicnum = 0x58414749 +versionnum = 1 +seqno = 0 +length = 6400 +count = 10432 +root = 2381 +level = 2 +freecount = 0 +newino = 14912 +dirino = null +unlinked[0-63] = +uuid = b9b4623b-f678-4d48-8ce7-ce08950e3cd6 +lsn = 0x600000ac4 +crc = 0xef550dbc (correct) +free_root = 4 +free_level = 1 +---- + +This AGI was formatted on a v5 filesystem; notice the extra v5 fields. So far +everything else looks much the same as always. + +---- +xfs_db> addr root +magic = 0x49414233 +level = 1 +numrecs = 2 +leftsib = null +rightsib = null +bno = 19048 +lsn = 0x50000192b +uuid = b9b4623b-f678-4d48-8ce7-ce08950e3cd6 +owner = 0 +crc = 0xd98cd2ca (correct) +keys[1-2] = [startino] 1:[128] 2:[35136] +ptrs[1-2] = 1:3 2:2380 +xfs_db> addr ptrs[1] +xfs_db> p +magic = 0x49414233 +level = 0 +numrecs = 159 +leftsib = null +rightsib = 2380 +bno = 24 +lsn = 0x600000ac4 +uuid = b9b4623b-f678-4d48-8ce7-ce08950e3cd6 +owner = 0 +crc = 0x836768a6 (correct) +recs[1-159] = [startino,holemask,count,freecount,free] + 1:[128,0,64,0,0] + 2:[14912,0xff,32,0,0xffffffff] + 3:[15040,0,64,0,0] + 4:[15168,0xff00,32,0,0xffffffff00000000] + 5:[15296,0,64,0,0] + 6:[15424,0xff,32,0,0xffffffff] + 7:[15552,0,64,0,0] + 8:[15680,0xff00,32,0,0xffffffff00000000] + 9:[15808,0,64,0,0] + 10:[15936,0xff,32,0,0xffffffff] +---- + +Here we see the difference in the inode B+tree records. For example, in record +2, we see that the holemask has a value of 0xff. This means that the first +sixteen inodes in this chunk record do not actually map to inode blocks; the +first inode in this chunk is actually inode 14944: + +---- +xfs_db> inode 14912 +Metadata corruption detected at block 0x3a40/0x2000 +... +Metadata CRC error detected for ino 14912 +xfs_db> p core.magic +core.magic = 0 +xfs_db> inode 14944 +xfs_db> p core.magic +core.magic = 0x494e +---- + +The chunk record also indicates that this chunk has 32 inodes, and that the +missing inodes are also ``free''. + [[Real-time_Devices]] == Real-time Devices diff --git a/design/XFS_Filesystem_Structure/docinfo.xml b/design/XFS_Filesystem_Structure/docinfo.xml index 6189fd6..ba97809 100644 --- a/design/XFS_Filesystem_Structure/docinfo.xml +++ b/design/XFS_Filesystem_Structure/docinfo.xml @@ -104,6 +104,7 @@ Discuss metadata integrity. Document the free inode B+tree. Create an index of magic numbers. + Document sparse inodes. From darrick.wong@oracle.com Wed Nov 11 13:24:52 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id BB95029DFC for ; Wed, 11 Nov 2015 13:24:52 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 5D2CFAC005 for ; Wed, 11 Nov 2015 11:24:52 -0800 (PST) X-ASG-Debug-ID: 1447269890-04bdf03f05121330001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id 3i423aJmiE81xAcB (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 11 Nov 2015 11:24:51 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tABJORTX025878 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 11 Nov 2015 19:24:27 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id tABJOQMe015312 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 11 Nov 2015 19:24:27 GMT Received: from abhmp0014.oracle.com (abhmp0014.oracle.com [141.146.116.20]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id tABJONY5000740; Wed, 11 Nov 2015 19:24:23 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 11 Nov 2015 11:24:23 -0800 Subject: [PATCH 17/21] xfsdocs: document magic numbers and theoretical limits From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 17/21] xfsdocs: document magic numbers and theoretical limits To: hch@infradead.org, david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Wed, 11 Nov 2015 11:24:20 -0800 Message-ID: <20151111192420.14235.39194.stgit@birch.djwong.org> In-Reply-To: <20151111192218.14235.13928.stgit@birch.djwong.org> References: <20151111192218.14235.13928.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0021.oracle.com [156.151.31.71] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1447269891 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24309 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Signed-off-by: Darrick J. Wong --- design/XFS_Filesystem_Structure/docinfo.xml | 1 design/XFS_Filesystem_Structure/magic.asciidoc | 86 ++++++++++++++++++++ .../xfs_filesystem_structure.asciidoc | 2 3 files changed, 89 insertions(+) create mode 100644 design/XFS_Filesystem_Structure/magic.asciidoc diff --git a/design/XFS_Filesystem_Structure/docinfo.xml b/design/XFS_Filesystem_Structure/docinfo.xml index 8ed38d9..6189fd6 100644 --- a/design/XFS_Filesystem_Structure/docinfo.xml +++ b/design/XFS_Filesystem_Structure/docinfo.xml @@ -103,6 +103,7 @@ Add v5 fields. Discuss metadata integrity. Document the free inode B+tree. + Create an index of magic numbers. diff --git a/design/XFS_Filesystem_Structure/magic.asciidoc b/design/XFS_Filesystem_Structure/magic.asciidoc new file mode 100644 index 0000000..301cfa0 --- /dev/null +++ b/design/XFS_Filesystem_Structure/magic.asciidoc @@ -0,0 +1,86 @@ += Magic Numbers + +These are the magic numbers that are known to XFS, along with links to the +relevant chapters. Magic numbers tend to have consistent locations: + +* 32-bit magic numbers are always at offset zero in the block. +* 16-bit magic numbers for the directory and attribute B+tree are at offset eight. +* The quota magic number is at offset zero. +* The inode magic is at the beginning of each inode. + +[options="header"] +|===== +| Flag | Hexadecimal | ASCII | Data structure +| +XFS_SB_MAGIC+ | 0x58465342 | XFSB | xref:Superblocks[Superblock] +| +XFS_AGF_MAGIC+ | 0x58414746 | XAGF | xref:AG_Free_Space_Block[Free Space] +| +XFS_AGI_MAGIC+ | 0x58414749 | XAGI | xref:Inode_Information[Inode Information] +| +XFS_AGFL_MAGIC+ | 0x5841464c | XAFL | xref:AG_Free_List[Free Space List], v5 only +| +XFS_DINODE_MAGIC+ | 0x494e | IN | xref:Inode_Core[Inodes] +| +XFS_DQUOT_MAGIC+ | 0x4451 | DQ | xref:Quota_Inodes[Quota Inodes] +| +XFS_SYMLINK_MAGIC+ | 0x58534c4d | XSLM | xref:Extent_Symbolic_Links[Symbolic Links] +| +XFS_ABTB_MAGIC+ | 0x41425442 | ABTB | xref:AG_Free_Space_Btrees[Free Space by Block B+tree] +| +XFS_ABTB_CRC_MAGIC+ | 0x41423342 | AB3B | xref:AG_Free_Space_Btrees[Free Space by Block B+tree], v5 only +| +XFS_ABTC_MAGIC+ | 0x41425443 | ABTC | xref:AG_Free_Space_Btrees[Free Space by Size B+tree] +| +XFS_ABTC_CRC_MAGIC+ | 0x41423343 | AB3C | xref:AG_Free_Space_Btrees[Free Space by Size B+tree], v5 only +| +XFS_IBT_MAGIC+ | 0x49414254 | IABT | xref:Inode_Btrees[Inode B+tree] +| +XFS_IBT_CRC_MAGIC+ | 0x49414233 | IAB3 | xref:Inode_Btrees[Inode B+tree], v5 only +| +XFS_FIBT_MAGIC+ | 0x46494254 | FIBT | xref:Inode_Btrees[Free Inode B+tree] +| +XFS_FIBT_CRC_MAGIC+ | 0x46494233 | FIB3 | xref:Inode_Btrees[Free Inode B+tree], v5 only +| +XFS_BMAP_MAGIC+ | 0x424d4150 | BMAP | xref:Btree_Extent_List[B+Tree Extent List] +| +XFS_BMAP_CRC_MAGIC+ | 0x424d4133 | BMA3 | xref:Btree_Extent_List[B+Tree Extent List], v5 only +| +XLOG_HEADER_MAGIC_NUM+ | 0xfeedbabe | | xref:Log_Records[Log Records] +| +XFS_DA_NODE_MAGIC+ | 0xfebe | | xref:Directory_Attribute_Internal_Node[Directory/Attribute Node] +| +XFS_DA3_NODE_MAGIC+ | 0x3ebe | | xref:Directory_Attribute_Internal_Node[Directory/Attribute Node], v5 only +| +XFS_DIR2_BLOCK_MAGIC+ | 0x58443242 | XD2B | xref:Block_Directories[Block Directory Data] +| +XFS_DIR3_BLOCK_MAGIC+ | 0x58444233 | XDB3 | xref:Block_Directories[Block Directory Data], v5 only +| +XFS_DIR2_DATA_MAGIC+ | 0x58443244 | XD2D | xref:Leaf_Directories[Leaf Directory Data] +| +XFS_DIR3_DATA_MAGIC+ | 0x58444433 | XDD3 | xref:Leaf_Directories[Leaf Directory Data], v5 only +| +XFS_DIR2_LEAF1_MAGIC+ | 0xd2f1 | | xref:Leaf_Directories[Leaf Directory] +| +XFS_DIR3_LEAF1_MAGIC+ | 0x3df1 | | xref:Leaf_Directories[Leaf Directory], v5 only +| +XFS_DIR2_LEAFN_MAGIC+ | 0xd2ff | | xref:Node_Directories[Node Directory] +| +XFS_DIR3_LEAFN_MAGIC+ | 0x3dff | | xref:Node_Directories[Node Directory], v5 only +| +XFS_DIR2_FREE_MAGIC+ | 0x58443246 | XD2F | xref:Node_Directories[Node Directory Free Space] +| +XFS_DIR3_FREE_MAGIC+ | 0x58444633 | XDF3 | xref:Node_Directories[Node Directory Free Space], v5 only +| +XFS_ATTR_LEAF_MAGIC+ | 0xfbee | | xref:Leaf_Attributes[Leaf Attribute] +| +XFS_ATTR3_LEAF_MAGIC+ | 0x3bee | | xref:Leaf_Attributes[Leaf Attribute], v5 only +| +XFS_ATTR3_RMT_MAGIC+ | 0x5841524d | XARM | xref:Remote_Values[Remote Attribute Value], v5 only +|===== + +The magic numbers for log items are at offset zero in each log item, but items +are not aligned to blocks. + +[options="header"] +|===== +| Flag | Hexadecimal | ASCII | Data structure +| +XFS_TRANS_HEADER_MAGIC+ | 0x5452414e | TRAN | xref:Log_Transaction_Headers[Log Transactions] +| +XFS_LI_EFI+ | 0x1236 | | xref:EFI_Log_Item[Extent Freeing Intent Log Item] +| +XFS_LI_EFD+ | 0x1237 | | xref:EFD_Log_Item[Extent Freeing Done Log Item] +| +XFS_LI_IUNLINK+ | 0x1238 | | Unknown? +| +XFS_LI_INODE+ | 0x123b | | xref:Inode_Log_Item[Inode Updates Log Item] +| +XFS_LI_BUF+ | 0x123c | | xref:Buffer_Log_Item[Buffer Writes Log Item] +| +XFS_LI_DQUOT+ | 0x123d | | xref:Quota_Update_Log_Item[Update Quota Log Item] +| +XFS_LI_QUOTAOFF+ | 0x123e | | xref:Quota_Off_Log_Item[Quota Off Log Item] +| +XFS_LI_ICREATE+ | 0x123f | | xref:Inode_Create_Log_Item[Inode Creation Log Item] +|===== + += Theoretical Limits + +XFS can create really big filesystems! + +[options="header"] +|===== +| Item | 1KiB blocks | 4KiB blocks | 64KiB blocks +| Blocks | 2^52^ | 2^52^ | 2^52^ +| Inodes | 2^63^ | 2^63^ | 2^64^ +| Allocation Groups | 2^32^ | 2^32^ | 2^32^ +| File System Size | 8EiB | 8EiB | 8EiB +| Blocks per AG | 2^31^ | 2^31^ | 2^31^ +| Inodes per AG | 2^32^ | 2^32^ | 2^32^ +| Max AG Size | 2TiB | 8TiB | 128TiB +| Blocks Per File | 2^54^ | 2^54^ | 2^54^ +| File Size | 8EiB | 8EiB | 8EiB +| Max Dir Size | 32GiB | 32GiB | 32GiB +|===== + +Linux doesn't suppport files or devices larger than 8EiB, so the block +limitations are largely ignorable. diff --git a/design/XFS_Filesystem_Structure/xfs_filesystem_structure.asciidoc b/design/XFS_Filesystem_Structure/xfs_filesystem_structure.asciidoc index 8aacbb7..0ab4906 100644 --- a/design/XFS_Filesystem_Structure/xfs_filesystem_structure.asciidoc +++ b/design/XFS_Filesystem_Structure/xfs_filesystem_structure.asciidoc @@ -50,6 +50,8 @@ include::metadata_integrity.asciidoc[] include::common_types.asciidoc[] +include::magic.asciidoc[] + // return titles to normal :leveloffset: 0 From darrick.wong@oracle.com Wed Nov 11 13:25:05 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 756CB29DFC for ; Wed, 11 Nov 2015 13:25:05 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 2C943304032 for ; Wed, 11 Nov 2015 11:25:05 -0800 (PST) X-ASG-Debug-ID: 1447269902-04bdf03f03121340001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id mgYBd1pJRqmFmgyJ (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 11 Nov 2015 11:25:02 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tABJObIQ027098 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 11 Nov 2015 19:24:37 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id tABJOawu015782 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 11 Nov 2015 19:24:37 GMT Received: from abhmp0009.oracle.com (abhmp0009.oracle.com [141.146.116.15]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id tABJOaM9014752; Wed, 11 Nov 2015 19:24:36 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 11 Nov 2015 11:24:36 -0800 Subject: [PATCH 19/21] xfsdocs: reverse-mapping btree documentation From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 19/21] xfsdocs: reverse-mapping btree documentation To: hch@infradead.org, david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Wed, 11 Nov 2015 11:24:35 -0800 Message-ID: <20151111192435.14235.18890.stgit@birch.djwong.org> In-Reply-To: <20151111192218.14235.13928.stgit@birch.djwong.org> References: <20151111192218.14235.13928.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 8bit X-Source-IP: userv0021.oracle.com [156.151.31.71] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1447269902 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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, UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24309 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines 0.00 BSF_SC5_SA210e Custom Rule SA210e Add chapters on the operation of the reverse mapping btree and future things we could do with rmap data. Signed-off-by: Darrick J. Wong --- .../allocation_groups.asciidoc | 24 +- design/XFS_Filesystem_Structure/docinfo.xml | 14 + .../reconstruction.asciidoc | 53 +++++ design/XFS_Filesystem_Structure/rmapbt.asciidoc | 223 ++++++++++++++++++++ .../xfs_filesystem_structure.asciidoc | 4 5 files changed, 310 insertions(+), 8 deletions(-) create mode 100644 design/XFS_Filesystem_Structure/reconstruction.asciidoc create mode 100644 design/XFS_Filesystem_Structure/rmapbt.asciidoc diff --git a/design/XFS_Filesystem_Structure/allocation_groups.asciidoc b/design/XFS_Filesystem_Structure/allocation_groups.asciidoc index ca3210c..a385a94 100644 --- a/design/XFS_Filesystem_Structure/allocation_groups.asciidoc +++ b/design/XFS_Filesystem_Structure/allocation_groups.asciidoc @@ -12,6 +12,7 @@ Each AG has the following characteristics: * A super block describing overall filesystem info * Free space management * Inode allocation and tracking + * Reverse block-mapping index (optional) Having multiple AGs allows XFS to handle most operations in parallel without degrading performance as the number of concurrent accesses increases. @@ -373,6 +374,12 @@ it doesn't understand the flag. Free inode B+tree. Each allocation group contains a B+tree to track inode chunks containing free inodes. This is a performance optimization to reduce the time required to allocate inodes. + +| +XFS_SB_FEAT_RO_COMPAT_RMAPBT+ | +Reverse mapping B+tree. Each allocation group contains a B+tree containing +records mapping AG blocks to their owners. See the section about +xref:Reconstruction[reconstruction] for more details. + |===== *sb_features_incompat*:: @@ -522,9 +529,7 @@ struct xfs_agf { __be32 agf_seqno; __be32 agf_length; __be32 agf_roots[XFS_BTNUM_AGF]; - __be32 agf_spare0; __be32 agf_levels[XFS_BTNUM_AGF]; - __be32 agf_spare1; __be32 agf_flfirst; __be32 agf_fllast; __be32 agf_flcount; @@ -543,9 +548,10 @@ struct xfs_agf { }; ---- -The rest of the bytes in the sector are zeroed. +XFS_BTNUM_AGF+ is set to 2: -index 0 for the free space B+tree indexed by block number; and index 1 for the -free space B+tree indexed by extent size. +The rest of the bytes in the sector are zeroed. +XFS_BTNUM_AGF+ is set to 3: +index 0 for the free space B+tree indexed by block number; index 1 for the free +space B+tree indexed by extent size; and index 2 for the reverse-mapping +B+tree. *agf_magicnum*:: Specifies the magic number for the AGF sector: ``XAGF'' (0x58414746). @@ -563,11 +569,13 @@ this could be less than the +sb_agblocks+ value. It is this value that should be used to determine the size of the AG. *agf_roots*:: -Specifies the block number for the root of the two free space B+trees. +Specifies the block number for the root of the two free space B+trees and the +reverse-mapping B+tree, if enabled. *agf_levels*:: -Specifies the level or depth of the two free space B+trees. For a fresh AG, this -will be one, and the ``roots'' will point to a single leaf of level 0. +Specifies the level or depth of the two free space B+trees and the +reverse-mapping B+tree, if enabled. For a fresh AG, this value will be one, +and the ``roots'' will point to a single leaf of level 0. *agf_flfirst*:: Specifies the index of the first ``free list'' block. Free lists are covered in diff --git a/design/XFS_Filesystem_Structure/docinfo.xml b/design/XFS_Filesystem_Structure/docinfo.xml index ba97809..19eb135 100644 --- a/design/XFS_Filesystem_Structure/docinfo.xml +++ b/design/XFS_Filesystem_Structure/docinfo.xml @@ -108,4 +108,18 @@ + + 3.14 + November 2015 + + Darrick + Wong + + + + + Document the reverse-mapping btree. + + + diff --git a/design/XFS_Filesystem_Structure/reconstruction.asciidoc b/design/XFS_Filesystem_Structure/reconstruction.asciidoc new file mode 100644 index 0000000..7eafe6c --- /dev/null +++ b/design/XFS_Filesystem_Structure/reconstruction.asciidoc @@ -0,0 +1,53 @@ +[[Reconstruction]] += Metadata Reconstruction + +[NOTE] +This is a theoretical discussion of how reconstruction could work; none of this +is implemented as of 2015. + +A simple UNIX filesystem can be thought of in terms of a directed acyclic graph. +To a first approximation, there exists a root directory node, which points to +other nodes. Those other nodes can themselves be directories or they can be +files. Each file, in turn, points to data blocks. + +XFS adds a few more details to this picture: + +* The real root(s) of an XFS filesystem are the allocation group headers +(superblock, AGF, AGI, AGFL). +* Each allocation group’s headers point to various per-AG btrees (free space, +inode, free inodes, free list, etc.) +* The free space btrees point to unused extents; +* The inode btrees point to blocks containing inode chunks; +* All superblocks point to the root directory and the log; +* Hardlinks mean that multiple directories can point to a single file node; +* File data block pointers are indexed by file offset; +* Files and directories can have a second collection of pointers to data blocks +which contain extended attributes; +* Large directories require multiple data blocks to store all the subpointers; +* Still larger directories use high-offset data blocks to store a btree of +hashes to directory entries; +* Large extended attribute forks similarly use high-offset data blocks to store +a btree of hashes to attribute keys; and +* Symbolic links can point to data blocks. + +The beauty of this massive graph structure is that under normal circumstances, +everything known to the filesystem is discoverable (access controls +notwithstanding) from the root. The major weakness of this structure of course +is that breaking a edge in the graph can render entire subtrees inaccessible. ++xfs_repair+ “recovers†from broken directories by scanning for unlinked inodes +and connecting them to +/lost+found+, but this isn’t sufficiently general to +recover from breaks in other parts of the graph structure. Wouldn’t it be +useful to have back pointers as a secondary data structure? The current repair +strategy is to reconstruct whatever can be rebuilt, but to scrap anything that +doesn't check out. + +The xref:Reverse_Mapping_Btree[reverse-mapping B+tree] fills in part of the +puzzle. Since it contains copies of every entry in each inode’s data and +attribute forks, we can fix a corrupted block map with these records. +Furthermore, if the inode B+trees become corrupt, it is possible to visit all +inode chunks using the reverse-mapping data. Should XFS ever gain the ability +to store parent directory information in each inode, it also becomes possible +to resurrect damaged directory trees, which should reduce the complaints about +inodes ending up in +/lost+found+. Everything else in the per-AG primary +metadata can already be reconstructed via +xfs_repair+. Hopefully, +reconstruction will not turn out to be a fool's errand. diff --git a/design/XFS_Filesystem_Structure/rmapbt.asciidoc b/design/XFS_Filesystem_Structure/rmapbt.asciidoc new file mode 100644 index 0000000..d9ccd27 --- /dev/null +++ b/design/XFS_Filesystem_Structure/rmapbt.asciidoc @@ -0,0 +1,223 @@ +[[Reverse_Mapping_Btree]] +== Reverse-Mapping B+tree + +[NOTE] +This data structure is under construction! Details may change. + +If the feature is enabled, each allocation group has its own reverse +block-mapping B+tree, which grows in the free space like the free space +B+trees. As mentioned in the chapter about +xref:Reconstruction[reconstruction], this data structure is another piece of +the puzzle necessary to reconstruct the data or attribute fork of a file from +reverse-mapping records; we can also use it to double-check allocations to +ensure that we are not accidentally cross-linking blocks, which can cause +severe damage to the filesystem. + +This B+tree is only present if the +XFS_SB_FEAT_RO_COMPAT_RMAPBT+ +feature is enabled. The feature requires a version 5 filesystem. + +Each record in the reverse-mapping B+tree has the following structure: + +[source, c] +---- +struct xfs_rmap_rec { + __be32 rm_startblock; + __be32 rm_unwritten:1; + __be32 rm_blockcount:31; + __be64 rm_owner; + __be64 rm_fork:1; + __be64 rm_bmbt:1; + __be64 rm_offset:62; +}; +---- + +*rm_startblock*:: +AG block number of this record. + +*rm_unwritten*:: +A flag indicating that the extent is unwritten. This corresponds to the flag in +the xref:Data_Extents[extent record] format which means +XFS_EXT_UNWRITTEN+. + +*rm_blockcount*:: +The length of this extent. + +*rm_owner*:: +A 64-bit number describing the owner of this extent. This is typically the +absolute inode number, but can also correspond to one of the following: + +.Special owner values +[options="header"] +|===== +| Value | Description +| +XFS_RMAP_OWN_NULL+ | No owner. This should never appear on disk. +| +XFS_RMAP_OWN_UNKNOWN+ | Unknown owner; for EFI recovery. This should never appear on disk. +| +XFS_RMAP_OWN_FS+ | Allocation group headers +| +XFS_RMAP_OWN_LOG+ | XFS log blocks +| +XFS_RMAP_OWN_AG+ | Per-allocation group B+tree blocks. This means free space B+tree blocks, blocks on the freelist, and reverse-mapping B+tree blocks. +| +XFS_RMAP_OWN_INOBT+ | Per-allocation group inode B+tree blocks. This includes free inode B+tree blocks. +| +XFS_RMAP_OWN_INODES+ | Inode chunks +| +XFS_RMAP_OWN_REFC+ | Per-allocation group refcount B+tree blocks. This will be used for reflink support. +|===== + +*rm_fork*:: +If +rm_owner+ describes an inode, this can be 1 if this record is for an +attribute fork. + +*rm_bmbt*:: +If +rm_owner+ describes an inode, this can be 1 to signify that this record is +for a block map B+tree block. In this case, +rm_offset+ has no meaning. + +*rm_offset*:: +The 62-bit logical file block offset, if +rm_owner+ describes an inode. +Meaningless otherwise. + +[NOTE] +The single-bit flag values +rm_unwritten+, +rm_fork+, and +rm_bmbt+ are packed +into the larger fields in the C structure definition. + +[NOTE] +For the moment, there is a requirement that all records in the data or +attribute forks must match exactly with the corresponding entry in the +reverse-mapping B+tree. This may be lifted in future versions of the patchset. + +For the reverse-mapping B+tree, the key definition is larger than the usual AG +block number. On a classic XFS filesystem, each block has only one owner, which +means that +rm_startblock+ is sufficient to uniquely identify each record. +However, shared block support (refink) on XFS breaks that assumption; now +filesystem blocks can be linked to any logical block offset of any file inode. +Therefore, the key must include the owner and offset information to preserve the +1 to 1 relation between key and record. The key has the following structure: + +[source, c] +---- +struct xfs_rmap_key { + __be32 rm_startblock; + __be64 rm_owner; + __be64 rm_fork:1; + __be64 rm_bmbt:1; + __be64 rm_offset:62; +}; +---- + +* As the reference counting is AG relative, all the block numbers are only +32-bits. +* The +bb_magic+ value is "RMB3" (0x524d4233). +* The +xfs_btree_sblock_t+ header is used for intermediate B+tree node as well +as the leaves. + +=== xfs_db rmapbt Example + +This example shows a reverse-mapping B+tree from a freshly formatted root +filesystem: + +---- +xfs_db> agi 0 +xfs_db> addr rmaproot +xfs_db> p +magic = 0x524d4233 +level = 1 +numrecs = 43 +leftsib = null +rightsib = null +bno = 56 +lsn = 0x3000004c8 +uuid = 1977221d-8345-464e-b1f4-aa2ea36895f4 +owner = 0 +crc = 0x7cf8be6f (correct) +keys[1-43] = [startblock,owner,offset] + 1:[0,-3,0] 2:[417,285,0] 3:[829,499,0] 4:[1292,710,0] 5:[32215,-5,0] + 6:[34083,1161,0] 7:[34896,256191,0] + ... + 41:[50998,326734,0] 42:[51431,327010,0] 43:[51611,327112,0] +ptrs[1-43] = 1:5 2:6 3:8 4:9 5:10 6:11 7:418 ... 41:46377 42:48784 43:49522 +xfs_db> addr ptrs[17] +xfs_db> p +magic = 0x524d4233 +level = 0 +numrecs = 168 +leftsib = 36284 +rightsib = 37617 +bno = 294760 +lsn = 0x200002761 +uuid = 1977221d-8345-464e-b1f4-aa2ea36895f4 +owner = 0 +crc = 0x2dad3fbe (correct) +recs[1-168] = [startblock,blockcount,owner,offset,extentflag,attrfork,bmbtblock] + 1:[40326,1,259615,0,0,0,0] 2:[40327,1,-5,0,0,0,0] + 3:[40328,2,259618,0,0,0,0] 4:[40330,1,259619,0,0,0,0] + ... + 127:[40540,1,324266,0,0,0,0] 128:[40541,1,324266,8388608,0,0,0] + 129:[40542,2,324266,1,0,0,0] 130:[40544,32,-7,0,0,0,0] +---- + +Several interesting things pop out here. The first record shows that inode +259,615 has mapped AG block 40,326 at offset 0. We confirm this by looking at +the block map for that inode: + +---- +xfs_db> inode 259615 +xfs_db> bmap +data offset 0 startblock 40326 (0/40326) count 1 flag 0 +---- + +Next, notice records 127 and 128, which describe neighboring AG blocks that are +mapped to non-contiguous logical blocks in inode 324,266. Given the logical +offset of 8,388,608 we surmise that this is a leaf directory, but let us +confirm: + +---- +xfs_db> inode 324266 +xfs_db> p core.mode +core.mode = 040755 +xfs_db> bmap +data offset 0 startblock 40540 (0/40540) count 1 flag 0 +data offset 1 startblock 40542 (0/40542) count 2 flag 0 +data offset 3 startblock 40576 (0/40576) count 1 flag 0 +data offset 8388608 startblock 40541 (0/40541) count 1 flag 0 +xfs_db> p core.mode +core.mode = 0100644 +xfs_db> dblock 0 +xfs_db> p dhdr.hdr.magic +dhdr.hdr.magic = 0x58444433 +xfs_db> dblock 8388608 +xfs_db> p lhdr.info.hdr.magic +lhdr.info.hdr.magic = 0x3df1 +---- + +Indeed, this inode 324,266 appears to be a leaf directory, as it has regular +directory data blocks at low offsets, and a single leaf block. + +Notice further the two reverse-mapping records with negative owners. An owner +of -7 corresponds to +XFS_RMAP_OWN_INODES+, which is an inode chunk, and an +owner code of -5 corresponds to +XFS_RMAP_OWN_AG+, which covers free space +B+trees and free space. Let's see if block 40,544 is part of an inode chunk: + +---- +xfs_db> blockget +xfs_db> fsblock 40544 +xfs_db> blockuse +block 40544 (0/40544) type inode +xfs_db> stack +1: + byte offset 166068224, length 4096 + buffer block 324352 (fsbno 40544), 8 bbs + inode 324266, dir inode 324266, type data +xfs_db> type inode +xfs_db> p +core.magic = 0x494e +---- + +Our suspicions are confirmed. Let's also see if 40,327 is part of a free space +tree: + +---- +xfs_db> fsblock 40327 +xfs_db> blockuse +block 40327 (0/40327) type btrmap +xfs_db> type rmapbt +xfs_db> p +magic = 0x524d4233 +---- + +As you can see, the reverse block-mapping B+tree is an important secondary +metadata structure, which can be used to reconstruct damaged primary metadata. diff --git a/design/XFS_Filesystem_Structure/xfs_filesystem_structure.asciidoc b/design/XFS_Filesystem_Structure/xfs_filesystem_structure.asciidoc index 0ab4906..4d089b6 100644 --- a/design/XFS_Filesystem_Structure/xfs_filesystem_structure.asciidoc +++ b/design/XFS_Filesystem_Structure/xfs_filesystem_structure.asciidoc @@ -48,6 +48,8 @@ include::overview.asciidoc[] include::metadata_integrity.asciidoc[] +include::reconstruction.asciidoc[] + include::common_types.asciidoc[] include::magic.asciidoc[] @@ -62,6 +64,8 @@ Global Structures include::allocation_groups.asciidoc[] +include::rmapbt.asciidoc[] + include::journaling_log.asciidoc[] include::internal_inodes.asciidoc[] From darrick.wong@oracle.com Wed Nov 11 13:25:10 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 67FE729E1A for ; Wed, 11 Nov 2015 13:25:10 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id E2147AC004 for ; Wed, 11 Nov 2015 11:25:09 -0800 (PST) X-ASG-Debug-ID: 1447269907-04cbb0242412cd40001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id CyMUx7vfG69TFkBH (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 11 Nov 2015 11:25:07 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tABJOhqn027195 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 11 Nov 2015 19:24:43 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id tABJOh7j021874 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 11 Nov 2015 19:24:43 GMT Received: from abhmp0014.oracle.com (abhmp0014.oracle.com [141.146.116.20]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id tABJOhsx014774; Wed, 11 Nov 2015 19:24:43 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 11 Nov 2015 11:24:42 -0800 Subject: [PATCH 20/21] xfsdocs: document refcount btree and reflink From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 20/21] xfsdocs: document refcount btree and reflink To: hch@infradead.org, david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Wed, 11 Nov 2015 11:24:41 -0800 Message-ID: <20151111192441.14235.71964.stgit@birch.djwong.org> In-Reply-To: <20151111192218.14235.13928.stgit@birch.djwong.org> References: <20151111192218.14235.13928.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1447269907 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24309 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Document the reference count btree and talk a little bit about how the reflink feature uses it. Signed-off-by: Darrick J. Wong --- .../allocation_groups.asciidoc | 20 ++- .../XFS_Filesystem_Structure/directories.asciidoc | 1 design/XFS_Filesystem_Structure/docinfo.xml | 2 .../XFS_Filesystem_Structure/ondisk_inode.asciidoc | 10 + .../XFS_Filesystem_Structure/refcountbt.asciidoc | 145 ++++++++++++++++++++ design/XFS_Filesystem_Structure/reflink.asciidoc | 40 ++++++ .../xfs_filesystem_structure.asciidoc | 4 + 7 files changed, 218 insertions(+), 4 deletions(-) create mode 100644 design/XFS_Filesystem_Structure/refcountbt.asciidoc create mode 100644 design/XFS_Filesystem_Structure/reflink.asciidoc diff --git a/design/XFS_Filesystem_Structure/allocation_groups.asciidoc b/design/XFS_Filesystem_Structure/allocation_groups.asciidoc index a385a94..5de9548 100644 --- a/design/XFS_Filesystem_Structure/allocation_groups.asciidoc +++ b/design/XFS_Filesystem_Structure/allocation_groups.asciidoc @@ -13,6 +13,7 @@ Each AG has the following characteristics: * Free space management * Inode allocation and tracking * Reverse block-mapping index (optional) + * Data block reference count index (optional) Having multiple AGs allows XFS to handle most operations in parallel without degrading performance as the number of concurrent accesses increases. @@ -380,6 +381,12 @@ Reverse mapping B+tree. Each allocation group contains a B+tree containing records mapping AG blocks to their owners. See the section about xref:Reconstruction[reconstruction] for more details. +| +XFS_SB_FEAT_RO_COMPAT_REFLINK+ | +Reference count B+tree. Each allocation group contains a B+tree to track the +reference counts of AG blocks. This enables files to share data blocks safely. +See the section about xref:Reflink_Deduplication[reflink and deduplication] for +more details. + |===== *sb_features_incompat*:: @@ -539,7 +546,9 @@ struct xfs_agf { /* version 5 filesystem fields start here */ uuid_t agf_uuid; - __be64 agf_spare64[16]; + __be32 agf_refcount_root; + __be32 agf_refcount_level; + __be64 agf_spare64[15]; /* unlogged fields, written during buffer writeback. */ __be64 agf_lsn; @@ -601,6 +610,12 @@ used if the +XFS_SB_VERSION2_LAZYSBCOUNTBIT+ bit is set in +sb_features2+. The UUID of this block, which must match either +sb_uuid+ or +sb_meta_uuid+ depending on which features are set. +*agf_refcount_root*:: +Block number for the root of the reference count B+tree, if enabled. + +*agf_refcount_root*:: +Depth of the reference count B+tree, if enabled. + *agf_spare64*:: Empty space in the logged part of the AGF sector, for use for future features. @@ -1287,4 +1302,5 @@ By placing the real time device (and the journal) on separate high-performance storage devices, it is possible to reduce most of the unpredictability in I/O response times that come from metadata operations. -None of the XFS per-AG B+trees are involved with real time files. +None of the XFS per-AG B+trees are involved with real time files. It is not +possible for real time files to share data blocks. diff --git a/design/XFS_Filesystem_Structure/directories.asciidoc b/design/XFS_Filesystem_Structure/directories.asciidoc index bccf912..1758c4e 100644 --- a/design/XFS_Filesystem_Structure/directories.asciidoc +++ b/design/XFS_Filesystem_Structure/directories.asciidoc @@ -1419,6 +1419,7 @@ The hash value of a particular record. The directory/attribute logical block containing all entries up to the corresponding hash value. +// * The freeindex's +bests+ array starts from the end of the block and grows to the start of the block. diff --git a/design/XFS_Filesystem_Structure/docinfo.xml b/design/XFS_Filesystem_Structure/docinfo.xml index 19eb135..fed339d 100644 --- a/design/XFS_Filesystem_Structure/docinfo.xml +++ b/design/XFS_Filesystem_Structure/docinfo.xml @@ -119,6 +119,8 @@ Document the reverse-mapping btree. + Document the reference-count btree. + Discuss block sharing, reflink, & deduplication. diff --git a/design/XFS_Filesystem_Structure/ondisk_inode.asciidoc b/design/XFS_Filesystem_Structure/ondisk_inode.asciidoc index 4aabc55..ed15285 100644 --- a/design/XFS_Filesystem_Structure/ondisk_inode.asciidoc +++ b/design/XFS_Filesystem_Structure/ondisk_inode.asciidoc @@ -313,8 +313,14 @@ Counts the number of changes made to the attributes in this inode. Log sequence number of the last inode write. *di_flags2*:: -Specifies extended flags associated with a v3 inode. There are no flags defined -currently. +Specifies extended flags associated with a v3 inode. + +.Version 3 Inode flags +[options="header"] +|===== +| Flag | Description +| +XFS_DIFLAG2_REFLINK+ | This inode shares (or has shared) data blocks with another inode. +|===== *di_pad2*:: Padding for future expansion of the inode. diff --git a/design/XFS_Filesystem_Structure/refcountbt.asciidoc b/design/XFS_Filesystem_Structure/refcountbt.asciidoc new file mode 100644 index 0000000..dbbb98e --- /dev/null +++ b/design/XFS_Filesystem_Structure/refcountbt.asciidoc @@ -0,0 +1,145 @@ +[[Reference_Count_Btree]] +== Reference Count B+tree + +[NOTE] +This data structure is under construction! Details may change. + +To support the sharing of file data blocks (reflink), each allocation group has +its own reference count B+tree, which grows in the allocated space like the +inode B+trees. This data could be gleaned by performing an interval query of +the reverse-mapping B+tree, but doing so would come at a huge performance +penalty. Therefore, this data structure is a cache of computable information. + +This B+tree is only present if the +XFS_SB_FEAT_RO_COMPAT_REFLINK+ +feature is enabled. The feature requires a version 5 filesystem. + +Each record in the reference count B+tree has the following structure: + +[source, c] +---- +struct xfs_refcount_rec { + __be32 rc_startblock; + __be32 rc_blockcount; + __be32 rc_refcount; +}; +---- + +*rc_startblock*:: +AG block number of this record. + +*rc_blockcount*:: +The length of this extent. + +*rc_refcount*:: +Number of mappings of this filesystem extent. + +Node pointers are an AG relative block pointer: + +[source, c] +---- +struct xfs_refcount_key { + __be32 rc_startblock; +}; +---- + +* As the reference counting is AG relative, all the block numbers are only +32-bits. +* The +bb_magic+ value is "R3FC" (0x52334643). +* The +xfs_btree_sblock_t+ header is used for intermediate B+tree node as well +as the leaves. + +=== xfs_db refcntbt Example + +For this example, an XFS filesystem was populated with a root filesystem and +a deduplication program was run to create shared blocks: + +---- +xfs_db> agf 0 +xfs_db> addr refcntroot +xfs_db> p +magic = 0x52334643 +level = 1 +numrecs = 6 +leftsib = null +rightsib = null +bno = 36892 +lsn = 0x200004ec2 +uuid = f1f89746-e00b-49c9-96b3-ecef0f2f14ae +owner = 0 +crc = 0x75f35128 (correct) +keys[1-6] = [startblock] 1:[14] 2:[65633] 3:[65780] 4:[94571] 5:[117201] 6:[152442] +ptrs[1-6] = 1:7 2:25836 3:25835 4:18447 5:18445 6:18449 +xfs_db> addr ptrs[3] +xfs_db> p +magic = 0x52334643 +level = 0 +numrecs = 80 +leftsib = 25836 +rightsib = 18447 +bno = 51670 +lsn = 0x200004ec2 +uuid = f1f89746-e00b-49c9-96b3-ecef0f2f14ae +owner = 0 +crc = 0xc3962813 (correct) +recs[1-80] = [startblock,blockcount,refcount] + 1:[65780,1,2] 2:[65781,1,3] 3:[65785,2,2] 4:[66640,1,2] + 5:[69602,4,2] 6:[72256,16,2] 7:[72871,4,2] 8:[72879,20,2] + 9:[73395,4,2] 10:[75063,4,2] 11:[79093,4,2] 12:[86344,16,2] +---- + +Record 6 in the reference count B+tree for AG 0 indicates that the AG extent +starting at block 72,256 and running for 16 blocks has a reference count of 2. +This means that there are two files sharing the block: + +---- +xfs_db> blockget -n +xfs_db> fsblock 72256 +xfs_db> blockuse +block 72256 (0/72256) type rldata inode 25169197 +---- + +The blockuse type changes to ``rldata'' to indicate that the block is shared +data. Unfortunately, blockuse only tells us about one block owner. If we +happen to have enabled the reverse-mapping B+tree, we can use it to find all +inodes that own this block: + +---- +xfs_db> agf 0 +xfs_db> addr rmaproot +... +xfs_db> addr ptrs[3] +... +xfs_db> addr ptrs[7] +xfs_db> p +magic = 0x524d4233 +level = 0 +numrecs = 22 +leftsib = 65057 +rightsib = 65058 +bno = 291478 +lsn = 0x200004ec2 +uuid = f1f89746-e00b-49c9-96b3-ecef0f2f14ae +owner = 0 +crc = 0xed7da3f7 (correct) +recs[1-22] = [startblock,blockcount,owner,offset,extentflag,attrfork,bmbtblock] + 1:[68957,8,3201,0,0,0,0] 2:[68965,4,25260953,0,0,0,0] + ... + 18:[72232,58,3227,0,0,0,0] 19:[72256,16,25169197,24,0,0,0] + 20:[72290,75,3228,0,0,0,0] 21:[72365,46,3229,0,0,0,0] +---- + +Records 18 and 19 intersect the block 72,256; they tell us that inodes 3,227 +and 25,169,197 both claim ownership. Let us confirm this: + +---- +xfs_db> inode 25169197 +xfs_db> bmap +data offset 0 startblock 12632259 (3/49347) count 24 flag 0 +data offset 24 startblock 72256 (0/72256) count 16 flag 0 +data offset 40 startblock 12632299 (3/49387) count 18 flag 0 +xfs_db> inode 3227 +xfs_db> bmap +data offset 0 startblock 72232 (0/72232) count 58 flag 0 +---- + +Inodes 25,169,197 and 3,227 both contain mappings to block 0/72,256. diff --git a/design/XFS_Filesystem_Structure/reflink.asciidoc b/design/XFS_Filesystem_Structure/reflink.asciidoc new file mode 100644 index 0000000..f39e6ff --- /dev/null +++ b/design/XFS_Filesystem_Structure/reflink.asciidoc @@ -0,0 +1,40 @@ +[[Reflink_Deduplication]] += Sharing Data Blocks + +On a traditional filesystem, there is a 1:1 mapping between a logical block +offset in a file and a physical block on disk, which is to say that physical +blocks are not shared. However, there exist various use cases for being able +to share blocks between files -- deduplicating files saves space on archival +systems; creating space-efficient clones of disk images for virtual machines +and containers facilitates efficient datacenters; and deferring the payment of +the allocation cost of a file system tree copy as long as possible makes +regular work faster. In all of these cases, a write to one of the shared +copies *must* not affect the other shared copies, which means that writes to +shared blocks must employ a copy-on-write strategy. Sharing blocks in this +manner is commonly referred to as ``reflinking''. + +XFS implements block sharing in a fairly straightforward manner. All existing +data fork structures remain unchanged, save for the addition of a +per-allocation group xref:Reference_Count_Btree[reference count B+tree]. This +data structure tracks reference counts for all shared physical blocks, with a +few rules to maintain compatibility with existing code: If a block is free, it +will be tracked in the free space B+trees. If a block is owned by a single +file, it appears in neither the free space nor the reference count B+trees. If +a block is shared, it will appear in the reference count B+tree with a +reference count >= 2. The first two cases are established precedent in XFS, so +the third case is the only behavioral change. + +When a filesystem block is shared, the block mapping in the destination file is +updated to point to that filesystem block and the reference count btree records +are updated to reflect the increased refcount. If a shared block is written, a +new block will be allocated, the dirty data written to this new block, and the +file's block mapping updated to point to the new block. If a shared block is +unmapped, the reference count records are updated to reflect the decreased +refcount and the block is also freed if its reference count becomes zero. This +enables users to create space efficient clones of disk images and to copy +filesystem subtrees quickly, using the standard Linux coreutils packages. + +Deduplication employs the same mechanism to share blocks and copy them at write +time. However, the kernel confirms that the contents of both files are +identical before updating the destination file's mapping. This enables XFS to +be used by userspace deduplication programs such as +duperemove+. diff --git a/design/XFS_Filesystem_Structure/xfs_filesystem_structure.asciidoc b/design/XFS_Filesystem_Structure/xfs_filesystem_structure.asciidoc index 4d089b6..4eec464 100644 --- a/design/XFS_Filesystem_Structure/xfs_filesystem_structure.asciidoc +++ b/design/XFS_Filesystem_Structure/xfs_filesystem_structure.asciidoc @@ -48,6 +48,8 @@ include::overview.asciidoc[] include::metadata_integrity.asciidoc[] +include::reflink.asciidoc[] + include::reconstruction.asciidoc[] include::common_types.asciidoc[] @@ -66,6 +68,8 @@ include::allocation_groups.asciidoc[] include::rmapbt.asciidoc[] +include::refcountbt.asciidoc[] + include::journaling_log.asciidoc[] include::internal_inodes.asciidoc[] From darrick.wong@oracle.com Wed Nov 11 13:25:12 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 61EC529E1F for ; Wed, 11 Nov 2015 13:25:12 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 03038AC001 for ; Wed, 11 Nov 2015 11:25:11 -0800 (PST) X-ASG-Debug-ID: 1447269910-04cb6c296c1250a0001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id VYFsbmyAOZS5CZ3G (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 11 Nov 2015 11:25:10 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tABJOoFT027325 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 11 Nov 2015 19:24:50 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id tABJOox4022144 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 11 Nov 2015 19:24:50 GMT Received: from abhmp0001.oracle.com (abhmp0001.oracle.com [141.146.116.7]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id tABJOn0h018808; Wed, 11 Nov 2015 19:24:49 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 11 Nov 2015 11:24:49 -0800 Subject: [PATCH 21/21] xfsdocs: move directory chapter before xattr chapter From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 21/21] xfsdocs: move directory chapter before xattr chapter To: hch@infradead.org, david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Wed, 11 Nov 2015 11:24:48 -0800 Message-ID: <20151111192448.14235.56366.stgit@birch.djwong.org> In-Reply-To: <20151111192218.14235.13928.stgit@birch.djwong.org> References: <20151111192218.14235.13928.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1447269910 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24309 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Since the chapter on directories introduces data structures that are referenced in the xattr chapter, the book should discuss directories first. Signed-off-by: Darrick J. Wong --- .../xfs_filesystem_structure.asciidoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/design/XFS_Filesystem_Structure/xfs_filesystem_structure.asciidoc b/design/XFS_Filesystem_Structure/xfs_filesystem_structure.asciidoc index 4eec464..4ec563c 100644 --- a/design/XFS_Filesystem_Structure/xfs_filesystem_structure.asciidoc +++ b/design/XFS_Filesystem_Structure/xfs_filesystem_structure.asciidoc @@ -85,10 +85,10 @@ include::ondisk_inode.asciidoc[] include::data_extents.asciidoc[] -include::extended_attributes.asciidoc[] - include::directories.asciidoc[] +include::extended_attributes.asciidoc[] + include::symbolic_links.asciidoc[] :leveloffset: 0 From darrick.wong@oracle.com Wed Nov 11 13:26:58 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id A8B717F63 for ; Wed, 11 Nov 2015 13:26:58 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 2B93CAC001 for ; Wed, 11 Nov 2015 11:26:58 -0800 (PST) X-ASG-Debug-ID: 1447270015-04cb6c296a125130001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id LKZfmtddHNgtBGk6 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 11 Nov 2015 11:26:55 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tABJQUol028268 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 11 Nov 2015 19:26:31 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id tABJQUwm021609 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 11 Nov 2015 19:26:30 GMT Received: from abhmp0006.oracle.com (abhmp0006.oracle.com [141.146.116.12]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id tABJQUEe001739; Wed, 11 Nov 2015 19:26:30 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 11 Nov 2015 11:26:29 -0800 Subject: [RFCv3.1 00/11] xfstests: test the nfs/cifs/btrfs/xfs reflink/dedupe ioctls From: "Darrick J. Wong" X-ASG-Orig-Subj: [RFCv3.1 00/11] xfstests: test the nfs/cifs/btrfs/xfs reflink/dedupe ioctls To: hch@infradead.org, david@fromorbit.com, darrick.wong@oracle.com Cc: fstests@vger.kernel.org, xfs@oss.sgi.com, tao.peng@primarydata.com, linux-ext4@vger.kernel.org, Anna.Schumaker@netapp.com, linux-btrfs@vger.kernel.org Date: Wed, 11 Nov 2015 11:26:28 -0800 Message-ID: <20151111192628.15056.6451.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0021.oracle.com [156.151.31.71] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1447270015 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24309 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Hi all, This is part of the third revision of an RFC for adding to XFS support for tracking reverse-mappings of physical blocks to file and metadata; and support for mapping multiple file logical blocks to the same physical block, more commonly known as reflinking. This patchset aims to make xfstests perform more rigorous testing of the NFS/CIFS/ocfs2/btrfs/XFS file clone, reflink, and dedupe ioctls. There are now tests of the basic functionality of the three ioctls; tests to ensure that the filesystem exhibits the expected copy on write semantics; tests to try to suss out race conditions in the new write paths; tests to ensure that the ioctls peform basic disk accounting correctly; tests of the interaction between reflink and the various fallocate verbs (allocate, punch, collapse, insert zeroes); and some attempts to test the upper limits of reflinking and ENOSPC behavior. Since the last posting, each test tries to reflink (or dedupe) on the test or scratch FS to decide if they're going to run, instead of guessing based on FS type. Per Dave's suggestion, I also converted the basic functionality tests to use fixed sizes so that I can use md5sum in the golden output to check that the file contents match exactly. Issues: * I think the race checks for dedupe could be a little sharper at finding mistakes. * The realtime reflink test (xfs/804) crashes XFS before we even get to the reflink attempt. * I started the numbering really high to prevent the tests from colliding with whatever new tests might arrive; this will require some intervention to fix. If you're going to start using this mess, you probably ought to just pull from my github trees for kernel[1], xfsprogs[2], xfstests[3], and xfs-docs[4]. They should just work with the btrfs that's in 4.3... and somewhat buggily with the 4.3 XFS patched with [1]. Comments and questions are, as always, welcome. --D [1] https://github.com/djwong/linux/tree/for-dave [2] https://github.com/djwong/xfsprogs/tree/for-dave [3] https://github.com/djwong/xfstests/tree/for-dave [4] https://github.com/djwong/xfs-documentation/tree/for-dave From darrick.wong@oracle.com Wed Nov 11 13:27:06 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 37EE429E1C for ; Wed, 11 Nov 2015 13:27:06 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 29B448F8035 for ; Wed, 11 Nov 2015 11:27:06 -0800 (PST) X-ASG-Debug-ID: 1447270022-04cbb0242212cdb0001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id aBReiNR4xznMnaaG (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 11 Nov 2015 11:27:02 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tABJQcTb028454 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 11 Nov 2015 19:26:38 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id tABJQcYv021966 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 11 Nov 2015 19:26:38 GMT Received: from abhmp0011.oracle.com (abhmp0011.oracle.com [141.146.116.17]) by userv0121.oracle.com (8.13.8/8.13.8) with ESMTP id tABJQbgP014670; Wed, 11 Nov 2015 19:26:37 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 11 Nov 2015 11:26:36 -0800 Subject: [PATCH 01/11] btrfs: move btrfs reflink tests to generic From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 01/11] btrfs: move btrfs reflink tests to generic To: hch@infradead.org, david@fromorbit.com, darrick.wong@oracle.com Cc: fstests@vger.kernel.org, xfs@oss.sgi.com, tao.peng@primarydata.com, linux-ext4@vger.kernel.org, Anna.Schumaker@netapp.com, linux-btrfs@vger.kernel.org Date: Wed, 11 Nov 2015 11:26:35 -0800 Message-ID: <20151111192635.15056.96745.stgit@birch.djwong.org> In-Reply-To: <20151111192628.15056.6451.stgit@birch.djwong.org> References: <20151111192628.15056.6451.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0021.oracle.com [156.151.31.71] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1447270022 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/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, UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24309 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.60 MARKETING_SUBJECT Subject contains popular marketing words 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Move the cp --reflink tests from btrfs/ to generic/ since xfs now supports that ioctl. Signed-off-by: Darrick J. Wong --- tests/btrfs/026 | 92 ----------------------------------------- tests/btrfs/026.out | 16 ------- tests/btrfs/027 | 109 ------------------------------------------------- tests/btrfs/027.out | 25 ----------- tests/btrfs/028 | 83 ------------------------------------- tests/btrfs/028.out | 7 --- tests/btrfs/group | 3 - tests/generic/800 | 92 +++++++++++++++++++++++++++++++++++++++++ tests/generic/800.out | 16 +++++++ tests/generic/801 | 109 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/801.out | 25 +++++++++++ tests/generic/802 | 83 +++++++++++++++++++++++++++++++++++++ tests/generic/802.out | 7 +++ tests/generic/group | 3 + 14 files changed, 335 insertions(+), 335 deletions(-) delete mode 100755 tests/btrfs/026 delete mode 100644 tests/btrfs/026.out delete mode 100755 tests/btrfs/027 delete mode 100644 tests/btrfs/027.out delete mode 100755 tests/btrfs/028 delete mode 100644 tests/btrfs/028.out create mode 100755 tests/generic/800 create mode 100644 tests/generic/800.out create mode 100755 tests/generic/801 create mode 100644 tests/generic/801.out create mode 100755 tests/generic/802 create mode 100644 tests/generic/802.out diff --git a/tests/btrfs/026 b/tests/btrfs/026 deleted file mode 100755 index 7559ca2..0000000 --- a/tests/btrfs/026 +++ /dev/null @@ -1,92 +0,0 @@ -#! /bin/bash -# FS QA Test No. 026 -# -# Tests file clone functionality of btrfs ("reflinks"): -# - Reflink a file -# - Reflink the reflinked file -# - Modify the original file -# - Modify the reflinked file -# -#----------------------------------------------------------------------- -# Copyright (c) 2014, Oracle and/or its affiliates. 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 -_supported_fs btrfs -_supported_os Linux - -_require_xfs_io_command "fiemap" -_require_cp_reflink -_require_test - -TESTDIR1=$TEST_DIR/test-$seq -rm -rf $TESTDIR1 -mkdir $TESTDIR1 - -_checksum_files() { - for F in original copy1 copy2 - do - md5sum $TESTDIR1/$F | _filter_test_dir - done -} - -rm -f $seqres.full - -echo "Create the original file and reflink to copy1, copy2" -$XFS_IO_PROG -f -c 'pwrite -S 0x61 0 9000' $TESTDIR1/original \ - >> $seqres.full 2>&1 -cp --reflink $TESTDIR1/original $TESTDIR1/copy1 -cp --reflink $TESTDIR1/copy1 $TESTDIR1/copy2 -_verify_reflink $TESTDIR1/original $TESTDIR1/copy1 -_verify_reflink $TESTDIR1/original $TESTDIR1/copy2 -echo "Original md5sums:" -_checksum_files - -echo "Overwrite original file with new data" -$XFS_IO_PROG -c 'pwrite -S 0x62 0 9000' $TESTDIR1/original \ - >> $seqres.full 2>&1 -echo "md5sums after overwriting original:" -_checksum_files - -echo "Overwrite copy1 with different new data" -$XFS_IO_PROG -c 'pwrite -S 0x63 0 9000' $TESTDIR1/copy1 \ - >> $seqres.full 2>&1 -echo "md5sums after overwriting copy1:" -_checksum_files - -# success, all done -status=0 -exit diff --git a/tests/btrfs/026.out b/tests/btrfs/026.out deleted file mode 100644 index 3b90ff0..0000000 --- a/tests/btrfs/026.out +++ /dev/null @@ -1,16 +0,0 @@ -QA output created by 026 -Create the original file and reflink to copy1, copy2 -Original md5sums: -42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-026/original -42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-026/copy1 -42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-026/copy2 -Overwrite original file with new data -md5sums after overwriting original: -4a847a25439532bf48b68c9e9536ed5b TEST_DIR/test-026/original -42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-026/copy1 -42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-026/copy2 -Overwrite copy1 with different new data -md5sums after overwriting copy1: -4a847a25439532bf48b68c9e9536ed5b TEST_DIR/test-026/original -e271cd47d9f62ebc96cb4e67ae4d16db TEST_DIR/test-026/copy1 -42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-026/copy2 diff --git a/tests/btrfs/027 b/tests/btrfs/027 deleted file mode 100755 index d2b812b..0000000 --- a/tests/btrfs/027 +++ /dev/null @@ -1,109 +0,0 @@ -#! /bin/bash -# FS QA Test No. 027 -# -# Tests file clone functionality of btrfs ("reflinks") on directory -# trees. -# - Create directory and subdirectory, each having one file -# - Create 2 recursive reflinked copies of the tree -# - Modify the original files -# - Modify one of the copies -# -#----------------------------------------------------------------------- -# Copyright (c) 2014, Oracle and/or its affiliates. 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 -_supported_fs btrfs -_supported_os Linux - -_require_xfs_io_command "fiemap" -_require_cp_reflink -_require_test - -TESTDIR1=$TEST_DIR/test-$seq -rm -rf $TESTDIR1 -mkdir $TESTDIR1 - -_checksum_files() { - for F in original/file1 original/subdir/file2 \ - copy1/file1 copy1/subdir/file2 \ - copy2/file1 copy2/subdir/file2 - do - md5sum $TESTDIR1/$F | _filter_test_dir - done -} - -rm -f $seqres.full - -mkdir $TESTDIR1/original -mkdir $TESTDIR1/original/subdir - -echo "Create the original files and reflink dirs" -$XFS_IO_PROG -f -c 'pwrite -S 0x61 0 9000' $TESTDIR1/original/file1 \ - >> $seqres.full 2>&1 -$XFS_IO_PROG -f -c 'pwrite -S 0x62 0 11000' \ - $TESTDIR1/original/subdir/file2 >> $seqres.full 2>&1 -cp --recursive --reflink $TESTDIR1/original $TESTDIR1/copy1 -cp --recursive --reflink $TESTDIR1/copy1 $TESTDIR1/copy2 - -_verify_reflink $TESTDIR1/original/file1 $TESTDIR1/copy1/file1 -_verify_reflink $TESTDIR1/original/subdir/file2 \ - $TESTDIR1/copy1/subdir/file2 -_verify_reflink $TESTDIR1/original/file1 $TESTDIR1/copy2/file1 -_verify_reflink $TESTDIR1/original/subdir/file2 \ - $TESTDIR1/copy2/subdir/file2 - -echo "Original md5sums:" -_checksum_files - -echo "Overwrite original/file1 and original/subdir/file2 with new data" -$XFS_IO_PROG -c 'pwrite -S 0x63 0 13000' $TESTDIR1/original/file1 \ - >> $seqres.full 2>&1 -$XFS_IO_PROG -c 'pwrite -S 0x64 5000 1000' \ - $TESTDIR1/original/subdir/file2 >> $seqres.full 2>&1 -echo "md5sums now:" -_checksum_files - -echo "Overwrite copy1/file1 and copy1/subdir/file2 with new data" -$XFS_IO_PROG -c 'pwrite -S 0x65 0 9000' $TESTDIR1/copy1/file1 \ - >> $seqres.full 2>&1 -$XFS_IO_PROG -c 'pwrite -S 0x66 5000 25000' \ - $TESTDIR1/copy1/subdir/file2 >> $seqres.full 2>&1 -echo "md5sums now:" -_checksum_files - -# success, all done -status=0 -exit diff --git a/tests/btrfs/027.out b/tests/btrfs/027.out deleted file mode 100644 index 7b7e3bb..0000000 --- a/tests/btrfs/027.out +++ /dev/null @@ -1,25 +0,0 @@ -QA output created by 027 -Create the original files and reflink dirs -Original md5sums: -42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-027/original/file1 -ca390545f0aedb54b808d6128c56a7dd TEST_DIR/test-027/original/subdir/file2 -42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-027/copy1/file1 -ca390545f0aedb54b808d6128c56a7dd TEST_DIR/test-027/copy1/subdir/file2 -42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-027/copy2/file1 -ca390545f0aedb54b808d6128c56a7dd TEST_DIR/test-027/copy2/subdir/file2 -Overwrite original/file1 and original/subdir/file2 with new data -md5sums now: -260f6785c0537fd12582dcae28a3c1a9 TEST_DIR/test-027/original/file1 -b8d91fb600f6f2191f2ba66665374860 TEST_DIR/test-027/original/subdir/file2 -42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-027/copy1/file1 -ca390545f0aedb54b808d6128c56a7dd TEST_DIR/test-027/copy1/subdir/file2 -42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-027/copy2/file1 -ca390545f0aedb54b808d6128c56a7dd TEST_DIR/test-027/copy2/subdir/file2 -Overwrite copy1/file1 and copy1/subdir/file2 with new data -md5sums now: -260f6785c0537fd12582dcae28a3c1a9 TEST_DIR/test-027/original/file1 -b8d91fb600f6f2191f2ba66665374860 TEST_DIR/test-027/original/subdir/file2 -b20229a003e3985c4b0e6806abcd6642 TEST_DIR/test-027/copy1/file1 -b815b24069db14e0a3a07169fd563e93 TEST_DIR/test-027/copy1/subdir/file2 -42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-027/copy2/file1 -ca390545f0aedb54b808d6128c56a7dd TEST_DIR/test-027/copy2/subdir/file2 diff --git a/tests/btrfs/028 b/tests/btrfs/028 deleted file mode 100755 index 7193337..0000000 --- a/tests/btrfs/028 +++ /dev/null @@ -1,83 +0,0 @@ -#! /bin/bash -# FS QA Test No. 028 -# -# Moving and deleting cloned ("reflinked") files on btrfs: -# - Create a file and a reflink -# - Move both to a directory -# - Delete the original (moved) file, check that the copy still exists. -# -#----------------------------------------------------------------------- -# Copyright (c) 2014, Oracle and/or its affiliates. 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 -_supported_fs btrfs -_supported_os Linux - -_require_xfs_io_command "fiemap" -_require_cp_reflink -_require_test - -rm -f $seqres.full - -TESTDIR1=$TEST_DIR/test-$seq -rm -rf $TESTDIR1 -mkdir $TESTDIR1 - -echo "Create the original files and reflink dirs" -$XFS_IO_PROG -f -c 'pwrite -S 0x61 0 9000' $TESTDIR1/original \ - >> $seqres.full -cp --reflink $TESTDIR1/original $TESTDIR1/copy - -_verify_reflink $TESTDIR1/original $TESTDIR1/copy - -echo "Move orig & reflink copy to subdir and md5sum:" -mkdir $TESTDIR1/subdir -mv $TESTDIR1/original $TESTDIR1/subdir/original_moved -mv $TESTDIR1/copy $TESTDIR1/subdir/copy_moved -_verify_reflink $TESTDIR1/subdir/original_moved \ - $TESTDIR1/subdir/copy_moved - -md5sum $TESTDIR1/subdir/original_moved | _filter_test_dir -md5sum $TESTDIR1/subdir/copy_moved | _filter_test_dir - -echo "remove orig from subdir and md5sum reflink copy:" -rm $TESTDIR1/subdir/original_moved -md5sum $TESTDIR1/subdir/copy_moved | _filter_test_dir -rm -rf $TESTDIR1/subdir - -# success, all done -status=0 -exit diff --git a/tests/btrfs/028.out b/tests/btrfs/028.out deleted file mode 100644 index f683fce..0000000 --- a/tests/btrfs/028.out +++ /dev/null @@ -1,7 +0,0 @@ -QA output created by 028 -Create the original files and reflink dirs -Move orig & reflink copy to subdir and md5sum: -42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-028/subdir/original_moved -42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-028/subdir/copy_moved -remove orig from subdir and md5sum reflink copy: -42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-028/subdir/copy_moved diff --git a/tests/btrfs/group b/tests/btrfs/group index 7cf7dd7..c5d529f 100644 --- a/tests/btrfs/group +++ b/tests/btrfs/group @@ -28,9 +28,6 @@ 023 auto 024 auto quick compress 025 auto quick send clone -026 auto quick clone -027 auto quick clone -028 auto quick clone 029 auto quick clone 030 auto quick send 031 auto quick subvol clone diff --git a/tests/generic/800 b/tests/generic/800 new file mode 100755 index 0000000..a71f11a --- /dev/null +++ b/tests/generic/800 @@ -0,0 +1,92 @@ +#! /bin/bash +# FS QA Test No. 800 +# +# Tests file clone functionality of btrfs ("reflinks"): +# - Reflink a file +# - Reflink the reflinked file +# - Modify the original file +# - Modify the reflinked file +# +#----------------------------------------------------------------------- +# Copyright (c) 2014, Oracle and/or its affiliates. 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 +_supported_fs btrfs +_supported_os Linux + +_require_xfs_io_command "fiemap" +_require_cp_reflink +_require_test + +TESTDIR1=$TEST_DIR/test-$seq +rm -rf $TESTDIR1 +mkdir $TESTDIR1 + +_checksum_files() { + for F in original copy1 copy2 + do + md5sum $TESTDIR1/$F | _filter_test_dir + done +} + +rm -f $seqres.full + +echo "Create the original file and reflink to copy1, copy2" +$XFS_IO_PROG -f -c 'pwrite -S 0x61 0 9000' $TESTDIR1/original \ + >> $seqres.full 2>&1 +cp --reflink $TESTDIR1/original $TESTDIR1/copy1 +cp --reflink $TESTDIR1/copy1 $TESTDIR1/copy2 +_verify_reflink $TESTDIR1/original $TESTDIR1/copy1 +_verify_reflink $TESTDIR1/original $TESTDIR1/copy2 +echo "Original md5sums:" +_checksum_files + +echo "Overwrite original file with new data" +$XFS_IO_PROG -c 'pwrite -S 0x62 0 9000' $TESTDIR1/original \ + >> $seqres.full 2>&1 +echo "md5sums after overwriting original:" +_checksum_files + +echo "Overwrite copy1 with different new data" +$XFS_IO_PROG -c 'pwrite -S 0x63 0 9000' $TESTDIR1/copy1 \ + >> $seqres.full 2>&1 +echo "md5sums after overwriting copy1:" +_checksum_files + +# success, all done +status=0 +exit diff --git a/tests/generic/800.out b/tests/generic/800.out new file mode 100644 index 0000000..6978d71 --- /dev/null +++ b/tests/generic/800.out @@ -0,0 +1,16 @@ +QA output created by 800 +Create the original file and reflink to copy1, copy2 +Original md5sums: +42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-800/original +42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-800/copy1 +42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-800/copy2 +Overwrite original file with new data +md5sums after overwriting original: +4a847a25439532bf48b68c9e9536ed5b TEST_DIR/test-800/original +42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-800/copy1 +42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-800/copy2 +Overwrite copy1 with different new data +md5sums after overwriting copy1: +4a847a25439532bf48b68c9e9536ed5b TEST_DIR/test-800/original +e271cd47d9f62ebc96cb4e67ae4d16db TEST_DIR/test-800/copy1 +42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-800/copy2 diff --git a/tests/generic/801 b/tests/generic/801 new file mode 100755 index 0000000..b21c44b --- /dev/null +++ b/tests/generic/801 @@ -0,0 +1,109 @@ +#! /bin/bash +# FS QA Test No. 801 +# +# Tests file clone functionality of btrfs ("reflinks") on directory +# trees. +# - Create directory and subdirectory, each having one file +# - Create 2 recursive reflinked copies of the tree +# - Modify the original files +# - Modify one of the copies +# +#----------------------------------------------------------------------- +# Copyright (c) 2014, Oracle and/or its affiliates. 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 +_supported_fs btrfs +_supported_os Linux + +_require_xfs_io_command "fiemap" +_require_cp_reflink +_require_test + +TESTDIR1=$TEST_DIR/test-$seq +rm -rf $TESTDIR1 +mkdir $TESTDIR1 + +_checksum_files() { + for F in original/file1 original/subdir/file2 \ + copy1/file1 copy1/subdir/file2 \ + copy2/file1 copy2/subdir/file2 + do + md5sum $TESTDIR1/$F | _filter_test_dir + done +} + +rm -f $seqres.full + +mkdir $TESTDIR1/original +mkdir $TESTDIR1/original/subdir + +echo "Create the original files and reflink dirs" +$XFS_IO_PROG -f -c 'pwrite -S 0x61 0 9000' $TESTDIR1/original/file1 \ + >> $seqres.full 2>&1 +$XFS_IO_PROG -f -c 'pwrite -S 0x62 0 11000' \ + $TESTDIR1/original/subdir/file2 >> $seqres.full 2>&1 +cp --recursive --reflink $TESTDIR1/original $TESTDIR1/copy1 +cp --recursive --reflink $TESTDIR1/copy1 $TESTDIR1/copy2 + +_verify_reflink $TESTDIR1/original/file1 $TESTDIR1/copy1/file1 +_verify_reflink $TESTDIR1/original/subdir/file2 \ + $TESTDIR1/copy1/subdir/file2 +_verify_reflink $TESTDIR1/original/file1 $TESTDIR1/copy2/file1 +_verify_reflink $TESTDIR1/original/subdir/file2 \ + $TESTDIR1/copy2/subdir/file2 + +echo "Original md5sums:" +_checksum_files + +echo "Overwrite original/file1 and original/subdir/file2 with new data" +$XFS_IO_PROG -c 'pwrite -S 0x63 0 13000' $TESTDIR1/original/file1 \ + >> $seqres.full 2>&1 +$XFS_IO_PROG -c 'pwrite -S 0x64 5000 1000' \ + $TESTDIR1/original/subdir/file2 >> $seqres.full 2>&1 +echo "md5sums now:" +_checksum_files + +echo "Overwrite copy1/file1 and copy1/subdir/file2 with new data" +$XFS_IO_PROG -c 'pwrite -S 0x65 0 9000' $TESTDIR1/copy1/file1 \ + >> $seqres.full 2>&1 +$XFS_IO_PROG -c 'pwrite -S 0x66 5000 25000' \ + $TESTDIR1/copy1/subdir/file2 >> $seqres.full 2>&1 +echo "md5sums now:" +_checksum_files + +# success, all done +status=0 +exit diff --git a/tests/generic/801.out b/tests/generic/801.out new file mode 100644 index 0000000..b8225cc --- /dev/null +++ b/tests/generic/801.out @@ -0,0 +1,25 @@ +QA output created by 801 +Create the original files and reflink dirs +Original md5sums: +42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-801/original/file1 +ca390545f0aedb54b808d6128c56a7dd TEST_DIR/test-801/original/subdir/file2 +42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-801/copy1/file1 +ca390545f0aedb54b808d6128c56a7dd TEST_DIR/test-801/copy1/subdir/file2 +42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-801/copy2/file1 +ca390545f0aedb54b808d6128c56a7dd TEST_DIR/test-801/copy2/subdir/file2 +Overwrite original/file1 and original/subdir/file2 with new data +md5sums now: +260f6785c0537fd12582dcae28a3c1a9 TEST_DIR/test-801/original/file1 +b8d91fb600f6f2191f2ba66665374860 TEST_DIR/test-801/original/subdir/file2 +42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-801/copy1/file1 +ca390545f0aedb54b808d6128c56a7dd TEST_DIR/test-801/copy1/subdir/file2 +42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-801/copy2/file1 +ca390545f0aedb54b808d6128c56a7dd TEST_DIR/test-801/copy2/subdir/file2 +Overwrite copy1/file1 and copy1/subdir/file2 with new data +md5sums now: +260f6785c0537fd12582dcae28a3c1a9 TEST_DIR/test-801/original/file1 +b8d91fb600f6f2191f2ba66665374860 TEST_DIR/test-801/original/subdir/file2 +b20229a003e3985c4b0e6806abcd6642 TEST_DIR/test-801/copy1/file1 +b815b24069db14e0a3a07169fd563e93 TEST_DIR/test-801/copy1/subdir/file2 +42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-801/copy2/file1 +ca390545f0aedb54b808d6128c56a7dd TEST_DIR/test-801/copy2/subdir/file2 diff --git a/tests/generic/802 b/tests/generic/802 new file mode 100755 index 0000000..afd8513 --- /dev/null +++ b/tests/generic/802 @@ -0,0 +1,83 @@ +#! /bin/bash +# FS QA Test No. 802 +# +# Moving and deleting cloned ("reflinked") files on btrfs: +# - Create a file and a reflink +# - Move both to a directory +# - Delete the original (moved) file, check that the copy still exists. +# +#----------------------------------------------------------------------- +# Copyright (c) 2014, Oracle and/or its affiliates. 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 +_supported_fs btrfs +_supported_os Linux + +_require_xfs_io_command "fiemap" +_require_cp_reflink +_require_test + +rm -f $seqres.full + +TESTDIR1=$TEST_DIR/test-$seq +rm -rf $TESTDIR1 +mkdir $TESTDIR1 + +echo "Create the original files and reflink dirs" +$XFS_IO_PROG -f -c 'pwrite -S 0x61 0 9000' $TESTDIR1/original \ + >> $seqres.full +cp --reflink $TESTDIR1/original $TESTDIR1/copy + +_verify_reflink $TESTDIR1/original $TESTDIR1/copy + +echo "Move orig & reflink copy to subdir and md5sum:" +mkdir $TESTDIR1/subdir +mv $TESTDIR1/original $TESTDIR1/subdir/original_moved +mv $TESTDIR1/copy $TESTDIR1/subdir/copy_moved +_verify_reflink $TESTDIR1/subdir/original_moved \ + $TESTDIR1/subdir/copy_moved + +md5sum $TESTDIR1/subdir/original_moved | _filter_test_dir +md5sum $TESTDIR1/subdir/copy_moved | _filter_test_dir + +echo "remove orig from subdir and md5sum reflink copy:" +rm $TESTDIR1/subdir/original_moved +md5sum $TESTDIR1/subdir/copy_moved | _filter_test_dir +rm -rf $TESTDIR1/subdir + +# success, all done +status=0 +exit diff --git a/tests/generic/802.out b/tests/generic/802.out new file mode 100644 index 0000000..c20e16e --- /dev/null +++ b/tests/generic/802.out @@ -0,0 +1,7 @@ +QA output created by 802 +Create the original files and reflink dirs +Move orig & reflink copy to subdir and md5sum: +42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-802/subdir/original_moved +42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-802/subdir/copy_moved +remove orig from subdir and md5sum reflink copy: +42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-802/subdir/copy_moved diff --git a/tests/generic/group b/tests/generic/group index 1dd4269..d9421c5 100644 --- a/tests/generic/group +++ b/tests/generic/group @@ -208,3 +208,6 @@ 323 auto aio stress 324 auto fsr quick 325 auto quick data log +800 auto quick clone +801 auto quick clone +802 auto quick clone From darrick.wong@oracle.com Wed Nov 11 13:27:08 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 D899029E27 for ; Wed, 11 Nov 2015 13:27:08 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 94BEA8F8040 for ; Wed, 11 Nov 2015 11:27:08 -0800 (PST) X-ASG-Debug-ID: 1447270025-04bdf03f02121430001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id eBpjOTfGNpZ0Wivw (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 11 Nov 2015 11:27:06 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tABJQiBR028581 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 11 Nov 2015 19:26:44 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id tABJQinp027921 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 11 Nov 2015 19:26:44 GMT Received: from abhmp0005.oracle.com (abhmp0005.oracle.com [141.146.116.11]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id tABJQhhs001823; Wed, 11 Nov 2015 19:26:44 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 11 Nov 2015 11:26:43 -0800 Subject: [PATCH 02/11] generic/80[0-2]: support xfs in addition to btrfs From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 02/11] generic/80[0-2]: support xfs in addition to btrfs To: hch@infradead.org, david@fromorbit.com, darrick.wong@oracle.com Cc: fstests@vger.kernel.org, xfs@oss.sgi.com, tao.peng@primarydata.com, linux-ext4@vger.kernel.org, Anna.Schumaker@netapp.com, linux-btrfs@vger.kernel.org Date: Wed, 11 Nov 2015 11:26:42 -0800 Message-ID: <20151111192642.15056.75362.stgit@birch.djwong.org> In-Reply-To: <20151111192628.15056.6451.stgit@birch.djwong.org> References: <20151111192628.15056.6451.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1447270026 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/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, UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24309 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.60 MARKETING_SUBJECT Subject contains popular marketing words 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Modify the reflink tests to support xfs. Signed-off-by: Darrick J. Wong --- common/rc | 42 ++++++------ common/reflink | 179 +++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/btrfs/029 | 1 tests/btrfs/031 | 1 tests/btrfs/108 | 1 tests/btrfs/109 | 1 tests/generic/800 | 3 + tests/generic/801 | 3 + tests/generic/802 | 3 + 9 files changed, 210 insertions(+), 24 deletions(-) create mode 100644 common/reflink diff --git a/common/rc b/common/rc index adf1edf..c016673 100644 --- a/common/rc +++ b/common/rc @@ -82,6 +82,27 @@ _md5_checksum() md5sum $1 | cut -d ' ' -f1 } +# Write a byte into a range of a file +_pwrite_byte() { + pattern="$1" + offset="$2" + len="$3" + file="$4" + xfs_io_args="$5" + + "$XFS_IO_PROG" $xfs_io_args -f -c "pwrite -S $pattern $offset $len" "$file" +} + +# mmap-write a byte into a range of a file +_mwrite_byte() { + pattern="$1" + offset="$2" + len="$3" + mmap_len="$4" + file="$5" + + "$XFS_IO_PROG" -f -c "mmap -rw 0 $mmap_len" -c "pwrite -S $pattern $offset $len" "$file" +} # ls -l w/ selinux sometimes puts a dot at the end: # -rwxrw-r--. id1 id2 file1 @@ -2569,12 +2590,6 @@ _require_ugid_map() fi } -_require_cp_reflink() -{ - cp --help | grep -q reflink || \ - _notrun "This test requires a cp with --reflink support." -} - _require_fssum() { FSSUM_PROG=$here/src/fssum @@ -2588,21 +2603,6 @@ _require_cloner() _notrun "cloner binary not present at $CLONER_PROG" } -# Given 2 files, verify that they have the same mapping but different -# inodes - i.e. an undisturbed reflink -# Silent if so, make noise if not -_verify_reflink() -{ - # not a hard link or symlink? - cmp -s <(stat -c '%i' $1) <(stat -c '%i' $2) \ - && echo "$1 and $2 are not reflinks: same inode number" - - # same mapping? - diff -u <($XFS_IO_PROG -c "fiemap" $1 | grep -v $1) \ - <($XFS_IO_PROG -c "fiemap" $2 | grep -v $2) \ - || echo "$1 and $2 are not reflinks: different extents" -} - _require_atime() { if [ "$FSTYP" == "nfs" ]; then diff --git a/common/reflink b/common/reflink new file mode 100644 index 0000000..d65816b --- /dev/null +++ b/common/reflink @@ -0,0 +1,179 @@ +##/bin/bash +# Routines for reflinking, deduping, and comparing parts of files. +#----------------------------------------------------------------------- +# Copyright (c) 2015 Oracle. 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; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +# USA +# +# Contact information: Oracle Corporation, 500 Oracle Parkway, +# Redwood Shores, CA 94065, USA, or: http://www.oracle.com/ +#----------------------------------------------------------------------- + +# Check that cp has a reflink argument +_require_cp_reflink() +{ + cp --help | grep -q reflink || \ + _notrun "This test requires a cp with --reflink support." +} + +# Given 2 files, verify that they have the same mapping but different +# inodes - i.e. an undisturbed reflink +# Silent if so, make noise if not +_verify_reflink() +{ + # not a hard link or symlink? + cmp -s <(stat -c '%i' $1) <(stat -c '%i' $2) \ + && echo "$1 and $2 are not reflinks: same inode number" + + # same mapping? + diff -u <($XFS_IO_PROG -c "fiemap" $1 | grep -v $1) \ + <($XFS_IO_PROG -c "fiemap" $2 | grep -v $2) \ + || echo "$1 and $2 are not reflinks: different extents" +} + +# New reflink/dedupe helpers + +# this test requires the test fs support reflink... +_require_test_reflink() +{ + _require_test + _require_xfs_io_command "reflink" + + rm -rf "$TEST_DIR/file1" "$TEST_DIR/file2" + "$XFS_IO_PROG" -f -c "pwrite -S 0x61 0 65536" "$TEST_DIR/file1" > /dev/null + "$XFS_IO_PROG" -f -c "reflink $TEST_DIR/file1 0 0 65536" "$TEST_DIR/file2" > /dev/null + if [ ! -s "$TEST_DIR/file2" ]; then + rm -rf "$TEST_DIR/file1" "$TEST_DIR/file2" + _notrun "Reflink not supported by test filesystem type: $FSTYP" + fi + rm -rf "$TEST_DIR/file1" "$TEST_DIR/file2" +} + +# this test requires the scratch fs support reflink... +_require_scratch_reflink() +{ + _require_scratch + _require_xfs_io_command "reflink" + + _scratch_mkfs > /dev/null + _scratch_mount + "$XFS_IO_PROG" -f -c "pwrite -S 0x61 0 65536" "$SCRATCH_MNT/file1" > /dev/null + "$XFS_IO_PROG" -f -c "reflink $SCRATCH_MNT/file1 0 0 65536" "$SCRATCH_MNT/file2" > /dev/null + if [ ! -s "$SCRATCH_MNT/file2" ]; then + _scratch_unmount + _notrun "Reflink not supported by scratch filesystem type: $FSTYP" + fi + _scratch_unmount +} + +# this test requires the test fs support dedupe... +_require_test_dedupe() +{ + _require_test + _require_xfs_io_command "dedupe" + + rm -rf "$TEST_DIR/file1" "$TEST_DIR/file2" + "$XFS_IO_PROG" -f -c "pwrite -S 0x61 0 65536" "$TEST_DIR/file1" > /dev/null + "$XFS_IO_PROG" -f -c "pwrite -S 0x61 0 65536" "$TEST_DIR/file2" > /dev/null + testio="$("$XFS_IO_PROG" -f -c "dedupe $TEST_DIR/file1 0 0 65536" "$TEST_DIR/file2" 2>&1)" + echo $testio | grep -q "Operation not supported" && \ + _notrun "Dedupe not supported by test filesystem type: $FSTYP" + rm -rf "$TEST_DIR/file1" "$TEST_DIR/file2" +} + +# this test requires the scratch fs support dedupe... +_require_scratch_dedupe() +{ + _require_scratch + _require_xfs_io_command "dedupe" + + _scratch_mkfs > /dev/null + _scratch_mount + "$XFS_IO_PROG" -f -c "pwrite -S 0x61 0 65536" "$SCRATCH_MNT/file1" > /dev/null + "$XFS_IO_PROG" -f -c "pwrite -S 0x61 0 65536" "$SCRATCH_MNT/file2" > /dev/null + testio="$("$XFS_IO_PROG" -f -c "dedupe $TEST_DIR/file1 0 0 65536" "$TEST_DIR/file2" 2>&1)" + echo $testio | grep -q "Operation not supported" && \ + _notrun "Dedupe not supported by test filesystem type: $FSTYP" + _scratch_unmount +} + +# Prints a range of a file as a hex dump +_read_range() { + file="$1" + offset="$2" + len="$3" + xfs_io_args="$4" + + $XFS_IO_PROG $xfs_io_args -f -c "pread -q -v $offset $len" "$file" | cut -d ' ' -f '3-18' +} + +# Compare ranges of two files +_compare_range() { + file1="$1" + offset1="$2" + file2="$3" + offset2="$4" + len="$5" + + cmp -s <(_read_range "$file1" "$offset1" "$len") \ + <(_read_range "$file2" "$offset2" "$len") +} + +# Prints the md5 checksum of a hexdump of a part of a given file +_md5_range_checksum() { + file="$1" + offset="$2" + len="$3" + + md5sum <(_read_range "$file" "$offset" "$len") | cut -d ' ' -f 1 +} + +# Reflink some file1 into file2 via cp +_cp_reflink() { + file1="$1" + file2="$2" + + cp --reflink=always "$file1" "$file2" +} + +# Reflink some file1 into file2 +_reflink() { + file1="$1" + file2="$2" + + "$XFS_IO_PROG" -f -c "reflink $file1" "$file2" +} + +# Reflink some part of file1 into another part of file2 +_reflink_range() { + file1="$1" + offset1="$2" + file2="$3" + offset2="$4" + len="$5" + + "$XFS_IO_PROG" -f -c "reflink $file1 $offset1 $offset2 $len" "$file2" +} + +# Dedupe some part of file1 into another part of file2 +_dedupe_range() { + file1="$1" + offset1="$2" + file2="$3" + offset2="$4" + len="$5" + + "$XFS_IO_PROG" -f -c "dedupe $file1 $offset1 $offset2 $len" "$file2" +} diff --git a/tests/btrfs/029 b/tests/btrfs/029 index 0b77b33..175317a 100755 --- a/tests/btrfs/029 +++ b/tests/btrfs/029 @@ -47,6 +47,7 @@ _cleanup() # get standard environment, filters and checks . ./common/rc . ./common/filter +. ./common/reflink # real QA test starts here _supported_fs btrfs diff --git a/tests/btrfs/031 b/tests/btrfs/031 index bcd332c..c5763da 100755 --- a/tests/btrfs/031 +++ b/tests/btrfs/031 @@ -48,6 +48,7 @@ _cleanup() # get standard environment, filters and checks . ./common/rc . ./common/filter +. ./common/reflink # real QA test starts here _supported_fs btrfs diff --git a/tests/btrfs/108 b/tests/btrfs/108 index 5e3a403..18e5b99 100755 --- a/tests/btrfs/108 +++ b/tests/btrfs/108 @@ -41,6 +41,7 @@ _cleanup() # get standard environment, filters and checks . ./common/rc . ./common/filter +. ./common/reflink # real QA test starts here _supported_fs btrfs diff --git a/tests/btrfs/109 b/tests/btrfs/109 index e2aeb73..b86336c 100755 --- a/tests/btrfs/109 +++ b/tests/btrfs/109 @@ -41,6 +41,7 @@ _cleanup() # get standard environment, filters and checks . ./common/rc . ./common/filter +. ./common/reflink # real QA test starts here _supported_fs btrfs diff --git a/tests/generic/800 b/tests/generic/800 index a71f11a..1e73c33 100755 --- a/tests/generic/800 +++ b/tests/generic/800 @@ -43,9 +43,10 @@ _cleanup() # get standard environment, filters and checks . common/rc . common/filter +. common/reflink # real QA test starts here -_supported_fs btrfs +_require_test_reflink _supported_os Linux _require_xfs_io_command "fiemap" diff --git a/tests/generic/801 b/tests/generic/801 index b21c44b..2facea9 100755 --- a/tests/generic/801 +++ b/tests/generic/801 @@ -43,9 +43,10 @@ _cleanup() # get standard environment, filters and checks . common/rc . common/filter +. common/reflink # real QA test starts here -_supported_fs btrfs +_require_test_reflink _supported_os Linux _require_xfs_io_command "fiemap" diff --git a/tests/generic/802 b/tests/generic/802 index afd8513..aaca2b4 100755 --- a/tests/generic/802 +++ b/tests/generic/802 @@ -41,9 +41,10 @@ _cleanup() # get standard environment, filters and checks . ./common/rc . ./common/filter +. ./common/reflink # real QA test starts here -_supported_fs btrfs +_require_test_reflink _supported_os Linux _require_xfs_io_command "fiemap" From darrick.wong@oracle.com Wed Nov 11 13:27:25 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 6015929E1F for ; Wed, 11 Nov 2015 13:27:25 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 50033304043 for ; Wed, 11 Nov 2015 11:27:25 -0800 (PST) X-ASG-Debug-ID: 1447270038-04cbb0242212cdc0001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id GEWKiZ0pi9lxm7va (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 11 Nov 2015 11:27:18 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tABJQpPn029933 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 11 Nov 2015 19:26:51 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id tABJQp74006922 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 11 Nov 2015 19:26:51 GMT Received: from abhmp0013.oracle.com (abhmp0013.oracle.com [141.146.116.19]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id tABJQpiw001945; Wed, 11 Nov 2015 19:26:51 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 11 Nov 2015 11:26:50 -0800 Subject: [PATCH 03/11] reflink: basic tests of the reflink and dedupe ioctls From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 03/11] reflink: basic tests of the reflink and dedupe ioctls To: hch@infradead.org, david@fromorbit.com, darrick.wong@oracle.com Cc: fstests@vger.kernel.org, xfs@oss.sgi.com, tao.peng@primarydata.com, linux-ext4@vger.kernel.org, Anna.Schumaker@netapp.com, linux-btrfs@vger.kernel.org Date: Wed, 11 Nov 2015 11:26:49 -0800 Message-ID: <20151111192648.15056.40329.stgit@birch.djwong.org> In-Reply-To: <20151111192628.15056.6451.stgit@birch.djwong.org> References: <20151111192628.15056.6451.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0022.oracle.com [141.146.126.234] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1447270038 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24309 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Test the operation of the btrfs (and now xfs) reflink and dedupe ioctls at various file offsets and with matching and nonmatching files. Signed-off-by: Darrick J. Wong --- tests/generic/803 | 92 +++++++++++++++++++++++++++ tests/generic/803.out | 8 ++ tests/generic/804 | 93 +++++++++++++++++++++++++++ tests/generic/804.out | 11 +++ tests/generic/805 | 170 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/805.out | 30 +++++++++ tests/generic/806 | 92 +++++++++++++++++++++++++++ tests/generic/806.out | 8 ++ tests/generic/807 | 92 +++++++++++++++++++++++++++ tests/generic/807.out | 12 +++ tests/generic/817 | 128 +++++++++++++++++++++++++++++++++++++ tests/generic/817.out | 16 +++++ tests/generic/818 | 128 +++++++++++++++++++++++++++++++++++++ tests/generic/818.out | 17 +++++ tests/generic/819 | 131 ++++++++++++++++++++++++++++++++++++++ tests/generic/819.out | 8 ++ tests/generic/group | 8 ++ 17 files changed, 1044 insertions(+) create mode 100755 tests/generic/803 create mode 100644 tests/generic/803.out create mode 100755 tests/generic/804 create mode 100644 tests/generic/804.out create mode 100755 tests/generic/805 create mode 100644 tests/generic/805.out create mode 100755 tests/generic/806 create mode 100644 tests/generic/806.out create mode 100755 tests/generic/807 create mode 100644 tests/generic/807.out create mode 100755 tests/generic/817 create mode 100644 tests/generic/817.out create mode 100755 tests/generic/818 create mode 100644 tests/generic/818.out create mode 100755 tests/generic/819 create mode 100644 tests/generic/819.out diff --git a/tests/generic/803 b/tests/generic/803 new file mode 100755 index 0000000..14c9e98 --- /dev/null +++ b/tests/generic/803 @@ -0,0 +1,92 @@ +#! /bin/bash +# FS QA Test No. 803 +# +# Ensure that we can reflink parts of two identical files: +# - Reflink identical parts of two identical files +# - Check that we still have identical contents +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_reflink + +rm -f "$seqres.full" + +TESTDIR="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original files" +BLKSZ=65536 +_pwrite_byte 0x61 $((BLKSZ * 2)) $((BLKSZ * 6)) "$TESTDIR/file1" >> "$seqres.full" +_pwrite_byte 0x61 $((BLKSZ * 2)) $((BLKSZ * 6)) "$TESTDIR/file2" >> "$seqres.full" +_test_remount + +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir + +_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file2" 0 $((BLKSZ * 8)) \ + || echo "Files do not match" + +echo "Reflink the middle blocks together" +free_before="$(stat -f -c '%a' "$TESTDIR")" +_reflink_range "$TESTDIR/file1" $((BLKSZ * 4)) "$TESTDIR/file2" \ + $((BLKSZ * 4)) $((BLKSZ * 2)) >> "$seqres.full" +_test_remount +free_after="$(stat -f -c '%a' "$TESTDIR")" +echo "freesp changed by $free_before -> $free_after" >> "$seqres.full" + +echo "Compare sections" +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir + +_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file2" 0 $((BLKSZ * 4)) \ + || echo "Start sections do not match" + +_compare_range "$TESTDIR/file1" $((BLKSZ * 4)) "$TESTDIR/file2" \ + $((BLKSZ * 4)) $((BLKSZ * 2)) \ + || echo "Middle sections do not match" + +_compare_range "$TESTDIR/file1" $((BLKSZ * 6)) "$TESTDIR/file2" \ + $((BLKSZ * 6)) $((BLKSZ * 2)) \ + || echo "End sections do not match" + +# success, all done +status=0 +exit diff --git a/tests/generic/803.out b/tests/generic/803.out new file mode 100644 index 0000000..09099aa --- /dev/null +++ b/tests/generic/803.out @@ -0,0 +1,8 @@ +QA output created by 803 +Create the original files +35ac8d7917305c385c30f3d82c30a8f6 TEST_DIR/test-803/file1 +35ac8d7917305c385c30f3d82c30a8f6 TEST_DIR/test-803/file2 +Reflink the middle blocks together +Compare sections +35ac8d7917305c385c30f3d82c30a8f6 TEST_DIR/test-803/file1 +35ac8d7917305c385c30f3d82c30a8f6 TEST_DIR/test-803/file2 diff --git a/tests/generic/804 b/tests/generic/804 new file mode 100755 index 0000000..611ad51 --- /dev/null +++ b/tests/generic/804 @@ -0,0 +1,93 @@ +#! /bin/bash +# FS QA Test No. 804 +# +# Ensuring that we can reflink non-matching parts of files: +# - Reflink identical ranges of two different files +# - Check that the non-linked ranges still do not match +# - Check that we end up with identical contents in the linked ranges +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_reflink + +rm -f "$seqres.full" + +TESTDIR="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original files" +BLKSZ=65536 +_pwrite_byte 0x61 $((BLKSZ * 2)) $((BLKSZ * 6)) "$TESTDIR/file1" >> "$seqres.full" +_pwrite_byte 0x62 $((BLKSZ * 2)) $((BLKSZ * 6)) "$TESTDIR/file2" >> "$seqres.full" +_test_remount + +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir + +_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file2" 0 $((BLKSZ * 8)) \ + || echo "Files do not match (intentional)" + +echo "Reflink the middle blocks together" +free_before="$(stat -f -c '%a' "$TESTDIR")" +_reflink_range "$TESTDIR/file1" $((BLKSZ * 4)) "$TESTDIR/file2" \ + $((BLKSZ * 4)) $((BLKSZ * 2)) >> "$seqres.full" +_test_remount +free_after="$(stat -f -c '%a' "$TESTDIR")" +echo "freesp changed by $free_before -> $free_after" >> "$seqres.full" + +echo "Compare sections" +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir + +_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file2" 0 $((BLKSZ * 4)) \ + || echo "Start sections do not match (intentional)" + +_compare_range "$TESTDIR/file1" $((BLKSZ * 4)) "$TESTDIR/file2" \ + $((BLKSZ * 4)) $((BLKSZ * 2)) \ + || echo "Middle sections do not match" + +_compare_range "$TESTDIR/file1" $((BLKSZ * 6)) "$TESTDIR/file2" \ + $((BLKSZ * 6)) $((BLKSZ * 2)) \ + || echo "End sections do not match (intentional)" + +# success, all done +status=0 +exit diff --git a/tests/generic/804.out b/tests/generic/804.out new file mode 100644 index 0000000..ad40ca2 --- /dev/null +++ b/tests/generic/804.out @@ -0,0 +1,11 @@ +QA output created by 804 +Create the original files +35ac8d7917305c385c30f3d82c30a8f6 TEST_DIR/test-804/file1 +5e3501f97fd2669babfcbd3e1972e833 TEST_DIR/test-804/file2 +Files do not match (intentional) +Reflink the middle blocks together +Compare sections +35ac8d7917305c385c30f3d82c30a8f6 TEST_DIR/test-804/file1 +f7f9e44d37909868014e9151f5293ab0 TEST_DIR/test-804/file2 +Start sections do not match (intentional) +End sections do not match (intentional) diff --git a/tests/generic/805 b/tests/generic/805 new file mode 100755 index 0000000..41ef722 --- /dev/null +++ b/tests/generic/805 @@ -0,0 +1,170 @@ +#! /bin/bash +# FS QA Test No. 805 +# +# Reflinking two sets of files together: +# - Reflink identical parts of two identical files +# - Reflink identical parts of two other identical files +# - Reflink identical parts of all four files +# - Check that we end up with identical contents +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_reflink + +rm -f "$seqres.full" + +TESTDIR=$TEST_DIR/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR + +echo "Create the original files" +BLKSZ=65536 +_pwrite_byte 0x61 0 $((BLKSZ * 8)) "$TESTDIR/file1" >> "$seqres.full" +_pwrite_byte 0x62 0 $((BLKSZ * 8)) "$TESTDIR/file2" >> "$seqres.full" +_pwrite_byte 0x63 0 $((BLKSZ * 8)) "$TESTDIR/file3" >> "$seqres.full" +_pwrite_byte 0x64 0 $((BLKSZ * 8)) "$TESTDIR/file4" >> "$seqres.full" +_test_remount + +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir +md5sum "$TESTDIR/file4" | _filter_test_dir + +_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file2" 0 $((BLKSZ * 8)) \ + || echo "Files 1-2 do not match (intentional)" + +_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file3" 0 $((BLKSZ * 8)) \ + || echo "Files 1-3 do not match (intentional)" + +_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file4" 0 $((BLKSZ * 8)) \ + || echo "Files 1-4 do not match (intentional)" + +echo "Reflink the first four blocks together, 1-2 3-4" +free_before="$(stat -f -c '%a' "$TESTDIR")" +_reflink_range "$TESTDIR/file1" 0 "$TESTDIR/file2" 0 $((BLKSZ * 4)) >> "$seqres.full" +_reflink_range "$TESTDIR/file3" 0 "$TESTDIR/file4" 0 $((BLKSZ * 4)) >> "$seqres.full" +_test_remount +free_after="$(stat -f -c '%a' "$TESTDIR")" +echo "freesp changed by $free_before -> $free_after" >> "$seqres.full" + +echo "Compare sections" +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir +md5sum "$TESTDIR/file4" | _filter_test_dir + +_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file2" 0 $((BLKSZ * 4)) \ + || echo "Sections of file 1-2 do not match" + +_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file3" 0 $((BLKSZ * 4)) \ + || echo "Sections of file 1-3 do not match (intentional)" + +_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file4" 0 $((BLKSZ * 4)) \ + || echo "Sections of file 1-4 do not match (intentional)" + +_compare_range "$TESTDIR/file2" 0 "$TESTDIR/file3" 0 $((BLKSZ * 4)) \ + || echo "Sections of file 2-3 do not match (intentional)" + +_compare_range "$TESTDIR/file2" 0 "$TESTDIR/file4" 0 $((BLKSZ * 4)) \ + || echo "Sections of file 2-4 do not match (intentional)" + +_compare_range "$TESTDIR/file3" 0 "$TESTDIR/file4" 0 $((BLKSZ * 4)) \ + || echo "Sections of file 3-4 do not match" + +echo "Reflink the first two blocks together, 1-3 1-4" +free_before="$(stat -f -c '%a' $TESTDIR)" +_reflink_range "$TESTDIR/file1" 0 "$TESTDIR/file3" 0 $((BLKSZ * 2)) >> "$seqres.full" +_reflink_range "$TESTDIR/file1" 0 "$TESTDIR/file4" 0 $((BLKSZ * 2)) >> "$seqres.full" +_test_remount +free_after="$(stat -f -c '%a' $TESTDIR)" +echo "freesp changed by $free_before -> $free_after" >> "$seqres.full" + +echo "Compare sections" +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir +md5sum "$TESTDIR/file4" | _filter_test_dir + +_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file2" 0 $((BLKSZ * 2)) \ + || echo "Sections of files 1-2 do not match" + +_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file3" 0 $((BLKSZ * 2)) \ + || echo "Sections of files 1-3 do not match" + +_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file4" 0 $((BLKSZ * 2)) \ + || echo "Sections of files 1-4 do not match" + +_compare_range "$TESTDIR/file2" 0 "$TESTDIR/file3" 0 $((BLKSZ * 2)) \ + || echo "Sections of files 2-3 do not match" + +_compare_range "$TESTDIR/file2" 0 "$TESTDIR/file4" 0 $((BLKSZ * 2)) \ + || echo "Sections of files 2-4 do not match" + +_compare_range "$TESTDIR/file3" 0 "$TESTDIR/file4" 0 $((BLKSZ * 2)) \ + || echo "Sections of files 3-4 do not match" + +echo "Compare previously reflinked sections" +_compare_range "$TESTDIR/file1" $((BLKSZ * 2)) "$TESTDIR/file2" \ + $((BLKSZ * 2)) $((BLKSZ * 2)) \ + || echo "Sections of file 1-2 do not match" + +_compare_range "$TESTDIR/file1" $((BLKSZ * 2)) "$TESTDIR/file3" \ + $((BLKSZ * 2)) $((BLKSZ * 2)) \ + || echo "Sections of file 1-3 do not match (intentional)" + +_compare_range "$TESTDIR/file1" $((BLKSZ * 2)) "$TESTDIR/file4" \ + $((BLKSZ * 2)) $((BLKSZ * 2)) \ + || echo "Sections of file 1-4 do not match (intentional)" + +_compare_range "$TESTDIR/file2" $((BLKSZ * 2)) "$TESTDIR/file3" \ + $((BLKSZ * 2)) $((BLKSZ * 2)) \ + || echo "Sections of file 2-3 do not match (intentional)" + +_compare_range "$TESTDIR/file2" $((BLKSZ * 2)) "$TESTDIR/file4" \ + $((BLKSZ * 2)) $((BLKSZ * 2)) \ + || echo "Sections of file 2-4 do not match (intentional)" + +_compare_range "$TESTDIR/file3" $((BLKSZ * 2)) "$TESTDIR/file4" \ + $((BLKSZ * 2)) $((BLKSZ * 2)) \ + || echo "Sections of file 3-4 do not match" + +# success, all done +status=0 +exit diff --git a/tests/generic/805.out b/tests/generic/805.out new file mode 100644 index 0000000..82f9658 --- /dev/null +++ b/tests/generic/805.out @@ -0,0 +1,30 @@ +QA output created by 805 +Create the original files +30c2557e8302a5beb290c71520d87f42 TEST_DIR/test-805/file1 +efb787f7990e43c7dc30565d8cc344d4 TEST_DIR/test-805/file2 +c83f38d4622a78b74e3480634194b08f TEST_DIR/test-805/file3 +1c11fd3151d2229f5cf43903386aa432 TEST_DIR/test-805/file4 +Files 1-2 do not match (intentional) +Files 1-3 do not match (intentional) +Files 1-4 do not match (intentional) +Reflink the first four blocks together, 1-2 3-4 +Compare sections +30c2557e8302a5beb290c71520d87f42 TEST_DIR/test-805/file1 +63bdb182cdf03a8a19e83234d869d00a TEST_DIR/test-805/file2 +c83f38d4622a78b74e3480634194b08f TEST_DIR/test-805/file3 +dc2ae3db14e97fad93faf939170b085c TEST_DIR/test-805/file4 +Sections of file 1-3 do not match (intentional) +Sections of file 1-4 do not match (intentional) +Sections of file 2-3 do not match (intentional) +Sections of file 2-4 do not match (intentional) +Reflink the first two blocks together, 1-3 1-4 +Compare sections +30c2557e8302a5beb290c71520d87f42 TEST_DIR/test-805/file1 +63bdb182cdf03a8a19e83234d869d00a TEST_DIR/test-805/file2 +89a444ff9d6af60ba487e9a0ca2161e2 TEST_DIR/test-805/file3 +0c263058794a54c5e197ece52386f5be TEST_DIR/test-805/file4 +Compare previously reflinked sections +Sections of file 1-3 do not match (intentional) +Sections of file 1-4 do not match (intentional) +Sections of file 2-3 do not match (intentional) +Sections of file 2-4 do not match (intentional) diff --git a/tests/generic/806 b/tests/generic/806 new file mode 100755 index 0000000..ab973e3 --- /dev/null +++ b/tests/generic/806 @@ -0,0 +1,92 @@ +#! /bin/bash +# FS QA Test No. 806 +# +# Ensure that we can dedupe parts of two files: +# - Dedupe identical parts of two identical files +# - Check that still have identical contents +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_reflink + +rm -f "$seqres.full" + +TESTDIR="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original files" +BLKSZ=65536 +_pwrite_byte 0x61 $((BLKSZ * 2)) $((BLKSZ * 6)) "$TESTDIR/file1" >> "$seqres.full" +_pwrite_byte 0x61 $((BLKSZ * 2)) $((BLKSZ * 6)) "$TESTDIR/file2" >> "$seqres.full" +_test_remount + +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir + +_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file2" 0 $((BLKSZ * 8)) \ + || echo "Files 1-2 do not match (intentional)" + +echo "Dedupe the middle blocks together" +free_before="$(stat -f -c '%a' "$TESTDIR")" +_dedupe_range "$TESTDIR/file1" $((BLKSZ * 4)) "$TESTDIR/file2" \ + $((BLKSZ * 4)) $((BLKSZ * 2)) >> "$seqres.full" +_test_remount +free_after="$(stat -f -c '%a' "$TESTDIR")" +echo "freesp changed by $free_before -> $free_after" >> "$seqres.full" + +echo "Compare sections" +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir + +_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file2" 0 $((BLKSZ * 4)) \ + || echo "Start sections do not match" + +_compare_range "$TESTDIR/file1" $((BLKSZ * 4)) "$TESTDIR/file2" \ + $((BLKSZ * 4)) $((BLKSZ * 2)) \ + || echo "Middle sections do not match" + +_compare_range "$TESTDIR/file1" $((BLKSZ * 6)) "$TESTDIR/file2" \ + $((BLKSZ * 6)) $((BLKSZ * 2)) \ + || echo "End sections do not match" + +# success, all done +status=0 +exit diff --git a/tests/generic/806.out b/tests/generic/806.out new file mode 100644 index 0000000..781b545 --- /dev/null +++ b/tests/generic/806.out @@ -0,0 +1,8 @@ +QA output created by 806 +Create the original files +35ac8d7917305c385c30f3d82c30a8f6 TEST_DIR/test-806/file1 +35ac8d7917305c385c30f3d82c30a8f6 TEST_DIR/test-806/file2 +Dedupe the middle blocks together +Compare sections +35ac8d7917305c385c30f3d82c30a8f6 TEST_DIR/test-806/file1 +35ac8d7917305c385c30f3d82c30a8f6 TEST_DIR/test-806/file2 diff --git a/tests/generic/807 b/tests/generic/807 new file mode 100755 index 0000000..6f5168a --- /dev/null +++ b/tests/generic/807 @@ -0,0 +1,92 @@ +#! /bin/bash +# FS QA Test No. 807 +# +# Ensuring that we cannot dedupe non-matching parts of files: +# - Fail to dedupe non-identical parts of two different files +# - Check that nothing changes in either file +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_dedupe + +rm -f "$seqres.full" + +TESTDIR="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original files" +BLKSZ=65536 +_pwrite_byte 0x61 $((BLKSZ * 2)) $((BLKSZ * 6)) "$TESTDIR/file1" >> "$seqres.full" +_pwrite_byte 0x62 $((BLKSZ * 2)) $((BLKSZ * 6)) "$TESTDIR/file2" >> "$seqres.full" +_test_remount + +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir + +_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file2" 0 "$((BLKSZ * 8))" \ + || echo "Files 1-2 do not match (intentional)" + +echo "(Fail to) dedupe the middle blocks together" +free_before="$(stat -f -c '%a' "$TESTDIR")" +_dedupe_range "$TESTDIR/file1" $((BLKSZ * 4)) "$TESTDIR/file2" \ + $((BLKSZ * 4)) $((BLKSZ * 2)) >> "$seqres.full" +_test_remount +free_after="$(stat -f -c '%a' "$TESTDIR")" +echo "freesp changed by $free_before -> $free_after" >> "$seqres.full" + +echo "Compare sections" +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir + +_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file2" 0 $((BLKSZ * 4)) \ + || echo "Start sections do not match (intentional)" + +_compare_range "$TESTDIR/file1" $((BLKSZ * 4)) "$TESTDIR/file2" \ + $((BLKSZ * 4)) $((BLKSZ * 2)) \ + || echo "Middle sections do not match (intentional)" + +_compare_range "$TESTDIR/file1" $((BLKSZ * 6)) "$TESTDIR/file2" \ + $((BLKSZ * 6)) $((BLKSZ * 2)) \ + || echo "End sections do not match (intentional)" + +# success, all done +status=0 +exit diff --git a/tests/generic/807.out b/tests/generic/807.out new file mode 100644 index 0000000..424d039 --- /dev/null +++ b/tests/generic/807.out @@ -0,0 +1,12 @@ +QA output created by 807 +Create the original files +35ac8d7917305c385c30f3d82c30a8f6 TEST_DIR/test-807/file1 +5e3501f97fd2669babfcbd3e1972e833 TEST_DIR/test-807/file2 +Files 1-2 do not match (intentional) +(Fail to) dedupe the middle blocks together +Compare sections +35ac8d7917305c385c30f3d82c30a8f6 TEST_DIR/test-807/file1 +5e3501f97fd2669babfcbd3e1972e833 TEST_DIR/test-807/file2 +Start sections do not match (intentional) +Middle sections do not match (intentional) +End sections do not match (intentional) diff --git a/tests/generic/817 b/tests/generic/817 new file mode 100755 index 0000000..667a79e --- /dev/null +++ b/tests/generic/817 @@ -0,0 +1,128 @@ +#! /bin/bash +# FS QA Test No. 817 +# +# Ensure that we can reflink the last block of a file whose size isn't +# block-aligned. +# - Create two 'a' files file whose size isn't block-aligned. +# - Create two 'b' files file whose size isn't block-aligned. +# - Reflink the last block of file1 to the last block in file2 and file3. +# - Check that files 1-2 match, 3-4 don't match, and that nothing matches 3. +# - Check that the ends of 1-3 match, and 1-3 do not match the end of file4. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_reflink + +rm -f "$seqres.full" + +TESTDIR="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original files" +BLKSZ=65536 +_pwrite_byte 0x61 0 $((BLKSZ + 37)) "$TESTDIR/file1" >> "$seqres.full" +_pwrite_byte 0x61 0 $((BLKSZ + 37)) "$TESTDIR/file2" >> "$seqres.full" +_pwrite_byte 0x62 0 $((BLKSZ + 37)) "$TESTDIR/file3" >> "$seqres.full" +_pwrite_byte 0x62 0 $((BLKSZ + 37)) "$TESTDIR/file4" >> "$seqres.full" +_test_remount + +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir +md5sum "$TESTDIR/file4" | _filter_test_dir + +C1="$(_md5_checksum $TESTDIR/file1)" +C2="$(_md5_checksum $TESTDIR/file2)" +C3="$(_md5_checksum $TESTDIR/file3)" +C4="$(_md5_checksum $TESTDIR/file4)" + +test "${C1}" = "${C2}" || echo "file1 and file2 should match" +test "${C1}" != "${C3}" || echo "file1 and file3 should not match" +test "${C1}" != "${C4}" || echo "file1 and file4 should not match" +test "${C2}" != "${C3}" || echo "file2 and file3 should not match" +test "${C2}" != "${C4}" || echo "file2 and file4 should not match" +test "${C3}" = "${C4}" || echo "file3 and file4 should match" + +echo "Reflink the last blocks together, 1-2 1-3" +_reflink_range "$TESTDIR/file1" $BLKSZ "$TESTDIR/file2" $BLKSZ 37 >> "$seqres.full" +_reflink_range "$TESTDIR/file1" $BLKSZ "$TESTDIR/file3" $BLKSZ 37 >> "$seqres.full" +_test_remount + +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir +md5sum "$TESTDIR/file4" | _filter_test_dir + +C1="$(_md5_checksum $TESTDIR/file1)" +C2="$(_md5_checksum $TESTDIR/file2)" +C3="$(_md5_checksum $TESTDIR/file3)" +C4="$(_md5_checksum $TESTDIR/file4)" + +echo "Compare files" +test "${C1}" = "${C2}" || echo "file1 and file2 should match" +test "${C1}" != "${C3}" || echo "file1 and file3 should not match" +test "${C1}" != "${C4}" || echo "file1 and file4 should not match" +test "${C2}" != "${C3}" || echo "file2 and file3 should not match" +test "${C2}" != "${C4}" || echo "file2 and file4 should not match" +test "${C3}" != "${C4}" || echo "file3 and file4 should match" + +echo "Compare sections" +_compare_range "$TESTDIR/file1" $BLKSZ "$TESTDIR/file2" $BLKSZ 37 \ + || echo "End sections of files 1-2 do not match" + +_compare_range "$TESTDIR/file1" $BLKSZ "$TESTDIR/file3" $BLKSZ 37 \ + || echo "End sections of files 1-3 do not match" + +_compare_range "$TESTDIR/file1" $BLKSZ "$TESTDIR/file4" $BLKSZ 37 \ + || echo "End sections of files 1-4 do not match (intentional)" + +_compare_range "$TESTDIR/file2" $BLKSZ "$TESTDIR/file3" $BLKSZ 37 \ + || echo "End sections of files 2-3 do not match" + +_compare_range "$TESTDIR/file2" $BLKSZ "$TESTDIR/file4" $BLKSZ 37 \ + || echo "End sections of files 2-4 do not match (intentional)" + +_compare_range "$TESTDIR/file3" $BLKSZ "$TESTDIR/file4" $BLKSZ 37 \ + || echo "End sections of files 3-4 do not match (intentional)" + +# success, all done +status=0 +exit diff --git a/tests/generic/817.out b/tests/generic/817.out new file mode 100644 index 0000000..dd6b1ee --- /dev/null +++ b/tests/generic/817.out @@ -0,0 +1,16 @@ +QA output created by 817 +Create the original files +c4fd505be25a0c91bcca9f502b9a8156 TEST_DIR/test-817/file1 +c4fd505be25a0c91bcca9f502b9a8156 TEST_DIR/test-817/file2 +07ac67bf7f271195442509e79cde4cee TEST_DIR/test-817/file3 +07ac67bf7f271195442509e79cde4cee TEST_DIR/test-817/file4 +Reflink the last blocks together, 1-2 1-3 +c4fd505be25a0c91bcca9f502b9a8156 TEST_DIR/test-817/file1 +c4fd505be25a0c91bcca9f502b9a8156 TEST_DIR/test-817/file2 +e236f2fe789f0aa34b50e981a2f0243a TEST_DIR/test-817/file3 +07ac67bf7f271195442509e79cde4cee TEST_DIR/test-817/file4 +Compare files +Compare sections +End sections of files 1-4 do not match (intentional) +End sections of files 2-4 do not match (intentional) +End sections of files 3-4 do not match (intentional) diff --git a/tests/generic/818 b/tests/generic/818 new file mode 100755 index 0000000..fba097d --- /dev/null +++ b/tests/generic/818 @@ -0,0 +1,128 @@ +#! /bin/bash +# FS QA Test No. 818 +# +# Ensure that we can dedupe the last block of a file whose size isn't +# block-aligned. +# - Create two 'a' files file whose size isn't block-aligned. +# - Create two 'b' files file whose size isn't block-aligned. +# - Dedupe the last block of file1 to the last block in file2 and file3. +# - Check that files 1-2 match, and that 3-4 match. +# - Check that the ends of 1-2 and 3-4 match, and that 1-3 don't match. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_dedupe + +rm -f "$seqres.full" + +TESTDIR="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original files" +BLKSZ=65536 +_pwrite_byte 0x61 0 $((BLKSZ + 37)) "$TESTDIR/file1" >> "$seqres.full" +_pwrite_byte 0x61 0 $((BLKSZ + 37)) "$TESTDIR/file2" >> "$seqres.full" +_pwrite_byte 0x62 0 $((BLKSZ + 37)) "$TESTDIR/file3" >> "$seqres.full" +_pwrite_byte 0x62 0 $((BLKSZ + 37)) "$TESTDIR/file4" >> "$seqres.full" +_test_remount + +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir +md5sum "$TESTDIR/file4" | _filter_test_dir + +C1="$(_md5_checksum $TESTDIR/file1)" +C2="$(_md5_checksum $TESTDIR/file2)" +C3="$(_md5_checksum $TESTDIR/file3)" +C4="$(_md5_checksum $TESTDIR/file4)" + +test "${C1}" = "${C2}" || echo "file1 and file2 should match" +test "${C1}" != "${C3}" || echo "file1 and file3 should not match" +test "${C1}" != "${C4}" || echo "file1 and file4 should not match" +test "${C2}" != "${C3}" || echo "file2 and file3 should not match" +test "${C2}" != "${C4}" || echo "file2 and file4 should not match" +test "${C3}" = "${C4}" || echo "file3 and file4 should match" + +echo "Dedupe the last blocks together" +_dedupe_range "$TESTDIR/file1" $BLKSZ "$TESTDIR/file2" $BLKSZ 37 >> "$seqres.full" +_dedupe_range "$TESTDIR/file1" $BLKSZ "$TESTDIR/file3" $BLKSZ 37 >> "$seqres.full" +_test_remount + +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir +md5sum "$TESTDIR/file4" | _filter_test_dir + +C1="$(_md5_checksum $TESTDIR/file1)" +C2="$(_md5_checksum $TESTDIR/file2)" +C3="$(_md5_checksum $TESTDIR/file3)" +C4="$(_md5_checksum $TESTDIR/file4)" + +echo "Compare files" +test "${C1}" = "${C2}" || echo "file1 and file2 should match" +test "${C1}" != "${C3}" || echo "file1 and file3 should not match" +test "${C1}" != "${C4}" || echo "file1 and file4 should not match" +test "${C2}" != "${C3}" || echo "file2 and file3 should not match" +test "${C2}" != "${C4}" || echo "file2 and file4 should not match" +test "${C3}" = "${C4}" || echo "file3 and file4 should match" + +echo "Compare sections" +_compare_range "$TESTDIR/file1" $BLKSZ "$TESTDIR/file2" $BLKSZ 37 \ + || echo "End sections of files 1-2 do not match" + +_compare_range "$TESTDIR/file1" $BLKSZ "$TESTDIR/file3" $BLKSZ 37 \ + || echo "End sections of files 1-3 do not match (intentional)" + +_compare_range "$TESTDIR/file1" $BLKSZ "$TESTDIR/file4" $BLKSZ 37 \ + || echo "End sections of files 1-4 do not match (intentional)" + +_compare_range "$TESTDIR/file2" $BLKSZ "$TESTDIR/file3" $BLKSZ 37 \ + || echo "End sections of files 2-3 do not match (intentional)" + +_compare_range "$TESTDIR/file2" $BLKSZ "$TESTDIR/file4" $BLKSZ 37 \ + || echo "End sections of files 2-4 do not match (intentional)" + +_compare_range "$TESTDIR/file3" $BLKSZ "$TESTDIR/file4" $BLKSZ 37 \ + || echo "End sections of files 3-4 do not match" + +# success, all done +status=0 +exit diff --git a/tests/generic/818.out b/tests/generic/818.out new file mode 100644 index 0000000..f7e30bf --- /dev/null +++ b/tests/generic/818.out @@ -0,0 +1,17 @@ +QA output created by 818 +Create the original files +c4fd505be25a0c91bcca9f502b9a8156 TEST_DIR/test-818/file1 +c4fd505be25a0c91bcca9f502b9a8156 TEST_DIR/test-818/file2 +07ac67bf7f271195442509e79cde4cee TEST_DIR/test-818/file3 +07ac67bf7f271195442509e79cde4cee TEST_DIR/test-818/file4 +Dedupe the last blocks together +c4fd505be25a0c91bcca9f502b9a8156 TEST_DIR/test-818/file1 +c4fd505be25a0c91bcca9f502b9a8156 TEST_DIR/test-818/file2 +07ac67bf7f271195442509e79cde4cee TEST_DIR/test-818/file3 +07ac67bf7f271195442509e79cde4cee TEST_DIR/test-818/file4 +Compare files +Compare sections +End sections of files 1-3 do not match (intentional) +End sections of files 1-4 do not match (intentional) +End sections of files 2-3 do not match (intentional) +End sections of files 2-4 do not match (intentional) diff --git a/tests/generic/819 b/tests/generic/819 new file mode 100755 index 0000000..918868a --- /dev/null +++ b/tests/generic/819 @@ -0,0 +1,131 @@ +#! /bin/bash +# FS QA Test No. 819 +# +# Ensure that we can reflink and dedupe blocks within the same file... +# - Create a file with three distinct blocks ABB +# - Reflink block zero to the multiple-of-three blocks +# - Reflink block one to the multiple-of-five blocks +# - Dedupe block two to the multiple-of-seven blocks +# - Check that we successfully avoid deduping with holes, unwritten +# extents, and non-matches; but actually dedupe real matches. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_reflink +_require_test_dedupe +_require_xfs_io_command "falloc" + +rm -f "$seqres.full" + +TESTDIR="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original file blocks" +BLKSZ=65536 +_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file1" >> "$seqres.full" +_pwrite_byte 0x62 $BLKSZ $((BLKSZ * 2)) "$TESTDIR/file1" >> "$seqres.full" + +NR_BLKS=1024 + +echo "fallocate half the file" +"$XFS_IO_PROG" -f -c "falloc $((NR_BLKS * BLKSZ / 2)) $((NR_BLKS * BLKSZ / 2))" "$TESTDIR/file1" >> "$seqres.full" + +echo "Reflink block zero to the threes" +seq 1 $((NR_BLKS / 3)) | while read nr; do + _reflink_range "$TESTDIR/file1" 0 "$TESTDIR/file1" $((nr * 3 * BLKSZ)) \ + $BLKSZ >> "$seqres.full" +done + +echo "Reflink block one to the fives" +seq 1 $((NR_BLKS / 5)) | while read nr; do + _reflink_range "$TESTDIR/file1" $BLKSZ "$TESTDIR/file1" \ + $((nr * 5 * BLKSZ)) $BLKSZ >> "$seqres.full" +done + +echo "Dedupe block two to the sevens" +seq 1 $((NR_BLKS / 7)) | while read nr; do + _dedupe_range "$TESTDIR/file1" $((BLKSZ * 2)) "$TESTDIR/file1" \ + $((nr * 7 * BLKSZ)) $BLKSZ >> "$seqres.full" +done + +_test_remount + +echo "Check block mappings" +md5sum "$TESTDIR/file1" | _filter_test_dir + +crcZ=$(_md5_range_checksum /dev/zero 0 $BLKSZ) +crc0=$(_md5_range_checksum "$TESTDIR/file1" 0 $BLKSZ) +crc1=$(_md5_range_checksum "$TESTDIR/file1" $BLKSZ $BLKSZ) +crc2=$(_md5_range_checksum "$TESTDIR/file1" $((BLKSZ * 2)) $BLKSZ) + +check_block() { + lblk="$1" + rem7=$((lblk % 7)) + rem5=$((lblk % 5)) + rem3=$((lblk % 3)) + + crc=$(_md5_range_checksum "$TESTDIR/file1" $((lblk * BLKSZ)) $BLKSZ) + + if [ $rem7 -eq 0 ]; then + if [ $rem5 -eq 0 ]; then + test $crc2 = $crc || echo "lblk $lblk doesn't match block 2" + elif [ $rem3 -eq 0 ]; then + test $crc0 = $crc || echo "lblk $lblk doesn't match block 0" + elif [ $lblk -lt $((NR_BLKS / 2)) ]; then + test $crcZ = $crc || echo "lblk $lblk isn't zeroed" + fi + elif [ $rem5 -eq 0 ]; then + test $crc1 = $crc || echo "lblk $lblk doesn't match block 1" + elif [ $rem3 -eq 0 ]; then + test $crc0 = $crc || echo "lblk $lblk doesn't match block 0" + elif [ $lblk -lt $((NR_BLKS / 2)) ]; then + test $crcZ = $crc || echo "lblk $lblk isn't zeroed" + fi +} + +seq 3 $((NR_BLKS - 1)) | while read lblk; do + err="$(check_block $lblk)" + test -n "$err" && echo "$lblk: $err" +done + +# success, all done +status=0 +exit diff --git a/tests/generic/819.out b/tests/generic/819.out new file mode 100644 index 0000000..203275d --- /dev/null +++ b/tests/generic/819.out @@ -0,0 +1,8 @@ +QA output created by 819 +Create the original file blocks +fallocate half the file +Reflink block zero to the threes +Reflink block one to the fives +Dedupe block two to the sevens +Check block mappings +2ea37912bdbd71b9ed4734d3141cbe9c TEST_DIR/test-819/file1 diff --git a/tests/generic/group b/tests/generic/group index d9421c5..7f25037 100644 --- a/tests/generic/group +++ b/tests/generic/group @@ -211,3 +211,11 @@ 800 auto quick clone 801 auto quick clone 802 auto quick clone +803 auto quick clone +804 auto quick clone +805 auto quick clone +806 auto quick clone +807 auto quick clone +817 auto quick clone +818 auto quick clone +819 auto quick clone From darrick.wong@oracle.com Wed Nov 11 13:27:31 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 BABDC29E2A for ; Wed, 11 Nov 2015 13:27:31 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id AC8B28F8035 for ; Wed, 11 Nov 2015 11:27:31 -0800 (PST) X-ASG-Debug-ID: 1447270047-04cbb0242512cdd0001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id gKbeAkjaQ6E9jwMs (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 11 Nov 2015 11:27:27 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tABJR2w0030477 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 11 Nov 2015 19:27:02 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id tABJR1N8029105 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 11 Nov 2015 19:27:02 GMT Received: from abhmp0008.oracle.com (abhmp0008.oracle.com [141.146.116.14]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id tABJR1nh019850; Wed, 11 Nov 2015 19:27:01 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 11 Nov 2015 11:26:57 -0800 Subject: [PATCH 04/11] reflink: test CoW behaviors of reflinked files From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 04/11] reflink: test CoW behaviors of reflinked files To: hch@infradead.org, david@fromorbit.com, darrick.wong@oracle.com Cc: fstests@vger.kernel.org, xfs@oss.sgi.com, tao.peng@primarydata.com, linux-ext4@vger.kernel.org, Anna.Schumaker@netapp.com, linux-btrfs@vger.kernel.org Date: Wed, 11 Nov 2015 11:26:56 -0800 Message-ID: <20151111192656.15056.46709.stgit@birch.djwong.org> In-Reply-To: <20151111192628.15056.6451.stgit@birch.djwong.org> References: <20151111192628.15056.6451.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1447270047 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24309 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Ensure that CoW happens correctly with buffered, directio, and mmap writes. Signed-off-by: Darrick J. Wong --- tests/generic/808 | 152 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/808.out | 19 ++++++ tests/generic/809 | 151 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/809.out | 19 ++++++ tests/generic/810 | 152 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/810.out | 19 ++++++ tests/generic/837 | 91 +++++++++++++++++++++++++++++ tests/generic/837.out | 8 +++ tests/generic/838 | 91 +++++++++++++++++++++++++++++ tests/generic/838.out | 8 +++ tests/generic/group | 5 ++ 11 files changed, 715 insertions(+) create mode 100755 tests/generic/808 create mode 100644 tests/generic/808.out create mode 100755 tests/generic/809 create mode 100644 tests/generic/809.out create mode 100755 tests/generic/810 create mode 100644 tests/generic/810.out create mode 100755 tests/generic/837 create mode 100644 tests/generic/837.out create mode 100755 tests/generic/838 create mode 100644 tests/generic/838.out diff --git a/tests/generic/808 b/tests/generic/808 new file mode 100755 index 0000000..3a3ec58 --- /dev/null +++ b/tests/generic/808 @@ -0,0 +1,152 @@ +#! /bin/bash +# FS QA Test No. 808 +# +# Ensuring that copy on write through the page cache works: +# - Reflink two files together +# - Write to the beginning, middle, and end +# - Check that the files are now different where we say they're different. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_reflink +_require_cp_reflink + +rm -f "$seqres.full" + +TESTDIR="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original files" +BLKSZ=65536 +_pwrite_byte 0x61 0 $((BLKSZ * 48 - 3)) "$TESTDIR/file1" >> "$seqres.full" +_cp_reflink "$TESTDIR/file1" "$TESTDIR/file2" >> "$seqres.full" +_pwrite_byte 0x61 0 $((BLKSZ * 48 - 3)) "$TESTDIR/file3" >> "$seqres.full" +_test_remount + +echo "Compare files" +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir + +cmp -s "$TESTDIR/file1" "$TESTDIR/file2" || echo "Files 1-2 do not match" +cmp -s "$TESTDIR/file1" "$TESTDIR/file3" || echo "Files 1-3 do not match" +cmp -s "$TESTDIR/file2" "$TESTDIR/file3" || echo "Files 2-3 do not match" + +echo "pagecache CoW the second file" +_pwrite_byte 0x62 0 17 "$TESTDIR/file2" >> "$seqres.full" +_pwrite_byte 0x62 0 17 "$TESTDIR/file3" >> "$seqres.full" + +_pwrite_byte 0x62 $((BLKSZ * 16 - 34)) 17 "$TESTDIR/file2" >> "$seqres.full" +_pwrite_byte 0x62 $((BLKSZ * 16 - 34)) 17 "$TESTDIR/file3" >> "$seqres.full" + +_pwrite_byte 0x62 $((BLKSZ * 48 - 8)) 17 "$TESTDIR/file2" >> "$seqres.full" +_pwrite_byte 0x62 $((BLKSZ * 48 - 8)) 17 "$TESTDIR/file3" >> "$seqres.full" +_test_remount + +echo "Compare files" +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir + +cmp -s "$TESTDIR/file1" "$TESTDIR/file2" || echo "Files 1-2 do not match (intentional)" +cmp -s "$TESTDIR/file1" "$TESTDIR/file3" || echo "Files 1-3 do not match (intentional)" +cmp -s "$TESTDIR/file2" "$TESTDIR/file3" || echo "Files 2-3 do not match" + +echo "Compare the CoW'd section to the before file" +_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file2" 0 17 \ + || echo "Start sections do not match (intentional)" + +_compare_range "$TESTDIR/file1" $((BLKSZ * 16 - 34)) \ + "$TESTDIR/file2" $((BLKSZ * 16 - 34)) 17 \ + || echo "Middle sections do not match (intentional)" + +_compare_range "$TESTDIR/file1" $((BLKSZ * 48 - 8)) \ + "$TESTDIR/file2" $((BLKSZ * 48 - 8)) 17 \ + || echo "End sections do not match (intentional)" + +echo "Compare the CoW'd section to the after file" +_compare_range "$TESTDIR/file2" 0 "$TESTDIR/file3" 0 17 \ + || echo "Start sections do not match" + +_compare_range "$TESTDIR/file2" $((BLKSZ * 16 - 34)) \ + "$TESTDIR/file3" $((BLKSZ * 16 - 34)) 17 \ + || echo "Middle sections do not match" + +_compare_range "$TESTDIR/file2" $((BLKSZ * 48 - 8)) \ + "$TESTDIR/file3" $((BLKSZ * 48 - 8)) 17 \ + || echo "End sections do not match" + +echo "Compare the not CoW'd sections" +_compare_range "$TESTDIR/file1" 18 "$TESTDIR/file2" 18 17 \ + || echo "Start sections of 1-2 do not match" + +_compare_range "$TESTDIR/file2" 18 "$TESTDIR/file3" 18 17 \ + || echo "Start sections of 2-3 do not match" + + +_compare_range "$TESTDIR/file1" $((BLKSZ * 16 - 17)) \ + "$TESTDIR/file2" $((BLKSZ * 16 - 17)) 82 \ + || echo "Middle sections of 1-2 do not match" + +_compare_range "$TESTDIR/file2" $((BLKSZ * 16 - 17)) \ + "$TESTDIR/file3" $((BLKSZ * 16 - 17)) 82 \ + || echo "Middle sections of 2-3 do not match" + +_compare_range "$TESTDIR/file1" $((BLKSZ * 48 - 108)) \ + "$TESTDIR/file2" $((BLKSZ * 48 - 108)) 100 \ + || echo "End sections of 1-2 do not match" + +_compare_range "$TESTDIR/file2" $((BLKSZ * 48 - 108)) \ + "$TESTDIR/file3" $((BLKSZ * 48 - 108)) 100 \ + || echo "End sections of 2-3 do not match" + + +_compare_range "$TESTDIR/file1" $((BLKSZ * 14)) \ + "$TESTDIR/file2" $((BLKSZ * 14)) $BLKSZ \ + || echo "Untouched sections of 1-2 do not match" + +_compare_range "$TESTDIR/file2" $((BLKSZ * 14)) \ + "$TESTDIR/file3" $((BLKSZ * 14)) $BLKSZ \ + || echo "Untouched sections of 2-3 do not match" + +# success, all done +status=0 +exit diff --git a/tests/generic/808.out b/tests/generic/808.out new file mode 100644 index 0000000..1e82e2d --- /dev/null +++ b/tests/generic/808.out @@ -0,0 +1,19 @@ +QA output created by 808 +Create the original files +Compare files +60ebe700450b6015c17fa15cacb9493b TEST_DIR/test-808/file1 +60ebe700450b6015c17fa15cacb9493b TEST_DIR/test-808/file2 +60ebe700450b6015c17fa15cacb9493b TEST_DIR/test-808/file3 +pagecache CoW the second file +Compare files +60ebe700450b6015c17fa15cacb9493b TEST_DIR/test-808/file1 +4a879c2f322121f6f4b8ebede1909a7c TEST_DIR/test-808/file2 +4a879c2f322121f6f4b8ebede1909a7c TEST_DIR/test-808/file3 +Files 1-2 do not match (intentional) +Files 1-3 do not match (intentional) +Compare the CoW'd section to the before file +Start sections do not match (intentional) +Middle sections do not match (intentional) +End sections do not match (intentional) +Compare the CoW'd section to the after file +Compare the not CoW'd sections diff --git a/tests/generic/809 b/tests/generic/809 new file mode 100755 index 0000000..99e88f6 --- /dev/null +++ b/tests/generic/809 @@ -0,0 +1,151 @@ +#! /bin/bash +# FS QA Test No. 809 +# +# Ensuring that copy on write in direct-io mode works: +# - Reflink two files together +# - Write to the beginning, middle, and end in direct-io mode +# - Check that the files are now different where we say they're different. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_reflink +_require_cp_reflink + +rm -f "$seqres.full" + +TESTDIR=$TEST_DIR/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR + +echo "Create the original files" +BLKSZ=65536 +_pwrite_byte 0x61 0 $((BLKSZ * 48 - 3)) "$TESTDIR/file1" >> "$seqres.full" +_cp_reflink "$TESTDIR/file1" "$TESTDIR/file2" >> "$seqres.full" +_pwrite_byte 0x61 0 $((BLKSZ * 48 - 3)) "$TESTDIR/file3" >> "$seqres.full" +_test_remount + +echo "Compare files" +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir + +cmp -s "$TESTDIR/file1" "$TESTDIR/file2" || echo "Files 1-2 should match" +cmp -s "$TESTDIR/file1" "$TESTDIR/file3" || echo "Files 1-3 should match" +cmp -s "$TESTDIR/file2" "$TESTDIR/file3" || echo "Files 2-3 should match" + +echo "directio CoW the second file" +_pwrite_byte 0x62 0 $BLKSZ "$TESTDIR/file2" -d >> "$seqres.full" +_pwrite_byte 0x62 0 $BLKSZ "$TESTDIR/file3" -d >> "$seqres.full" + +_pwrite_byte 0x62 $((BLKSZ * 16 - 512)) 512 "$TESTDIR/file2" -d >> "$seqres.full" +_pwrite_byte 0x62 $((BLKSZ * 16 - 512)) 512 "$TESTDIR/file3" -d >> "$seqres.full" + +_pwrite_byte 0x62 $((BLKSZ * 48)) $BLKSZ "$TESTDIR/file2" -d >> "$seqres.full" +_pwrite_byte 0x62 $((BLKSZ * 48)) $BLKSZ "$TESTDIR/file3" -d >> "$seqres.full" +_test_remount + +echo "Compare files" +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir + +cmp -s "$TESTDIR/file1" "$TESTDIR/file2" || echo "Files 1-2 should not match (intentional)" +cmp -s "$TESTDIR/file1" "$TESTDIR/file3" || echo "Files 1-3 should not match (intentional)" +cmp -s "$TESTDIR/file2" "$TESTDIR/file3" || echo "Files 2-3 should match" + +echo "Compare the CoW'd section to the before file" +_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file2" 0 $BLKSZ \ + || echo "Start sections do not match (intentional)" + +_compare_range "$TESTDIR/file1" $((BLKSZ * 16 - 512)) \ + "$TESTDIR/file2" $((BLKSZ * 16 - 512)) 512 \ + || echo "Middle sections do not match (intentional)" + +_compare_range "$TESTDIR/file1" $((BLKSZ * 48 - 512)) \ + "$TESTDIR/file2" $((BLKSZ * 48 - 512)) $BLKSZ \ + || echo "End sections do not match (intentional)" + +echo "Compare the CoW'd section to the after file" +_compare_range "$TESTDIR/file2" 0 "$TESTDIR/file3" 0 $BLKSZ \ + || echo "Start sections do not match" + +_compare_range "$TESTDIR/file2" $((BLKSZ * 16 - 512)) \ + "$TESTDIR/file3" $((BLKSZ * 16 - 512)) 512 \ + || echo "Middle sections do not match" + +_compare_range "$TESTDIR/file2" $((BLKSZ * 48 - 512)) \ + "$TESTDIR/file3" $((BLKSZ * 48 - 512)) $BLKSZ \ + || echo "End sections do not match" + +echo "Compare the not CoW'd sections" +_compare_range "$TESTDIR/file1" $BLKSZ "$TESTDIR/file2" $BLKSZ 512 \ + || echo "Start sections of 1-2 do not match" +_compare_range "$TESTDIR/file2" $BLKSZ "$TESTDIR/file3" $BLKSZ 512 \ + || echo "Start sections of 2-3 do not match" + + +_compare_range "$TESTDIR/file1" $((BLKSZ * 16 - 1024)) \ + "$TESTDIR/file2" $((BLKSZ * 16 - 1024)) 512 \ + || echo "Middle sections of 1-2 do not match" + +_compare_range "$TESTDIR/file2" $((BLKSZ * 16 - 1024)) \ + "$TESTDIR/file3" $((BLKSZ * 16 - 1024)) 512 \ + || echo "Middle sections of 2-3 do not match" + +_compare_range "$TESTDIR/file1" $((BLKSZ * 48 - 1024)) \ + "$TESTDIR/file2" $((BLKSZ * 48 - 1024)) 512 \ + || echo "End sections of 1-2 do not match" + +_compare_range "$TESTDIR/file2" $((BLKSZ * 48 - 1024)) \ + "$TESTDIR/file3" $((BLKSZ * 48 - 1024)) 512 \ + || echo "End sections of 2-3 do not match" + + +_compare_range "$TESTDIR/file1" $((BLKSZ * 16)) \ + "$TESTDIR/file2" $((BLKSZ * 16)) 512 \ + || echo "Untouched sections of 1-2 do not match" + +_compare_range "$TESTDIR/file2" $((BLKSZ * 16)) \ + "$TESTDIR/file3" $((BLKSZ * 16)) 512 \ + || echo "Untouched sections of 2-3 do not match" + +# success, all done +status=0 +exit diff --git a/tests/generic/809.out b/tests/generic/809.out new file mode 100644 index 0000000..ad63e4e --- /dev/null +++ b/tests/generic/809.out @@ -0,0 +1,19 @@ +QA output created by 809 +Create the original files +Compare files +60ebe700450b6015c17fa15cacb9493b TEST_DIR/test-809/file1 +60ebe700450b6015c17fa15cacb9493b TEST_DIR/test-809/file2 +60ebe700450b6015c17fa15cacb9493b TEST_DIR/test-809/file3 +directio CoW the second file +Compare files +60ebe700450b6015c17fa15cacb9493b TEST_DIR/test-809/file1 +ff5626fb6c71b242d6b1a43de25c9a85 TEST_DIR/test-809/file2 +ff5626fb6c71b242d6b1a43de25c9a85 TEST_DIR/test-809/file3 +Files 1-2 should not match (intentional) +Files 1-3 should not match (intentional) +Compare the CoW'd section to the before file +Start sections do not match (intentional) +Middle sections do not match (intentional) +End sections do not match (intentional) +Compare the CoW'd section to the after file +Compare the not CoW'd sections diff --git a/tests/generic/810 b/tests/generic/810 new file mode 100755 index 0000000..3b635f8 --- /dev/null +++ b/tests/generic/810 @@ -0,0 +1,152 @@ +#! /bin/bash +# FS QA Test No. 810 +# +# Ensuring that mmap copy on write through the page cache works: +# - Reflink two files together +# - Write to the beginning, middle, and end +# - Check that the files are now different where we say they're different. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_reflink +_require_cp_reflink + +rm -f "$seqres.full" + +TESTDIR="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original files" +BLKSZ=65536 +_pwrite_byte 0x61 0 $((BLKSZ * 48 - 3)) "$TESTDIR/file1" >> "$seqres.full" +_cp_reflink "$TESTDIR/file1" "$TESTDIR/file2" >> "$seqres.full" +_pwrite_byte 0x61 0 $((BLKSZ * 48 - 3)) "$TESTDIR/file3" >> "$seqres.full" +_test_remount + +echo "Compare files" +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir + +cmp -s "$TESTDIR/file1" "$TESTDIR/file2" || echo "Files 1-2 do not match" +cmp -s "$TESTDIR/file1" "$TESTDIR/file3" || echo "Files 1-3 do not match" +cmp -s "$TESTDIR/file2" "$TESTDIR/file3" || echo "Files 2-3 do not match" + +echo "mmap CoW the second file" +_mwrite_byte 0x62 0 17 $((BLKSZ * 48 - 3)) "$TESTDIR/file2" >> "$seqres.full" +_mwrite_byte 0x62 0 17 $((BLKSZ * 48 - 3)) "$TESTDIR/file3" >> "$seqres.full" + +_mwrite_byte 0x62 $((BLKSZ * 16 - 34)) 17 $((BLKSZ * 48 - 3)) "$TESTDIR/file2" >> "$seqres.full" +_mwrite_byte 0x62 $((BLKSZ * 16 - 34)) 17 $((BLKSZ * 48 - 3)) "$TESTDIR/file3" >> "$seqres.full" + +_mwrite_byte 0x62 $((BLKSZ * 48 - 20)) 17 $((BLKSZ * 48 - 3)) "$TESTDIR/file2" >> "$seqres.full" +_mwrite_byte 0x62 $((BLKSZ * 48 - 20)) 17 $((BLKSZ * 48 - 3)) "$TESTDIR/file3" >> "$seqres.full" +_test_remount + +echo "Compare files" +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir + +cmp -s "$TESTDIR/file1" "$TESTDIR/file2" || echo "Files 1-2 do not match (intentional)" +cmp -s "$TESTDIR/file1" "$TESTDIR/file3" || echo "Files 1-3 do not match (intentional)" +cmp -s "$TESTDIR/file2" "$TESTDIR/file3" || echo "Files 2-3 do not match" + +echo "Compare the CoW'd section to the before file" +_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file2" 0 17 \ + || echo "Start sections do not match (intentional)" + +_compare_range "$TESTDIR/file1" $((BLKSZ * 16 - 34)) \ + "$TESTDIR/file2" $((BLKSZ * 16 - 34)) 17 \ + || echo "Middle sections do not match (intentional)" + +_compare_range "$TESTDIR/file1" $((BLKSZ * 48 - 20)) \ + "$TESTDIR/file2" $((BLKSZ * 48 - 20)) 17 \ + || echo "End sections do not match (intentional)" + +echo "Compare the CoW'd section to the after file" +_compare_range "$TESTDIR/file2" 0 "$TESTDIR/file3" 0 17 \ + || echo "Start sections do not match" + +_compare_range "$TESTDIR/file2" $((BLKSZ * 16 - 34)) \ + "$TESTDIR/file3" $((BLKSZ * 16 - 34)) 17 \ + || echo "Middle sections do not match" + +_compare_range "$TESTDIR/file2" $((BLKSZ * 48 - 20)) \ + "$TESTDIR/file3" $((BLKSZ * 48 - 20)) 17 \ + || echo "End sections do not match" + +echo "Compare the not CoW'd sections" +_compare_range "$TESTDIR/file1" 18 "$TESTDIR/file2" 18 17 \ + || echo "Start sections of 1-2 do not match" + +_compare_range "$TESTDIR/file2" 18 "$TESTDIR/file3" 18 17 \ + || echo "Start sections of 2-3 do not match" + + +_compare_range "$TESTDIR/file1" $((BLKSZ * 16 - 17)) \ + "$TESTDIR/file2" $((BLKSZ * 16 - 17)) 82 \ + || echo "Middle sections of 1-2 do not match" + +_compare_range "$TESTDIR/file2" $((BLKSZ * 16 - 17)) \ + "$TESTDIR/file3" $((BLKSZ * 16 - 17)) 82 \ + || echo "Middle sections of 2-3 do not match" + +_compare_range "$TESTDIR/file1" $((BLKSZ * 48 - 120)) \ + "$TESTDIR/file2" $((BLKSZ * 48 - 120)) 100 \ + || echo "End sections of 1-2 do not match" + +_compare_range "$TESTDIR/file2" $((BLKSZ * 48 - 120)) \ + "$TESTDIR/file3" $((BLKSZ * 48 - 120)) 100 \ + || echo "End sections of 2-3 do not match" + + +_compare_range "$TESTDIR/file1" $((BLKSZ * 14)) \ + "$TESTDIR/file2" $((BLKSZ * 14)) $BLKSZ \ + || echo "Untouched sections of 1-2 do not match" + +_compare_range "$TESTDIR/file2" $((BLKSZ * 14)) \ + "$TESTDIR/file3" $((BLKSZ * 14)) $BLKSZ \ + || echo "Untouched sections of 2-3 do not match" + +# success, all done +status=0 +exit diff --git a/tests/generic/810.out b/tests/generic/810.out new file mode 100644 index 0000000..8cc94ab --- /dev/null +++ b/tests/generic/810.out @@ -0,0 +1,19 @@ +QA output created by 810 +Create the original files +Compare files +60ebe700450b6015c17fa15cacb9493b TEST_DIR/test-810/file1 +60ebe700450b6015c17fa15cacb9493b TEST_DIR/test-810/file2 +60ebe700450b6015c17fa15cacb9493b TEST_DIR/test-810/file3 +mmap CoW the second file +Compare files +60ebe700450b6015c17fa15cacb9493b TEST_DIR/test-810/file1 +795ecfd281dbda4916431376228e4187 TEST_DIR/test-810/file2 +795ecfd281dbda4916431376228e4187 TEST_DIR/test-810/file3 +Files 1-2 do not match (intentional) +Files 1-3 do not match (intentional) +Compare the CoW'd section to the before file +Start sections do not match (intentional) +Middle sections do not match (intentional) +End sections do not match (intentional) +Compare the CoW'd section to the after file +Compare the not CoW'd sections diff --git a/tests/generic/837 b/tests/generic/837 new file mode 100755 index 0000000..de5f233 --- /dev/null +++ b/tests/generic/837 @@ -0,0 +1,91 @@ +#! /bin/bash +# FS QA Test No. 837 +# +# Ensure that reflinking a file N times and CoWing the copies leaves the +# original intact. +# - Create a file and record its hash +# - Create some reflink copies +# - Rewrite all the reflink copies +# - Compare the contents of the original file +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_reflink +_require_cp_reflink + +rm -f "$seqres.full" + +TESTDIR="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original file blocks" +BLKSZ=65536 +NR=9 +_pwrite_byte 0x61 0 $((BLKSZ * 256)) "$TESTDIR/file1" >> "$seqres.full" +_test_remount + +md5sum "$TESTDIR/file1" | _filter_test_dir +csum="$(_md5_checksum "$TESTDIR/file1")" + +echo "Create the reflink copies" +seq 2 $NR | while read i; do + _cp_reflink "$TESTDIR/file1" "$TESTDIR/file$i" +done +_test_remount + +echo "Rewrite the copies" +seq 2 $NR | while read i; do + _pwrite_byte 0x62 0 $((BLKSZ * 256)) "$TESTDIR/file$i" >> "$seqres.full" +done +_test_remount + +echo "Examine original file" +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir + +mod_csum="$(_md5_checksum "$TESTDIR/file2")" +new_csum="$(_md5_checksum "$TESTDIR/file1")" +test "${csum}" != "${mod_csum}" || echo "checksums do not match" +test "${csum}" = "${new_csum}" || echo "checksums do not match" + +# success, all done +status=0 +exit diff --git a/tests/generic/837.out b/tests/generic/837.out new file mode 100644 index 0000000..3f9c2e5 --- /dev/null +++ b/tests/generic/837.out @@ -0,0 +1,8 @@ +QA output created by 837 +Create the original file blocks +f4820540fc0ac02750739896fe028d56 TEST_DIR/test-837/file1 +Create the reflink copies +Rewrite the copies +Examine original file +f4820540fc0ac02750739896fe028d56 TEST_DIR/test-837/file1 +eb34153e9ed1e774db28cbbe4090a449 TEST_DIR/test-837/file2 diff --git a/tests/generic/838 b/tests/generic/838 new file mode 100755 index 0000000..1130a2c --- /dev/null +++ b/tests/generic/838 @@ -0,0 +1,91 @@ +#! /bin/bash +# FS QA Test No. 838 +# +# Ensure that reflinking a file N times and DIO CoWing the copies leaves the +# original intact. +# - Create a file and record its hash +# - Create some reflink copies +# - Rewrite all the reflink copies w/ directio +# - Compare the contents of the original file +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_reflink +_require_cp_reflink + +rm -f "$seqres.full" + +TESTDIR="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original file blocks" +BLKSZ=65536 +NR=9 +_pwrite_byte 0x61 0 $((BLKSZ * 256)) "$TESTDIR/file1" >> "$seqres.full" +_test_remount + +md5sum "$TESTDIR/file1" | _filter_test_dir +csum="$(_md5_checksum "$TESTDIR/file1")" + +echo "Create the reflink copies" +seq 2 $NR | while read i; do + _cp_reflink "$TESTDIR/file1" "$TESTDIR/file$i" +done +_test_remount + +echo "Rewrite the copies" +seq 2 $NR | while read i; do + _pwrite_byte 0x62 0 $((BLKSZ * 256)) "$TESTDIR/file$i" -d >> "$seqres.full" +done +_test_remount + +echo "Examine original file" +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir + +mod_csum="$(_md5_checksum "$TESTDIR/file2")" +new_csum="$(_md5_checksum "$TESTDIR/file1")" +test "${csum}" != "${mod_csum}" || echo "checksums do not match" +test "${csum}" = "${new_csum}" || echo "checksums do not match" + +# success, all done +status=0 +exit diff --git a/tests/generic/838.out b/tests/generic/838.out new file mode 100644 index 0000000..cc44815 --- /dev/null +++ b/tests/generic/838.out @@ -0,0 +1,8 @@ +QA output created by 838 +Create the original file blocks +f4820540fc0ac02750739896fe028d56 TEST_DIR/test-838/file1 +Create the reflink copies +Rewrite the copies +Examine original file +f4820540fc0ac02750739896fe028d56 TEST_DIR/test-838/file1 +eb34153e9ed1e774db28cbbe4090a449 TEST_DIR/test-838/file2 diff --git a/tests/generic/group b/tests/generic/group index 7f25037..a72d416 100644 --- a/tests/generic/group +++ b/tests/generic/group @@ -216,6 +216,11 @@ 805 auto quick clone 806 auto quick clone 807 auto quick clone +808 auto quick clone +809 auto quick clone +810 auto quick clone 817 auto quick clone 818 auto quick clone 819 auto quick clone +837 auto quick clone +838 auto quick clone From darrick.wong@oracle.com Wed Nov 11 13:27:33 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 4A1C47F63 for ; Wed, 11 Nov 2015 13:27:33 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 2C87E304043 for ; Wed, 11 Nov 2015 11:27:33 -0800 (PST) X-ASG-Debug-ID: 1447270048-04cb6c296a125180001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id SlEklS3EWFDkLaID (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 11 Nov 2015 11:27:28 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tABJR506030561 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 11 Nov 2015 19:27:06 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id tABJR50H023590 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 11 Nov 2015 19:27:05 GMT Received: from abhmp0002.oracle.com (abhmp0002.oracle.com [141.146.116.8]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id tABJR5tU002085; Wed, 11 Nov 2015 19:27:05 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 11 Nov 2015 11:27:04 -0800 Subject: [PATCH 05/11] reflink: test the various fallocate modes From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 05/11] reflink: test the various fallocate modes To: hch@infradead.org, david@fromorbit.com, darrick.wong@oracle.com Cc: fstests@vger.kernel.org, xfs@oss.sgi.com, tao.peng@primarydata.com, linux-ext4@vger.kernel.org, Anna.Schumaker@netapp.com, linux-btrfs@vger.kernel.org Date: Wed, 11 Nov 2015 11:27:03 -0800 Message-ID: <20151111192703.15056.62918.stgit@birch.djwong.org> In-Reply-To: <20151111192628.15056.6451.stgit@birch.djwong.org> References: <20151111192628.15056.6451.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0021.oracle.com [156.151.31.71] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1447270048 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24309 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Check that the variants of fallocate (allocate, punch, zero range, collapse range, insert range) do the right thing when they're run against a range of reflinked blocks. Signed-off-by: Darrick J. Wong --- tests/generic/811 | 142 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/811.out | 16 ++++++ tests/generic/812 | 142 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/812.out | 19 +++++++ tests/generic/813 | 136 +++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/813.out | 19 +++++++ tests/generic/814 | 139 ++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/814.out | 19 +++++++ tests/generic/815 | 116 ++++++++++++++++++++++++++++++++++++++++ tests/generic/815.out | 15 +++++ tests/generic/816 | 136 +++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/816.out | 19 +++++++ tests/generic/group | 6 ++ 13 files changed, 924 insertions(+) create mode 100755 tests/generic/811 create mode 100644 tests/generic/811.out create mode 100755 tests/generic/812 create mode 100644 tests/generic/812.out create mode 100755 tests/generic/813 create mode 100644 tests/generic/813.out create mode 100755 tests/generic/814 create mode 100644 tests/generic/814.out create mode 100755 tests/generic/815 create mode 100644 tests/generic/815.out create mode 100755 tests/generic/816 create mode 100644 tests/generic/816.out diff --git a/tests/generic/811 b/tests/generic/811 new file mode 100755 index 0000000..7b09c05 --- /dev/null +++ b/tests/generic/811 @@ -0,0 +1,142 @@ +#! /bin/bash +# FS QA Test No. 811 +# +# Ensure that fallocate steps around reflinked ranges: +# - Reflink parts of two files together +# - Fallocate all the other sparse space. +# - Check that the reflinked areas are still there. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_reflink +_require_cp_reflink +_require_xfs_io_command "falloc" +_require_xfs_io_command "truncate" + +rm -f "$seqres.full" + +TESTDIR="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original files" +BLKSZ=65536 +_pwrite_byte 0x61 0 $((BLKSZ * 5 + 37)) "$TESTDIR/file1" >> "$seqres.full" + +_reflink_range "$TESTDIR/file1" $BLKSZ "$TESTDIR/file2" $BLKSZ \ + $((BLKSZ * 4 + 37)) >> "$seqres.full" + +"$XFS_IO_PROG" -f -c "truncate $((BLKSZ * 5 + 37))" "$TESTDIR/file3" >> "$seqres.full" +_reflink_range "$TESTDIR/file1" 0 "$TESTDIR/file3" 0 $BLKSZ >> "$seqres.full" + +"$XFS_IO_PROG" -f -c "truncate $((BLKSZ * 5 + 37))" "$TESTDIR/file4" >> "$seqres.full" +_reflink_range "$TESTDIR/file1" $BLKSZ "$TESTDIR/file4" $BLKSZ $BLKSZ >> "$seqres.full" +_reflink_range "$TESTDIR/file1" $((BLKSZ * 3)) "$TESTDIR/file4" $((BLKSZ * 3)) \ + $BLKSZ >> "$seqres.full" + +_cp_reflink "$TESTDIR/file1" "$TESTDIR/file5" +_test_remount + +echo "Compare sections" +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir +md5sum "$TESTDIR/file4" | _filter_test_dir +md5sum "$TESTDIR/file5" | _filter_test_dir + +_compare_range "$TESTDIR/file1" $BLKSZ "$TESTDIR/file2" $BLKSZ \ + $((BLKSZ * 4 + 37)) \ + || echo "shared parts of files 1-2 changed" + +_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file3" 0 $BLKSZ \ + || echo "shared parts of files 1-3 changed" + +_compare_range "$TESTDIR/file1" $BLKSZ "$TESTDIR/file4" $BLKSZ $BLKSZ \ + || echo "shared parts of files 1-4 changed" + +_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file5" 0 $((BLKSZ * 5 + 37)) \ + || echo "shared parts of files 1-5 changed" + +echo "Compare files" +C1="$(_md5_checksum "$TESTDIR/file1")" +C2="$(_md5_checksum "$TESTDIR/file2")" +C3="$(_md5_checksum "$TESTDIR/file3")" +C4="$(_md5_checksum "$TESTDIR/file4")" +C5="$(_md5_checksum "$TESTDIR/file5")" + +test "${C1}" != "${C2}" || echo "file1 and file2 should not match" +test "${C1}" != "${C3}" || echo "file1 and file3 should not match" +test "${C1}" != "${C4}" || echo "file1 and file4 should not match" +test "${C1}" = "${C5}" || echo "file1 and file5 should match" +test "${C2}" != "${C3}" || echo "file2 and file3 should not match" +test "${C2}" != "${C4}" || echo "file2 and file4 should not match" +test "${C2}" != "${C5}" || echo "file2 and file5 should not match" +test "${C3}" != "${C4}" || echo "file3 and file4 should not match" +test "${C3}" != "${C5}" || echo "file3 and file5 should not match" +test "${C4}" != "${C5}" || echo "file4 and file5 should not match" + +echo "falloc everything" +"$XFS_IO_PROG" -f -c "falloc 0 $((BLKSZ * 5))" "$TESTDIR/file2" >> "$seqres.full" +"$XFS_IO_PROG" -f -c "falloc 0 $((BLKSZ * 5))" "$TESTDIR/file3" >> "$seqres.full" +"$XFS_IO_PROG" -f -c "falloc 0 $((BLKSZ * 5))" "$TESTDIR/file4" >> "$seqres.full" +_test_remount + +echo "Compare files" +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir +md5sum "$TESTDIR/file4" | _filter_test_dir +md5sum "$TESTDIR/file5" | _filter_test_dir + +D1="$(_md5_checksum "$TESTDIR/file1")" +D2="$(_md5_checksum "$TESTDIR/file2")" +D3="$(_md5_checksum "$TESTDIR/file3")" +D4="$(_md5_checksum "$TESTDIR/file4")" +D5="$(_md5_checksum "$TESTDIR/file5")" + +test "${C1}" = "${D1}" || echo "file1 should not change" +test "${C2}" = "${D2}" || echo "file2 should not change" +test "${C3}" = "${D3}" || echo "file3 should not change" +test "${C4}" = "${D4}" || echo "file4 should not change" +test "${C5}" = "${D5}" || echo "file2 should not change" + +# success, all done +status=0 +exit diff --git a/tests/generic/811.out b/tests/generic/811.out new file mode 100644 index 0000000..950613a --- /dev/null +++ b/tests/generic/811.out @@ -0,0 +1,16 @@ +QA output created by 811 +Create the original files +Compare sections +ee8004e6298fa128477bd4aa1adc69fb TEST_DIR/test-811/file1 +a7cb8cb9697d59413e0d10495d226398 TEST_DIR/test-811/file2 +7d42a0a2865c94f45435a2ce7627da02 TEST_DIR/test-811/file3 +7f528bc76f4d61ff9cff7bc1906579c6 TEST_DIR/test-811/file4 +ee8004e6298fa128477bd4aa1adc69fb TEST_DIR/test-811/file5 +Compare files +falloc everything +Compare files +ee8004e6298fa128477bd4aa1adc69fb TEST_DIR/test-811/file1 +a7cb8cb9697d59413e0d10495d226398 TEST_DIR/test-811/file2 +7d42a0a2865c94f45435a2ce7627da02 TEST_DIR/test-811/file3 +7f528bc76f4d61ff9cff7bc1906579c6 TEST_DIR/test-811/file4 +ee8004e6298fa128477bd4aa1adc69fb TEST_DIR/test-811/file5 diff --git a/tests/generic/812 b/tests/generic/812 new file mode 100755 index 0000000..0c7647f --- /dev/null +++ b/tests/generic/812 @@ -0,0 +1,142 @@ +#! /bin/bash +# FS QA Test No. 812 +# +# Ensure that collapse range steps around reflinked ranges: +# - Create three reflink clones of a file +# - Collapse the start, middle, and end of the reflink range of each +# of the three files, respectively +# - Check that the reflinked areas are still there. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_reflink +_require_cp_reflink +_require_xfs_io_command "falloc" +_require_xfs_io_command "fcollapse" + +rm -f "$seqres.full" + +TESTDIR="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original files" +BLKSZ=65536 +_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file1" >> "$seqres.full" +_pwrite_byte 0x62 $BLKSZ $BLKSZ "$TESTDIR/file1" >> "$seqres.full" +_pwrite_byte 0x63 $((BLKSZ * 2)) $BLKSZ "$TESTDIR/file1" >> "$seqres.full" + +_cp_reflink "$TESTDIR/file1" "$TESTDIR/file2" +_cp_reflink "$TESTDIR/file1" "$TESTDIR/file3" +_cp_reflink "$TESTDIR/file1" "$TESTDIR/file4" + +"$XFS_IO_PROG" -f -c "falloc 0 $((BLKSZ * 4))" "$TESTDIR/file1" +"$XFS_IO_PROG" -f -c "falloc 0 $((BLKSZ * 4))" "$TESTDIR/file2" +"$XFS_IO_PROG" -f -c "falloc 0 $((BLKSZ * 4))" "$TESTDIR/file3" +"$XFS_IO_PROG" -f -c "falloc 0 $((BLKSZ * 4))" "$TESTDIR/file4" + +_pwrite_byte 0x62 0 $BLKSZ "$TESTDIR/file2.chk" >> "$seqres.full" +_pwrite_byte 0x63 $BLKSZ $BLKSZ "$TESTDIR/file2.chk" >> "$seqres.full" +_pwrite_byte 0x00 $((BLKSZ * 2)) $BLKSZ "$TESTDIR/file2.chk" >> "$seqres.full" + +_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file3.chk" >> "$seqres.full" +_pwrite_byte 0x63 $BLKSZ $BLKSZ "$TESTDIR/file3.chk" >> "$seqres.full" +_pwrite_byte 0x00 $((BLKSZ * 2)) $BLKSZ "$TESTDIR/file3.chk" >> "$seqres.full" + +_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file4.chk" >> "$seqres.full" +_pwrite_byte 0x62 $BLKSZ $BLKSZ "$TESTDIR/file4.chk" >> "$seqres.full" +_pwrite_byte 0x00 $((BLKSZ * 2)) $BLKSZ "$TESTDIR/file4.chk" >> "$seqres.full" +_test_remount + +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir +md5sum "$TESTDIR/file4" | _filter_test_dir +md5sum "$TESTDIR/file2.chk" | _filter_test_dir +md5sum "$TESTDIR/file3.chk" | _filter_test_dir +md5sum "$TESTDIR/file4.chk" | _filter_test_dir + +C1="$(_md5_checksum "$TESTDIR/file1")" +C2="$(_md5_checksum "$TESTDIR/file2")" +C3="$(_md5_checksum "$TESTDIR/file3")" +C4="$(_md5_checksum "$TESTDIR/file4")" + +test "${C1}" = "${C2}" || echo "file1 and file2 should match" +test "${C1}" = "${C3}" || echo "file1 and file3 should match" +test "${C1}" = "${C4}" || echo "file1 and file4 should match" +test "${C2}" = "${C3}" || echo "file2 and file3 should match" +test "${C2}" = "${C4}" || echo "file2 and file4 should match" +test "${C3}" = "${C4}" || echo "file3 and file4 should match" + +echo "fcollapse files" +"$XFS_IO_PROG" -f -c "fcollapse 0 $BLKSZ" "$TESTDIR/file2" +"$XFS_IO_PROG" -f -c "fcollapse $BLKSZ $BLKSZ" "$TESTDIR/file3" +"$XFS_IO_PROG" -f -c "fcollapse $((BLKSZ * 2)) $BLKSZ" "$TESTDIR/file4" +_test_remount + +echo "Compare files" +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir +md5sum "$TESTDIR/file4" | _filter_test_dir +md5sum "$TESTDIR/file2.chk" | _filter_test_dir +md5sum "$TESTDIR/file3.chk" | _filter_test_dir +md5sum "$TESTDIR/file4.chk" | _filter_test_dir + +C1="$(_md5_checksum "$TESTDIR/file1")" +C2="$(_md5_checksum "$TESTDIR/file2")" +C3="$(_md5_checksum "$TESTDIR/file3")" +C4="$(_md5_checksum "$TESTDIR/file4")" + +test "${C1}" != "${C2}" || echo "file1 and file2 should not match" +test "${C1}" != "${C3}" || echo "file1 and file3 should not match" +test "${C1}" != "${C4}" || echo "file1 and file4 should not match" +test "${C2}" != "${C3}" || echo "file2 and file3 should not match" +test "${C2}" != "${C4}" || echo "file2 and file4 should not match" +test "${C3}" != "${C4}" || echo "file3 and file4 should not match" + +echo "Compare against check files" +cmp -s "$TESTDIR/file2" "$TESTDIR/file2.chk" || echo "file2 and file2.chk do not match" +cmp -s "$TESTDIR/file3" "$TESTDIR/file3.chk" || echo "file3 and file3.chk do not match" +cmp -s "$TESTDIR/file4" "$TESTDIR/file4.chk" || echo "file4 and file4.chk do not match" + +# success, all done +status=0 +exit diff --git a/tests/generic/812.out b/tests/generic/812.out new file mode 100644 index 0000000..16dc3df --- /dev/null +++ b/tests/generic/812.out @@ -0,0 +1,19 @@ +QA output created by 812 +Create the original files +564b34fb4a562f6d864f371248e48540 TEST_DIR/test-812/file1 +564b34fb4a562f6d864f371248e48540 TEST_DIR/test-812/file2 +564b34fb4a562f6d864f371248e48540 TEST_DIR/test-812/file3 +564b34fb4a562f6d864f371248e48540 TEST_DIR/test-812/file4 +9a239246ce4bee20f2de1b0ba41a41e0 TEST_DIR/test-812/file2.chk +859c251680d8bbf0f859f5c6d7a6a2a2 TEST_DIR/test-812/file3.chk +c931e8500c1a56a5b7369f7f1b971690 TEST_DIR/test-812/file4.chk +fcollapse files +Compare files +564b34fb4a562f6d864f371248e48540 TEST_DIR/test-812/file1 +9a239246ce4bee20f2de1b0ba41a41e0 TEST_DIR/test-812/file2 +859c251680d8bbf0f859f5c6d7a6a2a2 TEST_DIR/test-812/file3 +c931e8500c1a56a5b7369f7f1b971690 TEST_DIR/test-812/file4 +9a239246ce4bee20f2de1b0ba41a41e0 TEST_DIR/test-812/file2.chk +859c251680d8bbf0f859f5c6d7a6a2a2 TEST_DIR/test-812/file3.chk +c931e8500c1a56a5b7369f7f1b971690 TEST_DIR/test-812/file4.chk +Compare against check files diff --git a/tests/generic/813 b/tests/generic/813 new file mode 100755 index 0000000..d313bc7 --- /dev/null +++ b/tests/generic/813 @@ -0,0 +1,136 @@ +#! /bin/bash +# FS QA Test No. 813 +# +# Ensure that punch-hole steps around reflinked ranges: +# - Create three reflink clones of a file +# - Punch the start, middle, and end of the reflink range of each +# of the three files, respectively +# - Check that the reflinked areas are still there. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_reflink +_require_cp_reflink +_require_xfs_io_command "fpunch" + +rm -f "$seqres.full" + +TESTDIR="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original files" +BLKSZ=65536 +_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file1" >> "$seqres.full" +_pwrite_byte 0x62 $BLKSZ $BLKSZ "$TESTDIR/file1" >> "$seqres.full" +_pwrite_byte 0x63 $((BLKSZ * 2)) $BLKSZ "$TESTDIR/file1" >> "$seqres.full" + +_cp_reflink "$TESTDIR/file1" "$TESTDIR/file2" +_cp_reflink "$TESTDIR/file1" "$TESTDIR/file3" +_cp_reflink "$TESTDIR/file1" "$TESTDIR/file4" + +_pwrite_byte 0x00 0 $BLKSZ "$TESTDIR/file2.chk" >> "$seqres.full" +_pwrite_byte 0x62 $BLKSZ $BLKSZ "$TESTDIR/file2.chk" >> "$seqres.full" +_pwrite_byte 0x63 $((BLKSZ * 2)) $BLKSZ "$TESTDIR/file2.chk" >> "$seqres.full" + +_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file3.chk" >> "$seqres.full" +_pwrite_byte 0x00 $BLKSZ $BLKSZ "$TESTDIR/file3.chk" >> "$seqres.full" +_pwrite_byte 0x63 $((BLKSZ * 2)) $BLKSZ "$TESTDIR/file3.chk" >> "$seqres.full" + +_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file4.chk" >> "$seqres.full" +_pwrite_byte 0x62 $BLKSZ $BLKSZ "$TESTDIR/file4.chk" >> "$seqres.full" +_pwrite_byte 0x00 $((BLKSZ * 2)) $BLKSZ "$TESTDIR/file4.chk" >> "$seqres.full" +_test_remount + +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir +md5sum "$TESTDIR/file4" | _filter_test_dir +md5sum "$TESTDIR/file2.chk" | _filter_test_dir +md5sum "$TESTDIR/file3.chk" | _filter_test_dir +md5sum "$TESTDIR/file4.chk" | _filter_test_dir + +C1="$(_md5_checksum "$TESTDIR/file1")" +C2="$(_md5_checksum "$TESTDIR/file2")" +C3="$(_md5_checksum "$TESTDIR/file3")" +C4="$(_md5_checksum "$TESTDIR/file4")" + +test "${C1}" = "${C2}" || echo "file1 and file2 should match" +test "${C1}" = "${C3}" || echo "file1 and file3 should match" +test "${C1}" = "${C4}" || echo "file1 and file4 should match" +test "${C2}" = "${C3}" || echo "file2 and file3 should match" +test "${C2}" = "${C4}" || echo "file2 and file4 should match" +test "${C3}" = "${C4}" || echo "file3 and file4 should match" + +echo "fpunch files" +"$XFS_IO_PROG" -f -c "fpunch 0 $BLKSZ" "$TESTDIR/file2" +"$XFS_IO_PROG" -f -c "fpunch $BLKSZ $BLKSZ" "$TESTDIR/file3" +"$XFS_IO_PROG" -f -c "fpunch $((BLKSZ * 2)) $BLKSZ" "$TESTDIR/file4" +_test_remount + +echo "Compare files" +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir +md5sum "$TESTDIR/file4" | _filter_test_dir +md5sum "$TESTDIR/file2.chk" | _filter_test_dir +md5sum "$TESTDIR/file3.chk" | _filter_test_dir +md5sum "$TESTDIR/file4.chk" | _filter_test_dir + +C1="$(_md5_checksum "$TESTDIR/file1")" +C2="$(_md5_checksum "$TESTDIR/file2")" +C3="$(_md5_checksum "$TESTDIR/file3")" +C4="$(_md5_checksum "$TESTDIR/file4")" + +test "${C1}" != "${C2}" || echo "file1 and file2 should not match" +test "${C1}" != "${C3}" || echo "file1 and file3 should not match" +test "${C1}" != "${C4}" || echo "file1 and file4 should not match" +test "${C2}" != "${C3}" || echo "file2 and file3 should not match" +test "${C2}" != "${C4}" || echo "file2 and file4 should not match" +test "${C3}" != "${C4}" || echo "file3 and file4 should not match" + +echo "Compare against check files" +cmp -s "$TESTDIR/file2" "$TESTDIR/file2.chk" || echo "file2 and file2.chk do not match" +cmp -s "$TESTDIR/file3" "$TESTDIR/file3.chk" || echo "file3 and file3.chk do not match" +cmp -s "$TESTDIR/file4" "$TESTDIR/file4.chk" || echo "file4 and file4.chk do not match" + +# success, all done +status=0 +exit diff --git a/tests/generic/813.out b/tests/generic/813.out new file mode 100644 index 0000000..98fda42 --- /dev/null +++ b/tests/generic/813.out @@ -0,0 +1,19 @@ +QA output created by 813 +Create the original files +856bb58abaf1ac79aa1aa45b7de7218b TEST_DIR/test-813/file1 +856bb58abaf1ac79aa1aa45b7de7218b TEST_DIR/test-813/file2 +856bb58abaf1ac79aa1aa45b7de7218b TEST_DIR/test-813/file3 +856bb58abaf1ac79aa1aa45b7de7218b TEST_DIR/test-813/file4 +e263fae701bc40c23a3edb20aad5573e TEST_DIR/test-813/file2.chk +91722d7c8baf83f300a8dc35f1ffcce2 TEST_DIR/test-813/file3.chk +c931e8500c1a56a5b7369f7f1b971690 TEST_DIR/test-813/file4.chk +fpunch files +Compare files +856bb58abaf1ac79aa1aa45b7de7218b TEST_DIR/test-813/file1 +e263fae701bc40c23a3edb20aad5573e TEST_DIR/test-813/file2 +91722d7c8baf83f300a8dc35f1ffcce2 TEST_DIR/test-813/file3 +c931e8500c1a56a5b7369f7f1b971690 TEST_DIR/test-813/file4 +e263fae701bc40c23a3edb20aad5573e TEST_DIR/test-813/file2.chk +91722d7c8baf83f300a8dc35f1ffcce2 TEST_DIR/test-813/file3.chk +c931e8500c1a56a5b7369f7f1b971690 TEST_DIR/test-813/file4.chk +Compare against check files diff --git a/tests/generic/814 b/tests/generic/814 new file mode 100755 index 0000000..c35bdd9 --- /dev/null +++ b/tests/generic/814 @@ -0,0 +1,139 @@ +#! /bin/bash +# FS QA Test No. 812 +# +# Ensure that insert range steps around reflinked ranges: +# - Create three reflink clones of a file +# - Insert into the start, middle, and end of the reflink range of each +# of the three files, respectively +# - Check that the reflinked areas are still there. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_reflink +_require_cp_reflink +_require_xfs_io_command "finsert" + +rm -f "$seqres.full" + +TESTDIR="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original files" +BLKSZ=65536 +_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file1" >> "$seqres.full" +_pwrite_byte 0x62 $BLKSZ $BLKSZ "$TESTDIR/file1" >> "$seqres.full" +_pwrite_byte 0x63 $((BLKSZ * 2)) $BLKSZ "$TESTDIR/file1" >> "$seqres.full" + +_cp_reflink "$TESTDIR/file1" "$TESTDIR/file2" +_cp_reflink "$TESTDIR/file1" "$TESTDIR/file3" +_cp_reflink "$TESTDIR/file1" "$TESTDIR/file4" + +_pwrite_byte 0x00 0 $BLKSZ "$TESTDIR/file2.chk" >> "$seqres.full" +_pwrite_byte 0x61 $BLKSZ $BLKSZ "$TESTDIR/file2.chk" >> "$seqres.full" +_pwrite_byte 0x62 $((BLKSZ * 2)) $BLKSZ "$TESTDIR/file2.chk" >> "$seqres.full" +_pwrite_byte 0x63 $((BLKSZ * 3)) $BLKSZ "$TESTDIR/file2.chk" >> "$seqres.full" + +_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file3.chk" >> "$seqres.full" +_pwrite_byte 0x00 $BLKSZ $BLKSZ "$TESTDIR/file3.chk" >> "$seqres.full" +_pwrite_byte 0x62 $((BLKSZ * 2)) $BLKSZ "$TESTDIR/file3.chk" >> "$seqres.full" +_pwrite_byte 0x63 $((BLKSZ * 3)) $BLKSZ "$TESTDIR/file3.chk" >> "$seqres.full" + +_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file4.chk" >> "$seqres.full" +_pwrite_byte 0x62 $BLKSZ $BLKSZ "$TESTDIR/file4.chk" >> "$seqres.full" +_pwrite_byte 0x00 $((BLKSZ * 2)) $BLKSZ "$TESTDIR/file4.chk" >> "$seqres.full" +_pwrite_byte 0x63 $((BLKSZ * 3)) $BLKSZ "$TESTDIR/file4.chk" >> "$seqres.full" +_test_remount + +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir +md5sum "$TESTDIR/file4" | _filter_test_dir +md5sum "$TESTDIR/file2.chk" | _filter_test_dir +md5sum "$TESTDIR/file3.chk" | _filter_test_dir +md5sum "$TESTDIR/file4.chk" | _filter_test_dir + +C1="$(_md5_checksum "$TESTDIR/file1")" +C2="$(_md5_checksum "$TESTDIR/file2")" +C3="$(_md5_checksum "$TESTDIR/file3")" +C4="$(_md5_checksum "$TESTDIR/file4")" + +test "${C1}" = "${C2}" || echo "file1 and file2 should match" +test "${C1}" = "${C3}" || echo "file1 and file3 should match" +test "${C1}" = "${C4}" || echo "file1 and file4 should match" +test "${C2}" = "${C3}" || echo "file2 and file3 should match" +test "${C2}" = "${C4}" || echo "file2 and file4 should match" +test "${C3}" = "${C4}" || echo "file3 and file4 should match" + +echo "finsert files" +"$XFS_IO_PROG" -f -c "finsert 0 $BLKSZ" "$TESTDIR/file2" +"$XFS_IO_PROG" -f -c "finsert $BLKSZ $BLKSZ" "$TESTDIR/file3" +"$XFS_IO_PROG" -f -c "finsert $((BLKSZ * 2)) $BLKSZ" "$TESTDIR/file4" +_test_remount + +echo "Compare files" +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir +md5sum "$TESTDIR/file4" | _filter_test_dir +md5sum "$TESTDIR/file2.chk" | _filter_test_dir +md5sum "$TESTDIR/file3.chk" | _filter_test_dir +md5sum "$TESTDIR/file4.chk" | _filter_test_dir + +C1="$(_md5_checksum "$TESTDIR/file1")" +C2="$(_md5_checksum "$TESTDIR/file2")" +C3="$(_md5_checksum "$TESTDIR/file3")" +C4="$(_md5_checksum "$TESTDIR/file4")" + +test "${C1}" != "${C2}" || echo "file1 and file2 should not match" +test "${C1}" != "${C3}" || echo "file1 and file3 should not match" +test "${C1}" != "${C4}" || echo "file1 and file4 should not match" +test "${C2}" != "${C3}" || echo "file2 and file3 should not match" +test "${C2}" != "${C4}" || echo "file2 and file4 should not match" +test "${C3}" != "${C4}" || echo "file3 and file4 should not match" + +echo "Compare against check files" +cmp -s "$TESTDIR/file2" "$TESTDIR/file2.chk" || echo "file2 and file2.chk do not match" +cmp -s "$TESTDIR/file3" "$TESTDIR/file3.chk" || echo "file3 and file3.chk do not match" +cmp -s "$TESTDIR/file4" "$TESTDIR/file4.chk" || echo "file4 and file4.chk do not match" + +# success, all done +status=0 +exit diff --git a/tests/generic/814.out b/tests/generic/814.out new file mode 100644 index 0000000..6093561 --- /dev/null +++ b/tests/generic/814.out @@ -0,0 +1,19 @@ +QA output created by 814 +Create the original files +856bb58abaf1ac79aa1aa45b7de7218b TEST_DIR/test-814/file1 +856bb58abaf1ac79aa1aa45b7de7218b TEST_DIR/test-814/file2 +856bb58abaf1ac79aa1aa45b7de7218b TEST_DIR/test-814/file3 +856bb58abaf1ac79aa1aa45b7de7218b TEST_DIR/test-814/file4 +2b0921503c9f661b7690ac5b42f01f97 TEST_DIR/test-814/file2.chk +c424badbaad621c331a8ef213b78ac2a TEST_DIR/test-814/file3.chk +33b4940294a1d94bee813907d6105ff7 TEST_DIR/test-814/file4.chk +finsert files +Compare files +856bb58abaf1ac79aa1aa45b7de7218b TEST_DIR/test-814/file1 +2b0921503c9f661b7690ac5b42f01f97 TEST_DIR/test-814/file2 +c424badbaad621c331a8ef213b78ac2a TEST_DIR/test-814/file3 +33b4940294a1d94bee813907d6105ff7 TEST_DIR/test-814/file4 +2b0921503c9f661b7690ac5b42f01f97 TEST_DIR/test-814/file2.chk +c424badbaad621c331a8ef213b78ac2a TEST_DIR/test-814/file3.chk +33b4940294a1d94bee813907d6105ff7 TEST_DIR/test-814/file4.chk +Compare against check files diff --git a/tests/generic/815 b/tests/generic/815 new file mode 100755 index 0000000..8d545ee --- /dev/null +++ b/tests/generic/815 @@ -0,0 +1,116 @@ +#! /bin/bash +# FS QA Test No. 815 +# +# Ensure that truncating the last block in a reflinked file CoWs appropriately: +# - Create a file that doesn't end on a block boundary +# - Create two reflink clones of the file +# - Shorten one of the clones with truncate +# - Lengthen the other clone with truncate +# - Check that the reflinked areas are still there. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_reflink +_require_cp_reflink +_require_xfs_io_command "truncate" + +rm -f "$seqres.full" + +TESTDIR="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original files" +BLKSZ=65536 +_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file1" >> "$seqres.full" +_pwrite_byte 0x62 $BLKSZ 37 "$TESTDIR/file1" >> "$seqres.full" + +_cp_reflink "$TESTDIR/file1" "$TESTDIR/file2" +_cp_reflink "$TESTDIR/file1" "$TESTDIR/file3" + +_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file2.chk" >> "$seqres.full" +_pwrite_byte 0x62 $BLKSZ 34 "$TESTDIR/file2.chk" >> "$seqres.full" + +_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file3.chk" >> "$seqres.full" +_pwrite_byte 0x62 $BLKSZ 37 "$TESTDIR/file3.chk" >> "$seqres.full" +_pwrite_byte 0x00 $((BLKSZ + 37)) 3 "$TESTDIR/file3.chk" >> "$seqres.full" +_test_remount + +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir +md5sum "$TESTDIR/file2.chk" | _filter_test_dir +md5sum "$TESTDIR/file3.chk" | _filter_test_dir + +C1="$(_md5_checksum "$TESTDIR/file1")" +C2="$(_md5_checksum "$TESTDIR/file2")" +C3="$(_md5_checksum "$TESTDIR/file3")" + +test "${C1}" = "${C2}" || echo "file1 and file2 should match" +test "${C1}" = "${C3}" || echo "file1 and file3 should match" +test "${C2}" = "${C3}" || echo "file2 and file3 should match" + +echo "truncate files" +"$XFS_IO_PROG" -f -c "truncate $((BLKSZ + 34))" "$TESTDIR/file2" +"$XFS_IO_PROG" -f -c "truncate $((BLKSZ + 40))" "$TESTDIR/file3" +_test_remount + +echo "Compare files" +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir +md5sum "$TESTDIR/file2.chk" | _filter_test_dir +md5sum "$TESTDIR/file3.chk" | _filter_test_dir + +C1="$(_md5_checksum "$TESTDIR/file1")" +C2="$(_md5_checksum "$TESTDIR/file2")" +C3="$(_md5_checksum "$TESTDIR/file3")" + +test "${C1}" != "${C2}" || echo "file1 and file2 should not match" +test "${C1}" != "${C3}" || echo "file1 and file3 should not match" +test "${C2}" != "${C3}" || echo "file2 and file3 should not match" + +echo "Compare against check files" +cmp -s "$TESTDIR/file2" "$TESTDIR/file2.chk" || echo "file2 and file2.chk do not match" +cmp -s "$TESTDIR/file3" "$TESTDIR/file3.chk" || echo "file3 and file3.chk do not match" + +# success, all done +status=0 +exit diff --git a/tests/generic/815.out b/tests/generic/815.out new file mode 100644 index 0000000..8c36c2d --- /dev/null +++ b/tests/generic/815.out @@ -0,0 +1,15 @@ +QA output created by 815 +Create the original files +f924bdda449af63913cad4357e39301e TEST_DIR/test-815/file1 +f924bdda449af63913cad4357e39301e TEST_DIR/test-815/file2 +f924bdda449af63913cad4357e39301e TEST_DIR/test-815/file3 +16cb529abe447a9f203a3d5eb3433c8b TEST_DIR/test-815/file2.chk +6f042ad39f6c74f4b73936db89baa2e2 TEST_DIR/test-815/file3.chk +truncate files +Compare files +f924bdda449af63913cad4357e39301e TEST_DIR/test-815/file1 +16cb529abe447a9f203a3d5eb3433c8b TEST_DIR/test-815/file2 +6f042ad39f6c74f4b73936db89baa2e2 TEST_DIR/test-815/file3 +16cb529abe447a9f203a3d5eb3433c8b TEST_DIR/test-815/file2.chk +6f042ad39f6c74f4b73936db89baa2e2 TEST_DIR/test-815/file3.chk +Compare against check files diff --git a/tests/generic/816 b/tests/generic/816 new file mode 100755 index 0000000..44b5ae4 --- /dev/null +++ b/tests/generic/816 @@ -0,0 +1,136 @@ +#! /bin/bash +# FS QA Test No. 813 +# +# Ensure that zero-range steps around reflinked ranges: +# - Create three reflink clones of a file +# - Zero-range the start, middle, and end of the reflink range of each +# of the three files, respectively +# - Check that the reflinked areas are still there. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_reflink +_require_cp_reflink +_require_xfs_io_command "fzero" + +rm -f "$seqres.full" + +TESTDIR="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original files" +BLKSZ=65536 +_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file1" >> "$seqres.full" +_pwrite_byte 0x62 $BLKSZ $BLKSZ "$TESTDIR/file1" >> "$seqres.full" +_pwrite_byte 0x63 $((BLKSZ * 2)) $BLKSZ "$TESTDIR/file1" >> "$seqres.full" + +_cp_reflink "$TESTDIR/file1" "$TESTDIR/file2" +_cp_reflink "$TESTDIR/file1" "$TESTDIR/file3" +_cp_reflink "$TESTDIR/file1" "$TESTDIR/file4" + +_pwrite_byte 0x00 0 $BLKSZ "$TESTDIR/file2.chk" >> "$seqres.full" +_pwrite_byte 0x62 $BLKSZ $BLKSZ "$TESTDIR/file2.chk" >> "$seqres.full" +_pwrite_byte 0x63 $((BLKSZ * 2)) $BLKSZ "$TESTDIR/file2.chk" >> "$seqres.full" + +_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file3.chk" >> "$seqres.full" +_pwrite_byte 0x00 $BLKSZ $BLKSZ "$TESTDIR/file3.chk" >> "$seqres.full" +_pwrite_byte 0x63 $((BLKSZ * 2)) $BLKSZ "$TESTDIR/file3.chk" >> "$seqres.full" + +_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file4.chk" >> "$seqres.full" +_pwrite_byte 0x62 $BLKSZ $BLKSZ "$TESTDIR/file4.chk" >> "$seqres.full" +_pwrite_byte 0x00 $((BLKSZ * 2)) $BLKSZ "$TESTDIR/file4.chk" >> "$seqres.full" +_test_remount + +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir +md5sum "$TESTDIR/file4" | _filter_test_dir +md5sum "$TESTDIR/file2.chk" | _filter_test_dir +md5sum "$TESTDIR/file3.chk" | _filter_test_dir +md5sum "$TESTDIR/file4.chk" | _filter_test_dir + +C1="$(_md5_checksum "$TESTDIR/file1")" +C2="$(_md5_checksum "$TESTDIR/file2")" +C3="$(_md5_checksum "$TESTDIR/file3")" +C4="$(_md5_checksum "$TESTDIR/file4")" + +test "${C1}" = "${C2}" || echo "file1 and file2 should match" +test "${C1}" = "${C3}" || echo "file1 and file3 should match" +test "${C1}" = "${C4}" || echo "file1 and file4 should match" +test "${C2}" = "${C3}" || echo "file2 and file3 should match" +test "${C2}" = "${C4}" || echo "file2 and file4 should match" +test "${C3}" = "${C4}" || echo "file3 and file4 should match" + +echo "fzero files" +"$XFS_IO_PROG" -f -c "fzero 0 $BLKSZ" "$TESTDIR/file2" +"$XFS_IO_PROG" -f -c "fzero $BLKSZ $BLKSZ" "$TESTDIR/file3" +"$XFS_IO_PROG" -f -c "fzero $((BLKSZ * 2)) $BLKSZ" "$TESTDIR/file4" +_test_remount + +echo "Compare files" +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir +md5sum "$TESTDIR/file4" | _filter_test_dir +md5sum "$TESTDIR/file2.chk" | _filter_test_dir +md5sum "$TESTDIR/file3.chk" | _filter_test_dir +md5sum "$TESTDIR/file4.chk" | _filter_test_dir + +C1="$(_md5_checksum "$TESTDIR/file1")" +C2="$(_md5_checksum "$TESTDIR/file2")" +C3="$(_md5_checksum "$TESTDIR/file3")" +C4="$(_md5_checksum "$TESTDIR/file4")" + +test "${C1}" != "${C2}" || echo "file1 and file2 should not match" +test "${C1}" != "${C3}" || echo "file1 and file3 should not match" +test "${C1}" != "${C4}" || echo "file1 and file4 should not match" +test "${C2}" != "${C3}" || echo "file2 and file3 should not match" +test "${C2}" != "${C4}" || echo "file2 and file4 should not match" +test "${C3}" != "${C4}" || echo "file3 and file4 should not match" + +echo "Compare against check files" +cmp -s "$TESTDIR/file2" "$TESTDIR/file2.chk" || echo "file2 and file2.chk do not match" +cmp -s "$TESTDIR/file3" "$TESTDIR/file3.chk" || echo "file3 and file3.chk do not match" +cmp -s "$TESTDIR/file4" "$TESTDIR/file4.chk" || echo "file4 and file4.chk do not match" + +# success, all done +status=0 +exit diff --git a/tests/generic/816.out b/tests/generic/816.out new file mode 100644 index 0000000..f3e1396 --- /dev/null +++ b/tests/generic/816.out @@ -0,0 +1,19 @@ +QA output created by 816 +Create the original files +856bb58abaf1ac79aa1aa45b7de7218b TEST_DIR/test-816/file1 +856bb58abaf1ac79aa1aa45b7de7218b TEST_DIR/test-816/file2 +856bb58abaf1ac79aa1aa45b7de7218b TEST_DIR/test-816/file3 +856bb58abaf1ac79aa1aa45b7de7218b TEST_DIR/test-816/file4 +e263fae701bc40c23a3edb20aad5573e TEST_DIR/test-816/file2.chk +91722d7c8baf83f300a8dc35f1ffcce2 TEST_DIR/test-816/file3.chk +c931e8500c1a56a5b7369f7f1b971690 TEST_DIR/test-816/file4.chk +fzero files +Compare files +856bb58abaf1ac79aa1aa45b7de7218b TEST_DIR/test-816/file1 +e263fae701bc40c23a3edb20aad5573e TEST_DIR/test-816/file2 +91722d7c8baf83f300a8dc35f1ffcce2 TEST_DIR/test-816/file3 +c931e8500c1a56a5b7369f7f1b971690 TEST_DIR/test-816/file4 +e263fae701bc40c23a3edb20aad5573e TEST_DIR/test-816/file2.chk +91722d7c8baf83f300a8dc35f1ffcce2 TEST_DIR/test-816/file3.chk +c931e8500c1a56a5b7369f7f1b971690 TEST_DIR/test-816/file4.chk +Compare against check files diff --git a/tests/generic/group b/tests/generic/group index a72d416..58c68c8 100644 --- a/tests/generic/group +++ b/tests/generic/group @@ -219,6 +219,12 @@ 808 auto quick clone 809 auto quick clone 810 auto quick clone +811 auto quick clone +812 auto quick clone +813 auto quick clone +814 auto quick clone +815 auto quick clone +816 auto quick clone 817 auto quick clone 818 auto quick clone 819 auto quick clone From darrick.wong@oracle.com Wed Nov 11 13:27:43 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id D13F029E1F for ; Wed, 11 Nov 2015 13:27:43 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id C37D1304043 for ; Wed, 11 Nov 2015 11:27:43 -0800 (PST) X-ASG-Debug-ID: 1447270058-04cb6c296b1251a0001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id 8JUkEROesRXkJgS3 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 11 Nov 2015 11:27:39 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tABJRCxh029333 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 11 Nov 2015 19:27:12 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id tABJRCjZ029581 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 11 Nov 2015 19:27:12 GMT Received: from abhmp0007.oracle.com (abhmp0007.oracle.com [141.146.116.13]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id tABJRCxr015961; Wed, 11 Nov 2015 19:27:12 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 11 Nov 2015 11:27:11 -0800 Subject: [PATCH 06/11] reflink: concurrent operations tests From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 06/11] reflink: concurrent operations tests To: hch@infradead.org, david@fromorbit.com, darrick.wong@oracle.com Cc: fstests@vger.kernel.org, xfs@oss.sgi.com, tao.peng@primarydata.com, linux-ext4@vger.kernel.org, Anna.Schumaker@netapp.com, linux-btrfs@vger.kernel.org Date: Wed, 11 Nov 2015 11:27:10 -0800 Message-ID: <20151111192710.15056.50137.stgit@birch.djwong.org> In-Reply-To: <20151111192628.15056.6451.stgit@birch.djwong.org> References: <20151111192628.15056.6451.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1447270059 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24309 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Make sure that running reflink ops while other IO is ongoing doesn't break the filesystem. Signed-off-by: Darrick J. Wong --- tests/generic/821 | 97 +++++++++++++++++++++++++++++++++++++++++++++ tests/generic/821.out | 6 +++ tests/generic/822 | 97 +++++++++++++++++++++++++++++++++++++++++++++ tests/generic/822.out | 6 +++ tests/generic/823 | 93 +++++++++++++++++++++++++++++++++++++++++++ tests/generic/823.out | 6 +++ tests/generic/824 | 93 +++++++++++++++++++++++++++++++++++++++++++ tests/generic/824.out | 6 +++ tests/generic/825 | 105 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/825.out | 7 +++ tests/generic/826 | 105 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/826.out | 7 +++ tests/generic/827 | 95 ++++++++++++++++++++++++++++++++++++++++++++ tests/generic/827.out | 7 +++ tests/generic/828 | 95 ++++++++++++++++++++++++++++++++++++++++++++ tests/generic/828.out | 7 +++ tests/generic/829 | 79 +++++++++++++++++++++++++++++++++++++ tests/generic/829.out | 6 +++ tests/generic/group | 9 ++++ 19 files changed, 926 insertions(+) create mode 100755 tests/generic/821 create mode 100644 tests/generic/821.out create mode 100755 tests/generic/822 create mode 100644 tests/generic/822.out create mode 100755 tests/generic/823 create mode 100644 tests/generic/823.out create mode 100755 tests/generic/824 create mode 100644 tests/generic/824.out create mode 100755 tests/generic/825 create mode 100644 tests/generic/825.out create mode 100755 tests/generic/826 create mode 100644 tests/generic/826.out create mode 100755 tests/generic/827 create mode 100644 tests/generic/827.out create mode 100755 tests/generic/828 create mode 100644 tests/generic/828.out create mode 100755 tests/generic/829 create mode 100644 tests/generic/829.out diff --git a/tests/generic/821 b/tests/generic/821 new file mode 100755 index 0000000..d38eff7 --- /dev/null +++ b/tests/generic/821 @@ -0,0 +1,97 @@ +#! /bin/bash +# FS QA Test No. 821 +# +# Test for races or FS corruption when DIO writing to a file that's also +# the target of a reflink operation. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015 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 7 15 + +_cleanup() +{ + cd / + rm -rf "$tmp".* + wait +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_scratch_reflink + +echo "Format and mount" +_scratch_mkfs > "$seqres.full" 2>&1 +_scratch_mount >> "$seqres.full" 2>&1 + +TESTDIR="$SCRATCH_MNT/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +loops=1024 +nr_loops=$((loops - 1)) +BLKSZ=65536 + +echo "Initialize files" +echo > "$seqres.full" +_pwrite_byte 0x61 0 $((loops * BLKSZ)) "$TESTDIR/file1" >> "$seqres.full" +_pwrite_byte 0x62 0 $((loops * BLKSZ)) "$TESTDIR/file2" >> "$seqres.full" +_scratch_remount + +# Direct I/O overwriter... +overwrite() { + while [ ! -e "$TESTDIR/finished" ]; do + seq $nr_loops -1 0 | while read i; do + _pwrite_byte 0x63 $((i * BLKSZ)) $BLKSZ -d "$TESTDIR/file2" >> "$seqres.full" + done + done +} + +echo "Reflink and dio write the target" +overwrite & +seq 1 10 | while read j; do + seq 0 $nr_loops | while read i; do + _reflink_range "$TESTDIR/file1" $((i * BLKSZ)) \ + "$TESTDIR/file2" $((i * BLKSZ)) $BLKSZ >> "$seqres.full" + [ $? -ne 0 ] && exit + done +done +touch "$TESTDIR/finished" +wait + +echo "Check for damage" +umount "$SCRATCH_MNT" +_check_scratch_fs + +echo "Done" + +# success, all done +status=0 +exit diff --git a/tests/generic/821.out b/tests/generic/821.out new file mode 100644 index 0000000..ca6bc53 --- /dev/null +++ b/tests/generic/821.out @@ -0,0 +1,6 @@ +QA output created by 821 +Format and mount +Initialize files +Reflink and dio write the target +Check for damage +Done diff --git a/tests/generic/822 b/tests/generic/822 new file mode 100755 index 0000000..b37207c --- /dev/null +++ b/tests/generic/822 @@ -0,0 +1,97 @@ +#! /bin/bash +# FS QA Test No. 822 +# +# Test for races or FS corruption when writing to a file that's also +# the target of a reflink operation. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015 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 7 15 + +_cleanup() +{ + cd / + rm -rf "$tmp".* + wait +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_scratch_reflink + +echo "Format and mount" +_scratch_mkfs > "$seqres.full" 2>&1 +_scratch_mount >> "$seqres.full" 2>&1 + +TESTDIR="$SCRATCH_MNT/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +loops=1024 +nr_loops=$((loops - 1)) +BLKSZ=65536 + +echo "Initialize files" +echo > "$seqres.full" +_pwrite_byte 0x61 0 $((loops * BLKSZ)) "$TESTDIR/file1" >> "$seqres.full" +_pwrite_byte 0x62 0 $((loops * BLKSZ)) "$TESTDIR/file2" >> "$seqres.full" +_scratch_remount + +# Direct I/O overwriter... +overwrite() { + while [ ! -e "$TESTDIR/finished" ]; do + seq $nr_loops -1 0 | while read i; do + _pwrite_byte 0x63 $((i * BLKSZ)) $BLKSZ "$TESTDIR/file2" >> "$seqres.full" + done + done +} + +echo "Reflink and write the target" +overwrite & +seq 1 10 | while read j; do + seq 0 $nr_loops | while read i; do + _reflink_range "$TESTDIR/file1" $((i * BLKSZ)) \ + "$TESTDIR/file2" $((i * BLKSZ)) $BLKSZ >> "$seqres.full" + [ $? -ne 0 ] && exit + done +done +touch "$TESTDIR/finished" +wait + +echo "Check for damage" +umount "$SCRATCH_MNT" +_check_scratch_fs + +echo "Done" + +# success, all done +status=0 +exit diff --git a/tests/generic/822.out b/tests/generic/822.out new file mode 100644 index 0000000..14399ae --- /dev/null +++ b/tests/generic/822.out @@ -0,0 +1,6 @@ +QA output created by 822 +Format and mount +Initialize files +Reflink and write the target +Check for damage +Done diff --git a/tests/generic/823 b/tests/generic/823 new file mode 100755 index 0000000..768623d --- /dev/null +++ b/tests/generic/823 @@ -0,0 +1,93 @@ +#! /bin/bash +# FS QA Test No. 823 +# +# Test for races or FS corruption when writing to a file that's also +# the source of a reflink operation. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015 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 7 15 + +_cleanup() +{ + cd / + rm -rf "$tmp".* + wait +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_scratch_reflink +_require_cp_reflink + +echo "Format and mount" +_scratch_mkfs > "$seqres.full" 2>&1 +_scratch_mount >> "$seqres.full" 2>&1 + +TESTDIR="$SCRATCH_MNT/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +loops=1024 +nr_loops=$((loops - 1)) +BLKSZ=65536 + +echo "Initialize file" +echo > "$seqres.full" +_pwrite_byte 0x61 0 $((loops * BLKSZ)) "$TESTDIR/file1" >> "$seqres.full" +_scratch_remount + +# Snapshot creator... +snappy() { + n=0 + while [ ! -e "$TESTDIR/finished" ]; do + _cp_reflink "$TESTDIR/file1" "$TESTDIR/snap_$n" || break + n=$((n + 1)) + done +} + +echo "Snapshot a file undergoing buffered rewrite" +snappy & +seq $nr_loops -1 0 | while read i; do + _pwrite_byte 0x63 $((i * BLKSZ)) $BLKSZ "$TESTDIR/file1" >> "$seqres.full" +done +touch $TESTDIR/finished +wait + +echo "Check for damage" +umount $SCRATCH_MNT +_check_scratch_fs + +echo "Done" + +# success, all done +status=0 +exit diff --git a/tests/generic/823.out b/tests/generic/823.out new file mode 100644 index 0000000..ef3e209 --- /dev/null +++ b/tests/generic/823.out @@ -0,0 +1,6 @@ +QA output created by 823 +Format and mount +Initialize file +Snapshot a file undergoing buffered rewrite +Check for damage +Done diff --git a/tests/generic/824 b/tests/generic/824 new file mode 100755 index 0000000..7055d33 --- /dev/null +++ b/tests/generic/824 @@ -0,0 +1,93 @@ +#! /bin/bash +# FS QA Test No. 824 +# +# Test for races or FS corruption when DIO writing to a file that's also +# the source of a reflink operation. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015 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 7 15 + +_cleanup() +{ + cd / + rm -rf "$tmp".* + wait +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_scratch_reflink +_require_cp_reflink + +echo "Format and mount" +_scratch_mkfs > "$seqres.full" 2>&1 +_scratch_mount >> "$seqres.full" 2>&1 + +TESTDIR="$SCRATCH_MNT/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +loops=1024 +nr_loops=$((loops - 1)) +BLKSZ=65536 + +echo "Initialize file" +echo > "$seqres.full" +_pwrite_byte 0x61 0 $((loops * BLKSZ)) "$TESTDIR/file1" >> "$seqres.full" +_scratch_remount + +# Snapshot creator... +snappy() { + n=0 + while [ ! -e "$TESTDIR/finished" ]; do + _cp_reflink "$TESTDIR/file1" "$TESTDIR/snap_$n" || break + n=$((n + 1)) + done +} + +echo "Snapshot a file undergoing directio rewrite" +snappy & +seq $nr_loops -1 0 | while read i; do + _pwrite_byte 0x63 $((i * BLKSZ)) $BLKSZ -d "$TESTDIR/file1" >> "$seqres.full" +done +touch $TESTDIR/finished +wait + +echo "Check for damage" +umount $SCRATCH_MNT +_check_scratch_fs + +echo "Done" + +# success, all done +status=0 +exit diff --git a/tests/generic/824.out b/tests/generic/824.out new file mode 100644 index 0000000..0376736 --- /dev/null +++ b/tests/generic/824.out @@ -0,0 +1,6 @@ +QA output created by 824 +Format and mount +Initialize file +Snapshot a file undergoing directio rewrite +Check for damage +Done diff --git a/tests/generic/825 b/tests/generic/825 new file mode 100755 index 0000000..2f58fb8 --- /dev/null +++ b/tests/generic/825 @@ -0,0 +1,105 @@ +#! /bin/bash +# FS QA Test No. 825 +# +# Test for races or FS corruption between reflink and direct I/O reading the +# target file. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015 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 7 15 + +_cleanup() +{ + cd / + rm -rf "$tmp".* + wait +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_scratch_reflink +_require_cp_reflink + +echo "Format and mount" +_scratch_mkfs > "$seqres.full" 2>&1 +_scratch_mount >> "$seqres.full" 2>&1 + +TESTDIR="$SCRATCH_MNT/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +loops=512 +nr_loops=$((loops - 1)) +BLKSZ=65536 + +echo "Initialize files" +echo > "$seqres.full" +_pwrite_byte 0x61 0 $((loops * BLKSZ)) "$TESTDIR/file1" >> "$seqres.full" +_pwrite_byte 0x62 0 $((loops * BLKSZ)) "$TESTDIR/file2" >> "$seqres.full" +_cp_reflink $TESTDIR/file1 $TESTDIR/file3 +_scratch_remount + +fbytes() { + egrep -v '(61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61|62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62)' +} + +reader() { + while [ ! -e "$TESTDIR/finished" ]; do + _read_range "$TESTDIR/file3" 0 $((loops * BLKSZ)) -d | fbytes + done +} + +echo "Reflink and dio reread the files!" +reader & +for i in `seq 1 2`; do + seq $nr_loops -1 0 | while read i; do + _reflink_range "$TESTDIR/file1" $((i * BLKSZ)) \ + "$TESTDIR/file3" $((i * BLKSZ)) $BLKSZ >> "$seqres.full" + [ $? -ne 0 ] && break + done + seq $nr_loops -1 0 | while read i; do + _reflink_range "$TESTDIR/file2" $((i * BLKSZ)) \ + "$TESTDIR/file3" $((i * BLKSZ)) $BLKSZ >> "$seqres.full" + [ $? -ne 0 ] && break + done +done +echo "Finished reflinking" +touch "$TESTDIR/finished" +wait + +echo "Check fs" +umount "$SCRATCH_MNT" +_check_scratch_fs + +echo "Done" +# success, all done +status=0 +exit diff --git a/tests/generic/825.out b/tests/generic/825.out new file mode 100644 index 0000000..1e2f36c --- /dev/null +++ b/tests/generic/825.out @@ -0,0 +1,7 @@ +QA output created by 825 +Format and mount +Initialize files +Reflink and dio reread the files! +Finished reflinking +Check fs +Done diff --git a/tests/generic/826 b/tests/generic/826 new file mode 100755 index 0000000..d5c8e14 --- /dev/null +++ b/tests/generic/826 @@ -0,0 +1,105 @@ +#! /bin/bash +# FS QA Test No. 826 +# +# Test for races or FS corruption between reflink and buffered I/O reading the +# target file. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015 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 7 15 + +_cleanup() +{ + cd / + rm -rf "$tmp".* + wait +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_scratch_reflink +_require_cp_reflink + +echo "Format and mount" +_scratch_mkfs > "$seqres.full" 2>&1 +_scratch_mount >> "$seqres.full" 2>&1 + +TESTDIR="$SCRATCH_MNT/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +loops=512 +nr_loops=$((loops - 1)) +BLKSZ=65536 + +echo "Initialize files" +echo > "$seqres.full" +_pwrite_byte 0x61 0 $((loops * BLKSZ)) "$TESTDIR/file1" >> "$seqres.full" +_pwrite_byte 0x62 0 $((loops * BLKSZ)) "$TESTDIR/file2" >> "$seqres.full" +_cp_reflink "$TESTDIR/file1" "$TESTDIR/file3" +_scratch_remount + +fbytes() { + egrep -v '(61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61|62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62)' +} + +reader() { + while [ ! -e "$TESTDIR/finished" ]; do + _read_range "$TESTDIR/file3" 0 $((loops * BLKSZ)) | fbytes + done +} + +echo "Reflink and reread the files!" +reader & +for i in `seq 1 2`; do + seq $nr_loops -1 0 | while read i; do + _reflink_range "$TESTDIR/file1" $((i * BLKSZ)) \ + "$TESTDIR/file3" $((i * BLKSZ)) $BLKSZ >> "$seqres.full" + [ $? -ne 0 ] && break + done + seq $nr_loops -1 0 | while read i; do + _reflink_range "$TESTDIR/file2" $((i * BLKSZ)) \ + "$TESTDIR/file3" $((i * BLKSZ)) $BLKSZ >> "$seqres.full" + [ $? -ne 0 ] && break + done +done +echo "Finished reflinking" +touch "$TESTDIR/finished" +wait + +echo "Check fs" +umount "$SCRATCH_MNT" +_check_scratch_fs + +echo "Done" +# success, all done +status=0 +exit diff --git a/tests/generic/826.out b/tests/generic/826.out new file mode 100644 index 0000000..144f4bc --- /dev/null +++ b/tests/generic/826.out @@ -0,0 +1,7 @@ +QA output created by 826 +Format and mount +Initialize files +Reflink and reread the files! +Finished reflinking +Check fs +Done diff --git a/tests/generic/827 b/tests/generic/827 new file mode 100755 index 0000000..ce9dbdc --- /dev/null +++ b/tests/generic/827 @@ -0,0 +1,95 @@ +#! /bin/bash +# FS QA Test No. 827 +# +# Test for race between dedupe and writing the source file +# +#----------------------------------------------------------------------- +# Copyright (c) 2015 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 7 15 + +_cleanup() +{ + cd / + rm -rf "$tmp".* + wait +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_scratch_dedupe + +echo "Format and mount" +_scratch_mkfs > "$seqres.full" 2>&1 +_scratch_mount >> "$seqres.full" 2>&1 + +TESTDIR="$SCRATCH_MNT/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +loops=512 +nr_loops=$((loops - 1)) +BLKSZ=65536 + +echo "Initialize files" +echo > "$seqres.full" +_pwrite_byte 0x61 0 $((loops * BLKSZ)) "$TESTDIR/file1" >> "$seqres.full" +_pwrite_byte 0x61 0 $((loops * BLKSZ)) "$TESTDIR/file2" >> "$seqres.full" +_scratch_remount + +overwrite() { + while [ ! -e "$TESTDIR/finished" ]; do + seq $nr_loops -1 0 | while read i; do + _pwrite_byte 0x61 $((i * BLKSZ)) $BLKSZ "$TESTDIR/file1" >> "$seqres.full" + done + done +} + +echo "Dedupe and rewrite the file!" +overwrite & +for i in `seq 1 2`; do + seq $nr_loops -1 0 | while read i; do + _dedupe_range "$TESTDIR/file1" $((i * BLKSZ)) \ + "$TESTDIR/file2" $((i * BLKSZ)) $BLKSZ >> "$seqres.full" + [ $? -ne 0 ] && break + done +done +echo "Finished dedupeing" +touch "$TESTDIR/finished" +wait + +echo "Check fs" +umount "$SCRATCH_MNT" +_check_scratch_fs + +echo "Done" +# success, all done +status=0 +exit diff --git a/tests/generic/827.out b/tests/generic/827.out new file mode 100644 index 0000000..1b05f59 --- /dev/null +++ b/tests/generic/827.out @@ -0,0 +1,7 @@ +QA output created by 827 +Format and mount +Initialize files +Dedupe and rewrite the file! +Finished dedupeing +Check fs +Done diff --git a/tests/generic/828 b/tests/generic/828 new file mode 100755 index 0000000..39c7206 --- /dev/null +++ b/tests/generic/828 @@ -0,0 +1,95 @@ +#! /bin/bash +# FS QA Test No. 828 +# +# Test for race between dedupe and writing the dest file +# +#----------------------------------------------------------------------- +# Copyright (c) 2015 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 7 15 + +_cleanup() +{ + cd / + rm -rf "$tmp".* + wait +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_scratch_dedupe + +echo "Format and mount" +_scratch_mkfs > "$seqres.full" 2>&1 +_scratch_mount >> "$seqres.full" 2>&1 + +TESTDIR="$SCRATCH_MNT/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +loops=512 +nr_loops=$((loops - 1)) +BLKSZ=65536 + +echo "Initialize files" +echo > "$seqres.full" +_pwrite_byte 0x61 0 $((loops * BLKSZ)) "$TESTDIR/file1" >> "$seqres.full" +_pwrite_byte 0x61 0 $((loops * BLKSZ)) "$TESTDIR/file2" >> "$seqres.full" +_scratch_remount + +overwrite() { + while [ ! -e "$TESTDIR/finished" ]; do + seq $nr_loops -1 0 | while read i; do + _pwrite_byte 0x61 $((i * BLKSZ)) $BLKSZ "$TESTDIR/file2" >> "$seqres.full" + done + done +} + +echo "Dedupe and rewrite the file!" +overwrite & +for i in `seq 1 2`; do + seq $nr_loops -1 0 | while read i; do + _dedupe_range "$TESTDIR/file1" $((i * BLKSZ)) \ + "$TESTDIR/file2" $((i * BLKSZ)) $BLKSZ >> "$seqres.full" + [ $? -ne 0 ] && break + done +done +echo "Finished dedupeing" +touch "$TESTDIR/finished" +wait + +echo "Check fs" +umount "$SCRATCH_MNT" +_check_scratch_fs + +echo "Done" +# success, all done +status=0 +exit diff --git a/tests/generic/828.out b/tests/generic/828.out new file mode 100644 index 0000000..fb31777 --- /dev/null +++ b/tests/generic/828.out @@ -0,0 +1,7 @@ +QA output created by 828 +Format and mount +Initialize files +Dedupe and rewrite the file! +Finished dedupeing +Check fs +Done diff --git a/tests/generic/829 b/tests/generic/829 new file mode 100755 index 0000000..7b5a40e --- /dev/null +++ b/tests/generic/829 @@ -0,0 +1,79 @@ +#! /bin/bash +# FS QA Test No. 829 +# +# Test for race between delete a file while rewriting its reflinked twin +# +#----------------------------------------------------------------------- +# Copyright (c) 2015 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 7 15 + +_cleanup() +{ + cd / + rm -rf "$tmp".* + wait +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_scratch_reflink +_require_cp_reflink + +echo "Format and mount" +_scratch_mkfs > "$seqres.full" 2>&1 +_scratch_mount >> "$seqres.full" 2>&1 + +TESTDIR="$SCRATCH_MNT/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +loops=4096 +BLKSZ=65536 + +echo "Initialize files" +echo > "$seqres.full" +_pwrite_byte 0x61 0 $((loops * BLKSZ)) "$TESTDIR/file1" >> "$seqres.full" +_cp_reflink "$TESTDIR/file1" "$TESTDIR/file2" +_scratch_remount + +echo "Delete while rewriting" +rm -rf "$TESTDIR/file1" & +_pwrite_byte 0x62 0 $((loops * BLKSZ)) "$TESTDIR/file1" >> "$seqres.full" +wait + +echo "Check fs" +umount "$SCRATCH_MNT" +_check_scratch_fs + +echo "Done" +# success, all done +status=0 +exit diff --git a/tests/generic/829.out b/tests/generic/829.out new file mode 100644 index 0000000..9cee8ba --- /dev/null +++ b/tests/generic/829.out @@ -0,0 +1,6 @@ +QA output created by 829 +Format and mount +Initialize files +Delete while rewriting +Check fs +Done diff --git a/tests/generic/group b/tests/generic/group index 58c68c8..0c137ea 100644 --- a/tests/generic/group +++ b/tests/generic/group @@ -228,5 +228,14 @@ 817 auto quick clone 818 auto quick clone 819 auto quick clone +821 auto quick clone +822 auto quick clone +823 auto quick clone +824 auto quick clone +825 auto quick clone +826 auto quick clone +827 auto quick clone +828 auto quick clone +829 auto quick clone 837 auto quick clone 838 auto quick clone From darrick.wong@oracle.com Wed Nov 11 13:27:47 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 6CFBA29E3D for ; Wed, 11 Nov 2015 13:27:47 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 4EAD1304043 for ; Wed, 11 Nov 2015 11:27:47 -0800 (PST) X-ASG-Debug-ID: 1447270062-04cbb0242512cde0001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id IlD1RL9XGYHdOs92 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 11 Nov 2015 11:27:43 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tABJRJgp030869 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 11 Nov 2015 19:27:20 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id tABJRJGX024289 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 11 Nov 2015 19:27:19 GMT Received: from abhmp0002.oracle.com (abhmp0002.oracle.com [141.146.116.8]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id tABJRJ6K002169; Wed, 11 Nov 2015 19:27:19 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 11 Nov 2015 11:27:18 -0800 Subject: [PATCH 07/11] reflink: test accuracy of free block counts From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 07/11] reflink: test accuracy of free block counts To: hch@infradead.org, david@fromorbit.com, darrick.wong@oracle.com Cc: fstests@vger.kernel.org, xfs@oss.sgi.com, tao.peng@primarydata.com, linux-ext4@vger.kernel.org, Anna.Schumaker@netapp.com, linux-btrfs@vger.kernel.org Date: Wed, 11 Nov 2015 11:27:17 -0800 Message-ID: <20151111192717.15056.86798.stgit@birch.djwong.org> In-Reply-To: <20151111192628.15056.6451.stgit@birch.djwong.org> References: <20151111192628.15056.6451.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0021.oracle.com [156.151.31.71] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1447270063 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/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, UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24309 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.60 MARKETING_SUBJECT Subject contains popular marketing words 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Check that the free block counts seem to be handled correctly in the reflink operation and subsequent attempts to rewrite reflinked copies. Signed-off-by: Darrick J. Wong --- tests/generic/830 | 78 ++++++++++++++++++++++++++++++ tests/generic/830.out | 4 ++ tests/generic/831 | 98 +++++++++++++++++++++++++++++++++++++ tests/generic/831.out | 8 +++ tests/generic/832 | 103 +++++++++++++++++++++++++++++++++++++++ tests/generic/832.out | 8 +++ tests/generic/833 | 102 +++++++++++++++++++++++++++++++++++++++ tests/generic/833.out | 8 +++ tests/generic/834 | 110 ++++++++++++++++++++++++++++++++++++++++++ tests/generic/834.out | 11 ++++ tests/generic/835 | 114 +++++++++++++++++++++++++++++++++++++++++++ tests/generic/835.out | 11 ++++ tests/generic/836 | 129 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/836.out | 32 ++++++++++++ tests/generic/group | 7 +++ 15 files changed, 823 insertions(+) create mode 100755 tests/generic/830 create mode 100644 tests/generic/830.out create mode 100755 tests/generic/831 create mode 100644 tests/generic/831.out create mode 100755 tests/generic/832 create mode 100644 tests/generic/832.out create mode 100755 tests/generic/833 create mode 100644 tests/generic/833.out create mode 100755 tests/generic/834 create mode 100644 tests/generic/834.out create mode 100755 tests/generic/835 create mode 100644 tests/generic/835.out create mode 100755 tests/generic/836 create mode 100644 tests/generic/836.out diff --git a/tests/generic/830 b/tests/generic/830 new file mode 100755 index 0000000..d85bacf --- /dev/null +++ b/tests/generic/830 @@ -0,0 +1,78 @@ +#! /bin/bash +# FS QA Test No. 830 +# +# Ensure that reflinking a file N times doesn't eat a lot of blocks +# - Create a file and record fs block usage +# - Create some reflink copies +# - Compare fs block usage to before +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_reflink +_require_cp_reflink + +rm -f "$seqres.full" + +TESTDIR="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original file blocks" +BLKSZ="$(stat -f $TESTDIR -c '%S')" +BLKS=2000 +MARGIN=100 +SZ=$((BLKSZ * BLKS)) +NR=7 +_pwrite_byte 0x61 0 $SZ "$TESTDIR/file1" >> "$seqres.full" +sync +FREE_BLOCKS0=$(stat -f "$TESTDIR" -c '%f') + +echo "Create the reflink copies" +for i in `seq 2 $NR`; do + _cp_reflink "$TESTDIR/file1" "$TESTDIR/file.$i" +done +_test_remount +FREE_BLOCKS1=$(stat -f "$TESTDIR" -c '%f') + +_within_tolerance "free blocks after reflink" $FREE_BLOCKS1 $FREE_BLOCKS0 $MARGIN -v + +# success, all done +status=0 +exit diff --git a/tests/generic/830.out b/tests/generic/830.out new file mode 100644 index 0000000..76e2f1d --- /dev/null +++ b/tests/generic/830.out @@ -0,0 +1,4 @@ +QA output created by 830 +Create the original file blocks +Create the reflink copies +free blocks after reflink is in range diff --git a/tests/generic/831 b/tests/generic/831 new file mode 100755 index 0000000..d729769 --- /dev/null +++ b/tests/generic/831 @@ -0,0 +1,98 @@ +#! /bin/bash +# FS QA Test No. 831 +# +# Ensure that deleting all copies of a file reflinked N times releases the blocks +# - Record fs block usage (0) +# - Create a file and some reflink copies +# - Record fs block usage (1) +# - Delete some copies of the file +# - Record fs block usage (2) +# - Delete all copies of the file +# - Compare fs block usage to (2), (1), and (0) +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_reflink +_require_cp_reflink + +rm -f "$seqres.full" + +TESTDIR="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original file blocks" +BLKSZ="$(stat -f "$TESTDIR" -c '%S')" +BLKS=2000 +MARGIN=100 +SZ=$((BLKSZ * BLKS)) +FREE_BLOCKS0=$(stat -f "$TESTDIR" -c '%f') +NR=7 +_pwrite_byte 0x61 0 $SZ "$TESTDIR/file1" >> "$seqres.full" +sync + +echo "Create the reflink copies" +for i in `seq 2 $NR`; do + _cp_reflink "$TESTDIR/file1" "$TESTDIR/file.$i" +done +_cp_reflink "$TESTDIR/file1" "$TESTDIR/survivor" +_test_remount +FREE_BLOCKS1=$(stat -f "$TESTDIR" -c '%f') + +echo "Delete most of the files" +rm -rf "$TESTDIR"/file* +_test_remount +FREE_BLOCKS2=$(stat -f "$TESTDIR" -c '%f') + +echo "Delete all the files" +rm -rf "$TESTDIR"/* +_test_remount +FREE_BLOCKS3=$(stat -f "$TESTDIR" -c '%f') +#echo $FREE_BLOCKS0 $FREE_BLOCKS1 $FREE_BLOCKS2 $FREE_BLOCKS3 + +_within_tolerance "free blocks after reflink" $FREE_BLOCKS1 $((FREE_BLOCKS0 - BLKS)) $MARGIN -v + +_within_tolerance "free blocks after deleting some reflink copies" $FREE_BLOCKS2 $FREE_BLOCKS1 $MARGIN -v + +_within_tolerance "free blocks after deleting all copies" $FREE_BLOCKS3 $FREE_BLOCKS0 $MARGIN -v + +# success, all done +status=0 +exit diff --git a/tests/generic/831.out b/tests/generic/831.out new file mode 100644 index 0000000..88e0a23 --- /dev/null +++ b/tests/generic/831.out @@ -0,0 +1,8 @@ +QA output created by 831 +Create the original file blocks +Create the reflink copies +Delete most of the files +Delete all the files +free blocks after reflink is in range +free blocks after deleting some reflink copies is in range +free blocks after deleting all copies is in range diff --git a/tests/generic/832 b/tests/generic/832 new file mode 100755 index 0000000..4f12b77 --- /dev/null +++ b/tests/generic/832 @@ -0,0 +1,103 @@ +#! /bin/bash +# FS QA Test No. 832 +# +# Ensure that punching all copies of a file reflinked N times releases the blocks +# - Record fs block usage (0) +# - Create a file and some reflink copies +# - Record fs block usage (1) +# - Punch some blocks of the copies +# - Record fs block usage (2) +# - Punch all blocks of the copies +# - Compare fs block usage to (2), (1), and (0) +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_reflink +_require_cp_reflink +_require_xfs_io_command "fpunch" + +rm -f "$seqres.full" + +TESTDIR="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original file blocks" +BLKSZ="$(stat -f "$TESTDIR" -c '%S')" +BLKS=2000 +MARGIN=100 +SZ=$((BLKSZ * BLKS)) +FREE_BLOCKS0=$(stat -f "$TESTDIR" -c '%f') +NR=4 +_pwrite_byte 0x61 0 $SZ "$TESTDIR/file1" >> "$seqres.full" +sync + +echo "Create the reflink copies" +for i in `seq 2 $NR`; do + _cp_reflink "$TESTDIR/file1" "$TESTDIR/file$i" +done +_test_remount +FREE_BLOCKS1=$(stat -f "$TESTDIR" -c '%f') + +echo "Punch most of the blocks" +"$XFS_IO_PROG" -f -c "fpunch 0 $SZ" "$TESTDIR/file2" +"$XFS_IO_PROG" -f -c "fpunch 0 $((SZ / 2))" "$TESTDIR/file3" +"$XFS_IO_PROG" -f -c "fpunch $((SZ / 2)) $((SZ / 2))" "$TESTDIR/file4" +_test_remount +FREE_BLOCKS2=$(stat -f "$TESTDIR" -c '%f') + +echo "Punch all the files" +for i in `seq 2 $NR`; do + "$XFS_IO_PROG" -f -c "fpunch 0 $SZ" "$TESTDIR/file$i" +done +"$XFS_IO_PROG" -f -c "fpunch 0 $SZ" "$TESTDIR/file1" +_test_remount +FREE_BLOCKS3=$(stat -f "$TESTDIR" -c '%f') +#echo $FREE_BLOCKS0 $FREE_BLOCKS1 $FREE_BLOCKS2 $FREE_BLOCKS3 + +_within_tolerance "free blocks after reflink" $FREE_BLOCKS1 $((FREE_BLOCKS0 - BLKS)) $MARGIN -v + +_within_tolerance "free blocks after punching some reflink copies" $FREE_BLOCKS2 $FREE_BLOCKS1 $MARGIN -v + +_within_tolerance "free blocks after punching all copies" $FREE_BLOCKS3 $FREE_BLOCKS0 $MARGIN -v + +# success, all done +status=0 +exit diff --git a/tests/generic/832.out b/tests/generic/832.out new file mode 100644 index 0000000..bb95578 --- /dev/null +++ b/tests/generic/832.out @@ -0,0 +1,8 @@ +QA output created by 832 +Create the original file blocks +Create the reflink copies +Punch most of the blocks +Punch all the files +free blocks after reflink is in range +free blocks after punching some reflink copies is in range +free blocks after punching all copies is in range diff --git a/tests/generic/833 b/tests/generic/833 new file mode 100755 index 0000000..07dfabf --- /dev/null +++ b/tests/generic/833 @@ -0,0 +1,102 @@ +#! /bin/bash +# FS QA Test No. 833 +# +# Ensure that collapse-range on all copies of a file reflinked N times releases the blocks +# - Record fs block usage (0) +# - Create a file and some reflink copies +# - Record fs block usage (1) +# - Collapse-range some blocks of the copies +# - Record fs block usage (2) +# - Truncate all blocks of the copies +# - Compare fs block usage to (2), (1), and (0) +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_reflink +_require_cp_reflink +_require_xfs_io_command "fcollapse" + +rm -f "$seqres.full" + +TESTDIR="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original file blocks" +BLKSZ="$(stat -f "$TESTDIR" -c '%S')" +BLKS=2000 +MARGIN=100 +SZ=$((BLKSZ * BLKS)) +FREE_BLOCKS0=$(stat -f "$TESTDIR" -c '%f') +NR=4 +_pwrite_byte 0x61 0 $SZ "$TESTDIR/file1" >> "$seqres.full" +_test_remount + +echo "Create the reflink copies" +for i in `seq 2 $NR`; do + _cp_reflink "$TESTDIR/file1" "$TESTDIR/file$i" +done +_test_remount +FREE_BLOCKS1=$(stat -f "$TESTDIR" -c '%f') + +echo "Collapse most of the blocks" +"$XFS_IO_PROG" -f -c "fcollapse 0 $(((BLKS - 1) * BLKSZ))" $TESTDIR/file2 +"$XFS_IO_PROG" -f -c "fcollapse 0 $((SZ / 2))" $TESTDIR/file3 +"$XFS_IO_PROG" -f -c "fcollapse $((SZ / 2)) $(( ((BLKS / 2) - 1) * BLKSZ))" $TESTDIR/file4 +_test_remount +FREE_BLOCKS2=$(stat -f "$TESTDIR" -c '%f') + +echo "Collpase nearly all the files" +"$XFS_IO_PROG" -f -c "fcollapse 0 $(( ((BLKS / 2) - 1) * BLKSZ))" $TESTDIR/file3 +"$XFS_IO_PROG" -f -c "fcollapse 0 $((SZ / 2))" $TESTDIR/file4 +"$XFS_IO_PROG" -f -c "fcollapse 0 $(( (BLKS - 1) * BLKSZ))" $TESTDIR/file1 +_test_remount +FREE_BLOCKS3=$(stat -f "$TESTDIR" -c '%f') +#echo $FREE_BLOCKS0 $FREE_BLOCKS1 $FREE_BLOCKS2 $FREE_BLOCKS3 + +_within_tolerance "free blocks after reflink" $FREE_BLOCKS1 $((FREE_BLOCKS0 - BLKS)) $MARGIN -v + +_within_tolerance "free blocks after fcollapsing some reflink copies" $FREE_BLOCKS2 $FREE_BLOCKS1 $MARGIN -v + +_within_tolerance "free blocks after fcollapsing all copies" $FREE_BLOCKS3 $FREE_BLOCKS0 $MARGIN -v + +# success, all done +status=0 +exit diff --git a/tests/generic/833.out b/tests/generic/833.out new file mode 100644 index 0000000..a9a2941 --- /dev/null +++ b/tests/generic/833.out @@ -0,0 +1,8 @@ +QA output created by 833 +Create the original file blocks +Create the reflink copies +Collapse most of the blocks +Collpase nearly all the files +free blocks after reflink is in range +free blocks after fcollapsing some reflink copies is in range +free blocks after fcollapsing all copies is in range diff --git a/tests/generic/834 b/tests/generic/834 new file mode 100755 index 0000000..d24dfa5 --- /dev/null +++ b/tests/generic/834 @@ -0,0 +1,110 @@ +#! /bin/bash +# FS QA Test No. 834 +# +# Ensure that CoW on all copies of a file reflinked N times increases block count +# - Record fs block usage (0) +# - Create a file and some reflink copies +# - Record fs block usage (1) +# - CoW some blocks of the copies +# - Record fs block usage (2) +# - CoW all the rest of the blocks of the copies +# - Compare fs block usage to (2), (1), and (0) +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_reflink +_require_cp_reflink + +rm -f "$seqres.full" + +TESTDIR="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original file blocks" +BLKSZ="$(stat -f "$TESTDIR" -c '%S')" +BLKS=2000 +MARGIN=100 +FREE_BLOCKS0=$(stat -f "$TESTDIR" -c '%f') +NR=4 +SZ=$((BLKS * BLKSZ)) +_pwrite_byte 0x61 0 $SZ "$TESTDIR/file1" >> "$seqres.full" +_test_remount + +echo "Create the reflink copies" +for i in `seq 2 $NR`; do + _cp_reflink "$TESTDIR/file1" "$TESTDIR/file$i" +done +_test_remount +FREE_BLOCKS1=$(stat -f "$TESTDIR" -c '%f') + +echo "Rewrite some of the blocks" +_pwrite_byte 0x62 0 $SZ "$TESTDIR/file2" >> "$seqres.full" +_pwrite_byte 0x63 0 $((SZ / 2)) "$TESTDIR/file3" >> "$seqres.full" +_pwrite_byte 0x64 $((SZ / 2)) $((SZ / 2)) "$TESTDIR/file4" >> "$seqres.full" +_test_remount +FREE_BLOCKS2=$(stat -f "$TESTDIR" -c '%f') + +echo "Rewrite all the files" +_pwrite_byte 0x62 0 $SZ "$TESTDIR/file2" >> "$seqres.full" +_pwrite_byte 0x63 0 $SZ "$TESTDIR/file3" >> "$seqres.full" +_pwrite_byte 0x64 0 $SZ "$TESTDIR/file4" >> "$seqres.full" +_test_remount +FREE_BLOCKS3=$(stat -f "$TESTDIR" -c '%f') + +echo "Rewrite the original file" +_pwrite_byte 0x65 0 $SZ "$TESTDIR/file1" >> "$seqres.full" +_test_remount +FREE_BLOCKS4=$(stat -f "$TESTDIR" -c '%f') +#echo $FREE_BLOCKS0 $FREE_BLOCKS1 $FREE_BLOCKS2 $FREE_BLOCKS3 $FREE_BLOCKS4 + +_within_tolerance "free blocks after reflinking" $FREE_BLOCKS1 $((FREE_BLOCKS0 - BLKS)) $MARGIN -v + +_within_tolerance "free blocks after partially CoWing some copies" $FREE_BLOCKS2 $((FREE_BLOCKS1 - (2 * BLKS))) $MARGIN -v + +_within_tolerance "free blocks after CoWing all copies" $FREE_BLOCKS3 $((FREE_BLOCKS2 - BLKS)) $MARGIN -v + +_within_tolerance "free blocks after overwriting original" $FREE_BLOCKS4 $FREE_BLOCKS3 $MARGIN -v + +_within_tolerance "free blocks after all tests" $FREE_BLOCKS4 $((FREE_BLOCKS0 - (4 * BLKS))) $MARGIN -v + +# success, all done +status=0 +exit diff --git a/tests/generic/834.out b/tests/generic/834.out new file mode 100644 index 0000000..e67e803 --- /dev/null +++ b/tests/generic/834.out @@ -0,0 +1,11 @@ +QA output created by 834 +Create the original file blocks +Create the reflink copies +Rewrite some of the blocks +Rewrite all the files +Rewrite the original file +free blocks after reflinking is in range +free blocks after partially CoWing some copies is in range +free blocks after CoWing all copies is in range +free blocks after overwriting original is in range +free blocks after all tests is in range diff --git a/tests/generic/835 b/tests/generic/835 new file mode 100755 index 0000000..881063b --- /dev/null +++ b/tests/generic/835 @@ -0,0 +1,114 @@ +#! /bin/bash +# FS QA Test No. 835 +# +# Ensure that CoW on all copies of a file reflinked N times increases block count +# - Record fs block usage (0) +# - Create a file and some reflink copies +# - Record fs block usage (1) +# - CoW some blocks of the copies +# - Record fs block usage (2) +# - CoW all the rest of the blocks of the copies +# - Compare fs block usage to (2), (1), and (0) +# +# The main difference from 834 is that we use zero range, directio, and +# mmap to mix things up a bit. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_reflink +_require_cp_reflink +_require_xfs_io_command "fzero" + +rm -f "$seqres.full" + +TESTDIR=$TEST_DIR/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR + +echo "Create the original file blocks" +BLKSZ="$(stat -f "$TESTDIR" -c '%S')" +BLKS=2000 +MARGIN=100 +SZ=$((BLKSZ * BLKS)) +FREE_BLOCKS0=$(stat -f "$TESTDIR" -c '%f') +NR=4 +_pwrite_byte 0x61 0 $SZ "$TESTDIR/file1" >> "$seqres.full" +_test_remount + +echo "Create the reflink copies" +for i in `seq 2 $NR`; do + _cp_reflink "$TESTDIR/file1" "$TESTDIR/file$i" +done +_test_remount +FREE_BLOCKS1=$(stat -f "$TESTDIR" -c '%f') + +echo "Rewrite some of the blocks" +"$XFS_IO_PROG" -f -c "fzero 0 $SZ" "$TESTDIR/file2" >> "$seqres.full" +_pwrite_byte 0x63 0 $((SZ / 2)) "$TESTDIR/file3" -d >> "$seqres.full" +_mwrite_byte 0x64 $((SZ / 2)) $((SZ / 2)) $SZ "$TESTDIR/file4" >> "$seqres.full" +_test_remount +FREE_BLOCKS2=$(stat -f "$TESTDIR" -c '%f') + +echo "Rewrite all the files" +_pwrite_byte 0x62 0 $SZ "$TESTDIR/file2" -d >> "$seqres.full" +_mwrite_byte 0x63 0 $SZ $SZ "$TESTDIR/file3" >> "$seqres.full" +"$XFS_IO_PROG" -f -c "fzero 0 $SZ" $TESTDIR/file4 >> "$seqres.full" +_test_remount +FREE_BLOCKS3=$(stat -f "$TESTDIR" -c '%f') + +echo "Rewrite the original file" +_pwrite_byte 0x65 0 $SZ "$TESTDIR/file1" >> "$seqres.full" +_test_remount +FREE_BLOCKS4=$(stat -f "$TESTDIR" -c '%f') +#echo $FREE_BLOCKS0 $FREE_BLOCKS1 $FREE_BLOCKS2 $FREE_BLOCKS3 $FREE_BLOCKS4 + +_within_tolerance "free blocks after reflinking" $FREE_BLOCKS1 $((FREE_BLOCKS0 - BLKS)) $MARGIN -v + +_within_tolerance "free blocks after partially CoWing some copies" $FREE_BLOCKS2 $((FREE_BLOCKS1 - (2 * BLKS))) $MARGIN -v + +_within_tolerance "free blocks after CoWing all copies" $FREE_BLOCKS3 $((FREE_BLOCKS2 - BLKS)) $MARGIN -v + +_within_tolerance "free blocks after overwriting original" $FREE_BLOCKS4 $FREE_BLOCKS3 $MARGIN -v + +_within_tolerance "free blocks after all tests" $FREE_BLOCKS4 $((FREE_BLOCKS0 - (4 * BLKS))) $MARGIN -v + +# success, all done +status=0 +exit diff --git a/tests/generic/835.out b/tests/generic/835.out new file mode 100644 index 0000000..c1103be --- /dev/null +++ b/tests/generic/835.out @@ -0,0 +1,11 @@ +QA output created by 835 +Create the original file blocks +Create the reflink copies +Rewrite some of the blocks +Rewrite all the files +Rewrite the original file +free blocks after reflinking is in range +free blocks after partially CoWing some copies is in range +free blocks after CoWing all copies is in range +free blocks after overwriting original is in range +free blocks after all tests is in range diff --git a/tests/generic/836 b/tests/generic/836 new file mode 100755 index 0000000..2e0639f --- /dev/null +++ b/tests/generic/836 @@ -0,0 +1,129 @@ +#! /bin/bash +# FS QA Test No. 836 +# +# Ensure that fallocate on reflinked files actually CoWs the shared blocks. +# - Record fs block usage (0) +# - Create a file and some reflink copies +# - Record fs block usage (1) +# - funshare half of one of the copies +# - Record fs block usage (2) +# - funshare all of the copies +# - Record fs block usage (3) +# - rewrite the original file +# - Record fs block usage (4) +# - Compare fs block usage of 0-4 to ensure that block usage behaves as +# we expect. +# +# "funshare" refers to fallocate copy-on-writing the shared blocks +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/attr +. ./common/reflink + +if [ $FSTYP = "btrfs" ]; then + _notrun "btrfs doesn't handle unshare on fallocate" +fi + +# real QA test starts here +_supported_os Linux +_require_test_reflink +_require_cp_reflink +_require_xfs_io_command "falloc" + +rm -f "$seqres.full" + +TESTDIR="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original file blocks" +BLKSZ="$(stat -f "$TESTDIR" -c '%S')" +BLKS=2000 +MARGIN=100 +SZ=$((BLKSZ * BLKS)) +FREE_BLOCKS0=$(stat -f "$TESTDIR" -c '%f') +NR=4 +_pwrite_byte 0x61 0 $SZ "$TESTDIR/file1" >> "$seqres.full" +_test_remount + +echo "Create the reflink copies" +for i in `seq 2 $NR`; do + _cp_reflink "$TESTDIR/file1" "$TESTDIR/file$i" +done +_test_remount +FREE_BLOCKS1=$(stat -f "$TESTDIR" -c '%f') +lsattr -l $TESTDIR/ | _filter_test_dir + +echo "funshare part of a file" +"$XFS_IO_PROG" -f -c "falloc 0 $((SZ / 2))" "$TESTDIR/file2" +_test_remount +lsattr -l $TESTDIR/ | _filter_test_dir + +echo "funshare some of the copies" +"$XFS_IO_PROG" -f -c "falloc 0 $SZ" "$TESTDIR/file2" +"$XFS_IO_PROG" -f -c "falloc 0 $SZ" "$TESTDIR/file3" +_test_remount +FREE_BLOCKS2=$(stat -f "$TESTDIR" -c '%f') +lsattr -l $TESTDIR/ | _filter_test_dir + +echo "funshare the rest of the files" +"$XFS_IO_PROG" -f -c "falloc 0 $SZ" "$TESTDIR/file4" +"$XFS_IO_PROG" -f -c "falloc 0 $SZ" "$TESTDIR/file1" +_test_remount +FREE_BLOCKS3=$(stat -f "$TESTDIR" -c '%f') +lsattr -l $TESTDIR/ | _filter_test_dir + +echo "Rewrite the original file" +_pwrite_byte 0x65 0 $SZ "$TESTDIR/file1" >> "$seqres.full" +_test_remount +FREE_BLOCKS4=$(stat -f "$TESTDIR" -c '%f') +lsattr -l $TESTDIR/ | _filter_test_dir +#echo $FREE_BLOCKS0 $FREE_BLOCKS1 $FREE_BLOCKS2 $FREE_BLOCKS3 $FREE_BLOCKS4 + +_within_tolerance "free blocks after reflinking" $FREE_BLOCKS1 $((FREE_BLOCKS0 - BLKS)) $MARGIN -v + +_within_tolerance "free blocks after nocow'ing some copies" $FREE_BLOCKS2 $((FREE_BLOCKS1 - (2 * BLKS))) $MARGIN -v + +_within_tolerance "free blocks after nocow'ing all copies" $FREE_BLOCKS3 $((FREE_BLOCKS2 - BLKS)) $MARGIN -v + +_within_tolerance "free blocks after overwriting original" $FREE_BLOCKS4 $FREE_BLOCKS3 $MARGIN -v + +_within_tolerance "free blocks after all tests" $FREE_BLOCKS4 $((FREE_BLOCKS0 - (4 * BLKS))) $MARGIN -v + +# success, all done +status=0 +exit diff --git a/tests/generic/836.out b/tests/generic/836.out new file mode 100644 index 0000000..45f7750 --- /dev/null +++ b/tests/generic/836.out @@ -0,0 +1,32 @@ +QA output created by 836 +Create the original file blocks +Create the reflink copies +TEST_DIR/test-836/file1 --- +TEST_DIR/test-836/file2 --- +TEST_DIR/test-836/file3 --- +TEST_DIR/test-836/file4 --- +funshare part of a file +TEST_DIR/test-836/file1 --- +TEST_DIR/test-836/file2 --- +TEST_DIR/test-836/file3 --- +TEST_DIR/test-836/file4 --- +funshare some of the copies +TEST_DIR/test-836/file1 --- +TEST_DIR/test-836/file2 No_COW +TEST_DIR/test-836/file3 No_COW +TEST_DIR/test-836/file4 --- +funshare the rest of the files +TEST_DIR/test-836/file1 No_COW +TEST_DIR/test-836/file2 No_COW +TEST_DIR/test-836/file3 No_COW +TEST_DIR/test-836/file4 No_COW +Rewrite the original file +TEST_DIR/test-836/file1 No_COW +TEST_DIR/test-836/file2 No_COW +TEST_DIR/test-836/file3 No_COW +TEST_DIR/test-836/file4 No_COW +free blocks after reflinking is in range +free blocks after nocow'ing some copies is in range +free blocks after nocow'ing all copies is in range +free blocks after overwriting original is in range +free blocks after all tests is in range diff --git a/tests/generic/group b/tests/generic/group index 0c137ea..9b57872 100644 --- a/tests/generic/group +++ b/tests/generic/group @@ -237,5 +237,12 @@ 827 auto quick clone 828 auto quick clone 829 auto quick clone +830 auto quick clone +831 auto quick clone +832 auto quick clone +833 auto quick clone +834 auto quick clone +835 auto quick clone +836 auto quick clone 837 auto quick clone 838 auto quick clone From darrick.wong@oracle.com Wed Nov 11 13:27:50 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 69D7629E34 for ; Wed, 11 Nov 2015 13:27:50 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id E3B4FAC002 for ; Wed, 11 Nov 2015 11:27:49 -0800 (PST) X-ASG-Debug-ID: 1447270067-04cbb0242412cde0001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id lUfzDuN20582kFSE (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 11 Nov 2015 11:27:47 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tABJRRql029648 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 11 Nov 2015 19:27:27 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id tABJRQ99030176 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 11 Nov 2015 19:27:26 GMT Received: from abhmp0013.oracle.com (abhmp0013.oracle.com [141.146.116.19]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id tABJRQmE020055; Wed, 11 Nov 2015 19:27:26 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 11 Nov 2015 11:27:25 -0800 Subject: [PATCH 08/11] reflink: test error conditions due to bad inputs From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 08/11] reflink: test error conditions due to bad inputs To: hch@infradead.org, david@fromorbit.com, darrick.wong@oracle.com Cc: fstests@vger.kernel.org, xfs@oss.sgi.com, tao.peng@primarydata.com, linux-ext4@vger.kernel.org, Anna.Schumaker@netapp.com, linux-btrfs@vger.kernel.org Date: Wed, 11 Nov 2015 11:27:24 -0800 Message-ID: <20151111192724.15056.40330.stgit@birch.djwong.org> In-Reply-To: <20151111192628.15056.6451.stgit@birch.djwong.org> References: <20151111192628.15056.6451.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1447270067 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24309 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Check that we can feed bad inputs to reflink and it'll reject them. Signed-off-by: Darrick J. Wong --- tests/generic/839 | 106 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/839.out | 19 +++++++++ tests/generic/846 | 106 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/846.out | 19 +++++++++ tests/generic/group | 2 + 5 files changed, 252 insertions(+) create mode 100755 tests/generic/839 create mode 100644 tests/generic/839.out create mode 100755 tests/generic/846 create mode 100644 tests/generic/846.out diff --git a/tests/generic/839 b/tests/generic/839 new file mode 100755 index 0000000..0b754b1 --- /dev/null +++ b/tests/generic/839 @@ -0,0 +1,106 @@ +#! /bin/bash +# FS QA Test No. 839 +# +# Check that various invalid reflink scenarios are rejected +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR1" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/attr +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_reflink +_require_scratch_reflink + +rm -f "$seqres.full" + +echo "Format and mount" +_scratch_mkfs > "$seqres.full" 2>&1 +_scratch_mount >> "$seqres.full" 2>&1 + +TESTDIR1="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR1" +mkdir "$TESTDIR1" + +TESTDIR2=$SCRATCH_MNT/test-$seq +rm -rf "$TESTDIR2" +mkdir "$TESTDIR2" + +echo "Create the original files" +BLKSZ="$(stat -f $TESTDIR1 -c '%S')" +BLKS=1000 +MARGIN=50 +SZ=$((BLKSZ * BLKS)) +FREE_BLOCKS0=$(stat -f $TESTDIR1 -c '%f') +NR=4 +_pwrite_byte 0x61 0 $SZ "$TESTDIR1/file1" >> "$seqres.full" +_pwrite_byte 0x61 0 $SZ "$TESTDIR1/file2" >> "$seqres.full" +_pwrite_byte 0x61 0 $SZ "$TESTDIR2/file1" >> "$seqres.full" +_pwrite_byte 0x61 0 $SZ "$TESTDIR2/file2" >> "$seqres.full" +sync + +echo "Try cross-device reflink" +_reflink_range "$TESTDIR1/file1" 0 "$TESTDIR2/file1" 0 $BLKSZ + +echo "Try unaligned reflink" +_reflink_range "$TESTDIR1/file1" 37 "$TESTDIR1/file1" 59 23 + +echo "Try overlapping reflink" +_reflink_range "$TESTDIR1/file1" 0 "$TESTDIR1/file1" 1 $((BLKSZ * 2)) + +echo "Try reflink past EOF" +_reflink_range "$TESTDIR1/file1" $(( (BLKS + 10) * BLKSZ)) "$TESTDIR1/file1" 0 $BLKSZ + +chattr +i $TESTDIR1/file1 $TESTDIR1/file2 +echo "Try reflink on immutable files" +_reflink_range "$TESTDIR1/file1" 0 "$TESTDIR1/file2" 0 $BLKSZ 2>&1 | _filter_test_dir +chattr -i $TESTDIR1/file1 $TESTDIR1/file2 + +echo "Reflink two files" +_reflink_range "$TESTDIR1/file1" 0 "$TESTDIR1/file2" 0 $BLKSZ >> "$seqres.full" +_reflink_range "$TESTDIR2/file1" 0 "$TESTDIR2/file2" 0 $BLKSZ >> "$seqres.full" + +lsattr -l $TESTDIR1/ | _filter_test_dir +lsattr -l $TESTDIR2/ | _filter_scratch + +echo "Check scratch fs" +umount $SCRATCH_MNT +_check_scratch_fs + +# success, all done +status=0 +exit diff --git a/tests/generic/839.out b/tests/generic/839.out new file mode 100644 index 0000000..d8703b1 --- /dev/null +++ b/tests/generic/839.out @@ -0,0 +1,19 @@ +QA output created by 839 +Format and mount +Create the original files +Try cross-device reflink +XFS_IOC_CLONE_RANGE: Invalid cross-device link +Try unaligned reflink +XFS_IOC_CLONE_RANGE: Invalid argument +Try overlapping reflink +XFS_IOC_CLONE_RANGE: Invalid argument +Try reflink past EOF +XFS_IOC_CLONE_RANGE: Invalid argument +Try reflink on immutable files +TEST_DIR/test-839/file2: Permission denied +Reflink two files +TEST_DIR/test-839/file1 --- +TEST_DIR/test-839/file2 --- +SCRATCH_MNT/test-839/file1 --- +SCRATCH_MNT/test-839/file2 --- +Check scratch fs diff --git a/tests/generic/846 b/tests/generic/846 new file mode 100755 index 0000000..e425fbd --- /dev/null +++ b/tests/generic/846 @@ -0,0 +1,106 @@ +#! /bin/bash +# FS QA Test No. 839 +# +# Check that various invalid dedupe scenarios are rejected +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR1" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/attr +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_dedupe +_require_scratch_dedupe + +rm -f "$seqres.full" + +echo "Format and mount" +_scratch_mkfs > "$seqres.full" 2>&1 +_scratch_mount >> "$seqres.full" 2>&1 + +TESTDIR1="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR1" +mkdir "$TESTDIR1" + +TESTDIR2=$SCRATCH_MNT/test-$seq +rm -rf "$TESTDIR2" +mkdir "$TESTDIR2" + +echo "Create the original files" +BLKSZ="$(stat -f $TESTDIR1 -c '%S')" +BLKS=1000 +MARGIN=50 +SZ=$((BLKSZ * BLKS)) +FREE_BLOCKS0=$(stat -f $TESTDIR1 -c '%f') +NR=4 +_pwrite_byte 0x61 0 $SZ "$TESTDIR1/file1" >> "$seqres.full" +_pwrite_byte 0x61 0 $SZ "$TESTDIR1/file2" >> "$seqres.full" +_pwrite_byte 0x61 0 $SZ "$TESTDIR2/file1" >> "$seqres.full" +_pwrite_byte 0x61 0 $SZ "$TESTDIR2/file2" >> "$seqres.full" +sync + +echo "Try cross-device dedupe" +_dedupe_range "$TESTDIR1/file1" 0 "$TESTDIR2/file1" 0 $BLKSZ + +echo "Try unaligned dedupe" +_dedupe_range "$TESTDIR1/file1" 37 "$TESTDIR1/file1" 59 23 + +echo "Try overlapping dedupe" +_dedupe_range "$TESTDIR1/file1" 0 "$TESTDIR1/file1" 1 $((BLKSZ * 2)) + +echo "Try dedupe past EOF" +_dedupe_range "$TESTDIR1/file1" $(( (BLKS + 10) * BLKSZ)) "$TESTDIR1/file1" 0 $BLKSZ + +chattr +i $TESTDIR1/file1 $TESTDIR1/file2 +echo "Try dedupe on immutable files" +_dedupe_range "$TESTDIR1/file1" 0 "$TESTDIR1/file2" 0 $BLKSZ 2>&1 | _filter_test_dir +chattr -i $TESTDIR1/file1 $TESTDIR1/file2 + +echo "Dedupe two files" +_dedupe_range "$TESTDIR1/file1" 0 "$TESTDIR1/file2" 0 $BLKSZ >> "$seqres.full" +_dedupe_range "$TESTDIR2/file1" 0 "$TESTDIR2/file2" 0 $BLKSZ >> "$seqres.full" + +lsattr -l $TESTDIR1/ | _filter_test_dir +lsattr -l $TESTDIR2/ | _filter_scratch + +echo "Check scratch fs" +umount $SCRATCH_MNT +_check_scratch_fs + +# success, all done +status=0 +exit diff --git a/tests/generic/846.out b/tests/generic/846.out new file mode 100644 index 0000000..65a20bf --- /dev/null +++ b/tests/generic/846.out @@ -0,0 +1,19 @@ +QA output created by 846 +Format and mount +Create the original files +Try cross-device dedupe +dedupe: Invalid cross-device link +Try unaligned dedupe +dedupe: Invalid argument +Try overlapping dedupe +dedupe: Invalid argument +Try dedupe past EOF +dedupe: Invalid argument +Try dedupe on immutable files +TEST_DIR/test-846/file2: Permission denied +Dedupe two files +TEST_DIR/test-846/file1 --- +TEST_DIR/test-846/file2 --- +SCRATCH_MNT/test-846/file1 --- +SCRATCH_MNT/test-846/file2 --- +Check scratch fs diff --git a/tests/generic/group b/tests/generic/group index 9b57872..90f28aa 100644 --- a/tests/generic/group +++ b/tests/generic/group @@ -246,3 +246,5 @@ 836 auto quick clone 837 auto quick clone 838 auto quick clone +839 auto quick clone +846 auto quick clone From darrick.wong@oracle.com Wed Nov 11 13:28:05 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 369ED29E1F for ; Wed, 11 Nov 2015 13:28:05 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id D9FEAAC002 for ; Wed, 11 Nov 2015 11:28:04 -0800 (PST) X-ASG-Debug-ID: 1447270082-04bdf03f051214a0001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id FZpo7EvHwXSMMGiI (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 11 Nov 2015 11:28:02 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tABJReDH029937 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 11 Nov 2015 19:27:40 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id tABJRe3N003369 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 11 Nov 2015 19:27:40 GMT Received: from abhmp0016.oracle.com (abhmp0016.oracle.com [141.146.116.22]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id tABJRdbA020188; Wed, 11 Nov 2015 19:27:39 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 11 Nov 2015 11:27:39 -0800 Subject: [PATCH 10/11] reflink: test what happens when we hit resource limits From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 10/11] reflink: test what happens when we hit resource limits To: hch@infradead.org, david@fromorbit.com, darrick.wong@oracle.com Cc: fstests@vger.kernel.org, xfs@oss.sgi.com, tao.peng@primarydata.com, linux-ext4@vger.kernel.org, Anna.Schumaker@netapp.com, linux-btrfs@vger.kernel.org Date: Wed, 11 Nov 2015 11:27:37 -0800 Message-ID: <20151111192737.15056.44475.stgit@birch.djwong.org> In-Reply-To: <20151111192628.15056.6451.stgit@birch.djwong.org> References: <20151111192628.15056.6451.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1447270082 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24309 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Add a few horrible opt-in stress tests to see what happens if we try to reflink the same block billions of times, and what happens if we run out of space while reflinking a file. Signed-off-by: Darrick J. Wong --- tests/generic/840 | 99 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/840.out | 0 tests/generic/841 | 81 ++++++++++++++++++++++++++++++++++++++++ tests/generic/841.out | 5 ++ tests/generic/group | 2 + 5 files changed, 187 insertions(+) create mode 100755 tests/generic/840 create mode 100644 tests/generic/840.out create mode 100755 tests/generic/841 create mode 100644 tests/generic/841.out diff --git a/tests/generic/840 b/tests/generic/840 new file mode 100755 index 0000000..137cc3d --- /dev/null +++ b/tests/generic/840 @@ -0,0 +1,99 @@ +#! /bin/bash +# FS QA Test No. 840 +# +# Try to hit the maximum reference count (eek!) +# +# This test runs extremely slowly, so it's not automatically run anywhere. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR1" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/attr +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_scratch_reflink +_require_cp_reflink + +rm -f "$seqres.full" + +echo "Format and mount" +_scratch_mkfs > "$seqres.full" 2>&1 +_scratch_mount >> "$seqres.full" 2>&1 + +TESTDIR="$SCRATCH_MNT/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +# Well let's hope the maximum reflink count is (less than (ha!)) 2^32... + +echo "Create a one block file" +BLKSZ="$(stat -f "$TESTDIR" -c '%S')" +_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file1" >> "$seqres.full" +_pwrite_byte 0x62 0 $BLKSZ "$TESTDIR/file2" >> "$seqres.full" +_cp_reflink "$TESTDIR/file1" "$TESTDIR/file2" >> "$seqres.full" + +nr=32 +fnr=32 +for i in $(seq 0 $fnr); do + echo " ++ Reflink size $i, $(( (2 ** i) * BLKSZ)) bytes" | tee -a "$seqres.full" + n=$(( (2 ** i) * BLKSZ)) + _reflink_range "$TESTDIR/file1" 0 "$TESTDIR/file1" $n $n >> "$seqres.full" || break +done + +nrf=$((nr - fnr)) +echo "Clone $((2 ** nrf)) files" +seq 0 $((2 ** nrf)) | while read i; do + _cp-reflink "$TESTDIR/file1" "$TESTDIR/file1-$i" +done + +echo "Check scratch fs" +umount "$SCRATCH_MNT" +_check_scratch_fs + +echo "Remove big file and recheck" +_scratch_mount >> "$seqres.full" 2>&1 +umount "$SCRATCH_MNT" +_check_scratch_fs + +echo "Remove all files and recheck" +_scratch_mount >> "$seqres.full" 2>&1 +umount "$SCRATCH_MNT" +_check_scratch_fs + +# success, all done +status=0 +exit diff --git a/tests/generic/840.out b/tests/generic/840.out new file mode 100644 index 0000000..e69de29 diff --git a/tests/generic/841 b/tests/generic/841 new file mode 100755 index 0000000..b89dba4 --- /dev/null +++ b/tests/generic/841 @@ -0,0 +1,81 @@ +#! /bin/bash +# FS QA Test No. 841 +# +# Try to run out of space while cloning? +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR1" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/attr +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_scratch_reflink + +rm -f "$seqres.full" + +echo "Format and mount" +_scratch_mkfs > "$seqres.full" 2>&1 +_scratch_mount >> "$seqres.full" 2>&1 + +TESTDIR="$SCRATCH_MNT/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +BLKSZ="$(stat -f "$TESTDIR" -c '%S')" +NR_FREE="$(stat -f -c '%f' "$TESTDIR")" +echo "Create a big file" +touch "$TESTDIR/file0" "$TESTDIR/file1" +_pwrite_byte 0x61 0 $((BLKSZ * NR_FREE)) "$TESTDIR/bigfile" >> "$seqres.full" 2>&1 +_scratch_remount +sz="$(stat -c '%s' "$TESTDIR/bigfile")" + +blks="$((sz / BLKSZ))" +echo "Try to reflink" +seq 0 $blks | while read lblk; do + fname="$TESTDIR/file$((lblk % 2))" + out="$(_reflink_range "$TESTDIR/bigfile" $((lblk * BLKSZ)) "$fname" $((lblk * BLKSZ)) $BLKSZ 2>&1)" + echo "$fname: $out" >> "$seqres.full" + echo "$out" | grep -q "No space left on device" && break +done + +echo "Check scratch fs" +umount "$SCRATCH_MNT" +_check_scratch_fs + +# success, all done +status=0 +exit diff --git a/tests/generic/841.out b/tests/generic/841.out new file mode 100644 index 0000000..33c46fd --- /dev/null +++ b/tests/generic/841.out @@ -0,0 +1,5 @@ +QA output created by 841 +Format and mount +Create a big file +Try to reflink +Check scratch fs diff --git a/tests/generic/group b/tests/generic/group index 90f28aa..eef608f 100644 --- a/tests/generic/group +++ b/tests/generic/group @@ -247,4 +247,6 @@ 837 auto quick clone 838 auto quick clone 839 auto quick clone +840 clone_stress +841 clone_stress 846 auto quick clone From darrick.wong@oracle.com Wed Nov 11 13:28:06 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id CB77729E1F for ; Wed, 11 Nov 2015 13:28:05 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 6C74DAC001 for ; Wed, 11 Nov 2015 11:28:05 -0800 (PST) X-ASG-Debug-ID: 1447270081-04bdf03f02121490001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id VYAshTYy12EJWDd3 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 11 Nov 2015 11:28:02 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tABJRXrA031107 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 11 Nov 2015 19:27:34 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id tABJRXcH002988 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 11 Nov 2015 19:27:33 GMT Received: from abhmp0008.oracle.com (abhmp0008.oracle.com [141.146.116.14]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id tABJRWpD020113; Wed, 11 Nov 2015 19:27:32 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 11 Nov 2015 11:27:32 -0800 Subject: [PATCH 09/11] xfs: test xfs-specific reflink pieces From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 09/11] xfs: test xfs-specific reflink pieces To: hch@infradead.org, david@fromorbit.com, darrick.wong@oracle.com Cc: fstests@vger.kernel.org, xfs@oss.sgi.com, tao.peng@primarydata.com, linux-ext4@vger.kernel.org, Anna.Schumaker@netapp.com, linux-btrfs@vger.kernel.org Date: Wed, 11 Nov 2015 11:27:30 -0800 Message-ID: <20151111192730.15056.19977.stgit@birch.djwong.org> In-Reply-To: <20151111192628.15056.6451.stgit@birch.djwong.org> References: <20151111192628.15056.6451.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1447270082 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/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=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24309 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Check that growfs and xfs_fsr still work properly on reflinked fses. Signed-off-by: Darrick J. Wong --- tests/xfs/800 | 79 ++++++++++++++++++++++++++++ tests/xfs/800.out | 6 ++ tests/xfs/801 | 148 +++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/xfs/801.out | 27 ++++++++++ tests/xfs/802 | 87 +++++++++++++++++++++++++++++++ tests/xfs/802.out | 6 ++ tests/xfs/803 | 109 +++++++++++++++++++++++++++++++++++++++ tests/xfs/803.out | 13 +++++ tests/xfs/804 | 77 ++++++++++++++++++++++++++++ tests/xfs/804.out | 0 tests/xfs/group | 5 ++ 11 files changed, 557 insertions(+) create mode 100755 tests/xfs/800 create mode 100644 tests/xfs/800.out create mode 100755 tests/xfs/801 create mode 100644 tests/xfs/801.out create mode 100755 tests/xfs/802 create mode 100644 tests/xfs/802.out create mode 100755 tests/xfs/803 create mode 100644 tests/xfs/803.out create mode 100755 tests/xfs/804 create mode 100644 tests/xfs/804.out diff --git a/tests/xfs/800 b/tests/xfs/800 new file mode 100755 index 0000000..d9fe5b4 --- /dev/null +++ b/tests/xfs/800 @@ -0,0 +1,79 @@ +#! /bin/bash +# FS QA Test No. 800 +# +# Tests xfs_growfs on a reflinked filesystem +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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/reflink + +# real QA test starts here +_supported_os Linux +_supported_fs xfs +_require_scratch_reflink +_require_cp_reflink + +echo "Format and mount" +_scratch_mkfs -d size=$((2 * 4096 * 4096)) -l size=4194304 > "$seqres.full" 2>&1 +_scratch_mount >> "$seqres.full" 2>&1 + +TESTDIR="$SCRATCH_MNT/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original file and reflink to copy1, copy2" +BLKSZ="$(stat -f "$TESTDIR" -c '%S')" +_pwrite_byte 0x61 0 $((BLKSZ * 14 + 71)) "$TESTDIR/original" >> "$seqres.full" +_cp_reflink "$TESTDIR/original" "$TESTDIR/copy1" +_cp_reflink "$TESTDIR/copy1" "$TESTDIR/copy2" + +echo "Grow fs" +"$XFS_GROWFS_PROG" "$SCRATCH_MNT" 2>&1 | _filter_growfs >> "$seqres.full" +_scratch_remount + +echo "Create more reflink copies" +_cp_reflink "$TESTDIR/original" "$TESTDIR/copy3" + +xfs_info "$SCRATCH_MNT" >> "$seqres.full" + +echo "Check scratch fs" +umount "$SCRATCH_MNT" +_check_scratch_fs + +# success, all done +status=0 +exit diff --git a/tests/xfs/800.out b/tests/xfs/800.out new file mode 100644 index 0000000..73d4f71 --- /dev/null +++ b/tests/xfs/800.out @@ -0,0 +1,6 @@ +QA output created by 800 +Format and mount +Create the original file and reflink to copy1, copy2 +Grow fs +Create more reflink copies +Check scratch fs diff --git a/tests/xfs/801 b/tests/xfs/801 new file mode 100755 index 0000000..172fb29 --- /dev/null +++ b/tests/xfs/801 @@ -0,0 +1,148 @@ +#! /bin/bash +# FS QA Test No. 801 +# +# Ensure that xfs_fsr un-reflinks files while defragmenting +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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/reflink + +# real QA test starts here +_supported_os Linux +_supported_fs xfs +_require_scratch_reflink +_require_cp_reflink + +echo "Format and mount" +_scratch_mkfs > "$seqres.full" 2>&1 +_scratch_mount >> "$seqres.full" 2>&1 + +TESTDIR="$SCRATCH_MNT/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" +FREE_BLOCKS0=$(stat -f "$TESTDIR" -c '%f') + +echo "Create the original file and reflink to file2, file3" +BLKS=2000 +MARGIN=100 +BLKSZ=65536 +REAL_BLKSZ="$(stat -f $TESTDIR -c '%S')" +BLKSZ_FACTOR=$((BLKSZ / REAL_BLKSZ)) +_pwrite_byte 0x61 0 $((BLKS * BLKSZ)) "$TESTDIR/file1" >> "$seqres.full" +_cp_reflink "$TESTDIR/file1" "$TESTDIR/file2" +_cp_reflink "$TESTDIR/file2" "$TESTDIR/file3" +_cp_reflink "$TESTDIR/file3" "$TESTDIR/file4" +_test_remount +FREE_BLOCKS1=$(stat -f "$TESTDIR" -c '%f') + +md5sum "$TESTDIR/file1" | _filter_scratch +md5sum "$TESTDIR/file2" | _filter_scratch +md5sum "$TESTDIR/file3" | _filter_scratch +md5sum "$TESTDIR/file4" | _filter_scratch + +C01=$(_md5_checksum "$TESTDIR/file1") +C02=$(_md5_checksum "$TESTDIR/file2") +C03=$(_md5_checksum "$TESTDIR/file3") +C04=$(_md5_checksum "$TESTDIR/file4") + +echo "CoW the reflink copies" +_pwrite_byte 0x62 $BLKSZ $BLKSZ "$TESTDIR/file2" >> "$seqres.full" +_pwrite_byte 0x63 $(( BLKSZ * (BLKS - 1) )) $BLKSZ "$TESTDIR/file3" >> "$seqres.full" +_test_remount +FREE_BLOCKS2=$(stat -f "$TESTDIR" -c '%f') + +md5sum "$TESTDIR/file1" | _filter_scratch +md5sum "$TESTDIR/file2" | _filter_scratch +md5sum "$TESTDIR/file3" | _filter_scratch +md5sum "$TESTDIR/file4" | _filter_scratch + +C11=$(_md5_checksum "$TESTDIR/file1") +C12=$(_md5_checksum "$TESTDIR/file2") +C13=$(_md5_checksum "$TESTDIR/file3") +C14=$(_md5_checksum "$TESTDIR/file4") + +echo "Defragment" +lsattr -l "$TESTDIR/" | _filter_scratch +xfs_fsr -v -d "$TESTDIR/file1" >> "$seqres.full" +xfs_fsr -v -d "$TESTDIR/file2" >> "$seqres.full" # fsr probably breaks the link +xfs_fsr -v -d "$TESTDIR/file3" >> "$seqres.full" # fsr probably breaks the link +xfs_fsr -v -d "$TESTDIR/file4" >> "$seqres.full" # fsr probably ignores this file +_test_remount +FREE_BLOCKS3=$(stat -f "$TESTDIR" -c '%f') + +md5sum "$TESTDIR/file1" | _filter_scratch +md5sum "$TESTDIR/file2" | _filter_scratch +md5sum "$TESTDIR/file3" | _filter_scratch +md5sum "$TESTDIR/file4" | _filter_scratch + +C21=$(_md5_checksum "$TESTDIR/file1") +C22=$(_md5_checksum "$TESTDIR/file2") +C23=$(_md5_checksum "$TESTDIR/file3") +C24=$(_md5_checksum "$TESTDIR/file4") + +echo "Check files" +test $C01 = $C02 || echo "Files 1-2 do not match" +test $C01 = $C03 || echo "Files 1-3 do not match" +test $C01 = $C04 || echo "Files 1-4 do not match" +test $C02 = $C03 || echo "Files 2-3 do not match" +test $C02 = $C04 || echo "Files 2-4 do not match" +test $C03 = $C04 || echo "Files 3-4 do not match" + +test $C01 = $C11 || echo "File1 should not be different after CoW" +test $C02 != $C12 || echo "File2 should be different after CoW" +test $C03 != $C13 || echo "File3 should be different after CoW" +test $C04 = $C14 || echo "File4 should not be different after CoW" + +test $C11 = $C21 || echo "File1 changed by defrag" +test $C12 = $C22 || echo "File2 changed by defrag" +test $C13 = $C23 || echo "File3 changed by defrag" +test $C14 = $C24 || echo "File4 changed by defrag" + +#echo $FREE_BLOCKS0 $FREE_BLOCKS1 $FREE_BLOCKS2 $FREE_BLOCKS3 + +_within_tolerance "free blocks after creating some reflink copies" $FREE_BLOCKS1 $((FREE_BLOCKS0 - (BLKS * BLKSZ_FACTOR) )) $MARGIN -v +_within_tolerance "free blocks after CoW some reflink copies" $FREE_BLOCKS2 $((FREE_BLOCKS1 - 2)) $MARGIN -v +_within_tolerance "free blocks after defragging all reflink copies" $FREE_BLOCKS3 $((FREE_BLOCKS2 - (BLKS * 2 * BLKSZ_FACTOR))) $MARGIN -v +_within_tolerance "free blocks after all tests" $FREE_BLOCKS3 $((FREE_BLOCKS0 - (BLKS * 3 * BLKSZ_FACTOR))) $MARGIN -v + +echo "Check scratch fs" +umount "$SCRATCH_MNT" +_check_scratch_fs + +# success, all done +status=0 +exit diff --git a/tests/xfs/801.out b/tests/xfs/801.out new file mode 100644 index 0000000..4733f18 --- /dev/null +++ b/tests/xfs/801.out @@ -0,0 +1,27 @@ +QA output created by 801 +Format and mount +Create the original file and reflink to file2, file3 +b81534f439aac5c34ce3ed60a03eba70 SCRATCH_MNT/test-801/file1 +b81534f439aac5c34ce3ed60a03eba70 SCRATCH_MNT/test-801/file2 +b81534f439aac5c34ce3ed60a03eba70 SCRATCH_MNT/test-801/file3 +b81534f439aac5c34ce3ed60a03eba70 SCRATCH_MNT/test-801/file4 +CoW the reflink copies +b81534f439aac5c34ce3ed60a03eba70 SCRATCH_MNT/test-801/file1 +c650f1cf6c9f07b22e3e21ec7d49ded5 SCRATCH_MNT/test-801/file2 +56ed2f712c91e035adeeb26ed105a982 SCRATCH_MNT/test-801/file3 +b81534f439aac5c34ce3ed60a03eba70 SCRATCH_MNT/test-801/file4 +Defragment +SCRATCH_MNT/test-801/file1 --- +SCRATCH_MNT/test-801/file2 --- +SCRATCH_MNT/test-801/file3 --- +SCRATCH_MNT/test-801/file4 --- +b81534f439aac5c34ce3ed60a03eba70 SCRATCH_MNT/test-801/file1 +c650f1cf6c9f07b22e3e21ec7d49ded5 SCRATCH_MNT/test-801/file2 +56ed2f712c91e035adeeb26ed105a982 SCRATCH_MNT/test-801/file3 +b81534f439aac5c34ce3ed60a03eba70 SCRATCH_MNT/test-801/file4 +Check files +free blocks after creating some reflink copies is in range +free blocks after CoW some reflink copies is in range +free blocks after defragging all reflink copies is in range +free blocks after all tests is in range +Check scratch fs diff --git a/tests/xfs/802 b/tests/xfs/802 new file mode 100755 index 0000000..f63ef14 --- /dev/null +++ b/tests/xfs/802 @@ -0,0 +1,87 @@ +#! /bin/bash +# FS QA Test No. 802 +# +# Ensure that we can create enough distinct reflink entries to force creation +# of a multi-level refcount btree, and that metadump will successfully copy +# said block. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 / + umount "$SCRATCH_MNT" > /dev/null 2>&1 + rm -rf "$tmp".* "$TESTDIR" "$METADUMP_FILE" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_supported_fs xfs +_require_scratch_reflink + +rm -f "$seqres.full" + +_scratch_mkfs >/dev/null 2>&1 +_scratch_mount + +TESTDIR="$SCRATCH_MNT/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" +METADUMP_FILE="$TEST_DIR/${seq}_metadump" + +echo "Create the original file blocks" +BLKSZ="$(stat -f "$TESTDIR" -c '%S')" +NR_BLKS=$((4 * BLKSZ / 12)) +_pwrite_byte 0x61 0 $((BLKSZ * NR_BLKS)) "$TESTDIR/file1" >> "$seqres.full" + +echo "Reflink every other block" +seq 1 $((NR_BLKS / 2)) | while read nr; do + _reflink_range "$TESTDIR/file1" $((nr * 2 * BLKSZ)) \ + "$TESTDIR/file2" $((nr * 2 * BLKSZ)) $BLKSZ >> "$seqres.full" +done + +echo "Create metadump file" +_scratch_unmount +_scratch_metadump "$METADUMP_FILE" + +# Now restore the obfuscated one back and take a look around +echo "Restore metadump" +xfs_mdrestore "$METADUMP_FILE" "$TEST_DIR/image" +_mount -t $FSTYP "$TEST_DIR/image" "$SCRATCH_MNT" +umount "$SCRATCH_MNT" + +echo "Check restored fs" +_check_generic_filesystem "$METADUMP_FILE" + +# success, all done +status=0 +exit diff --git a/tests/xfs/802.out b/tests/xfs/802.out new file mode 100644 index 0000000..ad2ef03 --- /dev/null +++ b/tests/xfs/802.out @@ -0,0 +1,6 @@ +QA output created by 802 +Create the original file blocks +Reflink every other block +Create metadump file +Restore metadump +Check restored fs diff --git a/tests/xfs/803 b/tests/xfs/803 new file mode 100755 index 0000000..4aed2e1 --- /dev/null +++ b/tests/xfs/803 @@ -0,0 +1,109 @@ +#! /bin/bash +# FS QA Test No. 803 +# +# Create and populate an XFS filesystem, corrupt the refcount btree, +# then see how the kernel and xfs_repair deal with it. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015 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.* +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/attr +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_supported_fs xfs +_require_scratch_reflink +_require_cp_reflink +test -n "${FORCE_FUZZ}" || _require_scratch_xfs_crc + +rm -f "$seqres.full" + +echo "+ create scratch fs" +_scratch_mkfs_xfs > /dev/null + +echo "+ mount fs image" +_scratch_mount +blksz="$(stat -f -c '%s' "${SCRATCH_MNT}")" +agcount="$(xfs_info "${SCRATCH_MNT}" | grep agcount= | sed -e 's/^.*agcount=\([0-9]*\),.*$/\1/g')" + +echo "+ make some files" +_pwrite_byte 0x62 0 $((blksz * 64)) "${SCRATCH_MNT}/file0" >> "$seqres.full" +_pwrite_byte 0x61 0 $((blksz * 64)) "${SCRATCH_MNT}/file1" >> "$seqres.full" +_cp_reflink "${SCRATCH_MNT}/file0" "${SCRATCH_MNT}/file2" +_cp_reflink "${SCRATCH_MNT}/file1" "${SCRATCH_MNT}/file3" +umount "${SCRATCH_MNT}" + +echo "+ check fs" +_scratch_xfs_repair -n >> "$seqres.full" 2>&1 || \ + _fail "xfs_repair should not fail" + +echo "+ corrupt image" +seq 0 $((agcount - 1)) | while read ag; do + $XFS_DB_PROG -x -c "agf ${ag}" -c "agf ${ag}" -c "addr refcntroot" \ + -c "stack" -c "blocktrash -x 4096 -y 4096 -z -n 8 -3" \ + "${SCRATCH_DEV}" >> "$seqres.full" 2>&1 +done + +echo "+ mount image" +_scratch_mount + +echo "+ reflink more" +_cp_reflink "${SCRATCH_MNT}/file1" "${SCRATCH_MNT}/file4" 2> /dev/null && \ + _fail "should not be able to reflink with busted refcount btree" +umount "${SCRATCH_MNT}" + +echo "+ repair fs" +_scratch_xfs_repair >> "$seqres.full" 2>&1 +_scratch_xfs_repair >> "$seqres.full" 2>&1 + +echo "+ mount image (2)" +_scratch_mount + +echo "+ chattr -R -i" +chattr -R -f -i "${SCRATCH_MNT}/" + +echo "+ reflink more (2)" +_cp_reflink "${SCRATCH_MNT}/file1" "${SCRATCH_MNT}/file5" || \ + _fail "modified refcount tree" +umount "${SCRATCH_MNT}" + +echo "+ check fs (2)" +_scratch_xfs_repair -n >> "$seqres.full" 2>&1 || \ + _fail "xfs_repair should not fail" + +status=0 +exit diff --git a/tests/xfs/803.out b/tests/xfs/803.out new file mode 100644 index 0000000..582682d --- /dev/null +++ b/tests/xfs/803.out @@ -0,0 +1,13 @@ +QA output created by 803 ++ create scratch fs ++ mount fs image ++ make some files ++ check fs ++ corrupt image ++ mount image ++ reflink more ++ repair fs ++ mount image (2) ++ chattr -R -i ++ reflink more (2) ++ check fs (2) diff --git a/tests/xfs/804 b/tests/xfs/804 new file mode 100755 index 0000000..c46a7a0 --- /dev/null +++ b/tests/xfs/804 @@ -0,0 +1,77 @@ +#! /bin/bash +# FS QA Test No. 804 +# +# Ensure that we can't reflink realtime files. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 / + umount "$SCRATCH_MNT" > /dev/null 2>&1 + rm -rf "$tmp".* "$TESTDIR" "$METADUMP_FILE" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_supported_fs xfs +test -b "$TEST_RTDEV" || _notrun "Need TEST_RTDEV to run this test." +_require_scratch_reflink +_require_cp_reflink + +rm -f "$seqres.full" + +_scratch_mkfs -r rtdev=$TEST_RTDEV >/dev/null 2>&1 +_scratch_mount -o rtdev=$TEST_RTDEV + +TESTDIR="$SCRATCH_MNT/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original file blocks" +BLKSZ=65536 +touch "$TESTDIR/file1" +$XFS_IO_PROG -c 'chattr +r' "$TESTDIR/file1" >> "$seqres.full" +_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file1" >> "$seqres.full" + +echo "Reflink every other block" +_cp_reflink "$TESTDIR/file1" "$TESTDIR/file2" + +test -s "$TESTDIR/file2" && _fail "Should not be able to reflink a realtime file." + +echo "Check restored fs" +umount "$SCRATCH_MNT" +_check_scratch_fs + +# success, all done +status=0 +exit diff --git a/tests/xfs/804.out b/tests/xfs/804.out new file mode 100644 index 0000000..e69de29 diff --git a/tests/xfs/group b/tests/xfs/group index 8261f86..eccfb73 100644 --- a/tests/xfs/group +++ b/tests/xfs/group @@ -220,3 +220,8 @@ 303 auto quick quota 304 auto quick quota 305 auto quota +800 auto quick clone +801 auto quick clone +802 auto quick clone +803 fuzzers +804 auto quick clone From darrick.wong@oracle.com Wed Nov 11 13:28:15 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 4038729E1F for ; Wed, 11 Nov 2015 13:28:15 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id AA424AC001 for ; Wed, 11 Nov 2015 11:28:14 -0800 (PST) X-ASG-Debug-ID: 1447270091-04cb6c296a1251d0001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id vt89k7BugkesWE4O (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 11 Nov 2015 11:28:11 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tABJRkS4031321 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 11 Nov 2015 19:27:46 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id tABJRk42031163 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 11 Nov 2015 19:27:46 GMT Received: from abhmp0017.oracle.com (abhmp0017.oracle.com [141.146.116.23]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id tABJRkCe002302; Wed, 11 Nov 2015 19:27:46 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 11 Nov 2015 11:27:46 -0800 Subject: [PATCH 11/11] reflink: test that CoW writes fail when we're out of space From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 11/11] reflink: test that CoW writes fail when we're out of space To: hch@infradead.org, david@fromorbit.com, darrick.wong@oracle.com Cc: fstests@vger.kernel.org, xfs@oss.sgi.com, tao.peng@primarydata.com, linux-ext4@vger.kernel.org, Anna.Schumaker@netapp.com, linux-btrfs@vger.kernel.org Date: Wed, 11 Nov 2015 11:27:44 -0800 Message-ID: <20151111192744.15056.4781.stgit@birch.djwong.org> In-Reply-To: <20151111192628.15056.6451.stgit@birch.djwong.org> References: <20151111192628.15056.6451.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1447270091 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24309 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Ensure that copy-on-writing a reflinked file when there's no free disk space reflects the desired ENOSPC back to userspace during the write call. Tests the buffered IO, direct IO, and mmap write paths. Signed-off-by: Darrick J. Wong --- common/rc | 2 - tests/generic/842 | 107 ++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/842.out | 10 ++++ tests/generic/843 | 107 ++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/843.out | 10 ++++ tests/generic/844 | 109 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/844.out | 8 ++++ tests/generic/845 | 107 ++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/845.out | 10 ++++ tests/generic/group | 4 ++ 10 files changed, 473 insertions(+), 1 deletion(-) create mode 100755 tests/generic/842 create mode 100644 tests/generic/842.out create mode 100755 tests/generic/843 create mode 100644 tests/generic/843.out create mode 100755 tests/generic/844 create mode 100644 tests/generic/844.out create mode 100755 tests/generic/845 create mode 100644 tests/generic/845.out diff --git a/common/rc b/common/rc index c016673..474fa84 100644 --- a/common/rc +++ b/common/rc @@ -101,7 +101,7 @@ _mwrite_byte() { mmap_len="$4" file="$5" - "$XFS_IO_PROG" -f -c "mmap -rw 0 $mmap_len" -c "pwrite -S $pattern $offset $len" "$file" + "$XFS_IO_PROG" -f -c "mmap -rw 0 $mmap_len" -c "mwrite -S $pattern $offset $len" "$file" } # ls -l w/ selinux sometimes puts a dot at the end: diff --git a/tests/generic/842 b/tests/generic/842 new file mode 100755 index 0000000..5eda56b --- /dev/null +++ b/tests/generic/842 @@ -0,0 +1,107 @@ +#! /bin/bash +# FS QA Test No. 842 +# +# Reflink a file, use up the rest of the space, then try to observe ENOSPC +# while copy-on-writing the file via the page cache. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR1" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/attr +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_scratch_reflink +_require_cp_reflink + +rm -f "$seqres.full" + +echo "Format and mount" +_scratch_mkfs > "$seqres.full" 2>&1 +_scratch_mount >> "$seqres.full" 2>&1 + +TESTDIR="$SCRATCH_MNT/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Reformat with appropriate size" +BLKSZ="$(stat -f "$TESTDIR" -c '%S')" +NR_BLKS=10240 +umount "$SCRATCH_MNT" +SZ_BYTES=$((NR_BLKS * 8 * BLKSZ)) +if [ $SZ_BYTES -lt $((32 * 1048576)) ]; then + SZ_BYTES=$((32 * 1048576)) +fi +_scratch_mkfs_sized $SZ_BYTES >> "$seqres.full" 2>&1 +_scratch_mount >> "$seqres.full" 2>&1 +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create a big file and reflink it" +_pwrite_byte 0x61 0 $((BLKSZ * NR_BLKS)) "$TESTDIR/bigfile" >> "$seqres.full" 2>&1 +_cp_reflink "$TESTDIR/bigfile" "$TESTDIR/clonefile" +sync + +echo "Allocate the rest of the space" +NR_FREE="$(stat -f -c '%f' "$TESTDIR")" +touch "$TESTDIR/file0" "$TESTDIR/file1" +_pwrite_byte 0x61 0 $((BLKSZ * NR_FREE)) "$TESTDIR/eat_my_space" >> "$seqres.full" 2>&1 +sync + +echo "CoW the big file" +out="$(_pwrite_byte 0x62 0 $((BLKSZ * NR_BLKS)) "$TESTDIR/bigfile" 2>&1)" +echo "${out}" | grep -q "No space left on device" || echo "CoW should have failed with ENOSPC" +echo "${out}" >> "$seqres.full" 2>&1 +echo "${out}" + +echo "Remount and try CoW again" +_scratch_remount + +out="$(_pwrite_byte 0x62 0 $((BLKSZ * NR_BLKS)) "$TESTDIR/bigfile" 2>&1)" +echo "${out}" | grep -q "No space left on device" || echo "CoW should have failed with ENOSPC" +echo "${out}" >> "$seqres.full" 2>&1 +echo "${out}" + +#filefrag -v $TESTDIR/bigfile +#filefrag -v $TESTDIR/clonefile + +echo "Check scratch fs" +umount "$SCRATCH_MNT" +_check_scratch_fs + +# success, all done +status=0 +exit diff --git a/tests/generic/842.out b/tests/generic/842.out new file mode 100644 index 0000000..df58025 --- /dev/null +++ b/tests/generic/842.out @@ -0,0 +1,10 @@ +QA output created by 842 +Format and mount +Reformat with appropriate size +Create a big file and reflink it +Allocate the rest of the space +CoW the big file +pwrite64: No space left on device +Remount and try CoW again +pwrite64: No space left on device +Check scratch fs diff --git a/tests/generic/843 b/tests/generic/843 new file mode 100755 index 0000000..03dc570 --- /dev/null +++ b/tests/generic/843 @@ -0,0 +1,107 @@ +#! /bin/bash +# FS QA Test No. 843 +# +# Reflink a file that uses more than half of the space, then try to observe +# ENOSPC while copy-on-writing the file via the page cache. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR1" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/attr +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_scratch_reflink +_require_cp_reflink + +rm -f "$seqres.full" + +echo "Format and mount" +_scratch_mkfs > "$seqres.full" 2>&1 +_scratch_mount >> "$seqres.full" 2>&1 + +TESTDIR="$SCRATCH_MNT/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Reformat with appropriate size" +BLKSZ="$(stat -f "$TESTDIR" -c '%S')" +NR_BLKS=10240 +umount "$SCRATCH_MNT" +SZ_BYTES=$((NR_BLKS * 3 / 2 * BLKSZ)) +if [ $SZ_BYTES -lt $((32 * 1048576)) ]; then + SZ_BYTES=$((32 * 1048576)) +fi +_scratch_mkfs_sized $SZ_BYTES >> "$seqres.full" 2>&1 +_scratch_mount >> "$seqres.full" 2>&1 +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create a big file and reflink it" +_pwrite_byte 0x61 0 $((BLKSZ * NR_BLKS)) "$TESTDIR/bigfile" >> "$seqres.full" 2>&1 +_cp_reflink "$TESTDIR/bigfile" "$TESTDIR/clonefile" +sync + +echo "Allocate the rest of the space" +NR_FREE="$(stat -f -c '%f' "$TESTDIR")" +touch "$TESTDIR/file0" "$TESTDIR/file1" +_pwrite_byte 0x61 0 $((BLKSZ * NR_FREE)) "$TESTDIR/eat_my_space" >> "$seqres.full" 2>&1 +sync + +echo "CoW the big file" +out="$(_pwrite_byte 0x62 0 $((BLKSZ * NR_BLKS)) "$TESTDIR/bigfile" 2>&1)" +echo "${out}" | grep -q "No space left on device" || echo "CoW should have failed with ENOSPC" +echo "${out}" >> "$seqres.full" 2>&1 +echo "${out}" + +echo "Remount and try CoW again" +_scratch_remount + +out="$(_pwrite_byte 0x62 0 $((BLKSZ * NR_BLKS)) "$TESTDIR/bigfile" 2>&1)" +echo "${out}" | grep -q "No space left on device" || echo "CoW should have failed with ENOSPC" +echo "${out}" >> "$seqres.full" 2>&1 +echo "${out}" + +#filefrag -v $TESTDIR/bigfile +#filefrag -v $TESTDIR/clonefile + +echo "Check scratch fs" +umount "$SCRATCH_MNT" +_check_scratch_fs + +# success, all done +status=0 +exit diff --git a/tests/generic/843.out b/tests/generic/843.out new file mode 100644 index 0000000..43c1cf6 --- /dev/null +++ b/tests/generic/843.out @@ -0,0 +1,10 @@ +QA output created by 843 +Format and mount +Reformat with appropriate size +Create a big file and reflink it +Allocate the rest of the space +CoW the big file +pwrite64: No space left on device +Remount and try CoW again +pwrite64: No space left on device +Check scratch fs diff --git a/tests/generic/844 b/tests/generic/844 new file mode 100755 index 0000000..70bc235 --- /dev/null +++ b/tests/generic/844 @@ -0,0 +1,109 @@ +#! /bin/bash +# FS QA Test No. 844 +# +# Reflink a file, use up the rest of the space, then try to observe ENOSPC +# while copy-on-writing the file via mmap. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR1" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/attr +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_scratch_reflink +_require_cp_reflink + +rm -f "$seqres.full" + +echo "Format and mount" +_scratch_mkfs > "$seqres.full" 2>&1 +_scratch_mount >> "$seqres.full" 2>&1 + +TESTDIR="$SCRATCH_MNT/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Reformat with appropriate size" +BLKSZ="$(stat -f "$TESTDIR" -c '%S')" +NR_BLKS=10240 +umount "$SCRATCH_MNT" +SZ_BYTES=$((NR_BLKS * 8 * BLKSZ)) +if [ $SZ_BYTES -lt $((32 * 1048576)) ]; then + SZ_BYTES=$((32 * 1048576)) +fi +_scratch_mkfs_sized $SZ_BYTES >> "$seqres.full" 2>&1 +_scratch_mount >> "$seqres.full" 2>&1 +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create a big file and reflink it" +_pwrite_byte 0x61 0 $((BLKSZ * NR_BLKS)) "$TESTDIR/bigfile" >> "$seqres.full" 2>&1 +_cp_reflink "$TESTDIR/bigfile" "$TESTDIR/clonefile" +sync + +echo "Allocate the rest of the space" +NR_FREE="$(stat -f -c '%f' "$TESTDIR")" +touch "$TESTDIR/file0" "$TESTDIR/file1" +_pwrite_byte 0x61 0 $((BLKSZ * NR_FREE)) "$TESTDIR/eat_my_space" >> "$seqres.full" 2>&1 +sync + +echo "mmap CoW the big file" +out="$(_mwrite_byte 0x62 0 $((BLKSZ * NR_BLKS)) $((BLKSZ * NR_BLKS)) "$TESTDIR/bigfile" 2>&1)" +err="$?" +if [ "$err" -lt 128 ]; then + echo "mmap CoW should have failed with SIGBUS, got SIG$(kill -l $err)" +fi + +echo "Remount and try CoW again" +_scratch_remount + +out="$(_mwrite_byte 0x62 0 $((BLKSZ * NR_BLKS)) $((BLKSZ * NR_BLKS)) "$TESTDIR/bigfile" 2>&1)" +err="$?" +if [ "$err" -lt 128 ]; then + echo "mmap CoW should have failed with SIGBUS, got SIG$(kill -l $err)" +fi + +#filefrag -v $TESTDIR/bigfile +#filefrag -v $TESTDIR/clonefile + +echo "Check scratch fs" +umount "$SCRATCH_MNT" +_check_scratch_fs + +# success, all done +status=0 +exit diff --git a/tests/generic/844.out b/tests/generic/844.out new file mode 100644 index 0000000..130afc1 --- /dev/null +++ b/tests/generic/844.out @@ -0,0 +1,8 @@ +QA output created by 844 +Format and mount +Reformat with appropriate size +Create a big file and reflink it +Allocate the rest of the space +mmap CoW the big file +Remount and try CoW again +Check scratch fs diff --git a/tests/generic/845 b/tests/generic/845 new file mode 100755 index 0000000..5efaf38 --- /dev/null +++ b/tests/generic/845 @@ -0,0 +1,107 @@ +#! /bin/bash +# FS QA Test No. 845 +# +# Reflink a file, use up the rest of the space, then try to observe ENOSPC +# while copy-on-writing the file via direct-io. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR1" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/attr +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_scratch_reflink +_require_cp_reflink + +rm -f "$seqres.full" + +echo "Format and mount" +_scratch_mkfs > "$seqres.full" 2>&1 +_scratch_mount >> "$seqres.full" 2>&1 + +TESTDIR="$SCRATCH_MNT/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Reformat with appropriate size" +BLKSZ="$(stat -f "$TESTDIR" -c '%S')" +NR_BLKS=10240 +umount "$SCRATCH_MNT" +SZ_BYTES=$((NR_BLKS * 8 * BLKSZ)) +if [ $SZ_BYTES -lt $((32 * 1048576)) ]; then + SZ_BYTES=$((32 * 1048576)) +fi +_scratch_mkfs_sized $SZ_BYTES >> "$seqres.full" 2>&1 +_scratch_mount >> "$seqres.full" 2>&1 +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create a big file and reflink it" +_pwrite_byte 0x61 0 $((BLKSZ * NR_BLKS)) "$TESTDIR/bigfile" >> "$seqres.full" 2>&1 +_cp_reflink "$TESTDIR/bigfile" "$TESTDIR/clonefile" +sync + +echo "Allocate the rest of the space" +NR_FREE="$(stat -f -c '%f' "$TESTDIR")" +touch "$TESTDIR/file0" "$TESTDIR/file1" +_pwrite_byte 0x61 0 $((BLKSZ * NR_FREE)) "$TESTDIR/eat_my_space" >> "$seqres.full" 2>&1 +sync + +echo "CoW the big file" +out="$(_pwrite_byte 0x62 0 $((BLKSZ * NR_BLKS)) "$TESTDIR/bigfile" -d 2>&1)" +echo "${out}" | grep -q "No space left on device" || echo "CoW should have failed with ENOSPC" +echo "${out}" >> "$seqres.full" 2>&1 +echo "${out}" + +echo "Remount and try CoW again" +_scratch_remount + +out="$(_pwrite_byte 0x62 0 $((BLKSZ * NR_BLKS)) "$TESTDIR/bigfile" -d 2>&1)" +echo "${out}" | grep -q "No space left on device" || echo "CoW should have failed with ENOSPC" +echo "${out}" >> "$seqres.full" 2>&1 +echo "${out}" + +#filefrag -v $TESTDIR/bigfile +#filefrag -v $TESTDIR/clonefile + +echo "Check scratch fs" +umount "$SCRATCH_MNT" +_check_scratch_fs + +# success, all done +status=0 +exit diff --git a/tests/generic/845.out b/tests/generic/845.out new file mode 100644 index 0000000..d367a73 --- /dev/null +++ b/tests/generic/845.out @@ -0,0 +1,10 @@ +QA output created by 845 +Format and mount +Reformat with appropriate size +Create a big file and reflink it +Allocate the rest of the space +CoW the big file +pwrite64: No space left on device +Remount and try CoW again +pwrite64: No space left on device +Check scratch fs diff --git a/tests/generic/group b/tests/generic/group index eef608f..e184473 100644 --- a/tests/generic/group +++ b/tests/generic/group @@ -249,4 +249,8 @@ 839 auto quick clone 840 clone_stress 841 clone_stress +842 auto quick clone +843 auto quick clone +844 auto quick clone +845 auto quick clone 846 auto quick clone From sandeen@sandeen.net Wed Nov 11 15:53:07 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 5FB427FBF for ; Wed, 11 Nov 2015 15:53:07 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 285BB8F8033 for ; Wed, 11 Nov 2015 13:53:03 -0800 (PST) X-ASG-Debug-ID: 1447278776-04bdf03f03125d10001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id 9ELWKwXzqVuPTqWC for ; Wed, 11 Nov 2015 13:52:56 -0800 (PST) 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 75E9761F88CD for ; Wed, 11 Nov 2015 15:52:56 -0600 (CST) To: xfs@oss.sgi.com From: Eric Sandeen Subject: [PATCH] xfs_fsr: more selinux fixes X-Enigmail-Draft-Status: N1110 X-ASG-Orig-Subj: [PATCH] xfs_fsr: more selinux fixes Message-ID: <5643B8B7.9030708@sandeen.net> Date: Wed, 11 Nov 2015 15:52:55 -0600 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1447278776 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24313 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Commit: 1adfe5c xfs_fsr: fix SWAPEXT failures under selinux attempted to fix up the fork offset under selinux, where the temp file is created with a local attribute, but the target file has remote attributes; this can lead to a smaller data area in the temp inode, without enough room to swap extents from the target inode. I remedied this by pushing the temp file attribute to remote, but *only* if the target file's attr was also remote. However, I have a case from the field where the parent dir and the target file both have a context of: system_u:object_r:samba_share_t:s0 but new files created in the dir have a context of unconfined_u:object_r:samba_share_t:s0 This means the temp file has a smaller forkoff, and less space in the inode for data, so we fail to swap the extents between the two, because they don't fit. The following patch fixes this by allowing xfs_fsr to kick the tempfile's attr out of local format even if the target file's attr is local, if this will move the forkoff in the right direction. This does pass all our fsr xfstests, though I'm not sure we have any real coverage of fsr under selinux... The only functional change is the test at the very end of the patch; the rest is comments, ascii art, and removing the now-extraneous XFS_IOC_FSGETXATTRA ioctl. Signed-off-by: Eric Sandeen --- diff --git a/fsr/xfs_fsr.c b/fsr/xfs_fsr.c index c8ef18f..68b9819 100644 --- a/fsr/xfs_fsr.c +++ b/fsr/xfs_fsr.c @@ -1104,14 +1104,12 @@ fsr_setup_attr_fork( } continue; } else if (i == 0) { - struct fsxattr fsx; /* * First pass, and temp file already has an inline * xattr, probably due to selinux. * * It's *possible* that the temp file attr area - * is larger than the target file's, if the - * target file's attrs are not inline: + * is larger than the target file's: * * Target Temp * +-------+ 0 +-------+ 0 @@ -1121,28 +1119,18 @@ fsr_setup_attr_fork( * | | v-------v forkoff * | | | | * v-------v forkoff | Attr | local - * | Attr | ext/btree | | + * | Attr | | | * +-------+ +-------+ - * - * FSGETXATTRA will tell us nr of attr extents in - * target, if any. If none, it's local: */ - memset(&fsx, 0, sizeof(fsx)); - if (ioctl(fd, XFS_IOC_FSGETXATTRA, &fsx)) { - fsrprintf(_("FSGETXATTRA failed on target\n")); - return -1; - } - /* - * If target attr area is less than the temp's (diff < 0) - * and the target is not local, write a big attr to - * the temp file to knock the attr out of local format, - * to match the target. (This should actually *increase* - * the temp file's forkoffset when the attr moves out - * of the inode) + * If target attr area is less than the temp's + * (diff < 0), write a big attr to the temp file to knock + * the attr out of local format. + * (This should actually *increase* the temp file's + * forkoffset when the attr moves out of the inode) */ - if (diff < 0 && fsx.fsx_nextents > 0) { + if (diff < 0) { char val[2048]; memset(val, 'X', 2048); if (fsetxattr(tfd, name, val, 2048, 0)) { From sandeen@redhat.com Wed Nov 11 16:13:28 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 EFE7F7FB2 for ; Wed, 11 Nov 2015 16:13:27 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 51888AC003 for ; Wed, 11 Nov 2015 14:13:24 -0800 (PST) X-ASG-Debug-ID: 1447279998-04cbb02424133500001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 0X7gMgE0tKeaJaCE (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 11 Nov 2015 14:13:19 -0800 (PST) X-Barracuda-Envelope-From: sandeen@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 (Postfix) with ESMTPS id BD1E3C06C9C0 for ; Wed, 11 Nov 2015 22:13:18 +0000 (UTC) Received: from liberator.sandeen.net (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tABMDHY9022497 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Wed, 11 Nov 2015 17:13:18 -0500 To: xfs@oss.sgi.com From: Eric Sandeen Subject: [PATCH] xfs: print name of verifier if it fails Message-ID: <5643BD7D.4000307@redhat.com> X-ASG-Orig-Subj: [PATCH] xfs: print name of verifier if it fails Date: Wed, 11 Nov 2015 16:13:17 -0600 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit 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: 1447279999 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 This adds a name to each buf_ops structure, so that if a verifier fails we can print the type of verifier that failed it. Should be a slight debugging aid, I hope. Signed-off-by: Eric Sandeen --- diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 3479294..e1e7fe3 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -535,6 +535,7 @@ xfs_agfl_write_verify( } const struct xfs_buf_ops xfs_agfl_buf_ops = { + .name = "xfs_agfl", .verify_read = xfs_agfl_read_verify, .verify_write = xfs_agfl_write_verify, }; @@ -2339,6 +2340,7 @@ xfs_agf_write_verify( } const struct xfs_buf_ops xfs_agf_buf_ops = { + .name = "xfs_agf", .verify_read = xfs_agf_read_verify, .verify_write = xfs_agf_write_verify, }; diff --git a/fs/xfs/libxfs/xfs_alloc_btree.c b/fs/xfs/libxfs/xfs_alloc_btree.c index 90de071..eb8bbfe 100644 --- a/fs/xfs/libxfs/xfs_alloc_btree.c +++ b/fs/xfs/libxfs/xfs_alloc_btree.c @@ -379,6 +379,7 @@ xfs_allocbt_write_verify( } const struct xfs_buf_ops xfs_allocbt_buf_ops = { + .name = "xfs_allocbt", .verify_read = xfs_allocbt_read_verify, .verify_write = xfs_allocbt_write_verify, }; diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c index aa187f7..01a5ecf 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.c +++ b/fs/xfs/libxfs/xfs_attr_leaf.c @@ -328,6 +328,7 @@ xfs_attr3_leaf_read_verify( } const struct xfs_buf_ops xfs_attr3_leaf_buf_ops = { + .name = "xfs_attr3_leaf", .verify_read = xfs_attr3_leaf_read_verify, .verify_write = xfs_attr3_leaf_write_verify, }; diff --git a/fs/xfs/libxfs/xfs_attr_remote.c b/fs/xfs/libxfs/xfs_attr_remote.c index 5ab95ff..f3ed9bf 100644 --- a/fs/xfs/libxfs/xfs_attr_remote.c +++ b/fs/xfs/libxfs/xfs_attr_remote.c @@ -201,6 +201,7 @@ xfs_attr3_rmt_write_verify( } const struct xfs_buf_ops xfs_attr3_rmt_buf_ops = { + .name = "xfs_attr3_rmt", .verify_read = xfs_attr3_rmt_read_verify, .verify_write = xfs_attr3_rmt_write_verify, }; diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c index 6b0cf65..1637c37 100644 --- a/fs/xfs/libxfs/xfs_bmap_btree.c +++ b/fs/xfs/libxfs/xfs_bmap_btree.c @@ -720,6 +720,7 @@ xfs_bmbt_write_verify( } const struct xfs_buf_ops xfs_bmbt_buf_ops = { + .name = "xfs_bmbt", .verify_read = xfs_bmbt_read_verify, .verify_write = xfs_bmbt_write_verify, }; diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c index e89a0f8..097bf77 100644 --- a/fs/xfs/libxfs/xfs_da_btree.c +++ b/fs/xfs/libxfs/xfs_da_btree.c @@ -245,6 +245,7 @@ xfs_da3_node_read_verify( } const struct xfs_buf_ops xfs_da3_node_buf_ops = { + .name = "xfs_da3_node", .verify_read = xfs_da3_node_read_verify, .verify_write = xfs_da3_node_write_verify, }; diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c index 9c10e2b..aa17cb7 100644 --- a/fs/xfs/libxfs/xfs_dir2_block.c +++ b/fs/xfs/libxfs/xfs_dir2_block.c @@ -123,6 +123,7 @@ xfs_dir3_block_write_verify( } const struct xfs_buf_ops xfs_dir3_block_buf_ops = { + .name = "xfs_dir3_block", .verify_read = xfs_dir3_block_read_verify, .verify_write = xfs_dir3_block_write_verify, }; diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c index af71a84..725fc78 100644 --- a/fs/xfs/libxfs/xfs_dir2_data.c +++ b/fs/xfs/libxfs/xfs_dir2_data.c @@ -305,11 +305,13 @@ xfs_dir3_data_write_verify( } const struct xfs_buf_ops xfs_dir3_data_buf_ops = { + .name = "xfs_dir3_data", .verify_read = xfs_dir3_data_read_verify, .verify_write = xfs_dir3_data_write_verify, }; static const struct xfs_buf_ops xfs_dir3_data_reada_buf_ops = { + .name = "xfs_dir3_data_reada", .verify_read = xfs_dir3_data_reada_verify, .verify_write = xfs_dir3_data_write_verify, }; diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c index 3923e1f..b887fb2 100644 --- a/fs/xfs/libxfs/xfs_dir2_leaf.c +++ b/fs/xfs/libxfs/xfs_dir2_leaf.c @@ -245,11 +245,13 @@ xfs_dir3_leafn_write_verify( } const struct xfs_buf_ops xfs_dir3_leaf1_buf_ops = { + .name = "xfs_dir3_leaf1", .verify_read = xfs_dir3_leaf1_read_verify, .verify_write = xfs_dir3_leaf1_write_verify, }; const struct xfs_buf_ops xfs_dir3_leafn_buf_ops = { + .name = "xfs_dir3_leafn", .verify_read = xfs_dir3_leafn_read_verify, .verify_write = xfs_dir3_leafn_write_verify, }; diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c index 70b0cb2..63ee03d 100644 --- a/fs/xfs/libxfs/xfs_dir2_node.c +++ b/fs/xfs/libxfs/xfs_dir2_node.c @@ -150,6 +150,7 @@ xfs_dir3_free_write_verify( } const struct xfs_buf_ops xfs_dir3_free_buf_ops = { + .name = "xfs_dir3_free", .verify_read = xfs_dir3_free_read_verify, .verify_write = xfs_dir3_free_write_verify, }; diff --git a/fs/xfs/libxfs/xfs_dquot_buf.c b/fs/xfs/libxfs/xfs_dquot_buf.c index 5331b7f..11cefb2 100644 --- a/fs/xfs/libxfs/xfs_dquot_buf.c +++ b/fs/xfs/libxfs/xfs_dquot_buf.c @@ -282,6 +282,7 @@ xfs_dquot_buf_write_verify( } const struct xfs_buf_ops xfs_dquot_buf_ops = { + .name = "xfs_dquot", .verify_read = xfs_dquot_buf_read_verify, .verify_write = xfs_dquot_buf_write_verify, }; diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index 70c1db9..66d702e 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -2572,6 +2572,7 @@ xfs_agi_write_verify( } const struct xfs_buf_ops xfs_agi_buf_ops = { + .name = "xfs_agi", .verify_read = xfs_agi_read_verify, .verify_write = xfs_agi_write_verify, }; diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.c b/fs/xfs/libxfs/xfs_ialloc_btree.c index f39b285..6dd44f9 100644 --- a/fs/xfs/libxfs/xfs_ialloc_btree.c +++ b/fs/xfs/libxfs/xfs_ialloc_btree.c @@ -304,6 +304,7 @@ xfs_inobt_write_verify( } const struct xfs_buf_ops xfs_inobt_buf_ops = { + .name = "xfs_inobt", .verify_read = xfs_inobt_read_verify, .verify_write = xfs_inobt_write_verify, }; diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c index 268c00f..1b8d98a 100644 --- a/fs/xfs/libxfs/xfs_inode_buf.c +++ b/fs/xfs/libxfs/xfs_inode_buf.c @@ -132,11 +132,13 @@ xfs_inode_buf_write_verify( } const struct xfs_buf_ops xfs_inode_buf_ops = { + .name = "xfs_inode", .verify_read = xfs_inode_buf_read_verify, .verify_write = xfs_inode_buf_write_verify, }; const struct xfs_buf_ops xfs_inode_buf_ra_ops = { + .name = "xxfs_inode_ra", .verify_read = xfs_inode_buf_readahead_verify, .verify_write = xfs_inode_buf_write_verify, }; diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c index a0b071d..8a53eaa 100644 --- a/fs/xfs/libxfs/xfs_sb.c +++ b/fs/xfs/libxfs/xfs_sb.c @@ -679,11 +679,13 @@ xfs_sb_write_verify( } const struct xfs_buf_ops xfs_sb_buf_ops = { + .name = "xfs_sb", .verify_read = xfs_sb_read_verify, .verify_write = xfs_sb_write_verify, }; const struct xfs_buf_ops xfs_sb_quiet_buf_ops = { + .name = "xfs_sb_quiet", .verify_read = xfs_sb_quiet_read_verify, .verify_write = xfs_sb_write_verify, }; diff --git a/fs/xfs/libxfs/xfs_symlink_remote.c b/fs/xfs/libxfs/xfs_symlink_remote.c index cb6fd20..2e2c671 100644 --- a/fs/xfs/libxfs/xfs_symlink_remote.c +++ b/fs/xfs/libxfs/xfs_symlink_remote.c @@ -168,6 +168,7 @@ xfs_symlink_write_verify( } const struct xfs_buf_ops xfs_symlink_buf_ops = { + .name = "xfs_symlink", .verify_read = xfs_symlink_read_verify, .verify_write = xfs_symlink_write_verify, }; diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h index c79b717..c75721a 100644 --- a/fs/xfs/xfs_buf.h +++ b/fs/xfs/xfs_buf.h @@ -132,6 +132,7 @@ struct xfs_buf_map { struct xfs_buf_map (map) = { .bm_bn = (blkno), .bm_len = (numblk) }; struct xfs_buf_ops { + char *name; void (*verify_read)(struct xfs_buf *); void (*verify_write)(struct xfs_buf *); }; diff --git a/fs/xfs/xfs_error.c b/fs/xfs/xfs_error.c index 74d0e59..88693a9 100644 --- a/fs/xfs/xfs_error.c +++ b/fs/xfs/xfs_error.c @@ -164,9 +164,9 @@ xfs_verifier_error( { struct xfs_mount *mp = bp->b_target->bt_mount; - xfs_alert(mp, "Metadata %s detected at %pF, block 0x%llx", + xfs_alert(mp, "Metadata %s detected at %pF, %s block 0x%llx", bp->b_error == -EFSBADCRC ? "CRC error" : "corruption", - __return_address, bp->b_bn); + __return_address, bp->b_ops->name, bp->b_bn); xfs_alert(mp, "Unmount and run xfs_repair"); From david@fromorbit.com Wed Nov 11 16:13:38 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 65D7F29E06 for ; Wed, 11 Nov 2015 16:13:38 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 3D1D48F804B for ; Wed, 11 Nov 2015 14:13:38 -0800 (PST) X-ASG-Debug-ID: 1447280014-04cbb02424133560001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id nAFdfFTps3AZRiB9 for ; Wed, 11 Nov 2015 14:13:35 -0800 (PST) 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: A2ChCAAsvENWPIYELHleKAECgxBTb4ZdpCgCChIGgQ2KJYUshA0ZhXEEAoFLTQEBAQEBAQcBAQEBQT+EYhMcIxgkNAUlAwctiC3FJRmFdI5+BYdEhVeJLYUdiAGBY4RAgyWFJ4UKiFSCdB2Baio0hA4lgSMBAQE Received: from ppp121-44-4-134.lns20.syd4.internode.on.net (HELO dastard) ([121.44.4.134]) by ipmail04.adl6.internode.on.net with ESMTP; 12 Nov 2015 08:43:33 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1Zwde0-00038V-Vu; Thu, 12 Nov 2015 09:13:33 +1100 Date: Thu, 12 Nov 2015 09:13:32 +1100 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: updates for 4.4-rc1 Message-ID: <20151111221332.GI14311@dastard> X-ASG-Orig-Subj: [GIT PULL] xfs: updates for 4.4-rc1 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: 1447280014 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24313 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 XFS changes from the tag below? There is nothing really major here - the only significant addition is the per-mount operation statistics infrastructure. Otherwises there's various ACL, xattr, DAX, AIO and logging fixes, and a smattering of small cleanups and fixes elsewhere. -Dave. The following changes since commit 1f93e4a96c9109378204c147b3eec0d0e8100fde: Linux 4.3-rc2 (2015-09-20 14:32:34 -0700) are available in the git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/dgc/linux-xfs.git tags/xfs-for-linus-4.4 for you to fetch changes up to 4e14e49a91e18098fd8ef30743972e0c3cb727c1: Merge branch 'xfs-misc-fixes-for-4.4-3' into for-next (2015-11-10 10:20:48 +1100) ---------------------------------------------------------------- xfs: updates for 4.4-rc1 This update contains: o per-mount operational statistics in sysfs o fixes for concurrent aio append write submission o various logging fixes o detection of zeroed logs and invalid log sequence numbers on v5 filesystems o memory allocation failure message improvements o a bunch of xattr/ACL fixes o fdatasync optimisation o miscellaneous other fixes and cleanups ---------------------------------------------------------------- Andreas Gruenbacher (4): xfs: Validate the length of on-disk ACLs xfs: Plug memory leak in xfs_attrmulti_attr_set xfs: invalidate cached acl if set via ioctl xfs: Fix error path in xfs_get_acl Bill O'Donnell (7): xfs: create global stats and stats_clear in sysfs xfs: create symlink proc/fs/xfs/stat to sys/fs/xfs/stats xfs: remove unused procfs code xfs: consolidate sysfs ops xfs: pass xfsstats structures to handlers and macros xfs: per-filesystem stats in sysfs xfs: per-filesystem stats counter implementation Brian Foster (8): xfs: add missing ilock around dio write last extent alignment xfs: log local to remote symlink conversions correctly on v5 supers xfs: validate metadata LSNs against log on v5 superblocks xfs: always drain dio before extending aio write submission xfs: add an xfs_zero_eof() tracepoint xfs: pass total block res. as total xfs_bmapi_write() parameter xfs: invalidate cached acl if set directly via xattr xfs: fix log recovery op header validation assert Chris Mason (1): xfs: give all workqueues rescuer threads Dan Carpenter (1): xfs: fix an error code in xfs_fs_fill_super() Darrick J. Wong (1): xfs: don't leak uuid table on rmmod Dave Chinner (15): Merge branch 'xfs-logging-fixes' into for-next Merge branch 'xfs-io-fixes' into for-next Merge branch 'xfs-misc-fixes-for-4.4-1' into for-next xfs: stats are no longer dependent on CONFIG_PROC_FS Merge branch 'xfs-stats-fixes' into for-next xfs: fix inode size update overflow in xfs_map_direct() xfs: introduce BMAPI_ZERO for allocating zeroed extents xfs: Don't use unwritten extents for DAX xfs: DAX does not use IO completion callbacks xfs: add ->pfn_mkwrite support for DAX xfs: xfs_filemap_pmd_fault treats read faults as write faults xfs: optimise away log forces on timestamp updates for fdatasync Merge branch 'xfs-misc-fixes-for-4.4-2' into for-next Merge branch 'xfs-dax-updates' into for-next Merge branch 'xfs-misc-fixes-for-4.4-3' into for-next Eric Sandeen (3): xfs: avoid null *src in memcpy call in xlog_write xfs: more info from kmem deadlocks and high-level error msgs xfs: simplify /proc teardown & error handling Geliang Tang (1): libxfs: fix two comment typos Jan Tulak (2): xfs: prefix XATTR_LIST_MAX with XFS_ xfs: avoid dependency on Linux XATTR_SIZE_MAX Jiri Kosina (1): xfs: clear PF_NOFREEZE for xfsaild kthread Tetsuo Handa (1): xfs: Print name and pid when memory allocation loops Zhaohongjiang (1): cancel the setfilesize transation when io error happen fs/dax.c | 5 + fs/xfs/Makefile | 2 +- fs/xfs/kmem.c | 10 +- fs/xfs/libxfs/xfs_alloc.c | 30 ++++-- fs/xfs/libxfs/xfs_alloc.h | 8 +- fs/xfs/libxfs/xfs_attr.c | 6 +- fs/xfs/libxfs/xfs_attr_leaf.c | 3 + fs/xfs/libxfs/xfs_attr_remote.c | 2 +- fs/xfs/libxfs/xfs_bmap.c | 65 +++++++++---- fs/xfs/libxfs/xfs_bmap.h | 13 ++- fs/xfs/libxfs/xfs_btree.c | 21 +++- fs/xfs/libxfs/xfs_btree.h | 39 ++++---- fs/xfs/libxfs/xfs_da_btree.c | 4 + fs/xfs/libxfs/xfs_dir2.c | 6 +- fs/xfs/libxfs/xfs_dir2_block.c | 3 + fs/xfs/libxfs/xfs_dir2_data.c | 3 + fs/xfs/libxfs/xfs_dir2_leaf.c | 3 + fs/xfs/libxfs/xfs_dir2_node.c | 3 + fs/xfs/libxfs/xfs_format.h | 18 +++- fs/xfs/libxfs/xfs_fs.h | 10 ++ fs/xfs/libxfs/xfs_ialloc.c | 10 +- fs/xfs/libxfs/xfs_sb.c | 10 ++ fs/xfs/libxfs/xfs_symlink_remote.c | 7 ++ fs/xfs/xfs_acl.c | 14 ++- fs/xfs/xfs_acl.h | 4 +- fs/xfs/xfs_aops.c | 119 ++++++++++++----------- fs/xfs/xfs_aops.h | 3 +- fs/xfs/xfs_attr_list.c | 2 +- fs/xfs/xfs_bmap_util.c | 38 +++++++- fs/xfs/xfs_buf.c | 21 ++-- fs/xfs/xfs_dir2_readdir.c | 2 +- fs/xfs/xfs_dquot.c | 14 +-- fs/xfs/xfs_file.c | 114 +++++++++++++++++----- fs/xfs/xfs_icache.c | 18 ++-- fs/xfs/xfs_inode.c | 8 +- fs/xfs/xfs_inode_item.c | 1 + fs/xfs/xfs_inode_item.h | 1 + fs/xfs/xfs_ioctl.c | 23 +++-- fs/xfs/xfs_ioctl32.c | 2 +- fs/xfs/xfs_iomap.c | 70 ++++++++++---- fs/xfs/xfs_iops.c | 4 +- fs/xfs/xfs_linux.h | 7 ++ fs/xfs/xfs_log.c | 93 ++++++++++++++---- fs/xfs/xfs_log.h | 1 + fs/xfs/xfs_log_priv.h | 51 ++++++++++ fs/xfs/xfs_log_recover.c | 14 ++- fs/xfs/xfs_message.c | 7 ++ fs/xfs/xfs_mount.c | 21 +++- fs/xfs/xfs_mount.h | 5 + fs/xfs/xfs_pnfs.c | 5 + fs/xfs/xfs_qm.c | 14 +-- fs/xfs/xfs_stats.c | 93 +++++++++--------- fs/xfs/xfs_stats.h | 36 ++++--- fs/xfs/xfs_super.c | 57 ++++++++--- fs/xfs/xfs_sysctl.c | 15 +-- fs/xfs/xfs_sysfs.c | 185 +++++++++++++++++++++--------------- fs/xfs/xfs_sysfs.h | 1 + fs/xfs/xfs_trace.h | 2 + fs/xfs/xfs_trans.c | 6 +- fs/xfs/xfs_trans_ail.c | 13 +-- fs/xfs/xfs_trans_inode.c | 9 ++ fs/xfs/xfs_xattr.c | 31 +++++- 62 files changed, 994 insertions(+), 411 deletions(-) -- Dave Chinner david@fromorbit.com From sandeen@redhat.com Wed Nov 11 16:15:47 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 9E0B47FC1 for ; Wed, 11 Nov 2015 16:15:47 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 88AFC30404E for ; Wed, 11 Nov 2015 14:15:44 -0800 (PST) X-ASG-Debug-ID: 1447280142-04cb6c296d128900001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id lKDkHg5bO51nvjel (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 11 Nov 2015 14:15:43 -0800 (PST) X-Barracuda-Envelope-From: sandeen@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 (Postfix) with ESMTPS id 72D5446B for ; Wed, 11 Nov 2015 22:15:42 +0000 (UTC) Received: from liberator.sandeen.net (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tABMFfW1023885 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Wed, 11 Nov 2015 17:15:42 -0500 To: xfs@oss.sgi.com From: Eric Sandeen Subject: [PATCH] xfsprogs: print name of verifier if it fails Message-ID: <5643BE0D.5030805@redhat.com> X-ASG-Orig-Subj: [PATCH] xfsprogs: print name of verifier if it fails Date: Wed, 11 Nov 2015 16:15:41 -0600 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit 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: 1447280142 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 This adds a name to each buf_ops structure, so that if a verifier fails we can print the type of verifier that failed it. Should be a slight debugging aid, I hope. Signed-off-by: Eric Sandeen --- diff --git a/db/attr.c b/db/attr.c index 5e69100..e26ac67 100644 --- a/db/attr.c +++ b/db/attr.c @@ -570,6 +570,7 @@ xfs_attr3_db_write_verify( } const struct xfs_buf_ops xfs_attr3_db_buf_ops = { + .name = "xfs_attr3", .verify_read = xfs_attr3_db_read_verify, .verify_write = xfs_attr3_db_write_verify, }; diff --git a/db/dir2.c b/db/dir2.c index cc76662..533f705 100644 --- a/db/dir2.c +++ b/db/dir2.c @@ -1037,6 +1037,7 @@ xfs_dir3_db_write_verify( } const struct xfs_buf_ops xfs_dir3_db_buf_ops = { + .name = "xfs_dir3", .verify_read = xfs_dir3_db_read_verify, .verify_write = xfs_dir3_db_write_verify, }; diff --git a/db/metadump.c b/db/metadump.c index e503d6f..8cdcb92 100644 --- a/db/metadump.c +++ b/db/metadump.c @@ -221,7 +221,8 @@ write_buf( bp->b_ops->verify_write(bp); if (bp->b_error) { print_warning( - "obfuscation corrupted block at bno 0x%llx/0x%x", + "obfuscation corrupted block at %s bno 0x%llx/0x%x", + bp->b_ops->name, (long long)bp->b_bn, bp->b_bcount); } } diff --git a/libxfs/libxfs_io.h b/libxfs/libxfs_io.h index 38b4c6f..86b18a0 100644 --- a/libxfs/libxfs_io.h +++ b/libxfs/libxfs_io.h @@ -52,6 +52,7 @@ struct xfs_buf_map { struct xfs_buf_map (map) = { .bm_bn = (blkno), .bm_len = (numblk) }; struct xfs_buf_ops { + char *name; void (*verify_read)(struct xfs_buf *); void (*verify_write)(struct xfs_buf *); }; diff --git a/libxfs/rdwr.c b/libxfs/rdwr.c index c19070f..0804285 100644 --- a/libxfs/rdwr.c +++ b/libxfs/rdwr.c @@ -1075,8 +1075,9 @@ libxfs_writebufr(xfs_buf_t *bp) bp->b_ops->verify_write(bp); if (bp->b_error) { fprintf(stderr, - _("%s: write verifer failed on bno 0x%llx/0x%x\n"), - __func__, (long long)bp->b_bn, bp->b_bcount); + _("%s: write verifer failed on %s bno 0x%llx/0x%x\n"), + __func__, bp->b_ops->name, + (long long)bp->b_bn, bp->b_bcount); return bp->b_error; } } diff --git a/libxfs/util.c b/libxfs/util.c index 6192e6c..0609ba4 100644 --- a/libxfs/util.c +++ b/libxfs/util.c @@ -725,9 +725,9 @@ void xfs_verifier_error( struct xfs_buf *bp) { - xfs_alert(NULL, "Metadata %s detected at block 0x%llx/0x%x", + xfs_alert(NULL, "Metadata %s detected at %s block 0x%llx/0x%x", bp->b_error == -EFSBADCRC ? "CRC error" : "corruption", - bp->b_bn, BBTOB(bp->b_length)); + bp->b_ops->name, bp->b_bn, BBTOB(bp->b_length)); } /* diff --git a/libxfs/xfs_alloc.c b/libxfs/xfs_alloc.c index 95c8d44..b43655c 100644 --- a/libxfs/xfs_alloc.c +++ b/libxfs/xfs_alloc.c @@ -531,6 +531,7 @@ xfs_agfl_write_verify( } const struct xfs_buf_ops xfs_agfl_buf_ops = { + .name = "xfs_agfl", .verify_read = xfs_agfl_read_verify, .verify_write = xfs_agfl_write_verify, }; @@ -2335,6 +2336,7 @@ xfs_agf_write_verify( } const struct xfs_buf_ops xfs_agf_buf_ops = { + .name = "xfs_agf", .verify_read = xfs_agf_read_verify, .verify_write = xfs_agf_write_verify, }; diff --git a/libxfs/xfs_alloc_btree.c b/libxfs/xfs_alloc_btree.c index e60538a..f583bd1 100644 --- a/libxfs/xfs_alloc_btree.c +++ b/libxfs/xfs_alloc_btree.c @@ -377,6 +377,7 @@ xfs_allocbt_write_verify( } const struct xfs_buf_ops xfs_allocbt_buf_ops = { + .name = "xfs_allocbt", .verify_read = xfs_allocbt_read_verify, .verify_write = xfs_allocbt_write_verify, }; diff --git a/libxfs/xfs_attr_leaf.c b/libxfs/xfs_attr_leaf.c index bf473eb..1186cac 100644 --- a/libxfs/xfs_attr_leaf.c +++ b/libxfs/xfs_attr_leaf.c @@ -323,6 +323,7 @@ xfs_attr3_leaf_read_verify( } const struct xfs_buf_ops xfs_attr3_leaf_buf_ops = { + .name = "xfs_attr3_leaf", .verify_read = xfs_attr3_leaf_read_verify, .verify_write = xfs_attr3_leaf_write_verify, }; diff --git a/libxfs/xfs_attr_remote.c b/libxfs/xfs_attr_remote.c index 39ab350..95383e3 100644 --- a/libxfs/xfs_attr_remote.c +++ b/libxfs/xfs_attr_remote.c @@ -196,6 +196,7 @@ xfs_attr3_rmt_write_verify( } const struct xfs_buf_ops xfs_attr3_rmt_buf_ops = { + .name = "xfs_attr3_rmt", .verify_read = xfs_attr3_rmt_read_verify, .verify_write = xfs_attr3_rmt_write_verify, }; diff --git a/libxfs/xfs_bmap_btree.c b/libxfs/xfs_bmap_btree.c index f42bc2d..52c9c75 100644 --- a/libxfs/xfs_bmap_btree.c +++ b/libxfs/xfs_bmap_btree.c @@ -717,6 +717,7 @@ xfs_bmbt_write_verify( } const struct xfs_buf_ops xfs_bmbt_buf_ops = { + .name = "xfs_bmbt", .verify_read = xfs_bmbt_read_verify, .verify_write = xfs_bmbt_write_verify, }; diff --git a/libxfs/xfs_da_btree.c b/libxfs/xfs_da_btree.c index bdd60a0..bf5fe21 100644 --- a/libxfs/xfs_da_btree.c +++ b/libxfs/xfs_da_btree.c @@ -240,6 +240,7 @@ xfs_da3_node_read_verify( } const struct xfs_buf_ops xfs_da3_node_buf_ops = { + .name = "xfs_da3_node", .verify_read = xfs_da3_node_read_verify, .verify_write = xfs_da3_node_write_verify, }; diff --git a/libxfs/xfs_dir2_block.c b/libxfs/xfs_dir2_block.c index d7ba0e9..32bde31 100644 --- a/libxfs/xfs_dir2_block.c +++ b/libxfs/xfs_dir2_block.c @@ -119,6 +119,7 @@ xfs_dir3_block_write_verify( } const struct xfs_buf_ops xfs_dir3_block_buf_ops = { + .name = "xfs_dir3_block", .verify_read = xfs_dir3_block_read_verify, .verify_write = xfs_dir3_block_write_verify, }; diff --git a/libxfs/xfs_dir2_data.c b/libxfs/xfs_dir2_data.c index 37b3b68..6ae5cd2 100644 --- a/libxfs/xfs_dir2_data.c +++ b/libxfs/xfs_dir2_data.c @@ -302,11 +302,13 @@ xfs_dir3_data_write_verify( } const struct xfs_buf_ops xfs_dir3_data_buf_ops = { + .name = "xfs_dir3_data", .verify_read = xfs_dir3_data_read_verify, .verify_write = xfs_dir3_data_write_verify, }; static const struct xfs_buf_ops xfs_dir3_data_reada_buf_ops = { + .name = "xfs_dir3_data_reada", .verify_read = xfs_dir3_data_reada_verify, .verify_write = xfs_dir3_data_write_verify, }; diff --git a/libxfs/xfs_dir2_leaf.c b/libxfs/xfs_dir2_leaf.c index 77c2e65..f80d91f 100644 --- a/libxfs/xfs_dir2_leaf.c +++ b/libxfs/xfs_dir2_leaf.c @@ -242,11 +242,13 @@ xfs_dir3_leafn_write_verify( } const struct xfs_buf_ops xfs_dir3_leaf1_buf_ops = { + .name = "xfs_dir3_leaf1", .verify_read = xfs_dir3_leaf1_read_verify, .verify_write = xfs_dir3_leaf1_write_verify, }; const struct xfs_buf_ops xfs_dir3_leafn_buf_ops = { + .name = "xfs_dir3_leafn", .verify_read = xfs_dir3_leafn_read_verify, .verify_write = xfs_dir3_leafn_write_verify, }; diff --git a/libxfs/xfs_dir2_node.c b/libxfs/xfs_dir2_node.c index 689a3fd..224daa6 100644 --- a/libxfs/xfs_dir2_node.c +++ b/libxfs/xfs_dir2_node.c @@ -147,6 +147,7 @@ xfs_dir3_free_write_verify( } const struct xfs_buf_ops xfs_dir3_free_buf_ops = { + .name = "xfs_dir3_free", .verify_read = xfs_dir3_free_read_verify, .verify_write = xfs_dir3_free_write_verify, }; diff --git a/libxfs/xfs_dquot_buf.c b/libxfs/xfs_dquot_buf.c index 1a2546b..38f9703 100644 --- a/libxfs/xfs_dquot_buf.c +++ b/libxfs/xfs_dquot_buf.c @@ -290,6 +290,7 @@ xfs_dquot_buf_write_verify( } const struct xfs_buf_ops xfs_dquot_buf_ops = { + .name = "xfs_dquot", .verify_read = xfs_dquot_buf_read_verify, .verify_write = xfs_dquot_buf_write_verify, }; diff --git a/libxfs/xfs_ialloc.c b/libxfs/xfs_ialloc.c index d39f9b6..5039f4b 100644 --- a/libxfs/xfs_ialloc.c +++ b/libxfs/xfs_ialloc.c @@ -2566,6 +2566,7 @@ xfs_agi_write_verify( } const struct xfs_buf_ops xfs_agi_buf_ops = { + .name = "xfs_agi", .verify_read = xfs_agi_read_verify, .verify_write = xfs_agi_write_verify, }; diff --git a/libxfs/xfs_ialloc_btree.c b/libxfs/xfs_ialloc_btree.c index 09ffdb4..f592ad1 100644 --- a/libxfs/xfs_ialloc_btree.c +++ b/libxfs/xfs_ialloc_btree.c @@ -303,6 +303,7 @@ xfs_inobt_write_verify( } const struct xfs_buf_ops xfs_inobt_buf_ops = { + .name = "xfs_inobt", .verify_read = xfs_inobt_read_verify, .verify_write = xfs_inobt_write_verify, }; diff --git a/libxfs/xfs_inode_buf.c b/libxfs/xfs_inode_buf.c index 747a879..324715e 100644 --- a/libxfs/xfs_inode_buf.c +++ b/libxfs/xfs_inode_buf.c @@ -141,11 +141,13 @@ xfs_inode_buf_write_verify( } const struct xfs_buf_ops xfs_inode_buf_ops = { + .name = "xfs_inode", .verify_read = xfs_inode_buf_read_verify, .verify_write = xfs_inode_buf_write_verify, }; const struct xfs_buf_ops xfs_inode_buf_ra_ops = { + .name = "xxfs_inode_ra", .verify_read = xfs_inode_buf_readahead_verify, .verify_write = xfs_inode_buf_write_verify, }; diff --git a/libxfs/xfs_sb.c b/libxfs/xfs_sb.c index c293d68..78ad889 100644 --- a/libxfs/xfs_sb.c +++ b/libxfs/xfs_sb.c @@ -661,11 +661,13 @@ xfs_sb_write_verify( } const struct xfs_buf_ops xfs_sb_buf_ops = { + .name = "xfs_sb", .verify_read = xfs_sb_read_verify, .verify_write = xfs_sb_write_verify, }; const struct xfs_buf_ops xfs_sb_quiet_buf_ops = { + .name = "xfs_sb_quiet", .verify_read = xfs_sb_quiet_read_verify, .verify_write = xfs_sb_write_verify, }; diff --git a/libxfs/xfs_symlink_remote.c b/libxfs/xfs_symlink_remote.c index 647444a..fb9ece8 100644 --- a/libxfs/xfs_symlink_remote.c +++ b/libxfs/xfs_symlink_remote.c @@ -164,6 +164,7 @@ xfs_symlink_write_verify( } const struct xfs_buf_ops xfs_symlink_buf_ops = { + .name = "xfs_symlink", .verify_read = xfs_symlink_read_verify, .verify_write = xfs_symlink_write_verify, }; From penguin-kernel@I-love.SAKURA.ne.jp Wed Nov 11 16:19:26 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 0AC2B7F53 for ; Wed, 11 Nov 2015 16:19:26 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id E91BD8F8040 for ; Wed, 11 Nov 2015 14:19:25 -0800 (PST) X-ASG-Debug-ID: 1447280360-04cb6c296c128a50001-NocioJ Received: from www262.sakura.ne.jp (www262.sakura.ne.jp [202.181.97.72]) by cuda.sgi.com with ESMTP id Yy8QanXhxcCKOM7z (version=TLSv1 cipher=DHE-RSA-CAMELLIA256-SHA bits=256 verify=NO) for ; Wed, 11 Nov 2015 14:19:21 -0800 (PST) X-Barracuda-Envelope-From: penguin-kernel@I-love.SAKURA.ne.jp X-Barracuda-Apparent-Source-IP: 202.181.97.72 Received: from fsav409.sakura.ne.jp (fsav409.sakura.ne.jp [133.242.250.108]) by www262.sakura.ne.jp (8.14.5/8.14.5) with ESMTP id tABMJE8j096150; Thu, 12 Nov 2015 07:19:14 +0900 (JST) (envelope-from penguin-kernel@I-love.SAKURA.ne.jp) Received: from www262.sakura.ne.jp (202.181.97.72) by fsav409.sakura.ne.jp (F-Secure/fsigk_smtp/522/fsav409.sakura.ne.jp); Thu, 12 Nov 2015 07:19:14 +0900 (JST) X-Virus-Status: clean(F-Secure/fsigk_smtp/522/fsav409.sakura.ne.jp) Received: from AQUA (softbank126094077227.bbtec.net [126.94.77.227]) (authenticated bits=0) by www262.sakura.ne.jp (8.14.5/8.14.5) with ESMTP id tABMJEmG096146; Thu, 12 Nov 2015 07:19:14 +0900 (JST) (envelope-from penguin-kernel@I-love.SAKURA.ne.jp) To: arekm@maven.pl Cc: linux-mm@kvack.org, xfs@oss.sgi.com Subject: Re: memory reclaim problems on fs usage From: Tetsuo Handa X-ASG-Orig-Subj: Re: memory reclaim problems on fs usage References: <201511102313.36685.arekm@maven.pl> <5643658B.9090206@I-love.SAKURA.ne.jp> <201511111719.44035.arekm@maven.pl> In-Reply-To: <201511111719.44035.arekm@maven.pl> Message-Id: <201511120719.EBF35970.OtSOHOVFJMFQFL@I-love.SAKURA.ne.jp> X-Mailer: Winbiff [Version 2.51 PL2] X-Accept-Language: ja,en,zh Date: Thu, 12 Nov 2015 07:19:13 +0900 Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Barracuda-Connect: www262.sakura.ne.jp[202.181.97.72] X-Barracuda-Start-Time: 1447280361 X-Barracuda-Encrypted: DHE-RSA-CAMELLIA256-SHA X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24313 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header Arkadiusz Mi?kiewicz wrote: > This patch is against which tree? (tried 4.1, 4.2 and 4.3) Oops. Whitespace-damaged. This patch is for vanilla 4.1.2. Reposting with one condition corrected. if (!dump_target_pid) => if (dump_target_pid <= 0) --- fs/xfs/kmem.c | 10 ++- fs/xfs/xfs_buf.c | 3 +- include/linux/mmzone.h | 1 + include/linux/vmstat.h | 1 + mm/page_alloc.c | 217 +++++++++++++++++++++++++++++++++++++++++++++++++ mm/vmscan.c | 22 +++++ 6 files changed, 249 insertions(+), 5 deletions(-) diff --git a/fs/xfs/kmem.c b/fs/xfs/kmem.c index a7a3a63..535c136 100644 --- a/fs/xfs/kmem.c +++ b/fs/xfs/kmem.c @@ -55,8 +55,9 @@ kmem_alloc(size_t size, xfs_km_flags_t flags) return ptr; if (!(++retries % 100)) xfs_err(NULL, - "possible memory allocation deadlock in %s (mode:0x%x)", - __func__, lflags); + "%s(%u) possible memory allocation deadlock in %s (mode:0x%x)", + current->comm, current->pid, + __func__, lflags); congestion_wait(BLK_RW_ASYNC, HZ/50); } while (1); } @@ -120,8 +121,9 @@ kmem_zone_alloc(kmem_zone_t *zone, xfs_km_flags_t flags) return ptr; if (!(++retries % 100)) xfs_err(NULL, - "possible memory allocation deadlock in %s (mode:0x%x)", - __func__, lflags); + "%s(%u) possible memory allocation deadlock in %s (mode:0x%x)", + current->comm, current->pid, + __func__, lflags); congestion_wait(BLK_RW_ASYNC, HZ/50); } while (1); } diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index 1790b00..16322cb 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c @@ -354,7 +354,8 @@ retry: */ if (!(++retries % 100)) xfs_err(NULL, - "possible memory allocation deadlock in %s (mode:0x%x)", + "%s(%u) possible memory allocation deadlock in %s (mode:0x%x)", + current->comm, current->pid, __func__, gfp_mask); XFS_STATS_INC(xb_page_retries); diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 54d74f6..932a6d6 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -527,6 +527,7 @@ struct zone { ZONE_PADDING(_pad3_) /* Zone statistics */ atomic_long_t vm_stat[NR_VM_ZONE_STAT_ITEMS]; + unsigned long stat_last_updated[NR_VM_ZONE_STAT_ITEMS]; } ____cacheline_internodealigned_in_smp; enum zone_flags { diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h index 82e7db7..2488925 100644 --- a/include/linux/vmstat.h +++ b/include/linux/vmstat.h @@ -115,6 +115,7 @@ static inline void zone_page_state_add(long x, struct zone *zone, { atomic_long_add(x, &zone->vm_stat[item]); atomic_long_add(x, &vm_stat[item]); + zone->stat_last_updated[item] = jiffies; } static inline unsigned long global_page_state(enum zone_stat_item item) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 18490f3..35a46b4 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -61,6 +61,8 @@ #include #include #include +#include +#include #include #include @@ -2496,6 +2498,8 @@ __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order, } #endif /* CONFIG_COMPACTION */ +pid_t dump_target_pid; + /* Perform direct synchronous page reclaim */ static int __perform_reclaim(gfp_t gfp_mask, unsigned int order, @@ -2645,6 +2649,208 @@ bool gfp_pfmemalloc_allowed(gfp_t gfp_mask) return !!(gfp_to_alloc_flags(gfp_mask) & ALLOC_NO_WATERMARKS); } +static unsigned long kmallocwd_timeout = 10 * HZ; /* Scan interval. */ +static u8 memalloc_counter_active_index; /* Either 0 or 1. */ +static int memalloc_counter[2]; /* Number of tasks doing memory allocation. */ + +struct memalloc { + struct list_head list; /* Connected to memalloc_list. */ + struct task_struct *task; /* Iniatilized to current. */ + unsigned long start; /* Initialized to jiffies. */ + unsigned int order; + gfp_t gfp; + u8 index; /* Initialized to memalloc_counter_active_index. */ + u8 dumped; +}; + +static LIST_HEAD(memalloc_list); /* List of "struct memalloc".*/ +static DEFINE_SPINLOCK(memalloc_list_lock); /* Lock for memalloc_list. */ + +/* + * kmallocwd - A kernel thread for monitoring memory allocation stalls. + * + * @unused: Not used. + * + * This kernel thread does not terminate. + */ +static int kmallocwd(void *unused) +{ + struct memalloc *m; + struct task_struct *g, *p; + unsigned long now; + unsigned int sigkill_pending; + unsigned int memdie_pending; + unsigned int stalling_tasks; + u8 index; + pid_t pid; + + not_stalling: /* Healty case. */ + /* Switch active counter and wait for timeout duration. */ + index = memalloc_counter_active_index; + spin_lock(&memalloc_list_lock); + memalloc_counter_active_index ^= 1; + spin_unlock(&memalloc_list_lock); + schedule_timeout_interruptible(kmallocwd_timeout); + /* + * If memory allocations are working, the counter should remain 0 + * because tasks will be able to call both start_memalloc_timer() + * and stop_memalloc_timer() within timeout duration. + */ + if (likely(!memalloc_counter[index])) + goto not_stalling; + maybe_stalling: /* Maybe something is wrong. Let's check. */ + now = jiffies; + /* Count stalling tasks, dying and victim tasks. */ + sigkill_pending = 0; + memdie_pending = 0; + stalling_tasks = 0; + pid = 0; + spin_lock(&memalloc_list_lock); + list_for_each_entry(m, &memalloc_list, list) { + if (time_after(now - m->start, kmallocwd_timeout)) + stalling_tasks++; + } + spin_unlock(&memalloc_list_lock); + preempt_disable(); + rcu_read_lock(); + for_each_process_thread(g, p) { + if (test_tsk_thread_flag(p, TIF_MEMDIE)) + memdie_pending++; + if (fatal_signal_pending(p)) + sigkill_pending++; + } + rcu_read_unlock(); + preempt_enable(); + cond_resched(); + pr_warn("MemAlloc-Info: %u stalling task, %u dying task, %u victim task.\n", + stalling_tasks, sigkill_pending, memdie_pending); + /* Report stalling tasks, dying and victim tasks. */ + spin_lock(&memalloc_list_lock); + list_for_each_entry(m, &memalloc_list, list) { + if (time_before(now - m->start, kmallocwd_timeout)) + continue; + p = m->task; + pr_warn("MemAlloc: %s(%u) gfp=0x%x order=%u delay=%lu\n", + p->comm, p->pid, m->gfp, m->order, now - m->start); + } + spin_unlock(&memalloc_list_lock); + preempt_disable(); + rcu_read_lock(); + for_each_process_thread(g, p) { + u8 type = 0; + + if (test_tsk_thread_flag(p, TIF_MEMDIE)) + type |= 1; + if (fatal_signal_pending(p)) + type |= 2; + if (likely(!type)) + continue; + if (p->state & TASK_UNINTERRUPTIBLE) + type |= 4; + pr_warn("MemAlloc: %s(%u)%s%s%s\n", p->comm, p->pid, + (type & 4) ? " uninterruptible" : "", + (type & 2) ? " dying" : "", + (type & 1) ? " victim" : ""); + } + rcu_read_unlock(); + preempt_enable(); + cond_resched(); + /* + * Show traces of newly reported (or too long) stalling tasks. + * + * Show traces only once per 256 timeouts because their traces + * will likely be the same (e.g. cond_sched() or congestion_wait()) + * when they are stalling inside __alloc_pages_slowpath(). + */ + spin_lock(&memalloc_list_lock); + list_for_each_entry(m, &memalloc_list, list) { + if (time_before(now - m->start, kmallocwd_timeout) || + m->dumped++) + continue; + p = m->task; + sched_show_task(p); + debug_show_held_locks(p); + touch_nmi_watchdog(); + if (!pid) + pid = p->pid; + } + spin_unlock(&memalloc_list_lock); + /* + * Show traces of dying tasks (including victim tasks). + * + * Only dying tasks which are in trouble (e.g. blocked at unkillable + * locks held by memory allocating tasks) will be repeatedly shown. + * Therefore, we need to pay attention to tasks repeatedly shown here. + */ + preempt_disable(); + rcu_read_lock(); + for_each_process_thread(g, p) { + if (likely(!fatal_signal_pending(p))) + continue; + sched_show_task(p); + debug_show_held_locks(p); + touch_nmi_watchdog(); + } + rcu_read_unlock(); + preempt_enable(); + show_workqueue_state(); + if (dump_target_pid <= 0) + dump_target_pid = -pid; + /* Wait until next timeout duration. */ + schedule_timeout_interruptible(kmallocwd_timeout); + if (memalloc_counter[index]) + goto maybe_stalling; + goto not_stalling; + return 0; /* To suppress "no return statement" compiler warning. */ +} + +static int __init start_kmallocwd(void) +{ + if (kmallocwd_timeout) { + struct task_struct *task = kthread_run(kmallocwd, NULL, + "kmallocwd"); + BUG_ON(IS_ERR(task)); + } + return 0; +} +late_initcall(start_kmallocwd); + +static int __init kmallocwd_config(char *str) +{ + if (kstrtoul(str, 10, &kmallocwd_timeout) == 0) + kmallocwd_timeout = min(kmallocwd_timeout * HZ, + (unsigned long) LONG_MAX); + return 0; +} +__setup("kmallocwd=", kmallocwd_config); + +static void start_memalloc_timer(struct memalloc *m, const gfp_t gfp_mask, + const int order) +{ + if (!kmallocwd_timeout || m->task) + return; + m->task = current; + m->start = jiffies; + m->gfp = gfp_mask; + m->order = order; + m->dumped = 0; + spin_lock(&memalloc_list_lock); + m->index = memalloc_counter_active_index; + memalloc_counter[m->index]++; + list_add_tail(&m->list, &memalloc_list); + spin_unlock(&memalloc_list_lock); +} + +static void stop_memalloc_timer(struct memalloc *m) +{ + if (!m->task) + return; + spin_lock(&memalloc_list_lock); + memalloc_counter[m->index]--; + list_del(&m->list); + spin_unlock(&memalloc_list_lock); +} + static inline struct page * __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order, struct alloc_context *ac) @@ -2657,6 +2863,7 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order, enum migrate_mode migration_mode = MIGRATE_ASYNC; bool deferred_compaction = false; int contended_compaction = COMPACT_CONTENDED_NONE; + struct memalloc m = { .task = NULL }; /* * In the slowpath, we sanity check order to avoid ever trying to @@ -2678,6 +2885,9 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order, goto nopage; retry: + if (dump_target_pid == -current->pid) + dump_target_pid = -dump_target_pid; + if (!(gfp_mask & __GFP_NO_KSWAPD)) wake_all_kswapds(order, ac); @@ -2740,6 +2950,8 @@ retry: if (test_thread_flag(TIF_MEMDIE) && !(gfp_mask & __GFP_NOFAIL)) goto nopage; + start_memalloc_timer(&m, gfp_mask, order); + /* * Try direct compaction. The first pass is asynchronous. Subsequent * attempts after direct reclaim are synchronous @@ -2798,6 +3010,10 @@ retry: goto got_pg; /* Check if we should retry the allocation */ + if (dump_target_pid == current->pid) { + printk(KERN_INFO "did_some_progress=%lu\n", did_some_progress); + dump_target_pid = 0; + } pages_reclaimed += did_some_progress; if (should_alloc_retry(gfp_mask, order, did_some_progress, pages_reclaimed)) { @@ -2834,6 +3050,7 @@ retry: nopage: warn_alloc_failed(gfp_mask, order, NULL); got_pg: + stop_memalloc_timer(&m); return page; } diff --git a/mm/vmscan.c b/mm/vmscan.c index 1a17bd7..c449371 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -2432,6 +2432,8 @@ static inline bool compaction_ready(struct zone *zone, int order) return watermark_ok; } +extern pid_t dump_target_pid; + /* * This is the direct reclaim path, for page-allocating processes. We only * try to reclaim pages from zones which will satisfy the caller's allocation @@ -2533,7 +2535,27 @@ static bool shrink_zones(struct zonelist *zonelist, struct scan_control *sc) if (global_reclaim(sc) && !reclaimable && zone_reclaimable(zone)) + { + if (dump_target_pid == current->pid) { + unsigned long rec = zone_reclaimable_pages(zone); + unsigned long free = zone_page_state(zone, NR_FREE_PAGES); + unsigned long min = min_wmark_pages(zone); + unsigned long scanned = zone_page_state(zone, NR_PAGES_SCANNED); + unsigned long now = jiffies; + unsigned long rec2 = zone_page_state_snapshot(zone, NR_ACTIVE_FILE) + + zone_page_state_snapshot(zone, NR_INACTIVE_FILE); + unsigned long free2 = zone_page_state_snapshot(zone, NR_FREE_PAGES); + unsigned long scanned2 = zone_page_state_snapshot(zone, NR_PAGES_SCANNED); + + printk(KERN_INFO "%s zone_reclaimable: reclaim:%lu(%lu,%lu,%ld) free:%lu(%lu,%ld) min:%lu pages_scanned:%lu(%lu,%ld) prio:%d\n", + zone->name, rec, now - zone->stat_last_updated[NR_ACTIVE_FILE], + now - zone->stat_last_updated[NR_INACTIVE_FILE], rec - rec2, + free, now - zone->stat_last_updated[NR_FREE_PAGES], free - free2, + min, scanned, now - zone->stat_last_updated[NR_PAGES_SCANNED], + scanned - scanned2, sc->priority); + } reclaimable = true; + } } /* -- 1.8.3.1 From david@fromorbit.com Wed Nov 11 18:42:11 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 178767F37 for ; Wed, 11 Nov 2015 18:42:11 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 13A118F8049 for ; Wed, 11 Nov 2015 16:42:02 -0800 (PST) X-ASG-Debug-ID: 1447288900-04cbb02422139a90001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id JeR0pBiFIXqNJklF for ; Wed, 11 Nov 2015 16:41:41 -0800 (PST) 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: A2DNCAB930NWPIYELHleKAECgxBTb6sjEgaLMok5I4VnBAICgTtNAQEBAQEBBwEBAQFAAT+ENQEBBDocIxAIAxgJJQ8FJQMHGhOILQ7ETAEBCAIhGYV0hUWCcYFRhHcFlkiFHYgBgWOWeINyhHsqNAGFVQEBAQ Received: from ppp121-44-4-134.lns20.syd4.internode.on.net (HELO dastard) ([121.44.4.134]) by ipmail04.adl6.internode.on.net with ESMTP; 12 Nov 2015 11:11:16 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1Zwfww-0003OK-Uw; Thu, 12 Nov 2015 11:41:15 +1100 Date: Thu, 12 Nov 2015 11:41:14 +1100 From: Dave Chinner To: "Darrick J. Wong" Cc: Christoph Hellwig , fstests@vger.kernel.org, linux-ext4@vger.kernel.org, Anna.Schumaker@netapp.com, linux-btrfs@vger.kernel.org, xfs@oss.sgi.com Subject: Re: [RFCv3 00/12] xfstests: test the btrfs/xfs reflink/dedupe ioctls Message-ID: <20151112004114.GO19199@dastard> X-ASG-Orig-Subj: Re: [RFCv3 00/12] xfstests: test the btrfs/xfs reflink/dedupe ioctls References: <20151007051257.3260.73072.stgit@birch.djwong.org> <20151109075926.GB17974@infradead.org> <20151109184913.GB3255@birch.djwong.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151109184913.GB3255@birch.djwong.org> 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: 1447288900 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24316 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header On Mon, Nov 09, 2015 at 10:49:13AM -0800, Darrick J. Wong wrote: > On Sun, Nov 08, 2015 at 11:59:26PM -0800, Christoph Hellwig wrote: > > On Tue, Oct 06, 2015 at 10:12:57PM -0700, Darrick J. Wong wrote: > > > * I don't have any interesting NFS/CIFS setups for test. :( > > > > I have a banrch with client and server support for NFSv4.2 CLONE > > support: > > > > http://git.infradead.org/users/hch/pnfs.git/shortlog/refs/heads/reflink+clone > > > > For now you want to use btrfs on the server, as using reflinks on XFS > > seems to be a little unstable over NFS. > > I found a few more bugs in the kernel-side implementation, which might explain > that. I'm about to start working on making CoW less crappy, but I'll push all > the patches out to github. (I wasn't planning on patchbombing again until > December.) > > > > If you're going to start using this mess, you probably ought to just > > > pull from my github trees for kernel[1], xfsprogs[2], and xfstests[3]. > > > They should just work with the btrfs that's in 4.3. > > > > > > Comments and questions are, as always, welcome. > > > > Any reason the groups are called clone? I don't really have an opinion > > on clone vs reflink but given that the xfs_io command is reflink I'd > > rather be consistent. > > The existing btrfs reflink tests were tagged in the 'clone' group prior to my > patchset. > > > Otherwise I'd say get it merged ASAP, we can still fix up various > > details later. > > I'll merge your patch and repost the whole pile of tests. I'm almost ready to > send a pile of updates for the XFS on-disk structure document which add stuff > about the v5 format, rmapbt, and reflink. Darrick, can you renumber the xfstests against what is currently at the head of the repo? If both you an Christoph need them working, you may as well both patch against the main xfstests repo... Cheers, Dave. -- Dave Chinner david@fromorbit.com From sandeen@redhat.com Wed Nov 11 20:09:02 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 4747C7F4E for ; Wed, 11 Nov 2015 20:09:02 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id BE156AC002 for ; Wed, 11 Nov 2015 18:08:55 -0800 (PST) X-ASG-Debug-ID: 1447294130-04bdf03f0312a460001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id ql00IiG8jmWvamcW (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 11 Nov 2015 18:08:50 -0800 (PST) X-Barracuda-Envelope-From: sandeen@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 (Postfix) with ESMTPS id 72EBBC05E140 for ; Thu, 12 Nov 2015 02:08:50 +0000 (UTC) Received: from liberator.sandeen.net (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAC28nX1025358 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Wed, 11 Nov 2015 21:08:49 -0500 To: xfs@oss.sgi.com From: Eric Sandeen Subject: [PATCH] xfs_repair: print XFS_WANT_CORRUPTED info with -vvv X-Enigmail-Draft-Status: N1110 X-ASG-Orig-Subj: [PATCH] xfs_repair: print XFS_WANT_CORRUPTED info with -vvv Message-ID: <5643F4B1.40500@redhat.com> Date: Wed, 11 Nov 2015 20:08:49 -0600 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit 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: 1447294130 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 In the kernel, the XFS_WANT_CORRUPTED_* macros print the caller information via XFS_ERROR_REPORT, but in userspace this is silenced, because i.e. xfs_repair's job is to find and fix corruption, not to complain loudly about it. However, there are times when we would like to know if we've hit an unexpected corruption point. To that end, make "xfs_repair -vvv" enable noisiness from these macros, so that they will print the function and line of the caller. Signed-off-by: Eric Sandeen --- diff --git a/include/xfs_mount.h b/include/xfs_mount.h index 5ec6866..67f3b05 100644 --- a/include/xfs_mount.h +++ b/include/xfs_mount.h @@ -143,6 +143,7 @@ typedef struct xfs_perag { #define LIBXFS_MOUNT_32BITINOOPT 0x0004 #define LIBXFS_MOUNT_COMPAT_ATTR 0x0008 #define LIBXFS_MOUNT_ATTR2 0x0010 +#define LIBXFS_MOUNT_WANT_CORRUPTED 0x0020 #define LIBXFS_BHASHSIZE(sbp) (1<<10) diff --git a/libxfs/libxfs_priv.h b/libxfs/libxfs_priv.h index 9135aac..0f4d3e5 100644 --- a/libxfs/libxfs_priv.h +++ b/libxfs/libxfs_priv.h @@ -147,10 +147,25 @@ enum ce { CE_DEBUG, CE_CONT, CE_NOTE, CE_WARN, CE_ALERT, CE_PANIC }; #define XFS_TRANS_RESERVE_QUOTA_NBLKS(mp,tp,ip,nblks,ninos,fl) 0 #define XFS_TRANS_UNRESERVE_QUOTA_NBLKS(mp,tp,ip,nblks,ninos,fl) 0 #define XFS_TEST_ERROR(expr,a,b,c) ( expr ) -#define XFS_WANT_CORRUPTED_GOTO(mp, expr, l) \ - { (mp) = (mp); if (!(expr)) { error = -EFSCORRUPTED; goto l; } } -#define XFS_WANT_CORRUPTED_RETURN(mp, expr) \ - { (mp) = (mp); if (!(expr)) { return -EFSCORRUPTED; } } +#define XFS_WANT_CORRUPTED_GOTO(mp, expr, l) \ +{ \ + if (!(expr)) { \ + if ((mp)->m_flags & LIBXFS_MOUNT_WANT_CORRUPTED) \ + printf("WANT_CORRUPTED_GOTO at %s:%d\n", \ + __func__, __LINE__); \ + error = -EFSCORRUPTED; \ + goto l; \ + } \ +} +#define XFS_WANT_CORRUPTED_RETURN(mp, expr) \ +{ \ + if (!(expr)) { \ + if ((mp)->m_flags & LIBXFS_MOUNT_WANT_CORRUPTED) \ + printf("WANT_CORRUPTED_RETURN at %s:%d\n", \ + __func__, __LINE__); \ + return -EFSCORRUPTED; \ + } \ +} #ifdef __GNUC__ #define __return_address __builtin_return_address(0) diff --git a/man/man8/xfs_repair.8 b/man/man8/xfs_repair.8 index 0394c50..1b4d9e3 100644 --- a/man/man8/xfs_repair.8 +++ b/man/man8/xfs_repair.8 @@ -158,7 +158,7 @@ outputs its progress every 15 minutes. Reporting is only activated when ag_stride is enabled. .TP .B \-v -Verbose output. +Verbose output. May be specified multiple times to increase verbosity. .TP .B \-d Repair dangerously. Allow diff --git a/repair/xfs_repair.c b/repair/xfs_repair.c index bed2ff5..1aeac5b 100644 --- a/repair/xfs_repair.c +++ b/repair/xfs_repair.c @@ -695,6 +695,10 @@ main(int argc, char **argv) } mp->m_log = &log; + /* Spit out function & line on these corruption macros */ + if (verbose > 2) + mp->m_flags |= LIBXFS_MOUNT_WANT_CORRUPTED; + /* * set XFS-independent status vars from the mount/sb structure */ From liruilong0128@gmail.com Wed Nov 11 20:21:18 2015 Return-Path: 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 422267F5D for ; Wed, 11 Nov 2015 20:21:18 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 07494304039 for ; Wed, 11 Nov 2015 18:21:14 -0800 (PST) X-ASG-Debug-ID: 1447294870-04bdf03f03130050001-NocioJ Received: from mail-qk0-f178.google.com (mail-qk0-f178.google.com [209.85.220.178]) by cuda.sgi.com with ESMTP id v8zuhAVnDf1ar0xL (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Wed, 11 Nov 2015 18:21:10 -0800 (PST) X-Barracuda-Envelope-From: liruilong0128@gmail.com X-Barracuda-Apparent-Source-IP: 209.85.220.178 Received: by qkao63 with SMTP id o63so18872714qka.2 for ; Wed, 11 Nov 2015 18:21:10 -0800 (PST) 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=Xs7+iKuXJaTzj7xSB6awtJGVoKt/UBH2pWuHG9kibBM=; b=GEgZZnX4g0L70B2cxShLtiQfHYoWG2t2EOG/UoS26DGCJx7qyGuDx+zpoHOZ7TPP7R tsJp69mWq5wAyq8kO5mArtFymJApKt+vcBXPVhfkXDv8SdIDrHkqdFPq2f73NkVohcJY HMXTuldv5IVWq6yIJwE388i/RgfAR1u0iPcCsFjl1OHo2/f0jJYqnKfNxYPO2/YTuQzR VUmXHYm1069rcCUdxdV++wmeFKj8xlYxIJKD9b8JPKxc0YQpS8YS7MhKW7PbvwSCbcLj notP1wzaxfcd2dRwzKIqDZrEXJwBS9MMENmN3/tiOdQ9IJk1z4Fs0eiHjxhbUQmnMLCL RErQ== MIME-Version: 1.0 X-Received: by 10.55.52.142 with SMTP id b136mr14003646qka.100.1447294869614; Wed, 11 Nov 2015 18:21:09 -0800 (PST) Received: by 10.140.81.175 with HTTP; Wed, 11 Nov 2015 18:21:09 -0800 (PST) In-Reply-To: <20151111125021.GA28745@redhat.com> References: <20151111125021.GA28745@redhat.com> Date: Thu, 12 Nov 2015 10:21:09 +0800 Message-ID: Subject: Re: xfsprogs install From: rui li X-ASG-Orig-Subj: Re: xfsprogs install To: rui li , xfs@oss.sgi.com Content-Type: multipart/alternative; boundary=001a114953ba96b47105244e9897 X-Barracuda-Connect: mail-qk0-f178.google.com[209.85.220.178] X-Barracuda-Start-Time: 1447294870 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/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 X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24319 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 0.50 BSF_SC0_SA_TO_FROM_ADDR_MATCH Sender Address Matches Recipient Address --001a114953ba96b47105244e9897 Content-Type: text/plain; charset=UTF-8 thanks ! when i run mkfs.xfs -f /dev/sda2p1 ,the error is no that file or directory acturally /dev/sda2p1 existed could you give me some help? thank you very much 2015-11-11 20:50 GMT+08:00 Carlos Maiolino : > On Wed, Nov 11, 2015 at 02:38:24PM +0800, rui li wrote: > > hello > > when i install xfsprogs i hava follwing problems > > FATAL ERROR: could not find a valid BLKID header > > Install the Block device ID development package > > could you give me some help? > > thanks > install libblkid-devel package in your distribution, or any similar > package that > your distribution provides with libblkid headers. > > > > _______________________________________________ > > xfs mailing list > > xfs@oss.sgi.com > > http://oss.sgi.com/mailman/listinfo/xfs > > > -- > Carlos > --001a114953ba96b47105244e9897 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
thanks !
when i run mkfs.xfs -f /dev/sda2p1 ,the error= is no that file or directory=C2=A0
acturally /dev/sda2p1 =C2=A0e= xisted
could you give me some help?
thank you very much= =C2=A0

2015-11-11 20:50 GMT+08:00 Carlos Maiolino <cmaiolino@redhat.com= >:
On Wed, Nov 11, 2015 at 02:38:24PM +0800, rui li wrote:
>=C2=A0 =C2=A0 hello
>=C2=A0 =C2=A0 when i install xfsprogs i hava follwing problems
>=C2=A0 =C2=A0 FATAL ERROR: could not find a valid BLKID header
>=C2=A0 =C2=A0 Install the Block device ID development package
>=C2=A0 =C2=A0 could you give me some help?
>=C2=A0 =C2=A0 thanks
install libblkid-devel package in your distribution, or any sim= ilar package that
your distribution provides with libblkid headers.


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


--
Carlos

--001a114953ba96b47105244e9897-- From robin.listas@gmail.com Wed Nov 11 20:28:30 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 DBA8E7F5D for ; Wed, 11 Nov 2015 20:28:29 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 5A8E6AC002 for ; Wed, 11 Nov 2015 18:28:29 -0800 (PST) X-ASG-Debug-ID: 1447295306-04bdf03f03130230001-NocioJ Received: from mail-wm0-f44.google.com (mail-wm0-f44.google.com [74.125.82.44]) by cuda.sgi.com with ESMTP id iUNvDLqOIp89i74g (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Wed, 11 Nov 2015 18:28:27 -0800 (PST) X-Barracuda-Envelope-From: robin.listas@gmail.com X-Barracuda-Apparent-Source-IP: 74.125.82.44 Received: by wmww144 with SMTP id w144so182600782wmw.1 for ; Wed, 11 Nov 2015 18:28:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:subject:to:references:from:message-id:date:user-agent :mime-version:in-reply-to:content-type:content-transfer-encoding; bh=wDt04GNKO7Q129oBmIatQiVicoY7v+3KyrZyhLLz6ec=; b=UVvvJuswT/uyCeQOVBsKxSc05GecW2W/+fRoITAmWquBWLXY6EUaSzNT1NL4XZ6hl3 ytbKs38+S9WxAp1JmgfFlqSLKySeOoWN4AJaw7RS6zKPVXveYkqQiEIoBear1VMHHLaP 50w25bPcgGzh7qje4MkX0yECh/QMeVINmP65b/F6sGpmynAEGP5hmVWFCCWsUfTecbLQ IedloYwPILC/Z6W3tWzffKxrDVTSJ8d1hzy2deKbDU5Zb4V/Ps26jPqphNqqjjkbV8WV uThwJB0IEdcDgOE5yRSf/P7Kj7o++vwt2R+J+OUErSCtBjx7wmTOhaHang+CJ5Sep1Y+ 107A== X-Received: by 10.194.186.196 with SMTP id fm4mr15875995wjc.152.1447295306513; Wed, 11 Nov 2015 18:28:26 -0800 (PST) Received: from Minas-Anor.Valinor (248.Red-81-36-103.dynamicIP.rima-tde.net. [81.36.103.248]) by smtp.googlemail.com with ESMTPSA id 69sm1207690wmw.0.2015.11.11.18.28.25 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 11 Nov 2015 18:28:25 -0800 (PST) Sender: Carlos Robinson Subject: Re: xfsprogs install To: xfs@oss.sgi.com X-ASG-Orig-Subj: Re: xfsprogs install References: <20151111125021.GA28745@redhat.com> From: "Carlos E. R" Message-ID: <5643F948.2030703@opensuse.org> Date: Thu, 12 Nov 2015 03:28:24 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mail-wm0-f44.google.com[74.125.82.44] X-Barracuda-Start-Time: 1447295307 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24319 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 11/12/2015 03:21 AM, rui li wrote: > thanks ! > when i run mkfs.xfs -f /dev/sda2p1 ,the error is no that file or directory > acturally /dev/sda2p1 existed > could you give me some help? > thank you very much Why don't you try: LANG=POSIX mkfs.xfs -f /dev/sda2p1 and then post what you get here (it will be in English). Use copy paste, don't type nor translate. -- Cheers/Saludos Carlos E. R. (openSUSE Leap 42.1, test at Minas-Anor) From sandeen@redhat.com Wed Nov 11 22:54:48 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 900747F5E for ; Wed, 11 Nov 2015 22:54:48 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 241AAAC001 for ; Wed, 11 Nov 2015 20:54:42 -0800 (PST) X-ASG-Debug-ID: 1447304079-04bdf03f04132900001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id PDfXCDxViWxbAwpu (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 11 Nov 2015 20:54:40 -0800 (PST) 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 (Postfix) with ESMTPS id E3B70C0A5170 for ; Thu, 12 Nov 2015 04:54:39 +0000 (UTC) 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 tAC4scnw032254 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Wed, 11 Nov 2015 23:54:39 -0500 To: xfs@oss.sgi.com From: Eric Sandeen Subject: [PATCH] xfs: create helper for bmap finish & trans join in xfs_attr.c X-Enigmail-Draft-Status: N1110 X-ASG-Orig-Subj: [PATCH] xfs: create helper for bmap finish & trans join in xfs_attr.c Message-ID: <56441B8E.6070603@redhat.com> Date: Wed, 11 Nov 2015 22:54:38 -0600 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 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: 1447304080 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Calls to xfs_bmap_finish() and xfs_trans_ijoin(), and the associated comments were replicated several times across xfs_attr.c. Factor out a new helper function, xfs_bmap_finish_and_join() to take care of this. This also fixes an ASSERT() test of an uninitialized variable in several locations: error = xfs_attr_thing(&args); if (!error) { error = xfs_bmap_finish(&args.trans, args.flist, &committed); } if (error) { ASSERT(committed); If the first xfs_attr_thing() failed, we'd skip the xfs_bmap_finish, never set "committed", and then test it in the ASSERT. Addresses-Coverity-Id: 102360 Addresses-Coverity-Id: 102361 Addresses-Coverity-Id: 102363 Addresses-Coverity-Id: 102364 Signed-off-by: Eric Sandeen --- ->>> I don't think I broke the logic, but feel free to scrutinize it :) xfs_attr.c | 168 ++++++++++++++++--------------------------------------------- 1 file changed, 45 insertions(+), 123 deletions(-) diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c index f949818..2fe1a3b 100644 --- a/fs/xfs/libxfs/xfs_attr.c +++ b/fs/xfs/libxfs/xfs_attr.c @@ -193,6 +193,28 @@ xfs_attr_calc_size( return nblks; } +STATIC int +xfs_bmap_finish_and_join( + struct xfs_da_args *args, + struct xfs_inode *dp) +{ + int error, committed; + + error = xfs_bmap_finish(&args->trans, args->flist, &committed); + if (error) { + ASSERT(committed); + return error; + } + /* + * bmap_finish() may have committed the last trans and started + * a new one. We need the inode to be in all transactions. + */ + if (committed) + xfs_trans_ijoin(args->trans, dp, 0); + + return 0; +} + int xfs_attr_set( struct xfs_inode *dp, @@ -207,7 +229,7 @@ xfs_attr_set( struct xfs_trans_res tres; xfs_fsblock_t firstblock; int rsvd = (flags & ATTR_ROOT) != 0; - int error, err2, committed, local; + int error, err2, local; XFS_STATS_INC(mp, xs_attr_set); @@ -334,25 +356,15 @@ xfs_attr_set( */ xfs_bmap_init(args.flist, args.firstblock); error = xfs_attr_shortform_to_leaf(&args); - if (!error) { - error = xfs_bmap_finish(&args.trans, args.flist, - &committed); - } + if (!error) + error = xfs_bmap_finish_and_join(&args, dp); if (error) { - ASSERT(committed); args.trans = NULL; xfs_bmap_cancel(&flist); goto out; } /* - * bmap_finish() may have committed the last trans and started - * a new one. We need the inode to be in all transactions. - */ - if (committed) - xfs_trans_ijoin(args.trans, dp, 0); - - /* * Commit the leaf transformation. We'll need another (linked) * transaction to add the new attribute to the leaf. */ @@ -568,7 +580,7 @@ xfs_attr_leaf_addname(xfs_da_args_t *args) { xfs_inode_t *dp; struct xfs_buf *bp; - int retval, error, committed, forkoff; + int retval, error, forkoff; trace_xfs_attr_leaf_addname(args); @@ -628,25 +640,15 @@ xfs_attr_leaf_addname(xfs_da_args_t *args) */ xfs_bmap_init(args->flist, args->firstblock); error = xfs_attr3_leaf_to_node(args); - if (!error) { - error = xfs_bmap_finish(&args->trans, args->flist, - &committed); - } + if (!error) + error = xfs_bmap_finish_and_join(args, dp); if (error) { - ASSERT(committed); args->trans = NULL; xfs_bmap_cancel(args->flist); return error; } /* - * bmap_finish() may have committed the last trans and started - * a new one. We need the inode to be in all transactions. - */ - if (committed) - xfs_trans_ijoin(args->trans, dp, 0); - - /* * Commit the current trans (including the inode) and start * a new one. */ @@ -729,25 +731,13 @@ xfs_attr_leaf_addname(xfs_da_args_t *args) xfs_bmap_init(args->flist, args->firstblock); error = xfs_attr3_leaf_to_shortform(bp, args, forkoff); /* bp is gone due to xfs_da_shrink_inode */ - if (!error) { - error = xfs_bmap_finish(&args->trans, - args->flist, - &committed); - } + if (!error) + error = xfs_bmap_finish_and_join(args, dp); if (error) { - ASSERT(committed); args->trans = NULL; xfs_bmap_cancel(args->flist); return error; } - - /* - * bmap_finish() may have committed the last trans - * and started a new one. We need the inode to be - * in all transactions. - */ - if (committed) - xfs_trans_ijoin(args->trans, dp, 0); } /* @@ -775,7 +765,7 @@ xfs_attr_leaf_removename(xfs_da_args_t *args) { xfs_inode_t *dp; struct xfs_buf *bp; - int error, committed, forkoff; + int error, forkoff; trace_xfs_attr_leaf_removename(args); @@ -803,23 +793,13 @@ xfs_attr_leaf_removename(xfs_da_args_t *args) xfs_bmap_init(args->flist, args->firstblock); error = xfs_attr3_leaf_to_shortform(bp, args, forkoff); /* bp is gone due to xfs_da_shrink_inode */ - if (!error) { - error = xfs_bmap_finish(&args->trans, args->flist, - &committed); - } + if (!error) + error = xfs_bmap_finish_and_join(args, dp); if (error) { - ASSERT(committed); args->trans = NULL; xfs_bmap_cancel(args->flist); return error; } - - /* - * bmap_finish() may have committed the last trans and started - * a new one. We need the inode to be in all transactions. - */ - if (committed) - xfs_trans_ijoin(args->trans, dp, 0); } return 0; } @@ -877,7 +857,7 @@ xfs_attr_node_addname(xfs_da_args_t *args) xfs_da_state_blk_t *blk; xfs_inode_t *dp; xfs_mount_t *mp; - int committed, retval, error; + int retval, error; trace_xfs_attr_node_addname(args); @@ -938,26 +918,13 @@ restart: state = NULL; xfs_bmap_init(args->flist, args->firstblock); error = xfs_attr3_leaf_to_node(args); - if (!error) { - error = xfs_bmap_finish(&args->trans, - args->flist, - &committed); - } + if (!error) + error = xfs_bmap_finish_and_join(args, dp); if (error) { - ASSERT(committed); args->trans = NULL; xfs_bmap_cancel(args->flist); goto out; } - - /* - * bmap_finish() may have committed the last trans - * and started a new one. We need the inode to be - * in all transactions. - */ - if (committed) - xfs_trans_ijoin(args->trans, dp, 0); - /* * Commit the node conversion and start the next * trans in the chain. @@ -977,23 +944,13 @@ restart: */ xfs_bmap_init(args->flist, args->firstblock); error = xfs_da3_split(state); - if (!error) { - error = xfs_bmap_finish(&args->trans, args->flist, - &committed); - } + if (!error) + error = xfs_bmap_finish_and_join(args, dp); if (error) { - ASSERT(committed); args->trans = NULL; xfs_bmap_cancel(args->flist); goto out; } - - /* - * bmap_finish() may have committed the last trans and started - * a new one. We need the inode to be in all transactions. - */ - if (committed) - xfs_trans_ijoin(args->trans, dp, 0); } else { /* * Addition succeeded, update Btree hashvals. @@ -1086,25 +1043,13 @@ restart: if (retval && (state->path.active > 1)) { xfs_bmap_init(args->flist, args->firstblock); error = xfs_da3_join(state); - if (!error) { - error = xfs_bmap_finish(&args->trans, - args->flist, - &committed); - } + if (!error) + error = xfs_bmap_finish_and_join(args, dp); if (error) { - ASSERT(committed); args->trans = NULL; xfs_bmap_cancel(args->flist); goto out; } - - /* - * bmap_finish() may have committed the last trans - * and started a new one. We need the inode to be - * in all transactions. - */ - if (committed) - xfs_trans_ijoin(args->trans, dp, 0); } /* @@ -1146,7 +1091,7 @@ xfs_attr_node_removename(xfs_da_args_t *args) xfs_da_state_blk_t *blk; xfs_inode_t *dp; struct xfs_buf *bp; - int retval, error, committed, forkoff; + int retval, error, forkoff; trace_xfs_attr_node_removename(args); @@ -1220,24 +1165,13 @@ xfs_attr_node_removename(xfs_da_args_t *args) if (retval && (state->path.active > 1)) { xfs_bmap_init(args->flist, args->firstblock); error = xfs_da3_join(state); - if (!error) { - error = xfs_bmap_finish(&args->trans, args->flist, - &committed); - } + if (!error) + error = xfs_bmap_finish_and_join(args, dp); if (error) { - ASSERT(committed); args->trans = NULL; xfs_bmap_cancel(args->flist); goto out; } - - /* - * bmap_finish() may have committed the last trans and started - * a new one. We need the inode to be in all transactions. - */ - if (committed) - xfs_trans_ijoin(args->trans, dp, 0); - /* * Commit the Btree join operation and start a new trans. */ @@ -1265,25 +1199,13 @@ xfs_attr_node_removename(xfs_da_args_t *args) xfs_bmap_init(args->flist, args->firstblock); error = xfs_attr3_leaf_to_shortform(bp, args, forkoff); /* bp is gone due to xfs_da_shrink_inode */ - if (!error) { - error = xfs_bmap_finish(&args->trans, - args->flist, - &committed); - } + if (!error) + error = xfs_bmap_finish_and_join(args, dp); if (error) { - ASSERT(committed); args->trans = NULL; xfs_bmap_cancel(args->flist); goto out; } - - /* - * bmap_finish() may have committed the last trans - * and started a new one. We need the inode to be - * in all transactions. - */ - if (committed) - xfs_trans_ijoin(args->trans, dp, 0); } else xfs_trans_brelse(args->trans, bp); } From sandeen@sandeen.net Wed Nov 11 22:59:01 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 2EB327F5E for ; Wed, 11 Nov 2015 22:59:01 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 08680304043 for ; Wed, 11 Nov 2015 20:59:00 -0800 (PST) X-ASG-Debug-ID: 1447304326-04cbb02423144c10001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id 67gPqklZOgdLWuSo for ; Wed, 11 Nov 2015 20:58:46 -0800 (PST) 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 1BA5A612961A for ; Wed, 11 Nov 2015 22:58:46 -0600 (CST) Subject: Re: [PATCH] xfs: create helper for bmap finish & trans join in xfs_attr.c To: xfs@oss.sgi.com X-ASG-Orig-Subj: Re: [PATCH] xfs: create helper for bmap finish & trans join in xfs_attr.c References: <56441B8E.6070603@redhat.com> From: Eric Sandeen Message-ID: <56441C85.2010406@sandeen.net> Date: Wed, 11 Nov 2015 22:58:45 -0600 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <56441B8E.6070603@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: 1447304326 X-Barracuda-URL: https://192.48.176.25:443/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= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24321 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 11/11/15 10:54 PM, Eric Sandeen wrote: > Calls to xfs_bmap_finish() and xfs_trans_ijoin(), and the > associated comments were replicated several times across > xfs_attr.c. > > Factor out a new helper function, xfs_bmap_finish_and_join() > to take care of this. > > This also fixes an ASSERT() test of an uninitialized variable > in several locations: > > error = xfs_attr_thing(&args); > if (!error) { > error = xfs_bmap_finish(&args.trans, args.flist, > &committed); > } > if (error) { > ASSERT(committed); > > If the first xfs_attr_thing() failed, we'd skip the xfs_bmap_finish, > never set "committed", and then test it in the ASSERT. Whoops, of course right after I send it I see that this can be used (and the ASSERT problem exists) in xfs_attr_remote.c as well; I'll send V2 tomorrow. -Eric From arekm@maven.pl Thu Nov 12 00:06:23 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 C62607F53 for ; Thu, 12 Nov 2015 00:06:23 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 880C38F8035 for ; Wed, 11 Nov 2015 22:06:20 -0800 (PST) X-ASG-Debug-ID: 1447308372-04bdf03f02134700001-NocioJ Received: from mail-lf0-f41.google.com (mail-lf0-f41.google.com [209.85.215.41]) by cuda.sgi.com with ESMTP id uoZGIP3ch06b8Lq7 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Wed, 11 Nov 2015 22:06:13 -0800 (PST) X-Barracuda-Envelope-From: arekm@maven.pl X-Barracuda-Apparent-Source-IP: 209.85.215.41 Received: by lfdo63 with SMTP id o63so28182419lfd.2 for ; Wed, 11 Nov 2015 22:06:12 -0800 (PST) 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=FH2EHEvVv1dA9Aca83nlC6zB2dSONT9McpAY3OG00UE=; b=FdfKUzcfv+QEU+ZRXz6TPTK8mB9P1eokkXzHcyCFQQoMh0mGYjbYYJHtKRlTkBV2bC YzBll2lVEoM4r8/+XKqOnt2v3rt4P/tqgp59xkvZu8kYpFJZja5ziJo+X6UoQOUMU9lb Ndd0Phmvo7v8P+ajwPl/ItU9i/7EYU3VdwTic= 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=FH2EHEvVv1dA9Aca83nlC6zB2dSONT9McpAY3OG00UE=; b=df4qtNLgUlv6ALJEqAOSjUY5jB5rWcMHWGQ2LRbkOjDAt3KGzZKfOvefp9ONSgF/LB wvrBfH6Khy57dhzADlCltRvyR0x6GLYyOGaOHDJ5fFGtoVDQiondZnQHQDd7susTDoIG 0BBP1NmX7zwRCOVNsgw8jv7cbjic7GIaPVyPoXI5Zzfq0Wk1Xuqo0oFpy8RudQKUhISm 3jRyEJo+1HwqFUrqGu9IvbPOh3wfaA4bMGzuswzY7PtfXuDK0rfKpjaTeQfmXUqmWJdh OqEUMP3/vkvmx16dDjBF2meZazuOEVqnkkGrub2yuLbuYhc1/o/BSn/D0xLDIV0azD9A 76vA== X-Gm-Message-State: ALoCoQkRIcKG7+xKswqYK93UAWkJ11atBJXH0LXQhVhbtiBNlkBl8cVMhc8qxk9q8/MF5mpd1dIU X-Received: by 10.25.26.210 with SMTP id a201mr6421385lfa.58.1447308372104; Wed, 11 Nov 2015 22:06:12 -0800 (PST) Received: from xps.localnet (85-222-71-204.dynamic.chello.pl. [85.222.71.204]) by smtp.gmail.com with ESMTPSA id q197sm2028857lfd.36.2015.11.11.22.06.11 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 11 Nov 2015 22:06:11 -0800 (PST) From: Arkadiusz =?utf-8?q?Mi=C5=9Bkiewicz?= To: Tetsuo Handa Subject: Re: memory reclaim problems on fs usage Date: Thu, 12 Nov 2015 07:06:10 +0100 X-ASG-Orig-Subj: Re: memory reclaim problems on fs usage User-Agent: KMail/1.13.7 (Linux/4.3.0; KDE/4.14.13; x86_64; ; ) Cc: linux-mm@kvack.org, xfs@oss.sgi.com References: <201511102313.36685.arekm@maven.pl> <201511111719.44035.arekm@maven.pl> <201511120719.EBF35970.OtSOHOVFJMFQFL@I-love.SAKURA.ne.jp> In-Reply-To: <201511120719.EBF35970.OtSOHOVFJMFQFL@I-love.SAKURA.ne.jp> MIME-Version: 1.0 Content-Type: Text/Plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <201511120706.10739.arekm@maven.pl> X-Barracuda-Connect: mail-lf0-f41.google.com[209.85.215.41] X-Barracuda-Start-Time: 1447308373 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24322 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 11 of November 2015, Tetsuo Handa wrote: > Arkadiusz Mi?kiewicz wrote: > > This patch is against which tree? (tried 4.1, 4.2 and 4.3) >=20 > Oops. Whitespace-damaged. This patch is for vanilla 4.1.2. > Reposting with one condition corrected. Here is log: http://ixion.pld-linux.org/~arekm/log-mm-1.txt.gz Uncompresses is 1.4MB, so not posting here. =2D-=20 Arkadiusz Mi=C5=9Bkiewicz, arekm / ( maven.pl | pld-linux.org ) From BATV+89ba7098823c58057a3d+4463+infradead.org+hch@bombadil.srs.infradead.org Thu Nov 12 03:08:09 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 977C27F62 for ; Thu, 12 Nov 2015 03:08:09 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 694DA8F8040 for ; Thu, 12 Nov 2015 01:08:06 -0800 (PST) X-ASG-Debug-ID: 1447319284-04bdf03f02138cb0001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id zYIYwYbPZ7256ru7 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Thu, 12 Nov 2015 01:08:04 -0800 (PST) X-Barracuda-Envelope-From: BATV+89ba7098823c58057a3d+4463+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 1ZwnrI-0006lj-Lp; Thu, 12 Nov 2015 09:07:56 +0000 Date: Thu, 12 Nov 2015 01:07:56 -0800 From: Christoph Hellwig To: "Darrick J. Wong" Cc: hch@infradead.org, david@fromorbit.com, fstests@vger.kernel.org, xfs@oss.sgi.com, tao.peng@primarydata.com, linux-ext4@vger.kernel.org, Anna.Schumaker@netapp.com, linux-btrfs@vger.kernel.org Subject: Re: [RFCv3.1 00/11] xfstests: test the nfs/cifs/btrfs/xfs reflink/dedupe ioctls Message-ID: <20151112090756.GA25685@infradead.org> X-ASG-Orig-Subj: Re: [RFCv3.1 00/11] xfstests: test the nfs/cifs/btrfs/xfs reflink/dedupe ioctls References: <20151111192628.15056.6451.stgit@birch.djwong.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151111192628.15056.6451.stgit@birch.djwong.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: 1447319284 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/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_MISMATCH_TO, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24325 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS Looks fine: Acked-by: Christoph Hellwig some of the free block range stuff might need minor fixups for certain file systems later, but I'd rather do this once all the patches are merged. From cmaiolino@redhat.com Thu Nov 12 06:37:20 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 5ED737F62 for ; Thu, 12 Nov 2015 06:37:20 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id D68F0AC001 for ; Thu, 12 Nov 2015 04:37:16 -0800 (PST) X-ASG-Debug-ID: 1447331834-04cb6c296d138de0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id xScelxZQZWB53L1Q (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 12 Nov 2015 04:37:15 -0800 (PST) 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 (Postfix) with ESMTPS id A039937F43; Thu, 12 Nov 2015 12:37:14 +0000 (UTC) Received: from redhat.com (dhcp-26-103.brq.redhat.com [10.34.26.103]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tACCbBm8001282 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Thu, 12 Nov 2015 07:37:13 -0500 Date: Thu, 12 Nov 2015 13:37:10 +0100 From: Carlos Maiolino To: "Carlos E. R" Cc: xfs@oss.sgi.com Subject: Re: xfsprogs install Message-ID: <20151112123710.GA2585@redhat.com> X-ASG-Orig-Subj: Re: xfsprogs install Mail-Followup-To: "Carlos E. R" , xfs@oss.sgi.com References: <20151111125021.GA28745@redhat.com> <5643F948.2030703@opensuse.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <5643F948.2030703@opensuse.org> User-Agent: Mutt/1.5.24 (2015-08-30) 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: 1447331835 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Thu, Nov 12, 2015 at 03:28:24AM +0100, Carlos E. R wrote: > On 11/12/2015 03:21 AM, rui li wrote: > >thanks ! > >when i run mkfs.xfs -f /dev/sda2p1 ,the error is no that file or directory > >acturally /dev/sda2p1 existed > >could you give me some help? > >thank you very much > > Why don't you try: > > LANG=POSIX mkfs.xfs -f /dev/sda2p1 > > and then post what you get here (it will be in English). Use copy paste, > don't type nor translate. +1 although the amount of information you provided isn't enough to say much. /dev/sda2p1 what kind of device is it? how did you ended up with it? It looks like to be created by device-mapper / lvm to me, but I can't say just for looking the device name. Anyway, what `ls -l /dev/sda2p1` shows to you, maybe it's a broken symbolic link to somewhere else? Anyway, just guesses, I don't have any information to say anything else > > -- > Cheers/Saludos > > Carlos E. R. (openSUSE Leap 42.1, test at Minas-Anor) > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs -- Carlos From bfoster@redhat.com Thu Nov 12 06:40:50 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 97C8F7F62 for ; Thu, 12 Nov 2015 06:40:50 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 84AB28F8033 for ; Thu, 12 Nov 2015 04:40:50 -0800 (PST) X-ASG-Debug-ID: 1447332048-04cbb0242514ec50001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id aXgpMZehGYeGIX2X (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 12 Nov 2015 04:40:48 -0800 (PST) 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 (Postfix) with ESMTPS id 48BD5461C8 for ; Thu, 12 Nov 2015 12:40:48 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-36.bos.redhat.com [10.18.41.36]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tACCelPD007192; Thu, 12 Nov 2015 07:40:47 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id 5CB20120059; Thu, 12 Nov 2015 07:40:47 -0500 (EST) Date: Thu, 12 Nov 2015 07:40:47 -0500 From: Brian Foster To: Eric Sandeen Cc: xfs@oss.sgi.com Subject: Re: [PATCH] xfs: print name of verifier if it fails Message-ID: <20151112124046.GA5068@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH] xfs: print name of verifier if it fails References: <5643BD7D.4000307@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <5643BD7D.4000307@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: 1447332048 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Wed, Nov 11, 2015 at 04:13:17PM -0600, Eric Sandeen wrote: > This adds a name to each buf_ops structure, so that if > a verifier fails we can print the type of verifier that > failed it. Should be a slight debugging aid, I hope. > > Signed-off-by: Eric Sandeen > --- Seems harmless, but is this really necessary when we dump a stack trace? I suppose that only happens if the error level is set appropriately. Another option might be to use _RET_IP_. It might not be as pretty, but we already use it all over the place for tracepoints and such. Brian > > diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c > index 3479294..e1e7fe3 100644 > --- a/fs/xfs/libxfs/xfs_alloc.c > +++ b/fs/xfs/libxfs/xfs_alloc.c > @@ -535,6 +535,7 @@ xfs_agfl_write_verify( > } > > const struct xfs_buf_ops xfs_agfl_buf_ops = { > + .name = "xfs_agfl", > .verify_read = xfs_agfl_read_verify, > .verify_write = xfs_agfl_write_verify, > }; > @@ -2339,6 +2340,7 @@ xfs_agf_write_verify( > } > > const struct xfs_buf_ops xfs_agf_buf_ops = { > + .name = "xfs_agf", > .verify_read = xfs_agf_read_verify, > .verify_write = xfs_agf_write_verify, > }; > diff --git a/fs/xfs/libxfs/xfs_alloc_btree.c b/fs/xfs/libxfs/xfs_alloc_btree.c > index 90de071..eb8bbfe 100644 > --- a/fs/xfs/libxfs/xfs_alloc_btree.c > +++ b/fs/xfs/libxfs/xfs_alloc_btree.c > @@ -379,6 +379,7 @@ xfs_allocbt_write_verify( > } > > const struct xfs_buf_ops xfs_allocbt_buf_ops = { > + .name = "xfs_allocbt", > .verify_read = xfs_allocbt_read_verify, > .verify_write = xfs_allocbt_write_verify, > }; > diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c > index aa187f7..01a5ecf 100644 > --- a/fs/xfs/libxfs/xfs_attr_leaf.c > +++ b/fs/xfs/libxfs/xfs_attr_leaf.c > @@ -328,6 +328,7 @@ xfs_attr3_leaf_read_verify( > } > > const struct xfs_buf_ops xfs_attr3_leaf_buf_ops = { > + .name = "xfs_attr3_leaf", > .verify_read = xfs_attr3_leaf_read_verify, > .verify_write = xfs_attr3_leaf_write_verify, > }; > diff --git a/fs/xfs/libxfs/xfs_attr_remote.c b/fs/xfs/libxfs/xfs_attr_remote.c > index 5ab95ff..f3ed9bf 100644 > --- a/fs/xfs/libxfs/xfs_attr_remote.c > +++ b/fs/xfs/libxfs/xfs_attr_remote.c > @@ -201,6 +201,7 @@ xfs_attr3_rmt_write_verify( > } > > const struct xfs_buf_ops xfs_attr3_rmt_buf_ops = { > + .name = "xfs_attr3_rmt", > .verify_read = xfs_attr3_rmt_read_verify, > .verify_write = xfs_attr3_rmt_write_verify, > }; > diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c > index 6b0cf65..1637c37 100644 > --- a/fs/xfs/libxfs/xfs_bmap_btree.c > +++ b/fs/xfs/libxfs/xfs_bmap_btree.c > @@ -720,6 +720,7 @@ xfs_bmbt_write_verify( > } > > const struct xfs_buf_ops xfs_bmbt_buf_ops = { > + .name = "xfs_bmbt", > .verify_read = xfs_bmbt_read_verify, > .verify_write = xfs_bmbt_write_verify, > }; > diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c > index e89a0f8..097bf77 100644 > --- a/fs/xfs/libxfs/xfs_da_btree.c > +++ b/fs/xfs/libxfs/xfs_da_btree.c > @@ -245,6 +245,7 @@ xfs_da3_node_read_verify( > } > > const struct xfs_buf_ops xfs_da3_node_buf_ops = { > + .name = "xfs_da3_node", > .verify_read = xfs_da3_node_read_verify, > .verify_write = xfs_da3_node_write_verify, > }; > diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c > index 9c10e2b..aa17cb7 100644 > --- a/fs/xfs/libxfs/xfs_dir2_block.c > +++ b/fs/xfs/libxfs/xfs_dir2_block.c > @@ -123,6 +123,7 @@ xfs_dir3_block_write_verify( > } > > const struct xfs_buf_ops xfs_dir3_block_buf_ops = { > + .name = "xfs_dir3_block", > .verify_read = xfs_dir3_block_read_verify, > .verify_write = xfs_dir3_block_write_verify, > }; > diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c > index af71a84..725fc78 100644 > --- a/fs/xfs/libxfs/xfs_dir2_data.c > +++ b/fs/xfs/libxfs/xfs_dir2_data.c > @@ -305,11 +305,13 @@ xfs_dir3_data_write_verify( > } > > const struct xfs_buf_ops xfs_dir3_data_buf_ops = { > + .name = "xfs_dir3_data", > .verify_read = xfs_dir3_data_read_verify, > .verify_write = xfs_dir3_data_write_verify, > }; > > static const struct xfs_buf_ops xfs_dir3_data_reada_buf_ops = { > + .name = "xfs_dir3_data_reada", > .verify_read = xfs_dir3_data_reada_verify, > .verify_write = xfs_dir3_data_write_verify, > }; > diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c > index 3923e1f..b887fb2 100644 > --- a/fs/xfs/libxfs/xfs_dir2_leaf.c > +++ b/fs/xfs/libxfs/xfs_dir2_leaf.c > @@ -245,11 +245,13 @@ xfs_dir3_leafn_write_verify( > } > > const struct xfs_buf_ops xfs_dir3_leaf1_buf_ops = { > + .name = "xfs_dir3_leaf1", > .verify_read = xfs_dir3_leaf1_read_verify, > .verify_write = xfs_dir3_leaf1_write_verify, > }; > > const struct xfs_buf_ops xfs_dir3_leafn_buf_ops = { > + .name = "xfs_dir3_leafn", > .verify_read = xfs_dir3_leafn_read_verify, > .verify_write = xfs_dir3_leafn_write_verify, > }; > diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c > index 70b0cb2..63ee03d 100644 > --- a/fs/xfs/libxfs/xfs_dir2_node.c > +++ b/fs/xfs/libxfs/xfs_dir2_node.c > @@ -150,6 +150,7 @@ xfs_dir3_free_write_verify( > } > > const struct xfs_buf_ops xfs_dir3_free_buf_ops = { > + .name = "xfs_dir3_free", > .verify_read = xfs_dir3_free_read_verify, > .verify_write = xfs_dir3_free_write_verify, > }; > diff --git a/fs/xfs/libxfs/xfs_dquot_buf.c b/fs/xfs/libxfs/xfs_dquot_buf.c > index 5331b7f..11cefb2 100644 > --- a/fs/xfs/libxfs/xfs_dquot_buf.c > +++ b/fs/xfs/libxfs/xfs_dquot_buf.c > @@ -282,6 +282,7 @@ xfs_dquot_buf_write_verify( > } > > const struct xfs_buf_ops xfs_dquot_buf_ops = { > + .name = "xfs_dquot", > .verify_read = xfs_dquot_buf_read_verify, > .verify_write = xfs_dquot_buf_write_verify, > }; > diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c > index 70c1db9..66d702e 100644 > --- a/fs/xfs/libxfs/xfs_ialloc.c > +++ b/fs/xfs/libxfs/xfs_ialloc.c > @@ -2572,6 +2572,7 @@ xfs_agi_write_verify( > } > > const struct xfs_buf_ops xfs_agi_buf_ops = { > + .name = "xfs_agi", > .verify_read = xfs_agi_read_verify, > .verify_write = xfs_agi_write_verify, > }; > diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.c b/fs/xfs/libxfs/xfs_ialloc_btree.c > index f39b285..6dd44f9 100644 > --- a/fs/xfs/libxfs/xfs_ialloc_btree.c > +++ b/fs/xfs/libxfs/xfs_ialloc_btree.c > @@ -304,6 +304,7 @@ xfs_inobt_write_verify( > } > > const struct xfs_buf_ops xfs_inobt_buf_ops = { > + .name = "xfs_inobt", > .verify_read = xfs_inobt_read_verify, > .verify_write = xfs_inobt_write_verify, > }; > diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c > index 268c00f..1b8d98a 100644 > --- a/fs/xfs/libxfs/xfs_inode_buf.c > +++ b/fs/xfs/libxfs/xfs_inode_buf.c > @@ -132,11 +132,13 @@ xfs_inode_buf_write_verify( > } > > const struct xfs_buf_ops xfs_inode_buf_ops = { > + .name = "xfs_inode", > .verify_read = xfs_inode_buf_read_verify, > .verify_write = xfs_inode_buf_write_verify, > }; > > const struct xfs_buf_ops xfs_inode_buf_ra_ops = { > + .name = "xxfs_inode_ra", > .verify_read = xfs_inode_buf_readahead_verify, > .verify_write = xfs_inode_buf_write_verify, > }; > diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c > index a0b071d..8a53eaa 100644 > --- a/fs/xfs/libxfs/xfs_sb.c > +++ b/fs/xfs/libxfs/xfs_sb.c > @@ -679,11 +679,13 @@ xfs_sb_write_verify( > } > > const struct xfs_buf_ops xfs_sb_buf_ops = { > + .name = "xfs_sb", > .verify_read = xfs_sb_read_verify, > .verify_write = xfs_sb_write_verify, > }; > > const struct xfs_buf_ops xfs_sb_quiet_buf_ops = { > + .name = "xfs_sb_quiet", > .verify_read = xfs_sb_quiet_read_verify, > .verify_write = xfs_sb_write_verify, > }; > diff --git a/fs/xfs/libxfs/xfs_symlink_remote.c b/fs/xfs/libxfs/xfs_symlink_remote.c > index cb6fd20..2e2c671 100644 > --- a/fs/xfs/libxfs/xfs_symlink_remote.c > +++ b/fs/xfs/libxfs/xfs_symlink_remote.c > @@ -168,6 +168,7 @@ xfs_symlink_write_verify( > } > > const struct xfs_buf_ops xfs_symlink_buf_ops = { > + .name = "xfs_symlink", > .verify_read = xfs_symlink_read_verify, > .verify_write = xfs_symlink_write_verify, > }; > diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h > index c79b717..c75721a 100644 > --- a/fs/xfs/xfs_buf.h > +++ b/fs/xfs/xfs_buf.h > @@ -132,6 +132,7 @@ struct xfs_buf_map { > struct xfs_buf_map (map) = { .bm_bn = (blkno), .bm_len = (numblk) }; > > struct xfs_buf_ops { > + char *name; > void (*verify_read)(struct xfs_buf *); > void (*verify_write)(struct xfs_buf *); > }; > diff --git a/fs/xfs/xfs_error.c b/fs/xfs/xfs_error.c > index 74d0e59..88693a9 100644 > --- a/fs/xfs/xfs_error.c > +++ b/fs/xfs/xfs_error.c > @@ -164,9 +164,9 @@ xfs_verifier_error( > { > struct xfs_mount *mp = bp->b_target->bt_mount; > > - xfs_alert(mp, "Metadata %s detected at %pF, block 0x%llx", > + xfs_alert(mp, "Metadata %s detected at %pF, %s block 0x%llx", > bp->b_error == -EFSBADCRC ? "CRC error" : "corruption", > - __return_address, bp->b_bn); > + __return_address, bp->b_ops->name, bp->b_bn); > > xfs_alert(mp, "Unmount and run xfs_repair"); > > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From BATV+89ba7098823c58057a3d+4463+infradead.org+hch@bombadil.srs.infradead.org Thu Nov 12 06:51:28 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 38C3C7F62 for ; Thu, 12 Nov 2015 06:51:28 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 2873C304039 for ; Thu, 12 Nov 2015 04:51:25 -0800 (PST) X-ASG-Debug-ID: 1447332681-04cbb0242314ef20001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id CDnPn14F8A2SALEp (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Thu, 12 Nov 2015 04:51:22 -0800 (PST) X-Barracuda-Envelope-From: BATV+89ba7098823c58057a3d+4463+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 1ZwrLP-0000lJ-6k; Thu, 12 Nov 2015 12:51:15 +0000 Date: Thu, 12 Nov 2015 04:51:15 -0800 From: Christoph Hellwig To: "Darrick J. Wong" Cc: david@fromorbit.com, fstests@vger.kernel.org, xfs@oss.sgi.com, tao.peng@primarydata.com, linux-ext4@vger.kernel.org, Anna.Schumaker@netapp.com, linux-btrfs@vger.kernel.org Subject: Re: [RFCv3.1 00/11] xfstests: test the nfs/cifs/btrfs/xfs reflink/dedupe ioctls Message-ID: <20151112125115.GA28822@infradead.org> X-ASG-Orig-Subj: Re: [RFCv3.1 00/11] xfstests: test the nfs/cifs/btrfs/xfs reflink/dedupe ioctls References: <20151111192628.15056.6451.stgit@birch.djwong.org> <20151112090756.GA25685@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151112090756.GA25685@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: 1447332682 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/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_MISMATCH_TO, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24329 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS On Thu, Nov 12, 2015 at 01:07:56AM -0800, Christoph Hellwig wrote: > Looks fine: > > Acked-by: Christoph Hellwig Actually I take this back. I had though this was the existing series with my fixes, but this one still incorrectly assumes that if reflink works dedup works as well, leading to lots of false failures on nfs. From eflorac@intellique.com Thu Nov 12 07:00:24 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 10D827F62 for ; Thu, 12 Nov 2015 07:00:24 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id F174C8F8040 for ; Thu, 12 Nov 2015 05:00:23 -0800 (PST) X-ASG-Debug-ID: 1447333221-04cb6c296a139460001-NocioJ Received: from mail1.g1.pair.com (mail1.g1.pair.com [66.39.3.162]) by cuda.sgi.com with ESMTP id HtXdMkkUmHgwhMxf (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 12 Nov 2015 05:00:21 -0800 (PST) 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 9F6042CCE4; Thu, 12 Nov 2015 08:00:20 -0500 (EST) Received: from harpe.intellique.com (labo.djinux.com [82.225.196.72]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail1.g1.pair.com (Postfix) with ESMTPSA id 84E692CCB6; Thu, 12 Nov 2015 08:00:19 -0500 (EST) Date: Thu, 12 Nov 2015 14:00:22 +0100 From: Emmanuel Florac To: rui li Cc: xfs@oss.sgi.com Subject: Re: xfsprogs install Message-ID: <20151112140022.7b8d8924@harpe.intellique.com> X-ASG-Orig-Subj: Re: xfsprogs install In-Reply-To: References: <20151111125021.GA28745@redhat.com> Organization: Intellique X-Mailer: Claws Mail 3.12.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: 1447333221 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 1.20 X-Barracuda-Spam-Status: No, SCORE=1.20 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_SA620b, BSF_SC7_SA298e, MAILTO_TO_SPAM_ADDR X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24329 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 MAILTO_TO_SPAM_ADDR URI: Includes a link to a likely spammer email 0.20 BSF_SC7_SA298e Custom Rule SA298e 1.00 BSF_SC0_SA620b Custom Rule SA620b Le Thu, 12 Nov 2015 10:21:09 +0800 rui li =C3=A9crivait: > when i run mkfs.xfs -f /dev/sda2p1 ,the error is no that file or > directory acturally /dev/sda2p1 existed > could you give me some help? Well, probably it doesn't exist then. Use the "lsblk" command or=20 "cat /proc/partitions" command to see a list of actual devices and partitions. --=20 ------------------------------------------------------------------------ Emmanuel Florac | Direction technique | Intellique | | +33 1 78 94 84 02 ------------------------------------------------------------------------ From bfoster@redhat.com Thu Nov 12 07:12:48 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 D15367F62 for ; Thu, 12 Nov 2015 07:12:48 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id C29CD8F8033 for ; Thu, 12 Nov 2015 05:12:45 -0800 (PST) X-ASG-Debug-ID: 1447333964-04cbb0242414f500001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id qB4z7ce4Ott6HtbH (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 12 Nov 2015 05:12:44 -0800 (PST) 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 (Postfix) with ESMTPS id 1374146A; Thu, 12 Nov 2015 13:12:43 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-36.bos.redhat.com [10.18.41.36]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tACDCh4U026091; Thu, 12 Nov 2015 08:12:43 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id 1F2C6120059; Thu, 12 Nov 2015 08:12:43 -0500 (EST) Date: Thu, 12 Nov 2015 08:12:43 -0500 From: Brian Foster To: Eric Sandeen Cc: xfs@oss.sgi.com Subject: Re: [PATCH] xfs_fsr: more selinux fixes Message-ID: <20151112131242.GB5068@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH] xfs_fsr: more selinux fixes References: <5643B8B7.9030708@sandeen.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <5643B8B7.9030708@sandeen.net> 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: 1447333964 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Wed, Nov 11, 2015 at 03:52:55PM -0600, Eric Sandeen wrote: > Commit: > > 1adfe5c xfs_fsr: fix SWAPEXT failures under selinux > > attempted to fix up the fork offset under selinux, where > the temp file is created with a local attribute, but the > target file has remote attributes; this can lead to a smaller > data area in the temp inode, without enough room to swap extents > from the target inode. I remedied this by pushing the temp > file attribute to remote, but *only* if the target file's attr > was also remote. > > However, I have a case from the field where the parent dir > and the target file both have a context of: > > system_u:object_r:samba_share_t:s0 > > but new files created in the dir have a context of > > unconfined_u:object_r:samba_share_t:s0 > > This means the temp file has a smaller forkoff, and less space > in the inode for data, so we fail to swap the extents between > the two, because they don't fit. > > The following patch fixes this by allowing xfs_fsr to > kick the tempfile's attr out of local format even if the target > file's attr is local, if this will move the forkoff in the right > direction. This does pass all our fsr xfstests, though I'm not > sure we have any real coverage of fsr under selinux... > > The only functional change is the test at the very end of the > patch; the rest is comments, ascii art, and removing the > now-extraneous XFS_IOC_FSGETXATTRA ioctl. > > Signed-off-by: Eric Sandeen > --- > > diff --git a/fsr/xfs_fsr.c b/fsr/xfs_fsr.c > index c8ef18f..68b9819 100644 > --- a/fsr/xfs_fsr.c > +++ b/fsr/xfs_fsr.c ... > /* > - * If target attr area is less than the temp's (diff < 0) > - * and the target is not local, write a big attr to > - * the temp file to knock the attr out of local format, > - * to match the target. (This should actually *increase* > - * the temp file's forkoffset when the attr moves out > - * of the inode) > + * If target attr area is less than the temp's > + * (diff < 0), write a big attr to the temp file to knock > + * the attr out of local format. > + * (This should actually *increase* the temp file's > + * forkoffset when the attr moves out of the inode) > */ > - if (diff < 0 && fsx.fsx_nextents > 0) { > + if (diff < 0) { Space before tab issue on the line above. Looks fine otherwise, but I wonder if it would also be a good idea to add an informative fsrprintf() here if we proceed when (fsx.fsx_nextents > 0)? Brian > char val[2048]; > memset(val, 'X', 2048); > if (fsetxattr(tfd, name, val, 2048, 0)) { > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From bfoster@redhat.com Thu Nov 12 07:12:58 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 CCA4B7F6B for ; Thu, 12 Nov 2015 07:12:58 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id AC4B430404E for ; Thu, 12 Nov 2015 05:12:55 -0800 (PST) X-ASG-Debug-ID: 1447333974-04cbb0242214f510001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id WF0s8pP15Z9jtWkP (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 12 Nov 2015 05:12:54 -0800 (PST) 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 (Postfix) with ESMTPS id 1D8E1C0D8047 for ; Thu, 12 Nov 2015 13:12:54 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-36.bos.redhat.com [10.18.41.36]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tACDCrKE026138; Thu, 12 Nov 2015 08:12:53 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id 6915F120059; Thu, 12 Nov 2015 08:12:53 -0500 (EST) Date: Thu, 12 Nov 2015 08:12:53 -0500 From: Brian Foster To: Eric Sandeen Cc: xfs@oss.sgi.com Subject: Re: [PATCH] xfs_repair: print XFS_WANT_CORRUPTED info with -vvv Message-ID: <20151112131252.GC5068@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH] xfs_repair: print XFS_WANT_CORRUPTED info with -vvv References: <5643F4B1.40500@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <5643F4B1.40500@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: 1447333974 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Wed, Nov 11, 2015 at 08:08:49PM -0600, Eric Sandeen wrote: > In the kernel, the XFS_WANT_CORRUPTED_* macros print the > caller information via XFS_ERROR_REPORT, but in userspace > this is silenced, because i.e. xfs_repair's job is to find > and fix corruption, not to complain loudly about it. > > However, there are times when we would like to know if > we've hit an unexpected corruption point. To that end, > make "xfs_repair -vvv" enable noisiness from these macros, > so that they will print the function and line of the caller. > > Signed-off-by: Eric Sandeen > --- Reviewed-by: Brian Foster > > diff --git a/include/xfs_mount.h b/include/xfs_mount.h > index 5ec6866..67f3b05 100644 > --- a/include/xfs_mount.h > +++ b/include/xfs_mount.h > @@ -143,6 +143,7 @@ typedef struct xfs_perag { > #define LIBXFS_MOUNT_32BITINOOPT 0x0004 > #define LIBXFS_MOUNT_COMPAT_ATTR 0x0008 > #define LIBXFS_MOUNT_ATTR2 0x0010 > +#define LIBXFS_MOUNT_WANT_CORRUPTED 0x0020 > > #define LIBXFS_BHASHSIZE(sbp) (1<<10) > > diff --git a/libxfs/libxfs_priv.h b/libxfs/libxfs_priv.h > index 9135aac..0f4d3e5 100644 > --- a/libxfs/libxfs_priv.h > +++ b/libxfs/libxfs_priv.h > @@ -147,10 +147,25 @@ enum ce { CE_DEBUG, CE_CONT, CE_NOTE, CE_WARN, CE_ALERT, CE_PANIC }; > #define XFS_TRANS_RESERVE_QUOTA_NBLKS(mp,tp,ip,nblks,ninos,fl) 0 > #define XFS_TRANS_UNRESERVE_QUOTA_NBLKS(mp,tp,ip,nblks,ninos,fl) 0 > #define XFS_TEST_ERROR(expr,a,b,c) ( expr ) > -#define XFS_WANT_CORRUPTED_GOTO(mp, expr, l) \ > - { (mp) = (mp); if (!(expr)) { error = -EFSCORRUPTED; goto l; } } > -#define XFS_WANT_CORRUPTED_RETURN(mp, expr) \ > - { (mp) = (mp); if (!(expr)) { return -EFSCORRUPTED; } } > +#define XFS_WANT_CORRUPTED_GOTO(mp, expr, l) \ > +{ \ > + if (!(expr)) { \ > + if ((mp)->m_flags & LIBXFS_MOUNT_WANT_CORRUPTED) \ > + printf("WANT_CORRUPTED_GOTO at %s:%d\n", \ > + __func__, __LINE__); \ > + error = -EFSCORRUPTED; \ > + goto l; \ > + } \ > +} > +#define XFS_WANT_CORRUPTED_RETURN(mp, expr) \ > +{ \ > + if (!(expr)) { \ > + if ((mp)->m_flags & LIBXFS_MOUNT_WANT_CORRUPTED) \ > + printf("WANT_CORRUPTED_RETURN at %s:%d\n", \ > + __func__, __LINE__); \ > + return -EFSCORRUPTED; \ > + } \ > +} > > #ifdef __GNUC__ > #define __return_address __builtin_return_address(0) > diff --git a/man/man8/xfs_repair.8 b/man/man8/xfs_repair.8 > index 0394c50..1b4d9e3 100644 > --- a/man/man8/xfs_repair.8 > +++ b/man/man8/xfs_repair.8 > @@ -158,7 +158,7 @@ outputs its progress every 15 minutes. Reporting is only activated when > ag_stride is enabled. > .TP > .B \-v > -Verbose output. > +Verbose output. May be specified multiple times to increase verbosity. > .TP > .B \-d > Repair dangerously. Allow > diff --git a/repair/xfs_repair.c b/repair/xfs_repair.c > index bed2ff5..1aeac5b 100644 > --- a/repair/xfs_repair.c > +++ b/repair/xfs_repair.c > @@ -695,6 +695,10 @@ main(int argc, char **argv) > } > mp->m_log = &log; > > + /* Spit out function & line on these corruption macros */ > + if (verbose > 2) > + mp->m_flags |= LIBXFS_MOUNT_WANT_CORRUPTED; > + > /* > * set XFS-independent status vars from the mount/sb structure > */ > > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From sandeen@sandeen.net Thu Nov 12 07:41:27 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 157327F62 for ; Thu, 12 Nov 2015 07:41:27 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 96CDAAC002 for ; Thu, 12 Nov 2015 05:41:26 -0800 (PST) X-ASG-Debug-ID: 1447335682-04bdf03f0313f790001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id iMuoidaTh1T0OZmj for ; Thu, 12 Nov 2015 05:41:23 -0800 (PST) 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 A149061451CC for ; Thu, 12 Nov 2015 07:41:22 -0600 (CST) Subject: Re: [PATCH] xfs: print name of verifier if it fails To: xfs@oss.sgi.com X-ASG-Orig-Subj: Re: [PATCH] xfs: print name of verifier if it fails References: <5643BD7D.4000307@redhat.com> <20151112124046.GA5068@bfoster.bfoster> From: Eric Sandeen Message-ID: <56449702.4010502@sandeen.net> Date: Thu, 12 Nov 2015 07:41:22 -0600 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <20151112124046.GA5068@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: 1447335682 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24330 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 11/12/15 6:40 AM, Brian Foster wrote: > On Wed, Nov 11, 2015 at 04:13:17PM -0600, Eric Sandeen wrote: >> This adds a name to each buf_ops structure, so that if >> a verifier fails we can print the type of verifier that >> failed it. Should be a slight debugging aid, I hope. >> >> Signed-off-by: Eric Sandeen >> --- > > Seems harmless, but is this really necessary when we dump a stack trace? > I suppose that only happens if the error level is set appropriately. > Another option might be to use _RET_IP_. It might not be as pretty, but > we already use it all over the place for tracepoints and such. The main motivator for the patch is userspace, where we have no dump_stack, error level, etc. This patch is just to keep things in sync in libxfs. Thanks, -Eric > Brian > >> >> diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c >> index 3479294..e1e7fe3 100644 >> --- a/fs/xfs/libxfs/xfs_alloc.c >> +++ b/fs/xfs/libxfs/xfs_alloc.c >> @@ -535,6 +535,7 @@ xfs_agfl_write_verify( >> } >> >> const struct xfs_buf_ops xfs_agfl_buf_ops = { >> + .name = "xfs_agfl", >> .verify_read = xfs_agfl_read_verify, >> .verify_write = xfs_agfl_write_verify, >> }; >> @@ -2339,6 +2340,7 @@ xfs_agf_write_verify( >> } >> >> const struct xfs_buf_ops xfs_agf_buf_ops = { >> + .name = "xfs_agf", >> .verify_read = xfs_agf_read_verify, >> .verify_write = xfs_agf_write_verify, >> }; >> diff --git a/fs/xfs/libxfs/xfs_alloc_btree.c b/fs/xfs/libxfs/xfs_alloc_btree.c >> index 90de071..eb8bbfe 100644 >> --- a/fs/xfs/libxfs/xfs_alloc_btree.c >> +++ b/fs/xfs/libxfs/xfs_alloc_btree.c >> @@ -379,6 +379,7 @@ xfs_allocbt_write_verify( >> } >> >> const struct xfs_buf_ops xfs_allocbt_buf_ops = { >> + .name = "xfs_allocbt", >> .verify_read = xfs_allocbt_read_verify, >> .verify_write = xfs_allocbt_write_verify, >> }; >> diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c >> index aa187f7..01a5ecf 100644 >> --- a/fs/xfs/libxfs/xfs_attr_leaf.c >> +++ b/fs/xfs/libxfs/xfs_attr_leaf.c >> @@ -328,6 +328,7 @@ xfs_attr3_leaf_read_verify( >> } >> >> const struct xfs_buf_ops xfs_attr3_leaf_buf_ops = { >> + .name = "xfs_attr3_leaf", >> .verify_read = xfs_attr3_leaf_read_verify, >> .verify_write = xfs_attr3_leaf_write_verify, >> }; >> diff --git a/fs/xfs/libxfs/xfs_attr_remote.c b/fs/xfs/libxfs/xfs_attr_remote.c >> index 5ab95ff..f3ed9bf 100644 >> --- a/fs/xfs/libxfs/xfs_attr_remote.c >> +++ b/fs/xfs/libxfs/xfs_attr_remote.c >> @@ -201,6 +201,7 @@ xfs_attr3_rmt_write_verify( >> } >> >> const struct xfs_buf_ops xfs_attr3_rmt_buf_ops = { >> + .name = "xfs_attr3_rmt", >> .verify_read = xfs_attr3_rmt_read_verify, >> .verify_write = xfs_attr3_rmt_write_verify, >> }; >> diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c >> index 6b0cf65..1637c37 100644 >> --- a/fs/xfs/libxfs/xfs_bmap_btree.c >> +++ b/fs/xfs/libxfs/xfs_bmap_btree.c >> @@ -720,6 +720,7 @@ xfs_bmbt_write_verify( >> } >> >> const struct xfs_buf_ops xfs_bmbt_buf_ops = { >> + .name = "xfs_bmbt", >> .verify_read = xfs_bmbt_read_verify, >> .verify_write = xfs_bmbt_write_verify, >> }; >> diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c >> index e89a0f8..097bf77 100644 >> --- a/fs/xfs/libxfs/xfs_da_btree.c >> +++ b/fs/xfs/libxfs/xfs_da_btree.c >> @@ -245,6 +245,7 @@ xfs_da3_node_read_verify( >> } >> >> const struct xfs_buf_ops xfs_da3_node_buf_ops = { >> + .name = "xfs_da3_node", >> .verify_read = xfs_da3_node_read_verify, >> .verify_write = xfs_da3_node_write_verify, >> }; >> diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c >> index 9c10e2b..aa17cb7 100644 >> --- a/fs/xfs/libxfs/xfs_dir2_block.c >> +++ b/fs/xfs/libxfs/xfs_dir2_block.c >> @@ -123,6 +123,7 @@ xfs_dir3_block_write_verify( >> } >> >> const struct xfs_buf_ops xfs_dir3_block_buf_ops = { >> + .name = "xfs_dir3_block", >> .verify_read = xfs_dir3_block_read_verify, >> .verify_write = xfs_dir3_block_write_verify, >> }; >> diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c >> index af71a84..725fc78 100644 >> --- a/fs/xfs/libxfs/xfs_dir2_data.c >> +++ b/fs/xfs/libxfs/xfs_dir2_data.c >> @@ -305,11 +305,13 @@ xfs_dir3_data_write_verify( >> } >> >> const struct xfs_buf_ops xfs_dir3_data_buf_ops = { >> + .name = "xfs_dir3_data", >> .verify_read = xfs_dir3_data_read_verify, >> .verify_write = xfs_dir3_data_write_verify, >> }; >> >> static const struct xfs_buf_ops xfs_dir3_data_reada_buf_ops = { >> + .name = "xfs_dir3_data_reada", >> .verify_read = xfs_dir3_data_reada_verify, >> .verify_write = xfs_dir3_data_write_verify, >> }; >> diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c >> index 3923e1f..b887fb2 100644 >> --- a/fs/xfs/libxfs/xfs_dir2_leaf.c >> +++ b/fs/xfs/libxfs/xfs_dir2_leaf.c >> @@ -245,11 +245,13 @@ xfs_dir3_leafn_write_verify( >> } >> >> const struct xfs_buf_ops xfs_dir3_leaf1_buf_ops = { >> + .name = "xfs_dir3_leaf1", >> .verify_read = xfs_dir3_leaf1_read_verify, >> .verify_write = xfs_dir3_leaf1_write_verify, >> }; >> >> const struct xfs_buf_ops xfs_dir3_leafn_buf_ops = { >> + .name = "xfs_dir3_leafn", >> .verify_read = xfs_dir3_leafn_read_verify, >> .verify_write = xfs_dir3_leafn_write_verify, >> }; >> diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c >> index 70b0cb2..63ee03d 100644 >> --- a/fs/xfs/libxfs/xfs_dir2_node.c >> +++ b/fs/xfs/libxfs/xfs_dir2_node.c >> @@ -150,6 +150,7 @@ xfs_dir3_free_write_verify( >> } >> >> const struct xfs_buf_ops xfs_dir3_free_buf_ops = { >> + .name = "xfs_dir3_free", >> .verify_read = xfs_dir3_free_read_verify, >> .verify_write = xfs_dir3_free_write_verify, >> }; >> diff --git a/fs/xfs/libxfs/xfs_dquot_buf.c b/fs/xfs/libxfs/xfs_dquot_buf.c >> index 5331b7f..11cefb2 100644 >> --- a/fs/xfs/libxfs/xfs_dquot_buf.c >> +++ b/fs/xfs/libxfs/xfs_dquot_buf.c >> @@ -282,6 +282,7 @@ xfs_dquot_buf_write_verify( >> } >> >> const struct xfs_buf_ops xfs_dquot_buf_ops = { >> + .name = "xfs_dquot", >> .verify_read = xfs_dquot_buf_read_verify, >> .verify_write = xfs_dquot_buf_write_verify, >> }; >> diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c >> index 70c1db9..66d702e 100644 >> --- a/fs/xfs/libxfs/xfs_ialloc.c >> +++ b/fs/xfs/libxfs/xfs_ialloc.c >> @@ -2572,6 +2572,7 @@ xfs_agi_write_verify( >> } >> >> const struct xfs_buf_ops xfs_agi_buf_ops = { >> + .name = "xfs_agi", >> .verify_read = xfs_agi_read_verify, >> .verify_write = xfs_agi_write_verify, >> }; >> diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.c b/fs/xfs/libxfs/xfs_ialloc_btree.c >> index f39b285..6dd44f9 100644 >> --- a/fs/xfs/libxfs/xfs_ialloc_btree.c >> +++ b/fs/xfs/libxfs/xfs_ialloc_btree.c >> @@ -304,6 +304,7 @@ xfs_inobt_write_verify( >> } >> >> const struct xfs_buf_ops xfs_inobt_buf_ops = { >> + .name = "xfs_inobt", >> .verify_read = xfs_inobt_read_verify, >> .verify_write = xfs_inobt_write_verify, >> }; >> diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c >> index 268c00f..1b8d98a 100644 >> --- a/fs/xfs/libxfs/xfs_inode_buf.c >> +++ b/fs/xfs/libxfs/xfs_inode_buf.c >> @@ -132,11 +132,13 @@ xfs_inode_buf_write_verify( >> } >> >> const struct xfs_buf_ops xfs_inode_buf_ops = { >> + .name = "xfs_inode", >> .verify_read = xfs_inode_buf_read_verify, >> .verify_write = xfs_inode_buf_write_verify, >> }; >> >> const struct xfs_buf_ops xfs_inode_buf_ra_ops = { >> + .name = "xxfs_inode_ra", >> .verify_read = xfs_inode_buf_readahead_verify, >> .verify_write = xfs_inode_buf_write_verify, >> }; >> diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c >> index a0b071d..8a53eaa 100644 >> --- a/fs/xfs/libxfs/xfs_sb.c >> +++ b/fs/xfs/libxfs/xfs_sb.c >> @@ -679,11 +679,13 @@ xfs_sb_write_verify( >> } >> >> const struct xfs_buf_ops xfs_sb_buf_ops = { >> + .name = "xfs_sb", >> .verify_read = xfs_sb_read_verify, >> .verify_write = xfs_sb_write_verify, >> }; >> >> const struct xfs_buf_ops xfs_sb_quiet_buf_ops = { >> + .name = "xfs_sb_quiet", >> .verify_read = xfs_sb_quiet_read_verify, >> .verify_write = xfs_sb_write_verify, >> }; >> diff --git a/fs/xfs/libxfs/xfs_symlink_remote.c b/fs/xfs/libxfs/xfs_symlink_remote.c >> index cb6fd20..2e2c671 100644 >> --- a/fs/xfs/libxfs/xfs_symlink_remote.c >> +++ b/fs/xfs/libxfs/xfs_symlink_remote.c >> @@ -168,6 +168,7 @@ xfs_symlink_write_verify( >> } >> >> const struct xfs_buf_ops xfs_symlink_buf_ops = { >> + .name = "xfs_symlink", >> .verify_read = xfs_symlink_read_verify, >> .verify_write = xfs_symlink_write_verify, >> }; >> diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h >> index c79b717..c75721a 100644 >> --- a/fs/xfs/xfs_buf.h >> +++ b/fs/xfs/xfs_buf.h >> @@ -132,6 +132,7 @@ struct xfs_buf_map { >> struct xfs_buf_map (map) = { .bm_bn = (blkno), .bm_len = (numblk) }; >> >> struct xfs_buf_ops { >> + char *name; >> void (*verify_read)(struct xfs_buf *); >> void (*verify_write)(struct xfs_buf *); >> }; >> diff --git a/fs/xfs/xfs_error.c b/fs/xfs/xfs_error.c >> index 74d0e59..88693a9 100644 >> --- a/fs/xfs/xfs_error.c >> +++ b/fs/xfs/xfs_error.c >> @@ -164,9 +164,9 @@ xfs_verifier_error( >> { >> struct xfs_mount *mp = bp->b_target->bt_mount; >> >> - xfs_alert(mp, "Metadata %s detected at %pF, block 0x%llx", >> + xfs_alert(mp, "Metadata %s detected at %pF, %s block 0x%llx", >> bp->b_error == -EFSBADCRC ? "CRC error" : "corruption", >> - __return_address, bp->b_bn); >> + __return_address, bp->b_ops->name, bp->b_bn); >> >> xfs_alert(mp, "Unmount and run xfs_repair"); >> >> >> _______________________________________________ >> 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 Nov 12 07:55:45 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 0D2837F62 for ; Thu, 12 Nov 2015 07:55:45 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id EE484304032 for ; Thu, 12 Nov 2015 05:55:44 -0800 (PST) X-ASG-Debug-ID: 1447336542-04cb6c296a13a730001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id yzkV9BJkftYArSkT (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 12 Nov 2015 05:55:43 -0800 (PST) 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 (Postfix) with ESMTPS id D1816A4526; Thu, 12 Nov 2015 13:55:42 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-36.bos.redhat.com [10.18.41.36]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tACDtgTF009404; Thu, 12 Nov 2015 08:55:42 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id CE0FB120059; Thu, 12 Nov 2015 08:55:41 -0500 (EST) Date: Thu, 12 Nov 2015 08:55:41 -0500 From: Brian Foster To: Eric Sandeen Cc: xfs@oss.sgi.com Subject: Re: [PATCH] xfs: print name of verifier if it fails Message-ID: <20151112135541.GD5068@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH] xfs: print name of verifier if it fails References: <5643BD7D.4000307@redhat.com> <20151112124046.GA5068@bfoster.bfoster> <56449702.4010502@sandeen.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <56449702.4010502@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: 1447336543 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Thu, Nov 12, 2015 at 07:41:22AM -0600, Eric Sandeen wrote: > > > On 11/12/15 6:40 AM, Brian Foster wrote: > > On Wed, Nov 11, 2015 at 04:13:17PM -0600, Eric Sandeen wrote: > >> This adds a name to each buf_ops structure, so that if > >> a verifier fails we can print the type of verifier that > >> failed it. Should be a slight debugging aid, I hope. > >> > >> Signed-off-by: Eric Sandeen > >> --- > > > > Seems harmless, but is this really necessary when we dump a stack trace? > > I suppose that only happens if the error level is set appropriately. > > Another option might be to use _RET_IP_. It might not be as pretty, but > > we already use it all over the place for tracepoints and such. > > The main motivator for the patch is userspace, where we have no dump_stack, > error level, etc. This patch is just to keep things in sync in libxfs. > Ah, sounds good to me: Reviewed-by: Brian Foster > Thanks, > -Eric > > > Brian > > > >> > >> diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c > >> index 3479294..e1e7fe3 100644 > >> --- a/fs/xfs/libxfs/xfs_alloc.c > >> +++ b/fs/xfs/libxfs/xfs_alloc.c > >> @@ -535,6 +535,7 @@ xfs_agfl_write_verify( > >> } > >> > >> const struct xfs_buf_ops xfs_agfl_buf_ops = { > >> + .name = "xfs_agfl", > >> .verify_read = xfs_agfl_read_verify, > >> .verify_write = xfs_agfl_write_verify, > >> }; > >> @@ -2339,6 +2340,7 @@ xfs_agf_write_verify( > >> } > >> > >> const struct xfs_buf_ops xfs_agf_buf_ops = { > >> + .name = "xfs_agf", > >> .verify_read = xfs_agf_read_verify, > >> .verify_write = xfs_agf_write_verify, > >> }; > >> diff --git a/fs/xfs/libxfs/xfs_alloc_btree.c b/fs/xfs/libxfs/xfs_alloc_btree.c > >> index 90de071..eb8bbfe 100644 > >> --- a/fs/xfs/libxfs/xfs_alloc_btree.c > >> +++ b/fs/xfs/libxfs/xfs_alloc_btree.c > >> @@ -379,6 +379,7 @@ xfs_allocbt_write_verify( > >> } > >> > >> const struct xfs_buf_ops xfs_allocbt_buf_ops = { > >> + .name = "xfs_allocbt", > >> .verify_read = xfs_allocbt_read_verify, > >> .verify_write = xfs_allocbt_write_verify, > >> }; > >> diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c > >> index aa187f7..01a5ecf 100644 > >> --- a/fs/xfs/libxfs/xfs_attr_leaf.c > >> +++ b/fs/xfs/libxfs/xfs_attr_leaf.c > >> @@ -328,6 +328,7 @@ xfs_attr3_leaf_read_verify( > >> } > >> > >> const struct xfs_buf_ops xfs_attr3_leaf_buf_ops = { > >> + .name = "xfs_attr3_leaf", > >> .verify_read = xfs_attr3_leaf_read_verify, > >> .verify_write = xfs_attr3_leaf_write_verify, > >> }; > >> diff --git a/fs/xfs/libxfs/xfs_attr_remote.c b/fs/xfs/libxfs/xfs_attr_remote.c > >> index 5ab95ff..f3ed9bf 100644 > >> --- a/fs/xfs/libxfs/xfs_attr_remote.c > >> +++ b/fs/xfs/libxfs/xfs_attr_remote.c > >> @@ -201,6 +201,7 @@ xfs_attr3_rmt_write_verify( > >> } > >> > >> const struct xfs_buf_ops xfs_attr3_rmt_buf_ops = { > >> + .name = "xfs_attr3_rmt", > >> .verify_read = xfs_attr3_rmt_read_verify, > >> .verify_write = xfs_attr3_rmt_write_verify, > >> }; > >> diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c > >> index 6b0cf65..1637c37 100644 > >> --- a/fs/xfs/libxfs/xfs_bmap_btree.c > >> +++ b/fs/xfs/libxfs/xfs_bmap_btree.c > >> @@ -720,6 +720,7 @@ xfs_bmbt_write_verify( > >> } > >> > >> const struct xfs_buf_ops xfs_bmbt_buf_ops = { > >> + .name = "xfs_bmbt", > >> .verify_read = xfs_bmbt_read_verify, > >> .verify_write = xfs_bmbt_write_verify, > >> }; > >> diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c > >> index e89a0f8..097bf77 100644 > >> --- a/fs/xfs/libxfs/xfs_da_btree.c > >> +++ b/fs/xfs/libxfs/xfs_da_btree.c > >> @@ -245,6 +245,7 @@ xfs_da3_node_read_verify( > >> } > >> > >> const struct xfs_buf_ops xfs_da3_node_buf_ops = { > >> + .name = "xfs_da3_node", > >> .verify_read = xfs_da3_node_read_verify, > >> .verify_write = xfs_da3_node_write_verify, > >> }; > >> diff --git a/fs/xfs/libxfs/xfs_dir2_block.c b/fs/xfs/libxfs/xfs_dir2_block.c > >> index 9c10e2b..aa17cb7 100644 > >> --- a/fs/xfs/libxfs/xfs_dir2_block.c > >> +++ b/fs/xfs/libxfs/xfs_dir2_block.c > >> @@ -123,6 +123,7 @@ xfs_dir3_block_write_verify( > >> } > >> > >> const struct xfs_buf_ops xfs_dir3_block_buf_ops = { > >> + .name = "xfs_dir3_block", > >> .verify_read = xfs_dir3_block_read_verify, > >> .verify_write = xfs_dir3_block_write_verify, > >> }; > >> diff --git a/fs/xfs/libxfs/xfs_dir2_data.c b/fs/xfs/libxfs/xfs_dir2_data.c > >> index af71a84..725fc78 100644 > >> --- a/fs/xfs/libxfs/xfs_dir2_data.c > >> +++ b/fs/xfs/libxfs/xfs_dir2_data.c > >> @@ -305,11 +305,13 @@ xfs_dir3_data_write_verify( > >> } > >> > >> const struct xfs_buf_ops xfs_dir3_data_buf_ops = { > >> + .name = "xfs_dir3_data", > >> .verify_read = xfs_dir3_data_read_verify, > >> .verify_write = xfs_dir3_data_write_verify, > >> }; > >> > >> static const struct xfs_buf_ops xfs_dir3_data_reada_buf_ops = { > >> + .name = "xfs_dir3_data_reada", > >> .verify_read = xfs_dir3_data_reada_verify, > >> .verify_write = xfs_dir3_data_write_verify, > >> }; > >> diff --git a/fs/xfs/libxfs/xfs_dir2_leaf.c b/fs/xfs/libxfs/xfs_dir2_leaf.c > >> index 3923e1f..b887fb2 100644 > >> --- a/fs/xfs/libxfs/xfs_dir2_leaf.c > >> +++ b/fs/xfs/libxfs/xfs_dir2_leaf.c > >> @@ -245,11 +245,13 @@ xfs_dir3_leafn_write_verify( > >> } > >> > >> const struct xfs_buf_ops xfs_dir3_leaf1_buf_ops = { > >> + .name = "xfs_dir3_leaf1", > >> .verify_read = xfs_dir3_leaf1_read_verify, > >> .verify_write = xfs_dir3_leaf1_write_verify, > >> }; > >> > >> const struct xfs_buf_ops xfs_dir3_leafn_buf_ops = { > >> + .name = "xfs_dir3_leafn", > >> .verify_read = xfs_dir3_leafn_read_verify, > >> .verify_write = xfs_dir3_leafn_write_verify, > >> }; > >> diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c > >> index 70b0cb2..63ee03d 100644 > >> --- a/fs/xfs/libxfs/xfs_dir2_node.c > >> +++ b/fs/xfs/libxfs/xfs_dir2_node.c > >> @@ -150,6 +150,7 @@ xfs_dir3_free_write_verify( > >> } > >> > >> const struct xfs_buf_ops xfs_dir3_free_buf_ops = { > >> + .name = "xfs_dir3_free", > >> .verify_read = xfs_dir3_free_read_verify, > >> .verify_write = xfs_dir3_free_write_verify, > >> }; > >> diff --git a/fs/xfs/libxfs/xfs_dquot_buf.c b/fs/xfs/libxfs/xfs_dquot_buf.c > >> index 5331b7f..11cefb2 100644 > >> --- a/fs/xfs/libxfs/xfs_dquot_buf.c > >> +++ b/fs/xfs/libxfs/xfs_dquot_buf.c > >> @@ -282,6 +282,7 @@ xfs_dquot_buf_write_verify( > >> } > >> > >> const struct xfs_buf_ops xfs_dquot_buf_ops = { > >> + .name = "xfs_dquot", > >> .verify_read = xfs_dquot_buf_read_verify, > >> .verify_write = xfs_dquot_buf_write_verify, > >> }; > >> diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c > >> index 70c1db9..66d702e 100644 > >> --- a/fs/xfs/libxfs/xfs_ialloc.c > >> +++ b/fs/xfs/libxfs/xfs_ialloc.c > >> @@ -2572,6 +2572,7 @@ xfs_agi_write_verify( > >> } > >> > >> const struct xfs_buf_ops xfs_agi_buf_ops = { > >> + .name = "xfs_agi", > >> .verify_read = xfs_agi_read_verify, > >> .verify_write = xfs_agi_write_verify, > >> }; > >> diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.c b/fs/xfs/libxfs/xfs_ialloc_btree.c > >> index f39b285..6dd44f9 100644 > >> --- a/fs/xfs/libxfs/xfs_ialloc_btree.c > >> +++ b/fs/xfs/libxfs/xfs_ialloc_btree.c > >> @@ -304,6 +304,7 @@ xfs_inobt_write_verify( > >> } > >> > >> const struct xfs_buf_ops xfs_inobt_buf_ops = { > >> + .name = "xfs_inobt", > >> .verify_read = xfs_inobt_read_verify, > >> .verify_write = xfs_inobt_write_verify, > >> }; > >> diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c > >> index 268c00f..1b8d98a 100644 > >> --- a/fs/xfs/libxfs/xfs_inode_buf.c > >> +++ b/fs/xfs/libxfs/xfs_inode_buf.c > >> @@ -132,11 +132,13 @@ xfs_inode_buf_write_verify( > >> } > >> > >> const struct xfs_buf_ops xfs_inode_buf_ops = { > >> + .name = "xfs_inode", > >> .verify_read = xfs_inode_buf_read_verify, > >> .verify_write = xfs_inode_buf_write_verify, > >> }; > >> > >> const struct xfs_buf_ops xfs_inode_buf_ra_ops = { > >> + .name = "xxfs_inode_ra", > >> .verify_read = xfs_inode_buf_readahead_verify, > >> .verify_write = xfs_inode_buf_write_verify, > >> }; > >> diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c > >> index a0b071d..8a53eaa 100644 > >> --- a/fs/xfs/libxfs/xfs_sb.c > >> +++ b/fs/xfs/libxfs/xfs_sb.c > >> @@ -679,11 +679,13 @@ xfs_sb_write_verify( > >> } > >> > >> const struct xfs_buf_ops xfs_sb_buf_ops = { > >> + .name = "xfs_sb", > >> .verify_read = xfs_sb_read_verify, > >> .verify_write = xfs_sb_write_verify, > >> }; > >> > >> const struct xfs_buf_ops xfs_sb_quiet_buf_ops = { > >> + .name = "xfs_sb_quiet", > >> .verify_read = xfs_sb_quiet_read_verify, > >> .verify_write = xfs_sb_write_verify, > >> }; > >> diff --git a/fs/xfs/libxfs/xfs_symlink_remote.c b/fs/xfs/libxfs/xfs_symlink_remote.c > >> index cb6fd20..2e2c671 100644 > >> --- a/fs/xfs/libxfs/xfs_symlink_remote.c > >> +++ b/fs/xfs/libxfs/xfs_symlink_remote.c > >> @@ -168,6 +168,7 @@ xfs_symlink_write_verify( > >> } > >> > >> const struct xfs_buf_ops xfs_symlink_buf_ops = { > >> + .name = "xfs_symlink", > >> .verify_read = xfs_symlink_read_verify, > >> .verify_write = xfs_symlink_write_verify, > >> }; > >> diff --git a/fs/xfs/xfs_buf.h b/fs/xfs/xfs_buf.h > >> index c79b717..c75721a 100644 > >> --- a/fs/xfs/xfs_buf.h > >> +++ b/fs/xfs/xfs_buf.h > >> @@ -132,6 +132,7 @@ struct xfs_buf_map { > >> struct xfs_buf_map (map) = { .bm_bn = (blkno), .bm_len = (numblk) }; > >> > >> struct xfs_buf_ops { > >> + char *name; > >> void (*verify_read)(struct xfs_buf *); > >> void (*verify_write)(struct xfs_buf *); > >> }; > >> diff --git a/fs/xfs/xfs_error.c b/fs/xfs/xfs_error.c > >> index 74d0e59..88693a9 100644 > >> --- a/fs/xfs/xfs_error.c > >> +++ b/fs/xfs/xfs_error.c > >> @@ -164,9 +164,9 @@ xfs_verifier_error( > >> { > >> struct xfs_mount *mp = bp->b_target->bt_mount; > >> > >> - xfs_alert(mp, "Metadata %s detected at %pF, block 0x%llx", > >> + xfs_alert(mp, "Metadata %s detected at %pF, %s block 0x%llx", > >> bp->b_error == -EFSBADCRC ? "CRC error" : "corruption", > >> - __return_address, bp->b_bn); > >> + __return_address, bp->b_ops->name, bp->b_bn); > >> > >> xfs_alert(mp, "Unmount and run xfs_repair"); > >> > >> > >> _______________________________________________ > >> 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 > > > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From penguin-kernel@I-love.SAKURA.ne.jp Thu Nov 12 08:12:53 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 D90037F62 for ; Thu, 12 Nov 2015 08:12:53 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id B6476304043 for ; Thu, 12 Nov 2015 06:12:50 -0800 (PST) X-ASG-Debug-ID: 1447337561-04cbb02423150840001-NocioJ Received: from www262.sakura.ne.jp (www262.sakura.ne.jp [202.181.97.72]) by cuda.sgi.com with ESMTP id ue798DcDINYxiChk (version=TLSv1 cipher=DHE-RSA-CAMELLIA256-SHA bits=256 verify=NO) for ; Thu, 12 Nov 2015 06:12:42 -0800 (PST) X-Barracuda-Envelope-From: penguin-kernel@I-love.SAKURA.ne.jp X-Barracuda-Apparent-Source-IP: 202.181.97.72 Received: from fsav402.sakura.ne.jp (fsav402.sakura.ne.jp [133.242.250.101]) by www262.sakura.ne.jp (8.14.5/8.14.5) with ESMTP id tACECZW6028251; Thu, 12 Nov 2015 23:12:35 +0900 (JST) (envelope-from penguin-kernel@I-love.SAKURA.ne.jp) Received: from www262.sakura.ne.jp (202.181.97.72) by fsav402.sakura.ne.jp (F-Secure/fsigk_smtp/522/fsav402.sakura.ne.jp); Thu, 12 Nov 2015 23:12:35 +0900 (JST) X-Virus-Status: clean(F-Secure/fsigk_smtp/522/fsav402.sakura.ne.jp) Received: from [192.168.1.8] (softbank126094077227.bbtec.net [126.94.77.227]) (authenticated bits=0) by www262.sakura.ne.jp (8.14.5/8.14.5) with ESMTP id tACECNOQ028171 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Thu, 12 Nov 2015 23:12:35 +0900 (JST) (envelope-from penguin-kernel@I-love.SAKURA.ne.jp) Subject: Re: memory reclaim problems on fs usage To: =?UTF-8?Q?Arkadiusz_Mi=c5=9bkiewicz?= X-ASG-Orig-Subj: Re: memory reclaim problems on fs usage References: <201511102313.36685.arekm@maven.pl> <201511111719.44035.arekm@maven.pl> <201511120719.EBF35970.OtSOHOVFJMFQFL@I-love.SAKURA.ne.jp> <201511120706.10739.arekm@maven.pl> Cc: linux-mm@kvack.org, xfs@oss.sgi.com From: Tetsuo Handa Message-ID: <56449E44.7020407@I-love.SAKURA.ne.jp> Date: Thu, 12 Nov 2015 23:12:20 +0900 User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <201511120706.10739.arekm@maven.pl> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit X-Barracuda-Connect: www262.sakura.ne.jp[202.181.97.72] X-Barracuda-Start-Time: 1447337562 X-Barracuda-Encrypted: DHE-RSA-CAMELLIA256-SHA X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24330 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 2015/11/12 15:06, Arkadiusz Miśkiewicz wrote: > On Wednesday 11 of November 2015, Tetsuo Handa wrote: >> Arkadiusz Mi?kiewicz wrote: >>> This patch is against which tree? (tried 4.1, 4.2 and 4.3) >> >> Oops. Whitespace-damaged. This patch is for vanilla 4.1.2. >> Reposting with one condition corrected. > > Here is log: > > http://ixion.pld-linux.org/~arekm/log-mm-1.txt.gz > > Uncompresses is 1.4MB, so not posting here. > Thank you for the log. The result is unexpected for me. What I feel strange is that free: remained below min: level. While GFP_ATOMIC allocations can access memory reserves, I think that these free: values are too small. Memory allocated by GFP_ATOMIC should be released shortly, or any __GFP_WAIT allocations would stall for long. [ 8633.753528] Node 0 Normal free:128kB min:7104kB low:8880kB high:10656kB active_anon:59008kB inactive_anon:75240kB active_file:14712kB inactive_file:3256960kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:20kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:697520kB slab_unreclaimable:274524kB kernel_stack:2000kB pagetables:2088kB unstable:0kB bounce:0kB free_pcp:1072kB local_pcp:672kB free_cma:128kB writeback_tmp:0kB pages_scanned:176 all_unreclaimable? no [ 8678.467783] Node 0 Normal free:228kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3244288kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:4kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:697376kB slab_unreclaimable:194712kB kernel_stack:1968kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:796kB local_pcp:64kB free_cma:128kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? no [ 9460.400303] Node 0 Normal free:128kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3241920kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:0kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:697376kB slab_unreclaimable:194860kB kernel_stack:1920kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:584kB local_pcp:584kB free_cma:128kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? no [ 9462.401840] Node 0 Normal free:128kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3241920kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:0kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:697376kB slab_unreclaimable:194860kB kernel_stack:1920kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:584kB local_pcp:584kB free_cma:128kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? no [ 9464.403368] Node 0 Normal free:128kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3241920kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:0kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:697376kB slab_unreclaimable:194860kB kernel_stack:1920kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:584kB local_pcp:584kB free_cma:128kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? no [ 9466.404900] Node 0 Normal free:128kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3241920kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:0kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:697376kB slab_unreclaimable:194860kB kernel_stack:1920kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:584kB local_pcp:584kB free_cma:128kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? no [ 9468.406432] Node 0 Normal free:128kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3241920kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:0kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:697376kB slab_unreclaimable:194860kB kernel_stack:1920kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:584kB local_pcp:584kB free_cma:128kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? no [ 9470.407964] Node 0 Normal free:128kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3241920kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:0kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:697376kB slab_unreclaimable:194860kB kernel_stack:1920kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:584kB local_pcp:584kB free_cma:128kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? no [ 9472.409498] Node 0 Normal free:128kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3241920kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:0kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:697376kB slab_unreclaimable:194860kB kernel_stack:1920kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:584kB local_pcp:584kB free_cma:128kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? no [ 9474.411031] Node 0 Normal free:128kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3241920kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:0kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:697376kB slab_unreclaimable:194860kB kernel_stack:1920kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:584kB local_pcp:584kB free_cma:128kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? no [ 9476.412561] Node 0 Normal free:128kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3241920kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:0kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:697376kB slab_unreclaimable:194860kB kernel_stack:1920kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:584kB local_pcp:584kB free_cma:128kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? no [ 9478.414094] Node 0 Normal free:128kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3241920kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:0kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:697376kB slab_unreclaimable:194860kB kernel_stack:1920kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:584kB local_pcp:584kB free_cma:128kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? no [ 9480.415627] Node 0 Normal free:128kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3241920kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:0kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:697376kB slab_unreclaimable:194860kB kernel_stack:1920kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:584kB local_pcp:584kB free_cma:128kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? no [ 9482.417161] Node 0 Normal free:128kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3241920kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:0kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:697376kB slab_unreclaimable:194860kB kernel_stack:1920kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:584kB local_pcp:584kB free_cma:128kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? no [ 9484.418691] Node 0 Normal free:128kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3241920kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:0kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:697376kB slab_unreclaimable:194860kB kernel_stack:1920kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:584kB local_pcp:584kB free_cma:128kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? no [ 9486.420224] Node 0 Normal free:128kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3241920kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:0kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:697376kB slab_unreclaimable:194860kB kernel_stack:1920kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:584kB local_pcp:584kB free_cma:128kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? no [ 9488.421755] Node 0 Normal free:128kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3241920kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:0kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:697376kB slab_unreclaimable:194860kB kernel_stack:1920kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:584kB local_pcp:584kB free_cma:128kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? no [ 9490.423290] Node 0 Normal free:128kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3241920kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:0kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:697376kB slab_unreclaimable:194860kB kernel_stack:1920kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:584kB local_pcp:584kB free_cma:128kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? no [ 9492.424822] Node 0 Normal free:128kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3241920kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:0kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:697376kB slab_unreclaimable:194860kB kernel_stack:1920kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:584kB local_pcp:584kB free_cma:128kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? no [ 9494.426353] Node 0 Normal free:128kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3241920kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:0kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:697376kB slab_unreclaimable:194860kB kernel_stack:1920kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:584kB local_pcp:584kB free_cma:128kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? no [ 9496.427886] Node 0 Normal free:128kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3241920kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:0kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:697376kB slab_unreclaimable:194860kB kernel_stack:1920kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:584kB local_pcp:584kB free_cma:128kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? no [ 9498.429419] Node 0 Normal free:128kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3241920kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:0kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:697376kB slab_unreclaimable:194860kB kernel_stack:1920kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:584kB local_pcp:584kB free_cma:128kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? no [ 9500.430955] Node 0 Normal free:128kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3241920kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:0kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:697376kB slab_unreclaimable:194860kB kernel_stack:1920kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:584kB local_pcp:584kB free_cma:128kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? no [ 9502.432503] Node 0 Normal free:40kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3240344kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:0kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:697304kB slab_unreclaimable:194896kB kernel_stack:1920kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:128kB writeback_tmp:0kB pages_scanned:20 all_unreclaimable? no [ 9504.434015] Node 0 Normal free:404kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3238768kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:0kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:697304kB slab_unreclaimable:194928kB kernel_stack:1920kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:128kB writeback_tmp:0kB pages_scanned:20 all_unreclaimable? no [ 9506.435566] Node 0 Normal free:280kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3237192kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:0kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:697304kB slab_unreclaimable:194960kB kernel_stack:1920kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:68kB local_pcp:0kB free_cma:128kB writeback_tmp:0kB pages_scanned:20 all_unreclaimable? no [ 9508.437089] Node 0 Normal free:128kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3235616kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:0kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:697304kB slab_unreclaimable:194972kB kernel_stack:1920kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:128kB writeback_tmp:0kB pages_scanned:20 all_unreclaimable? no [ 9510.438640] Node 0 Normal free:200kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3234040kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:0kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:697232kB slab_unreclaimable:194980kB kernel_stack:1920kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:136kB local_pcp:0kB free_cma:128kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? no [ 9512.440155] Node 0 Normal free:128kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3232464kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:0kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:697232kB slab_unreclaimable:194984kB kernel_stack:1920kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:128kB writeback_tmp:0kB pages_scanned:20 all_unreclaimable? no [ 9514.441700] Node 0 Normal free:616kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3230888kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:0kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:697232kB slab_unreclaimable:194996kB kernel_stack:1920kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:148kB local_pcp:0kB free_cma:128kB writeback_tmp:0kB pages_scanned:20 all_unreclaimable? no [ 9516.443219] Node 0 Normal free:128kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3229312kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:0kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:697232kB slab_unreclaimable:195040kB kernel_stack:1920kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:128kB writeback_tmp:0kB pages_scanned:20 all_unreclaimable? no [ 9518.444745] Node 0 Normal free:128kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3227736kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:0kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:697160kB slab_unreclaimable:195076kB kernel_stack:1920kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:128kB writeback_tmp:0kB pages_scanned:20 all_unreclaimable? no [ 9520.446278] Node 0 Normal free:128kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3226164kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:0kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:697160kB slab_unreclaimable:195104kB kernel_stack:1920kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:128kB writeback_tmp:0kB pages_scanned:16 all_unreclaimable? no [ 9522.447819] Node 0 Normal free:412kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3224596kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:0kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:697156kB slab_unreclaimable:195132kB kernel_stack:1920kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:68kB local_pcp:0kB free_cma:128kB writeback_tmp:0kB pages_scanned:16 all_unreclaimable? no [ 9524.449349] Node 0 Normal free:1544kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3223028kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:0kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:697088kB slab_unreclaimable:195152kB kernel_stack:1920kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:12kB local_pcp:0kB free_cma:128kB writeback_tmp:0kB pages_scanned:16 all_unreclaimable? no [ 9526.450875] Node 0 Normal free:404kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3221460kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:0kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:697080kB slab_unreclaimable:195196kB kernel_stack:1920kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:128kB writeback_tmp:0kB pages_scanned:16 all_unreclaimable? no [ 9528.452403] Node 0 Normal free:128kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3219892kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:0kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:697080kB slab_unreclaimable:195228kB kernel_stack:1920kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:128kB writeback_tmp:0kB pages_scanned:16 all_unreclaimable? no [ 9530.453942] Node 0 Normal free:128kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3218324kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:0kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:697080kB slab_unreclaimable:195248kB kernel_stack:1920kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:128kB writeback_tmp:0kB pages_scanned:16 all_unreclaimable? no [ 9532.455470] Node 0 Normal free:348kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3216756kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:0kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:697012kB slab_unreclaimable:195272kB kernel_stack:1920kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:88kB local_pcp:0kB free_cma:128kB writeback_tmp:0kB pages_scanned:16 all_unreclaimable? no [ 9534.457005] Node 0 Normal free:1268kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3215188kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:0kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:697012kB slab_unreclaimable:195300kB kernel_stack:1920kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:120kB local_pcp:0kB free_cma:128kB writeback_tmp:0kB pages_scanned:16 all_unreclaimable? no [ 9536.458545] Node 0 Normal free:128kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3213620kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:0kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:697008kB slab_unreclaimable:195316kB kernel_stack:1920kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:128kB writeback_tmp:0kB pages_scanned:16 all_unreclaimable? no [ 9538.460069] Node 0 Normal free:0kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3212052kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:0kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:696952kB slab_unreclaimable:195352kB kernel_stack:1920kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:128kB writeback_tmp:0kB pages_scanned:16 all_unreclaimable? no [ 9540.461626] Node 0 Normal free:128kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3210484kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:0kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:696952kB slab_unreclaimable:195356kB kernel_stack:1920kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:128kB writeback_tmp:0kB pages_scanned:16 all_unreclaimable? no [ 9542.463166] Node 0 Normal free:1696kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3208924kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:0kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:696952kB slab_unreclaimable:195348kB kernel_stack:1920kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:128kB writeback_tmp:0kB pages_scanned:12 all_unreclaimable? no [ 9544.465161] Node 0 Normal free:2756kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3207364kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:0kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:696948kB slab_unreclaimable:195348kB kernel_stack:1920kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:112kB local_pcp:112kB free_cma:128kB writeback_tmp:0kB pages_scanned:12 all_unreclaimable? no [ 9544.465338] Node 0 Normal free:2756kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3207364kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:0kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:696948kB slab_unreclaimable:195348kB kernel_stack:1920kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:112kB local_pcp:112kB free_cma:128kB writeback_tmp:0kB pages_scanned:12 all_unreclaimable? no [ 9544.465498] Node 0 Normal free:2756kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3207364kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:0kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:696948kB slab_unreclaimable:195348kB kernel_stack:1920kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:112kB local_pcp:112kB free_cma:128kB writeback_tmp:0kB pages_scanned:12 all_unreclaimable? no [ 9544.465662] Node 0 Normal free:2756kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3207364kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:0kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:696948kB slab_unreclaimable:195348kB kernel_stack:1920kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:112kB local_pcp:112kB free_cma:128kB writeback_tmp:0kB pages_scanned:12 all_unreclaimable? no [ 9544.465825] Node 0 Normal free:2756kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3207364kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:0kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:696948kB slab_unreclaimable:195348kB kernel_stack:1920kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:112kB local_pcp:112kB free_cma:128kB writeback_tmp:0kB pages_scanned:12 all_unreclaimable? no [ 9544.465984] Node 0 Normal free:2756kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3207364kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:0kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:696948kB slab_unreclaimable:195348kB kernel_stack:1920kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:112kB local_pcp:112kB free_cma:128kB writeback_tmp:0kB pages_scanned:12 all_unreclaimable? no [ 9544.466143] Node 0 Normal free:2756kB min:7104kB low:8880kB high:10656kB active_anon:58992kB inactive_anon:75240kB active_file:14732kB inactive_file:3207364kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:5242880kB managed:5109980kB mlocked:0kB dirty:0kB writeback:0kB mapped:7368kB shmem:0kB slab_reclaimable:696948kB slab_unreclaimable:195348kB kernel_stack:1920kB pagetables:2084kB unstable:0kB bounce:0kB free_pcp:112kB local_pcp:112kB free_cma:128kB writeback_tmp:0kB pages_scanned:12 all_unreclaimable? no There is no OOM victims thus ALLOC_NO_WATERMARKS is not by TIF_MEMDIE. There are many stalls which lasted for finite period. Sometimes the system slowed down, but it was not a livelock. [ 1065.668820] MemAlloc-Info: 4 stalling task, 0 dying task, 0 victim task. [ 1075.676226] MemAlloc-Info: 6 stalling task, 0 dying task, 0 victim task. [ 1085.683607] MemAlloc-Info: 6 stalling task, 0 dying task, 0 victim task. [ 1095.690955] MemAlloc-Info: 6 stalling task, 0 dying task, 0 victim task. [ 1105.698273] MemAlloc-Info: 6 stalling task, 0 dying task, 0 victim task. [ 1115.705598] MemAlloc-Info: 6 stalling task, 0 dying task, 0 victim task. [ 1125.712926] MemAlloc-Info: 6 stalling task, 0 dying task, 0 victim task. [ 1145.727590] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 1155.734973] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 1165.742333] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 1175.749707] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 1185.757076] MemAlloc-Info: 2 stalling task, 0 dying task, 0 victim task. [ 1195.764440] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 1205.771807] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 1215.779177] MemAlloc-Info: 3 stalling task, 0 dying task, 0 victim task. [ 1235.793909] MemAlloc-Info: 2 stalling task, 0 dying task, 0 victim task. [ 1245.801276] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 1255.808647] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 1275.823377] MemAlloc-Info: 4 stalling task, 0 dying task, 0 victim task. [ 1285.830754] MemAlloc-Info: 4 stalling task, 0 dying task, 0 victim task. [ 1295.838130] MemAlloc-Info: 5 stalling task, 0 dying task, 0 victim task. [ 1305.845492] MemAlloc-Info: 3 stalling task, 0 dying task, 0 victim task. [ 1315.852860] MemAlloc-Info: 4 stalling task, 0 dying task, 0 victim task. [ 1325.860228] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 1335.867595] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 1345.874966] MemAlloc-Info: 5 stalling task, 0 dying task, 0 victim task. [ 1365.889706] MemAlloc-Info: 2 stalling task, 0 dying task, 0 victim task. [ 1375.897073] MemAlloc-Info: 3 stalling task, 0 dying task, 0 victim task. [ 1385.904443] MemAlloc-Info: 4 stalling task, 0 dying task, 0 victim task. [ 1405.919177] MemAlloc-Info: 5 stalling task, 0 dying task, 0 victim task. [ 1415.926283] MemAlloc-Info: 4 stalling task, 0 dying task, 0 victim task. [ 1425.933051] MemAlloc-Info: 4 stalling task, 0 dying task, 0 victim task. [ 1435.939906] MemAlloc-Info: 4 stalling task, 0 dying task, 0 victim task. [ 1445.947270] MemAlloc-Info: 4 stalling task, 0 dying task, 0 victim task. [ 1455.954635] MemAlloc-Info: 4 stalling task, 0 dying task, 0 victim task. [ 1465.961996] MemAlloc-Info: 3 stalling task, 0 dying task, 0 victim task. [ 1475.969365] MemAlloc-Info: 3 stalling task, 0 dying task, 0 victim task. [ 1485.976728] MemAlloc-Info: 3 stalling task, 0 dying task, 0 victim task. [ 1495.984092] MemAlloc-Info: 3 stalling task, 0 dying task, 0 victim task. [ 1505.991462] MemAlloc-Info: 3 stalling task, 0 dying task, 0 victim task. [ 1515.998823] MemAlloc-Info: 3 stalling task, 0 dying task, 0 victim task. [ 1526.006189] MemAlloc-Info: 3 stalling task, 0 dying task, 0 victim task. [ 1536.013556] MemAlloc-Info: 3 stalling task, 0 dying task, 0 victim task. [ 1556.028246] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 1576.042951] MemAlloc-Info: 5 stalling task, 0 dying task, 0 victim task. [ 1586.050273] MemAlloc-Info: 3 stalling task, 0 dying task, 0 victim task. [ 1596.057617] MemAlloc-Info: 6 stalling task, 0 dying task, 0 victim task. [ 1606.064958] MemAlloc-Info: 6 stalling task, 0 dying task, 0 victim task. [ 1616.072324] MemAlloc-Info: 6 stalling task, 0 dying task, 0 victim task. [ 1626.079639] MemAlloc-Info: 6 stalling task, 0 dying task, 0 victim task. [ 1636.086982] MemAlloc-Info: 7 stalling task, 0 dying task, 0 victim task. [ 1656.101667] MemAlloc-Info: 4 stalling task, 0 dying task, 0 victim task. [ 1666.109005] MemAlloc-Info: 4 stalling task, 0 dying task, 0 victim task. [ 1706.138381] MemAlloc-Info: 2 stalling task, 0 dying task, 0 victim task. [ 1716.145730] MemAlloc-Info: 6 stalling task, 0 dying task, 0 victim task. [ 1726.153060] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 1736.160403] MemAlloc-Info: 2 stalling task, 0 dying task, 0 victim task. [ 1746.167741] MemAlloc-Info: 3 stalling task, 0 dying task, 0 victim task. [ 1756.175086] MemAlloc-Info: 3 stalling task, 0 dying task, 0 victim task. [ 1766.182427] MemAlloc-Info: 4 stalling task, 0 dying task, 0 victim task. [ 1776.189773] MemAlloc-Info: 3 stalling task, 0 dying task, 0 victim task. [ 1786.197115] MemAlloc-Info: 3 stalling task, 0 dying task, 0 victim task. [ 1796.204463] MemAlloc-Info: 3 stalling task, 0 dying task, 0 victim task. [ 1806.211968] MemAlloc-Info: 3 stalling task, 0 dying task, 0 victim task. [ 1816.219514] MemAlloc-Info: 3 stalling task, 0 dying task, 0 victim task. [ 1826.227075] MemAlloc-Info: 4 stalling task, 0 dying task, 0 victim task. [ 1856.249436] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 1866.256788] MemAlloc-Info: 2 stalling task, 0 dying task, 0 victim task. [ 1876.264140] MemAlloc-Info: 3 stalling task, 0 dying task, 0 victim task. [ 1886.271494] MemAlloc-Info: 3 stalling task, 0 dying task, 0 victim task. [ 1906.286192] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 1916.293546] MemAlloc-Info: 2 stalling task, 0 dying task, 0 victim task. [ 1936.308288] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 1946.315699] MemAlloc-Info: 2 stalling task, 0 dying task, 0 victim task. [ 1966.330503] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 1986.345304] MemAlloc-Info: 2 stalling task, 0 dying task, 0 victim task. [ 2006.360045] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 2016.367414] MemAlloc-Info: 2 stalling task, 0 dying task, 0 victim task. [ 2026.374783] MemAlloc-Info: 3 stalling task, 0 dying task, 0 victim task. [ 2036.382152] MemAlloc-Info: 4 stalling task, 0 dying task, 0 victim task. [ 2046.389518] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 2076.411626] MemAlloc-Info: 3 stalling task, 0 dying task, 0 victim task. [ 2086.419002] MemAlloc-Info: 3 stalling task, 0 dying task, 0 victim task. [ 2096.426372] MemAlloc-Info: 5 stalling task, 0 dying task, 0 victim task. [ 2106.433740] MemAlloc-Info: 5 stalling task, 0 dying task, 0 victim task. [ 2116.441108] MemAlloc-Info: 5 stalling task, 0 dying task, 0 victim task. [ 2126.448478] MemAlloc-Info: 3 stalling task, 0 dying task, 0 victim task. [ 2156.486445] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 2176.501708] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 2196.516972] MemAlloc-Info: 4 stalling task, 0 dying task, 0 victim task. [ 2206.524607] MemAlloc-Info: 2 stalling task, 0 dying task, 0 victim task. [ 2226.539866] MemAlloc-Info: 2 stalling task, 0 dying task, 0 victim task. [ 2236.547503] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 2246.555129] MemAlloc-Info: 2 stalling task, 0 dying task, 0 victim task. [ 2276.578029] MemAlloc-Info: 3 stalling task, 0 dying task, 0 victim task. [ 2286.585663] MemAlloc-Info: 3 stalling task, 0 dying task, 0 victim task. [ 2306.600929] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 2316.608562] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 2326.616191] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 2346.631457] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 2356.639093] MemAlloc-Info: 4 stalling task, 0 dying task, 0 victim task. [ 2366.646733] MemAlloc-Info: 3 stalling task, 0 dying task, 0 victim task. [ 2376.654360] MemAlloc-Info: 3 stalling task, 0 dying task, 0 victim task. [ 2426.692537] MemAlloc-Info: 5 stalling task, 0 dying task, 0 victim task. [ 2436.700160] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 2486.738327] MemAlloc-Info: 4 stalling task, 0 dying task, 0 victim task. [ 2496.745962] MemAlloc-Info: 4 stalling task, 0 dying task, 0 victim task. [ 2516.761238] MemAlloc-Info: 2 stalling task, 0 dying task, 0 victim task. [ 2526.768860] MemAlloc-Info: 2 stalling task, 0 dying task, 0 victim task. [ 2536.776489] MemAlloc-Info: 3 stalling task, 0 dying task, 0 victim task. [ 2546.784126] MemAlloc-Info: 3 stalling task, 0 dying task, 0 victim task. [ 2566.799391] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 2576.807024] MemAlloc-Info: 2 stalling task, 0 dying task, 0 victim task. [ 2586.814659] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 2626.845195] MemAlloc-Info: 2 stalling task, 0 dying task, 0 victim task. [ 2636.852824] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 2706.907138] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 2726.922671] MemAlloc-Info: 2 stalling task, 0 dying task, 0 victim task. [ 2736.930441] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 2746.938204] MemAlloc-Info: 2 stalling task, 0 dying task, 0 victim task. [ 2826.999851] MemAlloc-Info: 2 stalling task, 0 dying task, 0 victim task. [ 3067.183816] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 3087.199151] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 3477.497792] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 3567.566694] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 3577.574349] MemAlloc-Info: 2 stalling task, 0 dying task, 0 victim task. [ 3587.582008] MemAlloc-Info: 2 stalling task, 0 dying task, 0 victim task. [ 3597.589662] MemAlloc-Info: 2 stalling task, 0 dying task, 0 victim task. [ 3607.597314] MemAlloc-Info: 3 stalling task, 0 dying task, 0 victim task. [ 3617.604974] MemAlloc-Info: 2 stalling task, 0 dying task, 0 victim task. [ 3637.620285] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 3647.627939] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 3717.681530] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 3797.742794] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 4238.079941] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 4338.156578] MemAlloc-Info: 4 stalling task, 0 dying task, 0 victim task. [ 4468.256201] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 4558.325170] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 4618.371150] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 4788.501423] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 4828.532079] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 4858.555065] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 4898.585719] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 5058.711672] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 5469.025717] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 5559.094621] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 5649.163542] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 5669.178855] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 5679.186511] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 5709.209479] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 5759.247766] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 5939.385591] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 5989.423875] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 6009.439191] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 6019.446849] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 6029.454508] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 6079.492787] MemAlloc-Info: 2 stalling task, 0 dying task, 0 victim task. [ 6089.500450] MemAlloc-Info: 2 stalling task, 0 dying task, 0 victim task. [ 6099.508106] MemAlloc-Info: 2 stalling task, 0 dying task, 0 victim task. [ 6109.515761] MemAlloc-Info: 2 stalling task, 0 dying task, 0 victim task. [ 6119.523421] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 6129.531076] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 6199.584674] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 6209.592332] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 6229.607647] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 6239.615305] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 6249.622965] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 6269.638288] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 6559.860274] MemAlloc-Info: 1 stalling task, 0 dying task, 0 victim task. [ 6739.998076] MemAlloc-Info: 2 stalling task, 0 dying task, 0 victim task. [ 8401.269303] MemAlloc-Info: 3 stalling task, 0 dying task, 0 victim task. [ 8411.276966] MemAlloc-Info: 5 stalling task, 0 dying task, 0 victim task. [ 8421.284631] MemAlloc-Info: 7 stalling task, 0 dying task, 0 victim task. [ 8431.292299] MemAlloc-Info: 8 stalling task, 0 dying task, 0 victim task. [ 8441.299951] MemAlloc-Info: 9 stalling task, 0 dying task, 0 victim task. [ 8451.307616] MemAlloc-Info: 7 stalling task, 0 dying task, 0 victim task. [ 8461.315273] MemAlloc-Info: 7 stalling task, 0 dying task, 0 victim task. [ 8481.330599] MemAlloc-Info: 6 stalling task, 0 dying task, 0 victim task. [ 8491.338257] MemAlloc-Info: 6 stalling task, 0 dying task, 0 victim task. [ 8501.345922] MemAlloc-Info: 6 stalling task, 0 dying task, 0 victim task. [ 8511.353584] MemAlloc-Info: 5 stalling task, 0 dying task, 0 victim task. [ 8521.361249] MemAlloc-Info: 5 stalling task, 0 dying task, 0 victim task. [ 8531.368911] MemAlloc-Info: 5 stalling task, 0 dying task, 0 victim task. [ 8541.376566] MemAlloc-Info: 5 stalling task, 0 dying task, 0 victim task. [ 8551.384226] MemAlloc-Info: 5 stalling task, 0 dying task, 0 victim task. [ 8561.391891] MemAlloc-Info: 4 stalling task, 0 dying task, 0 victim task. [ 8571.399551] MemAlloc-Info: 4 stalling task, 0 dying task, 0 victim task. [ 8581.407215] MemAlloc-Info: 4 stalling task, 0 dying task, 0 victim task. [ 8591.414878] MemAlloc-Info: 4 stalling task, 0 dying task, 0 victim task. [ 8601.422538] MemAlloc-Info: 4 stalling task, 0 dying task, 0 victim task. [ 8611.430199] MemAlloc-Info: 3 stalling task, 0 dying task, 0 victim task. [ 8621.437860] MemAlloc-Info: 5 stalling task, 0 dying task, 0 victim task. [ 8631.445524] MemAlloc-Info: 5 stalling task, 0 dying task, 0 victim task. [ 8641.453189] MemAlloc-Info: 8 stalling task, 0 dying task, 0 victim task. [ 8651.460845] MemAlloc-Info: 8 stalling task, 0 dying task, 0 victim task. [ 8661.468509] MemAlloc-Info: 8 stalling task, 0 dying task, 0 victim task. [ 8671.476177] MemAlloc-Info: 8 stalling task, 0 dying task, 0 victim task. [ 9462.081427] MemAlloc-Info: 14 stalling task, 0 dying task, 0 victim task. [ 9472.089089] MemAlloc-Info: 14 stalling task, 0 dying task, 0 victim task. [ 9482.096751] MemAlloc-Info: 14 stalling task, 0 dying task, 0 victim task. [ 9492.104413] MemAlloc-Info: 14 stalling task, 0 dying task, 0 victim task. [ 9502.112092] MemAlloc-Info: 14 stalling task, 0 dying task, 0 victim task. [ 9512.119764] MemAlloc-Info: 15 stalling task, 0 dying task, 0 victim task. [ 9522.127417] MemAlloc-Info: 15 stalling task, 0 dying task, 0 victim task. [ 9532.135091] MemAlloc-Info: 15 stalling task, 0 dying task, 0 victim task. [ 9542.142743] MemAlloc-Info: 15 stalling task, 0 dying task, 0 victim task. [ 9552.150406] MemAlloc-Info: 14 stalling task, 0 dying task, 0 victim task. [ 9562.158067] MemAlloc-Info: 15 stalling task, 0 dying task, 0 victim task. [ 9572.165732] MemAlloc-Info: 15 stalling task, 0 dying task, 0 victim task. [ 9612.196377] MemAlloc-Info: 2 stalling task, 0 dying task, 0 victim task. [ 9622.204042] MemAlloc-Info: 5 stalling task, 0 dying task, 0 victim task. [ 9632.211698] MemAlloc-Info: 6 stalling task, 0 dying task, 0 victim task. [ 9642.219358] MemAlloc-Info: 5 stalling task, 0 dying task, 0 victim task. [ 9652.227029] MemAlloc-Info: 5 stalling task, 0 dying task, 0 victim task. [ 9662.234685] MemAlloc-Info: 3 stalling task, 0 dying task, 0 victim task. vmstat_update() and submit_flushes() remained pending for about 110 seconds. If xlog_cil_push_work() were spinning inside GFP_NOFS allocation, it should be reported as MemAlloc: traces, but no such lines are recorded. I don't know why xlog_cil_push_work() did not call schedule() for so long. Anyway, applying http://lkml.kernel.org/r/20151111160336.GD1432@dhcp22.suse.cz should solve vmstat_update() part. [ 8491.338279] Showing busy workqueues and worker pools: [ 8491.338281] workqueue events: flags=0x0 [ 8491.338283] pwq 4: cpus=2 node=0 flags=0x0 nice=0 active=2/256 [ 8491.338287] pending: vmstat_update, e1000_watchdog_task [e1000e] [ 8491.338310] workqueue md: flags=0x8 [ 8491.338312] pwq 4: cpus=2 node=0 flags=0x0 nice=0 active=1/256 [ 8491.338315] pending: submit_flushes [md_mod] [ 8491.338333] workqueue xfs-cil/md3: flags=0xc [ 8491.338334] pwq 4: cpus=2 node=0 flags=0x0 nice=0 active=1/256 [ 8491.338336] in-flight: 8895:xlog_cil_push_work [xfs] BAR(576) [ 8491.338368] pool 0: cpus=0 node=0 flags=0x0 nice=0 workers=3 manager: 12328 idle: 9632 8646 [ 8491.338372] pool 1: cpus=0 node=0 flags=0x0 nice=-20 workers=3 manager: 12327 idle: 4592 11916 [ 8491.338377] pool 4: cpus=2 node=0 flags=0x0 nice=0 workers=2 manager: 11509 (...snipped...) [ 8601.422538] MemAlloc-Info: 4 stalling task, 0 dying task, 0 victim task. [ 8601.422542] MemAlloc: kthreadd(2) gfp=0x2000d0 order=2 delay=61314 [ 8601.422544] MemAlloc: ssh(9797) gfp=0xd0 order=0 delay=60227 [ 8601.422546] MemAlloc: cp(10054) gfp=0x2052d0 order=3 delay=57397 [ 8601.422547] MemAlloc: irqbalance(703) gfp=0x280da order=0 delay=54234 [ 8601.422557] Showing busy workqueues and worker pools: [ 8601.422559] workqueue events: flags=0x0 [ 8601.422561] pwq 4: cpus=2 node=0 flags=0x0 nice=0 active=5/256 [ 8601.422566] pending: vmstat_update, e1000_watchdog_task [e1000e], vmpressure_work_fn, kernfs_notify_workfn, key_garbage_collector [ 8601.422597] workqueue md: flags=0x8 [ 8601.422598] pwq 4: cpus=2 node=0 flags=0x0 nice=0 active=1/256 [ 8601.422601] pending: submit_flushes [md_mod] [ 8601.422619] workqueue xfs-cil/md3: flags=0xc [ 8601.422621] pwq 4: cpus=2 node=0 flags=0x0 nice=0 active=1/256 [ 8601.422623] in-flight: 8895:xlog_cil_push_work [xfs] BAR(4592) BAR(576) [ 8601.422653] workqueue xfs-log/md3: flags=0x1c [ 8601.422655] pwq 1: cpus=0 node=0 flags=0x0 nice=-20 active=1/256 [ 8601.422658] in-flight: 4592:xfs_log_worker [xfs] [ 8601.422680] pool 0: cpus=0 node=0 flags=0x0 nice=0 workers=3 manager: 12328 idle: 9632 8646 [ 8601.422684] pool 1: cpus=0 node=0 flags=0x0 nice=-20 workers=3 manager: 12327 idle: 11916 [ 8601.422688] pool 4: cpus=2 node=0 flags=0x0 nice=0 workers=2 manager: 11509 Well, what steps should we try next for isolating the problem? Swap is not used at all. Turning off swap might help. [ 8633.753574] Free swap = 117220800kB [ 8633.753576] Total swap = 117220820kB Turning off perf might also help. [ 5001.394085] perf interrupt took too long (2505 > 2495), lowering kernel.perf_event_max_sample_rate to 50100 From bfoster@redhat.com Thu Nov 12 09:37:30 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 D47577F66 for ; Thu, 12 Nov 2015 09:37:30 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id B195D8F8035 for ; Thu, 12 Nov 2015 07:37:30 -0800 (PST) X-ASG-Debug-ID: 1447342649-04bdf03f04142600001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 6S9Sb1jvA87CzrLC (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 12 Nov 2015 07:37:29 -0800 (PST) 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 (Postfix) with ESMTPS id 40C23C0D8028 for ; Thu, 12 Nov 2015 15:37:29 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-36.bos.redhat.com [10.18.41.36]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tACFbSZq017070 for ; Thu, 12 Nov 2015 10:37:29 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id 5EF21120059; Thu, 12 Nov 2015 10:37:28 -0500 (EST) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH v2 0/8] xfs: log recovery torn write detection Date: Thu, 12 Nov 2015 10:37:20 -0500 X-ASG-Orig-Subj: [PATCH v2 0/8] xfs: log recovery torn write detection Message-Id: <1447342648-40012-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: 1447342649 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Hi all, Here's v2 of log recovery torn write detection. This fixes a couple bugs as noted in the replies to the v1 series and replaces the error injection mechanism with an alternate version that actually writes an invalid log record CRC to disk. An xfstests test based on this mechanism is forthcoming. This survives xfstests and runs through a significant number of error injection iterations without any related problems. I have seen one or two assert failures and whatnot that do not appear related to this series and so far are not repeatable. Thoughts, reviews, flames appreciated. Brian v2: - Fixed bug in first bad record detection to return correct block when log wraps. - Update torn record handling to truncate back to tail. - Fixed up warning messages. - Replaced v1 error injection mechanism with log write time CRC error injection. v1: http://oss.sgi.com/pipermail/xfs/2015-November/044841.html - Added bug fix for mkfs log record header inconsistency. - Refactored log recovery code to support a CRC-check-only recovery pass. - CRC verify the last 8 records behind the head to account for concurrent log writes. - Verify the tail of the log as well when the head is torn. - Added (rfc) crc error injection patch for testing purposes. rfc: http://oss.sgi.com/pipermail/xfs/2015-July/042415.html Brian Foster (8): xfs: detect and handle invalid iclog size set by mkfs xfs: refactor log record unpack and data processing xfs: refactor and open code log record crc check xfs: return start block of first bad log record during recovery xfs: support a crc verification only log record pass xfs: refactor log record start detection into a new helper xfs: detect and trim torn writes during log recovery xfs: debug mode log record crc error injection fs/xfs/libxfs/xfs_log_recover.h | 1 + fs/xfs/xfs_log.c | 45 +++- fs/xfs/xfs_log_priv.h | 3 + fs/xfs/xfs_log_recover.c | 569 ++++++++++++++++++++++++++++++++-------- fs/xfs/xfs_sysfs.c | 36 +++ 5 files changed, 541 insertions(+), 113 deletions(-) -- 2.1.0 From bfoster@redhat.com Thu Nov 12 09:37:31 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 3E4367F66 for ; Thu, 12 Nov 2015 09:37:31 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id EE55A8F8033 for ; Thu, 12 Nov 2015 07:37:30 -0800 (PST) X-ASG-Debug-ID: 1447342649-04bdf03f02142600001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 577Dsiokw4YUjpgT (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 12 Nov 2015 07:37:29 -0800 (PST) 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 (Postfix) with ESMTPS id 6C429C0B1B4D for ; Thu, 12 Nov 2015 15:37:29 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-36.bos.redhat.com [10.18.41.36]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tACFbTiA032673 for ; Thu, 12 Nov 2015 10:37:29 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id 957CB1200E2; Thu, 12 Nov 2015 10:37:28 -0500 (EST) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH v2 4/8] xfs: return start block of first bad log record during recovery Date: Thu, 12 Nov 2015 10:37:24 -0500 X-ASG-Orig-Subj: [PATCH v2 4/8] xfs: return start block of first bad log record during recovery Message-Id: <1447342648-40012-5-git-send-email-bfoster@redhat.com> In-Reply-To: <1447342648-40012-1-git-send-email-bfoster@redhat.com> References: <1447342648-40012-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: 1447342649 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Each log recovery pass walks from the tail block to the head block and processes records appropriately based on the associated log pass type. There are various failure conditions that can occur through this sequence, such as I/O errors, CRC errors, etc. Log torn write detection will perform CRC verification near the head of the log to detect torn writes and trim torn records from the log appropriately. As it is, xlog_do_recovery_pass() only returns an error code in the event of CRC failure, which isn't enough information to trim the head of the log. Update xlog_do_recovery_pass() to optionally return the start block of the associated record when an error occurs. This patch contains no functional changes. Signed-off-by: Brian Foster --- fs/xfs/xfs_log_recover.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 9ec4bbd..e0318e8 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -4239,10 +4239,12 @@ xlog_do_recovery_pass( struct xlog *log, xfs_daddr_t head_blk, xfs_daddr_t tail_blk, - int pass) + int pass, + xfs_daddr_t *first_bad) /* out: first bad log rec */ { xlog_rec_header_t *rhead; xfs_daddr_t blk_no; + xfs_daddr_t rhead_blk; char *offset; xfs_buf_t *hbp, *dbp; int error = 0, h_size, h_len; @@ -4251,6 +4253,7 @@ xlog_do_recovery_pass( struct hlist_head rhash[XLOG_RHASH_SIZE]; ASSERT(head_blk != tail_blk); + rhead_blk = 0; /* * Read the header of the tail block and get the iclog buffer size from @@ -4325,7 +4328,7 @@ xlog_do_recovery_pass( } memset(rhash, 0, sizeof(rhash)); - blk_no = tail_blk; + blk_no = rhead_blk = tail_blk; if (tail_blk > head_blk) { /* * Perform recovery around the end of the physical log. @@ -4436,11 +4439,14 @@ xlog_do_recovery_pass( pass); if (error) goto bread_err2; + blk_no += bblks; + rhead_blk = blk_no; } ASSERT(blk_no >= log->l_logBBsize); blk_no -= log->l_logBBsize; + rhead_blk = blk_no; } /* read first part of physical log */ @@ -4464,13 +4470,19 @@ xlog_do_recovery_pass( error = xlog_recover_process(log, rhash, rhead, offset, pass); if (error) goto bread_err2; + blk_no += bblks + hblks; + rhead_blk = blk_no; } bread_err2: xlog_put_bp(dbp); bread_err1: xlog_put_bp(hbp); + + if (error && first_bad) + *first_bad = rhead_blk; + return error; } @@ -4508,7 +4520,7 @@ xlog_do_log_recovery( INIT_LIST_HEAD(&log->l_buf_cancel_table[i]); error = xlog_do_recovery_pass(log, head_blk, tail_blk, - XLOG_RECOVER_PASS1); + XLOG_RECOVER_PASS1, NULL); if (error != 0) { kmem_free(log->l_buf_cancel_table); log->l_buf_cancel_table = NULL; @@ -4519,7 +4531,7 @@ xlog_do_log_recovery( * When it is complete free the table of buf cancel items. */ error = xlog_do_recovery_pass(log, head_blk, tail_blk, - XLOG_RECOVER_PASS2); + XLOG_RECOVER_PASS2, NULL); #ifdef DEBUG if (!error) { int i; -- 2.1.0 From bfoster@redhat.com Thu Nov 12 09:37:32 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 770D57F6C for ; Thu, 12 Nov 2015 09:37:32 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 6295A304043 for ; Thu, 12 Nov 2015 07:37:32 -0800 (PST) X-ASG-Debug-ID: 1447342650-04cb6c296b13cf40001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id MZ2h4Tlt06ST25aP (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 12 Nov 2015 07:37:30 -0800 (PST) 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 (Postfix) with ESMTPS id ECD473D1EA for ; Thu, 12 Nov 2015 15:37:29 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-36.bos.redhat.com [10.18.41.36]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tACFbTlh003343 for ; Thu, 12 Nov 2015 10:37:29 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id C77411201E2; Thu, 12 Nov 2015 10:37:28 -0500 (EST) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH v2 8/8] xfs: debug mode log record crc error injection Date: Thu, 12 Nov 2015 10:37:28 -0500 X-ASG-Orig-Subj: [PATCH v2 8/8] xfs: debug mode log record crc error injection Message-Id: <1447342648-40012-9-git-send-email-bfoster@redhat.com> In-Reply-To: <1447342648-40012-1-git-send-email-bfoster@redhat.com> References: <1447342648-40012-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: 1447342650 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 XFS now uses CRC verification over a limited section of the log to detect torn writes prior to a crash. This is difficult to test directly due to the timing and hardware requirements to cause a short write. Add a mechanism to inject CRC errors into log records to facilitate testing torn write detection during log recovery. This mechanism is dangerous and can result in filesystem corruption. Thus, it is only available in DEBUG mode for testing/development purposes. Set a non-zero value to the following sysfs entry to enable error injection: /sys/fs/xfs//log/log_badcrc_factor Once enabled, XFS intentionally writes an invalid CRC to a log record at some random point in the future based on the provided frequency. The filesystem immediately shuts down once the record has been written to the physical log to prevent metadata writeback (e.g., AIL insertion) once the log write completes. This helps reasonably simulate a torn write to the log as the affected record must be safe to discard. The next mount after the intentional shutdown requires log recovery and should detect and recover from the torn write. Note again that this _will_ result in data loss or worse. For testing and development purposes only! Signed-off-by: Brian Foster --- fs/xfs/xfs_log.c | 45 ++++++++++++++++++++++++++++++++++++++------- fs/xfs/xfs_log_priv.h | 3 +++ fs/xfs/xfs_sysfs.c | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 7 deletions(-) diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index f52c72a..887c443 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -1188,10 +1188,16 @@ xlog_iodone(xfs_buf_t *bp) int aborted = 0; /* - * Race to shutdown the filesystem if we see an error. + * Race to shutdown the filesystem if we see an error or the iclog is in + * IOABORT state. The IOABORT state is only set in DEBUG mode to inject + * CRC errors into log recovery. */ - if (XFS_TEST_ERROR(bp->b_error, l->l_mp, - XFS_ERRTAG_IODONE_IOERR, XFS_RANDOM_IODONE_IOERR)) { + if (XFS_TEST_ERROR(bp->b_error, l->l_mp, XFS_ERRTAG_IODONE_IOERR, + XFS_RANDOM_IODONE_IOERR) || + iclog->ic_state & XLOG_STATE_IOABORT) { + if (iclog->ic_state & XLOG_STATE_IOABORT) + iclog->ic_state &= ~XLOG_STATE_IOABORT; + xfs_buf_ioerror_alert(bp, __func__); xfs_buf_stale(bp); xfs_force_shutdown(l->l_mp, SHUTDOWN_LOG_IO_ERROR); @@ -1838,6 +1844,23 @@ xlog_sync( /* calculcate the checksum */ iclog->ic_header.h_crc = xlog_cksum(log, &iclog->ic_header, iclog->ic_datap, size); +#ifdef DEBUG + /* + * Intentionally corrupt the log record CRC based on the error injection + * frequency, if defined. This facilitates testing log recovery in the + * event of torn writes. Hence, set the IOABORT state to abort the log + * write on I/O completion and shutdown the fs. The subsequent mount + * detects the bad CRC and attempts to recover. + */ + if (log->l_badcrc_factor && + (prandom_u32() % log->l_badcrc_factor == 0)) { + iclog->ic_header.h_crc &= 0xAAAAAAAA; + iclog->ic_state |= XLOG_STATE_IOABORT; + xfs_warn(log->l_mp, + "Intentionally corrupted log record at LSN 0x%llx. Shutdown imminent.", + be64_to_cpu(iclog->ic_header.h_lsn)); + } +#endif bp->b_io_length = BTOBB(count); bp->b_fspriv = iclog; @@ -2791,11 +2814,19 @@ xlog_state_do_callback( } } while (!ioerrors && loopdidcallbacks); +#ifdef DEBUG /* - * make one last gasp attempt to see if iclogs are being left in - * limbo.. + * Make one last gasp attempt to see if iclogs are being left in limbo. + * If the above loop finds an iclog earlier than the current iclog and + * in one of the syncing states, the current iclog is put into + * DO_CALLBACK and the callbacks are deferred to the completion of the + * earlier iclog. Walk the iclogs in order and make sure that no iclog + * is in DO_CALLBACK unless an earlier iclog is in one of the syncing + * states. + * + * Note that SYNCING|IOABORT is a valid state so we cannot just check + * for ic_state == SYNCING. */ -#ifdef DEBUG if (funcdidcallbacks) { first_iclog = iclog = log->l_iclog; do { @@ -2810,7 +2841,7 @@ xlog_state_do_callback( * IOERROR - give up hope all ye who enter here */ if (iclog->ic_state == XLOG_STATE_WANT_SYNC || - iclog->ic_state == XLOG_STATE_SYNCING || + iclog->ic_state & XLOG_STATE_SYNCING || iclog->ic_state == XLOG_STATE_DONE_SYNC || iclog->ic_state == XLOG_STATE_IOERROR ) break; diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h index 8daba74..ed88963 100644 --- a/fs/xfs/xfs_log_priv.h +++ b/fs/xfs/xfs_log_priv.h @@ -62,6 +62,7 @@ static inline uint xlog_get_client_id(__be32 i) #define XLOG_STATE_CALLBACK 0x0020 /* Callback functions now */ #define XLOG_STATE_DIRTY 0x0040 /* Dirty IC log, not ready for ACTIVE status*/ #define XLOG_STATE_IOERROR 0x0080 /* IO error happened in sync'ing log */ +#define XLOG_STATE_IOABORT 0x0100 /* force abort on I/O completion (debug) */ #define XLOG_STATE_ALL 0x7FFF /* All possible valid flags */ #define XLOG_STATE_NOTUSED 0x8000 /* This IC log not being used */ @@ -410,6 +411,8 @@ struct xlog { /* The following field are used for debugging; need to hold icloglock */ #ifdef DEBUG void *l_iclog_bak[XLOG_MAX_ICLOGS]; + /* log record crc error injection factor */ + uint32_t l_badcrc_factor; #endif }; diff --git a/fs/xfs/xfs_sysfs.c b/fs/xfs/xfs_sysfs.c index ee70f5d..641d625 100644 --- a/fs/xfs/xfs_sysfs.c +++ b/fs/xfs/xfs_sysfs.c @@ -255,11 +255,47 @@ write_grant_head_show( } XFS_SYSFS_ATTR_RO(write_grant_head); +#ifdef DEBUG +STATIC ssize_t +log_badcrc_factor_store( + struct kobject *kobject, + const char *buf, + size_t count) +{ + struct xlog *log = to_xlog(kobject); + int ret; + uint32_t val; + + ret = kstrtouint(buf, 0, &val); + if (ret) + return ret; + + log->l_badcrc_factor = val; + + return count; +} + +STATIC ssize_t +log_badcrc_factor_show( + struct kobject *kobject, + char *buf) +{ + struct xlog *log = to_xlog(kobject); + + return snprintf(buf, PAGE_SIZE, "%d\n", log->l_badcrc_factor); +} + +XFS_SYSFS_ATTR_RW(log_badcrc_factor); +#endif /* DEBUG */ + static struct attribute *xfs_log_attrs[] = { ATTR_LIST(log_head_lsn), ATTR_LIST(log_tail_lsn), ATTR_LIST(reserve_grant_head), ATTR_LIST(write_grant_head), +#ifdef DEBUG + ATTR_LIST(log_badcrc_factor), +#endif NULL, }; -- 2.1.0 From bfoster@redhat.com Thu Nov 12 09:37:33 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 C95B97F6D for ; Thu, 12 Nov 2015 09:37:32 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 3B1DAAC002 for ; Thu, 12 Nov 2015 07:37:32 -0800 (PST) X-ASG-Debug-ID: 1447342649-04cb6c296d13cf40001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id g8gADF2Cji2gpcf2 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 12 Nov 2015 07:37:30 -0800 (PST) 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 (Postfix) with ESMTPS id D24ACC60EE for ; Thu, 12 Nov 2015 15:37:29 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-36.bos.redhat.com [10.18.41.36]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tACFbTri032681 for ; Thu, 12 Nov 2015 10:37:29 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id A1FFE120142; Thu, 12 Nov 2015 10:37:28 -0500 (EST) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH v2 5/8] xfs: support a crc verification only log record pass Date: Thu, 12 Nov 2015 10:37:25 -0500 X-ASG-Orig-Subj: [PATCH v2 5/8] xfs: support a crc verification only log record pass Message-Id: <1447342648-40012-6-git-send-email-bfoster@redhat.com> In-Reply-To: <1447342648-40012-1-git-send-email-bfoster@redhat.com> References: <1447342648-40012-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: 1447342650 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Log recovery torn write detection uses CRC verification over a range of the active log to identify torn writes. Since the generic log recovery pass code implements a superset of the functionality required for CRC verification, it can be easily modified to support a CRC verification only pass. Create a new CRC pass type and update the log record processing helper to skip everything beyond CRC verification when in this mode. This pass will be invoked in subsequent patches to implement torn write detection. Signed-off-by: Brian Foster --- fs/xfs/libxfs/xfs_log_recover.h | 1 + fs/xfs/xfs_log_recover.c | 24 +++++++++++++++++++----- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/fs/xfs/libxfs/xfs_log_recover.h b/fs/xfs/libxfs/xfs_log_recover.h index 1c55ccb..8e385f9 100644 --- a/fs/xfs/libxfs/xfs_log_recover.h +++ b/fs/xfs/libxfs/xfs_log_recover.h @@ -60,6 +60,7 @@ typedef struct xlog_recover { */ #define XLOG_BC_TABLE_SIZE 64 +#define XLOG_RECOVER_CRCPASS 0 #define XLOG_RECOVER_PASS1 1 #define XLOG_RECOVER_PASS2 2 diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index e0318e8..1be2590 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -4159,13 +4159,27 @@ xlog_recover_process( int error; __le32 crc; + crc = xlog_cksum(log, rhead, dp, be32_to_cpu(rhead->h_len)); + /* - * Check the CRC and issue a warning if and only if the CRC in the - * header is non-zero. This is an advisory warning and the zero CRC - * check prevents warnings from being emitted when upgrading the kernel - * from one that does not add CRCs by default. + * Nothing else to do if this is a CRC verification pass. Just return + * if this a record with a non-zero crc. Unfortunately, mkfs always + * sets h_crc to 0 so we must consider this valid even on v5 supers. + * Otherwise, return EFSBADCRC on failure so the callers up the stack + * know precisely what failed. + */ + if (pass == XLOG_RECOVER_CRCPASS) { + if (rhead->h_crc && crc != le32_to_cpu(rhead->h_crc)) + return -EFSBADCRC; + return 0; + } + + /* + * We're in the normal recovery path. Issue a warning if and only if the + * CRC in the header is non-zero. This is an advisory warning and the + * zero CRC check prevents warnings from being emitted when upgrading + * the kernel from one that does not add CRCs by default. */ - crc = xlog_cksum(log, rhead, dp, be32_to_cpu(rhead->h_len)); if (crc != le32_to_cpu(rhead->h_crc)) { if (rhead->h_crc || xfs_sb_version_hascrc(&log->l_mp->m_sb)) { xfs_alert(log->l_mp, -- 2.1.0 From bfoster@redhat.com Thu Nov 12 09:37:33 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 E374E7F6C for ; Thu, 12 Nov 2015 09:37:32 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 54E8DAC003 for ; Thu, 12 Nov 2015 07:37:32 -0800 (PST) X-ASG-Debug-ID: 1447342649-04cb6c296a13cf30001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 6Mdkc69rTAcyPLxp (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 12 Nov 2015 07:37:29 -0800 (PST) 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 (Postfix) with ESMTPS id 6E19AC1A1657 for ; Thu, 12 Nov 2015 15:37:29 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-36.bos.redhat.com [10.18.41.36]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tACFbTWE017072 for ; Thu, 12 Nov 2015 10:37:29 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id 890401201AB; Thu, 12 Nov 2015 10:37:28 -0500 (EST) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH v2 3/8] xfs: refactor and open code log record crc check Date: Thu, 12 Nov 2015 10:37:23 -0500 X-ASG-Orig-Subj: [PATCH v2 3/8] xfs: refactor and open code log record crc check Message-Id: <1447342648-40012-4-git-send-email-bfoster@redhat.com> In-Reply-To: <1447342648-40012-1-git-send-email-bfoster@redhat.com> References: <1447342648-40012-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: 1447342649 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Log record CRC verification currently occurs during active log recovery, immediately before a log record is unpacked. Therefore, the CRC calculation code is buried within the data unpack function. CRC verification pass support only needs to go so far as check the CRC, but this is not easily allowed as the code is currently organized. Since we now have a new log record processing helper, pull the record CRC verification code out from the unpack helper and open-code it at the top of the new process helper. This facilitates the ability to modify how records are processed based on the type of the current pass. This patch contains no functional changes. Signed-off-by: Brian Foster --- fs/xfs/xfs_log_recover.c | 72 +++++++++++++++++------------------------------- 1 file changed, 26 insertions(+), 46 deletions(-) diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 236ebaf..9ec4bbd 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -4118,46 +4118,6 @@ xlog_recover_process_iunlinks( mp->m_dmevmask = mp_dmevmask; } -/* - * Upack the log buffer data and crc check it. If the check fails, issue a - * warning if and only if the CRC in the header is non-zero. This makes the - * check an advisory warning, and the zero CRC check will prevent failure - * warnings from being emitted when upgrading the kernel from one that does not - * add CRCs by default. - * - * When filesystems are CRC enabled, this CRC mismatch becomes a fatal log - * corruption failure - */ -STATIC int -xlog_unpack_data_crc( - struct xlog_rec_header *rhead, - char *dp, - struct xlog *log) -{ - __le32 crc; - - crc = xlog_cksum(log, rhead, dp, be32_to_cpu(rhead->h_len)); - if (crc != rhead->h_crc) { - if (rhead->h_crc || xfs_sb_version_hascrc(&log->l_mp->m_sb)) { - xfs_alert(log->l_mp, - "log record CRC mismatch: found 0x%x, expected 0x%x.", - le32_to_cpu(rhead->h_crc), - le32_to_cpu(crc)); - xfs_hex_dump(dp, 32); - } - - /* - * If we've detected a log record corruption, then we can't - * recover past this point. Abort recovery if we are enforcing - * CRC protection by punting an error back up the stack. - */ - if (xfs_sb_version_hascrc(&log->l_mp->m_sb)) - return -EFSCORRUPTED; - } - - return 0; -} - STATIC int xlog_unpack_data( struct xlog_rec_header *rhead, @@ -4165,11 +4125,6 @@ xlog_unpack_data( struct xlog *log) { int i, j, k; - int error; - - error = xlog_unpack_data_crc(rhead, dp, log); - if (error) - return error; for (i = 0; i < BTOBB(be32_to_cpu(rhead->h_len)) && i < (XLOG_HEADER_CYCLE_SIZE / BBSIZE); i++) { @@ -4191,7 +4146,7 @@ xlog_unpack_data( } /* - * Unpack and process a log record. + * CRC check, unpack and process a log record. */ STATIC int xlog_recover_process( @@ -4202,6 +4157,31 @@ xlog_recover_process( int pass) { int error; + __le32 crc; + + /* + * Check the CRC and issue a warning if and only if the CRC in the + * header is non-zero. This is an advisory warning and the zero CRC + * check prevents warnings from being emitted when upgrading the kernel + * from one that does not add CRCs by default. + */ + crc = xlog_cksum(log, rhead, dp, be32_to_cpu(rhead->h_len)); + if (crc != le32_to_cpu(rhead->h_crc)) { + if (rhead->h_crc || xfs_sb_version_hascrc(&log->l_mp->m_sb)) { + xfs_alert(log->l_mp, + "log record CRC mismatch: found 0x%x, expected 0x%x.", + le32_to_cpu(rhead->h_crc), + le32_to_cpu(crc)); + xfs_hex_dump(dp, 32); + } + + /* + * If the filesystem is CRC enabled, this mismatch becomes a + * fatal log corruption failure. + */ + if (xfs_sb_version_hascrc(&log->l_mp->m_sb)) + return -EFSCORRUPTED; + } error = xlog_unpack_data(rhead, dp, log); if (error) -- 2.1.0 From bfoster@redhat.com Thu Nov 12 09:37:33 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 916B27F74 for ; Thu, 12 Nov 2015 09:37:33 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id E3890AC006 for ; Thu, 12 Nov 2015 07:37:32 -0800 (PST) X-ASG-Debug-ID: 1447342650-04cb6c296a13cf40001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id v8WWUH6V1BzpQqo1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 12 Nov 2015 07:37:31 -0800 (PST) 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 (Postfix) with ESMTPS id EF149935D2 for ; Thu, 12 Nov 2015 15:37:29 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-36.bos.redhat.com [10.18.41.36]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tACFbTTF003341 for ; Thu, 12 Nov 2015 10:37:29 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id AE7221201BB; Thu, 12 Nov 2015 10:37:28 -0500 (EST) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH v2 6/8] xfs: refactor log record start detection into a new helper Date: Thu, 12 Nov 2015 10:37:26 -0500 X-ASG-Orig-Subj: [PATCH v2 6/8] xfs: refactor log record start detection into a new helper Message-Id: <1447342648-40012-7-git-send-email-bfoster@redhat.com> In-Reply-To: <1447342648-40012-1-git-send-email-bfoster@redhat.com> References: <1447342648-40012-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: 1447342651 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 As part of the head/tail discovery process, log recovery locates the head block and then reverse seeks to find the start of the last active record in the log. This is non-trivial as the record itself could have wrapped around the end of the physical log. Log recovery torn write detection potentially needs to walk further behind the last record in the log, as multiple log I/Os can be in-flight at one time during a crash event. Therefore, refactor the reverse log record header search mechanism into a new helper that supports the ability to seek past an arbitrary number of log records (or until the tail is hit). Update the head/tail search mechanism to call the new helper, but otherwise there is no change in log recovery behavior. Signed-off-by: Brian Foster --- fs/xfs/xfs_log_recover.c | 118 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 83 insertions(+), 35 deletions(-) diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 1be2590..423c36d 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -868,6 +868,79 @@ validate_head: } /* + * Seek backwards in the log for log record headers. + * + * Given a starting log block, walk backwards until we find the provided number + * of records or hit the provided tail block. The return value is the number of + * records encountered or a negative error code. The log block and buffer + * pointer of the last record seen are returned in rblk and rhead respectively. + */ +STATIC int +xlog_rseek_logrec_hdr( + struct xlog *log, + xfs_daddr_t head_blk, + xfs_daddr_t tail_blk, + int count, + struct xfs_buf *bp, + xfs_daddr_t *rblk, + struct xlog_rec_header **rhead, + bool *wrapped) +{ + int i; + int error; + int found = 0; + char *offset = NULL; + xfs_daddr_t end_blk; + + *wrapped = false; + + /* + * Walk backwards from the head block until we hit the tail or the first + * block in the log. + */ + end_blk = head_blk > tail_blk ? tail_blk : 0; + for (i = (int) head_blk - 1; i >= end_blk; i--) { + error = xlog_bread(log, i, 1, bp, &offset); + if (error) + goto out_error; + + if (*(__be32 *) offset == cpu_to_be32(XLOG_HEADER_MAGIC_NUM)) { + *rblk = i; + *rhead = (struct xlog_rec_header *) offset; + if (++found == count) + break; + } + } + + /* + * If we haven't hit the tail block or the log record header count, + * start looking again from the end of the physical log. Note that + * callers can pass head == tail if the tail is not yet known. + */ + if (tail_blk >= head_blk && found != count) { + for (i = log->l_logBBsize - 1; i >= (int) tail_blk; i--) { + error = xlog_bread(log, i, 1, bp, &offset); + if (error) + goto out_error; + + if (*(__be32 *)offset == + cpu_to_be32(XLOG_HEADER_MAGIC_NUM)) { + *wrapped = true; + *rblk = i; + *rhead = (struct xlog_rec_header *) offset; + if (++found == count) + break; + } + } + } + + return found; + +out_error: + return error; +} + +/* * Find the sync block number or the tail of the log. * * This will be the block number of the last record to have its @@ -898,8 +971,7 @@ xlog_find_tail( xfs_daddr_t after_umount_blk; xfs_lsn_t tail_lsn; int hblks; - - found = 0; + bool wrapped = false; /* * Find previous log record @@ -923,37 +995,16 @@ xlog_find_tail( } /* - * Search backwards looking for log record header block + * Search backwards through the log looking for the log record header + * block. This wraps all the way back around to the head so something is + * seriously wrong if we can't find it. */ ASSERT(*head_blk < INT_MAX); - for (i = (int)(*head_blk) - 1; i >= 0; i--) { - error = xlog_bread(log, i, 1, bp, &offset); - if (error) - goto done; - - if (*(__be32 *)offset == cpu_to_be32(XLOG_HEADER_MAGIC_NUM)) { - found = 1; - break; - } - } - /* - * If we haven't found the log record header block, start looking - * again from the end of the physical log. XXXmiken: There should be - * a check here to make sure we didn't search more than N blocks in - * the previous code. - */ - if (!found) { - for (i = log->l_logBBsize - 1; i >= (int)(*head_blk); i--) { - error = xlog_bread(log, i, 1, bp, &offset); - if (error) - goto done; - - if (*(__be32 *)offset == - cpu_to_be32(XLOG_HEADER_MAGIC_NUM)) { - found = 2; - break; - } - } + found = xlog_rseek_logrec_hdr(log, *head_blk, *head_blk, 1, bp, &i, + &rhead, &wrapped); + if (found < 0) { + error = found; + goto done; } if (!found) { xfs_warn(log->l_mp, "%s: couldn't find sync record", __func__); @@ -961,9 +1012,6 @@ xlog_find_tail( ASSERT(0); return -EIO; } - - /* find blk_no of tail of log */ - rhead = (xlog_rec_header_t *)offset; *tail_blk = BLOCK_LSN(be64_to_cpu(rhead->h_tail_lsn)); /* @@ -979,7 +1027,7 @@ xlog_find_tail( log->l_prev_block = i; log->l_curr_block = (int)*head_blk; log->l_curr_cycle = be32_to_cpu(rhead->h_cycle); - if (found == 2) + if (wrapped) log->l_curr_cycle++; atomic64_set(&log->l_tail_lsn, be64_to_cpu(rhead->h_tail_lsn)); atomic64_set(&log->l_last_sync_lsn, be64_to_cpu(rhead->h_lsn)); -- 2.1.0 From bfoster@redhat.com Thu Nov 12 09:37:33 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 681457F6D for ; Thu, 12 Nov 2015 09:37:33 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id D2FEEAC005 for ; Thu, 12 Nov 2015 07:37:32 -0800 (PST) X-ASG-Debug-ID: 1447342650-04cb6c296c13cf40001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id ijQbGgxqOCGDVQ1S (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 12 Nov 2015 07:37:30 -0800 (PST) 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 (Postfix) with ESMTPS id E403FB4C4D for ; Thu, 12 Nov 2015 15:37:29 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-36.bos.redhat.com [10.18.41.36]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tACFbTm3014213 for ; Thu, 12 Nov 2015 10:37:29 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id BB0C71201BD; Thu, 12 Nov 2015 10:37:28 -0500 (EST) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH v2 7/8] xfs: detect and trim torn writes during log recovery Date: Thu, 12 Nov 2015 10:37:27 -0500 X-ASG-Orig-Subj: [PATCH v2 7/8] xfs: detect and trim torn writes during log recovery Message-Id: <1447342648-40012-8-git-send-email-bfoster@redhat.com> In-Reply-To: <1447342648-40012-1-git-send-email-bfoster@redhat.com> References: <1447342648-40012-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: 1447342650 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Certain types of storage, such as persistent memory, do not provide sector atomicity for writes. This means that if a crash occurs while XFS is writing log records, only part of those records might make it to the storage. This is problematic because log recovery uses the cycle value packed at the top of each log block to locate the head/tail of the log. This can lead to CRC verification failures during log recovery and an unmountable fs for a filesystem that is otherwise consistent. Update log recovery to incorporate log record CRC verification as part of the head/tail discovery process. Once the head is located via the traditional algorithm, run a CRC-only pass over the records up to the head of the log. If CRC verification fails, assume that the records are torn as a matter of policy and trim the head block back to the start of the first bad record. Signed-off-by: Brian Foster --- fs/xfs/xfs_log_recover.c | 306 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 287 insertions(+), 19 deletions(-) diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 423c36d..5bf8076 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -61,6 +61,9 @@ xlog_recover_check_summary( #else #define xlog_recover_check_summary(log) #endif +STATIC int +xlog_do_recovery_pass( + struct xlog *, xfs_daddr_t, xfs_daddr_t, int, xfs_daddr_t *); /* * This structure is used during recovery to record the buf log items which @@ -941,6 +944,278 @@ out_error: } /* + * Seek forward in the log for log record headers. + * + * Given head and tail blocks, walk forward from the tail block until we find + * the provided number of records or hit the head block. The return value is the + * number of records encountered or a negative error code. The log block and + * buffer pointer of the last record seen are returned in rblk and rhead + * respectively. + */ +STATIC int +xlog_seek_logrec_hdr( + struct xlog *log, + xfs_daddr_t head_blk, + xfs_daddr_t tail_blk, + int count, + struct xfs_buf *bp, + xfs_daddr_t *rblk, + struct xlog_rec_header **rhead, + bool *wrapped) +{ + int i; + int error; + int found = 0; + char *offset = NULL; + xfs_daddr_t end_blk; + + *wrapped = false; + + /* + * Walk forward from the tail block until we hit the head or the last + * block in the log. + */ + end_blk = head_blk > tail_blk ? head_blk : log->l_logBBsize - 1; + for (i = (int) tail_blk; i <= end_blk; i++) { + error = xlog_bread(log, i, 1, bp, &offset); + if (error) + goto out_error; + + if (*(__be32 *) offset == cpu_to_be32(XLOG_HEADER_MAGIC_NUM)) { + *rblk = i; + *rhead = (struct xlog_rec_header *) offset; + if (++found == count) + break; + } + } + + /* + * If we haven't hit the head block or the log record header count, + * start looking again from the start of the physical log. + */ + if (tail_blk > head_blk && found != count) { + for (i = 0; i < (int) head_blk; i++) { + error = xlog_bread(log, i, 1, bp, &offset); + if (error) + goto out_error; + + if (*(__be32 *)offset == + cpu_to_be32(XLOG_HEADER_MAGIC_NUM)) { + *wrapped = true; + *rblk = i; + *rhead = (struct xlog_rec_header *) offset; + if (++found == count) + break; + } + } + } + + return found; + +out_error: + return error; +} + +/* + * Check the log tail for torn writes. This is required when torn writes are + * detected at the head and the head had to be walked back to a previous record. + * The tail of the previous record must now be verified to ensure the torn + * writes didn't corrupt the previous tail. + * + * Return an error if CRC verification fails as recovery cannot proceed. + */ +STATIC int +xlog_verify_tail( + struct xlog *log, + xfs_daddr_t head_blk, + xfs_daddr_t tail_blk) +{ + struct xlog_rec_header *thead; + struct xfs_buf *bp; + xfs_daddr_t first_bad; + int count; + int error = 0; + bool wrapped; + xfs_daddr_t tmp_head; + + bp = xlog_get_bp(log, 1); + if (!bp) + return -ENOMEM; + + /* + * Seek XLOG_MAX_ICLOGS + 1 records past the current tail record to get + * a temporary head block that points after the last possible + * concurrently written record of the tail. + */ + count = xlog_seek_logrec_hdr(log, head_blk, tail_blk, + XLOG_MAX_ICLOGS + 1, bp, &tmp_head, &thead, + &wrapped); + if (count < 0) { + error = count; + goto out; + } + + /* + * If the call above didn't find XLOG_MAX_ICLOGS + 1 records, we ran + * into the actual log head. tmp_head points to the start of the record + * so update it to the actual head block. + */ + if (count < XLOG_MAX_ICLOGS + 1) + tmp_head = head_blk; + + /* + * We now have a tail and temporary head block that covers at least + * XLOG_MAX_ICLOGS records from the tail. We need to verify that these + * records were completely written. Run a CRC verification pass from + * tail to head and return the result. + */ + error = xlog_do_recovery_pass(log, tmp_head, tail_blk, + XLOG_RECOVER_CRCPASS, &first_bad); + +out: + xlog_put_bp(bp); + return error; +} + +/* + * Detect and trim torn writes from the head of the log. + * + * Storage without sector atomicity guarantees can result in torn writes in the + * log in the event of a crash. Our only means to detect this scenario is via + * CRC verification. While we can't always be certain that CRC verification + * failure is due to a torn write vs. an unrelated corruption, we do know that + * only a certain number (XLOG_MAX_ICLOGS) of log records can be written out at + * one time. Therefore, CRC verify up to XLOG_MAX_ICLOGS records at the head of + * the log and treat failures in this range as torn writes as a matter of + * policy. In the event of CRC failure, the head is walked back to the last good + * record in the log and the tail is updated from that record and verified. + */ +STATIC int +xlog_verify_head( + struct xlog *log, + xfs_daddr_t *head_blk, /* in/out: unverified head */ + xfs_daddr_t *tail_blk, /* out: tail block */ + struct xfs_buf *bp, + xfs_daddr_t *rhead_blk, /* start blk of last record */ + struct xlog_rec_header **rhead, /* ptr to last record */ + bool *wrapped) /* last rec. wraps phys. log */ +{ + struct xlog_rec_header *tmp_rhead; + struct xfs_buf *tmp_bp; + xfs_daddr_t first_bad; + xfs_daddr_t tmp_rhead_blk; + int found; + int error; + bool tmp_wrapped; + + /* + * Search backwards through the log looking for the log record header + * block. This wraps all the way back around to the head so something is + * seriously wrong if we can't find it. + */ + found = xlog_rseek_logrec_hdr(log, *head_blk, *head_blk, 1, bp, rhead_blk, + rhead, wrapped); + if (found < 0) + return found; + if (!found) { + xfs_warn(log->l_mp, "%s: couldn't find sync record", __func__); + return -EIO; + } + + *tail_blk = BLOCK_LSN(be64_to_cpu((*rhead)->h_tail_lsn)); + + /* + * Now that we have a tail block, check the head of the log for torn + * writes. Search again until we hit the tail or the maximum number of + * log record I/Os that could have been in flight at one time. Use a + * temporary buffer so we don't trash the rhead/bp pointer from the + * call above. + */ + tmp_bp = xlog_get_bp(log, 1); + if (!tmp_bp) + return -ENOMEM; + error = xlog_rseek_logrec_hdr(log, *head_blk, *tail_blk, + XLOG_MAX_ICLOGS, tmp_bp, &tmp_rhead_blk, + &tmp_rhead, &tmp_wrapped); + xlog_put_bp(tmp_bp); + if (error < 0) + return error; + + /* + * Now run a CRC verification pass over the records starting at the + * block found above to the current head. If a CRC failure occurs, the + * log block of the first bad record is saved in first_bad. + */ + error = xlog_do_recovery_pass(log, *head_blk, tmp_rhead_blk, + XLOG_RECOVER_CRCPASS, &first_bad); + if (error == -EFSBADCRC) { + /* + * We've hit a potential torn write. Reset the error and warn + * about it. + */ + error = 0; + xfs_warn(log->l_mp, +"Torn write (CRC failure) detected at log block 0x%llx. Truncating head block from 0x%llx.", + first_bad, *head_blk); + + /* + * Get the header block and buffer pointer for the last good + * record before the bad record. + * + * Note that xlog_find_tail() clears the blocks at the new head + * (i.e., the records with invalid CRC) if the cycle number + * matches the the current cycle. + */ + found = xlog_rseek_logrec_hdr(log, first_bad, *tail_blk, 1, bp, + rhead_blk, rhead, wrapped); + if (found < 0) + return found; + if (found == 0) /* XXX: right thing to do here? */ + return -EIO; + + /* + * Reset the head block to the starting block of the first bad + * log record and set the tail block based on the last good + * record. + * + * Bail out if the updated head/tail match as this indicates + * possible corruption outside of the acceptable + * (XLOG_MAX_ICLOGS) range. This is a job for xfs_repair... + */ + *head_blk = first_bad; + *tail_blk = BLOCK_LSN(be64_to_cpu((*rhead)->h_tail_lsn)); + if (*head_blk == *tail_blk) { + ASSERT(0); + return 0; + } + + /* + * Now verify the tail based on the updated head. This is + * required because the torn writes trimmed from the head could + * have been written over the tail of a previous record. Return + * any errors since recovery cannot proceed if the tail is + * corrupt. + * + * XXX: This leaves a gap in truly robust protection from torn + * writes in the log. If the head is behind the tail, the tail + * pushes forward to create some space and then a crash occurs + * causing the writes into the previous record's tail region to + * tear, log recovery isn't able to recover. + * + * How likely is this to occur? If possible, can we do something + * more intelligent here? Is it safe to push the tail forward if + * we can determine that the tail is within the range of the + * torn write (e.g., the kernel can only overwrite the tail if + * it has actually been pushed forward)? Alternatively, could we + * somehow prevent this condition at runtime? + */ + error = xlog_verify_tail(log, *head_blk, *tail_blk); + } + + return error; +} + +/* * Find the sync block number or the tail of the log. * * This will be the block number of the last record to have its @@ -966,9 +1241,10 @@ xlog_find_tail( xlog_op_header_t *op_head; char *offset = NULL; xfs_buf_t *bp; - int error, i, found; + int error; xfs_daddr_t umount_data_blk; xfs_daddr_t after_umount_blk; + xfs_daddr_t rhead_blk; xfs_lsn_t tail_lsn; int hblks; bool wrapped = false; @@ -995,24 +1271,16 @@ xlog_find_tail( } /* - * Search backwards through the log looking for the log record header - * block. This wraps all the way back around to the head so something is - * seriously wrong if we can't find it. + * Trim the head block back to skip over torn records. We can have + * multiple log I/Os in flight at any time, so we assume CRC failures + * back through the previous several records are torn writes and skip + * them. */ ASSERT(*head_blk < INT_MAX); - found = xlog_rseek_logrec_hdr(log, *head_blk, *head_blk, 1, bp, &i, - &rhead, &wrapped); - if (found < 0) { - error = found; + error = xlog_verify_head(log, head_blk, tail_blk, bp, &rhead_blk, + &rhead, &wrapped); + if (error) goto done; - } - if (!found) { - xfs_warn(log->l_mp, "%s: couldn't find sync record", __func__); - xlog_put_bp(bp); - ASSERT(0); - return -EIO; - } - *tail_blk = BLOCK_LSN(be64_to_cpu(rhead->h_tail_lsn)); /* * Reset log values according to the state of the log when we @@ -1024,7 +1292,7 @@ xlog_find_tail( * written was complete and ended exactly on the end boundary * of the physical log. */ - log->l_prev_block = i; + log->l_prev_block = rhead_blk; log->l_curr_block = (int)*head_blk; log->l_curr_cycle = be32_to_cpu(rhead->h_cycle); if (wrapped) @@ -1062,12 +1330,12 @@ xlog_find_tail( } else { hblks = 1; } - after_umount_blk = (i + hblks + (int) + after_umount_blk = (rhead_blk + hblks + (int) BTOBB(be32_to_cpu(rhead->h_len))) % log->l_logBBsize; tail_lsn = atomic64_read(&log->l_tail_lsn); if (*head_blk == after_umount_blk && be32_to_cpu(rhead->h_num_logops) == 1) { - umount_data_blk = (i + hblks) % log->l_logBBsize; + umount_data_blk = (rhead_blk + hblks) % log->l_logBBsize; error = xlog_bread(log, umount_data_blk, 1, bp, &offset); if (error) goto done; -- 2.1.0 From bfoster@redhat.com Thu Nov 12 09:37:34 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 ECCD17F6C for ; Thu, 12 Nov 2015 09:37:33 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id A341CAC001 for ; Thu, 12 Nov 2015 07:37:30 -0800 (PST) X-ASG-Debug-ID: 1447342649-04bdf03f03142600001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id Dcw20R1TNP5aQgG5 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 12 Nov 2015 07:37:29 -0800 (PST) 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 (Postfix) with ESMTPS id 451B14AD67 for ; Thu, 12 Nov 2015 15:37:29 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-36.bos.redhat.com [10.18.41.36]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tACFbS55032666 for ; Thu, 12 Nov 2015 10:37:29 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id 6FB0F120042; Thu, 12 Nov 2015 10:37:28 -0500 (EST) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH v2 1/8] xfs: detect and handle invalid iclog size set by mkfs Date: Thu, 12 Nov 2015 10:37:21 -0500 X-ASG-Orig-Subj: [PATCH v2 1/8] xfs: detect and handle invalid iclog size set by mkfs Message-Id: <1447342648-40012-2-git-send-email-bfoster@redhat.com> In-Reply-To: <1447342648-40012-1-git-send-email-bfoster@redhat.com> References: <1447342648-40012-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: 1447342649 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 XFS log records have separate fields for the record size and the iclog size used to write the record. mkfs.xfs zeroes the log and writes an unmount record to generate a clean log for the subsequent mount. The userspace record logging code has a bug where the iclog size (h_size) field of the log record is hardcoded to 32k, even if a log stripe unit is specified. The log record length is correctly extended to the stripe unit. Since the kernel log recovery code uses the h_size field to determine the log buffer size, this means that the kernel can attempt to read/process records larger than the buffer size and overrun the buffer. This has historically not been a problem because the kernel doesn't actually run through log recovery in the clean unmount case. Instead, the kernel detects that a single unmount record exists between the head and tail and pushes the tail forward such that the log is viewed as clean (head == tail). Once CRC verification is enabled, however, all records at the head of the log are verified for CRC errors and thus we are susceptible to overrun problems if the iclog field is not correct. While the core problem must be fixed in userspace, this is historical behavior that must be detected in the kernel to avoid severe side effects such as memory corruption and crashes. Update the log buffer size calculation code to detect this condition, warn the user and resize the log buffer based on the log stripe unit. Return a corruption error in cases where this does not look like a clean filesystem (i.e., the log record header indicates more than one operation). Signed-off-by: Brian Foster --- fs/xfs/xfs_log_recover.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index c5ecaac..4f880d6 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -4245,7 +4245,7 @@ xlog_do_recovery_pass( xfs_daddr_t blk_no; char *offset; xfs_buf_t *hbp, *dbp; - int error = 0, h_size; + int error = 0, h_size, h_len; int bblks, split_bblks; int hblks, split_hblks, wrapped_hblks; struct hlist_head rhash[XLOG_RHASH_SIZE]; @@ -4274,7 +4274,31 @@ xlog_do_recovery_pass( error = xlog_valid_rec_header(log, rhead, tail_blk); if (error) goto bread_err1; + + /* + * xfsprogs has a bug where record length is based on lsunit but + * h_size (iclog size) is hardcoded to 32k. Now that we + * unconditionally CRC verify the unmount record, this means the + * log buffer can be too small for the record and cause an + * overrun. + * + * Detect this condition here. Use lsunit for the buffer size as + * long as this looks like the mkfs case. Otherwise, return an + * error to avoid a buffer overrun. + */ h_size = be32_to_cpu(rhead->h_size); + h_len = be32_to_cpu(rhead->h_len); + if (h_len > h_size) { + if (h_len <= log->l_mp->m_logbsize && + be32_to_cpu(rhead->h_num_logops) == 1) { + xfs_warn(log->l_mp, + "invalid iclog size (%d bytes), using lsunit (%d bytes)", + h_size, log->l_mp->m_logbsize); + h_size = log->l_mp->m_logbsize; + } else + return -EFSCORRUPTED; + } + if ((be32_to_cpu(rhead->h_version) & XLOG_VERSION_2) && (h_size > XLOG_HEADER_CYCLE_SIZE)) { hblks = h_size / XLOG_HEADER_CYCLE_SIZE; -- 2.1.0 From bfoster@redhat.com Thu Nov 12 09:37:34 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 C27767F77 for ; Thu, 12 Nov 2015 09:37:34 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id B0682304039 for ; Thu, 12 Nov 2015 07:37:31 -0800 (PST) X-ASG-Debug-ID: 1447342649-04cb6c296b13cf30001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id D3pCuT5eHBL03U8B (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 12 Nov 2015 07:37:29 -0800 (PST) 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 (Postfix) with ESMTPS id 5211D8F4E0 for ; Thu, 12 Nov 2015 15:37:29 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-36.bos.redhat.com [10.18.41.36]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tACFbTln032668 for ; Thu, 12 Nov 2015 10:37:29 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id 7C26912014A; Thu, 12 Nov 2015 10:37:28 -0500 (EST) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH v2 2/8] xfs: refactor log record unpack and data processing Date: Thu, 12 Nov 2015 10:37:22 -0500 X-ASG-Orig-Subj: [PATCH v2 2/8] xfs: refactor log record unpack and data processing Message-Id: <1447342648-40012-3-git-send-email-bfoster@redhat.com> In-Reply-To: <1447342648-40012-1-git-send-email-bfoster@redhat.com> References: <1447342648-40012-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: 1447342649 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 xlog_do_recovery_pass() duplicates a couple function calls related to processing log records because the function must handle wrapping around the end of the log if the head is behind the tail. This is implemented as separate loops. CRC verification pass support will modify how records are processed in both of these loops. Rather than continue to duplicate code, factor the calls that process a log record into a new helper and call that helper from both loops. This patch contains no functional changes. Signed-off-by: Brian Foster --- fs/xfs/xfs_log_recover.c | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 4f880d6..236ebaf 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -4190,6 +4190,26 @@ xlog_unpack_data( return 0; } +/* + * Unpack and process a log record. + */ +STATIC int +xlog_recover_process( + struct xlog *log, + struct hlist_head rhash[], + struct xlog_rec_header *rhead, + char *dp, + int pass) +{ + int error; + + error = xlog_unpack_data(rhead, dp, log); + if (error) + return error; + + return xlog_recover_process_data(log, rhash, rhead, dp, pass); +} + STATIC int xlog_valid_rec_header( struct xlog *log, @@ -4432,12 +4452,8 @@ xlog_do_recovery_pass( goto bread_err2; } - error = xlog_unpack_data(rhead, offset, log); - if (error) - goto bread_err2; - - error = xlog_recover_process_data(log, rhash, - rhead, offset, pass); + error = xlog_recover_process(log, rhash, rhead, offset, + pass); if (error) goto bread_err2; blk_no += bblks; @@ -4465,12 +4481,7 @@ xlog_do_recovery_pass( if (error) goto bread_err2; - error = xlog_unpack_data(rhead, offset, log); - if (error) - goto bread_err2; - - error = xlog_recover_process_data(log, rhash, - rhead, offset, pass); + error = xlog_recover_process(log, rhash, rhead, offset, pass); if (error) goto bread_err2; blk_no += bblks + hblks; -- 2.1.0 From sandeen@sandeen.net Thu Nov 12 09:50:29 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 95FBF7F67 for ; Thu, 12 Nov 2015 09:50:29 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 821568F8049 for ; Thu, 12 Nov 2015 07:50:29 -0800 (PST) X-ASG-Debug-ID: 1447343426-04cb6c296a13d520001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id h6OxIOxyr0y5coL3 for ; Thu, 12 Nov 2015 07:50:26 -0800 (PST) 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 2D8A965FC660 for ; Thu, 12 Nov 2015 09:50:26 -0600 (CST) Subject: Re: [PATCH] xfs_fsr: more selinux fixes To: xfs@oss.sgi.com X-ASG-Orig-Subj: Re: [PATCH] xfs_fsr: more selinux fixes References: <5643B8B7.9030708@sandeen.net> <20151112131242.GB5068@bfoster.bfoster> From: Eric Sandeen Message-ID: <5644B541.8070207@sandeen.net> Date: Thu, 12 Nov 2015 09:50:25 -0600 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <20151112131242.GB5068@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: 1447343426 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24333 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 11/12/15 7:12 AM, Brian Foster wrote: > On Wed, Nov 11, 2015 at 03:52:55PM -0600, Eric Sandeen wrote: >> Commit: >> >> 1adfe5c xfs_fsr: fix SWAPEXT failures under selinux >> >> attempted to fix up the fork offset under selinux, where >> the temp file is created with a local attribute, but the >> target file has remote attributes; this can lead to a smaller >> data area in the temp inode, without enough room to swap extents >> from the target inode. I remedied this by pushing the temp >> file attribute to remote, but *only* if the target file's attr >> was also remote. >> >> However, I have a case from the field where the parent dir >> and the target file both have a context of: >> >> system_u:object_r:samba_share_t:s0 >> >> but new files created in the dir have a context of >> >> unconfined_u:object_r:samba_share_t:s0 >> >> This means the temp file has a smaller forkoff, and less space >> in the inode for data, so we fail to swap the extents between >> the two, because they don't fit. >> >> The following patch fixes this by allowing xfs_fsr to >> kick the tempfile's attr out of local format even if the target >> file's attr is local, if this will move the forkoff in the right >> direction. This does pass all our fsr xfstests, though I'm not >> sure we have any real coverage of fsr under selinux... >> >> The only functional change is the test at the very end of the >> patch; the rest is comments, ascii art, and removing the >> now-extraneous XFS_IOC_FSGETXATTRA ioctl. >> >> Signed-off-by: Eric Sandeen >> --- >> >> diff --git a/fsr/xfs_fsr.c b/fsr/xfs_fsr.c >> index c8ef18f..68b9819 100644 >> --- a/fsr/xfs_fsr.c >> +++ b/fsr/xfs_fsr.c > ... >> /* >> - * If target attr area is less than the temp's (diff < 0) >> - * and the target is not local, write a big attr to >> - * the temp file to knock the attr out of local format, >> - * to match the target. (This should actually *increase* >> - * the temp file's forkoffset when the attr moves out >> - * of the inode) >> + * If target attr area is less than the temp's >> + * (diff < 0), write a big attr to the temp file to knock >> + * the attr out of local format. >> + * (This should actually *increase* the temp file's >> + * forkoffset when the attr moves out of the inode) >> */ >> - if (diff < 0 && fsx.fsx_nextents > 0) { >> + if (diff < 0) { > > Space before tab issue on the line above. Looks fine otherwise, but I > wonder if it would also be a good idea to add an informative fsrprintf() > here if we proceed when (fsx.fsx_nextents > 0)? I can add a debug message, sure - I'm not sure when it would be useful, but we have plenty of other fiddly messages in there about what action is taken. Thanks, -Eric From bfoster@redhat.com Thu Nov 12 09:51:59 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 6EA887F67 for ; Thu, 12 Nov 2015 09:51:59 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 5C7D68F8033 for ; Thu, 12 Nov 2015 07:51:59 -0800 (PST) X-ASG-Debug-ID: 1447343517-04cb6c296d13d5b0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id tj5sNmVWR3zWGVHb (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 12 Nov 2015 07:51:58 -0800 (PST) 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 (Postfix) with ESMTPS id 61DBF42E5B9; Thu, 12 Nov 2015 15:51:57 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-36.bos.redhat.com [10.18.41.36]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tACFpuIF014109; Thu, 12 Nov 2015 10:51:57 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id 723C2120059; Thu, 12 Nov 2015 10:51:56 -0500 (EST) From: Brian Foster To: fstests@vger.kernel.org Cc: xfs@oss.sgi.com Subject: [RFC PATCH] xfs: test XFS torn log write detection Date: Thu, 12 Nov 2015 10:51:56 -0500 X-ASG-Orig-Subj: [RFC PATCH] xfs: test XFS torn log write detection Message-Id: <1447343516-41363-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: 1447343518 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 XFS torn log write detection includes a mechanism to inject CRC errors into log records at runtime and shutdown the fs accordingly. This ensures that the CRC verification pass on the subsequent mount discovers an invalid record near the head of the log and considers it a torn write. This test runs a workload with error injection enabled and verifies that the subsequent mount is successful. The test repeats for several iterations using a random frequency factor for the error event each time. Signed-off-by: Brian Foster --- Hi all, This test accompanies the torn log write detection series here: http://oss.sgi.com/pipermail/xfs/2015-November/044945.html ... and is based on the associated test mechanism. Note that this is quick and dirty and subject to change based on review of that series. I also hadn't put too much thought into how many iterations to use, how long the test should run in general and what the range of the injection param should be. As such, this is RFC for now. Thoughts appreciated. Brian tests/xfs/350 | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/xfs/350.out | 2 ++ tests/xfs/group | 1 + 3 files changed, 88 insertions(+) create mode 100755 tests/xfs/350 create mode 100644 tests/xfs/350.out diff --git a/tests/xfs/350 b/tests/xfs/350 new file mode 100755 index 0000000..f18637a --- /dev/null +++ b/tests/xfs/350 @@ -0,0 +1,85 @@ +#! /bin/bash +# FS QA Test No. 350 +# +# Use the XFS log record CRC error injection mechanism to test torn writes to +# the log. The error injection mechanism writes an invalid CRC and shuts down +# the filesystem. The test verifies that a subsequent remount recovers the log +# and that the filesystem is consistent. +# +# Note that this test requires a DEBUG mode kernel. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015 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.* + killall -9 fsstress > /dev/null 2>&1 + wait > /dev/null 2>&1 +} + +rm -f $seqres.full + +# get standard environment, filters and checks +. ./common/rc + +# real QA test starts here + +# Modify as appropriate. +_supported_fs xfs +_supported_os Linux +_require_xfs_sysfs $(_short_dev $SCRATCH_DEV)/log/log_badcrc_factor +_require_scratch + +echo "Silence is golden." + +_scratch_mkfs >> $seqres.full 2>&1 || _fail "mkfs failed" +_scratch_mount + +sdev=$(_short_dev $SCRATCH_DEV) + +for i in $(seq 1 5); do + # Enable error injection. Use a random bad crc factor up to 100 + # (increase this value to run fsstress longer). + factor=$((RANDOM % 100)) + echo iteration $i log_badcrc_factor: $factor >> $seqres.full 2>&1 + echo $factor > /sys/fs/xfs/$sdev/log/log_badcrc_factor + + # Run fsstress until the filesystem shuts down. It will shut down + # automatically when error injection triggers. + $FSSTRESS_PROG -d $SCRATCH_MNT -p 4 -n 999999 >> $seqres.full 2>&1 + + # Verify that we can remount the fs. Log recovery should handle the torn + # write. + _scratch_unmount + _scratch_mount || _fail "failed to mount" +done + +# success, all done +status=0 +exit diff --git a/tests/xfs/350.out b/tests/xfs/350.out new file mode 100644 index 0000000..c725135 --- /dev/null +++ b/tests/xfs/350.out @@ -0,0 +1,2 @@ +QA output created by 350 +Silence is golden. diff --git a/tests/xfs/group b/tests/xfs/group index 8261f86..bf66c0f 100644 --- a/tests/xfs/group +++ b/tests/xfs/group @@ -220,3 +220,4 @@ 303 auto quick quota 304 auto quick quota 305 auto quota +350 auto log metadata -- 2.1.0 From sandeen@sandeen.net Thu Nov 12 09:58:49 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 2AEBF7F66 for ; Thu, 12 Nov 2015 09:58:49 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id E8D3E304039 for ; Thu, 12 Nov 2015 07:58:48 -0800 (PST) X-ASG-Debug-ID: 1447343926-04bdf03f03143020001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id NbU7rcsJNNwE3bb8 for ; Thu, 12 Nov 2015 07:58:46 -0800 (PST) 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 8C58F65FC660 for ; Thu, 12 Nov 2015 09:58:46 -0600 (CST) Subject: [PATCH V2] xfs_fsr: more selinux fixes To: xfs@oss.sgi.com X-ASG-Orig-Subj: [PATCH V2] xfs_fsr: more selinux fixes References: <5643B8B7.9030708@sandeen.net> From: Eric Sandeen Message-ID: <5644B735.2090002@sandeen.net> Date: Thu, 12 Nov 2015 09:58:45 -0600 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <5643B8B7.9030708@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: 1447343926 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24333 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Commit: 1adfe5c xfs_fsr: fix SWAPEXT failures under selinux attempted to fix up the fork offset under selinux, where the temp file is created with a local attribute, but the target file has remote attributes; this can lead to a smaller data area in the temp inode, without enough room to swap extents from the target inode. I remedied this by pushing the temp file attribute to remote, but *only* if the target file's attr was also remote. However, I have a case from the field where the parent dir and the target file both have a context of: system_u:object_r:samba_share_t:s0 but new files created in the dir have a context of unconfined_u:object_r:samba_share_t:s0 This means the temp file has a smaller forkoff, and less space in the inode for data, so we fail to swap the extents between the two, because they don't fit. The following patch fixes this by allowing xfs_fsr to kick the tempfile's attr out of local format even if the target file's attr is local, if this will move the forkoff in the right direction. This does pass all our fsr xfstests, though I'm not sure we have any real coverage of fsr under selinux... The only functional change is the test at the very end of the patch; the rest is comments, ascii art, and removing the now-extraneous XFS_IOC_FSGETXATTRA ioctl. Signed-off-by: Eric Sandeen --- V2: Fix a whitespace issue. Brian, I didn't add the debug printf; we don't do it for any other attr operations unless they fail, and I don't think it's needed here either. And I couldn't fit it gracefully into 80 cols. ;) diff --git a/fsr/xfs_fsr.c b/fsr/xfs_fsr.c index b902acc..2bae1d0 100644 --- a/fsr/xfs_fsr.c +++ b/fsr/xfs_fsr.c @@ -1115,14 +1115,12 @@ fsr_setup_attr_fork( } continue; } else if (i == 0) { - struct fsxattr fsx; /* * First pass, and temp file already has an inline * xattr, probably due to selinux. * * It's *possible* that the temp file attr area - * is larger than the target file's, if the - * target file's attrs are not inline: + * is larger than the target file's: * * Target Temp * +-------+ 0 +-------+ 0 @@ -1132,28 +1130,18 @@ fsr_setup_attr_fork( * | | v-------v forkoff * | | | | * v-------v forkoff | Attr | local - * | Attr | ext/btree | | + * | Attr | | | * +-------+ +-------+ - * - * FSGETXATTRA will tell us nr of attr extents in - * target, if any. If none, it's local: */ - memset(&fsx, 0, sizeof(fsx)); - if (ioctl(fd, XFS_IOC_FSGETXATTRA, &fsx)) { - fsrprintf(_("FSGETXATTRA failed on target\n")); - return -1; - } - /* - * If target attr area is less than the temp's (diff < 0) - * and the target is not local, write a big attr to - * the temp file to knock the attr out of local format, - * to match the target. (This should actually *increase* - * the temp file's forkoffset when the attr moves out - * of the inode) + * If target attr area is less than the temp's + * (diff < 0) write a big attr to the temp file to knock + * the attr out of local format. + * (This should actually *increase* the temp file's + * forkoffset when the attr moves out of the inode) */ - if (diff < 0 && fsx.fsx_nextents > 0) { + if (diff < 0) { char val[2048]; memset(val, 'X', 2048); if (fsetxattr(tfd, name, val, 2048, 0)) { From bfoster@redhat.com Thu Nov 12 10:05:28 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 2D3477F66 for ; Thu, 12 Nov 2015 10:05:28 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 1A94F304032 for ; Thu, 12 Nov 2015 08:05:24 -0800 (PST) X-ASG-Debug-ID: 1447344323-04cb6c296a13db20001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id eq91RkDknVgEsO5s (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 12 Nov 2015 08:05:23 -0800 (PST) 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 (Postfix) with ESMTPS id 1B5658F506; Thu, 12 Nov 2015 16:05:23 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-36.bos.redhat.com [10.18.41.36]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tACG5MMW025559; Thu, 12 Nov 2015 11:05:22 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id 1799C120059; Thu, 12 Nov 2015 11:05:22 -0500 (EST) Date: Thu, 12 Nov 2015 11:05:22 -0500 From: Brian Foster To: Eric Sandeen Cc: xfs@oss.sgi.com Subject: Re: [PATCH V2] xfs_fsr: more selinux fixes Message-ID: <20151112160521.GE5068@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH V2] xfs_fsr: more selinux fixes References: <5643B8B7.9030708@sandeen.net> <5644B735.2090002@sandeen.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <5644B735.2090002@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: 1447344323 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Thu, Nov 12, 2015 at 09:58:45AM -0600, Eric Sandeen wrote: > Commit: > > 1adfe5c xfs_fsr: fix SWAPEXT failures under selinux > > attempted to fix up the fork offset under selinux, where > the temp file is created with a local attribute, but the > target file has remote attributes; this can lead to a smaller > data area in the temp inode, without enough room to swap extents > from the target inode. I remedied this by pushing the temp > file attribute to remote, but *only* if the target file's attr > was also remote. > > However, I have a case from the field where the parent dir > and the target file both have a context of: > > system_u:object_r:samba_share_t:s0 > > but new files created in the dir have a context of > > unconfined_u:object_r:samba_share_t:s0 > > This means the temp file has a smaller forkoff, and less space > in the inode for data, so we fail to swap the extents between > the two, because they don't fit. > > The following patch fixes this by allowing xfs_fsr to > kick the tempfile's attr out of local format even if the target > file's attr is local, if this will move the forkoff in the right > direction. This does pass all our fsr xfstests, though I'm not > sure we have any real coverage of fsr under selinux... > > The only functional change is the test at the very end of the > patch; the rest is comments, ascii art, and removing the > now-extraneous XFS_IOC_FSGETXATTRA ioctl. > > Signed-off-by: Eric Sandeen > --- > > V2: Fix a whitespace issue. > > Brian, I didn't add the debug printf; we don't do it for any > other attr operations unless they fail, and I don't think it's needed > here either. And I couldn't fit it gracefully into 80 cols. ;) > Ok, no problem. I was originally thinking that this would affect the target file. As pointed out on IRC, the target file xattrs should remain unmodified and the extent information is just swapped into the data area. Looks fine to me: Reviewed-by: Brian Foster > diff --git a/fsr/xfs_fsr.c b/fsr/xfs_fsr.c > index b902acc..2bae1d0 100644 > --- a/fsr/xfs_fsr.c > +++ b/fsr/xfs_fsr.c > @@ -1115,14 +1115,12 @@ fsr_setup_attr_fork( > } > continue; > } else if (i == 0) { > - struct fsxattr fsx; > /* > * First pass, and temp file already has an inline > * xattr, probably due to selinux. > * > * It's *possible* that the temp file attr area > - * is larger than the target file's, if the > - * target file's attrs are not inline: > + * is larger than the target file's: > * > * Target Temp > * +-------+ 0 +-------+ 0 > @@ -1132,28 +1130,18 @@ fsr_setup_attr_fork( > * | | v-------v forkoff > * | | | | > * v-------v forkoff | Attr | local > - * | Attr | ext/btree | | > + * | Attr | | | > * +-------+ +-------+ > - * > - * FSGETXATTRA will tell us nr of attr extents in > - * target, if any. If none, it's local: > */ > > - memset(&fsx, 0, sizeof(fsx)); > - if (ioctl(fd, XFS_IOC_FSGETXATTRA, &fsx)) { > - fsrprintf(_("FSGETXATTRA failed on target\n")); > - return -1; > - } > - > /* > - * If target attr area is less than the temp's (diff < 0) > - * and the target is not local, write a big attr to > - * the temp file to knock the attr out of local format, > - * to match the target. (This should actually *increase* > - * the temp file's forkoffset when the attr moves out > - * of the inode) > + * If target attr area is less than the temp's > + * (diff < 0) write a big attr to the temp file to knock > + * the attr out of local format. > + * (This should actually *increase* the temp file's > + * forkoffset when the attr moves out of the inode) > */ > - if (diff < 0 && fsx.fsx_nextents > 0) { > + if (diff < 0) { > char val[2048]; > memset(val, 'X', 2048); > if (fsetxattr(tfd, name, val, 2048, 0)) { > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From sandeen@sandeen.net Thu Nov 12 10:32:01 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 3A64C7F55 for ; Thu, 12 Nov 2015 10:32:01 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 92BF5AC002 for ; Thu, 12 Nov 2015 08:31:57 -0800 (PST) X-ASG-Debug-ID: 1447345913-04cb6c296c13e5e0001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id Ka9JCfRYZDVKlOEO for ; Thu, 12 Nov 2015 08:31:53 -0800 (PST) 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 059E165FC660 for ; Thu, 12 Nov 2015 10:31:52 -0600 (CST) Subject: [PATCH V2] xfs: create helper for bmap finish & trans join in attr code To: xfs@oss.sgi.com X-ASG-Orig-Subj: [PATCH V2] xfs: create helper for bmap finish & trans join in attr code References: <56441B8E.6070603@redhat.com> From: Eric Sandeen Message-ID: <5644BEF8.6070201@sandeen.net> Date: Thu, 12 Nov 2015 10:31:52 -0600 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <56441B8E.6070603@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: 1447345913 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24333 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Calls to xfs_bmap_finish() and xfs_trans_ijoin(), and the associated comments were replicated several times across the attribute code. Factor out a new helper function, xfs_bmap_finish_and_join() to take care of this. This also fixes an ASSERT() test of an uninitialized variable in several locations: error = xfs_attr_thing(&args); if (!error) { error = xfs_bmap_finish(&args.trans, args.flist, &committed); } if (error) { ASSERT(committed); If the first xfs_attr_thing() failed, we'd skip the xfs_bmap_finish, never set "committed", and then test it in the ASSERT. Addresses-Coverity-Id: 102360 Addresses-Coverity-Id: 102361 Addresses-Coverity-Id: 102363 Addresses-Coverity-Id: 102364 Signed-off-by: Eric Sandeen --- V2: Do the same for xfs_attr_remote.c ->>> I don't think I broke the logic, but feel free to scrutinize it :) libxfs/xfs_attr.c | 168 ++++++++++++----------------------------------- libxfs/xfs_attr_remote.c | 33 +-------- xfs_attr.h | 2 3 files changed, 52 insertions(+), 151 deletions(-) diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c index f949818..1bd430e 100644 --- a/fs/xfs/libxfs/xfs_attr.c +++ b/fs/xfs/libxfs/xfs_attr.c @@ -194,6 +194,28 @@ xfs_attr_calc_size( } int +xfs_attr_bmap_finish_and_join( + struct xfs_da_args *args, + struct xfs_inode *dp) +{ + int error, committed; + + error = xfs_bmap_finish(&args->trans, args->flist, &committed); + if (error) { + ASSERT(committed); + return error; + } + /* + * bmap_finish() may have committed the last trans and started + * a new one. We need the inode to be in all transactions. + */ + if (committed) + xfs_trans_ijoin(args->trans, dp, 0); + + return 0; +} + +int xfs_attr_set( struct xfs_inode *dp, const unsigned char *name, @@ -207,7 +229,7 @@ xfs_attr_set( struct xfs_trans_res tres; xfs_fsblock_t firstblock; int rsvd = (flags & ATTR_ROOT) != 0; - int error, err2, committed, local; + int error, err2, local; XFS_STATS_INC(mp, xs_attr_set); @@ -334,25 +356,15 @@ xfs_attr_set( */ xfs_bmap_init(args.flist, args.firstblock); error = xfs_attr_shortform_to_leaf(&args); - if (!error) { - error = xfs_bmap_finish(&args.trans, args.flist, - &committed); - } + if (!error) + error = xfs_attr_bmap_finish_and_join(&args, dp); if (error) { - ASSERT(committed); args.trans = NULL; xfs_bmap_cancel(&flist); goto out; } /* - * bmap_finish() may have committed the last trans and started - * a new one. We need the inode to be in all transactions. - */ - if (committed) - xfs_trans_ijoin(args.trans, dp, 0); - - /* * Commit the leaf transformation. We'll need another (linked) * transaction to add the new attribute to the leaf. */ @@ -568,7 +580,7 @@ xfs_attr_leaf_addname(xfs_da_args_t *args) { xfs_inode_t *dp; struct xfs_buf *bp; - int retval, error, committed, forkoff; + int retval, error, forkoff; trace_xfs_attr_leaf_addname(args); @@ -628,25 +640,15 @@ xfs_attr_leaf_addname(xfs_da_args_t *args) */ xfs_bmap_init(args->flist, args->firstblock); error = xfs_attr3_leaf_to_node(args); - if (!error) { - error = xfs_bmap_finish(&args->trans, args->flist, - &committed); - } + if (!error) + error = xfs_attr_bmap_finish_and_join(args, dp); if (error) { - ASSERT(committed); args->trans = NULL; xfs_bmap_cancel(args->flist); return error; } /* - * bmap_finish() may have committed the last trans and started - * a new one. We need the inode to be in all transactions. - */ - if (committed) - xfs_trans_ijoin(args->trans, dp, 0); - - /* * Commit the current trans (including the inode) and start * a new one. */ @@ -729,25 +731,13 @@ xfs_attr_leaf_addname(xfs_da_args_t *args) xfs_bmap_init(args->flist, args->firstblock); error = xfs_attr3_leaf_to_shortform(bp, args, forkoff); /* bp is gone due to xfs_da_shrink_inode */ - if (!error) { - error = xfs_bmap_finish(&args->trans, - args->flist, - &committed); - } + if (!error) + error = xfs_attr_bmap_finish_and_join(args, dp); if (error) { - ASSERT(committed); args->trans = NULL; xfs_bmap_cancel(args->flist); return error; } - - /* - * bmap_finish() may have committed the last trans - * and started a new one. We need the inode to be - * in all transactions. - */ - if (committed) - xfs_trans_ijoin(args->trans, dp, 0); } /* @@ -775,7 +765,7 @@ xfs_attr_leaf_removename(xfs_da_args_t *args) { xfs_inode_t *dp; struct xfs_buf *bp; - int error, committed, forkoff; + int error, forkoff; trace_xfs_attr_leaf_removename(args); @@ -803,23 +793,13 @@ xfs_attr_leaf_removename(xfs_da_args_t *args) xfs_bmap_init(args->flist, args->firstblock); error = xfs_attr3_leaf_to_shortform(bp, args, forkoff); /* bp is gone due to xfs_da_shrink_inode */ - if (!error) { - error = xfs_bmap_finish(&args->trans, args->flist, - &committed); - } + if (!error) + error = xfs_attr_bmap_finish_and_join(args, dp); if (error) { - ASSERT(committed); args->trans = NULL; xfs_bmap_cancel(args->flist); return error; } - - /* - * bmap_finish() may have committed the last trans and started - * a new one. We need the inode to be in all transactions. - */ - if (committed) - xfs_trans_ijoin(args->trans, dp, 0); } return 0; } @@ -877,7 +857,7 @@ xfs_attr_node_addname(xfs_da_args_t *args) xfs_da_state_blk_t *blk; xfs_inode_t *dp; xfs_mount_t *mp; - int committed, retval, error; + int retval, error; trace_xfs_attr_node_addname(args); @@ -938,26 +918,13 @@ restart: state = NULL; xfs_bmap_init(args->flist, args->firstblock); error = xfs_attr3_leaf_to_node(args); - if (!error) { - error = xfs_bmap_finish(&args->trans, - args->flist, - &committed); - } + if (!error) + error = xfs_attr_bmap_finish_and_join(args, dp); if (error) { - ASSERT(committed); args->trans = NULL; xfs_bmap_cancel(args->flist); goto out; } - - /* - * bmap_finish() may have committed the last trans - * and started a new one. We need the inode to be - * in all transactions. - */ - if (committed) - xfs_trans_ijoin(args->trans, dp, 0); - /* * Commit the node conversion and start the next * trans in the chain. @@ -977,23 +944,13 @@ restart: */ xfs_bmap_init(args->flist, args->firstblock); error = xfs_da3_split(state); - if (!error) { - error = xfs_bmap_finish(&args->trans, args->flist, - &committed); - } + if (!error) + error = xfs_attr_bmap_finish_and_join(args, dp); if (error) { - ASSERT(committed); args->trans = NULL; xfs_bmap_cancel(args->flist); goto out; } - - /* - * bmap_finish() may have committed the last trans and started - * a new one. We need the inode to be in all transactions. - */ - if (committed) - xfs_trans_ijoin(args->trans, dp, 0); } else { /* * Addition succeeded, update Btree hashvals. @@ -1086,25 +1043,13 @@ restart: if (retval && (state->path.active > 1)) { xfs_bmap_init(args->flist, args->firstblock); error = xfs_da3_join(state); - if (!error) { - error = xfs_bmap_finish(&args->trans, - args->flist, - &committed); - } + if (!error) + error = xfs_attr_bmap_finish_and_join(args, dp); if (error) { - ASSERT(committed); args->trans = NULL; xfs_bmap_cancel(args->flist); goto out; } - - /* - * bmap_finish() may have committed the last trans - * and started a new one. We need the inode to be - * in all transactions. - */ - if (committed) - xfs_trans_ijoin(args->trans, dp, 0); } /* @@ -1146,7 +1091,7 @@ xfs_attr_node_removename(xfs_da_args_t *args) xfs_da_state_blk_t *blk; xfs_inode_t *dp; struct xfs_buf *bp; - int retval, error, committed, forkoff; + int retval, error, forkoff; trace_xfs_attr_node_removename(args); @@ -1220,24 +1165,13 @@ xfs_attr_node_removename(xfs_da_args_t *args) if (retval && (state->path.active > 1)) { xfs_bmap_init(args->flist, args->firstblock); error = xfs_da3_join(state); - if (!error) { - error = xfs_bmap_finish(&args->trans, args->flist, - &committed); - } + if (!error) + error = xfs_attr_bmap_finish_and_join(args, dp); if (error) { - ASSERT(committed); args->trans = NULL; xfs_bmap_cancel(args->flist); goto out; } - - /* - * bmap_finish() may have committed the last trans and started - * a new one. We need the inode to be in all transactions. - */ - if (committed) - xfs_trans_ijoin(args->trans, dp, 0); - /* * Commit the Btree join operation and start a new trans. */ @@ -1265,25 +1199,13 @@ xfs_attr_node_removename(xfs_da_args_t *args) xfs_bmap_init(args->flist, args->firstblock); error = xfs_attr3_leaf_to_shortform(bp, args, forkoff); /* bp is gone due to xfs_da_shrink_inode */ - if (!error) { - error = xfs_bmap_finish(&args->trans, - args->flist, - &committed); - } + if (!error) + error = xfs_attr_bmap_finish_and_join(args, dp); if (error) { - ASSERT(committed); args->trans = NULL; xfs_bmap_cancel(args->flist); goto out; } - - /* - * bmap_finish() may have committed the last trans - * and started a new one. We need the inode to be - * in all transactions. - */ - if (committed) - xfs_trans_ijoin(args->trans, dp, 0); } else xfs_trans_brelse(args->trans, bp); } diff --git a/fs/xfs/libxfs/xfs_attr_remote.c b/fs/xfs/libxfs/xfs_attr_remote.c index f3ed9bf..b66a83e 100644 --- a/fs/xfs/libxfs/xfs_attr_remote.c +++ b/fs/xfs/libxfs/xfs_attr_remote.c @@ -448,8 +448,6 @@ xfs_attr_rmtval_set( * Roll through the "value", allocating blocks on disk as required. */ while (blkcnt > 0) { - int committed; - /* * Allocate a single extent, up to the size of the value. * @@ -467,24 +465,14 @@ xfs_attr_rmtval_set( error = xfs_bmapi_write(args->trans, dp, (xfs_fileoff_t)lblkno, blkcnt, XFS_BMAPI_ATTRFORK, args->firstblock, args->total, &map, &nmap, args->flist); - if (!error) { - error = xfs_bmap_finish(&args->trans, args->flist, - &committed); - } + if (!error) + xfs_attr_bmap_finish_and_join(args, dp); if (error) { - ASSERT(committed); args->trans = NULL; xfs_bmap_cancel(args->flist); return error; } - /* - * bmap_finish() may have committed the last trans and started - * a new one. We need the inode to be in all transactions. - */ - if (committed) - xfs_trans_ijoin(args->trans, dp, 0); - ASSERT(nmap == 1); ASSERT((map.br_startblock != DELAYSTARTBLOCK) && (map.br_startblock != HOLESTARTBLOCK)); @@ -615,31 +603,20 @@ xfs_attr_rmtval_remove( blkcnt = args->rmtblkcnt; done = 0; while (!done) { - int committed; - xfs_bmap_init(args->flist, args->firstblock); error = xfs_bunmapi(args->trans, args->dp, lblkno, blkcnt, XFS_BMAPI_ATTRFORK, 1, args->firstblock, args->flist, &done); - if (!error) { - error = xfs_bmap_finish(&args->trans, args->flist, - &committed); - } + if (!error) + error = xfs_attr_bmap_finish_and_join(args, args->dp); + if (error) { - ASSERT(committed); args->trans = NULL; xfs_bmap_cancel(args->flist); return error; } /* - * bmap_finish() may have committed the last trans and started - * a new one. We need the inode to be in all transactions. - */ - if (committed) - xfs_trans_ijoin(args->trans, args->dp, 0); - - /* * Close out trans and start the next one in the chain. */ error = xfs_trans_roll(&args->trans, args->dp); diff --git a/fs/xfs/xfs_attr.h b/fs/xfs/xfs_attr.h index dd48245..18813d0 100644 --- a/fs/xfs/xfs_attr.h +++ b/fs/xfs/xfs_attr.h @@ -144,6 +144,8 @@ int xfs_attr_list_int(struct xfs_attr_list_context *); int xfs_inode_hasattr(struct xfs_inode *ip); int xfs_attr_get(struct xfs_inode *ip, const unsigned char *name, unsigned char *value, int *valuelenp, int flags); +int xfs_attr_bmap_finish_and_join(struct xfs_da_args *args, + struct xfs_inode *dp); int xfs_attr_set(struct xfs_inode *dp, const unsigned char *name, unsigned char *value, int valuelen, int flags); int xfs_attr_remove(struct xfs_inode *dp, const unsigned char *name, int flags); From BATV+89ba7098823c58057a3d+4463+infradead.org+hch@bombadil.srs.infradead.org Thu Nov 12 10:58:05 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 5A0437F62 for ; Thu, 12 Nov 2015 10:58:05 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id B4C65AC004 for ; Thu, 12 Nov 2015 08:58:04 -0800 (PST) X-ASG-Debug-ID: 1447347481-04cbb02423154a80001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id cM8DqH4jKGBlB0nn (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Thu, 12 Nov 2015 08:58:02 -0800 (PST) X-Barracuda-Envelope-From: BATV+89ba7098823c58057a3d+4463+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 1ZwvCD-0001g4-CA; Thu, 12 Nov 2015 16:58:01 +0000 Date: Thu, 12 Nov 2015 08:58:01 -0800 From: Christoph Hellwig To: Eric Sandeen Cc: xfs@oss.sgi.com Subject: Re: [PATCH V2] xfs: create helper for bmap finish & trans join in attr code Message-ID: <20151112165801.GA14854@infradead.org> X-ASG-Orig-Subj: Re: [PATCH V2] xfs: create helper for bmap finish & trans join in attr code References: <56441B8E.6070603@redhat.com> <5644BEF8.6070201@sandeen.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <5644BEF8.6070201@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: 1447347482 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.30 X-Barracuda-Spam-Status: No, SCORE=0.30 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_SA827, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24335 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS 0.20 BSF_SC0_SA827 Custom Outbreak Rule BSF_SC0_SA827 I think the problem here is simply that our interfaces suck. xfs_trans_roll really needs to rejoin any inode to the new transaction to that was joined to the previous one. Once we've fixed that we can get rid of the silly committed arguments and everyone will be happy. From darrick.wong@oracle.com Thu Nov 12 11:35:09 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 26B157F66 for ; Thu, 12 Nov 2015 11:35:09 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 169D9304032 for ; Thu, 12 Nov 2015 09:35:05 -0800 (PST) X-ASG-Debug-ID: 1447349702-04cbb02422155820001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id qxP6HWJB0VBEA9TB (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 12 Nov 2015 09:35:02 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tACHYU6f031722 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 12 Nov 2015 17:34:30 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id tACHYTHp010924 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Thu, 12 Nov 2015 17:34:29 GMT Received: from abhmp0010.oracle.com (abhmp0010.oracle.com [141.146.116.16]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id tACHYTJc005296; Thu, 12 Nov 2015 17:34:29 GMT Received: from localhost (/71.198.20.188) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Thu, 12 Nov 2015 09:34:28 -0800 Date: Thu, 12 Nov 2015 09:34:27 -0800 From: "Darrick J. Wong" To: Christoph Hellwig Cc: david@fromorbit.com, fstests@vger.kernel.org, xfs@oss.sgi.com, tao.peng@primarydata.com, linux-ext4@vger.kernel.org, Anna.Schumaker@netapp.com, linux-btrfs@vger.kernel.org Subject: Re: [RFCv3.1 00/11] xfstests: test the nfs/cifs/btrfs/xfs reflink/dedupe ioctls Message-ID: <20151112173427.GC2217@birch.djwong.org> X-ASG-Orig-Subj: Re: [RFCv3.1 00/11] xfstests: test the nfs/cifs/btrfs/xfs reflink/dedupe ioctls References: <20151111192628.15056.6451.stgit@birch.djwong.org> <20151112090756.GA25685@infradead.org> <20151112125115.GA28822@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151112125115.GA28822@infradead.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1447349702 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24335 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines On Thu, Nov 12, 2015 at 04:51:15AM -0800, Christoph Hellwig wrote: > On Thu, Nov 12, 2015 at 01:07:56AM -0800, Christoph Hellwig wrote: > > Looks fine: > > > > Acked-by: Christoph Hellwig > > Actually I take this back. I had though this was the existing series > with my fixes, but this one still incorrectly assumes that if reflink > works dedup works as well, leading to lots of false failures on nfs. Bleargh, _require_*_dedupe forgot to check for ENOTTY output, so all the dedupe tests should have _notrun. Also, generic/806 was calling the wrong _require. I'll start renumbering tests; Christoph, did you see anything else? --D > -- > To unsubscribe from this list: send the line "unsubscribe fstests" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html From BATV+89ba7098823c58057a3d+4463+infradead.org+hch@bombadil.srs.infradead.org Thu Nov 12 11:36:46 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 9031E7F66 for ; Thu, 12 Nov 2015 11:36:46 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 6C1ED8F8035 for ; Thu, 12 Nov 2015 09:36:43 -0800 (PST) X-ASG-Debug-ID: 1447349801-04cbb02423155890001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id Q0Kct2EZqIYzc1TD (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Thu, 12 Nov 2015 09:36:42 -0800 (PST) X-Barracuda-Envelope-From: BATV+89ba7098823c58057a3d+4463+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 1ZwvnX-0003FB-Pv; Thu, 12 Nov 2015 17:36:35 +0000 Date: Thu, 12 Nov 2015 09:36:35 -0800 From: Christoph Hellwig To: "Darrick J. Wong" Cc: Christoph Hellwig , david@fromorbit.com, fstests@vger.kernel.org, xfs@oss.sgi.com, tao.peng@primarydata.com, linux-ext4@vger.kernel.org, Anna.Schumaker@netapp.com, linux-btrfs@vger.kernel.org Subject: Re: [RFCv3.1 00/11] xfstests: test the nfs/cifs/btrfs/xfs reflink/dedupe ioctls Message-ID: <20151112173635.GA9247@infradead.org> X-ASG-Orig-Subj: Re: [RFCv3.1 00/11] xfstests: test the nfs/cifs/btrfs/xfs reflink/dedupe ioctls References: <20151111192628.15056.6451.stgit@birch.djwong.org> <20151112090756.GA25685@infradead.org> <20151112125115.GA28822@infradead.org> <20151112173427.GC2217@birch.djwong.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151112173427.GC2217@birch.djwong.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: 1447349801 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/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_MISMATCH_TO, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24335 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS On Thu, Nov 12, 2015 at 09:34:27AM -0800, Darrick J. Wong wrote: > Bleargh, _require_*_dedupe forgot to check for ENOTTY output, so all the dedupe > tests should have _notrun. > > Also, generic/806 was calling the wrong _require. > > I'll start renumbering tests; Christoph, did you see anything else? Looks fine so far otherwise. From david@fromorbit.com Thu Nov 12 14:07:20 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 B72EC7F66 for ; Thu, 12 Nov 2015 14:07:20 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 995C48F804B for ; Thu, 12 Nov 2015 12:07:17 -0800 (PST) X-ASG-Debug-ID: 1447358831-04cbb02424158860001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id w845YYowVGfcjD52 for ; Thu, 12 Nov 2015 12:07:11 -0800 (PST) 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: A2DQBwDC8ERWPIYELHleFhIBAoMQU2+CX6hdAwaLM4k6IYVpBAICgT5NAQEBAQEBBwEBAQFAAT+ENAEBAQMBIw8BIyMFCwgDDgoCAgUhAgIPBSUDBxoTiCYHDrNKkGQBAQEHAiEZaIUMhUWHdYFEBZJng2GFHYgCgiyaIYJ0HYFqKjQBhTwBAQE Received: from ppp121-44-4-134.lns20.syd4.internode.on.net (HELO dastard) ([121.44.4.134]) by ipmail04.adl6.internode.on.net with ESMTP; 13 Nov 2015 06:36:42 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1Zwy8n-0005VS-JX; Fri, 13 Nov 2015 07:06:41 +1100 Date: Fri, 13 Nov 2015 07:06:41 +1100 From: Dave Chinner To: Tetsuo Handa Cc: Arkadiusz =?utf-8?Q?Mi=C5=9Bkiewicz?= , linux-mm@kvack.org, xfs@oss.sgi.com Subject: Re: memory reclaim problems on fs usage Message-ID: <20151112200641.GR19199@dastard> X-ASG-Orig-Subj: Re: memory reclaim problems on fs usage References: <201511102313.36685.arekm@maven.pl> <201511111719.44035.arekm@maven.pl> <201511120719.EBF35970.OtSOHOVFJMFQFL@I-love.SAKURA.ne.jp> <201511120706.10739.arekm@maven.pl> <56449E44.7020407@I-love.SAKURA.ne.jp> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <56449E44.7020407@I-love.SAKURA.ne.jp> 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: 1447358831 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24339 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Thu, Nov 12, 2015 at 11:12:20PM +0900, Tetsuo Handa wrote: > On 2015/11/12 15:06, Arkadiusz Miśkiewicz wrote: > >On Wednesday 11 of November 2015, Tetsuo Handa wrote: > >>Arkadiusz Mi?kiewicz wrote: > >>>This patch is against which tree? (tried 4.1, 4.2 and 4.3) > >> > >>Oops. Whitespace-damaged. This patch is for vanilla 4.1.2. > >>Reposting with one condition corrected. > > > >Here is log: > > > >http://ixion.pld-linux.org/~arekm/log-mm-1.txt.gz > > > >Uncompresses is 1.4MB, so not posting here. > > > Thank you for the log. The result is unexpected for me. > > What I feel strange is that free: remained below min: level. > While GFP_ATOMIC allocations can access memory reserves, I think that > these free: values are too small. Memory allocated by GFP_ATOMIC should > be released shortly, or any __GFP_WAIT allocations would stall for long. > > [ 8633.753528] Node 0 Normal free:128kB min:7104kB low:8880kB > high:10656kB active_anon:59008kB inactive_anon:75240kB > active_file:14712kB inactive_file:3256960kB unevictable:0kB .... > isolated(anon):0kB isolated(file):0kB present:5242880kB > managed:5109980kB mlocked:0kB dirty:20kB writeback:0kB mapped:7368kB .... > pages_scanned:176 all_unreclaimable? no So: we have 3.2GB (800,000 pages) of immediately reclaimable page cache in this zone (inactive_file) and a GFP_ATOMIC allocation context so we can only really reclaim clean page cache pages reliably. So why have we only scanned *176* pages* during reclaim? On other OOM reports in this trace it's as low as 12. Either that stat is completely wrong, or we're not doing sufficient page LRU reclaim scanning.... > [ 9662.234685] MemAlloc-Info: 3 stalling task, 0 dying task, 0 victim task. > > vmstat_update() and submit_flushes() remained pending for about 110 seconds. > If xlog_cil_push_work() were spinning inside GFP_NOFS allocation, it should be > reported as MemAlloc: traces, but no such lines are recorded. I don't know why > xlog_cil_push_work() did not call schedule() for so long. I'd say it is repeatedly waiting for IO completion on log buffers to write out the checkpoint. It's making progress, just if it's taking multiple second per journal IO it will take a long time to write a checkpoint. All the other blocked tasks in XFS inode reclaim are either waiting directly on IO completion or waiting for the log to complete a flush, so this really just looks like an overloaded IO subsystem to me.... > Well, what steps should we try next for isolating the problem? I think there's plenty that needs to be explained from this information. We don't have a memory allocation livelock - slow progress is being made on reclaiming inodes, but we clearly have a zone imbalance and direct page reclaim is not freeing clean inactive pages when there are huge numbers of them available for reclaim. Somebody who understands the page reclaim code needs to look closely at the code to explain this behaviour now, then we'll know what information needs to be gathered next... Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Thu Nov 12 14:12:43 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 48C807F66 for ; Thu, 12 Nov 2015 14:12:43 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id D06CBAC002 for ; Thu, 12 Nov 2015 12:12:39 -0800 (PST) X-ASG-Debug-ID: 1447359152-04cb6c296c143570001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id 7M3nQHvgp74BGaAz for ; Thu, 12 Nov 2015 12:12:33 -0800 (PST) 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: A2AXCAAn8kRWPIYELHlWCCgBAoMQgUKCX4N+pF8DBoszhS2CfYEQhgoEAgKBPk0BAQEBAQEHAQEBAUABP4Q1AQEEOhwjEAgDDgoJJQ8FJQMHGhOILcQ7AQEIAiEZhXSFRYQ2hQMFlkiNH5xNgnQdgWoqNIU9AQEB Received: from ppp121-44-4-134.lns20.syd4.internode.on.net (HELO dastard) ([121.44.4.134]) by ipmail04.adl6.internode.on.net with ESMTP; 13 Nov 2015 06:42:32 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZwyER-0005W5-Lq; Fri, 13 Nov 2015 07:12:31 +1100 Date: Fri, 13 Nov 2015 07:12:31 +1100 From: Dave Chinner To: Christoph Hellwig Cc: Eric Sandeen , xfs@oss.sgi.com Subject: Re: [PATCH V2] xfs: create helper for bmap finish & trans join in attr code Message-ID: <20151112201231.GS19199@dastard> X-ASG-Orig-Subj: Re: [PATCH V2] xfs: create helper for bmap finish & trans join in attr code References: <56441B8E.6070603@redhat.com> <5644BEF8.6070201@sandeen.net> <20151112165801.GA14854@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151112165801.GA14854@infradead.org> 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: 1447359153 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24339 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Thu, Nov 12, 2015 at 08:58:01AM -0800, Christoph Hellwig wrote: > I think the problem here is simply that our interfaces suck. > xfs_trans_roll really needs to rejoin any inode to the new transaction > to that was joined to the previous one. Once we've fixed that we can > get rid of the silly committed arguments and everyone will be happy. xfs_trans_roll is not specifically for rolling transactions with locked inodes in them. We could use it for any object that needs multiple transactions to modify. e.g. we could roll transactions across an AGF (using hold+join) so that it remains locked across multiple allocation/free transactions. So I think pushing the inode joining inside xfs_trans_roll() is not the right thing to do, but an "inode specific wrapper" such as "xfs_trans_roll_inode()" would handle this just fine... Cheers, Dave. -- Dave Chinner david@fromorbit.com From arekm@maven.pl Thu Nov 12 15:28:40 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 39F027F66 for ; Thu, 12 Nov 2015 15:28:40 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id C2C50AC002 for ; Thu, 12 Nov 2015 13:28:36 -0800 (PST) X-ASG-Debug-ID: 1447363709-04bdf03f0514ae30001-NocioJ Received: from mail-lf0-f51.google.com (mail-lf0-f51.google.com [209.85.215.51]) by cuda.sgi.com with ESMTP id 6ybEbmZoWCcVWBMC (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Thu, 12 Nov 2015 13:28:30 -0800 (PST) X-Barracuda-Envelope-From: arekm@maven.pl X-Barracuda-Apparent-Source-IP: 209.85.215.51 Received: by lffu14 with SMTP id u14so42009911lff.1 for ; Thu, 12 Nov 2015 13:28:28 -0800 (PST) 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=n7XN7de5lSCOxC500e8GRABdsEbtyuLtvbCrtkyb/l4=; b=RW4yEegy8UiAYS02jlKd4KaZ/gJQfUexI6HGXIBDIQZKSX51VUPethDkrOIf0iVo5O o9BtaI4pYOIodOgi/czujSiaxu6W24260fawtZhz3MsvoT3vyxvEsvY7CrS5mWod+TB0 RYhyGCURDjPD3jM8KNI3GlOM77m6T+F14QjDw= 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=n7XN7de5lSCOxC500e8GRABdsEbtyuLtvbCrtkyb/l4=; b=OvrhvHVdS7/X+7kCWT2gqowV1xSXoSTUClmUGatA1QeKCaDmCLN1LZsFxhLZKkTFGG +d559Fmi7V/0r2DmV4Jow4kKDGFaOqdpaZAPHPW4MeXejDWNewggWFFndU5KPPgSxS8G mvhUEBYgYeWCD/GIAhSsTn7K+/GMFz1BpCUc8Z8BSx0NtEqT7VbIZ/UC81sZvoh8LTX2 zB+2wLqBNIvVdjFzF+K5afMelNWQPUdu3oAu5tbjNcZAbjsBuV/z1pzbQPkfdFrMfLOY pL7RuuGbmoneyiEEm3cXeffWElsy6dZdbSunwnOjC19fXizNASypXhYVKAekWAwnH/x7 FevA== X-Gm-Message-State: ALoCoQl4v6q72VUFnlNGsDYPOei6/dwg2k77OFYydurR7Egh6DRgcUD0Ov0YUdZpVZE216OWsoGh X-Received: by 10.25.22.214 with SMTP id 83mr8482368lfw.8.1447363708471; Thu, 12 Nov 2015 13:28:28 -0800 (PST) Received: from xps.localnet (85-222-71-204.dynamic.chello.pl. [85.222.71.204]) by smtp.gmail.com with ESMTPSA id zz9sm2573920lbb.32.2015.11.12.13.28.27 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 12 Nov 2015 13:28:27 -0800 (PST) From: Arkadiusz =?utf-8?q?Mi=C5=9Bkiewicz?= To: Tetsuo Handa Subject: Re: memory reclaim problems on fs usage Date: Thu, 12 Nov 2015 22:28:26 +0100 X-ASG-Orig-Subj: Re: memory reclaim problems on fs usage User-Agent: KMail/1.13.7 (Linux/4.3.0; KDE/4.14.13; x86_64; ; ) Cc: linux-mm@kvack.org, xfs@oss.sgi.com References: <201511102313.36685.arekm@maven.pl> <201511120706.10739.arekm@maven.pl> <56449E44.7020407@I-love.SAKURA.ne.jp> In-Reply-To: <56449E44.7020407@I-love.SAKURA.ne.jp> MIME-Version: 1.0 Content-Type: Text/Plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <201511122228.26399.arekm@maven.pl> X-Barracuda-Connect: mail-lf0-f51.google.com[209.85.215.51] X-Barracuda-Start-Time: 1447363710 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24342 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 Thursday 12 of November 2015, Tetsuo Handa wrote: > On 2015/11/12 15:06, Arkadiusz Mi=C5=9Bkiewicz wrote: > > On Wednesday 11 of November 2015, Tetsuo Handa wrote: > >> Arkadiusz Mi?kiewicz wrote: > >>> This patch is against which tree? (tried 4.1, 4.2 and 4.3) > >>=20 > >> Oops. Whitespace-damaged. This patch is for vanilla 4.1.2. > >> Reposting with one condition corrected. > >=20 > > Here is log: > >=20 > > http://ixion.pld-linux.org/~arekm/log-mm-1.txt.gz > >=20 > > Uncompresses is 1.4MB, so not posting here. >=20 > Thank you for the log. The result is unexpected for me. [...] >=20 > vmstat_update() and submit_flushes() remained pending for about 110 > seconds. If xlog_cil_push_work() were spinning inside GFP_NOFS allocation, > it should be reported as MemAlloc: traces, but no such lines are recorded. > I don't know why xlog_cil_push_work() did not call schedule() for so long. > Anyway, applying > http://lkml.kernel.org/r/20151111160336.GD1432@dhcp22.suse.cz should solve > vmstat_update() part. To apply that patch on top of 4.1.13 I also had to apply patches listed bel= ow.=20 So in summary appllied: http://sprunge.us/GYBb http://sprunge.us/XWUX http://sprunge.us/jZjV (Could try http://lkml.kernel.org/r/20151111160336.GD1432@dhcp22.suse.cz on= ly=20 if there is version for 4.1 tree somewhere) commit 0aaa29a56e4fb0fc9e24edb649e2733a672ca099 Author: Mel Gorman Date: Fri Nov 6 16:28:37 2015 -0800 mm, page_alloc: reserve pageblocks for high-order atomic allocations on= =20 demand commit 974a786e63c96a2401a78ddba926f34c128474f1 Author: Mel Gorman Date: Fri Nov 6 16:28:34 2015 -0800 mm, page_alloc: remove MIGRATE_RESERVE commit c2d42c16ad83006a706d83e51a7268db04af733a Author: Andrew Morton Date: Thu Nov 5 18:48:43 2015 -0800 mm/vmstat.c: uninline node_page_state() commit 176bed1de5bf977938cad26551969eca8f0883b1 Author: Linus Torvalds Date: Thu Oct 15 13:01:50 2015 -0700 vmstat: explicitly schedule per-cpu work on the CPU we need it to run on [...] >=20 > Well, what steps should we try next for isolating the problem? >=20 > Swap is not used at all. Turning off swap might help. Disabled swap. >=20 > [ 8633.753574] Free swap =3D 117220800kB > [ 8633.753576] Total swap =3D 117220820kB >=20 > Turning off perf might also help. >=20 > [ 5001.394085] perf interrupt took too long (2505 > 2495), lowering > kernel.perf_event_max_sample_rate to 50100 Didn't find a way to disable perf. kernel .config option gets autoenabled b= y=20 some dependency. So left this untouched. With mentioned patches I wasn't able to reproduce memory allocation problem= =20 (still trying though).=20 Current debug log: http://ixion.pld-linux.org/~arekm/log-mm-2.txt.gz =2D-=20 Arkadiusz Mi=C5=9Bkiewicz, arekm / ( maven.pl | pld-linux.org ) From arkadiusz.bubala@open-e.com Fri Nov 13 00:39:33 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 088C97F6C for ; Fri, 13 Nov 2015 00:39:33 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id EC170304032 for ; Thu, 12 Nov 2015 22:39:29 -0800 (PST) X-ASG-Debug-ID: 1447396765-04cb6c0cd10a010001-NocioJ Received: from mout.kundenserver.de (mout.kundenserver.de [212.227.126.131]) by cuda.sgi.com with ESMTP id m7FkVG71OIzXzOmE (version=TLSv1.2 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 12 Nov 2015 22:39:26 -0800 (PST) X-Barracuda-Envelope-From: arkadiusz.bubala@open-e.com X-Barracuda-Apparent-Source-IP: 212.227.126.131 Received: from [192.168.176.17] ([85.14.118.246]) by mrelayeu.kundenserver.de (mreue001) with ESMTPSA (Nemesis) id 0Mbour-1ZeDaT1xI5-00Izi3 for ; Fri, 13 Nov 2015 07:39:24 +0100 Message-ID: <56458591.6070706@open-e.com> Date: Fri, 13 Nov 2015 07:39:13 +0100 From: =?UTF-8?B?QXJrYWRpdXN6IEJ1YmHFgmE=?= User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Icedove/31.8.0 MIME-Version: 1.0 To: xfs@oss.sgi.com Subject: Re: "Internal error xfs_attr3_leaf_write_verify at line 216", "directory flags set on non-directory inode" and other errors References: <20150709011526.GE3902@dastard> X-ASG-Orig-Subj: Re: "Internal error xfs_attr3_leaf_write_verify at line 216", "directory flags set on non-directory inode" and other errors In-Reply-To: <20150709011526.GE3902@dastard> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit X-Provags-ID: V03:K0:y2mZtt9EVvs7Ed0+dfcH8327/6atYaWQgktchukmSjRPjRxTPVI GvXMLI3Citb48GD0vELk++Tv6Jqj87BO9/muEI/LS2MQTsCfFn801N3ZtOgGEyZiJtWhZUq qpZ8/sg7YIuLCPayd4GI5/khfxvH1YWev4Lbb5TtcatCfRi0Shxn3aepyYGCXmC1aHQsmND /ZqO/xjMJRmJRR+qI9dpg== X-UI-Out-Filterresults: notjunk:1;V01:K0:b0jx3o4wduw=:3R0qi9p5IqWG60KBndkm02 vJVunLPU/qFRtXoCdeIpkn5L1cGy2zFDkEe71MWoUhzgATlKh8xwDoJ8Bj8r0FQMou+3PjP5x 6pebulyVoMEm1rteDY5IGqQ8JbrLPBPHCl0lrT2q0viIzTnDycb+KbwG/HWFr2ng2rPccVDrQ J7z/iWFBBXqARvklM6JDblPw67SQzbN0dvXo7V5AB6mE7MjQwXScub4N8J1CkJVdtET+lpCXE VRIM5WAyeODdGaiGXI1ZjcP93jLu+uD6imVUcH+KJGT2kk/77IIhpnow7x7ZZNXYlLLhQr5qM 8zA81CiIYZ9cwXBCMGHN2WHnZMgdyo2oimbbyQXRLGKgLFVLA0VYS0IL6BHjcbV5N1/NekwiC rBO54DJMzCqcQe8Gy2B5Dvkfd3tv6SXPTMa/76OuuaN8z4ruVH3G84dsGMsHT6Pu0/0doQ3xJ g1OuvMEFeEqLGv+34Die0UHAojoXT55K3yox2cy/uXCavZ34aENpAqrPtNNh2Rve8zpWLKAoW 9ZyvT/lzI2S8POcmIVs38b0xMv5BMj7OUqg45f4fP/2q78ERm3jS4hm8lg/rFsn5PQu4pziOP T2z0cn/7ktF4Cuyn15BMZ+KOeS83AjQaqLH0iJ93jiyiVLdylqnTxPCC9ZJdQBFA5AUkROEg1 fsaZGpDiVFrPvZUwywAd4dXQwtres9cPkCP3aORrqbO0QxoKvUo52P0gNDjDHORZQrvNHmK21 Ao8za6ToSPyshRq7 X-Barracuda-Connect: mout.kundenserver.de[212.227.126.131] X-Barracuda-Start-Time: 1447396766 X-Barracuda-Encrypted: DHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24351 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Hello, I encountered the same issue on the Linux kernel 3.10. Here's the information you previously asked about. I hope it'll help to find the root of this problem. The ls command invoked on lost+found: #ls -la ls: 246185005270: Operation not permitted total 4 drwxr-xr-x 2 root root 33 Nov 7 00:51 . drwxr-xr-x 5 root root 61 Sep 21 21:07 .. -rwxrwxrwx 1 user user 0 Oct 27 18:22 246185005270 Execution of ls generates following error in the dmesg: [486147.297493] ffff88063af38000: 00 00 00 00 00 00 00 00 fb ee 00 00 00 00 00 00 ................ [486147.318762] ffff88063af38010: 10 00 00 00 00 20 0f e0 00 00 00 00 00 00 00 00 ..... .......... [486147.339328] ffff88063af38020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ [486147.359597] ffff88063af38030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ [486147.359599] XFS (dm-16): Internal error xfs_attr3_leaf_read_verify at line 256 of file fs/xfs/xfs_attr_leaf.c. Caller 0xffffffff81263bcd [486147.359599] [486147.359601] CPU: 8 PID: 14315 Comm: kworker/8:1H Tainted: G O 3.10.80 #45 [486147.359602] Hardware name: Supermicro X9DRi-LN4+/X9DR3-LN4+/X9DRi-LN4+/X9DR3-LN4+, BIOS 3.2 03/04/2015 [486147.359607] Workqueue: xfslogd xfs_buf_iodone_work [486147.359611] ffffffff816bf9df 000000000000007e ffffffff81265a42 ffffffff81263bcd [486147.359612] ffff000000000100 ffff8800518b4fc0 ffff88000de01200 ffff88085adf5000 [486147.359613] ffff88087fd18f00 0000000000000000 ffffffff8127e95f ffffffff81263bcd [486147.359614] Call Trace: [486147.359617] [] ? dump_stack+0xd/0x17 [486147.359620] [] ? xfs_corruption_error+0x62/0x90 [486147.359621] [] ? xfs_buf_iodone_work+0x8d/0xb0 [486147.359624] [] ? xfs_attr3_leaf_read_verify+0x6f/0x100 [486147.359625] [] ? xfs_buf_iodone_work+0x8d/0xb0 [486147.359627] [] ? xfs_buf_iodone_work+0x8d/0xb0 [486147.359630] [] ? process_one_work+0x141/0x3b0 [486147.359633] [] ? pwq_activate_delayed_work+0x2e/0x50 [486147.359636] [] ? worker_thread+0x112/0x370 [486147.359638] [] ? manage_workers.isra.28+0x290/0x290 [486147.359641] [] ? kthread+0xb3/0xc0 [486147.359644] [] ? sched_clock+0x5/0x10 [486147.359646] [] ? __alloc_workqueue_key+0x210/0x510 [486147.359648] [] ? kthread_freezable_should_stop+0x60/0x60 [486147.359652] [] ? ret_from_fork+0x58/0x90 [486147.359654] [] ? kthread_freezable_should_stop+0x60/0x60 [486147.359655] XFS (dm-16): Corruption detected. Unmount and run xfs_repair [486147.359664] XFS (dm-16): metadata I/O error: block 0x1ca8ebe310 ("xfs_trans_read_buf_map") error 117 numblks 8 # xfs_db -r /dev/mapper/vg+vg01-lv+n+lv0100 xfs_db> inode 246185005270 xfs_db> p core.magic = 0x494e core.mode = 0100777 core.version = 2 core.format = 2 (extents) core.nlinkv2 = 1 core.onlink = 0 core.projid_lo = 0 core.projid_hi = 0 core.uid = 106 core.gid = 103 core.flushiter = 4 core.atime.sec = Tue Oct 27 18:22:48 2015 core.atime.nsec = 000000000 core.mtime.sec = Tue Oct 27 18:22:48 2015 core.mtime.nsec = 000000000 core.ctime.sec = Sun Nov 1 19:05:21 2015 core.ctime.nsec = 337962467 core.size = 0 core.nblocks = 1 core.extsize = 0 core.nextents = 0 core.naextents = 1 core.forkoff = 9 core.aformat = 2 (extents) core.dmevmask = 0 core.dmstate = 0 core.newrtbm = 0 core.prealloc = 0 core.realtime = 0 core.immutable = 0 core.append = 0 core.sync = 0 core.noatime = 0 core.nodump = 0 core.rtinherit = 0 core.projinherit = 0 core.nosymlinks = 0 core.extsz = 0 core.extszinherit = 0 core.nodefrag = 0 core.filestream = 0 core.gen = 2298109809 next_unlinked = null u = (empty) a.bmx[0] = [startoff,startblock,blockcount,extentflag] 0:[0,15386639515,1,0] xfs_db> ablock 0 xfs_db> p hdr.info.forw = 0 hdr.info.back = 0 hdr.info.magic = 0xfbee hdr.count = 0 hdr.usedbytes = 0 hdr.firstused = 4096 hdr.holes = 0 hdr.freemap[0-2] = [base,size] 0:[32,4064] 1:[0,0] 2:[0,0] xfs_db> type text xfs_db> p 000: 00 00 00 00 00 00 00 00 fb ee 00 00 00 00 00 00 ................ 010: 10 00 00 00 00 20 0f e0 00 00 00 00 00 00 00 00 ................ 020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ ... (zeros only) ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ #xfs_db -r -c "convert daddr 0x1ca8ebe310 fsb" /dev/mapper/lv0100 0x3951d7c9b (15386639515) # xfs_db -r -c "fsb 0x3951d7c9b" -c p -c "type attr" -c p /dev/mapper/lv0100 000: 00000000 00000000 fbee0000 00000000 10000000 00200fe0 00000000 00000000 020: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 040: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 060: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 080: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0a0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0c0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0e0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 100: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 120: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 140: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 160: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 180: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 1a0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 1c0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 1e0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 200: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 220: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 240: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 260: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 280: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 2a0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 2c0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 2e0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 300: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 320: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 340: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 360: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 380: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 3a0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 3c0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 3e0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 400: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 420: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 440: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 460: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 480: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 4a0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 4c0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 4e0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 500: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 520: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 540: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 560: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 580: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 5a0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 5c0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 5e0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 600: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 620: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 640: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 660: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 680: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 6a0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 6c0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 6e0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 700: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 720: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 740: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 760: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 780: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 7a0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 7c0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 7e0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 800: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 820: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 840: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 860: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 880: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 8a0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 8c0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 8e0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 900: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 920: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 940: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 960: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 980: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 9a0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 9c0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 9e0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 a00: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 a20: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 a40: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 a60: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 a80: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 aa0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ac0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ae0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 b00: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 b20: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 b40: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 b60: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 b80: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ba0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 bc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 be0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 c00: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 c20: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 c40: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 c60: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 c80: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ca0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 cc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ce0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 d00: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 d20: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 d40: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 d60: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 d80: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 da0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 dc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 de0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 e00: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 e20: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 e40: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 e60: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 e80: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ea0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ec0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ee0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 f00: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 f20: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 f40: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 f60: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 f80: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 fa0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 fe0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 hdr.info.forw = 0 hdr.info.back = 0 hdr.info.magic = 0xfbee hdr.count = 0 hdr.usedbytes = 0 hdr.firstused = 4096 hdr.holes = 0 hdr.freemap[0-2] = [base,size] 0:[32,4064] 1:[0,0] 2:[0,0] -- Best regards Arkadiusz Bubała Open-E Poland Sp. z o.o. www.open-e.com From BATV+a52e32bc34450c8b0692+4464+infradead.org+hch@bombadil.srs.infradead.org Fri Nov 13 03:08:47 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 4E78C7F6C for ; Fri, 13 Nov 2015 03:08:47 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id DD2BDAC002 for ; Fri, 13 Nov 2015 01:08:43 -0800 (PST) X-ASG-Debug-ID: 1447405721-04bdf07f0a0f9c0001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id nGPingDevKKW3Jzz (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Fri, 13 Nov 2015 01:08:41 -0800 (PST) X-Barracuda-Envelope-From: BATV+a52e32bc34450c8b0692+4464+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 1ZxALY-0004KG-L3; Fri, 13 Nov 2015 09:08:40 +0000 Date: Fri, 13 Nov 2015 01:08:40 -0800 From: Christoph Hellwig To: Dave Chinner Cc: Christoph Hellwig , Eric Sandeen , xfs@oss.sgi.com Subject: Re: [PATCH V2] xfs: create helper for bmap finish & trans join in attr code Message-ID: <20151113090840.GA16423@infradead.org> X-ASG-Orig-Subj: Re: [PATCH V2] xfs: create helper for bmap finish & trans join in attr code References: <56441B8E.6070603@redhat.com> <5644BEF8.6070201@sandeen.net> <20151112165801.GA14854@infradead.org> <20151112201231.GS19199@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151112201231.GS19199@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: 1447405721 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/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.24354 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS On Fri, Nov 13, 2015 at 07:12:31AM +1100, Dave Chinner wrote: > On Thu, Nov 12, 2015 at 08:58:01AM -0800, Christoph Hellwig wrote: > > I think the problem here is simply that our interfaces suck. > > xfs_trans_roll really needs to rejoin any inode to the new transaction > > to that was joined to the previous one. Once we've fixed that we can > > get rid of the silly committed arguments and everyone will be happy. > > xfs_trans_roll is not specifically for rolling transactions with > locked inodes in them. We could use it for any object that needs > multiple transactions to modify. e.g. we could roll transactions > across an AGF (using hold+join) so that it remains locked across > multiple allocation/free transactions. xfs_trans_roll already logs the inode core, which requires the inode to be attached to the transaction. While I could see the point of moving this out of the core __xfs_trans_roll into an xfs_trans_roll_inode helper we might as well follow the current interface for now. From darrick.wong@oracle.com Fri Nov 13 03:08:56 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 54B7F7F6C for ; Fri, 13 Nov 2015 03:08:56 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id EE1C1AC001 for ; Fri, 13 Nov 2015 01:08:55 -0800 (PST) X-ASG-Debug-ID: 1447405733-04bdf07f0a0fa00001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id kMlMoCTw57lyxGwI (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 13 Nov 2015 01:08:54 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tAD98Sou028570 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 13 Nov 2015 09:08:28 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id tAD98RYO016154 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Fri, 13 Nov 2015 09:08:28 GMT Received: from abhmp0001.oracle.com (abhmp0001.oracle.com [141.146.116.7]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id tAD98RGq021152; Fri, 13 Nov 2015 09:08:27 GMT Received: from localhost (/71.198.20.188) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 13 Nov 2015 01:08:25 -0800 Date: Fri, 13 Nov 2015 01:08:22 -0800 From: "Darrick J. Wong" To: Christoph Hellwig Cc: david@fromorbit.com, fstests@vger.kernel.org, xfs@oss.sgi.com, tao.peng@primarydata.com, linux-ext4@vger.kernel.org, Anna.Schumaker@netapp.com, linux-btrfs@vger.kernel.org Subject: Re: [RFCv3.1 00/11] xfstests: test the nfs/cifs/btrfs/xfs reflink/dedupe ioctls Message-ID: <20151113090822.GB2214@birch.djwong.org> X-ASG-Orig-Subj: Re: [RFCv3.1 00/11] xfstests: test the nfs/cifs/btrfs/xfs reflink/dedupe ioctls References: <20151111192628.15056.6451.stgit@birch.djwong.org> <20151112090756.GA25685@infradead.org> <20151112125115.GA28822@infradead.org> <20151112173427.GC2217@birch.djwong.org> <20151112173635.GA9247@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151112173635.GA9247@infradead.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1447405734 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24354 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines On Thu, Nov 12, 2015 at 09:36:35AM -0800, Christoph Hellwig wrote: > On Thu, Nov 12, 2015 at 09:34:27AM -0800, Darrick J. Wong wrote: > > Bleargh, _require_*_dedupe forgot to check for ENOTTY output, so all the dedupe > > tests should have _notrun. > > > > Also, generic/806 was calling the wrong _require. > > > > I'll start renumbering tests; Christoph, did you see anything else? > > Looks fine so far otherwise. I think I got all the tests renumbered correctly and fixed all the other bugs. I'd like to send the updated patchpile to Dave tomorrow, but if you have a few spare cycles would you mind giving this a quick test to make sure I fixed everything? https://github.com/djwong/xfstests/tree/for-dave --D > -- > To unsubscribe from this list: send the line "unsubscribe fstests" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html From penguin-kernel@I-love.SAKURA.ne.jp Fri Nov 13 06:20:09 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 39EFD7F6C for ; Fri, 13 Nov 2015 06:20:09 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 29B758F8033 for ; Fri, 13 Nov 2015 04:20:05 -0800 (PST) X-ASG-Debug-ID: 1447417200-04cb6c0cd21a0c0001-NocioJ Received: from www262.sakura.ne.jp (www262.sakura.ne.jp [202.181.97.72]) by cuda.sgi.com with ESMTP id aqDnHVixO5PzyY5E (version=TLSv1 cipher=DHE-RSA-CAMELLIA256-SHA bits=256 verify=NO) for ; Fri, 13 Nov 2015 04:20:02 -0800 (PST) X-Barracuda-Envelope-From: penguin-kernel@I-love.SAKURA.ne.jp X-Barracuda-Apparent-Source-IP: 202.181.97.72 Received: from fsav102.sakura.ne.jp (fsav102.sakura.ne.jp [27.133.134.229]) by www262.sakura.ne.jp (8.14.5/8.14.5) with ESMTP id tADCJnfk097933; Fri, 13 Nov 2015 21:19:49 +0900 (JST) (envelope-from penguin-kernel@I-love.SAKURA.ne.jp) Received: from www262.sakura.ne.jp (202.181.97.72) by fsav102.sakura.ne.jp (F-Secure/fsigk_smtp/522/fsav102.sakura.ne.jp); Fri, 13 Nov 2015 21:19:49 +0900 (JST) X-Virus-Status: clean(F-Secure/fsigk_smtp/522/fsav102.sakura.ne.jp) Received: from AQUA (softbank126094077227.bbtec.net [126.94.77.227]) (authenticated bits=0) by www262.sakura.ne.jp (8.14.5/8.14.5) with ESMTP id tADCJnYL097929; Fri, 13 Nov 2015 21:19:49 +0900 (JST) (envelope-from penguin-kernel@I-love.SAKURA.ne.jp) To: david@fromorbit.com Cc: arekm@maven.pl, htejun@gmail.com, cl@linux.com, mhocko@suse.com, linux-mm@kvack.org, xfs@oss.sgi.com Subject: Re: memory reclaim problems on fs usage From: Tetsuo Handa X-ASG-Orig-Subj: Re: memory reclaim problems on fs usage References: <201511111719.44035.arekm@maven.pl> <201511120719.EBF35970.OtSOHOVFJMFQFL@I-love.SAKURA.ne.jp> <201511120706.10739.arekm@maven.pl> <56449E44.7020407@I-love.SAKURA.ne.jp> <20151112200641.GR19199@dastard> In-Reply-To: <20151112200641.GR19199@dastard> Message-Id: <201511132119.BAG65154.QVHStOOFFMOLFJ@I-love.SAKURA.ne.jp> X-Mailer: Winbiff [Version 2.51 PL2] X-Accept-Language: ja,en,zh Date: Fri, 13 Nov 2015 21:19:46 +0900 Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Barracuda-Connect: www262.sakura.ne.jp[202.181.97.72] X-Barracuda-Start-Time: 1447417201 X-Barracuda-Encrypted: DHE-RSA-CAMELLIA256-SHA X-Barracuda-URL: https://192.48.176.15:443/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 Dave Chinner wrote: > So why have we only scanned *176* pages* during reclaim? On other > OOM reports in this trace it's as low as 12. Either that stat is > completely wrong, or we're not doing sufficient page LRU reclaim > scanning.... > > > [ 9662.234685] MemAlloc-Info: 3 stalling task, 0 dying task, 0 victim task. > > > > vmstat_update() and submit_flushes() remained pending for about 110 seconds. > > If xlog_cil_push_work() were spinning inside GFP_NOFS allocation, it should be > > reported as MemAlloc: traces, but no such lines are recorded. I don't know why > > xlog_cil_push_work() did not call schedule() for so long. > > I'd say it is repeatedly waiting for IO completion on log buffers to > write out the checkpoint. It's making progress, just if it's taking > multiple second per journal IO it will take a long time to write a > checkpoint. All the other blocked tasks in XFS inode reclaim are > either waiting directly on IO completion or waiting for the log to > complete a flush, so this really just looks like an overloaded IO > subsystem to me.... The vmstat statistics can become wrong when vmstat_update() workqueue item cannot be processed due to in-flight workqueue item not calling schedule(). If in-flight workqueue item (in this case xlog_cil_push_work()) called schedule(), the pending vmstat_update() workqueue item will be processed and the vmstat becomes up to dated. Like you expect that xlog_cil_push_work() was waiting for IO completion on log buffers rather than spinning inside GFP_NOFS allocation, what should happened is xlog_cil_push_work() called schedule() and vmstat_update() was processed. But vmstat_update() remained pending for about 110 seconds. That's strange... Arkadiusz is trying http://marc.info/?l=linux-mm&m=144725782107096&w=2 which is for making sure that vmstat_update() workqueue item is processed by changing wait_iff_congested() to call schedule(), and we are waiting for test results. Well, one of dependent patches "vmstat: explicitly schedule per-cpu work on the CPU we need it to run on" might be relevant to this problem. If http://sprunge.us/GYBb and http://sprunge.us/XWUX solve the problem (for both with swap case and without swap case), the vmstat statistics was wrong. From BATV+a52e32bc34450c8b0692+4464+infradead.org+hch@bombadil.srs.infradead.org Fri Nov 13 08:12:39 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 C7C9C7F6C for ; Fri, 13 Nov 2015 08:12:39 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 65E09AC002 for ; Fri, 13 Nov 2015 06:12:36 -0800 (PST) X-ASG-Debug-ID: 1447423954-04bdf07f0824860001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id Bdo9bKAMAqOz4OtU (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Fri, 13 Nov 2015 06:12:34 -0800 (PST) X-Barracuda-Envelope-From: BATV+a52e32bc34450c8b0692+4464+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 1ZxF5Y-0002GU-9V; Fri, 13 Nov 2015 14:12:28 +0000 Date: Fri, 13 Nov 2015 06:12:28 -0800 From: Christoph Hellwig To: "Darrick J. Wong" Cc: Christoph Hellwig , david@fromorbit.com, fstests@vger.kernel.org, xfs@oss.sgi.com, tao.peng@primarydata.com, linux-ext4@vger.kernel.org, Anna.Schumaker@netapp.com, linux-btrfs@vger.kernel.org Subject: Re: [RFCv3.1 00/11] xfstests: test the nfs/cifs/btrfs/xfs reflink/dedupe ioctls Message-ID: <20151113141228.GA7218@infradead.org> X-ASG-Orig-Subj: Re: [RFCv3.1 00/11] xfstests: test the nfs/cifs/btrfs/xfs reflink/dedupe ioctls References: <20151111192628.15056.6451.stgit@birch.djwong.org> <20151112090756.GA25685@infradead.org> <20151112125115.GA28822@infradead.org> <20151112173427.GC2217@birch.djwong.org> <20151112173635.GA9247@infradead.org> <20151113090822.GB2214@birch.djwong.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151113090822.GB2214@birch.djwong.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: 1447423954 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/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_MISMATCH_TO, BSF_SC7_SA_HREF_FROM_MISMATCH_TEXT_URIx1_HL, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24359 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS 2.50 BSF_SC7_SA_HREF_FROM_MISMATCH_TEXT_URIx1_HL Custom Rule HREF_FROM_MISMATCH_TEXT_URIx1_HL On Fri, Nov 13, 2015 at 01:08:22AM -0800, Darrick J. Wong wrote: > I think I got all the tests renumbered correctly and fixed all the other bugs. > I'd like to send the updated patchpile to Dave tomorrow, but if you have a few > spare cycles would you mind giving this a quick test to make sure I fixed > everything? > > https://github.com/djwong/xfstests/tree/for-dave Looks good enough to go in Acked-by: Christoph Hellwig I have for failing tests on NFS currently. Two of them probably are NFS issues (free block count), but and two others fail because NFS doesn't support chattr/lsattr. I will send an incremental check to adda feature test for those. From darrick.wong@oracle.com Fri Nov 13 12:33:14 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id A3C8B7F53 for ; Fri, 13 Nov 2015 12:33:14 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 4805CAC006 for ; Fri, 13 Nov 2015 10:33:14 -0800 (PST) X-ASG-Debug-ID: 1447439588-04bdf07f093cfc0001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id uKBYMWqCohGgMZgL (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 13 Nov 2015 10:33:08 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tADIWc2L004368 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 13 Nov 2015 18:32:39 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id tADIWZic007588 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Fri, 13 Nov 2015 18:32:35 GMT Received: from abhmp0017.oracle.com (abhmp0017.oracle.com [141.146.116.23]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id tADIWZnn008266; Fri, 13 Nov 2015 18:32:35 GMT Received: from localhost (/71.198.20.188) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 13 Nov 2015 10:32:35 -0800 Date: Fri, 13 Nov 2015 10:32:34 -0800 From: "Darrick J. Wong" To: Christoph Hellwig Cc: fstests@vger.kernel.org, xfs@oss.sgi.com, tao.peng@primarydata.com, linux-ext4@vger.kernel.org, Anna.Schumaker@netapp.com, linux-btrfs@vger.kernel.org Subject: Re: [RFCv3.1 00/11] xfstests: test the nfs/cifs/btrfs/xfs reflink/dedupe ioctls Message-ID: <20151113183234.GD2224@birch.djwong.org> X-ASG-Orig-Subj: Re: [RFCv3.1 00/11] xfstests: test the nfs/cifs/btrfs/xfs reflink/dedupe ioctls References: <20151111192628.15056.6451.stgit@birch.djwong.org> <20151112090756.GA25685@infradead.org> <20151112125115.GA28822@infradead.org> <20151112173427.GC2217@birch.djwong.org> <20151112173635.GA9247@infradead.org> <20151113090822.GB2214@birch.djwong.org> <20151113141228.GA7218@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151113141228.GA7218@infradead.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-Source-IP: aserv0022.oracle.com [141.146.126.234] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1447439588 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24366 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines On Fri, Nov 13, 2015 at 06:12:28AM -0800, Christoph Hellwig wrote: > On Fri, Nov 13, 2015 at 01:08:22AM -0800, Darrick J. Wong wrote: > > I think I got all the tests renumbered correctly and fixed all the other bugs. > > I'd like to send the updated patchpile to Dave tomorrow, but if you have a few > > spare cycles would you mind giving this a quick test to make sure I fixed > > everything? > > > > https://github.com/djwong/xfstests/tree/for-dave > > Looks good enough to go in > > Acked-by: Christoph Hellwig > > I have for failing tests on NFS currently. Two of them probably are > NFS issues (free block count), but and two others fail because NFS > doesn't support chattr/lsattr. I will send an incremental check to adda > feature test for those. I separated the chattr +i tests into a separate test that doesn't run if lsattr doesn't make sense; will post patches shortly. --D > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From wpowreibn@finnair.com Fri Nov 13 13:31:06 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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,WEIRD_QUOTING 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 8F44D7F5A for ; Fri, 13 Nov 2015 13:31:06 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 6F0258F8035 for ; Fri, 13 Nov 2015 11:31:03 -0800 (PST) X-ASG-Debug-ID: 1447443055-04cbb0605c416b0001-NocioJ Received: from finnair.com (119.162.35.171.adsl-pool.jx.chinaunicom.com [171.35.162.119]) by cuda.sgi.com with ESMTP id gbIQaGEG0i6TTH5G for ; Fri, 13 Nov 2015 11:30:56 -0800 (PST) X-Barracuda-Envelope-From: wpowreibn@finnair.com X-Barracuda-Apparent-Source-IP: 171.35.162.119 Received: from twtoir (unknown [208.12.165.144]) by finnair.com with SMTP id mD4j3mlQreJOuuwW.1 for ; Sat, 14 Nov 2015 03:31:00 +0800 Date: Sat, 14 Nov 2015 03:30:52 +0800 From: =?gb2312?B?1uyD0Q==?= To: xfs Subject: =?gb2312?B?sKLD17DNvq2gScSjyr25ub2o0+vUy9OquN+8tszY05aw4A==?= X-Priority: 3 X-ASG-Orig-Subj: =?gb2312?B?sKLD17DNvq2gScSjyr25ub2o0+vUy9OquN+8tszY05aw4A==?= X-Mailer: Foxmail 6, 13, 102, 15 [cn] Mime-Version: 1.0 Message-ID: <201511140331008343100@finnair.com> Content-Type: multipart/alternative; boundary="----=_000_NextPart083471748037_=----" X-Barracuda-Connect: 119.162.35.171.adsl-pool.jx.chinaunicom.com[171.35.162.119] X-Barracuda-Start-Time: 1447443055 X-Barracuda-URL: https://192.48.176.25:443/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=HTML_MESSAGE, MAILTO_TO_SPAM_ADDR, RDNS_DYNAMIC, WEIRD_QUOTING X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24368 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 WEIRD_QUOTING BODY: Weird repeated double-quotation marks 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.10 RDNS_DYNAMIC Delivered to trusted network by host with dynamic-looking rDNS This is a multi-part message in MIME format. ------=_000_NextPart083471748037_=---- Content-Type: text/plain; charset="gb2312" Content-Transfer-Encoding: base64 DQoNCtHQt6Ltl8S/udzA7Q0KDQqhvsqxvOS12LXjob8gMjAxNcTqMTHUwjIzLTI0sbG+qaGiMTHU wjI2LTI3yc+6o6GiMTHUwjMwLTEy1MIxye7b2g0KDQqhvrLOvNO21M/zob8gxvPStUNFTy/X3L2b wO2hosbz0rXW0LjfsuO53MDtoaLR0LBs19y84KGi19y5pKGi19y5pLDsoaK8vNBnsr/Dxb2bwO2h otb3udyhos/uxL+9m8DtoaK8vMr1uce4yaGiz+7Ev7ncwO25pLPMyqaholFBtcihow0KDQqhvsra v863vcq9ob8gvbLKpr2yytogKyDSlca10d3S7yArILC4wP3R0NORICu9x8mrsOfR3SArIL2yyqb8 Y8bADQoNCqG+0afPsLfR08OhvyAzMjAw1KovyMujqLqswb3M7NbQss2hota4tqi9zLLEoaKy6LXj o6kNCg0Kob6z0LDstaXOu6G/ILLFIL6tIMXgING1IL5XIA0KDQqhvrS50a/IyL6Aob8gMDIwLS04 NjQxOTUxMCAgIDg2NDE2NTM5ICAgwdbPyMn6ICAg0e7Qob3jDQoNCqG+1rWw4MrWu/qhvyAxMzY4 ODg3Mjc2MQ0KDQq/zrPMsbO+sA0KDQrU2rL6xre/qrei316zzNbQo6zG89K1u/LV38/uxL++rcDt L7ncwO3Iy9Sxzaizo8PmxVLS1M/CzsrufaOsz6PN+82ouf2xvr/Os8y1xNGnwZWjrM6qxvOYSczh uam+38zltcS94ptRy7zCt7rN06aMprTryqmhow0KMaGi1Nqy+sa3v6q3orn9s8zW0KOslXK85L30 0bnBprTzysfG89K1xtWx6cPmxVK1xNK7uPaGlszioaPtl8S/vq3A7S/tl8S/uLrYn8jLL7L6xre4 utifyMsv1ve53L+qt6K5pLPMyqYvz+7Ev7WjtbHV36OsDQrO3sLbxPq1xM23z8678rdRzr3I57rO o6zfQLj2zsrM4ra8ysfE+rOjs6PT9rW9tcTAp76z1q7Su6GjvNOw4LPJnunE+rXEzaizo9Gh1PGh o9Xiyse38dfjubujv8rHt/HfgNPQxuTL+7e9yr23vbeosO/W+g0KxPq+ob/JxNy077PJlXK85MS/ seqjv7G+v86zzL2rvW+z9tL9jKfRp4ZU1dK1vbTwsLihow0KMqGixvPStc/rvajBotHQsGzP7sS/ iEa206OsyM7D/M/uxL++rcDtL8/uxL+4utifyMuho7WrysfP7sS/vq3A7bjDyOe6zrmk1/ejrMjn us6FZrX3zcW206OsyOe6ztPrv82R9KGiuN+y49LUvLC3x9HQsGwNCrK/w8W5tc2oo6yzyc6qwcvP 7sS/vq3A7bXEwKe786OszazKsdKy1+i1S9fFudzA7bjfjNO21M/uxL++rcDtt8XIqLrNytqZ4KGj DQozoaLtl8S/vq3A7bW9tdfTpr7fsbjU9ZjTtcTL2NbKo7/G85hJ06a4w8jnus7F4NH4z+7Ev72b wO2jvw0KNKGiuavLvtKyzai5/cHLSVNPOTAwMC9UUzE2OTQ5L0NNTUm1xMjP1qSjrNKyvajBosHL 0rvM17L6xre/qrBswfezzKOstavKx9Tavt/M5YjM0NC5/bPM1tCjrMi0zerIq9ff0fmju7K7zay1 xM/uxL8NCra819/V4oKAwfezzKOs0rK3x7Ojt7HL9qOs09rKx7TzvNK2vLK7sLTV1dXigoDB97PM 1rTQ0KGj30C4w9T1w7Sw7KO/DQo1oaK087zSs6PLtaO6obC/zbun0OjH89PWuMSx5MHLobGjrKGw 7ZfEv9bQzqjSu7K7seS1xL7NysfXg6Gxo6yhsL/Nu6fX3MrHutzHv8rGo6zL+4KDzOGz9rXE0qrH 86OsztLDx5tdsOy3qL7cvvihsaGjDQqx5MrHv82527nmwsmjrM/uxL/X6Z9vt6i+3L74uMSx5KOs tavKx4Vz06a4w9PQsOy3qMPmttTfQNbWseS7r6GjxMe1vbXX06bUk8jnus7TprbU7ZfEv7n9s8zW 0LXEseS7r8TYo78NCjahos/uxL+8xruum13T0NPDo6zFY8q1vMrH6Ztyz+CxyKOsjte69c3qyKuy u82so6zL+dLU04u7rsO709DTw6GjxMfO0sPH1/bTi7uuu7nT0Mqyw7TTw8TYo78NCjehoqGwvMaE ndfcysfDu9PQseS7r7/sobGjrLzGhJ3X3MrHyqe/2KOsudzA7cjLhlS40L71z+7Ev7n9s8y88tax vs3Kx9K7uPa62rrQ19OjrMjnus6yxcTcyMPR0LeiudzA7dKyxNy5u7j8zbjD96OsDQq4/L/Jwb+7 r7vy1d+4/NPQobC118b4obGjrLb4sdzD4tK7zLi1ve2XxL+jrLTzvNK2vNa71WahsLLusru24MHL obHV4tCpt8/UkqGjDQo4oaKhraGtDQoNCr/Os8zK1dLmDQoNCjGhotXGztWhsNPWusPT1r/sobG1 xL+qt6KuYca3tcTW99Kqyta2zqOsye6/zMjPyrauYca36V+3or34tsi7usL9oaLWysG/sru80bXE 1vfSqoaWzOKjrMHLveLStb3n0dC3ou2XxL+53MDttcSzybmm1/a3qKGjDQoyoaLVxs7Vu/nT2sbz 0rXX1Mntt6LVuetBts6hophJzvHEo8q9oaKuYca3zNj8Y7rNxvPStc7Eu6+1yL2owaLEv7HqjKfP 8rXE0dC3os/uxL/X6davxKPKvaGjDQozoaLNqLn9z7XNs7XE0afPsO2XxL+53MDto6zF4NH4vt+x uO2XxL+53MDtu/mxvry8xNy1xO2XxL+53MDtyMvUsaGjDQo0oaLNqLn90afBlcq1yqm55re2tcTP 7sS/udzA7d9es8yjrL340NDT0NCntcS358/VudzA7aOsvPXJ2bL6xre/qrBsuf2zzNbQtcSx5Lj8 o6jQ6MfzseS4/KGiyei8xrHkuPyhormks8zXg7j8o6m1xA0KuMXCyqOsvbW1zbe1uaS0zpS1oaMN CjWhos2ouf2MV8+w7ZfEv7ywz+7Ev7ncwO21xLG+1sqjrMzhuN/P7sS/vZvA7bXE19TJ7cvY1sq6 zdXGztXP4NOmtcS8vMr1uaS+39PrudzA7by8x8mjrNLUsO/W+s/uxL+9m8Dts8nOqtHQt6K5pNf3 tcQNCtifyM6z0LWj1d/NrJVy0rLKx4hGttPB7Iyn1d+how0KNqGiwcu94r/nsr/DxYVm1/eyu7Op ysfU7LPJsvrGt7+qt6K9+LbI0dPG2rXE1vfSqtSt0vLWrtK7o6zNqLn9vajBorvy08W7r7/nsr/p VLL6xre/qreiwfezzLrNv+eyv8PFzcW2099c1/e7+tbGo6wNCtDOs8m439CntcS/57K/w8WFZtf3 u/rWxqOs1cbO1dHQt6Kyv8PFxWPK0LOhoaKyybm6oaLJ+rL6oaLGt9l8tciyv8PF1q685LXEudjB qrultq+52M+1us23vbeoo6zVxs7VvajBor/nsr/pVLL6xre/qrBsDQrB97PMus2/57K/w8XNxbbT 31zX97v61sa1xNKqteO6zdK1vefX7rzRjI28+b6t8p6how0KN6Gi1cbO1cjnus7NqLn9wby6w7XE 7ZfEv7zGu666zbzgv9i807/sz+7Ev99NtsijrNXGztXIzs7xt9a94qGiuPfP7sjOhNW8xruu45W9 06Giz+7Ev7fnz9W53MDtoaLP7sS/hpbM4pzPzai6zbSmwO2hog0Kz+7Ev7FPv9i1yLj3z+7KtZHw vLzE3KOszOG437L6xrfpX7eiz+7Ev7ncwO3Iy4ZUzca2r+2XxL/fXNf3tcTE3MGmoaMNCjihotXG ztXI57rOzai5/by8yvXGwIyPus2uYca3suLUh76h1OewbM/WzsrM4qGiveK+9s7K7n2jrNXGztWu Yca36V+3orj3uPbrQbbO06bUdcnzxMTQqYPIyN2jrNXGztWuYca3suLK1N9es8zS1LywDQrI57rO 1+m/l7L6xrey4srUuaTX96GjDQoNCiANCg0K0dC3os/uxL+53MDtoaqhqtVus8y087jZDQoNCg0K MdHQt6Ltl8S/udzA7bjFyvYNCrG+1cK92tGnwZXEv7Hqo7q9qMGisb6/zrPM0afBlbXEz+7Ev71N 1q+jrMP3yLexvr/Os8yMV8+wxNrI3aO7wO294tf2usPtl8S/udzA7bXE6lC8/NLyy9i8sLPJuabX 9reooaMNCjEuMcqyw7TKx+2XxL+jv8/uxL+1xMzY1fejvw0KMS4yyrLDtMrHudzA7aO/udzA7bmk 1/fT67y8yvW5pNf3tcTW99Kqsu6EZQ0KMS4zz+7Ev7ncwO3Wqsq2zOXPtaO6z+7Ev8n6w/zW3Mba oaLtl8S/udzA7bn9s8yhos/uxL+53MDtvsW089aqyrbB7NPyDQoxLjTR0Lei7ZfEv7ncwO21xMzY teOjvw0KMS410dCwbM/uxL+53MDtw+bFUrXE1ti088z01b0NCjEuNrC4wP3R0MzWo7pLuavLvrL6 xre/qrBsz+7Ev8qnlKG1xNSt0vK31s72DQrNqN9esLjA/bfWzvajrNL9tbyMV9Sxt9bO9rKiwO29 4rL6xre/qreiz+7Ev7PJuaa1xLnY5knS8svYDQo/z+7Ev8S/mMuyu8P3tF8NCj/Q6Mfzt9bO9rK7 s+S31g0KP8/uxL+8xruusrvXvMi3o6y5/dPawNa526OsuaTX98G/ucC8xrK71+MNCj/P7sS/v9jW xrK7waajrL3Xts6/2NbGsrvRz7jxDQo/v+eyv8PF0K3X97K7s6kNCj/ZWdS0xeSxuMO709Cxo9XP DQo/rmHGt7LiytSyu7Pkt9YNCj+8vNBnxsDJ88H309rQzsq9DQo/yLG3pofAuPG1xM7vwc/Iz9ak DQo/yejTi7HkuPzL5tLi0NS08w0Koa2hrQ0KMS43s8m5ptHQt6LP7sS/udzA7bXEz8i9+Nf2t6ij ug0KP72owaK/57K/w8Wy+sa36V+3osH3s8wNCj+9qMGiv+eyv+lUsvrGt7+qsGzP7sS/zcXqoNTL 1/e7+tbGDQo/s+S31rXErmHGt9Dox/O31s72DQo/1sa2qM3qyca1xM/uxL/Ti7uuDQo/ysqulLXE 7ZfEv7zgv9gNCj/BvLrDtcTP7sS/70zP1bncwO0NCj/Rz7jxtcTtl8S/1srBv7ncwO2jury8yvXG wIyPoaKy+sa3suLK1LncwO0NCqGtoa0NCjEuONHQt6LP7sS/udzA7d+AsdjQ67340NDPtb150NS1 xL+8wscNCg0KDQoyz+7Ev8b0hNMNCrG+1cK92oxXz7DEv7Hqo7rVxs7V7ZfEv8b0hNO1xLncwO23 vbeoo6zI57rOyerH6+2XxL/P7sS/18rUtKOsyOe6zsi3tqjP7sS/t7bOp6Os0tS8sM/uxL/G9Lav lf7S6bXEz+C52LncwO28vMfJoaMNCjIuMc/uxL/G9ITTtcSx6ta+DQoyLjLI57rOu/G1w+2XxL/I y8Gm2VnUtKGqoarIy8Gm18rUtMnqx+ux7Q0KMi4zz+7Ev8S/seq1xLRftqgNCjIuMy4xz+7Ev8S/ mMu1xMC01LShqqGqsqKyu8rHzcW209ORwtu1w7P2tcQNCjIuMy4yxL+x6rXEtKu13be9yr2hqqGq yc+0q8/CtO8NCjIuMy4zxL+x6rXEt9a94re9yr2hqqGq7ZfEv8S/mMvXqruvzqrWuJjLDQoyLjTP 7sS/t7bOp7XEyLe2qA0KMi41yOe6zr+qusPP7sS/xvS2r7vhoaqhqrvh0um53MDtvLzHyQ0KMi42 wby6w7XEv6q2y7XI09qzybmmwcvSu7DrDQoNCg0KM8/uxL+8xruu1sa2qA0Ksb7Vwrmd0afPsMS/ mMujutXGztXP7sS/04u7rtbGtqi1xLn9s8yhormkvt+hore9t6ihornYvPzSqsvYus2/2NbGvLzH yaOs1cbO1cjnus7NqLn9wby6w7XEz+7Ev7zGhJ221M/uxL+zybmmDQrM4cew1/az9rCyxcWjrLb4 srvKx8OkxL+1xL+q1bnP7sS/uaTX96GjDQozLjGy+sa3v6q3ou2XxL/Ti7uuysfSu4KAv+eyv8PF vK+zybXEvMaEnQ0KMy4yz+7Ev7ncwO28xruutcTWxraouf2zzA0KMy4zsvrGt7+qsGzP7sS/04u7 rrXE1vfSqtTYzOWhqqGq7ZfEv7zGu66V+A0KMy40z+7Ev9OLu67K6bXE1vfSqsTayN0NCjMuNe2X xL+9+LbIvMa7rrXE1sa2qLn9s8wNCjMuNrvutq+2qMF4o6hXQlOjqQ0KMy43ye7I67XEV0JTt9a9 4rXE0qrH86Gi1K3U8sVjstnX99KqteMNCjMuOLC0svrGt7+qt6LB97PMvfjQ0LXa0ruM01dCU7fW veINCjMuOdK1vefX7rzRyrW8+aGqoapJUETB97PMvPK96aO6uMXE7qGi04u7rqGiv6q3oqGi0enW pKGisGyyvKGiyfrD/NbcxtoNCjMuMTDhmLbUsrvNrNDCsvrGt7+qt6Ltl8S/7pDQzbbUrmHGt7+q t6LB97PMvfjQ0LLDvPQNCjMuMTGy+sa3v6q3osH3s8y31sDgssO89LXEzaizo9f2t6ijrMq+wP0N CjMuMTK77ravxcXQ8qOoUEVSVKOpDQozLjEzssm5uqGiuaTS1elft6K1yLvutq/T68no04u5pNf3 s+S31rKi0NANCjMuMTMuMcjnus7NqLn9v+eyv8PFuaTX97XEsqLQ0LzTv+zP7sS/vfi2yKO/DQoz LjEzLjLM4cew11Kx8LnY5knO78HP0+vpTL27xtrO78HPo6y9+NDQs+S31rXEv8myybm60NTGwLnA DQozLjEzLjPM4cewhqK2r9DCuanTpsnMv6qwbKGi0MLO78HPyM/WpLXIuaTX9w0KMy4xMy40zOHH sN9N0NC5pMuHyei8xqGi1Iey+te8sbi1yLmk1/cNCjMuMTS77oTTuaTG2rnAvMYNCjMuMTQuMdb3 0qq1xLvuhNO5pMbaucC8xre9t6ijug0KMy4xNC4yv+2Op7XCtvu3xre9t6i1xLnA04u5/bPMDQoz LjE0LjPI/bXjucC8xreotcS5wLzGuf2zzA0KMy4xNC40wOCxyKGiss7K/bXIucC8xre9t6gNCjMu MTQuNdGh1PGyu82sucDTi7e9t6i1xNLAvt0NCjMuMTWuYca36V+3os/uxL/fTbbIvMa7rrXEt9a8 iaO6MS8yvLbTi7uuoaIxLzIvMy80vLa8xoSdoaLW3LzGu64gLi4uLi4uDQozLjE2yr7A/aO6xLO1 59fTsvrGt7XEMS8yLzMvNLy2vMaEnQ0KMy4xN8/uxL/ZWdS0vMaEnQ0KMy4xONHQzNajus/uxL/G 9LavyrHI57rO0K2198Dvs8yxrrzGu666zdfK1LSjvw0KMy4xOc/uxL/XytS00K219w0KMy4yMNbG tqiy+sa3v6q3os/uxL+9+LbI04u7rsrHy/nT0IhGttOzydSxtcTWsNifDQozLjIx7ZfEv8jOhNXI 57rOwuTKtaGqoaq78bXDz+7Ev7PJ1LG1xLPQxbUNCjMuMjKwuMD9t9bO9qO6ssnTw8TE0KnK1rbO v3O2zM/uxL/W3MbaoaK807/s6V+3or34tsijvw0KMy4yMi4xvbKOn9L9tbyMV9Sxt9bO9rj3t07T 0Nb609rKselnxL+x6t9fs8mjqL9ztsy/qrBsyrG85KOptcTK1rbOo6zWwcnZMTDW1tLUyc+how0K My4yMi4y1euMpsO/1tbK1rbOo6y9ssqmvbK94sbk08X8Y6GiyLG146Gi323Tw7Ohus+1yKOszOG4 39Gn1LGRqrbUuMPA4M7K7n21xMTcwaahow0KDQoNCjTP7sS/04u7rr/Y1sa5/bPMDQqxvtXCvdrR p8+wxL+x6qO61cbO1e2XxL/Ti7uuv9jWxrXEudi8/NKqy9i6zbj3t07W99Kqt723qKOs0afPsMjn us7Vxr/Y7ZfEv9e0zKyjrMjnus6439CntcTX6davz+7Ev5X+0umjrA0KyOe6ztPQ0KfQrbX3oaKc z82o0tS/7MvZveK+9s/uxL/W0LXEzsrufaOsyOe6zr340NC358/Vus2x5Lj8udzA7aOs0tTIt7Gj z+7Ev7/Jv9iyosihtcOzybmmoaMNCjQuMc/uxL+8xruuv9jWxrXEu/m0oaGqoarE49aqtcDE47i6 2J+1xM/uxL+1xKDuzKzC8KO/DQo0LjK8xoSdtcS31ozTyrXKqcVjt9ay47/Y1sYNCjQuM7/Y1sbf XrPMoaqhqpX+0um804jzuOajrNPDlLW+3cu1u7CjrNe8yLfBy73i7ZfEv7XE17SRQg0KNC40v9jW xsrWts696b1CDQo0LjXA77PMsa653MDtDQo0LjUuMcjnus7J6NbDwO+zzLGuo78NCjQuNS4yyOe6 zr1vz+7Ev7PJ1LG9+NDQ0bnBptPrtq/BprncwO2jvw0KNC427ZfEv7GouOYNCjQuNi4x1twv63DW 3LGoDQo0LjYuMtTCtsixqLjmDQo0LjYuM73Xts6xqLjmDQo0LjYuNMDvs8yxrrGouOYNCjQuNi41 UUHWysG/1tyxqKO6v82527e007PP7sS/uf2zzNl8wb/T67mk1/euYca31srBvw0KNC42LjbR0MzW o7rI57rO16vQtLjf1srBv7XEz+7Ev7GouOajvw0KNC437ZfEv7vh0umjuulfuaS74aGi1twv1MLA /bvhoaK917bOlf7S6aGi1HXJ85X+oaLX3L1Zu+ENCjQuONHQ05Gjusjnus7fTdDQuN/Qp7XEz+7E v5X+0um53MDto78NCjQuOb/Y1sbK1rbOo7rP7sS/hpbM4rncwO0NCjQuOS4xz+7Ev7FPv9i5/bPM 1tDI57rOvNOPis7KzOK6zbfnz9W53MDto78NCjQuOS4yyOe6ztCttfehorm1zaihor3ivvay+sa3 v6q3otbQtcSzo7z7zsrM4qO/DQo0LjkuM7L6xrfpX7ei1tC1xIaWzOLI57rOvfjQ0LfWvIm53MDt o78NCjQuOS400dDM1qO6yOe6zrzTv+yuYca36V+3os7K7n21xL3ivvbL2bbIo78NCjQuMTC/2NbG yta2zqO6z+7Ev+9Mz9W53MDtDQo0LjEwLjG358/VudzA7bXEsr3zRQ0KNC4xMC4y70zP1cq2sfAN CjQuMTAuM+9Mz9W31s72DQo0LjEwLjTWxraot+fP1bncwO3Ti7uuDQo0LjEwLjXR0MzWo7rI57rO vfjQ0Lfn61W53MDto78NCjQuMTAuNrfnz9W84L/YDQo0LjEwLjfvTM/VuPrX2b7Y6ocNCjQuMTG/ 2NbGyta2zqO6seS4/LncwO0NCjQuMTEuMdHQzNajusqyw7TH6Ztyz8LQ6NKqyejTi7HkuPy/2NbG o78NCjQuMTEuMsno04ux5Lj8v9jWxg0KNC4xMS4zvMa7rrHkuPy53MDtDQo0LjExLjSx5Lj8v9jW xsH3s8yjuszhs/ax5Lj8yerViKGiseS4/LfWzvahorHkuPzF+te8oaLXg7j8yrXKqbrNuPrX2Q0K NC4xMS41yOe6zr2owaLUT7zGseS4/L/Y1sbOr4ZUu+GhqqGqQ0NCo78NCjQuMTEuNr2owaLUT7zG seS4/NOwz+y31sDgmMvXvA0KNC4xMr/Y1sbK1rbOo7rtl8S/s8nUsbmk1/e4urrJsU+/2A0KNC4x M8bky/u/2NbGyta2zqO6z+7Ev7zGhJ2y4sbAoaKbUbLfxsDJ89PrwP3N4rncwO2hotSkvq+horfH 1f255r/Y1sYNCg0KDQo10dC3os/uxL/NxbbTvajJ6LrNudzA7Q0Ksb7Vwr3a0afPsMS/seqjusDt veK/57K/w8WuYca3v6q3os3F6qC53MDt0+u/vLrLysfP7sS/s8m5prXEudi8/NLyy9ijrNXGztW/ 57K/w8XNxeqgudzA7dPrv7y6y7XEz8i9+Le9t6i6zcq1vPm9m9HpoaMNCjUuMbL6xre/qrei7ZfE v9Do0qq9qMGiv+eyv8PFiEa209TL1/e7+tbGDQo1LjKy+sa3v6q3os/uxL/NxbbTubmzybywxuTU 2rmry77X6davvVm5udbQtcTOu9bDDQo1LjPStb3n1+680cq122ChqqGq1ti2yL7Y1fPP7sS/iEa2 06Gqoaq6y9DE0KHX6beovenJ3A0KNS4zLjG6y9DE0KHX6bXEubmzyQ0KNS4zLjLCmsTcsr/pVL6t wO21xNaw2J8NCjUuMy4zz+7Ev76twO21xMKa1PANCjUuMy40jKbP7sS/vZvA7bXEy9jZfLrNvLzE 3NKqx/MNCjUuMy41usvQxNChvU2zydSxwprU8A0KNS4zLjbN4s6n1+m1xNaw1PANCjUuNLjf0KfN xbbTtcTSqsvYo7q5ss2stcTEv7HqoaLD97Rft9a5pKGiz+C7pdLAwLWhosG8usO5tc2oIKGtoa0N CjUuNdHQt6LNxeqgtc3Qp7XE1vfSqtSt0vKjutbYvLzK9aGix+G53MDto6zKwrHYuarH16Osv+fC msTcubXNqLK7lbMgoa2hrQ0KNS42zcXqoL2oyei6zbei1bm1xLn9s8yjutDOs8mhosSlus+hornm t7ahorHtrEYgoa2hrQ0KNS43zcW207K7zay3otW5vde2zrXEudzA7dKqteMNCjUuOMjnus7T0NCn 1MvX97/nsr/DxbL6xre/qreizcXqoKO/DQo1LjguMbjfsuPNxravzsS7r72oyegNCjUuOC4yuPjt l8S/vq3A7brNiEa207PJ1LGz5LfWytrIqA0KNS44LjPHv7uvz+7Ev7zGhJ3NxravDQo1LjguNL2o waK/57K/w8W1xMbAvNu7+tbGDQo1Ljm9qMGiuN/Qp7L6xre/qreiiEa207XEsOy3qKO6DQo/tKuy pc/uxL/UuL6wo6y9qMGiubLNrLXEzcXqoMS/seqjrMvmlXK+wMarvLDNs9K7xL+x6g0KP8flzvq9 57aoz+7Ev83F6qCzyYZUtcS9x8mr0+vCmtTwDQo/ubLNrLXEuaTX97e9t6ihorulsrm1xLy8xNyj rM/gu6XSwMC1sqK5ss2ss9CT+tTwyM4NCj/NxeqgubXNqMuzs6mjrL2owaLS19PazcXqoLPJ1LG9 u8H3tcS7t76zDQo/1f3It8PmttSIRrbTs+XNu7KivLDKsb3ivvYNCj/BvLrDtcTK2sioDQo1LjEw yOe6zrykwPjP7sS/zcW206O/DQo1LjExv+eyv8PFrmHGt+lft6LNxeqg1MvX99bQs6PSirXEs+XN uw0KNS4xMrSmwO2bX827tcTUrYR0oaK3vbeous28vMfJDQo1LjEzrmHGt7+qsGzNxbbTtcTE2s3i sr+cz82oDQo/0+u434zTweyMp6Oovvay34zTo6m1xLm1zagNCj/T69awxNyyv+lUvq3A7bXEnM/N qA0KP83FttOzydSxg8iyv7XEubXNqA0KNS4xNLL6xrfpX7eizcW207XEg8jN4rK/ubXNqLXEubXN qM2+vra6zbm1zai8vMfJDQo1LjE10d3Bt6O6yOe6zr3im1HXytS0m1/Nu6O/yOe6zr340NC/57K/ w8XXytS0ubXNqNPr0K2196O/DQoNCg0KNtHQsGzIy9SxuaTX98jOzvG53MDtDQqxvtXCvdrRp8GV xL+Yy6O60afBlbj2yMuVcrzkudzA7be9w+a1xLy8x8mjrNLUvLDI57rOw+a21Lmks8zKprmk1/e4 urrJzbvIu9T2vNO1xNe0v/ajrMjnus7WxraouaTX98jOzvHW3LGoo6wNCtXGztW5pNf3yM7O8dbc sai1xIVSsai3vbeooaMNCjYuMbj2yMvKsbzkudzA7Q0KNi4xLjHKssO0ysfKselnudzA7aO/DQo2 LjEuMpVyvOS53MDttcS4xcTuus3O88f4DQo2LjEuM8qx6We53MDttcS7+bG+17yEdA0KNi4xLjTK sbzkudzA7bXEt723qLrNvLzHyQ0KNi4yuaSzzMqmuaTX97i6usmx5Lj8udzA7Q0KNi4z7ZfEv7PJ 1LHT6+2XxL++rcDttcS5tc2ooaqhqrmk1/fIzs7xudzA7bXEx8XBug0KNi40uaSzzMqmuaTX98jO zvHW3IjzudzA7Q0KNi40LjG5pNf3yM7O8dbcsajE2sjdDQo2LjQuMrmk1/fIzs7x1tyxqLXEu+OI 87bUz/MNCjYuNC4zuaTX98jOzvHW3LGotcS747Got73KvQ0KDQoNCjfR0Lei7ZfEv9bKwb+53MDt DQqxvtXCvdqMV8+wxL+x6qO6wcu94u2XxL/WysG/udzA7bXE1vfSqre9t6ijrNXGztXI57rO09DQ p7XEvfjQ0Ly8yvXUdcnzus2y4tSHo6zS1L/Y1sbtl8S/1srBv6Os31+1vc/uxL+9+LbIus3WysG/ tcTGvbrioaMNCjcuMdHQt6Ltl8S/1srBv7ncwO21xLb+1tbW99Kqyta2zqO6vLzK9cbAjI+6zbLi 1IcNCjcuMry80GfGwMnzysey+sa3v6q3otTnxtq/2NbG2XzBv7XE09DQp8rWts4NCjcuM8novMbJ 87LpL7zsytO1xMS/tcS6zdf308MNCjcuNLj316jSte5J0/LUT7zGjI+y6S+87MrTtcS21M/zDQo3 LjXJ6LzGyfOy6S+87MrTtcTSu7Djuf2zzKOshaLT68jLhlQNCjcuNry8yvXUdcnzteO1xNRP1sOj rNb30qq8vMr1xsDJ8/xjtcTE2sjdDQo3Lje8vMr1xsDJ89Kqy9ix7bXE1tjSqtf308OjrLC4wP0N CjcuOLy80GfGwMnzwfezzKGi1K3U8qGi1+nWrw0KNy45yOe6ztf2usO8vMr1xsCMj7mk1/ejvw0K Ny4xMLC4wP2jutHp1qSyu7Pkt9a1xK5hxre4+MbzmEm0+IHttcS+3rTzk3DKpw0KNy4xMbL6xrfJ 6LzG8p7WpMH3s8y1xNLiwXi6zcS/tcQNCjcuMTKy+sa31E+8xtPrsuLK1LXEobBWobHEo9DNo7qy 4tSHysfT69RPvMbP4Iym06a1xNK7uPbfXrPMDQo3LjEzsvrGt5x5ytTB97PMo7oNCjcuMTMuMdbG tqiy4tSHst/C1NPr04u7rqOsg8jI3aOsxKOw5cq+wP0NCjcuMTMuMsnovMacecrUt72wuKOsxNrI 3aOsxKOw5cq+wP0NCjcuMTMuM7+qt6Ky4tSH08PA/Q0KNy4xMy401rTQ0Jx5ytQNCjcuMTMuNdDO s8mcecrUiPO45rKi303Q0MbAjI8NCjcuMTTR0MzWo7rI57rOvNOPis7SuavLvu2XxL/WysG/udzA 7aO/DQoNCjjX3L1ZvLDR0NORo7rO0rmry77I57rOuMTJxtHQsGzP7sS/udzA7aO/DQoNCiANCg0K ICAgICAgICAgsaggIMP7oaG72CAg1rQNCg0Kx+uMotLUz8KxqMP7se3E2sjdtPLToczujJG687ei RS1NQUlMtb06ZGFvcHUwMjBAMTYzLmNvbQ0KDQoNCsqxvOSjul9fX19fX19fX19fX19fX19fX19f X19fX6GhoaG12Pxjo7pfX19fX19fX19fX1+hoaGhoaENCg0KhaK74bWlzrvD+7dRo7pfX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fXyBFbWFpbKO6X19fX19fX19fX19fX19fX19fX19f XyChoQ0KDQrI57eixrHMp8230+uxvrvY1rS1pc67w/uzxrK7zay1xKGjx+vXosP3o7pfX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fXw0KDQrBqs+1yMujul9fX19fX19fX19fX19fXyDr iruwo7pfX19fX19fX19fX19fX19fX19fX18gtKvV5qO6X19fX19fX19fX19fX19fX19fX19fDQog oaENCrLOvNOMV9Sxo7pfX19fX19fX19fX19fX1/WsITVo7pfX19fX19fX19fX19fX1/K1rv6o7pf X19fX19fX19fX19fX19FbWFpbKO6X19fX19fX19fX19fDQoNCrLOvNOMV9Sxo7pfX19fX19fX19f X19fX1/Cms7xOl9fX19fX19fX19fX19fXyDK1plDo7pfX19fX19fX19fX19fX19FbWFpbKO6X19f X19fX19fX19fDQoNCrLOvNPRp4ZUo7pfX19fX19fX19fX19fX1/WsM7xo7pfX19fX19fX19fX19f X1/K1rv6o7pfX19fX19fX19fX19fX19FbWFpbKO6X19fX19fX19fX19fDQogICAgICANCri2v+63 vcq9o7qh9axGvfChoaH11qfGsaGhofXXqo6kDQoNCsjLlLWjul9fX19fX8jLICAghaK74bfR08Oj urmyvMajul9fX19fX9SqIA0KDQqxuNeiDQoxLsrVtb2588u+sajD+9DFz6K686OsztLDx4yitdrS u8qx6We6zbnzy76ForvhwarPtcjLvfjQ0Mi31Uqjuw0KMi7U2r+qv87HsNK71tyjrM7Sw8fT0Neo yMu4+Lnzy763osvNss6808Xg0bW1xMi3yM+6r6Osyc/D5tPQxeDTlrGotb3WuNL9o6zS1Lywz+rP uLXEyc+/zrXY1re6zcK3z9+IRKO7DQozLrTLv86zzNKyv8nS1LCyxcXG89K1xNrRtaOsu7bTrcC0 tefXydGvvLDJ6tWIxcXG2qO7DQo0LsjnttS0y7/Os8zT0MjOus7Syc7Ko6y7ttOtsqa08uuKu7DP 8s7SgoPXydGvoaMNCg0K ------=_000_NextPart083471748037_=---- Content-Type: text/html; charset="gb2312" Content-Transfer-Encoding: base64 PGh0bWw+PGhlYWQ+DQo8bWV0YSBjb250ZW50PSJ0ZXh0L2h0bWw7IGNoYXJzZXQ9Z2IyMzEyIiBo dHRwLWVxdWl2PUNvbnRlbnQtVHlwZT4NCjwvaGVhZD4NCjxib2R5Pg0KPHA+PGJyPtHQt6Ltl8S/ udzA7TwvcD4NCjxwPqG+yrG85LXYteOhvyAyMDE1xOoxMdTCMjMtMjSxsb6poaIxMdTCMjYtMjfJ z7qjoaIxMdTCMzAtMTLUwjHJ7tvaPC9wPg0KPHA+ob6yzrzTttTP86G/IMbz0rVDRU8v19y9m8Dt oaLG89K11tC437LjudzA7aGi0dCwbNfcvOChotfcuaShotfcuaSw7KGivLzQZ7K/w8W9m8DtoaLW 97ncoaLP7sS/vZvA7aGivLzK9bnHuMmhos/uxL+53MDtuaSzzMqmoaJRQbXIoaM8L3A+DQo8cD6h vsrav863vcq9ob8gvbLKpr2yytogKyDSlca10d3S7yArILC4wP3R0NORICu9x8mrsOfR3SArIL2y yqb8Y8bAPC9wPg0KPHA+ob7Rp8+wt9HTw6G/IDMyMDDUqi/Iy6OouqzBvczs1tCyzaGi1ri2qL3M ssShorLoteOjqTwvcD4NCjxwPqG+s9Cw7LWlzruhvyCyxSC+rSDF4CDRtSC+VyZuYnNwOzwvcD4N CjxwPqG+tLnRr8jIvoChvyAwMjAtLTg2NDE5NTEwJm5ic3A7Jm5ic3A7IDg2NDE2NTM5Jm5ic3A7 Jm5ic3A7IMHWz8jJ+iZuYnNwOyZuYnNwOyDR7tChveM8L3A+DQo8cD6hvta1sODK1rv6ob8gMTM2 ODg4NzI3NjE8L3A+DQo8cD6/zrPMsbO+sDwvcD4NCjxwPtTasvrGt7+qt6LfXrPM1tCjrMbz0rW7 8tXfz+7Ev76twO0vudzA7cjL1LHNqLOjw+bFUtLUz8LOyu59o6zPo837zai5/bG+v86zzLXE0afB laOszqrG85hJzOG5qb7fzOW1xL3im1HLvMK3us3TpoymtOvKqaGjPGJyPjGhotTasvrGt7+qt6K5 /bPM1tCjrJVyvOS99NG5waa088rHxvPStcbVsenD5sVStcTSu7j2hpbM4qGj7ZfEv76twO0v7ZfE v7i62J/Iyy+y+sa3uLrYn8jLL9b3udy/qreiuaSzzMqmL8/uxL+1o7Wx1d+jrDxicj7O3sLbxPq1 xM23z8678rdRzr3I57rOo6zfQLj2zsrM4ra8ysfE+rOjs6PT9rW9tcTAp76z1q7Su6GjvNOw4LPJ nunE+rXEzaizo9Gh1PGho9Xiyse38dfjubujv8rHt/HfgNPQxuTL+7e9yr23vbeosO/W+jxicj7E +r6hv8nE3LTvs8mVcrzkxL+x6qO/sb6/zrPMvau9b7P20v2Mp9GnhlTV0rW9tPCwuKGjPGJyPjKh osbz0rXP672owaLR0LBsz+7Ev4hGttOjrMjOw/zP7sS/vq3A7S/P7sS/uLrYn8jLoaO1q8rHz+7E v76twO24w8jnus65pNf3o6zI57rOhWa1983FttOjrMjnus7T67/NkfShorjfsuPS1Lywt8fR0LBs PGJyPrK/w8W5tc2oo6yzyc6qwcvP7sS/vq3A7bXEwKe786OszazKsdKy1+i1S9fFudzA7bjfjNO2 1M/uxL++rcDtt8XIqLrNytqZ4KGjPGJyPjOhou2XxL++rcDttb2119Omvt+xuNT1mNO1xMvY1sqj v8bzmEnTprjDyOe6zsXg0fjP7sS/vZvA7aO/PGJyPjShormry77Sss2ouf3By0lTTzkwMDAvVFMx Njk0OS9DTU1JtcTIz9ako6zSsr2owaLBy9K7zNey+sa3v6qwbMH3s8yjrLWrysfU2r7fzOWIzNDQ uf2zzNbQo6zItM3qyKvX39H5o7uyu82stcTP7sS/PGJyPra819/V4oKAwfezzKOs0rK3x7Ojt7HL 9qOs09rKx7TzvNK2vLK7sLTV1dXigoDB97PM1rTQ0KGj30C4w9T1w7Sw7KO/PGJyPjWhorTzvNKz o8u1o7qhsL/Nu6fQ6Mfz09a4xLHkwcuhsaOsobDtl8S/1tDOqNK7srux5LXEvs3Kx9eDobGjrKGw v827p9fcyse63Me/ysajrMv7goPM4bP2tcTSqsfzo6zO0sPHm12w7Leovty++KGxoaM8YnI+seTK x7/Nudu55sLJo6zP7sS/1+mfb7eovty++LjEseSjrLWryseFc9OmuMPT0LDst6jD5rbU30DW1rHk u6+ho8THtb2119Om1JPI57rO06a21O2XxL+5/bPM1tC1xLHku6/E2KO/PGJyPjahos/uxL+8xruu m13T0NPDo6zFY8q1vMrH6Ztyz+CxyKOsjte69c3qyKuyu82so6zL+dLU04u7rsO709DTw6GjxMfO 0sPH1/bTi7uuu7nT0Mqyw7TTw8TYo788YnI+N6GiobC8xoSd19zKx8O709Cx5Luvv+yhsaOsvMaE ndfcysfKp7/Yo6y53MDtyMuGVLjQvvXP7sS/uf2zzLzy1rG+zcrH0ru49rrautDX06OsyOe6zrLF xNzIw9HQt6K53MDt0rLE3Lm7uPzNuMP3o6w8YnI+uPy/ycG/u6+78tXfuPzT0KGwtdfG+KGxo6y2 +LHcw+LSu8y4tb3tl8S/o6y087zStrzWu9VmobCy7rK7tuDBy6Gx1eLQqbfP1JKhozxicj44oaKh raGtPC9wPg0KPHA+v86zzMrV0uY8L3A+DQo8cD4xoaLVxs7VobDT1rrD09a/7KGxtcS/qreirmHG t7XE1vfSqsrWts6jrMnuv8zIz8q2rmHGt+lft6K9+LbIu7rC/aGi1srBv7K7vNG1xNb30qqGlszi o6zBy73i0rW959HQt6Ltl8S/udzA7bXEs8m5ptf2t6ihozxicj4yoaLVxs7Vu/nT2sbz0rXX1Mnt t6LVuetBts6hophJzvHEo8q9oaKuYca3zNj8Y7rNxvPStc7Eu6+1yL2owaLEv7HqjKfP8rXE0dC3 os/uxL/X6davxKPKvaGjPGJyPjOhos2ouf3Ptc2ztcTRp8+w7ZfEv7ncwO2jrMXg0fi+37G47ZfE v7ncwO27+bG+vLzE3LXE7ZfEv7ncwO3Iy9SxoaM8YnI+NKGizai5/dGnwZXKtcqpuea3trXEz+7E v7ncwO3fXrPMo6y9+NDQ09DQp7XEt+fP1bncwO2jrLz1ydmy+sa3v6qwbLn9s8zW0LXEseS4/KOo 0OjH87HkuPyhosnovMax5Lj8oaK5pLPM14O4/KOptcQ8YnI+uMXCyqOsvbW1zbe1uaS0zpS1oaM8 YnI+NaGizai5/YxXz7Dtl8S/vLDP7sS/udzA7bXEsb7WyqOszOG438/uxL+9m8DttcTX1Mnty9jW yrrN1cbO1c/g06a1xLy8yvW5pL7f0+u53MDtvLzHyaOs0tSw79b6z+7Ev72bwO2zyc6q0dC3ormk 1/e1xDxicj7Yn8jOs9C1o9XfzayVctKyyseIRrbTweyMp9XfoaM8YnI+NqGiwcu94r/nsr/DxYVm 1/eyu7OpysfU7LPJsvrGt7+qt6K9+LbI0dPG2rXE1vfSqtSt0vLWrtK7o6zNqLn9vajBorvy08W7 r7/nsr/pVLL6xre/qreiwfezzLrNv+eyv8PFzcW2099c1/e7+tbGo6w8YnI+0M6zybjf0Ke1xL/n sr/DxYVm1/e7+tbGo6zVxs7V0dC3orK/w8XFY8rQs6GhorLJubqhosn6svqhosa32Xy1yLK/w8XW rrzktcS52MGqu6W2r7nYz7W6zbe9t6ijrNXGztW9qMGiv+eyv+lUsvrGt7+qsGw8YnI+wfezzLrN v+eyv8PFzcW2099c1/e7+tbGtcTSqrXjus3Stb3n1+680YyNvPm+rfKeoaM8YnI+N6Gi1cbO1cjn us7NqLn9wby6w7XE7ZfEv7zGu666zbzgv9i807/sz+7Ev99NtsijrNXGztXIzs7xt9a94qGiuPfP 7sjOhNW8xruu45W906Giz+7Ev7fnz9W53MDtoaLP7sS/hpbM4pzPzai6zbSmwO2hojxicj7P7sS/ sU+/2LXIuPfP7sq1kfC8vMTco6zM4bjfsvrGt+lft6LP7sS/udzA7cjLhlTNxrav7ZfEv99c1/e1 xMTcwaahozxicj44oaLVxs7VyOe6zs2ouf28vMr1xsCMj7rNrmHGt7Li1Ie+odTnsGzP1s7KzOKh or3ivvbOyu59o6zVxs7VrmHGt+lft6K497j260G2ztOm1HXJ88TE0KmDyMjdo6zVxs7VrmHGt7Li ytTfXrPM0tS8sDxicj7I57rO1+m/l7L6xrey4srUuaTX96GjPC9wPg0KPHA+Jm5ic3A7PC9wPg0K PHA+0dC3os/uxL+53MDtoaqhqtVus8y087jZPC9wPg0KPHA+PGJyPjHR0Lei7ZfEv7ncwO24xcr2 PGJyPrG+1cK92tGnwZXEv7Hqo7q9qMGisb6/zrPM0afBlbXEz+7Ev71N1q+jrMP3yLexvr/Os8yM V8+wxNrI3aO7wO294tf2usPtl8S/udzA7bXE6lC8/NLyy9i8sLPJuabX9reooaM8YnI+MS4xyrLD tMrH7ZfEv6O/z+7Ev7XEzNjV96O/PGJyPjEuMsqyw7TKx7ncwO2jv7ncwO25pNf30+u8vMr1uaTX 97XE1vfSqrLuhGU8YnI+MS4zz+7Ev7ncwO3Wqsq2zOXPtaO6z+7Ev8n6w/zW3MbaoaLtl8S/udzA 7bn9s8yhos/uxL+53MDtvsW089aqyrbB7NPyPGJyPjEuNNHQt6Ltl8S/udzA7bXEzNi146O/PGJy PjEuNdHQsGzP7sS/udzA7cPmxVK1xNbYtPPM9NW9PGJyPjEuNrC4wP3R0MzWo7pLuavLvrL6xre/ qrBsz+7Ev8qnlKG1xNSt0vK31s72PGJyPs2o316wuMD9t9bO9qOs0v21vIxX1LG31s72sqLA7b3i svrGt7+qt6LP7sS/s8m5prXEudjmSdLyy9g8YnI+P8/uxL/Ev5jLsrvD97RfPGJyPj/Q6Mfzt9bO 9rK7s+S31jxicj4/z+7Ev7zGu66yu9e8yLejrLn909rA1rnbo6y5pNf3wb+5wLzGsrvX4zxicj4/ z+7Ev7/Y1sayu8Gmo6y917bOv9jWxrK70c+48Txicj4/v+eyv8PF0K3X97K7s6k8YnI+P9lZ1LTF 5LG4w7vT0LGj1c88YnI+P65hxrey4srUsruz5LfWPGJyPj+8vNBnxsDJ88H309rQzsq9PGJyPj/I sbemh8C48bXEzu/Bz8jP1qQ8YnI+P8no04ux5Lj8y+bS4tDUtPM8YnI+oa2hrTxicj4xLjezybmm 0dC3os/uxL+53MDttcTPyL341/a3qKO6PGJyPj+9qMGiv+eyv8PFsvrGt+lft6LB97PMPGJyPj+9 qMGiv+eyv+lUsvrGt7+qsGzP7sS/zcXqoNTL1/e7+tbGPGJyPj+z5LfWtcSuYca30OjH87fWzvY8 YnI+P9bGtqjN6snGtcTP7sS/04u7rjxicj4/ysqulLXE7ZfEv7zgv9g8YnI+P8G8usO1xM/uxL/v TM/VudzA7Txicj4/0c+48bXE7ZfEv9bKwb+53MDto7q8vMr1xsCMj6GisvrGt7LiytS53MDtPGJy PqGtoa08YnI+MS440dC3os/uxL+53MDt34Cx2NDrvfjQ0M+1vXnQ1LXEv7zCxzwvcD4NCjxwPjxi cj4yz+7Ev8b0hNM8YnI+sb7Vwr3ajFfPsMS/seqjutXGztXtl8S/xvSE07XEudzA7be9t6ijrMjn us7J6sfr7ZfEv8/uxL/XytS0o6zI57rOyLe2qM/uxL+3ts6no6zS1Lywz+7Ev8b0tq+V/tLptcTP 4LnYudzA7by8x8mhozxicj4yLjHP7sS/xvSE07XEserWvjxicj4yLjLI57rOu/G1w+2XxL/Iy8Gm 2VnUtKGqoarIy8Gm18rUtMnqx+ux7Txicj4yLjPP7sS/xL+x6rXEtF+2qDxicj4yLjMuMc/uxL/E v5jLtcTAtNS0oaqhqrKisrvKx83FttPTkcLbtcOz9rXEPGJyPjIuMy4yxL+x6rXEtKu13be9yr2h qqGqyc+0q8/CtO88YnI+Mi4zLjPEv7HqtcS31r3it73KvaGqoartl8S/xL+Yy9equ6/Oqta4mMs8 YnI+Mi40z+7Ev7e2zqe1xMi3tqg8YnI+Mi41yOe6zr+qusPP7sS/xvS2r7vhoaqhqrvh0um53MDt vLzHyTxicj4yLjbBvLrDtcS/qrbLtcjT2rPJuabBy9K7sOs8L3A+DQo8cD48YnI+M8/uxL+8xruu 1sa2qDxicj6xvtXCuZ3Rp8+wxL+Yy6O61cbO1c/uxL/Ti7uu1sa2qLXEuf2zzKGiuaS+36Git723 qKGiudi8/NKqy9i6zb/Y1sa8vMfJo6zVxs7VyOe6zs2ouf3BvLrDtcTP7sS/vMaEnbbUz+7Ev7PJ uaY8YnI+zOHHsNf2s/awssXFo6y2+LK7ysfDpMS/tcS/qtW5z+7Ev7mk1/ehozxicj4zLjGy+sa3 v6q3ou2XxL/Ti7uuysfSu4KAv+eyv8PFvK+zybXEvMaEnTxicj4zLjLP7sS/udzA7bzGu661xNbG tqi5/bPMPGJyPjMuM7L6xre/qrBsz+7Ev9OLu661xNb30qrU2Mzloaqhqu2XxL+8xruulfg8YnI+ My40z+7Ev9OLu67K6bXE1vfSqsTayN08YnI+My417ZfEv734tsi8xruutcTWxraouf2zzDxicj4z Lja77ravtqjBeKOoV0JTo6k8YnI+My43ye7I67XEV0JTt9a94rXE0qrH86Gi1K3U8sVjstnX99Kq teM8YnI+My44sLSy+sa3v6q3osH3s8y9+NDQtdrSu4zTV0JTt9a94jxicj4zLjnStb3n1+680cq1 vPmhqqGqSVBEwfezzLzyvemjurjFxO6hotOLu66hor+qt6KhotHp1qShorBssryhosn6w/zW3Mba PGJyPjMuMTDhmLbUsrvNrNDCsvrGt7+qt6Ltl8S/7pDQzbbUrmHGt7+qt6LB97PMvfjQ0LLDvPQ8 YnI+My4xMbL6xre/qreiwfezzLfWwOCyw7z0tcTNqLOj1/a3qKOsyr7A/Txicj4zLjEyu+62r8XF 0PKjqFBFUlSjqTxicj4zLjEzssm5uqGiuaTS1elft6K1yLvutq/T68no04u5pNf3s+S31rKi0NA8 YnI+My4xMy4xyOe6zs2ouf2/57K/w8W5pNf3tcSyotDQvNO/7M/uxL+9+LbIo788YnI+My4xMy4y zOHHsNdSsfC52OZJzu/Bz9Pr6Uy9u8bazu/Bz6OsvfjQ0LPkt9a1xL/Jssm5utDUxsC5wDxicj4z LjEzLjPM4cewhqK2r9DCuanTpsnMv6qwbKGi0MLO78HPyM/WpLXIuaTX9zxicj4zLjEzLjTM4cew 303Q0Lmky4fJ6LzGoaLUh7L617yxuLXIuaTX9zxicj4zLjE0u+6E07mkxtq5wLzGPGJyPjMuMTQu Mdb30qq1xLvuhNO5pMbaucC8xre9t6ijujxicj4zLjE0LjK/7Y6ntcK2+7fGt723qLXEucDTi7n9 s8w8YnI+My4xNC4zyP2147nAvMa3qLXEucC8xrn9s8w8YnI+My4xNC40wOCxyKGiss7K/bXIucC8 xre9t6g8YnI+My4xNC410aHU8bK7zay5wNOLt723qLXE0sC+3Txicj4zLjE1rmHGt+lft6LP7sS/ 3022yLzGu661xLfWvImjujEvMry204u7rqGiMS8yLzMvNLy2vMaEnaGi1ty8xruuIA0KLi4uLi4u PGJyPjMuMTbKvsD9o7rEs7Xn19Oy+sa3tcQxLzIvMy80vLa8xoSdPGJyPjMuMTfP7sS/2VnUtLzG hJ08YnI+My4xONHQzNajus/uxL/G9LavyrHI57rO0K2198Dvs8yxrrzGu666zdfK1LSjvzxicj4z LjE5z+7Ev9fK1LTQrbX3PGJyPjMuMjDWxraosvrGt7+qt6LP7sS/vfi2yNOLu67Kx8v509CIRrbT s8nUsbXE1rDYnzxicj4zLjIx7ZfEv8jOhNXI57rOwuTKtaGqoaq78bXDz+7Ev7PJ1LG1xLPQxbU8 YnI+My4yMrC4wP231s72o7qyydPDxMTQqcrWts6/c7bMz+7Ev9bcxtqhorzTv+zpX7eivfi2yKO/ PGJyPjMuMjIuMb2yjp/S/bW8jFfUsbfWzva497dO09DW+tPayrHpZ8S/serfX7PJo6i/c7bMv6qw bMqxvOSjqbXEyta2zqOs1sHJ2TEw1tbS1MnPoaM8YnI+My4yMi4y1euMpsO/1tbK1rbOo6y9ssqm vbK94sbk08X8Y6GiyLG146Gi323Tw7Ohus+1yKOszOG439Gn1LGRqrbUuMPA4M7K7n21xMTcwaah ozwvcD4NCjxwPjxicj40z+7Ev9OLu66/2NbGuf2zzDxicj6xvtXCvdrRp8+wxL+x6qO61cbO1e2X xL/Ti7uuv9jWxrXEudi8/NKqy9i6zbj3t07W99Kqt723qKOs0afPsMjnus7Vxr/Y7ZfEv9e0zKyj rMjnus6439CntcTX6davz+7Ev5X+0umjrDxicj7I57rO09DQp9CttfehopzPzajS1L/sy9m94r72 z+7Ev9bQtcTOyu59o6zI57rOvfjQ0Lfnz9W6zbHkuPy53MDto6zS1Mi3saPP7sS/v8m/2LKiyKG1 w7PJuaahozxicj40LjHP7sS/vMa7rr/Y1sa1xLv5tKGhqqGqxOPWqrXAxOO4utiftcTP7sS/tcSg 7syswvCjvzxicj40LjK8xoSdtcS31ozTyrXKqcVjt9ay47/Y1sY8YnI+NC4zv9jWxt9es8yhqqGq lf7S6bzTiPO45qOs08OUtb7dy7W7sKOs17zIt8HLveLtl8S/tcTXtJFCPGJyPjQuNL/Y1sbK1rbO vem9Qjxicj40LjXA77PMsa653MDtPGJyPjQuNS4xyOe6zsno1sPA77PMsa6jvzxicj40LjUuMsjn us69b8/uxL+zydSxvfjQ0NG5wabT67avwaa53MDto788YnI+NC427ZfEv7GouOY8YnI+NC42LjHW 3C/rcNbcsag8YnI+NC42LjLUwrbIsai45jxicj40LjYuM73Xts6xqLjmPGJyPjQuNi40wO+zzLGu sai45jxicj40LjYuNVFB1srBv9bcsaijur/Nudu3tNOzz+7Ev7n9s8zZfMG/0+u5pNf3rmHGt9bK wb88YnI+NC42LjbR0MzWo7rI57rO16vQtLjf1srBv7XEz+7Ev7GouOajvzxicj40Ljftl8S/u+HS 6aO66V+5pLvhoaLW3C/UwsD9u+Ghor3Xts6V/tLpoaLUdcnzlf6hotfcvVm74Txicj40LjjR0NOR o7rI57rO303Q0Ljf0Ke1xM/uxL+V/tLpudzA7aO/PGJyPjQuOb/Y1sbK1rbOo7rP7sS/hpbM4rnc wO08YnI+NC45LjHP7sS/sU+/2Ln9s8zW0Mjnus6804+KzsrM4rrNt+fP1bncwO2jvzxicj40Ljku Msjnus7QrbX3oaK5tc2ooaK94r72svrGt7+qt6LW0LXEs6O8+87KzOKjvzxicj40LjkuM7L6xrfp X7ei1tC1xIaWzOLI57rOvfjQ0LfWvIm53MDto788YnI+NC45LjTR0MzWo7rI57rOvNO/7K5hxrfp X7eizsrufbXEveK+9svZtsijvzxicj40LjEwv9jWxsrWts6jus/uxL/vTM/VudzA7Txicj40LjEw LjG358/VudzA7bXEsr3zRTxicj40LjEwLjLvTM/Vyrax8Dxicj40LjEwLjPvTM/Vt9bO9jxicj40 LjEwLjTWxraot+fP1bncwO3Ti7uuPGJyPjQuMTAuNdHQzNajusjnus69+NDQt+frVbncwO2jvzxi cj40LjEwLja358/VvOC/2Dxicj40LjEwLjfvTM/VuPrX2b7Y6oc8YnI+NC4xMb/Y1sbK1rbOo7qx 5Lj8udzA7Txicj40LjExLjHR0MzWo7rKssO0x+mbcs/C0OjSqsno04ux5Lj8v9jWxqO/PGJyPjQu MTEuMsno04ux5Lj8v9jWxjxicj40LjExLjO8xruuseS4/LncwO08YnI+NC4xMS40seS4/L/Y1sbB 97PMo7rM4bP2seS4/Mnq1YihorHkuPy31s72oaKx5Lj8xfrXvKGi14O4/Mq1yqm6zbj619k8YnI+ NC4xMS41yOe6zr2owaLUT7zGseS4/L/Y1sbOr4ZUu+GhqqGqQ0NCo788YnI+NC4xMS42vajBotRP vMax5Lj807DP7LfWwOCYy9e8PGJyPjQuMTK/2NbGyta2zqO67ZfEv7PJ1LG5pNf3uLq6ybFPv9g8 YnI+NC4xM8bky/u/2NbGyta2zqO6z+7Ev7zGhJ2y4sbAoaKbUbLfxsDJ89PrwP3N4rncwO2hotSk vq+horfH1f255r/Y1sY8L3A+DQo8cD48YnI+NdHQt6LP7sS/zcW2072oyei6zbncwO08YnI+sb7V wr3a0afPsMS/seqjusDtveK/57K/w8WuYca3v6q3os3F6qC53MDt0+u/vLrLysfP7sS/s8m5prXE udi8/NLyy9ijrNXGztW/57K/w8XNxeqgudzA7dPrv7y6y7XEz8i9+Le9t6i6zcq1vPm9m9HpoaM8 YnI+NS4xsvrGt7+qt6Ltl8S/0OjSqr2owaK/57K/w8WIRrbT1MvX97v61sY8YnI+NS4ysvrGt7+q t6LP7sS/zcW207m5s8m8sMbk1Nq5q8u+1+nWr71ZubnW0LXEzrvWwzxicj41LjPStb3n1+680cq1 22ChqqGq1ti2yL7Y1fPP7sS/iEa206Gqoaq6y9DE0KHX6beovenJ3Dxicj41LjMuMbrL0MTQodfp tcS5ubPJPGJyPjUuMy4ywprE3LK/6VS+rcDttcTWsNifPGJyPjUuMy4zz+7Ev76twO21xMKa1PA8 YnI+NS4zLjSMps/uxL+9m8DttcTL2Nl8us28vMTc0qrH8zxicj41LjMuNbrL0MTQob1Ns8nUscKa 1PA8YnI+NS4zLjbN4s6n1+m1xNaw1PA8YnI+NS40uN/Qp83FttO1xNKqy9ijurmyzay1xMS/seqh osP3tF+31rmkoaLP4Lul0sDAtaGiwby6w7m1zaggDQqhraGtPGJyPjUuNdHQt6LNxeqgtc3Qp7XE 1vfSqtSt0vKjutbYvLzK9aGix+G53MDto6zKwrHYuarH16Osv+fCmsTcubXNqLK7lbMgoa2hrTxi cj41LjbNxeqgvajJ6LrNt6LVubXEuf2zzKO60M6zyaGixKW6z6Giuea3tqGise2sRiANCqGtoa08 YnI+NS43zcW207K7zay3otW5vde2zrXEudzA7dKqteM8YnI+NS44yOe6ztPQ0KfUy9f3v+eyv8PF svrGt7+qt6LNxeqgo788YnI+NS44LjG437Ljzca2r87Eu6+9qMnoPGJyPjUuOC4yuPjtl8S/vq3A 7brNiEa207PJ1LGz5LfWytrIqDxicj41LjguM8e/u6/P7sS/vMaEnc3Gtq88YnI+NS44LjS9qMGi v+eyv8PFtcTGwLzbu/rWxjxicj41Ljm9qMGiuN/Qp7L6xre/qreiiEa207XEsOy3qKO6PGJyPj+0 q7Klz+7Ev9S4vrCjrL2owaK5ss2stcTNxeqgxL+x6qOsy+aVcr7Axqu8sM2z0rvEv7HqPGJyPj/H 5c76vee2qM/uxL/Nxeqgs8mGVLXEvcfJq9PrwprU8Dxicj4/ubLNrLXEuaTX97e9t6ihorulsrm1 xLy8xNyjrM/gu6XSwMC1sqK5ss2ss9CT+tTwyM48YnI+P83F6qC5tc2oy7OzqaOsvajBotLX09rN xeqgs8nUsb27wfe1xLu3vrM8YnI+P9X9yLfD5rbUiEa207PlzbuyorywyrG94r72PGJyPj/BvLrD tcTK2sioPGJyPjUuMTDI57rOvKTA+M/uxL/NxbbTo788YnI+NS4xMb/nsr/Dxa5hxrfpX7eizcXq oNTL1/fW0LOj0oq1xLPlzbs8YnI+NS4xMrSmwO2bX827tcTUrYR0oaK3vbeous28vMfJPGJyPjUu MTOuYca3v6qwbM3FttO1xMTazeKyv5zPzag8YnI+P9PruN+M08HsjKejqL72st+M06OptcS5tc2o PGJyPj/T69awxNyyv+lUvq3A7bXEnM/NqDxicj4/zcW207PJ1LGDyLK/tcS5tc2oPGJyPjUuMTSy +sa36V+3os3FttO1xIPIzeKyv7m1zai1xLm1zajNvr62us25tc2ovLzHyTxicj41LjE10d3Bt6O6 yOe6zr3im1HXytS0m1/Nu6O/yOe6zr340NC/57K/w8XXytS0ubXNqNPr0K2196O/PC9wPg0KPHA+ PGJyPjbR0LBsyMvUsbmk1/fIzs7xudzA7Txicj6xvtXCvdrRp8GVxL+Yy6O60afBlbj2yMuVcrzk udzA7be9w+a1xLy8x8mjrNLUvLDI57rOw+a21Lmks8zKprmk1/e4urrJzbvIu9T2vNO1xNe0v/aj rMjnus7WxraouaTX98jOzvHW3LGoo6w8YnI+1cbO1bmk1/fIzs7x1tyxqLXEhVKxqLe9t6ihozxi cj42LjG49sjLyrG85LncwO08YnI+Ni4xLjHKssO0ysfKselnudzA7aO/PGJyPjYuMS4ylXK85Lnc wO21xLjFxO66zc7zx/g8YnI+Ni4xLjPKselnudzA7bXEu/mxvte8hHQ8YnI+Ni4xLjTKsbzkudzA 7bXEt723qLrNvLzHyTxicj42LjK5pLPMyqa5pNf3uLq6ybHkuPy53MDtPGJyPjYuM+2XxL+zydSx 0+vtl8S/vq3A7bXEubXNqKGqoaq5pNf3yM7O8bncwO21xMfFwbo8YnI+Ni40uaSzzMqmuaTX98jO zvHW3IjzudzA7Txicj42LjQuMbmk1/fIzs7x1tyxqMTayN08YnI+Ni40LjK5pNf3yM7O8dbcsai1 xLvjiPO21M/zPGJyPjYuNC4zuaTX98jOzvHW3LGotcS747Got73KvTwvcD4NCjxwPjxicj430dC3 ou2XxL/WysG/udzA7Txicj6xvtXCvdqMV8+wxL+x6qO6wcu94u2XxL/WysG/udzA7bXE1vfSqre9 t6ijrNXGztXI57rO09DQp7XEvfjQ0Ly8yvXUdcnzus2y4tSHo6zS1L/Y1sbtl8S/1srBv6Os31+1 vc/uxL+9+LbIus3WysG/tcTGvbrioaM8YnI+Ny4x0dC3ou2XxL/WysG/udzA7bXEtv7W1tb30qrK 1rbOo7q8vMr1xsCMj7rNsuLUhzxicj43LjK8vNBnxsDJ88rHsvrGt7+qt6LU58bav9jWxtl8wb+1 xNPQ0KfK1rbOPGJyPjcuM8novMbJ87LpL7zsytO1xMS/tcS6zdf308M8YnI+Ny40uPfXqNK17knT 8tRPvMaMj7LpL7zsytO1xLbUz/M8YnI+Ny41yei8xsnzsukvvOzK07XE0ruw47n9s8yjrIWi0+vI y4ZUPGJyPjcuNry8yvXUdcnzteO1xNRP1sOjrNb30qq8vMr1xsDJ8/xjtcTE2sjdPGJyPjcuN7y8 yvXGwMnz0qrL2LHttcTW2NKq1/fTw6OssLjA/Txicj43Lji8vNBnxsDJ88H3s8yhotSt1PKhotfp 1q88YnI+Ny45yOe6ztf2usO8vMr1xsCMj7mk1/ejvzxicj43LjEwsLjA/aO60enWpLK7s+S31rXE rmHGt7j4xvOYSbT4ge21xL7etPOTcMqnPGJyPjcuMTGy+sa3yei8xvKe1qTB97PMtcTS4sF4us3E v7XEPGJyPjcuMTKy+sa31E+8xtPrsuLK1LXEobBWobHEo9DNo7qy4tSHysfT69RPvMbP4Iym06a1 xNK7uPbfXrPMPGJyPjcuMTOy+sa3nHnK1MH3s8yjujxicj43LjEzLjHWxraosuLUh7LfwtTT69OL u66jrIPIyN2jrMSjsOXKvsD9PGJyPjcuMTMuMsnovMacecrUt72wuKOsxNrI3aOsxKOw5cq+wP08 YnI+Ny4xMy4zv6q3orLi1IfTw8D9PGJyPjcuMTMuNNa00NCcecrUPGJyPjcuMTMuNdDOs8mcecrU iPO45rKi303Q0MbAjI88YnI+Ny4xNNHQzNajusjnus6804+KztK5q8u+7ZfEv9bKwb+53MDto788 L3A+DQo8cD4419y9Wbyw0dDTkaO6ztK5q8u+yOe6zrjEycbR0LBsz+7Ev7ncwO2jvzwvcD4NCjxw PiZuYnNwOzwvcD4NCjxwPiZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyCxqCZuYnNwOyDD+6Ghu9gmbmJzcDsg1rQ8L3A+DQo8cD7H64yi0tTPwrGow/ux7cTa yN208tOhzO6Mkbrzt6JFLU1BSUy1vTpkYW9wdTAyMEAxNjMuY29tPC9wPg0KPHA+PGJyPsqxvOSj ul9fX19fX19fX19fX19fX19fX19fX19fX6GhoaG12Pxjo7pfX19fX19fX19fX1+hoaGhoaE8L3A+ DQo8cD6ForvhtaXOu8P7t1Gjul9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fIEVt YWlso7pfX19fX19fX19fX19fX19fX19fX19fIKGhPC9wPg0KPHA+yOe3osaxzKfNt9Prsb672Na0 taXOu8P7s8ayu82stcSho8fr16LD96O6X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X188L3A+DQo8cD7Bqs+1yMujul9fX19fX19fX19fX19fXyDriruwo7pfX19fX19fX19fX19fX19f X19fX18gDQq0q9Xmo7pfX19fX19fX19fX19fX19fX19fX188YnI+Jm5ic3A7oaE8YnI+ss6804xX 1LGjul9fX19fX19fX19fX19fX9awhNWjul9fX19fX19fX19fX19fX8rWu/qjul9fX19fX19fX19f X19fX0VtYWlso7pfX19fX19fX19fX188L3A+DQo8cD6yzrzTjFfUsaO6X19fX19fX19fX19fX19f wprO8TpfX19fX19fX19fX19fX18gDQrK1plDo7pfX19fX19fX19fX19fX19FbWFpbKO6X19fX19f X19fX19fPC9wPg0KPHA+ss6809GnhlSjul9fX19fX19fX19fX19fX9awzvGjul9fX19fX19fX19f X19fX8rWu/qjul9fX19fX19fX19fX19fX0VtYWlso7pfX19fX19fX19fX188YnI+Jm5ic3A7Jm5i c3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7IA0KPGJyPri2v+63vcq9o7qh9axGvfChoaH11qfGsaGhofXX qo6kPC9wPg0KPHA+yMuUtaO6X19fX19fyMsmbmJzcDsmbmJzcDsghaK74bfR08OjurmyvMajul9f X19fX9SqIDwvcD4NCjxwPrG416I8YnI+MS7K1bW9ufPLvrGow/vQxc+iuvOjrM7Sw8eMorXa0rvK selnus2588u+haK74cGqz7XIy7340NDIt9VKo7s8YnI+Mi7U2r+qv87HsNK71tyjrM7Sw8fT0Neo yMu4+Lnzy763osvNss6808Xg0bW1xMi3yM+6r6Osyc/D5tPQxeDTlrGotb3WuNL9o6zS1Lywz+rP uLXEyc+/zrXY1re6zcK3z9+IRKO7PGJyPjMutMu/zrPM0rK/ydLUsLLFxcbz0rXE2tG1o6y7ttOt wLS159fJ0a+8sMnq1YjFxcbao7s8YnI+NC7I57bUtMu/zrPM09DIzrrO0snOyqOsu7bTrbKmtPLr iruwz/LO0oKD18nRr6GjPGJyPjwvcD48L2JvZHk+PC9odG1sPg0K ------=_000_NextPart083471748037_=------ From sandeen@sandeen.net Fri Nov 13 15:29:47 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 099AB7F5A for ; Fri, 13 Nov 2015 15:29:47 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id D53AB304032 for ; Fri, 13 Nov 2015 13:29:43 -0800 (PST) X-ASG-Debug-ID: 1447450180-04bdf07f0a46300001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id ZCfJvplMmd4XGH6S for ; Fri, 13 Nov 2015 13:29:40 -0800 (PST) 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 1547061451CC for ; Fri, 13 Nov 2015 15:29:40 -0600 (CST) Subject: Re: [PATCH V2] xfs: create helper for bmap finish & trans join in attr code To: xfs@oss.sgi.com X-ASG-Orig-Subj: Re: [PATCH V2] xfs: create helper for bmap finish & trans join in attr code References: <56441B8E.6070603@redhat.com> <5644BEF8.6070201@sandeen.net> <20151112165801.GA14854@infradead.org> <20151112201231.GS19199@dastard> <20151113090840.GA16423@infradead.org> From: Eric Sandeen Message-ID: <56465643.5070504@sandeen.net> Date: Fri, 13 Nov 2015 15:29:39 -0600 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <20151113090840.GA16423@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: 1447450180 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24371 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 11/13/15 3:08 AM, Christoph Hellwig wrote: > On Fri, Nov 13, 2015 at 07:12:31AM +1100, Dave Chinner wrote: >> On Thu, Nov 12, 2015 at 08:58:01AM -0800, Christoph Hellwig wrote: >>> I think the problem here is simply that our interfaces suck. >>> xfs_trans_roll really needs to rejoin any inode to the new transaction >>> to that was joined to the previous one. Once we've fixed that we can >>> get rid of the silly committed arguments and everyone will be happy. >> >> xfs_trans_roll is not specifically for rolling transactions with >> locked inodes in them. We could use it for any object that needs >> multiple transactions to modify. e.g. we could roll transactions >> across an AGF (using hold+join) so that it remains locked across >> multiple allocation/free transactions. > > xfs_trans_roll already logs the inode core, which requires the > inode to be attached to the transaction. While I could see the > point of moving this out of the core __xfs_trans_roll into an > xfs_trans_roll_inode helper we might as well follow the current > interface for now. Trying to follow you guys ;) Something like this? diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index dbae649..d23bce8 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -91,32 +91,32 @@ xfs_zero_extent( * last due to locking considerations. We never free any extents in * the first transaction. * - * Return 1 if the given transaction was committed and a new one - * started, and 0 otherwise in the committed parameter. + * If an inode *ip is provided, rejoin it to the transaction if + * the transaction was committed. */ int /* error */ xfs_bmap_finish( struct xfs_trans **tp, /* transaction pointer addr */ struct xfs_bmap_free *flist, /* i/o: list extents to free */ - int *committed)/* xact committed or not */ + xfs_inode_t *ip) { struct xfs_efd_log_item *efd; /* extent free data */ struct xfs_efi_log_item *efi; /* extent free intention */ int error; /* error return value */ + int committed;/* xact committed or not */ struct xfs_bmap_free_item *free; /* free extent item */ struct xfs_bmap_free_item *next; /* next item on free list */ ASSERT((*tp)->t_flags & XFS_TRANS_PERM_LOG_RES); - if (flist->xbf_count == 0) { - *committed = 0; + if (flist->xbf_count == 0) return 0; - } + efi = xfs_trans_get_efi(*tp, flist->xbf_count); for (free = flist->xbf_first; free; free = free->xbfi_next) xfs_trans_log_efi_extent(*tp, efi, free->xbfi_startblock, free->xbfi_blockcount); - error = __xfs_trans_roll(tp, NULL, committed); + error = __xfs_trans_roll(tp, ip, &committed); if (error) { /* * If the transaction was committed, drop the EFD reference @@ -128,16 +128,13 @@ xfs_bmap_finish( * transaction so we should return committed=1 even though we're * returning an error. */ - if (*committed) { + if (committed) { xfs_efi_release(efi); xfs_force_shutdown((*tp)->t_mountp, (error == -EFSCORRUPTED) ? SHUTDOWN_CORRUPT_INCORE : SHUTDOWN_META_IO_ERROR); - } else { - *committed = 1; } - return error; } From darrick.wong@oracle.com Fri Nov 13 15:37:14 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 40B697F5A for ; Fri, 13 Nov 2015 15:37:14 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 06C408F8035 for ; Fri, 13 Nov 2015 13:37:13 -0800 (PST) X-ASG-Debug-ID: 1447450631-04bdf07f09469e0001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id 9meTbw9oPuVxgIZP (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 13 Nov 2015 13:37:11 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tADLak7Y032147 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 13 Nov 2015 21:36:47 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id tADLakB4023152 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Fri, 13 Nov 2015 21:36:46 GMT Received: from abhmp0008.oracle.com (abhmp0008.oracle.com [141.146.116.14]) by userv0121.oracle.com (8.13.8/8.13.8) with ESMTP id tADLajE1028290; Fri, 13 Nov 2015 21:36:45 GMT Received: from localhost (/71.198.20.188) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 13 Nov 2015 13:36:45 -0800 Subject: [RFCv3.2 00/12] xfstests: test the nfs/cifs/btrfs/xfs reflink/dedupe ioctls From: "Darrick J. Wong" X-ASG-Orig-Subj: [RFCv3.2 00/12] xfstests: test the nfs/cifs/btrfs/xfs reflink/dedupe ioctls To: david@fromorbit.com, darrick.wong@oracle.com Cc: fstests@vger.kernel.org, xfs@oss.sgi.com, hch@infradead.org, tao.peng@primarydata.com, linux-ext4@vger.kernel.org, Anna.Schumaker@netapp.com, linux-btrfs@vger.kernel.org Date: Fri, 13 Nov 2015 13:36:43 -0800 Message-ID: <20151113213643.31124.80975.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0022.oracle.com [141.146.126.234] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1447450631 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24371 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Hi all, This is part of the third revision of an RFC for adding to XFS support for tracking reverse-mappings of physical blocks to file and metadata; and support for mapping multiple file logical blocks to the same physical block, more commonly known as reflinking. This patchset aims to make xfstests perform more rigorous testing of the NFS/CIFS/btrfs/XFS file clone, reflink, and dedupe ioctls. There are now tests of the basic functionality of the three ioctls; tests to ensure that the filesystem exhibits the expected copy on write semantics; tests to try to suss out race conditions in the new write paths; tests to ensure that the ioctls peform basic disk accounting correctly; tests of the interaction between reflink and the various fallocate verbs (allocate, punch, collapse, insert zeroes); and some attempts to test the upper limits of reflinking and ENOSPC behavior. Since the last posting, each test tries to reflink (or dedupe) on the test or scratch FS to decide if they're going to run, instead of guessing based on FS type. Per Dave's suggestion, I also converted the basic functionality tests to use fixed sizes so that I can use md5sum in the golden output to check that the file contents match exactly. Since "RFCv3.1", I've made the following changes: * Renumbered the tests to the lowest numbers possible, per Dave's request. * Fixed the reflink and dedupe _require tests so that they can run on things like NFS which support reflink but not dedupe. * Added checks for lsattr/chattr support so that we don't produce bogus failures on NFS, and put the *attr tests in separate test files. * Appended a couple of tools I wrote to handle finding minimal test numbers and moving tests around. If you're going to start using this mess, you probably ought to just pull from my github trees for kernel[1], xfsprogs[2], xfstests[3], and xfs-docs[4]. They should just work with the btrfs that's in 4.3... and somewhat buggily with the 4.3 XFS patched with [1]. Comments and questions are, as always, welcome. --D [1] https://github.com/djwong/linux/tree/for-dave [2] https://github.com/djwong/xfsprogs/tree/for-dave [3] https://github.com/djwong/xfstests/tree/for-dave [4] https://github.com/djwong/xfs-documentation/tree/for-dave From darrick.wong@oracle.com Fri Nov 13 15:37:26 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 3801F7F5A for ; Fri, 13 Nov 2015 15:37:26 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id F22F7304043 for ; Fri, 13 Nov 2015 13:37:25 -0800 (PST) X-ASG-Debug-ID: 1447450643-04bdf07f0a46a10001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id ivAoR1VJ1EAy7hFe (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 13 Nov 2015 13:37:23 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tADLatTl018005 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 13 Nov 2015 21:36:55 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id tADLasK5009200 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Fri, 13 Nov 2015 21:36:55 GMT Received: from abhmp0003.oracle.com (abhmp0003.oracle.com [141.146.116.9]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id tADLapvD007176; Fri, 13 Nov 2015 21:36:51 GMT Received: from localhost (/71.198.20.188) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 13 Nov 2015 13:36:51 -0800 Subject: [PATCH 01/12] test-scripts: test migration scripts From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 01/12] test-scripts: test migration scripts To: david@fromorbit.com, darrick.wong@oracle.com Cc: fstests@vger.kernel.org, xfs@oss.sgi.com, hch@infradead.org, tao.peng@primarydata.com, linux-ext4@vger.kernel.org, Anna.Schumaker@netapp.com, linux-btrfs@vger.kernel.org Date: Fri, 13 Nov 2015 13:36:50 -0800 Message-ID: <20151113213650.31124.16817.stgit@birch.djwong.org> In-Reply-To: <20151113213643.31124.80975.stgit@birch.djwong.org> References: <20151113213643.31124.80975.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1447450643 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24371 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Add two scripts: "nextid" finds the next available test ID number in a group, and "mvtest" relocates a test, fixes the golden output, and moves the group entry for that test. Signed-off-by: Darrick J. Wong --- mvtest | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ nextid | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100755 mvtest create mode 100755 nextid diff --git a/mvtest b/mvtest new file mode 100755 index 0000000..b5406d1 --- /dev/null +++ b/mvtest @@ -0,0 +1,58 @@ +#!/bin/sh + +# Renumber a test + +if [ -z "$1" ] || [ "$1" = "--help" ]; then + echo "Usage: $0 path_to_test new_path_to_test" + exit 1 +fi + +src="$1" +dest="$2" + +die() { + echo "$@" + exit 1 +} + +nsort() { + sort -g < "$1" > "$2" +} + +append() { + out="$1" + shift + echo "$@" >> "${out}" +} + +test "${src}" != "${dest}" || die "Test \"${src}\" is the same as dest." +test -e "tests/${src}" || die "Test \"${src}\" does not exist." +test ! -e "tests/${dest}" || die "Test \"${src}\" already exists." + +sid="$(basename "${src}")" +did="$(basename "${dest}")" + +sgroup="$(basename "$(dirname "tests/${src}")")" +dgroup="$(basename "$(dirname "tests/${dest}")")" + +sgroupfile="tests/${sgroup}/group" +dgroupfile="tests/${sgroup}/group" + +$DBG git mv "tests/${src}" "tests/${dest}" +$DBG git mv "tests/${src}.out" "tests/${dest}.out" +$DBG sed -e "s/^# FS QA Test No. ${sid}$/# FS QA Test No. ${did}/g" -i "tests/${dest}" +$DBG sed -e "s/^QA output created by ${sid}$/QA output created by ${did}/g" -i "tests/${dest}.out" +$DBG sed -e "s/test-${sid}/test-${did}/g" -i "tests/${dest}.out" + +grpline="$(grep "^${sid} " "${sgroupfile}")" +newgrpline="$(echo "${grpline}" | sed -e "s/^${sid} /${did} /g")" + +$DBG sed -e "/^${sid}.*$/d" -i "${sgroupfile}" +$DBG cp "${dgroupfile}" "${dgroupfile}.new" +$DBG append "${dgroupfile}.new" "${newgrpline}" +$DBG nsort "${dgroupfile}.new" "${dgroupfile}" +$DBG rm "${dgroupfile}.new" + +echo "Moved \"${src}\" to \"${dest}\"." + +exit 0 diff --git a/nextid b/nextid new file mode 100755 index 0000000..285b549 --- /dev/null +++ b/nextid @@ -0,0 +1,35 @@ +#!/bin/sh + +# Given a group name, find the next available test number. + +if [ -z "$1" ] || [ "$1" = "--help" ]; then + echo "Usage: $0 groupname[/start_looking_at_this_number]" + exit 1 +fi + +die() { + echo "$@" + exit 1 +} + +if [ "$(basename "$1")" != "$1" ]; then + group="$(dirname "$1")" + id="$(basename "$1")" +else + group="$1" + id=1 +fi +test -e "tests/${group}/group" || die "Unknown group \"${group}\"." + +while test "${id}" -lt 1000; do + name="$(printf "%.03d" "${id}")" + if [ ! -e "tests/${group}/${name}" ]; then + echo "${group}/${name}" + exit 0 + fi + id=$((id + 1)) +done + +echo "No free IDs less than ${id} in group \"${group}\"." + +exit 1 From darrick.wong@oracle.com Fri Nov 13 15:37:27 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 8A7ED7F5A for ; Fri, 13 Nov 2015 15:37:27 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 7D03A8F8049 for ; Fri, 13 Nov 2015 13:37:27 -0800 (PST) X-ASG-Debug-ID: 1447450642-04cb6c0cd342880001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id ZsNUzJTrJVT9XwO1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 13 Nov 2015 13:37:23 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tADLawXd032281 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 13 Nov 2015 21:36:58 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id tADLaw3H023642 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Fri, 13 Nov 2015 21:36:58 GMT Received: from abhmp0013.oracle.com (abhmp0013.oracle.com [141.146.116.19]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id tADLawKm007246; Fri, 13 Nov 2015 21:36:58 GMT Received: from localhost (/71.198.20.188) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 13 Nov 2015 13:36:57 -0800 Subject: [PATCH 02/12] btrfs: move btrfs reflink tests to generic From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 02/12] btrfs: move btrfs reflink tests to generic To: david@fromorbit.com, darrick.wong@oracle.com Cc: fstests@vger.kernel.org, xfs@oss.sgi.com, hch@infradead.org, tao.peng@primarydata.com, linux-ext4@vger.kernel.org, Anna.Schumaker@netapp.com, linux-btrfs@vger.kernel.org Date: Fri, 13 Nov 2015 13:36:56 -0800 Message-ID: <20151113213656.31124.99827.stgit@birch.djwong.org> In-Reply-To: <20151113213643.31124.80975.stgit@birch.djwong.org> References: <20151113213643.31124.80975.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0022.oracle.com [141.146.126.234] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1447450643 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/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, UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24370 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.60 MARKETING_SUBJECT Subject contains popular marketing words 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Move the cp --reflink tests from btrfs/ to generic/ since xfs now supports that ioctl. Signed-off-by: Darrick J. Wong --- tests/btrfs/026 | 92 ----------------------------------------- tests/btrfs/026.out | 16 ------- tests/btrfs/027 | 109 ------------------------------------------------- tests/btrfs/027.out | 25 ----------- tests/btrfs/028 | 83 ------------------------------------- tests/btrfs/028.out | 7 --- tests/btrfs/group | 3 - tests/generic/110 | 92 +++++++++++++++++++++++++++++++++++++++++ tests/generic/110.out | 16 +++++++ tests/generic/111 | 109 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/111.out | 25 +++++++++++ tests/generic/115 | 83 +++++++++++++++++++++++++++++++++++++ tests/generic/115.out | 7 +++ tests/generic/group | 3 + 14 files changed, 335 insertions(+), 335 deletions(-) delete mode 100755 tests/btrfs/026 delete mode 100644 tests/btrfs/026.out delete mode 100755 tests/btrfs/027 delete mode 100644 tests/btrfs/027.out delete mode 100755 tests/btrfs/028 delete mode 100644 tests/btrfs/028.out create mode 100755 tests/generic/110 create mode 100644 tests/generic/110.out create mode 100755 tests/generic/111 create mode 100644 tests/generic/111.out create mode 100755 tests/generic/115 create mode 100644 tests/generic/115.out diff --git a/tests/btrfs/026 b/tests/btrfs/026 deleted file mode 100755 index 7559ca2..0000000 --- a/tests/btrfs/026 +++ /dev/null @@ -1,92 +0,0 @@ -#! /bin/bash -# FS QA Test No. 026 -# -# Tests file clone functionality of btrfs ("reflinks"): -# - Reflink a file -# - Reflink the reflinked file -# - Modify the original file -# - Modify the reflinked file -# -#----------------------------------------------------------------------- -# Copyright (c) 2014, Oracle and/or its affiliates. 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 -_supported_fs btrfs -_supported_os Linux - -_require_xfs_io_command "fiemap" -_require_cp_reflink -_require_test - -TESTDIR1=$TEST_DIR/test-$seq -rm -rf $TESTDIR1 -mkdir $TESTDIR1 - -_checksum_files() { - for F in original copy1 copy2 - do - md5sum $TESTDIR1/$F | _filter_test_dir - done -} - -rm -f $seqres.full - -echo "Create the original file and reflink to copy1, copy2" -$XFS_IO_PROG -f -c 'pwrite -S 0x61 0 9000' $TESTDIR1/original \ - >> $seqres.full 2>&1 -cp --reflink $TESTDIR1/original $TESTDIR1/copy1 -cp --reflink $TESTDIR1/copy1 $TESTDIR1/copy2 -_verify_reflink $TESTDIR1/original $TESTDIR1/copy1 -_verify_reflink $TESTDIR1/original $TESTDIR1/copy2 -echo "Original md5sums:" -_checksum_files - -echo "Overwrite original file with new data" -$XFS_IO_PROG -c 'pwrite -S 0x62 0 9000' $TESTDIR1/original \ - >> $seqres.full 2>&1 -echo "md5sums after overwriting original:" -_checksum_files - -echo "Overwrite copy1 with different new data" -$XFS_IO_PROG -c 'pwrite -S 0x63 0 9000' $TESTDIR1/copy1 \ - >> $seqres.full 2>&1 -echo "md5sums after overwriting copy1:" -_checksum_files - -# success, all done -status=0 -exit diff --git a/tests/btrfs/026.out b/tests/btrfs/026.out deleted file mode 100644 index 3b90ff0..0000000 --- a/tests/btrfs/026.out +++ /dev/null @@ -1,16 +0,0 @@ -QA output created by 026 -Create the original file and reflink to copy1, copy2 -Original md5sums: -42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-026/original -42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-026/copy1 -42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-026/copy2 -Overwrite original file with new data -md5sums after overwriting original: -4a847a25439532bf48b68c9e9536ed5b TEST_DIR/test-026/original -42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-026/copy1 -42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-026/copy2 -Overwrite copy1 with different new data -md5sums after overwriting copy1: -4a847a25439532bf48b68c9e9536ed5b TEST_DIR/test-026/original -e271cd47d9f62ebc96cb4e67ae4d16db TEST_DIR/test-026/copy1 -42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-026/copy2 diff --git a/tests/btrfs/027 b/tests/btrfs/027 deleted file mode 100755 index d2b812b..0000000 --- a/tests/btrfs/027 +++ /dev/null @@ -1,109 +0,0 @@ -#! /bin/bash -# FS QA Test No. 027 -# -# Tests file clone functionality of btrfs ("reflinks") on directory -# trees. -# - Create directory and subdirectory, each having one file -# - Create 2 recursive reflinked copies of the tree -# - Modify the original files -# - Modify one of the copies -# -#----------------------------------------------------------------------- -# Copyright (c) 2014, Oracle and/or its affiliates. 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 -_supported_fs btrfs -_supported_os Linux - -_require_xfs_io_command "fiemap" -_require_cp_reflink -_require_test - -TESTDIR1=$TEST_DIR/test-$seq -rm -rf $TESTDIR1 -mkdir $TESTDIR1 - -_checksum_files() { - for F in original/file1 original/subdir/file2 \ - copy1/file1 copy1/subdir/file2 \ - copy2/file1 copy2/subdir/file2 - do - md5sum $TESTDIR1/$F | _filter_test_dir - done -} - -rm -f $seqres.full - -mkdir $TESTDIR1/original -mkdir $TESTDIR1/original/subdir - -echo "Create the original files and reflink dirs" -$XFS_IO_PROG -f -c 'pwrite -S 0x61 0 9000' $TESTDIR1/original/file1 \ - >> $seqres.full 2>&1 -$XFS_IO_PROG -f -c 'pwrite -S 0x62 0 11000' \ - $TESTDIR1/original/subdir/file2 >> $seqres.full 2>&1 -cp --recursive --reflink $TESTDIR1/original $TESTDIR1/copy1 -cp --recursive --reflink $TESTDIR1/copy1 $TESTDIR1/copy2 - -_verify_reflink $TESTDIR1/original/file1 $TESTDIR1/copy1/file1 -_verify_reflink $TESTDIR1/original/subdir/file2 \ - $TESTDIR1/copy1/subdir/file2 -_verify_reflink $TESTDIR1/original/file1 $TESTDIR1/copy2/file1 -_verify_reflink $TESTDIR1/original/subdir/file2 \ - $TESTDIR1/copy2/subdir/file2 - -echo "Original md5sums:" -_checksum_files - -echo "Overwrite original/file1 and original/subdir/file2 with new data" -$XFS_IO_PROG -c 'pwrite -S 0x63 0 13000' $TESTDIR1/original/file1 \ - >> $seqres.full 2>&1 -$XFS_IO_PROG -c 'pwrite -S 0x64 5000 1000' \ - $TESTDIR1/original/subdir/file2 >> $seqres.full 2>&1 -echo "md5sums now:" -_checksum_files - -echo "Overwrite copy1/file1 and copy1/subdir/file2 with new data" -$XFS_IO_PROG -c 'pwrite -S 0x65 0 9000' $TESTDIR1/copy1/file1 \ - >> $seqres.full 2>&1 -$XFS_IO_PROG -c 'pwrite -S 0x66 5000 25000' \ - $TESTDIR1/copy1/subdir/file2 >> $seqres.full 2>&1 -echo "md5sums now:" -_checksum_files - -# success, all done -status=0 -exit diff --git a/tests/btrfs/027.out b/tests/btrfs/027.out deleted file mode 100644 index 7b7e3bb..0000000 --- a/tests/btrfs/027.out +++ /dev/null @@ -1,25 +0,0 @@ -QA output created by 027 -Create the original files and reflink dirs -Original md5sums: -42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-027/original/file1 -ca390545f0aedb54b808d6128c56a7dd TEST_DIR/test-027/original/subdir/file2 -42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-027/copy1/file1 -ca390545f0aedb54b808d6128c56a7dd TEST_DIR/test-027/copy1/subdir/file2 -42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-027/copy2/file1 -ca390545f0aedb54b808d6128c56a7dd TEST_DIR/test-027/copy2/subdir/file2 -Overwrite original/file1 and original/subdir/file2 with new data -md5sums now: -260f6785c0537fd12582dcae28a3c1a9 TEST_DIR/test-027/original/file1 -b8d91fb600f6f2191f2ba66665374860 TEST_DIR/test-027/original/subdir/file2 -42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-027/copy1/file1 -ca390545f0aedb54b808d6128c56a7dd TEST_DIR/test-027/copy1/subdir/file2 -42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-027/copy2/file1 -ca390545f0aedb54b808d6128c56a7dd TEST_DIR/test-027/copy2/subdir/file2 -Overwrite copy1/file1 and copy1/subdir/file2 with new data -md5sums now: -260f6785c0537fd12582dcae28a3c1a9 TEST_DIR/test-027/original/file1 -b8d91fb600f6f2191f2ba66665374860 TEST_DIR/test-027/original/subdir/file2 -b20229a003e3985c4b0e6806abcd6642 TEST_DIR/test-027/copy1/file1 -b815b24069db14e0a3a07169fd563e93 TEST_DIR/test-027/copy1/subdir/file2 -42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-027/copy2/file1 -ca390545f0aedb54b808d6128c56a7dd TEST_DIR/test-027/copy2/subdir/file2 diff --git a/tests/btrfs/028 b/tests/btrfs/028 deleted file mode 100755 index 7193337..0000000 --- a/tests/btrfs/028 +++ /dev/null @@ -1,83 +0,0 @@ -#! /bin/bash -# FS QA Test No. 028 -# -# Moving and deleting cloned ("reflinked") files on btrfs: -# - Create a file and a reflink -# - Move both to a directory -# - Delete the original (moved) file, check that the copy still exists. -# -#----------------------------------------------------------------------- -# Copyright (c) 2014, Oracle and/or its affiliates. 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 -_supported_fs btrfs -_supported_os Linux - -_require_xfs_io_command "fiemap" -_require_cp_reflink -_require_test - -rm -f $seqres.full - -TESTDIR1=$TEST_DIR/test-$seq -rm -rf $TESTDIR1 -mkdir $TESTDIR1 - -echo "Create the original files and reflink dirs" -$XFS_IO_PROG -f -c 'pwrite -S 0x61 0 9000' $TESTDIR1/original \ - >> $seqres.full -cp --reflink $TESTDIR1/original $TESTDIR1/copy - -_verify_reflink $TESTDIR1/original $TESTDIR1/copy - -echo "Move orig & reflink copy to subdir and md5sum:" -mkdir $TESTDIR1/subdir -mv $TESTDIR1/original $TESTDIR1/subdir/original_moved -mv $TESTDIR1/copy $TESTDIR1/subdir/copy_moved -_verify_reflink $TESTDIR1/subdir/original_moved \ - $TESTDIR1/subdir/copy_moved - -md5sum $TESTDIR1/subdir/original_moved | _filter_test_dir -md5sum $TESTDIR1/subdir/copy_moved | _filter_test_dir - -echo "remove orig from subdir and md5sum reflink copy:" -rm $TESTDIR1/subdir/original_moved -md5sum $TESTDIR1/subdir/copy_moved | _filter_test_dir -rm -rf $TESTDIR1/subdir - -# success, all done -status=0 -exit diff --git a/tests/btrfs/028.out b/tests/btrfs/028.out deleted file mode 100644 index f683fce..0000000 --- a/tests/btrfs/028.out +++ /dev/null @@ -1,7 +0,0 @@ -QA output created by 028 -Create the original files and reflink dirs -Move orig & reflink copy to subdir and md5sum: -42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-028/subdir/original_moved -42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-028/subdir/copy_moved -remove orig from subdir and md5sum reflink copy: -42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-028/subdir/copy_moved diff --git a/tests/btrfs/group b/tests/btrfs/group index 7cf7dd7..c5d529f 100644 --- a/tests/btrfs/group +++ b/tests/btrfs/group @@ -28,9 +28,6 @@ 023 auto 024 auto quick compress 025 auto quick send clone -026 auto quick clone -027 auto quick clone -028 auto quick clone 029 auto quick clone 030 auto quick send 031 auto quick subvol clone diff --git a/tests/generic/110 b/tests/generic/110 new file mode 100755 index 0000000..ec74357 --- /dev/null +++ b/tests/generic/110 @@ -0,0 +1,92 @@ +#! /bin/bash +# FS QA Test No. 110 +# +# Tests file clone functionality of btrfs ("reflinks"): +# - Reflink a file +# - Reflink the reflinked file +# - Modify the original file +# - Modify the reflinked file +# +#----------------------------------------------------------------------- +# Copyright (c) 2014, Oracle and/or its affiliates. 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 +_supported_fs btrfs +_supported_os Linux + +_require_xfs_io_command "fiemap" +_require_cp_reflink +_require_test + +TESTDIR1=$TEST_DIR/test-$seq +rm -rf $TESTDIR1 +mkdir $TESTDIR1 + +_checksum_files() { + for F in original copy1 copy2 + do + md5sum $TESTDIR1/$F | _filter_test_dir + done +} + +rm -f $seqres.full + +echo "Create the original file and reflink to copy1, copy2" +$XFS_IO_PROG -f -c 'pwrite -S 0x61 0 9000' $TESTDIR1/original \ + >> $seqres.full 2>&1 +cp --reflink $TESTDIR1/original $TESTDIR1/copy1 +cp --reflink $TESTDIR1/copy1 $TESTDIR1/copy2 +_verify_reflink $TESTDIR1/original $TESTDIR1/copy1 +_verify_reflink $TESTDIR1/original $TESTDIR1/copy2 +echo "Original md5sums:" +_checksum_files + +echo "Overwrite original file with new data" +$XFS_IO_PROG -c 'pwrite -S 0x62 0 9000' $TESTDIR1/original \ + >> $seqres.full 2>&1 +echo "md5sums after overwriting original:" +_checksum_files + +echo "Overwrite copy1 with different new data" +$XFS_IO_PROG -c 'pwrite -S 0x63 0 9000' $TESTDIR1/copy1 \ + >> $seqres.full 2>&1 +echo "md5sums after overwriting copy1:" +_checksum_files + +# success, all done +status=0 +exit diff --git a/tests/generic/110.out b/tests/generic/110.out new file mode 100644 index 0000000..e58b9d8 --- /dev/null +++ b/tests/generic/110.out @@ -0,0 +1,16 @@ +QA output created by 110 +Create the original file and reflink to copy1, copy2 +Original md5sums: +42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-110/original +42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-110/copy1 +42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-110/copy2 +Overwrite original file with new data +md5sums after overwriting original: +4a847a25439532bf48b68c9e9536ed5b TEST_DIR/test-110/original +42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-110/copy1 +42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-110/copy2 +Overwrite copy1 with different new data +md5sums after overwriting copy1: +4a847a25439532bf48b68c9e9536ed5b TEST_DIR/test-110/original +e271cd47d9f62ebc96cb4e67ae4d16db TEST_DIR/test-110/copy1 +42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-110/copy2 diff --git a/tests/generic/111 b/tests/generic/111 new file mode 100755 index 0000000..9da3f40 --- /dev/null +++ b/tests/generic/111 @@ -0,0 +1,109 @@ +#! /bin/bash +# FS QA Test No. 111 +# +# Tests file clone functionality of btrfs ("reflinks") on directory +# trees. +# - Create directory and subdirectory, each having one file +# - Create 2 recursive reflinked copies of the tree +# - Modify the original files +# - Modify one of the copies +# +#----------------------------------------------------------------------- +# Copyright (c) 2014, Oracle and/or its affiliates. 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 +_supported_fs btrfs +_supported_os Linux + +_require_xfs_io_command "fiemap" +_require_cp_reflink +_require_test + +TESTDIR1=$TEST_DIR/test-$seq +rm -rf $TESTDIR1 +mkdir $TESTDIR1 + +_checksum_files() { + for F in original/file1 original/subdir/file2 \ + copy1/file1 copy1/subdir/file2 \ + copy2/file1 copy2/subdir/file2 + do + md5sum $TESTDIR1/$F | _filter_test_dir + done +} + +rm -f $seqres.full + +mkdir $TESTDIR1/original +mkdir $TESTDIR1/original/subdir + +echo "Create the original files and reflink dirs" +$XFS_IO_PROG -f -c 'pwrite -S 0x61 0 9000' $TESTDIR1/original/file1 \ + >> $seqres.full 2>&1 +$XFS_IO_PROG -f -c 'pwrite -S 0x62 0 11000' \ + $TESTDIR1/original/subdir/file2 >> $seqres.full 2>&1 +cp --recursive --reflink $TESTDIR1/original $TESTDIR1/copy1 +cp --recursive --reflink $TESTDIR1/copy1 $TESTDIR1/copy2 + +_verify_reflink $TESTDIR1/original/file1 $TESTDIR1/copy1/file1 +_verify_reflink $TESTDIR1/original/subdir/file2 \ + $TESTDIR1/copy1/subdir/file2 +_verify_reflink $TESTDIR1/original/file1 $TESTDIR1/copy2/file1 +_verify_reflink $TESTDIR1/original/subdir/file2 \ + $TESTDIR1/copy2/subdir/file2 + +echo "Original md5sums:" +_checksum_files + +echo "Overwrite original/file1 and original/subdir/file2 with new data" +$XFS_IO_PROG -c 'pwrite -S 0x63 0 13000' $TESTDIR1/original/file1 \ + >> $seqres.full 2>&1 +$XFS_IO_PROG -c 'pwrite -S 0x64 5000 1000' \ + $TESTDIR1/original/subdir/file2 >> $seqres.full 2>&1 +echo "md5sums now:" +_checksum_files + +echo "Overwrite copy1/file1 and copy1/subdir/file2 with new data" +$XFS_IO_PROG -c 'pwrite -S 0x65 0 9000' $TESTDIR1/copy1/file1 \ + >> $seqres.full 2>&1 +$XFS_IO_PROG -c 'pwrite -S 0x66 5000 25000' \ + $TESTDIR1/copy1/subdir/file2 >> $seqres.full 2>&1 +echo "md5sums now:" +_checksum_files + +# success, all done +status=0 +exit diff --git a/tests/generic/111.out b/tests/generic/111.out new file mode 100644 index 0000000..e410802 --- /dev/null +++ b/tests/generic/111.out @@ -0,0 +1,25 @@ +QA output created by 111 +Create the original files and reflink dirs +Original md5sums: +42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-111/original/file1 +ca390545f0aedb54b808d6128c56a7dd TEST_DIR/test-111/original/subdir/file2 +42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-111/copy1/file1 +ca390545f0aedb54b808d6128c56a7dd TEST_DIR/test-111/copy1/subdir/file2 +42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-111/copy2/file1 +ca390545f0aedb54b808d6128c56a7dd TEST_DIR/test-111/copy2/subdir/file2 +Overwrite original/file1 and original/subdir/file2 with new data +md5sums now: +260f6785c0537fd12582dcae28a3c1a9 TEST_DIR/test-111/original/file1 +b8d91fb600f6f2191f2ba66665374860 TEST_DIR/test-111/original/subdir/file2 +42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-111/copy1/file1 +ca390545f0aedb54b808d6128c56a7dd TEST_DIR/test-111/copy1/subdir/file2 +42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-111/copy2/file1 +ca390545f0aedb54b808d6128c56a7dd TEST_DIR/test-111/copy2/subdir/file2 +Overwrite copy1/file1 and copy1/subdir/file2 with new data +md5sums now: +260f6785c0537fd12582dcae28a3c1a9 TEST_DIR/test-111/original/file1 +b8d91fb600f6f2191f2ba66665374860 TEST_DIR/test-111/original/subdir/file2 +b20229a003e3985c4b0e6806abcd6642 TEST_DIR/test-111/copy1/file1 +b815b24069db14e0a3a07169fd563e93 TEST_DIR/test-111/copy1/subdir/file2 +42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-111/copy2/file1 +ca390545f0aedb54b808d6128c56a7dd TEST_DIR/test-111/copy2/subdir/file2 diff --git a/tests/generic/115 b/tests/generic/115 new file mode 100755 index 0000000..35f0417 --- /dev/null +++ b/tests/generic/115 @@ -0,0 +1,83 @@ +#! /bin/bash +# FS QA Test No. 115 +# +# Moving and deleting cloned ("reflinked") files on btrfs: +# - Create a file and a reflink +# - Move both to a directory +# - Delete the original (moved) file, check that the copy still exists. +# +#----------------------------------------------------------------------- +# Copyright (c) 2014, Oracle and/or its affiliates. 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 +_supported_fs btrfs +_supported_os Linux + +_require_xfs_io_command "fiemap" +_require_cp_reflink +_require_test + +rm -f $seqres.full + +TESTDIR1=$TEST_DIR/test-$seq +rm -rf $TESTDIR1 +mkdir $TESTDIR1 + +echo "Create the original files and reflink dirs" +$XFS_IO_PROG -f -c 'pwrite -S 0x61 0 9000' $TESTDIR1/original \ + >> $seqres.full +cp --reflink $TESTDIR1/original $TESTDIR1/copy + +_verify_reflink $TESTDIR1/original $TESTDIR1/copy + +echo "Move orig & reflink copy to subdir and md5sum:" +mkdir $TESTDIR1/subdir +mv $TESTDIR1/original $TESTDIR1/subdir/original_moved +mv $TESTDIR1/copy $TESTDIR1/subdir/copy_moved +_verify_reflink $TESTDIR1/subdir/original_moved \ + $TESTDIR1/subdir/copy_moved + +md5sum $TESTDIR1/subdir/original_moved | _filter_test_dir +md5sum $TESTDIR1/subdir/copy_moved | _filter_test_dir + +echo "remove orig from subdir and md5sum reflink copy:" +rm $TESTDIR1/subdir/original_moved +md5sum $TESTDIR1/subdir/copy_moved | _filter_test_dir +rm -rf $TESTDIR1/subdir + +# success, all done +status=0 +exit diff --git a/tests/generic/115.out b/tests/generic/115.out new file mode 100644 index 0000000..a532214 --- /dev/null +++ b/tests/generic/115.out @@ -0,0 +1,7 @@ +QA output created by 115 +Create the original files and reflink dirs +Move orig & reflink copy to subdir and md5sum: +42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-115/subdir/original_moved +42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-115/subdir/copy_moved +remove orig from subdir and md5sum reflink copy: +42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-115/subdir/copy_moved diff --git a/tests/generic/group b/tests/generic/group index 1dd4269..aa31c8b 100644 --- a/tests/generic/group +++ b/tests/generic/group @@ -112,9 +112,12 @@ 107 auto quick metadata 108 auto quick rw 109 auto metadata dir +110 auto quick clone +111 auto quick clone 112 rw aio auto quick 113 rw aio auto quick 114 rw aio auto quick +115 auto quick clone 117 attr auto quick 120 other auto quick 123 perms auto quick From darrick.wong@oracle.com Fri Nov 13 15:37:37 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 44A8D7F5A for ; Fri, 13 Nov 2015 15:37:37 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 35EC5304032 for ; Fri, 13 Nov 2015 13:37:37 -0800 (PST) X-ASG-Debug-ID: 1447450654-04cb6c0cd4428b0001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id 2vIBF4vxJdRltIvg (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 13 Nov 2015 13:37:34 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tADLb5Vc018429 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 13 Nov 2015 21:37:05 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id tADLb5PR009868 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Fri, 13 Nov 2015 21:37:05 GMT Received: from abhmp0002.oracle.com (abhmp0002.oracle.com [141.146.116.8]) by userv0121.oracle.com (8.13.8/8.13.8) with ESMTP id tADLb4js028445; Fri, 13 Nov 2015 21:37:04 GMT Received: from localhost (/71.198.20.188) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 13 Nov 2015 13:37:04 -0800 Subject: [PATCH 03/12] reflink: add test support routines to a separate file From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 03/12] reflink: add test support routines to a separate file To: david@fromorbit.com, darrick.wong@oracle.com Cc: fstests@vger.kernel.org, xfs@oss.sgi.com, hch@infradead.org, tao.peng@primarydata.com, linux-ext4@vger.kernel.org, Anna.Schumaker@netapp.com, linux-btrfs@vger.kernel.org Date: Fri, 13 Nov 2015 13:37:03 -0800 Message-ID: <20151113213703.31124.57109.stgit@birch.djwong.org> In-Reply-To: <20151113213643.31124.80975.stgit@birch.djwong.org> References: <20151113213643.31124.80975.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1447450654 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24370 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Put all the reflink/dedupe-related test support routines in a separate file, then modify the existing reflink tests to use them. Signed-off-by: Darrick J. Wong --- common/rc | 51 +++++++++------ common/reflink | 185 +++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/btrfs/029 | 1 tests/btrfs/031 | 1 tests/btrfs/108 | 1 tests/btrfs/109 | 1 tests/generic/110 | 3 + tests/generic/111 | 3 + tests/generic/115 | 3 + 9 files changed, 225 insertions(+), 24 deletions(-) create mode 100644 common/reflink diff --git a/common/rc b/common/rc index adf1edf..4c2f42c 100644 --- a/common/rc +++ b/common/rc @@ -82,6 +82,27 @@ _md5_checksum() md5sum $1 | cut -d ' ' -f1 } +# Write a byte into a range of a file +_pwrite_byte() { + pattern="$1" + offset="$2" + len="$3" + file="$4" + xfs_io_args="$5" + + "$XFS_IO_PROG" $xfs_io_args -f -c "pwrite -S $pattern $offset $len" "$file" +} + +# mmap-write a byte into a range of a file +_mwrite_byte() { + pattern="$1" + offset="$2" + len="$3" + mmap_len="$4" + file="$5" + + "$XFS_IO_PROG" -f -c "mmap -rw 0 $mmap_len" -c "mwrite -S $pattern $offset $len" "$file" +} # ls -l w/ selinux sometimes puts a dot at the end: # -rwxrw-r--. id1 id2 file1 @@ -2569,12 +2590,6 @@ _require_ugid_map() fi } -_require_cp_reflink() -{ - cp --help | grep -q reflink || \ - _notrun "This test requires a cp with --reflink support." -} - _require_fssum() { FSSUM_PROG=$here/src/fssum @@ -2588,21 +2603,6 @@ _require_cloner() _notrun "cloner binary not present at $CLONER_PROG" } -# Given 2 files, verify that they have the same mapping but different -# inodes - i.e. an undisturbed reflink -# Silent if so, make noise if not -_verify_reflink() -{ - # not a hard link or symlink? - cmp -s <(stat -c '%i' $1) <(stat -c '%i' $2) \ - && echo "$1 and $2 are not reflinks: same inode number" - - # same mapping? - diff -u <($XFS_IO_PROG -c "fiemap" $1 | grep -v $1) \ - <($XFS_IO_PROG -c "fiemap" $2 | grep -v $2) \ - || echo "$1 and $2 are not reflinks: different extents" -} - _require_atime() { if [ "$FSTYP" == "nfs" ]; then @@ -2764,6 +2764,15 @@ _require_btrfs_dev_del_by_devid() "(must support 'btrfs device delete /')" } +_require_test_lsattr() +{ + testio=$(lsattr -d $TEST_DIR 2>&1) + echo $testio | grep -q "Operation not supported" && \ + _notrun "lsattr not supported by test filesystem type: $FSTYP" + echo $testio | grep -q "Inappropriate ioctl for device" && \ + _notrun "lsattr not supported by test filesystem type: $FSTYP" +} + _get_total_inode() { if [ -z "$1" ]; then diff --git a/common/reflink b/common/reflink new file mode 100644 index 0000000..eab7f66 --- /dev/null +++ b/common/reflink @@ -0,0 +1,185 @@ +##/bin/bash +# Routines for reflinking, deduping, and comparing parts of files. +#----------------------------------------------------------------------- +# Copyright (c) 2015 Oracle. 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; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +# USA +# +# Contact information: Oracle Corporation, 500 Oracle Parkway, +# Redwood Shores, CA 94065, USA, or: http://www.oracle.com/ +#----------------------------------------------------------------------- + +# Check that cp has a reflink argument +_require_cp_reflink() +{ + cp --help | grep -q reflink || \ + _notrun "This test requires a cp with --reflink support." +} + +# Given 2 files, verify that they have the same mapping but different +# inodes - i.e. an undisturbed reflink +# Silent if so, make noise if not +_verify_reflink() +{ + # not a hard link or symlink? + cmp -s <(stat -c '%i' $1) <(stat -c '%i' $2) \ + && echo "$1 and $2 are not reflinks: same inode number" + + # same mapping? + diff -u <($XFS_IO_PROG -c "fiemap" $1 | grep -v $1) \ + <($XFS_IO_PROG -c "fiemap" $2 | grep -v $2) \ + || echo "$1 and $2 are not reflinks: different extents" +} + +# New reflink/dedupe helpers + +# this test requires the test fs support reflink... +_require_test_reflink() +{ + _require_test + _require_xfs_io_command "reflink" + + rm -rf "$TEST_DIR/file1" "$TEST_DIR/file2" + "$XFS_IO_PROG" -f -c "pwrite -S 0x61 0 65536" "$TEST_DIR/file1" > /dev/null + "$XFS_IO_PROG" -f -c "reflink $TEST_DIR/file1 0 0 65536" "$TEST_DIR/file2" > /dev/null + if [ ! -s "$TEST_DIR/file2" ]; then + rm -rf "$TEST_DIR/file1" "$TEST_DIR/file2" + _notrun "Reflink not supported by test filesystem type: $FSTYP" + fi + rm -rf "$TEST_DIR/file1" "$TEST_DIR/file2" +} + +# this test requires the scratch fs support reflink... +_require_scratch_reflink() +{ + _require_scratch + _require_xfs_io_command "reflink" + + _scratch_mkfs > /dev/null + _scratch_mount + "$XFS_IO_PROG" -f -c "pwrite -S 0x61 0 65536" "$SCRATCH_MNT/file1" > /dev/null + "$XFS_IO_PROG" -f -c "reflink $SCRATCH_MNT/file1 0 0 65536" "$SCRATCH_MNT/file2" > /dev/null + if [ ! -s "$SCRATCH_MNT/file2" ]; then + _scratch_unmount + _notrun "Reflink not supported by scratch filesystem type: $FSTYP" + fi + _scratch_unmount +} + +# this test requires the test fs support dedupe... +_require_test_dedupe() +{ + _require_test + _require_xfs_io_command "dedupe" + + rm -rf "$TEST_DIR/file1" "$TEST_DIR/file2" + "$XFS_IO_PROG" -f -c "pwrite -S 0x61 0 65536" "$TEST_DIR/file1" > /dev/null + "$XFS_IO_PROG" -f -c "pwrite -S 0x61 0 65536" "$TEST_DIR/file2" > /dev/null + testio="$("$XFS_IO_PROG" -f -c "dedupe $TEST_DIR/file1 0 0 65536" "$TEST_DIR/file2" 2>&1)" + echo $testio | grep -q "Operation not supported" && \ + _notrun "Dedupe not supported by test filesystem type: $FSTYP" + echo $testio | grep -q "Inappropriate ioctl for device" && \ + _notrun "Dedupe not supported by test filesystem type: $FSTYP" + rm -rf "$TEST_DIR/file1" "$TEST_DIR/file2" +} + +# this test requires the scratch fs support dedupe... +_require_scratch_dedupe() +{ + _require_scratch + _require_xfs_io_command "dedupe" + + _scratch_mkfs > /dev/null + _scratch_mount + "$XFS_IO_PROG" -f -c "pwrite -S 0x61 0 65536" "$SCRATCH_MNT/file1" > /dev/null + "$XFS_IO_PROG" -f -c "pwrite -S 0x61 0 65536" "$SCRATCH_MNT/file2" > /dev/null + testio="$("$XFS_IO_PROG" -f -c "dedupe $TEST_DIR/file1 0 0 65536" "$TEST_DIR/file2" 2>&1)" + echo $testio | grep -q "Operation not supported" && \ + _notrun "Dedupe not supported by test filesystem type: $FSTYP" + echo $testio | grep -q "Inappropriate ioctl for device" && \ + _notrun "Dedupe not supported by test filesystem type: $FSTYP" + _scratch_unmount +} + +# Prints a range of a file as a hex dump +_read_range() { + file="$1" + offset="$2" + len="$3" + xfs_io_args="$4" + + $XFS_IO_PROG $xfs_io_args -f -c "pread -q -v $offset $len" "$file" | cut -d ' ' -f '3-18' +} + +# Compare ranges of two files +_compare_range() { + file1="$1" + offset1="$2" + file2="$3" + offset2="$4" + len="$5" + + cmp -s <(_read_range "$file1" "$offset1" "$len") \ + <(_read_range "$file2" "$offset2" "$len") +} + +# Prints the md5 checksum of a hexdump of a part of a given file +_md5_range_checksum() { + file="$1" + offset="$2" + len="$3" + + md5sum <(_read_range "$file" "$offset" "$len") | cut -d ' ' -f 1 +} + +# Reflink some file1 into file2 via cp +_cp_reflink() { + file1="$1" + file2="$2" + + cp --reflink=always "$file1" "$file2" +} + +# Reflink some file1 into file2 +_reflink() { + file1="$1" + file2="$2" + + "$XFS_IO_PROG" -f -c "reflink $file1" "$file2" +} + +# Reflink some part of file1 into another part of file2 +_reflink_range() { + file1="$1" + offset1="$2" + file2="$3" + offset2="$4" + len="$5" + xfs_io_args="$6" + + "$XFS_IO_PROG" $xfs_io_args -f -c "reflink $file1 $offset1 $offset2 $len" "$file2" +} + +# Dedupe some part of file1 into another part of file2 +_dedupe_range() { + file1="$1" + offset1="$2" + file2="$3" + offset2="$4" + len="$5" + xfs_io_args="$6" + + "$XFS_IO_PROG" $xfs_io_args -f -c "dedupe $file1 $offset1 $offset2 $len" "$file2" +} diff --git a/tests/btrfs/029 b/tests/btrfs/029 index 0b77b33..175317a 100755 --- a/tests/btrfs/029 +++ b/tests/btrfs/029 @@ -47,6 +47,7 @@ _cleanup() # get standard environment, filters and checks . ./common/rc . ./common/filter +. ./common/reflink # real QA test starts here _supported_fs btrfs diff --git a/tests/btrfs/031 b/tests/btrfs/031 index bcd332c..c5763da 100755 --- a/tests/btrfs/031 +++ b/tests/btrfs/031 @@ -48,6 +48,7 @@ _cleanup() # get standard environment, filters and checks . ./common/rc . ./common/filter +. ./common/reflink # real QA test starts here _supported_fs btrfs diff --git a/tests/btrfs/108 b/tests/btrfs/108 index 5e3a403..18e5b99 100755 --- a/tests/btrfs/108 +++ b/tests/btrfs/108 @@ -41,6 +41,7 @@ _cleanup() # get standard environment, filters and checks . ./common/rc . ./common/filter +. ./common/reflink # real QA test starts here _supported_fs btrfs diff --git a/tests/btrfs/109 b/tests/btrfs/109 index e2aeb73..b86336c 100755 --- a/tests/btrfs/109 +++ b/tests/btrfs/109 @@ -41,6 +41,7 @@ _cleanup() # get standard environment, filters and checks . ./common/rc . ./common/filter +. ./common/reflink # real QA test starts here _supported_fs btrfs diff --git a/tests/generic/110 b/tests/generic/110 index ec74357..468d859 100755 --- a/tests/generic/110 +++ b/tests/generic/110 @@ -43,9 +43,10 @@ _cleanup() # get standard environment, filters and checks . common/rc . common/filter +. common/reflink # real QA test starts here -_supported_fs btrfs +_require_test_reflink _supported_os Linux _require_xfs_io_command "fiemap" diff --git a/tests/generic/111 b/tests/generic/111 index 9da3f40..1797233 100755 --- a/tests/generic/111 +++ b/tests/generic/111 @@ -43,9 +43,10 @@ _cleanup() # get standard environment, filters and checks . common/rc . common/filter +. common/reflink # real QA test starts here -_supported_fs btrfs +_require_test_reflink _supported_os Linux _require_xfs_io_command "fiemap" diff --git a/tests/generic/115 b/tests/generic/115 index 35f0417..b5c64ec 100755 --- a/tests/generic/115 +++ b/tests/generic/115 @@ -41,9 +41,10 @@ _cleanup() # get standard environment, filters and checks . ./common/rc . ./common/filter +. ./common/reflink # real QA test starts here -_supported_fs btrfs +_require_test_reflink _supported_os Linux _require_xfs_io_command "fiemap" From darrick.wong@oracle.com Fri Nov 13 15:37:45 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 B5EA47F7C for ; Fri, 13 Nov 2015 15:37:45 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id A6F0B8F804C for ; Fri, 13 Nov 2015 13:37:45 -0800 (PST) X-ASG-Debug-ID: 1447450660-04cbb0605d47e50001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id 4muQNeN2ljJAe89D (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 13 Nov 2015 13:37:40 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tADLbCRr032698 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 13 Nov 2015 21:37:12 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id tADLbCUI025676 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Fri, 13 Nov 2015 21:37:12 GMT Received: from abhmp0006.oracle.com (abhmp0006.oracle.com [141.146.116.12]) by userv0121.oracle.com (8.13.8/8.13.8) with ESMTP id tADLbBAr028558; Fri, 13 Nov 2015 21:37:11 GMT Received: from localhost (/71.198.20.188) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 13 Nov 2015 13:37:10 -0800 Subject: [PATCH 04/12] reflink: basic tests of the reflink and dedupe ioctls From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 04/12] reflink: basic tests of the reflink and dedupe ioctls To: david@fromorbit.com, darrick.wong@oracle.com Cc: fstests@vger.kernel.org, xfs@oss.sgi.com, hch@infradead.org, tao.peng@primarydata.com, linux-ext4@vger.kernel.org, Anna.Schumaker@netapp.com, linux-btrfs@vger.kernel.org Date: Fri, 13 Nov 2015 13:37:09 -0800 Message-ID: <20151113213709.31124.35294.stgit@birch.djwong.org> In-Reply-To: <20151113213643.31124.80975.stgit@birch.djwong.org> References: <20151113213643.31124.80975.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1447450660 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24370 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Test the operation of the btrfs (and now xfs) reflink and dedupe ioctls at various file offsets and with matching and nonmatching files. Signed-off-by: Darrick J. Wong --- tests/generic/116 | 92 +++++++++++++++++++++++++++ tests/generic/116.out | 8 ++ tests/generic/118 | 93 +++++++++++++++++++++++++++ tests/generic/118.out | 11 +++ tests/generic/119 | 170 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/119.out | 30 +++++++++ tests/generic/121 | 92 +++++++++++++++++++++++++++ tests/generic/121.out | 8 ++ tests/generic/122 | 92 +++++++++++++++++++++++++++ tests/generic/122.out | 12 +++ tests/generic/134 | 128 +++++++++++++++++++++++++++++++++++++ tests/generic/134.out | 16 +++++ tests/generic/136 | 128 +++++++++++++++++++++++++++++++++++++ tests/generic/136.out | 17 +++++ tests/generic/137 | 131 ++++++++++++++++++++++++++++++++++++++ tests/generic/137.out | 8 ++ tests/generic/group | 8 ++ 17 files changed, 1044 insertions(+) create mode 100755 tests/generic/116 create mode 100644 tests/generic/116.out create mode 100755 tests/generic/118 create mode 100644 tests/generic/118.out create mode 100755 tests/generic/119 create mode 100644 tests/generic/119.out create mode 100755 tests/generic/121 create mode 100644 tests/generic/121.out create mode 100755 tests/generic/122 create mode 100644 tests/generic/122.out create mode 100755 tests/generic/134 create mode 100644 tests/generic/134.out create mode 100755 tests/generic/136 create mode 100644 tests/generic/136.out create mode 100755 tests/generic/137 create mode 100644 tests/generic/137.out diff --git a/tests/generic/116 b/tests/generic/116 new file mode 100755 index 0000000..2b4b505 --- /dev/null +++ b/tests/generic/116 @@ -0,0 +1,92 @@ +#! /bin/bash +# FS QA Test No. 116 +# +# Ensure that we can reflink parts of two identical files: +# - Reflink identical parts of two identical files +# - Check that we still have identical contents +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_reflink + +rm -f "$seqres.full" + +TESTDIR="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original files" +BLKSZ=65536 +_pwrite_byte 0x61 $((BLKSZ * 2)) $((BLKSZ * 6)) "$TESTDIR/file1" >> "$seqres.full" +_pwrite_byte 0x61 $((BLKSZ * 2)) $((BLKSZ * 6)) "$TESTDIR/file2" >> "$seqres.full" +_test_remount + +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir + +_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file2" 0 $((BLKSZ * 8)) \ + || echo "Files do not match" + +echo "Reflink the middle blocks together" +free_before="$(stat -f -c '%a' "$TESTDIR")" +_reflink_range "$TESTDIR/file1" $((BLKSZ * 4)) "$TESTDIR/file2" \ + $((BLKSZ * 4)) $((BLKSZ * 2)) >> "$seqres.full" +_test_remount +free_after="$(stat -f -c '%a' "$TESTDIR")" +echo "freesp changed by $free_before -> $free_after" >> "$seqres.full" + +echo "Compare sections" +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir + +_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file2" 0 $((BLKSZ * 4)) \ + || echo "Start sections do not match" + +_compare_range "$TESTDIR/file1" $((BLKSZ * 4)) "$TESTDIR/file2" \ + $((BLKSZ * 4)) $((BLKSZ * 2)) \ + || echo "Middle sections do not match" + +_compare_range "$TESTDIR/file1" $((BLKSZ * 6)) "$TESTDIR/file2" \ + $((BLKSZ * 6)) $((BLKSZ * 2)) \ + || echo "End sections do not match" + +# success, all done +status=0 +exit diff --git a/tests/generic/116.out b/tests/generic/116.out new file mode 100644 index 0000000..5adfc62 --- /dev/null +++ b/tests/generic/116.out @@ -0,0 +1,8 @@ +QA output created by 116 +Create the original files +35ac8d7917305c385c30f3d82c30a8f6 TEST_DIR/test-116/file1 +35ac8d7917305c385c30f3d82c30a8f6 TEST_DIR/test-116/file2 +Reflink the middle blocks together +Compare sections +35ac8d7917305c385c30f3d82c30a8f6 TEST_DIR/test-116/file1 +35ac8d7917305c385c30f3d82c30a8f6 TEST_DIR/test-116/file2 diff --git a/tests/generic/118 b/tests/generic/118 new file mode 100755 index 0000000..651b72c --- /dev/null +++ b/tests/generic/118 @@ -0,0 +1,93 @@ +#! /bin/bash +# FS QA Test No. 118 +# +# Ensuring that we can reflink non-matching parts of files: +# - Reflink identical ranges of two different files +# - Check that the non-linked ranges still do not match +# - Check that we end up with identical contents in the linked ranges +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_reflink + +rm -f "$seqres.full" + +TESTDIR="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original files" +BLKSZ=65536 +_pwrite_byte 0x61 $((BLKSZ * 2)) $((BLKSZ * 6)) "$TESTDIR/file1" >> "$seqres.full" +_pwrite_byte 0x62 $((BLKSZ * 2)) $((BLKSZ * 6)) "$TESTDIR/file2" >> "$seqres.full" +_test_remount + +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir + +_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file2" 0 $((BLKSZ * 8)) \ + || echo "Files do not match (intentional)" + +echo "Reflink the middle blocks together" +free_before="$(stat -f -c '%a' "$TESTDIR")" +_reflink_range "$TESTDIR/file1" $((BLKSZ * 4)) "$TESTDIR/file2" \ + $((BLKSZ * 4)) $((BLKSZ * 2)) >> "$seqres.full" +_test_remount +free_after="$(stat -f -c '%a' "$TESTDIR")" +echo "freesp changed by $free_before -> $free_after" >> "$seqres.full" + +echo "Compare sections" +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir + +_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file2" 0 $((BLKSZ * 4)) \ + || echo "Start sections do not match (intentional)" + +_compare_range "$TESTDIR/file1" $((BLKSZ * 4)) "$TESTDIR/file2" \ + $((BLKSZ * 4)) $((BLKSZ * 2)) \ + || echo "Middle sections do not match" + +_compare_range "$TESTDIR/file1" $((BLKSZ * 6)) "$TESTDIR/file2" \ + $((BLKSZ * 6)) $((BLKSZ * 2)) \ + || echo "End sections do not match (intentional)" + +# success, all done +status=0 +exit diff --git a/tests/generic/118.out b/tests/generic/118.out new file mode 100644 index 0000000..8fdaf59 --- /dev/null +++ b/tests/generic/118.out @@ -0,0 +1,11 @@ +QA output created by 118 +Create the original files +35ac8d7917305c385c30f3d82c30a8f6 TEST_DIR/test-118/file1 +5e3501f97fd2669babfcbd3e1972e833 TEST_DIR/test-118/file2 +Files do not match (intentional) +Reflink the middle blocks together +Compare sections +35ac8d7917305c385c30f3d82c30a8f6 TEST_DIR/test-118/file1 +f7f9e44d37909868014e9151f5293ab0 TEST_DIR/test-118/file2 +Start sections do not match (intentional) +End sections do not match (intentional) diff --git a/tests/generic/119 b/tests/generic/119 new file mode 100755 index 0000000..9d57379 --- /dev/null +++ b/tests/generic/119 @@ -0,0 +1,170 @@ +#! /bin/bash +# FS QA Test No. 119 +# +# Reflinking two sets of files together: +# - Reflink identical parts of two identical files +# - Reflink identical parts of two other identical files +# - Reflink identical parts of all four files +# - Check that we end up with identical contents +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_reflink + +rm -f "$seqres.full" + +TESTDIR=$TEST_DIR/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR + +echo "Create the original files" +BLKSZ=65536 +_pwrite_byte 0x61 0 $((BLKSZ * 8)) "$TESTDIR/file1" >> "$seqres.full" +_pwrite_byte 0x62 0 $((BLKSZ * 8)) "$TESTDIR/file2" >> "$seqres.full" +_pwrite_byte 0x63 0 $((BLKSZ * 8)) "$TESTDIR/file3" >> "$seqres.full" +_pwrite_byte 0x64 0 $((BLKSZ * 8)) "$TESTDIR/file4" >> "$seqres.full" +_test_remount + +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir +md5sum "$TESTDIR/file4" | _filter_test_dir + +_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file2" 0 $((BLKSZ * 8)) \ + || echo "Files 1-2 do not match (intentional)" + +_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file3" 0 $((BLKSZ * 8)) \ + || echo "Files 1-3 do not match (intentional)" + +_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file4" 0 $((BLKSZ * 8)) \ + || echo "Files 1-4 do not match (intentional)" + +echo "Reflink the first four blocks together, 1-2 3-4" +free_before="$(stat -f -c '%a' "$TESTDIR")" +_reflink_range "$TESTDIR/file1" 0 "$TESTDIR/file2" 0 $((BLKSZ * 4)) >> "$seqres.full" +_reflink_range "$TESTDIR/file3" 0 "$TESTDIR/file4" 0 $((BLKSZ * 4)) >> "$seqres.full" +_test_remount +free_after="$(stat -f -c '%a' "$TESTDIR")" +echo "freesp changed by $free_before -> $free_after" >> "$seqres.full" + +echo "Compare sections" +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir +md5sum "$TESTDIR/file4" | _filter_test_dir + +_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file2" 0 $((BLKSZ * 4)) \ + || echo "Sections of file 1-2 do not match" + +_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file3" 0 $((BLKSZ * 4)) \ + || echo "Sections of file 1-3 do not match (intentional)" + +_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file4" 0 $((BLKSZ * 4)) \ + || echo "Sections of file 1-4 do not match (intentional)" + +_compare_range "$TESTDIR/file2" 0 "$TESTDIR/file3" 0 $((BLKSZ * 4)) \ + || echo "Sections of file 2-3 do not match (intentional)" + +_compare_range "$TESTDIR/file2" 0 "$TESTDIR/file4" 0 $((BLKSZ * 4)) \ + || echo "Sections of file 2-4 do not match (intentional)" + +_compare_range "$TESTDIR/file3" 0 "$TESTDIR/file4" 0 $((BLKSZ * 4)) \ + || echo "Sections of file 3-4 do not match" + +echo "Reflink the first two blocks together, 1-3 1-4" +free_before="$(stat -f -c '%a' $TESTDIR)" +_reflink_range "$TESTDIR/file1" 0 "$TESTDIR/file3" 0 $((BLKSZ * 2)) >> "$seqres.full" +_reflink_range "$TESTDIR/file1" 0 "$TESTDIR/file4" 0 $((BLKSZ * 2)) >> "$seqres.full" +_test_remount +free_after="$(stat -f -c '%a' $TESTDIR)" +echo "freesp changed by $free_before -> $free_after" >> "$seqres.full" + +echo "Compare sections" +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir +md5sum "$TESTDIR/file4" | _filter_test_dir + +_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file2" 0 $((BLKSZ * 2)) \ + || echo "Sections of files 1-2 do not match" + +_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file3" 0 $((BLKSZ * 2)) \ + || echo "Sections of files 1-3 do not match" + +_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file4" 0 $((BLKSZ * 2)) \ + || echo "Sections of files 1-4 do not match" + +_compare_range "$TESTDIR/file2" 0 "$TESTDIR/file3" 0 $((BLKSZ * 2)) \ + || echo "Sections of files 2-3 do not match" + +_compare_range "$TESTDIR/file2" 0 "$TESTDIR/file4" 0 $((BLKSZ * 2)) \ + || echo "Sections of files 2-4 do not match" + +_compare_range "$TESTDIR/file3" 0 "$TESTDIR/file4" 0 $((BLKSZ * 2)) \ + || echo "Sections of files 3-4 do not match" + +echo "Compare previously reflinked sections" +_compare_range "$TESTDIR/file1" $((BLKSZ * 2)) "$TESTDIR/file2" \ + $((BLKSZ * 2)) $((BLKSZ * 2)) \ + || echo "Sections of file 1-2 do not match" + +_compare_range "$TESTDIR/file1" $((BLKSZ * 2)) "$TESTDIR/file3" \ + $((BLKSZ * 2)) $((BLKSZ * 2)) \ + || echo "Sections of file 1-3 do not match (intentional)" + +_compare_range "$TESTDIR/file1" $((BLKSZ * 2)) "$TESTDIR/file4" \ + $((BLKSZ * 2)) $((BLKSZ * 2)) \ + || echo "Sections of file 1-4 do not match (intentional)" + +_compare_range "$TESTDIR/file2" $((BLKSZ * 2)) "$TESTDIR/file3" \ + $((BLKSZ * 2)) $((BLKSZ * 2)) \ + || echo "Sections of file 2-3 do not match (intentional)" + +_compare_range "$TESTDIR/file2" $((BLKSZ * 2)) "$TESTDIR/file4" \ + $((BLKSZ * 2)) $((BLKSZ * 2)) \ + || echo "Sections of file 2-4 do not match (intentional)" + +_compare_range "$TESTDIR/file3" $((BLKSZ * 2)) "$TESTDIR/file4" \ + $((BLKSZ * 2)) $((BLKSZ * 2)) \ + || echo "Sections of file 3-4 do not match" + +# success, all done +status=0 +exit diff --git a/tests/generic/119.out b/tests/generic/119.out new file mode 100644 index 0000000..85893d5 --- /dev/null +++ b/tests/generic/119.out @@ -0,0 +1,30 @@ +QA output created by 119 +Create the original files +30c2557e8302a5beb290c71520d87f42 TEST_DIR/test-119/file1 +efb787f7990e43c7dc30565d8cc344d4 TEST_DIR/test-119/file2 +c83f38d4622a78b74e3480634194b08f TEST_DIR/test-119/file3 +1c11fd3151d2229f5cf43903386aa432 TEST_DIR/test-119/file4 +Files 1-2 do not match (intentional) +Files 1-3 do not match (intentional) +Files 1-4 do not match (intentional) +Reflink the first four blocks together, 1-2 3-4 +Compare sections +30c2557e8302a5beb290c71520d87f42 TEST_DIR/test-119/file1 +63bdb182cdf03a8a19e83234d869d00a TEST_DIR/test-119/file2 +c83f38d4622a78b74e3480634194b08f TEST_DIR/test-119/file3 +dc2ae3db14e97fad93faf939170b085c TEST_DIR/test-119/file4 +Sections of file 1-3 do not match (intentional) +Sections of file 1-4 do not match (intentional) +Sections of file 2-3 do not match (intentional) +Sections of file 2-4 do not match (intentional) +Reflink the first two blocks together, 1-3 1-4 +Compare sections +30c2557e8302a5beb290c71520d87f42 TEST_DIR/test-119/file1 +63bdb182cdf03a8a19e83234d869d00a TEST_DIR/test-119/file2 +89a444ff9d6af60ba487e9a0ca2161e2 TEST_DIR/test-119/file3 +0c263058794a54c5e197ece52386f5be TEST_DIR/test-119/file4 +Compare previously reflinked sections +Sections of file 1-3 do not match (intentional) +Sections of file 1-4 do not match (intentional) +Sections of file 2-3 do not match (intentional) +Sections of file 2-4 do not match (intentional) diff --git a/tests/generic/121 b/tests/generic/121 new file mode 100755 index 0000000..9a5b383 --- /dev/null +++ b/tests/generic/121 @@ -0,0 +1,92 @@ +#! /bin/bash +# FS QA Test No. 121 +# +# Ensure that we can dedupe parts of two files: +# - Dedupe identical parts of two identical files +# - Check that still have identical contents +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_dedupe + +rm -f "$seqres.full" + +TESTDIR="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original files" +BLKSZ=65536 +_pwrite_byte 0x61 $((BLKSZ * 2)) $((BLKSZ * 6)) "$TESTDIR/file1" >> "$seqres.full" +_pwrite_byte 0x61 $((BLKSZ * 2)) $((BLKSZ * 6)) "$TESTDIR/file2" >> "$seqres.full" +_test_remount + +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir + +_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file2" 0 $((BLKSZ * 8)) \ + || echo "Files 1-2 do not match (intentional)" + +echo "Dedupe the middle blocks together" +free_before="$(stat -f -c '%a' "$TESTDIR")" +_dedupe_range "$TESTDIR/file1" $((BLKSZ * 4)) "$TESTDIR/file2" \ + $((BLKSZ * 4)) $((BLKSZ * 2)) >> "$seqres.full" +_test_remount +free_after="$(stat -f -c '%a' "$TESTDIR")" +echo "freesp changed by $free_before -> $free_after" >> "$seqres.full" + +echo "Compare sections" +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir + +_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file2" 0 $((BLKSZ * 4)) \ + || echo "Start sections do not match" + +_compare_range "$TESTDIR/file1" $((BLKSZ * 4)) "$TESTDIR/file2" \ + $((BLKSZ * 4)) $((BLKSZ * 2)) \ + || echo "Middle sections do not match" + +_compare_range "$TESTDIR/file1" $((BLKSZ * 6)) "$TESTDIR/file2" \ + $((BLKSZ * 6)) $((BLKSZ * 2)) \ + || echo "End sections do not match" + +# success, all done +status=0 +exit diff --git a/tests/generic/121.out b/tests/generic/121.out new file mode 100644 index 0000000..d865c7e --- /dev/null +++ b/tests/generic/121.out @@ -0,0 +1,8 @@ +QA output created by 121 +Create the original files +35ac8d7917305c385c30f3d82c30a8f6 TEST_DIR/test-121/file1 +35ac8d7917305c385c30f3d82c30a8f6 TEST_DIR/test-121/file2 +Dedupe the middle blocks together +Compare sections +35ac8d7917305c385c30f3d82c30a8f6 TEST_DIR/test-121/file1 +35ac8d7917305c385c30f3d82c30a8f6 TEST_DIR/test-121/file2 diff --git a/tests/generic/122 b/tests/generic/122 new file mode 100755 index 0000000..0edb48d --- /dev/null +++ b/tests/generic/122 @@ -0,0 +1,92 @@ +#! /bin/bash +# FS QA Test No. 122 +# +# Ensuring that we cannot dedupe non-matching parts of files: +# - Fail to dedupe non-identical parts of two different files +# - Check that nothing changes in either file +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_dedupe + +rm -f "$seqres.full" + +TESTDIR="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original files" +BLKSZ=65536 +_pwrite_byte 0x61 $((BLKSZ * 2)) $((BLKSZ * 6)) "$TESTDIR/file1" >> "$seqres.full" +_pwrite_byte 0x62 $((BLKSZ * 2)) $((BLKSZ * 6)) "$TESTDIR/file2" >> "$seqres.full" +_test_remount + +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir + +_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file2" 0 "$((BLKSZ * 8))" \ + || echo "Files 1-2 do not match (intentional)" + +echo "(Fail to) dedupe the middle blocks together" +free_before="$(stat -f -c '%a' "$TESTDIR")" +_dedupe_range "$TESTDIR/file1" $((BLKSZ * 4)) "$TESTDIR/file2" \ + $((BLKSZ * 4)) $((BLKSZ * 2)) >> "$seqres.full" +_test_remount +free_after="$(stat -f -c '%a' "$TESTDIR")" +echo "freesp changed by $free_before -> $free_after" >> "$seqres.full" + +echo "Compare sections" +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir + +_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file2" 0 $((BLKSZ * 4)) \ + || echo "Start sections do not match (intentional)" + +_compare_range "$TESTDIR/file1" $((BLKSZ * 4)) "$TESTDIR/file2" \ + $((BLKSZ * 4)) $((BLKSZ * 2)) \ + || echo "Middle sections do not match (intentional)" + +_compare_range "$TESTDIR/file1" $((BLKSZ * 6)) "$TESTDIR/file2" \ + $((BLKSZ * 6)) $((BLKSZ * 2)) \ + || echo "End sections do not match (intentional)" + +# success, all done +status=0 +exit diff --git a/tests/generic/122.out b/tests/generic/122.out new file mode 100644 index 0000000..c7cfec2 --- /dev/null +++ b/tests/generic/122.out @@ -0,0 +1,12 @@ +QA output created by 122 +Create the original files +35ac8d7917305c385c30f3d82c30a8f6 TEST_DIR/test-122/file1 +5e3501f97fd2669babfcbd3e1972e833 TEST_DIR/test-122/file2 +Files 1-2 do not match (intentional) +(Fail to) dedupe the middle blocks together +Compare sections +35ac8d7917305c385c30f3d82c30a8f6 TEST_DIR/test-122/file1 +5e3501f97fd2669babfcbd3e1972e833 TEST_DIR/test-122/file2 +Start sections do not match (intentional) +Middle sections do not match (intentional) +End sections do not match (intentional) diff --git a/tests/generic/134 b/tests/generic/134 new file mode 100755 index 0000000..4dc710c --- /dev/null +++ b/tests/generic/134 @@ -0,0 +1,128 @@ +#! /bin/bash +# FS QA Test No. 134 +# +# Ensure that we can reflink the last block of a file whose size isn't +# block-aligned. +# - Create two 'a' files file whose size isn't block-aligned. +# - Create two 'b' files file whose size isn't block-aligned. +# - Reflink the last block of file1 to the last block in file2 and file3. +# - Check that files 1-2 match, 3-4 don't match, and that nothing matches 3. +# - Check that the ends of 1-3 match, and 1-3 do not match the end of file4. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_reflink + +rm -f "$seqres.full" + +TESTDIR="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original files" +BLKSZ=65536 +_pwrite_byte 0x61 0 $((BLKSZ + 37)) "$TESTDIR/file1" >> "$seqres.full" +_pwrite_byte 0x61 0 $((BLKSZ + 37)) "$TESTDIR/file2" >> "$seqres.full" +_pwrite_byte 0x62 0 $((BLKSZ + 37)) "$TESTDIR/file3" >> "$seqres.full" +_pwrite_byte 0x62 0 $((BLKSZ + 37)) "$TESTDIR/file4" >> "$seqres.full" +_test_remount + +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir +md5sum "$TESTDIR/file4" | _filter_test_dir + +C1="$(_md5_checksum $TESTDIR/file1)" +C2="$(_md5_checksum $TESTDIR/file2)" +C3="$(_md5_checksum $TESTDIR/file3)" +C4="$(_md5_checksum $TESTDIR/file4)" + +test "${C1}" = "${C2}" || echo "file1 and file2 should match" +test "${C1}" != "${C3}" || echo "file1 and file3 should not match" +test "${C1}" != "${C4}" || echo "file1 and file4 should not match" +test "${C2}" != "${C3}" || echo "file2 and file3 should not match" +test "${C2}" != "${C4}" || echo "file2 and file4 should not match" +test "${C3}" = "${C4}" || echo "file3 and file4 should match" + +echo "Reflink the last blocks together, 1-2 1-3" +_reflink_range "$TESTDIR/file1" $BLKSZ "$TESTDIR/file2" $BLKSZ 37 >> "$seqres.full" +_reflink_range "$TESTDIR/file1" $BLKSZ "$TESTDIR/file3" $BLKSZ 37 >> "$seqres.full" +_test_remount + +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir +md5sum "$TESTDIR/file4" | _filter_test_dir + +C1="$(_md5_checksum $TESTDIR/file1)" +C2="$(_md5_checksum $TESTDIR/file2)" +C3="$(_md5_checksum $TESTDIR/file3)" +C4="$(_md5_checksum $TESTDIR/file4)" + +echo "Compare files" +test "${C1}" = "${C2}" || echo "file1 and file2 should match" +test "${C1}" != "${C3}" || echo "file1 and file3 should not match" +test "${C1}" != "${C4}" || echo "file1 and file4 should not match" +test "${C2}" != "${C3}" || echo "file2 and file3 should not match" +test "${C2}" != "${C4}" || echo "file2 and file4 should not match" +test "${C3}" != "${C4}" || echo "file3 and file4 should match" + +echo "Compare sections" +_compare_range "$TESTDIR/file1" $BLKSZ "$TESTDIR/file2" $BLKSZ 37 \ + || echo "End sections of files 1-2 do not match" + +_compare_range "$TESTDIR/file1" $BLKSZ "$TESTDIR/file3" $BLKSZ 37 \ + || echo "End sections of files 1-3 do not match" + +_compare_range "$TESTDIR/file1" $BLKSZ "$TESTDIR/file4" $BLKSZ 37 \ + || echo "End sections of files 1-4 do not match (intentional)" + +_compare_range "$TESTDIR/file2" $BLKSZ "$TESTDIR/file3" $BLKSZ 37 \ + || echo "End sections of files 2-3 do not match" + +_compare_range "$TESTDIR/file2" $BLKSZ "$TESTDIR/file4" $BLKSZ 37 \ + || echo "End sections of files 2-4 do not match (intentional)" + +_compare_range "$TESTDIR/file3" $BLKSZ "$TESTDIR/file4" $BLKSZ 37 \ + || echo "End sections of files 3-4 do not match (intentional)" + +# success, all done +status=0 +exit diff --git a/tests/generic/134.out b/tests/generic/134.out new file mode 100644 index 0000000..b5e0f43 --- /dev/null +++ b/tests/generic/134.out @@ -0,0 +1,16 @@ +QA output created by 134 +Create the original files +c4fd505be25a0c91bcca9f502b9a8156 TEST_DIR/test-134/file1 +c4fd505be25a0c91bcca9f502b9a8156 TEST_DIR/test-134/file2 +07ac67bf7f271195442509e79cde4cee TEST_DIR/test-134/file3 +07ac67bf7f271195442509e79cde4cee TEST_DIR/test-134/file4 +Reflink the last blocks together, 1-2 1-3 +c4fd505be25a0c91bcca9f502b9a8156 TEST_DIR/test-134/file1 +c4fd505be25a0c91bcca9f502b9a8156 TEST_DIR/test-134/file2 +e236f2fe789f0aa34b50e981a2f0243a TEST_DIR/test-134/file3 +07ac67bf7f271195442509e79cde4cee TEST_DIR/test-134/file4 +Compare files +Compare sections +End sections of files 1-4 do not match (intentional) +End sections of files 2-4 do not match (intentional) +End sections of files 3-4 do not match (intentional) diff --git a/tests/generic/136 b/tests/generic/136 new file mode 100755 index 0000000..89ee751 --- /dev/null +++ b/tests/generic/136 @@ -0,0 +1,128 @@ +#! /bin/bash +# FS QA Test No. 136 +# +# Ensure that we can dedupe the last block of a file whose size isn't +# block-aligned. +# - Create two 'a' files file whose size isn't block-aligned. +# - Create two 'b' files file whose size isn't block-aligned. +# - Dedupe the last block of file1 to the last block in file2 and file3. +# - Check that files 1-2 match, and that 3-4 match. +# - Check that the ends of 1-2 and 3-4 match, and that 1-3 don't match. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_dedupe + +rm -f "$seqres.full" + +TESTDIR="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original files" +BLKSZ=65536 +_pwrite_byte 0x61 0 $((BLKSZ + 37)) "$TESTDIR/file1" >> "$seqres.full" +_pwrite_byte 0x61 0 $((BLKSZ + 37)) "$TESTDIR/file2" >> "$seqres.full" +_pwrite_byte 0x62 0 $((BLKSZ + 37)) "$TESTDIR/file3" >> "$seqres.full" +_pwrite_byte 0x62 0 $((BLKSZ + 37)) "$TESTDIR/file4" >> "$seqres.full" +_test_remount + +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir +md5sum "$TESTDIR/file4" | _filter_test_dir + +C1="$(_md5_checksum $TESTDIR/file1)" +C2="$(_md5_checksum $TESTDIR/file2)" +C3="$(_md5_checksum $TESTDIR/file3)" +C4="$(_md5_checksum $TESTDIR/file4)" + +test "${C1}" = "${C2}" || echo "file1 and file2 should match" +test "${C1}" != "${C3}" || echo "file1 and file3 should not match" +test "${C1}" != "${C4}" || echo "file1 and file4 should not match" +test "${C2}" != "${C3}" || echo "file2 and file3 should not match" +test "${C2}" != "${C4}" || echo "file2 and file4 should not match" +test "${C3}" = "${C4}" || echo "file3 and file4 should match" + +echo "Dedupe the last blocks together" +_dedupe_range "$TESTDIR/file1" $BLKSZ "$TESTDIR/file2" $BLKSZ 37 >> "$seqres.full" +_dedupe_range "$TESTDIR/file1" $BLKSZ "$TESTDIR/file3" $BLKSZ 37 >> "$seqres.full" +_test_remount + +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir +md5sum "$TESTDIR/file4" | _filter_test_dir + +C1="$(_md5_checksum $TESTDIR/file1)" +C2="$(_md5_checksum $TESTDIR/file2)" +C3="$(_md5_checksum $TESTDIR/file3)" +C4="$(_md5_checksum $TESTDIR/file4)" + +echo "Compare files" +test "${C1}" = "${C2}" || echo "file1 and file2 should match" +test "${C1}" != "${C3}" || echo "file1 and file3 should not match" +test "${C1}" != "${C4}" || echo "file1 and file4 should not match" +test "${C2}" != "${C3}" || echo "file2 and file3 should not match" +test "${C2}" != "${C4}" || echo "file2 and file4 should not match" +test "${C3}" = "${C4}" || echo "file3 and file4 should match" + +echo "Compare sections" +_compare_range "$TESTDIR/file1" $BLKSZ "$TESTDIR/file2" $BLKSZ 37 \ + || echo "End sections of files 1-2 do not match" + +_compare_range "$TESTDIR/file1" $BLKSZ "$TESTDIR/file3" $BLKSZ 37 \ + || echo "End sections of files 1-3 do not match (intentional)" + +_compare_range "$TESTDIR/file1" $BLKSZ "$TESTDIR/file4" $BLKSZ 37 \ + || echo "End sections of files 1-4 do not match (intentional)" + +_compare_range "$TESTDIR/file2" $BLKSZ "$TESTDIR/file3" $BLKSZ 37 \ + || echo "End sections of files 2-3 do not match (intentional)" + +_compare_range "$TESTDIR/file2" $BLKSZ "$TESTDIR/file4" $BLKSZ 37 \ + || echo "End sections of files 2-4 do not match (intentional)" + +_compare_range "$TESTDIR/file3" $BLKSZ "$TESTDIR/file4" $BLKSZ 37 \ + || echo "End sections of files 3-4 do not match" + +# success, all done +status=0 +exit diff --git a/tests/generic/136.out b/tests/generic/136.out new file mode 100644 index 0000000..99a5465 --- /dev/null +++ b/tests/generic/136.out @@ -0,0 +1,17 @@ +QA output created by 136 +Create the original files +c4fd505be25a0c91bcca9f502b9a8156 TEST_DIR/test-136/file1 +c4fd505be25a0c91bcca9f502b9a8156 TEST_DIR/test-136/file2 +07ac67bf7f271195442509e79cde4cee TEST_DIR/test-136/file3 +07ac67bf7f271195442509e79cde4cee TEST_DIR/test-136/file4 +Dedupe the last blocks together +c4fd505be25a0c91bcca9f502b9a8156 TEST_DIR/test-136/file1 +c4fd505be25a0c91bcca9f502b9a8156 TEST_DIR/test-136/file2 +07ac67bf7f271195442509e79cde4cee TEST_DIR/test-136/file3 +07ac67bf7f271195442509e79cde4cee TEST_DIR/test-136/file4 +Compare files +Compare sections +End sections of files 1-3 do not match (intentional) +End sections of files 1-4 do not match (intentional) +End sections of files 2-3 do not match (intentional) +End sections of files 2-4 do not match (intentional) diff --git a/tests/generic/137 b/tests/generic/137 new file mode 100755 index 0000000..a640f4f --- /dev/null +++ b/tests/generic/137 @@ -0,0 +1,131 @@ +#! /bin/bash +# FS QA Test No. 137 +# +# Ensure that we can reflink and dedupe blocks within the same file... +# - Create a file with three distinct blocks ABB +# - Reflink block zero to the multiple-of-three blocks +# - Reflink block one to the multiple-of-five blocks +# - Dedupe block two to the multiple-of-seven blocks +# - Check that we successfully avoid deduping with holes, unwritten +# extents, and non-matches; but actually dedupe real matches. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_reflink +_require_test_dedupe +_require_xfs_io_command "falloc" + +rm -f "$seqres.full" + +TESTDIR="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original file blocks" +BLKSZ=65536 +_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file1" >> "$seqres.full" +_pwrite_byte 0x62 $BLKSZ $((BLKSZ * 2)) "$TESTDIR/file1" >> "$seqres.full" + +NR_BLKS=1024 + +echo "fallocate half the file" +"$XFS_IO_PROG" -f -c "falloc $((NR_BLKS * BLKSZ / 2)) $((NR_BLKS * BLKSZ / 2))" "$TESTDIR/file1" >> "$seqres.full" + +echo "Reflink block zero to the threes" +seq 1 $((NR_BLKS / 3)) | while read nr; do + _reflink_range "$TESTDIR/file1" 0 "$TESTDIR/file1" $((nr * 3 * BLKSZ)) \ + $BLKSZ >> "$seqres.full" +done + +echo "Reflink block one to the fives" +seq 1 $((NR_BLKS / 5)) | while read nr; do + _reflink_range "$TESTDIR/file1" $BLKSZ "$TESTDIR/file1" \ + $((nr * 5 * BLKSZ)) $BLKSZ >> "$seqres.full" +done + +echo "Dedupe block two to the sevens" +seq 1 $((NR_BLKS / 7)) | while read nr; do + _dedupe_range "$TESTDIR/file1" $((BLKSZ * 2)) "$TESTDIR/file1" \ + $((nr * 7 * BLKSZ)) $BLKSZ >> "$seqres.full" +done + +_test_remount + +echo "Check block mappings" +md5sum "$TESTDIR/file1" | _filter_test_dir + +crcZ=$(_md5_range_checksum /dev/zero 0 $BLKSZ) +crc0=$(_md5_range_checksum "$TESTDIR/file1" 0 $BLKSZ) +crc1=$(_md5_range_checksum "$TESTDIR/file1" $BLKSZ $BLKSZ) +crc2=$(_md5_range_checksum "$TESTDIR/file1" $((BLKSZ * 2)) $BLKSZ) + +check_block() { + lblk="$1" + rem7=$((lblk % 7)) + rem5=$((lblk % 5)) + rem3=$((lblk % 3)) + + crc=$(_md5_range_checksum "$TESTDIR/file1" $((lblk * BLKSZ)) $BLKSZ) + + if [ $rem7 -eq 0 ]; then + if [ $rem5 -eq 0 ]; then + test $crc2 = $crc || echo "lblk $lblk doesn't match block 2" + elif [ $rem3 -eq 0 ]; then + test $crc0 = $crc || echo "lblk $lblk doesn't match block 0" + elif [ $lblk -lt $((NR_BLKS / 2)) ]; then + test $crcZ = $crc || echo "lblk $lblk isn't zeroed" + fi + elif [ $rem5 -eq 0 ]; then + test $crc1 = $crc || echo "lblk $lblk doesn't match block 1" + elif [ $rem3 -eq 0 ]; then + test $crc0 = $crc || echo "lblk $lblk doesn't match block 0" + elif [ $lblk -lt $((NR_BLKS / 2)) ]; then + test $crcZ = $crc || echo "lblk $lblk isn't zeroed" + fi +} + +seq 3 $((NR_BLKS - 1)) | while read lblk; do + err="$(check_block $lblk)" + test -n "$err" && echo "$lblk: $err" +done + +# success, all done +status=0 +exit diff --git a/tests/generic/137.out b/tests/generic/137.out new file mode 100644 index 0000000..7808988 --- /dev/null +++ b/tests/generic/137.out @@ -0,0 +1,8 @@ +QA output created by 137 +Create the original file blocks +fallocate half the file +Reflink block zero to the threes +Reflink block one to the fives +Dedupe block two to the sevens +Check block mappings +2ea37912bdbd71b9ed4734d3141cbe9c TEST_DIR/test-137/file1 diff --git a/tests/generic/group b/tests/generic/group index aa31c8b..50cc132 100644 --- a/tests/generic/group +++ b/tests/generic/group @@ -118,8 +118,13 @@ 113 rw aio auto quick 114 rw aio auto quick 115 auto quick clone +116 auto quick clone 117 attr auto quick +118 auto quick clone +119 auto quick clone 120 other auto quick +121 auto quick clone +122 auto quick clone 123 perms auto quick 124 pattern auto quick 125 other auto @@ -131,7 +136,10 @@ 131 perms auto quick 132 pattern auto 133 rw auto +134 auto quick clone 135 metadata auto quick +136 auto quick clone +137 auto quick clone 141 rw auto quick 169 rw metadata auto quick 184 metadata auto quick From darrick.wong@oracle.com Fri Nov 13 15:37:51 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 276127F82 for ; Fri, 13 Nov 2015 15:37:51 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 074948F8033 for ; Fri, 13 Nov 2015 13:37:50 -0800 (PST) X-ASG-Debug-ID: 1447450666-04cbb0605d47e70001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id x5GBzlRPZT39ZBOS (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 13 Nov 2015 13:37:46 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tADLbINP018580 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 13 Nov 2015 21:37:18 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id tADLbIgq010271 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Fri, 13 Nov 2015 21:37:18 GMT Received: from abhmp0019.oracle.com (abhmp0019.oracle.com [141.146.116.25]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id tADLbHfb026437; Fri, 13 Nov 2015 21:37:17 GMT Received: from localhost (/71.198.20.188) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 13 Nov 2015 13:37:17 -0800 Subject: [PATCH 05/12] reflink: test CoW behaviors of reflinked files From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 05/12] reflink: test CoW behaviors of reflinked files To: david@fromorbit.com, darrick.wong@oracle.com Cc: fstests@vger.kernel.org, xfs@oss.sgi.com, hch@infradead.org, tao.peng@primarydata.com, linux-ext4@vger.kernel.org, Anna.Schumaker@netapp.com, linux-btrfs@vger.kernel.org Date: Fri, 13 Nov 2015 13:37:16 -0800 Message-ID: <20151113213716.31124.72794.stgit@birch.djwong.org> In-Reply-To: <20151113213643.31124.80975.stgit@birch.djwong.org> References: <20151113213643.31124.80975.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1447450666 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24370 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Ensure that CoW happens correctly with buffered, directio, and mmap writes. Signed-off-by: Darrick J. Wong --- tests/generic/138 | 152 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/138.out | 19 ++++++ tests/generic/139 | 151 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/139.out | 19 ++++++ tests/generic/140 | 152 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/140.out | 19 ++++++ tests/generic/142 | 91 +++++++++++++++++++++++++++++ tests/generic/142.out | 8 +++ tests/generic/143 | 91 +++++++++++++++++++++++++++++ tests/generic/143.out | 8 +++ tests/generic/group | 5 ++ 11 files changed, 715 insertions(+) create mode 100755 tests/generic/138 create mode 100644 tests/generic/138.out create mode 100755 tests/generic/139 create mode 100644 tests/generic/139.out create mode 100755 tests/generic/140 create mode 100644 tests/generic/140.out create mode 100755 tests/generic/142 create mode 100644 tests/generic/142.out create mode 100755 tests/generic/143 create mode 100644 tests/generic/143.out diff --git a/tests/generic/138 b/tests/generic/138 new file mode 100755 index 0000000..c084679 --- /dev/null +++ b/tests/generic/138 @@ -0,0 +1,152 @@ +#! /bin/bash +# FS QA Test No. 138 +# +# Ensuring that copy on write through the page cache works: +# - Reflink two files together +# - Write to the beginning, middle, and end +# - Check that the files are now different where we say they're different. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_reflink +_require_cp_reflink + +rm -f "$seqres.full" + +TESTDIR="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original files" +BLKSZ=65536 +_pwrite_byte 0x61 0 $((BLKSZ * 48 - 3)) "$TESTDIR/file1" >> "$seqres.full" +_cp_reflink "$TESTDIR/file1" "$TESTDIR/file2" >> "$seqres.full" +_pwrite_byte 0x61 0 $((BLKSZ * 48 - 3)) "$TESTDIR/file3" >> "$seqres.full" +_test_remount + +echo "Compare files" +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir + +cmp -s "$TESTDIR/file1" "$TESTDIR/file2" || echo "Files 1-2 do not match" +cmp -s "$TESTDIR/file1" "$TESTDIR/file3" || echo "Files 1-3 do not match" +cmp -s "$TESTDIR/file2" "$TESTDIR/file3" || echo "Files 2-3 do not match" + +echo "pagecache CoW the second file" +_pwrite_byte 0x62 0 17 "$TESTDIR/file2" >> "$seqres.full" +_pwrite_byte 0x62 0 17 "$TESTDIR/file3" >> "$seqres.full" + +_pwrite_byte 0x62 $((BLKSZ * 16 - 34)) 17 "$TESTDIR/file2" >> "$seqres.full" +_pwrite_byte 0x62 $((BLKSZ * 16 - 34)) 17 "$TESTDIR/file3" >> "$seqres.full" + +_pwrite_byte 0x62 $((BLKSZ * 48 - 8)) 17 "$TESTDIR/file2" >> "$seqres.full" +_pwrite_byte 0x62 $((BLKSZ * 48 - 8)) 17 "$TESTDIR/file3" >> "$seqres.full" +_test_remount + +echo "Compare files" +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir + +cmp -s "$TESTDIR/file1" "$TESTDIR/file2" || echo "Files 1-2 do not match (intentional)" +cmp -s "$TESTDIR/file1" "$TESTDIR/file3" || echo "Files 1-3 do not match (intentional)" +cmp -s "$TESTDIR/file2" "$TESTDIR/file3" || echo "Files 2-3 do not match" + +echo "Compare the CoW'd section to the before file" +_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file2" 0 17 \ + || echo "Start sections do not match (intentional)" + +_compare_range "$TESTDIR/file1" $((BLKSZ * 16 - 34)) \ + "$TESTDIR/file2" $((BLKSZ * 16 - 34)) 17 \ + || echo "Middle sections do not match (intentional)" + +_compare_range "$TESTDIR/file1" $((BLKSZ * 48 - 8)) \ + "$TESTDIR/file2" $((BLKSZ * 48 - 8)) 17 \ + || echo "End sections do not match (intentional)" + +echo "Compare the CoW'd section to the after file" +_compare_range "$TESTDIR/file2" 0 "$TESTDIR/file3" 0 17 \ + || echo "Start sections do not match" + +_compare_range "$TESTDIR/file2" $((BLKSZ * 16 - 34)) \ + "$TESTDIR/file3" $((BLKSZ * 16 - 34)) 17 \ + || echo "Middle sections do not match" + +_compare_range "$TESTDIR/file2" $((BLKSZ * 48 - 8)) \ + "$TESTDIR/file3" $((BLKSZ * 48 - 8)) 17 \ + || echo "End sections do not match" + +echo "Compare the not CoW'd sections" +_compare_range "$TESTDIR/file1" 18 "$TESTDIR/file2" 18 17 \ + || echo "Start sections of 1-2 do not match" + +_compare_range "$TESTDIR/file2" 18 "$TESTDIR/file3" 18 17 \ + || echo "Start sections of 2-3 do not match" + + +_compare_range "$TESTDIR/file1" $((BLKSZ * 16 - 17)) \ + "$TESTDIR/file2" $((BLKSZ * 16 - 17)) 82 \ + || echo "Middle sections of 1-2 do not match" + +_compare_range "$TESTDIR/file2" $((BLKSZ * 16 - 17)) \ + "$TESTDIR/file3" $((BLKSZ * 16 - 17)) 82 \ + || echo "Middle sections of 2-3 do not match" + +_compare_range "$TESTDIR/file1" $((BLKSZ * 48 - 108)) \ + "$TESTDIR/file2" $((BLKSZ * 48 - 108)) 100 \ + || echo "End sections of 1-2 do not match" + +_compare_range "$TESTDIR/file2" $((BLKSZ * 48 - 108)) \ + "$TESTDIR/file3" $((BLKSZ * 48 - 108)) 100 \ + || echo "End sections of 2-3 do not match" + + +_compare_range "$TESTDIR/file1" $((BLKSZ * 14)) \ + "$TESTDIR/file2" $((BLKSZ * 14)) $BLKSZ \ + || echo "Untouched sections of 1-2 do not match" + +_compare_range "$TESTDIR/file2" $((BLKSZ * 14)) \ + "$TESTDIR/file3" $((BLKSZ * 14)) $BLKSZ \ + || echo "Untouched sections of 2-3 do not match" + +# success, all done +status=0 +exit diff --git a/tests/generic/138.out b/tests/generic/138.out new file mode 100644 index 0000000..b0cafab --- /dev/null +++ b/tests/generic/138.out @@ -0,0 +1,19 @@ +QA output created by 138 +Create the original files +Compare files +60ebe700450b6015c17fa15cacb9493b TEST_DIR/test-138/file1 +60ebe700450b6015c17fa15cacb9493b TEST_DIR/test-138/file2 +60ebe700450b6015c17fa15cacb9493b TEST_DIR/test-138/file3 +pagecache CoW the second file +Compare files +60ebe700450b6015c17fa15cacb9493b TEST_DIR/test-138/file1 +4a879c2f322121f6f4b8ebede1909a7c TEST_DIR/test-138/file2 +4a879c2f322121f6f4b8ebede1909a7c TEST_DIR/test-138/file3 +Files 1-2 do not match (intentional) +Files 1-3 do not match (intentional) +Compare the CoW'd section to the before file +Start sections do not match (intentional) +Middle sections do not match (intentional) +End sections do not match (intentional) +Compare the CoW'd section to the after file +Compare the not CoW'd sections diff --git a/tests/generic/139 b/tests/generic/139 new file mode 100755 index 0000000..54c68fb --- /dev/null +++ b/tests/generic/139 @@ -0,0 +1,151 @@ +#! /bin/bash +# FS QA Test No. 139 +# +# Ensuring that copy on write in direct-io mode works: +# - Reflink two files together +# - Write to the beginning, middle, and end in direct-io mode +# - Check that the files are now different where we say they're different. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_reflink +_require_cp_reflink + +rm -f "$seqres.full" + +TESTDIR=$TEST_DIR/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR + +echo "Create the original files" +BLKSZ=65536 +_pwrite_byte 0x61 0 $((BLKSZ * 48 - 3)) "$TESTDIR/file1" >> "$seqres.full" +_cp_reflink "$TESTDIR/file1" "$TESTDIR/file2" >> "$seqres.full" +_pwrite_byte 0x61 0 $((BLKSZ * 48 - 3)) "$TESTDIR/file3" >> "$seqres.full" +_test_remount + +echo "Compare files" +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir + +cmp -s "$TESTDIR/file1" "$TESTDIR/file2" || echo "Files 1-2 should match" +cmp -s "$TESTDIR/file1" "$TESTDIR/file3" || echo "Files 1-3 should match" +cmp -s "$TESTDIR/file2" "$TESTDIR/file3" || echo "Files 2-3 should match" + +echo "directio CoW the second file" +_pwrite_byte 0x62 0 $BLKSZ "$TESTDIR/file2" -d >> "$seqres.full" +_pwrite_byte 0x62 0 $BLKSZ "$TESTDIR/file3" -d >> "$seqres.full" + +_pwrite_byte 0x62 $((BLKSZ * 16 - 512)) 512 "$TESTDIR/file2" -d >> "$seqres.full" +_pwrite_byte 0x62 $((BLKSZ * 16 - 512)) 512 "$TESTDIR/file3" -d >> "$seqres.full" + +_pwrite_byte 0x62 $((BLKSZ * 48)) $BLKSZ "$TESTDIR/file2" -d >> "$seqres.full" +_pwrite_byte 0x62 $((BLKSZ * 48)) $BLKSZ "$TESTDIR/file3" -d >> "$seqres.full" +_test_remount + +echo "Compare files" +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir + +cmp -s "$TESTDIR/file1" "$TESTDIR/file2" || echo "Files 1-2 should not match (intentional)" +cmp -s "$TESTDIR/file1" "$TESTDIR/file3" || echo "Files 1-3 should not match (intentional)" +cmp -s "$TESTDIR/file2" "$TESTDIR/file3" || echo "Files 2-3 should match" + +echo "Compare the CoW'd section to the before file" +_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file2" 0 $BLKSZ \ + || echo "Start sections do not match (intentional)" + +_compare_range "$TESTDIR/file1" $((BLKSZ * 16 - 512)) \ + "$TESTDIR/file2" $((BLKSZ * 16 - 512)) 512 \ + || echo "Middle sections do not match (intentional)" + +_compare_range "$TESTDIR/file1" $((BLKSZ * 48 - 512)) \ + "$TESTDIR/file2" $((BLKSZ * 48 - 512)) $BLKSZ \ + || echo "End sections do not match (intentional)" + +echo "Compare the CoW'd section to the after file" +_compare_range "$TESTDIR/file2" 0 "$TESTDIR/file3" 0 $BLKSZ \ + || echo "Start sections do not match" + +_compare_range "$TESTDIR/file2" $((BLKSZ * 16 - 512)) \ + "$TESTDIR/file3" $((BLKSZ * 16 - 512)) 512 \ + || echo "Middle sections do not match" + +_compare_range "$TESTDIR/file2" $((BLKSZ * 48 - 512)) \ + "$TESTDIR/file3" $((BLKSZ * 48 - 512)) $BLKSZ \ + || echo "End sections do not match" + +echo "Compare the not CoW'd sections" +_compare_range "$TESTDIR/file1" $BLKSZ "$TESTDIR/file2" $BLKSZ 512 \ + || echo "Start sections of 1-2 do not match" +_compare_range "$TESTDIR/file2" $BLKSZ "$TESTDIR/file3" $BLKSZ 512 \ + || echo "Start sections of 2-3 do not match" + + +_compare_range "$TESTDIR/file1" $((BLKSZ * 16 - 1024)) \ + "$TESTDIR/file2" $((BLKSZ * 16 - 1024)) 512 \ + || echo "Middle sections of 1-2 do not match" + +_compare_range "$TESTDIR/file2" $((BLKSZ * 16 - 1024)) \ + "$TESTDIR/file3" $((BLKSZ * 16 - 1024)) 512 \ + || echo "Middle sections of 2-3 do not match" + +_compare_range "$TESTDIR/file1" $((BLKSZ * 48 - 1024)) \ + "$TESTDIR/file2" $((BLKSZ * 48 - 1024)) 512 \ + || echo "End sections of 1-2 do not match" + +_compare_range "$TESTDIR/file2" $((BLKSZ * 48 - 1024)) \ + "$TESTDIR/file3" $((BLKSZ * 48 - 1024)) 512 \ + || echo "End sections of 2-3 do not match" + + +_compare_range "$TESTDIR/file1" $((BLKSZ * 16)) \ + "$TESTDIR/file2" $((BLKSZ * 16)) 512 \ + || echo "Untouched sections of 1-2 do not match" + +_compare_range "$TESTDIR/file2" $((BLKSZ * 16)) \ + "$TESTDIR/file3" $((BLKSZ * 16)) 512 \ + || echo "Untouched sections of 2-3 do not match" + +# success, all done +status=0 +exit diff --git a/tests/generic/139.out b/tests/generic/139.out new file mode 100644 index 0000000..28d04f5 --- /dev/null +++ b/tests/generic/139.out @@ -0,0 +1,19 @@ +QA output created by 139 +Create the original files +Compare files +60ebe700450b6015c17fa15cacb9493b TEST_DIR/test-139/file1 +60ebe700450b6015c17fa15cacb9493b TEST_DIR/test-139/file2 +60ebe700450b6015c17fa15cacb9493b TEST_DIR/test-139/file3 +directio CoW the second file +Compare files +60ebe700450b6015c17fa15cacb9493b TEST_DIR/test-139/file1 +ff5626fb6c71b242d6b1a43de25c9a85 TEST_DIR/test-139/file2 +ff5626fb6c71b242d6b1a43de25c9a85 TEST_DIR/test-139/file3 +Files 1-2 should not match (intentional) +Files 1-3 should not match (intentional) +Compare the CoW'd section to the before file +Start sections do not match (intentional) +Middle sections do not match (intentional) +End sections do not match (intentional) +Compare the CoW'd section to the after file +Compare the not CoW'd sections diff --git a/tests/generic/140 b/tests/generic/140 new file mode 100755 index 0000000..6299d8e --- /dev/null +++ b/tests/generic/140 @@ -0,0 +1,152 @@ +#! /bin/bash +# FS QA Test No. 140 +# +# Ensuring that mmap copy on write through the page cache works: +# - Reflink two files together +# - Write to the beginning, middle, and end +# - Check that the files are now different where we say they're different. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_reflink +_require_cp_reflink + +rm -f "$seqres.full" + +TESTDIR="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original files" +BLKSZ=65536 +_pwrite_byte 0x61 0 $((BLKSZ * 48 - 3)) "$TESTDIR/file1" >> "$seqres.full" +_cp_reflink "$TESTDIR/file1" "$TESTDIR/file2" >> "$seqres.full" +_pwrite_byte 0x61 0 $((BLKSZ * 48 - 3)) "$TESTDIR/file3" >> "$seqres.full" +_test_remount + +echo "Compare files" +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir + +cmp -s "$TESTDIR/file1" "$TESTDIR/file2" || echo "Files 1-2 do not match" +cmp -s "$TESTDIR/file1" "$TESTDIR/file3" || echo "Files 1-3 do not match" +cmp -s "$TESTDIR/file2" "$TESTDIR/file3" || echo "Files 2-3 do not match" + +echo "mmap CoW the second file" +_mwrite_byte 0x62 0 17 $((BLKSZ * 48 - 3)) "$TESTDIR/file2" >> "$seqres.full" +_mwrite_byte 0x62 0 17 $((BLKSZ * 48 - 3)) "$TESTDIR/file3" >> "$seqres.full" + +_mwrite_byte 0x62 $((BLKSZ * 16 - 34)) 17 $((BLKSZ * 48 - 3)) "$TESTDIR/file2" >> "$seqres.full" +_mwrite_byte 0x62 $((BLKSZ * 16 - 34)) 17 $((BLKSZ * 48 - 3)) "$TESTDIR/file3" >> "$seqres.full" + +_mwrite_byte 0x62 $((BLKSZ * 48 - 20)) 17 $((BLKSZ * 48 - 3)) "$TESTDIR/file2" >> "$seqres.full" +_mwrite_byte 0x62 $((BLKSZ * 48 - 20)) 17 $((BLKSZ * 48 - 3)) "$TESTDIR/file3" >> "$seqres.full" +_test_remount + +echo "Compare files" +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir + +cmp -s "$TESTDIR/file1" "$TESTDIR/file2" || echo "Files 1-2 do not match (intentional)" +cmp -s "$TESTDIR/file1" "$TESTDIR/file3" || echo "Files 1-3 do not match (intentional)" +cmp -s "$TESTDIR/file2" "$TESTDIR/file3" || echo "Files 2-3 do not match" + +echo "Compare the CoW'd section to the before file" +_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file2" 0 17 \ + || echo "Start sections do not match (intentional)" + +_compare_range "$TESTDIR/file1" $((BLKSZ * 16 - 34)) \ + "$TESTDIR/file2" $((BLKSZ * 16 - 34)) 17 \ + || echo "Middle sections do not match (intentional)" + +_compare_range "$TESTDIR/file1" $((BLKSZ * 48 - 20)) \ + "$TESTDIR/file2" $((BLKSZ * 48 - 20)) 17 \ + || echo "End sections do not match (intentional)" + +echo "Compare the CoW'd section to the after file" +_compare_range "$TESTDIR/file2" 0 "$TESTDIR/file3" 0 17 \ + || echo "Start sections do not match" + +_compare_range "$TESTDIR/file2" $((BLKSZ * 16 - 34)) \ + "$TESTDIR/file3" $((BLKSZ * 16 - 34)) 17 \ + || echo "Middle sections do not match" + +_compare_range "$TESTDIR/file2" $((BLKSZ * 48 - 20)) \ + "$TESTDIR/file3" $((BLKSZ * 48 - 20)) 17 \ + || echo "End sections do not match" + +echo "Compare the not CoW'd sections" +_compare_range "$TESTDIR/file1" 18 "$TESTDIR/file2" 18 17 \ + || echo "Start sections of 1-2 do not match" + +_compare_range "$TESTDIR/file2" 18 "$TESTDIR/file3" 18 17 \ + || echo "Start sections of 2-3 do not match" + + +_compare_range "$TESTDIR/file1" $((BLKSZ * 16 - 17)) \ + "$TESTDIR/file2" $((BLKSZ * 16 - 17)) 82 \ + || echo "Middle sections of 1-2 do not match" + +_compare_range "$TESTDIR/file2" $((BLKSZ * 16 - 17)) \ + "$TESTDIR/file3" $((BLKSZ * 16 - 17)) 82 \ + || echo "Middle sections of 2-3 do not match" + +_compare_range "$TESTDIR/file1" $((BLKSZ * 48 - 120)) \ + "$TESTDIR/file2" $((BLKSZ * 48 - 120)) 100 \ + || echo "End sections of 1-2 do not match" + +_compare_range "$TESTDIR/file2" $((BLKSZ * 48 - 120)) \ + "$TESTDIR/file3" $((BLKSZ * 48 - 120)) 100 \ + || echo "End sections of 2-3 do not match" + + +_compare_range "$TESTDIR/file1" $((BLKSZ * 14)) \ + "$TESTDIR/file2" $((BLKSZ * 14)) $BLKSZ \ + || echo "Untouched sections of 1-2 do not match" + +_compare_range "$TESTDIR/file2" $((BLKSZ * 14)) \ + "$TESTDIR/file3" $((BLKSZ * 14)) $BLKSZ \ + || echo "Untouched sections of 2-3 do not match" + +# success, all done +status=0 +exit diff --git a/tests/generic/140.out b/tests/generic/140.out new file mode 100644 index 0000000..51a5b85 --- /dev/null +++ b/tests/generic/140.out @@ -0,0 +1,19 @@ +QA output created by 140 +Create the original files +Compare files +60ebe700450b6015c17fa15cacb9493b TEST_DIR/test-140/file1 +60ebe700450b6015c17fa15cacb9493b TEST_DIR/test-140/file2 +60ebe700450b6015c17fa15cacb9493b TEST_DIR/test-140/file3 +mmap CoW the second file +Compare files +60ebe700450b6015c17fa15cacb9493b TEST_DIR/test-140/file1 +795ecfd281dbda4916431376228e4187 TEST_DIR/test-140/file2 +795ecfd281dbda4916431376228e4187 TEST_DIR/test-140/file3 +Files 1-2 do not match (intentional) +Files 1-3 do not match (intentional) +Compare the CoW'd section to the before file +Start sections do not match (intentional) +Middle sections do not match (intentional) +End sections do not match (intentional) +Compare the CoW'd section to the after file +Compare the not CoW'd sections diff --git a/tests/generic/142 b/tests/generic/142 new file mode 100755 index 0000000..cf6d634 --- /dev/null +++ b/tests/generic/142 @@ -0,0 +1,91 @@ +#! /bin/bash +# FS QA Test No. 142 +# +# Ensure that reflinking a file N times and CoWing the copies leaves the +# original intact. +# - Create a file and record its hash +# - Create some reflink copies +# - Rewrite all the reflink copies +# - Compare the contents of the original file +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_reflink +_require_cp_reflink + +rm -f "$seqres.full" + +TESTDIR="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original file blocks" +BLKSZ=65536 +NR=9 +_pwrite_byte 0x61 0 $((BLKSZ * 256)) "$TESTDIR/file1" >> "$seqres.full" +_test_remount + +md5sum "$TESTDIR/file1" | _filter_test_dir +csum="$(_md5_checksum "$TESTDIR/file1")" + +echo "Create the reflink copies" +seq 2 $NR | while read i; do + _cp_reflink "$TESTDIR/file1" "$TESTDIR/file$i" +done +_test_remount + +echo "Rewrite the copies" +seq 2 $NR | while read i; do + _pwrite_byte 0x62 0 $((BLKSZ * 256)) "$TESTDIR/file$i" >> "$seqres.full" +done +_test_remount + +echo "Examine original file" +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir + +mod_csum="$(_md5_checksum "$TESTDIR/file2")" +new_csum="$(_md5_checksum "$TESTDIR/file1")" +test "${csum}" != "${mod_csum}" || echo "checksums do not match" +test "${csum}" = "${new_csum}" || echo "checksums do not match" + +# success, all done +status=0 +exit diff --git a/tests/generic/142.out b/tests/generic/142.out new file mode 100644 index 0000000..b55d0f0 --- /dev/null +++ b/tests/generic/142.out @@ -0,0 +1,8 @@ +QA output created by 142 +Create the original file blocks +f4820540fc0ac02750739896fe028d56 TEST_DIR/test-142/file1 +Create the reflink copies +Rewrite the copies +Examine original file +f4820540fc0ac02750739896fe028d56 TEST_DIR/test-142/file1 +eb34153e9ed1e774db28cbbe4090a449 TEST_DIR/test-142/file2 diff --git a/tests/generic/143 b/tests/generic/143 new file mode 100755 index 0000000..d2ccb94 --- /dev/null +++ b/tests/generic/143 @@ -0,0 +1,91 @@ +#! /bin/bash +# FS QA Test No. 143 +# +# Ensure that reflinking a file N times and DIO CoWing the copies leaves the +# original intact. +# - Create a file and record its hash +# - Create some reflink copies +# - Rewrite all the reflink copies w/ directio +# - Compare the contents of the original file +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_reflink +_require_cp_reflink + +rm -f "$seqres.full" + +TESTDIR="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original file blocks" +BLKSZ=65536 +NR=9 +_pwrite_byte 0x61 0 $((BLKSZ * 256)) "$TESTDIR/file1" >> "$seqres.full" +_test_remount + +md5sum "$TESTDIR/file1" | _filter_test_dir +csum="$(_md5_checksum "$TESTDIR/file1")" + +echo "Create the reflink copies" +seq 2 $NR | while read i; do + _cp_reflink "$TESTDIR/file1" "$TESTDIR/file$i" +done +_test_remount + +echo "Rewrite the copies" +seq 2 $NR | while read i; do + _pwrite_byte 0x62 0 $((BLKSZ * 256)) "$TESTDIR/file$i" -d >> "$seqres.full" +done +_test_remount + +echo "Examine original file" +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir + +mod_csum="$(_md5_checksum "$TESTDIR/file2")" +new_csum="$(_md5_checksum "$TESTDIR/file1")" +test "${csum}" != "${mod_csum}" || echo "checksums do not match" +test "${csum}" = "${new_csum}" || echo "checksums do not match" + +# success, all done +status=0 +exit diff --git a/tests/generic/143.out b/tests/generic/143.out new file mode 100644 index 0000000..70a1e71 --- /dev/null +++ b/tests/generic/143.out @@ -0,0 +1,8 @@ +QA output created by 143 +Create the original file blocks +f4820540fc0ac02750739896fe028d56 TEST_DIR/test-143/file1 +Create the reflink copies +Rewrite the copies +Examine original file +f4820540fc0ac02750739896fe028d56 TEST_DIR/test-143/file1 +eb34153e9ed1e774db28cbbe4090a449 TEST_DIR/test-143/file2 diff --git a/tests/generic/group b/tests/generic/group index 50cc132..7b55707 100644 --- a/tests/generic/group +++ b/tests/generic/group @@ -140,7 +140,12 @@ 135 metadata auto quick 136 auto quick clone 137 auto quick clone +138 auto quick clone +139 auto quick clone +140 auto quick clone 141 rw auto quick +142 auto quick clone +143 auto quick clone 169 rw metadata auto quick 184 metadata auto quick 192 atime auto From darrick.wong@oracle.com Fri Nov 13 15:37:54 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 B7A727F7B for ; Fri, 13 Nov 2015 15:37:54 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 6404C8F8035 for ; Fri, 13 Nov 2015 13:37:54 -0800 (PST) X-ASG-Debug-ID: 1447450668-04bdf07f0a46a70001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id RnXv8TR5z17BzZZ5 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 13 Nov 2015 13:37:48 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tADLbPpZ000404 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 13 Nov 2015 21:37:25 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id tADLbP0p024880 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Fri, 13 Nov 2015 21:37:25 GMT Received: from abhmp0013.oracle.com (abhmp0013.oracle.com [141.146.116.19]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id tADLbOVU002343; Fri, 13 Nov 2015 21:37:24 GMT Received: from localhost (/71.198.20.188) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 13 Nov 2015 13:37:24 -0800 Subject: [PATCH 06/12] reflink: test the various fallocate modes From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 06/12] reflink: test the various fallocate modes To: david@fromorbit.com, darrick.wong@oracle.com Cc: fstests@vger.kernel.org, xfs@oss.sgi.com, hch@infradead.org, tao.peng@primarydata.com, linux-ext4@vger.kernel.org, Anna.Schumaker@netapp.com, linux-btrfs@vger.kernel.org Date: Fri, 13 Nov 2015 13:37:22 -0800 Message-ID: <20151113213722.31124.56074.stgit@birch.djwong.org> In-Reply-To: <20151113213643.31124.80975.stgit@birch.djwong.org> References: <20151113213643.31124.80975.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0022.oracle.com [141.146.126.234] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1447450668 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24371 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Check that the variants of fallocate (allocate, punch, zero range, collapse range, insert range) do the right thing when they're run against a range of reflinked blocks. Signed-off-by: Darrick J. Wong --- tests/generic/144 | 142 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/144.out | 16 ++++++ tests/generic/145 | 142 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/145.out | 19 +++++++ tests/generic/146 | 136 +++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/146.out | 19 +++++++ tests/generic/147 | 139 ++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/147.out | 19 +++++++ tests/generic/148 | 116 ++++++++++++++++++++++++++++++++++++++++ tests/generic/148.out | 15 +++++ tests/generic/149 | 136 +++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/149.out | 19 +++++++ tests/generic/group | 6 ++ 13 files changed, 924 insertions(+) create mode 100755 tests/generic/144 create mode 100644 tests/generic/144.out create mode 100755 tests/generic/145 create mode 100644 tests/generic/145.out create mode 100755 tests/generic/146 create mode 100644 tests/generic/146.out create mode 100755 tests/generic/147 create mode 100644 tests/generic/147.out create mode 100755 tests/generic/148 create mode 100644 tests/generic/148.out create mode 100755 tests/generic/149 create mode 100644 tests/generic/149.out diff --git a/tests/generic/144 b/tests/generic/144 new file mode 100755 index 0000000..bee0893 --- /dev/null +++ b/tests/generic/144 @@ -0,0 +1,142 @@ +#! /bin/bash +# FS QA Test No. 144 +# +# Ensure that fallocate steps around reflinked ranges: +# - Reflink parts of two files together +# - Fallocate all the other sparse space. +# - Check that the reflinked areas are still there. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_reflink +_require_cp_reflink +_require_xfs_io_command "falloc" +_require_xfs_io_command "truncate" + +rm -f "$seqres.full" + +TESTDIR="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original files" +BLKSZ=65536 +_pwrite_byte 0x61 0 $((BLKSZ * 5 + 37)) "$TESTDIR/file1" >> "$seqres.full" + +_reflink_range "$TESTDIR/file1" $BLKSZ "$TESTDIR/file2" $BLKSZ \ + $((BLKSZ * 4 + 37)) >> "$seqres.full" + +"$XFS_IO_PROG" -f -c "truncate $((BLKSZ * 5 + 37))" "$TESTDIR/file3" >> "$seqres.full" +_reflink_range "$TESTDIR/file1" 0 "$TESTDIR/file3" 0 $BLKSZ >> "$seqres.full" + +"$XFS_IO_PROG" -f -c "truncate $((BLKSZ * 5 + 37))" "$TESTDIR/file4" >> "$seqres.full" +_reflink_range "$TESTDIR/file1" $BLKSZ "$TESTDIR/file4" $BLKSZ $BLKSZ >> "$seqres.full" +_reflink_range "$TESTDIR/file1" $((BLKSZ * 3)) "$TESTDIR/file4" $((BLKSZ * 3)) \ + $BLKSZ >> "$seqres.full" + +_cp_reflink "$TESTDIR/file1" "$TESTDIR/file5" +_test_remount + +echo "Compare sections" +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir +md5sum "$TESTDIR/file4" | _filter_test_dir +md5sum "$TESTDIR/file5" | _filter_test_dir + +_compare_range "$TESTDIR/file1" $BLKSZ "$TESTDIR/file2" $BLKSZ \ + $((BLKSZ * 4 + 37)) \ + || echo "shared parts of files 1-2 changed" + +_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file3" 0 $BLKSZ \ + || echo "shared parts of files 1-3 changed" + +_compare_range "$TESTDIR/file1" $BLKSZ "$TESTDIR/file4" $BLKSZ $BLKSZ \ + || echo "shared parts of files 1-4 changed" + +_compare_range "$TESTDIR/file1" 0 "$TESTDIR/file5" 0 $((BLKSZ * 5 + 37)) \ + || echo "shared parts of files 1-5 changed" + +echo "Compare files" +C1="$(_md5_checksum "$TESTDIR/file1")" +C2="$(_md5_checksum "$TESTDIR/file2")" +C3="$(_md5_checksum "$TESTDIR/file3")" +C4="$(_md5_checksum "$TESTDIR/file4")" +C5="$(_md5_checksum "$TESTDIR/file5")" + +test "${C1}" != "${C2}" || echo "file1 and file2 should not match" +test "${C1}" != "${C3}" || echo "file1 and file3 should not match" +test "${C1}" != "${C4}" || echo "file1 and file4 should not match" +test "${C1}" = "${C5}" || echo "file1 and file5 should match" +test "${C2}" != "${C3}" || echo "file2 and file3 should not match" +test "${C2}" != "${C4}" || echo "file2 and file4 should not match" +test "${C2}" != "${C5}" || echo "file2 and file5 should not match" +test "${C3}" != "${C4}" || echo "file3 and file4 should not match" +test "${C3}" != "${C5}" || echo "file3 and file5 should not match" +test "${C4}" != "${C5}" || echo "file4 and file5 should not match" + +echo "falloc everything" +"$XFS_IO_PROG" -f -c "falloc 0 $((BLKSZ * 5))" "$TESTDIR/file2" >> "$seqres.full" +"$XFS_IO_PROG" -f -c "falloc 0 $((BLKSZ * 5))" "$TESTDIR/file3" >> "$seqres.full" +"$XFS_IO_PROG" -f -c "falloc 0 $((BLKSZ * 5))" "$TESTDIR/file4" >> "$seqres.full" +_test_remount + +echo "Compare files" +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir +md5sum "$TESTDIR/file4" | _filter_test_dir +md5sum "$TESTDIR/file5" | _filter_test_dir + +D1="$(_md5_checksum "$TESTDIR/file1")" +D2="$(_md5_checksum "$TESTDIR/file2")" +D3="$(_md5_checksum "$TESTDIR/file3")" +D4="$(_md5_checksum "$TESTDIR/file4")" +D5="$(_md5_checksum "$TESTDIR/file5")" + +test "${C1}" = "${D1}" || echo "file1 should not change" +test "${C2}" = "${D2}" || echo "file2 should not change" +test "${C3}" = "${D3}" || echo "file3 should not change" +test "${C4}" = "${D4}" || echo "file4 should not change" +test "${C5}" = "${D5}" || echo "file2 should not change" + +# success, all done +status=0 +exit diff --git a/tests/generic/144.out b/tests/generic/144.out new file mode 100644 index 0000000..0bcf4b9 --- /dev/null +++ b/tests/generic/144.out @@ -0,0 +1,16 @@ +QA output created by 144 +Create the original files +Compare sections +ee8004e6298fa128477bd4aa1adc69fb TEST_DIR/test-144/file1 +a7cb8cb9697d59413e0d10495d226398 TEST_DIR/test-144/file2 +7d42a0a2865c94f45435a2ce7627da02 TEST_DIR/test-144/file3 +7f528bc76f4d61ff9cff7bc1906579c6 TEST_DIR/test-144/file4 +ee8004e6298fa128477bd4aa1adc69fb TEST_DIR/test-144/file5 +Compare files +falloc everything +Compare files +ee8004e6298fa128477bd4aa1adc69fb TEST_DIR/test-144/file1 +a7cb8cb9697d59413e0d10495d226398 TEST_DIR/test-144/file2 +7d42a0a2865c94f45435a2ce7627da02 TEST_DIR/test-144/file3 +7f528bc76f4d61ff9cff7bc1906579c6 TEST_DIR/test-144/file4 +ee8004e6298fa128477bd4aa1adc69fb TEST_DIR/test-144/file5 diff --git a/tests/generic/145 b/tests/generic/145 new file mode 100755 index 0000000..8a14f82 --- /dev/null +++ b/tests/generic/145 @@ -0,0 +1,142 @@ +#! /bin/bash +# FS QA Test No. 145 +# +# Ensure that collapse range steps around reflinked ranges: +# - Create three reflink clones of a file +# - Collapse the start, middle, and end of the reflink range of each +# of the three files, respectively +# - Check that the reflinked areas are still there. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_reflink +_require_cp_reflink +_require_xfs_io_command "falloc" +_require_xfs_io_command "fcollapse" + +rm -f "$seqres.full" + +TESTDIR="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original files" +BLKSZ=65536 +_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file1" >> "$seqres.full" +_pwrite_byte 0x62 $BLKSZ $BLKSZ "$TESTDIR/file1" >> "$seqres.full" +_pwrite_byte 0x63 $((BLKSZ * 2)) $BLKSZ "$TESTDIR/file1" >> "$seqres.full" + +_cp_reflink "$TESTDIR/file1" "$TESTDIR/file2" +_cp_reflink "$TESTDIR/file1" "$TESTDIR/file3" +_cp_reflink "$TESTDIR/file1" "$TESTDIR/file4" + +"$XFS_IO_PROG" -f -c "falloc 0 $((BLKSZ * 4))" "$TESTDIR/file1" +"$XFS_IO_PROG" -f -c "falloc 0 $((BLKSZ * 4))" "$TESTDIR/file2" +"$XFS_IO_PROG" -f -c "falloc 0 $((BLKSZ * 4))" "$TESTDIR/file3" +"$XFS_IO_PROG" -f -c "falloc 0 $((BLKSZ * 4))" "$TESTDIR/file4" + +_pwrite_byte 0x62 0 $BLKSZ "$TESTDIR/file2.chk" >> "$seqres.full" +_pwrite_byte 0x63 $BLKSZ $BLKSZ "$TESTDIR/file2.chk" >> "$seqres.full" +_pwrite_byte 0x00 $((BLKSZ * 2)) $BLKSZ "$TESTDIR/file2.chk" >> "$seqres.full" + +_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file3.chk" >> "$seqres.full" +_pwrite_byte 0x63 $BLKSZ $BLKSZ "$TESTDIR/file3.chk" >> "$seqres.full" +_pwrite_byte 0x00 $((BLKSZ * 2)) $BLKSZ "$TESTDIR/file3.chk" >> "$seqres.full" + +_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file4.chk" >> "$seqres.full" +_pwrite_byte 0x62 $BLKSZ $BLKSZ "$TESTDIR/file4.chk" >> "$seqres.full" +_pwrite_byte 0x00 $((BLKSZ * 2)) $BLKSZ "$TESTDIR/file4.chk" >> "$seqres.full" +_test_remount + +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir +md5sum "$TESTDIR/file4" | _filter_test_dir +md5sum "$TESTDIR/file2.chk" | _filter_test_dir +md5sum "$TESTDIR/file3.chk" | _filter_test_dir +md5sum "$TESTDIR/file4.chk" | _filter_test_dir + +C1="$(_md5_checksum "$TESTDIR/file1")" +C2="$(_md5_checksum "$TESTDIR/file2")" +C3="$(_md5_checksum "$TESTDIR/file3")" +C4="$(_md5_checksum "$TESTDIR/file4")" + +test "${C1}" = "${C2}" || echo "file1 and file2 should match" +test "${C1}" = "${C3}" || echo "file1 and file3 should match" +test "${C1}" = "${C4}" || echo "file1 and file4 should match" +test "${C2}" = "${C3}" || echo "file2 and file3 should match" +test "${C2}" = "${C4}" || echo "file2 and file4 should match" +test "${C3}" = "${C4}" || echo "file3 and file4 should match" + +echo "fcollapse files" +"$XFS_IO_PROG" -f -c "fcollapse 0 $BLKSZ" "$TESTDIR/file2" +"$XFS_IO_PROG" -f -c "fcollapse $BLKSZ $BLKSZ" "$TESTDIR/file3" +"$XFS_IO_PROG" -f -c "fcollapse $((BLKSZ * 2)) $BLKSZ" "$TESTDIR/file4" +_test_remount + +echo "Compare files" +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir +md5sum "$TESTDIR/file4" | _filter_test_dir +md5sum "$TESTDIR/file2.chk" | _filter_test_dir +md5sum "$TESTDIR/file3.chk" | _filter_test_dir +md5sum "$TESTDIR/file4.chk" | _filter_test_dir + +C1="$(_md5_checksum "$TESTDIR/file1")" +C2="$(_md5_checksum "$TESTDIR/file2")" +C3="$(_md5_checksum "$TESTDIR/file3")" +C4="$(_md5_checksum "$TESTDIR/file4")" + +test "${C1}" != "${C2}" || echo "file1 and file2 should not match" +test "${C1}" != "${C3}" || echo "file1 and file3 should not match" +test "${C1}" != "${C4}" || echo "file1 and file4 should not match" +test "${C2}" != "${C3}" || echo "file2 and file3 should not match" +test "${C2}" != "${C4}" || echo "file2 and file4 should not match" +test "${C3}" != "${C4}" || echo "file3 and file4 should not match" + +echo "Compare against check files" +cmp -s "$TESTDIR/file2" "$TESTDIR/file2.chk" || echo "file2 and file2.chk do not match" +cmp -s "$TESTDIR/file3" "$TESTDIR/file3.chk" || echo "file3 and file3.chk do not match" +cmp -s "$TESTDIR/file4" "$TESTDIR/file4.chk" || echo "file4 and file4.chk do not match" + +# success, all done +status=0 +exit diff --git a/tests/generic/145.out b/tests/generic/145.out new file mode 100644 index 0000000..e36c61d --- /dev/null +++ b/tests/generic/145.out @@ -0,0 +1,19 @@ +QA output created by 145 +Create the original files +564b34fb4a562f6d864f371248e48540 TEST_DIR/test-145/file1 +564b34fb4a562f6d864f371248e48540 TEST_DIR/test-145/file2 +564b34fb4a562f6d864f371248e48540 TEST_DIR/test-145/file3 +564b34fb4a562f6d864f371248e48540 TEST_DIR/test-145/file4 +9a239246ce4bee20f2de1b0ba41a41e0 TEST_DIR/test-145/file2.chk +859c251680d8bbf0f859f5c6d7a6a2a2 TEST_DIR/test-145/file3.chk +c931e8500c1a56a5b7369f7f1b971690 TEST_DIR/test-145/file4.chk +fcollapse files +Compare files +564b34fb4a562f6d864f371248e48540 TEST_DIR/test-145/file1 +9a239246ce4bee20f2de1b0ba41a41e0 TEST_DIR/test-145/file2 +859c251680d8bbf0f859f5c6d7a6a2a2 TEST_DIR/test-145/file3 +c931e8500c1a56a5b7369f7f1b971690 TEST_DIR/test-145/file4 +9a239246ce4bee20f2de1b0ba41a41e0 TEST_DIR/test-145/file2.chk +859c251680d8bbf0f859f5c6d7a6a2a2 TEST_DIR/test-145/file3.chk +c931e8500c1a56a5b7369f7f1b971690 TEST_DIR/test-145/file4.chk +Compare against check files diff --git a/tests/generic/146 b/tests/generic/146 new file mode 100755 index 0000000..9e3eff6 --- /dev/null +++ b/tests/generic/146 @@ -0,0 +1,136 @@ +#! /bin/bash +# FS QA Test No. 146 +# +# Ensure that punch-hole steps around reflinked ranges: +# - Create three reflink clones of a file +# - Punch the start, middle, and end of the reflink range of each +# of the three files, respectively +# - Check that the reflinked areas are still there. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_reflink +_require_cp_reflink +_require_xfs_io_command "fpunch" + +rm -f "$seqres.full" + +TESTDIR="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original files" +BLKSZ=65536 +_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file1" >> "$seqres.full" +_pwrite_byte 0x62 $BLKSZ $BLKSZ "$TESTDIR/file1" >> "$seqres.full" +_pwrite_byte 0x63 $((BLKSZ * 2)) $BLKSZ "$TESTDIR/file1" >> "$seqres.full" + +_cp_reflink "$TESTDIR/file1" "$TESTDIR/file2" +_cp_reflink "$TESTDIR/file1" "$TESTDIR/file3" +_cp_reflink "$TESTDIR/file1" "$TESTDIR/file4" + +_pwrite_byte 0x00 0 $BLKSZ "$TESTDIR/file2.chk" >> "$seqres.full" +_pwrite_byte 0x62 $BLKSZ $BLKSZ "$TESTDIR/file2.chk" >> "$seqres.full" +_pwrite_byte 0x63 $((BLKSZ * 2)) $BLKSZ "$TESTDIR/file2.chk" >> "$seqres.full" + +_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file3.chk" >> "$seqres.full" +_pwrite_byte 0x00 $BLKSZ $BLKSZ "$TESTDIR/file3.chk" >> "$seqres.full" +_pwrite_byte 0x63 $((BLKSZ * 2)) $BLKSZ "$TESTDIR/file3.chk" >> "$seqres.full" + +_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file4.chk" >> "$seqres.full" +_pwrite_byte 0x62 $BLKSZ $BLKSZ "$TESTDIR/file4.chk" >> "$seqres.full" +_pwrite_byte 0x00 $((BLKSZ * 2)) $BLKSZ "$TESTDIR/file4.chk" >> "$seqres.full" +_test_remount + +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir +md5sum "$TESTDIR/file4" | _filter_test_dir +md5sum "$TESTDIR/file2.chk" | _filter_test_dir +md5sum "$TESTDIR/file3.chk" | _filter_test_dir +md5sum "$TESTDIR/file4.chk" | _filter_test_dir + +C1="$(_md5_checksum "$TESTDIR/file1")" +C2="$(_md5_checksum "$TESTDIR/file2")" +C3="$(_md5_checksum "$TESTDIR/file3")" +C4="$(_md5_checksum "$TESTDIR/file4")" + +test "${C1}" = "${C2}" || echo "file1 and file2 should match" +test "${C1}" = "${C3}" || echo "file1 and file3 should match" +test "${C1}" = "${C4}" || echo "file1 and file4 should match" +test "${C2}" = "${C3}" || echo "file2 and file3 should match" +test "${C2}" = "${C4}" || echo "file2 and file4 should match" +test "${C3}" = "${C4}" || echo "file3 and file4 should match" + +echo "fpunch files" +"$XFS_IO_PROG" -f -c "fpunch 0 $BLKSZ" "$TESTDIR/file2" +"$XFS_IO_PROG" -f -c "fpunch $BLKSZ $BLKSZ" "$TESTDIR/file3" +"$XFS_IO_PROG" -f -c "fpunch $((BLKSZ * 2)) $BLKSZ" "$TESTDIR/file4" +_test_remount + +echo "Compare files" +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir +md5sum "$TESTDIR/file4" | _filter_test_dir +md5sum "$TESTDIR/file2.chk" | _filter_test_dir +md5sum "$TESTDIR/file3.chk" | _filter_test_dir +md5sum "$TESTDIR/file4.chk" | _filter_test_dir + +C1="$(_md5_checksum "$TESTDIR/file1")" +C2="$(_md5_checksum "$TESTDIR/file2")" +C3="$(_md5_checksum "$TESTDIR/file3")" +C4="$(_md5_checksum "$TESTDIR/file4")" + +test "${C1}" != "${C2}" || echo "file1 and file2 should not match" +test "${C1}" != "${C3}" || echo "file1 and file3 should not match" +test "${C1}" != "${C4}" || echo "file1 and file4 should not match" +test "${C2}" != "${C3}" || echo "file2 and file3 should not match" +test "${C2}" != "${C4}" || echo "file2 and file4 should not match" +test "${C3}" != "${C4}" || echo "file3 and file4 should not match" + +echo "Compare against check files" +cmp -s "$TESTDIR/file2" "$TESTDIR/file2.chk" || echo "file2 and file2.chk do not match" +cmp -s "$TESTDIR/file3" "$TESTDIR/file3.chk" || echo "file3 and file3.chk do not match" +cmp -s "$TESTDIR/file4" "$TESTDIR/file4.chk" || echo "file4 and file4.chk do not match" + +# success, all done +status=0 +exit diff --git a/tests/generic/146.out b/tests/generic/146.out new file mode 100644 index 0000000..ead7e90 --- /dev/null +++ b/tests/generic/146.out @@ -0,0 +1,19 @@ +QA output created by 146 +Create the original files +856bb58abaf1ac79aa1aa45b7de7218b TEST_DIR/test-146/file1 +856bb58abaf1ac79aa1aa45b7de7218b TEST_DIR/test-146/file2 +856bb58abaf1ac79aa1aa45b7de7218b TEST_DIR/test-146/file3 +856bb58abaf1ac79aa1aa45b7de7218b TEST_DIR/test-146/file4 +e263fae701bc40c23a3edb20aad5573e TEST_DIR/test-146/file2.chk +91722d7c8baf83f300a8dc35f1ffcce2 TEST_DIR/test-146/file3.chk +c931e8500c1a56a5b7369f7f1b971690 TEST_DIR/test-146/file4.chk +fpunch files +Compare files +856bb58abaf1ac79aa1aa45b7de7218b TEST_DIR/test-146/file1 +e263fae701bc40c23a3edb20aad5573e TEST_DIR/test-146/file2 +91722d7c8baf83f300a8dc35f1ffcce2 TEST_DIR/test-146/file3 +c931e8500c1a56a5b7369f7f1b971690 TEST_DIR/test-146/file4 +e263fae701bc40c23a3edb20aad5573e TEST_DIR/test-146/file2.chk +91722d7c8baf83f300a8dc35f1ffcce2 TEST_DIR/test-146/file3.chk +c931e8500c1a56a5b7369f7f1b971690 TEST_DIR/test-146/file4.chk +Compare against check files diff --git a/tests/generic/147 b/tests/generic/147 new file mode 100755 index 0000000..c35bdd9 --- /dev/null +++ b/tests/generic/147 @@ -0,0 +1,139 @@ +#! /bin/bash +# FS QA Test No. 812 +# +# Ensure that insert range steps around reflinked ranges: +# - Create three reflink clones of a file +# - Insert into the start, middle, and end of the reflink range of each +# of the three files, respectively +# - Check that the reflinked areas are still there. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_reflink +_require_cp_reflink +_require_xfs_io_command "finsert" + +rm -f "$seqres.full" + +TESTDIR="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original files" +BLKSZ=65536 +_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file1" >> "$seqres.full" +_pwrite_byte 0x62 $BLKSZ $BLKSZ "$TESTDIR/file1" >> "$seqres.full" +_pwrite_byte 0x63 $((BLKSZ * 2)) $BLKSZ "$TESTDIR/file1" >> "$seqres.full" + +_cp_reflink "$TESTDIR/file1" "$TESTDIR/file2" +_cp_reflink "$TESTDIR/file1" "$TESTDIR/file3" +_cp_reflink "$TESTDIR/file1" "$TESTDIR/file4" + +_pwrite_byte 0x00 0 $BLKSZ "$TESTDIR/file2.chk" >> "$seqres.full" +_pwrite_byte 0x61 $BLKSZ $BLKSZ "$TESTDIR/file2.chk" >> "$seqres.full" +_pwrite_byte 0x62 $((BLKSZ * 2)) $BLKSZ "$TESTDIR/file2.chk" >> "$seqres.full" +_pwrite_byte 0x63 $((BLKSZ * 3)) $BLKSZ "$TESTDIR/file2.chk" >> "$seqres.full" + +_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file3.chk" >> "$seqres.full" +_pwrite_byte 0x00 $BLKSZ $BLKSZ "$TESTDIR/file3.chk" >> "$seqres.full" +_pwrite_byte 0x62 $((BLKSZ * 2)) $BLKSZ "$TESTDIR/file3.chk" >> "$seqres.full" +_pwrite_byte 0x63 $((BLKSZ * 3)) $BLKSZ "$TESTDIR/file3.chk" >> "$seqres.full" + +_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file4.chk" >> "$seqres.full" +_pwrite_byte 0x62 $BLKSZ $BLKSZ "$TESTDIR/file4.chk" >> "$seqres.full" +_pwrite_byte 0x00 $((BLKSZ * 2)) $BLKSZ "$TESTDIR/file4.chk" >> "$seqres.full" +_pwrite_byte 0x63 $((BLKSZ * 3)) $BLKSZ "$TESTDIR/file4.chk" >> "$seqres.full" +_test_remount + +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir +md5sum "$TESTDIR/file4" | _filter_test_dir +md5sum "$TESTDIR/file2.chk" | _filter_test_dir +md5sum "$TESTDIR/file3.chk" | _filter_test_dir +md5sum "$TESTDIR/file4.chk" | _filter_test_dir + +C1="$(_md5_checksum "$TESTDIR/file1")" +C2="$(_md5_checksum "$TESTDIR/file2")" +C3="$(_md5_checksum "$TESTDIR/file3")" +C4="$(_md5_checksum "$TESTDIR/file4")" + +test "${C1}" = "${C2}" || echo "file1 and file2 should match" +test "${C1}" = "${C3}" || echo "file1 and file3 should match" +test "${C1}" = "${C4}" || echo "file1 and file4 should match" +test "${C2}" = "${C3}" || echo "file2 and file3 should match" +test "${C2}" = "${C4}" || echo "file2 and file4 should match" +test "${C3}" = "${C4}" || echo "file3 and file4 should match" + +echo "finsert files" +"$XFS_IO_PROG" -f -c "finsert 0 $BLKSZ" "$TESTDIR/file2" +"$XFS_IO_PROG" -f -c "finsert $BLKSZ $BLKSZ" "$TESTDIR/file3" +"$XFS_IO_PROG" -f -c "finsert $((BLKSZ * 2)) $BLKSZ" "$TESTDIR/file4" +_test_remount + +echo "Compare files" +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir +md5sum "$TESTDIR/file4" | _filter_test_dir +md5sum "$TESTDIR/file2.chk" | _filter_test_dir +md5sum "$TESTDIR/file3.chk" | _filter_test_dir +md5sum "$TESTDIR/file4.chk" | _filter_test_dir + +C1="$(_md5_checksum "$TESTDIR/file1")" +C2="$(_md5_checksum "$TESTDIR/file2")" +C3="$(_md5_checksum "$TESTDIR/file3")" +C4="$(_md5_checksum "$TESTDIR/file4")" + +test "${C1}" != "${C2}" || echo "file1 and file2 should not match" +test "${C1}" != "${C3}" || echo "file1 and file3 should not match" +test "${C1}" != "${C4}" || echo "file1 and file4 should not match" +test "${C2}" != "${C3}" || echo "file2 and file3 should not match" +test "${C2}" != "${C4}" || echo "file2 and file4 should not match" +test "${C3}" != "${C4}" || echo "file3 and file4 should not match" + +echo "Compare against check files" +cmp -s "$TESTDIR/file2" "$TESTDIR/file2.chk" || echo "file2 and file2.chk do not match" +cmp -s "$TESTDIR/file3" "$TESTDIR/file3.chk" || echo "file3 and file3.chk do not match" +cmp -s "$TESTDIR/file4" "$TESTDIR/file4.chk" || echo "file4 and file4.chk do not match" + +# success, all done +status=0 +exit diff --git a/tests/generic/147.out b/tests/generic/147.out new file mode 100644 index 0000000..bee79c2 --- /dev/null +++ b/tests/generic/147.out @@ -0,0 +1,19 @@ +QA output created by 147 +Create the original files +856bb58abaf1ac79aa1aa45b7de7218b TEST_DIR/test-147/file1 +856bb58abaf1ac79aa1aa45b7de7218b TEST_DIR/test-147/file2 +856bb58abaf1ac79aa1aa45b7de7218b TEST_DIR/test-147/file3 +856bb58abaf1ac79aa1aa45b7de7218b TEST_DIR/test-147/file4 +2b0921503c9f661b7690ac5b42f01f97 TEST_DIR/test-147/file2.chk +c424badbaad621c331a8ef213b78ac2a TEST_DIR/test-147/file3.chk +33b4940294a1d94bee813907d6105ff7 TEST_DIR/test-147/file4.chk +finsert files +Compare files +856bb58abaf1ac79aa1aa45b7de7218b TEST_DIR/test-147/file1 +2b0921503c9f661b7690ac5b42f01f97 TEST_DIR/test-147/file2 +c424badbaad621c331a8ef213b78ac2a TEST_DIR/test-147/file3 +33b4940294a1d94bee813907d6105ff7 TEST_DIR/test-147/file4 +2b0921503c9f661b7690ac5b42f01f97 TEST_DIR/test-147/file2.chk +c424badbaad621c331a8ef213b78ac2a TEST_DIR/test-147/file3.chk +33b4940294a1d94bee813907d6105ff7 TEST_DIR/test-147/file4.chk +Compare against check files diff --git a/tests/generic/148 b/tests/generic/148 new file mode 100755 index 0000000..3d7a762 --- /dev/null +++ b/tests/generic/148 @@ -0,0 +1,116 @@ +#! /bin/bash +# FS QA Test No. 148 +# +# Ensure that truncating the last block in a reflinked file CoWs appropriately: +# - Create a file that doesn't end on a block boundary +# - Create two reflink clones of the file +# - Shorten one of the clones with truncate +# - Lengthen the other clone with truncate +# - Check that the reflinked areas are still there. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_reflink +_require_cp_reflink +_require_xfs_io_command "truncate" + +rm -f "$seqres.full" + +TESTDIR="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original files" +BLKSZ=65536 +_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file1" >> "$seqres.full" +_pwrite_byte 0x62 $BLKSZ 37 "$TESTDIR/file1" >> "$seqres.full" + +_cp_reflink "$TESTDIR/file1" "$TESTDIR/file2" +_cp_reflink "$TESTDIR/file1" "$TESTDIR/file3" + +_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file2.chk" >> "$seqres.full" +_pwrite_byte 0x62 $BLKSZ 34 "$TESTDIR/file2.chk" >> "$seqres.full" + +_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file3.chk" >> "$seqres.full" +_pwrite_byte 0x62 $BLKSZ 37 "$TESTDIR/file3.chk" >> "$seqres.full" +_pwrite_byte 0x00 $((BLKSZ + 37)) 3 "$TESTDIR/file3.chk" >> "$seqres.full" +_test_remount + +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir +md5sum "$TESTDIR/file2.chk" | _filter_test_dir +md5sum "$TESTDIR/file3.chk" | _filter_test_dir + +C1="$(_md5_checksum "$TESTDIR/file1")" +C2="$(_md5_checksum "$TESTDIR/file2")" +C3="$(_md5_checksum "$TESTDIR/file3")" + +test "${C1}" = "${C2}" || echo "file1 and file2 should match" +test "${C1}" = "${C3}" || echo "file1 and file3 should match" +test "${C2}" = "${C3}" || echo "file2 and file3 should match" + +echo "truncate files" +"$XFS_IO_PROG" -f -c "truncate $((BLKSZ + 34))" "$TESTDIR/file2" +"$XFS_IO_PROG" -f -c "truncate $((BLKSZ + 40))" "$TESTDIR/file3" +_test_remount + +echo "Compare files" +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir +md5sum "$TESTDIR/file2.chk" | _filter_test_dir +md5sum "$TESTDIR/file3.chk" | _filter_test_dir + +C1="$(_md5_checksum "$TESTDIR/file1")" +C2="$(_md5_checksum "$TESTDIR/file2")" +C3="$(_md5_checksum "$TESTDIR/file3")" + +test "${C1}" != "${C2}" || echo "file1 and file2 should not match" +test "${C1}" != "${C3}" || echo "file1 and file3 should not match" +test "${C2}" != "${C3}" || echo "file2 and file3 should not match" + +echo "Compare against check files" +cmp -s "$TESTDIR/file2" "$TESTDIR/file2.chk" || echo "file2 and file2.chk do not match" +cmp -s "$TESTDIR/file3" "$TESTDIR/file3.chk" || echo "file3 and file3.chk do not match" + +# success, all done +status=0 +exit diff --git a/tests/generic/148.out b/tests/generic/148.out new file mode 100644 index 0000000..1896d95 --- /dev/null +++ b/tests/generic/148.out @@ -0,0 +1,15 @@ +QA output created by 148 +Create the original files +f924bdda449af63913cad4357e39301e TEST_DIR/test-148/file1 +f924bdda449af63913cad4357e39301e TEST_DIR/test-148/file2 +f924bdda449af63913cad4357e39301e TEST_DIR/test-148/file3 +16cb529abe447a9f203a3d5eb3433c8b TEST_DIR/test-148/file2.chk +6f042ad39f6c74f4b73936db89baa2e2 TEST_DIR/test-148/file3.chk +truncate files +Compare files +f924bdda449af63913cad4357e39301e TEST_DIR/test-148/file1 +16cb529abe447a9f203a3d5eb3433c8b TEST_DIR/test-148/file2 +6f042ad39f6c74f4b73936db89baa2e2 TEST_DIR/test-148/file3 +16cb529abe447a9f203a3d5eb3433c8b TEST_DIR/test-148/file2.chk +6f042ad39f6c74f4b73936db89baa2e2 TEST_DIR/test-148/file3.chk +Compare against check files diff --git a/tests/generic/149 b/tests/generic/149 new file mode 100755 index 0000000..44b5ae4 --- /dev/null +++ b/tests/generic/149 @@ -0,0 +1,136 @@ +#! /bin/bash +# FS QA Test No. 813 +# +# Ensure that zero-range steps around reflinked ranges: +# - Create three reflink clones of a file +# - Zero-range the start, middle, and end of the reflink range of each +# of the three files, respectively +# - Check that the reflinked areas are still there. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_reflink +_require_cp_reflink +_require_xfs_io_command "fzero" + +rm -f "$seqres.full" + +TESTDIR="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original files" +BLKSZ=65536 +_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file1" >> "$seqres.full" +_pwrite_byte 0x62 $BLKSZ $BLKSZ "$TESTDIR/file1" >> "$seqres.full" +_pwrite_byte 0x63 $((BLKSZ * 2)) $BLKSZ "$TESTDIR/file1" >> "$seqres.full" + +_cp_reflink "$TESTDIR/file1" "$TESTDIR/file2" +_cp_reflink "$TESTDIR/file1" "$TESTDIR/file3" +_cp_reflink "$TESTDIR/file1" "$TESTDIR/file4" + +_pwrite_byte 0x00 0 $BLKSZ "$TESTDIR/file2.chk" >> "$seqres.full" +_pwrite_byte 0x62 $BLKSZ $BLKSZ "$TESTDIR/file2.chk" >> "$seqres.full" +_pwrite_byte 0x63 $((BLKSZ * 2)) $BLKSZ "$TESTDIR/file2.chk" >> "$seqres.full" + +_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file3.chk" >> "$seqres.full" +_pwrite_byte 0x00 $BLKSZ $BLKSZ "$TESTDIR/file3.chk" >> "$seqres.full" +_pwrite_byte 0x63 $((BLKSZ * 2)) $BLKSZ "$TESTDIR/file3.chk" >> "$seqres.full" + +_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file4.chk" >> "$seqres.full" +_pwrite_byte 0x62 $BLKSZ $BLKSZ "$TESTDIR/file4.chk" >> "$seqres.full" +_pwrite_byte 0x00 $((BLKSZ * 2)) $BLKSZ "$TESTDIR/file4.chk" >> "$seqres.full" +_test_remount + +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir +md5sum "$TESTDIR/file4" | _filter_test_dir +md5sum "$TESTDIR/file2.chk" | _filter_test_dir +md5sum "$TESTDIR/file3.chk" | _filter_test_dir +md5sum "$TESTDIR/file4.chk" | _filter_test_dir + +C1="$(_md5_checksum "$TESTDIR/file1")" +C2="$(_md5_checksum "$TESTDIR/file2")" +C3="$(_md5_checksum "$TESTDIR/file3")" +C4="$(_md5_checksum "$TESTDIR/file4")" + +test "${C1}" = "${C2}" || echo "file1 and file2 should match" +test "${C1}" = "${C3}" || echo "file1 and file3 should match" +test "${C1}" = "${C4}" || echo "file1 and file4 should match" +test "${C2}" = "${C3}" || echo "file2 and file3 should match" +test "${C2}" = "${C4}" || echo "file2 and file4 should match" +test "${C3}" = "${C4}" || echo "file3 and file4 should match" + +echo "fzero files" +"$XFS_IO_PROG" -f -c "fzero 0 $BLKSZ" "$TESTDIR/file2" +"$XFS_IO_PROG" -f -c "fzero $BLKSZ $BLKSZ" "$TESTDIR/file3" +"$XFS_IO_PROG" -f -c "fzero $((BLKSZ * 2)) $BLKSZ" "$TESTDIR/file4" +_test_remount + +echo "Compare files" +md5sum "$TESTDIR/file1" | _filter_test_dir +md5sum "$TESTDIR/file2" | _filter_test_dir +md5sum "$TESTDIR/file3" | _filter_test_dir +md5sum "$TESTDIR/file4" | _filter_test_dir +md5sum "$TESTDIR/file2.chk" | _filter_test_dir +md5sum "$TESTDIR/file3.chk" | _filter_test_dir +md5sum "$TESTDIR/file4.chk" | _filter_test_dir + +C1="$(_md5_checksum "$TESTDIR/file1")" +C2="$(_md5_checksum "$TESTDIR/file2")" +C3="$(_md5_checksum "$TESTDIR/file3")" +C4="$(_md5_checksum "$TESTDIR/file4")" + +test "${C1}" != "${C2}" || echo "file1 and file2 should not match" +test "${C1}" != "${C3}" || echo "file1 and file3 should not match" +test "${C1}" != "${C4}" || echo "file1 and file4 should not match" +test "${C2}" != "${C3}" || echo "file2 and file3 should not match" +test "${C2}" != "${C4}" || echo "file2 and file4 should not match" +test "${C3}" != "${C4}" || echo "file3 and file4 should not match" + +echo "Compare against check files" +cmp -s "$TESTDIR/file2" "$TESTDIR/file2.chk" || echo "file2 and file2.chk do not match" +cmp -s "$TESTDIR/file3" "$TESTDIR/file3.chk" || echo "file3 and file3.chk do not match" +cmp -s "$TESTDIR/file4" "$TESTDIR/file4.chk" || echo "file4 and file4.chk do not match" + +# success, all done +status=0 +exit diff --git a/tests/generic/149.out b/tests/generic/149.out new file mode 100644 index 0000000..dc3ceda --- /dev/null +++ b/tests/generic/149.out @@ -0,0 +1,19 @@ +QA output created by 149 +Create the original files +856bb58abaf1ac79aa1aa45b7de7218b TEST_DIR/test-149/file1 +856bb58abaf1ac79aa1aa45b7de7218b TEST_DIR/test-149/file2 +856bb58abaf1ac79aa1aa45b7de7218b TEST_DIR/test-149/file3 +856bb58abaf1ac79aa1aa45b7de7218b TEST_DIR/test-149/file4 +e263fae701bc40c23a3edb20aad5573e TEST_DIR/test-149/file2.chk +91722d7c8baf83f300a8dc35f1ffcce2 TEST_DIR/test-149/file3.chk +c931e8500c1a56a5b7369f7f1b971690 TEST_DIR/test-149/file4.chk +fzero files +Compare files +856bb58abaf1ac79aa1aa45b7de7218b TEST_DIR/test-149/file1 +e263fae701bc40c23a3edb20aad5573e TEST_DIR/test-149/file2 +91722d7c8baf83f300a8dc35f1ffcce2 TEST_DIR/test-149/file3 +c931e8500c1a56a5b7369f7f1b971690 TEST_DIR/test-149/file4 +e263fae701bc40c23a3edb20aad5573e TEST_DIR/test-149/file2.chk +91722d7c8baf83f300a8dc35f1ffcce2 TEST_DIR/test-149/file3.chk +c931e8500c1a56a5b7369f7f1b971690 TEST_DIR/test-149/file4.chk +Compare against check files diff --git a/tests/generic/group b/tests/generic/group index 7b55707..477c52b 100644 --- a/tests/generic/group +++ b/tests/generic/group @@ -146,6 +146,12 @@ 141 rw auto quick 142 auto quick clone 143 auto quick clone +144 auto quick clone +145 auto quick clone +146 auto quick clone +147 auto quick clone +148 auto quick clone +149 auto quick clone 169 rw metadata auto quick 184 metadata auto quick 192 atime auto From darrick.wong@oracle.com Fri Nov 13 15:38:02 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id B479F7F78 for ; Fri, 13 Nov 2015 15:38:01 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 17F3BAC008 for ; Fri, 13 Nov 2015 13:37:57 -0800 (PST) X-ASG-Debug-ID: 1447450673-04cb6c0cd442900001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id FR3YIzZVlShGgney (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 13 Nov 2015 13:37:53 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tADLbVOk000460 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 13 Nov 2015 21:37:31 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id tADLbVwW025259 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Fri, 13 Nov 2015 21:37:31 GMT Received: from abhmp0017.oracle.com (abhmp0017.oracle.com [141.146.116.23]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id tADLbV4F007418; Fri, 13 Nov 2015 21:37:31 GMT Received: from localhost (/71.198.20.188) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 13 Nov 2015 13:37:30 -0800 Subject: [PATCH 07/12] reflink: test accuracy of free block counts From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 07/12] reflink: test accuracy of free block counts To: david@fromorbit.com, darrick.wong@oracle.com Cc: fstests@vger.kernel.org, xfs@oss.sgi.com, hch@infradead.org, tao.peng@primarydata.com, linux-ext4@vger.kernel.org, Anna.Schumaker@netapp.com, linux-btrfs@vger.kernel.org Date: Fri, 13 Nov 2015 13:37:29 -0800 Message-ID: <20151113213729.31124.57712.stgit@birch.djwong.org> In-Reply-To: <20151113213643.31124.80975.stgit@birch.djwong.org> References: <20151113213643.31124.80975.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0022.oracle.com [141.146.126.234] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1447450673 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/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, UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24370 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.60 MARKETING_SUBJECT Subject contains popular marketing words 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Check that the free block counts seem to be handled correctly in the reflink operation and subsequent attempts to rewrite reflinked copies. Signed-off-by: Darrick J. Wong --- tests/generic/150 | 78 +++++++++++++++++++++++++++++++ tests/generic/150.out | 4 ++ tests/generic/151 | 98 +++++++++++++++++++++++++++++++++++++++ tests/generic/151.out | 8 +++ tests/generic/152 | 103 +++++++++++++++++++++++++++++++++++++++++ tests/generic/152.out | 8 +++ tests/generic/153 | 102 ++++++++++++++++++++++++++++++++++++++++ tests/generic/153.out | 8 +++ tests/generic/154 | 110 +++++++++++++++++++++++++++++++++++++++++++ tests/generic/154.out | 11 ++++ tests/generic/155 | 114 +++++++++++++++++++++++++++++++++++++++++++++ tests/generic/155.out | 11 ++++ tests/generic/156 | 124 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/156.out | 12 +++++ tests/generic/group | 7 +++ 15 files changed, 798 insertions(+) create mode 100755 tests/generic/150 create mode 100644 tests/generic/150.out create mode 100755 tests/generic/151 create mode 100644 tests/generic/151.out create mode 100755 tests/generic/152 create mode 100644 tests/generic/152.out create mode 100755 tests/generic/153 create mode 100644 tests/generic/153.out create mode 100755 tests/generic/154 create mode 100644 tests/generic/154.out create mode 100755 tests/generic/155 create mode 100644 tests/generic/155.out create mode 100755 tests/generic/156 create mode 100644 tests/generic/156.out diff --git a/tests/generic/150 b/tests/generic/150 new file mode 100755 index 0000000..3046e92 --- /dev/null +++ b/tests/generic/150 @@ -0,0 +1,78 @@ +#! /bin/bash +# FS QA Test No. 150 +# +# Ensure that reflinking a file N times doesn't eat a lot of blocks +# - Create a file and record fs block usage +# - Create some reflink copies +# - Compare fs block usage to before +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_reflink +_require_cp_reflink + +rm -f "$seqres.full" + +TESTDIR="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original file blocks" +BLKSZ="$(stat -f $TESTDIR -c '%S')" +BLKS=2000 +MARGIN=100 +SZ=$((BLKSZ * BLKS)) +NR=7 +_pwrite_byte 0x61 0 $SZ "$TESTDIR/file1" >> "$seqres.full" +sync +FREE_BLOCKS0=$(stat -f "$TESTDIR" -c '%f') + +echo "Create the reflink copies" +for i in `seq 2 $NR`; do + _cp_reflink "$TESTDIR/file1" "$TESTDIR/file.$i" +done +_test_remount +FREE_BLOCKS1=$(stat -f "$TESTDIR" -c '%f') + +_within_tolerance "free blocks after reflink" $FREE_BLOCKS1 $FREE_BLOCKS0 $MARGIN -v + +# success, all done +status=0 +exit diff --git a/tests/generic/150.out b/tests/generic/150.out new file mode 100644 index 0000000..94580a6 --- /dev/null +++ b/tests/generic/150.out @@ -0,0 +1,4 @@ +QA output created by 150 +Create the original file blocks +Create the reflink copies +free blocks after reflink is in range diff --git a/tests/generic/151 b/tests/generic/151 new file mode 100755 index 0000000..c42ca1d --- /dev/null +++ b/tests/generic/151 @@ -0,0 +1,98 @@ +#! /bin/bash +# FS QA Test No. 151 +# +# Ensure that deleting all copies of a file reflinked N times releases the blocks +# - Record fs block usage (0) +# - Create a file and some reflink copies +# - Record fs block usage (1) +# - Delete some copies of the file +# - Record fs block usage (2) +# - Delete all copies of the file +# - Compare fs block usage to (2), (1), and (0) +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_reflink +_require_cp_reflink + +rm -f "$seqres.full" + +TESTDIR="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original file blocks" +BLKSZ="$(stat -f "$TESTDIR" -c '%S')" +BLKS=2000 +MARGIN=100 +SZ=$((BLKSZ * BLKS)) +FREE_BLOCKS0=$(stat -f "$TESTDIR" -c '%f') +NR=7 +_pwrite_byte 0x61 0 $SZ "$TESTDIR/file1" >> "$seqres.full" +sync + +echo "Create the reflink copies" +for i in `seq 2 $NR`; do + _cp_reflink "$TESTDIR/file1" "$TESTDIR/file.$i" +done +_cp_reflink "$TESTDIR/file1" "$TESTDIR/survivor" +_test_remount +FREE_BLOCKS1=$(stat -f "$TESTDIR" -c '%f') + +echo "Delete most of the files" +rm -rf "$TESTDIR"/file* +_test_remount +FREE_BLOCKS2=$(stat -f "$TESTDIR" -c '%f') + +echo "Delete all the files" +rm -rf "$TESTDIR"/* +_test_remount +FREE_BLOCKS3=$(stat -f "$TESTDIR" -c '%f') +#echo $FREE_BLOCKS0 $FREE_BLOCKS1 $FREE_BLOCKS2 $FREE_BLOCKS3 + +_within_tolerance "free blocks after reflink" $FREE_BLOCKS1 $((FREE_BLOCKS0 - BLKS)) $MARGIN -v + +_within_tolerance "free blocks after deleting some reflink copies" $FREE_BLOCKS2 $FREE_BLOCKS1 $MARGIN -v + +_within_tolerance "free blocks after deleting all copies" $FREE_BLOCKS3 $FREE_BLOCKS0 $MARGIN -v + +# success, all done +status=0 +exit diff --git a/tests/generic/151.out b/tests/generic/151.out new file mode 100644 index 0000000..214be54 --- /dev/null +++ b/tests/generic/151.out @@ -0,0 +1,8 @@ +QA output created by 151 +Create the original file blocks +Create the reflink copies +Delete most of the files +Delete all the files +free blocks after reflink is in range +free blocks after deleting some reflink copies is in range +free blocks after deleting all copies is in range diff --git a/tests/generic/152 b/tests/generic/152 new file mode 100755 index 0000000..95ffe40 --- /dev/null +++ b/tests/generic/152 @@ -0,0 +1,103 @@ +#! /bin/bash +# FS QA Test No. 152 +# +# Ensure that punching all copies of a file reflinked N times releases the blocks +# - Record fs block usage (0) +# - Create a file and some reflink copies +# - Record fs block usage (1) +# - Punch some blocks of the copies +# - Record fs block usage (2) +# - Punch all blocks of the copies +# - Compare fs block usage to (2), (1), and (0) +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_reflink +_require_cp_reflink +_require_xfs_io_command "fpunch" + +rm -f "$seqres.full" + +TESTDIR="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original file blocks" +BLKSZ="$(stat -f "$TESTDIR" -c '%S')" +BLKS=2000 +MARGIN=100 +SZ=$((BLKSZ * BLKS)) +FREE_BLOCKS0=$(stat -f "$TESTDIR" -c '%f') +NR=4 +_pwrite_byte 0x61 0 $SZ "$TESTDIR/file1" >> "$seqres.full" +sync + +echo "Create the reflink copies" +for i in `seq 2 $NR`; do + _cp_reflink "$TESTDIR/file1" "$TESTDIR/file$i" +done +_test_remount +FREE_BLOCKS1=$(stat -f "$TESTDIR" -c '%f') + +echo "Punch most of the blocks" +"$XFS_IO_PROG" -f -c "fpunch 0 $SZ" "$TESTDIR/file2" +"$XFS_IO_PROG" -f -c "fpunch 0 $((SZ / 2))" "$TESTDIR/file3" +"$XFS_IO_PROG" -f -c "fpunch $((SZ / 2)) $((SZ / 2))" "$TESTDIR/file4" +_test_remount +FREE_BLOCKS2=$(stat -f "$TESTDIR" -c '%f') + +echo "Punch all the files" +for i in `seq 2 $NR`; do + "$XFS_IO_PROG" -f -c "fpunch 0 $SZ" "$TESTDIR/file$i" +done +"$XFS_IO_PROG" -f -c "fpunch 0 $SZ" "$TESTDIR/file1" +_test_remount +FREE_BLOCKS3=$(stat -f "$TESTDIR" -c '%f') +#echo $FREE_BLOCKS0 $FREE_BLOCKS1 $FREE_BLOCKS2 $FREE_BLOCKS3 + +_within_tolerance "free blocks after reflink" $FREE_BLOCKS1 $((FREE_BLOCKS0 - BLKS)) $MARGIN -v + +_within_tolerance "free blocks after punching some reflink copies" $FREE_BLOCKS2 $FREE_BLOCKS1 $MARGIN -v + +_within_tolerance "free blocks after punching all copies" $FREE_BLOCKS3 $FREE_BLOCKS0 $MARGIN -v + +# success, all done +status=0 +exit diff --git a/tests/generic/152.out b/tests/generic/152.out new file mode 100644 index 0000000..10b2003 --- /dev/null +++ b/tests/generic/152.out @@ -0,0 +1,8 @@ +QA output created by 152 +Create the original file blocks +Create the reflink copies +Punch most of the blocks +Punch all the files +free blocks after reflink is in range +free blocks after punching some reflink copies is in range +free blocks after punching all copies is in range diff --git a/tests/generic/153 b/tests/generic/153 new file mode 100755 index 0000000..2deee20 --- /dev/null +++ b/tests/generic/153 @@ -0,0 +1,102 @@ +#! /bin/bash +# FS QA Test No. 153 +# +# Ensure that collapse-range on all copies of a file reflinked N times releases the blocks +# - Record fs block usage (0) +# - Create a file and some reflink copies +# - Record fs block usage (1) +# - Collapse-range some blocks of the copies +# - Record fs block usage (2) +# - Truncate all blocks of the copies +# - Compare fs block usage to (2), (1), and (0) +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_reflink +_require_cp_reflink +_require_xfs_io_command "fcollapse" + +rm -f "$seqres.full" + +TESTDIR="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original file blocks" +BLKSZ="$(stat -f "$TESTDIR" -c '%S')" +BLKS=2000 +MARGIN=100 +SZ=$((BLKSZ * BLKS)) +FREE_BLOCKS0=$(stat -f "$TESTDIR" -c '%f') +NR=4 +_pwrite_byte 0x61 0 $SZ "$TESTDIR/file1" >> "$seqres.full" +_test_remount + +echo "Create the reflink copies" +for i in `seq 2 $NR`; do + _cp_reflink "$TESTDIR/file1" "$TESTDIR/file$i" +done +_test_remount +FREE_BLOCKS1=$(stat -f "$TESTDIR" -c '%f') + +echo "Collapse most of the blocks" +"$XFS_IO_PROG" -f -c "fcollapse 0 $(((BLKS - 1) * BLKSZ))" $TESTDIR/file2 +"$XFS_IO_PROG" -f -c "fcollapse 0 $((SZ / 2))" $TESTDIR/file3 +"$XFS_IO_PROG" -f -c "fcollapse $((SZ / 2)) $(( ((BLKS / 2) - 1) * BLKSZ))" $TESTDIR/file4 +_test_remount +FREE_BLOCKS2=$(stat -f "$TESTDIR" -c '%f') + +echo "Collpase nearly all the files" +"$XFS_IO_PROG" -f -c "fcollapse 0 $(( ((BLKS / 2) - 1) * BLKSZ))" $TESTDIR/file3 +"$XFS_IO_PROG" -f -c "fcollapse 0 $((SZ / 2))" $TESTDIR/file4 +"$XFS_IO_PROG" -f -c "fcollapse 0 $(( (BLKS - 1) * BLKSZ))" $TESTDIR/file1 +_test_remount +FREE_BLOCKS3=$(stat -f "$TESTDIR" -c '%f') +#echo $FREE_BLOCKS0 $FREE_BLOCKS1 $FREE_BLOCKS2 $FREE_BLOCKS3 + +_within_tolerance "free blocks after reflink" $FREE_BLOCKS1 $((FREE_BLOCKS0 - BLKS)) $MARGIN -v + +_within_tolerance "free blocks after fcollapsing some reflink copies" $FREE_BLOCKS2 $FREE_BLOCKS1 $MARGIN -v + +_within_tolerance "free blocks after fcollapsing all copies" $FREE_BLOCKS3 $FREE_BLOCKS0 $MARGIN -v + +# success, all done +status=0 +exit diff --git a/tests/generic/153.out b/tests/generic/153.out new file mode 100644 index 0000000..c9ff37c --- /dev/null +++ b/tests/generic/153.out @@ -0,0 +1,8 @@ +QA output created by 153 +Create the original file blocks +Create the reflink copies +Collapse most of the blocks +Collpase nearly all the files +free blocks after reflink is in range +free blocks after fcollapsing some reflink copies is in range +free blocks after fcollapsing all copies is in range diff --git a/tests/generic/154 b/tests/generic/154 new file mode 100755 index 0000000..173b981 --- /dev/null +++ b/tests/generic/154 @@ -0,0 +1,110 @@ +#! /bin/bash +# FS QA Test No. 154 +# +# Ensure that CoW on all copies of a file reflinked N times increases block count +# - Record fs block usage (0) +# - Create a file and some reflink copies +# - Record fs block usage (1) +# - CoW some blocks of the copies +# - Record fs block usage (2) +# - CoW all the rest of the blocks of the copies +# - Compare fs block usage to (2), (1), and (0) +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_reflink +_require_cp_reflink + +rm -f "$seqres.full" + +TESTDIR="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original file blocks" +BLKSZ="$(stat -f "$TESTDIR" -c '%S')" +BLKS=2000 +MARGIN=100 +FREE_BLOCKS0=$(stat -f "$TESTDIR" -c '%f') +NR=4 +SZ=$((BLKS * BLKSZ)) +_pwrite_byte 0x61 0 $SZ "$TESTDIR/file1" >> "$seqres.full" +_test_remount + +echo "Create the reflink copies" +for i in `seq 2 $NR`; do + _cp_reflink "$TESTDIR/file1" "$TESTDIR/file$i" +done +_test_remount +FREE_BLOCKS1=$(stat -f "$TESTDIR" -c '%f') + +echo "Rewrite some of the blocks" +_pwrite_byte 0x62 0 $SZ "$TESTDIR/file2" >> "$seqres.full" +_pwrite_byte 0x63 0 $((SZ / 2)) "$TESTDIR/file3" >> "$seqres.full" +_pwrite_byte 0x64 $((SZ / 2)) $((SZ / 2)) "$TESTDIR/file4" >> "$seqres.full" +_test_remount +FREE_BLOCKS2=$(stat -f "$TESTDIR" -c '%f') + +echo "Rewrite all the files" +_pwrite_byte 0x62 0 $SZ "$TESTDIR/file2" >> "$seqres.full" +_pwrite_byte 0x63 0 $SZ "$TESTDIR/file3" >> "$seqres.full" +_pwrite_byte 0x64 0 $SZ "$TESTDIR/file4" >> "$seqres.full" +_test_remount +FREE_BLOCKS3=$(stat -f "$TESTDIR" -c '%f') + +echo "Rewrite the original file" +_pwrite_byte 0x65 0 $SZ "$TESTDIR/file1" >> "$seqres.full" +_test_remount +FREE_BLOCKS4=$(stat -f "$TESTDIR" -c '%f') +#echo $FREE_BLOCKS0 $FREE_BLOCKS1 $FREE_BLOCKS2 $FREE_BLOCKS3 $FREE_BLOCKS4 + +_within_tolerance "free blocks after reflinking" $FREE_BLOCKS1 $((FREE_BLOCKS0 - BLKS)) $MARGIN -v + +_within_tolerance "free blocks after partially CoWing some copies" $FREE_BLOCKS2 $((FREE_BLOCKS1 - (2 * BLKS))) $MARGIN -v + +_within_tolerance "free blocks after CoWing all copies" $FREE_BLOCKS3 $((FREE_BLOCKS2 - BLKS)) $MARGIN -v + +_within_tolerance "free blocks after overwriting original" $FREE_BLOCKS4 $FREE_BLOCKS3 $MARGIN -v + +_within_tolerance "free blocks after all tests" $FREE_BLOCKS4 $((FREE_BLOCKS0 - (4 * BLKS))) $MARGIN -v + +# success, all done +status=0 +exit diff --git a/tests/generic/154.out b/tests/generic/154.out new file mode 100644 index 0000000..726b819 --- /dev/null +++ b/tests/generic/154.out @@ -0,0 +1,11 @@ +QA output created by 154 +Create the original file blocks +Create the reflink copies +Rewrite some of the blocks +Rewrite all the files +Rewrite the original file +free blocks after reflinking is in range +free blocks after partially CoWing some copies is in range +free blocks after CoWing all copies is in range +free blocks after overwriting original is in range +free blocks after all tests is in range diff --git a/tests/generic/155 b/tests/generic/155 new file mode 100755 index 0000000..2551295 --- /dev/null +++ b/tests/generic/155 @@ -0,0 +1,114 @@ +#! /bin/bash +# FS QA Test No. 155 +# +# Ensure that CoW on all copies of a file reflinked N times increases block count +# - Record fs block usage (0) +# - Create a file and some reflink copies +# - Record fs block usage (1) +# - CoW some blocks of the copies +# - Record fs block usage (2) +# - CoW all the rest of the blocks of the copies +# - Compare fs block usage to (2), (1), and (0) +# +# The main difference from 834 is that we use zero range, directio, and +# mmap to mix things up a bit. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_reflink +_require_cp_reflink +_require_xfs_io_command "fzero" + +rm -f "$seqres.full" + +TESTDIR=$TEST_DIR/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR + +echo "Create the original file blocks" +BLKSZ="$(stat -f "$TESTDIR" -c '%S')" +BLKS=2000 +MARGIN=100 +SZ=$((BLKSZ * BLKS)) +FREE_BLOCKS0=$(stat -f "$TESTDIR" -c '%f') +NR=4 +_pwrite_byte 0x61 0 $SZ "$TESTDIR/file1" >> "$seqres.full" +_test_remount + +echo "Create the reflink copies" +for i in `seq 2 $NR`; do + _cp_reflink "$TESTDIR/file1" "$TESTDIR/file$i" +done +_test_remount +FREE_BLOCKS1=$(stat -f "$TESTDIR" -c '%f') + +echo "Rewrite some of the blocks" +"$XFS_IO_PROG" -f -c "fzero 0 $SZ" "$TESTDIR/file2" >> "$seqres.full" +_pwrite_byte 0x63 0 $((SZ / 2)) "$TESTDIR/file3" -d >> "$seqres.full" +_mwrite_byte 0x64 $((SZ / 2)) $((SZ / 2)) $SZ "$TESTDIR/file4" >> "$seqres.full" +_test_remount +FREE_BLOCKS2=$(stat -f "$TESTDIR" -c '%f') + +echo "Rewrite all the files" +_pwrite_byte 0x62 0 $SZ "$TESTDIR/file2" -d >> "$seqres.full" +_mwrite_byte 0x63 0 $SZ $SZ "$TESTDIR/file3" >> "$seqres.full" +"$XFS_IO_PROG" -f -c "fzero 0 $SZ" $TESTDIR/file4 >> "$seqres.full" +_test_remount +FREE_BLOCKS3=$(stat -f "$TESTDIR" -c '%f') + +echo "Rewrite the original file" +_pwrite_byte 0x65 0 $SZ "$TESTDIR/file1" >> "$seqres.full" +_test_remount +FREE_BLOCKS4=$(stat -f "$TESTDIR" -c '%f') +#echo $FREE_BLOCKS0 $FREE_BLOCKS1 $FREE_BLOCKS2 $FREE_BLOCKS3 $FREE_BLOCKS4 + +_within_tolerance "free blocks after reflinking" $FREE_BLOCKS1 $((FREE_BLOCKS0 - BLKS)) $MARGIN -v + +_within_tolerance "free blocks after partially CoWing some copies" $FREE_BLOCKS2 $((FREE_BLOCKS1 - (2 * BLKS))) $MARGIN -v + +_within_tolerance "free blocks after CoWing all copies" $FREE_BLOCKS3 $((FREE_BLOCKS2 - BLKS)) $MARGIN -v + +_within_tolerance "free blocks after overwriting original" $FREE_BLOCKS4 $FREE_BLOCKS3 $MARGIN -v + +_within_tolerance "free blocks after all tests" $FREE_BLOCKS4 $((FREE_BLOCKS0 - (4 * BLKS))) $MARGIN -v + +# success, all done +status=0 +exit diff --git a/tests/generic/155.out b/tests/generic/155.out new file mode 100644 index 0000000..efb8faf --- /dev/null +++ b/tests/generic/155.out @@ -0,0 +1,11 @@ +QA output created by 155 +Create the original file blocks +Create the reflink copies +Rewrite some of the blocks +Rewrite all the files +Rewrite the original file +free blocks after reflinking is in range +free blocks after partially CoWing some copies is in range +free blocks after CoWing all copies is in range +free blocks after overwriting original is in range +free blocks after all tests is in range diff --git a/tests/generic/156 b/tests/generic/156 new file mode 100755 index 0000000..78b7e8c --- /dev/null +++ b/tests/generic/156 @@ -0,0 +1,124 @@ +#! /bin/bash +# FS QA Test No. 156 +# +# Ensure that fallocate on reflinked files actually CoWs the shared blocks. +# - Record fs block usage (0) +# - Create a file and some reflink copies +# - Record fs block usage (1) +# - funshare half of one of the copies +# - Record fs block usage (2) +# - funshare all of the copies +# - Record fs block usage (3) +# - rewrite the original file +# - Record fs block usage (4) +# - Compare fs block usage of 0-4 to ensure that block usage behaves as +# we expect. +# +# "funshare" refers to fallocate copy-on-writing the shared blocks +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/attr +. ./common/reflink + +if [ $FSTYP = "btrfs" ]; then + _notrun "btrfs doesn't handle unshare on fallocate" +fi + +# real QA test starts here +_supported_os Linux +_require_test_reflink +_require_cp_reflink +_require_xfs_io_command "falloc" + +rm -f "$seqres.full" + +TESTDIR="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original file blocks" +BLKSZ="$(stat -f "$TESTDIR" -c '%S')" +BLKS=2000 +MARGIN=100 +SZ=$((BLKSZ * BLKS)) +FREE_BLOCKS0=$(stat -f "$TESTDIR" -c '%f') +NR=4 +_pwrite_byte 0x61 0 $SZ "$TESTDIR/file1" >> "$seqres.full" +_test_remount + +echo "Create the reflink copies" +for i in `seq 2 $NR`; do + _cp_reflink "$TESTDIR/file1" "$TESTDIR/file$i" +done +_test_remount +FREE_BLOCKS1=$(stat -f "$TESTDIR" -c '%f') + +echo "funshare part of a file" +"$XFS_IO_PROG" -f -c "falloc 0 $((SZ / 2))" "$TESTDIR/file2" +_test_remount + +echo "funshare some of the copies" +"$XFS_IO_PROG" -f -c "falloc 0 $SZ" "$TESTDIR/file2" +"$XFS_IO_PROG" -f -c "falloc 0 $SZ" "$TESTDIR/file3" +_test_remount +FREE_BLOCKS2=$(stat -f "$TESTDIR" -c '%f') + +echo "funshare the rest of the files" +"$XFS_IO_PROG" -f -c "falloc 0 $SZ" "$TESTDIR/file4" +"$XFS_IO_PROG" -f -c "falloc 0 $SZ" "$TESTDIR/file1" +_test_remount +FREE_BLOCKS3=$(stat -f "$TESTDIR" -c '%f') + +echo "Rewrite the original file" +_pwrite_byte 0x65 0 $SZ "$TESTDIR/file1" >> "$seqres.full" +_test_remount +FREE_BLOCKS4=$(stat -f "$TESTDIR" -c '%f') +#echo $FREE_BLOCKS0 $FREE_BLOCKS1 $FREE_BLOCKS2 $FREE_BLOCKS3 $FREE_BLOCKS4 + +_within_tolerance "free blocks after reflinking" $FREE_BLOCKS1 $((FREE_BLOCKS0 - BLKS)) $MARGIN -v + +_within_tolerance "free blocks after nocow'ing some copies" $FREE_BLOCKS2 $((FREE_BLOCKS1 - (2 * BLKS))) $MARGIN -v + +_within_tolerance "free blocks after nocow'ing all copies" $FREE_BLOCKS3 $((FREE_BLOCKS2 - BLKS)) $MARGIN -v + +_within_tolerance "free blocks after overwriting original" $FREE_BLOCKS4 $FREE_BLOCKS3 $MARGIN -v + +_within_tolerance "free blocks after all tests" $FREE_BLOCKS4 $((FREE_BLOCKS0 - (4 * BLKS))) $MARGIN -v + +# success, all done +status=0 +exit diff --git a/tests/generic/156.out b/tests/generic/156.out new file mode 100644 index 0000000..d6fdc81 --- /dev/null +++ b/tests/generic/156.out @@ -0,0 +1,12 @@ +QA output created by 156 +Create the original file blocks +Create the reflink copies +funshare part of a file +funshare some of the copies +funshare the rest of the files +Rewrite the original file +free blocks after reflinking is in range +free blocks after nocow'ing some copies is in range +free blocks after nocow'ing all copies is in range +free blocks after overwriting original is in range +free blocks after all tests is in range diff --git a/tests/generic/group b/tests/generic/group index 477c52b..3141ae5 100644 --- a/tests/generic/group +++ b/tests/generic/group @@ -152,6 +152,13 @@ 147 auto quick clone 148 auto quick clone 149 auto quick clone +150 auto quick clone +151 auto quick clone +152 auto quick clone +153 auto quick clone +154 auto quick clone +155 auto quick clone +156 auto quick clone 169 rw metadata auto quick 184 metadata auto quick 192 atime auto From darrick.wong@oracle.com Fri Nov 13 15:38:06 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 82F0A7F5E for ; Fri, 13 Nov 2015 15:38:06 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 664F4304032 for ; Fri, 13 Nov 2015 13:38:06 -0800 (PST) X-ASG-Debug-ID: 1447450683-04cbb0605e47ec0001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id iwEpk3iAREIWg8Kk (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 13 Nov 2015 13:38:03 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tADLbcYR000552 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 13 Nov 2015 21:37:38 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id tADLbbYP010616 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Fri, 13 Nov 2015 21:37:37 GMT Received: from abhmp0007.oracle.com (abhmp0007.oracle.com [141.146.116.13]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id tADLbbvD026585; Fri, 13 Nov 2015 21:37:37 GMT Received: from localhost (/71.198.20.188) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 13 Nov 2015 13:37:37 -0800 Subject: [PATCH 08/12] reflink: test error conditions due to bad inputs From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 08/12] reflink: test error conditions due to bad inputs To: david@fromorbit.com, darrick.wong@oracle.com Cc: fstests@vger.kernel.org, xfs@oss.sgi.com, hch@infradead.org, tao.peng@primarydata.com, linux-ext4@vger.kernel.org, Anna.Schumaker@netapp.com, linux-btrfs@vger.kernel.org Date: Fri, 13 Nov 2015 13:37:36 -0800 Message-ID: <20151113213736.31124.61530.stgit@birch.djwong.org> In-Reply-To: <20151113213643.31124.80975.stgit@birch.djwong.org> References: <20151113213643.31124.80975.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0021.oracle.com [156.151.31.71] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1447450683 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24370 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Check that we can feed bad inputs to reflink/dedupe and it'll reject them. Signed-off-by: Darrick J. Wong --- tests/generic/157 | 122 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/157.out | 25 ++++++++++ tests/generic/158 | 123 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/158.out | 24 ++++++++++ tests/generic/159 | 74 +++++++++++++++++++++++++++++ tests/generic/159.out | 5 ++ tests/generic/160 | 74 +++++++++++++++++++++++++++++ tests/generic/160.out | 5 ++ tests/generic/group | 4 ++ 9 files changed, 456 insertions(+) create mode 100755 tests/generic/157 create mode 100644 tests/generic/157.out create mode 100755 tests/generic/158 create mode 100644 tests/generic/158.out create mode 100755 tests/generic/159 create mode 100755 tests/generic/159.out create mode 100755 tests/generic/160 create mode 100755 tests/generic/160.out diff --git a/tests/generic/157 b/tests/generic/157 new file mode 100755 index 0000000..a43fb0d --- /dev/null +++ b/tests/generic/157 @@ -0,0 +1,122 @@ +#! /bin/bash +# FS QA Test No. 157 +# +# Check that various invalid reflink scenarios are rejected. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR1" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/attr +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_reflink +_require_scratch_reflink + +rm -f "$seqres.full" + +echo "Format and mount" +_scratch_mkfs > "$seqres.full" 2>&1 +_scratch_mount >> "$seqres.full" 2>&1 + +TESTDIR1="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR1" +mkdir "$TESTDIR1" + +TESTDIR2=$SCRATCH_MNT/test-$seq +rm -rf "$TESTDIR2" +mkdir "$TESTDIR2" + +echo "Create the original files" +BLKSZ="$(stat -f $TESTDIR1 -c '%S')" +BLKS=1000 +MARGIN=50 +SZ=$((BLKSZ * BLKS)) +FREE_BLOCKS0=$(stat -f $TESTDIR1 -c '%f') +NR=4 +_pwrite_byte 0x61 0 $SZ "$TESTDIR1/file1" >> "$seqres.full" +_pwrite_byte 0x61 0 $SZ "$TESTDIR1/file2" >> "$seqres.full" +_pwrite_byte 0x61 0 $SZ "$TESTDIR2/file1" >> "$seqres.full" +_pwrite_byte 0x61 0 $SZ "$TESTDIR2/file2" >> "$seqres.full" +mkdir "$TESTDIR1/dir1" +seq 1 $((2 * BLKSZ / 250)) | while read f; do + touch "$TESTDIR1/dir1/$f" +done +mknod "$TESTDIR1/dev1" b 8 0 +mkfifo "$TESTDIR1/fifo1" +sync + +echo "Try cross-device reflink" +_reflink_range "$TESTDIR1/file1" 0 "$TESTDIR2/file1" 0 $BLKSZ + +echo "Try unaligned reflink" +_reflink_range "$TESTDIR1/file1" 37 "$TESTDIR1/file1" 59 23 + +echo "Try overlapping reflink" +_reflink_range "$TESTDIR1/file1" 0 "$TESTDIR1/file1" 1 $((BLKSZ * 2)) + +echo "Try reflink past EOF" +_reflink_range "$TESTDIR1/file1" $(( (BLKS + 10) * BLKSZ)) "$TESTDIR1/file1" 0 $BLKSZ + +echo "Try to reflink a dir" +_reflink_range "$TESTDIR1/dir1" 0 "$TESTDIR1/file2" 0 $BLKSZ + +echo "Try to reflink a device" +_reflink_range "$TESTDIR1/dev1" 0 "$TESTDIR1/file2" 0 $BLKSZ + +echo "Try to reflink to a dir" +_reflink_range "$TESTDIR1/file1" 0 "$TESTDIR1/dir1" 0 $BLKSZ + +echo "Try to reflink to a device" +_reflink_range "$TESTDIR1/file1" 0 "$TESTDIR1/dev1" 0 $BLKSZ + +echo "Try to reflink to a fifo" +_reflink_range "$TESTDIR1/file1" 0 "$TESTDIR1/fifo1" 0 $BLKSZ -n + +echo "Try to reflink an append-only file" +_reflink_range "$TESTDIR1/file1" 0 "$TESTDIR1/file3" 0 $BLKSZ -a + +echo "Reflink two files" +_reflink_range "$TESTDIR1/file1" 0 "$TESTDIR1/file2" 0 $BLKSZ >> "$seqres.full" +_reflink_range "$TESTDIR2/file1" 0 "$TESTDIR2/file2" 0 $BLKSZ >> "$seqres.full" + +echo "Check scratch fs" +umount $SCRATCH_MNT +_check_scratch_fs + +# success, all done +status=0 +exit diff --git a/tests/generic/157.out b/tests/generic/157.out new file mode 100644 index 0000000..177e7f8 --- /dev/null +++ b/tests/generic/157.out @@ -0,0 +1,25 @@ +QA output created by 157 +Format and mount +Create the original files +Try cross-device reflink +XFS_IOC_CLONE_RANGE: Invalid cross-device link +Try unaligned reflink +XFS_IOC_CLONE_RANGE: Invalid argument +Try overlapping reflink +XFS_IOC_CLONE_RANGE: Invalid argument +Try reflink past EOF +XFS_IOC_CLONE_RANGE: Invalid argument +Try to reflink a dir +XFS_IOC_CLONE_RANGE: Is a directory +Try to reflink a device +XFS_IOC_CLONE_RANGE: Invalid argument +Try to reflink to a dir +/mnt/test-157/dir1: Is a directory +Try to reflink to a device +XFS_IOC_CLONE_RANGE: Operation not supported +Try to reflink to a fifo +XFS_IOC_CLONE_RANGE: Operation not supported +Try to reflink an append-only file +XFS_IOC_CLONE_RANGE: Bad file descriptor +Reflink two files +Check scratch fs diff --git a/tests/generic/158 b/tests/generic/158 new file mode 100755 index 0000000..a499b21 --- /dev/null +++ b/tests/generic/158 @@ -0,0 +1,123 @@ +#! /bin/bash +# FS QA Test No. 158 +# +# Check that various invalid dedupe scenarios are rejected. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR1" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/attr +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_dedupe +_require_scratch_dedupe + +rm -f "$seqres.full" + +echo "Format and mount" +_scratch_mkfs > "$seqres.full" 2>&1 +_scratch_mount >> "$seqres.full" 2>&1 + +TESTDIR1="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR1" +mkdir "$TESTDIR1" + +TESTDIR2=$SCRATCH_MNT/test-$seq +rm -rf "$TESTDIR2" +mkdir "$TESTDIR2" + +echo "Create the original files" +BLKSZ="$(stat -f $TESTDIR1 -c '%S')" +BLKS=1000 +MARGIN=50 +SZ=$((BLKSZ * BLKS)) +FREE_BLOCKS0=$(stat -f $TESTDIR1 -c '%f') +NR=4 +_pwrite_byte 0x61 0 $SZ "$TESTDIR1/file1" >> "$seqres.full" +_pwrite_byte 0x61 0 $SZ "$TESTDIR1/file2" >> "$seqres.full" +_pwrite_byte 0x61 0 $SZ "$TESTDIR1/file3" >> "$seqres.full" +_pwrite_byte 0x61 0 $SZ "$TESTDIR2/file1" >> "$seqres.full" +_pwrite_byte 0x61 0 $SZ "$TESTDIR2/file2" >> "$seqres.full" +mkdir "$TESTDIR1/dir1" +seq 1 $((2 * BLKSZ / 250)) | while read f; do + touch "$TESTDIR1/dir1/$f" +done +mknod "$TESTDIR1/dev1" b 8 0 +mkfifo "$TESTDIR1/fifo1" +sync + +echo "Try cross-device dedupe" +_dedupe_range "$TESTDIR1/file1" 0 "$TESTDIR2/file1" 0 $BLKSZ + +echo "Try unaligned dedupe" +_dedupe_range "$TESTDIR1/file1" 37 "$TESTDIR1/file1" 59 23 + +echo "Try overlapping dedupe" +_dedupe_range "$TESTDIR1/file1" 0 "$TESTDIR1/file1" 1 $((BLKSZ * 2)) + +echo "Try dedupe past EOF" +_dedupe_range "$TESTDIR1/file1" $(( (BLKS + 10) * BLKSZ)) "$TESTDIR1/file1" 0 $BLKSZ + +echo "Try to dedupe a dir" +_dedupe_range "$TESTDIR1/dir1" 0 "$TESTDIR1/file2" 0 $BLKSZ + +echo "Try to dedupe a device" +_dedupe_range "$TESTDIR1/dev1" 0 "$TESTDIR1/file2" 0 $BLKSZ + +echo "Try to dedupe to a dir" +_dedupe_range "$TESTDIR1/file1" 0 "$TESTDIR1/dir1" 0 $BLKSZ + +echo "Try to dedupe to a device" +_dedupe_range "$TESTDIR1/file1" 0 "$TESTDIR1/dev1" 0 $BLKSZ + +echo "Try to dedupe to a fifo" +_dedupe_range "$TESTDIR1/file1" 0 "$TESTDIR1/fifo1" 0 $BLKSZ -n + +echo "Try to dedupe an append-only file" +_dedupe_range "$TESTDIR1/file1" 0 "$TESTDIR1/file3" 0 $BLKSZ -a >> "$seqres.full" + +echo "Dedupe two files" +_dedupe_range "$TESTDIR1/file1" 0 "$TESTDIR1/file2" 0 $BLKSZ >> "$seqres.full" +_dedupe_range "$TESTDIR2/file1" 0 "$TESTDIR2/file2" 0 $BLKSZ >> "$seqres.full" + +echo "Check scratch fs" +umount $SCRATCH_MNT +_check_scratch_fs + +# success, all done +status=0 +exit diff --git a/tests/generic/158.out b/tests/generic/158.out new file mode 100644 index 0000000..36a3f1f --- /dev/null +++ b/tests/generic/158.out @@ -0,0 +1,24 @@ +QA output created by 158 +Format and mount +Create the original files +Try cross-device dedupe +dedupe: Invalid cross-device link +Try unaligned dedupe +dedupe: Invalid argument +Try overlapping dedupe +dedupe: Invalid argument +Try dedupe past EOF +dedupe: Invalid argument +Try to dedupe a dir +XFS_IOC_FILE_EXTENT_SAME: Is a directory +Try to dedupe a device +XFS_IOC_FILE_EXTENT_SAME: Permission denied +Try to dedupe to a dir +/mnt/test-158/dir1: Is a directory +Try to dedupe to a device +dedupe: Permission denied +Try to dedupe to a fifo +dedupe: Permission denied +Try to dedupe an append-only file +Dedupe two files +Check scratch fs diff --git a/tests/generic/159 b/tests/generic/159 new file mode 100755 index 0000000..7944267 --- /dev/null +++ b/tests/generic/159 @@ -0,0 +1,74 @@ +#! /bin/bash +# FS QA Test No. 159 +# +# Check that we can't reflink immutable files +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR1" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/attr +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_lsattr +_require_test_reflink + +rm -f "$seqres.full" + +echo "Format and mount" +TESTDIR1="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR1" +mkdir "$TESTDIR1" + +echo "Create the original files" +BLKSZ="$(stat -f $TESTDIR1 -c '%S')" +BLKS=1000 +MARGIN=50 +SZ=$((BLKSZ * BLKS)) +FREE_BLOCKS0=$(stat -f $TESTDIR1 -c '%f') +NR=4 +_pwrite_byte 0x61 0 $SZ "$TESTDIR1/file1" >> "$seqres.full" +_pwrite_byte 0x61 0 $SZ "$TESTDIR1/file2" >> "$seqres.full" +sync + +echo "Try reflink on immutable files" +$CHATTR_PROG +i $TESTDIR1/file1 $TESTDIR1/file2 +_reflink_range "$TESTDIR1/file1" 0 "$TESTDIR1/file2" 0 $BLKSZ 2>&1 | _filter_test_dir +$CHATTR_PROG -i $TESTDIR1/file1 $TESTDIR1/file2 + +# success, all done +status=0 +exit diff --git a/tests/generic/159.out b/tests/generic/159.out new file mode 100755 index 0000000..92fe33a --- /dev/null +++ b/tests/generic/159.out @@ -0,0 +1,5 @@ +QA output created by 159 +Format and mount +Create the original files +Try reflink on immutable files +TEST_DIR/test-159/file2: Permission denied diff --git a/tests/generic/160 b/tests/generic/160 new file mode 100755 index 0000000..e8c43df --- /dev/null +++ b/tests/generic/160 @@ -0,0 +1,74 @@ +#! /bin/bash +# FS QA Test No. 160 +# +# Check that we can't dedupe immutable files +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR1" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/attr +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_lsattr +_require_test_dedupe + +rm -f "$seqres.full" + +echo "Format and mount" +TESTDIR1="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR1" +mkdir "$TESTDIR1" + +echo "Create the original files" +BLKSZ="$(stat -f $TESTDIR1 -c '%S')" +BLKS=1000 +MARGIN=50 +SZ=$((BLKSZ * BLKS)) +FREE_BLOCKS0=$(stat -f $TESTDIR1 -c '%f') +NR=4 +_pwrite_byte 0x61 0 $SZ "$TESTDIR1/file1" >> "$seqres.full" +_pwrite_byte 0x61 0 $SZ "$TESTDIR1/file2" >> "$seqres.full" +sync + +echo "Try dedupe on immutable files" +$CHATTR_PROG +i $TESTDIR1/file1 $TESTDIR1/file2 +_dedupe_range "$TESTDIR1/file1" 0 "$TESTDIR1/file2" 0 $BLKSZ 2>&1 | _filter_test_dir +$CHATTR_PROG -i $TESTDIR1/file1 $TESTDIR1/file2 + +# success, all done +status=0 +exit diff --git a/tests/generic/160.out b/tests/generic/160.out new file mode 100755 index 0000000..a999a9c --- /dev/null +++ b/tests/generic/160.out @@ -0,0 +1,5 @@ +QA output created by 160 +Format and mount +Create the original files +Try dedupe on immutable files +TEST_DIR/test-160/file2: Permission denied diff --git a/tests/generic/group b/tests/generic/group index 3141ae5..0a20421 100644 --- a/tests/generic/group +++ b/tests/generic/group @@ -159,6 +159,10 @@ 154 auto quick clone 155 auto quick clone 156 auto quick clone +157 auto quick clone +158 auto quick clone +159 auto quick clone +160 auto quick clone 169 rw metadata auto quick 184 metadata auto quick 192 atime auto From darrick.wong@oracle.com Fri Nov 13 15:38:13 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 01CC27F5E for ; Fri, 13 Nov 2015 15:38:13 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id BA5F1304039 for ; Fri, 13 Nov 2015 13:38:12 -0800 (PST) X-ASG-Debug-ID: 1447450687-04bdf07f0846ae0001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id qcKm0ffJJHoXUTTh (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 13 Nov 2015 13:38:08 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tADLbj8K000626 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 13 Nov 2015 21:37:46 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id tADLbjxl011328 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Fri, 13 Nov 2015 21:37:45 GMT Received: from abhmp0005.oracle.com (abhmp0005.oracle.com [141.146.116.11]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id tADLbiNE002463; Fri, 13 Nov 2015 21:37:44 GMT Received: from localhost (/71.198.20.188) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 13 Nov 2015 13:37:43 -0800 Subject: [PATCH 09/12] xfs: test xfs-specific reflink pieces From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 09/12] xfs: test xfs-specific reflink pieces To: david@fromorbit.com, darrick.wong@oracle.com Cc: fstests@vger.kernel.org, xfs@oss.sgi.com, hch@infradead.org, tao.peng@primarydata.com, linux-ext4@vger.kernel.org, Anna.Schumaker@netapp.com, linux-btrfs@vger.kernel.org Date: Fri, 13 Nov 2015 13:37:42 -0800 Message-ID: <20151113213742.31124.28249.stgit@birch.djwong.org> In-Reply-To: <20151113213643.31124.80975.stgit@birch.djwong.org> References: <20151113213643.31124.80975.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1447450688 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24371 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Check that the various XFS tools still work properly on reflinked XFSes. Signed-off-by: Darrick J. Wong --- tests/xfs/127 | 79 ++++++++++++++++++++++++++++ tests/xfs/127.out | 6 ++ tests/xfs/128 | 149 +++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/xfs/128.out | 27 ++++++++++ tests/xfs/129 | 87 +++++++++++++++++++++++++++++++ tests/xfs/129.out | 6 ++ tests/xfs/130 | 109 +++++++++++++++++++++++++++++++++++++++ tests/xfs/130.out | 13 +++++ tests/xfs/131 | 76 +++++++++++++++++++++++++++ tests/xfs/131.out | 6 ++ tests/xfs/132 | 130 ++++++++++++++++++++++++++++++++++++++++++++++ tests/xfs/132.out | 32 +++++++++++ tests/xfs/group | 6 ++ 13 files changed, 726 insertions(+) create mode 100755 tests/xfs/127 create mode 100644 tests/xfs/127.out create mode 100755 tests/xfs/128 create mode 100644 tests/xfs/128.out create mode 100755 tests/xfs/129 create mode 100644 tests/xfs/129.out create mode 100755 tests/xfs/130 create mode 100644 tests/xfs/130.out create mode 100755 tests/xfs/131 create mode 100644 tests/xfs/131.out create mode 100755 tests/xfs/132 create mode 100644 tests/xfs/132.out diff --git a/tests/xfs/127 b/tests/xfs/127 new file mode 100755 index 0000000..61301de --- /dev/null +++ b/tests/xfs/127 @@ -0,0 +1,79 @@ +#! /bin/bash +# FS QA Test No. 127 +# +# Tests xfs_growfs on a reflinked filesystem +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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/reflink + +# real QA test starts here +_supported_os Linux +_supported_fs xfs +_require_scratch_reflink +_require_cp_reflink + +echo "Format and mount" +_scratch_mkfs -d size=$((2 * 4096 * 4096)) -l size=4194304 > "$seqres.full" 2>&1 +_scratch_mount >> "$seqres.full" 2>&1 + +TESTDIR="$SCRATCH_MNT/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original file and reflink to copy1, copy2" +BLKSZ="$(stat -f "$TESTDIR" -c '%S')" +_pwrite_byte 0x61 0 $((BLKSZ * 14 + 71)) "$TESTDIR/original" >> "$seqres.full" +_cp_reflink "$TESTDIR/original" "$TESTDIR/copy1" +_cp_reflink "$TESTDIR/copy1" "$TESTDIR/copy2" + +echo "Grow fs" +"$XFS_GROWFS_PROG" "$SCRATCH_MNT" 2>&1 | _filter_growfs >> "$seqres.full" +_scratch_remount + +echo "Create more reflink copies" +_cp_reflink "$TESTDIR/original" "$TESTDIR/copy3" + +xfs_info "$SCRATCH_MNT" >> "$seqres.full" + +echo "Check scratch fs" +umount "$SCRATCH_MNT" +_check_scratch_fs + +# success, all done +status=0 +exit diff --git a/tests/xfs/127.out b/tests/xfs/127.out new file mode 100644 index 0000000..e4e76e2 --- /dev/null +++ b/tests/xfs/127.out @@ -0,0 +1,6 @@ +QA output created by 127 +Format and mount +Create the original file and reflink to copy1, copy2 +Grow fs +Create more reflink copies +Check scratch fs diff --git a/tests/xfs/128 b/tests/xfs/128 new file mode 100755 index 0000000..49652cb --- /dev/null +++ b/tests/xfs/128 @@ -0,0 +1,149 @@ +#! /bin/bash +# FS QA Test No. 128 +# +# Ensure that xfs_fsr un-reflinks files while defragmenting +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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/reflink + +# real QA test starts here +_supported_os Linux +_supported_fs xfs +_require_test_lsattr +_require_scratch_reflink +_require_cp_reflink + +echo "Format and mount" +_scratch_mkfs > "$seqres.full" 2>&1 +_scratch_mount >> "$seqres.full" 2>&1 + +TESTDIR="$SCRATCH_MNT/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" +FREE_BLOCKS0=$(stat -f "$TESTDIR" -c '%f') + +echo "Create the original file and reflink to file2, file3" +BLKS=2000 +MARGIN=100 +BLKSZ=65536 +REAL_BLKSZ="$(stat -f $TESTDIR -c '%S')" +BLKSZ_FACTOR=$((BLKSZ / REAL_BLKSZ)) +_pwrite_byte 0x61 0 $((BLKS * BLKSZ)) "$TESTDIR/file1" >> "$seqres.full" +_cp_reflink "$TESTDIR/file1" "$TESTDIR/file2" +_cp_reflink "$TESTDIR/file2" "$TESTDIR/file3" +_cp_reflink "$TESTDIR/file3" "$TESTDIR/file4" +_test_remount +FREE_BLOCKS1=$(stat -f "$TESTDIR" -c '%f') + +md5sum "$TESTDIR/file1" | _filter_scratch +md5sum "$TESTDIR/file2" | _filter_scratch +md5sum "$TESTDIR/file3" | _filter_scratch +md5sum "$TESTDIR/file4" | _filter_scratch + +C01=$(_md5_checksum "$TESTDIR/file1") +C02=$(_md5_checksum "$TESTDIR/file2") +C03=$(_md5_checksum "$TESTDIR/file3") +C04=$(_md5_checksum "$TESTDIR/file4") + +echo "CoW the reflink copies" +_pwrite_byte 0x62 $BLKSZ $BLKSZ "$TESTDIR/file2" >> "$seqres.full" +_pwrite_byte 0x63 $(( BLKSZ * (BLKS - 1) )) $BLKSZ "$TESTDIR/file3" >> "$seqres.full" +_test_remount +FREE_BLOCKS2=$(stat -f "$TESTDIR" -c '%f') + +md5sum "$TESTDIR/file1" | _filter_scratch +md5sum "$TESTDIR/file2" | _filter_scratch +md5sum "$TESTDIR/file3" | _filter_scratch +md5sum "$TESTDIR/file4" | _filter_scratch + +C11=$(_md5_checksum "$TESTDIR/file1") +C12=$(_md5_checksum "$TESTDIR/file2") +C13=$(_md5_checksum "$TESTDIR/file3") +C14=$(_md5_checksum "$TESTDIR/file4") + +echo "Defragment" +lsattr -l "$TESTDIR/" | _filter_scratch +xfs_fsr -v -d "$TESTDIR/file1" >> "$seqres.full" +xfs_fsr -v -d "$TESTDIR/file2" >> "$seqres.full" # fsr probably breaks the link +xfs_fsr -v -d "$TESTDIR/file3" >> "$seqres.full" # fsr probably breaks the link +xfs_fsr -v -d "$TESTDIR/file4" >> "$seqres.full" # fsr probably ignores this file +_test_remount +FREE_BLOCKS3=$(stat -f "$TESTDIR" -c '%f') + +md5sum "$TESTDIR/file1" | _filter_scratch +md5sum "$TESTDIR/file2" | _filter_scratch +md5sum "$TESTDIR/file3" | _filter_scratch +md5sum "$TESTDIR/file4" | _filter_scratch + +C21=$(_md5_checksum "$TESTDIR/file1") +C22=$(_md5_checksum "$TESTDIR/file2") +C23=$(_md5_checksum "$TESTDIR/file3") +C24=$(_md5_checksum "$TESTDIR/file4") + +echo "Check files" +test $C01 = $C02 || echo "Files 1-2 do not match" +test $C01 = $C03 || echo "Files 1-3 do not match" +test $C01 = $C04 || echo "Files 1-4 do not match" +test $C02 = $C03 || echo "Files 2-3 do not match" +test $C02 = $C04 || echo "Files 2-4 do not match" +test $C03 = $C04 || echo "Files 3-4 do not match" + +test $C01 = $C11 || echo "File1 should not be different after CoW" +test $C02 != $C12 || echo "File2 should be different after CoW" +test $C03 != $C13 || echo "File3 should be different after CoW" +test $C04 = $C14 || echo "File4 should not be different after CoW" + +test $C11 = $C21 || echo "File1 changed by defrag" +test $C12 = $C22 || echo "File2 changed by defrag" +test $C13 = $C23 || echo "File3 changed by defrag" +test $C14 = $C24 || echo "File4 changed by defrag" + +#echo $FREE_BLOCKS0 $FREE_BLOCKS1 $FREE_BLOCKS2 $FREE_BLOCKS3 + +_within_tolerance "free blocks after creating some reflink copies" $FREE_BLOCKS1 $((FREE_BLOCKS0 - (BLKS * BLKSZ_FACTOR) )) $MARGIN -v +_within_tolerance "free blocks after CoW some reflink copies" $FREE_BLOCKS2 $((FREE_BLOCKS1 - 2)) $MARGIN -v +_within_tolerance "free blocks after defragging all reflink copies" $FREE_BLOCKS3 $((FREE_BLOCKS2 - (BLKS * 2 * BLKSZ_FACTOR))) $MARGIN -v +_within_tolerance "free blocks after all tests" $FREE_BLOCKS3 $((FREE_BLOCKS0 - (BLKS * 3 * BLKSZ_FACTOR))) $MARGIN -v + +echo "Check scratch fs" +umount "$SCRATCH_MNT" +_check_scratch_fs + +# success, all done +status=0 +exit diff --git a/tests/xfs/128.out b/tests/xfs/128.out new file mode 100644 index 0000000..7e72dcd --- /dev/null +++ b/tests/xfs/128.out @@ -0,0 +1,27 @@ +QA output created by 128 +Format and mount +Create the original file and reflink to file2, file3 +b81534f439aac5c34ce3ed60a03eba70 SCRATCH_MNT/test-128/file1 +b81534f439aac5c34ce3ed60a03eba70 SCRATCH_MNT/test-128/file2 +b81534f439aac5c34ce3ed60a03eba70 SCRATCH_MNT/test-128/file3 +b81534f439aac5c34ce3ed60a03eba70 SCRATCH_MNT/test-128/file4 +CoW the reflink copies +b81534f439aac5c34ce3ed60a03eba70 SCRATCH_MNT/test-128/file1 +c650f1cf6c9f07b22e3e21ec7d49ded5 SCRATCH_MNT/test-128/file2 +56ed2f712c91e035adeeb26ed105a982 SCRATCH_MNT/test-128/file3 +b81534f439aac5c34ce3ed60a03eba70 SCRATCH_MNT/test-128/file4 +Defragment +SCRATCH_MNT/test-128/file1 --- +SCRATCH_MNT/test-128/file2 --- +SCRATCH_MNT/test-128/file3 --- +SCRATCH_MNT/test-128/file4 --- +b81534f439aac5c34ce3ed60a03eba70 SCRATCH_MNT/test-128/file1 +c650f1cf6c9f07b22e3e21ec7d49ded5 SCRATCH_MNT/test-128/file2 +56ed2f712c91e035adeeb26ed105a982 SCRATCH_MNT/test-128/file3 +b81534f439aac5c34ce3ed60a03eba70 SCRATCH_MNT/test-128/file4 +Check files +free blocks after creating some reflink copies is in range +free blocks after CoW some reflink copies is in range +free blocks after defragging all reflink copies is in range +free blocks after all tests is in range +Check scratch fs diff --git a/tests/xfs/129 b/tests/xfs/129 new file mode 100755 index 0000000..6279d69 --- /dev/null +++ b/tests/xfs/129 @@ -0,0 +1,87 @@ +#! /bin/bash +# FS QA Test No. 129 +# +# Ensure that we can create enough distinct reflink entries to force creation +# of a multi-level refcount btree, and that metadump will successfully copy +# said block. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 / + umount "$SCRATCH_MNT" > /dev/null 2>&1 + rm -rf "$tmp".* "$TESTDIR" "$METADUMP_FILE" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_supported_fs xfs +_require_scratch_reflink + +rm -f "$seqres.full" + +_scratch_mkfs >/dev/null 2>&1 +_scratch_mount + +TESTDIR="$SCRATCH_MNT/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" +METADUMP_FILE="$TEST_DIR/${seq}_metadump" + +echo "Create the original file blocks" +BLKSZ="$(stat -f "$TESTDIR" -c '%S')" +NR_BLKS=$((4 * BLKSZ / 12)) +_pwrite_byte 0x61 0 $((BLKSZ * NR_BLKS)) "$TESTDIR/file1" >> "$seqres.full" + +echo "Reflink every other block" +seq 1 $((NR_BLKS / 2)) | while read nr; do + _reflink_range "$TESTDIR/file1" $((nr * 2 * BLKSZ)) \ + "$TESTDIR/file2" $((nr * 2 * BLKSZ)) $BLKSZ >> "$seqres.full" +done + +echo "Create metadump file" +_scratch_unmount +_scratch_metadump "$METADUMP_FILE" + +# Now restore the obfuscated one back and take a look around +echo "Restore metadump" +xfs_mdrestore "$METADUMP_FILE" "$TEST_DIR/image" +_mount -t $FSTYP "$TEST_DIR/image" "$SCRATCH_MNT" +umount "$SCRATCH_MNT" + +echo "Check restored fs" +_check_generic_filesystem "$METADUMP_FILE" + +# success, all done +status=0 +exit diff --git a/tests/xfs/129.out b/tests/xfs/129.out new file mode 100644 index 0000000..da6f43f --- /dev/null +++ b/tests/xfs/129.out @@ -0,0 +1,6 @@ +QA output created by 129 +Create the original file blocks +Reflink every other block +Create metadump file +Restore metadump +Check restored fs diff --git a/tests/xfs/130 b/tests/xfs/130 new file mode 100755 index 0000000..b64ea8c --- /dev/null +++ b/tests/xfs/130 @@ -0,0 +1,109 @@ +#! /bin/bash +# FS QA Test No. 130 +# +# Create and populate an XFS filesystem, corrupt the refcount btree, +# then see how the kernel and xfs_repair deal with it. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015 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.* +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/attr +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_supported_fs xfs +_require_scratch_reflink +_require_cp_reflink +test -n "${FORCE_FUZZ}" || _require_scratch_xfs_crc + +rm -f "$seqres.full" + +echo "+ create scratch fs" +_scratch_mkfs_xfs > /dev/null + +echo "+ mount fs image" +_scratch_mount +blksz="$(stat -f -c '%s' "${SCRATCH_MNT}")" +agcount="$(xfs_info "${SCRATCH_MNT}" | grep agcount= | sed -e 's/^.*agcount=\([0-9]*\),.*$/\1/g')" + +echo "+ make some files" +_pwrite_byte 0x62 0 $((blksz * 64)) "${SCRATCH_MNT}/file0" >> "$seqres.full" +_pwrite_byte 0x61 0 $((blksz * 64)) "${SCRATCH_MNT}/file1" >> "$seqres.full" +_cp_reflink "${SCRATCH_MNT}/file0" "${SCRATCH_MNT}/file2" +_cp_reflink "${SCRATCH_MNT}/file1" "${SCRATCH_MNT}/file3" +umount "${SCRATCH_MNT}" + +echo "+ check fs" +_scratch_xfs_repair -n >> "$seqres.full" 2>&1 || \ + _fail "xfs_repair should not fail" + +echo "+ corrupt image" +seq 0 $((agcount - 1)) | while read ag; do + $XFS_DB_PROG -x -c "agf ${ag}" -c "agf ${ag}" -c "addr refcntroot" \ + -c "stack" -c "blocktrash -x 4096 -y 4096 -z -n 8 -3" \ + "${SCRATCH_DEV}" >> "$seqres.full" 2>&1 +done + +echo "+ mount image" +_scratch_mount + +echo "+ reflink more" +_cp_reflink "${SCRATCH_MNT}/file1" "${SCRATCH_MNT}/file4" 2> /dev/null && \ + _fail "should not be able to reflink with busted refcount btree" +umount "${SCRATCH_MNT}" + +echo "+ repair fs" +_scratch_xfs_repair >> "$seqres.full" 2>&1 +_scratch_xfs_repair >> "$seqres.full" 2>&1 + +echo "+ mount image (2)" +_scratch_mount + +echo "+ chattr -R -i" +chattr -R -f -i "${SCRATCH_MNT}/" + +echo "+ reflink more (2)" +_cp_reflink "${SCRATCH_MNT}/file1" "${SCRATCH_MNT}/file5" || \ + _fail "modified refcount tree" +umount "${SCRATCH_MNT}" + +echo "+ check fs (2)" +_scratch_xfs_repair -n >> "$seqres.full" 2>&1 || \ + _fail "xfs_repair should not fail" + +status=0 +exit diff --git a/tests/xfs/130.out b/tests/xfs/130.out new file mode 100644 index 0000000..58d153b --- /dev/null +++ b/tests/xfs/130.out @@ -0,0 +1,13 @@ +QA output created by 130 ++ create scratch fs ++ mount fs image ++ make some files ++ check fs ++ corrupt image ++ mount image ++ reflink more ++ repair fs ++ mount image (2) ++ chattr -R -i ++ reflink more (2) ++ check fs (2) diff --git a/tests/xfs/131 b/tests/xfs/131 new file mode 100755 index 0000000..5d092f1 --- /dev/null +++ b/tests/xfs/131 @@ -0,0 +1,76 @@ +#! /bin/bash +# FS QA Test No. 131 +# +# Ensure that we can't reflink realtime files. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 / + umount "$SCRATCH_MNT" > /dev/null 2>&1 + rm -rf "$tmp".* "$TESTDIR" "$METADUMP_FILE" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_supported_fs xfs +_require_realtime +_require_scratch_reflink +_require_cp_reflink + +rm -f "$seqres.full" + +echo "Format and mount scratch device" +_scratch_mkfs >> "$seqres.full" +_scratch_mount + +TESTDIR="$SCRATCH_MNT/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original file blocks" +BLKSZ=65536 +$XFS_IO_PROG -R -f -c "truncate $BLKSZ" "$TESTDIR/file1" + +echo "Reflink every block" +_cp_reflink "$TESTDIR/file1" "$TESTDIR/file2" 2>&1 | _filter_scratch + +test -s "$TESTDIR/file2" && _fail "Should not be able to reflink a realtime file." + +echo "Check restored fs" +umount "$SCRATCH_MNT" +_check_scratch_fs + +# success, all done +status=0 +exit diff --git a/tests/xfs/131.out b/tests/xfs/131.out new file mode 100644 index 0000000..7b700c9 --- /dev/null +++ b/tests/xfs/131.out @@ -0,0 +1,6 @@ +QA output created by 131 +Format and mount scratch device +Create the original file blocks +Reflink every block +cp: failed to clone 'SCRATCH_MNT/test-131/file2' from 'SCRATCH_MNT/test-131/file1': Invalid argument +Check restored fs diff --git a/tests/xfs/132 b/tests/xfs/132 new file mode 100755 index 0000000..ec7b178 --- /dev/null +++ b/tests/xfs/132 @@ -0,0 +1,130 @@ +#! /bin/bash +# FS QA Test No. 132 +# +# Ensure that fallocate on reflinked files actually CoWs the shared blocks. +# - Record fs block usage (0) +# - Create a file and some reflink copies +# - Record fs block usage (1) +# - funshare half of one of the copies +# - Record fs block usage (2) +# - funshare all of the copies +# - Record fs block usage (3) +# - rewrite the original file +# - Record fs block usage (4) +# - Compare fs block usage of 0-4 to ensure that block usage behaves as +# we expect. +# - Compare the status of the inode reflink flag at each step. +# +# "funshare" refers to fallocate copy-on-writing the shared blocks +# +# This is the same test as generic/156 except that we also check the inode +# reflink flag. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/attr +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_test_reflink +_require_test_lsattr +_require_cp_reflink +_require_xfs_io_command "falloc" + +rm -f "$seqres.full" + +TESTDIR="$TEST_DIR/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create the original file blocks" +BLKSZ="$(stat -f "$TESTDIR" -c '%S')" +BLKS=2000 +MARGIN=100 +SZ=$((BLKSZ * BLKS)) +FREE_BLOCKS0=$(stat -f "$TESTDIR" -c '%f') +NR=4 +_pwrite_byte 0x61 0 $SZ "$TESTDIR/file1" >> "$seqres.full" +_test_remount + +echo "Create the reflink copies" +for i in `seq 2 $NR`; do + _cp_reflink "$TESTDIR/file1" "$TESTDIR/file$i" +done +_test_remount +FREE_BLOCKS1=$(stat -f "$TESTDIR" -c '%f') +lsattr -l $TESTDIR/ | _filter_test_dir + +echo "funshare part of a file" +"$XFS_IO_PROG" -f -c "falloc 0 $((SZ / 2))" "$TESTDIR/file2" +_test_remount +lsattr -l $TESTDIR/ | _filter_test_dir + +echo "funshare some of the copies" +"$XFS_IO_PROG" -f -c "falloc 0 $SZ" "$TESTDIR/file2" +"$XFS_IO_PROG" -f -c "falloc 0 $SZ" "$TESTDIR/file3" +_test_remount +FREE_BLOCKS2=$(stat -f "$TESTDIR" -c '%f') +lsattr -l $TESTDIR/ | _filter_test_dir + +echo "funshare the rest of the files" +"$XFS_IO_PROG" -f -c "falloc 0 $SZ" "$TESTDIR/file4" +"$XFS_IO_PROG" -f -c "falloc 0 $SZ" "$TESTDIR/file1" +_test_remount +FREE_BLOCKS3=$(stat -f "$TESTDIR" -c '%f') +lsattr -l $TESTDIR/ | _filter_test_dir + +echo "Rewrite the original file" +_pwrite_byte 0x65 0 $SZ "$TESTDIR/file1" >> "$seqres.full" +_test_remount +FREE_BLOCKS4=$(stat -f "$TESTDIR" -c '%f') +lsattr -l $TESTDIR/ | _filter_test_dir +#echo $FREE_BLOCKS0 $FREE_BLOCKS1 $FREE_BLOCKS2 $FREE_BLOCKS3 $FREE_BLOCKS4 + +_within_tolerance "free blocks after reflinking" $FREE_BLOCKS1 $((FREE_BLOCKS0 - BLKS)) $MARGIN -v + +_within_tolerance "free blocks after nocow'ing some copies" $FREE_BLOCKS2 $((FREE_BLOCKS1 - (2 * BLKS))) $MARGIN -v + +_within_tolerance "free blocks after nocow'ing all copies" $FREE_BLOCKS3 $((FREE_BLOCKS2 - BLKS)) $MARGIN -v + +_within_tolerance "free blocks after overwriting original" $FREE_BLOCKS4 $FREE_BLOCKS3 $MARGIN -v + +_within_tolerance "free blocks after all tests" $FREE_BLOCKS4 $((FREE_BLOCKS0 - (4 * BLKS))) $MARGIN -v + +# success, all done +status=0 +exit diff --git a/tests/xfs/132.out b/tests/xfs/132.out new file mode 100644 index 0000000..fd2b7bd --- /dev/null +++ b/tests/xfs/132.out @@ -0,0 +1,32 @@ +QA output created by 132 +Create the original file blocks +Create the reflink copies +TEST_DIR/test-132/file1 --- +TEST_DIR/test-132/file2 --- +TEST_DIR/test-132/file3 --- +TEST_DIR/test-132/file4 --- +funshare part of a file +TEST_DIR/test-132/file1 --- +TEST_DIR/test-132/file2 --- +TEST_DIR/test-132/file3 --- +TEST_DIR/test-132/file4 --- +funshare some of the copies +TEST_DIR/test-132/file1 --- +TEST_DIR/test-132/file2 No_COW +TEST_DIR/test-132/file3 No_COW +TEST_DIR/test-132/file4 --- +funshare the rest of the files +TEST_DIR/test-132/file1 No_COW +TEST_DIR/test-132/file2 No_COW +TEST_DIR/test-132/file3 No_COW +TEST_DIR/test-132/file4 No_COW +Rewrite the original file +TEST_DIR/test-132/file1 No_COW +TEST_DIR/test-132/file2 No_COW +TEST_DIR/test-132/file3 No_COW +TEST_DIR/test-132/file4 No_COW +free blocks after reflinking is in range +free blocks after nocow'ing some copies is in range +free blocks after nocow'ing all copies is in range +free blocks after overwriting original is in range +free blocks after all tests is in range diff --git a/tests/xfs/group b/tests/xfs/group index 8261f86..9884329 100644 --- a/tests/xfs/group +++ b/tests/xfs/group @@ -124,6 +124,12 @@ 124 fuzzers 125 fuzzers 126 fuzzers +127 auto quick clone +128 auto quick clone +129 auto quick clone +130 fuzzers +131 auto quick clone +132 auto quick clone 134 quota auto quick 136 attr2 142 dmapi From darrick.wong@oracle.com Fri Nov 13 15:38:23 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 ECE357F6F for ; Fri, 13 Nov 2015 15:38:22 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id DEE538F8033 for ; Fri, 13 Nov 2015 13:38:22 -0800 (PST) X-ASG-Debug-ID: 1447450697-04cb6c0cd142950001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id dH7AeJiFdtGuWC3U (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 13 Nov 2015 13:38:18 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tADLbqqu000706 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 13 Nov 2015 21:37:52 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id tADLbpx0025926 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Fri, 13 Nov 2015 21:37:52 GMT Received: from abhmp0005.oracle.com (abhmp0005.oracle.com [141.146.116.11]) by userv0121.oracle.com (8.13.8/8.13.8) with ESMTP id tADLboPd028684; Fri, 13 Nov 2015 21:37:50 GMT Received: from localhost (/71.198.20.188) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 13 Nov 2015 13:37:50 -0800 Subject: [PATCH 10/12] reflink: concurrent operations tests From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 10/12] reflink: concurrent operations tests To: david@fromorbit.com, darrick.wong@oracle.com Cc: fstests@vger.kernel.org, xfs@oss.sgi.com, hch@infradead.org, tao.peng@primarydata.com, linux-ext4@vger.kernel.org, Anna.Schumaker@netapp.com, linux-btrfs@vger.kernel.org Date: Fri, 13 Nov 2015 13:37:49 -0800 Message-ID: <20151113213749.31124.34969.stgit@birch.djwong.org> In-Reply-To: <20151113213643.31124.80975.stgit@birch.djwong.org> References: <20151113213643.31124.80975.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0022.oracle.com [141.146.126.234] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1447450698 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24370 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Make sure that running reflink ops while other IO is ongoing doesn't break the filesystem. Signed-off-by: Darrick J. Wong --- tests/generic/161 | 79 +++++++++++++++++++++++++++++++++++++ tests/generic/161.out | 6 +++ tests/generic/162 | 95 ++++++++++++++++++++++++++++++++++++++++++++ tests/generic/162.out | 7 +++ tests/generic/163 | 95 ++++++++++++++++++++++++++++++++++++++++++++ tests/generic/163.out | 7 +++ tests/generic/164 | 105 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/164.out | 7 +++ tests/generic/165 | 105 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/165.out | 7 +++ tests/generic/166 | 93 +++++++++++++++++++++++++++++++++++++++++++ tests/generic/166.out | 6 +++ tests/generic/167 | 93 +++++++++++++++++++++++++++++++++++++++++++ tests/generic/167.out | 6 +++ tests/generic/168 | 97 +++++++++++++++++++++++++++++++++++++++++++++ tests/generic/168.out | 6 +++ tests/generic/170 | 97 +++++++++++++++++++++++++++++++++++++++++++++ tests/generic/170.out | 6 +++ tests/generic/group | 9 ++++ 19 files changed, 926 insertions(+) create mode 100755 tests/generic/161 create mode 100644 tests/generic/161.out create mode 100755 tests/generic/162 create mode 100644 tests/generic/162.out create mode 100755 tests/generic/163 create mode 100644 tests/generic/163.out create mode 100755 tests/generic/164 create mode 100644 tests/generic/164.out create mode 100755 tests/generic/165 create mode 100644 tests/generic/165.out create mode 100755 tests/generic/166 create mode 100644 tests/generic/166.out create mode 100755 tests/generic/167 create mode 100644 tests/generic/167.out create mode 100755 tests/generic/168 create mode 100644 tests/generic/168.out create mode 100755 tests/generic/170 create mode 100644 tests/generic/170.out diff --git a/tests/generic/161 b/tests/generic/161 new file mode 100755 index 0000000..efb137c --- /dev/null +++ b/tests/generic/161 @@ -0,0 +1,79 @@ +#! /bin/bash +# FS QA Test No. 161 +# +# Test for race between delete a file while rewriting its reflinked twin +# +#----------------------------------------------------------------------- +# Copyright (c) 2015 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 7 15 + +_cleanup() +{ + cd / + rm -rf "$tmp".* + wait +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_scratch_reflink +_require_cp_reflink + +echo "Format and mount" +_scratch_mkfs > "$seqres.full" 2>&1 +_scratch_mount >> "$seqres.full" 2>&1 + +TESTDIR="$SCRATCH_MNT/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +loops=4096 +BLKSZ=65536 + +echo "Initialize files" +echo > "$seqres.full" +_pwrite_byte 0x61 0 $((loops * BLKSZ)) "$TESTDIR/file1" >> "$seqres.full" +_cp_reflink "$TESTDIR/file1" "$TESTDIR/file2" +_scratch_remount + +echo "Delete while rewriting" +rm -rf "$TESTDIR/file1" & +_pwrite_byte 0x62 0 $((loops * BLKSZ)) "$TESTDIR/file1" >> "$seqres.full" +wait + +echo "Check fs" +umount "$SCRATCH_MNT" +_check_scratch_fs + +echo "Done" +# success, all done +status=0 +exit diff --git a/tests/generic/161.out b/tests/generic/161.out new file mode 100644 index 0000000..1db11c3 --- /dev/null +++ b/tests/generic/161.out @@ -0,0 +1,6 @@ +QA output created by 161 +Format and mount +Initialize files +Delete while rewriting +Check fs +Done diff --git a/tests/generic/162 b/tests/generic/162 new file mode 100755 index 0000000..6bd3a33 --- /dev/null +++ b/tests/generic/162 @@ -0,0 +1,95 @@ +#! /bin/bash +# FS QA Test No. 162 +# +# Test for race between dedupe and writing the dest file +# +#----------------------------------------------------------------------- +# Copyright (c) 2015 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 7 15 + +_cleanup() +{ + cd / + rm -rf "$tmp".* + wait +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_scratch_dedupe + +echo "Format and mount" +_scratch_mkfs > "$seqres.full" 2>&1 +_scratch_mount >> "$seqres.full" 2>&1 + +TESTDIR="$SCRATCH_MNT/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +loops=512 +nr_loops=$((loops - 1)) +BLKSZ=65536 + +echo "Initialize files" +echo > "$seqres.full" +_pwrite_byte 0x61 0 $((loops * BLKSZ)) "$TESTDIR/file1" >> "$seqres.full" +_pwrite_byte 0x61 0 $((loops * BLKSZ)) "$TESTDIR/file2" >> "$seqres.full" +_scratch_remount + +overwrite() { + while [ ! -e "$TESTDIR/finished" ]; do + seq $nr_loops -1 0 | while read i; do + _pwrite_byte 0x61 $((i * BLKSZ)) $BLKSZ "$TESTDIR/file2" >> "$seqres.full" + done + done +} + +echo "Dedupe and rewrite the file!" +overwrite & +for i in `seq 1 2`; do + seq $nr_loops -1 0 | while read i; do + _dedupe_range "$TESTDIR/file1" $((i * BLKSZ)) \ + "$TESTDIR/file2" $((i * BLKSZ)) $BLKSZ >> "$seqres.full" + [ $? -ne 0 ] && break + done +done +echo "Finished dedupeing" +touch "$TESTDIR/finished" +wait + +echo "Check fs" +umount "$SCRATCH_MNT" +_check_scratch_fs + +echo "Done" +# success, all done +status=0 +exit diff --git a/tests/generic/162.out b/tests/generic/162.out new file mode 100644 index 0000000..4481f8c --- /dev/null +++ b/tests/generic/162.out @@ -0,0 +1,7 @@ +QA output created by 162 +Format and mount +Initialize files +Dedupe and rewrite the file! +Finished dedupeing +Check fs +Done diff --git a/tests/generic/163 b/tests/generic/163 new file mode 100755 index 0000000..1f5042f --- /dev/null +++ b/tests/generic/163 @@ -0,0 +1,95 @@ +#! /bin/bash +# FS QA Test No. 163 +# +# Test for race between dedupe and writing the source file +# +#----------------------------------------------------------------------- +# Copyright (c) 2015 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 7 15 + +_cleanup() +{ + cd / + rm -rf "$tmp".* + wait +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_scratch_dedupe + +echo "Format and mount" +_scratch_mkfs > "$seqres.full" 2>&1 +_scratch_mount >> "$seqres.full" 2>&1 + +TESTDIR="$SCRATCH_MNT/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +loops=512 +nr_loops=$((loops - 1)) +BLKSZ=65536 + +echo "Initialize files" +echo > "$seqres.full" +_pwrite_byte 0x61 0 $((loops * BLKSZ)) "$TESTDIR/file1" >> "$seqres.full" +_pwrite_byte 0x61 0 $((loops * BLKSZ)) "$TESTDIR/file2" >> "$seqres.full" +_scratch_remount + +overwrite() { + while [ ! -e "$TESTDIR/finished" ]; do + seq $nr_loops -1 0 | while read i; do + _pwrite_byte 0x61 $((i * BLKSZ)) $BLKSZ "$TESTDIR/file1" >> "$seqres.full" + done + done +} + +echo "Dedupe and rewrite the file!" +overwrite & +for i in `seq 1 2`; do + seq $nr_loops -1 0 | while read i; do + _dedupe_range "$TESTDIR/file1" $((i * BLKSZ)) \ + "$TESTDIR/file2" $((i * BLKSZ)) $BLKSZ >> "$seqres.full" + [ $? -ne 0 ] && break + done +done +echo "Finished dedupeing" +touch "$TESTDIR/finished" +wait + +echo "Check fs" +umount "$SCRATCH_MNT" +_check_scratch_fs + +echo "Done" +# success, all done +status=0 +exit diff --git a/tests/generic/163.out b/tests/generic/163.out new file mode 100644 index 0000000..2d27d1b --- /dev/null +++ b/tests/generic/163.out @@ -0,0 +1,7 @@ +QA output created by 163 +Format and mount +Initialize files +Dedupe and rewrite the file! +Finished dedupeing +Check fs +Done diff --git a/tests/generic/164 b/tests/generic/164 new file mode 100755 index 0000000..4df953d --- /dev/null +++ b/tests/generic/164 @@ -0,0 +1,105 @@ +#! /bin/bash +# FS QA Test No. 164 +# +# Test for races or FS corruption between reflink and buffered I/O reading the +# target file. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015 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 7 15 + +_cleanup() +{ + cd / + rm -rf "$tmp".* + wait +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_scratch_reflink +_require_cp_reflink + +echo "Format and mount" +_scratch_mkfs > "$seqres.full" 2>&1 +_scratch_mount >> "$seqres.full" 2>&1 + +TESTDIR="$SCRATCH_MNT/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +loops=512 +nr_loops=$((loops - 1)) +BLKSZ=65536 + +echo "Initialize files" +echo > "$seqres.full" +_pwrite_byte 0x61 0 $((loops * BLKSZ)) "$TESTDIR/file1" >> "$seqres.full" +_pwrite_byte 0x62 0 $((loops * BLKSZ)) "$TESTDIR/file2" >> "$seqres.full" +_cp_reflink "$TESTDIR/file1" "$TESTDIR/file3" +_scratch_remount + +fbytes() { + egrep -v '(61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61|62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62)' +} + +reader() { + while [ ! -e "$TESTDIR/finished" ]; do + _read_range "$TESTDIR/file3" 0 $((loops * BLKSZ)) | fbytes + done +} + +echo "Reflink and reread the files!" +reader & +for i in `seq 1 2`; do + seq $nr_loops -1 0 | while read i; do + _reflink_range "$TESTDIR/file1" $((i * BLKSZ)) \ + "$TESTDIR/file3" $((i * BLKSZ)) $BLKSZ >> "$seqres.full" + [ $? -ne 0 ] && break + done + seq $nr_loops -1 0 | while read i; do + _reflink_range "$TESTDIR/file2" $((i * BLKSZ)) \ + "$TESTDIR/file3" $((i * BLKSZ)) $BLKSZ >> "$seqres.full" + [ $? -ne 0 ] && break + done +done +echo "Finished reflinking" +touch "$TESTDIR/finished" +wait + +echo "Check fs" +umount "$SCRATCH_MNT" +_check_scratch_fs + +echo "Done" +# success, all done +status=0 +exit diff --git a/tests/generic/164.out b/tests/generic/164.out new file mode 100644 index 0000000..0b4ed70 --- /dev/null +++ b/tests/generic/164.out @@ -0,0 +1,7 @@ +QA output created by 164 +Format and mount +Initialize files +Reflink and reread the files! +Finished reflinking +Check fs +Done diff --git a/tests/generic/165 b/tests/generic/165 new file mode 100755 index 0000000..49187ec --- /dev/null +++ b/tests/generic/165 @@ -0,0 +1,105 @@ +#! /bin/bash +# FS QA Test No. 165 +# +# Test for races or FS corruption between reflink and direct I/O reading the +# target file. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015 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 7 15 + +_cleanup() +{ + cd / + rm -rf "$tmp".* + wait +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_scratch_reflink +_require_cp_reflink + +echo "Format and mount" +_scratch_mkfs > "$seqres.full" 2>&1 +_scratch_mount >> "$seqres.full" 2>&1 + +TESTDIR="$SCRATCH_MNT/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +loops=512 +nr_loops=$((loops - 1)) +BLKSZ=65536 + +echo "Initialize files" +echo > "$seqres.full" +_pwrite_byte 0x61 0 $((loops * BLKSZ)) "$TESTDIR/file1" >> "$seqres.full" +_pwrite_byte 0x62 0 $((loops * BLKSZ)) "$TESTDIR/file2" >> "$seqres.full" +_cp_reflink $TESTDIR/file1 $TESTDIR/file3 +_scratch_remount + +fbytes() { + egrep -v '(61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61|62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62)' +} + +reader() { + while [ ! -e "$TESTDIR/finished" ]; do + _read_range "$TESTDIR/file3" 0 $((loops * BLKSZ)) -d | fbytes + done +} + +echo "Reflink and dio reread the files!" +reader & +for i in `seq 1 2`; do + seq $nr_loops -1 0 | while read i; do + _reflink_range "$TESTDIR/file1" $((i * BLKSZ)) \ + "$TESTDIR/file3" $((i * BLKSZ)) $BLKSZ >> "$seqres.full" + [ $? -ne 0 ] && break + done + seq $nr_loops -1 0 | while read i; do + _reflink_range "$TESTDIR/file2" $((i * BLKSZ)) \ + "$TESTDIR/file3" $((i * BLKSZ)) $BLKSZ >> "$seqres.full" + [ $? -ne 0 ] && break + done +done +echo "Finished reflinking" +touch "$TESTDIR/finished" +wait + +echo "Check fs" +umount "$SCRATCH_MNT" +_check_scratch_fs + +echo "Done" +# success, all done +status=0 +exit diff --git a/tests/generic/165.out b/tests/generic/165.out new file mode 100644 index 0000000..a89071d --- /dev/null +++ b/tests/generic/165.out @@ -0,0 +1,7 @@ +QA output created by 165 +Format and mount +Initialize files +Reflink and dio reread the files! +Finished reflinking +Check fs +Done diff --git a/tests/generic/166 b/tests/generic/166 new file mode 100755 index 0000000..71eb2ab --- /dev/null +++ b/tests/generic/166 @@ -0,0 +1,93 @@ +#! /bin/bash +# FS QA Test No. 166 +# +# Test for races or FS corruption when DIO writing to a file that's also +# the source of a reflink operation. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015 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 7 15 + +_cleanup() +{ + cd / + rm -rf "$tmp".* + wait +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_scratch_reflink +_require_cp_reflink + +echo "Format and mount" +_scratch_mkfs > "$seqres.full" 2>&1 +_scratch_mount >> "$seqres.full" 2>&1 + +TESTDIR="$SCRATCH_MNT/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +loops=1024 +nr_loops=$((loops - 1)) +BLKSZ=65536 + +echo "Initialize file" +echo > "$seqres.full" +_pwrite_byte 0x61 0 $((loops * BLKSZ)) "$TESTDIR/file1" >> "$seqres.full" +_scratch_remount + +# Snapshot creator... +snappy() { + n=0 + while [ ! -e "$TESTDIR/finished" ]; do + _cp_reflink "$TESTDIR/file1" "$TESTDIR/snap_$n" || break + n=$((n + 1)) + done +} + +echo "Snapshot a file undergoing directio rewrite" +snappy & +seq $nr_loops -1 0 | while read i; do + _pwrite_byte 0x63 $((i * BLKSZ)) $BLKSZ -d "$TESTDIR/file1" >> "$seqres.full" +done +touch $TESTDIR/finished +wait + +echo "Check for damage" +umount $SCRATCH_MNT +_check_scratch_fs + +echo "Done" + +# success, all done +status=0 +exit diff --git a/tests/generic/166.out b/tests/generic/166.out new file mode 100644 index 0000000..a2ba34e --- /dev/null +++ b/tests/generic/166.out @@ -0,0 +1,6 @@ +QA output created by 166 +Format and mount +Initialize file +Snapshot a file undergoing directio rewrite +Check for damage +Done diff --git a/tests/generic/167 b/tests/generic/167 new file mode 100755 index 0000000..c4e6ce8 --- /dev/null +++ b/tests/generic/167 @@ -0,0 +1,93 @@ +#! /bin/bash +# FS QA Test No. 167 +# +# Test for races or FS corruption when writing to a file that's also +# the source of a reflink operation. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015 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 7 15 + +_cleanup() +{ + cd / + rm -rf "$tmp".* + wait +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_scratch_reflink +_require_cp_reflink + +echo "Format and mount" +_scratch_mkfs > "$seqres.full" 2>&1 +_scratch_mount >> "$seqres.full" 2>&1 + +TESTDIR="$SCRATCH_MNT/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +loops=1024 +nr_loops=$((loops - 1)) +BLKSZ=65536 + +echo "Initialize file" +echo > "$seqres.full" +_pwrite_byte 0x61 0 $((loops * BLKSZ)) "$TESTDIR/file1" >> "$seqres.full" +_scratch_remount + +# Snapshot creator... +snappy() { + n=0 + while [ ! -e "$TESTDIR/finished" ]; do + _cp_reflink "$TESTDIR/file1" "$TESTDIR/snap_$n" || break + n=$((n + 1)) + done +} + +echo "Snapshot a file undergoing buffered rewrite" +snappy & +seq $nr_loops -1 0 | while read i; do + _pwrite_byte 0x63 $((i * BLKSZ)) $BLKSZ "$TESTDIR/file1" >> "$seqres.full" +done +touch $TESTDIR/finished +wait + +echo "Check for damage" +umount $SCRATCH_MNT +_check_scratch_fs + +echo "Done" + +# success, all done +status=0 +exit diff --git a/tests/generic/167.out b/tests/generic/167.out new file mode 100644 index 0000000..7cfb14e --- /dev/null +++ b/tests/generic/167.out @@ -0,0 +1,6 @@ +QA output created by 167 +Format and mount +Initialize file +Snapshot a file undergoing buffered rewrite +Check for damage +Done diff --git a/tests/generic/168 b/tests/generic/168 new file mode 100755 index 0000000..414dcb0 --- /dev/null +++ b/tests/generic/168 @@ -0,0 +1,97 @@ +#! /bin/bash +# FS QA Test No. 168 +# +# Test for races or FS corruption when writing to a file that's also +# the target of a reflink operation. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015 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 7 15 + +_cleanup() +{ + cd / + rm -rf "$tmp".* + wait +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_scratch_reflink + +echo "Format and mount" +_scratch_mkfs > "$seqres.full" 2>&1 +_scratch_mount >> "$seqres.full" 2>&1 + +TESTDIR="$SCRATCH_MNT/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +loops=1024 +nr_loops=$((loops - 1)) +BLKSZ=65536 + +echo "Initialize files" +echo > "$seqres.full" +_pwrite_byte 0x61 0 $((loops * BLKSZ)) "$TESTDIR/file1" >> "$seqres.full" +_pwrite_byte 0x62 0 $((loops * BLKSZ)) "$TESTDIR/file2" >> "$seqres.full" +_scratch_remount + +# Direct I/O overwriter... +overwrite() { + while [ ! -e "$TESTDIR/finished" ]; do + seq $nr_loops -1 0 | while read i; do + _pwrite_byte 0x63 $((i * BLKSZ)) $BLKSZ "$TESTDIR/file2" >> "$seqres.full" + done + done +} + +echo "Reflink and write the target" +overwrite & +seq 1 10 | while read j; do + seq 0 $nr_loops | while read i; do + _reflink_range "$TESTDIR/file1" $((i * BLKSZ)) \ + "$TESTDIR/file2" $((i * BLKSZ)) $BLKSZ >> "$seqres.full" + [ $? -ne 0 ] && exit + done +done +touch "$TESTDIR/finished" +wait + +echo "Check for damage" +umount "$SCRATCH_MNT" +_check_scratch_fs + +echo "Done" + +# success, all done +status=0 +exit diff --git a/tests/generic/168.out b/tests/generic/168.out new file mode 100644 index 0000000..d0dd08e --- /dev/null +++ b/tests/generic/168.out @@ -0,0 +1,6 @@ +QA output created by 168 +Format and mount +Initialize files +Reflink and write the target +Check for damage +Done diff --git a/tests/generic/170 b/tests/generic/170 new file mode 100755 index 0000000..704b646 --- /dev/null +++ b/tests/generic/170 @@ -0,0 +1,97 @@ +#! /bin/bash +# FS QA Test No. 170 +# +# Test for races or FS corruption when DIO writing to a file that's also +# the target of a reflink operation. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015 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 7 15 + +_cleanup() +{ + cd / + rm -rf "$tmp".* + wait +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_scratch_reflink + +echo "Format and mount" +_scratch_mkfs > "$seqres.full" 2>&1 +_scratch_mount >> "$seqres.full" 2>&1 + +TESTDIR="$SCRATCH_MNT/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +loops=1024 +nr_loops=$((loops - 1)) +BLKSZ=65536 + +echo "Initialize files" +echo > "$seqres.full" +_pwrite_byte 0x61 0 $((loops * BLKSZ)) "$TESTDIR/file1" >> "$seqres.full" +_pwrite_byte 0x62 0 $((loops * BLKSZ)) "$TESTDIR/file2" >> "$seqres.full" +_scratch_remount + +# Direct I/O overwriter... +overwrite() { + while [ ! -e "$TESTDIR/finished" ]; do + seq $nr_loops -1 0 | while read i; do + _pwrite_byte 0x63 $((i * BLKSZ)) $BLKSZ -d "$TESTDIR/file2" >> "$seqres.full" + done + done +} + +echo "Reflink and dio write the target" +overwrite & +seq 1 10 | while read j; do + seq 0 $nr_loops | while read i; do + _reflink_range "$TESTDIR/file1" $((i * BLKSZ)) \ + "$TESTDIR/file2" $((i * BLKSZ)) $BLKSZ >> "$seqres.full" + [ $? -ne 0 ] && exit + done +done +touch "$TESTDIR/finished" +wait + +echo "Check for damage" +umount "$SCRATCH_MNT" +_check_scratch_fs + +echo "Done" + +# success, all done +status=0 +exit diff --git a/tests/generic/170.out b/tests/generic/170.out new file mode 100644 index 0000000..103aaa5 --- /dev/null +++ b/tests/generic/170.out @@ -0,0 +1,6 @@ +QA output created by 170 +Format and mount +Initialize files +Reflink and dio write the target +Check for damage +Done diff --git a/tests/generic/group b/tests/generic/group index 0a20421..6ae3105 100644 --- a/tests/generic/group +++ b/tests/generic/group @@ -163,7 +163,16 @@ 158 auto quick clone 159 auto quick clone 160 auto quick clone +161 auto quick clone +162 auto quick clone +163 auto quick clone +164 auto quick clone +165 auto quick clone +166 auto quick clone +167 auto quick clone +168 auto quick clone 169 rw metadata auto quick +170 auto quick clone 184 metadata auto quick 192 atime auto 193 metadata auto quick From darrick.wong@oracle.com Fri Nov 13 15:38:30 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 ECAFC7F5E for ; Fri, 13 Nov 2015 15:38:30 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 958358F8033 for ; Fri, 13 Nov 2015 13:38:30 -0800 (PST) X-ASG-Debug-ID: 1447450706-04bdf07f0946b50001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id LAknARALzYLmMuoa (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 13 Nov 2015 13:38:27 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tADLbv1s019016 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 13 Nov 2015 21:37:58 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id tADLbvwX011631 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Fri, 13 Nov 2015 21:37:57 GMT Received: from abhmp0014.oracle.com (abhmp0014.oracle.com [141.146.116.20]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id tADLbvnj007514; Fri, 13 Nov 2015 21:37:57 GMT Received: from localhost (/71.198.20.188) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 13 Nov 2015 13:37:56 -0800 Subject: [PATCH 11/12] reflink: test that CoW writes fail when we're out of space From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 11/12] reflink: test that CoW writes fail when we're out of space To: david@fromorbit.com, darrick.wong@oracle.com Cc: fstests@vger.kernel.org, xfs@oss.sgi.com, hch@infradead.org, tao.peng@primarydata.com, linux-ext4@vger.kernel.org, Anna.Schumaker@netapp.com, linux-btrfs@vger.kernel.org Date: Fri, 13 Nov 2015 13:37:55 -0800 Message-ID: <20151113213755.31124.31309.stgit@birch.djwong.org> In-Reply-To: <20151113213643.31124.80975.stgit@birch.djwong.org> References: <20151113213643.31124.80975.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0021.oracle.com [156.151.31.71] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1447450706 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24371 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Ensure that copy-on-writing a reflinked file when there's no free disk space reflects the desired ENOSPC back to userspace during the write call. Tests the buffered IO, direct IO, and mmap write paths. Signed-off-by: Darrick J. Wong --- tests/generic/171 | 107 ++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/171.out | 10 ++++ tests/generic/172 | 107 ++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/172.out | 10 ++++ tests/generic/173 | 109 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/173.out | 8 ++++ tests/generic/174 | 107 ++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/174.out | 10 ++++ tests/generic/group | 4 ++ 9 files changed, 472 insertions(+) create mode 100755 tests/generic/171 create mode 100644 tests/generic/171.out create mode 100755 tests/generic/172 create mode 100644 tests/generic/172.out create mode 100755 tests/generic/173 create mode 100644 tests/generic/173.out create mode 100755 tests/generic/174 create mode 100644 tests/generic/174.out diff --git a/tests/generic/171 b/tests/generic/171 new file mode 100755 index 0000000..99e4d5e --- /dev/null +++ b/tests/generic/171 @@ -0,0 +1,107 @@ +#! /bin/bash +# FS QA Test No. 171 +# +# Reflink a file, use up the rest of the space, then try to observe ENOSPC +# while copy-on-writing the file via the page cache. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR1" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/attr +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_scratch_reflink +_require_cp_reflink + +rm -f "$seqres.full" + +echo "Format and mount" +_scratch_mkfs > "$seqres.full" 2>&1 +_scratch_mount >> "$seqres.full" 2>&1 + +TESTDIR="$SCRATCH_MNT/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Reformat with appropriate size" +BLKSZ="$(stat -f "$TESTDIR" -c '%S')" +NR_BLKS=10240 +umount "$SCRATCH_MNT" +SZ_BYTES=$((NR_BLKS * 8 * BLKSZ)) +if [ $SZ_BYTES -lt $((32 * 1048576)) ]; then + SZ_BYTES=$((32 * 1048576)) +fi +_scratch_mkfs_sized $SZ_BYTES >> "$seqres.full" 2>&1 +_scratch_mount >> "$seqres.full" 2>&1 +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create a big file and reflink it" +_pwrite_byte 0x61 0 $((BLKSZ * NR_BLKS)) "$TESTDIR/bigfile" >> "$seqres.full" 2>&1 +_cp_reflink "$TESTDIR/bigfile" "$TESTDIR/clonefile" +sync + +echo "Allocate the rest of the space" +NR_FREE="$(stat -f -c '%f' "$TESTDIR")" +touch "$TESTDIR/file0" "$TESTDIR/file1" +_pwrite_byte 0x61 0 $((BLKSZ * NR_FREE)) "$TESTDIR/eat_my_space" >> "$seqres.full" 2>&1 +sync + +echo "CoW the big file" +out="$(_pwrite_byte 0x62 0 $((BLKSZ * NR_BLKS)) "$TESTDIR/bigfile" 2>&1)" +echo "${out}" | grep -q "No space left on device" || echo "CoW should have failed with ENOSPC" +echo "${out}" >> "$seqres.full" 2>&1 +echo "${out}" + +echo "Remount and try CoW again" +_scratch_remount + +out="$(_pwrite_byte 0x62 0 $((BLKSZ * NR_BLKS)) "$TESTDIR/bigfile" 2>&1)" +echo "${out}" | grep -q "No space left on device" || echo "CoW should have failed with ENOSPC" +echo "${out}" >> "$seqres.full" 2>&1 +echo "${out}" + +#filefrag -v $TESTDIR/bigfile +#filefrag -v $TESTDIR/clonefile + +echo "Check scratch fs" +umount "$SCRATCH_MNT" +_check_scratch_fs + +# success, all done +status=0 +exit diff --git a/tests/generic/171.out b/tests/generic/171.out new file mode 100644 index 0000000..c2b0ddd --- /dev/null +++ b/tests/generic/171.out @@ -0,0 +1,10 @@ +QA output created by 171 +Format and mount +Reformat with appropriate size +Create a big file and reflink it +Allocate the rest of the space +CoW the big file +pwrite64: No space left on device +Remount and try CoW again +pwrite64: No space left on device +Check scratch fs diff --git a/tests/generic/172 b/tests/generic/172 new file mode 100755 index 0000000..eb00f0a --- /dev/null +++ b/tests/generic/172 @@ -0,0 +1,107 @@ +#! /bin/bash +# FS QA Test No. 172 +# +# Reflink a file that uses more than half of the space, then try to observe +# ENOSPC while copy-on-writing the file via the page cache. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR1" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/attr +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_scratch_reflink +_require_cp_reflink + +rm -f "$seqres.full" + +echo "Format and mount" +_scratch_mkfs > "$seqres.full" 2>&1 +_scratch_mount >> "$seqres.full" 2>&1 + +TESTDIR="$SCRATCH_MNT/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Reformat with appropriate size" +BLKSZ="$(stat -f "$TESTDIR" -c '%S')" +NR_BLKS=10240 +umount "$SCRATCH_MNT" +SZ_BYTES=$((NR_BLKS * 3 / 2 * BLKSZ)) +if [ $SZ_BYTES -lt $((32 * 1048576)) ]; then + SZ_BYTES=$((32 * 1048576)) +fi +_scratch_mkfs_sized $SZ_BYTES >> "$seqres.full" 2>&1 +_scratch_mount >> "$seqres.full" 2>&1 +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create a big file and reflink it" +_pwrite_byte 0x61 0 $((BLKSZ * NR_BLKS)) "$TESTDIR/bigfile" >> "$seqres.full" 2>&1 +_cp_reflink "$TESTDIR/bigfile" "$TESTDIR/clonefile" +sync + +echo "Allocate the rest of the space" +NR_FREE="$(stat -f -c '%f' "$TESTDIR")" +touch "$TESTDIR/file0" "$TESTDIR/file1" +_pwrite_byte 0x61 0 $((BLKSZ * NR_FREE)) "$TESTDIR/eat_my_space" >> "$seqres.full" 2>&1 +sync + +echo "CoW the big file" +out="$(_pwrite_byte 0x62 0 $((BLKSZ * NR_BLKS)) "$TESTDIR/bigfile" 2>&1)" +echo "${out}" | grep -q "No space left on device" || echo "CoW should have failed with ENOSPC" +echo "${out}" >> "$seqres.full" 2>&1 +echo "${out}" + +echo "Remount and try CoW again" +_scratch_remount + +out="$(_pwrite_byte 0x62 0 $((BLKSZ * NR_BLKS)) "$TESTDIR/bigfile" 2>&1)" +echo "${out}" | grep -q "No space left on device" || echo "CoW should have failed with ENOSPC" +echo "${out}" >> "$seqres.full" 2>&1 +echo "${out}" + +#filefrag -v $TESTDIR/bigfile +#filefrag -v $TESTDIR/clonefile + +echo "Check scratch fs" +umount "$SCRATCH_MNT" +_check_scratch_fs + +# success, all done +status=0 +exit diff --git a/tests/generic/172.out b/tests/generic/172.out new file mode 100644 index 0000000..3913dd7 --- /dev/null +++ b/tests/generic/172.out @@ -0,0 +1,10 @@ +QA output created by 172 +Format and mount +Reformat with appropriate size +Create a big file and reflink it +Allocate the rest of the space +CoW the big file +pwrite64: No space left on device +Remount and try CoW again +pwrite64: No space left on device +Check scratch fs diff --git a/tests/generic/173 b/tests/generic/173 new file mode 100755 index 0000000..76463d2 --- /dev/null +++ b/tests/generic/173 @@ -0,0 +1,109 @@ +#! /bin/bash +# FS QA Test No. 173 +# +# Reflink a file, use up the rest of the space, then try to observe ENOSPC +# while copy-on-writing the file via mmap. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR1" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/attr +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_scratch_reflink +_require_cp_reflink + +rm -f "$seqres.full" + +echo "Format and mount" +_scratch_mkfs > "$seqres.full" 2>&1 +_scratch_mount >> "$seqres.full" 2>&1 + +TESTDIR="$SCRATCH_MNT/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Reformat with appropriate size" +BLKSZ="$(stat -f "$TESTDIR" -c '%S')" +NR_BLKS=10240 +umount "$SCRATCH_MNT" +SZ_BYTES=$((NR_BLKS * 8 * BLKSZ)) +if [ $SZ_BYTES -lt $((32 * 1048576)) ]; then + SZ_BYTES=$((32 * 1048576)) +fi +_scratch_mkfs_sized $SZ_BYTES >> "$seqres.full" 2>&1 +_scratch_mount >> "$seqres.full" 2>&1 +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create a big file and reflink it" +_pwrite_byte 0x61 0 $((BLKSZ * NR_BLKS)) "$TESTDIR/bigfile" >> "$seqres.full" 2>&1 +_cp_reflink "$TESTDIR/bigfile" "$TESTDIR/clonefile" +sync + +echo "Allocate the rest of the space" +NR_FREE="$(stat -f -c '%f' "$TESTDIR")" +touch "$TESTDIR/file0" "$TESTDIR/file1" +_pwrite_byte 0x61 0 $((BLKSZ * NR_FREE)) "$TESTDIR/eat_my_space" >> "$seqres.full" 2>&1 +sync + +echo "mmap CoW the big file" +out="$(_mwrite_byte 0x62 0 $((BLKSZ * NR_BLKS)) $((BLKSZ * NR_BLKS)) "$TESTDIR/bigfile" 2>&1)" +err="$?" +if [ "$err" -lt 128 ]; then + echo "mmap CoW should have failed with SIGBUS, got SIG$(kill -l $err)" +fi + +echo "Remount and try CoW again" +_scratch_remount + +out="$(_mwrite_byte 0x62 0 $((BLKSZ * NR_BLKS)) $((BLKSZ * NR_BLKS)) "$TESTDIR/bigfile" 2>&1)" +err="$?" +if [ "$err" -lt 128 ]; then + echo "mmap CoW should have failed with SIGBUS, got SIG$(kill -l $err)" +fi + +#filefrag -v $TESTDIR/bigfile +#filefrag -v $TESTDIR/clonefile + +echo "Check scratch fs" +umount "$SCRATCH_MNT" +_check_scratch_fs + +# success, all done +status=0 +exit diff --git a/tests/generic/173.out b/tests/generic/173.out new file mode 100644 index 0000000..49abb17 --- /dev/null +++ b/tests/generic/173.out @@ -0,0 +1,8 @@ +QA output created by 173 +Format and mount +Reformat with appropriate size +Create a big file and reflink it +Allocate the rest of the space +mmap CoW the big file +Remount and try CoW again +Check scratch fs diff --git a/tests/generic/174 b/tests/generic/174 new file mode 100755 index 0000000..8df292a --- /dev/null +++ b/tests/generic/174 @@ -0,0 +1,107 @@ +#! /bin/bash +# FS QA Test No. 174 +# +# Reflink a file, use up the rest of the space, then try to observe ENOSPC +# while copy-on-writing the file via direct-io. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR1" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/attr +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_scratch_reflink +_require_cp_reflink + +rm -f "$seqres.full" + +echo "Format and mount" +_scratch_mkfs > "$seqres.full" 2>&1 +_scratch_mount >> "$seqres.full" 2>&1 + +TESTDIR="$SCRATCH_MNT/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Reformat with appropriate size" +BLKSZ="$(stat -f "$TESTDIR" -c '%S')" +NR_BLKS=10240 +umount "$SCRATCH_MNT" +SZ_BYTES=$((NR_BLKS * 8 * BLKSZ)) +if [ $SZ_BYTES -lt $((32 * 1048576)) ]; then + SZ_BYTES=$((32 * 1048576)) +fi +_scratch_mkfs_sized $SZ_BYTES >> "$seqres.full" 2>&1 +_scratch_mount >> "$seqres.full" 2>&1 +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +echo "Create a big file and reflink it" +_pwrite_byte 0x61 0 $((BLKSZ * NR_BLKS)) "$TESTDIR/bigfile" >> "$seqres.full" 2>&1 +_cp_reflink "$TESTDIR/bigfile" "$TESTDIR/clonefile" +sync + +echo "Allocate the rest of the space" +NR_FREE="$(stat -f -c '%f' "$TESTDIR")" +touch "$TESTDIR/file0" "$TESTDIR/file1" +_pwrite_byte 0x61 0 $((BLKSZ * NR_FREE)) "$TESTDIR/eat_my_space" >> "$seqres.full" 2>&1 +sync + +echo "CoW the big file" +out="$(_pwrite_byte 0x62 0 $((BLKSZ * NR_BLKS)) "$TESTDIR/bigfile" -d 2>&1)" +echo "${out}" | grep -q "No space left on device" || echo "CoW should have failed with ENOSPC" +echo "${out}" >> "$seqres.full" 2>&1 +echo "${out}" + +echo "Remount and try CoW again" +_scratch_remount + +out="$(_pwrite_byte 0x62 0 $((BLKSZ * NR_BLKS)) "$TESTDIR/bigfile" -d 2>&1)" +echo "${out}" | grep -q "No space left on device" || echo "CoW should have failed with ENOSPC" +echo "${out}" >> "$seqres.full" 2>&1 +echo "${out}" + +#filefrag -v $TESTDIR/bigfile +#filefrag -v $TESTDIR/clonefile + +echo "Check scratch fs" +umount "$SCRATCH_MNT" +_check_scratch_fs + +# success, all done +status=0 +exit diff --git a/tests/generic/174.out b/tests/generic/174.out new file mode 100644 index 0000000..702d067 --- /dev/null +++ b/tests/generic/174.out @@ -0,0 +1,10 @@ +QA output created by 174 +Format and mount +Reformat with appropriate size +Create a big file and reflink it +Allocate the rest of the space +CoW the big file +pwrite64: No space left on device +Remount and try CoW again +pwrite64: No space left on device +Check scratch fs diff --git a/tests/generic/group b/tests/generic/group index 6ae3105..09a7828 100644 --- a/tests/generic/group +++ b/tests/generic/group @@ -173,6 +173,10 @@ 168 auto quick clone 169 rw metadata auto quick 170 auto quick clone +171 auto quick clone +172 auto quick clone +173 auto quick clone +174 auto quick clone 184 metadata auto quick 192 atime auto 193 metadata auto quick From darrick.wong@oracle.com Fri Nov 13 15:38:34 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 555957F91 for ; Fri, 13 Nov 2015 15:38:34 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 375B48F8033 for ; Fri, 13 Nov 2015 13:38:34 -0800 (PST) X-ASG-Debug-ID: 1447450711-04cb6c0cd342980001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id 97CCxvOjdGQxBh8B (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 13 Nov 2015 13:38:32 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tADLc4JA019451 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 13 Nov 2015 21:38:04 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id tADLc3hJ012257 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Fri, 13 Nov 2015 21:38:04 GMT Received: from abhmp0005.oracle.com (abhmp0005.oracle.com [141.146.116.11]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id tADLc3de026766; Fri, 13 Nov 2015 21:38:03 GMT Received: from localhost (/71.198.20.188) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 13 Nov 2015 13:38:03 -0800 Subject: [PATCH 12/12] reflink: test what happens when we hit resource limits From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 12/12] reflink: test what happens when we hit resource limits To: david@fromorbit.com, darrick.wong@oracle.com Cc: fstests@vger.kernel.org, xfs@oss.sgi.com, hch@infradead.org, tao.peng@primarydata.com, linux-ext4@vger.kernel.org, Anna.Schumaker@netapp.com, linux-btrfs@vger.kernel.org Date: Fri, 13 Nov 2015 13:38:02 -0800 Message-ID: <20151113213802.31124.74408.stgit@birch.djwong.org> In-Reply-To: <20151113213643.31124.80975.stgit@birch.djwong.org> References: <20151113213643.31124.80975.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1447450712 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24370 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Add a few horrible opt-in stress tests to see what happens if we try to reflink the same block billions of times, and what happens if we run out of space while reflinking a file. Signed-off-by: Darrick J. Wong --- tests/generic/175 | 99 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/175.out | 0 tests/generic/176 | 81 ++++++++++++++++++++++++++++++++++++++++ tests/generic/176.out | 5 ++ tests/generic/group | 2 + 5 files changed, 187 insertions(+) create mode 100755 tests/generic/175 create mode 100644 tests/generic/175.out create mode 100755 tests/generic/176 create mode 100644 tests/generic/176.out diff --git a/tests/generic/175 b/tests/generic/175 new file mode 100755 index 0000000..a7da533 --- /dev/null +++ b/tests/generic/175 @@ -0,0 +1,99 @@ +#! /bin/bash +# FS QA Test No. 175 +# +# Try to hit the maximum reference count (eek!) +# +# This test runs extremely slowly, so it's not automatically run anywhere. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR1" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/attr +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_scratch_reflink +_require_cp_reflink + +rm -f "$seqres.full" + +echo "Format and mount" +_scratch_mkfs > "$seqres.full" 2>&1 +_scratch_mount >> "$seqres.full" 2>&1 + +TESTDIR="$SCRATCH_MNT/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +# Well let's hope the maximum reflink count is (less than (ha!)) 2^32... + +echo "Create a one block file" +BLKSZ="$(stat -f "$TESTDIR" -c '%S')" +_pwrite_byte 0x61 0 $BLKSZ "$TESTDIR/file1" >> "$seqres.full" +_pwrite_byte 0x62 0 $BLKSZ "$TESTDIR/file2" >> "$seqres.full" +_cp_reflink "$TESTDIR/file1" "$TESTDIR/file2" >> "$seqres.full" + +nr=32 +fnr=32 +for i in $(seq 0 $fnr); do + echo " ++ Reflink size $i, $(( (2 ** i) * BLKSZ)) bytes" | tee -a "$seqres.full" + n=$(( (2 ** i) * BLKSZ)) + _reflink_range "$TESTDIR/file1" 0 "$TESTDIR/file1" $n $n >> "$seqres.full" || break +done + +nrf=$((nr - fnr)) +echo "Clone $((2 ** nrf)) files" +seq 0 $((2 ** nrf)) | while read i; do + _cp-reflink "$TESTDIR/file1" "$TESTDIR/file1-$i" +done + +echo "Check scratch fs" +umount "$SCRATCH_MNT" +_check_scratch_fs + +echo "Remove big file and recheck" +_scratch_mount >> "$seqres.full" 2>&1 +umount "$SCRATCH_MNT" +_check_scratch_fs + +echo "Remove all files and recheck" +_scratch_mount >> "$seqres.full" 2>&1 +umount "$SCRATCH_MNT" +_check_scratch_fs + +# success, all done +status=0 +exit diff --git a/tests/generic/175.out b/tests/generic/175.out new file mode 100644 index 0000000..e69de29 diff --git a/tests/generic/176 b/tests/generic/176 new file mode 100755 index 0000000..bf930b7 --- /dev/null +++ b/tests/generic/176 @@ -0,0 +1,81 @@ +#! /bin/bash +# FS QA Test No. 176 +# +# Try to run out of space while cloning? +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. 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 -rf "$tmp".* "$TESTDIR1" +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/attr +. ./common/reflink + +# real QA test starts here +_supported_os Linux +_require_scratch_reflink + +rm -f "$seqres.full" + +echo "Format and mount" +_scratch_mkfs > "$seqres.full" 2>&1 +_scratch_mount >> "$seqres.full" 2>&1 + +TESTDIR="$SCRATCH_MNT/test-$seq" +rm -rf "$TESTDIR" +mkdir "$TESTDIR" + +BLKSZ="$(stat -f "$TESTDIR" -c '%S')" +NR_FREE="$(stat -f -c '%f' "$TESTDIR")" +echo "Create a big file" +touch "$TESTDIR/file0" "$TESTDIR/file1" +_pwrite_byte 0x61 0 $((BLKSZ * NR_FREE)) "$TESTDIR/bigfile" >> "$seqres.full" 2>&1 +_scratch_remount +sz="$(stat -c '%s' "$TESTDIR/bigfile")" + +blks="$((sz / BLKSZ))" +echo "Try to reflink" +seq 0 $blks | while read lblk; do + fname="$TESTDIR/file$((lblk % 2))" + out="$(_reflink_range "$TESTDIR/bigfile" $((lblk * BLKSZ)) "$fname" $((lblk * BLKSZ)) $BLKSZ 2>&1)" + echo "$fname: $out" >> "$seqres.full" + echo "$out" | grep -q "No space left on device" && break +done + +echo "Check scratch fs" +umount "$SCRATCH_MNT" +_check_scratch_fs + +# success, all done +status=0 +exit diff --git a/tests/generic/176.out b/tests/generic/176.out new file mode 100644 index 0000000..eec98eb --- /dev/null +++ b/tests/generic/176.out @@ -0,0 +1,5 @@ +QA output created by 176 +Format and mount +Create a big file +Try to reflink +Check scratch fs diff --git a/tests/generic/group b/tests/generic/group index 09a7828..8a40797 100644 --- a/tests/generic/group +++ b/tests/generic/group @@ -177,6 +177,8 @@ 172 auto quick clone 173 auto quick clone 174 auto quick clone +175 clone_stress +176 clone_stress 184 metadata auto quick 192 atime auto 193 metadata auto quick From ross.zwisler@linux.intel.com Fri Nov 13 18:07:08 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 51D7C7F5A for ; Fri, 13 Nov 2015 18:07:08 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 2A9968F808F for ; Fri, 13 Nov 2015 16:07:07 -0800 (PST) X-ASG-Debug-ID: 1447459622-04cbb0605d4e430001-NocioJ Received: from mga14.intel.com ([192.55.52.115]) by cuda.sgi.com with ESMTP id Jvc6doaZysjApBax for ; Fri, 13 Nov 2015 16:07:03 -0800 (PST) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 192.55.52.115 Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga103.fm.intel.com with ESMTP; 13 Nov 2015 16:07:02 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,289,1444719600"; d="scan'208";a="684969759" Received: from theros.lm.intel.com ([10.232.112.87]) by orsmga003.jf.intel.com with ESMTP; 13 Nov 2015 16:07:01 -0800 From: Ross Zwisler To: linux-kernel@vger.kernel.org Cc: Ross Zwisler , "H. Peter Anvin" , "J. Bruce Fields" , "Theodore Ts'o" , Alexander Viro , Andreas Dilger , Dan Williams , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@lists.01.org, x86@kernel.org, xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox , Dave Hansen Subject: [PATCH v2 01/11] pmem: add wb_cache_pmem() to the PMEM API Date: Fri, 13 Nov 2015 17:06:40 -0700 X-ASG-Orig-Subj: [PATCH v2 01/11] pmem: add wb_cache_pmem() to the PMEM API Message-Id: <1447459610-14259-2-git-send-email-ross.zwisler@linux.intel.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> References: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> X-Barracuda-Connect: UNKNOWN[192.55.52.115] X-Barracuda-Start-Time: 1447459623 X-Barracuda-URL: https://192.48.176.25:443/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, BSF_SC5_MJ1963, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24375 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 The function __arch_wb_cache_pmem() was already an internal implementation detail of the x86 PMEM API, but this functionality needs to be exported as part of the general PMEM API to handle the fsync/msync case for DAX mmaps. One thing worth noting is that we really do want this to be part of the PMEM API as opposed to a stand-alone function like clflush_cache_range() because of ordering restrictions. By having wb_cache_pmem() as part of the PMEM API we can leave it unordered, call it multiple times to write back large amounts of memory, and then order the multiple calls with a single wmb_pmem(). Signed-off-by: Ross Zwisler --- arch/x86/include/asm/pmem.h | 11 ++++++----- include/linux/pmem.h | 22 +++++++++++++++++++++- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/arch/x86/include/asm/pmem.h b/arch/x86/include/asm/pmem.h index d8ce3ec..6c7ade0 100644 --- a/arch/x86/include/asm/pmem.h +++ b/arch/x86/include/asm/pmem.h @@ -67,18 +67,19 @@ static inline void arch_wmb_pmem(void) } /** - * __arch_wb_cache_pmem - write back a cache range with CLWB + * arch_wb_cache_pmem - write back a cache range with CLWB * @vaddr: virtual start address * @size: number of bytes to write back * * Write back a cache range using the CLWB (cache line write back) * instruction. This function requires explicit ordering with an - * arch_wmb_pmem() call. This API is internal to the x86 PMEM implementation. + * arch_wmb_pmem() call. */ -static inline void __arch_wb_cache_pmem(void *vaddr, size_t size) +static inline void arch_wb_cache_pmem(void __pmem *addr, size_t size) { u16 x86_clflush_size = boot_cpu_data.x86_clflush_size; unsigned long clflush_mask = x86_clflush_size - 1; + void *vaddr = (void __force *)addr; void *vend = vaddr + size; void *p; @@ -115,7 +116,7 @@ static inline size_t arch_copy_from_iter_pmem(void __pmem *addr, size_t bytes, len = copy_from_iter_nocache(vaddr, bytes, i); if (__iter_needs_pmem_wb(i)) - __arch_wb_cache_pmem(vaddr, bytes); + arch_wb_cache_pmem(addr, bytes); return len; } @@ -138,7 +139,7 @@ static inline void arch_clear_pmem(void __pmem *addr, size_t size) else memset(vaddr, 0, size); - __arch_wb_cache_pmem(vaddr, size); + arch_wb_cache_pmem(addr, size); } static inline bool __arch_has_wmb_pmem(void) diff --git a/include/linux/pmem.h b/include/linux/pmem.h index 85f810b3..2cd5003 100644 --- a/include/linux/pmem.h +++ b/include/linux/pmem.h @@ -53,12 +53,18 @@ static inline void arch_clear_pmem(void __pmem *addr, size_t size) { BUG(); } + +static inline void arch_wb_cache_pmem(void __pmem *addr, size_t size) +{ + BUG(); +} #endif /* * Architectures that define ARCH_HAS_PMEM_API must provide * implementations for arch_memcpy_to_pmem(), arch_wmb_pmem(), - * arch_copy_from_iter_pmem(), arch_clear_pmem() and arch_has_wmb_pmem(). + * arch_copy_from_iter_pmem(), arch_clear_pmem(), arch_wb_cache_pmem() + * and arch_has_wmb_pmem(). */ static inline void memcpy_from_pmem(void *dst, void __pmem const *src, size_t size) { @@ -202,4 +208,18 @@ static inline void clear_pmem(void __pmem *addr, size_t size) else default_clear_pmem(addr, size); } + +/** + * wb_cache_pmem - write back processor cache for PMEM memory range + * @addr: virtual start address + * @size: number of bytes to write back + * + * Write back the processor cache range starting at 'addr' for 'size' bytes. + * This function requires explicit ordering with a wmb_pmem() call. + */ +static inline void wb_cache_pmem(void __pmem *addr, size_t size) +{ + if (arch_has_pmem_api()) + arch_wb_cache_pmem(addr, size); +} #endif /* __PMEM_H__ */ -- 2.1.0 From ross.zwisler@linux.intel.com Fri Nov 13 18:07:08 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 BC9D27F5D for ; Fri, 13 Nov 2015 18:07:08 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 3D6CAAC011 for ; Fri, 13 Nov 2015 16:07:08 -0800 (PST) X-ASG-Debug-ID: 1447459625-04cbb0605c4e440001-NocioJ Received: from mga14.intel.com ([192.55.52.115]) by cuda.sgi.com with ESMTP id hTfsQfhoq1yfMYkr for ; Fri, 13 Nov 2015 16:07:05 -0800 (PST) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 192.55.52.115 Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga103.fm.intel.com with ESMTP; 13 Nov 2015 16:07:05 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,289,1444719600"; d="scan'208";a="684969821" Received: from theros.lm.intel.com ([10.232.112.87]) by orsmga003.jf.intel.com with ESMTP; 13 Nov 2015 16:07:04 -0800 From: Ross Zwisler To: linux-kernel@vger.kernel.org Cc: Ross Zwisler , "H. Peter Anvin" , "J. Bruce Fields" , "Theodore Ts'o" , Alexander Viro , Andreas Dilger , Dan Williams , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@lists.01.org, x86@kernel.org, xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox , Dave Hansen Subject: [PATCH v2 03/11] pmem: enable REQ_FUA/REQ_FLUSH handling Date: Fri, 13 Nov 2015 17:06:42 -0700 X-ASG-Orig-Subj: [PATCH v2 03/11] pmem: enable REQ_FUA/REQ_FLUSH handling Message-Id: <1447459610-14259-4-git-send-email-ross.zwisler@linux.intel.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> References: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> X-Barracuda-Connect: UNKNOWN[192.55.52.115] X-Barracuda-Start-Time: 1447459625 X-Barracuda-URL: https://192.48.176.25:443/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, BSF_SC5_MJ1963, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24375 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 Currently the PMEM driver doesn't accept REQ_FLUSH or REQ_FUA bios. These are sent down via blkdev_issue_flush() in response to a fsync() or msync() and are used by filesystems to order their metadata, among other things. When we get an msync() or fsync() it is the responsibility of the DAX code to flush all dirty pages to media. The PMEM driver then just has issue a wmb_pmem() in response to the REQ_FLUSH to ensure that before we return all the flushed data has been durably stored on the media. Signed-off-by: Ross Zwisler --- drivers/nvdimm/pmem.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c index 0ba6a97..b914d66 100644 --- a/drivers/nvdimm/pmem.c +++ b/drivers/nvdimm/pmem.c @@ -80,7 +80,7 @@ static void pmem_make_request(struct request_queue *q, struct bio *bio) if (do_acct) nd_iostat_end(bio, start); - if (bio_data_dir(bio)) + if (bio_data_dir(bio) || (bio->bi_rw & (REQ_FLUSH|REQ_FUA))) wmb_pmem(); bio_endio(bio); @@ -189,6 +189,7 @@ static int pmem_attach_disk(struct device *dev, blk_queue_physical_block_size(pmem->pmem_queue, PAGE_SIZE); blk_queue_max_hw_sectors(pmem->pmem_queue, UINT_MAX); blk_queue_bounce_limit(pmem->pmem_queue, BLK_BOUNCE_ANY); + blk_queue_flush(pmem->pmem_queue, REQ_FLUSH|REQ_FUA); queue_flag_set_unlocked(QUEUE_FLAG_NONROT, pmem->pmem_queue); disk = alloc_disk(0); -- 2.1.0 From ross.zwisler@linux.intel.com Fri Nov 13 18:07:09 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 9A66B7F5A for ; Fri, 13 Nov 2015 18:07:09 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 86D02304093 for ; Fri, 13 Nov 2015 16:07:09 -0800 (PST) X-ASG-Debug-ID: 1447459621-04cb6c0cd349010003-NocioJ Received: from mga14.intel.com ([192.55.52.115]) by cuda.sgi.com with ESMTP id 7YQEt1gpKW73Fjrt for ; Fri, 13 Nov 2015 16:07:07 -0800 (PST) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 192.55.52.115 Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga103.fm.intel.com with ESMTP; 13 Nov 2015 16:07:06 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,289,1444719600"; d="scan'208";a="684969827" Received: from theros.lm.intel.com ([10.232.112.87]) by orsmga003.jf.intel.com with ESMTP; 13 Nov 2015 16:07:05 -0800 From: Ross Zwisler To: linux-kernel@vger.kernel.org Cc: Ross Zwisler , "H. Peter Anvin" , "J. Bruce Fields" , "Theodore Ts'o" , Alexander Viro , Andreas Dilger , Dan Williams , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@lists.01.org, x86@kernel.org, xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox , Dave Hansen Subject: [PATCH v2 04/11] dax: support dirty DAX entries in radix tree Date: Fri, 13 Nov 2015 17:06:43 -0700 X-ASG-Orig-Subj: [PATCH v2 04/11] dax: support dirty DAX entries in radix tree Message-Id: <1447459610-14259-5-git-send-email-ross.zwisler@linux.intel.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> References: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> X-Barracuda-Connect: UNKNOWN[192.55.52.115] X-Barracuda-Start-Time: 1447459625 X-Barracuda-URL: https://192.48.176.15:443/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, BSF_SC5_MJ1963, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24375 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 Add support for tracking dirty DAX entries in the struct address_space radix tree. This tree is already used for dirty page writeback, and it already supports the use of exceptional (non struct page*) entries. In order to properly track dirty DAX pages we will insert new exceptional entries into the radix tree that represent dirty DAX PTE or PMD pages. These exceptional entries will also contain the writeback addresses for the PTE or PMD faults that we can use at fsync/msync time. There are currently two types of exceptional entries (shmem and shadow) that can be placed into the radix tree, and this adds a third. There shouldn't be any collisions between these various exceptional entries because only one type of exceptional entry should be able to be found in a radix tree at a time depending on how it is being used. Signed-off-by: Ross Zwisler --- fs/block_dev.c | 3 ++- fs/inode.c | 1 + include/linux/dax.h | 5 ++++ include/linux/fs.h | 1 + include/linux/radix-tree.h | 8 ++++++ mm/filemap.c | 10 +++++--- mm/truncate.c | 62 ++++++++++++++++++++++++++-------------------- 7 files changed, 59 insertions(+), 31 deletions(-) diff --git a/fs/block_dev.c b/fs/block_dev.c index 073bb57..afaaf44 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -66,7 +66,8 @@ void kill_bdev(struct block_device *bdev) { struct address_space *mapping = bdev->bd_inode->i_mapping; - if (mapping->nrpages == 0 && mapping->nrshadows == 0) + if (mapping->nrpages == 0 && mapping->nrshadows == 0 && + mapping->nrdax == 0) return; invalidate_bh_lrus(); diff --git a/fs/inode.c b/fs/inode.c index 78a17b8..f7c87a6 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -496,6 +496,7 @@ void clear_inode(struct inode *inode) spin_lock_irq(&inode->i_data.tree_lock); BUG_ON(inode->i_data.nrpages); BUG_ON(inode->i_data.nrshadows); + BUG_ON(inode->i_data.nrdax); spin_unlock_irq(&inode->i_data.tree_lock); BUG_ON(!list_empty(&inode->i_data.private_list)); BUG_ON(!(inode->i_state & I_FREEING)); diff --git a/include/linux/dax.h b/include/linux/dax.h index b415e52..e9d57f68 100644 --- a/include/linux/dax.h +++ b/include/linux/dax.h @@ -36,4 +36,9 @@ static inline bool vma_is_dax(struct vm_area_struct *vma) { return vma->vm_file && IS_DAX(vma->vm_file->f_mapping->host); } + +static inline bool dax_mapping(struct address_space *mapping) +{ + return mapping->host && IS_DAX(mapping->host); +} #endif diff --git a/include/linux/fs.h b/include/linux/fs.h index 72d8a84..f791698 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -433,6 +433,7 @@ struct address_space { /* Protected by tree_lock together with the radix tree */ unsigned long nrpages; /* number of total pages */ unsigned long nrshadows; /* number of shadow entries */ + unsigned long nrdax; /* number of DAX entries */ pgoff_t writeback_index;/* writeback starts here */ const struct address_space_operations *a_ops; /* methods */ unsigned long flags; /* error bits/gfp mask */ diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h index 33170db..19a533a 100644 --- a/include/linux/radix-tree.h +++ b/include/linux/radix-tree.h @@ -51,6 +51,14 @@ #define RADIX_TREE_EXCEPTIONAL_ENTRY 2 #define RADIX_TREE_EXCEPTIONAL_SHIFT 2 +#define RADIX_DAX_MASK 0xf +#define RADIX_DAX_PTE (0x4 | RADIX_TREE_EXCEPTIONAL_ENTRY) +#define RADIX_DAX_PMD (0x8 | RADIX_TREE_EXCEPTIONAL_ENTRY) +#define RADIX_DAX_TYPE(entry) ((__force u64)entry & RADIX_DAX_MASK) +#define RADIX_DAX_ADDR(entry) ((void __pmem *)((u64)entry & ~RADIX_DAX_MASK)) +#define RADIX_DAX_PTE_ENTRY(addr) ((void *)((__force u64)addr | RADIX_DAX_PTE)) +#define RADIX_DAX_PMD_ENTRY(addr) ((void *)((__force u64)addr | RADIX_DAX_PMD)) + static inline int radix_tree_is_indirect_ptr(void *ptr) { return (int)((unsigned long)ptr & RADIX_TREE_INDIRECT_PTR); diff --git a/mm/filemap.c b/mm/filemap.c index 327910c..d5e94fd 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -11,6 +11,7 @@ */ #include #include +#include #include #include #include @@ -538,6 +539,9 @@ static int page_cache_tree_insert(struct address_space *mapping, p = radix_tree_deref_slot_protected(slot, &mapping->tree_lock); if (!radix_tree_exceptional_entry(p)) return -EEXIST; + + BUG_ON(dax_mapping(mapping)); + if (shadowp) *shadowp = p; mapping->nrshadows--; @@ -1201,9 +1205,9 @@ repeat: if (radix_tree_deref_retry(page)) goto restart; /* - * A shadow entry of a recently evicted page, - * or a swap entry from shmem/tmpfs. Return - * it without attempting to raise page count. + * A shadow entry of a recently evicted page, a swap + * entry from shmem/tmpfs or a DAX entry. Return it + * without attempting to raise page count. */ goto export; } diff --git a/mm/truncate.c b/mm/truncate.c index 76e35ad..32d2964 100644 --- a/mm/truncate.c +++ b/mm/truncate.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -34,31 +35,37 @@ static void clear_exceptional_entry(struct address_space *mapping, return; spin_lock_irq(&mapping->tree_lock); - /* - * Regular page slots are stabilized by the page lock even - * without the tree itself locked. These unlocked entries - * need verification under the tree lock. - */ - if (!__radix_tree_lookup(&mapping->page_tree, index, &node, &slot)) - goto unlock; - if (*slot != entry) - goto unlock; - radix_tree_replace_slot(slot, NULL); - mapping->nrshadows--; - if (!node) - goto unlock; - workingset_node_shadows_dec(node); - /* - * Don't track node without shadow entries. - * - * Avoid acquiring the list_lru lock if already untracked. - * The list_empty() test is safe as node->private_list is - * protected by mapping->tree_lock. - */ - if (!workingset_node_shadows(node) && - !list_empty(&node->private_list)) - list_lru_del(&workingset_shadow_nodes, &node->private_list); - __radix_tree_delete_node(&mapping->page_tree, node); + + if (dax_mapping(mapping)) { + radix_tree_delete(&mapping->page_tree, index); + mapping->nrdax--; + } else { + /* + * Regular page slots are stabilized by the page lock even + * without the tree itself locked. These unlocked entries + * need verification under the tree lock. + */ + if (!__radix_tree_lookup(&mapping->page_tree, index, &node, &slot)) + goto unlock; + if (*slot != entry) + goto unlock; + radix_tree_replace_slot(slot, NULL); + mapping->nrshadows--; + if (!node) + goto unlock; + workingset_node_shadows_dec(node); + /* + * Don't track node without shadow entries. + * + * Avoid acquiring the list_lru lock if already untracked. + * The list_empty() test is safe as node->private_list is + * protected by mapping->tree_lock. + */ + if (!workingset_node_shadows(node) && + !list_empty(&node->private_list)) + list_lru_del(&workingset_shadow_nodes, &node->private_list); + __radix_tree_delete_node(&mapping->page_tree, node); + } unlock: spin_unlock_irq(&mapping->tree_lock); } @@ -228,7 +235,8 @@ void truncate_inode_pages_range(struct address_space *mapping, int i; cleancache_invalidate_inode(mapping); - if (mapping->nrpages == 0 && mapping->nrshadows == 0) + if (mapping->nrpages == 0 && mapping->nrshadows == 0 && + mapping->nrdax == 0) return; /* Offsets within partial pages */ @@ -423,7 +431,7 @@ void truncate_inode_pages_final(struct address_space *mapping) smp_rmb(); nrshadows = mapping->nrshadows; - if (nrpages || nrshadows) { + if (nrpages || nrshadows || mapping->nrdax) { /* * As truncation uses a lockless tree lookup, cycle * the tree lock to make sure any ongoing tree -- 2.1.0 From ross.zwisler@linux.intel.com Fri Nov 13 18:07:10 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 094CC7F5D for ; Fri, 13 Nov 2015 18:07:10 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id E8A5A8F8081 for ; Fri, 13 Nov 2015 16:07:06 -0800 (PST) X-ASG-Debug-ID: 1447459621-04cb6c0cd349010002-NocioJ Received: from mga14.intel.com ([192.55.52.115]) by cuda.sgi.com with ESMTP id qghAzLtjbQq25SL1 for ; Fri, 13 Nov 2015 16:07:04 -0800 (PST) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 192.55.52.115 Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga103.fm.intel.com with ESMTP; 13 Nov 2015 16:07:04 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,289,1444719600"; d="scan'208";a="684969807" Received: from theros.lm.intel.com ([10.232.112.87]) by orsmga003.jf.intel.com with ESMTP; 13 Nov 2015 16:07:02 -0800 From: Ross Zwisler To: linux-kernel@vger.kernel.org Cc: Ross Zwisler , "H. Peter Anvin" , "J. Bruce Fields" , "Theodore Ts'o" , Alexander Viro , Andreas Dilger , Dan Williams , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@lists.01.org, x86@kernel.org, xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox , Dave Hansen Subject: [PATCH v2 02/11] mm: add pmd_mkclean() Date: Fri, 13 Nov 2015 17:06:41 -0700 X-ASG-Orig-Subj: [PATCH v2 02/11] mm: add pmd_mkclean() Message-Id: <1447459610-14259-3-git-send-email-ross.zwisler@linux.intel.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> References: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> X-Barracuda-Connect: UNKNOWN[192.55.52.115] X-Barracuda-Start-Time: 1447459622 X-Barracuda-URL: https://192.48.176.15:443/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, BSF_SC5_MJ1963, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24375 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 Currently PMD pages can be dirtied via pmd_mkdirty(), but cannot be cleaned. For DAX mmap dirty page tracking we need to be able to clean PMD pages when we flush them to media so that we get a new write fault the next time the are written to. Signed-off-by: Ross Zwisler --- arch/x86/include/asm/pgtable.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index 867da5b..c548e4c 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h @@ -277,6 +277,11 @@ static inline pmd_t pmd_mkdirty(pmd_t pmd) return pmd_set_flags(pmd, _PAGE_DIRTY | _PAGE_SOFT_DIRTY); } +static inline pmd_t pmd_mkclean(pmd_t pmd) +{ + return pmd_clear_flags(pmd, _PAGE_DIRTY | _PAGE_SOFT_DIRTY); +} + static inline pmd_t pmd_mkhuge(pmd_t pmd) { return pmd_set_flags(pmd, _PAGE_PSE); -- 2.1.0 From ross.zwisler@linux.intel.com Fri Nov 13 18:07:10 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 CA2FB7F5A for ; Fri, 13 Nov 2015 18:07:10 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id B5F28304093 for ; Fri, 13 Nov 2015 16:07:10 -0800 (PST) X-ASG-Debug-ID: 1447459621-04cb6c0cd349010004-NocioJ Received: from mga14.intel.com ([192.55.52.115]) by cuda.sgi.com with ESMTP id cRHxEA4SOIhsgamb for ; Fri, 13 Nov 2015 16:07:09 -0800 (PST) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 192.55.52.115 Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga103.fm.intel.com with ESMTP; 13 Nov 2015 16:07:08 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,289,1444719600"; d="scan'208";a="684969843" Received: from theros.lm.intel.com ([10.232.112.87]) by orsmga003.jf.intel.com with ESMTP; 13 Nov 2015 16:07:06 -0800 From: Ross Zwisler To: linux-kernel@vger.kernel.org Cc: Ross Zwisler , "H. Peter Anvin" , "J. Bruce Fields" , "Theodore Ts'o" , Alexander Viro , Andreas Dilger , Dan Williams , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@lists.01.org, x86@kernel.org, xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox , Dave Hansen Subject: [PATCH v2 05/11] mm: add follow_pte_pmd() Date: Fri, 13 Nov 2015 17:06:44 -0700 X-ASG-Orig-Subj: [PATCH v2 05/11] mm: add follow_pte_pmd() Message-Id: <1447459610-14259-6-git-send-email-ross.zwisler@linux.intel.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> References: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> X-Barracuda-Connect: UNKNOWN[192.55.52.115] X-Barracuda-Start-Time: 1447459628 X-Barracuda-URL: https://192.48.176.15:443/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, BSF_SC5_MJ1963, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24375 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 Similar to follow_pte(), follow_pte_pmd() allows either a PTE leaf or a huge page PMD leaf to be found and returned. Signed-off-by: Ross Zwisler Suggested-by: Dave Hansen --- include/linux/mm.h | 2 ++ mm/memory.c | 38 ++++++++++++++++++++++++++++++-------- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/include/linux/mm.h b/include/linux/mm.h index 80001de..393441c 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1166,6 +1166,8 @@ int copy_page_range(struct mm_struct *dst, struct mm_struct *src, struct vm_area_struct *vma); void unmap_mapping_range(struct address_space *mapping, loff_t const holebegin, loff_t const holelen, int even_cows); +int follow_pte_pmd(struct mm_struct *mm, unsigned long address, + pte_t **ptepp, pmd_t **pmdpp, spinlock_t **ptlp); int follow_pfn(struct vm_area_struct *vma, unsigned long address, unsigned long *pfn); int follow_phys(struct vm_area_struct *vma, unsigned long address, diff --git a/mm/memory.c b/mm/memory.c index deb679c..7f4090e 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -3512,8 +3512,8 @@ int __pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address) } #endif /* __PAGETABLE_PMD_FOLDED */ -static int __follow_pte(struct mm_struct *mm, unsigned long address, - pte_t **ptepp, spinlock_t **ptlp) +static int __follow_pte_pmd(struct mm_struct *mm, unsigned long address, + pte_t **ptepp, pmd_t **pmdpp, spinlock_t **ptlp) { pgd_t *pgd; pud_t *pud; @@ -3529,12 +3529,20 @@ static int __follow_pte(struct mm_struct *mm, unsigned long address, goto out; pmd = pmd_offset(pud, address); - VM_BUG_ON(pmd_trans_huge(*pmd)); - if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd))) - goto out; - /* We cannot handle huge page PFN maps. Luckily they don't exist. */ - if (pmd_huge(*pmd)) + if (pmd_huge(*pmd)) { + if (!pmdpp) + goto out; + + *ptlp = pmd_lock(mm, pmd); + if (pmd_huge(*pmd)) { + *pmdpp = pmd; + return 0; + } + spin_unlock(*ptlp); + } + + if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd))) goto out; ptep = pte_offset_map_lock(mm, pmd, address, ptlp); @@ -3557,9 +3565,23 @@ static inline int follow_pte(struct mm_struct *mm, unsigned long address, /* (void) is needed to make gcc happy */ (void) __cond_lock(*ptlp, - !(res = __follow_pte(mm, address, ptepp, ptlp))); + !(res = __follow_pte_pmd(mm, address, ptepp, NULL, + ptlp))); + return res; +} + +int follow_pte_pmd(struct mm_struct *mm, unsigned long address, + pte_t **ptepp, pmd_t **pmdpp, spinlock_t **ptlp) +{ + int res; + + /* (void) is needed to make gcc happy */ + (void) __cond_lock(*ptlp, + !(res = __follow_pte_pmd(mm, address, ptepp, pmdpp, + ptlp))); return res; } +EXPORT_SYMBOL(follow_pte_pmd); /** * follow_pfn - look up PFN at a user virtual address -- 2.1.0 From ross.zwisler@linux.intel.com Fri Nov 13 18:07:13 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 1A3AC7F62 for ; Fri, 13 Nov 2015 18:07:13 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 6AEF6AC011 for ; Fri, 13 Nov 2015 16:07:12 -0800 (PST) X-ASG-Debug-ID: 1447459621-04cb6c0cd349010005-NocioJ Received: from mga14.intel.com ([192.55.52.115]) by cuda.sgi.com with ESMTP id 7ge1G27wmzYCbe0c for ; Fri, 13 Nov 2015 16:07:10 -0800 (PST) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 192.55.52.115 Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga103.fm.intel.com with ESMTP; 13 Nov 2015 16:07:10 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,289,1444719600"; d="scan'208";a="684969856" Received: from theros.lm.intel.com ([10.232.112.87]) by orsmga003.jf.intel.com with ESMTP; 13 Nov 2015 16:07:08 -0800 From: Ross Zwisler To: linux-kernel@vger.kernel.org Cc: Ross Zwisler , "H. Peter Anvin" , "J. Bruce Fields" , "Theodore Ts'o" , Alexander Viro , Andreas Dilger , Dan Williams , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@lists.01.org, x86@kernel.org, xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox , Dave Hansen Subject: [PATCH v2 06/11] mm: add pgoff_mkclean() Date: Fri, 13 Nov 2015 17:06:45 -0700 X-ASG-Orig-Subj: [PATCH v2 06/11] mm: add pgoff_mkclean() Message-Id: <1447459610-14259-7-git-send-email-ross.zwisler@linux.intel.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> References: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> X-Barracuda-Connect: UNKNOWN[192.55.52.115] X-Barracuda-Start-Time: 1447459630 X-Barracuda-URL: https://192.48.176.15:443/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, BSF_SC5_MJ1963, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24375 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 Introduce pgoff_mkclean() which conceptually is similar to page_mkclean() except it works in the absence of struct page and it can also be used to clean PMDs. This is needed for DAX's dirty page handling. pgoff_mkclean() doesn't return an error for a missing PTE/PMD when looping through the VMAs because it's not a requirement that each of the potentially many VMAs associated with a given struct address_space have a mapping set up for our pgoff. Signed-off-by: Ross Zwisler --- include/linux/rmap.h | 5 +++++ mm/rmap.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/include/linux/rmap.h b/include/linux/rmap.h index 29446ae..171a4ac 100644 --- a/include/linux/rmap.h +++ b/include/linux/rmap.h @@ -223,6 +223,11 @@ unsigned long page_address_in_vma(struct page *, struct vm_area_struct *); int page_mkclean(struct page *); /* + * Cleans and write protects the PTEs of shared mappings. + */ +void pgoff_mkclean(pgoff_t, struct address_space *); + +/* * called in munlock()/munmap() path to check for other vmas holding * the page mlocked. */ diff --git a/mm/rmap.c b/mm/rmap.c index f5b5c1f..8114862 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -586,6 +586,16 @@ vma_address(struct page *page, struct vm_area_struct *vma) return address; } +static inline unsigned long +pgoff_address(pgoff_t pgoff, struct vm_area_struct *vma) +{ + unsigned long address; + + address = vma->vm_start + ((pgoff - vma->vm_pgoff) << PAGE_SHIFT); + VM_BUG_ON_VMA(address < vma->vm_start || address >= vma->vm_end, vma); + return address; +} + #ifdef CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH static void percpu_flush_tlb_batch_pages(void *data) { @@ -1040,6 +1050,47 @@ int page_mkclean(struct page *page) } EXPORT_SYMBOL_GPL(page_mkclean); +void pgoff_mkclean(pgoff_t pgoff, struct address_space *mapping) +{ + struct vm_area_struct *vma; + int ret = 0; + + i_mmap_lock_read(mapping); + vma_interval_tree_foreach(vma, &mapping->i_mmap, pgoff, pgoff) { + struct mm_struct *mm = vma->vm_mm; + pmd_t pmd, *pmdp = NULL; + pte_t pte, *ptep = NULL; + unsigned long address; + spinlock_t *ptl; + + address = pgoff_address(pgoff, vma); + + /* when this returns successfully ptl is locked */ + ret = follow_pte_pmd(mm, address, &ptep, &pmdp, &ptl); + if (ret) + continue; + + if (pmdp) { + flush_cache_page(vma, address, pmd_pfn(*pmdp)); + pmd = pmdp_huge_clear_flush(vma, address, pmdp); + pmd = pmd_wrprotect(pmd); + pmd = pmd_mkclean(pmd); + set_pmd_at(mm, address, pmdp, pmd); + spin_unlock(ptl); + } else { + BUG_ON(!ptep); + flush_cache_page(vma, address, pte_pfn(*ptep)); + pte = ptep_clear_flush(vma, address, ptep); + pte = pte_wrprotect(pte); + pte = pte_mkclean(pte); + set_pte_at(mm, address, ptep, pte); + pte_unmap_unlock(ptep, ptl); + } + } + i_mmap_unlock_read(mapping); +} +EXPORT_SYMBOL_GPL(pgoff_mkclean); + /** * page_move_anon_rmap - move a page to our anon_vma * @page: the page to move to our anon_vma -- 2.1.0 From ross.zwisler@linux.intel.com Fri Nov 13 18:07:13 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 948327F62 for ; Fri, 13 Nov 2015 18:07:13 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 8442D8F807A for ; Fri, 13 Nov 2015 16:07:13 -0800 (PST) X-ASG-Debug-ID: 1447459621-04cb6c0cd349010006-NocioJ Received: from mga14.intel.com ([192.55.52.115]) by cuda.sgi.com with ESMTP id YR7J3K8kGhHZgghZ for ; Fri, 13 Nov 2015 16:07:11 -0800 (PST) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 192.55.52.115 Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga103.fm.intel.com with ESMTP; 13 Nov 2015 16:07:11 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,289,1444719600"; d="scan'208";a="684969873" Received: from theros.lm.intel.com ([10.232.112.87]) by orsmga003.jf.intel.com with ESMTP; 13 Nov 2015 16:07:09 -0800 From: Ross Zwisler To: linux-kernel@vger.kernel.org Cc: Ross Zwisler , "H. Peter Anvin" , "J. Bruce Fields" , "Theodore Ts'o" , Alexander Viro , Andreas Dilger , Dan Williams , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@lists.01.org, x86@kernel.org, xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox , Dave Hansen Subject: [PATCH v2 07/11] mm: add find_get_entries_tag() Date: Fri, 13 Nov 2015 17:06:46 -0700 X-ASG-Orig-Subj: [PATCH v2 07/11] mm: add find_get_entries_tag() Message-Id: <1447459610-14259-8-git-send-email-ross.zwisler@linux.intel.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> References: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> X-Barracuda-Connect: UNKNOWN[192.55.52.115] X-Barracuda-Start-Time: 1447459631 X-Barracuda-URL: https://192.48.176.15:443/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, BSF_SC5_MJ1963, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24375 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 Add find_get_entries_tag() to the family of functions that include find_get_entries(), find_get_pages() and find_get_pages_tag(). This is needed for DAX dirty page handling because we need a list of both page offsets and radix tree entries ('indices' and 'entries' in this function) that are marked with the PAGECACHE_TAG_TOWRITE tag. Signed-off-by: Ross Zwisler --- include/linux/pagemap.h | 3 +++ mm/filemap.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index a6c78e0..6fea3be 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h @@ -354,6 +354,9 @@ unsigned find_get_pages_contig(struct address_space *mapping, pgoff_t start, unsigned int nr_pages, struct page **pages); unsigned find_get_pages_tag(struct address_space *mapping, pgoff_t *index, int tag, unsigned int nr_pages, struct page **pages); +unsigned find_get_entries_tag(struct address_space *mapping, pgoff_t start, + int tag, unsigned int nr_entries, + struct page **entries, pgoff_t *indices); struct page *grab_cache_page_write_begin(struct address_space *mapping, pgoff_t index, unsigned flags); diff --git a/mm/filemap.c b/mm/filemap.c index d5e94fd..89ab448 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -1454,6 +1454,67 @@ repeat: } EXPORT_SYMBOL(find_get_pages_tag); +/** + * find_get_entries_tag - find and return entries that match @tag + * @mapping: the address_space to search + * @start: the starting page cache index + * @tag: the tag index + * @nr_entries: the maximum number of entries + * @entries: where the resulting entries are placed + * @indices: the cache indices corresponding to the entries in @entries + * + * Like find_get_entries, except we only return entries which are tagged with + * @tag. + */ +unsigned find_get_entries_tag(struct address_space *mapping, pgoff_t start, + int tag, unsigned int nr_entries, + struct page **entries, pgoff_t *indices) +{ + void **slot; + unsigned int ret = 0; + struct radix_tree_iter iter; + + if (!nr_entries) + return 0; + + rcu_read_lock(); +restart: + radix_tree_for_each_tagged(slot, &mapping->page_tree, + &iter, start, tag) { + struct page *page; +repeat: + page = radix_tree_deref_slot(slot); + if (unlikely(!page)) + continue; + if (radix_tree_exception(page)) { + if (radix_tree_deref_retry(page)) + goto restart; + /* + * A shadow entry of a recently evicted page, a swap + * entry from shmem/tmpfs or a DAX entry. Return it + * without attempting to raise page count. + */ + goto export; + } + if (!page_cache_get_speculative(page)) + goto repeat; + + /* Has the page moved? */ + if (unlikely(page != *slot)) { + page_cache_release(page); + goto repeat; + } +export: + indices[ret] = iter.index; + entries[ret] = page; + if (++ret == nr_entries) + break; + } + rcu_read_unlock(); + return ret; +} +EXPORT_SYMBOL(find_get_entries_tag); + /* * CD/DVDs are error prone. When a medium error occurs, the driver may fail * a _large_ part of the i/o request. Imagine the worst scenario: -- 2.1.0 From ross.zwisler@linux.intel.com Fri Nov 13 18:07:17 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 644047F5A for ; Fri, 13 Nov 2015 18:07:17 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 46B96304096 for ; Fri, 13 Nov 2015 16:07:17 -0800 (PST) X-ASG-Debug-ID: 1447459634-04cbb0605d4e480001-NocioJ Received: from mga14.intel.com ([192.55.52.115]) by cuda.sgi.com with ESMTP id wPNLh3c0rIbi1Ocg for ; Fri, 13 Nov 2015 16:07:14 -0800 (PST) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 192.55.52.115 Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga103.fm.intel.com with ESMTP; 13 Nov 2015 16:07:12 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,289,1444719600"; d="scan'208";a="684969898" Received: from theros.lm.intel.com ([10.232.112.87]) by orsmga003.jf.intel.com with ESMTP; 13 Nov 2015 16:07:11 -0800 From: Ross Zwisler To: linux-kernel@vger.kernel.org Cc: Ross Zwisler , "H. Peter Anvin" , "J. Bruce Fields" , "Theodore Ts'o" , Alexander Viro , Andreas Dilger , Dan Williams , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@lists.01.org, x86@kernel.org, xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox , Dave Hansen Subject: [PATCH v2 08/11] dax: add support for fsync/sync Date: Fri, 13 Nov 2015 17:06:47 -0700 X-ASG-Orig-Subj: [PATCH v2 08/11] dax: add support for fsync/sync Message-Id: <1447459610-14259-9-git-send-email-ross.zwisler@linux.intel.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> References: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> X-Barracuda-Connect: UNKNOWN[192.55.52.115] X-Barracuda-Start-Time: 1447459634 X-Barracuda-URL: https://192.48.176.25:443/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, BSF_SC5_MJ1963, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24375 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 To properly handle fsync/msync in an efficient way DAX needs to track dirty pages so it is able to flush them durably to media on demand. The tracking of dirty pages is done via the radix tree in struct address_space. This radix tree is already used by the page writeback infrastructure for tracking dirty pages associated with an open file, and it already has support for exceptional (non struct page*) entries. We build upon these features to add exceptional entries to the radix tree for DAX dirty PMD or PTE pages at fault time. When called as part of the msync/fsync flush path DAX queries the radix tree for dirty entries, flushing them and then marking the PTE or PMD page table entries as clean. The step of cleaning the PTE or PMD entries is necessary so that on subsequent writes to the same page we get a new write fault allowing us to once again dirty the DAX tag in the radix tree. Signed-off-by: Ross Zwisler --- fs/dax.c | 140 +++++++++++++++++++++++++++++++++++++++++++++++++--- include/linux/dax.h | 1 + mm/huge_memory.c | 14 +++--- 3 files changed, 141 insertions(+), 14 deletions(-) diff --git a/fs/dax.c b/fs/dax.c index 131fd35a..9ce6d1b 100644 --- a/fs/dax.c +++ b/fs/dax.c @@ -24,7 +24,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -287,6 +289,53 @@ static int copy_user_bh(struct page *to, struct buffer_head *bh, return 0; } +static int dax_dirty_pgoff(struct address_space *mapping, unsigned long pgoff, + void __pmem *addr, bool pmd_entry) +{ + struct radix_tree_root *page_tree = &mapping->page_tree; + int error = 0; + void *entry; + + __mark_inode_dirty(mapping->host, I_DIRTY_PAGES); + + spin_lock_irq(&mapping->tree_lock); + entry = radix_tree_lookup(page_tree, pgoff); + if (addr == NULL) { + if (entry) + goto dirty; + else { + WARN(1, "DAX pfn_mkwrite failed to find an entry"); + goto out; + } + } + + if (entry) { + if (pmd_entry && RADIX_DAX_TYPE(entry) == RADIX_DAX_PTE) { + radix_tree_delete(&mapping->page_tree, pgoff); + mapping->nrdax--; + } else + goto dirty; + } + + BUG_ON(RADIX_DAX_TYPE(addr)); + if (pmd_entry) + error = radix_tree_insert(page_tree, pgoff, + RADIX_DAX_PMD_ENTRY(addr)); + else + error = radix_tree_insert(page_tree, pgoff, + RADIX_DAX_PTE_ENTRY(addr)); + + if (error) + goto out; + + mapping->nrdax++; + dirty: + radix_tree_tag_set(page_tree, pgoff, PAGECACHE_TAG_DIRTY); + out: + spin_unlock_irq(&mapping->tree_lock); + return error; +} + static int dax_insert_mapping(struct inode *inode, struct buffer_head *bh, struct vm_area_struct *vma, struct vm_fault *vmf) { @@ -327,7 +376,10 @@ static int dax_insert_mapping(struct inode *inode, struct buffer_head *bh, } error = vm_insert_mixed(vma, vaddr, pfn); + if (error) + goto out; + error = dax_dirty_pgoff(mapping, vmf->pgoff, addr, false); out: i_mmap_unlock_read(mapping); @@ -450,6 +502,7 @@ int __dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf, delete_from_page_cache(page); unlock_page(page); page_cache_release(page); + page = NULL; } /* @@ -537,7 +590,7 @@ int __dax_pmd_fault(struct vm_area_struct *vma, unsigned long address, pgoff_t size, pgoff; sector_t block, sector; unsigned long pfn; - int result = 0; + int error, result = 0; /* Fall back to PTEs if we're going to COW */ if (write && !(vma->vm_flags & VM_SHARED)) @@ -638,6 +691,10 @@ int __dax_pmd_fault(struct vm_area_struct *vma, unsigned long address, } result |= vmf_insert_pfn_pmd(vma, address, pmd, pfn, write); + + error = dax_dirty_pgoff(mapping, pgoff, kaddr, true); + if (error) + goto fallback; } out: @@ -689,15 +746,12 @@ EXPORT_SYMBOL_GPL(dax_pmd_fault); * dax_pfn_mkwrite - handle first write to DAX page * @vma: The virtual memory area where the fault occurred * @vmf: The description of the fault - * */ int dax_pfn_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) { - struct super_block *sb = file_inode(vma->vm_file)->i_sb; + struct file *file = vma->vm_file; - sb_start_pagefault(sb); - file_update_time(vma->vm_file); - sb_end_pagefault(sb); + dax_dirty_pgoff(file->f_mapping, vmf->pgoff, NULL, false); return VM_FAULT_NOPAGE; } EXPORT_SYMBOL_GPL(dax_pfn_mkwrite); @@ -772,3 +826,77 @@ int dax_truncate_page(struct inode *inode, loff_t from, get_block_t get_block) return dax_zero_page_range(inode, from, length, get_block); } EXPORT_SYMBOL_GPL(dax_truncate_page); + +static void dax_sync_entry(struct address_space *mapping, pgoff_t pgoff, + void *entry) +{ + struct radix_tree_root *page_tree = &mapping->page_tree; + int type = RADIX_DAX_TYPE(entry); + size_t size; + + BUG_ON(type != RADIX_DAX_PTE && type != RADIX_DAX_PMD); + + spin_lock_irq(&mapping->tree_lock); + if (!radix_tree_tag_get(page_tree, pgoff, PAGECACHE_TAG_TOWRITE)) { + /* another fsync thread already wrote back this entry */ + spin_unlock_irq(&mapping->tree_lock); + return; + } + radix_tree_tag_clear(page_tree, pgoff, PAGECACHE_TAG_TOWRITE); + radix_tree_tag_clear(page_tree, pgoff, PAGECACHE_TAG_DIRTY); + spin_unlock_irq(&mapping->tree_lock); + + if (type == RADIX_DAX_PMD) + size = PMD_SIZE; + else + size = PAGE_SIZE; + + wb_cache_pmem(RADIX_DAX_ADDR(entry), size); + pgoff_mkclean(pgoff, mapping); +} + +/* + * Flush the mapping to the persistent domain within the byte range of (start, + * end). This is required by data integrity operations to ensure file data is on + * persistent storage prior to completion of the operation. It also requires us + * to clean the mappings (i.e. write -> RO) so that we'll get a new fault when + * the file is written to again so we have an indication that we need to flush + * the mapping if a data integrity operation takes place. + * + * We don't need commits to storage here - the filesystems will issue flushes + * appropriately at the conclusion of the data integrity operation via REQ_FUA + * writes or blkdev_issue_flush() commands. This requires the DAX block device + * to implement persistent storage domain fencing/commits on receiving a + * REQ_FLUSH or REQ_FUA request so that this works as expected by the higher + * layers. + */ +void dax_fsync(struct address_space *mapping, loff_t start, loff_t end) +{ + struct inode *inode = mapping->host; + pgoff_t indices[PAGEVEC_SIZE]; + struct pagevec pvec; + int i; + + pgoff_t start_page = start >> PAGE_CACHE_SHIFT; + pgoff_t end_page = end >> PAGE_CACHE_SHIFT; + + if (mapping->nrdax == 0) + return; + + BUG_ON(inode->i_blkbits != PAGE_SHIFT); + + tag_pages_for_writeback(mapping, start_page, end_page); + + pagevec_init(&pvec, 0); + while (1) { + pvec.nr = find_get_entries_tag(mapping, start_page, + PAGECACHE_TAG_TOWRITE, PAGEVEC_SIZE, + pvec.pages, indices); + + if (pvec.nr == 0) + break; + + for (i = 0; i < pvec.nr; i++) + dax_sync_entry(mapping, indices[i], pvec.pages[i]); + } +} diff --git a/include/linux/dax.h b/include/linux/dax.h index e9d57f68..2b3ce6f 100644 --- a/include/linux/dax.h +++ b/include/linux/dax.h @@ -41,4 +41,5 @@ static inline bool dax_mapping(struct address_space *mapping) { return mapping->host && IS_DAX(mapping->host); } +void dax_fsync(struct address_space *mapping, loff_t start, loff_t end); #endif diff --git a/mm/huge_memory.c b/mm/huge_memory.c index bbac913..1b3df56 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -877,15 +877,13 @@ static void insert_pfn_pmd(struct vm_area_struct *vma, unsigned long addr, spinlock_t *ptl; ptl = pmd_lock(mm, pmd); - if (pmd_none(*pmd)) { - entry = pmd_mkhuge(pfn_pmd(pfn, prot)); - if (write) { - entry = pmd_mkyoung(pmd_mkdirty(entry)); - entry = maybe_pmd_mkwrite(entry, vma); - } - set_pmd_at(mm, addr, pmd, entry); - update_mmu_cache_pmd(vma, addr, pmd); + entry = pmd_mkhuge(pfn_pmd(pfn, prot)); + if (write) { + entry = pmd_mkyoung(pmd_mkdirty(entry)); + entry = maybe_pmd_mkwrite(entry, vma); } + set_pmd_at(mm, addr, pmd, entry); + update_mmu_cache_pmd(vma, addr, pmd); spin_unlock(ptl); } -- 2.1.0 From ross.zwisler@linux.intel.com Fri Nov 13 18:07:19 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 4FF7C7F5D for ; Fri, 13 Nov 2015 18:07:19 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 401F48F808F for ; Fri, 13 Nov 2015 16:07:19 -0800 (PST) X-ASG-Debug-ID: 1447459634-04cbb0605d4e480002-NocioJ Received: from mga14.intel.com ([192.55.52.115]) by cuda.sgi.com with ESMTP id YtZtoGaqMKcv2U1D for ; Fri, 13 Nov 2015 16:07:17 -0800 (PST) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 192.55.52.115 Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga103.fm.intel.com with ESMTP; 13 Nov 2015 16:07:14 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,289,1444719600"; d="scan'208";a="684969923" Received: from theros.lm.intel.com ([10.232.112.87]) by orsmga003.jf.intel.com with ESMTP; 13 Nov 2015 16:07:12 -0800 From: Ross Zwisler To: linux-kernel@vger.kernel.org Cc: Ross Zwisler , "H. Peter Anvin" , "J. Bruce Fields" , "Theodore Ts'o" , Alexander Viro , Andreas Dilger , Dan Williams , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@lists.01.org, x86@kernel.org, xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox , Dave Hansen Subject: [PATCH v2 09/11] ext2: add support for DAX fsync/msync Date: Fri, 13 Nov 2015 17:06:48 -0700 X-ASG-Orig-Subj: [PATCH v2 09/11] ext2: add support for DAX fsync/msync Message-Id: <1447459610-14259-10-git-send-email-ross.zwisler@linux.intel.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> References: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> X-Barracuda-Connect: UNKNOWN[192.55.52.115] X-Barracuda-Start-Time: 1447459635 X-Barracuda-URL: https://192.48.176.25:443/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, BSF_SC5_MJ1963, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24375 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 To properly support the new DAX fsync/msync infrastructure filesystems need to call dax_pfn_mkwrite() so that DAX can properly track when a user write faults on a previously cleaned address. They also need to call dax_fsync() in the filesystem fsync() path. This dax_fsync() call uses addresses retrieved from get_block() so it needs to be ordered with respect to truncate. This is accomplished by using the same locking that was set up for DAX page faults. Signed-off-by: Ross Zwisler --- fs/ext2/file.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/fs/ext2/file.c b/fs/ext2/file.c index 11a42c5..6c30ea2 100644 --- a/fs/ext2/file.c +++ b/fs/ext2/file.c @@ -102,8 +102,8 @@ static int ext2_dax_pfn_mkwrite(struct vm_area_struct *vma, { struct inode *inode = file_inode(vma->vm_file); struct ext2_inode_info *ei = EXT2_I(inode); - int ret = VM_FAULT_NOPAGE; loff_t size; + int ret; sb_start_pagefault(inode->i_sb); file_update_time(vma->vm_file); @@ -113,6 +113,8 @@ static int ext2_dax_pfn_mkwrite(struct vm_area_struct *vma, size = (i_size_read(inode) + PAGE_SIZE - 1) >> PAGE_SHIFT; if (vmf->pgoff >= size) ret = VM_FAULT_SIGBUS; + else + ret = dax_pfn_mkwrite(vma, vmf); up_read(&ei->dax_sem); sb_end_pagefault(inode->i_sb); @@ -161,6 +163,16 @@ int ext2_fsync(struct file *file, loff_t start, loff_t end, int datasync) struct super_block *sb = file->f_mapping->host->i_sb; struct address_space *mapping = sb->s_bdev->bd_inode->i_mapping; +#ifdef CONFIG_FS_DAX + if (dax_mapping(mapping)) { + struct ext2_inode_info *ei = EXT2_I(file_inode(file)); + + down_read(&ei->dax_sem); + dax_fsync(mapping, start, end); + up_read(&ei->dax_sem); + } +#endif + ret = generic_file_fsync(file, start, end, datasync); if (ret == -EIO || test_and_clear_bit(AS_EIO, &mapping->flags)) { /* We don't really know where the IO error happened... */ -- 2.1.0 From ross.zwisler@linux.intel.com Fri Nov 13 18:07:22 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 987277F5D for ; Fri, 13 Nov 2015 18:07:22 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 183ECAC009 for ; Fri, 13 Nov 2015 16:07:22 -0800 (PST) X-ASG-Debug-ID: 1447459634-04cbb0605d4e480003-NocioJ Received: from mga14.intel.com ([192.55.52.115]) by cuda.sgi.com with ESMTP id LAcQcag9i3dFigdC for ; Fri, 13 Nov 2015 16:07:20 -0800 (PST) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 192.55.52.115 Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga103.fm.intel.com with ESMTP; 13 Nov 2015 16:07:16 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,289,1444719600"; d="scan'208";a="684969929" Received: from theros.lm.intel.com ([10.232.112.87]) by orsmga003.jf.intel.com with ESMTP; 13 Nov 2015 16:07:14 -0800 From: Ross Zwisler To: linux-kernel@vger.kernel.org Cc: Ross Zwisler , "H. Peter Anvin" , "J. Bruce Fields" , "Theodore Ts'o" , Alexander Viro , Andreas Dilger , Dan Williams , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@lists.01.org, x86@kernel.org, xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox , Dave Hansen Subject: [PATCH v2 10/11] ext4: add support for DAX fsync/msync Date: Fri, 13 Nov 2015 17:06:49 -0700 X-ASG-Orig-Subj: [PATCH v2 10/11] ext4: add support for DAX fsync/msync Message-Id: <1447459610-14259-11-git-send-email-ross.zwisler@linux.intel.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> References: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> X-Barracuda-Connect: UNKNOWN[192.55.52.115] X-Barracuda-Start-Time: 1447459638 X-Barracuda-URL: https://192.48.176.25:443/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, BSF_SC5_MJ1963, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24375 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 To properly support the new DAX fsync/msync infrastructure filesystems need to call dax_pfn_mkwrite() so that DAX can properly track when a user write faults on a previously cleaned address. They also need to call dax_fsync() in the filesystem fsync() path. This dax_fsync() call uses addresses retrieved from get_block() so it needs to be ordered with respect to truncate. This is accomplished by using the same locking that was set up for DAX page faults. Signed-off-by: Ross Zwisler --- fs/ext4/file.c | 4 +++- fs/ext4/fsync.c | 12 ++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/fs/ext4/file.c b/fs/ext4/file.c index 749b222..8c8965c 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c @@ -291,8 +291,8 @@ static int ext4_dax_pfn_mkwrite(struct vm_area_struct *vma, { struct inode *inode = file_inode(vma->vm_file); struct super_block *sb = inode->i_sb; - int ret = VM_FAULT_NOPAGE; loff_t size; + int ret; sb_start_pagefault(sb); file_update_time(vma->vm_file); @@ -300,6 +300,8 @@ static int ext4_dax_pfn_mkwrite(struct vm_area_struct *vma, size = (i_size_read(inode) + PAGE_SIZE - 1) >> PAGE_SHIFT; if (vmf->pgoff >= size) ret = VM_FAULT_SIGBUS; + else + ret = dax_pfn_mkwrite(vma, vmf); up_read(&EXT4_I(inode)->i_mmap_sem); sb_end_pagefault(sb); diff --git a/fs/ext4/fsync.c b/fs/ext4/fsync.c index 8850254..e87c29b 100644 --- a/fs/ext4/fsync.c +++ b/fs/ext4/fsync.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "ext4.h" #include "ext4_jbd2.h" @@ -86,7 +87,8 @@ static int ext4_sync_parent(struct inode *inode) int ext4_sync_file(struct file *file, loff_t start, loff_t end, int datasync) { - struct inode *inode = file->f_mapping->host; + struct address_space *mapping = file->f_mapping; + struct inode *inode = mapping->host; struct ext4_inode_info *ei = EXT4_I(inode); journal_t *journal = EXT4_SB(inode->i_sb)->s_journal; int ret = 0, err; @@ -112,7 +114,13 @@ int ext4_sync_file(struct file *file, loff_t start, loff_t end, int datasync) goto out; } - ret = filemap_write_and_wait_range(inode->i_mapping, start, end); + if (dax_mapping(mapping)) { + down_read(&ei->i_mmap_sem); + dax_fsync(mapping, start, end); + up_read(&ei->i_mmap_sem); + } + + ret = filemap_write_and_wait_range(mapping, start, end); if (ret) return ret; /* -- 2.1.0 From ross.zwisler@linux.intel.com Fri Nov 13 18:07:23 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 102DF7F5A for ; Fri, 13 Nov 2015 18:07:23 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 003DC30408F for ; Fri, 13 Nov 2015 16:07:22 -0800 (PST) X-ASG-Debug-ID: 1447459634-04cbb0605d4e480004-NocioJ Received: from mga14.intel.com ([192.55.52.115]) by cuda.sgi.com with ESMTP id j6AGgPxshpqGqm0D for ; Fri, 13 Nov 2015 16:07:21 -0800 (PST) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 192.55.52.115 Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga103.fm.intel.com with ESMTP; 13 Nov 2015 16:07:17 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,289,1444719600"; d="scan'208";a="684969946" Received: from theros.lm.intel.com ([10.232.112.87]) by orsmga003.jf.intel.com with ESMTP; 13 Nov 2015 16:07:15 -0800 From: Ross Zwisler To: linux-kernel@vger.kernel.org Cc: Ross Zwisler , "H. Peter Anvin" , "J. Bruce Fields" , "Theodore Ts'o" , Alexander Viro , Andreas Dilger , Dan Williams , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@lists.01.org, x86@kernel.org, xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox , Dave Hansen Subject: [PATCH v2 11/11] xfs: add support for DAX fsync/msync Date: Fri, 13 Nov 2015 17:06:50 -0700 X-ASG-Orig-Subj: [PATCH v2 11/11] xfs: add support for DAX fsync/msync Message-Id: <1447459610-14259-12-git-send-email-ross.zwisler@linux.intel.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> References: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> X-Barracuda-Connect: UNKNOWN[192.55.52.115] X-Barracuda-Start-Time: 1447459641 X-Barracuda-URL: https://192.48.176.25:443/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, BSF_SC5_MJ1963, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24375 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 To properly support the new DAX fsync/msync infrastructure filesystems need to call dax_pfn_mkwrite() so that DAX can properly track when a user write faults on a previously cleaned address. They also need to call dax_fsync() in the filesystem fsync() path. This dax_fsync() call uses addresses retrieved from get_block() so it needs to be ordered with respect to truncate. This is accomplished by using the same locking that was set up for DAX page faults. Signed-off-by: Ross Zwisler --- fs/xfs/xfs_file.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 39743ef..2b490a1 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -209,7 +209,8 @@ xfs_file_fsync( loff_t end, int datasync) { - struct inode *inode = file->f_mapping->host; + struct address_space *mapping = file->f_mapping; + struct inode *inode = mapping->host; struct xfs_inode *ip = XFS_I(inode); struct xfs_mount *mp = ip->i_mount; int error = 0; @@ -218,7 +219,13 @@ xfs_file_fsync( trace_xfs_file_fsync(ip); - error = filemap_write_and_wait_range(inode->i_mapping, start, end); + if (dax_mapping(mapping)) { + xfs_ilock(XFS_I(inode), XFS_MMAPLOCK_SHARED); + dax_fsync(mapping, start, end); + xfs_iunlock(XFS_I(inode), XFS_MMAPLOCK_SHARED); + } + + error = filemap_write_and_wait_range(mapping, start, end); if (error) return error; @@ -1603,9 +1610,8 @@ xfs_filemap_pmd_fault( /* * pfn_mkwrite was originally inteneded to ensure we capture time stamp * updates on write faults. In reality, it's need to serialise against - * truncate similar to page_mkwrite. Hence we open-code dax_pfn_mkwrite() - * here and cycle the XFS_MMAPLOCK_SHARED to ensure we serialise the fault - * barrier in place. + * truncate similar to page_mkwrite. Hence we cycle the XFS_MMAPLOCK_SHARED + * to ensure we serialise the fault barrier in place. */ static int xfs_filemap_pfn_mkwrite( @@ -1628,6 +1634,8 @@ xfs_filemap_pfn_mkwrite( size = (i_size_read(inode) + PAGE_SIZE - 1) >> PAGE_SHIFT; if (vmf->pgoff >= size) ret = VM_FAULT_SIGBUS; + else if (IS_DAX(inode)) + ret = dax_pfn_mkwrite(vma, vmf); xfs_iunlock(ip, XFS_MMAPLOCK_SHARED); sb_end_pagefault(inode->i_sb); return ret; -- 2.1.0 From dan.j.williams@intel.com Fri Nov 13 18:20:43 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 32E377F5A for ; Fri, 13 Nov 2015 18:20:43 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 112298F80A1 for ; Fri, 13 Nov 2015 16:20:42 -0800 (PST) X-ASG-Debug-ID: 1447460440-04cb6c0cd249960001-NocioJ Received: from mail-wm0-f43.google.com (mail-wm0-f43.google.com [74.125.82.43]) by cuda.sgi.com with ESMTP id 5WeMclriDTWcAPpX (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Fri, 13 Nov 2015 16:20:40 -0800 (PST) X-Barracuda-Envelope-From: dan.j.williams@intel.com X-Barracuda-Apparent-Source-IP: 74.125.82.43 Received: by wmec201 with SMTP id c201so51920558wme.1 for ; Fri, 13 Nov 2015 16:20:40 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=intel_com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=IY+Terkz3WO7LQ7CdwwNh6+eiIv46gLyobGqgFDqPjk=; b=m1TeuW3N+XVqVTzsqARN++GBguqGKu5pEeTUCexSiYCsY5naJ8KYYXpygHq7pXufd6 oy/bWYIbc2/e9W+MuV0GYDpMw4jQpA1GFz4aAQcjQ4ypXM6p276ba88JxhpQlJYCDJkR C1V/Mhpwp+dMMqbBltrn3EKEB5T5wk148cdH0nrJz0jFkbccQIcmfaiRvbIJrhQ/HpdE qgj9bJds1cbnC0K7RhEJYnTj9xyv8D9ZNVqWaBuVGDbzC83j9F8gd6W3Yjas502bG2bG 4oSUYzA0Q0JV3uvDQeQWJtIUn5EmgYrXzi5LHY+2LO9w7azfueMQJ8tf/oPOGmTQesBQ Oasw== 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=IY+Terkz3WO7LQ7CdwwNh6+eiIv46gLyobGqgFDqPjk=; b=IQOpuypHaR6YmSLXn5HyFXy+Z05jMsXh1DUs4BOxfXzSRsAbeCtsr89fQ67XuOxKAP zIhSPAt+CSZfwNA3oi7SwtSGGDtIzQUkpaBHIo+1rH8xOPJkCn9v+1CNzwU3YNbXYu1Q NY6yRqn6aaO1fYNxVnkLFTTcqKbsABrT0FLq7nrM+zRNjBw2OXLp5frvFFlM165RWk42 MJpzQIlhIwfiNjdGN2ewxqEi7fsJR5ZT1qslYFC7IOeOXbIAwI2hRVjwcy0haFaJVRZP gu3Ocs2JToqSjpiMyLMy6KiPTVfsVQV0Bzm65AlMO1d8gdAjQiK5wa1fDGC2z5kZhnxg uUPg== X-Gm-Message-State: ALoCoQnEOUHXefTa2YQXYAdZWaJU5MglL+P5Kp2j64GO1YfER0GdiW1dcR8OkALB0kO/yQ/2Kq2y MIME-Version: 1.0 X-Received: by 10.194.186.170 with SMTP id fl10mr25441833wjc.91.1447460439998; Fri, 13 Nov 2015 16:20:39 -0800 (PST) Received: by 10.27.88.130 with HTTP; Fri, 13 Nov 2015 16:20:39 -0800 (PST) In-Reply-To: <1447459610-14259-4-git-send-email-ross.zwisler@linux.intel.com> References: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> <1447459610-14259-4-git-send-email-ross.zwisler@linux.intel.com> Date: Fri, 13 Nov 2015 16:20:39 -0800 Message-ID: Subject: Re: [PATCH v2 03/11] pmem: enable REQ_FUA/REQ_FLUSH handling From: Dan Williams X-ASG-Orig-Subj: Re: [PATCH v2 03/11] pmem: enable REQ_FUA/REQ_FLUSH handling To: Ross Zwisler Cc: "linux-kernel@vger.kernel.org" , "H. Peter Anvin" , "J. Bruce Fields" , "Theodore Ts'o" , Alexander Viro , Andreas Dilger , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel , Linux MM , "linux-nvdimm@lists.01.org" , X86 ML , xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox , Dave Hansen Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-wm0-f43.google.com[74.125.82.43] X-Barracuda-Start-Time: 1447460440 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24375 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, Nov 13, 2015 at 4:06 PM, Ross Zwisler wrote: > Currently the PMEM driver doesn't accept REQ_FLUSH or REQ_FUA bios. These > are sent down via blkdev_issue_flush() in response to a fsync() or msync() > and are used by filesystems to order their metadata, among other things. > > When we get an msync() or fsync() it is the responsibility of the DAX code > to flush all dirty pages to media. The PMEM driver then just has issue a > wmb_pmem() in response to the REQ_FLUSH to ensure that before we return all > the flushed data has been durably stored on the media. > > Signed-off-by: Ross Zwisler Hmm, I'm not seeing why we need this patch. If the actual flushing of the cache is done by the core why does the driver need support REQ_FLUSH? Especially since it's just a couple instructions. REQ_FUA only makes sense if individual writes can bypass the "drive" cache, but no I/O submitted to the driver proper is ever cached we always flush it through to media. From adilger@dilger.ca Fri Nov 13 18:43:39 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 32A3F7F5A for ; Fri, 13 Nov 2015 18:43:39 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id AC4F5AC01B for ; Fri, 13 Nov 2015 16:43:38 -0800 (PST) X-ASG-Debug-ID: 1447461815-04cb6c0cd34a500001-NocioJ Received: from mail-pa0-f46.google.com (mail-pa0-f46.google.com [209.85.220.46]) by cuda.sgi.com with ESMTP id eeATjeBjBfIIXzWU (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Fri, 13 Nov 2015 16:43:35 -0800 (PST) X-Barracuda-Envelope-From: adilger@dilger.ca X-Barracuda-Apparent-Source-IP: 209.85.220.46 Received: by pacej9 with SMTP id ej9so8428852pac.2 for ; Fri, 13 Nov 2015 16:43:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=dilger_ca.20150623.gappssmtp.com; s=20150623; h=subject:mime-version:content-type:from:in-reply-to:date:cc :message-id:references:to; bh=4Bd2fcbtzmuCSDtBoxz0OYGSMbhBMaSdK9ZMD8COeDs=; b=FRtcPR0XF7cuA4iOY1vat9ULQlqU5MTzG+Fj3JzRMSdDQJwGUn1g69o1F8XQc2xFH7 pMURBGhyLkx7I0z0aDjNI9B5yPHStdC+9xWePHiHxnuvrhZqQ4ZaxK9qfbAT5Nzn1RNg UKFhMwzdOlnrRVOcunyGTpyVtCxWCb+It0HKQYaYKsiVkle+VznmmitiEvqn2lswlW+W vDinfQohq8Ndghmxb+BGgy7Be+vOcavhaA+N7hVQJk1YKjgkY56HPmLdjnHRd4T36qz6 PYXQ9LvYHDq8UDbCvXHhT+RnHjvCxF7WaTQ9PpsdxX9GL2puAajOjaLEZbclTA6gExV/ A1yQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:subject:mime-version:content-type:from :in-reply-to:date:cc:message-id:references:to; bh=4Bd2fcbtzmuCSDtBoxz0OYGSMbhBMaSdK9ZMD8COeDs=; b=fWRfsI/Xf2R8ZL0FcwXx7DExFZtw+e+lxO/ZmqH6pgdlMPNC83FjRunC7NZkFBv8w6 /nOZ/6YPvLqeAT/oW1UhRdAsZOOmjJZRCZA8rCLVFYKgH9x4B1brMqExBpS9aIkPq0bN s/jYgGGrZKqn3mRZvUhKs1o1+hbkAcEQL1Av/OSw3hf8WcYV3zoqyPEe1eaMwzxAffB4 srK/kx9+e7fLkc8C+7FsoFGTm56zdxnixhCcwFY/exJOFhEtmo72aJLKsh7KyHR4h5Ed M5bah7M3y1VX90wDPFmwKTXlWKO9E3EvjJDvjESanPmjjttN/QIcavd7NE4djDOV3foa Dhgg== X-Gm-Message-State: ALoCoQnUuOkKt1+ApWV6CFrjlaWdklOQboujWP7z5hv0ylDkQN1MqDwgCMQw1mqWI+zApZpd2B1g X-Received: by 10.66.140.39 with SMTP id rd7mr36788052pab.86.1447461814733; Fri, 13 Nov 2015 16:43:34 -0800 (PST) Received: from cabot-wlan.adilger.int (S0106002191d9348b.cg.shawcable.net. [96.51.76.157]) by smtp.gmail.com with ESMTPSA id ef2sm22560202pbc.92.2015.11.13.16.43.32 (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 13 Nov 2015 16:43:33 -0800 (PST) Subject: Re: [PATCH v2 03/11] pmem: enable REQ_FUA/REQ_FLUSH handling Mime-Version: 1.0 (Mac OS X Mail 8.2 \(2104\)) X-ASG-Orig-Subj: Re: [PATCH v2 03/11] pmem: enable REQ_FUA/REQ_FLUSH handling Content-Type: multipart/signed; boundary="Apple-Mail=_1216766E-B738-4495-BFC0-CB153BFD6B45"; protocol="application/pgp-signature"; micalg=pgp-sha256 X-Pgp-Agent: GPGMail 2.5.2 From: Andreas Dilger In-Reply-To: Date: Fri, 13 Nov 2015 17:43:28 -0700 Cc: Ross Zwisler , "linux-kernel@vger.kernel.org" , "H. Peter Anvin" , "J. Bruce Fields" , Theodore Ts'o , Alexander Viro , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4 , linux-fsdevel , Linux MM , "linux-nvdimm@lists.01.org" , X86 ML , XFS Developers , Andrew Morton , Matthew Wilcox , Dave Hansen Message-Id: <22E0F870-C1FB-431E-BF6C-B395A09A2B0D@dilger.ca> References: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> <1447459610-14259-4-git-send-email-ross.zwisler@linux.intel.com> To: Dan Williams X-Mailer: Apple Mail (2.2104) X-Barracuda-Connect: mail-pa0-f46.google.com[209.85.220.46] X-Barracuda-Start-Time: 1447461815 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24375 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 --Apple-Mail=_1216766E-B738-4495-BFC0-CB153BFD6B45 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii On Nov 13, 2015, at 5:20 PM, Dan Williams = wrote: >=20 > On Fri, Nov 13, 2015 at 4:06 PM, Ross Zwisler > wrote: >> Currently the PMEM driver doesn't accept REQ_FLUSH or REQ_FUA bios. = These >> are sent down via blkdev_issue_flush() in response to a fsync() or = msync() >> and are used by filesystems to order their metadata, among other = things. >>=20 >> When we get an msync() or fsync() it is the responsibility of the DAX = code >> to flush all dirty pages to media. The PMEM driver then just has = issue a >> wmb_pmem() in response to the REQ_FLUSH to ensure that before we = return all >> the flushed data has been durably stored on the media. >>=20 >> Signed-off-by: Ross Zwisler >=20 > Hmm, I'm not seeing why we need this patch. If the actual flushing of > the cache is done by the core why does the driver need support > REQ_FLUSH? Especially since it's just a couple instructions. REQ_FUA > only makes sense if individual writes can bypass the "drive" cache, > but no I/O submitted to the driver proper is ever cached we always > flush it through to media. If the upper level filesystem gets an error when submitting a flush request, then it assumes the underlying hardware is broken and cannot be as aggressive in IO submission, but instead has to wait for in-flight IO to complete. Since FUA/FLUSH is basically a no-op for pmem devices, it doesn't make sense _not_ to support this functionality. Cheers, Andreas --Apple-Mail=_1216766E-B738-4495-BFC0-CB153BFD6B45 Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename=signature.asc Content-Type: application/pgp-signature; name=signature.asc Content-Description: Message signed with OpenPGP using GPGMail -----BEGIN PGP SIGNATURE----- Comment: GPGTools - http://gpgtools.org iQIVAwUBVkaDsXKl2rkXzB/gAQibwBAAgoTcZevnn7sprjKcrySWAvw9bcubKzY8 W4c6wkFftY8858ROsblZ/0+OhZPFlf2zJ2G3g+8sJ4Upv1s0MpyGHYS6QVu/QLn3 xy4O7ivbLMtFOfMFWfheKAb8GxJxzpklB5yhyHaMnxtCxEg71K5D9mnqTi/jPIv6 L0yWugsuzeSVeJ423NsFCxRZkWN2wrSuT6PS7bPeN/VBUC8wfU+LMXnmye9+tl1Z EkZWf11PQOz5kkEkN6Xk+ShgAVz7GR6w3jYHxDvNbZ+bDvlPGsV8Wvf+GZIo0Q4/ SdhfRfNG/D2KKQlCAfZyyEdcSRcoSvkhAPny+ocGW9+rUNd86LMllbvfGzkRNH9Y pfocoQZHxcJ9G52XeqVVJvFzajQhPryzdOePg5YwnckY5h6Td0K46THztFKMN51K vXNhhbV/EHy7EjgNOsu+4tTfWrVdSGB4AiKlJlZ4SU5e4FaJxLR00jzm5nVSZpbC NW8NO+uE8deVLw1BJbVFq6S4qm1NshY0EZ4SYuksdJaAwo3kZtdjvbmnFq2Er+ta PVoWA5oJl5pZ0WRxEckchTIXC7iqwgVdBtPBqiAOZ4u+X3caU7kx+hYpjCymozvy 6RdWl1hfgIv5lkJGf1SBOaLz1KSu2ElTtGDbWaQpxnKNnsE0Ye/gTd4m9bb86e+O b5j4DzeyM0E= =ibQq -----END PGP SIGNATURE----- --Apple-Mail=_1216766E-B738-4495-BFC0-CB153BFD6B45-- From dave.hansen@intel.com Fri Nov 13 19:03:03 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 0866D7F5A for ; Fri, 13 Nov 2015 19:03:03 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id DF0C88F80CE for ; Fri, 13 Nov 2015 17:02:59 -0800 (PST) X-ASG-Debug-ID: 1447462973-04bdf07f094f3a0001-NocioJ Received: from mga11.intel.com ([192.55.52.93]) by cuda.sgi.com with ESMTP id CoY8yha69U0KhSTm for ; Fri, 13 Nov 2015 17:02:53 -0800 (PST) X-Barracuda-Envelope-From: dave.hansen@intel.com X-Barracuda-Apparent-Source-IP: 192.55.52.93 X-ASG-Whitelist: EmailCat (corporate) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga102.fm.intel.com with ESMTP; 13 Nov 2015 17:02:53 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,289,1444719600"; d="scan'208";a="819571450" Received: from djnaayke-mobl.amr.corp.intel.com (HELO [10.254.116.159]) ([10.254.116.159]) by orsmga001.jf.intel.com with ESMTP; 13 Nov 2015 17:02:48 -0800 Subject: Re: [PATCH v2 02/11] mm: add pmd_mkclean() To: Ross Zwisler , linux-kernel@vger.kernel.org X-ASG-Orig-Subj: Re: [PATCH v2 02/11] mm: add pmd_mkclean() References: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> <1447459610-14259-3-git-send-email-ross.zwisler@linux.intel.com> Cc: "H. Peter Anvin" , "J. Bruce Fields" , Theodore Ts'o , Alexander Viro , Andreas Dilger , Dan Williams , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@lists.01.org, x86@kernel.org, xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox From: Dave Hansen Message-ID: <56468838.6010506@intel.com> Date: Fri, 13 Nov 2015 17:02:48 -0800 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <1447459610-14259-3-git-send-email-ross.zwisler@linux.intel.com> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: UNKNOWN[192.55.52.93] X-Barracuda-Start-Time: 1447462973 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On 11/13/2015 04:06 PM, Ross Zwisler wrote: > +static inline pmd_t pmd_mkclean(pmd_t pmd) > +{ > + return pmd_clear_flags(pmd, _PAGE_DIRTY | _PAGE_SOFT_DIRTY); > +} pte_mkclean() doesn't clear _PAGE_SOFT_DIRTY. What the thought behind doing it here? From dan.j.williams@intel.com Fri Nov 13 20:32:47 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 8C3D67F50 for ; Fri, 13 Nov 2015 20:32:47 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 38DCBAC030 for ; Fri, 13 Nov 2015 18:32:44 -0800 (PST) X-ASG-Debug-ID: 1447468360-04bdf07f08529d0001-NocioJ Received: from mail-wm0-f44.google.com (mail-wm0-f44.google.com [74.125.82.44]) by cuda.sgi.com with ESMTP id l75nREyp8WfHDC2a (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Fri, 13 Nov 2015 18:32:41 -0800 (PST) X-Barracuda-Envelope-From: dan.j.williams@intel.com X-Barracuda-Apparent-Source-IP: 74.125.82.44 Received: by wmec201 with SMTP id c201so106552505wme.0 for ; Fri, 13 Nov 2015 18:32:40 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=intel_com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=cAUx42EW9QZf6LP/gz5MdcnBjBopzClnUW/w69zkUa4=; b=UwoCzqq63fc2UPrdckYX9rej02YrNKkft4/y30WGDZoWnIKw8aZ60kUQmi/al4T1D9 sOVaIAgKzqi73MeAZhitmELbUhK1761ThLprqvxgBhlYmLnVZMK5J0+z6kNZztW6csBs zzsV941Qldnb0HSk+axWfxXWOq3OEF26O4k/sXqeSqJXwFfjGKcfLtf2+5bkxwN1pCxR 7yze+2RH5OJHfFyIrHYbcU51dUoVtO4bC2Ssr6jP6wYGqXXvVGDTLYCIC5B/UygWaBFB dWO/VX1Exh2i2cg3BPW6kYwsQRqSff9mgxK7ru5kEhzE3DHqV4UB9xrkM2TSEgUtHgnm R5/g== 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=cAUx42EW9QZf6LP/gz5MdcnBjBopzClnUW/w69zkUa4=; b=lTE8gIz1lQFMK+NjPB/3ejspnmLB+C0GAlytlUPPcyT6XZFunqKYLqIoIOJ9QMZ95W GN3U3c/xLakK1hsMOV2phXh1bzep9BdpwpbFUCRZiitIa5g4/sz70Tpjln8LxWucuSzn QMhRfLkwse7PI2CWUcjI35fN05Gl24UgUPIveeEYHI7ooBdFqSz5IzrI7NHgkpXt3HSh yyiFbAoIEqLgbYp4+fM/UT4WH4B7s+DzhLZo2Jj2ZDhoBJOO6v62BuG62wqo3lR7mvpJ MmSVrclEGn/dCJBmjcuSRR6hzfrVDAMaJpOHQyt2CovSYlA/3vy+Hspp0Ihcr9SCMvMa thVA== X-Gm-Message-State: ALoCoQmwlympo5oD2d4lAd8vALtKovRNgnXReV991M92WtkeDeYBkkrfmCBuROjkQdhMbLhV7nQj MIME-Version: 1.0 X-Received: by 10.28.220.69 with SMTP id t66mr6791474wmg.4.1447468360080; Fri, 13 Nov 2015 18:32:40 -0800 (PST) Received: by 10.27.88.130 with HTTP; Fri, 13 Nov 2015 18:32:40 -0800 (PST) In-Reply-To: <22E0F870-C1FB-431E-BF6C-B395A09A2B0D@dilger.ca> References: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> <1447459610-14259-4-git-send-email-ross.zwisler@linux.intel.com> <22E0F870-C1FB-431E-BF6C-B395A09A2B0D@dilger.ca> Date: Fri, 13 Nov 2015 18:32:40 -0800 Message-ID: Subject: Re: [PATCH v2 03/11] pmem: enable REQ_FUA/REQ_FLUSH handling From: Dan Williams X-ASG-Orig-Subj: Re: [PATCH v2 03/11] pmem: enable REQ_FUA/REQ_FLUSH handling To: Andreas Dilger Cc: Ross Zwisler , "linux-kernel@vger.kernel.org" , "H. Peter Anvin" , "J. Bruce Fields" , "Theodore Ts'o" , Alexander Viro , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4 , linux-fsdevel , Linux MM , "linux-nvdimm@lists.01.org" , X86 ML , XFS Developers , Andrew Morton , Matthew Wilcox , Dave Hansen Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-wm0-f44.google.com[74.125.82.44] X-Barracuda-Start-Time: 1447468361 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24378 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, Nov 13, 2015 at 4:43 PM, Andreas Dilger wrote: > On Nov 13, 2015, at 5:20 PM, Dan Williams wrote: >> >> On Fri, Nov 13, 2015 at 4:06 PM, Ross Zwisler >> wrote: >>> Currently the PMEM driver doesn't accept REQ_FLUSH or REQ_FUA bios. These >>> are sent down via blkdev_issue_flush() in response to a fsync() or msync() >>> and are used by filesystems to order their metadata, among other things. >>> >>> When we get an msync() or fsync() it is the responsibility of the DAX code >>> to flush all dirty pages to media. The PMEM driver then just has issue a >>> wmb_pmem() in response to the REQ_FLUSH to ensure that before we return all >>> the flushed data has been durably stored on the media. >>> >>> Signed-off-by: Ross Zwisler >> >> Hmm, I'm not seeing why we need this patch. If the actual flushing of >> the cache is done by the core why does the driver need support >> REQ_FLUSH? Especially since it's just a couple instructions. REQ_FUA >> only makes sense if individual writes can bypass the "drive" cache, >> but no I/O submitted to the driver proper is ever cached we always >> flush it through to media. > > If the upper level filesystem gets an error when submitting a flush > request, then it assumes the underlying hardware is broken and cannot > be as aggressive in IO submission, but instead has to wait for in-flight > IO to complete. Upper level filesystems won't get errors when the driver does not support flush. Those requests are ended cleanly in generic_make_request_checks(). Yes, the fs still needs to wait for outstanding I/O to complete but in the case of pmem all I/O is synchronous. There's never anything to await when flushing at the pmem driver level. > Since FUA/FLUSH is basically a no-op for pmem devices, > it doesn't make sense _not_ to support this functionality. Seems to be a nop either way. Given that DAX may lead to dirty data pending to the device in the cpu cache that a REQ_FLUSH request will not touch, its better to leave it all to the mm core to handle. I.e. it doesn't make sense to call the driver just for two instructions (sfence + pcommit) when the mm core is taking on the cache flushing. Either handle it all in the mm or the driver, not a mixture. From BATV+83429bba74d63fe5ba36+4465+infradead.org+hch@bombadil.srs.infradead.org Sat Nov 14 02:41:13 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 E80AA7F4E for ; Sat, 14 Nov 2015 02:41:13 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id D1F118F812A for ; Sat, 14 Nov 2015 00:41:13 -0800 (PST) X-ASG-Debug-ID: 1447490470-04cb6c0cd155150001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id LxyqJFoW9GtzRlL7 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Sat, 14 Nov 2015 00:41:11 -0800 (PST) X-Barracuda-Envelope-From: BATV+83429bba74d63fe5ba36+4465+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 1ZxWON-0001pt-NX; Sat, 14 Nov 2015 08:41:03 +0000 Date: Sat, 14 Nov 2015 00:41:03 -0800 From: Christoph Hellwig To: "Darrick J. Wong" Cc: david@fromorbit.com, fstests@vger.kernel.org, xfs@oss.sgi.com, hch@infradead.org, tao.peng@primarydata.com, linux-ext4@vger.kernel.org, Anna.Schumaker@netapp.com, linux-btrfs@vger.kernel.org Subject: Re: [RFCv3.2 00/12] xfstests: test the nfs/cifs/btrfs/xfs reflink/dedupe ioctls Message-ID: <20151114084103.GA6894@infradead.org> X-ASG-Orig-Subj: Re: [RFCv3.2 00/12] xfstests: test the nfs/cifs/btrfs/xfs reflink/dedupe ioctls References: <20151113213643.31124.80975.stgit@birch.djwong.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151113213643.31124.80975.stgit@birch.djwong.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: 1447490471 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/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=BSF_SC0_MISMATCH_TO, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24383 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS Looks good, Acked-by: Christoph Hellwig From rasheedkazeem@peace.com Sat Nov 14 04:06:05 2015 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 32B447F4E for ; Sat, 14 Nov 2015 04:06:05 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id BAA52AC062 for ; Sat, 14 Nov 2015 02:06:01 -0800 (PST) X-ASG-Debug-ID: 1447495550-04bdf07f095c7a0001-NocioJ Received: from ip151.50-31-1.static.steadfastdns.net (ip151.50-31-1.static.steadfastdns.net [50.31.1.151]) by cuda.sgi.com with ESMTP id cqAeZxdYEpgJKzNI for ; Sat, 14 Nov 2015 02:05:53 -0800 (PST) X-Barracuda-Envelope-From: rasheedkazeem@peace.com X-Barracuda-Apparent-Source-IP: 50.31.1.151 MIME-Version: 1.0 From: "Rasheed Kazeem" Reply-To: rasheed.kazeem@tewsmail.com To: xfs@oss.sgi.com Subject: Proposal Content-Type: multipart/mixed; boundary="----=_NextPart_001_41B7_43CA0D4D.1A016EDD" X-ASG-Orig-Subj: Proposal X-Mailer: Smart_Send_3_1_6 Date: Sat, 14 Nov 2015 02:05:46 -0800 Message-ID: <22243914835206998242@ADMINISTRATOR> X-Barracuda-Connect: ip151.50-31-1.static.steadfastdns.net[50.31.1.151] X-Barracuda-Start-Time: 1447495551 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Barracuda-BRTS-Status: 1 X-Virus-Scanned: by bsmtpd at sgi.com 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 ------=_NextPart_001_41B7_43CA0D4D.1A016EDD Content-Type: text/plain Content-Transfer-Encoding: quoted-printable Good day. Please find a copy of the proposal enclosed to this email for our= mutual benefit. I hope we can collaborate together on the proposal and mak= e very good profit. Please let me know if for some reason you are unable to= view the proposal so that I can resend it to you in a different format. It= is currently in a pdf format. I will be looking for your response. Regards, Rasheed. ------=_NextPart_001_41B7_43CA0D4D.1A016EDD Content-Type: application/pdf; name="Proposal.pdf" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="Proposal.pdf" JVBERi0xLjcKJeHg394KMSAwIG9iago8PC9UeXBlIC9DYXRhbG9nL1BhZ2VzIDMgMCBSL01ldGFk YXRhIDEyIDAgUj4+CmVuZG9iagoyIDAgb2JqCjw8L1Byb2R1Y2VyIChWaXNhZ2Vzb2Z0IFBERiBs aWJyYXJ5KS9DcmVhdGlvbkRhdGUgKEQ6MjAxNTEwMzAxNzI2MTRaMDAnMDAnKS9Nb2REYXRlIChE OjIwMTUxMDMwMTcyNzEwWikvVGl0bGUgKEZ1bGwgcGFnZSBwaG90bykvQ3JlYXRvciAoUFNjcmlw dDUuZGxsIFZlcnNpb24gNS4yLjIpL0F1dGhvciAocGNob21lKT4+CmVuZG9iagozIDAgb2JqCjw8 L1R5cGUgL1BhZ2VzL0tpZHMgWyA0IDAgUiBdL0NvdW50IDE+PgplbmRvYmoKNCAwIG9iago8PC9U eXBlIC9QYWdlL01lZGlhQm94IFsgMCAwIDU5NSA4NDIgXS9QYXJlbnQgMyAwIFIvUmVzb3VyY2Vz IDw8L1Byb2NTZXQgWyAvUERGIC9JbWFnZUMgXS9FeHRHU3RhdGUgMTAgMCBSL1hPYmplY3QgMTEg MCBSPj4KL0NvbnRlbnRzIDUgMCBSL1JvdGF0ZSAxODA+PgplbmRvYmoKNSAwIG9iago8PC9MZW5n dGggNiAwIFIvRmlsdGVyIC9GbGF0ZURlY29kZT4+CnN0cmVhbQp4nCtUMNAzNFIwAEEYIzmXSz/I XCG9mKsQyDM3MDRV0DUyNzRX0DVQANMGepZGhkamEIUWCi75XIHISo1MDEBKTSxN0ZRaQpQGcgEA hlYX0QplbmRzdHJlYW0KZW5kb2JqCjYgMCBvYmoKODAKZW5kb2JqCjcgMCBvYmoKPDwvVHlwZSAv RXh0R1N0YXRlL09QTSAxPj4KZW5kb2JqCjggMCBvYmoKPDwvU3VidHlwZSAvSW1hZ2UvQ29sb3JT cGFjZSAvRGV2aWNlUkdCL1dpZHRoIDEyODcvSGVpZ2h0IDUwMC9CaXRzUGVyQ29tcG9uZW50IDgv RmlsdGVyIC9EQ1REZWNvZGUvTGVuZ3RoIDIzODYwNT4+CnN0cmVhbQr/2P/uAA5BZG9iZQBkAAAA AAH/2wBDAAICAgICAgICAgIDAwIDBAYEBAMDBAcFBgQGCQgJCQkICAgKCw4MCgoNCggIDBAMDQ4P DxAPCQwREhEPEg4PDw//2wBDAQMDAwQDBAcEBAcPCggKDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8P Dw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw//wAARCAH0BQcDAREAAhEBAxEB/8QAHwAAAQUBAQEB AQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1Fh ByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZ WmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXG x8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAEC AwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHB CSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0 dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX 2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD94fDef+Ed0D/ryg/9FrQBt0AFABQA UAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQ AUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAB QAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFA BQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAF ABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAYvhv8A5F3QP+vK D/0WtAG1QAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAF ABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUA FABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAU AFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQA UAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQ Bi+G/wDkXdA/68oP/Ra0AbVABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQA UAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQ AUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAB QAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFA BQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAF ABQAUAFABQAUAFAGL4b/AORd0D/ryg/9FrQBtUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFA BQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAF ABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUA FABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAU AFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQA UAFABQAUAFABQAUAFABQAUAFABQAUAYvhv8A5F3QP+vKD/0WtAG1QAUAFABQAUAFABQAUAFABQAU AFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQA UAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQ AUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAB QAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFA BQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQBi+G/wDkXdA/68oP/Ra0AbVABQAUAFAB QAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFA BQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAF ABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUA FABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAU AFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAGL4b/AORd0D/ryg/9 FrQBtUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAU AFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQA UAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQ AUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAB QAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAYv hv8A5F3QP+vKD/0WtAG1QAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAB QAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFA BQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAF ABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUA FABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAU AFABQAUAFABQBi+G/wDkXdA/68oP/Ra0AbVABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUA FABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAU AFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQA UAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQ AUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAB QAUAFABQAUAFABQAUAFABQAUAFAGL4b/AORd0D/ryg/9FrQBtUAFABQAUAFABQAUAFABQAUAFABQ AUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAB QAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFA BQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAF ABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUA FABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAYvhv8A5F3QP+vKD/0WtAG1QAUAFABQAUAF ABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUA FABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAU AFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQA UAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQ AUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQBi+G/wDkXdA/68oP/Ra0 AbVABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQ AUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAB QAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFA BQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAF ABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAGL4b/ AORd0D/ryg/9FrQBtUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAF ABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUA FABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAU AFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQA UAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQ AUAFABQAUAYvhv8A5F3QP+vKD/0WtAG1QAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQA UAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUARyzQ wIZJpUjjHVnYAD8aai5OyRMpxguaTshVkRwjI6srDKkHO4eoos1oNSTV0x9IYUAFABQAUAFABQAU AFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQA UAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQ AUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAB QAUAFAGL4b/5F3QP+vKD/wBFrQBtUAFABQAUAFABQAUAFABQAUAFABQAUAFABkUAFABQAUAFABQA UAFABQAUAFABQAUAFABQAUAFABQAUAFAGHrnifw34Yt47rxJr+naVbSNtSXUbqO3Vj6AsRk1tQw1 bEtqjBya7Jv8jnr4qhhUnXmo37tL8zXE8JmNuJk+0BQ5i3DcFJIBx6ZBGfasuV25raG3PHm5L672 JaRQUAGRQAUAFABQAUAFABQAUAFABQAUAFAHwR+1FbeANc+KXhDwz8dddlsPhRceGdQuNIs7nUJd P07VNdWRB5dzKjIHkSAhoonbDbpTtYrx0YdYuvzYfBTlCfxPkdpyS7Ne9yp6y5bPVX0MqssPh4/W cTTjKK0vOKlGLfVp3jd7JtaWdrNnnXwS+JOk+KbH/gnV4Q8C+LodW8XaT4SgufFdjp12JzY6Z/wj 3lP9tCkhWN/9hChvm3qcdGq66xGHiqmIuvbbJ3vL7XNbrb+Z/wA1upnQ9hiHJUEmqWjaWkXtyX6N /wAvldrQ/TyuQ6QoAKACgAoAKACgAoAKACgAoAKACgAoAKADI9aACgAoAMigAoAKACgAoAKACgAo AKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoA8e+Mnxn8O/BjQ9H1DVNJ1fW9d1u9XTNF8 N+Hrb7Tf6vdFGfy4Y8gcIjuzMQqqpJNaU407OpXqKnCO8nd76JJJNtvokmyJe0lKNOhDmnLZXSWm rbbskl1Z5j4R/ahuL7xd4b8HfE/4K+OPhxe+Ip/smj6h4jhtprK+uSpdbfz7eWRY5mCttR9u4jAy eKcZYLEXWFr800r8soTptpbuPPFKVuqTulrawpU8Zh0pV6ceRu3NCcZpN7cyVmrvRO1r6X1R9X1k aBQAUAFABQAUAFABQAUAFACbh6iiwroNw9RRYLoWgYUAFABQAUAFABQAUAcH8R/iT4M+EvhDU/HX j7Wo9L8N2JRZLhkeRnd2CRxxxoC0kjMwVUUEknAFa0aLrS5U0urbaSSW7bdkkvMzqTcErRcm9Ekr tt7JI+dl/ba+FzhSngf4rMpxhh8PtZwf/IFHNl3/AEH0P/BiL9hmP/QFU+6P/wAkfYtZDCgAoAKA CgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAK ACgAoAKAMXw3/wAi7oH/AF5Qf+i1oA2qACgAoAKACgAoAKACgAoAKACgAoAKAIZ5HigmljhaWREL LEuAXIHAGe56c0rrqG+x+bHhD9qb4/3Xxw+M2j3f7M3xD1DRLDTNAks/DEd1oyS6I8ovfNleQ3AV xcbIyAHcr5ByFyM9DxeWyioOrJJbNUanM778ytdJdLpXu7XtpCwOPXvqELve9Vcum3K7Wb/mttpf c+gPhn4z+PXxC+Lo1vxJ8LNZ+Hvwl07w9cWsum+I7ywuJ9V1SS4gaGWJLd5CiRQx3Cks4DGUfKdu RlLFYaf7nDc01u5SpyhbslzWbvu9LKy170sLWh+9xDipbJRnz3W7bslFW0S66u+h9W1IwoAKACgA oAKACgAoAKACgAoAKACgAoAKACgAoAKAPyE/brj+GOnTftJ33xt02GXX9R8BiH4aajrdu01nDMsE /wBohs2IMcV8bgxuTxIyGHaSFIFx5sUvZxq29n73Jzct+vPa657Wt9rltsubWozqYZOcKbaqaOaj zW6crdm4J3utk7vV20+o/h/8R/C3xr/alt/G3wi1ddb8BeHfA97o+ueIrBGNldXs99aTWdvHMRtm eKOG9c7SQgnwTl8VdeMsLU+rTknJ6uKafLbZuzdm7uy3aV+xnTU61NVnCUY7Rck481/ismk2lZXf fRdT7YrEoKAOPl8b6LF46tPh3m4fxHPpUuskRxExQ2ySpCDJJ0VmdyFXqdjn+E1XKuXmvr0Wt33e 1tNN2t9COZ81ktO+n3WvfvsmlbVrS/iHw/8A2rfh/wDETxzZeDdL0PxNZ2Grz3tt4e8Uanpxh0vx NLabjcJZT7jvKrHK43Ku9YnZdwBradKinKEK0ZVIfFFKV4623aUZWbSlyt2e5EXXajUnStTn8LvF 30urxT5o3SvG61R9P1zmwUAGRQAZFABkUAFABQAUAFABQB8oftA/ES4k8QaF8D/DfwMs/in4n13T ptZutH1q4trXTbCwikWLzriWdHG5pJNqIqMxwx4AqK1HAVKaeOUpa6RhFSlfvrKCil35lq7IuhUx sKt8HUjSstZSckvRKKcpN9rWS1bMT4Fad8UPB/iKy0Bf2R/Afw28DXxkbUdV8L+ILWWRCsbtGTbx WsZlJkCJyw2hye2DlRhldNv6rRrRqP7U4wt85KtOXpZPW2261ryx9VJ4nFU6kY/Zj7S/yUoqK89t PM+yq6DnCgAoAKACgAoAKACgAoAKACgAoAKACgDxX42eBdM8YeH7K+vfil4g+H9xokrXVv4h0LU4 7IQsVwfPWVWiljxyUkUjjsa1ofXedRwT95/ZcFNS8mnr84uL8zGtPBQjzY2Kce/M4NPupJrX1uu6 Z8NeGv2sPjLo3jCz8F+AhY/tLaDHKYrzXvBelzaTc6YqjrPctu0+VuMYSWMkn7oFa4jEYbDS9lmc FSq9qUvaO/8Aeo/xKa9ZSHSwlfEQ9tgHJ09Le2Sgn/hq+7z/APgv57n6AfCn4nWfxW8O3mu2/hTx L4bu7G9fTrzR/FWmvYXVtcIiOw2tlXTbKmJELIecE4OOZyoT1w9WNSPdX08mmlKMu6aT1XRmijXp 6Yim4S9U013Ti2mn0Z6fSGeT/FZvjRb6bpV/8F4vCt5qltMz32k+KnngS/h28JFcRBvJk3fxMjLz yB1pxrwou86LqJ/yyUZLzSkuWXo3H1F7H221b2bXePMn5PVNLzV35M8BuP20vC/w71HSPD37Svgv WPhRrmoSGC2vdUaPUNJvJAOfKvrcsoHU/vVjOByBXVQo0Mcm8JU1X2aidOXonL3Jf9uzkc9adbCO 1aMZrTWnLn368mlVfOFvM+tfDPirwz4z0e18QeEfEGn6zoVyMxX+mXKXEMn0dCQeorKvh62Fn7Ot Bxl2asVQxFLEx56Uk1tp37evkdDWJuFABQAUAFABQAUAFABkUAFABQAUAFABQAUAFABketABQAUA FABQAUAFAHzb8fPDHxCbV/hb8V/hh4dtPEnibwLfXck3hi6uUtX1Wyu7cwTLbzv8kc6fu3UthWCu pI3ZqHUhSknWi5Q68qvJdpJac1tmr3s3bUuNN1VKMJqM+jlflf8AdbSbSfezs0rqx4xr2s/G79o/ WPh/4PvfgBrnw88EaP4n0vxHrPiHxbf2TSsNPuY7uK3tIIJJGd5JYY1LnCqhbqcVVTE4NpRwjnOd 93TlTjFdW3Ozbaukknvq7ChhsTBuWJlCMbbRnzyk+mysknq7u/RI++aZIUAFABQAUAFABQAUAFAB QB+THizWf2IU8U+Jk1z4+/Fy11pdQuBeW1p4j8TRxQz+Y29EVBsVQ2QAvygAY4xXZHE46KSWaU4r s5YS68nzQ5tPPXvqL6um7/2NOXmqFdp+d1o773Wj6GCutfsGkgD9ob4yE9Mf8JP4p/wp/W8f/wBD al/4Fgv/AJAX1Zf9CSp/4T1z9ha4igoAKACgAoAKACgAoA/PD4+eLf2gPHmmRaN4d/ZL8Sy6t4Y8 RWmu6HqlxrujG0u7iyuN8Rlja4DiKVQwPG9Q4YDcoFTUxGW8qUpVJbXj7Gdmuqvf7nqrpOzRUMNj W96UU9n7T3l2duS3qr6q6utz0mL9oD9ocxRef+xb4wWYqN4TxLohUN3wTcDI/CtfrWV/8/Kv/giX +ZCwmYdfY/8Ag1//ACs+xcjrkYqBi0AFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAB QAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQBi+G/+Rd0D/ryg/8ARa0AbVABQAUAFABQ AUAFABQAUAFABQAUAFABQB8ZeMdZ+PfxD+OHjj4afC3x/wCHfh/oXhHSdMvbnUNQ0MaxfazJeeeV ZI2ljVII/IZN3JLhhxiqVVUI81DDRqTbtKU3JJW2ilCzbs73bsk9FuT7GNWVsRWnGNrxjDkTfdtz jNb2VlH1ex6h8LfA/wAefDOv3l/8Ufjlp3jPQZLNoodMs/CsWkNDcF0ImMqzOWARZF2Ywd+c/LzP 1qtX92pQpwXeDqN+nvyat+OxX1fD0veo1Ksn2m6bX/klKDv87b6Xs177QAUAFABQAUAFABQAUAFA BQBEs8LySQpMjSx43oGBK56ZHam4tJNrRkqcXJxT1RLSKCgAoAKACgAoAKAPj34kfEX4zeLvib4q +EXwa+HHgrVbLwvY2V3rmsfEC9mitmluxI0MFvBFE7OQkZZnbCjIAyc1FdYGVNRxGHlXk+icIxj6 uSlq+yW2reo6KxPtHKniFQSW/LKcn8lOnZLu5avpod58IIv2jbTV7my+LHh34Y6X4Njs2+yp4Hur 2SYXO9NoZJokQR7PNyQc5C8YzU0pYaMfZYbBuit9ZwkvS0YR1879PMurTqc3tKmL9s309k4P15nV qX7Wt1vfSz+hq1MwoA+Nv2o/D/gKzutG8ceJP2jn+Duo3Wn3Hh6fU0nsozrFhIyyPCouVOJEYFkk j+ZPMbg546MJh8xqzc8BCMrLXmi5KPaStKNmtd24vqtDGtWwSiqeLUnfVKEmm+6aUZXjtfRNdGrn MeCfFH7K/jnxl+zd4H+E/wAbfCt3B8NVun0LwjpF5HcXF9IumzWiNvD52xW0l07DaSxIYkbTl1Mp xuDpKUo2it22m302Xdu7fl5lU8dRxMpPklzPb3ZKK9bx8rLVL1dj7wrmNAoA+Kvi9B8S/EP7R3hr wl4K+NT/AA+09/BVzeyM1nDfHUJFvox+4hnby9yDb5j7SwV1AxuJG1OtiYwccNShUtq+dSaV9F8D i9dUvesuzdjCtHCaSxU5QvonGUYt9WryjLbeyWveyd/HdN8beOf2hdW+Bfwv8S/EfVfD8VyPGsus a94Cu/7Mk1+bQ9Sg021mhf5jHBL50lwUBIJULkqDm5161JSeFSpzdk7xjPlsveilNNfFbVq6Wm7u KNPDVGvb/vYa8qbcb3+FvkcdVG+1lf3klY+vv2afFniDxp8GvDOreKNRfUtdtLvVNGn1WRFRtT+w ahc2K3TBQFBmW2WU7QB+844xWNSaqSc7JPqlsn9qy1sr3suhrTjyRSTdul9Xbpd9Xa2vU95qCwoA MigAoA5zxZB4oufDetQeCr7T7HxZJbuun3erW73FtDNj5WljRlZ1B6gMCfUUKfs3zcnNbpflv5c1 pW9bP0DlVT3ZScU+qSbXonofCGsfDD9rnVPij4R8RH48fCGx+I2kabdiKztPDd6smoaZI8QlSeFr wl4FmEDBgAVcDDDcwbb61US9vDL0ofDK9eTT6qz9irSWtnrpdNPonRwjaoPF1Ob4l+7p37P7W2qu u9nuke2+C4f2mtE8d+Frb4s/Ff4W3nhrUHuI/wCx9G0K7sb/AFB1gkcLbvLduMoQsjDY3yI3TqH9 YeIhJRwKglvJVnPl1/l9lG93p8S3+TU6NCg4tYmcm9lKEEn8029rv5H1LWBQUAFABQAUAFABQAUA FABQAUAFABQAUAfEn7YF/wDDLTNY+Ad98bPDXhjU/hE3iC4t9ZvfE0zGPSXe1cWswt94SVTcCKN2 dXWMSbiB94bUqFTFKWHg5rn092ThH0m1upbRTkk5WWrsnnLE/U5Rrxcbro4qU3/gvqmt5cqcuW/S 7Pc/DXxi/Z+Q6R4V8IfEvwGplkjs7DSNI1ayXe7EKkUUSNySSAFUckgCtafD+LwVJuGFlCC1fuNL TdvT72zkef4PGVVzYlSnJpayu23+J7NzXGdw6mM+af2nLq2sPB+lX+uftDyfCLwel35epaxarapc 6gGXCW8E04YROSCcojMQOMda6MLHGTk1goQcrauaclFd7XjH/wACbXkzGrLCK31rna6Rg2nJ9nyp zat0jZ+eh8v/AAc8a/8ABOjSvGOiW3hPxzo3iv4qa7dw6fb674qlutZ1W+uZnCIi3FyrbC7sBhNi 5PQVOKyyvjI8+PxEa1tUnVpuK0+zTjJRXlaNy8PmnsP3WCw06MXvy0asP/ApuPM13c5NK3kfoN4P 8AeCfh9aatY+BfCml6BY6nfPqV3a6RapbRz3ToiPKUQAb2WKMEgc7RXJRoxoQVOF+VbJtu3krt2X krLfTU6K1epiJc9R3l36v1fV+b1OwrUyCgAoAKACgAoAKAPmj47/ABI+K3g3xb8IPDPwl8KaX4i1 rxPcalHcadq179hiWKC18wStPtcoiuyZCozNuAGM5q41aNFN14Skn/Lbmv5XlGPq29O1zOVKpVaV KooNfzXtb5JtvslbzdrnlWt/tHfFHV9B0rwJonhjRvCvx9vPHUPgS9h1OV9V03SpW0x9WN2jJ5TT xtZIpRfkbfIAwG01qqmGivbU6cpK2kJNQle9rScedWW943utrN6T7Kq5eyqVErPWcVe6tf3VK1m3 o1LbXfS/vXwJ8feK/Gmh+MNH8fxaavj/AMFa/P4b1mbRUkS0u5khguYp4VclkWS2u7dyhJ2szLk4 zWdSUJ2nTjyXXw35rO7Vr2V1pdOydmro0jF024uXMls7WbXmruz6PpdXR7lWZQUAFABQBVu7q3sr W5vbqVYrWCNpZJW6IijJJ+gBoSu7CeiPlr/hub9kj/ovXhX/AMCT/hXo/wBl4jvH/wADh/8AJHN9 a/6dVP8AwVU/+RNXQP2yP2YPFGu6N4a8P/Grw1fa9q13DY2VjBcEyXM8rhI41GOWZmAH1qJ5bXpx c3y2X9+H5c1yo4jnaXs6nzp1Evm3GyXdvQ+mq4ToCgAoAKACgAoA+aPj54w1v4e+IfhF43ksPFF9 8O9Mv74a9a+E7K4vpt8lo6WrzW8AMkkAkLggKQHaJiMDIcK9Om/Z1akacZfala2mtuZp8t+91ty3 1s5eHqVrTpU3OUdop2eul0m0pW7O+97aXXzAnhz4sMfAH7Rurat430/4seMfiDp1tZeB5L2dbLTP DM96Ims7mwz5SuunLLcyyMN6TZ+b5QtP+05te7USw792MXGK5r6KSbjz8zfvLXSOjVrjWXwWjpXr L3pTTbcbatXT5eRL3dmm9ndo/TapGFABQAUAFABQAUAFABQAUAeB+ItY+Ptho/jWfSPD/gF9bXXV g8Nw6pqlzbQXemFE+e5kETFLnf5mERSpAHNZwhhZO7wcpW3s4Xf95XVlHyepEoygvfxMYqWzcZaf 3WuZXfmml5Hmw1z9ukkf8Wz+DGD3HifUv/kKj2mXf9AFT/wKiafVKv8A0Gw/8FT/APkz7FrQQUAF ABQAUAFABQAUAfKX7Xd1rNt4E8Cf2N47l8GGbxrosFx4pXYU0yF5ipeQOQhUsUQB8pudNwIyK1oT rRqJYdKU5aJO9n5NJpvTomr7X1M6sKU4N17qEdW1a6802ml62036Hyt8QPid458FaF8Zvg43x3uv FVnE/guC38ds9ra6lpSa1rDWN7bGW2VI/NjtojMjhVZBOCc7Qa6nLFxkpVqMYVle3LBqOukW4Sc9 VK/lLTTe/KpYGaapVG6T3Up321klJJPlatfqtdddPqP4AWE3gT4m/Gz4M6Z4k1zW/A/hy10LV9Lu PEGoy6lPYS3yXiz2f2iQl3RfscMwDMxX7Vjgba5alatVS+sy5qn8zUYtrpflUU3dSV7K6te9jqhC gm5YaChB9E3ypre127XTWm19ep9Z1kaBQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQA UAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAYvhv/kXdA/68oP8A0WtAG1QAUAFABQAU AFABQAUAFABQAUAFABQAUAfnH+1jF+z74X+I+n+PfiX8d/ib4T8ZxaM4j07wBdzFrPTQw82aWKC3 kaOAugJeUhNynbzmtqFLGqSqUcVToxl7q51S95rWy503Nq+mj5b6Wu7xOWHqxlSngnXcfebUqy5U /ONSEYXt0s5W1vyq3v3wt+Gnhz4YfEy90UfG74keKfFdxoTXQ0HxnrTX1ulo1wim5iXylXzFkjCE hiVEnIG8Go9pj60ObE1ozinsqdKDT6P3IqVrXtfR69UL2eCpTth8P7OTW/PWkmuq/eVJx7PRXWmt m7/T1QaBQAUAFABQAUAFABQAUAFAHwT+02v7L2i+MLfxB4w+I2u+EfjlcW8cVlJ8PdSuv7dvY1B8 pPsEAkFwnJwJYWWuqlSx1Kk8TTxPsaPX2jj7Jv8Aw1Lq/wDgtPzMnUw9eawzwvt5rW0YvnS/6+Q5 ZRX+KSj5HD/DD4k/t1Wkuraknwpm8b/Cu1jVtPl8dNaeF/E+oL3xBEzwk4wR5qwFu4FYvNMDV92d KUu9SjGSh8qdVqb83GTXZM0/syvTs6daMH/z7qz9o1/3EpR5Y9tedrq7an6J+HNTu9c8PaDrd9ot 3o97qFlBdTaTqGzz7B5EVmhl2ErvQkq20kZU4JFZtxk703ePR2auu9nqvRq66haUdJ2T62d1fyfV efU26BhQAUAFAHCfEXQPGfiXwvdaV4B8d/8ACIeI5JI2i1z+zYtS8pVbLL5MhCncOM54zml7WpR9 6lCMn2nzcv8A5K4v01E6dOr7tVyUe8Goy+TlGa9fdfy3PiXT/gT8Z9Q+LniTVtI/bWjHxP0nSLOz 1q2tPA9grGymeaSz+0x+Zh8MlyYmPK5kAOCRVfWsxpr2ioYfkl0/etNrrb2rcXZ2urXW97KyWHy6 d6TniHKOzdSmmk+if1dJp21Wtnta7v738MtG+JXg74jf8I58Tv2kofGt9qGi3F5ZeGH8NWukybI5 4Ee7WSJiXEZkWMr0/fqT2qlWxWIg5VaNKEU94c/NfWyanUlpvrbdb9HPscLQmlRnWcmv+XkoSjb/ ALdpQ97/ALe2vp1X01UGgUAfN3ir4anXv2jPCvjPWvCNvrPhgeD7/SYdRuUimGh3v2qGXIR+QZ4i w3qDj7MAcbhXPXp0sVahiI8yWqTV432d+l7WtfztqbUalWgnUoytfR2dpW6W7q972fbTt8u/A3wn 8QdG8Xfs0/Dxfgpq/hvU/hNY3Wi+J/Ht3a20Vhr+mJYSWsSWsquzzme4SyucEAx+SwYg5BmksvjJ ToL99L4o8klyvdycnFRbvpFptuMn0bLqrFyi1WmvZR+BqabfZcl+aKtrJSSV0rXsj9M8j1rqOYKA PjH9qfWfhFq2q+Cfhp4y+AupfFzxxeQ3Gq6d4e0eyhebT7WMpHLcvcSyRrBGWZE++C54wcU1ChTt iKuJlRfwpwdTnd9WkqfvW6u+m3UunUxTbpYanGaer53BQXa/Omr72sr77HjHg34O/C/xz4rs/D+p /sJ+MPh5ZX+f+Kqj1WzsY9F8qKR1EBsr4y24kYbGECgO0mXyMkRGeGptSwWOr+0V+VONZJX1kr1E 4pPdqV7tLrY0k8XPmeLw9CUJay1pycmtI3SipSa2TveK20P0P8H+EfDvgLwvoXgzwjpceneGtGtU tLKyiLEQxKMAZYkk9ySSSSSSSaUI8sbNtvu3dt9W33e7MpzdSXNZL0Vl6JLRJHTZFWSfL/xo+IPx aj8X2Hwy+C0Xhyz8Qroc/iPVfEHiqKa4t7C0STyo44reJkaWaSQP1dVVYyTkkCtI1qVCPNKk6sm9 ubkSXVylyyfZJKOuuqtrDoyrSs6vs4JbqPNJvokm0kurbv0SWt1meDPjx4m1Tw1+xfret2Gns3xg 0qE6p9mjdDa30miNqatCCxxFm3nQqdx+dOeDluVKTnaLV9Y67a7PTXTrdbba6SozXL717b6avTfy 18uvkfWdZGoUAfnv4j/Zi/aK1b9oxfijpf7TF/p2hf8ACOajplvfpoOmyXGnLPfW06WCQtGVkh2w 7jM58wGJR0ZqSx2KjNJYek7LdxqcrX95Kqpc/mrRtfS9rV9UwcoXlKpq9UppO/dP2bSj/d1d7a6H q3hb9nHxrH8Q/BPxB+Kvx/8AEPjyTwhLc3ejaTc6VYaZbW91NbyWzTSC3QNIwhmlVQTgbyeaJ4nF YhpVIUoRX/PuM030s3OpPTrZWuKNHCUU3RU3J9Zz5kvRKMdfN3PrKmIKAPPfiJ8V/ht8JNIg174m eN9H8NaTNJ5MNxq90kAnfGdqAnLtjnABNdOGwlbFt+xje272S9W7JfNnPWxNPD2U3q9kk236JJv8 DC+GPx8+DPxm+2p8LfiToPiO4s0WS4tdOulaeBD0Z4jh1HuRjNVXwOIw0FUnH3Hs01KP3ptfiKli qdWXJrGXaUZRf3SSZ6/XIdIUAFABQAUAFABQAUAFABQB84/tEa94Q03TvB+iax8Hrb4neM9cvntv D/hWe1tZfMlWJpJpmluR5cESRqS8h9VUAlgDjWwmDxMHPHX5I9EnKTb2UY3V36tJK7bRth8VjcPO 2AnySe7cnCKS6yaTdttEm29keL+Ate+CUXw4+Gfxi1T9mzwh4X1nUfGn/CKyw6fpthLJoOoJq8+l xzLcJCpYfa4IsMoBHmBv4SayhlGVqqp0INLeLkkndK/vJSaWt1o5a276azzjN5UnCtiHLdSSnOzT dtLq70s2mlpftZ/e1dZyBQB8R/tfa1o3hDXf2d/HEnhq58XeLdJ8TTRaR4FsrFryfW1ntJI7h4Fw VSa3izOsj4QBGUld4YTOnh5wf1ySVBW5r66/ZtGzc7P7Nr2u1qkndJ1ua2FT9r0d0kl9rmk2uVNa X3vbRq50Xhr9oG51rxFoGjn9k/4raOL+9htjq2paDYxW9gHdV86V1uSyxpncxAJABwCeKxWFyGLT o1YOfS1GsnfpZuikteraS3bRo5Zu1+8S5ev7+m9Ouild+i3PrqugwCgAoAKACgAoAKACgD5p/ac0 /wCGSeENE8X/ABE+K138NZ/Dt/5+k+MtOvY7a4tLiSN4miVZFdJlkRmDRMjBsA4yoI1w9HFVanPh GlKKd+ZJw5evNzNJK9tbxadrMipWw9OPs8RBzUtlHm5r9HHk96+/Rq17pnwLoFt+zP4j8a+HYvBv 7cvia7+IN/4gi1fTHu7S2uZbrxNLAunx3UmbRd6tbkW/kEiMIxxtPIc4Y+N6sq2Hk7828LvS3IlG t8NtlFc/NZ8zehooUbcrwOJhG1r8ldJa353KdNpSvvKT5Lbxsfpn8G/hdP8ACzw9rdnqviifxL4s 8Qavca7rfiC4tY7RtQvJVSPcIU+VESGGCJVycLEvJrmjKrO86ySk+kbqK0SSV23suru3djkqcUoU U+VfzNOT63bSim230SXRI9dqyQoAKACgCnem4Wyu2tLdJ7sRMYoJG2LI+DhS2DgE4GcUtGveV12B X6Oz7nxp/wAJP+17/wBGq/DT/wALn/7grD2OQ/8AQDW/8F4f/wCWnV/wof8AQfD7qxteGfEn7U0/ iPQIfEP7Nfw90vQJL2BL7U7LxkbiaytzIoklji+xLvdE3ME3LkgDIzmmqWSp3pYOrGfRuFBJPo21 VbST7Jvsrky+vWfPjYSXVJVdV210189O59e1uc4UAFABQAUAVbxLmS0uks5lhvGjYQzOm8RuR8rF e4Bwcd6V7apCtfTY+QbjwD+2TaQvcXX7T3gKGBBlpJfADIqj3Jvq2hja1R8scDTb/wCvlX/5EmeG wdKPPPF1Ul1aor/20Twvpn7RyeJvDz67+1P8OtW0Rb6BrzSrDwksE99AJF3wxyfbm2O65UNtbBYH B6VtP65yvny6EF/Nz1Xbz1ilp56dznhUy1yShjpyl0T9jZvonZXs/LXsfZNch1hQAUAFABQAUAFA BQAUAFAHz7+01rXwJ8P/AAk1nVP2jILaX4ZQzwmdbm3mnxPu/dFFhBcPu+6y4IPcVpRozrzUadV0 pdJKfs2v+3rr7uvZidV0U5Kn7TvHlU011upJq3dvRHwV4Wsfj1ryabqv7FD+P9C8DyyJJFP8YNdt 77RJoCQT5NtL5+oKCv3QHjA44rWtmNTCv2dWTxb86PJb/uM/Yt+vJVuY0sHQxfvw5MMr6+zq87/8 FR9pRXpzQa/L9d65jcKACgAoAKACgAoAKAPKfjLPqsfgHVbfS/hKnxJN6yW1x4TlubS3S7gY/OXN yREVXAJU9e1Z1VhpRaxak4f3Y80r9LK8du97o0oyxEZqWFnGM11lKUV98Yzfy5dep+dHiS28N+Br Dw/feJ/+CZGkaToMN2NOhvW1PQTb2j3Z8rM5RiFRmcJvk+VS45Gc1Ef7KqScFUxN5tXTjJc7Xw3b rWlJfYu7p/DrY2qVs3pJVPaYdqPVTn7ie7S+rXS/m5VtrJWu1+kXwy+EHw4+Dulalo3w28LW+i2G oXP2y6EUksr3M21UDPJIzO2ERVAJwoUAACrjGd3OpUlOT6zk5PyV23ojCc1JKMYxjFbKMYwXnpFJ XfV2uz0utCAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoA KACgAoAKACgAoAKACgAoAKAMXw3/AMi7oH/XlB/6LWgDaoAKACgAoAKACgAoAKACgAoAKACgAoAK APzY/a18L/E3Q9N/aYHhP4Saz430z4teEE0i31Dw0IprvRb2G2ngEU8DsrtbN5qyK0W8q5lyvIJw nWwtJynim4yivdlyykmt3G8U3F31u1yu+6sbQoVq6jHDuLTfvRlJQflJOXuvTRq6atpe+nsXw0m8 e/Fz462Xxs134Y694D8G+HfCt74d0yx8VeTHqOrz3t1aXE0rwRyP5MUS2MaqGO5mkY4AXnaVfD1J qOEm5xtrLllCLfRRU1GTtrduKWqSvqZqhVpQbxPKpX0UZKdl1ba93XRJJvZt7o+xaZIUAFABQAUA FABQAUAFABQB8R+N/EXxk1v45+PPDH7Pfw9+G1l4g8PaZpkuueNvHSXHnXrXIlMMEC26+Y0aRxNl mfaGYgDg1m44GjONeeFlXq91OMFFLZXlGbu97JLzeppH29dexqYp0aW/Koc8pPvZzhFK6td8zdvI 9T+EcX7VSeIr9vjnefDCXwobJhbL4Jh1FLoXe+PaXNwSvlbPNzj5t23tmtni4Yj3YYR0vN1VO/lZ U4et79LW1JlhqdH3oYmVTylTjD53U5fdbre+h9E1JIUAFABQAUAQTxGeCaESyRmRCvmRnDJkYyPQ jtS1Wwt9z89/D/7D/jHS/ib8SPGU/wC1N8U4rHX7LSraC8stVtl1C4NsLneLtza7GRfPHlBACN0m 7ORiVjMz52+emttfY02n6RtaNurXxX12NXhsrcV+5k99Pa11bz5lV5pX7S0jb3d2fQPwt/Zw0X4b +Nbv4jap8Q/G/jjxtJpr6Pb6p401JLo6fZvIkskUCRxxou+SKNmbBY7F5wKHUxdeSniailZaKMIw WtrtqKV3p12Fy4WlDkw1Hku7tuVScn2V6kpNLyVj6OqyAoA808V/GD4Y+BNdt/DvjbxtpWgalNZH UUOsXC2kTQeasWRLIQm4uwAXO7vjArqw2BxGMT+rwc32Wr9bLW3nscuIxlHC2deXKn1e3p3v122M 74kfHT4UfCTQtC8S+PPGNrYaPrUoh06aBJLw3p2GQmJIVdmUIC5cDaqjJIFRHDTcpKo1Dl3c5Rgk 9rNyaV323LVb2nL7CMqjlqlCLm2lq3aN9F3+W56JoWvaL4o0XSfEnhzVLbUdB1O3ju7O/s5BJFcw uoZHRhwVIIINZ1Kc6M3TqK0lozSE41IqcdmbFQWfJXxs8HfHkfFfwB8TvgNofg66v9P0y60nWT4q 1W5tFv7OV1kWAJFBJysscciy7gV+ddrB8hRr06ErzozqJq3uuCt53k736W2aeuqRXsPbw/jKm1te Mpet7NK34prRpXT6PwBrf7V954s0q3+JngD4a6b4Jfzftt74f8QX13dx4jcx+XFJaorZkEYOWGFL EZIANvF4eouWnhqsH3lKm0vVR1+4n6rUp+9LEwn5KnOLfzcml32fY+kqkDG8QeIND8K6JqfiPxLq 9ppXh/ToWuLvUb+VYYbWJRlnkdiAqgdSaulTnXmqdNXk9Eu7InNU4uUtl5X/AAWp8I/GL4ofssfE 670fxH4b/bH8L+B/H+l21xYW/iHQ9f06bzrOcqZba4t5i0c0RaNGAIDKy5Vhk59NZHnVGXtKFC91 ZxnFyi+17Si010aatdp3TOdY7A1Y8mIhJq904qcZJ+UuV6PqmmnppdJnM/swaB8CdL8WfC/RW/bD 0r4t+MvCOjtongzw/De6dDFpVvHa+XI9vaW5LyTC1hZTK7OwjD9NzVz4jLM4p0YzxtGNOnC3wxau /hUpSlKTb10S5YpvbY3hi8BzyWEjNSn1m5Oyvey92MYq6XS7slc/S2uE0CgDwP4xfHMfDHUNH8Me Hfh/r/jjx5qVpcajFoOgGGI29lCVElzcTzOkcUYZ0QZJZmOFU4ONI/V4Q9pianLG9klFylJ+UV0X VtpLTW7RHLXqy5MPFN2u3KXLFLpd2bu+iSb0fYm8MfHnw74i0j9nnVn0q+sofi9piX+kGUoy2sra eNQW3mIOfMMAmIKggmFuRlctwp3nyS220tdXt8n1t69iVKolFyS13s3o7X001Wlru3TTXT3asjUK APgH9ojxT4A+Gn7S3wf+IvxF8M6p4j0dvDmo6PDFp+g3ernw9M80covgkUTriQRNAxB8wZjwpUuV yqQwuJSoY6tThC94qpOMU5baqTWltpNOKas2m0bUni6adTBUpyk9G4rp25ujT3jpdO99LPyHxh+0 X8CNX/aD+CvxA8NeF/F2kQeFYtSn1jxNb+AdYik1OCe2e3j00qtqHdfNkS4LONi/Z1Cks3Do0Mtw c3DDYvDxc171qtNR5Vqm3zWcr7W1SvdpWu6izTExtiMLWko6xurvmenfRWvfXV8ummn6VeAfHOg/ EnwnpPjXwz9v/sPUvN8j+07CfT5/3crxNvgnRJE+aNsblGRgjIINbSUE7U5xmv5oyUov0km0+z7O 6OflqLSrBwl2krNev5+h2VSMKACgAoAKACgAoAKACgD5X/aVlsdKuvhd4q0v4peGPBPxM0vUrhfD 0vjEgadrPnQ+XcWMx3KwDoUYMjB1eJSAwDKdsPRxFafNh6PtbJ3hflbXeLs2mtNeWStdNa3Mq1Wh TptYibpp7TS5lF/3k7Jp7NOUe6d0eFfCj9n/APaJ1XS/BfhH4va74AsvhVofjC68bta+D5bu9utc u5NVn1a3ieaVY0igjuZ0b5VZnEKgkZNc0sROa9isM6bv70pzTaSd7RjGO70Tk3tdqKb06IUqEf3y xPtVb3VGHLG9rc0pOcm+rUUkk7XlK2v6O1ZAUAfMn7Rngv4ua/P8MPFfwQ0zwzN4/wDCmrSXcd14 ovprWBLWWIw3EJWOKQyCWNiuMqVZUcE7dpn2sKM1UnSlU8ouK37uTVmt01fVWas2XGl7eMoOqqfm 03qttnt0ae6elnZqh4d1/wDbMn8QaHD4p+G3wotfDEl5Cuo3OneJtQmuIbUuPNaKNrRVaQJuKqzA E4BI61q8ZhZrljhaqb6udKy82lrZdbakfVKsfeeLg/JUppvyu52V+7WnY+qqgAoAKACgAoAKACgA oA+Nf2r2u9B134CfEqx+GviHx5ceEtfuJn8O6DpDaiXhuLZ7eSfrtili8wSRs3B2ugwWDDCtPCJK GOmlSlumpPXo7KLuk907aO6u0k9qNPEzbeDX7xdXOEFbqrzlH4louW7vZNKLbWt4a/aZstf8RaDo Uf7OPxh0x9RvIbQalqnhD7PbWfmOqebNJ5nyRru3M2OACaiNPI1JexxFNz6JU6qbfRJukknfZtpL q0ZuObW/e0LR6v29B2XXRVXJ+iTb6Jn1pXUSFABQAUAFABQB8PfGfwv4S+GPw88I6J4w+LvxvstD TV726fxV4XuLm9uovPd5dl9LDBIy2yb9sZKYUIATxzccVib3li6VKb0vOFJRdtkueLgml10bFLDU KqtDAurFa8sJVE0+r92pGcrvoub0KHwd+HPwt8Z6nofjD4c/ti/ErxrbaZeQ3bab/wAJtDeQTmNw 3lXMAiD7G27WRtpIJFdGIp55Qiniai9nLqqFFJrynGH4xd10ZyQlk8qjp08OoVV0dTEKSfS8J1en aUWu6aPvCuQ7AoAKACgAoAKAPlD9o34faV8SfGXwA8N+N/D13rnwrn1u9XV9MiWV7WS6+xStZteK nWAOko+f5PMeLPak8ROkvZwquk56XjJxbtryqSs1ffRpu1ioU7yVZU1Nw7pStfTms97bbOyd/M+B dC+F3wV+Hnj3wd8PdA+C1vH+0r4f+LT6lpzw+G5jBL4dm1iSdLk3PliHyLfTJxsO/MU9tGF5UAqN aKXtZ4tt/C6brS5m9l7jk3babla0lfmbu0dEli5JxjRtBq/tFBKK6tcyW71hyvXW6Wia/amqOUKA CgAoAKACgAoAKACgAoA80+K/iHWfDXg27vtC+GV/4+1OWWO3j8N2MltEZ95xud52WNY16sTnjsaz qQwlSNsan7Pyhztvp7v6uyXVoqn9Y5r4VpT7ylyJfNJv5JN+R8A3H7JHxi+JOrw+IrTT/Bf7PAe4 S5lk+GNxd3GsTgEErNLE1vaEkZB3Qyj3NXSx9bCwVLK4VIwSsvbVOaCXlh/fgv8AwNM0rUKOKk55 pUjWk1b3KajLy/fzvV08oxP1JpmIUAFABQAUAFABQAUAef8AxIPxNHhiU/CQeGv+Ew86PZ/wlhuB Z+Tn58+R8+7GMdvWj2qpe86TqeSkofi4y/ITpqquV1fZ/wB7k5//ACXmh9/NofHnjHwN+1l8d/De u/Cjxr45+Dmk+B9ciNlr1z4QS/vdSFmxAljhWYhI3Zdyh2ztznBNaVq9aMPcy+VNvaU6vMk+6SpR ba3XvLUyw6wkqmuP9rbXljSjC/k5e2qNJ7O0b2Pv+NFjjjjXO1VAGTk4FZGxJTAKACgAoAKACgAo AKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgD F8N/8i7oH/XlB/6LWgDaoAKACgAoAKACgAoAKACgAoAKACgAoAKAPifx1B8Zvif8evGPwz0H423n wx8LaBomnahp8Gi6ZaXN94hM7Sie4825RwIoXjSIrGuQzAsQGXOscVWp02sLSptp+9KopStf4Uoq UUk0nq73aaWzM3Rw8pr61KfvfCoy5Fp8V3ZtyV1pfRNO2p6n8J/hF8SvAHiG+1jxl+0V4q8faZNZ PbR6Prthp9vFBKZI2E4aCFGLhUZACduJDxkDESxWLrrlrxpJf3IOLv6uctPK29tS1QwlLWgpp/3q jmrejS18/wDM+hakYUAFABQAUAFABQAUAFABQB8BeOfAfjf4nftWeJ4dP+Lmq/DFvDvhWxj0qXw1 Z2v2vxNbzyytO80lxG6SxW8saoqBSY2lLZXzRuulWr0lJ4OENLc/OnO+/J7qlFKy5rS3butkRUjh 3yrGSlZ35FGXJbbm96zbb0vG9rcrsfQPwt+E/jrwJr95q/if9oTxh47sZrNrZNI8QW2mxQwSF0YT Kbe3jfeAjKAWK4kbjOCHPE4quuWvGml/cpuDv6uctPK3bUUKeDg74fn5v71RzVvSy8tf8z3yszQK APn/AMe/tLfC34WeLx4T+Jd3qnhmCWKOS38S6tps6aPcF/4BfhTEjg8FZGX8a2oUoYmXsqdWHtf5 HJRk/RSspekW35EVPb04+19jJ0+sormS/wASjeUfVxS8z2jRde0PxJpttrHh3WLLVNJuFDRXunzp PFKD0KupIP50q9Crh5claLjLs1Z/iZ0MRSxMeejNSXk7mxWRuFAHy5fftH6B4M+Pni34T/FPxD4X 8MaE+j2Gp+Fr+/1BIJNVY+cL6OVncLG0RFuVQgFllLDdg47cPg6uNhy4ajJzjv15k+sVbXl2lZuz auldX4cRjKWDm5V6sVFpf9uv+876c32bpJ2aTb0XtPhj4n/DbxrfzaV4O+IHhzXdTihNxJaaPqlv dypEGVS5SNiQoLKM9MsB3FLE5djMJFTxFGUIvS7i0r9tUGFzPB42fJh6sZyteyabt/TO6rjO4KAP ij4+eGBpfxk8IfFjWfgLe/FPwvF4cudC+x6TZ2d9daNctcJKJRb3DoHSVMoXU5TYOMOTXPWp4Kv+ 6zCTjDdPlnKLfaSgpNP+V8rW+q0OihPGUk54GSU9mnNQdvKTst91dX03sfK/ww1Pxp8L/Gfww1zx j8AfiLp3gnwND4zhmsrPRhqKaFFrWqQXOm29qkDubiOG1gMLGEMItyqQFzjR4rA4pqjVxCsv541E ly+7HncoWTlG9rt9m7sl4XGRlKpCmpSf8s6d5X96TiuZOyla6kotvVJpXPvj9lfQ9b8P/Avwjaa/ pN1pN7dXWqanDpF7H5U2mWl3qN1dWtq6fwNFbzwxlP4dmO1OE41Ipwd4rRecVpF2aT1SW6M5wlTk 4z+Ld63956vXVPVvyPddX02LWdJ1PSLia4hgvreS2eW0lMMsaupUsjjlWAOQw5Bwaq8lrB2fR9vP UnR6SV127nxF8evDP7PXw78PfC/Rvir8aviF4cGnWH9kaPBonijVY7/WFiC7pJYrTMlzIBt3SlTj PJGa68PPMuWVWGLVNac0pqgk35urFpN9o29DOSwjmqUcEqsn8MYxnJxS7KL0iu8vvOO+Aeo/sw3H xY8Kx/Dv4wfGLXPGB+0/Y9L8Vaj4lmsJ8W0u/wA5LuMQHbHvZd5+8q7fmxRUxGLnBxqZjSqxf2Yy wrk/RU4qem7t0Wuly/q0Ye8sslR/vuFRJfOUmtdtV1P0grlGVLyys9RtJ7HULWG5sp1KS29xGHSR T1DKRgj2NZ1KcK0HCok0909mVCcqUlODs1s1ufH3xh1uLw5438M/Cb4Ofs++EvFfxI1bTp9ank1l INN07SNPjkWLzZ5RC7szyOFWNFycMSQBXKsqyajD2lfDczbsowhG77tuVoxS7u93okdP13M68uWl ieRLeUpTfyUYu7fzSXUyvhx418ZeDvin4L8B/G34BeCvCmteKVuYvDvi7wLcLd2lxdwwPNLayB4Y 5YJDBHM6nlWCMM5rWhg8ov7TC4Z0asVe0lB3Wz5Zw6q+qaTtqZVq+Yxio18Sq0JaO3PGz3V4yctH bdPR77o+4a6TEKAPmP40eAPipJ4psvid8F28P3vif+xLjw7qfh7xNNJbW+pWbyCWN47iNXaKaKTf jKMrLKwOCFIlVvYy5qlJ1INW91pST7rm91p7NO3Rp6Wb9nGslFVfZyWqbjzRa6ppNNdLSV7a3i76 eJfs/wDwf+N8s37PmlfGYeDtG0H4I6LDZaXo3hvUpdRvNTv1006ct1duyIsMYt5JysShstLkthRl urKrCm4YedOO7lNx1dvhio3Vr6tuV9ErbkxVKE5p4iNSeyjFNKKvvJt3cunwpLV77foTTGc54sPi oeG9aPgddLPi77O39nDWzILTz8fL53l/Ps9dvNHOoe84OVuifK35XadvWz9A5ef3eflv1tzW8+W8 b+nMr9z5Xnuv28LaJ7i6X4CRQIMtJLPrKqo9yRTji6dRqMcum3/1/j/8pM54WFGPNPMbLu8Ol/7s na/Dyb9rSfxTo0nxLX4SHwE6yNdv4Wk1N7xgYm8ow+aPLI8zy8k/w7sc4qXiKc26f1KVN93VjJL1 iqUW+26tv0sOOHULVI432i6L2Khf/t7207W3+F320vc+lPpQlbYsdTAKACgAoAKACgAoAKACgDwP 4/8Ajn4b+EvDOn6Z8RfAOp+Nodeme0s/DGleH21uW+kC5I8raURQDy8hVRnrWVbD4KvG+OqQhFbO Td7/AN1JOTl/hVzahVx1KXNgISlLrytRSX95yaSXqz43+FvwO+Ny/Ejwf4u+E/hG8+AnwitNTgu9 W8Jat4kk1Z9dslYGS3XSlMltYl1yN8coZc5xnit/7TqWVChKpXhs5VkkorvByTrtropOMe6MpYCl KXt8T7OnU7UU7t/9PJJwpy87Qk/73f8AUSpEFAHK614y8P8Ah/XfCPhrUruRda8TXE1vpttFBJKZ WhheeQsVBCIqIcuxAyyrnLAG40+aMpXSt3e9+iXV9bLom9kS27pJX+7Rd3f5LS7PHJP2pfhLF8Up PhM13rB1ePUo9Dk1pdJuDpMWqugdLBr4L5QuSGUBCfvMFzuOK19hD4faw9pbm5L+/wAve1rba2ve 2trGXPVt7T2UvZX5efTlvta1+a19Obl5b6XPo2uc3CgAoAKACgAoAKACgD5r1jw5+0R/wivh3QdK +OPhKx+Ib399PPqV/wCGBPHfWfmM0MUVsLhCrRRtErOGOcZIGauGIrWdVYSEujXPUUV0TvZu76p6 X2M/YUE1TniaiveztT5n1tZq1l0sr2WpyVto37TvhLWvC2pfET9pb4ef8ItNq9laT2R8HGxk1HzZ 0QWsMzXp2zSk+WmFY7mHynGK0p16+J5owwMFZNtqpUbilvKzVtPPQJ0cJQs5Yqq23ZJxpWb6J2je 3e2qV3ofYNYGgUAFABQAUAFAHz9+0R40+OXgnwlY6j8CPhXZ+OPEE1wY7u2u79Lf7DBj/XLEzJ55 B/5Zh0J9aFXwtDXFwlKL/l2/7e92TS9ISfkJ4eviItUKsYSX8ybv5LWKT/xSSPgnwn4R+F/j740f DTxx+0D8Ubzw/wDGbStbtZtG8Nr4KXwRHd36yAx24uZUeW+DN8vlrdMr5xt5p4WnOanLKZUaUGrz jSlJ1HFbqpGbg7d37CPqbV6zpQjRx9OtUbtyuq1OEZdHD2V4RkraKU5PufrvSMgoAKACgAoAMgcn pQDdtWVftVr/AM/EX/fYqvZzf2Wc/wBbof8APyP3oBcWrMNs0Rc8D5gTUOjrzuGvexSxVGT5VUXp dFqmbBQAUAFABQAUAFABQAUAFAHzp4v/AGtv2avAPiTVfB/jP41eF9G8T6Y4ivNMv7wRy27FQwDL jglWB/EV30ssxNeCqQSs/wC9Ffg3c46mPo0puElK67Qm196i0c6P25v2QmwB+0N4M56f8TAf4Vp/ ZGL/AJV/4HD/AOSM1mVB6Wn/AOC6n/yJ9W15h6AUAFABQAUAFABQAUAfKH7Y93HB8JtLs9X1++0P wFqfibSNP8V6xp8rwSWmjS3KrcEzLzFG58uOSQEbY5HORjNaUZ1YTUaEuWpL3YvS6b7X05ukf7zR E6cKkW6kOeMfecd7pd11S3a6pM+Z/j58H/2W/gv8Jr74l/BCw8PeFvi9o6wzeDr/AMLahtu9X1Le v2e0ZUkJu0nYiN0bduVySRjI2hh8ywjlXqVa3JHWftJzlGUeqkptq76WSaduXUieY4PMeXD2pylJ +7yxgpKXSUXFJq276WvfQ/UKEyPFE0qbJWUFk67TjkVyehsS0wCgAoAKACgAoAKACgAoAKACgAoA KACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAxfDf/ACLugf8A XlB/6LWgDaoAKACgAoAKACgAoAKACgAoAKACgAoAKAPy++ONn+ztrf7VOv6d+1J8ToNNsrXw3ZS+ DbGbxTJo1vYqzSC/8wwzRss7v9mYeYQHj27N2x9vbh8HmeLSeBlOm1f4LRlNO13zWu1HROKfu3Ta 95GE6+DoNqvSjV5t1ODqKNtvdacVe7ala71V1bX3D9nPw/8AsfaT411W4/Z9+IWma94yfS5EubSz 8a3OuvHZebCXcwSXEgUCQQDftBG4DPzEGsXgM4w0FPMKtaUL2SqO6v5Lva/yuFKvgaz5cNhqdOXe FFU3btdRWnlfonbQ+0a4DcKAPnb4kfHjU/hV4nktfEvwe8Z3/wAPfJjkXxn4XtV1eKFz99Z7SIm5 QL/fWNwQe1VCpgvgrVvZz/vxag/+4ivFPvzcq8xewxc1z0KaqLspJTX/AG7LlUl/hk3/AHTuvh18 Z/hX8WbWW6+HPjzR9cMXE9taXA+0Wp7rNA2JI2GeQ6g10VsFXo01VlG8HtJNSi/SSvF/JmEcVTdR 0J3jUW8ZJxl/4DJJ/O1j0+uU6AoAKACgAoAKAPnX4l/sqfAn4v8AiqPxr8QvBcmq+Jo4BbR3o1S9 tzFHgDaqxTKq52rnABOBnOBWT+sqanRxNSnZWXJNxS77d+vc0jOkoOE6FKaer56VObdtruUW9Ona 7saPwu/Zp+DHwa1688TfDrwnNpmtXVm1hLcS6peXe6BnRym2aV1HzRIcgZ4xnBNae0xc9MRiqtVd pzlJX72btfz82Q1QX8LD0qb7wpU4P0bjFO3W17Xsz3mmIKAPmX4r+KPj9qPiK6+H/wAKPg9oN7pD 28ZufGnjjUQmmIXByiWcStNcMvGQdiknG7riKk8BKPs69GdaX8qUYw+dSV/ujCTLp0sTzKpCvGlF ddZVPlFcqXk5T+TPAfBf7BF74c1fxB49Hx08ReGfiRq4Dk/DOztvD+jWsgOcjTQrpPnoxmLlvYgY dLGZjSiqdCUKdJbUmpVYL1dSTa/7h+z8kVWpYGvLnrwlVqPepKXLU+TpqKSXaXP531v9++HLHVtM 8PaDp2vaydX1y0soIL3VjAtv9vnVFWSbyl+VN7Bm2jgbsDpT5pT96SSb6K9k+yu27drtvuZcsY6Q vbpd3dvNpK776L0Rt5HrTA+E/jfqGmeKvizfeBPh/wDss+D/AIn/ABE03TrW813X/F32WztNIgmM gtoXuHglkklYRSMI1XCrgk8iuavgsrk1VxsJznLaMEm7LrJylGMVfbdvXQ68Njs0gnSwmI9jTXVu dm30UY6vTVvRLRdTe/Z71Lw5pPxA1vwH4k/Zw8NfCj4wRaR9vjfw4lpPba5pnmokr211FFG7LHN5 IkidQVLxHnINPD4LLqadfARlFrSSmrSV9VtKUZJ2eqe61SJxONzKrajja3tYvWLUpNNrR3jKzjJX 8007p7pfZ1dBzBQB8h/Gi7+Kfiz40eAPhB4P+J9x8OvDGoaDfa3Prum2Ftc3urXMM0MYs4GuEeOP Ykvmv8pYgjHAYjSniZ0U44enCU925pyUY7XUVKN3eybbstOrREqNKbUsS58j0Si+W8t9ZWdtNl11 7HVeAfgp8TPCPi3SvEPiH9pzx14t0e083zvD+s2WlRW13uidF3tDbJINrMrjaw5QZyMgqWMxdZcl WFJRf8tNxl8m6jt56baFLDYOn71JVObpzVHJfNWV/wCmfSGKzGOpgfFHxxv/ABV8P/2gPhr8VvCn wX8U/EBP+EevdA1NNCt7Vv7Ot5Jo50lhkmmTEvmRbWjxh0kB3gxhWzlLBc6jjp2X2fcqTs+75YyV mtHrzJ2smm7WoYqcGsKl53nGCa7a63T1XTdPWx6D8P8A49eJ/Gvi3SvDWo/s2fE3wrZ3nm79e8Q2 2nJZ2myJ3HmGK6d/mKhBhT8zrnAyRpbK/wDmGr80+i9lVjfv70qcYrTXVq+y1sR7HGw96tCCj5VY yf3LV/pufS1AHOeLIvFM/hvWovBN3p1p4te3Yafc6vA89rFN/C0saMrMgPUBgT6ihT9m+bk57dL8 t/LmtK3rZ+gcqn7rk4p9Uk2vRPRnw5rfwk/bT1Px74T+I5+LXwj07xNoltc2AktPDeoomoWU21nt rhGvDvQSRxyKRtZWThgGcNosa+fmpZerPRp127rdW/cq0k9nro2mndWmpSwkI8lXGzT3TdOmmuj+ 1qn1TutE90jtfCfws/aN1f4z+APiH8ZPH/w61zw74YgvFtNG8P6NeWj21xPBJEbqIyXDjztrCMlw wETSBQpctU1cROu1H6p7KC1v7Vyd9tU6Ubq2iScbN8zcrJKKf1WDbo4t1JNWs4wWm9lyy01Sbdm9 LaJu/wBo1JqFAHyR8Z7j4q+CfinovxL8BfCvUfiBBL4Xu9AtdP06/trY6VfvcRzLNKJ3QeRKERXd SzL5I+UhqccVSpfu8TKahvaMXJSa6NJ6O3wtqyvK7V9V9VnWfPQ5OfZub5Wk+qfK7q+sorV+7ZO2 nlfgH9mrU/hR49/Zr8S6Rps138TrybVLv4n+N4HfZrCTWE7ypcMT84OoS2phTHyLCdu0AgysbiJt +2qSbqfYbk4RtqrL4Y8qSimrN366mjoU+VQpxjy09pWipNvR/wB5813J7pW6aH6F0yAoA+Af2q4P hjqPxO8Iab+0PfQwfB+Tw1fvo8Os3L22kXOviVRtu2yI2mEBBhSU4P74gFgK3w/1nES+q4SpKEn7 zUJOMppdE1aTUd3FPW6bTS0mXJh19bnTUktLuPOoX62adnLbmtpa11za+Z/Af4leGfG9n/wTv8H/ AA48VWmt+LfC/hOCbxbBpFwtwNI07/hHvIkivGUkRu199iAjb590ROMKa0xKxOFipV217bZN6y+1 z23aX8z/AJrJ6szo+zxLk4R0p9bNJPblTtZt66LorvZH6lVyGwUAFABQAUAFABQAUAFABQBm3mqa Vp9xplrqGo2tvdahKbeziuJVR7qUIzlI1JyzBEdsDJwpPQGqjRnUTnGN+XVu2ybtr21sjOVWEHGE nZy0Xm7X0+Sb9DkH+K3wyj8eJ8Ln8f6AvxHeHz18NNqEQvjHt3ZEGd33Ru6Zxz0roWAxLofWfZv2 ffp2v6dL7GX1ugqvsXL3tutr72vtfra9z0GuU6QoA+Mfjn4v+GfiXQPh78UvDP7SvhTwDq+j6lf2 uieLdTe0u7C7co9veWjxyugkwUBO1wyvCDyMg9tPAZg63LhqCqSSu4u9rPZ3g009tfVNamCxOFlT /fuai9nBWkmv8UJKz8467p6HlGhT/syaj4E+FHwS8J/tQeCNV1ZPHGm+JdSvG1ezn1DxRqa6kNQY IiSDbNcXvlDABwhKKPukOrkmb04Sr1sO+ZvmlKzSiurS10UVypNqy1bdrMjj8JOcYQ5lFK0Vyyd9 LK7sur5m7avor6fpLXCbhQAUAFABQAUAFAFW7uBZ2l1d+TLMII2k8mBNzyYBOFXuxxgD1paLd2Qa vY/Oz4ufGnQfito2mRN8Bv2g9D8XaHdf2j4f8TaX4OdbnR7wKVEigy7ZEKsyvE+UdCVYeh9cwFKS qUMxgpLo4V3GS6xkvZaxfya3TTSYvquYVIunWwV4v/p/hk01s4v2ukl0fyaabR538H/EeveOvil4 Q8c/tG/C74ueI/iJHqMVtoEMvgqXTvDfhHdII1u0ieViJcEO9xIWZBkJgDkqY/B41KmsXCEE040o qs3KS2c5ulHmd/hT5YR0b1uy6WDxmCvKOGcpNWlUlVw7ai91GEarsrb8qcpeex+sNMkKACgAoAKA CgDyT4s+DviT4107SNL+HfxVl8BqJ2bUtRs9Kgv7qeHbxHAZspE2eS5RuOgojiKtB3pU4Sf9/maX mlGUb/N2D2NGt/HlNJdINRv6ycZNL/DZ+Z5n4V/ZE+Fmj+INE8beMb3xL8QfHek3Ud9Za9481ebU nsrmM7klt4CRBCysAQY41wQMVlWeJxjg8VWclF3UYqNOC/7dglf/ALecjSn9Xw3MsLQjC6ab1lNp 9HOblL7mj6nrUzCgAoAKACgCrdWsF9aXNldR77W4jaKRCSNyMMEfiCaWvTQE7an5W/tE/sufsn/D 7xJ8CbXWvAel+FPhvrfiGWDXvEhurmJI/LtpJbW0knMmII551VWc4yE2ZG/NdFCtmdSfsKOOrupL a9ab82opys5Nbb6XaV0iq1SlGDr1KFNwhq7UoLyTlaF+VPfZXtf3bpx/ED4YfsffDr4i/s9678FL DwvefFFvGmmQWnhzRdUOoG/tJZ1We4eISPs+yoDcrNwFMG0kq5B6KlLN8FTc8dXrqk/daqVKmrek UryV9fijrFxbutmuWlj8Hmj9nhI0pTjreEKfupb8zjGyutm7SUrOL3T/AFgrgOgKACgAoAKACgAo AKACgAoA5678K+F7+4lu7/w3pdxdScvNPZxu7npyxGT0FcVTLsHWk51KMXJ9XFN/kdMMbiacVGFW SXZNpEH/AAhXg0EMPCejAjv9hiH/ALLUf2TgP+fEP/AV/kV/aGL/AOf0v/An/mdRXoHIFABQAUAF ABQAUAFAHz1+0x8RpPhd8NYfFV1o+jaj4R/tjT7PxNHrmGit9EmmEd7OseR5rxwsziPnIVvlbGKq FGnib0a1NzjLTTZX2lJ2dop2u9LdWlqs6laeHSq06ihKLT13dvsx1XvPaPVvRJuyPIvA/hv/AIJ7 +D9csfHvgb/hTOma8Qtxa6nZ3unpJBuGQ0WX/dnB/hANbvhnMJWVSjWmo7KTqTirbNJtx9LfIznx XhPei8TCLekrcsZPupWSl6p/M+4q5joCgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgA oAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAMXw3/yLugf9eUH/otaANqgAoAKACgA oAKACgAoAKACgAoAKACgCCeeO2gmuZmxDEhdjgnAAyeBRuHofmraftsfsx+Lfi38S9I8Y6ZYXHhr SbDR5NI1ufwdqVzd3skwuvtKTKbZmRY/Kg2EqobzGxu2nE4jKcsxTUqsqDn1lKtRs10UW5WuvtWk 7XV0uulHE5th7xp0qyj/ACqE04+bSe0umi2e57J8HfjN8O/iD8ZW0D4KeBYD4Ft/Ddzdav4rXw1c 6Qba++026wWiyTRR+YJI2nkKqp2+SpzzisqeCyzAy5MN7N1X1pyhK0eqlyXSu7W97o9OpVWtmVdc 2LjUjBdKiau+jSbvor306rXv9m1uYhQB8yfFa3/aP1vxNLo3gTxp4L8A/DUQx+Z4q1G2bUtVmkYf OsFvIVgi28APIXyf4eOdKVed/Z0MJ7WfeUnyL/tyC55PveUUY1Y4eP7zFYrkj/LFJSfrOV0l/hi3 5o8n0n9h34Aa5qeqeJvFfirxD41+LF7EvneN7jxDJBqVttPytbfZGjS3Ck8BEA5wc55yVDMsJJ11 UlRb6U4KnD0cVG0v+4nO2bQxuX4iH1alThUh1Un7WT83KTcl/wBu8qXSx9seHNG/4R3w9oPh/wDt O/1IaZZwWf8AaOqTeddXfloqebNJgb5G27mbAyxJp805e9Ud5Pd2Su+rsrJeiVl0FaK0pxtHotXZ dFdtt28233bNugYUAFABQBwnxEsviJqHhe6tvhdrui6P4waSMw32v2El9bIgYFw0KSRsSVyAdwwe eelONT2L5vZKp5OTivvSk/wF7NVfdc3Bd0k39z0PinTdd/bi1r4q+J/hlpPxN+FU0fhrTbW91fWX 8JXqR2090XNvbJH9tJkcxxPIzZUKCg+Ysdu8sfTjGP8AsMeZ309tOyXdv2e7eyV9E27aXiOChJy/ 2uokrfYp3b8lfZd+7stnb074TeLP2g9L+OWr/C746+K/BuoWdx4cfWtBbwzok9k2oqk8MU7s8lxJ sMDSorRlTuFzEyv8rqJeIhiabth1ScXr+8crp7WvFXXd6NNLS0kynQhQa5a8qnNfeMYpWtvZb7W1 aavs0fYdYlHB/EXwFYfErwtdeFNS13X9Is55I5WvfDWpzaZdqUYMAs8RDqDjBAPI4PFONWvRfPh5 8ku9oy/CcZR+9eguWjL+PTU49ne34NP8T4y0T9n34R6/8QfHnw0sPjF8b18ReErTTb2/aX4g6osL R3wuDB5bedlj/osu4EDHy9c11SxebKCksZdu+nsaF16/uba9LN7a2OdTyrmd8JTUej5pWfe3v306 +p6b8M/BHw2+EPxstfA+l/EH4i65411rwxealFZ+KfFN3rNnHZw3VpHI/lzSsEm3ywhW28qZAD94 VE6uPrUubF1+eN9IunThr3ThTje2zXN1Tt1VQlgpTthaEI6ayi2/k7ye++3Tfv8AXlc5uYOv+JtA 8LW1jeeItWttPtr29ttNt5Ll9omuriRYoYV9XeR1VR3JFXTpyqtqPRN9tFvuROappN9dNm9/T+l1 0PlbxtpHxg8I/GHxr45+ATeD/Flzren6dH4o8C+IdUbT7iyniWVLW8hnjSQp5sW5CkiYbyAVPDUl P6sufEYec6cvhlBxUk1urTspLbZpxd97lcsMR7lKuqdSO6lFyi09n7rTi1rrZprR2tc1fhX4F+NP iP4sSfG/46WXhzQtS0/QZvDugeFPDN3LfLZwXE8M9zPc3LonmSu1rbqqqoVVQ8ktWcq8cRNexoyp wS+24uUm+6jdRS6K7erv0LVH2EWp1VUm39mLjGKV9Fdttvdt22SSPrKqJCgD4W/bC0z9ny61P4dT /FvTPHfiDxvvnPhrwx8P7zUvt9wyD97PHBayoBsWXaZnI2iTbu+bFaQdWlH2/wBc+rQi/i01b6L3 JSba6RVtNegK1WXsIYSNeUls7WST3lKUoxST7vfa5xv7OGl/s9t8VNPg0XQ/jB4Q+K+m21ze2fhz 4m6trAF9b7DBLLFFNcS29wqiUZwWKFlbAIBGksRXxNOUqeZPEU1bmjta+3NGVOE7X2aVrq1+hDoU 8NJKpl9OjJ/DOKjJeaU4Skk7bp2dr9D9G65ywyPWgD5J+Mmu/GHxF8ZPA/wY+Gfj6x8BaffaBe+I L3xJPpcWpXV8YJ4YRaWsUx8sFfOEkjEMQrLgck1pHEOjB+xoxqT0vzuXLGPe0HFtt6fEkvVoh0IV WpV5zjDZKFk5S3s5SjKyS1sld662TOk8A/Cz47+HPFula14z/aZ1HxZ4at/N+0aBP4Y0yxS73Ruq ZmiQOu12V/lPJTB4JqXjcRWXJOhRin1gqvN8uarJet4vS+z1VfVsJT96k6rl/enFr5pQj+e59JVI woA+Sf2i/D37IGs6z4cm/aV1Twfaa3HayLpi+JtZGnu0G/LmNTKm4bupwea7cJgc0xaby+pWilv7 Ocoryvyta9rmcsbRw3u1acZX/mpqf4uMreh8t+AtB/ZI8PftW/A+7/Zel8O6/rd7b6rba5a+HNRb U4NFs1s5WTUDIHdYZPM222Mjet0cglFIrFQzLAxVLMsRVan8MZ1ZttrW/K5O8bXvzJpSUXGzvchV p45udCjGPJ8UlSUFZ6JX5VaV9nHW3Mndbfq1XAaBQB8f/GS2+IHxB+M/hz4SeHPizrfgLw8nhW78 Qyy+Gktlv9ZnW5igEayzI+yKEOrPtXJM6ZIxWkcRWo039WjDm6ynHnsneyUW+W7s7tp7K25HscPU mnieZx6RU5QTfVtxtLRWsk11fQ+av2edU8Z6brP7IHi/xL+0X438X3fxFsLqz1rwZqmoW0kdhqqa XNcys8Sxq4igkgnhZGO5ZWhJb5WVtalbHVIOeI5VSlZxapQje+qXMo31Wt018NndPTGnSwEJ+zwy bqwupXq1Z2to5OLm4p3stVbW6SaTP1VrmOkKAPlf46/ErxJH4q0D4K+Afg5pfxB8Vazpk2tXtr4k v0sdM0+wjlWEPM7RSl3eVwqoqHoxJAFTVp4CdP8A26Eql3pGEYt+rcnFRS73u3oiqUsUql8LUVKy 1lLm+5KOrfV6pL5mZ8GLX44+G/EWm6Fqn7OPwx8DfD+cyG+vPCGvtLNERG5j224solfMmxTlhhWJ 5xg50KeV0E1hMNVhJ9Zezt83Gbk/Ky3t0Na8sfXfPisXGql0tUv8nLRH13WxgFABQAUAFABQAUAF ABQAUAfPPxw8JfEq+1n4afET4U6ZoWseKvCF1en+wvEV5LZW95DdW5hdlnRJDHKhCkEoQVMi8bs1 PtIU5RdWnKcOqi4qSfRrmsn1TV1o79LDjD2sWoVFCXRtNrzTSafZ3V9Vt1Xh0X7MPii18CeAze2+ j3/xo1H4j6d448VeLYMIbRkvlurhLeRgJGiW2iWxjTjMbDIA3CsHJut9clTtVeitZ8sWrcremijv Zay6a3W6tGn9VhUvSWrvdczve9lezcrNXei66JP73rpOcKAOTl8DeCbjT7fSZ/B+iyaXBLJPFZyW EJijkclndUK4DMSSSBkkkmuKeX4WpTVKdKLim2k0rXZ0rG4mM3UjUlzPS93ey2K1p8Ofh/Y3VtfW PgbQLe8t3WWK4h02BHidTlWVguQQQCCOmKiGVYGnJThQimtU1FFSzDFzi4yqyafS7O1r0DkCgAoA KACgAoAKACkB80ftA+OPido2rfCX4dfCe+0TR/E/jzVLqy/4SXxDbNd2+mRW9rJcuEgDJ5s7rGQi FgMK5P3a1p1I0lKSpe0nbSLbivNyaV7LstW2tSJ0/a2Uqjpwvq0k5eSXNdXfdp+l7GT4c+HX7Wll 4h0K98S/tJ+GtU8O295DLf6bb+BY7WS8t1cGSJZftLeWXQMofB25zg4rP67Xn7rwlGKfVSqtrzV5 Wuul9O5o8JhIe9HEV210bo2fk7UU7d7NO2zT1Pq2gQUAFABQAUAFAHlnjH4g3Hhrx/8ACjwTDZWz ReLZ9QE97dymMW8VrbGbEY6NKzFMKSPkWRuduKuCUk1ZuXS3Tu3o9NlbTVrUyqS5LSlJRj1v17Ld W7312tbW6+YI/wBpz4nXniG3+IGn+FfDc37NNz41g8C2t958/wDa99LLerp39oxf8sTbC9fYExua NWcN0U68+GU3hnTlzJO8+Zcqklfl5OW9vsuXNpL7NlcUadWUFiFVWu0OXeL68/Nu17yXLbl63PvK uc2CgAoAKACgCreSzwWl1Na2xuLmOJmjtwwTzWAJC7jwMnAyemaLpb7Ba+x8X618U/2jPEemXei+ IP2HDqej3S7J7G/8Z6RPFKvoyMpBH1FZVq2T4mHs6sK7XnRh/wDLi6VDM6E1UpV6EZLqqlZP/wBR znPhLZeLvBXi7Sf+Eb/4J+aB4EtdRu4rfUPEOka7oyvZ27uBJKVhQPIEUltinJxgVz0qeTwmp0oV +fZOVNWV/N1pOK7tJ6dHsdNetnFeHLiMTRlDdpTq3fonQim+12td2tz79rtOMKACgAoAKACgAoAK ACgAoA8C1D9qf9mnSr+90vVPj54AtNSs5nt7i1ufENpHJBKjFWR1L5DBgQQeQQa9WGRZlUipwoSa aunbucTx9CLs29P7sv8AI8w+KX7Qf7PHj/wde+GvDf7ZPhTwVq800MieINA8R6cbmAJIrMiiRmXD gFTkdDVLJM6ovnw+H97+/DnXno2v+AS8Xgq3uV+fl/u88H96V/U+ygDgckn1PevIO8dQAUAGRQAU AFABQAUAeH/tBeKfhl4Q+HF1q3xV8Jr4o0CS9trS08OLpianNql9LIEt4ILdxteVnbjOAOSSADUT wtDFxcMTJRprVt3skvTV+SSbbsaUsTicLNSwd/aPRWfK9fPSy7vsfISXngklHj/4Ji66M4Kk6F4Z Uj063PFcn9m8Ob+1l/4Jr/5Hd/aXEfWov/ChH6W13HmhQB4V+0F8R/Fvw18EaXeeA9F07UfGev65 p3h3TBrMrxWNrcXkwiWa5ZPm8tc9FwWYqoOWq6cqcHepFy3tGLScn2u00u7dnZJ6ETjKSspqC0vJ q/Ku9rq76JXWrR5EfDX7fTNu/wCFq/BxFJzsXwtqBC+wzd5o/tHXTL42/wCv8v8A5UV9Ro/9BlT/ AMF0/wDM+0qgYUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQA UAFABQAUAFABQAUAFAGL4b/5F3QP+vKD/wBFrQBtUAFABQAUAFABQAUAFABQAUAFABQAUANxkdKW 4HyjrPxP8BfDfxj+05431jwzpunp4O0LSLrVdViP+na3tguZYYtmMbV3+VFjJaSWQduSlgaFRpqP +Jv4Ypauyto0vek+qtpoZ1cVOHuOSv8AZjZKTb03vd3eiVtLPXUqfB34tfGa6+IekfDr45eDfDOj at4o8NT+K9GHhieeQ2UME1tFPZ3gl6zIb23IkTCthxgYGbjPCVablh6MqVnpzNPmWuukY8r7xd91 aTsynRq0Zcs6yqd7R5eV9l70uaL6PR6arU+u6koKAPzA+P8Ab/sy2H7TOsf8Nd6ppV/oes+HLKXw faa1dyS2ulCB5FvEe1Q/u5JXeJ1mZSHCsoYGMg9MIYzE0vZwryowT0SqeyjN9Xzc0byjouVvRNNJ 62iFaOHqN0aPtZte9am6s4rouVRk1F73XVPmtpf1z9miP9hZPHWrn9mOPwiPHn9ky/bDoEUqzfYP Oh37iwA2eb5GR64rKeErYdc1TEOouzr+1+fLzyt2vbS9r6mssVVrrlnh5U0uroSpfLmdON/S/S9t D7jrMkKACgAoAKACgD4X/aK0TwH4K8eQ/E21/aog+CnxC12wjsLs3s9hNa69BAX8p5bK6BDPF5jq JU2kBtpJ4FdWDwuZzc6mCpRqQdrxnFuN+6lGUJJ23SdmrXWhhXr4C8YYtS5ls6balZ9GlGSavteO jvZ7lf8AZpX4S698TNb8YxftTWfxn+M50V7RZ4rqyVdI0rz4mlW3s7YBYkab7Pvc5JIjGarGYTMo ONbGwjTitFGCtFN6tu8pSk9N29NluOhiMFJOlhIzu9XKfM5O2iV3GKS62SV3dn3hXGbEE8EdzBNb zpuhlQo6njKkYI/I0g8z8nvHfwE/YA+CfxS8Q2/jHw3fanr3iDTbGe28F6Jp2p6s+kQQmdWudtqH dFmaQAmU4zCNo+9W1OOOSdetmUqUXopSryhKTXRtzvNLppaN33LddTfJh8Eqklvy0qbir7WTilFv rZ3el9kfQv7Lr/spWvi3xDY/AX4Za14e8TXGnGa91DVvC+qacZbZJI18sXN3GAfnkQ+WrZOC2PlJ GVSEJTVaWOWJna38Z1ZJejbsr2v52G6mKceSphXRh/ghBN9Ph3dr2v5n3HQZnl/xd+FWifGLwbJ4 Q1rUdR0xor601Sw1fSJViutMvrWZJ7e4hZgyh0kjU4YEHkEc1E1UspUpWkmmrpNad09Gn1RcHBO1 SPNFqzV2tPJppp9mj448Nfsg/HfSPiv8T/Gb/tZ+L7a01+w0e1h1W2stKkvr82ougyXKPaeWqx+e PLMfLeY+/otaRzDG88n7KjfTV03y/wDbqVS6fe++lrWFLB4DkjrU66e0aa23lb3r9FbTzufTvwu+ FPxE8C69eav4t/aC8WeOtOms2t49J12y02CGCUujCZWt7eNy4CMoBYriQ8ZwRUsXia65a0aSX9yD i/vc5aeVu2pmsPhaOtHnv/em5K3o0tfM96qCgoA+SPjD/wAJr8OPjH4U+Onh74a6n468ODw7c+Gd W03w95T6npga5juY7m3ikZFlRijpIisG4iIBAIqPaYeFRLFtxj0lyuSi+vMopys19pJ2tZqzL9lW qQf1Zxcr6xk+XmXlJ6XT6Oyab1ujidG8T+N/2ivjP8F/FVl8GfF3gbwH8PbrUNXu9a8cW0Vhd6jP PYz2SWdvbLI77P8ASWld2wP3KAA5zTnXwbko4Or7WT3kozjFR3teai220tErK12xrDYmnGTxajG1 rRU4zbff3bpJK/W7v6n3bVGZm6rqljomlalrWpzeTpun28l1cTbS3lxIpZmwAScAE4AJoSu0r29X ZfjovmK7torvstz4G/aG8TfsnfEBPg/46+JXxk8VeHra70/+2vC9x4ev9U03zoZVI+0BYE3K5SQr lsNtYjGK3jDE0ql8Pi4UnG61lQ970dS/NHyXutpNq6QOCatVwE6z6pU6suXykqeifrrvbqZfwE1f 9li7+LHhaD4b/tG/EjxT4zb7T9j0LX/Eet3lpc/6NKZPMiuAIm2x73G7oyqRyBWlWtj5warY6nUj 1jF4W79PZpT0306LXS5KpUYu8ctnRf8AO6VeKX/b0/dV9td72Wtj9H65CwoA+Svj94x1IeM/CXw0 +HvwZ8P+PvilqmnXGqeZ4okS2sNE06KRIzNPMY5H+eWQKkaLlirngKaxrYXLppVcdSdR7RjFRcn1 estIpd9dWkka0q2Oi3DCVlSju5Nyt2SUYtOTevVJJbmP8K/HXjfwP8Q9B+Gvxg+Cvg/wbqHi5Lga H4i8CXn2iw1K4gjaZ7SVXijkjm8hHkXO5WET8gjBMNhstSlLB4eVGoldxkou6va8ZxtezteLSfXV Jir1Md7qxGIVaDdk0pRae6vGUpbrqpOzVuqPs2tjMKAPDtX8VwXH7QngzwDD4W024vbTwxf69N4g vP8Aj5sYWngt1gthjP7x8tIcgARIMEsCDkpW9pZue107JLd373aVlps3fSzOeovc5koPW1ruTXbV W5U9Xruloecap4Y+Ffwd/aI+G+s6D8JvDFn4g+KdxqWmXPiextliv476O1kvsnAwY5Y7afewwd4T OdxxlSw9KK15vdu43lJwTb1Sg9It3burbNW1NauKxFRRhzKz3XKuZpLRuV7tR2s09001Y+uK1Mjn PFlp4lvvDWtWng7VrTS/FM1uy2Goaham7htpsfK8kIZS6g9V3DPqKFN03zKKlbo20n6tar5C5VP3 ZScV3Vrr0vp958T6x8Bv2v8AWPGnhX4gH9ojwJaeJ9ChuLSK6s/A8qfarSfaZLacG8O+MvHFIBwV eMEEcgv69VU+aOCp2as17WpZrf8Al0a6PfVrZsr6nhnHlliartqny07p+VktH1Tuno7XSa9o8A+E /wBqPTPFmlX3xH+MfgzXPBsfm/bNL0nwlJp9xcZjcR7JzdOE2yFGPynIUjjORTxkqq5HhIQT+0qk 5NfJpLy1JWFpUvfjiKkn2lGmk/XlSf3dfI+k6gYUAFABQAUAFABQAUAFABQB86ar+y/8MtY8GaN4 EurrxXFoWmahd6nA9l4m1G1uDNcyPJIHnjlWR03SNtRiVUYAAwKqOJx0fehipqfWXu3a6J3i1ZbL QlUcH8MsNTcekXHRPq0r7vqc/wCHP2O/hD4X8QaH4l0zUfHjajpN5DfW63njXWLmFpInDqJInuCk i5UZRgVIyCCDTeMzOacamMqSi90+SzXVO0Fo/kP2GAjrDB0ovo1HVPutd10PquoGFAHzR8ffEviP wL4i+EHjy30PxZrPgTRr++/tzTPB9vLd3JaW0eO2llto2DTwq5cFcMA7xvj5MhrEU6N4VqipxlvJ ptaapNpScb91bazetm44epXd6MOea2jeKeu7Tm4xuvVOzdj5fXwF8US3gD9ovWH8ZWXxy8XfELTk g8Mpf3LWmi+GprwRvYXVojGBQmmJLNK7DInJw2doqv7TqNXjVth/hjBpJSvopWaUudv3091HR6Jo TwFH4fZRdb4pVFrJNatc6+wl7lvhb83c/TeoAKACgAoAKACgAoAKAPlr9q7wv8LvEXgbRLz4ufGL VPh34Z0nVIbyHVtL1WLTXlu1O6ECR0Zi6lSyhMN97qMitKWHxtea+oyUZR1u4xdltvPSKd7Pa6dn dOxMq2FpK2Kp+0UtFG9TV/4abTla11e9muZWaTXy78OPFf7Nl94+8E2vh39vf4jeJddk1a1Wz8P3 niRpodVnEy7beSP7MNyO2EZcjIJGRXROObRi3WxNFx6pRwqbT6Jx9676cut9tTngsubXs8BVjK7s 39dsmt2+eXL7tve5vdVnzaXP1HrjOoKAPHPi98WT8MbTw5Z6P4P1Txb448SXbWWi+GdJeOKS8kSN pZHeWQhIYY41LNIx4yoAJYA3F0YxdSvJxiuy5pN9FGOl2/NpJJttENVaklCik5P+Z8sUurbs3byU W29kcJ4T/aRg1f4VeAPiZ4n8G3OhnxB4tfwdeaat4l1/ZN4NUn0pWaUKBIhuoUXKgYEoPQE1dqE5 WpylytXXNFJ3te0lzNLqtG9bd9I/fwiudRck9bN2te143im+js0tL9tfp6sTYKAPAPjZo3wx8fap 8N/hL8SfAkPieDxNe3VxaJcYVdNNrbtI9xvyGU4dYhsOT53Py7qTgv4kakoTj8Lg3GWu+qaaVr33 6KxUKs4PlUYyi91JJprp7rjJN31V7W1d9D51m+LHw/k1/wAGeBrT4FXCfs7eCvG1h4X0nxjYX8cF lZ+IIZRb26rYJhpLeO8kSHzSSonAbb8m4X7DCRisIqk1U+J+7eD+3yyqOXNzPd+7ZvRyu2iVWxcr 4pqDi9LP47X5eaK5eVLorNPlu1pofoTUgFABQAUAFABQB5L8VvhrqvxK0/SbLSvip4v8DyWczStd +EbmCCS7BXGyUyxSAqOowAc0KtiaWuGcU3vzQjP7lLYXJhp/71ByXS05w/GEot+jdj5C8efD7xp8 CvFHwZ8Y3n7UXxO8Q+Gr7xhpeh6h4b1nUbMtqBu7hIYfLCQKWVZWQyx9WhMhBUqM608TmNVONaVP 2dtWqNOLXbWz+J+7dWabTT0aeU6GXKcfYU5Kp0TrVpJ93Z1HrFe9reLs1KLvdfovWRsFAHhHxg+M g+EXiH4SjW7Oxt/h94k1afS9a8TX915MehE27vasw6bZbhY4NzEKpkXJ5Fb4en7eXsYxcpy+G211 q09N2r8q0u9N9DCvU9lH2sppRW6e7W2mq23lo7LW1rteoweNfBt1PDa2vi3RprmZxHHDFfws0jE4 CqA2SSTgAVpLL8XCLlKjJJbvlf8AkYwzLBVJKMK0G3slJf5nTVyHaFABQAUAFABQB83/ABpk+Gnw u8Lf8JS/wb07xR4j1TUrfTNN0PT9OtBc6rf3Mm1E8yQBVH3nZ2OAqMecVw/2TlknKriKUVFXbfIp N+i6tvRK61erR1f2hmFlToVHzPRXm4xXq9bJLsn6Hx7d/HLxXp8fju8vv2E/CdrpvgzWLbRtdvJf Edhs0yWaC1uFkk22h/dLFewO8gyEBYnhSa1jlvDk3CKoVby2/c0972Uf42jb2vpqrtEyxWdRjOX1 uFo/36uyV21eK0Wt9E9HZPS/6pV0nOFABkUAeZ/FK0+Imr+Dr2y+Eni7RfD/AI3aaFoNS1uy+3W6 RiQGRWiDKSWTcAc8E1SlUo+/Giqn92TlFffHXQ53Uw9Zckq/s/OPK390tNT0oZwM4z3xxUnQOoAK ACgD4B+NOkftjfEKwk0bS/hz8L7H+y9bt9W8O67P4pvBNbXNtP5ltK8P2QqSwG14txBV3UHnNN4r DuzhhazlHX4qXK7b9b2ffRrfRoFhpL+Li6ajLS3JNNX2s+a10/Jp9U07HaDxh+3JDBG958IvhENq gSS/8JffouehODZ8DPbNXHGYSbssHXv/AIqREsJVprmljaaS6unP/wCTPsqsywoA+UP2zYdV1D4I 3mhWmox6VoGtavpum6/4ge2W4bQtKluEW4vEVgVVoxgiUjEXMvGzIcb8yUIpzbShe9lO/uvRp3T2 1V5WXUmXLZupK0Fdys0nKNvejrfdbqzbV0k2cna/s0a2kFsIP20vjDJbhF2N/benNvXHHzfZsnI7 5rZ1s6V7uF/+weH+Rgp5D0h/5c1//lp9t1gdIUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFA BQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAGL4b/5F3QP+vKD/wBFrQBtUAFABQAUAFAB QAUAFABQAUAFABQAUAFAH5y/tY+LfhPoPjPUvGl3+zUfib4y+Gujxa9retmeGyt9Cs0aSaBZZJM+ fKDHLKkIR9v3vl3DLVLCq0cRWqRVXRwp8zUkutRc0I8qeivdvXRpFKti+V/V407QvaU7XTa2p+5K SbVrv3UtNbn1ZNf+Cbb9orTtNu9EnHxFvvBlxNYaw8zNE2nw3sIuYEjztRhLcWjsQAXBTJPljC9n GS9pzO8dLaWtLqnu37tnpppbdkupNfu+Vcr1v1uuj021utd76d/bqACgD4F8b63rfwp/aZ8deL9P /Z48ZeP9E8V6DpsFzrOiWFnK2nXFr5oSKF5p13xOkxLrhNkkefn3/JhNZbVnyY+paS+G9OpNJdU+ WDWr1TTd9VK1lfaCx3LfBxST+K9SMLvo7PXTVO+mzXU9y+Evxbu/H3iK90if9n7x34GSGye5/tbx PYWNvbzESRr5KtDPIxkO/cAVxiNuc4BuNDK6euBqKUuqVOpDT1nCKettL362smTNY+3+1JcvlUjP X0X5n0RWhmFAHzx8SE/aobxNKfhJefDKLwf5MexfFVtqEl35uPnyYZFTbnpxn1qo4unSXLLCyqea qqHy5XSn99/kH1aNX3niXDyVNS/Fzj+RxXwk+IX7QZ+NGvfC347p4CtoxoB1nRZPClveK+rIJoop XV5pWAELOFkQrn99CwYgsBo69HEU70sPKm4vXmqKe+1kqcbp2et7pqzjqmZuhKhNfv3Ui1p7ij63 952e1lqmne900fXlYmgUAfnN8QPF/wAPPhX+1b468QeP/hj4n8WweJfDmmR22taZ4QvNZTQmtjKG tQ6RMuyYTLJ+7JIdHDgZQ1hVpYDFtQx9enHl+FTlpZ73jZ2d7Wf2k7K3Lr0UpZhRjz4GlNqXxctk 21s7uSuujTtZ6q93b6C+Dfxg+E/xA8TX+jeA/h74l0HVobB7qS71nwbd6JE8IkjUoJpYkVmLOh2A 5IUnHyming8sw75sFVpSltam9beei0vb52FUr5lVjbGUqkY95uLV/lJu9r9PmfS9bmAUAfC3jHWf if8ACn9o7xv4v8Efs8+JfHXhfxdomnRalqem3enW5tru08xYhAZplZkaOZg6sFCtGrKW3tiI1cDC bWKlJS6NU5SsuqbWlno1bVO9+lrdHF1IKWH5LdVKoo38/hbTW2t7q1rW19t+FvxY8e+O9fvdJ8U/ s++K/Amnw2bXKatrt5p00M8geNRAq28zuHIdmyQFxGeckZ0dTAz0wtSUpedOUFb1e/p/kR7HGU9c QoJf3anO7+nKtPO/yPfKQBQB8ufEr46fEGw+Idx8Kfgn8JF8beLtMsbfUdbvtS1ZdJ07RopzIIEe YxyM8ziKRtiJwoBJ5FaqphKEU8RzylLaNOKbsusnKUYxV9t27PTQhUsRiG/ZShCK+1Pm1fZRirvT Vu6S07mr8JfjZ4p8VeLdW+GHxW+Gsngb4m2WnjV4LOLUU1Ky1ex3iJ57W4VUJ8uRkV0ZAV8yPqGB pOeGrwdXDOSs7OM4qMlfbZyjJOzs09000up7OvRkoVnGSe0oN2dt01JJxavtqmtU97fR1ZlhQB8X fHPxf8UPhn8dfhv478HfD/x3478IT6FeaNrXhzw6YvslpvnilivlEkqK10hhaPaV5jmJDqRhqjjM PRXscVV5YS1VoSk1Lu3GL9y101e97NRl0X1WtW/eYeEXNaXlOMdOyu7p31vZp6p20O98AftBa/45 8W6T4Yvf2dvih4Ytb3zd+ueIrOxjs7XZE8g8xo7p3G4oEXCn5nXOBkipVMvkrUMTzy6L2dWN/nKn GK011a7LUPq+Nh71anFR6tVIyf3LV/0z6UrMYxlDKVZcqRggjqKTSaswTtqj5N+KvxN+Lvh/4waF 8N/hR8LtE8XQSeF5NXuIdU1JdLjsGW6WJC03lyEhl3qqKnUEkgDFSoZfCKjiaMpduSMW7Lp70oxS /F7JbiccTVnzUaqj35r2+6Kbb+aSW+tjhr74/fEP4hn4S+Fvgl4f8P8Ahv4jeJP+Ehk1hfGNvJeQ 6G2i3MVneW2IHjMjtdzoiuDt2KzYyQK0hSwOF/f0qHtL25VdU3Zq7cmozs1tbu92t4Ua9f8Ad1qv s7Xu4rnu07Ll5raPe7s7aWufTHwV+Idz8VPhp4d8Z6jpsWn61M91YalYQOZI7a/s7mazuo42IBZF uLeYKxHKgHvVVORyvTvZ2avurq9n0utn5oqKklabu1pdaJ26pa2vva+h6tUFHyj8YfDvjb/ha/hb xn8EvGPhWH4vWmg3NpeeDPFUjCDXdHM8beZ+6PmxNDcbQsoVl/fMrDkVSdWhF13QdSk7RdpcrT3T jJpq9r3i1quqsLlp137F1HTmtVLl51bZqSvHTa1pJrXe5ieD/h5+0P8AEL4neAfiL+0C/gzRNF8D Pd3mjeF/Bktzdm41Ce3ktftNzczBPlSCedVjVcZkyTwBWc8UsQ4xo4d0oLVuc1KT6JJRSSXVvVuy 2Lhh1Qi5Va/tZvT3YOEF56ylKT6a2S106n2TVEhQB4X8YPgP4d+Ll14e18+IvEHhXx3oCzR6Z4r8 KXv2O9tYpdvmwkkFZInKITG6suVBxmpU8RRn7XC1OWVrNOKlGS3tKMk0/J6NdGVajVh7LEU+eN77 yi0+8ZRakn6Oz63OS+Gf7MOl+CfGlh8R/GPxM8bfEXxzptvNa6XqXjO/SZNJjmAWX7NBEiRo7qNr PtLFcjOCRROti8VKLxVSLUdVGEIwjfa7S1btorvToghDC4aDhhaTTe8pSlOTV725pN2V+it53PqG qJCgDwD4yfHqy+Fep+GPCei+BvEHjf4j+Io57jT/AAt4bSLzjbwlBLcTSysscMKtJGu5jyzgAHtp H6vCDq4qpyRvZWi5Sb7RitXpq27JdWZuOIqy9nhoKUrXd5KMUvOTT36JJvcxfhr+0Vc+K/Gdr8OP iL8JvFHw58c39tNd6Za+IGtrm21eOHBlFvdW7ujSIpDGNtrbcsAQCQ08JXg54Sq5cu8ZQcJJPS9n dNX0upOzava4OGKoNLEwjZ6KUJ88b72ekWnbVXjrZ9j6ZrI0CgAoAKACgAoAKACgAoAKAPz/APjx +0v8U/h/8e/g54H8M/BrxvqHhq51XUYL06dHpzR+K410qadEtGkmDIYZQsjF/LyIWALZAO1PEYGE XCpUs38X7uo3HW6cbK0r7O17Jtu1iHhcZVftKcE0tv3iSfR8y+z5X62tudFqXxr+P/xB1XwP4a8D fs8eOfBby+IdOm1fxF4ql0tbS30qOdHvEKxzyu7yQCSNQqghnByMVLxeX0v4FR1ZPSzpVIrXq5SU UuXdea2Y1g8ZPWuoQitbqopPTZJRWt3o76Wv5H29WZQUAfN2teAvj+3gbStN0/8AaHstM8VWuoXl zfeI7jwvazJdWjyO0EHkM4WPykZFLg5bZk9apYnEN3p4anKT05X7S3quWSld7u7a7E1KWDjF+0q1 IQWt1KCd3vdzpyVr7WSe2pxnhjwb+0Ra+JfD91r37Xmg6zosN9BJd6PD4RsLd7+ESKXgWRZSyF1y u4AkbsjmtpTzFq1TA0ox6tKvdLq1eo1deaa76HPGWV8y9ni6rl0TqUGm+iaVFNp9Umn2aPsSuc6g oAKACgAoAKACgAoA+f8A4r+Ar/xR8S/gD4oXw5b65oHhzVb/APtC1uDGRYi4spI4r1Ufh2jkVY8D 5gtwxGcYrGtGnVSpVo3hLyurrbm8t/nY1pSnC9SlLlkvk7PdLz2+V0fKKeBvihoPifQ/hBofwcvh LpvxRm8aaf8AFON7RbC10i61WXULqM/P5wnNvc3NiYgmGD7sgHjKn9RpNTUX9YT5eXkdnHa/P8PK o2dr3UkrLRMuUMTUTTnH2Ls9Z+9zLW3Ja93Lre3K9Xuj9Lq6znCgDwr40fD7xp4nl8FeNvhjrmma Z8R/B91PcWA1yBprHUIJ4jFcWtwEIdFZdjB0O5XjU4Iypn2kqUlNU/aLrG/K3/hlZ2kul009U1rd PlhODjObh1Ukr2a7ptXT6q67ppo+Uvhb8Bv2jdTsPB/gT4xX3gLSPhnoHjO78bT2vhe5ur291q7f V59Wt4GkkWNYYY7qZCcKzOIVBxk0niJVoezp4aUHfWU5J6J3tGMVu1ZOTe12krq0pYanPmli1Uey jGPKr2teTc5N9WopKzsnKVtf0iqxhQB8s/tVR/C1PCfhbUfiFq3izTtct9U2eHJfAEtwmuT3skMi vDZrB877oTLvU/IFUs2NoIqCqQbrwrqioLWUkpRs9LOMoyUru1kot32E7VF7B4f23N9nbbW/NzQ5 bdW5RVnZvWx574Q/4UJ4h+AvwBi0u08SeHPhlbeNbS20/StTiCXMus2mpTxxx6iWLtltSt9zNu3P LsyfmIM+wveFOup395ys7z+27XjGzet7pKyaXQaxEornq0LW93lurQ+ynpKzS2Wst07aXX3RQAUA FABQAUAFAHyb+1rH8ED4Q8MSfGfw3rviKSTU/sugeHfDEt0NQ1S+kjY+VBHBJGXPlo7EuwVVUkkV pTdWKlUji5YeK+KUZSj5JPlTk9dkk22TZTlGn9XhWlLaM4wkl3f7xWikt3277Hzf8FdF/Zn8MfFf wX/bX7Mfjn4d+Pb2dovDOr/EDzL+2luvLLeXbz/aZ0huCgfaG2M2CASeKmThj/dWZVMQ4+9yVHVj t9pRmkpW33bW9tLml6+Cjrg6VKMtHKlGl10Sk4JSV9lpZ7N66/qFUkhQB8yftM6BpviDQfDNvqf7 NEXxlhju3ZdLlmsYxpp2f67/AEpgp3fd+Xmsqv1Vxtip1Ixf/PtSd/W0o6et9TajLFJ/7K6afX2j cV8rU6mvyXqfI3hfT/hx4U+KHwosNV/4J0WfgjVdY1uCHS/E802jGPT7qNhKJA8TEiRFRpEXIZ/K ITLYFEJZdUdqVfEOe6UlNJ273q6pfa0dld2aTLq181pr977DkejcZttX6fwFq9o3aV7JyTaP1UrU 5goAKADIoAKACgDwX4qzfDvxroET3XxQ0bQp/BvijT7xtXa+ttum6jbSpL9mn3sFVpImeNkJDbJi Rg4NdCwONnKCo0m5PVLlb5o7N2Wvez6OzOeWNwlKE5V52gtG78tnutXpvbvfY+Wvi34W8B+Ptf8A iDb+FP2tvBPhv4a/EuOGPxt4e+0afdTahsgS1d7W5MwNu8trDFC5KvxGGXBya3eVZ1TjOlTwTkpb SlGpzQurOyXuy2uk9nrrsc8c4ySo41KuKs49Izgoy6pSunJW68rV1p5n6NxokSJGgwiKFA9AK889 AkpgfIv7a9/a6d8EvtWt+Kp9B8CrruljxRcWV+LG5n0b7Qv2uKCXcrbzHyUQ+Y6K6oCxArfDfWPa Wwzam9OZK7h/e62t/N9n4uhlVVBxviIqUVryvaT6Ra637PRuye587W/gL/glg8UMkfir4YshVSDL 4wG4/wC8GuM59c8+tej/AGTxJv7fFf8Ag2p/8kR/auC/58U//BEf/lZ+odeOdAUAFABQB8K/td/D r9pjx7ffDhfhFrXhgeFtN8V+HtUewv8ATZJLq1ntr4StdyTfaEV7aNQjPCq72CsA2WGKWPeEVo0e a+nMpyTaeji0ou0Xs5X0T2Y44SFdtuu46bcsWvVN6uXZbNkXjj4L/tffFbwprfw68dfGr4eWngzx BCbLVZvD3hO6ivfsrHEggeW7dEcrkBip2k5xkU5ZhUUf3GDjTn0l7WUuV90uSN2t1qtSYYOhGSdT E1Jx6x5IR5vJvWyfXTY+6o08uOOMFiFUKC3JOPWoGS0AfP8A+0zcfCK0+EmsXHxs8Mv4i8GC5tok 0CG3a5m1S9kkEVvbwwggvK8kiqq5A5ycAZpql7ZSjKq6UbPmkpSjaNtbuOrTXRXvtYSqTpSTp01O baSTSd30+LRW3u9krn5+WfgX9mnRLrS7v4s/8E/NY8BeCL64htU8U6j9jvbaxaV9kbXiQTs9uhYq C5Uqu75iBzWlLE08RJUcNmeJ5/sqcq8FJ9otzau+ily32RvOrmFCLq1sPQcFvyezlKK6txdOOi3f K5aeh+wdZGIUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUA FABQAUAFABQAUAFAGL4b/wCRd0D/AK8oP/Ra0AbVABQAUAFABQAUAFABQAUAFABQAUAFABQB+eX7 S3wy+IHjXUvjb4Q+B/jnwNca58RvDCaR4m8GeJ7pobm1PkSQw39s8W51Jhk2sroyN5SkFTuzbjiK FCVZ4aVSm9pRduV9ndOMls7Xi07u9mR7TC1asKMsQqdRdGrqS8leLTW3MuZW3joj2b4V/Dr4w6p8 TpfjV8eLvw1beI7PQ5fD+ieG/CRnlttNtp54Z7mWWeXDTSyPbW4GFVVWPAzuJrKVf6xJOnRdKCW0 pKUm31bSSSVtEr7tt7GqoxoRs6vtZvd8vJFJdIxcpPXq2+iskfU9UScH4/8AiJ4d+G2naDqfiRrh bbWNb07w/a/Z495N3e3KW0IbJGF8yRdzdhk+1XSpqo2nJLR7318lZPV7L8bLUyq1HTjzWvtfbRdW 720W7/C7LmleOvDGteMfFvgHTtQMnirwzbWN1qdmYnX7PFeCY27biNrbvs83QnG3nGRQ6fLCM7rW /qrd189O5SneTjZq3Xo/T0OwrMsKYBQB8TftJaxc+CtftfEOt/to/wDCptA1CJIrPQJdN0q486RO Hkj8+J5XySM44HHSu3CrHzjJ4ehRlBbyqKat5OSqwj6Lc5qssApqNf2rqPpTlJ/dCMJP/Mm/Zp8I +DfE3iPUvjna/tHXPxm8T/2cdAt9WZ7OODRrV5EnkhS2tkQRPI0cLMXG4iNegrHF0sfGpGeLjCEb PlVONoO9rvmcpuT0WvNZfM0oVcFKEoYWMr3XNzuTn5K0lFxW/wBlXe70PtOsDUKAPgv9oj42/H3w 7cfHK7+D9p4Ns/C/wm8NLrer3nia1uLy51S4NtLdfZ7eOOSNY0EUa5kYt8z8D5TW0K+HouKnQdRv d8/Kor05W5S67pbGboTq8z9s4JbJRTbfdt6JdFZN7+R2fwm8X/H+w+MqfD342+J/BOo6Xq3haXXd Dbwto9zZyXTRXFvFcb2knkCiIXMHy4O/7QpBHlsCOvCvBqOGVJxa+25XTvsnGPbXtpvfQ9iqTTVe VS/eMVb7tdemuut0rK/2DWJoFAH5o/tY+IviLrMf7TM2gfF7XfBlv8JvBsWuaXonhqeO1n1e5lt5 5vtVzIQZGt1eERKiFRujkyTkAdFLE4ijGMsNGKSfvSlBTbe6iuZNRVtW0ru++hhUoYeq3HE3cmvd XPKKS6ytFrmd+7aStpd3Pqi98bazD+1P4d+HtlqhuPD194D1DVtR00HcLC5gv7OO2lOPumVLm6XB +95Ax901m5ONNRktG7p2V9Pi13a1j5L5lRUZ1HKL1jo9dNdVpsno/NrySPoaszUKAPknx94T+O/g L4oeJfin8ENG8OeKtL8WWVnBrfhTxDfvpskV1aq6RXNrcrG4+aJwjxuuP3akEc0oYinQk1iKMpxe zg48y7pqVk0+lmmnfe5Toe3inTrKnNfzRbi1/wBuu8ZL0aa3ta474V+CPjT4n+LUnxw+OWmeHvD1 7p2gT+HdA8KeHbyS/wDssNzPBPdT3NyyJvkZrW3VVVQqhDyS1TKvHETTo0pU4JfbcXKTflHSKXRX bd3cFR9hFqdVVJt/Zi4xilfa7u2+rdrWSSPrSrJCgD5Z/aLh03Sv7I8aXH7Tt38JL7T4WiiM11ZN YagC2f31ncqRK2eAUw2DgGuvC08wnd4SnGcF8SnC8fVzTjKH/gSXdGFWeB5lDEc3tH8PJKSn8orm UvnCVjyD4C/tI/GXxv8AE7RfAN94Yt/HPw6uI7g3HxV0TQ7/AMP2tmY4neMPBd5E5kdQgaBtoLg4 xWFTF4KT9i0o1u1Op7aHneSilDTZOc30NlgsVTXtVzey7VYxhU8tFK713vSh/l+gtZjCgD4x/arP w78MXvhD4ga58bPEfw18crBc6VYXnhS3F/d6vasUllgNiYZvOVGRXD+X+7JJ3Dcc7UI4mLdajOnG Oil7Xl5PLWUotS3sou7V9GiJyo1LUJ0p1JatKm5Ka7u8dOXa/Npe1tbHjPg74BWGn3nwo8Y/Cz9q fxDBrPiHTNR1PwNNrmjWl3Hd2upNFqWpNOphRp3nZoZ/3jLIuz5eFYVlfH05Sk1RqOF73TXNeW75 ZrSL0i6aSSfvXuW/qVRKLhUhzWtafw2Wy5ozWqvzKfNd3atY+6vhH8Orb4T/AA78OeA7bU59TksB NNdapcoqSX93PNJcXNw6qAFaSeaWQgcAvUR52uapbmd27bau9knfRbLyKm4X/dq0dlfV2Wmr0u+7 7npVUSfHPxy+HPxT1/40fDnx38EfG3gfw94+0TRry0u4vEVtNd3Gq6ZLNE0kDQpKubYTJbvvADLI AAwDEFxnVw/76OG9rB+67zcUuqt7krT00d7WunF6WTVGvajUrunL4koxTfZvWS01s009bNNM6TwT J+1HpvjjwzafFjxt8JpPC181wr6doWmX1rqF4ywOyi3aW5dSVYI7Da3yK3TqNvbrEQlyYJwtvL2v Py69Y+yjvt8S1fyalRo0Gn9alJvaLhGKfzTb21+R9RVgUFAHzN8Xfi58TtG8f+GvhL8F/AOk+IPG +o6VPrt5e+JNRewsNMsY5UhBZo0d5JHkfAVRwFJJ6Vaq4ejDnrQnOV7KMLJ+rlLRLto236EeyrVp 8sKkacbaylFy+SinG76v3kl8x/w/1n9rS78XaVb/ABO8EfDPT/A7CX7bd+HtZvrm8jxG5j8uOSFU OZBGDkjCliOcCpeLoVfchhakG+sqkGl8lFN323Xc0+qTpe+8XGf91UZQb/7edWSVt/hd9tL3X0tS EFAHyr8YNG+KfhD4o+G/jh8LvBVv41EehT+HNa8LG9jsbx7czrcRXFpNJ+73q6yK0bbQwdTkFRUe 1pUp3xEZOFt4JScX/hbV0+tndNLRleynWjy0ZxjPtNtRku10pNNdHZrV7HE+H/8Ahdnx1+Lvwm8Z +N/g9N8NfAPw8ub7VootY1S2vdR1i/msprJI1SDckUCR3UzsSxZmCYAGacsThaslHBqcv5pThyJK 3wpXbbbs23ZJIUKFalFyxc4KT2hCTn13cnGK22ST31fQ+4KoQUAFABQAUAFABQAUAFABQB83az4Q /aUufB+gW2j/ABS8Gw+P7XUbya61jUPDLXEElo7v5EcUKzoY5EjKKz7juweOaX1j3lVlhISa2XPN KPS6dm7tbrp0BUIWdN4mol3UYXfWzTVrLp17mL4d8H/thW3iDQ7nxP8AGv4f33hqG8hk1CysvB09 vNc2wcGWOOQ3bBHZNwDFTgnODjFaPHSmuX6lCN+qqTbXnZqzt2Ylg6MfeWKqya6ONNJ+Tsr2721P quoGVrm5gs7a4vLqVYrWBGlklc4CIBkk+wAJoSu0kJ6K5+Xf7TX7RH7J3xM1L4LWHiT40eG9d+El r4gc+J/D+n6of9KElvIlpLPGnMtvFcFC6dAGDkEIa9L6jj6HuU5+z59HKM4p9+XmUrxUtrrrZaJt nPDE0pP2nspSlHVKVOdtdG0nGzkuifS9ruyfW+BbX/gmOnjbwe3gB/hSfHY1S1/sX+zmiNx9v81f s/lY/wCWnm7NvvisZ5VmFOLnUrVHFatOu2rdmud3XlZ32NlmkanuKja+n8Br8fZq3rdW3P0grjLC gAoAKACgAoAKACgD5N/acufF+pan8F/h/o/jzUvBHg7xfrs2n674q0ZhFdxBbWSW3tIpyCIGuJU2 CTg5ARTucA60qtWm3HDRi6rWjklJJLWTUXpKVtk07K7toY1I0JJTxDvTjuk2r30XM1ZqN97NXuk3 qeTeJvhj4i/Zy8VfCLXfhn8ZvH2u3Gv+KrDRNQ8EeLtbk1qHWbO4kC3U8Qmy8MlvD5lwZEIULEQw waf13HOMnjZqpT2u4QjKLekeWUIx66crurX2sX9XwU5JYWl7Opv7jlZpfFzRcmrW2ejTaSd3Y/Qu sSyCeeG2gmubiVIreJS8kshCqigZJJ7ADvQld2Qm7K7PzW/af+N/7N/xEv8A4MaDrfx/8M3Xwgk1 +SPxXpvh7xTBHJcK9tItmbjyZRIbVbnZ5gXpuRm+VWI9f+zM4wvu04TouWnOlZrryqX2XLZP/t2+ pxLF4Kr+8qQVTk1UZQk12vytWk472fS7s2rG14I8Cf8ABOCy8aeEbzwN4n+HcvjaHU7WTR4rLxYs 8z3wlUwCOPzzvcyBMLg5OBg1NTLOIKcJTr1sS4JXfNUqONut03Zq26ejRusywdRqEaNNN6JqjFP5 PkVvW6sfotXlG4UAfO/xy8MePn1b4a/E/wCGug2PiHxN4Ku7t5PDV/dfZP7UtLqAwyiGcgrHOhEb qWBUgOpxuyIdSnTknWjKVPry2ck+kkm0nbZq60bs7qzpQdSLjCajPo5X5X3UrJtJ90nZpaNHyD8L fB37Qnjzwz4I+E3i74Kz+BfBuk/EO78cav4h1nV7W4muIhr9xrVta2sEBfLGSSCN5HZQFVyASRS+ t4apBRwym5t7yhyRir73crttaJJWTe7S1r6rWpScq86ailooycpSdv8ADFRinre7bS2jfT9Rq0Mw oAKACgAoAKAPmf8AaA8PePYda+FHxa+HXhSHxVrPgS/vJLnwu9wltNqFnd2xglNrK/yLcRnYy7sB l3rkbs1DqU6bi68W6fXlV3F9JcunNbZq97O61RcKcqqcaclGfTmuovvFtJtX6Oz1SvoeM+I/FHxZ /aV1j4d+C7f9n7xT4F8J6R4p0rxHrPibxnNZxNCmn3Ud2kFpDDLI0kkskSRljhVRn68VVTE4J2WD nKpUvv7OUFFbNtzs72ukknvq7Cp4fFwvLE8kIW2U+eUn0VkrJJ6tt+iPv6mSFAHk/wAVp/jZBp2l N8E7DwddaoZm+3L4xmuooli2/L5RgBJbd1zxij28KGs6Eql+kZqFvm4yv9yF7F1tFW9n5uHPfytz wt63fofOd/8ADr9qr4u614F074uan8NtC+H2geIdO8RXUfg4Xt1fahNYzrcQwCSfCxIZY03sAWK5 AxmlPGc9o0cI6cr/ABSqKVl1sowjq1dau1m9B0qFKN5yxftVquVU+RX6cz9pUejs7K2x9yUwCgDK 1nWtH8OaVqOveINUtNN0Swha4ur++mWCG2iUZZ3diAqgdSTV0qU681Tpxbk9ktWzOpUjSi5zdkv6 /rucH4T+NPwm8deF9Q8b+EfiFoep+ELG+GmXOsW12v2eG6JjAiaQ4AYmeHHr5i46itqmDrUqipSX vNXsmn37N66PTciGIhODnaSS3vGSfrZpO2t72tbW56jXMbhQB8D/ALTnxm/Zk+CMlh4L8ZaD4Ku9 W8ZeKNIvNe0HV7Rf3lvc3C28uqzL5ZWRoo42bLckRYpwyyhiKcvbW5ZPbninzdHZu6jfd2S31LeY Y2lOEsPzpxVk1CclbrFSircz6Ru3qvdd0eS+P/i9/wAE99G8Ha9qPwz8F/C3xj8QYoP+JN4W03w8 kk+r3ZIEcCBICQWJxu6L1PArCXD+Bwy9tiXD2cdXatC9vJKTbfZW1eh1xznOsQ/Z0vbqT2cqVZRX m3KMUkurckfqdGzPHG7IUZlBKHqp9K132OEkpgeHftBeNtC8CfDx9T1bwOPGWoX2oWml6P4WKRsd U1K4lEcEeZAVQZYszkYVFZu1RPD4XERaxn8NavTmenRLq29FtqVCpiaUl9UdpvRO9ku7b3slq+uh 8l6hrXxG+GFmnjb44fsnfC21+FsDxnVdR8I3q3d5oFuzbWuJoZbZFljjyGfYwIUMwBxiuangcixE lSWDnSb0jKSpyi30UlGzhfa/vJdbLU6J4nNqMXU+uxqWV3FKpB268rcpKVlra0b7LofpGGVlDKQV IyCO4rs2OXcdQAUAFAHn/wATfiX4T+EfgvVfHnjS7mg0SxMcey1haee6mkdY4oIYl+aSWSR1RVHU t+NXSpqo7OSikm227JJbt+hnOUopcsXKTaSS3beyV7L72l3PnnS/2wtMj1LRoviF8E/iX4C8N6tc w2lr4l8T6XALJJZW2RLcNDNI1vuYqoMihQWGSKuDwGIkqeGxSlN7JwqQ5vKLlFJvsrpvpdhUpY7D xdSvRXIt3GcZuK7tJ3surV7bvTU+xqxNAoA8J/aC8DeLPGvgzR7rwD/Z8njfwrrth4l0qz1Ylba/ mtZNxt5XAJQSRtIgfB2Mytg4qJS5LScOeN1eK0bXlfS63V9LqzKilK65+RtaS3s/Nduj62eh8zfE vxJ+0n+0N4K8SfA4/s03ngax8Uwf2TrPi3xDr9ldWunWcpC3EltHCWeaXy9/lgqg3FS2OlVUxeAl BrDKrOp0UqfIk+jlLmei3tG7ewqeExcZ3xNSlGmusZynKXkouEeW+15PTsz9CoY1hiiiUkoihct1 IAxzQIlpgFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQ AUAFABQAUAFAGL4b/wCRd0D/AK8oP/Ra0AbVABQAUAFABQAUAFABQAUAFABQAUAFABQB8F/tOav+ zLq/iyLwh4z+F2u+OPjLBbxzWtt4I0i4bVrJGyY2/tCPy1txwSC0y/SiFKjh5fW3jFh5PS6k+eS7 ezheUl/ijy+ZrGri6tN4anhvbU+qmo+zT85Tsr/4by8i5+yv4V/ab0PxX4hvviRf6lp/wTm00R6H 4T8XazHruuWV35iESTXqRriPyg6+WzyncwO7irnmLxfucjklr7SUI0pS8uSDcbdbtRlptqZfUqWG XNGSjLZwhKcoLzUqmt+lopRt8j7oqAOM8ffD/wAIfFDwrqXgrx3ocGreGb/YZrO4yAWRw6OrDBV1 dVZWBBBUEVE4OaVpOLTTTTaaa2aa1TLp1HB3smno00mmnumndNep+XfxB/Z9/ZB+BPxN10+Ktb+I ura94q0+xfTvBfhS/wBb1DULSC3M6PPI1vKZGidpQF80hVMbBOrVvTqZhBPEYjMnRg9FKU7Sk102 bla+lo6Xd9zKSwdRqjh8shVktXFUqbjG+zXNyxg5W1vLWy7H0p+yho37NE+t+JfEXwWvvF0Xi6ys 1sdW0PxlqGrfa7CGZ0kUvZ3rnbuMI2yqpB2sA3UVdV4ucFUqY54ik9nzqUbr5JqSXRpOz2JSoU5c iwMMNU30pxhJp+cbpq61s2rpX6H3HWBoFAHwB4z8W/Cb4QftQeP/ABr+0DbRafp+vaFpUHhTxdrV k9xYW0MHni6s1lCssE3nOsp3bfMWRcE7MVP1WjmklRqyi5Q+GM5RimnvKPM0m+j6pJdGX7evgaTq 0YScJfE4RlJq2ykopyStqna17knwc8VfDv4mftTax47+ANqkvw6g8Gzaf4n8RabYva2Gsam15bvY pGxVRPLDCt9udc7VmVSTnAaoUsvbwlKUXf3nGMlJRa0u+VtJyvsndpXeyE6lfGRjia8JJLSLmnGU k9XZStLlVlZtbvTdn33TJCgDz25+GXg+88R+MfE11pzS3nivR4dD1i3eRjb39rF5+wPF93cFuZk3 YyVbB4AxlKm5qUXJ8slt0vtddU2tHrbRdUaRqcvLJJc0dn17281fVdrvueafCP8AZp8G/CLxJdeL LHxL4r8Q62NP/sbTp/Fery6idG07ekhtbXf9yMtHESTlm8tMk7RVupiq8lLFVee2i92Md7Xb5Uua Tsrti/2enFxw9FU+bV2cnff+ZuyV3pGy8j6NqiAoA+Hvir4H+Cn7Qvxk8V/Bz40fD9LTUNH0G0ut C8Rf2pJY3PiGzuTMLyGBoijNHA8UYkQsw/fqSoBBLVCdWE54OrUhPapy6Llfw3Wqkn726snotWS8 XDD8scUqcoXvFTSdpLdpv4ZbWtZ216ae6/CD4G/CX4Lx6uvw40ZIdR1XY2oapd3kt/e3oTIQS3Er NIyruOATgZOBzUyp13N18VUnUm9Oabbduyvol5IIYvD1IrD4ZQjBaqMFFLzdo/m9T2ymUcJ8RfAO m/EvwtdeE9W1bXNNsbiSORrvw9qU2m3SlGDALPEyuoJGCAeRwacatai+fD1OSXdJP8JJr8BOFKp7 taCnHs72/Bpn546F+zx4R1r9o34g/DS6+M/xQ07RvC2habdW+jSePdSFzrEt2Zme6DNNu8mIQrEA nG9nLE/KK6ljc3nTvSxDai/elyU9G9lb2dkra3d77K1nfnnRyqjO1bDU1zfCnzJWW7u5au+lk9Fq 1qrenfCHwfonwg/ax1j4eaL8RPFniu01jwTLq62ev+JbzVf+EdaG8tonSRJJGX/SPMRo2YeYvkzg Eq+AqmIx06Sjjajkm7xvGMea270in7t1ZrRqWquky6awTd8FRjG2knG7s+ivd763TfRNdT77rlNg oA+Gf2tbD9mrUNc8Ep8WfCPifXfidbxPP4bXwPY38uqwKHGWimtsLEN+OZHVc1EqNOVqtXFRopfz STT/AO4TUuf/AMAZtRq4mKcKGG9rff3Y2XrOTjyfKSfYwPgGv7WMvxM0O4vrXXNN/Z1ENx9qsfid d2N1rpbyW8j7P9kjyg8wx7vPlkbbu6HrosfRnFYenTVT/p4qfsV30jzWlfb+FDuYfUHRftXNQsv4 aqSqpvu5TV423tGclol10/QXIpDCgD49+O1v4q8FfEjSvi/pXw01Txz4fk8LXnhm7s9AWKXUNHkk mWZLmGGRlEkcmCkgVt42REBhms3LDc6WLfLFXcZcrkk+vMopyV1tJJ2s097msadecX9WactLxcuW 68pPS6fR2ve99LPwn9naD4jfEaw/Y10G++E3ijwd4f8AgvokEms614st0s21LUE0STSxa2kG8yNH uuJJWkcKMRqMZbhrE4Wah9Wqe0k/itGSjFW2bkleV7aRutG77BLDYig5/WVGKXwpSUnJ33926SSv u7ttaaM/TirMgoA/PHxH+zl+1Bqf7SKfEzSP2iVsNBXw3qWmWuojw9YSS6dHPf206WAhZMSJthDG ZvnBiA/iNCx+IjNRWGpOy6+05X5ytUT5/S0bX0vYr6phJR5pTqa7pSV7+X7tpR8nd3troeseFv2e viVJ8RfAvj74ufH3U/Gsfg6a5vNH0dNFs9Lgjup7aS1aaUwqGkxDPKFUnALZpTxWJxDSlTpU4rfk U7vybnOVl1030CNHC0U3S9pKT/nkml6JRjr0u7n1tTJI5pobeGW4uJUigiUu8kjBVRQMkkngADvT inJqKV2xSkopyk7JHyJ8cPAXiLxz4w+G3xI+G3x+8PeA9R0eyuEgv5NOttQbVLa42l08x5VD27FI m24I3xIwIIraNHMaNR/VsMp9JKSqfc1FqzT1v8S1V7Np4SxOWypr63XlFPWLhOnH/t5OUJN6aWvy vqm0mrvwy0b42WvjbRrjxh+1R4Z8YeHkE3n+HdO8O2VnNeZicLtljlZl2Ptc4HIQjoTVVFmHK/b4 KFOPWSVa6/8AA5OOu2q66akUquWSklh8XUnPopTotPvdQpRltro156XR9ZVzHWFAH5xeJfD/AO28 /wC1HB4r8O23w7/4RyDwnqmn2V5eR6h9hWB9RtZIo7hVlDG9KRghlAQKJfUVX9qU4fuHhptbuPtU k2tOe/sml25Xd635rJ3P7PhL999Ys9r+zi2r68tudNrrzaapaanrPh74eftN+K/ih8NfF/xj8UeB bHwx4MuLy/i03wTa3qTapPPaS2oSd55GAiVZmfaByyp/dpSx0qn7uhh3Si/ibq891ukkoQW9nd32 0D6pRh7867qSWy5FFJ9780ntddNz7EpAFABQAUAFABQAUAFABQAUAcD4j8eWXh/xh8PvBbafcXOq eLJbtYXiKqlrFbQGWSWTPJGTGgAySZB2BNUlHlbk9emnX79Fbrr0VtSXzXSilbrd2+7R3flppd30 sfPb/tYoPiBNpUPw11SX4RQ+KIvBMnxGS8h8ga08q24iW2++0AuXW3MwOBJnjAJrblwt/YOcvbWv 8PuLS/K53+K2tuW19L3M0sQ4+3Sj7O9rcz52r25kuW1r/wB69tdj7CrnNhjIrqyOoZGGCGHBFJrm VnsCbWqPzo+DH7U37Os3g/UIfjP8Qfh9pnxAsvEWvWFxYXkdraSwQQapdQ2waMKAP9Hjh56nqeTV rh6ji0qtHC01F/4Vto37zvq9X+Glhf2tiMO/ZyqVZPvyze+u6jbTb8D3Dw9+0V+x9rev6Fovhj4m fD668SX95Da6fbWU0BmmuZHCxJGAM7y5UDHOSKb4aVD96qEFy63ThfTXo7/cL+2a1X3HKpZ6awqJ fO8bW9dD6qqCgoAKACgAoAKACgCreWkN/aXdjdIWtrmNopFDFSVYEEAjkcE8ildrVOzF6o+Obv8A YA/Zcv4hBfeB9TuLfesgjn8Ram4DKcq2DP1BAIPYionUzCqkp4+s0tdaknqtn8jam8LSfNTwdBPb SjTWj0a+Hqje8OfsS/s6eFfFXhzxtovhHUovEuhXKXdheTa9qMxgkVlcfK8xBUlFypBDAYIIolPG 1JRdbGVppdJTbXZrXo1o+6EpYaMHCnhaMU7fDSpp3WzTUbpp6p7p7H1lWhmRSRRTxSQyxq8UilWR xkMD1BHpSa5lZjTad0fnH8Yvj3+y58JfjD8PvhhqHgrwvsu9Qu7XxLM/ha4kfSo00+S5gaExwFZS 8ohQhN+A5JxgkYU8iytw9+NK72vUprls/tpu8brRX5bu1r3SfRPMc2ck6ftWvKMnzafZa3tu7X0T L0/7QX7N9/4g+H2j/AjwHpniPx9qXiXS7QW0Pg+7tTZWb3KC5u/PeBFiMEW+UMW6oBjmn/ZOVYNq rN0W/sqFSnKXN0souT0er0WnVDli83rpwlGrGPVzjJRt1TvbdaLz6M/ROtzlCgD5M/agufFt1e/B rwfpvxA1TwL4E8Ta9LY+IfFeissV1ABbSPa2yTsCLcTzqsfmcHO1AcuK2oVa0JOGGjF1ZfC5RUkr au0Xo5W2un1droyqxw9ufFN+zjulJxvfRXaalyp7pNb66XGeGv2ZtP0DxFoOur+0R8WtTfTr2C7G nal4wluLa7MbqwimjP342xtZe4JHem8Tm0k1UqRcXv8AuKS066qmmvVNNbohTyhtKlSgpdLVKj16 aObT9GmfW1YHQFABQAUAFABQB8zftNR/CCPwxoOpfFj4p6p4CFnds2k6xomtz6ZdvcFMGOJYjm4J GP3ZVwf7tdOGhjpuTwVTksveb5HG395VE429bHPiKmEpRX1ul7RPZWk2n3i4e8n5po+Yvhn8Uv2m ZfiB4J0P4cjxT8S/g5d6hDDrHif4j+GI/D0+nWLOBJNbz74ZLl1Q5Cta/Nj71RPMcM7063s6tTZO hzpJ953UqTXf2cl5I6I5dUSdWHPRiteWrOM7rtFK9RPt7SXqu/6bViAUAfHn7U8EPibxB8CPhb4k 8X6h4a+G/jHW7u31u7029ewk1JobOSa3083KkNGszqzHDAt5OwH5q2oVMQm4YN8tVrRrWSS+Jxv9 q3W10rsyqxw6j7XFxUqa3Uvhu9FzdLX6PRux5P44+D/w1/Ze8RfB/wAW/BDUNS0HxNrXjHSPD8/h ZNZubq38SWV3OkF0HtpZG3PDAz3AlUAqYMk4JzUK2YckpYmvUq0tn7RuVm9IuLeqfM1onqrq3YnP B4qajSpU41d04RjF2WrTUbJxtffZ2tqfo3XOahQB83ftReHdQ8QfDvR7i38K3HinSNC8RaZrWr+F 7VVeXWLC3mDyxJG3EjL8swjP3zCF71E5wjFxqScYS0k1fRPe6Wtv5rXfLfR7FU4zlJSpJc61jdpa rzeifZvRStqtz8/T8TdK+Ivg39rn4L/DT4eeMpfFnxU8VOmgW83hi80620y3n0fSbM3tzLLGiQJD NbXDEZ3kxDaDuU0lPAYam/Y4im3B+7GErty0asktFd6t2S1vqi3Rx1aa9tQnFP4pTskls7vm9522 Ub3uulz9joUaOGKN3LuqgFz1Y461oZEtAHzd+0zqXw88OeCtD8SeNfh9P4w1S38Q6V/wj+g6eqi5 1DWBcK1nGjkgACUbyXOwKrEggYrGWDwteXtMS+VRWrSu2l9my1lfbl2d9dDSOIxNNcmHSbeiTdoq /Vtp2tvzJNrpqebW3xM/aUieK4t/2J9MglHKt/wmdirIfwt+D9KUIZDFqUaVa6/6cU//AJcXKnmM 1aWJpP8A7eq//Kz7arcwCgDxv43fDnVfib4Nt9P8LeIo9D8baHqlpruiarLCJ4re/tn3oJo8jdE6 l43UEHZIcEHFTJ1KfLOnFSa1s9FJdVfpfo+jswg6VTmhOVls2rXi909e29nutOp8z+L/AAV+2R8c NA1P4TfEqy+GfhX4ca0q2eva14cvL2+vdQsCR58NvFKqrC0qBk3szFA5xkjNOpjYVIOGHwk4zenN OpFxjfqlGKcmul7K+4U8Iqc+evi1OC1UY03GT8pNzkku/Km33R98RRpFGkcYxGihQPQCgCSmAUAF AHgH7Rfgzxd4u8FaFqHgLTrLU/F/hLxBp3iax0bUZPKh1VrWTc1sZMEIzxs+xyCFkCE8ConKMLOc XKF1dLe3lfRtaOzte1updOPO2lLldtG9k/O2tns7apO580/FT4hfGT9ovwB4m+BeifsxeMfC914t t/7I1PxJ4vuLGOw0S2lws06GKV2nkRN5jVVGWCkkCqq4rLlH/Z6kqlT7MfZyjZ9HKUrJJPV2bell 3FTwuOUk66hCHVqpzNrqoxSvd7Lmsl17H6IRJ5UUUW4sEULubqcetG+pPoS0wPmT9q631tvhno+p abo+raxoWjeJtH1XxBo2hhnur/SoLpJLhI0UgyY2o7Rj76RsvO7FNYn6q+Zz5E9HJX91PRvTVLo2 tUm2HsHifdjFTktVF2s2tlrpfqr6XSPm/wCO/wC1R8KvjV8MfEXwx+CF/r/iP4z6o1unh/T9P0TU LWXStSWVHguriWWFVgjhkUO5Y/dUjBziuicoYBfWViqemyhUjKU/7qjCTbUtndJWbuL6pisR+6q4 Sai93OHLFW68z0ut1y3d0rH6TRCQRRiVgZAo3EDgnvXLe4yWmAUAFABQAUAFABQAUAFABQAUAFAB QAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAYvhv/kXdA/68oP/AEWtAG1Q AUAFABQAUAFABQAUAFABQAUAFABQAUAfGfjPxH8e/HPxu8b/AA3+DviPwl4M0vwlpem3moaxrmkN ql5qst4JjGI4hIgSFFgZd5yS4YD7tNVKeHXPSwsas3vKUpRStsly2bdtdXZK2gvZe2lavXnCP2VB Ru+7bmpJK+lkr+Z6d8K/Cv7Q2h+ILy7+Lfxb8OeKfDr2bRwafo/hv+y5IrkuhWVpfOfKhBIu3HJc HPHKeKqV/dnh4U13jKbfp7zat+Ow/q1Cj71KtVm+0/Z2/wDJIRd/nbfS9j36gAoA+HvGXiy5/Z++ PXxF+JHin4aeJfEPgnxvpWlRW3iXwnprarPpUtms0b2k8CfvFibzVlR0BBZ5A2ODWalg3U/2uqqU kvdck+Vp6tXSdnfe9rq1noXKGKdP/ZYOotXKMXFSv0aUnFSVtNHdWemo/wCFPiHVfjV+0X/wujQf h74j8LfDrRPB9z4e/tDxRp50258R3Vxd206FbdjvEVultJh5AMtckKOtP2mFU3DB1FUvrKUU+W60 ik2lzOzd2lZLS4ezxKgp4qHI/sxbTkk93LlbUdlZXv3sfb1WQFAHzR8V9P8A2irTxBPrnw8t/A3i 7wI8MYl8FeKYZLKdHX77w3y71+bg7ZIiAe4qJzw9SPscXhfaQ/mi1zL/ALckuWXycX5lRhKP72ji XSmv5o3h96cZx83eS8jyXwd+3h8B7PxDf/Df4gQ/8K28Y6TsW8sL57e60+AscL/ptqzwoCeP3vln pkDIrvp5VRhGMMI1Fy1UJr2U/lGVlL/tyUrnI8ZXq81WpF1Ix3qU26kPm0lJed46dz7ksL+x1Wxs tT0y8hu9NvIkuLe7tpBJHPE6hldGHDKVIII4INcs4SpycJqzWjT6M2hONSKnF3T1Xmi7kVJZ8L/t CftB/G3wbdfGST4QeDvClz4c+Fnh0a54g1XxTcXG+5kNvLdC2tYYdvIhjUl2bGZAMcGt6dfC0XCN WlOo29eWUYKK+cZNvd2VtLa6mboVavNKNZQS2XI5OT9eZKK6bNnX/CX4h/tAv8XZfh18cLbwHbWV 94afXdGl8KR3nmX5juIYpwTNIwAhE8W4bcn7RGQcBhUuvRrwfssPKm4tX5qilo72slCPZ3d9LJWd 003RdGSft/aJp/Y5bWtv7z7q3fXa2v1zWRYUAfEni34X/s8fG/8AaF8c+Efij8H7O78a6Do2mXtl rurTMDrNrP5yuLVARlYGhCSEZwZUzjIyck5pVcPiKsZQ3UZyioc220vtWd9Fta76VHEyw8lCpThy z+FuMW5W3Wsfs3Wl3o72S39l+GP7NfwP+DevXnib4afD/T9C126s2sJry1LlngZ0kZOSeC0UZ/4C KPaYmatWxFSou06kpK/e0m1fz7XLnWVRWUIr/DGMX96S0PdqDIKAPzs/bA8Yfs5S6vqem/Ez4E+I viHrXgzRTrOq6t4bskU+G9PcSPma8aWIpuWKR/LQscLnHIzdOlQpVI13jHh6stFyOpzNX68ity3/ AJmtblRr4rklTpUY1KcdXz8vLfyUk7u29ltY6H9k/VvhZovjDxV8OfAH7M/ib4Y6v/ZcWtX9/wCI oLVX1CJpfLiBlWeSSUkmUjqq7GyVJUNMo4WrJ4inipV6mzc1U5kvWey7LS+tr2dqnUxllTr04U4b pQcbX2vaKS0W73WndH3lSMwoA5DVPGfgzRtci0XWtf06x1trM3qx3sqxH7P5ix797YGN7KuM5JPS tKWCqYl89KnzPbRXffbe3nsYVsZRw2laain3dl970v5bmZ8QPit8NvhVo1l4g+I3jbSfD2jXk621 vd6ncrEk8rAsFT+8cAnjoASeK0oYStiJOMFtvdpW6buyvfRLdhUxEIJPV325U5N9b2im7W3eyOz0 /ULDV7Gy1TS72C80y8iSe3u7aQSRzxsAyujDhlIIII4INYzhKnJwmrNaNPoaU5xqxU4O6exfqSz4 9+Ny/Ebx58ZvAXwX8P8AxM1T4e+Dr/QL3XbrWdBSNdQ1i4hnhi+x280isIwiS+a+0byCMcAkaQxN WjGSw0Yupu3OKlyx2uovRtvRtppadWZyo0ajUsTzOGyUZOF5b6yjZ7bJNX17HL+H9C+JnwF+Nvwi 8Dw/GfxN8QvA/jr+0ba90fxi8V3faN9mtHuFvorhEV/J3pHA6vkbriPBzgU/reIqU2saoO7tGUYK D5t+VqNotNJu9rq3ZlPD4ZT5sIpQa1lHnlONtk1ztuLvZaOz100PuqsigoA8Y1/4uReGfjN4O+Fu taOtloniTRbu/sfE93ciOGfUIZolGnIpGDM0MjzD5gSsTYBwcbUqcaylCF3UWtracuzd99G1dW2d 2zCrU9hadSSUNtd79PRPz3eh6+l3ayMEjuYnc9FVwSah05xV2mEMTRqPlhNN+TRYqDco6jp9lq+n 3+lalax3Om3sL29xbzLuWaJ1KsrDuCpIP1qWuZWHF8rTPGPEP7M/wC8WaZ4U0bxL8JvDmp6X4asV 03SLa9sklXT7VcYiiB+6o2jj2rL2Dskqk1btOSv62er83qdEMVUptuKjr/dj+Gmnohvg39mP9n74 eeJNO8YeCPhF4Z0TxRYeZ9m1PT7COKaDfG0b7WAyMo7qfZiKcaTi03Um/Jzk19zdgqYypUi4NKz7 RS/JHu9bHMFAHj3xZ+Ofw6+C1rpUvjbUrw6hqhkFhpGkWE+oXt4IwDI0cEKs2xAV3OQFG4AnJGdq dFSi6lScYQWjlJpK72Xdt9km/KxlKU3JU6NOVSbV7RSvZdXdpJa9WjX0H4s+BfEdl8Lr7TtXbyfi Hpo1Xw6JoXQ30H2dLnuMK/kyB9jEHCtjO04UqLTnyyT5fxV7XXdXt96BVG1FuLXN3to7Xs9d99rr R6npVZGoUAFABQAUAFAGNruv6F4X0q817xLrNjpWiWi77jUNSuEt4YF9XkchVHPc1pRoVcTNU6MX KT6JXZlVrU6EeepKy8/669ji/A3xn+EnxNuLuz+HnxM8M+JL22XfNbaLqkF1JEvHzMiMSByOcYrp xGXYvCR561Jxj36el9r+RjRx2Hry5IS97s0036JpN+dj02uI6woA+Yf2pbT4Ur4P8P6/8TfF3iDw xd6ZqQGh6t4RnuItWN3LE8bQWqQBpJTJEZA0YUjau4425F0qdZy9rQqqlyrWUuXkSenvKacXra2l 72tqTKUGvY1KPtebaKvdta3TTTVle7ula6b1OC8IWX7PXiX4F/AO08OanrOk/CyHxhajSba/glin 1HWLO/nKRX/mqZA7ajbs7FypeVFBPz4MfVp3cKdVTb95z/m+07aLV9dNrpIpYi3v1KPLb3eV29z7 K2k07aJay3TPtugAoA+dfgZ8CtO+G3gObw14p03RdV1mXXdb1Rr1LRX3R3mpXN3GpLrnKxzop91O OK4Hg6GIbqYijHmfo9tFrbt92x1/WqtFKFCrLl+a9dLvr9+57LB4Q8J208NzbeGdKiuImDxyx2ca sjA5DAgcEHnNVDLsJCSlGlFNbaLQmWNxM4uMqjafmzpa7TmCgAoAKACgAoAKACgD57+N/i/4i2Wp /Dr4b/Cq90vS/GPjO6uk/wCEg1m2N1DpVpaw+dNIsAK+bM2Y0RSwA3MxztwbjUjRjKfs/aS6RbaX rJrWy7KzbaV0RKn7VqMpuEerSTl6R5k0m+7Tsk9GeMeE/jd8SNI+Afwx8beKtXs9b8Ty/EtvBmr3 f2RLYajbHxLc6Krxxp8sbhRDLgdfLYdyav2sak3OVNRTWqXNaLturtv4u7ejfkZ+ycIqMajdnpe1 3rs9F07JapdLn3XWJuFAHJ6v4I8JeINd8MeJtZ0Czu9e8PTTXGmXs0YL2kk0LQSMp9Wid0Psxrnn hqVSSnJa/n69/K+xpCtOMXFdf607fI6OO1tYmDxW8SN/eRADVRoUoPmjFJ+hLnKSs2Wa2JCgD4g+ NPij4MfFP4ceFdd+K/wB8e+J9DbV7y2tdCHh2ae7s5oHaJp5YEcFY38vKOScgqRjNTUnhWrfXvZw 096LqxTa1t7kb+6+6tdaGlOGMpy9zCqc+zdJ2T2d5yUdV2d9dTw34d6H+yFH4/8AA8vhj9kL4jaN 4kTV7N9P1i/8JXUEGn3ImQxTySNIQiI4VixGAFJrR4ylL3VnEql/supiGpf3bSjyu+1np30Lk8wS /eYCMY9X/s2i7+7UctN9E32Vz9UakwCgAoAMigAoAKAPmX9pyf4Yt4W0LS/iR8FdW+Jq3920enaH pGipqUkc4XJcu5VIBj/lozL6VlUp4So1LF1/ZW1T9/mv/dUE5N/cvM1o1MZBSjhKfPdWkm4qNv73 M0reVm79D5p+Gnwr/abPj3wfr3gq11D4S/Ca01KC41Twt4m8Uy+JZtTsVcGS2jtWDRWZdAVDRyEr nI6V0PNJySpUVOtB3TlWjCDXnFpOrJrpzyS7oxeXUov2lV06cltGjz8ra25tYQfnanfz7/phUDCg D51/aR0zWNc8FW+jQ/BDTfil4XupydY8OXl9HazrEo3JLbeYpR5Qw4BZOxDCom8No8TzqzupU9XF rr8UZfOLuuzNKX1jmvh5wT2ane0k+l0pJfNNHy58C/8AhiP4deM7TUIfAd38M/iqS0Vvb/EyG4tr iBnGGS0urh3gOQSMQynIPSuqOEq5rJSp4yWL5dVFzk5R8/ZStNNd+V+pnXx9TBQ5cTh44eMt5RhB Qa8501a3X3mnpqj9KYpYp4o54JUkhcBlkjYMrA9CCOorGUXBuMlZomE41IqUHdPqiSkUeCftE/ET xh8OvAulXHgGz0yTxj4h17TfDmn3WuFvsWnzXk4hE9wFILKueFBG52Vc81pSlCMrzg572inbmfa+ tl1b7J21M6kJTjZT5FpeVr2XVpdX2vpfc8tj+HH7awIc/tG+BEZuW2eBP6/aayWOqJ3jgKK/7fq/ 5mv1PDNWeLxD/wDBH/yo+zaYgoA8I/aK+H3i74l/DaTQPAOpaTpfjK21C01PTdY1hJWTTLi3lEsd wgjZSXVlGA2UILKwZSQZc5U2pwp88lqlzcqb83yyuujVrtPRp6glCSlGpU5Itauyenzas1unfRpM 8b0yf9t/UbTzrD4gfAq/ghfyJbm30vUZB5gwCGK3eA3I446iuypiPZSUauWyjJq9nXtp5J0b2MKd PC1YOdPMG4p2uoQav2upWufbdcpuFAHxN8dtF/Zy8AaJf6D46hmkg+JXjjSpNRsYNfktZ1vryWK0 S7P71Xjt02qzBMLhWOOtdeHoY+rH2kK1WK2jKN9H0hFrZN9NdzmxGNwlOSpVIUZNK8ozUNY9Zyi0 7td2um6PHfif8Gf2GPhb4A8U/EC9nOp2+iWrXR02w8dXb3F4RjEUK/afmkYnCr3JA71qsJnsPer4 vEwgt25Tsl1bvbRephHMMmrtU8Nh8LOo9FFU6TbfbSLf4H6bxuskSSqCAyggMMHB9RXnHoElMAoA KAPlf9rTUfElh4I8BL4X8cf8IffXnjXRrSTxLKqNFp8TzEFpVchGVjtQK/yl3QEEVrRnWhO1CKlN 6KLvaXk7We19E03axlVhSqQbrNqC1bVrrzV00terWm/Q+ZvH3xQ+KXgfQfjJ8Hr74zP4lvbZvBkN p4/gitrK+0uPXNYbT7mBzAFjE8UMLzRuAGUTKTnaDXS54hNTq0Iwq625Yvld9Itxm5aqV9NpWWm5 zr6nK6pVXKl1UppvTWSUlZ2atfrG712t9KfAS21TwP8AEn4z/BQ+LNd8R+FfDNpoesaXf+I757+6 tPt63iy2jXD/ADOqGxWVdxLAXOOm2uWpXq1op4iSlPXXlUbrpdRSV78yvbVJdTpjTo02/q8eWH8q baT62u3a6adu+vU+razNBuM9uD2pbgeZfE+w+I6eEb+T4KxeGLf4gtND5EviWCQ2hi8xfN3+Vh8+ Xuxz1xWVOFHCy9sqCm+yai387P8AIuzxC9nOq4Lulzfg2lqemrnAz1x2rUgdTAKACgAoAKACgAoA KACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAMXw3/yLugf9 eUH/AKLWgDaoAKACgAoAKACgAoAKACgAoAKACgAoA5nxf4v8M+AfDWr+MfGWtW2k+GNLi8+91G7J WO3TIG5iO2SPzq6VKVaahHd92l+LskZ1KipQc5Xsuybf3JNv5I+Ff2gLT4Cy/F628W+LP2vtb+G3 jWLSI7WLS9I1y30/FnIRICVeMsyuVDDcSAc4xk10YfCZq26mClBRejThTle3fm3td2vtd23ZNSvg HH2eKoTm90066t6ezaSv1tq7K+yO1/Zt1H4XXfjjVo/BX7XniH4q6sNKkaTw/q2uwX8drF50ObkR oikMrFE3E8CUjvTxFHNKcL46UHG+nLClF39Ya2tfTb52JpSwMn/stGcJd5SrtW7fvW439Nd+lz7b rjOgKAMGz8S+H9S13XPDFlq1tP4g0eK3nv8AT0fMtpHPvMLOvYP5Um099h9KqVKSgpyWjvb5b/mR GonJwW6t0fXz2fyHSeItCi8Q2vhOTVLdPEdzZyahDpzNiWW2jdI3kVe6q8sakjoXXPUUKlL2bqJe 6nb79tPkwdRc6g93rs/z267bm5UlhQB82fEz9nHTvjB4rk1Tx78QvF9x4FEMcSeBdN1J9P06RlHz PP5O2SbcequxXAxjrTWKx1P3MPV9nHvGKU3/ANvu7S/w2BUcJf2lWipz/vtyiu1ofDfzaZ6T4W+D 3wr8FeHJPCPhX4faBpvhuRCkun29jEI5geu8Y+bPqc1wf2fh5cznDmct3LVv1b1Z1yx2Ik4y52rb W0S9EtEdzpel6dommabouj2MNlpGn28dra2Vsgjjt4UUKkaKOFVVAAA6ACuuEFTiox2WhzTnKpJz k7t6v1ZieN/G3hj4c+E9c8ceM9VXTfC2jw/aL2+eN5BDHkDJVAWPJHQHrW1Km6slBNK/dpL5t2S+ Zm+a3uxcn2Su36I+XfiR8TP2VfA3j3x7F8SPiBDp+s+N/DlppmtaFdx3Mlve2QWfypCixkB2juZU JByV2gj5RhxwU60ZJ1YKMukqlOLT2bXNJS1VvLS6KdedNxccPUlKP2o0qkl3s3GLjo/mrnEfssL8 BdQ+I9/feCv2hfEPxQ8baZoElhpsXiJ5HOhaN58BkjiJhQNukW1DOxaRtiZJwadeOLk41MVWpzto lTdO7vvKShJtvTeyS8myY+xgnGjhalK+rc41UtNoxdRJJa3UU7/JafoLWRQUAfnH+01ov7L2ofFe PUfix8L/AIna742tLKNYdU8K6drE9tFC4+7HJbMEDEAbgOeBmpU405qf9p/V5JW5VOUWl/27F7+p rCGInCUKeXRrwla8nGg722X7ySlp00t2Nf8AZPl/Zml+JHiy2+DHhH4gaT4x0/STHqR8XQ6pFHBb ySwuqFbpyFkcqjLwCVR8HAatp1Z1Iq+ZPEr+VznJK3X3opXV7b312szmVPkm4vL4Ydq2qhRi3fp+ 7k5NO29uW6te6sfoLWZoFAHzD4k+FGh+LfGP7QnhHUPFlg2mfFDwhbWeoaDEQL+xIiubJrsYbPlP FJGq5HDwNgnJxEqdbklJRsn8MvO2qt1S0end33Q41KXOldtrdW0t0d+jeqt1STWzOP8Ag/4P+LM/ xqTxH8avHPgm98T+D/CkmhWOjeEVljnura8uIJGv71JGLJvbT1VFX5AfNwT0GsqtStFTjh/ZQ2b5 +bmktkrRVlFN2Tu/eF7OjR9xVnUlurw5bLrrdqTel2rJWWmp9nVIBQB8B/tNeEfAcfxm8GfEX4vf BrVvH/w7j8M3OjwLpOknV/7LvzcpLumtVO4iSM7UcK2wo2cbs1nKdFv2VfEOjF63vNRl5NwTd1uk 9H6pHRQli6X7zB0+eezScFJLuudxVv5tb7abnzF8OPG2leE/GHwi/wCFnfD7xtY/DzwFB4ztpLXW vDd3eReHIdS1OB9Fgcqj+aV0+GSLdHvEYYIxGaqrVwuZctKtiYT5us3a/J7qc3JLlbV2udrm33Zn ChjMFetRw8k/7ji/i1koqMm2k7J2Wnax+hH7JNjqNh8APBMd/p9zYQTz6nd6bp95E0Mtnpc2o3U1 hC0bAFClnJbJsIyu3HaiNSNRJwd4rRPulon80r36kThKnJqatJ6tdm9Wvk3Y9u8WeGbHxl4a1vwt qc97Bp+qW7W002nXMlrOitwTHKhDo3oykEVSnUh71KTjJbNWuvvuieWE9KkVKPVPZ+TPkq9/YK+C eqXGmXuo678Rbq702Yz2c8/jXVXe1kKlC8ZM2VbazLkdiRTli8znJTeMndbaQ/8AkSlSy+KcVg6d nvo9fxO1+H37I/ws+GvxB074naDqnjK68WWdtJZpPrPii/v43gdXBjeOWRldQXLAEEBgGHIBpSr4 6tJPEYiU1tZqNvwimtbbPW2ug1DCU4ONDDQg31inf8+2noz6joJCgD4Z/a5sfgPquueAdH+IHwU1 P4pfE69huX0Lw1osYeeO3iK+dcO7OkcMStLGpdj95wBns3CCiq1fFTowi1bklO7lZ25Ywd20r66W XUcKtdSdPDUI1JWu3NRSS85STtd9EnfscF+zx4Y/Z60L4uaHYt+zHrPwm+MUVtdXmiHXdssd/EI2 iuPs1xFK8bOsUp3IcMFYkAgEjX27xVNyo4+tVivihUlUTXZuEm01fqm7O17OxVSeJpWhiaFKPNtK nytXWtuZRjJO3dK6ufpHWJAUAfHnx0uPGfjT4naP8ItD+Jmp+BtDTwre+Jp7vQGji1DWpYpkhW3i lcEpHEHDybBuPmx8gZzrCtWpQbwsY8yteUoqaiulov3byfVp2tpuZSp0JyX1m7i9FFScbvrdxak7 LaKavre6Ry3w/wDip4xk8Nf8E8muPEU1/q/xA0CH/hIbeZg8l/GfDzXj3j98pdQwgv0zcEdWFVKp KSnOcVyyfZK0t1btpzaKyt6ImMIKUacZO8Ve12/d217621et/Vn3ZWBuFAHyL8ctO8d+EfiFp3xf 8I/Dq68dabL4Zu/DGoaRpU0UeoafvmWaO5tllZUdWIZJE3K3EZGdpFZupQjNLFXUOklHmUX1vFa2 a6q9rWtrpcadacf9mcebqpPl5l5Ss1dPo9HfdWPDP2edD+LXji0/ZD0HxN8Jda8EeGPgpokB1DVP EUsCzazqSaM+liG2gjZiIR580hkcgnagC8mhYrDVlD6tKUpPWTcXFRVtves3K9tlZJb3sH1atScp YjlS2ilLmb13dlZK19Lt3fY/S2tCAoAKACgAoAKAPiv9rtPB0OsfATWfi7ZPc/AvTdfuZfEAmhaa yt7lrSRbCa+QA5t1mLDJBVZHjLcDNCj7f/ZeflVTTV8vNbXk5tEr+bV7W6lQ56T+s0oOUoa6K7V9 HJLdteSbSba2PH/iP4t/Zr8U+OfgTb/s53/hTU/jbD4v0p7WfwOsUklrpAnUambuSEbVtzZeepEh 5YpgZxi3lTyL984qlze7y3Xv30typ62+K9tLbkxzGpm6dJ804x95txlaFtU+ZpWb+Gy1d7bH6aVA BQB82fHnRvGFvrvwq+KXgzwkni2/8FXt7Jc+F1nSC4vLa5tzC8tq0hCfaIjtIDYBRpFyCwNRKVNW +sRk6fVxV3F9JcvVLVNJ31ur2sNKUvdpTjGo9uZ2TXVXV7X0d7NXVnvc+Pfhfp3xk+JHhHwJ8Hb7 4HeJPCGh6b8SLrxtrPifxPJbQpFap4juNat7e2ijkdpJn3wRMSAq/vCC3GZ+tYScEsNOU6l7fBKK ik7Ntytutkk9XrazL+q4mEubEcsYJdJqUpO2ySVkk923stFrp+qtamYUAGRQB5t4/wDF/i/wreeB IPCvw5vfFNtrWtQabqc9neRW40O0fO+9kD/6xExyi/Mc8U1Uw8L+2lJN6RtHmvLonquVd3rYSp1a n8Pl01fM7aeWju+yPSaQwoAKACgAoAKACgAyPWgD5t/adtPg8fAmna18X/G83g6DSdRjudG8T6de Pa3+n35V0X7IyAuzsjSKYwrBlZgQRmtaFDE1J8+FmoSinq+XlSej5uf3eV9pdbW1sROtSgvZVqbq KenKlJyb3XLye8mt01ZrvY+IPgZF+ytpPjbwJptx+0j4/wDH9/a+IZb7w74f8RWF7FY2+r3tzJIb gxpaxxtKZ7qVw8pIRpCw24yHKjjKlPkr4qg4J83LCVFOTTuk7ScpWe0V1sktEjVRhSk6lHA1Yyat zTVWXKrWdub3Y6fFK12rtt3Z+uNYkhQB8m/tPXfjC5vvg14N0nx/qXgXwT4n12Wx1/xZo5WO5twL aR7a2SdgRB586rH5nXO1AcuK1oVa0JOGGjF1ZfC5RUkrau0Xo5W2Tv1dtDKrCg1z4pv2cd0pON76 K7TUuW+6T6q+lyPw1+zNDoHiLQdd/wCGjPizqf8AZ17DdjTdS8VvPbXflureVNHj542xtZe4JHem 8Vmsk1UqR5Xv+4pLTrqoJr1Wq3RKnlN7U6UVLp+8m9emjm09ejR9bVibhQB88/Gf4tQfCrxb8Hpf EfiWw8OfDnVr6/h1nWtTCrAHS0d7e3aVxti8yTcwYkEmHaD82Dthqbry9hTgpTltd221dtVd+t9L u2l1jWbhH2zb5Y72V99FeybS81bW2ttH8xWvxf8AjbqcnhP9om08aLF8JvFHjzT/AAvoXw8l0yFR qOi3V8lhHqHnlfOE77mvFAO0RAArjJp/WYXlRjSg6UdHPXn5trp83Ly83upW1Wqd2hvCuNpVJTVZ 68u0Ut+Vxavflu273T8kfpHWBqFAHjvxk+M/h/4MaJo1/qekavrmva5fLpmi+HNAtxPe6tdFGk2R KSAAqRu7OxCqqkmtKcaVnUr1FCEd27vySSV22+iRnL2rap0Ic83srpLTVtt6JLueXeD/ANqK8vvF vhzwf8Ufgn4z+HF54iuPsej6jrv2W5sry5KF1t2ngkYRSsA21XADEYBzgGoSwWJTWFrNyV3yzhKD aW7je6dt2rp21towlTxmHtLE048rsrwnzpN7c3uxa10vZq9tdT6zrE0CgDmvFnjDwp4E0K88T+NP EWnaH4etAPO1LVbhLeGMk4ALsQMkkADqTwK1oYeriqnJSjzP+tfJeZlWrQoR5pu33tt9klq35Iyv DnxL+H/i7w74c8XeG/GGl3/hrxBcNaaXqMNwvlX86tIpjiJxucNDKNo5yjelOeGq05yhJaxV3Zp6 aa3V11FCvCcVPVJu2qad9tU0mtdNUvxR3VYmwUAeP/F3SvjRrmnaRpfwc8WaD4aup5mGpa1rOntq EtvBt+X7NDuVDIW7vlQB0NONf2GsaKqN7c0nGK83y6v0TXqHsadbSpVlBL+VK78ryul62Z43p37F /wAONY1C18RfG/Wtc+LXimHLR3Pje58+0tmPX7PYoFgiHptTPvXPiFiMfb61UtFbRppU4r/wH3pf 9vSbNqE6GCd8JSSl/NJuc3/29K9vSNl5aHvHwt+Engj4M6DqPhj4fadPp/h66v5NQGnyXUs8drI6 RoyQB2PlR/ugRGuFBZiBya25600vbVZVGtE5O7S6K71dvO7M5uEpOUIRjfflSim+7S0vtfvY9Mpk ng/7SXhbwb4v+Dvi3SviH4+vfBvghY1uNS16xuI7d4IUbON7qwGW24wN24Lt5xTjSxFeShhWlO6a bSdra310TVr83Te4vbUKC58RHmh1V5K99Le41Jp7OOz2aZ8FeCdX+D3jHXtE8J6N+3P8cbbUNSdL bTP7ckn06HUnPCpDPcWiI7Njgbst2ya61PNJ39ji8PUktWoww8pK2+iV3bra/mYzoYGjrXy+rTi3 ZN1MQo3ey0qNLyvZdD9ba4zcKAPl79rdFl+FVomr/wBpH4enXtN/4S8aSJDMdE84faciP5/K/wBX 5oXnyvM4PSqhWlRkuWp7Ny0Ur25b9b/ZfRS05W73VridP2mvs+fl15bX5rdLdbb8vW1rPY/Pm1+J PwJ0z4OftgfCD4JeJNEl1/xT408n4f8AhrwrKJZZ7qTR9GFtPbxx5KRpeRyO0pwqtFIScg10yw+I wNN16s7Kn1lK7b3UU225OV9Er3v2IVf67V9nCDcprW0Gkl8LctEopJdbNetj9ooRIIYhMQZto3kd Ccc1ybmhLQB8VftbfCL4H+KoPAfinx/8MbbxJ4yuPFGhaVpphSGOe+c3YZLaeZ1bFpgzPKuDlFcD k1hPCwrSc51JRSWtru67JXSu72vo1vfQ6aWOr4eCpU0mm7q7sk/5rrXS10tm7J7k3xL+Df7M/wAB fB+o/GG0/Z18ITxeFGi1C6ls9NgimsrVXXzrmPKHc0SFpNvBOwgEHFZ08tws5qFZy5XpvKSv0unJ K193rZa2exrWzjMJQlyVLvttddUnbe23d6aXufZaOkiJJGcowBBHcGus4dySgAoAKAMDxL4Y8O+M tC1Lwx4r0Wz1bw9qEflXWnX8KyxTrkHDKcg8gH6is6lKNaPJP/L5p9GjSlVnQmqlN2aPBE/Y3/Zf RLCKP4J+GFhtBKI0WzUBvMBDbx/GcE4LZ254xWToSlzXq1Pes5fvJ+9y/C5a68v2e3Q3+vVbxaUf dvb3Y6X3tppfrbfqekfCz4NfDz4NaZq2l/D7Qjp8GqXQvLyWa4luZrmUIsal5ZGZiFRVVRnAAwK2 SqOTnWqyqSfWbcnZbK76I55SjyqFOEYRWyjFRWu7skld9WepVZB+bnjD4c/swWqfEjxp4g+IHxat rTQfEL6Tq5ste8QlYL6TbKUhghJLR4lXDRqUA4zxXRDFZg2oxzJRXnKklH+63JJJ+TdyHhcNLX+z FKX+BtyX8y11Xn3PIRe/sMZH/F2Pjd6YN74w/wDiK39tmH/Q2h/4Nw4vqlH/AKE3/lN//JH7A1wG gUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAB QAUAFAGL4b/5F3QP+vKD/wBFrQBtUAFABQAUAFABQAUAFABQAUAFABQAUAUb/T7DVbK407U7KG70 +4XbLbXMYkSRfRlPB/Gs6tOFeDhUV4voyqdSVKSnB2a6mVf+EvCuqzi61Tw3pl3chQglubSORgo6 DJHQelYVMDhq0uapTTfmjaGLr0o8sJtLyZJpfhfw3ok73WjeH9Osbl08tpbO2SJmTIO0lQDjIBx7 VVHB4ehLmpQUX5IVXFVq65as215s366TAguI2mgmhSV4nkQqJU+8mRjI9xRdrYN9z82/DP7JfxBs PjL8W9YP7YfjOK81HStD8ySyubA6nJFF9tCm9QwbUiBdxCQBn99nOBhxxWap8/LTSlom6UWpW6KP Rq+rW912G8PlXLZwm7dPa1Vy+s+a8r9n8NtNz079m/wn8K9T+IPiX4h6D+0jqvxf8d6NYP4fe51T U7e4Gi2ssySyJHFCiKBJJboTJg58rAPFbYrD5jGUamOcUldJQjGKvo3zcv2l2eq7GNGvgZRdPB05 RvZ3m6km1rbldT7O+sdL9T7drA1CgD48+I37UGl/CrxP8dbLxbqOmRSeFtG0268NeGGdY7/xHc3E cxAgUndL5k4jt1VAdrIxPUY6qNH20HU5f3dPWcu3XXolbbu20c9STpzjBNudTSCto3tvbu/e10Vn oV/g/wCLPj14d+LWh/DD43+KNG8RXnirwldeKozpGmrZf8I/cW1zaQzWfyk+bCfty7Hb5swtknPG TxMcTDmlRVJ393lcnePXm5m/eWl2rJ32Vka+wjRnanVlNW97m5d+jjZKyeujvto9z7LrIsr3FvBd wSW11bxzW8g2vFKoZXHoQeDUVKcasXGaun0KjKUGpRdmj4d8a/tM+AvhR+0f4v8AAHxs8S6LZ+Ed Q0TTr3w2405pnspkEwvI7uRUZgXzbvF/CQHHBHNrB4XGrknCnGa6ylFOaf8AikkuW2zte91fW0p4 ulerRjVnB78sJtRf/bsfe5utnK1tVG937d8Lfj38Avilr97oHwq8X6Tq2v29m15Pb2FpLC6W6uiM xZo1GN8kYxnPI4oeXUsH79P2d3p7k4Sf3Rk3bz228hfWK1b3asKkV/fp1Ir75xSv5bnvlAwoA+c/ iT8Wfi94Q8Ty6N4N/Zx1nxnoiwxyLrdlrdlZxu7D5k8uX5sr696Xt8BT0xDqc392kpL7+eP5B9Xx dTWjKkl/fnKL+5U5K3z+RwfwqsfjN45+PF18YfHXwzj+HXhiz8Ly+H00eXVIr+81u4kuoZ0nn8oB FSBYpVj5Lf6TJ0BxUxr4eUnHBwnyvWUpxULtbJRTk9E3dt66LoW6FSnFPE1ISktlByaSe95SjG92 lZJdGfZFWQFAHxV401H4hfBH44+P/ifp3wi1jx94L8b6Xpds9x4WeF9R0aeyE6eS0MroHt3EwkBV sq5kyDkGlCvhYyccZKULfDLlco26pqOqd9b2aflYp0cRUgnheWX80ZS5XfpJNqz00adrWut2SfCq X4i/Ff4/H43658MNV+H/AIK0jwnceG7Sy8QyRDUdcnnu7e482WKJmWOKEW7KgZixM7ngdU8Rh5y5 MHKU4vWUnFxTa2UVLV2u7tpb2BUa1OF8VyqV/djGXNZdW2klrZWSvtqfaNUSFAHyl8YvG3xnv/it 4S+C/wAGdT8OeH9QvtCuvEd/4k8SWb3wEEM8UAgtrdXTe+6YM7E4VSvdhVxrQowclQ9rLs5OMUu7 tq29klbZ3M3R9tNKdV04f3VFyb7LmTSstXozT8AeDP2otO8WaXe/Ez4xeDtf8FJ5v23SdM8LGynu cxuI9sxmYLtkKMflOQpHfNZyxUq6cJ4SnBPqpTbXyk7Ptr08zVYahS9+niKsmuklS5fnywUvua13 0PpcDGMDAA4AoSS0QtWPpgfL3xp8ffFseL7H4Y/Bg6Bp+uroU/iPVfEPiSCS6is7VJBFFFDAjJvl kk38s21VjPBLDGka1OhHmdL2km9FzcsUurk0m/JJWvq76ax7J15csqrpxtuknJvsr6JLq2n00Mrw Z8d/E+peGv2LNZ1qzsXPxf0qH+1fJRka2vZNEbU1eEZwI8286FTk/vEweDlylTk5tRtfVa7a7a+X XyJUZpRXNdrfbXTf1vbay1fkfW1ZGpSv9QsdLsrnUdSvYLTT7dDJNdXUixRxIOSzMxAUD1NVThKr JQgm29kt2ROcaUXObSS1beiR8ufF/T/iV4N+K/hn43fDTwVB43jTw/P4e1nwvFeR2l99nNwlxFc2 kknyEq4dXjbAYOhyCoqPaUqUubExl7P+aK5nF+cbq6a3s7qy0ZpySqr2dCcY1N7TbSkvVJtNPZ2a 1exxvh+f4y/Hn4vfCTxj4s+Dd78N/AHw8ub7VlOvX9vcahq99PZTWSRJHCWWOBUupXYlssyoAOtK eJwlWUY4Pnl3lKHIkv5Um2227NvRKwU8PXpwcsXKCfSEJOet95StFLTZK++r6H3FVCCgD5D+Ounf DH4kfFLwF8Fvi14K/wCJTqmkXuq6J40OoPYyQajFLFE1hbSptdZ3hleXAcblhb5WwcXTpym3LC1J wrxV/c09z7V31V7XjZrW7JlXjQj/ALQoSoysnGaUlzbq6ei62ffRM6n4L/sv/A/4GX0epfD/AEWV tdSyXTINS1XUZtRubazXGLeF5XYxxfIvyJgfKPSsfZYmXLLE1Z1ORWjzPSK20Vkl22HHGYZqVLDR pw5ndqCScn3k95Prqz6TqxhQB8efHKf4n+KfjD8P/hN4a+Kd38OPCGr6Hf6i2vaZaQS3er38UsSi yhkmVkjKRO0xAG9gCRwjEa0sRVpxlHDU4SqbtzXMlHa6jdX1tdu6WncyqUKM0p4qUlT2tGXJ7z1V 5LVaJ2Wl3fyNv4b/AAG+I3grxno/iXXv2o/Hvi/SbTzvN8O62tiLa83xOi7/AC4Vb5GYOMEcoM8Z FS8ZmFVctdUuV78tJRfyd9Nfw0Jhh8upvmoOpz9OatKS/wDAW7PT7tz6oqDcKACgAoAKACgDxz4h +O00Hxt8KfAd5Z6Y+keMZ9QivbjViPLWK2tWl8uMEgNK7lcA5GxJDjiqVCGKhKlKm5trRfm2rO66 W01ad9LGU60sM41edQinq336JO6s+t9drW1uvj/wz8XvEOh+IYvin4H+HHgTT/2b9T8bW/gi2m0+ yaHV9UM16mnDUo5VIjMH2x8Km0lolLhskCs6WFy/CVJUaWHtNJp1LrSVr8vLy3sn7rfNfm6WRtUr 4zFUo1qmIbT1UGtHHo+a/wATXvLS1rLfU/SOqEFAHzr+0doHwR1fwppmpfGzxenhbT9KuGuNO15N bfR7i0uCuCYJUdWL7f4RnPpXRhaOOrTbwE5Qkt3Ha39+/uuP+LQyrV8LSSjiqcZqWyceZt/3Uvev /h1Pj/4VfFz44TfEjwZ4b+CuveK/i58FbjU4bfWfEvj3QRpo0mxLASS2uoHypLtlXJAaF9xH36VX H0Y/ucU6dWq9E6N00+87XpWXXlaZpHL5te1pQnQiteWrJNSXVRi71U+3M7LtY/UqsBhQB+fXx78d /tV6V8f/AIL6f8O/hPDqHgi31XUtksXiGS3g12M6TOdt+qwMtukcp3IWL7pI0AwWGNI4/CUF7KcZ 3lvZQd7arkvJO663tpffrP1CvXvVjOGm11L3b6e93vsrd0dPqN9+2J8R9X8D6HqHw28OfD/w9aeI dO1TVdfsPFUl/O9lbTpNNbRwrBHu89UMR3Nt2u2QaHj8PFWwtGrzPS81BRSe7dpSbdttN7O4LA1G 74mtTcVraKlzNrbV2S13fbS2p9vVmUFABQAUAFABQAUAVLy4NnaXV2IJJvJjaTyoVy8mBnao7k4w KWnXYWr23PzQ+LPxp17xr4w+DHjfTf2U/izfXXgfWZ7uTS9X0WzENxb3Ns9tI6H7S22eLesiEgg7 WXjduBWqZTJKNTFqcHulTrb9HZ00mk9121WqSNqeGzKClKNKMZW0ftYfNP1X426XPoDwz+0iNd8R 6Bog/Zj+Kulf2hewWv8Aamo6HZRW9l5jhfOldbglY0zuYgEgA4B6VKpZOtaWIg5dF7Oqm30SbppL 1bSXVol08z3qU0o9f3sXp10vr6dT66qyAoA+HfjV4q+CXxU+G/hTXviv8DfHniXw++r3ltaaInh+ ea6tZ7eRommlgRwVjby8o5zkEEYzSnLCtW+vKnHT3oyqRTa1t7sb+6+6tdaGlOGMpy93Cqc+zdJ2 T63nJLVdnfXU8O+HWjfsfR/EDwPJ4Y/ZW+JGkeJU1izbT9Vv/C97BBY3ImQxTSyNIQiI4VixGAFJ rR4yE/dWcynf7PtK75v7tnCzvtZu3fQuX163v5eorq/9n08/dqOWm+ib7K5+qdQYBQB4n8bIvijd aFpll8MvAfg/xXJNOft9j4yvJLaBIwMoybY33Nu7ECsqv1Zx5cVQlVT6RcVbzfMn+BdJVua9HEKi 11cJSv5WjKNvvfofOV98SP2lPDvjH4Q6R8WPgv8ADLT/AATqfiC10+LXLDWLi5XSLhvkj2q0KhJX VnjiPQyMqErvFXGpga6jQhhKkZLWN5wsrLfSP2Vd20uk7O9iZUsVh26v1yE4vSVqU03d+dV6N6N6 2bTcWr2++aoQUAfNnx88MfEFtW+F3xW+GOgWXiLxP4FvruSXwze3Atjqlld25gmWCYgrHOuI3UsM EKynAbNQ6kKclKtFyh15dZLtJJtXts1daN21KjB1YuEJqE+jlflfdO12k+6Ts0tDxXW9b+Of7SOs fD/whqXwB1X4d+B9G8T6X4i1jX/E+pWs08i6fcpdxwWkMBbLSSwxqzsQAhbgmnUxWCmlHB88533l DkjFdXq222rpJLrqxU8NiYXli5U4x1sozc3Lt9mKir663emyPv2qEFAHyb+0zZQ2Wr/Br4g+IvBl 94r+HXhPVru51nSdOtDfSWzS2rxW979lGTMIXLAqoLATFwCVxWc3RlH2OInyU57t35brVKVtot+T V7XstVdJV1L2mFjzVFsrpOz35b2XN81dXS8/jX4VeOrT4ofD34Y/BP4d+E/Ex8R2fxWu/Fd5qVzo dzp9loWlQ+KbrVRI80qIN8tqY41iTLZnwwADVXtMLRhF0a8JSvyxjCXM/wCVt20UUr7vVWSWoOji qkpOtRlGG7lKyu90km7t81ullZu5+vlUQFAHifxm+NWnfB+08LwJ4W1rxT4w8TXrWGieGfD8aNc3 0qRtLI252VI40jUszscDj1rSHsVF1MRU5ILrZybb2SitW38tFe5ElWm1ToQUpPu+VK27bd7L5N+R 514b+P3xg1vxDoOj6p+yV430bTb68htrjV7zVNNeKwidwrTOqyliqKSxCgkgcVH1vLJaU6lRye16 TSv0u+bRefQv6pmEPen7G3W1WTdvJeyV32V1fuj6xpAFAHzH+1b4e1XW/hxoOp6d4Tn8U2PhnxPp PiHU/DFqA0uq2VrOHljjQ8SOnEyxnhzCF71nOdNR5azapy0k7Xsn1aWtv5rfZuXSjOUk6Vudaxu7 a9rvZvo3s7HzP8c/2gPhx8fvhf4g+Dfwl8F+LNY+J/iKOOx0mGfwveaevh67LKY72e4mjRYBbsPN 3KxOY8L1qqlLL8Ko14V6UpR1goNSk5dEkldefNZJXv2Cmswqt050Jwi9JOdlFR69XzeSV7v7z9L4 VdYolkffIFAZ+m49zVXvqQS0AfCnxX/aC/aU+GdhrGs6j+zj4dv/AA0uoJpun+V4vLXWqvNMIbeO O3+yn95KXQbN2Bk5OATW0a+XTi41adWyT5m1T5bLf7d2u2l3orXM5YfGRadOvTu2rK076/ctOrvZ as4bW/ib8cPhJbweOdT/AGNvAeh2dzdwW15rdl4njB0/zmCLLcslnuSIMyh3GQucn5QWHLhqGSKq vZYerGT292mrvovj0b2V7a6X1Our/alSnL2uLpuKV38b0W7s7Xtu+tuh+klaGAUAeO/HXwR4S8e/ DnU9N8Y+KZPDFhp89vq1t4ogu0tJNEu7eRZIbpJX+VSjqPvcEEqcg0QpYitOKwv8S91pzfJx6prR rsKVWhShJ4lJ02rO7tv2e6d9ra3Pz61G98K/EKN/B/xq/wCCivhHxP8ACyaSM3vh3TU0nTJdYhRg xgubiNtzRMVAcIF3DI6GvUrYLOq0JU1hKdK+jlHncrPeynNqLfe110OanicopyjKm605LZTbcb9L pQTlbezb1Wp+soAVQqjCgYAFeWdQ6gAoAKAPnP8Aaf8AFHjfwr8NbGTwJrkegX+ra9pej3niiS2F yPD9lc3CxTXmxgV+QMBuf5V37m4U1dKp7Oa5YKUnpFS+Fye19VfyXV2XUipTVWD5pNRWsrb8q3t2 03fRXfQ8/T9mD4msEZv2yPiu2QCSracA30/0ek8fmfel/wCCYjWFypq6pVH/ANzFb/5M+zKkoKAP E/jl8QNY+G/hDT7rwf4VtNe8beIdYtNE0jS72b7NbzXdwxAeeQAkRoiSOxAyQmByaUI4ePNKtFuO 9opXk+iV9L+b2Wope2naNKSi+7u0l3smm/RNXZ8V6n8dv2wNHsfi7rWpeEvg/Fonw11mDTPEE6Jq Dm3gezs72W6QeYN8cMF8rMOCfKfHYVrGpl0nCP1Cd5afxYWTvZX/AHW2130vtoKVGvGM2sZ8Ov8A DeqSu7e+9d7Lrprqfp6rq6K6nKkZBHcVmNMfQMKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAC gAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAMXw3/yLugf9eUH/AKLWgDaoAKACgAoAKACg AoAKACgAoAKACgAoAKAPhvx1oHjT4rftEeLfAOtfGfxR4C8IaJoWn32g6V4Uul0+XXjK0wurl5yp aTyXSKMxqfk3KzffFb08Ri4wccEorl+JuEZvX4dJJpR0eqWrv2MZxwUJc+N97m+Fc7jFW30i03LV b9Nup7H8Kfgm/wANvEN5rj/Gbx94uE9m1qNO8Va0b63i3PG/mqmBiQeXtDejsO9RPEY6qrYmUXHy pQhr6xin30269Bwll7f+ywSl5TlLT0cmu2tj6BrM1CgD4X+OHwz+Mcnif4mjwH4l8KaP4K+Kmn2O k6z4i1m7kttQ8PLFHJbytZgfLKXgk+QErskLNznFXQqV1Jqjh5VKlvdaatH/ABRs20n7ytvsya31 VRi8TiFTh1i18X+GXMkrrR3T02PSvDXwRt/Bvxz8G+I/Bmh6Xonw98N+Abjw0IbLEct9LLd2rwq8 agfLDHZyYckkm4YDGDnkoU44a9OnFpS1k+ja263ctW27dtXc3q1niZc9Wd5LZdUnv6LRJW7PsfT1 dBkVbu8tLC1uL6/uobaygQyS3Fw4jSJRyWZjwAB3NVCEqslCCu30W5E5xpxc5uyW7eh8RfEH9p/9 nO/8Q2lz4T8HXHxd+Ieglzanwdo66l/Z7AbiTfsBBEB14kJHpmjFZZg6NRTzKpCnNdH70/8AwCN3 /wCBWReHxePq0pRwNOTg+r9yH/gUrX/7dTOg/Zz8XfFb4y61YfHjxR8OPCPhXwB4j8MQ/wBiG3uH vtcu4JXjuLc3E+1USEI8zeUoJ3OCTxRVqYadVxoUp+7dc8mlfyjBXsnu23fRIcI14UV7WunfXkjF 2Wm7k3dyW1kkj7HqRBQB8xfFPTf2g9M8WTeKfh1o3gTxd4PaCNZfCviGJrG9RlB3tDfAOpz2WSMg eorKSwjlbFYTnX88WudesZK0kulnF+ZajUcealinTa6SV4ffFqUX3fvLyPLPB37cf7P8HivUfAvj 61T4b/EKwVUvrPVBbzWsW4jGb62LxKpP/PQxnpkDIrupZPh04ywllKW0ZR9lUa/wytf/ALdcrnJL HYiSk6qc4R3nBupT+9K687xVu59yWN9Z6nZWepaddw3WnXcSTwXVtIJI542AZXRhwykEEEcEGsJw lTk4TVmtGuzNYTjUipRd09V6FypLPiTxD8ZvCvwZ/aT+Id58bvFN54f8LaxoOkx+FNS1IS/2SY4z cG8iDqCiXJmZGbdgsnl4ztNdFDnxn+zQqRTjryuSje/2lzNc1rW3vHtqY1YrDR+sulKSejlGLly2 +y+VNpdb2s310HfDP4u6F8YP2n9R1n4O+ILvXfhbaeDHtvEGrQCX+zJNVF5EbJLdmAV5lhN75hTI 2mME5Aqa7lhn9VnNSb97lUlLk6bptLm7b+7cdKn7WKxapuCeicouLn12aUmo23at72h9s1ianG+P vDur+LvBuv8AhvQPFl/4Y1i/g8q31/TFRriwbIO+MOCucAjkd6FUqUnz0rcy25lzL5rqJwp1fdq3 5Xvyvlfya2PmP472Q0PX7DVdd/bPvfhdYXdrHDb6PNLpUSXDxjDzL9pjLkscFsHAPpXbhYZrWi/q lGnKK6ypt6+t0vRHNWlltNr6y583aM5LT0Sf39R37O+qaHfeNNUi039spvi1ONLkY+HGn0yT7Kvm wj7Vi2RX+UkR5J2/vvXFPF0czpwTxtGEI30cYcrv2vzPS19AoVMvnK2E9pzf3pTat6SSV9vP8T7M rhOooajqFlpOn32raldR2+m2cL3FxcSnCxRIpZmJ9AASfpTjFzait2JvlV+x8K/tC3nwH8f3vwj+ IGuftVXnw+RbF9T8O3uiarBY/wBowTLtM6tIhZkZGAI6H5cjIFdNPB5n7RvBOCcbqV4wlfy956rR O2qur7oxeKwLppYqlKalZqzqxt52ha0vN+8k2tmyt8ENQ+FU/wAUPDUXhz9uPxF8QtaYXHkeEL/X 7W6i1D/R5d26JIwzbF3SjB4MYPatK9DOIQcsU6fs+vLTpRflZx95a9vR6EUqmWyklh6NSM+jlOu1 81N8v39dtbH6BVwnUFAHyJ+1Lo/wytbfw7438V/G9vhR4vtYrjTNO8TW91Cj3dvNsaa1eCUMs8ZK RvtKnaVBBFbYahjZylUwfLZK0lNJwa6Xu1Zro009+lzKrWwkVGliYyld3jyc3On1a5E213TTT0v0 PAP2WtP/AGf7Lxn8MtDtv2qz8UvGPhXR30TwboUzxQw6RbR2uyRoIIkUNL9mhKGVyW2Bhnk5dXDY 904PFSpKMLaU3DV2tzS96UpOzemyu3YcKuGjKXsKNVOe8qkKtkt7JyhGEVdeTbsuyP06rA0PN/i7 8ONN+MHwv8d/C/V724stO8T6ZPpst5aEeZb+YpAdc8ZU4ODwcYqJ86i/ZStLo/6/EqHJzL2ivHqj 4cuPgp+2+vx60TxlB8afCVza2fhC90hfENx4a2xjzL20lEElqsw3SsId/mjAUIy4+ar/ALVrp+z+ qQtvZTqcj897qWtktrNh9QwvLzfWaqXpTc/T+Hbl7t+9e3S59J/D7wl+1Ppni7Sr74kfGHwdrfgu Lzftml6V4ZeyuJ8xOI9sxmbbiQox4OQpHfNN4ypV9yWFhC/2lOba9E3by1J+qYel79PEVZPtJUlF +vLBP7nv5H0xSAKAPiD9q60/Ztvdd8IL8dfhV4l8W6jHbSSadPomh3upJaqHw25oOEfJ784pP2d0 5472DTulzzjd9/dT22uzWl9Z1+r4T23d2pu3l78o+uh5d+z/ACfsYD41eGtM+FXwj8U6D8Uobe5u 7O41fQtQshbQGGVJJGMxwEZS8YYjG5wvUit5VnOH/I0dZbcvtKkk+uqatpurtbaaoidTE83s62B9 lpfm5aK08nGTb1snyp2vrZO5+mFYkhQB+cn7W6fBa++OXwb0z9pPxpBY/CiXSL9tN0qXVGsol1sS JsuLgIwYp9n89Ec/KrbgeXWuihSxmI9zCzdNp35otRbe3LzPVaO9l8WvaxEqtHD/AL2pTVR7WcXN JPW/LZp3as+q00tdrd+CXhv9hCw+Jvhm7+DHi/w/ffEpPtH9m21l4hmu5XzbyiXbE0hDYhMpORwA T2revhc3p03LFYmrOn1UqvMn2ur666+upEMbhaz5KeHjF91R5Wv+3uVW7b67dT7+rgNgoAMigAoA KAKt5O9raXVzFbPcSQxs6wRY3SkDIUZ4ycY/GldLV7Bq9tz4G+InxQuvi1oK+GPiL+wt8RNe0NZl uUtb9dMcRyqCA6n7TlWwzDI7EjvVSq5VJxnHFzjJbONOpFro9Vrqi6VLNKd7UqTT3TqxafqnGxr6 D47bxDN8L/AF3+xl480Pwjoer2EmmNONOjsdEeJtkVw0cdwTsh3mTAUkFcgEgVmllXs1So4ifkvZ zV3e6Um+jerv11Y3HMnOVatTpu97v2ibXdpcu9rpWt26n3ZVmYUAfMf7RepWyXPw00DRvhdofjj4 n6tqFwPDtp4iKx2emeVD5lxdyyFWKqiBVwo3M0igYySM6lHDVIc+LjKcVtGL1k3stdElq22nbs2z SlVxMJcuGqKm2tZNN2XorNt6aJq/fQ5nwb+0J4ij+Cnw4+IXi/wvpVtqWo+OG8E6vZ6K7i3s3/ty 40ZZoN3JXzo4GIP8Lt6CuiCwydqUHCLWiunZ2vq0knqraJbp9Dnar296alJPV2aur9Fd2dtdW9mu p9hVmaBQB8v/ALRXiP4lwat8Hvh78N/FNt4Sn8baxcWN54vubNLs6fHDayXCwwxyfJ50xjKqXBHy tgE4FXTrKk3yU4zqfZUr8qtu2k03ZdE/N6JkTpxqK9Wco0+vLo23oldp8qb697LqUvDnwS+PGk+I NC1XWf2sPEmsaRZ3kNxdaTPoOlxJfwo4Z4WdIQyq6gqSpBAPBBpvH4ua5ZUaKT6qM7/K83r20GsH goe9GVW62vUur+atqvI+razKCgAoAKACgAoAKACgD8+/j18Yv2j/AAz8ffg14f8AAnwV1XU/Bw1X UUaS01yKGDxPH/ZMzhJgYz9nEUuHUuTuaIAcsKuONwVFeyqud5b/ALuL21Xs25pyf83w2V9+qeBx FZqrCULLb3pK3T37RtbtvrbY6XUPGv7WPxH1bwR4fs/ggfh5pkXiDTr/AFbxJceKIbzGnQTpJc26 wRxguZo1aLBOBvJ7Ch47Bw/3WNWUnp79OMYpPdt88tUtrK97ajeCrPWvVp8q19xzcm1qlrGK33u9 rn2/UANd0jR5JHVY1GWZjgAepNNJt2Qm0ldnG/8ACxPh9/0Pfh7/AMGlv/8AF12f2Vjf+gef/gL/ AMjz/wC2Mve2Jh/4HH/MntvHfga8uILSz8Z6FPdTOI4oYdRgd5HJwFVQ2SSeABUzyzGU4ucqEklq 3ytWXnoVDNMDVkoQrwbeiSlF3f3nW1yHeFAHjfxj0v4naholhcfDX4o6P4HezkeXUNR1nS47+KSH bgD53UR4PO7NXSnXjJRoUI1ZPpJz/DkabZnVWH5HLE1pU4rrFwX388ZK33HzT4b+GPjz4x+IPCz/ ABC/at8PeOvBvhfWLTXW8OeDdNs7UXV5aTCW3+0yxyO/lpMiPsGMlBmtcXDMqcVGvg4UItq7SqXf Wyc20r9WtbaEYatlc5Xw+InWmk7KUqdldWvaEIt73V9NmffVc5uFAH58/HvS/wBsC/8Aj98GNU+G 2keDpvBGkarqUtnPdPeBY0k0maNv7TCOAUMjsI9g+/5ee9Usyp4dexdCb5t7TSU7apfA+S2/vN3t ZatB9QjX/euslbvBNw6XXvJyvtpayfkdPf8Agj9r/wCJGreCNM+Ies/DrQPBuk+INO129ufCa3zX 1ytnOk4t0Mr7VWQoEckH5CwxzQ8w0thcLKnJ6OUqqkrPfSMI3utNXYPqVJe9VxHtEteX2fLd9NXK Wzs9Efb9SAUAfnf8dr79tf4WeB/it8VdP+Lvw+uPC3hqyv8AWLfR5PC8nnvaxB5EhMvnY37AFLbc Z5xWkMe+ZQngYOPf2k72722+RhUwCknKGNqJ9FyU7Lyva9j0DwL4T/bQ/tbwnq/iX4xfDu58JyXF tdalp9h4UkgnuLUsrSxxyecQrlNyhiDgkHFZrGbxjgKcL9VUndedno7b2ZosEk1KWNqyt0cKdn5N pXSflqfaFBYUAfMf7Rvgj4teJJfhh4p+Cdn4dPj7wnq73sV34jupoYUt5IWhnhKxqfMWWN2Ug42k IwOVFZussPNVPZOp0smlo/VPXazWz3urp3GjGvFwlV9mt78rk7ra3vR+d73Teidmszw3rX7aU3iH QovFfgn4VW/hd7yEalPp2qX8lxFalx5rRKyBTIE3bQTjOM1p9dw8/dWDqRb6urBpebSgm7dUmrkf U6kPe+uRlboqMlfyv7V2v3s7dmfV9ABQB+fHxu1L9sf4cWZ1rQ/i/wCCLxtc1620Xw/oD+FWEk01 3PsgiknM+AEQlnfb92NiATgVpTx0lfnwdNxit+epd9tL2u38l6IieCozS5cVVjJ+VLlX/kl7Lor3 eivd3M/4myfto/CPwdefEbWvjJ8P7rw3pDR3GuvZeEWjlsrHIE9wmZj5nlAlynBKq2DnAOdPFvnS WApRcna/PUdm9r6rTu+m9mOrhKfJeOMrO2rTVJXS3Uf3bs+17320vdfomjLIiSI2UYZBHcUDRJQM 8Q+Ofw5uPiv4Mg0vw54ti0HxjoGr2euaNrDRpcR2WoWriSMTRE4dGBZWQ4O1zjBxSnGvT5Z04Xe9 pXtJdtNbea2evQhVsM1KNado7Npq8X5X0uuz3Wj0Z83eMPh3+118afDup/Cz4neLvhjoPw41lPse t6l4Vt7uXUL+yOPNiiE0hSEyLuUt8xUNxWtXEyqQccPgnCb+1KpzKPmoqEW2ul2TD6lTalUx3Ol9 lRjG/k5cz02vZK60PvyNFijjjTOxFCgH0FZGpJTA+c/2lvBV1468HeDtOHhx/EOh2fi/Rb7WNBQK ft9glyol3KxAdYy6TlD94QEc5xWdSSjFxk2oy0bV72fprZuydujZdKMnJShbmjqr9166Xte3nY+K fjR8OE8Gav8AHzwF4a/Z9vda8T+P9TsNd+H/AIi0TR7d7HRb6OwsrVFuJiR9nWC5sTcNkbXSUjkk iuaNPLqPvVWozh8MbSbmt7Kyas23GSbWjvszr58wrL90705fE3JLle12m7uys4uKbvp0P1dj3+VG JSDLtG4r0zjnFdlzhJaYBQAUAeA/tL2vwdvfhFr8Px2uriH4cNJCl1HazXEcl1I7iOOFVg/eSM7u FCLndnpTjRqV7wp1fZ95cyjZLe7eyF7VUZRm6SqO+kXFTu+lk9L/AJH5pRah+wBFLLZxeE/jIv2S 9h0yRWi19FhuZBGYoG3SDa7iWIqhwSJEwPmFb+3rpJf249VdfvJu6V72tDXZ7djOVK7k5ZLDR2b9 nh93Z6+/5rXZdT9q65zUKAPI/jVY+ALjwOdX+JPiVPD3hzw9qNjri669yLb7BcWtwksTbz6soQrz uVyuDuxVUqFbETjHD/Fv0263vpa1029tyJ16WHi5VleO1tfla2t72atqfnZ8Vvif+xV8T/F+v6pJ +1HreieHvE6wW3izwtosF0tj4nWFRGonzbllLRKsTtGw3xqqnIArp+o42EJ0qOIoqE97zouSurPl k53i2lbrbdamkY+05atXA1pSjs+Sqlbdc0UkpJN3V15PTQ/WxUWNFRFCoowFHQCuQQ+gAoAKACgA oAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAxfDf /Iu6B/15Qf8AotaANqgAoAKACgAoAKACgAoAKACgAoAKACgAoA/Nz9rC7/Y603x7qWrfGL4aa94v 8daToq6jqU3h+wuLs6Ppo37ZLiRXVIlIic4zkhCcdK1p0mpwnLHvDt3UUpzjfa9lBOyva7dlcca1 VKSo4VVEtZScYWXVJuTTbtskmbv7Kjfs4R/FDxLpvwl+CPjHwV42tdCE17deJrCS1VrKaePai75n yXeIEYH/ACxbkYwXUq+1hdZjLEq/wuVSVvO04pLsuurtpcdSVdNRrYWNLrdKGvleL18+2l+h+g1Y khQB+Q37c8Xw3luv2k5fjRdCPxDb+AxJ8NF1aV47TzfInNwbTnYb37SE3A/Ps8nGRmtqbr4iLhRq uKp+84qXK315mtHJK1uvLZ7X1XMsP7zp39ppzcvNbpy3s+W979L330Pqzwf8SPDPxW/aut9Z+FPi OHX/AAdofgW8sPEeraXIZrE3kt9aSWEIlHyPKsaX7EKTtWTn7wFPEQqYSX1aq/eevLdNxtpdpbXv s97eSIpS+sQ9vFNRWibTV772uldKyu9le3c+zawNDkPHngnw/wDEjwZ4l8B+K7WS48N69ZyWF7BD K0LPC42sA6kFTjuKmSk01CTi+63RUJKElJpPyeqfqj5ItPgD8dPg14fn0D4DfEfSNa8HJbNbweEv HlguY0K7Qsd/AFlzjvKJKijW+rp+1w0Kn96H7ub9d4P/AMBTfcqdKlXs4Vp032b9pD7pPmXpGSXk b/7Jev8Ajzwx4O8C/s+/Ef4S674b8ReCfC1pZLr/AJkV3pWrJaJBbFobhCCrsWDCN1BwG5O2tI18 LWgvZTaqdYSi4td2nrFpPS977aEToYilJuai4dJRlf5OLSadvVab6pH2PTEc/wCJ/E2h+DfDmu+L fE+pRad4d0a0lvr6+nzst4I1Lu5xzgKCcDn0qqdOVWahDd/1u9iKk1Ti5vZHx/8AtE+FPhzqui3X xm+NHxg8YWvwTSytGg8F6TcS2FvevIAEV44gs88szOqiJj7YHNa0KmOk3Sw1eNKCu3NJKVurdR3a Xbls/Vk1I4WlapWw7qVb2UZXkr9EoX5ebzd/Wxq/s5a9+zL460PxF8Pfhv8ADAeGpNNgjk1Pwl4l 8Pf2ddvbylhHM8cgJljcow35PIwcGuGplmCqRdeFSNdSdnNNyd97NySkn1XfodssdjoVFTrxlSkl dLS1tvd5W46bNbrqfXOk6TpuhaVpmiaNYw2Wj6dbx2lpZ2yBI7eGNQiIijgKqgADsBWkIqEVFbLQ xnOVSTnJ3b1fzNKrJMvUtJ0fW4DZaxptnfW33vIu4lmX67WBrGthqWJjatBSXmiqWInRl+6naXk7 MqaD/wAIzFbT2Phj+zEtLWQxS2+lmMLBIOqsqcK3sea0jgfqUVFU+RPVaWv5+ZmsbHGyclVU2t9b 29exv1RQUAfmz8SvFfwg+G/7V/jjWPi14F1bxTF4g8OaYmn6nB4Yu9Xj0E25lEltlY2ULN5qSgpk 7kcPj5aznRwuMtTxleEeX4VKdlrvp0e2r3T02ZtTnjcOufB0ZyUvicUr3W2rauraW0s+99PoD4If FP4C+OPFOoaV8LPBV9o+vxae9zNc3PhK50dWtxJErJ50kSBjveM7M5O0nHymlHA4HDPnw1WnKW1o Su7d7dtvwCpicwrK2KpVIx7yta/yb13PqatTEgmhiuIZYJ4kkglUo8cg3K6kYIIPUEVMoqacZbMc W4tNbnyP8afFmp6X4z8F/B74U/BDw54v8ZSaNNqv/E/kjstP0TTYpUhUbvLdizyMFVEAA2kmsnhc uhTTxNJztpGMUr27tvRJeju/Q0jXx06jVGuqaerlLmd32UYtNvvqrCfC3Tvj1B460SXxr8Bfhb4b 8NKJvtOs+G9See9t/wBy4Ty0MC53PtVvmGFZuvSopwy1STw+DnTn0lKUGl6pK+q0+ZdR4zlaq46N SP8AKqc4t/NzklbfZn2BXUc5zfi3xLa+D/DOt+KL2x1C9tNMt2uZLTSrZrm5mCjO2KIcux7AUJwW tSajHq3ey83ZN/cmFpy0px5pdErJvy1aX3tI/NHxn8ffA2u/H34efFO8+BfxO17Q7LQr7QLi01Hw VcM2kySyxTpdwq2VJby3icYDYZCDgEHKtPKq9qNfGU5Q3Xx2UtveXJqmtnrZ9NbrajRzWmnUo4WU ZdffpJuPZNVN09bOya66K/098Mfjx8LvGnjfRvDfhr4OeNND1i8E3k6rq3g59Ot4NkTu2+cj5Nyq VHqWA71nDDZTTlzYWvSlUWyip387Xglt57DqVM1lG2Jo1Iw6uU6bXldRqSe/ZPU+tK6TA5vxb4ms PBvhnW/FeqW97Pp2lW73M0OnWz3M7qoyRHEgLO3oo5NCcE/fkoru9l5sLTlpTi5S6JWu/JXaX3tH yRd/t8/BHT7nTbG/0L4iW97qMjRWdvP4Ov0e6dVLMsalMuQoJIGcAZrdLAyi5LG0rLfWX/yJnKnm MJKLwNS721pv/wByaLzeh3Hw7/a4+FvxN8e6f8NtA0vxja+Kry3ku1g1rw7dWCJAisxkdpFAVCUK huhYqvUipksK481LFQm9rRcm/wD0lLa71auk7BbFwqclfDTp6XvJwtbbpNt62Widrq9lqfUdZGgU AeGfFf4l/EfwLqGk2ngf4F6x48tLqFpJ7vTNTtbNbNw2AjCY5Ykc5FL2uCp/70536ctPn+/3o2D2 OJq60HTt155uP3WhK/4HiGiT/HP4vfG74S+MNe+C8vw28KeCW1Ge/wBQ1PVoLu71lLi0eBbJI4Rg Q+a8c7Fz963TAzzULEYNy/2KM25K0nOCglHey96TbbS7WV+5f1avCN8VOnprGMJSk+ba7bjGys3p bXQ+4q0ICgDn9X8LeGtfkhm13w9p2oyxKUR761SYopOcAsDgZrmrYShiWnVgpW7m1LE1qCapTav2 ZW07wT4N0e8i1HSfCmkWd/FnZc2tlFFImQQcMFyMgkH2NTSwOGoyU6dNJoqpjMRVi4zqNrs2dTXW c4UAfM3xg+M3xC8NeOPD/wAK/g/8NLfxb4+1HSp9cnfVdS/s6x02yjlWFWkk2Mzu8r4CqOikk1pG phaMOeupyfSMEr+rb0S++7M5U69aXLRlGCt8U7teiS1b6vXT5lL4ceL/ANrXVPGWkWPxO+D/AII0 PwRIJftuqaP4imvLmDETmPZE0ShsyCNTyMBie2Kl4zCVVyUsPVhJ9ZODivW2v/BCOFxVN89XEU5R 7RhNN+jcmvP0PqapNAoA+aPj3r3xKl8QfCX4ZfDLxda+E9U8ZXt99q8S3FlHeyW1va2xmaKCKT5D NISMFgcKjnHFaU6zoqUoUlUl0Um+Vd2+Vpu2iSutzOVOFRxVWbjDry2Tb6JN3t1ffQ+QvCPiH9oX RbPwd8RPGH7Sepal4etPinL4I1vw22i6dFJcQrrcumW+1hGGBlItpJAORFM7JjCmt/rlerpKhSUJ J+8lK66N/E95JxXZtXvZmf1bCU3aM6jqJ7Oe/VaeUfe7NJ99P1UrkOgKAPkz426p8N/GfhrwX490 T4+6B4J8QaHqlyfDvjCW+tWtXuFV7e6tZElYJPGy7lePOQyKwwVBrrp4HHqtbDUeeaWsWm04vvy6 ro007pnO8XhJUv37koy2cbqSa6q6a7rVNNM+V/g34R0afVPAvg/4k/tj/DfxV4V0rxbP4m0zwd4V ks7Z9X1i51Ga+h85jM7yBLy5LxxJj5ljBziqqYDOJUnGpgvZQWspLnk2k72u9Ira7tdpavVhDE5d GpzU6s6k3pFSSUVdWvaMVdvzdk3okfq3XEdAUAfJv7XWh/BnWvAmgD40at4mg0qLVYm0zTfCd1dR 32p34+eNIorc75XXyzIOy7CxIxmqgq2tSnX9io6ubtZfNpu/SyV3e1hXg2oOh7aUtFH8+sUl3cmk eLfDDwF8AbjRPhZ8aNL8efFq203VPE0el6da+JfE2okDUob2W3Fvd27SlQrXNq0RVshiVU/exXRL EZhOTp/XvaQavpGNpK12l7ie197bMxVLBQip/UYwknbbWLvZP4mt7Wavuj9G65TcKACgAoAKACgA oAKAOd8T+KPC3g3SZ/EXjDX9N0XRLYjfqOrXMdtFGTwAXcgAnpjvWlDDVMVUUKMHKXkrsyrV4YeH NUlZP8fK3U8z0n9pP9n3XtU03RNF+NPgu+1jUbiO1tLK01q2kluZnYKkaIGyzMxAAHJJrsqZRjaU HOdJpJXfoc0Mww9SSjGTu/KX+R7dXnncV7m2gvLee0uYVktpkaOSJxkOpGCD7EGk1dWBOzuj8wv2 lf2ev2Xvh1rnwN1DX/hN4e0D4SXHiGUeJ9csNNwsGy2kaziuZEBMdtJcBQ7dPlVWO1jWFHCRcvYR qyjOeibqSW2rSbdlJrRX6XtrY7qmYYqpB1JL2kY6uKin6SsldqO9vR20MDxdpn7Glj8RPgJefs26 P4J1f4uR+MNM8nTfCKJdq2nPOovJ7ny8rGsEO6dJGIKyRJjqQemrlFTLbVcVKSi3bllNtyb+Gybb 0eraVrXT0Zywzarmd40rtpX5uSyiuqbslaS0tvezSukfrJSMyvcXEFpbz3dzKsVtCjSSSucBFAyS fYAZoS5mkhN2V2fmT+038d/2XPiLq3wRs/E/xh8Ma38IrbxDIfE2hWWqq63Bkt3SzluI0OZLeO4K l16DeGIIU16E8ux0E6Sbgp6OSlFPvy3TulLa/eydk7nLTxlFyVZQcpQ1ScJddG1eNm10Xa9rtJPl vFt9+xxbfEj4AJ+zN4h8E6P8Ybrxhp0MNx4Uu4raObTfNX7dBdBSFkWWBnijjILNLJHt6EjCnlWK yuMqkG7NWcOfmUl1bV3bl+K/lbd2OqpmazZqFdN8uqk4STi1tZ8qeuzW1rt2SP1nrmGVbq6gsrW5 vbqTy7aCNpZHwTtVRknA56ChK+ga9D5Pn/bt/ZUtY/Ou/itDBDkL5k2l36LknAGTCOSSAB3Jrvjl 05u0atNv/r7S/wDkzCVWrDWVCovWnL/I2fD37ZX7NvirxLofg/QPiTHdeJdZuEtbGwGm3yPPI7qg A3QgAbnUFiQBkZIqZYCcYOp7Sm0u1Wm/lZSu2+iWr6A6s4yUZ0akb94SXrutl17dT6hriNwoA/Pr 41+Bf23/AIreEPid8Mo2+Edt4J8UWl7pMd0V1D7ZHZzBkVj85TzQjAnjG7tiipjqapuNPBS57aP2 sbX725L28r/M0p4OlzKU8Y7dV7Nfdfm/E7zwTH+3HZav4UsPFkHwg/4Q63uLaLUZNNXUftRs1ZRK Ytz7fM2BtuRjdjIxV/XqE1yrBTi31dWLS87cibXldepLwVOPvLGOVuns0r+V+bS/c+yagkKAPnHV v2ZvBWr+C9G8Dy+KfG1vpem6hd6lFdWHiO7t7qSS4keR1kmRwzxguQqE4UAY6VUcVj4+/DEyU3u7 Rba6LVW06E/V8E1yyw0HHoneyfV77vqc/wCHP2RPAPhnxDoXiOz8c/Em4u9JvIb2KC/8YahcQSvE 4dVliaQq6EgBlIwRkHrVPHZnNctTFSlF7rlhquq0jcf1bL46wwlOMujSd0+613R9XVmMKAPMvi38 LPD/AMYvBl14N8RXF9aR/aIL6z1TSpzb3Wm3kEgkguIJB92RHUEH6g8E1EvaJqdKXLOLunZPXzT0 aa0ae6ZcHDVVIqUXo0+q/NeqPm6//ZM8d+NYYfDnxe/aY8YeL/hv5iNdeGGs7OwTVY0IYQ3c0Mav JGSo3Lkbu/Wrq4zHV4Ok1Sgno3CDUmutm21G/dJeRNPDYGjNVYRnJrVKc24p9HbS9unNfzPtxQqq qqMKBgAdqBDqAPx48ZfHv9n3SfBniDwh8ZvAUdn448U/FDy/Fnhe4t9ThjjiOpNaR6lHLtIkxZRW 8+2NtrsSAOcV1UVGqvb0MVKKeitWjGcHtZptOMOa7askovfqKbxVBqLoc1raulzRknrpbRys7K93 fSzNYWX/AAS1JwIrQn/rz1n/AON1t7LMf+hnL/wqj/8ALDT6zP8A6AH/AOE//wBqfrjXnkBQB4J+ 0N401j4f+EPDPiiyvLyz8P2viXS/+EhvrC1a5lttKMw85tiqzbCfLVyoJVHdh0zThUjCSTaXNonK 1lfu3ouyb0TaE6cqqfLFytraN7u3a2r726pW1ufGvxF+IfxR8deFPjH+1D4F+I/iLw74E8DbIPAf h6KAwW3i+WEIZZbqCRA8qXNzIbWJeDhAy8sDWyxroTdKlySpR/iO0Zc3WSjP7KiusX8V9yVglWjz VoTVWXwq8ouC6NxWjberUl8Ntj9QImZ4o3ePY7KCVP8ACfSufToWS0wCgAoA8X+NfgfWPGui+DJt AFi+qeG/FOla+ttqTFIbmKCYCZCcHDeTJKyEggSKmaietk48ye662/4Ds7dbWGpRinKU+W2z7P8A 4O3lc+YvjT8KPjlNqnxy8GfDbw5oN/4M+Mk9rdzeJ9R1M2tx4TvRZWthJMkIQmYrHZQTRbWUiXPb FSqtOkpJ0ZSqJ3g425bq1ua+q5ZK90ndaFOmqnLKVaMIPSaabbvf4ej5k+Wz2tfU/QGJSkcaM5Yq oBZurcdTWlyCSmB8iftqy6FY/Bux8QaxbnULzQ/Euj6npXh427XI8RahFcqYbAxD73nElQeithzk Lik4RnF+0aVO3v3drw6rrr2VtXZPRjhKUZL2abm9I26S6PW2i66qyvbU5S3/AGjZXihZ/wBjD4oR yFQSg0XTSEOORn7QOnrisVhuH91Wj/4Kqf8AyJpfOnvTX/g6J9zVuZBQAUAFABQAUAFABQAUAFAB QAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAYvhv/kXdA/68oP8A 0WtAG1QAUAFABQAUAFABQAUAFABQAUAFABQAUAfM3iz4F3ni3Vv2kNOvdQt4/B3xX8LQaRJLGCLq xultri0kbPQxmGSBlHZkf+9WMuaXMlHW2kv0t5PW/W/kax5Fytv1X6p+mnyRzHwk8GfH/U/ivp3x F+Ndj4Y0iPw54YufDNpB4Zupbj+3ZJ7i1le7m3geWqi0GyPkqZ5Oea0eJjVlajRlTi/i5mndrZKy WivLV6u5H1dUo3nWVR/ZtFxsut7t+87K9tND7AqiQoA+CviX+0J8MPBnx+8XfCn9ovWPDbeAr7R9 P1DwzFfad9pFpOomF6l02xirPm3aLsVDjqOXLBUMyh7KrCClHZymk5J9rySXLbbS97q/Rwq4rCSd egqkovflhJqL6fDF83N5XtbVLd+4/Bz4zfs6+NL258E/BPxNoF1d2lq1/JpeiWrW4jhV0RpCNij7 0kY9fmFP+zY4CF4ciTf2Zwk/moyb+exMsZVxcr1Y1L95wnFeicopfJan0JUjCgAoA4SL4leBrj4i XXwmi8R2zfES20pdbl0PDealiZBEJum3bvIXrnJHFa+wl7JVtLXtur99r3t52sQp+/yWe172dvv2 v5bnd1kWeQ/Hv4ZSfGb4L/E74WQ6iNPufE+jXOnQ3rKWWCV0OxmA5KhtuR3Gaio5qLdPf+tPmXT5 HNe0+HqfM2lfDj9ob43/ABM+GOs/tEeFvDHhv4e/Dm4OsW+h6FqDagPEOtCMxw3Em5F8uGEM7onJ 3MM9KK2JpYqCoYejKEHZz52tbaqMUt1fVt9loFKhLCydarWjUltHlTVk95O7+JrSy27ntMngXxPq P7Vtl8TDpiWfg7RPAtxoS33mLv1S7u76CcrsHISBLTqerXBA6HMqUYycIJ6q8nay0+Feb1d+2ncf LeHNKS30XVd2+19LW87n0dWpmFAHwl8XrD496D8Qfi7B8LPAlzqt98S9H03StH8aJfRxweE2iSaG VriJ/m2xmZrhNgO9nKnGM01j6dFctXmco6wio3i2+7uuXX4rr4UrF/VJV4+7OKg/ju2pL/CrPmut FqrPU1/hV8ANM+Cfx48P2vww8NXWmfD1PAc9t4i1JpC0et6oLu2+ySSZYl7lY479ncjpMOTnjOFe ok6VSrKbk+Z8zbs9rq+i5rvRPpqtEVVSq2q8iiorljZJaPW1l0jZavvp1PtarMgoA+c/iVYftQ3H ieWX4Ua18OrXwiYYwkXibTrue683HzktHKq7emBjNCr0aek8J7R/zc/L8rcr/MX1d1PeWJcPJQT/ ABbOK+Efjj4/2/xs1v4X/HO48EJA3h46zosnhiyuYm1RVniilcNJIwXyWkCuhGT58LBsbgLVShWg 3Sw3spJq/v8ANo9re6rp63fRq1tUwlR9g1fEOpzX+yla297bPVW11u+x9g1Azm/Ftn4k1Dw1rdl4 P1m30nxPPbulhqV3bC5jtZj912iJG8D0zzRzuHvKKk10d0n6ta/cHLGfuyk0n1Vrr0umr+qaPgvW vg9+03qnxS8IahN+1N4NtvidpGm3c9pBbeEY0nutMkeJJ0kTzfng877OeejhCMGqWKxiTrRwdJR+ F+/U16q6crq1nZrXdX1aEsPgb+xniK7e6/hK3S+lOz7NPR720R7T4O0n9oTwp4+8HRfFb9oHwrq2 g6nLcwRaBa+G0sLjVJVtpZAkUu8kMm3zSAMlY27Zqo4iviIyTwtOCWrcZVG1r0UpWetk9NLkyo4a g044irJvZSVPlfq4wTWmq1Wp9X1mWNxmlYD85PEvx3/ac079qCHQdI/Z81u/8IweFdU8rR0163jt 9SZNRtUi1DzCm2NxGWURH5sTE9FNaLG5cl7Cbn3dqScrrTT37uG+umttNdF9RxUpe1jOHZXlLls9 bP3bc/Za6X1PV/Dviz9pn4ifFH4ay6t8Jpfh18PtDuLy716W716G/bWY3tJYobZYo0HSeSKUsTx5 XHWk8XhLezwkZyct3OmoJLe6fNJ3bstLaXuN4StH369SGmyhKTbfndJWt662PsapAb1/+vStcD5A +NVv8QPBHxp8BfG3w/8ADa+8f+FrDw/faDd6No8kYv8ASJZp4ZheW0chCyb1i8txkNhVwcZBhTws GqeKvGnupKPMlLb3ktbW2avbXTUtUq04SlhnHn2cZPl5l2UtVdPo9H30OX0TxH8Svjn8cvhH4usf g14j8A+DPBDajcaprfizybe61eO4tJIFsIoI3YmPzninZnOAbdMDNN1sEp2wUnUlJWk+Rxio77ys 27pWstNddRLD4lQvi1GCWsYqXNJva+islZvrd9j7pqyQoA/N/wAS+I/22Iv2oobrw/8ACzw5c+FY PCmqW1pDPr9xHp91GdRtTFPOwiIS82LhY8H5Hl545f8AamGh/s7o1Gt3FOF21pzJ20jraz11XZh/ ZlSf79YimntzOnJ2T15GudNvrzKy021R6v4d0v8Aau8c/FH4a698StF8J+DfA/hS4vL67tvDmsT3 8+uPLaS28cEgZEVYlaUSnOfmiTGMZo+vxmvZ4ahOCl8TnKLVlqklFb3tr0XqH1KMP3lbERqSXwqN OUbPq25Sl00su59k0gOc8WeHYvFvhrW/DU+pajp8Gp2727Xuk3DW1zAGGN0Uq8ow7MORQpTg+alK 0ls7J2+T0fzFywn7tSPNF7p9fu1Pze8SfAGxtf2hfAHwjt/j/wDFXStIvfD994huZLzxldGXWGjm igS1tyzcFPNaWQrlsBAMAtXVDHZrODVOtzSWrfs6fux72UdbvS70Xq0YVMNldKSnVw8Yxei96Wsu zbfRapLV+iZ21r8OrP4GftM/Aezsfi/478S2Pi4app58Ma94luL77LNFYzTretGzfPDsR4mDghZH gZcEHJ9Zx9SlL61UvB2s+SEby35bpLprpqrWejKjDL1K2EoxVRb2bdo99W7O9l2ab6pH6HVymwUA fDXx80b4k+Mv2ivg/wCGPhj4psPA2uad4f1TV28Y3Nn9rmv4PNghk02OJiEkTLRTuGzgxxso4Jpw xDoNujTU5v4lJvl5O7Ss782zTVtV9obpU6sUsROUYX05bX5v8TTt7t9PtfI9P+H/AMPf2jtC8W6V qvj39oGz8S+FIPN+1aJD4ZtbJrrdE6p++T5l2yMj8dduOhqpYyrVXJLDUoJ9Yuo5L05pNeWq28w+ r4aHvU6lRvtJxt87RT/Hc+lqgQUAc5rXhbw/4iu/Dmoa1pcN1faDe/2jps8i/PZ3HlyReYh7Exyy IfUORWcoc0lK7TXbTfSz8vIqM3GMo9H3+/70eUXf7NHwWvfinF8ZbnwZC/juO4W9FyZZPJN2qBFu TBnyzOqgASbdwwOalwqcvs/az9nfm5OZ8l9729de19TX2+l+SPNa3Nyrmt25t7dPTQ96rYwKl5NN b2l1cW9s1xNFEzpboQDKwBIUE8AkgDPvSTXXYPQ/P+78Z+Lr/R7Pw/e/8E9dSuNDtZ5bqCwmv9Ja GGaVi0jqh4DMzMSepJNczWSSgoN1bJt/wX1/7iHVF5zGbqKdG70/jS2W3/Lot+C7u8fxj4VRv2AH 8OodStgfEBn0o/2UPMX/AEnCDd+7+/8ALz8vHNTCjkiknR9rzdL0mlfpd87sr9bO3YqdbOXF+1qU nHrarJu3Wy9krvsrq/c/QCuw4woA+cvjt4d8crrHww+Kfw+8M23ifW/BF5dvN4ZnuBbPf2t1bmGR reVgVW4QhGXcMFd65G7NQ504Ne3i3T68qu0+klFtc1tmrrR36FxhKomqclGfTmuovvFtXav3s7NL Sx8e/C3w98d/iH4W8D/CLxB8EdV8E+F9M+I11431jxJ4hvbcs0C+IbjWre2toYyxaRmeCN3JAADk Z4qfrmFqQUcK5ym31g4xir7tt6trZJaN6vQawtenJyrygoJaKMuaUnb0Sik+rd2lsrn6n1qZhQAU AFABQAUAFABQB8M/tmXfhDQtS+AHjLx/4dv/ABN4O0PxHPJe+GLHS59S+1ebavClyYo1ZWNu7rJh 8Arvx8wUVMvZ1IujXqqnTlu3Llv2Xdq+jS20eyZpT9tGXtMLTcqkdrK+j0fo7bPya0vdR+EPjh+y Zq3izwxpfhv4cX1r4ivdQt7ewuX8BXlqIbh5FWNjM0AEYDlTvJAXGSRioWV5bT9+nXouS1SU7tvp ZdX2NHjc1mnGpQqqL3bSsl1v723c+6q1OcKAPn746+N/E+jR+EPh/wCAvCmj6/468a3E9vaW/iJi unWltBF5txcXIA3OqgooRcFmkXkDNKSw7pt4mm6i091WTb9Wmopbt2fZbhH23PFUans+8rN2Xkk1 dvprbq72seE/DP4kJ4S+DPw++J998OPB+m+JtV8ev4K14+GrH7LEAdeuNFWaD+L/AFqQOQxPyl/a opYTAU6rqUqPJdaa3cXbq7aq+mlt12Lq4jF1KahOs52fXS6v2WidvyPvetCCJ0SWN45EDRsCGVhk MD2IpNXVnsCbWqOLHwy+HA5HgLw9/wCC2D/4muH+zMI96S+46/7QxX/P2X3smtPh74Bsbm3vbHwX oUF3A6yxTw6fCrxupyGVguQQRkEVUMvwtOSlGmk0S8diakXF1G0/M7Ou05iMqGUhhkEYIPOaT1Vg TPj79pzRrrRtV+Cnj+3+HNz4r8A+FNemvvEHh/Q7SOW5Ia1ljtrtYTjzhBK24x5zlgw5QVyujgaf 7uulCEt5ct0rapSsr8re+j2V9DeLxNV89F81SOycrXvo+VvTmtte2l1c8k8TfFnRvj14x+Duk/BL 4U+LYPFeieK9P1W68W6z4dk0i20PTo5P9OVpJQpdprbzYRGoOTIDkbQa1cMtwslPD1adSo9OWCbu nu5PlSSXxLrzJWJUMxrRccTSlTprVuco3utuVRlJtt6PZWb3ufpBWxkFABkUAefeN/if4L+HN14L svF+rNZXPivV4dD0lRbyS/ab2X/Vx5RTtzj7zYA9aunTVS/vJWV9WlfyV935bifP9iEpd7K9l3fZ eZ6DUDCgDwv4p/FWP4deNvg9pWravpWjeEfEV7fxalrGsSLDGphtHligWRiFR5H+YFuqwuBya2oU 5V5OjShzTey62W7SW7207NvoY1pKlH21SXLBb/Pa+mi+7Wy6nzBZ/Hn406re6D8dtN1jRj+z/rvj my8IaP4VfT/9L1PT7i/TTk1VLrO7c07mdExtMCjuc1TxFJSlh/YrljdOpzPm512Xw8ql7nfrfoNU HyxqupJTlqoWXLyvo9Obm5fevfTa1j9E65zUKAPJ/jH8SLr4ZeE7fVdH8PSa94r1XULbRtF0VJhA L6+uG2xq8hBCRqA7u2DhUbAJ4q4ezV51m+Vauyu35Jd29O3VkyU52hStzPq9l5u2tl+Ox4Jon7Rn xE0f4P8A7Q3j34neDtEg8UfCjWpbO/03QLqWWCe0isbC/kdJH5MghvXA4ALRjpmrVTD1ZQlGEoRe jTkm072vdJKy0bVu5m6danGUfaRm1s+VxT8rNt90tex9nxyJNHHLGcxuoZT6g8isTYkoA+cv2lda 8E+FvBOi+IPE/wAOf+E01tPEOlx+HtBt0QTXus+epswsjcJtkG8s3ACk4PSsXhcJVbqYl8sVq2ld u3SytzX2tez6lxrV4pQo2beiu7Jeb7W3vvfY8xTx5+1K21v+GQfCig4OG8XwZH1/0WnbJf8AoHq/ +C6f/wAkHssy/wCgqn99Q+261ICgDwr9oL4keIvhr4GsLrwd4dsta8Y+IdZsPDmk2eqSmKzW6u5R Gj3LDkRLySByThRyRTh7F39vFyjZ+6rXl5K+i829lcl87tySUNvef2fO3V9Eu7R5GdB/bjmto7Wb Xvgt9lBU/ZzomoMiEEEYHn44IBH0zR9aw/Jyf2f7vb2qt/6QV9Ulzc/16V+/s1f8z7RpAFABQAUA fMn7V2n69d/DXRtR0fQtR13S9D8TaPrOt6DpBP2nUtMtrpJZo41yN5Xashjz84jK/wAVCxCw+spu EXo5K+iejemtujt0bKhSlWfuJOS1inaza2Wul+19L2PnD47ftN+APjl8MNe+Ffwa03xZrfxc1swR 6HbJoN9Y/wBkagsqPDd3E8sapEkDqJGOT9wjBzW86lDBL28cVBtbKElKUn/Koro9neys3cinTxda XspYacYu6k5pKKXV3vuulru9rH6SxCQRRrKwaQKNzAYycc1z3GS0wPn/APaS8EeOPHfw4isfhpZ6 VJ8QdM1Wy1fRrnWLh4IbG7t5BJHMSoO7BGChGGVmB61nOfsrVORzs72TSv636W+fVNPUuEFVvTlP kT0vZtr0Sa17a27prQ8vTxT+3XH9mhufh58IBcuMca5fDeR1KrsrZY3DyTksDV/8GU9P/JDGWFlB qLx9O72vRld/+VfyPtCpLCgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAK ACgAoAKACgAoAKACgAoAKACgAoAxfDf/ACLugf8AXlB/6LWgDaoAKACgAoAKACgAoAKACgAoAKAC gAoAKAPlf46ftWeFvgjc61YN4N8TeKtQ0LSv7d1xfDtsjxaHYfPia5ldlVSwjkKoMsQhOAMZ3pww 8VF4msoc2kVZyb87LZLu2vK+plL6zPmeHp8yju3JRXot7vyS7dz29/HuhxfEa2+GEwnj8R3Wiya9 bF0HlXFtHOkEoRs8vG8sO4Y6Sr74zUE4Od9nt67P8H/TKcmpJW0fX0tp+Kt317Hc1BYUAfnx+1B8 V/ifox+M2pfC3wz4LGl/Cvw8mta9q/iqxa7m1CZoXuEtLZFICgQoC0jEjMoAHBpezwKcXWwyrTlu 27KK+67e+miS33GniZRkoYmVJLZRV233d9Eum13r2PpEeKbXw58ftA+F9p4b0q20/XfCN9rlvfWd usU6S2l5awyxuRwUZb2Bl942z1GM6OGw1GLlTpqM+6SV11Xydvv8h1K9aq0pzco9m9n0fz1X3eZ7 tWpJBPPHbQS3EpIiiUuxAycAZPFAteh+fnh7/goV8ItQ+KHxL8M6rfX8PgzR7HSJ9Iv4PD2ptcXU 04uvtKzRiIlFTyoNhKru3tgnBx2uhQaUY1qaa3bqR5X2S81116o508Sm37Co7/Z5dV5v16ejPUfh p+0F4d+MHxw/s34b+F7m98IWvhm4n1bxff6Jc6fJb3YuYFtrRJZkQyK8bXLlQDgxKc81xVaWDpVP dnGdZreElK0eqdtNXa2vR6HTD65KHNUhOFNPaSteT6pXvot+mqPrmgAoA+fPin+038KPhF4htPCP iW/1W98WT2wvTo/h7SrjU7iC3LFVllWFT5asVYAtjODito0aapqrXrQpxeic3a/ey1enpYyUq1Sb p4ajKpJb8qWl9ruTivle5J8K/wBo/wABfGHX73w14W0rxZa39rZtfPJrvh+606Exq6IQskqgF8yr 8o5IDHsaibw1v3OIhUfaLbfrqlp/mjX2WMhriMNOnHvLltft7spO/wAraHv9QBxnj/wvfeNvBniD wrpvirVfDV9qUHkxa7orhLqxOQd8RIIDcY6dCaFOpSfPRtzLa6uvmnuCjTn7taN49Vdq/wA1qjyD 4hfAnxh4219da0j9of4geFbQW0Nv/ZehTwLAWQYMmGQne3U89aaxWNpe7QlTUf71KMnf1etvIPq+ Cqa16cm/KrUgrekWl89zT+FXwZ8U/DrxBea1rnx18ceNbSeza1XS/E00LwQuXjfzlCIp3gIVHOMO 1J4nGVtMRKDj/dpxg7+q6eX+QewwdLXDwlGXnUnNW9JNr57/AHnv9ABQB8f/AB507UdP8SR67e/t gyfC3RruBI4NFmXTEjdl4aRDcKXYkkZwcCuzCxzOrFrB0ITiusoOT+bTS9DlrSy6D/2qU1N9Iza0 /wAKT+8w/wBnnw78Mbn4l6x42j/aXHxe+K39jPYQyy6hZyHSdMM0TyrDbW+FRXlWDe+MkhBnpSxe FzOLVbHQUIrRKMeWN3rd6tt6dXoiqGJwEk6WDUrvVuTlKTtsrySSSvsvU+3K5DoCgD8rPil8KtT8 M/tR6J4p8Vftnax4RXWvDupWmmS3wtIJoBNf28wsoJJIvK8gCIE728zdHHjIJrbDzzTET5cPClJp fyRbt/gveT/vLbXuRWhltGnzV4VeVvVqdTlv350/cX93SOt+h9OeBf2ar6z8deDfiX44+PHi/wCI c3hoz3Oh2urvbR2lrPPA9u9wFhRRI3kyyKCSQA5xWNarjqslDEuEVF7RpqDb21e9l27l0lgI03LC Qb5vtSqSqaeV20r9z63oAKAOL8a+PvAnw40tfEPj7xVpHh/Sy3kpe6tcpbq7HnYpYgseM7Rk8Vth 8HVxcn7GF2lq+y829l6mNbEww6Sm9+iTbfoldv7jS07xX4a1eDw7daZrtjcw69afbtLaOdT/AGhb 7EfzYRnLrtkjbI7MPWpnRqQck18Ls/JlRqxmotbSV1o/X5ej1OirM0CgD4n/AGhY5fGvxU8O/C3x B8RdY8I+Cn8LX+uQQ6JqB0ybxDqEcqR+QbgYbbDGwkMSkFvNBIITjooVMUoyjgtJrWUrKUlHb3U7 213la60V9TCqsLFqeNipQeiUnaN/Pa7t8Kfmcb8MfibrV3on/BOjS7LxfNqHiXxJ4Yhm8S6d9q86 S5sT4dM0l3cpknK3qWgEjfxTMP4jTqutGLq1lpUe7W8vi0+Sd7aWfoTSVGbVOja9NdOi+Gz7XbWn l5M/QquY6QoA+f8A4xfCXw38SNS0a81z4p+LfCklnA0Udv4c8RSaSlwC2d8iqRvI6AnoK3oPMUn9 Sk0uvuRn+adjnrSy6LX12EW+nNJx0+TR8y6T4O0b4O/tM/AvT9F+OHjTxfY+K11Sxfwzq3iiXURZ zRWU063ske47oNiPEQ4wJHhZcEHO06mZqm446XuO1n7OMbvfl0S6a3WqtZ6MVL+zKj/2GnHnW7Un K0e+7s72XZpvqj9Gq4jpCgD4v/a1uvhjrMfhjwL4m+DOo/EzxvJDc6tp2k6Oy28+mW0W1Zbprssv kJuZE4OWJwAcHCUKNNxxVSvKlJO0XTu5tvdJJrS293ZaF06mIfNSo04zT1kqjSh5Xunr2SXfVHPf ATw3+zp8O/8AhQfjjwR8PLjS9f8AjLoyzaZq+p3L39zbb9PXUBaPNIxYFoElPy4BMJ9RV1KcsRVl Ur4idWUL8rm76Xs2lsnqtNdL66CeJmqcacKUKcZfEoJLXdbLVXvr6aan3jUkmZq+qW2i6Vqes3qy mzsLeS6lEMZkcoiljtUcscA4A5JoVursu72XqJ3+yrvst35I+AP2iNb/AGcviHF8HvHPxF1j4n6d 9p07+2NA/wCEWt9Ut3hSUYLzJboTHNtcrh8HBIrWDnCXNh8dClbZ3j7y7pyTvF/ddJiUHUi41MDK re1018Pk1zLX7zL+AN7+zzL8WvCkfgXx38Z9R8Un7V9ls/FsmtHT5P8ARpd/nC4QRcR7yu4/eC45 xWtTEYmpBxqZjCqv5U4Xf3RT03+RMcNCm+aOWuk/52rW/wDJnvtt1P0mrlNAoA+afj38Rbz4XeIv hB4s1e51m3+F8GoXya/No1nNdnzGtHFos8cSs5hMhfoD84izxV0pw5vZSnGHN1lZLTW138Le99NE 11InSnNe0pwlNx6R310va65ku3ne2h8wRXXxjuD4D/aTvPFvi/T9f8ZfEDTtL0j4bzuyWMPhq5vV twlxaY+Wf7EJL15GwyPx0XFP+0W04wlH6v8AClyq8nspKTXNdy1S25d1a43gIxtzwft93JNvl6uL SfLypaP+9s72P01rMoKAPl/9ofUfEOo698H/AIX6X47vPBej+NNTu4NQ8RabIsN2Vt7Zp0s7eVuI 5JmB+YfNticLya1pVKsLrDxTqW0uuZJLd8r0bXndK7fQyqQpNKeIv7NbpNxu3sm1ql81d2j1Pn7w p8QvFnhP9nv4MNH441TU/F5+Ls/heFtUuzcXmt2CeKb3T5IpSfmk2WKs5P8AD5AY8LWnta0+avUS aslJ8qS10TVtE72231XVkRhRvGhR0e6SfRe8/VWvv+dj9Ia5joCgD5R/ab1Lx59r+EHhTw34+ufA nhPxLrktjr3jGxiR57JRbu9tAjuCsRnmCx+Yeh2qOXFaUq1SnL2dCMXVl8PMrrTV+7tKVtk/MzqU qU4+0xDl7OO6jLleuivJaqN97d+iuzmvCf7NfiDQPFHhzXZ/2vPihrUGnX0F0+j6jq1vJb6gEkVj DKoTJR8bWA5IY1o8Rm8k1V9ny9bUIp262drp+fTcftcmlpSpJT6fvZvXpo5Wfo9z7TrnLCgAoAKA CgAoAKACgD5w1gftTHwXov8AYS/Dl/H39oXf2/8AtOO7azFl5j/ZvKCOG8zy/L35OM5xS+sUZPnq YRyX8qmk153cXe/aysNYZfCsU1/e5Fr5Wvpba/U5zw2v7aH/AAkOhHxVF8Ih4Y+2Q/2kdMg1AXP2 XePN8ktIV8zZu27gRnGeKf1jCS0jgZRff2sHbzsqabtva6v3G8Ly6/XHK3T2aV/K99Ln1lQSFAHy h+1Rd+BdM0vwFrPib4kah8PvE9hqckvh/wAZ2dm1zFYXDQskkdyNjR+TJE7KwlwpwDkFRV0YVZVF KhOCmvszaSmnvHVryejTTSsJuLg41KU5w6uCfNHtJWu/LZpq6Z498C/2bdb1G08IX3iv9oyz+IXw y0LxFd+LNM0bw5ZW1vZ3Wpz3k1+JriWMs0nl3Nw8qJkKrBOPlFGIWPgvq+JoQoq93ZS5pK90ryek dtldpat6jo1cum/bYScpySt70k1F2s3ZJe89d9rs/RCoAKAPkb9qK5s73U/g14J8W+Mr7wr8LPEu r3Vtrmq2N61gbiSO2eS1s5LoYMMcsgYk7l3GJUz8+Dvh5YhydLBu1WS0a1kktXy3+1b5pXaM6qoq Dq4mClTjun8Ouzl3iut9LtXPmfwL47sPD3wH+BfgrwZ41+0eOV+MF3pulaVHqP2q7u9Li8V30NwJ BuLPAmmCYl24CqpznbW1T63CLxWI5mn7rlL7T+G1+rvr5Na7M56TwleX1fDqN17yUbWj9q+myael 907K9z9Ua4jsCgD5w+O/iHx7JrXws+F3w88UQeFtW8bXt4lx4nltkuZLK2tbczvHbxyfI08nygbg QFWRsZUVpTqOkpShTU59FK/Ku8pJau2yV7XavoZzhCbiqsnGF9bOzb6JPpfe++llueHeE/i18RvD v7Pnwp8S6t4sfW/FJ+Kb+D7+8vYIll1qz/4Se70jBVQAsi24SXKDrB6ZpxqKUpVJ04q615VypO1k 0unvW9bk+yjBKnTb30u23vdpt6v3b7+vQ/QCsjYKAPJ/G3xFm8K+PvhL4Njgs1tvFlzqC3N7eybB BHbWrTbY+QDKzFMA/wACyHtWlKCqKUVFyl0t07t6O66aW1aMas/Z2nKSjHq3+CWuj669E1uz5aH7 SHxF1fxDp/xGt/Cfhm6/Zsk8cW3gqwu5DI2q3c0l4unLqcBz5fkfbX2hQNxjUuDyBTqLCSl9XnSb lH7d1ZTSvbltfT4W76S8kOnGvyKvGrbm+xbeDe/Nfdr3krWtbqz79rI1CgDw/wCKuo+GtU8T/DD4 V+KfB2ma/pXjC5vXlXV0R4rZLS2MxZUYHdIWaNQOPlLn+GoqYejiIONWLbW1tLed97dNOrQ4Yirh pKdOfKut+vl+ut9j5im+OWo6t4i8Ma7H8JPDV1+zJofju08IaLrXnEXsWpfaP7Njv7WADy/syXkp gGPm2hnB4Arb2eCivqfJJSjrzXXIpL3uRx3du97KXTS4o1MVJPFKqvf+zZ8zi3a/Ne13va2seup+ htQAUAeRfGzwRpfjrwFeWmoeK38LXOk3EGs2HiiOREOjXds4kjuCX+QoMEMrfKyMyng04RrSqR+r q809E1dPyaWtmrrTVbrUUqlGnGTxHwW11s15p9GnZrzPzf8AAHhSb4r+JPiJ8NvEX7Z3w58R+EvH uvprHiLw74StIbe/10ra2ls9qHaQhYpIbGEOIgSdz4IzXXXwuaRp1E8JCmnvJSlNxXWyvp11le1/ Q5qOJyx1Iv29SbW0ZRUIt7ptqK5umisnZXTdz9elCqqqowoGAB6VxnUPoA8H/aK+Hnin4m/DO68P eCdb0nRfFUF7a6lYa5q8Lyppc9vIJUuECsp8xGVSMnbjIYEEilzThKM6dPnknor2189HdPZrqmwt TlGSqz5YtO7snp87WtvfdNXPn/w/rn7WHiK7bR9B/aB+Besatbrie30/T5p5hjqWRLkkdD2r0Kzx WHh7Stlbiu7nNL8YnFS+o15qFPMZNvoo09fTuffFcB2hQB4f+0P4AsfiV8Ktf8Map4+bwZpbtFcz +I0EG6yWJw4dXmG2Ng4Rlk4KsoIINOEMROcVhYqVS+l03qtU0lrdfd30E6lCnFyxDahazs7XT0s/ J9up8aQ6hYxLFbj/AIKcI+wBQWk0NmYDjJO3np1r1nQz3rhaX/gt/wDyRwKrkzdlKs/+35//ACJ+ ndeQegFABQAUAVru7tbG1uL6+uYreygQyS3E7hEiQDJZmPAAHJJpwhKpJQirt9O5E5xpRc5uyXV6 I5Hw743+HniPS7vxL4W8V+H9R0WG5+xTappt5DLCk+UHlNKpxvzJH8uc/OvqKueW1MNVUJUeWbV7 W1t+fRijjYV6fOp3itNb2/H1O3rM0CgDwD9oq08Vv4N8O6z4U0PUdcOgeJNL1jUdB0mQR3Op2UEw eSOLcQGYHZJsJAbytueaca6w75nJxi9HJJtpPfRa26O32WyXQWI91JOS1Sk7Jtba9H1XnY+NPiH8 LfHnxX8E/GX9o3xF4Q8S6X8XiYrf4W+HvtDJeeHEg8tLaV443KLJPdtJLLnIERVTwpolmU6b58PW lGhDayaVTu5RtdqXwpPor6XNI4JOLpVacZVJ77Pl7JSdrOPxNrre17I/UWLzPKi80jzdo3Feme+K m5JLTAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoA KACgAoAKAMXw3/yLugf9eUH/AKLWgDaoAKACgAoAKACgAoAKACgAoAKACgAoAKAPzy/af+Gnxf1i L4/aT8GtN8P+J4Pih4ZTR9Z0a91FbO90a6W3kgiuozg743ikTMbAcx5B+Y1MpvD05TrUZyi/hlHX VfZadrq+t07q7v0CMYV6kYU68YyW8ZdV3TWqfTVNOy7HrXwu8LfGHxl8XR8bvjJ4Z0rwmdJ8P3Hh 3QfC+m3/ANvlVLqe3nuri5nCqpYmzt1RFGAAxOSaJV6dea+r05RglvO3NJu3RbJeru35FKi6EH7W opzf8qajFLzerb76WtY+s6okKAPh/wCOXwM8NfH7xR8UvCPgn4u6p4R8d3Hh600jxlp+mwJcQ6hp t0tyLX7RFIu3ftW6CyIQwGQe1E/rdCk5UHFxndWkr2aSXMrNSi9V5Oy7Dh9XqzSrwleO0ou10+j6 SXk1pfTc7L4VfDjTvh/8WLi7+Ivxa1Pxz8dNd0CX7JcarBHbLa6RBPEJktIYlEaKZ5rcyfxMSmeF qm8Tiv39blSjoowVkr6t6tuTdt3ta2lyV9Xw/wC5oRlrq5SfM3bZX2Vr6JJJ6vc+rqkY3qORkelK wHxV4x8ceL7D42+PPDHwA+BGheIPGltpmly+LPE2t6iNNhIYTmytlIRmkdUaVuwUSY6mo9nl+HXN WpzqSl9mCjaKXVuWib7JXdrsvmxmI92FaNOEeslKTbfZRadlbdv06nqnwn8QftDapr99a/Fj4X+E /DPhpbNpILzQdae+llut8YVGjMagKUMh3Z6qB3qo1sJJcuGw86b7ycLenuq9/wDgkujWg+ariYVP KMJxfreUmreR9B1QgoA+FfGmrfFP4U/tG+NvGXgP4Aa7448NeLtF06HUtQsru0tzb3dp5ixeS0h3 FGjmZXU8Bo1YfeasvbYGM3HF89+jjTcrLqt1vvpazve+ltPq+Kq01LDyppLdSm483npF2ttre67W 19q+FXxY+I3jzX73SfF/wB8ReBtNgs2uU1XV761njnlDxqIVWIk7iHZsnjEZ9RVqpgJq2FlNy/vU +RW9bvXy/wAjN0MXS1r+zt/cqOTv6ckdPO/yPoCqAKAPhz9o/wDaG+LngWP4ry/CDwl4evNL+GOg rrviTVfEs0oEjPE86WlrFGQTJ5Me9nY7R5iDB5renVw1JxVWnKbl2aiora7bTu3rorbeZlKjVrcz VRQS205nJ/fZJd3e722Z9E3fxGubD44aF8J7mwi+xa14XvNftL5Cd4ktLq3gmjcdNpW9t2UjnIfP as1yOm9+ZP5Nf5r9fIp8ykv5fxv/AJP9D1qoLCgD8zPjB4h+BPgH9q3xTd/GPwo/ji78R+GNPksY bTR5dam8LpbvKjRSQKrCKO5L+YrjBLRODxtNKrh6OJgo4+qqcF8HNJqL/m0WvMnbVqzTsmra6UK+ LpSksvpSnL7fKldfy6yaTVr6XunrrfT3b4A+PP2dvFPjDU7H4RfDO88O+Io9NkmnvrjwlNo6yWwl iDR+c8ahiXaM7M5O3P8ADWNPBYDDPmwlaE5bWjKTdu+q22NK1fMqsbYyjOEejly2v292Td7X6H17 W5zhQB8v/tDeOvD+nf2X4AvPgTrPxQ1zW7d5YNIs9OiltIkDBS09zL8kIz9TjnFZVKWX1FzY2pyt bJJym/8AClb720bUZ4+Lvg1p1k5KMV67t+iTPlz4e/stftHWHiKXxd4P8dWHwR0EwsYPAPh+4m16 0klPKtcrcHyhjoREq9etbrNcVZU6MHOmv+gh80vSPLZwX/bzM54HCTbniZ/vXq5UY+zXzvfn+aS8 j9DPh5D4+t/B2jQfE+90m88cxiVb670KF4bWfEriN0RySpMXllhnhi2OMVLqe2fOqfJf7N+a3z0v fdfcQqape6pufm0k36paeWnqdvQM+F/2lG8N+FPih4Z+I/xP8HXuvfDiPwvf6RZ3lvpz6nFoOqyS o/my26hmAmiUIJQp2mLHG/NRJUcRbDYiooR+JczajJrSze10vhT01etzSm8RSvWwsHKWz5bcyW90 na6v8VtdtDxX9nPxlD8WLL9hTwt4I0TW/M+FHh23n8W61e6dNZ21mw0B9ONgskir5sjXMyMQuVAt 9xPSrnUowUFTrRnKa2i72jveVtFqkkr3v6EKjXfM6tJwjF6OWnNLb3Vvs272t06n6pUCCgD5C/al 8WfBMx+GPhp8TPhlqvxE8Qays1/p3hjQdN+2XcUUWFkud25fJQF1XduGS2OaHQoOKxFev7HldlK8 lK76R5U29N+hVOriVJ0sNT9pdap25befNp6dTzv9mlfhN4N8Y2fh34cfsl+OfAlzqsL283iTW9Ki SKCGONpFjkmMzuqEoFVQMbmUe4zjDAXThjHWqJWipKo2l2Tkklp+RpOWYONqtCNOne75ZQ372jq3 /wAOfoDWhieV/Gzxf4q8AfCP4i+NvA/h0a74t0PSbi+sNIKs32yWNCwTavzHgHgcnGByaFUo0mp1 78i3tvb9AVKpXfs6TtJ7HwD8Sv2j/wBiD4wfFvwt4d+JVnpWt6ND4Zur5PEOpWd9HJY3K3UCCzMP lhgXWWSTOOPKxnkV2PAzkuWniOWW/u1oxg15tSXvXta+tr6aGdPEYinLXDtrtKk5Sv5aP3e9tL21 PZ/gFr37DGmePbbSfgNB4et/iBrEUsETWWnXSTzRojSuglkTCrtjZiMjOO/ArnqZXOn/ALRVrKo4 7Xqxm1fsuZv1stvI3eOr1I+ydKUIvV/u3BfN8qXpc+66zICgD5e+NXgT4pt4tsvib8Fn0G+8Uroc /h/VfDniGR4YdRspJPNieOZMtFLHIJMEgqwkYEZAwlV9g+epSdSD091pST7q9013W+1mNQjXXIqq pyWt2uZNdmk0/Rp6a9zxT4C/CH45QSfs16d8c4vCvh7w78IdJj0/QdI0a+a7utc1KPS3sBcSyMFU Ktq10wiQE5bJOEpRrPExj7GhKCjrOUmm+1kl8Ku9277IHTp4eT9rXU5S0jFJpLrq27ylZdEktXY/ QyqEMIDDkce9Jq+gbHy38YPiN8W4viV4U+DfwS0Dw0/iO80W48QX+s+LDL9ksrOKaOBUiiiIaSRp JBnkBVGT1FUnhaUOapRdWWyimopLu20/RJLUThUrSt7b2a3vbmbfZK626t+Rf+H1l+1fF4u0mT4l 6l8MpfBI837bH4esb2K8b90/l+W0khUfvPLzkfd3d6XtsPPSng/Zv+bnTt8lFXvtuNYdw954pz8u RK/zv03PpigAoA+b9Z0X9qCXwTo9rovi/wABjx0NQu2v7rUdKnktJbMyObZI41cESKnlhiSQSDTe Ji/enhFJP7PO7K3W9ne+9uglh18KxMlb7SjG7v0tsrbX6nO+H9A/bHHiLw9P4t8a/C658MwXsMl/ DY6JdpcNbhx5ohdpSFkMe8KxBAJ9KbxlOouX6io9n7Ru3mlboEcLGn7yxc35ckVfybXRn1lUjCgD 5g/ao8S/DDTfA2leFfiN4AvvHN14ov1s9F8I6TB5t5qF2iNJuiOR5XlqrMZdw2j60KlSa9tWquko WfMr8yey5batvt2vccateElTw8FOUrqzso268zd0l8nrY+QfgNpfwW+DvxL8HjxX+yx4v+G2v67f yWPh7xJ4o1AaxaR3twXPkrKHYW0sxZgMgbmfGcmhPD460IY2rVcLyUKqcV1bcVqm93rruzWvPFYd XlQpRhKycqTTa2SUvdi7bK6utj9XaDEKAPg39uGT4cxw/BAfGvXPJ+CjeI3XxBo4mkT7exgYWsjq nzSRQ3Bjd1HQEPzsxV01UqXpU6ns+b7V1FprVJNtWu1a68r2TbFazVRUnVlHaKi5aWs3ZJrRdH0v bWyOD8A6f/wTbj8c+DX8Cal4Zfxuuq2h0ZLe4vGka+85fIChuC3mbMZ4zXRLCZhGLlPFylFbp14u 67W5tb9upKxtKXurC8t9L+wnG3ndwVvW6tufpdXIWFABQAUAFABQAUAFAHFa/wCOdI8O+J/A3hC6 huptZ8Vz3MNmltGGWJbeBppZZSSNqABVyMndIgxzkXGKcZSckrbLvft+L9ES+bmSS9f67+R4TJ+1 j4PX4lz+Bk8J+I5PC8Gvx+E5vHqW6HSotacqq2Zfduz5rpCXC7RK2wnOa19nQv7J1f31ubls9rXt zbc1teXt56Gd8Ry+29n+6va/Mube1+Xflvpe/na2p9V1zmwUAeKfGv4g3HgbRdLtbD4Ua58QNT1q Z7aDRdIt4pIwQuS1xJKdkcfIG45+lROOClH/AG6Vo9FyuTb7JLr6tepUFi274RK/VuXIl5t7/cj4 58CfsvfFbWfir4T+LR0nw58E9I07U4dQvPDPge4luLnXoUYM1tfPlYNjgFWCR5wevenDGVKUfYZf GcaL39rLmTX92Gqg+zu2i62Hp12quOqKpVj8LhFRs/Ob96S8tEz9MaoyCgD5U/ac+JHhnwG/wt0v 4naZ4Zn+C3irVptK8T3niJlYWCm2drR0jJ+YNdLEjNg7A4bgcjSnhIY69BwcpP4WnZJru+ja0jqt dL62cSxMsI1XjU5bbq121/kt2uxlfCrRf2Ivh94jtpvhLd/C/TvFeoyi1t20jUrR7maSVtoji+ct udmA2ryScc5p/wCr2LofvqlGo1G7vLmaXd66L1HLPY4heyU17z2UbXfnZK/zPsCsigoA8I+NegfD Tx7/AMIP8NPH1vfyapr9/LLodxpLvBdadcW0DyvcxzoQ0O1MrvHUyhcHdQoT/jU6vs5x+Fre70sl Zp3V7p6WXoL2kU/ZTpqcJbpq6stbv52tbW9vM+Ivhl4c/Zl+Fnxv0rwwlx8S/Es3h/xJNpen+JvE tzNfeH9I8RXbNLJCjltou3kuHBfaf3sxXcGJrR069WKoYnGqUvjVKyjfeV3yxs2viUW9rNLYSlCH NXw2EUYP3HUvd9tE3dR+y2lvvofqpWZQUAfP/wAbNJ+G/jvVPht8JfiJ4Hi8S2/ii9uri3Wdti6c LS3aR7jcPmB+dI8KQT53oDS5Iv8AeKpKE4/C43Tu99U1ZWvfforajjWnSlyqKlGXxXs1bpo07u9u 3V9D51l+LfgWXX/B3gq0+B7j9nXwZ42sfC+leLrW7jjtbTXoZhbQeXZgZeCO8kWHzM4Eq7sHbmqW HwkIrCKpNVFq9Pdb+LllK93J/E9LXsnqL22KqN4uSi4vTX47P3eaKtZLdd+W7R+hVIAoA+V/2rP+ FZ3vhLwv4f8AHngDVfGmvapqmzw74e0BjHfT3iwyF3ilDL5SLD5m9ywG045yAXFRh/tEq8qPJ9qN +bXS0Ut2+23XoOMqkv3NOlGpzbqduSy1vJtOyXo3focF4V8U/CPXPgR8A9W1T4b3vhfwZp/je20S w8Mxzgpouq2up3GnW5uCmBIgvoUI6/O6MeRmhUKMv3dGpJxfvXas5P4mpXbabad3fV6dRfWK6bnU hFy2dndJfDeOi6WtorJvsfctIAoA/Mn9rf8AaQ+APjDwT/whsvia81f+wvFGnXeu+FINK1BTrdna XYNzZhvJ2NkKWCltrmMLnDZrpdB06bk68IxkrSaqQ5lF7uylzeqWtr9SaarSmmsPNtaxvB2bW3/A fR2Z51+0L8XP2OPGfwpm8N/DSxsbT4iXMttH4e1bT/DN5ZSeHLvepS9aVYAyJDgswGS2NuPmrmp5 VQy+SxFCrTU18PLVheT6J+9s+vNpa/WyN6mNx2Ki6OIo1HTl8XNB6Lq15rpbrY/XeMOscau29woB bGNx9aRiSUxnyZ+2W1qfhFptv4gvb6z+HNz4l0iHxfdaezq8WitcqLjcyfMsRPlrKw6RM57VUKs6 clGnPklL3VLazfZvRN7J9GxOmprmcOdR97lte9vLrbe3W1j5e+Pnhz9kDwZ8Jp/E3wLfwZp/xm08 QP4Gk8E3cL6hdarvU2sKpCxaVJJCFcMCpRm3cVtDKsZlTeLlzwjHWTk5csl1i+Z2fNsra3tYcs1h m1sJdTctkoq8X0ktPd5d+miP1OhMhiiMwAlKjcF6A45rmvcCamB84ftNeC7nxz4M8IaY3h2bxB4e tvF2i3mt6FCAxvtPW5UShlJAdIyyTMvdYSOelROahFxcnGMtG1e9n6a2bsm10bLpxcpKUEnKOqvb deul7arzsfDvxo+GWi+B9Y+PfgLQP2ernV/F3jrU7DXfh1rmi6FDLZaZepYWVskc83SBYbqyadwR tZJj1JIrmjDL6XvVZ8s4fDF815reyto+Ztxkm1bc6+fH1l+61hL4pXS5Xtdp66Kzi0nrp0P1sj8z yo/Nx5m0bivTOOcV13OElpgFABQB8w/tZaW2p/C+we+0W/1nwTY6/pt74o0fTEaSa+0eOYNOgjX5 pEU7JHjHLJG64OcUnVVNWlPkUvdctVyp9brVJ7N9E2yoU5VZJwjzSjqk7ateul+qT3aSPz1t/ix8 JNe+HH7X/wAFPgtFLd+LfiB4vMXg3QNC0q4txC02jaPBFdtmNVt44bmCZ2ZtpBhYgE4zr7KGCpOp 7WKUHpaak3LdKKTbd299t7vcclisVUXtKM/f3cotJLVNtuy0Sei1eltz9o4VkWGJZX3ShQGb1OOT WV7kEtMDxv46af4I1H4e36fEHx9eeDNAgninHiKw1Y6VLayqfk2zgjknjbzu6YrbDwxdSolgpWn6 Jq3W6lpbvcxrVMNShzYuClDs7/hbW/ax8AWfxy+Pnh/ULPTv2efEWv8Ax50fz1jePxN4bbT44Isg Fhqv7oPgZOSj5xV1cdRoNwzH2c522ot+0v5xXNT/ABRdHATxEfa4RTpQaunVacH9/wC91P1jrmLC gAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKA CgAoAxfDf/Iu6B/15Qf+i1oA2qACgAoAKACgAoAKACgAoAKACgAoAKACgD4E/aff9lW08YRXfjfW da0/44tbRfZH+H8l3/brRD/V4W3z8vUDzMDrW9KliaEXiqeK9hDq5SXI7d4O/N8kS6scR/srwvt7 a25dr9efTl/8C+Rpfsran+05feK/EEfxGtdXb4HrpudDvfHEdtD4ge781NomSD5TEYvMOXJfcF9T Wc8wo4v3IQUpLV1IxcIy8lFv53SS8hrAyw3vuXKn/wAu+b2jXdudk/K13v5H3TUDIJ4vtEE0O90E iFN8Zwy5GMg9jSu+gWXU/LDxD+zn8J/gx8S/Gfir4mftd+MPDtt4qstMh0+K58WyW2oT/ZftIkM8 hOZYwZlEfGE/ef3q7MM86xLlUpTjbROThTs99LNJK3lq767I567yiko05UG3q+Vc7t5+7d6+fbTq e4/s36J+zUPiNq/iD4b/ABrv/iN8TRoz2xudb8QSarcWGm+dE0ixBuERpfI3EdSF9KnFYfME1Wxt VSWyS5ElfVu0Oum7HQr4SzpYWg6d9W3GavbRe9NdL7L1PuWuY3CgD4X+N/hL4ieFvi3J8WfCP7QP gT4cWGsaXBo9xaeJrGN/7WMTM0bOzyKHaMyyBCBkLKwPGK2w0cdKUo4XCRrR0bu579H7u2mnnpfZ GdeWAUY/WsROE/s8qht10aba9dI9N2ewfCrRfj7o3ivUIfi38W/C3iXS/wCzi0OkaNowsLiGVpFC Tsd5Jj2pMuMYJPX5ah16teN54aFOP80ZTld9ve06377FexoUpfu8RUnLtNU0rd/dSfl23PoioKON 8f8Ah/XfFXg3X/D3hjxZd+GNevoPLtdesokllsHyDvRX+UnAI59aFUqUnz0lFyW3Mrx+a6icIVVy VG+V78rs/k+h5D8QPhH8XvFWvrqnhL9o3XfCmki2ihOl2elWdyhkVcNJvkUtljyR0FXHG4qiuWnT pNf3otv8Ht2E8NhavvVXUv8A3Z8q+625p/Cz4YfFLwV4gvNV8b/HrWfG+lS2bW8elajplpapDKXR hMGiUMWCo64PGJD6ClLF4nELlrQpxX9yLT/FvQaw+Gpe9R57/wB6fMrelt/M99qRhQB8L/tV/A+1 8YWvjK70j472Pw3uPHeht4d1+21n7PJZa3bKsiI2yVlKTIszr5iHJUgHoK0o0cfUU1g6Kqp9Gpe6 9uZOO2m6d07ImdfL6coLGzcGtnGSTa6pp6Ndn0u+50/wG8J6fL4+1b4g+Mfj7o/xO+LMmkf2ZAdI e1hg0fTvNSSVYLaFiQJJRCXkbJJSMZ4Fa4rDZgmquLw/sYLSMUpWu9W3KWremnZLTqRRxGBadLB1 HNvVuTTlpolZWSSv06vU+wa5jUKAPh/xqfjZ8N/2g/GXjj4XfAseMPDHirR7C31W6l1m3sZPtdrv ETQ7lJC+XKyupyCURlxlsxGrgozccXGo30cYKSj5ayV09+lnfe+luhiK0V7GpCK6qTevnZLRr8U/ I9h+FfxF+Mni/wAQXmm/EP4DSeCdFis3ni1V9eg1ATTB41WHy0QEZVnbdnA2Y71bngJaYXn5v71N QVvXmeu2hHsMRS96tOEl/dbb/FbHv9ABQB8g/Gu6+Kfiz4zeAvg/4O+JE3w+8N6hoN7rU+vWNnFc XeqXMM0MYs4GlBRCiSmVh94g8cK2NKdedKMvq9OMqm7c1dKPlHrd7t6LTuZzo0puMsTKXs9koy5b y31ktVpeyW+vY6b4ffBH4oeEPF2k+IvEf7S3i/xXo1oJfO0DVLKzigu90Tou9o0DDazBxg9UGeKh 4zG1fcqqly9eWnyv5O+n+Rf1bA0/eowqKXTmqykv/AXo/wCmfTFIYUAfMvjT4mP4d/aS+H3gnxL4 qtdC8C6j4X1G9t4b3ZFFreprcQRiEyvwDFCzOIwct5medlbUqc8XGWHpU1N7vS7tsrLtf4n6dGY1 Zww1sRVm4rZO9op+fy+G/n1M7xf8VrXTvj98AfAvgPxXp+oQ+Im1aHXPDmmvFOILKKzeeO+fZkx7 LiKGEE4DfaSOSBQ8LPA0rVaXJGTsrx5XzLXTurXv52ZMMRTx0+ejU53Hdp3jZ6WfS97W67n1XWJ0 BQB8gfG7RPjdo/xi8AfFH4I/DzSfEV3baPdaLrY1bV1sVnspJUmSNBsYiRJY1cP0wzqQcgiVWoUJ 3r05zTX2UtPO7e/Rrqmn0KdGpXhanUjBp/a5tfJpdO3VPybOp+H/AI7/AGltZ8W6VpvxB+BuheHv CM3m/a9Xs/Ey3slviN2TbCIl3bpAinkYDE9q1eKwVVctKnVUn1ko2+dnf08zNYXEU/eqVqcl2ip3 fpfQ+lqgobjNJpNAcLN8MvANx4vg8ezeE9MfxXDp8ulJqDW6lhaySxyvHjGDmSKNs9flrj+oYdy5 uRW7WVr97d+l+x0fWqyVuZ379fS/byOnt9F0a0mS5tNIsoZ1ztkht0Rhng4IGelaU8Jh6UueFNJ9 0lciWIqzVpTbXqzVrpMjnPFfifSfBnhvWvFmutOuj6VbtdXLWsDzyCNRk7Y0BZj7AE04KMmlKSiu 7dkvVifNb3IuT7Ld+h+c3xc/ah+F2ratoXxN+Fvi/wAV6d8SvDsEkEWn3nhnVDp+vWjMHks7pBFx krlJR80bc9CRXR7tB3jiaU4P4oe0Sv5xfSa6dHs9CPY1665ZYSrGX2Z8uz7NX1i+q+a1Q39m/wCI HhL4sfGDwz47+KfizXta+NtzHdDQPD8Wh6hY6N4Sia3kMscDSRhXmMIdGnkOWyVXGQKirUdeKcK9 ONNaqnGacn0vO3xStrb4Y9C40Z4a8Xh5uT+KpOKS9I6vljf5vqz9PqxGc54s0nVtd8Na1o+g+IZ9 B1i8t2ittZtoklkspCOJFRwVYj0PFCnKm+eCTa2T1XzE4xn7s72fZ2fyfQ+MtW/ZO+Mmt+IfDXiu 9/a68VDxDoBmFjew6Jp8bokqhZYmwnzxttQlDkZRT1Ap/XsdzqcadFO1n7j1W9nr3VxrC4Hk5H7V rfWps+600009D1r4f/CD4x+F/Fuk674r/aT17xVoFt5vn6De6RZW8V3ujdF3SRoGG1mVxg8lADwa qWNxVZclSnSUe8YtP5Nv7/IlYbCU/epOpzdOad181bU+lqgoKAPJ/iz8XvD/AMI9I0m91TTNV1fW dZvBp+k+H9BtvtN7qdxsZykaZAwqI7szEBVU5PQHSnCm1KpWqKEI7t366JJK7bfRL8iJe0lJU6MO aT2V0lpu23oku/ojkvCf7RfhTxJ8OPAfxJv9F1fRdO8TeI28LCz1CJfO07UBfz6eEuNpwoN1AY8g nmRPWq5KU5tUp3ja6bTV9L2s9nv9xN6sY3qRSknZpO9tbXTtr0+XofQtYmpVvHuYrS6lsoFmu0jZ ooWbaJHAO1SewJwM0rpavYLN6I/PD4gXH7Zfi7xB8N/GGlfs9eFdP8U+DdSe7tJ5vFqyxT288TQX Vu6+UOHibhhyroh7EFyxuBUoyjRrPumobPqtdGt19z0YLB4hxcZYil0s0p6W/NPZr5rVI2vE8P7V Xxb8U/CfRfHPwO8PaN8NdK8T6fresvZ+J0uLiQ2s6SwMo8ofLHKqysowX8oLkAmipi8HUj7OlSqp v7UlHS3o+uzfSN+o6eFr0251K9OSSeiU9fv7dOl7N7H3/QIKAPgH4+ftfeA/h/8AGf4Z/DDWPDGo 6lp8mpXsGvvN4buLzy4xpslxCbJghErGURB9mcLvzjBpzo4CtDlxNSm3/efweclbrsvVBH+0YTUs NSqW6cvL7/kveT03d7bMiuP2lvAXijXvAPh34H/CjV77xhqHiLTYbiTUfB01jBZacbhPtlw08iKE McG9lIOd4UYNc/1XJ8K1OM6U5bJQ1ld7NadHq76WR0OWcVk1Vp1acFq3Nxtbqvibd9tEfoHW5zhQ AUAFABQAUAFAFa6uoLO2uL26kEdtBG0sjnoiqMk/kKEr6Afnl8Zf2h/2VfiTaeG9Qs/2lZvBnivw 9dPPpviTSbadZLfzozDLEyyQlHSRWA2kfeVCOQK745djYTU8NOlzK+kpU5Jrrdc3le/Qx9tTcXDE 4eo4u20ZxafS0kr+VutzN8NeMf2Rdb8M/B74A+DfjV5zWHivTtcW3kt7iS88R38V8LwGaR4hzLfN FJI/HpkA1jPLcXCnKrKcJNu8pc8L6u7slLd7Ja6aLWxbxUPaRi6M4q1orkkltZXbWy3b76vqfpRX MWVLyCS6tLq2iuJLeSaNkWeL70RIIDL7jr+FLVaoNOp8F+PvhHrHwu8M3njD4gftyfEXQ/Ddsyo9 7ey2iguxwqKBEWZyeiqCT6V0UK+bYiXLTdHvrRgkl3bbSSM6tHK6SV6VVt6JKtVbb7JJ3Zx3wU1b wf478f6DY+GP24fiBr+r2VxHf/8ACLa3All/a0MTK7x7JYEaSNlGG2HO0k8da1qPM3Tc+ehOH2uS FNtJ+cW3HyfRmfJgKclGWHrU5v4eepVs2vV8r9HufphXGdAUAfIXxC8Vaz4q8BeG9b8U/sl6p4s1 N9Tvbc+F7qWyml06OOR40uSZPl2yqisAOQGGaxrxyzER/fym6fS0JN363ipLRPZm9FY+g7YeVPn6 3nyq3Sz5Xd91ZHmXgmazbxl4TCf8E/Lrw4x1O2x4hddMA0n96v8ApJ2fN+7+/wDLz8vHNZQp5Mmn SnV5ul6c0r9LtzaS7to1nWzhxaqypcvW1W7t1svZq78rq/c/Qqus4woA+I/jn49+D/i/wp8P/idp P7QcPgS/0zVb+00PxfBbi4jllCvbXls0MiFXXKHORw0SkHiumGGxVOsnRVNtLVTlHlafnzLVb6O/ R9TKVSk6fLXhUs/5Yz5k11sovR+aszzHw54g/ZW1XwX8IvgX4R+P+nX9zbeM9M165nlDyXviXUk1 AX3zttAEk995bMey5UYFRPL8ZCDqSlBybvJ88PV8qUt7e6lrp52GsZQnNRVKpGKVor2dSy6Lmk47 dW7rXV6XP0qrE0CgD5W/ath+F3/CI+GL74g3/ii01yDVBH4cfwNJKmszXkkTo8VqI+SGhMm8H5do ySMCrpqcJe3hXVHk3lKzjZ6Waad7u1kk3ez6EvlqfuHR9tz7R9Nb3uuW3V3201vY8+8IP8BvEPwD +AEemaf4g8P/AA0t/Gtpa6fpmox7Lg6xZ6lPHGmoEsTltSt9zMSS0pTP3qn6tduFKupX95y6z+07 XWjfXbRNFOu0+erRs1pZPSH2Vtul03to+h91UgCgDwT41+BfHmuXXgTx98LLzS0+IPg26uJrax1w N9j1O1uITFcW8jr80ZIEbq46NGM5BNT7T2UlOVPnjreKdn6xb0uvPRq6KUI1IuDnyPpK10n5rS6f WzT2fQ+Tfhb8GP2lfEGleDvh38V9D8JeGPhrofje68b3r6VqT6he6tO2sz6xb2yfKqxRpczRbmOS yxY43Gp+tRrQ5KNCcW3rKbVkk72SWrbWjbdlq+wlRhTk51MTGfaMYtXdrXk5Pa+qSV9k2z9La0EF AGc2l6UxZ3020JOSWaFfzPFc31TDyd3Tjf0Rp9YqxV+d29WZdlL4P1Kea206TR7q5i/1kVs0MjJ/ vAcj8a3qZVGjHmqYeyfeNv0MKeZxrS5KddSfZSu/zOlqiwoA8X+N/jufwP4a8OwWWhWWrah4q8Q6 b4YhtNUOLUfbJgkjzeqrEJDt/iIVe9NQo1FKNaLlFp6Ld/f978kyXOpBqVOXK01q+n/B6LzaPJvi n4F+EH7Nngnxj8e/A/wa8IQ654ajXVL6ZLFIJXtEcG48lwPlmERcp2LADvXNQwGFVWPtIycf8TfL 52d1ZbvyWh14nMcZVoumqlvVaPy0s9dl5vU+vInSWOOVM7XUMM8cGtzmJaYHzL+1cfHtt8MNP134 aafr+peMNB8QaXq9vo3h8Dfq6284ke0nO5cQSorI5zxuBwcYpxxKwj55T5Y7S0u3F7pWTs2tn3E8 P9ZXIopy3V3ZKS2bvuk+nU4u0/at8bS29s91+yX8Wobp0UyQi0tHEbkcqG87kA5Ge+Kv6xlL1WKf /guf+Qlhsy60Yf8Ag2P+R9nVmUFABQAUAeffEvRfG+veFp7P4eeNIPC/iZJY5otUurFL2Iqp+aOS JuCrDgkEEdqFOdN3hTjPylez/wDAdbicaU1+9nKK7xtdffp8mfA+rftba/8AAXW49K+JnhLwN4y1 OaZYJLz4SXPnakSTt3S6ftZx6n5wK3+pYGgvbYnDPCP+aXK4v0+GaXykZOvia9qeCr/WVe1rSi16 yV6fy0P05rA2CgDwr9omf4XQ/DHUk+L/AIJufFvg6e4hhbQrPTH1KW5nZv3YSFec5/i4A65FRUpU a0eXEVVTj/M21b5rW/ka0auJpTvhYOU9rK23W/NZW7nwfo3gH9o3UprFf2X/AAn4p+EPhWN0EbfE HWxdWawgjIj0j59mV/2xWkcyhh4KnhXLFL+/BRj8qjtN+VkjOeXKs1LEKFB/9O5Scn/iStC/rex+ stIQUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUA FABQAUAFAGL4b/5F3QP+vKD/ANFrQBtUAFABQAUAFABQAUAFABQAUAFABQAUAFAH5+ftAfF74peD PEXxu8SfB74e+CZLf4ZeGo9Z8R+I/EiyG6v2FtLcra24jwflgjU7mOMyAAcGiEcDTqRnVw7qVHu7 pKK26ptvrZW0B/WatOUFX9nBbRtdt9b9Eui+Z6R8JvH/AO0APi+/w6+N48DxWOoeGZNd0aXwul0J L5o7iCKcEyMQFiE8W4dSbiMjgNW0q1LEU37PDum01e81LR3tayXbXtp3IVB0Gm6/tL/3eW1t7/hb vr2PrusSwoA/N/4keLvhv8L/ANqrx1rvxF+Gmu+L7bxH4d0yO11Oz8My6suhvbGUNbg7SoSYTLJl eQ6OG6rWFWOAxL9ljq8IuOsVJu1nvdJOzvs9brtbXoorMaUXVwFGck/icXFNvpa8k2kt1pbfW579 8Evi58HfH3ijUdI+Hnw31nw/rENg9zLeaj4UfSEeESRqYxKVG5izodncKT2op4XLqL5sHWpzl1UG 7276pabfgKrWzKorYylUjHo5uLV/lKWtr9O59RVuYBQB+Rn7cY8BaNL+0xe/FzQ5bjWtc8BC1+Hm r3llLdWtvKtvOJ7aBlBWG5NwUkLNgsrx4PymhWxGkqvK6XvKLly3v9papSelmtWrLTU1pxrUlehT clU0biuZrsn1S1uns9b7H038PPiLoHxv/adtPHnwruLrUfh54d8E3uj6t4g+zSwWt/e3N7ZzWsMR dV80xR292xYDC+eBn5jWla2Hn9X51KT1ai1JRttdq6u7vRa2WvQxhCcoe1nTcEnZcys3ffR62Vlv 126n2xWYwoA+c/iV4o/aJ8HeKZNW8EfDzQvG3w5aGPfplvfmx1a3kA/eMhfMUqngheD71UcThqa5 MRSn/jhaX3w0fzTF9Wq1Pfo1op/yzTSfpNXt80zmfCX7Z/wN13xG/gXxTr0ngb4iw48/wx4zVbG4 jJ6YfcYyCeh3c+ldkMA8RH2mEkqi8rqX/gMkn9yfqccsZ7CThiI8tuqtKP8A4FG6++x9WxTQ3EMU 8EqSwSKHSSNgyup5BBHBBriknFuMlZo64yU0pRd0zjfH/wAQvCHwu8M3XjDxzq403w7byRxSXfky TbWdgqjbGrMckjoKqlTdaagmlfu1Ffe2kEnJL3YOT7RV39x+X+s/GX9j3xp+0l4x8W/FW/h8W+Gd R8P6fD4evtR0i+uLXRGgaYXVuYjFhHlaSKUOAdw3LkbBnWrgZYi1CriIq2sYqrFJ33d1JarRavZq 3UujXxGFTq0MNPmlpJ+z95W2Wv2X5dVruj64/Z/8T/sh614x1O0/Z/03QrfxgumSSXT6Xo09jIbM SxBwXeNQV8ww/LnOQDjisZZasGvaKal00qqf4cz++35mlTG4rErlr05RW/vQ5Vf1tv5H1/UmQUAf C/xH0r4nfFD49+Lfh03xy1r4Z+ENI0TT77Rbbw7HDHca+ZWlF1OZ5QcrE6RxmNem4E/fFb0sTiox ccFCF4/E5Q53r8Nk9EtHr1ehnKlhISVXG8zUvhSm4R03vbVy1Ts+lrdT1L4N/BjxJ8OPEuoa1rP7 RPjTx9bT2L2q6R4juIJIIGMkbeeojUHeAhUdsSNU1K+Pqq2KUFH+7TUHf1XTy/yKUsub/wBjhaXX 95Keno2/LX/M+lqyKCgD4b/a80z9me41PwDffHbXPEcXiCBZ5NC03wzc3ouX2DEsyw2wLfKJQpc4 GHxWkKWIt7enivYRj15lFXfqm27LZCVSDbo/VFiJSW3JzO3zaS18zyP9m/Wf2RNS+Lngj/hVOvfE q88Z3drdXulrr9xqj2Vzb/Z3Ekv77926bJOG5G50xyRWlWpibOFTM/bJOzhzJ3fmuVbWvutjKFOn 7s45WqN1dT5FGy8nzPe9rWvqfqBXObBQB8e/tPeL/BF9feGfg5qvwMuviz4r1m2m1eHw7bpEiWFp EyxtdSzyYEQLyKi45Y59KmdHBuKq4upKFnaPIm53td25WmlbfW2xdGrjFNwwqja3vObSjbondO7f RW8zi/2cdE/4QbxjbaR4d/Ypk+G2l6qsq3/in+07S5aFVjZ1V8ZkZWdETAOAWBPSoSy5y5qdWtOr snUhK1uvvOTt92r0Nan15QUajpKmukJfooq/zPvatTnCgD4s+Pdp4g8X/Gz4afDbVfiprfgL4Z6j ol9fLdeH7xbGfWtVjliC2jXB5QLA0koQcvtb+4a3oVcWk6eCiufdtx53y7Winpu1d72a8zCtHCK0 8Z70dkublSfd211Wi6b9bHWfDj4C+H/BfjLR/E1j8dfH/iK6s/N2aPrfic3trc74nQ74f4toYsPR lB7VVSpmsoNYmV4df3UY+mqV1r/kTTeVcy+rQip9LTbfnpfsfU9cx0hQB8ifGr4sat8HPitonibW 9I8V6r4DufC15aadpvhuykvI7nWvtMTCOdEB2yPEqLE7fKP3uSM1cMRQinSr1Y018V5dbdE7Pb+X rddhrDV6q58PSdSW2jXu+bu1o+r1tY8k+Hng34sfDv4jfs5+JfFHjLxPqvxE+JE2pzePNDubqS40 vTrf7BPdKsMWNkAtrn7HbowILBz1ycH9oV68Wqsl7OXwQsk49Vbq/dT576XfexH1HD0pL2MPfjrK evv9He+mracVpZLtc/RaoKGEBgQQCp6gjrUuKkrNaAm1qj538c/GnQfh58WLfw1401jRNB8DxeEb vX5L/VHWF7uaO4jjMcLMQD5ce5mUZY+amO9a4fAwxV6dGipSWrdtl6dr3u3oreZlWxH1e1SpNqL0 S7v179l117Hhvww+L3x3m8X/AAR8TfEWPRIvAXxlub2HSfCtvYmC/wDDMa2Vxf2rzS5/elre1IlU gbXlXHSpVTCVFL2WHUYr4Zpu8unvLZKSu1borMuVGrSa56snP7UWlyr/AAta+67J333Pv2kUFAHz b8Y/jl4i8D+LfDHwy+Gnw2u/G/xL1uxn1UWCXaWVrp1jE6RtPcTsCFBkcIqgEkg+laRnhaMPaYmU tXZRiryffskl3ZDp4itLkocqtq5SbSXZWWrbOd8A/tAfEI/EHw38L/jn8H5PBOv+JYpzoWq2Gppq Wn6nPDEZpbcSBVaOURI8gDD5lRsdKaqYPExbw7nGS1cZpJ22umnZ2bV1uL2WJw/L7aUJxel4X0dr 6p6q+tn5H1pWRoFAHz/8bvB3j6/1D4ffEj4XWum6h428F3V1ImiavKYINVtLmHyp4hKAfKkGI3R8 EZQqeGNR7SNKSlUg5w6pfEu0lfRtdnum+pSp+1i4RnyS6Nq69GlrZ+WzSPkn4X/DD9pDxboXgr4X /EP4c6T4N+H2jePLvxxqmqHV1vrrUG/ty41m2tII0UBAJpYVeRjysbYA3Uni6NaHJQp1OdveaUVF J9FdttrTsrvsV9WnSlz1qsHFLSMbtttdW9Ek9bbvQ/TatDMKAPP/AIjfE7wP8JvDp8U+Ptei0zSD MltEzI8slzM2dsUUSAvI5wTtUE4BPQGtaNCVdvlaSSu22kku7b0M51OSyUXKT2SV2/RGF4U+OHw0 8Z+DPBvj7R9fK+GvFWpto+mT3kEkDTXqzTQGFkYZR/Nt5Uw2PmUDqRTdB87jCSlZXundNWvp30/J iVV8qlODjrZprVa21176fNHrtYmoUAeBfFDxPo2hfFH4CWOq6ZogN/f6o0Wu6yQjab5dhJuW2ckA TSh9vPWNZaKeEpYmT/duVTdW+5trqraerT6CniHh6cnKfLB6O+ze6V3t3v5W6nz1bftIfFvUdZ0/ 4saZp3hx/wBmzUPG1r4J0+32S/2nqSTXyacNTikzs8o3bnamPmiXcDkitr4anOWH9jrFNOpfaXbl t8Kfut738jJUasoRr+11lZqHKrcr682/M17y6W0P0CrE2CgAoAKACgAoAKAI2QOrKyhlYEEMMgj3 pPVAnY+NP2ndBi0LVPgp48Hw0l8TfDnwvr0194i0XQrCOe4GbWSO1uvJABmSCZtxQc5Ktg7a5Pq2 Ap/u60Y04S3ly6K2qUrK6i3u/JX0OmNTF1ffoyc5x2i5Wbvo+W7tzJbX6X6nk3iT4s+EPjn40+De l/Ab4Z+IT4z0XxXp+p3Pim98OSaXbaJpqSYv1kllVdxltvNhEYByzqeNoNbOjluDkp0KlOc3oow1 unu5aJJR+JPdNKxP/ClXi44mlOnTWrc2lqtlFKTbb2fSzZ+lFbGAUAfH/wC1HFbaN4g+BfxO8S+E b3xL8OfButXc+tWNjam8exae0eG3vzbAEyrDIxBABKibeB8tZz9jUtQxMlGnLq/hutUpPon917XN KUaybqYaPNUS0S+Jp78t+tunVXPG/Hnxh+F/7Qnir4M+FfgXpN/rHjvS/GOk6xJ4ig0Wezi8P6fb XCyXrS3EiLjzbZZYPLGd3nYxirnh8Jl8lVp1KbqP3UoNNtPR35dOVK716pW1FGpjMVGUKtKcaa1b mrK61ja+rk32+Z+klMgKAPz3+Pfiv9rSx+P3wat/hz8MdPv/AARZ6rqJgnGtvDFq8baTNlb9QhEC JISyE53PGg43U1mOHw/7mVOp72jty+9bVct9rbu/RMP7Oq4j98q0Fy6q8ZNwvp71n719ly7XV9md Lff8NkfEnWPA+ia94G8K+A/DNj4g07VtT1zS/EMl9cyWttOk0ltHEEUHzlQxMWONrtxT/tGklbC0 Kik9LzcOVJ76LV6beevQPqHXEYmE0tUowmm2ttZOyV9T7jqQCgD5m+Ofjm0+HcPgDwZ4S+EVn4z8 aeLNRuYdH8P4gtbaMxxNPc3EsjqVjVV5JAyxf61lHC4D2b+tRvCO0Yx5m2+yei7tvY09vjHNfV6n LJ7yk2kkl1tq+yX+R5j4Q1T9pd/FnhlNe/ZO+Hmj6E2oW4vdXsddhlmsIDIvmTRoIQWdFywAIyQB msoxya69lg6sZdG1CyfRu2tk+wc2bNfvcZTlHql7S7XZXdtfPQ+566jMKAPnf45+GPHsmq/Db4of DTQ7LX/E/gm7u3bw5fXAtRqVpdQGGVYpiCI51xGysRggOv8AFUOcKcourFyh15dWu0kuttrdm7al wh7SLjGajLo3s/J21Sffo0r6HyD8LfBn7Qnjzw34K+E/i/4OyeCPBmk/EK78b6vr+q6nDcTXMY1+ 41q2tbaGP+IySQRvIxxtVyByKX1vDVIWw6m5t7yjyxik99XdtrZLZvVuxbwlWjLmrVIONtotybbX orJPXzt5n6jVoYhQB8UftizaTJJ8EtJ8e+O7rwv8GdU8QyWvia5sdS/s+S5Jtn+xxvKCHEBudgfb 3ZM4XJHThfrcpOngm4zl9pK7VtbJvROWyb9Fq0Y1vq0UqmKipxjryu9n5tL4uXe3a76HN+Dfg5+x XpXi/wALan4V+Ithc+KLTUrafTbZPHD3JmullVolEXnnzCXCjZg5zjBzXTUwufxg3WrV3C2t9rdb +7tbfyIjjstm1GnQpKT2ahZ36WfR9j77rzTpCgD5R/bFvPI+FGlWGo6/eaF4I1bxNpGm+KNZsJGh ks9IluVWc+avMaOfLieT+FJGbjFaUalSE0qEuWpLSL7N9r6X6R87EzpwnFyqx5ox95rul37pbtdU mfMvx3+E37MvwY+FOo/E34Jz6V4f+LeirDceFLvw9qzS3Os6jvHkWrRiRvtCTuwjZSDlXJ461rTw uZYFyxFSdTkSvPnbcXHqnzaXfS2t7WMpY/B5glhqapyk9I8ijzRfRrl1Vnq76W3P1ChZ2iieVdsr KCyjse4rmdjcmoA8/wDiZ8NvCnxa8Hal4I8Y2ks2j3jRSiS2laGa1nicSRTQyLykiSKrKw5BFZzU pJShJxkndNbprr/W60LpyUW+aKlFqzT1TT6M+Zrf9jG11O+tIviT8c/iP458FWtxFcp4T8Q6krWU zRMGQThFDTKGVSVc4OOa0rYrMMTB0atSKg9+SnGEmuqcl0fWxUKeAoONShh7TWzc5SSfdRbtddOx 9sDHbpSRkLTA+Ev2vfiL+0L4Tv8A4b6d8Jvhpealocnizw80+t2GrLA93uvgJbCSHYSsMiAK8pO1 VkJPSrhjMLhVarzcz0+FONnpo2/j/lXe2pLwdfFawcbLWzbumtbu32V18rlfx54y/bO+IHhLXPBX hn4EWXgrWtahNpB4tk8WxTf2KWIBuAiRhmZBlgo6kAU/r+CpLnoU6sprZShFRv8A3m29O+mwLAYi p7uIq0uR725m7eS017dtz7xjDrHGJG3OFAZsY3H1rIZJTGFABQB4F+0r4X+GPjH4S67onxe8Z3Hh bwRJJE9xrFrqh0143U5VfNBGcnjZ/F0wa1oRxk58uBm4VO6tt130M6lTD0kpYmCnHtZvXpa2t+x+ cPgTxr4l+GU9lov7IHh1fi7pyTJE82oeEP7LSOLIDM2r4QyEA53MGzWMvqOFlbMVTqVP+ncpSqt+ j5qa87NHXyYzGJui6lGFtFVcVTv6aVHf5H7N0zAKAPAv2ifFvijwx4L0Gx8HazbaJr3ijxBp3h2P xDeRLKmjrdS7WuNjfKX2gogbgySJmrpNKV1BTl9mL2b8+tlvZb2sROKlH35OMPtNb28u13ZX6Xv0 PlxPHXxI+FXwC/bLvb34m6n4i8U/DTxPNHomta8IzNcBNJ0i9S1KqACJJrmWMKBnEuBzitIYirVl GpVjFuK97lioppXbdujt16WT6Gc6NGCcKTlFSel5OTu7WV3q9enXU/RuGQyQxSshQsoYqeq5HSuf TobktMAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACg AoAKACgAoAxfDf8AyLugf9eUH/otaANqgAoAKACgAoAKACgAoAKACgAoAKACgAoA+Rfi342/Zs+F /jfxa/xN8WLba94/8Pw6XqvhxUmuxfWMRnRZXt4kYqStzLGXONygD+GtaeAq4inKUpqNOWnvSjHW 2tm2nta9uyJeJ5JxVOlKc46+6m9OifTe9uurPMP2VE+Bd78SNSvPBfxj8Y+P/GWnaBJY6cPFkVyo 0TR/PgLwwtJEiktILbcxJdhGvYGnXhiZONTEV6c7aJQ5E9d5SUW7vTfb7wpulFONHCzpJ6ty5rab Jc2y1ei/Q/QmsSjjfH8Pji48G+IIfhte6ZaeOXgxptzrMbS2scuRzKq8lcbunfFCqey9/k57fZva /lfoJw9quTn5L9bXt8nueQ/EHT/2qZ9fV/hh4h+Htt4Z+zRAx+ILK6kuPPx+8OY2A2E9B1prFU6f uywntPPnt8rW6CeGVX3vrMoeShF/O7ZpfCyy/aTttfvJPjHrngS98MmzYW8Xhe0uobgXW+PaWaRi NmzzQQOclfQ0PEQre7HC+z8+fm+VrL7/ACGsOqWqxDqeTio/O6f4Hv1IYUAfG3xL+Ifxu8YfE7xb 8JPg14E8GXll4WsLC71jV/HUkjRSS3YkaKKCCMZYBImLOeMnA5BoqvBKnFVsPKvLXROMYx23ck9X vZdLDpRrSm3HEexXSybk/PdJLp5u53HwZt/2k7LW7u1+LmmfDqy8GpZP9lj8GrcpMLrzI9u5X+Xy /L83OOc7feohVocvs6GEdHrfnjJPysktfPyHOlOL9pPFOq9rONvne7+7zPpGrJOP8beO/B/w38P3 Hirxz4gtNF8OwSJHJf3rFY0Z22qCQD1JxWlGjOvLkha/m0vxdkZ1Kipx5mm/ROT+5Js+APid8XPg l8VfFkr6p+2yug/C8QxoPC3hWb7DLdPg+YZrwKZNrE/dXAAruWHzSkuTDezh/fvCU/leVo27pXOd 1svqe9iKVWb/AJXCoofNKN353Z6b8HfDH7DPjGDWfh18L7Hwd4pu57NrrUoZkN/dXEAdEaSWaUFz 88iDOerCvLxeTy5vrOLk5zb+J1FKXy5XdfJJHoYfNpu1PDp04rp7OUI/jFJ/O7PsrQND0rwxoWi+ G9Cs0tNE0m0hsbK1QkrBBEgSNBnnAVQOfSmr/abb7vVvzb7kSd23a3pp+BoTwW9zEYrqGKWHOSkq hl/I1E6cK0eWcU12auEajpPmi7fgUf7H0P8A6BVj/wB+E/wrL6hhv+fUf/AV/kX9dqf8/X9//BJ7 ax060cyWllbQyEbS0MaqSPTgdOKqnhqNF81OCi/JJEyxE6ytKbfzuX63JCgD8uvjjF+zbeftUeI7 X9qbxTbNZjw3Yt4Rtbu+nht9MXc/25GWLBWWRjbuCThkGB9w1vSpYvEWVCs6Tje3LKMHJPdtt62t az20avdmbqU8PecqHtE7XbhKai1srJNK93qut07WR7h+zhpv7G9n421aX9njWNJvPGZ0uRbqOx1C 5uXFl50JclZGIA8zyeevI96qthsdRipYmvKpHs6kZa97Jv7xQxVCs+SlQUHvf2cofK7ivu/yPtWu Y1CgDxDVPAGrzfHvQviPDa2lz4dm8J3egXrzNiexl+0xTwvECOVcGdXxg5SP0rGcY1JKNSN+z0aT 66eeln5W6lxfLFuMrPqu66fd+vkfMvwj+Gfx20bxR+z94B8QeDdO0jwL8GYrmyTxrbakssviixFh LY2sAgADRhg8E8oYkCS3XHanCtRtFUqUlVatNtJRt15X9q8kmuyvcc6ElzSnVi4XvBK/Nf8AvX0V k2vPc/QmtTMMigD5N+NngT46XfxQ8A/Ez4FDwlFqel6bdaXqb+JZbjbqNpM6yC3Kx9lkjjkV/vA7 h0Y0lXWGneVCVRPR2lGNvNXT978LN36DVFYmFvb8ltV7vN/Sfbukzc+H93+1rL4u0lPidpPw0g8D nzftsvh+a9a7H7p/L8sSfL/rPLzn+HdjnFayxeHqrlhhZwfdzg0vVJJvsL6p7L3vrPPbpyWv87/M +lqzAKAPhr9q9PgVqfifwTofxA+Cet/E74gtZXF7pmj6DA8sljaRuqyTu29VjXfIFDE5JJA6Ghxp KKq18VKjFPTlcrt26KOrst35oqnLENunhqMZu125cqSXS7knu9lY8X/Zo1f4Aal8UfhXqfgX9lXx T4N1LxHpl1rGgeLdVb/RpLT7KS0iEytu3xzqoGM/vQcYBIqU6DcoU8bVqyjvGSly+ru7WXR97d0T z4zljKth6UISW8ZQcr72sop37q+1+x+ptSByfjew8V6p4R8Q6f4G1220XxfcWzpp2q3lt9pitJj9 13i43gelCm6fvqKk10baT8m1r9wKMJvlqNqL3cbX+V9LnlXw28Z+OtEvz8P/AI7a54Q/4TQQpNpm p6Tdi2/t+LLq7i0kO6N0Kru2kqd/GMVuqcsdB1aeHceX4l8UV2cXvbfdXXfUxqTo4OShKupJ7cy5 Zekvst9rb9j30qpYMVG8AgNjnFczim721N7u1iSqEFAHx/8AtIeLNFn8S+Efh5a/ACH4reNBaTa9 HZ3jW8Fvo9rG6R+dJNKCFLyEKEA+bYf7tRUoYGcVPGuXZKCbk++zXu7XvoXSq4yMnHCOMdLtydl5 WVnd77bfM8/+E3x/8S/Frx98A9Y8Xfs5Q+HdH8U6Pd6n4X8W3WtwXBgt5LRZjHFEqgiaSMR/J1EY kOcKwreawFRuFB1OaGqTjaNtubfZXsv8S7mcPrtKHNVnDkna6V277pa7dX8n5H6AVmMKAPk343eA /jrd/FDwB8S/gUPCUGp6Tp11pmqN4lknA1K0ldXFuVj7LJHHIr/eBDDoxqY4iOHnd0JVE1Z2lGNv NXXxX+TTd9bFewVeNnW9nZ3Xu8z/AD2fbukzyPXvA37cPib4heB/HusWXwjmHhFLmTS9JE2oCGG8 njaF7pm+8ziB5YlB4Alc9TVyx1GUkvqU1Ba/xIXb23tay7dXvshxwSim/rmrVv4eyvfa+7tv206s +2/h/J48l8JaQ/xNg0aHxufN+3R+H2kazX96/l+WZPm/1fl5z/FuxxilKpGq+eEHBPo2m16tWTI9 n7P3Ofnt1ta/y/A7OgD82P2nPgH4h8CfCX44fF/w5+0P8VLfXNG0jUtds7Bdc/0WGVEeVYwm3/Vg 4AGegrWnj8yhJfvouK6ezht2vv8AMieEy6cX/s/vPrzS372vY9a8BfstXmk3/g3xdP8AtDfFfUns 5bTUX07UNd8y2uyhWQxSpt+aNsbWXuCRUPHZlP3Z1ouL3XsoLT13Xr0KWFy6OsMPaXR88t+9rn2b UjCgD5m/aA0jxNaa58Jvir4e8FS+MYfBF/eTXvhu1KfaZYbm2aH7RbK/ytPEcYU4JSSTBzis5yo6 QxV/ZPdpXs1s3Hqt79rp9C4Qqyu8O0qnS7smuqv0b0300t1Pjj4XS/Ev4n+DvAXwag+DHi3w3Z2H xMu/Gus+JvE1stnBZWUfiS51qGKEbi0k8itBEQBhdznJxSWKwUoL6tV553skotJJOzbbSt7uyW91 5jeFxUZc2IioQtfWSbbtokl2e7fbzP1grUzCgD5g/agvvCl34c8K+BNZ+EsXxI8S+J9RaLRfC00i woZYYmkluJJ2/wBTHHHu3OOTvC/xUnToNe0xE5RUduS/O29LRs1ur3u7JXbLpVsRCfLhrXe7l8KX dpp31tZWvc888NfEfwfrHwP+Bvi3xh8J7LStNsfHkPhqHQLGdZLbw7qEGq3Oj288eABIq3MceOOP NDfw0/YYd2p0XKEN0nu2vetK3mvvtch1cQm6lVxlO7u0nqm7XjfbR/ddH3FQAUAFABQAUAFABQAU AfN/x8+IvxH8M6j8L/AHwlsNGPjjx1qNzaQap4iL/YtNht7Z7iV2VPmkkKphEB5+Y9FNXTqU6alK dN1GlpFO1+7b6JdeuxnOnKq1FVOSPWVrtdkk9Lvz0Oc8NeG/2zLbxDoU3in4kfDS58MJeQvqVtp+ iXUU81sHBlWJi+FcpuAJ4BINZxxa1jHAxhfqqknbztbW29jT6nSj7yxdSTXRwppPybWqXpqfWdMA oA8j+LXg7x/4r03Spvh18T5vBut6bM8xlayivba+Urjy7iN/4O+QQRTVWrT0p04TT0cZp6+jWqYp QoTV60pRts4uzX36NeTPkjw1+1j4m8C/FHwd8F/iV4f8J+JNe8R6nBpaa58Lbs3QtZJGCCW+tMFo EGQWYtgDnFdDw2EoQ9pVoPCzeylytTfaLVpa9Lr5mMalfESSw9b6xBbuzi4rq29YP0iz9E65jcKA PlL9pnU/Hcuo/BrwL4V8dXHgfw/4u1yaw1nxfZxI89oqWsksFvEzgrG88qBA59No5YCtKNWpTfLQ hGVV/DzK6VtZPl6u2y9X0M6lOlJc+Ik1TW6T5W76K73SvvbuiDw3+zj4q0PxFoOt3P7UHxL1a30+ 8hun0u/v4GgvVR1YwygICUcDawHYmqeMzGScZunyve1GKdutnfR9n0BLK/8Al3B83T97J69NL6+n U+tKxNAoA+Mv2s7Xxpr+s/s/+D/h3e2Og+NNU8TSz2Pje/jaRdCNvaSyuiIMCR7iISQ+Wx2sjP3A pwq+wlz04c9TpFu0Wvtc3VpLtrez6D5I1YuNWTjTdrtLW/2bX0Tv1+XU3fDfw+/azsvEOhXniX9o Lw5qPh2C8hlv9Pt/CscD3durgyRLJv8AkLIGUN2zmreOqTXK8HTjfqp1G15pPRtdL6dw+q4aPvRr VW10ahZ+tlex9YVmIKAPkj9qK78T3F98GPCFn8QL/wADeBPEuuy2XiDxRpMiQ3MQFtI9rbpM3EIn mUIX9dq9WFbUKlaEuTCxTqS2co8yVtXZbOVtr9n1MqsaDXPidaa3V7Xvom3vyp727q+lyp4Y/Zx0 DQvEnh/W4f2i/iVqc2n30F0mm3/ivz4LxkcMIpY8fOjY2svcEjvWkqucOLVWS5ev7qK066209ehl F5PzL2VOPN0/eN69NL66n2FXKdQUAfH/AMRfFV/4u8A+Gtb8X/slaz4tv31S9t/+EXuvsc82nJE7 xpcsZDt2yqisuOcMM1jXWWV1+/nPk6WhK9+t0mnZPZv1N6KzCg2sO6fP1vNJW6Wbi7vuvU8t8EHQ j408I+R/wT61Dw5L/adrs8QyW2mquknzVxckqdwEf3/l5+Xjms4wyhNOlVquXS8KiV+l25WS7t6G s62cOL9q6XL1tVi3brZciu+yurn6JV1HGFAHx5+0/wDtRfCj4NL4d8EeMbnSb+/8Q6tpWnanoWqR yOsek3lz5E90wClWEaCRtp67cYrohgoYmm/a2cXp8UU+bpdN3te1307mTr1qU4yoJ3Wt+WTVuqTW l30X4HzDqvj79gT4WWWtfEL4H+EvCuv/ABftI/M0HRbGwu5Zry9JAjihUoRGzE4DADb17VnLKFQi quNrOVKGtnWUrW7Lmd320ep0fX8XW5oYei4znpf2XLf/ABPlWnfU/VyNmeNHZChZQSp6r7VkQS0w PD/j58TvEHwt8FadqPg/w7BrfjPXdZsfD2j2F7OYLc3l3KI0eeTqsajcxxycADkirpulFuVZNpXd o/E/JX0Xq9lqRKM5WjCSjfq9ku9uvkurseUKv7eDBS03wbUnqPL1I4/8ep/X6H/QFL/wbH/5Ef1F 3/33/wAp/wDBPsesygoAw9e8RaF4atrO81/UoLO2ubu3sYHnP+tuJpFjijUdSzOygD3pwoutpFXt r06ev9diJ1Y0rXe7t836f0jzbxl+0B8Hvh9400P4e+MPHVhpvi7Vlie3sZt52rI/lxGVwCsQdwVU uRkg4rppYKrWh7SNutk2k3beybu7eRjUxMacmuVtK12k2o325n0PZa5TpCgAoAKAMHXvDfh7xVYx 6b4l0Sx1XTkmSdbXUIFnjEiHKttYEZB6VjVowxEeSoro0pVp0Jc9OVmaFkmnwRCz05baOGEbfItg oEY9No6VpDDrDxtCHKvSxj9ZVeTfPzPrrdl6qKCgD5n/AGk/iL8G/DvhfS/BPxYTTdT0rxdrOl6D No895FFJAt5crCl2wZgyxxPiQyDBXZkEYrengamJjzpSSv7sop/H9lJrZ3t/kYyxscNOyab6p/y/ abXVWvp1Pk3xD8Kf2L/gVo/ij4wS+M7rxh/Yk6+IU8MXvjEagl7fRLGkTR2xciWcCKJU3Bv9Wg7C tJZdm04yjj6tX2Ld53jZadZNJXWiurq5MMwwEGpYKjTVW1o8t769I6vlu3vbqfqNHIJY45FBCuoY Bhg4PrXIdBJQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQA UAFABQAUAFABQAUAYvhv/kXdA/68oP8A0WtAG1QAUAFABQAUAFABQAUAFABQAUAFABQBwfxG8aXH gDwrdeJbXwhrniaWGSOMaT4egE91IHYDcqEgELnJ56UKVGLviJ8ke9m/wWonGrPSjHml2bUfxeh+ f+lfGHxLovx58cfE1P2T/iff6P4u0ewtLme50aE3WnXFmZVVI8ucwypNkgEbXjJ53cZTlk9adq2I UrL3W4SaXdWa01s015p7I1jTzOnBeyppd17SOvZ3/Bp+Vup9cfCf4y3PxE8Q3uizfBHxv4OSGye6 /tPxJpsdrBMQ8a+SrKxJc79wGOiN6VUYZbHXBVFKXVKDjp6tLy0Jl9ft/tUbR/xqWvovzPoSrJCg D5P+O/7VejfBW48RWNj4B8ReML7w3pP9u6//AGGiLDodiQ5WS4lcgBmWKVlQZYhSeOK2prDR5frN XlcnZJRcn6tLaPS7MprEzUpUKaaju3JRV+y3bfke6SeP9Gg+JVp8LriOaPX73Q5detZGH7u4ghnj gmCn+8jTwEj0lX3qFGLg5J6prTyd7P8AB37adyuaSmlbR9fNdLfl317HeVBYUAfn9478EfEL4l/t WeKoPD/xZuPhifDnhawjsZdIsoZrnxPBcSSvLJKZfleO3kjCKACUaRicCQZuFbEUoyeDpxe3O5py V/s2j00v73XVdDOpTwrs8bKWt+RRlyW25veWuumm2z7nv3wo+FvxJ8D+Ib3VfGP7QOueOtNmsnt4 9J1OwtbeOGQvGwmDRDcWCoy4PGJD7VMsTi62leFNL+5Bxd/W+3kEYYCLvhefm/vVHNW9LLXz+XU+ g6RoZOsWWk3+nXMWtadb3unKvmPb3MKzq23nOwggnjisqtGnWjyVUmvPYunVqUpc9JtPy0Z+Znhz 9sz9nS/+KXxL8Oap8P1XwbpVjpE2kTweCp2uZZZxdfaRNGIsooMUGwkDdufGcUPLMncVHmopr7XM rS8lpvHr6o1WKzzmdqddvT3esfN+99rp6M98+Dnxn8MfEr4xvpXwl+HUtn8O7Tw5cT6t4juvDz6U 0eoG5txb20bOqmQNEbh2GMDy0NEKGW4WXJhXCVR63g72XZ6W1drddGKrLM6sefGKcIbKM92+6V3t t8z7NrUwOD+I3w78OfFLwtd+D/FX246LcyRyuNPu5LSXcjBlxJGQwGQOM80RnWpvmoVHCXeNr/im Ncj/AIkFNdpK6PzbsP2bvgNL+0r48+HniXxP4h0PR9A0DTrnStFu/Fd5C2tvctM092GeQbli8pIg qng7yeorsp4jOcRC1DF1ZKPxW5XJN7L4dFbrbV6dDGrPL8M1Ovh6Ueb4bxtHTfW+sr/crdz1H4I+ DPhn8K/2tPEHgz4ZeI9Q8QWGq+CpNRvEuNam1NfDksV5bRiIlnZR9pDb1U/MptXxw5qcRUx6gqWY VZyvrFSsrrZtqy2drS82uiFSlhMRJ1sHTgktJOK0u9VZ7a2fMvJM/Q+uU2CgD4t+K3inx/4u+K+r /DT4MfCjwVrWs6BYWl34h8V+OI829mbjzDb20SopeSTZGXPOFV19ayq0cvVp4jDutUl0XKrJaXlK V99bJdjWjUxkrxpYn2NNerbb7JNKyW7fWxsfBLxf4m0z4i6l8Kfiv8MPCnhf4ito7axpur+EFBs9 c09Jo4p9pKh0eKWW33I3BEqEU6VDAWdXC0HSktHF8rdnqmpR0a09U1ruKtWxl1Tr1/aweqeq1W6c W3Z66NaNXPrqtDMKAPHPi38dfh58FbTSpvGt/dnUNUaQWOk6VaSXt5eCMAyMkMYJ2qCuWOANw55r WFKMoupUqRhBac0nZXey836GcpTclCjTlUk9bRV3ZdXeyS9Wa+gfFnwN4jsfhZf6dqrCD4iaaNV8 PefGUN7D9nS6xg/dfyZA+084Vv7polSs5pST5e3VXtdd1e33oSqaQbi1zfg7Xs/Pf7memVkamXrG mW+t6TqmjXbSrZ39tJaytA5jcI6lSVYcqcE4I6GleS1i7Po+waPdXXZ7M+T/ABX8Cfg34m1v4c/B 7UvEHjePV/DvhlmsV03XbqA/2fDJFCJLqVWG+RnYAM3LbX9DWqrY6MPaU8XKEm9bct5PrKzi9uu2 5MlhKk+WrhITW6vF8sV0itVa/Ra6I8W+AI/Zri+NWjw+BNV+J0mrxS6jb6FrHiTUrybRvEMsEckV 0tq0jFJyi+awyORGWXO2taksXLmpVMwdVx+Onpdbb2itm1ez0e5lCGHSjVhgIUoy+GaWv/pTtdXt dao/S2uY3I5ZYoI3lmlSOJRlndgoUepJpxi5O0VdilJQXNJ2R4xfeGrGX4x6P8TbPxVpS6efDl14 f1PTppELXCmeKe3kjcH5djC4VgeolH92r+rYlSt7JtNb2d0/u2fX0Rj9cwrj/FV0+6s1569Onqz5 0+FvwS+J2h+MPg54Z8QePPCd38IvhJJct4Wj0nf/AGpqMZsp7G2iuyTtCw21w4bb99kRj0qX9ZUI xlhnBrSU76SXkraXdm79VoaqeElKUoYjnctYwsvde71T1srqPk9T72qSgoA+O/2ptc/Z0jXQfDPx i8D3Xi7xbfRO+jaPoelzXepMoYAtDJFgxDdjkuozQqFP/eamIVDl2lzuL+SWsvuZpTq4rWjh6Dqp 7qycf+3nLRfmfPXw18CftoWWsnVfhXdT+C/hdHCWt/Cfxc1I65c3DdVVDH89snbBZiPetJZw6j5V TeJj/PJKlL5W1lp1krGX9mU4vnlUVCX8tK84rzfN7v8A4D/kfoj8O9Q8c6p4N0a9+JXh+w0Txs4l W/07TLo3VvGyyuqNHIQCVdFR8EZG/B5FZupTqvnpRlFPpK113vbTfZ9UPklT9yU1Jrqk0n8nqvPz O4oA81vfh7HcfFTRfifbarJBNBod1oN9pvlho7+GSaKaJieqtE6S4x1Ez57VHv8ANpbla176bW/G /wAuxXuOOt+ZbdvO6+5r/gnzx8O/2YvGfhHxl8Of7d+KSar8I/hpNcz+DPDMWnLBPZmS2mtIkubj OZUgtrmWNOBnIJ6UlWxE4wpShFKO8k3zSSVldPRdG7btFunhouVWm5OUvsu3LHW75bavyvsmfaNa GRzfi3wxp/jPwzrfhXVZryLTtVt3tppdPuGt5kRuCUkXlW9COaFKcfepScZdGt194WhLSpFSj1T2 fk/I/O34v/BP9mz4Mpo1vr+u/F3VfEGriZ7HQfDviDUL68uI4gDLL5at8sablBdiBlgOpreniMw5 XUrZnKnC9rycd30SUG2/kZuhgpz9nQyynOVr6Rei7tuVkuh6R8Hfhz8AvDOv/Af4jeFPEnjyS/8A HumSap4ai17XLu5t7mOSw88pNE7FfM+zTO4U55jYj7tEp4+fPCrjZVIx3i+W0le11aKdk7Pp0BRw cOWVPBQpyf2op3i7bXv1V1t3Pu6sDQKAPhD4jfshfE74l2fjXQdb/a38cr4M8Si6guNBTT7MwpaT FgbcNt3FQjbM5zgU6mOx8oOnGFFLa/J73re+/mVTw2XRmqkoVG9/4suVv0ta3l8jpfB/7Nnxi8Ma /wCGNT1D9rzxzrGi6Vd2802iXen2Sw30MbqTA7Ku4K6rtJHOCaf1/HzXJOFFJ72p2dvJ30fmT9Uy +PvQjV5ul60mr+atqvI+yqkAoA+XP2jtf+JMWqfB74ffD3xXD4QTxrrM9hf+L5bRbprBIrWWdIYV f5BNM0ZVS3HykDJIFaUqzpN+zpqdS2ilfl03bS1dl0+eyM6lKFRKVabjTT15XZu+yv0Te7+XUoeG /gN8a9G8Q6Dq+r/tYeK9Y0qxvIbm50m40eyjjv4kcM0Lso3KrgFSRyAah47HT92cKKT3tBp28nfR 9mX9Uy+PvQjVv0vWbV+l1bVd11PrKkMKAPmD9o62s4Zfht4j0r4m6H4J+Jek6hOfD134kI+xal5s Pl3FpMCRlHQq2QQwaNSOla0KWIqT58PSVS28W7XT7Napro0n2ejM6tShGFsRNwTekkr8r876Wet7 29bo8H+FP7Ovx7vrHwZ4Y+LPjLwb/wAKr0LxZdeNf7P8KRTSTa1fSapPqsKyTSHCQR3U4cBeWESA nrWE8RVnH2P1b2TvrKUruyd0kktHaybfnbc2hSoRfto13V00SilG9rNt3u+rSWl/Q/ReqJCgAoAK ACgAoAKACgD5K/az0PwLr3h3wTH43+OcvwwSx1Zb/T9YtpIYppbqJcqI5JB8pALZx1VmU5BNa0KO MqzUsDy80eskno9Latb7PuiJ1sJSi1jISlB6Wi5L7+VN6brazPDvAGreDrjxx4Phs/8AgoVq3ia6 Op2uzw689iw1Y+auLdgqbsSHCHHPzV11KWcRg3VjRUOtoRTt5Pm37HJGtk8pqFKNZTe151Wr+acU mu99O5+k1eedwUAfJX7W5+Dq+E/CrfGfxD4lt9Bk1LyLTw94WnuFuPENyyEi3MUHzyqFV2KggAAk mtaP1hKU6OIVCKXvS0WnTVp2u+yuyH7NzjF4f282/dja+vV2ulp3eiOB+Dvxh/Z98J6l4f8ABXwy +AvjTw22q3cNil2fB01sivK4QPcXDfMEBbLMxOBk1zRw2WKTqrGU6lTu5SlJvsm1u/kjrqzzSpHl q4eUYL/Aopd7J9PQ+860OcKAPk/9rTTvgrqnhDwxZfGLwzrXib7RqaxaH4a8P+c95qV7tLgRxxsu 7YsbSFmICBc5BxVKDlFzeIdCEbNyTt10Wzbd9kt/S44zamowoqrN3smla1tW29Erbt+R4J8MPhz+ ynH4a+E/xwsvBHivQpNQ8Wx6LYwatqt48mm6tDqMtnGlyhlKhftlr5fOQWdAetbuvjKsnGOYVJwa vq7KStdqzjfVX06idSKheeEpxlezsk7a2TTW+tnp69D9K65gCgD5X/az8NfCDXfh9pmo/Grx9rHh XwppGow3UFzot+9pLPeZBhVdgLu4YZVVGcg9s1rRp4qpL/ZKig1q5NR0Xe8tFvZ907GdSrQprlrU vac2ijq2+tklvt8rHzX8Ek/Z08ZfETw5ZeE/2hfi3N4stLmPULPQPFWr3tqmqCBllKiOaNRMmB8y A5K54xmumVTMqlOUoY2FWC+JQUHZPTWyur7XRkqeEpSSqYB0pP4XJSWtrq3vNX6pPsfp5XCdIUAf EPxp8UfB74o/DfwrrfxU+BPjnxPoT6veW9tocGjTS3NrNBI0ZmlhR1IRvL3IxJzlSKUpYWe2NVOH 815RTa6aJu6ZpShjYO0cMpT6puLsns9dNV/wTxT4e6b+yqnj7wRJ4c/ZU+Jmk+IV1ezNjq1/od5H BY3HnJ5c0rtMQqI21mJBAAOQar2lB7Ztzv8Al55vm8rONnfbXQt08ck3LBRiurtTul30108tT9Sa RgFAHzT8eviZP8KvEfwf8T65qWo6f8LV1C+j1+70+1kuQJDaP9kSdUVmERk3nIH31jB61pRkpS9i 5Ri59ZWS01sm9E3vfsmupnUpTkvawjKXL0jvrpdrql27tPofMUGtfGW7PgX9pS58Z+KLG58ZeP8A TtI0b4aTptsh4bub1bVfOtyu5bg2nmXrOSCh4PAo/tByTjBwdBe78K5pPbmUt9ZbLZxG8DGNueMv b7t3do9XFpaWUdH/AHvkfpnWZYUAcJ4y+Gngb4gro/8Awl/hqy1NtL1C01W1eeIFo7m2kEsLbupC uAdvQ9xXNWwlGu+aa179Wuz8n1RtSxNSkrRenbs+6810Zv2/hvw5azR3NroGmw3EZ3LLFaRqyH1B AyKmOAwsGpRpRTX91Dli681aVSTXqzcrrMAoA8L/AGjPAdv8RvhN4h8O3nj1PBlirRXs3iVoonOn rC4kEqNIQI3VlVlkzlSoIpwjXnOKw0VKpfS99+j07fda99CZTowi5YhtQtrZ2unpbZ/1Y+L/AAN4 lv8Ax7rlr4R8G/8ABR2LVtefCQ2iaHYCS6IyPkLACQ/Kfu5r0qizanBzlhqDS3tdteqUnY5UstvH mdeKlteUop+jcEfqJXmHYFAHhfxv8K6h488KaefBniXR7Dxl4X12z1nT5tWPmWgu7ds+TcqpyA8b uOPmUsrDpVOnVi4tUnNb8uq5l5P8U9rpEKrQakp1OVbcys+V+j+5rs2fOmqfAHXPEXwY+PumeLfF nhPU/jd8WmK6jrELhbTSYfLjtoIrbcS+y2gUyL3aUs3G6pq4fE1pvEvDPmj8Ed3G23vW3veUmvRd B08XhKUVQhiVyv4pO3vN76J7W91X2W/U++Yk8uKOLcWCKF3N1OB1NLcompgFABQB8tftc6vf2Hww 0XS4vFV14X0HxD4n0jQ9c8SWUnlS6ZptxcBJmWX/AJZF/lh8z+Hzt3atKE6sZpULe0ekb62b62e7 S2XexnUp06kW6yvBayXdLvbW3fyufNvxu+BXwf8A2d/hZrPxl+EHiLVNA+JPhqKO80aZNfnuh4hu g48uymid2E4uC3lEAZ/eZHStYTzOnKU61epOC1mp2ceVb9Fyvs1s7E1K2X4lKnGlTUpP3XBJSUul rPXzTurXP0xhdpIondNjsoJQ/wAJx0rl0eqNiamB8FftZaf+yPqfiTwrb/GnR11P4hWtxY6tBZ6L psmoajPa2s5kWOVI1Yi2dg6sGwGBYCpqYLngsRVrqjC9ryk4p90lffX4krrua0cZXUnQw9GVVrW0 UnZ9G27L5N69jV+D+h/sT/EHX1T4ffDnwzbeM9KxejTNS0M2N7bhSMSrFKoJAYj5lyASOlTUyulO l7WNT2tPuqkpK/Zpv80aPM8bCfsq8JU5tbSik7eTWn3O59v5FaHMLQAUAFABQAUAFABQAUAFABQA UAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAYvhv8A5F3QP+vKD/0W tAG1QAUAFABQAUAFABQAUAFABQAUAFABQBWuru1sreW7vLmKC1iUtJNM4RIx3LMeAKcIyqNRirtk TnGnFym7JdXsc7/wnngf/oc9C/8ABjB/8VXT9Qxf/PqX/gL/AMjl/tLB/wDP6H/gS/zL+m+JvDms zPbaR4g02+uVQyNFZ3cczKuQMkKSQMkDPuKzq4WvRXNUg4rzTX5mlHF4fES5aVSMn5NP8jcrE6Qo A+A/2ovg18cNa0743xfBjTtB13Svit4bGi6xpWr3Rs59Pukgkt47q3lwVdTFIoaNscxAj7xrN4iN BS9pSlO+zi1deUk949VbVO5oqKrcrjVUGt1JNqS8mtpdNdLW7Hpnwr8GfGTxR8Vz8bfjbo+ieHL3 TNAn8O6F4X0S8a9MEVzPBPdT3E+AGdmtLZVVRhQrZ5NVKvGvNexpShBL7bXNJvyWiSt6u5Ko+wg/ aVVUm/5U1FLsubVt9X5aH1hVEhQB+e37T+nfscRfEjTtQ+NsmrXXxKl08eTaaHNqEtxb2edu4x2x /dozJ1ONxTvitqdLEwSxEca6EdUrzjFPvZNNvp6BCtzSdGlg/by0btDma3tdtpd7dTR/ZaP7LJ8f 6yfgfY+LIfFf9jy/aH15NTWE2nnQbgv2k7N+/wArGPmwD2zRVrVaitUzD2/93nUredlFbbX8y5Rq pXngHQX83Io38r3frbyPvisSBM8Z7UraAfF/jDx78R0+OHjzwn+z98IPDepeJrDTNLl8V+KvEl81 lHLvE7WdsgQFpGRDK2ei+ZjqamNPL8OuapRnUnLpDlSSXdy0u77LXv0HbE4hcnto06cduZOTbe9k umm767Hqfwr1f9o+/wBfvIfjB4N8F6R4ZWzZoLjw3qU91O9zvjCqyuoATYZST1yF9a09rhZrloYe dN95ODXpaOt/w0YnQnS96WIjU8lGUfndtnv1IAoA+DP2kPEXw38c+Ov+FVXH7NOo/F7xdoNjDf38 lgsVumhxXBfyUa6dlIeTy3YRqegyetTOjgoONbEV505u6Xs1Jysu/K1ZX2ua0amOlzU6EIOmt/aO KjfslJO7tu0jq/2ZLSHw3qOseGNG/ZOvPhRoUtq15Lq09zbTi+nV0VYmZGMjNtkdgWOAEPrUxWAu 54erUnUe7qQktP8AFJv7l69Cq0sa0liHT5FsoSWj/wAKil8z7IrQwCgD48+Ifg/4o6P8Yde8Y/s/ eN/Co8Xa5pFofEPgnxWJGiuI4Gkjtr2NovnibDvGcja4jXutXCdTDRdSdD2tKT0tLlkmlrZvRpq1 09n6icaOJfs1VdOpFbpcyab6ro072a1110JfhB4J+Id58Y9Z+I3xy8beGb74lad4fGk6Z4U8LK6Q aHp9zOkssrGT55HmktYhvxgCHA71M51MRy1VR9lSV0lzc0m9LuTWit0S82KMaNBukqrqVHZtuPKk tbKK/NvXY+vqRQUAfInxz07x74P+IemfGHwd8PLnxxp0nhi78MahpOmSIuoWG+ZZo7i2V+HViGSR QQxxGR901m6mHi/9ruorVSUeaz63S1s116W8y406tSLWHcebS6k+VSX+LZNPo97+R4X+zvonxb8c 2n7IeheKfhNrPgjwx8E9EgN/qXiFo0n1jUk0Z9KENvCpLCHFxNIXbrsQY5NNYrDVVBYWUpN/E3Fx ilbZN/E27baJL0H9XrUuaWIcUtopSUm9fidtIq3Te7P0vqzMKAPnD4yfA7xJ8QtesfFXgP4qaj4F 8RtpU2gajeWNnFdfbdPlcSbQH/1cqMGKSDkeY1KNavh5OdCMZXX203Z9JK3Vdno+uw/Z4evHlr81 k7+67XXVPyffddC7D8A9C0u7/Z1sPDt1/Z/g34S+fJYaYqbnuZTp8thEWf0WO5nZu7MVPrWUYzgo xjZ9293/AMO9X6Gkpwm5Tle72S2X66LRH0FWxkc94o8NaH4z8O6x4V8R2IvNB1WBra7tWZkEsTDB XKkEZ9iKl81vck4vunZr0Y00ndpP1V180fnr8YvhB+xh8HL7w54fvvgxq3iHxr4gWWTTfDPhhr69 vLiKLb5kpUSgJGpdQWYgZYCtIqrGm6uJzCdOC0u5vV9kkm2xurOpL2WHwsJytf4IJJd22rIufs72 37Ltv8WdF0/Rfgl4m+G3xjgtbi80qz8XRXUDXcXlNHObdmlaOUrHI25eoBzjjIpWxEHUw+PlWivi i5Sur7Nxklpfr3JlOvT5Y4nCxp82zioNaatKUdn+aufo/WYHMeMIvEk/hbXovB+qWOm+J2tn+w3+ pxGa3tpcfK8iAjco7jNNScXzKHO/5W2r+V1qhNRkrTk4rukm15pPT79D5Dbw1+2OJLfUW+Ofwm82 WIeVdHw8+XjJz8reZyvfjir9pWnPm/s2DlHS/PO68vh0IcMJCCTzGoovX4aVn57nefDfTv2mIPGe jzfEL4v/AA/1vwgol+16Xoekvb3U/wC6fZscucbZNjHjlVI71U6uInG08FGmv5lOba+TSWu3zJjH CKX7rGTqS/lcaaT+cXfTfQ+p6xNgoA8tv/iTbWHxST4dz2kUVpD4am8SXmrXEwRII1uFhVAp6/8A LVmbooVc/eFaRipxSim5N9Nvn5vp6MynPkfNJpRt13fp5Lr6o+efhj+07458ZeLPhxc+JfhrbaP8 JfifcXlv4K1qO9Ml5P5NvNdRPdwEARrPbW00qYJx8oP3quU8JU5qdLm5o/aduWVnZ8ttVZ7X3SbQ KliKfLUqSi+beKT5o3V1dvR+dtmz7YrA1CgD5O+N2g/Evw747sfi58NvBEfjITeG7nwxqmgJdpaX cUTyieK4tXf5Tht6uhwWBQj7tR7SjTmniIy5LOziuZxf+HdqS0utVZdC1SnVhalOMZ32lomvXo10 vo7vrY8O/Z68F/G7xVa/so6R8QvhhN4G8KfBPRYUefUr2Ka613U49IfS1EcSZ8uAJPPISxyTsHrR 9ZoVowWGUm3rJyjypafCr6yd+u1l5lyw06EputODW0VF83X4m9lpsu78j9IqsxCgAoA81+IHjnW/ Bl54DttH+H2s+Jotf1qDSrufSNm3RYZM5vLjcR+6THzY5pqeHjf203Fv4fdbvLotNvV6ByVan8JJ 21d3bTy7vyPSqQFS8tY76zu7KZnWK4iaJjExVgGBBwR0OD1pXa1Tsw06o+LdS/YG+CWswR22ra98 QLy3jljnSO58V3jhJUYMjjJ4ZWAIPUGlPEZlUtzY2ejutIb/APgJdOGX0neGCpK+nwvb/wACOq8N /sc/DHwt4h0HxNp/ifx9NfaTeQ30EV74pu54XkicOokjZsOhKjKngjIq/rWZS92pjJyj1TUbNdVp HqZ+wy9a08FTjLo0ndPo1726PrOkMKAPnj9orxh8I/DHhfTLP4s+C7jxXa6vcNbafoNnozarPdTh ckRoAdhx/ESuPWolh8NXXNiasaajreUnH7ra39DSlVxdOVsJTlNvdK1rf3r6W9T47+FPwk+OP/Cx /Bvif4P+GNc+DnwbttThudX8OeLNbbUTrNkGBkiisDu+ys65AYvlSelbf2pJx9hRnPERenNUikor vBv33bpfRmc8BGUvbYhQpTWtqTbcn/fa9y197I/UuoAKACgAoAKACgAoAKAPB/jr49+FvgPSdBu/ il4Qudf0+7uXjtYbbQG1gwyBcligVtnHGe/SsquHweIVsZUhBLbndlfyNqNXG0m3goTlLryb289V ofGut+N/hb8UfHfwXg/Z/wDglqtr8QtI8Wafey69P4Q/sq10zShKBfmeV0UENb+YqKMt5nlsMFax jhcqwslOhWp1JbKMG5N36vTTl+K/deZtOrm2Ii1iqdSEN+abSt5K0m3zfC1s09T9Qq6zjCgD5O/a Z0n4hQav8GPiH8LPh1L4v8ZeEdZnnFibuG2i+x3Fu0FwrtJ0Yo+UZeQ0YB+UmodTD0mpYlSlDtGP M79H5OO+u6ut2i4U6tWMo0ZRi+8nb5eaez7aPoO8OfGz4+6t4h0LS9Z/ZT1nSNIvLyG3u9Wl8RWM q2MLOFeZkX5mCKS20cnGBW7xGWy0pzq83S9FpX6Xd9F59CfqeMj70p0rLe0nf5ab9j6vrMQUAfPn xv8ACPj681H4efEr4YWGnap4y8F3V066Dqk3kRapaXUJhmiSb/llKMRujnj5Sp4Y1DqRpSUqkHKH VK3Mu0lfRtduqbtqNU3Vi4xmoS6Nptekra2fdbNI+SPhf8N/2jvGGgeCvhb4++GNj4L8A6P49u/H Gq6vPq8d5c3x/t241m2tLeKMfL++khR5GP3Y2x94Uni6FWHJQpz5295JRUUn63ba7aK77FrDVKUu etVg420jG7bbXV7JJ693p5n6dVoZhQB8kftN28+ieIvgd8WL7wXfeKvBvgjWLy41fS9Nt/tU9mLi 0eCK+jt/+WphZiCByFmZhytZTdCSVLFS5acnq38Ka25v7t+vR2ua0419ZYZXqLZbNp7qLfX81dHi /jb40eDv2mPEfwi8HfBfwp4gv/EukeMdI1u68T3eiT2EHh6ytLhZrotPKqndNAkluI1zu87nirnT wWEkqlGtTlVeiVN3bT0ley0ild69bW1IpxxteEo1qM6dJbuemq1Sirtt3tr0R+j9USFAHzz8Z/iw vwt8X/Bx9e8Q2egfDvVb+/i1rV7+MGLdHZu9vbmQ8Rb3y27v5O3+KtsPH2snRhFOctru229ujfl2 u+hnU92PtZX5Y9k3q9rpJu36tHzBbfFv43ajN4U/aJh8Zpb/AAs8UePLDwvoXw7n01FOoaLc3yWC X3nH94J3y94oxjygAe5p/W1eVKNOLpRTTlrzc23Mnty83u26rXcHhLKM5Skqz1tf3Ut+Vx78urd7 p6WsfpLWBoFAHkPxc0z4yappmlw/BzW/C2nagJmN8fFVnLdRSxY+UIIyCG3evaolUjCNp4dVk+jl ypfg7jjTVRputKlbrGKk/wDyZqx8yaz4h/a2+Hfi/wCFN18UfE3w0vPh1q/iOy0i/v8AS9KuVmsZ LiQRQqu88GZ28hXH3XlTPBNaRxMMQ1SeCjF7p+0bSsn5b2vbu9OpnLDex/eU8XOS6xcIK99tnte3 N1S1Wx980iwoA+f/ANozxD4h8J+DfDnifR21ddG0vxJpd1r50GJpbr+ykmBn2ooJZM+X5gAyYvMx ThXjQfvtRT0vLZX6vt2T6N3BUZV9IR52tVFbu3ba76pdbHxl8RdT+JXxJ8G/GH9qfQ/FPjfw5aeG fLg+GPhm1ElsmrNCIx593Zld0ovLuRoQrAYiRTxnNaLMJUpcmGqRdGHxaJqfWXvPWyWkbfau1ciW Xxkv9ppNV57Xb5qfSOidk7+9K99HZn6jxeY0UbSqFkKgso5wccisSyamB8p/th6UupfCnSbnVNCv dc8EaT4m0jVPE+jafE0sl5pENwrzjyxzIikRyug+8kTDvUyqxprlnPkjL3XLsn3fRPZvom2XThOU lKlHmnHVLu12vo31S6tI+XPj78Xf2Wvib8KtQ8C/BAaLrnxnvBBD4OsfDGlGK90vVd6m2n3LGpgS J8O7MQAqsDnpWjyillKWMXJDl1TjKN5P+VJO8ubZp9HqUsZjMffDzjUcZ6S51JRS6tuWitumtbrQ /UmESCKISsDKFAYjoTjmpMiagD5d+Mfgn9nPwP8ADn4ia58VNIht/BOu6xFrWsqZbhnv9Sfy4Yii o28yMVjVUTqe3WnRo1qsmoV5R683PblS316R8gnWjSs1SUm9LKKbk35dX5nxMkH7DD7Xi/Zr+JbK cFSPD+rYPof9ZT56P/Q5X/g2X/yJuoY5a/2cv/AKf+Z+vdSYBQAUAFAHlHxe1vwvYeG9L8O+LvDS eINK8YataeG/7IlRXjuDcsQxcNxsSNZJD3wnHOKTpUq0XGq7K19L3v0tbVO/Xpv0BVqtCcZ0V711 1tZdX93Trt1Pz28R6F+zd8Dfir4h1bwp+zlqPiPQPhmbS+8UeKzqb3Fp4ReVRKphtpnbzJIoGSZw gyiMp61cqcKqp0cdjKsnKzjF3lBa2i5tWsm1pe+13oUq1e062Eo04pXTaSjOWl5KOnTrtd6I/VxH WRVdCCjDcCO4qSFqSUDPzV1zV9a8LaZ8ffG/hDxJZaF8WvEPxYtfDDeI9WgjuYNLtglpBaxXG/G2 2EDrKFBGZLgY5ariuerGq6aqytyxi+tr3Sa2d7ttatfIluCpunOTjBPmk07Wuvi87Ky1076XOufQ fitaftF/s+XHxj8YeFbvT4JdVOhax4d09rW61e8OnzhrG5ySFiMBmuBtJBe1XPIFRFucpcmHjRlb 3mpNqUbrRXS1UrPXonbqH7qMIxVeVVPZNRXLL+b3d1a6v3eu6PpT4J+MPEPi/SPHY8TXMFzqGh+M Nb0WK4t4vKD20F24twV/vLC0aMe5UnvVTmptNRtpt+vz38rhCPLezuvP8vk9F5HtFSUFABQAUAFA BQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAGL4b/5 F3QP+vKD/wBFrQBtUAFABQAUAFABQAUAFABQAUAFABQAUAc/4n8MaD408O6z4U8UabFqHh3Vrd7W 8sZ87J4nGGU4IOCPQ1LTa92TT7p2a9H0KhLkkpKz9UmvuejPmj/hhD9kf/oiGh/99z//ABysvZ1/ +gmr/wCDJf5nV9en/JD/AMF0/wD5E9E+GX7NvwO+Det3viT4Y/DrTdA1y7tGsZryzaUtJAzo5Q7m IwWjQ/8AARVQhUTvOtOflKTkvuf5mVXESrLlcYr0hGP4xSZ7nWpgUb7UdP0u2a81O+t7O0UgGe6l WJASeAWYgVdOnOq+WnFt9lqZ1KtOjHnqSUV3bsj4A8c2eifGD9orxZ4S8c/HbVvDvgzTNB0+88Ma T4W1+LTotTLtMt5PJMpJeSORYk2cbVdDzurrjDNIRdPCJ02vi9y8nfb4k/d0tot736HJ7fKpS9pi eSqnteXuq2691rV3vq9tup7n8Gfg58O/h54nv9a8JfFfxR4n1Kewe1ex1vxP/asUURkjYyLF/CwK KN/YMR3rCqs0SvjakpQ84KKv6pLpc3pVcsqStgqVOMu8G27fOT0vbp2PpqsDoCgD4O8Z6/4++Ef7 Sfjjxj4S+APinxx4e8XaHp0N/qmkpADZ3Vp5ixrC7sC0bxzEOvG14wRneaydTAc/LjG+ZbNU5Tsu q00130879DX2GMq01LDcluqlUUebs7Pa22u6tbqe4fCn4xeMfiH4gvdH8Q/Abxh4JsoLNrpdV8Qe R5Mzh41EK7GJ3kOzemEPtVRll7/3SbcvOnKGnq/lp/kZOhjKeuIjBR/u1FN39EtvP/M+gasAoA+E /jx4V8U+FviuPi1of7Svhf4YRappcWkSWOs6bBMNUWJiytL5ki+Y0bSPsIGVErAkgjHTg4Y2UpLC 4WFWD35pSWvTbRO2n95W7GOIqYGKj9brTi1e3LbRdfO22+z23Z7H8K/Dfxu8P+Lr+H4pfG/RfF1g dNLR6JY6FFp00LtKoS4LK5YpiOZMYwS3X5azniKteF5YaFON94ynLXt7yt59zT2WGpStSqzlLtK1 rd9Op9E1kUFAHxl4+8GftJaD8b9e+I3wQ03wO/h3XdItLHVrTxJeXMbX89uX8mbEanYyLLImRnep XONopU8TToScamHnUT1vGUFZ+V+j637JrdlSoKtFSeIVO391u/r89vVp9D074V6h+0pd+IL2P4ya D4DsfDAs3aCXwveXU9w11vj2hllUKI9nmknrkL71pLEUKy5aeHnTfeUoSXpaOt/wIVD2Wv1hVPJR cfne57/UDCgD4o8baj8Q/gh8b/HvxR0v4Rax4/8ABnjbS9LtnuPDHlyajo89kJ08loXILQOJg4Kn hy+eoqY4jCwk1jJOFvhlyuUbdU7ap31v1+RUqOInTvhFGT6xclBt9Gm9HppbdfMk+E8vxF+K/wAf D8cde+F2q/D/AMG6R4TuPDdpZeIDGmoa3NPdwXBlliQnZFCLchNxyTcORgZo+sYecnHBycotXlJx cU2vhST1dru787B7CtCmpYrlUukVLm5U97taXdloux9p1RIUAfHXxwf4keL/AI0fDz4S6D8UL74e eDdR0O+1eTWNJhja71i9hmhjFnFJICqbI5DKwA3MOnCnG1KvWpxccNCLmtW5x5ko7aRur67vpp3M 50sPJqpipS5Nkoy5by39577J2XVpnWfD74FeMfBvi/SfEmq/tHeO/FNhZ+bv0LWZLY211uidBvCI G+UuHGD1QUp4vHVVy1vZ8r35aXK/k+Z218ttBqGXp3oRkpdL1HL8Hvp/mfTNZFhQB8IeIP29vg54 c+Ox+GGo+IraLwzaaJf3F/qptLoy22q295BALUIE5Uo87FhkZjHPNd0MJGUFHnjzPW/PG1uz10le 2na5yupVUuZU5tbW5Hd+a8vPzR2GiftdeCPiJ8Ufhn8Pvg/JL4ng1i4vG1+8SxuYU0WzitJZI52d 0C5adYYgp6+aSOlZVqdLDK1WcXKXwqMk3fd3Svpa/wA7GtNV6zclTlGMdW5RstdEk31v26Jn1/XM ahQB8bfG9Pip4P8Ajf8AD34qfCn4RXXjWVdCu9B1yNL63tVWzeZJ4/KaQ5EyzRg/3WSRs8qtQq2G pVF9Z5mntywcuXz077Nb7NbMtUa9aFqMoxs/tStfyt+KfTVdTyDxf4z/AGlPGXxT+FXje/8A2R9Z i0LwK17f2lpH4hsPtFxqFxbyWmXfOBCsE8x2jlnKk8KK0eKyz2iUZVV3l7GWq/ltfvZt+SS6hHB4 1J3qUnfZc7tfvtvbRerPvTwBr/iPxR4S0jXfFng248K+ILnzTcaBdXMdzJabZXRcyR/K25FV+Ogc DqKJSpTfNQbcenNFxfzT1Wv+ZHJOn7tRpy/uu6+T/rU6PVNNsta0zUdH1KDztOv7eS2uISSPMjdS rLkcjKkjipd2tHbzW4Le7Vz4T/aC8Pfsn+Brb4XeBPHnw81rxHrGn6U9l4b8M+GY728vItPg2BmK ROD5akoN7nqcZq4QnCn7WrjXRitHJza5n9zcpDUpzqezw+FjUe9uWNor1lol2RynwAh/ZwT4teFG 8Bfs3/Efwt4rAuvsmva/pl9DaWv+jS7/ADHklZBuj3oMg/M4A5xU/WKFT3YZm6z/AJOaTv8AJpLT f5FypYyKvVwUacf5koXX3a67aH6UUGYUAfEP7W7/ALPl3qfgnRvit4Q8TeJvGNxbXb6fpPgyG5lv ZrAGP7SswhZf9GZvKDBzgnGO9VGHInXeL+rp+63e3NfW1rO/qlddwU5zfsaeGVZr3rNK0baXu2rP y69tDD+Gvx4+DXxr+JPwHsdE+Gnj3TJdP0y81Pwhcalo7WelJatZiI3KnO0gQOIoyOn2jAHzZBKh hIR9nQxUZcj+FXvfVdVslf5+dgjPGO9SvQsp/abTffSz66X62+Z99VICEgAkkAepo3E2oq7Pjr43 S/EXxj8afh58JfD/AMU7v4feDdR0K+1eTWNIiia81i9hmhjFnFJICqbI5TKwA3MOnCmtqdavSi44 anFzWrc4uSUdtI3V3fd9NO5k44Wo1UxE24bJRly3lv7zWuy0XV3Os+H3wK8Y+DfF+k+JNV/aO8d+ KbC083foWsyWxtrrdE6DeEQN8pcOMHqgpSxWOqrlrez5Xvy0uV/J8ztr5baFqOXp3oRkp9L1HL8H vp/mfTVZFhQB4z8Z/A114w0PT7zT/itrHw/1LRpXuoda0yeJIjlcFbmOT5JI++0kfWtKU8XGVsIk 291KPMn+q9UZ1PqnLfFr3ejUuVr0f+aZ8Q6P+2F8UPCXjG08A21npnx8iDmOfVvhnayQ3dio4L3K Nm3z7I/Nb4mrhsLaOZQ+rze3LL2if/bnxx+ZFGhXxC58vk6lNbupHk+Sn8L+aPvP4T/Fbw/8X/Dl 54i0DTdZ002N6+m3um6/YSWV1Z3KIjtG8b9fllQhhkHPBrmn7LR0KsakX1i7r0fVPumbKNaGlem4 S7O2vmmtGvM9RqRng/xX+Ko+HPjb4O6fq2sabovg3xBe38WqavqpCRgw2jyQwLIxCo8j/MCeohYD k1vh6brN0acOab212S3aXV+Xa76GNaXs0qspWgt9L3vtfsvPvZdT5ftfjp8a9Uu/D/x6sNd0kfAj X/HVl4R0bwfJp+LrU9NuL5NOTU1uc7t7ys1wiY2mFR65p/WKd5UFSThG6c+Z83Muy+HlUvd7vddA +rvljVlUkqktVGy5eXs+vNy+9fpsfoxXObBQB8w/tD+KviZY6x8Ifh/8LdU0rQdd8b6rc2UnivV7 T7VHpcUFrJcFI4iQGml8vagJA+Vj2qoTp03zexVWa+FN2S7tta6Lot/QmUPaWU6jhT6uO77LXRXf V+i1Zn+HPhV+03p3iDQ9Q8QftN2+q6DbXkM17pi+E7aA3sCuDJCJA+U3qCu4cjOap4+vNcrw1JJ9 U53Xmr6X7B9TwsPejVqtro3G3z02Pq6sygoAKACgAoAKACgDL1m0u7/R9VsbC8NpfXNtLFDdAZMD shCuB7Eg/hSu46x3CylpLY/MCb4ofto/DnW/2X/h7qvwavNZutN+1aXq9/Ya9byw+MjBpMwE0sjD MBMkYuMvjLDYOTWv9o4Kcf38ZqU/ivBNp7vks7PXt9m4v7MxK/gVIOEfhd5LTZc6f/B96x9S+HPi /wDtGap4h0LTdc/ZbudI0W7vIYLzVW8T2UwsYGcK83lry+xSW2jk4wKlYjLXdU/a8z2vTsr9Lu+i 7sSwuNjrOdK3W0m3by037H1dUlBQB846t8BNb1TwXo3hGD46eP8ATrmx1C7vn1ywvY0vLtZ5HcQy sUIMcYcKoA6KKqOLxsH7SM4OT0d6aat0sr6Pz6h7DBP3ZUXy9Fzy36u++vboc74c/Zm8R6D4h0HX Z/2lvipqkGnXkN2+majqUL296sbhjFKojBMb42sARkE1Tx+YTXLOVLle9qMU7eTvo+z6B9Xy9awo NNbPnk9fTqfWFZgFAHnPxM+Kvgj4Q+HV8T+OtXNnp8s6WtvFFE0895O2SsUMSAtI5AY4A6AnoK0p Uva3bkoxirtydkl5sznOSajCLnJ6JRV2/RGB4T+PHw58Y+CPBXxB03U7i38OeKdWfQ9PfUbZ7eT7 ctxNbGGRG5RvPt5Ixn+LA7iqdFc7jCcZaXTT0el9O+mvyZPtJKKlODi72aa1Wtteyv8Amj2WsTYK APkb9qLx542+GGq/Bbx34U07xRrukabrdwmueEvDNk1w2sWc1q8W52AwpgkeOZQcBihHXFNYqhh0 44mcYU5aNtXflyr1+Lry3fQX1ariNaFNynHVa2Xnf1Wz2uTeGv2tPCviLxDofhy0+E3xRsp9WvYb Nbq/8KTW9vA0rqgkmkJwiDdlmPQAntRGOWQTVHGUm+ybu30S91avoXKhmK1qYdpLd80dF959Z0iQ oA8R+OE/xBGgabZeA/hLoXj9bqci+0vxBfRWsMKKMq+JFZXO7jGOOtZVfqjjy4ulKa6KKTs/m1b5 GlL6wpc2GrxpS7y5vuXJr9589TfF/wCPGleM/hH4c+KH7NnhnRfC+ra7b2Fpri+IIbqHSZyCqlVC fLKYzIsQ43N8gILCrjUy6so0aVCqpLWKailovJ/ZWrXZNrYynSxtGTqyxFKUX8TSqc2vqvtPS+yb V9GfedUMKAPnb9o9IrbwdZ+IL74+Xnwp0XTJy91rNqICLvcMLEfNByc8gKMmt8NHGTny4KMHLrzx 5kl96S9WzGq8IkvrSm09EoScW320Tb9D5L+E2n/CD4yfEDwpb6x+2Nr3xOu/D1/FreneD9S8qwin u7dt8U7RBFacRuA6gZAKg9q0xFDNKlJuq6Xs01zeyjG+j2bUpNK+/fYKc8Bh5pRo1I1HfldWUn0s +VNJXs/U/T2uQ2CgDwXX9E/aCbRPHq6B498KWutXGti48P3N/pkjw2GlbEBguFDDfLuEh3g4wRTW IbtbDRlbSzk1zebaTafSy0FKjSa96vKKerfLF8vkk9GvN6niBtP2v22pL+0B8HigIODo7nGD/wBd a3f1mS5Xlcbduep8vsnMpZfHVZnO/wDho/8AyR901znUFAHgXiXV/j7Y6L41l0fTfA39tnXktvDc erXs0UF1prKgBuGAyLguXARcg8VUatOfxYaUkk7pSjeX97XRLumS6SVr4lRv1cdn0jvq/M8Rhj/b B8PzXetw/DX4E6ZM4zPqCXl1AxHq8gjB79zWVGOWRqJ0cuqcz7SpX+R01VXlC1XMbxXeErfiz7rq zAKAPzt+PXir9oP4gafFoegfsrau+o+GvEdprmh6tda5YtbXM9lcb4mliJ3eXIgYEfeXfkcqKVTE 5aoe86sn1j7KVn3V729Htez2NaWFxl7qpTSa0fO7rs9vvXa6PR4vj9+0fsjE37HGv+aQN2zxJp+3 PfGT0rVYnKX9uqv+4Mv8zL6ljv56X/gb/wAj7LrMAoAKACgDzz4nfDbQfit4Vm8Ka/cX9rGLiC9t NS0qc291p91C4eKeGQfddWA9QQSDwTUv2kWp0pcsk7p2v96ejT2a7FRcNY1IqUXo0+v3bd0+55jb fsyeBrT4OeMfgzDqmsy6R4umln8QazfXPn6hrLzMn2hppiOTJGgiyB8qYA6Cs5KvPnnKpepPeVl6 aLZWWi7blqVJOEY07QjtFN+ur3d3q+59GoqRoqIMIowAOgArZGRJQB8h/Fz4J+KZNf8AF3jL4daT oXiLSPGFtDB4t+Hnib93Z668KhIrqGUA+TdCNUQsRtZY48kFAaycoxjKnWpudNu/uu04y7xfVOyu tHdXWrZtH33GdOp7OpFWTa5ouPaS30u7NX3s1Y+bvBvgHxR4E8XWniTwF+xl4ht/HtlFJFpV94m8 ax3mmaQ8qNE7xbpGKjYSpKjcVJA610VMbhqvK6+KxFZR1UHTtra3xWS62u27E/Vq6i1Thh6d95xb ba3+FK/nZWPur4FfDXUfhZ8PLPw/r2rpqvi6+vb3W9d1OJSsd1qV7cSXNw0ankRh5SqA8hEWsYyn UvOorN62Wy7L5Kyv13JkoRtCm20la73fm/V6+R7HVkhQAUAFABQAUAFABQAUAFABQAUAFABQAUAF ABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQBi+G/8AkXdA/wCvKD/0WtAG1QAUAFAB QAUAFABQAUAFABQAUAFABQAUAfnj+1D8TPjfbwftA33wv8dWPhLQ/hF4Yj1qdTp6Xl3rt5JBLcqn zkCK3VIlXcASzM/92t6eJ9go+zoxnd+85XsvKKXW2rbel1bqYyoQr8yq1JRdvdUWl/28276X0SXZ n03f+P8AW7D9pDwz8MfNhm8Oa14L1DW/JVB5tpc2l7aQ7i39yVL0jB6GDjqaz5o+z5Wtb6Pv3Xy0 f9Iu153T2Wq/L9fX5HudQWcV4/8AA3gr4ieGL3w38QNDtdW8LOVuJ7O83eWTGd6scEHgjNRKLqLl UnG/VNxf3qzLp1HSlzJJ+qUl9zTR+VmheJf+CamrfEv4geFNS8KfD+18O6BZaXcaX4gaWdhqUlyL j7RGo/h8ryIc46+aPSux5FWm0o1KntI73rO1ntZ8/k7/ACEs5rxvemuR20VFXuv5lyeemnc+iP2f 9b/ZhT47y+HP2a/Behz2z+FLq71fxboQn22TC7tVis3Z/lPmgtIADkfZ/Q1lVwf1L3K1WUqj1SdR zVlu7czs7tWfqDxVbFrm9mowXX2ag79LNRV1a916H6AVmSFAHwl438a/F/4TftIeMde8N/CDxz8Q Ph54o0XTo7j+zZI/J0a7tRNg2quwBWZZsSDgholPINNY/DxX1fF1JJLWPLTlJK+6dlrfRrtswWAr 1L18LGF9nzVFFytta+3Lre+j6antvwq+Mvi/4i+IL3Rtf+BPjLwVZwWbXS6p4iWAQzOHjUQrsYne Q7N6YRqTrYKqrYarKUuzpyjp6y0+QewxlLXEQgo/3akZu/otl5/5n0BQAUAfkl+3BH4O8Pv+0xqH xR8Kz3+reKPAi2HgDXbjT3vbe0mSCdZbSFgrCC4M7pJuwCwdOfkqW6eIXJUqqLp+8ouXKn1clspN Ws1urLuaQ+sUU3QptxnpKUVdrolLqo9V0u2fSnw4+IGi/HP9pm0+JHwxS9ufh14a8F3uh6j4hmtJ ba31O9ur2znt4YS6gy+SltcszYwpnA/iNa1XGjP6vGopPeSi7qNtrtaXd38lr0M4QqzgqtWnKC+z zKzd/iaW9lZK76n2zUAFAH5n/tI/D3xD8XPE37UVkfFXiyHxH4M8DQX3gnw5oWpS2ME08trduLoi PHnSG6h8raTgCJePmrSOPxWGipYeryRg7ySUW5PfW6b5baJK3USwlCrL97RU5S0i5Xsullqle+rb vuiX9mWL4P6X+0JbJ8EPGus+K/Duu+AZb7Uje63c6jHoE6XdoI0YSMQklwssnynDL9kbHDGt8TPH wSpY6u6l9Y35Nlo37qV1quV+b3Maf1es3Uw1BU+X3ZWi1r0WvXR83y+f6V1yG4UAfFfjaT42fFD4 7+NPhr4Q+LQ+HPhbwpo2m30Js9LivbzXHujPvlBlIVYYzD5eFyd2c4yM6rE1aVO2GpQk0/elO7t2 SSa6a3fotmZ/V6NSd8VOdmvdUJKN7btuzv006b9T1T4VfC74q+CPEF5qvjr4+6t450mWza3i0q/0 i2s0hlLowmDxnJIVHXB4/eE9hWbxWKr+7WhTiv7kWnf1behf1fCUveoe0v8A36nMrenKtfO59AUh hQB8P/te6b+zhLdeAb742ab4i1rxSzzR+HdC8LS3b3s7qP3skUMDA/KJADIcYD4zzirhGol7f628 PCL+K6Su76apttq+i07rQIT5p+xp4ZVptbNXsl3baSV7b9djhv2bdG/ZeufihZnwZoPj7wz8VdIt p7y20PxzdalBJPbsjQSSxwzyFJlAlwcZ2lgeODWsq2IxFNzp5i8RTWkknF27cy5U1rs+4TfspKFb BRoyezUVrbe0k2r23XY/RmucAoA+PPjJ4tXwx8ZPCel/DL4HweN/jff+HruRrua6isINM0b7TCZP Omfj95cLHtUAsSh7Vh9Wy+mnVxUXK+ihCKbb3cnfRW2u+9kaqvjar9lQqKCWrlNvTokuW8n6LTS7 Oj+G/jH9o7UfF+l6d45/Z+0Hwv4RnEv2zWbDxHBdyQbY3aPEKKC26QIvsGJ7VUJ5atMLh6kJPq4w S+dnf08yZ0sX8VbFU5pdEql/lzK3r5H1BWpAUAc9L4p8PweJ7HwZJqkI8UXllLqUOnZJke2ieON5 cdlDyxrz3b61apydN1fs3t89yb3fKl/kv+H6Hlvg79pD4NePfH2rfDPwr40t73xfp7To9ssbqlw0 DbZ1hlI2SmNuGCE4wfQ1tUwk6cHJyTatdJpyjfbmW6uYwr87T5JKMr8smmoytvyvqe51zHQFAHwv 8d/Efjjw7+0f8L5/gj4CHin4pP4av11qzvruOysxoH2iPaTO33ZhdhCgAOV8wHtRz0KD9rXUpp6K MVeS68yb0S6O+99Ng9nVxH7unOMLa80r2fTlaWr73W3oz1D4fePP2mNa8XaTpnxC+BGjeHPCE3m/ a9YtfE0N7Jb4idk2wqoLbpAi+wYntTeLwdX3aVKqpd5KNvnZ3/4Ivqten708RSku0VUTfpzJL7+h 9MUhhQB47qXgPUf+F1aP8Tra8s/7Ck8MXXh7U7a4yJQftEc9vJE3QD/j4Vweu5D/AA1CUnU5eW+m j7P08/0Q5OEYczlbXZ7Nevdfk2fMvwq+Dfxs0TxZ8DvB3ia68Lw/Cj4Nm5TRNZ0y7eTUfEFv9hns LWCeIgCMJDOHk5IZ4UI6cWqs+WMVQlGdrTk2uVr+6t/eaT12sHLQvKUcQpp6xglrF+b2dk2lbe+p 9+UCOc8WeGNK8a+Gta8Ka6k7aNqtu9rcLbTvBIY24O2RCGU+4INClOHvU5OMls1un3V7jXLf3oqS 7PVP1PlK4/YH/Zuu5LSe70DX5prV/Nt5JvEeoO0D4K7kJlyrYJGRzgkUp18xqOMpY2reO2sf/kfw 2NlUw8U4rDU7Pf3f+Cd54A/ZQ+Dnw08W6V428K2OuJr+neb9ne8169uox5kbxNujkkKt8sjYyODg jkCtHisfVXLWxVSceqk42f3RT0eu5EnQa9yhCL7qNmvxPpSoMypeTva2d1cxW8lxJDEzrBF96UgE hV9zjA+tK66hvsfnX8T/AB5cfGWDQbH4jfsT/FTVtJ0m4a6i055oYoJpCu398iSgSADorZHtTli8 vcXGnjKsE9+WlUV12bte3o0XSw+ZU5c3sKLa25q1N281dWv8j0/4cfGTXNMv/DfgrQf2OvG3hHw5 dXcFo1zHaWdtaafG7hDNIsbfcQEs2ATgGsaP9j0brD1Jcz/6dTV35ya692yq0M1qvnxEYNL/AKfR dl5RX4Jeh9mgDkhRzyT61oopXstzK7e4+qA+af2kPF9lpmmeD/AcXwig+JfiXxffSQ6f4ZvTAtsB bxGaW4mkmBVEjXaM4zmRQOtTKnhZwc8W5WW3Km5NvtZq2l7u+xVOeJjNLCyUW93J2il5731tZW/I +bvCX7QPxP8AFM/wr/4Sj9mTw9pHw4Txs3hi31Ya9BJFoV/aXc+ns6wqoAxLDNFFjhnaMLgsKr/h Nmo4elSq3STjdRUbpX1s/s7teTtqiFHMIc1erXpNNtSspuVm7XV19rRX6X10ufpPQMKAPhn9oTxP +zb8Wvhv4P1vx58Y9V8OeChrk39n6poVzLZvcX9pIyMNwjZgY5I2IIxyDyQSD0ww2LlU5cJVjGS1 v7j+5tpdbNdm0zNVIOL9th5TT0taX4pd91f1R4/8PtX/AGXpfHvgmPw/+2H8Q9b159XsxY6Ne67P LDqNwZk8uCRDAAyO+1SCRkEjIrqqUs5UG6teDjZ3SVK7XVKzv92plGnglJcmClF9G1UsvPV2089D 9Rq8w6QoAKACgAoAKACgAoA4/wAbePPBvw48P3Pivx14istE8P27Kr3t9IEXcxwqjuzE9AMk1pQw 08VPlpxu1r0087vYyq1oUUnLroktW32SW5jeGPi58N/GPhbwr408OeLbG88MeJbxtP0q/DFUvblX ljMSZAO8PBMuDzlCKueFqwnKna7iruzT00e/XcSrxcVKScbu2qs7+fY9JrA2CgDy3xj8QpPDHj34 VeCobKB18W3F+Jry5l8tbaK2tjKdn96RmMYC/wB3ef4aumoyUlZuXS34t+XTTq0ZVJODi7pR6t/g l59deifU+Zov2ofiFeeJ4vGVh4K0ab9m6XxnB4Fg1wXj/wBpXd1Jdrp/22KLGxrYXr+V13FVLjit XLDRk8O4S50tZ6cqla/Lbfyb6S0JVOtKCxCqKz2hZ3cb25uba/VL+XzZ911zm4UAfNfx70Pxhba3 8Kvit4N8H/8ACXXfge+vJLrw1HKkdxc291bmFprUv8vnxHaQDjKNIAckVEpUk0sSm6fWy5mn0fLu 0vLVXv0LhGc1JUZJT6Xdk11i30v3emlnufHfwstPjD8TPCXgT4PXfwR8T+EtH074k3fjbWfE3ihI 7aOG1TxHc61BBbpktJNJugiYjhcuewqfreEnBLCzc5t2+GSUVfVtvutorW7s9mNYXEwk5YjljBLp NSlJ22SWyT3b3S03P1YrUzCgD5j/AGhvGPxO07VfhN8NfhPqWmaJ4k8eapdWknifV7f7TFpcFvav cSeXFkCSdwmEUnHDHtV060aN5Kn7SfSLdl5uTWtl2W5EqSrWU6jhDq0tfJK+iv3f5s8n1Ob9pD9n 7Xvh3rfi74v2XxH8B+IfEen+HNR0u80aPT721e+nEEU9q8ZIcRu6syEf6sMc/LVxxs66ccVQhFW0 lByVn0Uk9Gm7K+92S8JSpWeGqzcr/DNqSa3dmkmmlr2smfelYmoUAeIfHG4+Jun+HLLVfhx498I+ E0s5WfUtR8Y27S25h24UKQy7Tu7k1pRdXn5aWHVaT6czjbz0TM6vsVHmr15UorrGMZX8rSa/DU+U /CekeP8A9oPxN4TsPG/7Tfw68S+DvDOtWfiGbw/4BtQlzf3NlOs8CyyM5KxLNHGx2jnbjNb4unj6 cFzYONFXV5c8pu3ZXSSb2b7XMsLWy6Ur08VOtLWylGMF2u7O7tuvNH6N1yHSVLy6isbO7vZg5gt4 mlfYpZtqgk4A5JwOlCt1YavY/LL44/tN/Bjxz4u+Bnis+EvF/iPRvB2vS3V/4eu/Ct6UljuLZ7db pUZNryW7usgVv4S+PmxRWeAnH2VXGUnTlvad9VqrrrG+/wAnsjWhQzRS56WCqxqLZuKWnVJ30bW3 3dTQ+Ivxk+DPxn8d/ADwz4B8F69p/iq28a6XqEfiybwtcWX9kwQzozxCUoDi5H+jkZ2hZGZuFrCN PLcHJTwmIpe0eiUJLVP4k7Kz0+FPVytY0azSvTksTh6qpLV8y6rZrV2s9ZS6JPufqRW5zBQB+dP7 XX7QPwO1/wCHk3hKL4y6atpZeItPHinSNI1Iw311pUV0ovbeMrhtwUEsqkMyoyjkiu+ODxlCKqw9 xS05rxvFP7W+nrbRa9DieJw9aXs5Rc2ndR5ZWk102s/LWzdl1OUt9A/4JcyRwyxal4GKsoZS+sXe TnkZzJ1rL+xsyl/y/qO//T3/AO2Oj+26EdPZRVv+nC/+Vn6g1ymoUAfDP7W/wr/aP+I+o/DxvhR4 w0O18MaX4n0DU30280/fNazW16JXvGl3gPEihGMOMsFIzzR9enhkoxoKV3vzSTd/stJW5X1luk9t BrC0a/vVKrjbpaNtOqb15uy2uZ3jH4I/tP8AxO8Nax8P/iB+0X4TXwTrsRs9WXRPDogu3tm/1iRS NIQjEZG7HGcjmtp4vFOP7nBwpy6S56ja80uVXa6amSp5eneeJnNfyv2aT8m1rZ9T7zjQRRxxqSVU BQScngdzWBoSUwPhH9r69/ae+3/De0+Dfg/TL/wxD4s8PXUt6mpTQXTypfBpIZ40XAsygUSPk4Rm 44qo5hRwatOE7y0unGzT05VfXmeye12tQ+oyxevtIpLWzTbVtea60st7buxX8dWP7cPxO8Ja58P5 vC3w+8IW2vQmzm8Tabrl1Pc6XGxG6aFAi5kUZ28jnFU8xo0/ew2GqqotnKVPlT7uzbsu1tQeAU1y 1sVGUOqUJJtdk27K/c+8YlKRxoXLsqgFj1b3NZgS0AFABQB+f3xn8Xftn/DW0m1vS/EPwwvrbVdb g0fQNG+wXv2q8mupxHbxM+doIU7nb7oVHPataeOgr8+C92K1ftdXbsrbvovMieCU7KGMmpS704cq 9XzXsvS79WU/iP4p/bh+FfhKXx54l8SfCibwtprxSa1PZ2F8X02zLAS3OCfnSIHcwHO0MR0qYY9V JKH1FJydk/auyb2v7u3S/Td6CqYFRjzQxs3bVr2UFdLfl97fqk99t2j9ClZXVXRgVIyCO4qC0PoG fPH7THjXxz4I+HVjdfD69sNM1vV9d0zRX8Q6pD51voUF1cLE95ImRuCbgACQNzqSQAaujUVOa9zn k9IxbsnLom97emr2W5E6bqRfvOMVrJrV8q3t5+fTfoeUf8KA/aekfzv+G0dVAY7tsfhex28nOB83 Sj+0cwv/ALvQ/wDAZ/5mX1HAN39tW/8ABkf/AJE+3qg6AoAKACgAoAKACgAoAKACgAoAKACgAoAK ACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAMXw3/yLugf9eUH/otaANqgAoAK ACgAoAKACgAoAKACgAoAKACgAoA+Lvjx8Gvgt8eNa+IWla74q1/w14i0Pw/FbeJ9W0C6NnFPpU6z utveFgY5VCJM+D8yK+cgNR7PEx0wtZRdTRxspeSfK9nuk01e3kJVsO3/ALTR5lDVS1VurSkt9k2m mtV3OV/ZC1j4Jal4n8U3vhPWfHmtfErVdLguzr/xIilS71fR1kIjlst6qv2XzHBOwD5nUt1Fa1VO vJ16mKhWcfd9yyjC+trLvbe7vbfQUf3MVRjhnRjL3lfVy8223qr7aWvsffdZFDGVXUqwBVhggjII pPXQEeY6f8GfhdpnijxJ4xs/A2jrr2vQWlvfTNaRsskdt5ohAQjauPOkyQATkZzgVw/2bhL+9TTX RNKy72VtL9e9kdbx+ItpNp9Xd3fq7626fM73TdF0fRkkj0fSbOxSQhnWzgSEOemSFAzW9HC0MPf2 NNRv2SX5GNXEVa9vazcrd22aldBkFAH5rftYeKfidqcX7Sd14X+LWqeCrL4S+D4tb0/SdCESXGtX UlvNOLid3BP2dTCIgqjllkyeldFLE1qCToQja/vOUeZ/4VqlHTW+t7+RhOjh6jaxDbbXupS5Uu7d tZO/S+iXmfUt5451eD9qTw78OrTVPtPh7UPAmoatfacu1vsFzb39nFBKccqZUurhcHr5Ax0NQ240 lGUd3dPrpuvNar0fqVFRnNyhK9tGumu3z0fy9D6ErI1CgD4M8fftG23we/aL8Z+FPiUNf1v4b65o mnXGlQ6VoU17DoN1EJhcJMUQ7vtAeFlbJwYmU44onPBYiP1fF1KULarmavK+/Nfa1vd7pl08Njov 6zg6NSa2fL0fTl1V73962qsr6Ht/wk/aM+GHxb1u68KeBbbXYLyysmvnTUdDudPhESuiEK0iBS26 VflHOMnsaUaWDpR5MNWpy/uwkm/Wy6efoTJYxy58Vh6kL/amrJvte71/RH0JTEFAFf7Pbm4+1iCP 7UU8vztg37M527uuM84qOSLfNbXb5D5pW5b6GHoPhDwp4Xk1Kbw14Z0rSZdRl8+7fTbOO3a6k/vS FANx5PJz1rGjhaOHbdKCV/6+7y2Nq2JrYhJVZuVtru50ldJgch478b+Hvhx4Q17xx4rupLfw7o8H 2i7mhheZkTIGQigs3JHAFOEVOSi5KKfVuyXq3sROTjFyjFyfZK7foj4M/aPT9k68+K1prvxU+JPj fQ/HkGlxJAmgXl9bJFaSgMAvkoR8+xSwz1UcCtqNLFX9ph8bGl0tzU19/Mm35X+RUnSlB06uA9st 78k38rqSS87fO+h1n7Ldz+zjN4+1hfhB8T/HHiTxINHlM9l4m1C+uYI7bzoN0irMgUOH8oAjnDN2 Jqq/1zl/2jGKsv5U6bs+/upPy7amcKdCL5qWB9g/5uWav5XlJrz76H3tXMahQB8g/GSbxP8ADL40 eEPjrY/DrVPGfhVfDl14Z1KDw/CLnUNGLXMdwlxFD1eN9jJIF+YbIz0zUe0wymli5ckd4ys3FPrz W1V1tLpZrqWqVapB/VrOXWN0nJdLN6Np9Ot/I4zSPGPiL9oz43fBXxN4e+FXirwv4J+H1zqOq3/i Txbp506S+eexns0sreNjvZS1x5rk/KPITviiVbBua+p1VVk9JOKfKo72baV22lZdLNgqGLjF/Woe zj0i5Jycu9lskm9XvsfeNWQFAHyX8fPh18WdU8d+BPif8KPH3hHwjf8Ah+zubG8vfEltJKL63nZW a3fBC+XujikGfmDx8cE5dOdeFS1DDqrdWacmvS1k9V37Nq2oTWFlTbxNeVNLZqMXr5uTWj/l66O+ hqfDjSv2povFeg33xF+JHw81bwLJHLJPaaBpc8NzcqYm8topGYrtEjRMT3XI7iqliZ1Lwlg1T7tV JSa+TivTchUKEEp08XOd9k4QSfzUm/PRH1BUFhQB8p/HbwD8RJfFFh8R/hd8SvDfhHWJ9Fm8Nalc eKITJELZ5RNHNAQwxPG3mEKflbeM42iqouuql6NBVtNFdrlffRO6f2l5KxNV4Xktiazpa7rlfMu3 vNWfZq9rvQwPDvwm8D6bqv7K/hXwB4y0CTQPhW97cusd3FLf6pM+mz2fRTyZDdTzyk9WQHnkifqG Jwy9rOi+aXxTatvq79XeVrdFb0BY/DYmbjGorfZinfbb5Rjdd9fU+y6CgoA+T/j78NPH2v8AjHwL 8R/AXxh0T4f3/h62ubOS91TTkuft8U5UvBIWkVTFmON9vUPGCCOQboyxMan+zYeNW61UnLb0in11 UumqtqTVeE5EsXWlBXurcq173flo1ts90ip8L4fjUnjnRW8XftN+CPFmgDzvtHh/R9Fgtri7/cvt 2SLMxXa+1zhTkIR3zXVW+tuD9rgY04/zKVRtfKUUtdtX1MYSy9y/cYmc5dE+Wz+7XbU+u64joMzV tX0vQdMvda1rULex0mzjMtxeXUgjjgQdWZjwAPU1VOnKtNQgrtkTnGlFzk7JH5yfHPxx8Bfih8b/ AIX6H8QvjPYP8HJdHvkgsNG8RfZIJtcEkTJ9seFw202wl8vJC7lbPOK9COEzSn+4oc1JvW6S5pW+ ym72tvZatejOSOMwEv301GpbS0k2o362632v007nqnwi+G37HegfELQNX+FfinT7zx5D5/2C3g8V 3F+75gkWTEDzMGxEZDypxjPbNZVsLm1ODniq1SVNbqTVvK9kutvma08dl9aXJQpU1J7OMbP7z7ar iOkKAPlL4x+NvjTe/Fbwh8Gfgxd+HtDv73Q7rxFqHiXxJbvdIkEU8UCwW8Ckb5C0oZiThV2/3hWk K8KMW1R9rLs5OMUu7aTer0SSJ9h7aSdSq6cP7sU5SfZX0SS1b+41/h/4T/ak0zxdpN98R/i34Q1r wbF5v2zTNL8PPaTz5icJtlMhC4kKMeOQpHelLGOquR4SEL/aVSUmvROKTvtuV9WoU/ehXqSfaUYJ fNrU+lqgAoA+Zv2gdW8XXuufCX4W+FvG0vg2HxrqF5Fe+J7VEa5iitrYzi2ti/yrNMRwxBwkcmAT itKVSpTu6MFKp05ldJdXy3V7dFe2t3sZ1IU5WddtU1vZ2bfRX6Lv3tbqeCeFPiX448L/ALPXwe1G fxxf6x4s/wCFtS+FGuNTdJLrXLEeKbzTGjkwBuKWY8wlQMGAE8A1o605uVapFPSzsrJX0TS6Pmt3 6rqQqdNctKk2tbpXu9NXe+rVr/mfopXObhQB514u+H9v4o8VfDbxhHqs9hq3g+/nuojCgZbyCe3k gmt5Af4W3o+RyGiU1D51JONrbO/by7NNL8V1KXK4tSXp5P8AVWurfPofPl/+y3r1346VofipcQfB JvFcfjeXwImnpubVUuhfYW63bhA16ouCmPvEjODS9riFD2CjHlvfn157Xvy2230vvbSxXLh3L275 ue1rXXJe1ua1r3t02vqfZFaGYUAZLaJor28dq2j2LWqMzrCbdCisxJZgMYBJJJPfNc0sHh5xUJU4 tLWzStqbLE1oyc1N373ZHFoPh+GWOaHRdPjmjYMrpbRhlI6EEDg1McvwsGpRoxTXXlX+QPG1prll VbT83/mbVdZiFABQAUAFABQAUAFAHyt+0jp13Yaz8HviZceB77xl4S8G6pd3Gq6BptsLueIT2zRR XsVuf9a0DkjaOQszMOVrKo6EkqWKly0pbt/CmtVz/wB2/wAk7NmtGNa7nhv4i2V7Np6NRfR/mrrq fGfwn8Wap8WPAnw7+C3gz4e+LLTUbD4qXfi7VNd1bR5dPs9H02LxPdaun7xwN0ssBiiEa9DMQeAa arYOEI+wrRnO9oxhrZXabelox5b273S6jlhcZGTeJpOELXbk1q7XSSvdu9r9rNn661oYhQB8y/tB 6d4D8bav8H/hL408EHxDJ4r1i4e2lS7ezbSI7W1llmullRlcHYREFU/N52DwDTSt+9jUlCa+Fw0d 3ve+nLa9736W1sCnJPk5Yyi/iUldNLy73226lb4qaV8Ovhf4W+Bfh+TwPE3w30rxhounWdnZTeVH pNzJN5NhOY/+WqrdyQ5BOQzBznaayp0KfKqTlJdb73a973m9fefXva+jKqV6kpe1tFvbVa2el4pa XS+Vr21sfUdaEhQB8p/tKa34/bU/g34B8E+Oh4K0vxlrc9hqvi+KCOeazWO1lmit4Q/yLLO8ewM3 A2kDJIFa0qlSk2qNNSqPbmTcVbWTsrXaWyv59DGUaFZc1abVOO/K0m76JX1sr7teSIfDf7PXxE0T xDoWs3/7VXxA1eysLyG5m0m9WyEN8iOGaGTbGDscAqcHOCcUPG4+acZqlyve1Kzt1s+d2fZ20L9n lq/hxlzdL1W9emltfTqfWVZFhQB4V8dfgha/HPRvDmj3fjbX/DQ0bUY9VgvPDskcU4uI+Y2DspKl Tn7uMhiDkEgz7TEUpKeGlGMl1ceb1tqt1o97plRjQmmq8XKL6KTX32+9dmrnhmq/sWalrmqeH9b1 j9p74rXep6FM9xp0019bH7JK6FGkVfK27tpIDEEjJxjNXPHZlUavOlZO9vYqzfRv3tbdOl9ewRw+ WxbaoSu1b+JLb/gn038LPh/qfw48PXeh6r8Q/EXjK5nvHuxqnieWOW4iUpGohUoqjYChYDGcu3NE q1fEPmr8t/7seRW9LvXzJ9nQp6YeDiuzk5a+rPQ7q5gsrW4vLqUR2sEbSySHoqqMkn6AUkr6Cfc/ Lf8AaO/aP/ZX+I/iD4GTa58QNN8UfDfR/EMk2v8AhuFJnSfzbaSK2uZotv72KCdlZk5wG34Oyu+p l2JhB0pzUIT0bU4r0i2ndKT0fna+jIpVpRl7WNGTnHa8H13aurcyWq8r21sZ3jXxp+yF4l+I37P1 l+z3eeGNM+Kx8ZaYYNZ8O2TWCwWCzJ9rt52RFVxcREwJG2cvIp42k1zQyqpld5UpWck1yqakpLq2 uZr3V71972S3NKuOq421PE05ct780oNWa2s7X1ej6crbZ+sdYgJ/Kp3AhnntrWCS5uZoobeMbnll YKqj1JPApxoqb5Yxu35EznGmnKbsl3K9pqWm39tb3ljfW1xZ3BIinglV0lIzwrA4PQ9PQ05Yd05O MoWa301RMK0KkVKMk09tdy/QaBQB+fP7Uvxz+BfwG1zwhol74C0C58V6vr+kDURP4b89V026u/Lu Z1lWMhplQSMFyWJA4OaxpZZlkm51o07u+jaUlf7TXZPVv1OmWPzZxSoSquKtquZxf9xa/E9kvNHJ +Ov2nf2bJPCmtxfB34Y2niT4pTQ+XoWhnwTIq314xAjjdjCAqknliRgZPapeWZNhk6tWVGUVulKL b8la7u+nmarF5/X/AHcYV4X+1JSUV5tt2sj9LYy7Ro0ihZCoLLnODjpW5wktMD5k/astr3Uvh74a 0T+1tV0zwvrHizRtN8QX2iSvFcx6dPcrG4WRPmRXkaFHYfdR2PGKqnWnQlelNQm9FJ20b7X0u9lf q0J0o1l78OeK1cddbd7atLdrqkfmp8XfhR8CfhTe/tE+GdXm163+JVjqNhq3w50KTXNSkfxBatY2 WyzjAk/eLLqEV9FJ/EokzkDFdFLE4+cHWeMnyU/jvKKdt77btO0Wuq20HKnRjOMI4SLdT4WoXSe2 +ys0m090/M/cGJmeKN3Uo7KCynsfSuTfYCWmB8oad+1/8LZ/B+heK9Vuhp02peMW8GNo89zCbqyu f7Tl05ZZ49wKRloxKSfuo4JrtWCc1zwu4NaS5XZv+VW/vXSOOeKVJ+znbnT1V7WW99ey1Z75/wAL G+H3/Q8+H/8AwZQf/FUv7Pxf/PmX/gL/AMg/tDCf8/Y/ejs64zsCgAoAKAPI/jZ8N/DvxQ8A3mg+ IdfudAWyubfVrLxFZTrBNo95buJIblHb5QUZeQeCCQeDSUa0pReGfvp3WnNfya6p7NB7SjTjJ4hX g1Z6209ej7PufEur+D5PiHZjwd8Y/wBurw/r/wAMZnVdR0LSobDTZtZgUgmC4nWViEbGGCgZGRxm vQq4fOa0HTWEhTvo5RUnK3XlT0i331scVPFZPRkqirTm1qlKS5b9L2V5W7aXP0zVVRFRAAijAA7C uA7R9AHyL+20YX+BV7a6x4jfRfAV3q+nW/iy8gkVJ/7CecC8WIsD8xjznALbA+OcVUFUk+Wkvelo na/Lf7Xy7/ZevQluEfeqapa2vbmt9nTv267dTwi0+Ef7DptrY23x51A2+xfLx8RLnBXHH/LX0r0/ q3EX/QRV+6n/APIHK8wydv8A3el/4DL/ADP0xryjsCgAoAKACgAoAKACgAoAKACgAoAKACgAoAKA CgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAxfDf/ACLugf8AXlB/6LWgDaoAKACg AoAKACgAoAKACgAoAKACgAoAKAPz4/aH8JfDrUfHvizSNd/aa0zwLoHjSxsrbxn4PujbibV7aIMi +VK7hoPNgPkuQDlAMYNdVHC5lUpyeEpxcZfad+aHR8utnptfZ66nPVxmX0px+tOXNHovhl1XNo9n ro9Vo7bnr/g6++FXxD+Ouh+OPAfxM8O6wPC/g670Kz8PaHcRyvBFcXVpJNM+08IotbRFHbc3qKyr ZfisEo+0p8sLWv1b6L0ST+bHRzDDYxy9nNyne700Xd+rv9y8z6orI3IJ2mWCZrZFe4CEojHAZscA nsM0tNw3PzT8IeJP26ofjj8aL+T4TeF5bS50zQEjs77xFcLp1uUW93NaSeWQztuXzQANu2Lrmtf7 Uwc37J0arUdop0uZX3cnzWadtLN7O9g/sypH959YgnL7XLO0rdEt1a+ve59DfDLQv2jdd+Lg+Inx gtfD3hvw1p3h+40e18NeHNSmvlv7ia4gm+0zFlVVMawMi4Gf3r84qZYyNX91QpShT3fO4Nt9Lcrd lZu+uummgnhI0X7SdVVJ7LljKKS63vvdpW+Z9W1IwoA/PT9rTwz8P/FXiNoPjB8BfGmp+DF04Wg+ IPgaZ5JUgkz5ttdQwN5phBJPzqyfMSMZNRz4ePNH61LDzkrNtWhJdE5NON/Wz7M3p/WrJwoQrwi7 qLa50+6i7N3/ALr9Ueqfsu6V+zPY2euX3wK8QR6zreoJG2rX+pajNe6rIkeQizmc+YqqWOFwFBb1 NdNfCYqMlisVUdVvRSbTVt7R5Uorvtd9TljjKU28NTpqk46uHK4tPa7T1fa92fW9YlhQB8NeMv2q ND+C/wC0f4w8DfFjxKyeB9U0TTrzQTZadLMNJuE84XUd06KTmUNA8Z6fK46it6dOniI8k3CDWzk0 nLvu9OXTTqnczlCrB+1pQnUT0aUW1G21rLW/Xs0e2/DD9pP4OfGPXrzw18PPFJ1LWbWza/lgNnPD thV0QtudQPvSoMdeaVXCRoLmU4P/AAyi39y6BCdWXx0pxXeUWl6XfU94rE0CgD81v2kNB+IXxG1/ 9p+HRfiZ4u0XU/h54Jg1Pwr4W8LXYtBqFzLa3cq3MxClpt1xAYQgIA8k92rVY7E4aClQlGEYv3ny qUn1td3srdl37EfUsPiW416fPKatG8pJLppZr3r66vTTQ1P2d08H+H/2gLDSvAHxm8UfELw54k8B S6uy6vrv9pxaLJHd2iguAAA06z/IDgr9mlGDuONcR/aFNKGYVL31j7sY37vRa2urPZ8z7IxoRwNR urgaKhbSVnN2fRe9JpX15lvdLbVH6K1ynSRPHHMjRyRq8bDDKwyD+BqJwjUi4yV0+44ycHzRdmQz RWfEk8cOTxukVf61nLC0qzvKmpP0TD27pL47fMSEWQY/ZRAHxz5QXOPwqoYWFB80aaj6Kwvb+105 7/O5crUDm/FmlazrnhrW9J8PeIZNB1u8tnitdZigW4aykI4kEbfKxHoeDRzyp+9BJvpzbfO3QXLG fuzvZ72dn8nZ2fnZn59av4N/afh+NPhL4QaP+1tqMsl3ol14i1S/uvDVkn2e0jljt40hUN88jyyH PZVjJJyyg6rH4xU3L2FFyv8Ayzsl3fvfJLrr2IeCwEpL360Uv+nkXzPsvcVrbt+nc7rR9O+N/wAJ fj18H9F+Iv7Qd74w8DeMjqGn22nvoltaO2ow2c1wqSlGJERiilcMvR4VU8OKlYvE4hShVpUopa3j GV3rtq3Z9dndKWzsJ4XC0ZqdGVRva0pppf3tIK66W0s2nrqfd9QahQB8CftTQ/Di7+KPg6z+Pt00 fwkfw1qB0iO+mlh0yXXhInF0yEAyfZ8eUrnaf33BIrWlGtib4bD1HB/E1F8spJdE9HaO7Set10RM pRwy+tTpqS+G7jzKF+tmmve2vbS3S55l8BviVoPjqy/4J5eEPh34lXV/FHhfwpBc+Lo9OlMqabp/ /CPG3eO7YfKHa+azAQ/NujJ/hNaV1Vw6U6z1q7Ju7f2ua3lZavvbqZUeTEc3s46U+trJPblT+/Rd F5I/UiuY3CgD46+Lfwm8OfFX9oXwRpnxN8M3Gu+A18I6g+lWs/mnT4NUW5g81p1UhTK0Dp5e7tHL ipnVlKPsI1ZQ62jJxcum6s7R7X636GlKLpv26gpPa7Sly+id7X118rHx1+zL4U+Gfhr4kfsweGPB Hwul0/46+DLC90T4jXculzRJaxR6dLFJdNO42tJLeR2/lOpJaO4l7Hh+2hJKq8S6jqfY9pKTUt23 G7S5dY2atdq2qRdSOJknCdHlhDafKkpJ6JRla75tH3Vtep+xVMwAkAZJ4oE2lqz47+Lfwm8O/Fb9 oTwRpnxN8M3Gu+Al8I6g2lW0/mnT4NUW5g8xp1UhTK0Dp5e7tHLipnVlKPsI1ZQ62jJxcum6s7R7 X636G1KLpv6xGCl0u0pcvayd7c2uvlY+Ov2ZfCnw08NfEj9mDwx4I+F02n/HXwZp97onxGu5dLmi S1ij06WKS6adxtaSW8jt/KdSd0dxL2PD9tCSVV4l1HU+x7SUmpbtuN2ly6xs1a7TWqRVSOJknCdH lhDafKkpJ6JRla75tH3Vtep+xNMwM3VtI0rXtMvdH1vTra/0i8jMNxZXkSyxToequjcMD6GonBVI uEtmVCcqclKDs0eXD9nr4DDIHwZ8E4P/AFArXn/xyuT+zsO90/8AwKX+Z1/2jiv+fjNjw/8ABv4S eE9Xtdf8L/DLwvpOuWu7ydQ07SbeCaHcpRtsiqCMqzKcHkEjvWlPB0qUlOKd/Vv82RUxuIrRcJzb TPS66jlCgD4z/ao8H/Dm/wBU8A+OfH37QeqfDCfQjOml3OmXtvaPNI64kILozOCpAKcrwpIyAR0Y WjmNWfNgOXTfmgpXT6NuSVtL23urp7mVWtgYJQxcXK+yUmtutkm7q+/ZtHn/AMC9d+FeofFHwzB4 Z/bg8SfELWGW4eHwle6jazQ6iv2eTLMqQqxCDMgII5Qdeh7MTQzeFKUsVGkqfXlpqL+/ndtfLa5n CplrmlQozjN7Nym157q2x+hleWdIUAfIP7Q/xC+AOq+Ifh78DfirJpl+ninUrmJpzqiWsnh2e2sp btJ3cOskLME8tGUgkyAdCQemGX16sY1afNGe8HFat9bPba97pprRow/tCnQlKLcXHaalqrPa69be m6PEdB8H/sd/s8a/4C8R+C9VPjDxfqPie10jR7KfxMdWl0+41K68qW4t4GcqpBnkkkcLu27znJOS eX45QvmNWo6cW2uZJR5m21dJK7bel72vdLQtZlhq8uTA0qanJJPlTu4rfV3tZLyvazZ+llcxoFAH knxY1T4w6Np2lan8IfDOheIbuCZjqOj6xetZSXMG3gW8uCok3f38Kc9aca9Kj/GpynF/yNXXnZ2v 6J3F7GVbSFVQa/mTafldar1szxmy/bJ8AaDqOneHfjjoOs/CnxPeN5UMPi6JUtLqT0gvEJik/A11 UMPRx1/qNVTf8rThNesZW/A561Stg7fWoaP7UWpx/DVfNH1bo+taP4gsINV0LVLTUdMmGY7qymWa Nx7MpIPWuerRqUZclSLT8zWlWp1489OSa8jUqDQ+M/2uZPtE3wV0HxL4/wBQ8IfCLWPEEln4m1TS b4WM8mbZ/scLT/ejhkudiOy85KDIDZrow0sU5Ong9KktpWTtbVpXuk2tm16a2MaywySqYpKUY68r bSfm7WbUd2vm9EY3hL4C/szaN4r8M6xoPxZ1q812y1C3ubK0m8eT3S3E6SK0aNCZSJAWAGwg7s47 1vUp56oN1q1Vw63jBK3VNqCdrb2aIji8qk0qdCkpPZpSun0t72/Y+5a4DpCgAoAKACgAoAKACgD5 r/aA8ffE7w/qXws+H3wjh0a38Y+OtSubNNc8RK72elw29s9xIxjXmSVlTaiZGfmPRTV06tOkpSdP 2kukb8qfdt2dkvJNkSpOq0nU9nDrJLmfkknZXfd7GJ4c8Hftg2viDQrnxP8AGTwLe+GobyGTULKz 8NSwzXNsHBljjcykK7JuAbBwSDR9d5k4rBQjfqqs3bztyJO3a+po8JQj7yxNRtdHGFn5OzvY+r6g QUAfHPxy1/4C/ErwP4P8X33xxtfCM2m6xcP4Z8c6ZepG9pqEIkt7iNNw2yLgyxyRsMEfQGuqGBx0 a3+zJe0itnZxaktpK6unps7p6mE8XhY07YqLcJduZSutmmk2n2drNHgvgdfhl4y+IPgGT4p/twWf xMm0vWba70DwlAlrp9vPqYfbbSSpES0zrIylFJADhTzitK+EzetTarUqdOmtXyLVpa2bcnZaXaS1 McPi8roy/cupOb0TqNtRvpolCKv0u/wP1ArhO0q3lrFfWl1ZTlxBcRtE+xip2sMHBHIOD1pXfTQF bqrn5qfEL9nr9jrwv43+G3w38VHxBc3/AItv7m3hFz4yvHi02a1tJL0STq8+UyIcIcZ3lcV18ma4 mneeMq9HHSPvNPo1Dort+V0ZyxuCoz5Y4el/e0tZPur9XZfM6HWPhb+yf8HdY+HXivT9a13U9cn8 VaPpum2lp4zu7xvtc93HHC7QGciSNHKs6kEbA2QRmtWs3UZPFYqqoW15lGz/ALrtBfFtv1IWMwFV qGHoUnN/yrVd2tei1+R+ilcBuFAHl/jD4gyeGfHnwr8Ew2EMn/CW3F+Jry4m8tbWG2tjKdvHzSMx jAX+7vP8NXBRkpKzculvxb8umnVoyqSlFxd0o9b/AIJefXXon1PmeP8Aaj8f3fimPxbYeB9Im/Zw k8Zw+BYfEH25/wC0bu7ku1sPtkUO3Y1qL1/K+9uKqXHFauWGjJ4dxlzpay05VK1+W3xeTeyloSoV pQWIU48rekbO7je3Nfa/VL+XzZ90Vzm5Gyq6MjqGVhggjII+lJq6swT6ox/+EY8Nf9C9pn/gJH/h XH/ZuC/58Q/8BX+R0/XcT/z9l97/AMwi0Dw7BPHJDoumx3MZDoyW0aspB4YYGRz3qo5fhYWnCjFW 6qK3+4mWNryvCVVu/S729Lm5XWYBQB8cftZr4Wluvg5B8Vru7t/gTNrNwniVopJYrZpvszfYVvXj wVtjMGzkhTJ5QPBrSk6tSX1ejU5JT0TTs3bVxi+jflrZNLcTUYJ15U+dQ1s1zJf3nHW9vR73tofJ Xwz+I/gK/wDg98D/AIP/AAm8S2l54+g+L95daZo2iTmVrHR4PFV9PPLJgnZb/wBmGUAucMsqgZJF a1adfCwWIrSevuq8ruX2bb3dtW77Wv0MaU6eLm6dKN7e82o2UftJ7JJvolrrbufr5XMbhQBz3iDw t4e8VxaXB4i0i21CHTr+21S1S4XcILuBxJDKv+0jgMPcVhUw9Ks05q/9fl5bGlOrOlfle6a+83CY 1KjKh2+6OMn6VUcPTj70YLTyRk5q9m9yWtRhQB4T8fviBrHw/wDDHhKXQ20+C88QeKdI8PvqGqrv trCG6uVSSVxkAnYGVASBvdM1VOMJvlnDnvtHu+nR7b7dLETlKC51PkS1b7L/AIO1+l79DK/ad8Xp 8MvhH4m+MGn2ehz694OiTUrb+1rZJWuI1kUyW8Ln5kllTciFf42Xg1nHC0atVVK1FTtvfeK6u9vs 72/Ip4qpGk6VGs483Z3TfRNdU9vK9z6Gik82KOTaVDKGw3UZ9aejGS0wPhz9qX4FfsqJ4duPiv8A FbwBYx3NjrWn6jNc6NYBr3XLoXCeVaFEGZjcSFY2XG5gx5HWsaeC5pP2dZ047yfNJRS3k7cySfZp XT21Oh46rGKg4e0e0VZXv01a2XZu1t9D5+0yL9mOx1DSX+Jn7C2seAfCepXMNrB4n1/R4mtIJJX8 uP7SY3YwBmKjLgAbhnFbU4YHEyVLDY6pKb2UpV4c3lFyaTb6Lr0Kq4jM8PH2lajT5Vvy+ym4ru0l ey6tXt1P1koOUKACgAoA+Ov24zoMfwQh1Dxa803gzTvEOk32s6LAZN2u2MVwrzWYCcsXQEhOjlAp +9VQc4u0Z8iejlezSe7T/O2tr21BRbacIc8lrFWurra61+V9E7N6Hhtv8Uf+CazRQOng7wagKqQk nhBgy+xBh60f2LSev1iP/g9//Jm39p49v/d6n/gr/gH6b1JiFAHh37QPiHwx4e+HwfxH4Bh8b3Go 6ja6bpPhWaCKYanqMz7YE/eDYgB3Oztwqqzdql0aFaL+sNqC1dr39Elq29kvPXQqFSvTkvq9ud6K 7sl3bfZL/gHyPoV/8NLL4SfHn4h/Ev8AZW+H+k698K9aksdU0bSrK0u1a2js7G+klSXygC6wXxO0 dWjx3rGOCy+rKDpwqRi91J6p3t0la2z3va5q8dmVOMk6ynJbOPMk/vV77pfI/SWN0ljSSM5jYBlY dweldBgiSgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoA KACgAoAKACgAoAxfDf8AyLugf9eUH/otaANqgAoAKACgAoAKACgAoAKACgAoAKACgAoA+OfjT8VP 2XPCfjifR/iv4Dg1bxcltFI93J4OfVSYmB2DzxCwOBn5c8Vz1MBl+IfPia1KMu05qLt6XOqji81o x5cHSrSh3ppuN+uz37nnf7P2oeBPFX7SHiHxl8CfhjP4f+F8/hNrXX9Xn8P/ANkQ32qrdQm1S2DI rEiAXPm7RtO2HPKg0qVHA4abp4apGo3reD5lBdub+9o7dOW/VhXnmFaKqY2M4eU3Zy83G/2dk3ra VtrW/Qquk5QoA+G/HWj+OPin+0N4w8A6n8bPEPw/8I6DoWnX2i6Z4Ykgtp9cMzTC5uXmlRtyxOiR 7FHG4E/eFb08Ri4wccFGHu/E5Q53rskrpJaPXq0+xjOnhObmxl3zfClLlStvtu9V6Kx6/wDCf4OX Pw88RXutTfHHxx4zWeye1GmeJtQt7iCHLxt5yrHGpDjZtBzjDtxzU1K2Oqq2KceXyp8jv63fnp/k OEMDF3wsWpf43LT0f5n0LWRqFAHx78evE/xm0vxD9h0z4p/D74YfDGSKNV8T6+ftWpXUpHzrBbuy RqFyAGZj9K6sN7apeGFwftZr7UpWgvkrtv1svM5sRLC0rTxeKcIv7MUuZ/8Abz2+SZY/Z4+Bnwk8 N+IdW+Nvhnx/dfEL4ia5Yf2Xf+Nru+hnM9uZElMSpCBGil442xgt8o5xXJPCYrDVW8SuS/2IxUIe qir3fm23qdNPG4XE0lHCq8V1cnKXzlJ7eSSXkfXVMAoA+b/iZJ+02viiYfCvw18OL3wl5MeyfxNe XUN0ZcHeCscTLt6Y5zWbeCv+/wAHKpL+ZOC/9K10KVKtNXhilTXZxk/xTOS+D/xG+Odx8ZNf+GHx q8LeCNDMOg/2xpk3hu6uJ31ZPOjid4y8ajZEzbZFJ3BpITgh81pCOCnBzw2GdKSdndw2e3w73tvs rNPWwp06tJpVcQqnNeyUWtrXvd7q69b6bM+vaBEFxPHbW81xKSIokLsQM4AGTxQI/Ofw/wD8FA/g Tf8Axd+Jmn6rdeT4e03S9IXStbi0S6a7vTMbprmGUeXuWONo4SoOATI2Ohrd4fCPatTUtnJ1I2ku iXR8ut99/MmMcxu4/VqrX8qpyvF93/i6bbPsdx8AviZ8JvFHxj1jQv2e/hrY2PgK40O41PxF4ns9 AfSx/aYuIVtrfeyKJC8cl05Ufd2A/wAVckaGCwr9nSnGdR9Yz51GK6btRV2rJNbPQ6qs8xrRVTFQ nCC0tOPK231XV2W7a67n3PWhgFAH5wfFnSPhN4s/ae8UeHf2i/iLc6foCeHrC48IaIviGXSrQgNK L53EUiFrgO0BG8/6tl2g847MPHMq8PZ4KcqaWr5Uryv1u07pbWW2je6OapVwOGlz4mnGblpeV3y2 6W6X3v126Ht3wJ+Hv7MvhPxbqOo/BjxLBqPiiXTXhuIY/FFxqpW1MsTM3lSTOFG9YhvxkZxnk5nE YfM6UebG1ako9Oe1r/JLW1x0cZgMQ+XC04Rlv7qs7f5H1jXKdAUAeGfF/wCAnhL4w3Ph3W77Vtc8 PeM9AEq6Z4n8MXps721jl2+ZFuwVeNiiEo6kZUHg1ClXoz9rhqnJK1nopRa7Si9/LZruX+6qQdKv TU4PXqmn3TVmn+HdHK/Df9l7w14G8aWXxI8ReOfF/jvxzYW8ttp2p+MNQW4XS0kXbIbeJFVEd1+U vgsVJGcE06lXF4qUXiqqajtGMVCN9rtK7b7XenYUIYbDxlHC0uXm3bblJrtdvRdbJH07VEhQB8n/ AB8+JfiWPxPovwU8A/BjT/iL4r1jSZ9cu7LX7mG202yso5UhV5mkVgzNI+FUKT8pNTVhgZ0v9thK eukYpN+t20o+t732LovFqqnhasaXecnL7ko3bffotLnOfA4ftBaB4q07Q9d/Zm+HXgL4e3ZlbUdR 8K6zE8qMsTmMiBIl8zMmxSSeAxPas6SyyndYXDVYTf2pclvm1Jy9PM6MRHEzSlWxsKqX2VGon8uZ WXc+062OQKAPlr4wfEn4xR/Ezwt8HPgjo3hz/hJL7RbjxDf654sllW0s7SKaOBY444gWkkZ5OccK ACeoq41qNCDlKk6suiTUUl3bd/RJLXXsZujOtNL2vs4d+XmbfZK6W2rbfYt/D6w/a0g8X6ZP8TtY +GU3gnEv26Pw7BereP8Aun8vyzIAvEnlk5/h3Y5xWSxFOpJ8uD9m3vL2il+HKr9t/M0+rRp2axcp 2+y6cYp/NTdu+2ux9NVQHlnxs8Da18TPhH8RfAPhvxDLoWv69pFxZWWsQsyNZzOhCPlfmAzjJHOM 4pKrVofvaHxrVeo1CnUfLW+F7nxNN4q/bzt/j5oRf4V+FZ9Lj8G3sUlpbeIJ10i4m+22m2dpDFlb gLvCRkZMbyHPy1r/AGng7+x9hVS35b03K+10+a3Ktnre7WhP9mVW/bfWIX25uWdtdbOPd2vfZJNX 1PpT4feJv2pNR8X6Xa/Eb4U+CtG8HSiX7bqek+IJLu5ixE5j2RGJQ2ZAinJGAxPaodbBTb9jh6kZ v7UvZ2+fLJy8lpv5FfVqtNXliYTS6KM0/k3p5n0xSEFAHxn8fG8Q+Nfifonwoj+JureCPCw8K33i JpdAmjtr3XbqOVIhbpM4O2OJW3uFG5jKnIANb0quIhGX1RLmVryceay6WW129272ta2pjOGGck8X rF6Jczim+t2rPRbK66vocl8Ovij4ouPD/wDwTthHimfUNc8aeHYW8SWLyLI97AfDpunvJh94FLuK 3G/gZnYdWFE5z5ZVKkdJve1ve30+Sd0unoKEabap03rBX3vZfDr82tXrdep981gbhQB80+L/AIYx eJP2i/Cfi7xB4Otdc8Kjwhf6VBfXsMdwmiX32qGXIjfODPESN4HH2cDPzVz16dLEpUa6ulqlq432 d+l0rWv52N6NSrQTqUZcrejs7O3S3W297eR8tfAnwh420Xxl+zb8PofglqHhvWfhPZXWjeKPHdxZ Qw2Wu6clhJaxLbTLzM1xcLZ3HqnlsCeSDFKOXwkp0EnWl8S5GuV7uTbVr30i1upPoVVWMknGrP8A dR+F86bktkuW7aSWsk7JNLyP07rrOYKAPhn9pvwB+zHonin4ffEz4j/Cg+JfHt1qs8Om6PoWipf3 fiS4aykjZbiIITMkUILgsQEZEOeAKx+qUpt1a1f2dNfE3KWvZRSd07/yq71vpc3ji8TFRpUKfPLp 8Kt3bbsrdPe79zy34U/GH9nb/hOPA03g79j3XfDOqazr0vh2w8TP4St7SK0vo5ZIbhDOOUaJoZw+ OR5Tjtin9Wyrm9zEuc0rpNVX6P3rrqtem5MsVm0o/vaSjBtptVKXR215Xdp20X2tLXuj9OK1MgoA +a/j7qPiS/1j4WfDTwl8Xv8AhAdc8Z315bxXUGlC/ur5be2a4kjgZvkhYRo7b3z0wAa1pzq0oynR hCUl/O3pruorWT8rpJaszlGjNxjX5+Vv7Fl02lJ3sn0srtmf4R/ZC+Dmg3y694rsNQ8f+Ljkvrfj 27bVZNx6lIn/AHMf/AEFcWJhWzG316q6iW0fhgvSMbfi2zroVaeC/wBypqnfqtZP1m7y+5peR7L8 Pvhj4D+FWl6povw88NWuhaNqN++pzWNjuEP2h0jRmRCSEBESfKuFyCcZJzrCMox5XOUktuZuVl2T d3by8yKtV1pc8krveySv5u1rvz3O/qzM+Xf2o9a+FOk+G/Ctt8RvhafiLreq6kbHw54Rt7JLu4v7 wxs7+Wr/ACqqxRuzuxAVV5qZYehWg5Yqo4U1a7Tkru+iSg05O+y8r9C6VfEUqihhYqU5d+WyS3bc lZJLf7j5z+H1v8GfDvxE8C2PxE/Ymg+F+s6lqUMfh3xLPZ2V1bDUVxJBEZ4CfJmLJ8m7GWUAHNEK eCru2GxNVzV3yzdaN0tXbmlyyst49r6WNq2JzKlH9+oOD0bg4O19FdWTSe11sz9Lqo5goAKACgAo AKACgCpeQPdWd1bR3EkEk0bRrPFjdGSCAy57jOR9KWq1QWT32Pzv8f8A7NdrN4h+GXgrxz+1n8VJ 9b17VZJvDsTvablvrS3kumdJFgBjZYY5TnI3AlTkEg7vFZlVi6kZ0YuOulKzd9Gl7+qaeq7C5Mtp v2fsJtS0f7yTXfXTTVKz72O9vvhRqXwm1TwX4s8Z/tY/E680hvEOmWCaffvZvb6hcT3UcUNvMEgD COWRljYgjh+o61cMXmFe8JOilZ3/AHXK7eT53Z9tNyJ08up2lToy5r6fvG9e9uqW78j7ermNAoA/ Ov44ftQfs/8Aww+Knw2+DGseGNFn0T+1r9fEFtceHnmTSt1hLdRy26iIo7yTmMOVycSMT0NTHL8v q0fZ1XT7pOaXI73bkntfZXtq0arFZpCqqtCNXXS8YyfOrbRaevLu7XskyKT9of8AZ71rxF8PtD+A nw20zXvHuoeJNMtzHF4Se2+w2TXCfarszmFREYYd8gbP3lA71j/Z2U4Nqq3Sk9koSi5cz2aSvs9X 5X1OiWLzzExcJxrwh9pzUlG3VO7W+3X0P0ZroOIKAPl34jfsefAL4pfELQPiV4t8CWF14hsLma6v CYwV1gvatbKtz/eVFKsuMYZFPasJ06sppxqzS6pSkv8AwG0ly+fLurp7nVTxThGzim1tpH8br3vK +251PhT9mL9n3wPr1h4p8J/CPw3pviGxYva38FmDJbtjG5Cc7Wx3HNJ4fnadSpOVne0pzkr97OTQ SxtWUXHRJ9oxT+9JM95roOUKAPlb9q2++DieEvCujfFjwlrXie61TVPK0DRfDENxJqc14sMjO1uY GV0Ah8ze24Da2D1pwil+/eI9hy/bvZ66WSs737WffoClUb9lToqrzbxdrWWt23ZK3e67dT568IfH j4P+MIPgn8L9P/Z1+Iui+CbDxXBpug/adK+z6daapYTyptmfecm3mhmkYMSd8BJyRUuGX8vsaWLc paSsozvL7Wrceracndeelwc8xlJ162Gik7q/tKfu7xukpdk1Gy105Vex+l1MAoA+Z/j7r/iXwX4g +EPj608P+Jtd8FaJqF8dZ0vwpA9zcl5bR47aV4EO6WJHZwRzhpEYj5acMRTpP2daoqcJbya001Sb s7J99NUlfUTw869p0oc847K9nro2rtJtdn0bfQ+YE+HHxLP/AAr/APaG1n/hK7P48eLviDprR+Hx fTG20Tw5LeBHsLi1B8oBNMSWSRiMiYnBzgUf2nUavGrag/djBpWlfRS25uZv3730WlrIf1CCXJ7N SqL3pTWrTWrSd7cq+C2z9WfpvSAp3j3UdndSWUCzXixs0ULttDuAdqluwJwM0rpasLX0R8a33jv9 sXU7O4sNS/Ze8GXdhOhSW2ufF0MkcinqGVoyCPY0qmIy2tBwqYas0+jVJ/8At5VPC42lJThjKKa6 pVlb58pnfDJPjr4Z8T6Wlh+yR8OfCWh395DFq2raBrdqs0FsZAJXCRxAyFVywTPJAFY0qeV0ZXpY WtGb2clDT1fO2l3t0Nak8wxEf3uOpTitbL2uve142u+767n3PXQYBQB4B+0VN4psPBnh3X/DWm6z qdroniTTNT1jS/DwZry906KbdKkSqQXwfLdkHLIjLzmnGuqDvKfIno5WvZPq9Hp0btom3pa5LofW PdjHma1Sva7W2t1r1SejaSPjL4i+EfiH8U/Bfxi/aZvLHxxoPjqxMdv8KfC6Tz2c9iIfLWGa4s1O 1nurt3LrKDiHYDjk03mkqWuHr2oQ30XLU73urtP4Y2t3W5ay9TXs61FSrT87uHazTsnH4pb9nsfq PF5hiiMoAlKjdjpnvUXES0wPmD4oeOPC3ivwB8UNE8b/AAV8X+I/DGm6uNBudGt9Je4l1YbY5BdW iqdzRKzDEqkFWTIwRUVHgqiSniFFLeXvJwktUrpXv1TWhVJ4ynLmp0rt7JuNpRe71drbpp6nwx4e 8PfArRPEGm69efs8ftIa+mnXEd1Y6T4ntdR1GxtZo2DRusEjlSVIBG7cBgVtWxlHFw9lic354PeN rX8m4wTa+epcKeJpPnoZbTpz/mUoXXpebS9UvQ/YbpUGQUAeC/tDeCvF3jDwVot94BtbK88a+E9f 0/xNpul6lJ5cGpSWsm5rdn6IXjaQK54V9jHpWc5KCUpQc431S3a8r9Vul1asVCPPeKnytrRvVJ+f Wz2dtbM+Y/ib43+PX7RXgfxR8CrD9mbxJ4P/AOEqt/7J1bxR4pu7T7FpdpLhZ5ofLdmnkVN2wKPv bTxWlXFZfyv6vOdSp9lezlGz6OUpJJJPXRt6aFQweLg1LESpxh15ZqTa6pRWuu2u17n6IwxiKKKJ SSEULknJOB3o1MyWgAoAKAPEfj58Rdb+HHge0u/CXhy313xxrurWWgaFpl5J5UEt7cybFeZ8HbFG okkYgZ2xnHWjlw8k3iY80FrZJNt9Er6Xb69FqJ+1bUaMuVvq9kur038l1dkfN3iPxL+1n8D9Bu/i n8U7n4b+LPh3o6Ld+IdM8PWFxZXenWQb99Pbu+RN5UZ3lWClghxzWcPqNeSp1cBGmnopKSlZvbmT itO7Tdt+hdSlOnHnoYyc5LVqUFFS8k4ybT7X0fVo++43SWNJIyCjAMrDuDWhKJKAPI/jV4ETx94I ktYPFP8AwjOt6NeW+t6X4iZVdNMvLZt6SSKxAaMjcjqSMo7DIzmiKq88XRipSvonez8nbXVdVtv0 BypRjL27tC2rWjXmvNPXz2Pgvwh8HvjJ8TtN+Len+Lvjr8M7z4MePPE6Xviu88GpLJcXxFpY2clg kjkJAJYrSBWOWYec2M5FaVnjIuWHeD9nOWzc+a0Xvyq2r0dm7W7aGVF4GSVdYqVSMenIopy/vPme mq0S17q5+pqqqIqIAEUYAHpWZqPoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgA oAKACgAoAKACgAoAKACgAoAKACgAoAKAMXw3/wAi7oH/AF5Qf+i1oA2qACgAoAKACgAoAKACgAoA KACgAoAKACgD4Q/aE+PPxz8K3fxpl+EXhrwo3hr4U+HF1zXNS8TTTmW9lNvLdfZrWGIdRDGpLsQM yAdjVxqYWnyqpQdST3d1FRXq0231sl27mcqFWspOFdU7bLl5m356xSXTq99DsvhJ47/aBj+L7fDv 44z+BfsOo+GZNd0WXwqtzvvTHcQRTgmUDAiE8O4Hr9oQrnDYSrwrQahhvZcr19/mve9rJRXnfXTT uh+w9jJP6w6qe37tRtbe7U5f9u6aq+qtY+vaksKAPzS/a8n/AGZtM8Z6t4n8f/CPxd478b+HdD/t PV7jwvdXcaeHtL+bEk7pMkcW8Qudo+ZxFkg4FaQioShOeNlR5tIqN23td2jFtRvbV6X2E5VZQkqW FhUUdW5cqV+ivL4pW2Su7H0F8NfhZ8Bvgz8Y28LeB/D2o6b471Pw1PfxzXWp3l3Fc2CXUKTqgmld d6Sm1LYGQJF5wTUqWIqQbq4mdS1vdk7pXvZ7Ls15fMJSgpKMKEIJ/ajGKenTTXrfs/kfVdSMKAPz 08bJ8DbT9q3xveftKw6M3naBpY8EzeMo0fTVtl8/7atv5oMQuPPKmTPzbDFjjNVHBzzdfV4NyUNe RNq9/tNJrm/l62t5ieM/smP1j4VP7dr2t9m/2e/S9/Is/Be6+Esv7Vevx/s2ppf/AAr3/hDpT4wP hhQulf2r9rtxp+0J+7Fx5H2/fs52hN38NVPD1MtisHUk9feUW7uFtL6tuKlfbyuluKOJ/tJfXErr 4ee1ubra9lzcvfz3P0CrMoKAPlT4h6P8VfFvxR1Lw58N/wBpXTvC1za6Zb383hQ+HodRmtoXZ4xO 0jSqQsjo4AI/gOK2VfE4empRw9OUXezk5XffRdFdGSo4evN89Somt+VxUVfbeL1fqZnwj+GcmgfG vXfEPxL+OMvj34zWPh1bS2sGsYtNi0fSbidXZordGbd5s1qgaQk/6oDiok8ViEq9SMIQV4pQvvo7 ybd27bKyW+5qo4egvZ0lNuWvNN3ul0jZJJK+u7va59fVACfyqbaAfF3jD4geN7H44+PfDHwB+CGk eIPGNtpmlS+LPE+t6oNNg2sJzZWynazSOqGZuFAUScnJqVRy2glKtSnOUvswUbRS6tzaim+y1drv oVbFYhciqwpwjs5Jttvsoq9lbdvfRdT1T4V+Iv2h9X1+9tvi38NPCvh3w2tm0kF5oeuPfyyXO+MK jRmNQEKGUls9VAxzxp7TBtcuGoVKb/vezt/5JJu/ytvqS6FSl7068J+UYzT9byVrHv1ABQB+df7V fjzwroWq/EPV9L/Zj8M/EfU/Aegx634q1/xDHaxR6fbbJJIrdJJEZ5pjFG7hFGFDLnG4VMsPgHKE sXzuUtlC/urbmd5RS9Fq7eRccRj4wl9VqRhGP81/ee9opJv1bsj6G8N6X8Jfhv8AHCw+HvhL4V+H /D2v634Wu9Xt9a0bTre1a4gt7u2iuLdiig4DXFo+CcH/AIDUUcLQpRc4X5vNtqz7Xb1TWunValVs Xia7UKkrw/G6+W1np8z6OrUyCgD88fEn7bE3h/8AaPT4dn4c+PbnwbbeG9SmuLa08KXUt3cahBf2 0KXEGBl7Ty3mBkA27nj55FbKtl/s+WWJprvJyej/AJHpv1+TIeHxzlzQoSfZXjqv5t/167Ho/h79 onxf8Tvil8NPDXw/+FvjbS/CP2i8n8V6r4u8PzabDBZraS+QsTy4zK115HCg/LvzjrWcsTgUvZ0a 8a0pfyNvltrdu1rdLeZSw2Mf7yvSdKMe7j719LJK7fe/S3mfY9SMKAPhz4+aV8SfGH7RHwh8L/C7 xPpvgjX7DQNT1h/F97aG8fUIPNghfTUg3KsqbninfccqUQrj5suFZ0G50aSqT2kpNqPL0vZN35tm ttb7kypwqpRr1HCHTlS5ub1bsly7rW//AG7p6b8P/AH7SWi+LdJ1Px/8edF8R+EofN+16NaeFlsZ LnMbqmJhM23bIUY/Kchcd81UsbUrLklhqcE+sZzbXomkvIawuHpe9CtUk+0lG3ztqfS1QM5vxbpG ra94a1vR9C8RT6BrF5btFbazbQpNJYyEcSKj/KxHoeKFOUPegk305ldfNJptfNBywn7tS/K97Oz+ Ts7Pzsz4w1X9kj4w614g8NeK779r3xSfEWg+cLG/h0CwjkjSZQssTEfejbahKHIyinqAaX13MOfn jGiujtTlZrs/f76rZrvq70sJlvK4SjWfa9ZaPuv3ej6drbrY9b+H3wb+MPhTxbpOv+K/2mNf8WaD bCXz9AvdGs7aK73ROi7pI/mG1mVxjqUA6GqeMxdX3KsKSj/dhJS+Tc2vXTYj6rgqfvUfa8396opR +a5Ffy131PpikMKAMCXxPoEHiSx8Hy6rbr4nvLObUYNNLfvZLaJ445JQv91XljXPqwq1Tk6bq292 9vna/wChPNeXKl/kvX16HmPhH9on4NeO/Hus/DLwp46sL/xppbTLNYxbhvaFgswicjbIY24YKTtO c9K3qYOpTg5tp2tdJpuN9uZbq/mYwxCm17slF35ZOLUZW35W9HbyPba5ToCgD41/au8QfBG5HhH4 efEj4da/468XakJ9Q0jQvCNpPNqVtFHtSW4SSFlaGP8AeKpO4BiQOcUezpQSxVXE+wtopJvmd9Wk km5LS7TTWzHCpXlJ0KNFVU9Wpcqil0bc2knro0097Hmv7MGmfCfwR4403RvAf7LPxO8Jalf2j2H/ AAlXjDT7h4rG1ijaRYPPmkbyYiY1VUQAFigx0xlGpg6nKljpV5xVoqSmrLrb3YxWnV6u1rms442K fNhqdKDd5ck6TbfdqMnOWvrbfuz9FK1MQoA+O/i/8TNL+FP7Qvw28S/E3xHfaJ8JZvDWoWdnfszr psesvcQEi8ZeAxtlYRF/l/1vfFb4dzxEvqdOSUnrZ2Tnbom/5d7Jpu/kZ1KfJH6z7Nyto2rvlvre y6Pa9tLW6nMyfHbwf8Wf2i/gTYfAnxs3iaGwXVm8Wy6LM82nW2ktZv5fnkfu/ON6tp5ePmx5nYmt MTTrZelQrtJz2jo3przdWktVvZ3JpQ+tfvo02lD7TTjvpy62vffytfTr91VyGwUAeB/Faz0e2+Iv wL8X3njLRdEv9H1K+hFrrUwi/tS1uLRo5ooCTxMri3kHsjDvV0qFavL9zT50t7brtJd7bejZnVr0 aEb1pct9n0v2fZNa+qR4TcfAb4zSeJbbwNpGteF0/Z/bx4nxAXVBJMdXhc6l/aslkiBfLKveFx5m 7/VSFcE1j7edNey9i/aJ6T5ly8rvf3fi5uVuHZrW/Q3VOlUftlW91r4FHdpaPmvblulLvfTzPvKr ICgD5J/ai8E6T8TL74NeAX+Keo+BfGOoa3PdeH9R0iwS4uZLu1tZLhxHK3+qxBHNns6llIOaajXh ++wzgpQ/mV9Ho0ldXvfXfTXRq4KeGv7LFQlKEukZcq01Tk7N6NaWs79bXRy174D+Jvwr1TwX4n8f /tgeJL7w7L4h0zTm02bQLJY9RluLmOKO2d0G5FldljLjpvzWlPEY6u3CUKCVnf3JJ28m5tX7aPXo ZToZdStKn7ZyurfvVJX817NXXfVaH2/WRqFAHzh8evCPxDutS+GfxQ+FWl2Gs+MfA19dSnw7qM4t l1ayuoDBPFHMeIph+7dGPB2FSQGqPaRpSUqsHKHXltzLTSST0dtmr6pu2pcaftU4RmoS6N35fSVt bPutmkeM6vcftA/tE6z4B8K+JPgdN8O/h/oviTTPEWr6xrerWt1c3J0+5S7ht7WKFm5eaKIM7EAK G7mqq4rCTSjg1UlO+8oOEYrq9dW2tEl3uxQwuIpvnxNSCjb4YScnJ9Lu1kk9XfV9D71pkhQAUAFA BQAUAFABQB8U/Fz9inwZ8Wvix4S+KF/4z8W2E1he3F3f2NlrVzEkoeye1RbXawFsQSrMU+8Ayn7x pPE5hCUVRrtRV7aQ93/DeDvfrzN6PToaRjg5RftKEXL5+9/i95bdLW1SudL4c/Y0+DmgeJPD3ii4 ufF2u3uh3keoWNt4k8R3moW0F1Gd0c3kyOVLo2CpIODzRVrY7ExUMRipzjdO1oJO2uvLBO3lcI/V aV5UMNCEn1Sd1fteTPrGmZhQB4N8StZ0PT/iv8AbDUfD2l3OoXd9qstrrepSmNtJEdhIJPI7NNIs gTDY/d+aeoqFg6FdtyhzT6W/Fy7pdN9Wn0uDryoxac1GD3uvmkn06u/lbqeAQftM/E698Q23xE03 wt4dl/ZruvGtv4GtL37RL/at9JLerpw1CJQvlm3+2vsC53NGhcdRW0YYOjUdCNFqSWs1y2UrX5eX e3Ru/wAXSxkqdaUI1/ar3rNQ5d4t2vzX3a95K1rdbn3xUGoUAfn98eP2jfi94F+PXwe8G+Ffgx4z 1HwvLquow3b6etoYvFEY0qaZEt2Z8oYpdshLbciFgM5AOsMTgacXTqVGm9/3c249VytL3r6J8t7J u9rMh4PFVWpw5bdPfSv3519nyvu7dzodQ+MX7Q3xD1fwR4a8Hfs/eL/BIbxBp1zq3iHxJPZC1h0u KdHu4yquzM0kIeNQozlgcjFS8ZgKa/2ecqknpZ0qkVro23JJK268+hbwWLetdwjFa+7UUnpqkku+ z8j7gqACgDyTx34Hv9a8c/CTx9pmp2dq/hG+vDexXoO25sbq1eKRUYfdkEgt3BPBCMON1T7zlFRj zX/Ds137ejY24KLc5Wt/Vn5dfVI+XLn4M/FR/Flr8P8ASPFPg5PgO3j5PHq6gLqQ6zDKdT/tWSxS MDYQ94XHmbs+VIVwT1vmrwhyfV5c6btUuuVRd76fFzcrce1tW90QpYWpLn+sKzVuSyu5Wsveva17 S2vfRdz7+pFBQB8xeKfBnxk074faZbH9o+y0PXLHULu5vvFGoaFbvHcWskjtBAY2kVU8tWRd2ctt 6c1rRr4upO9PD05Tf2fftps1bW769OxjUp4SlH97WqKC63ind9HdNWXTQ8x8IJ8TR4s8MHUP23fC mvWH9oW/naHbaHZRyamnmLut0dbglWkGUBAJBbgGuupHM+V+0wNOMerXPdLq1fTTzOeFXK3JezxN SUuico2b6J2jsfddeedwjMqgsxAUDJJ4wKNwPiz9qTVbfxJqHwW8Ez/E2bw18MPEevy2PiXV9A1B Le4b/RpGs7YzqcwxzTqELjBzsXI31104Yyi+TDxcaktpON7W1fKmrczW109Lu1zjlXwNS1StJThH Vx5tHfROVnflT3XpfQ8t8SfCzwl8BfGvwZ1b4DfErxE3ivW/FVhpV34RvvEkurW2u6bJIPtzvHM7 FGht/MnEikYMYHO4ClKrmdKEpYupKpTejU4xum9nFxjFpp6tarlvtY158uxUksPThCotU4O2i3Ul dpp7Lrdqx+k1cpuFAHwj+194+/aK8MX/AMN7D4SfDK51PQH8V+Hnm1qy1eGB7pjfAS2MkJ+ZYZEC q8p+VVkJPQ01j8PhNKinzPS6inGz0sm38b6ab21D6jWxesJwstbPn5k1rzPli1yrrq3a/usreOfF X7a3xD8J634I0H4E6d4J1TWoTZxeL38XW039i7iAbhY4gXdkGSFHU4B4o/tHCU/ew9Kq6i25owUb +bcnp30/EP7Pq1PdxGIpcnXl9rzW8rwir/NWPvKMMsaB33uFALEY3H1qb3Alpgflp8QtI/bY+FWh eFvBfgrR9N8V+H4fiPbaja+JINZuFv7uxutYe6NrfRGM7IAk5hkcEqsSggYGKv8AtaEEniac/aP3 W17NxktkoptNSasldLXW/UJZaq7/AHFWPJvyuMrxa1bbWjSd2+rXS59CDxx+24SM/Aj4fDP/AFN0 vH/kCq+u4H/oHr/+Uv8A5MPqNb/oLp/+AVP8j7HrIAoA57xR4p8O+CvD+qeKvFus2mleHNNiM91q F7II4oEHdifwHuTWlGjPEVFTpq7ZnUqxox5pbf1a3ds838H/ALQnwf8AHngrW/iJ4b8a2c/gzR9R GlX2qSq8MdtdHySEbeARkXMBB6YkFaSws1UVKLUm9rNNddLrS+mxKrPllKUJRtunFp7XvZ62trfs e01zmwUAFABQB478cvAOkfEP4e3+m6n4ql8L3GmXFvrOn+J4XRW0a9tpBLDcfPhSoZcMp4ZWZeM0 RjXnKP1bWaeiaun5NdmtH16ic6EIyeI/hta62a80+jT1Xn0PhLTbjxb+0VqEvwg8dftj/DDxB4Du 5Y4tT0PwRZi31LXrdSGe2d2lYIkgAD+WCSrECvQxeHzJUZWwMaV1Zz55Tsnvyx5VZ9m3oc1HE5VG cJRxNSpLeMZRjGLfTX7ST6Le1j9TFVUVVQAKowAOwrzkdQ+mB8xftY6U2q/C6wa/0a/1nwTY6/pt 94o0fTEeSa/0eOYNcJ5a/NIi/JI8Y5eON1wc4o9sqO9T2alo5bcqfW61S6OXRNu6tccacqjTpw55 LVR01a8no31S6tJH54W/xV+Duv8Aw1/a7+CPwVhiuvFHxD8XmLwV4d8P6bJCsZl0fR4Y7zaqBYIo bqCaRpDja0DHrWnsY4Ck6vtYpQenvpuUtJJR1bk3deWuo3PE4yryypzvJe83FpRjs+Z9LLpvt3P2 mhDrDEsr75QoDN/ePrWW5JNTAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKA CgAoAKACgAoAKACgAoAKACgAoAKAMXw3/wAi7oH/AF5Qf+i1oA2qACgAoAKACgAoAKACgAoAKACg AoAKACgD56h074aeJ/jL8YfDC6fqF5ruoeFdOsvFcDgnTpraVrtbeNweDcNE9xux/wAsym7+GpnS Tg4yqaTv7vVdHK/S+1nva62Y4VZKaah8P2u/XltfVLe9tL2uea/B/wCF/gX4U/HO88M3njbxt4l+ IEXhQnQp/F9wk8Nnon2mNZoLN1VdzLKlp5pfL4MOeDzo54jEJVMRVUnDSyhy7/al0k3bdWStsrk/ uaP7uhR5FLW/M5Xt0V23FK+i693Y+z6kYUAfn5+1L8JPjjqOm/HaD4O+G9I8T6R8WPDQ0bU9OvL9 bC70q8jgkt0uYnf5JYmidA0ZKkGPIzuOM5YiFBS9rTlK/wAMo2dvKSbTt1Tjfd3RoqPtuXkqxg1u pXs13TSdpdNbJq2qPS/hT4c+Lnjj4un43fF/w3pPhNtG0C48N6J4W03Ul1KaNbq4t57qe6mQbAxN nboiKTgByeorSdWNWS9jTnCFt5pKUm+yTdkrddW35GcIKEHz1Y1Jv+S/LFdrySbb66JK2lz64oA8 ++KvxD0n4TfDXx38Tdcikm0nwxpVzqk0EON8wijLiNc8bmICj3Iq6UYzmoydl1fkZ1JOMHKKu+i8 zxP46eK7mH4VfDu78SfA7RvGvi3xPqVhpieDNVmt2ht7y4heRl86ZSnyeWw3YGcVz1KOAxK9piYS cFqrJc+v/byt52ZvSq43D+5h6sYTejbclDz2TbXb3TJ+AvxI1Wx8eXnwN8VfALTvhXqQ0M+ItKst Hu7S4ttRtknW3nI+zgKrxvJBkHnEgNOhSwEaTeBhKLurqcUm73s7pu/Va7CrVMdKovrdWNRNaOLm 7W3TU4xt0tbTfsfYdaEhQB8beOLP4x/CT4xeN/in8PPhgvxC8K+NtO06DUNOsL+Gz1HS7qyWVEKe cQskDpKDtByrhjj5qmFfD0ptYuM7WVpQjz6dYuK131TV97MqVCrWgvq84pq94zbin5qVmr9GnbZW JPhXpHxg+IfxvHxy+Jfw/TwDomkeGLnw3pHh2e+ivL2+NzdW9xLcXLREoip9kjVEyT+8c8d069Gr O2FjLktrKa5XJ9Eo72V3q7avQFRqUof7ROLnfRQbaiut3ZXctNtktdT7FqyQoA+K/in8O/imnxov fiP8M/jp4O8EveaRBpl7pWsaZ9rbUFjZnjkmBmQFkLyhGABCyMDuGMbUHiqbfscJGrB73lNara3L B200ervptbXKpPAyssTiJQktklHZ+r1vvqtOm7O/+Dtr8a4fEt8/xH+NvgrxhoZsHEOmeG9H+xTx T+ZHtmZ/PkygXepXHV1OeMG6060o/vMGqK7qc5X8rShFed7302JpvBt/7NiJVJdny2t3913/AOHP pWuY3CgD4L/as+CfjbxFp3xNuPh18T/C3hu1+JWg/wDCPeIdK8ZApbXJWOSKO5tplO6OcRylCCGV gidMcun9ZcZxo4f2yeujalF7dmmnpo7Wa0epNSeEjyOvWdJryTUl2abTVv5lffbY9Q+FHwu+JyfE i8+Lnx08X6Bqnj6LRW0TSdG8LwSRWej2Us0c07ZkO+WSaS3gyxAAEIA6molVqYiSn7H2UFolzczb e7lKyWnRLuy406VCLpxqupN6ttKOnRRinKy7tu78rH1JVCCgD5I+M2u/E7Vfi54U+G3wRtPDWleO Z/D9zqmq+OfEVkbs6Vpf2iONLeCNSrSPNMC20sFHk5POKcZ0qH772Ptaj0ScnGKW7cmk3vaySu9e iBQlWfs51XCnu+VJyb2SV9FbW7fp1KPhXxd8evhf8T/APw/+NniTw54u8MeO5bux0fxFomnvptxZ 6hBbS3fkzwF3Vo3ggnKurcNGAR8wNaLExxKkp0FSktU4ycoy1s1qk1LW63TVzOWHVBqVGtKcXo1J JNdmmnZro1ZNaM+xayNAoA+IP2u9H/Z6kvfh/wCIfjh8U/EnhXUbGSb+w7fw5qklrPNLtIkkSOJG diEfaxHGGwe1a0qOLk/bYeuqUY7yfIlr0bmn2+HbS9rpEurQv7CphfbyltFKpJ2XVKEl9+6vZOzZ 5l+z/q/7Md18W/CsHw8+OfxP8ReMHF19k0jxFqd/PZ3GLaUyGRJIlQ7Y97Lk/eVSOcVdSpi3Fqrj 4VY/yp0bv05IqWm+j6a6XBYWlT9+OVzotfbcayS+c5uOu2q66a2P0srnKCgD5t+M3xc8feGPEOmf D/4ReBrHxH45uNLn128l1m/NjY6XYRsIxJK4VmZ5JCVRFUk7HJwBWkamHoxUq6lJt2UYWv5tuTSS WnW7b0T1I9nVrS5ac4wildyld+iSWrb+SS63aIfCXx+n1zQP2UNb1Tw/Fbx/GTS4p2MM5YabeSaS dTWIAj50KQ3K7jggqnHzcN+xbny3X8t7bX2fnZ9NNH5Er2i5dn3+7deV9/VH0xWRqRSSRxRvLI6p GgLM7HAUDuT6UJN6IltJXZ8p/GbwZ8RNU8WaT8Rfgv8AEbwloet6hoEvh+7k8Sq00RtHlE0V1alD zLGxkwp+V94yRt50j7ejNuOH9rbS13Hlfno7p/aWj0ViXUwlWmlVxDp31ulF8y7ayjbykr2u9Cjo XwL0Dw/f/sreHfBOvaSfDnwrkvbq4uGnRr7VJpNNntP4fvGV7qa4lYnlkHXORzrC1sO/aSpvnl8U 7W31d+rvK1uit6Gn13D4luMaisrcsU77aL/wGN1317XPr+tAOb8W33iPTfDWt33hDRIdY8TQW7PY 6XcXItUu5QPlRpSCEB9TQpQh7002u0bX+V2l97DllP3YyUW+sr2XrZN29E2fA+sXH7Z138VfCnxX 0n9nPw1aatYaZc6FqNrL4wgkTUbCWRJlUHZlJI5owyt0IdwRyCJ+vYNTusPWaatqqd15r3/k07X0 d9NbWBxEoWli6Ka1VlWs/J+5t1TWqfTU+hPh947/AGmda8XaVpvxC+BGieHPCEol+16xaeKIr6S3 xE7JthVQW3SBFPPAYntV/WsJV9ylSrRl3koKPztNv0stzP6riKfvzxFKS7RVXm+XNBL1u9vM+mKQ woAzdUsdJ1KwuLPWrS0utMkGJYb6NZInH+0rcH8ayqYeGKj7OpBSXZq5UK8sO/aQnyvunb8TP8Oa D4U0CzeDwlo2k6dYO25o9It4oY2b1IjABNRSwNHBtqnTUG+ysVUxtXGvmqVXO3d3OiroMwoA+cP2 k/E3wM0HwnpVp8cvDEXiLTtTujBpmjLo76pc3VyFzi3jRWYPj+JcY9aX1ejX9+rVVJR15nPkt6NN O/kjSnWxNJ8mGpyqOWjjGPMmv7yfu2/xaHyF8J/h58eP+Fi+DNc+CPh/xf8ADL4GwalDNrGh/EnW ft41OwDAyx2li/mT2zsuQpeRQDj5a1eauUfY05yxSenPOCjy+cZ+7KdvOMk/5jKWXxv7atGFCS15 acnJyfaSV6aXflaa7H6mVmMKAPzz/ab/AGcvgtP448K/Hr4ofGDX/COiabqM0t+sniG4tYpnlsnt YorMBx9nfJVm8sZcB1Iwxrags0xFSNPCVXyxu9oe4u6bg732fO3ZPTWxNSeBpQvWoKUnptJub7O0 r6LVcqW2uhwHw/i/YIu/iB4EbS/jPrHivxTDq9q2iaV4g8TahqEB1EyKtu6wyHY0gkK7Sehwa6cR g81q0/8AacU5wWrV6SvbXXkim/S5nTxOFhL9xguST05uSel9HrJtL16H6l1wGwUAedfEz4r/AA++ D3h1fFXxH8TWmi6K8y20UtySWuJmyVjjQAs7EAnABOAa2oYeeIb5bJJXbbSSXdt6IyqVVTsrOUno lFNtvyS1Z4v4b/bV/Z18WeINC8L6F4zubjWtXvIbCzhOlXaCSaVwiKWaMAZZhyTgd6cqNJJtYik/ JVItvySvq30RfJjN5YStFdW6U0l5t20S6vofVtYFBQAUAFABQAUAFABQB4J8a/H/AI98PXfgTwJ8 KtK0q6+IXjG6uIrW616R0sdNtreLzZ7iUIC74BjRUXktIOgBNXGdOlGVScHNraKdrt95a2S6uzey SuyXTlVagp8i6ytzW8krq7fS7S3dzyXwn8f/AB7a/A34b/EDxna6Re+Irz4hN4K1ptNjeGF4z4gu NFWa3RiSCGWCQgnoH74q+elUm5ez5U1tzX5XbvZXV9Nlo79DNU6kIqKqczT3aSclfaydk7euq8z7 VrE2CgD4v+LvibQ/iR8LNBufiH+y1468TW1zrF1Evhy3tFF/pj27yRJdFkkVo0lQEqytkpJg8Eip nUwV1UWKlBLacY1L36r3Vfyd1Z/cawhjqd4U6VObe8ZTp8tt18fut7abpnN6B8QtJ8SSfCv4dS/s efEvRPCehazp8ulfadNit7DR5Yn2wzyhZP8AVwlvM5BwVDYJANQpZY4KlRxUvT2dX3ne9nKUOr1b bWu7tcHTzPndarRh1u/bUm0rWdoqWul0kl5JXsfelamQUAfNfx68T/EmDX/hR8PvhPdaFpfi7xZe XpPiLxBaNdxaXbW1sZZTFEpUvM+5FA3Abd5PApxnSpv2kqKqzXwpvlSvo22k3a2mi1uJxlU9x1XT g97K7fZK+nnd9F3PlLwf8Qv2pLO18G/EDxr8aPDV14GT4ly+B9c0q28LiK52R6zLpUTI3nnBnlSD PGY0uN3zbOelYx1XyfVYRi18SnPR213XdNLu7XtrbL6rRp6qvUlJP4Xy69ul9rNrtez2v+oNcpsV 554bWCa6uJVjtoUMjyOcKigZJJ9AAaEuZ2W4rpK5+bP7Tnxr/Z4+IWofBfSdb+NmkXXwjGvyJ4q0 7QddEEk6vbSLaNOYnEhtluSgkCn+NSflU16X1DMaC5IXpc+nMrX/AMKevK5bX76Xuzz44/A15czS qOOvK4tp93a1pcu9u13bQ6DwT4J/4J42fjPwnd+CNd8KSeM4dTtZNJjtvFN3PI96JVMASNrgh28z ZhSCCeMGsZZVm1OLnVrVnFau821Zb3V9V3XY2jnOAqyUIU6Sb0VqME7vs1BWfZ30P0OrjOsq3d1b 2NpdXty+y2t42lkfGdqqMk/kKFqJn5V/tG/tLfsr/E3WvgpNrvi+HxT8OtE1+SbXvC6WtyyXSy20 kVvcSRbQJkgmZHZDnhi2DsxXXPC1IL2ft4wjPRuNSKfkm07qLejt5X0uRTqVVL2scNNzjtzU5ddH a6tzJbX87a2PTPBHjj/gnVd+M/CVr4H8PeA4/Gk+p2sekSWfh0RTJemVRAY38obX8wphsjBwaweU eyXP7e9tbe3bv8ud39La7HR/aWLqLldCaT3fsrJd9eXT16H6JVmZlW6tYL21ubK6jElpcRtFLGej owwR+INL0BaH57/GP4BfsT/CDS9Cl8R/Al9Z1LXr37BpWgaFDfaheajOqNKRHCsh4VI2YseBgc9K hUPaQcsTjKkIRs7yq1LX6WV2277W16nTHGVozUcNhqcpu/w0qS06ttxSS73fWx478LdY/ZGn+IXw 2vvC37I/jrQ9cvPEp0fSfEd9pl1FBZ6lbzusqtK0xAMMltKXU5/1DZBxiqlDBzmmsxnUmldJyrO9 7d1azTV76W30Mvb5h7NqeDpwpt2bX1ZWs2r+7re/wtat25dWj9dKozCgD5z/AGnvF3jfwj8N9Ok8 A6xaaJq2s6/peiT+Jr6ATxaDbXVwsUl20ZIDFdwUbiFDOpPANXSmoTVoKcnpFPZy6XtrbyWr2W5E 6aqJqUnGK1k472W9r6L1eyuzz+P9nL4zFUZ/2zPHrkgEsmm6YA30/dVf1/MP+fdD/wAFS/8Aloew yvtU/wDB3/2p9mViWFAHy18TfDp8L+Htbg1v49eLtAbxx4ysLfStTsI4Hm0qa6eK3g0+3zGwELy9 3BILnmtaNXFyfNCVO8U7c0NLLWzXMuaXZ3XoZzWDjbnpyak1e0ne76/3Uuq26nmPjj4KeJvhz4R8 Q+OvF37Z/wAVbTwxodq97fXQTT38mFOWbatsSQBzwK0p43Mas1BewV+9JpfN+0HUo5XTi5exm7dF Vlf5aas+71ZJUWRGBRgCGHcVzFklAHzx+0p4V1vxN4E0S+0LwyPE0vhrxDpviG48LZUHWbe1l3vC ob5WkAPmIrcM8SDvWdScFFqrf2ctJWV3yvfRatd0t43VnsVBScr0mlNaxbdlf16X2T6Oz0PgdvGf iz4peGv2rvg54Q+CXj+0134u+J3+w32t6FLp9noljPpGl2Ml1czSAKpie0uGCLlmKpj7wNSsRltO Eo4evGco/DGCd27Jp2S91J7t2tZlvDY6Uk8RS5Yv4pSlG1uqWr5m1ta6d/U/XqFDFDFGXL7VCl26 tgda19TIlpgFABQB8cftyN4dt/gjb6r4yb7R4J0vxHpGoa1omWzrtjFcq8tmAv3y6jcI+jmMJ/FV Q5m+WM+VPSTTs1F7tPf1try3sHK3rGHNJaxVr3a26P5N6J2b0Pjr9on4xfsQ+J/hNJo3wztvDtj8 RJ5raLw5rGjaE1jP4cuy6sl60qRK0ccG3ewz823ZglgKKOT0cvksRh6kIzW3LUV5P+V66p9ebRK7 Np5hjsdF0MRTqypvfmhJpLuk18S+zy63tbQ/Sv4T/HP4XfGmPWh8N/FsWuPoogF88UMkflGXfsJ3 KPveVJ09K1r0HRteUXf+WSl99m7eRywlOXxU5R/xRcb+l0r+Z7DWBofM37U/xF+IPw38CeELv4Xy aSnjDX/GOheG7d9cieW2UX12luS4UhgPnHIyQOxq6dSFO8qlPnVnpe19O9mRKn7W0edx1WqV/wAH v6XXqfPnxU/axuPht8Kfi3H4m8IW/wAN/wBonSNBur/TbbUIUmsddliXIksboALcoSOUJEgzyopY TB4CU3icFTi3HWUXFRnFeaW8f70W4vuPE1cXGCo4qbcZaRnFtxb8r/DL+7JJ9ro/RypKCgAoAKAC gAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAxf Df8AyLugf9eUH/otaANqgAoAKACgAoAKACgAoAKACgAoAKACgAoA+KfjV4f8e/Db4gar8XvhX8Uv A3h678U2drYax4f+IjtFZX8ttvWG4gmQ70lCS7GGCrBV6EVthY4mUpKlhfbx7KXLKL8nZpp9naz1 W7MMVVwsYL2uI9jNbPlUotecbxendPysdJ8Jfhh8U2+Kl38XPjz4z8Oah4+t9BfRNI8O+E4pI7PS LGeeOaeQtKfMlklktoRuKhQIsDOTWEqtTENVFR9lTV0lzczbdtXKyWi2S7ts3jCjQj7NVXUqOzba UVbtGKb0vu27vTY+sqYBQB8JfF3W/jd4O+IPxesfh94C8Sa9rvxA0bTdO8JeIbQ+bpXh6ZEnila7 BbbB5UkxuC23MgKqCSoApY6jSXLXk7x1jDlb52/NK29lLmekUmP6nUrq9PlUX8UnKKlFeSb5pafD y3969y78Ivgl/wAKQ+POieH/AAEPEU3gi58Czy+KdT1a9uLuHU9YF3bLaT7pWYC5ZBqDOEwNpXIH y1P1uvNeyxFd1JP3tbe70000i76R293TZhKhRv7WjSjTjHRcqtzJ662+Jxtq3r727ufcFAjyj44/ DSL4yfB74lfCyW9Fn/wlGj3WnR3jLuFvLIhEchHcK+0474qKnNyPk36F03FTXPt1PkmT9rTw3omn +HfD/wC0/wDCLxjoPxN8O3UVwqWWg3eqWN5fxKUW5sbiBWV1be5UHBG4gjIrZSy7F2nHFQptauNS XJKL7NO3MvNXTHTwuZ07xpYd1Va3NC0k1311i+97NHc/Bn/hNfjL8cNU/aM8R+CdU8I+CNL8OSeF fCek6/F9nv79J7mK4u76eHrEjG2tkjVucK5I5FYyr0K0lHCS54Jazs0pN/y31ajbfq3psTGjVowb xKUZu3u3u4pfzW05nfVa2sfalWSFAHjnxL+P/wAGfg/d6dp/xK+IujaBqN9GZrezvrgCWWMHBcIM nbnjOMZrsw+Ar4mDqU17u120lftdnPUxMKUuSzlLe0U399k7FP4bftG/BL4v65d+G/hr8Q9L17XL W0a+ls7F2LJArohc5HQNJGP+BCliMDVw0eepa3lJP8mOlX9s7ckl6xaX3tI9vrkNwoA+H/jx/wAM Jj4gXB/aAk8Dr8RDawmT+35Stx9nwfL4z93GcV10MsxuLj7TD1JqPaNWUFf0UkvnYP7QeG9xU+bz 9kp/i4v8zzH9mu1/Z7tv2pPFVz+y7o2l3fgi88HM3iDWNIidrXTb9buBbeCCY8ZniEryRgkA2sbc EnOWIhWwrWGxVaU5bpSqSm4rZ3Tk1rpyt+8ve1s7KvaTxa9v7Lkivdb5FDme6tonot7aO6vqj9Lq xJCgD8hP26Y/hnDcftJy/GuJH8QXHgMD4aS6wJDZrKLef7Qtp/yzF79o2MT9/aYccZrWk62IvGlV cfZe84qTjf8AvtJrmStazulbbUaTw69pGnze093m5VK3929m4336c3d8un1P4F+JHhj4x/tU2/ij 4S65Hrvgfw/4GvNL1/XNPJeymvZ760lsoFk+7JIkcV8x252iXn7wqsRGpg5fVakvefvON78ttE2u jld+bS8kZUl7aH1jkaSdk2mua+rtfVpWXld6dT7UrA0CgD5X/aI8F2J1Dwv8VdI+M1p8MPH2iQz6 bb67qYims9QtJmR3tLmCR0Ei74o3UqwZSDjgkVthqeNnUbwdNVNPejJOzXR3WsWtbPXd3RjiK+Dp 0+XGTcFfSUWlJP53TT6p+WqPKfhBpun+L/i14R8X/E/9qfwt8SPG2iRXa+GvDPhqK3srazmlhZZ7 kRLK7yzfZ/NXJICqz4HOa2xOFzKUVPEYaNGnHW0eZ3eyvKVtNdElu7t6GOHxmV8zhhq0qtSWl5Na LdpRSt01be2h9/VxnYFAHxF8dtS8Q/Dz9oD4Z/Fbw78HPFHj5P8AhH73QdRTQdPW4OmwSTRzJPFI zALJvi2MnBZJAc/Jg4VJ4LmUMdL3enuSlZ92lFqzWndaWVm7awpYqpBvCKN+t6kIcy7e807p6r7O 92nY9D+Hv7QGu+OPF2k+GLz9nj4leGLa883frniDTIoLS12RO48xw5I3FQg4+8wFVFZVf/Zqqc+i 9lUj6+9KCS07vyMnQzCGtelFR6tVqcn5e7GTb17LTfY+mq1AKAPl/wCP3w+1i/vdK+I/gj4paX4F 8aWdhPost14ggW40/VbGZlcwToXRgyuoZHVsrucYIbi6EcS6jeHpKqmtYu69GpJNpr0aafkiKtTC xgliqjp66STV/NWejT+TVrp9H4f+zl8J9T0vVPgvZ/E349+D/F0nwy0YaT4Q8M+E0WKOJ0svshu5 maRnnmFqJEGFVVEkhx6aVaGPdODrYb2UI6t3lJydratxiorW9lfW2uhMcTl3tJLDV3UlLbm5VZb2 STd3pu3svNn6IVgamdqmm2OtaZqOj6nbrcaZfwSW1xA5IEsTqVdTjsVJH40ne2jt5rR/eCdnc+E/ j/4a/ZV8Gr8K/hz4r+DereMdfsdJez8NeE/C1reX13a6ZAUVm2xuMRKSi73PJOMk1XKo0/bYjGyp R2v7Sacn6Q1k+7toX7etUqOFHDQqyervClaK9ai5YryTRhfAXQfgTZ/Fbwvc+C/2Q/iJ4J8SoLn7 P4m17SLy3tbHNvKH8ySSVlG9C0YyDlnA71kq2FlpTzGdV/yuVZp+qmuXTfXtprYuccYo3q4OlCP8 0fq3MvT2b59dnbpvpc/RqtDEKACgDzDxj8ZPhh8PvEvhbwj428aabouv+I9/9l22oSiL7WUKhgrH jOXUYJGc10UMJVxKbpK7XS6v8lu/kc9bEQoWdRNLvZ2Xq9l8z01WRkVkYMhGQQcgiudq2jN001dD qBnw/wDHbw74f+KX7QXw5+E3xN8UX+m/DSTwzfazbaLZajLpqeI9SS5hiMcs0bKzrDC+8RBhuM27 kJW1OeKcJUsHNwe8nG3Py7KzadlfdrXZX1Mqiw0GquKgpp6RUtYp76rZu219NznNP8DeBP2ff2h/ gf4b+Cmt6hBY+OJdUs/EHgxtYn1G2SzhsprlNQWOV3aFkuI4YtwIVhc4OTijmxtOlbFVJVKbdo8+ slLfSVk2rJ3Tv0egubC16l8PThGcdXyJRTi9PeUfdvdqzsnv3P0DrE2CgD5M8Wx/GzTdK+HfhBPj d4H0v4t61qupi1u9T0Fp11W3QSTrBbQearB4rdVLtk5CE4rSDnUviJYOE+TpzySj0TT5W231VluL 2dBNUfb1VF9UotvrZ9LLoS+HPBP7X9r4g0G68T/HDwLf+G4byGTULG08JSwS3NsHBljjkNyQjMgY BiDgkHBxim8c5rleChG/VVZtrzSdNJ27XVx/VMNH3o4io2ujjCz9bPbufV1ZAFAHxf8AtauNB1v4 CfEb/hXOu+Ov+EV8QXEsnhvRtJfUjJFPbPA8+0AqkkPmCRC+AcOoIYisqrwsl7PG1FGk9076vpp9 pJ7rs762saUliLueEV6i2d0tOqu2rXWzV9VZ6Ns0PDP7SfhbXvEnh/RLb9n/AOJunXGo3sFrHqGo eC57aC0aRwglllK4jRc7mY9ACe1ZxwuRxalRrUXPolF3b6W93e+xbq5vJNVaU1HrepB6ddOd306d T7ArpMAoA+O/2qV1zRNb+BXxM8M/DLXPHeseENduJjoWj2Qud1vcWzW80hJIEcqK4eNj1KMvG/Iy qzwqtHGP92+nLKWvR2Sd7Po7aPTVJPWlSxFW6wtlPu5xgrdVeTXxbaXd7X0uzQ8N/tLeItf8Q6Do c37MPxW0mHUbyG1fVNS0mGO3sld1UyysJCRGgO5iBwAaSWTX/dVk5dP3NRa9NXBJerdl1Mnh8zjr UoxUetq1J6ddFK79Fq+h9aVsAUAFABQAUAFABQAUAfNX7Ren+ANUtvA1t4m+JVx4B8Y299cX3hrx VaypG1lPFbv54bzB5bxNCzq8b8MCMYYAjWhRxNSfPhLOa6SXMpJ7pxum110aasmZVq+HpQ5cUnyS 6p2aa1TUrOz7XTTu1Y+YPDPwe8J/B7wn4Z+JXxr/AGpX8W/B3w5r8/iPSdPt7C3tLC41e7vJrpZp PKaR7mQXVzLJHGCAr7Tg7RR7PMK7eGrwp0kvelZNOyd/elJ2jFO3TVJJvu41cDFe3wqqVJS92N3z 9LPljGKvJq9279Wkun6D+CPHHhP4j+GNM8Y+CNdttX8N6grNb31o25W2sVYHuGVlKkHkEEUq1GdC fJPf7009mn1TClUVWN0mujTVmmt009U12OtrM0PkT9pG4+Ilz49+AHhr4ffEmHwTPrF9q0d1q15b C6hkRLIssYhLqrykksgY4Gxm524rWlWq0+ZUaam2tne1l1dleydtE1fq7GdSnh5WniZSjFdYtJ3f S7ulfu0/S54LrHxK+JviuDSfgFr3xO8vWX+KsXgjUfH/AITWOxn1DThoT6yTEpMiwz7vLtnIyAQx GCcDV1qsPfp0lTq22tzRi39pKW946pS2b6pGSp0JaTm50b3V3ZtbWlKNtpdVa6XQ+pP2bdZ8QTaT 8T/A3iLxJeeI5vAHi658OWviDUdhuNQtha2l5GZmQBWkjF75DMAMmAkjJNYVKsq1pVEue3vWVk30 dtbXVm13btobQpwp39lfkfw3d7LqrvdJ3Svrbdn0jUFnz98e/G3wj+Hdt4A8YfE2O7m1fT9aD+Gb XSLea6v7jUHt5omS3hhBeTMEkwZcFdpyegIqFBVL1ZVVTjHeUmlGz0s7737b3WgnOa/dU6TqSlsk rvTW/S1u9/LqfJGk6l+zz40+OXh3xsPhL8abfxDqWuWt4ljqGgatbaGmqFkjj1CeBl8pJEO1jKcA Fd5GRmoc8M4OjTzODpt3VNSWrveyfLzavW3Na5so4tP2k8vtNK3tHa6jaz+1bRaX5b20TP04pmRF LHHPHJFLGskLqVZHAKsp6gjuKT1VmCdtUebH4OfBpGVT8LPBqu33QdEtAW+nyVwf2PgnqqMfuPQe dY/Z4mf/AIHL/Mt2Pwl+FemXtpqWnfDTwraahayLNBdW2j2sckMikFXRgmVYEAgjkGnDLMFTkpxp RTWqdhVM1x9WLhOvNp6NOTs1956HXecAwgMCCAQeoqWr6MNtUfAnxw/aztfhf8cPhZ8OLL4e+KLv SLnU76212S08KXN39viXTJbiEafIq4mZZhEZNm7CK+cYJqKeFyeMXGpKkn1vZcnnJW+1svVFP+0Z yUqcJtdLNWl976b9NjWv/wBprVvGeseBfDPwe+DXjqHxBfeIdNS/vvEvhG50+zs9K+0Ib2R5pVUK wt/M2YJO/bwaSp5LQalTqUqs3olDWV3s9Fpy7tvTQfs8zq6Vqc6cVq3KStp0td3vtZevQ+6K2ICg Dxf4g+F21P4lfA/xTY69ptnq2h6hqEZ0/UGw2p2lxZSLOlvjnzUKQy9MbY3BxnNHJUlecYc0Vv8A 3b6KX36ejYnUpxtCUrSe3nbdeltfVI+aNZ+DPxa0nxLp/gQeIPCNh8Ap/iLD42g1m5upY9XS5k1T +1G06OPbsJkvWdA+/PlSFcE9VTqVJR9nToN1E2+fmXKo63dvivytx2tbVvcqpGjF+1qVrRdlycur lsveva17S730S6n3/TEFAHgf7Sll8Ir/AOEPiOD45axcad8NSYlvntrua2a43tsSHMR3v5jOF8sZ 3EgYNVClVr3hRqcjtrL3VZLVu8k0rd91ummS6kKTUpU/aa6Rs22+llFpt+X36H5sxa7+wOsjWlv4 g+N3+j3UWnFI7vxPtjnkCGKE88MyyRlV6kOuOoruVbGWX/CzDVXXv4fVLd/Brs/uCUEk28o20fuP R6WT97R6rTzP2irzygoA+Iv2tP2cfh18TYNH+JHjv4n614Q03w1qGl399d/23NaWCWlpc+c2IwwS OdtxVZh8ynaRkgCrpvMKso0cFUerT5bR3/mTcW7rdJvl01W4nLBU4upiaSb76tvtHSS0ezsr66Hz Iy/8E671oYdf/aH17X9JEiPLpGueMdRu7O72kELNETiRMgZU8HvXoVcFnNeDpVcW3F6NL2MbrteM U/uaMIYrBUpKVLAJSWz9nUdn82196P12VQoULwo4AFeYdA6gDwL9ofxzqnw68IeGvFNtqc2meHbf xLpa+IdVgg85rLSjMPOcjacIT5aO2PlR2bjGaulJKajpeXurm2u/mtei1+JrfYmdKVRXjzPl1tHd 26bO66tLVpPbc+OviD8T/in488K/GT9p74cfEzVtF+GvgLbD4K0G0s4za+NZYFQ3EtwHTzHinuHN rFsKn93vGdwrV4t4eboU1CUIfxG1dvrJRknaPKutn7177EPBqpH2lZTjUlbkV2uVfZbjbXmerTt7 tu5+nkLNJFG7psdlBKH+E+lc+jNSagAoAKAPH/jF49n8A6X4LuIraxeLW/E+maJPc6m22Czhnlw8 rH+9tUomcAu6AnmkqNPEfu6kOe+y7v7nsrv5WJlOVNc6nypbvy+9b6K/Tc+Ufid+0F8S7W9+MfxD +Fuj+ELz4JfCDbHrr6hG7XXiS4jiW4vYrGVPkTyIpEQM2Q0u5eME0fVMvoTWHq4RSk/ilouS+3u8 r5nb3mm1o0lqCqV69P6xDEuK+wrXUrb3d00m/dVk9U2z9A7VLYRJLawJGkqh8IgXIxxnFZUqFKhf 2UFG/ZJX+41lUnU+Nt+rLdbEHh/x88Z+H/AvgzStb1fwLN4x1dtc0+DQfDtrHG813qzTD7MYzIQq MjAyeYSNgjLdqXs6FT3sRJxhHXS7emySWrbeltu+gKVaPu0EnKWmrSXm23tZdd+2p8U+P/2hPiB4 50Lx3pPxL/Yu07WPCPg7W7XS9dXWvEOn3MOl3MkNrcJK4OcIkV7bu8q/KgLZICtgrrKcU4RnCs5P Z8ii7vS1+dNc21rq90nuFL+08NzyhWopLf3qjvGybdvZtPl7b3TaP1F4x7Uw3FoAKACgAoAKACgA oAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAMXw3/AMi7 oH/XlB/6LWgDaoAKACgAoAKACgAoAKACgAoAKACgAoAKAPyJ/bnj+Hmjy/tK3/xi0IXWua34DFr8 ONX1Sza5tbeZYJxPbWrYKQ3huGSQnhmVosE7OGrYpezdW3s/eUOblv157XXO1a3XlstFza3GVbDp ypU24z0lJK9uijJq7jF3utk232Ppz4efEbw38cP2n7Xx/wDCe8k1T4feG/BN7ouseI4YXS0vr24v bSa1gikYATNFHBdsxXITz8Zy5FaVv9nn9W505PWSTUuW217Oybu7Ley16GcI1KtNVpwlGO0eZOPN f4mk9bKyV++3U+2qyGFAH5m/tZ+IfiDq6ftL3Gi/F3WvBtt8KfBsWt6Ronh2SGCbWLqSCeb7VcyO rM0CvCIlRNvKSZPIrppYjEUYJ4aMUk/ek48zb6RV9Iq2rdm3fpYwqUcNUbjiLuTXupScUltfSzbv 52VlpqfVN1441eP9qjw98P8AT9YN14cvPAd/qmo6ahVlsLmC/tI7aUkDKmVLm6XBOCIBgfKc5yco U1Gcfid0+um/qtV6P1Kjy1JucH8Oj+e3lfR+bv5I+iayNQoAoXupabpyo+o39tbKxwrXMqxgn2ya caEq/wAMOa3lcyqV6dH+JJL1diGy1vR9SlaHT9Ws7qYLuMdvOkjBcgZwD05H51c6FWmrzi0vNE08 TRrPlpzTfk7mrWZuFAH57+OPF2nfCL9qXx14o1L4LeM/Gmn+K/D+mRNrmheGJtS/seW180C3SQKQ 0UqzByEOVeNtw+ZTXPUhlteShmFaCa+FSu7J76Wdm9Gn1V1pbXeDx9OPNgoNp72lGN30d3JX7NO1 tGr3dvfvhJ8afD3xH8RX2iaR8JfG/he4gsnu2v8AxL4Ym0qCVRJGnlLK6gM5LghOpCMe1Onh8rpP mwNWnKfVQVnbz0Wl7fgTUqZjNWxcJRj5zjLX0Um9r62PoqtzI5vxZqOv6R4Z1vU/C3h/+3PENtbv JZ6R9pS1+2ygcR+a/wAqZ9TwKOaEPeqX5Vvyq7+Surv5i5ZT92DSb6yvb52TdvRP0PkG9+IP7Sep 3ButR/Yh066uSADNc+K9IkYgdBk81y1lkeIlz1sPVk+7owb/ABmdFOOaUY8tPF0UuynWX/uI7T4Q fGnxFqPxFn+DnxB+CUvw58VT6PL4h06G3vrS+tdRtYpooJiHtzhZEeeHKsOQ2R0roo0cvjScsDFw 11jKCg/JqzafnrdGNWWMdRfWqkammkoylL5NTjFry0toz6uqhBQB8VfFrxV8Y/iZ8SPFXwV+EHhD wJLpvhexsrvXNf8AiJDJd23nXayNDBb2qKS5CRlmdiAMgdaissG4RVbDfWJ66NqMYrzk1J3fZLbV l4f6xGpzwxLoRVtYx5py7296KSXdt69NDW+Cnjn4meGPiLJ8Avi94N8Jabq0uiTeIdC1nwIHj07U bWGeGC4jaB1DQyo1xAcchg/B4NOjHBqk/q9B0JJ6xumn5xkkr7WaaTWncVZ4iVXmq4j2ya+Jpxkv KSvJa7pptb7H1/VEhQB+dn7Ums/B/wAIftDfCDxV8cNBXxN4Ok8P6hpsGlT6VLqkWj3bzRSLfG3C MjB0jeEsQWQ7MDDEiJqhXj9XxVeNOD1SlNQUmv5tU7W2b92909WjfDrGU28RgKM5zWjcIttR8mlo 77pPma1WiZ2vwf8Aij+xt4j+Ifh/R/hP4H0ew8e3An+w3lp4LfTZIwsEjSYuDAgTMSyD7wznbznF Ywy3L8PJVKFalKa2UasZS7aJSbenltqa1sfnFaDhiqWIVN7ucJqPldvTfbzsfb1dJxhQB8WfHbxn 8TPhh8c/ht468H+APHXjrwjcaHeaNrXh3w3bmS2tN88Usd8MkK1whiaPY2CY5SQeCC1jaFH9xiqn LCWqtCUmpLZtxi/dtdWTvezs90LBVsR+9w0YucdPeqRgmn0SlJe9dJp2ta6bWl+8+H37QuueOvF2 k+F7z9nz4m+Gra8Eu7W/EWlxwWdrsieQeY4ckbioQccswo9vl8/doYjml0Xs6kb/ADlBJaa6vy3F 9Xx8PerUYxj1aq0pP/wGMnJ/Jab7H0vSGc94p8UaF4L8Oaz4t8Taglj4f0q3a6vLyQErDEoyWIAJ wKqnB1JKKa17uy+96EyfKrpN+STb+SWrPyy+Lv7QH7HvxJ+PHwx1/wCIXirS/GHwwttFv9OTS7q3 muLTSdUeWKRLue3K7XDwpJEHIOwgDjfmumeDrSX1d11CL192qo8zXSTjJPbVK9nr1sKlWqUn7enh 5uWzvSk2l3ipRtv8VtdraJnv/wAGPFP7BGo/Enw7afBTSPAkHxMl+0f2bLoujLbXK4gkMuyQRjb+ 5EoPPIyO9YSyyWHXtXW5rdPbOf8A5Lzu/wB2m/Q2eYYiuvZzpSin1dJxX/gXKrff5H3fWZBzfi2/ 8RaZ4a1u/wDCWhRaz4lgt2ey0qa5W1S8lA+VDKQQgP8AeNHPCHvVE3HtFJv5XaV/VoOWU/djJRb6 yvZetk3b0TZ8D6xe/tlXXxX8KfFjSP2adBtNUsNLudC1G1m8ZWsiahYSyJMoU7MpJHNGGU8gq7gj kET9ewSndUKzTVtY0015r94/Rp2vo76WdrA4mULSxdFNaq3trPyd6e3VNap9Hc+hfh94/wD2ldc8 XaVpnxA+AOleGvCMwl+161b+KoL97bETsmIVUFt0gROvAYntV/WsJV92lTrKXRyjBR+bU2/Syevk Z/VcTS9+dejJdo+15vlzU4r1u1p5n0vSGc54s1HXtI8Na3qXhbw//bviG2t3ks9I+0pbfbZQPlj8 1/lTJ7ngUueEPeqX5Vvyq7+Surv5i5ZT92DSb6yvb52TdvRN+R8T6t+1B+0ho3i/wx4Duv2SpH8V a/Dc3NpYW/i/T5WFvBs82aTacRxq0ka72wCzqo5OK1WKy7kdSUa6V7L93HV72Xv9tX2W5LwmOcuW FWg+r96qrLu70ur0SV2+2jNjTfid43+InxM8PfBr48fss6boujeItPvJ47/WtYsNUhniiTLxRIoO +Td5WUU7grb8YUkc1VZbjtadOo6kdU5QjFxV/iUlNyWul47Ste10bU5Zhgpa1qfs3/JKo7v+VqVN La796yaUrXaaPs3RNH07w9o+l6Do8Bg0nTreO1toTI0nlxIoVV3MSxwAOSSa0V+rbfd6t+r6ktpu 6SXokl8ktF6LRGtTEfHP7VHib4SX0nhP4U+N/g9rXxP8V6sk2q6d4c8O2nmXVjDEVje78/en2dQ0 ioH3qSWwM0Olh0liK+IdFp2jKPPz3e6ioJyatvpba/QqnPFOTpYelGomveU+Tkt05ufRvto2cB+z To/gvwR45g0/wf8Asb+OfAl1rEUsN34y8SPDd+REiNKI5J3uZZQjMiqFXjcVyOMiXLB1pe0+uVK9 Vbc8K23WznFRjp6N7F+zxlGn7P2NKnS3apyp7/4Y6y+d7H6C1RkFAHzH+0r8JfGPxMsvAOseAPHW j+DfFng/VW1a08TanYtdSWeYmidI/nVQskckkcgbIZG4wQGCUqtOcZ4ekqk9rSk0td7pRk3dejTs 79GP2Mqco4io4QfZK91s7tq1n631TVjkvA9h+1BqniHRrm7/AGivhlr3hu2vYX1Ox0bw24mntlkH mxpILphG7KGUMQQCQcHGK7K1WtTXLVy+ML9fazdvNJ0knbtdX7mFJYCrrRxc5tdLQs/WzvbufZNc huFAHk3xW034zajp+kx/BnxN4Y0bUkmY3svibT5r2OWLHyiNY3Uhs9SSeKqNf2GroKrfo5uFvO6j K/pYPYwraTqyp/4YqV/W7R8x634k/a++GXi74WXfxH8efDe8+Get+IrPRdVu9J0O6intWuJVjgQb 5yAJpCIQ+DseWMlSuSNoYyFa9N4NQk07P2zktN9PZLW2qTsm1a6bV86uEhSSqU8TOVmrpwirr5Se l7X6papOzPvWuc0CgD5F/ak134keDNS+C/xB+HHhbxd4sn8P63cNqXhHwzEWj1ezntngfz2yArRG RZo93yl48HGQQ1jKeF0rz5actHaLlLumrJ2s7X1V1s29GLBzxbXsUueOqcpxhFdHe7V7rRWUrOzt a7Vrw3+034h8QeIdB0Kf9mb4taXDqN5DaPqep6PHHbWSu4UzTN5h2xoDuY44ANH1jLZaU8TeXRez qq76K7gkr920l1F9WzKOtShFLq1Wouy9FNt+iV30PrCkMKACgAoAKACgAoAKAPkL9qTwbFrGqfB7 x1q3wmm+JHhPwjqV7LqXhe0tY7ycC4tmijuo7eQgT+UwwY+T+83AZWsarov3MTNwpvdpSfylye9y vro9bX0ub0JYiDc8I17RbJtR9bSlZKXa7XXW58V6fceJfDnjLRb+1/Z08e6F8M9M+Jg+IcPhq20F ng0nRhoDaezpFHlRM1/K9ybVPnXLNtzTeJwFSnHDyxF6ekVzqfw/Fd8yv7NS0Tei8kglh8dKTruk nUertOm7y+GytLWTjv32TbZ93fstpd32j/F3xmuh6ho3hnxf43vtZ0LTNUs3sp4rI21pbtI0DgNH 51zb3U4BAJE+TyadOVG3Jh5KVOOicfhfV27q7avt20M6kaialXi1OWrT3XRX315UvQ+o60IPlr9q vWvh1b+DfDnhTxt8MLr4ia14l1RbTw/4R01QLq6vUiklaWObcvkCOJJGabcu1cjPOCezote2rVZU lDaUebnu9Eo8urb7bW30HGpXv7LDwjNyWqly8llq3LmTVlp0bvax8geHvh18KLPxT4T8M/Gb9j7V vhra+Ipl0jRPEVj4kN9Zw6jIAYi8lvOTb3shXYtwRvYgJvOcFU3Qr6YXF141E+dKpdOTS1km+ZNq O8ZO1r+6VKWJpRviKNCcHaL9mlon0acIPlvpeOzs0+p+knw2+GvhL4T+F4fCPg20nh0lZ5ruSS8u ZLqe5nlcvJLLNIS8jsxySx9B0AqY893KpNzk3dt2u38kl5JJJWFKUZWUIqMUrJLZL+u/U7a8lngt Lqe1tjcXMcbPHbhgplYAkLk8DJwMn1qrpavYizeiPzp+Iviz9qLxZ4n+FvjfRf2R9RtvEvgrU5rq Bb7xPpTw3NtcQNb3URxLlXMbhkcdGQA8MaJ4rLeaMl7WS6p0n8mtd09fNXWl7qo4XGcri6lJN7NT l9zXIrp9ddNHraz9z8O/GT9oXVPEGhaZrf7Ker6Ro13eQwXerS+JdLmWxhdwrzFElLOEUltqgk4w Oa0eJy6StTdXm6XpNK/m76LuyPq+MjrOdK3lOTfyXIrvsfVtQUFAHyp+1bd/s/6d4T8Pah8evF99 4dtorxhot/pGp3Vje/aynK2/kMGkYjHyEMDxxXRh6eKm3LC1/ZW3d4pW/vc6cWvVGNetRpQ/f0Pa p9OVyfycbOL800fN3ws8RftRT+O/A8Pwnk8a+JPgXNqEA1nU/jFpltp9xDp5cea9nKrRzyuEyVDw YJ6tUzzKk06VXkrzeilSjOCX96UnenNLqoWfkaxy/R1o3oLR8sqiqKXkopOUG/789Ovn+nlYjCgD KvNH0e+vtJ1a/wBMtLjUdKeSWyu54leSzZ0MbtGx5QsjMpIxkEjoazdONSUZNarb8ilUlCMop2T3 /M0RNCSAJUJPbcK15X2M+eL6klIoKAPz3+OXwP8Ajl4++Nfwo+I3gz9oTT9J8H6JquoT2yyaRazf 8I75mmzWrGMtKPtTSO7IVONgkJ/hGalXxtOapww0JW7qfX+ezWnbltra+lyIxy+dN1Kleav2nFJ6 7QvTdmvtczldXtZ2t0kfwA+Ini3XfB3/AAtb9qtvFnhTRNbsdcXw7YaHZ6b9uu7SZZ7YSSpI7bFm RGKqAW2gZp1KuYVY8sqFOmt24xnzWW6XNJpX2bttcVKWV03enUnOT0SnVg1d6XtGnFt9lfc+5Kg0 CgDxH45+DtS8XaJ4GuNHWwl1Hw74s0nXFstSlEUN5HDPiVNx43iJ5Xjzx5iJ061Eo+0XLyc8Xul2 769nZvulYcZxg7ymoPo337ad9vmfM3xo+F/x0l1T46eCfht4L07V/CfxjuLW/wD+EtudVjtn8H3y WVrYvOYT88nlpY29xEY8t5gxxgGp9tRoXU6UnUi7w5UuW+luZt+7aV29LNaK7ui1QddKUasYwaam nzc1tb8tk0+ZO1m1Z67H6BxKyRxqz72VQC56t71ruZklAHyf+2TprXnwj07VIfCWo+Kp/D/iTSdc j8Ladp8l+daNtOJDbSRID8jgH5mBRXCFuAazqTpKLWImo03pK7tePVLu+qWl7W6l041ZSXsFea1i 9NH31a06XWqvdJtWOPt/2qfBbRQZ/Zq+LELlVzF/wgVwfLPpkJjj2rFYLh57V6H/AIC//kTVV87f /Lqf/gyH/wAmfcFdRzhQB8xftZeP/EPwv+Fll488P6k0KaRr+mXGpafFafapdZ00Tg3VlEu1gJZY Q4UnA3ADIzmj2lGCf1hR9m9Jc70Sel1qrtbpa36JvQaoVsQ1HDqbqLWKgm22tUnZNqL2b6btpanB Rftz/sw6lp9nBcX+si3dYpFsbnwtf/umGGUFPJwGVgPoR7U/q2A5PZLE0OTt7Snb7r/oVbNYTc3g sRza3apzfrqt/XqfbVIgKACgAoA8S/aC17wNoXwx1ZPH/g5/F+karPb6ZbeFIbZbmXWryaRVt4I0 bA3mTawYkBNpckBcgVGlWv7afJGOrkr3Vuq5fe5r7KOreiCNSrTkvYK8nok7W135r6ctr819LHzb 4Z8dfDuH9mz4yWfjH9n/AP4RHwP8MtZOn654EtLmCVRFHFY6i85aFwjgR3iyuu4lvLdTuzgio4Sp aFKpPlnvKaak23Z8125Wel23ez6WKdfF05OpU5HOO3LrGyV7JcqSe6SStezT6n34rpIqsjAowyCO 4otbQkfQB4z8a9H8Oa1ofg9Nf8XR+Gruz8T6Ve6TqsoUqL6KcMkJDEAiZBJCRkHEpwc4pwpVasl7 BJyWtn1XXzva7Xa1+hM6tOlFurflel10fR3s7K9r9Ht1PmL9p/4V2+j23xP8V6p8dLLwL8FvH8cE XjjSLrTBdXGpusEdo32GXeCk09tFDAVCOfkUqM06McVUVSlRpwaevPJtOnpZv+VpWurtWd9xznho uFSq5uS0UIWftNbpWtzXu9bXutNLXPv+NFijSNOEQBQPQCoGSUwCgAoAKACgAoAKACgAoAKACgAo AKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgDF8N/8i7oH/XlB/wCi1oA2 qACgAoAKACgAoAKACgAoAKACgAoAKACgD4y+JHir47/Ej4r+Lvg/8HD4P0LQfCen2F1rXiLxhYSa kbqe8ErRQ21qrKCqpES0jNjJwBwaVV4Z01CeFVeTv8UuWEe32ZNt72SVl11HRhN1HOWIlSituRJy l3d20lFbdW36Gn8IvHPxh8MfFWT4D/Gm28LX13daDN4i0HxL4Qt5LOC6t4J4YLiGe1ct5Uitcwsp DFWDHutOn9W9lajh/YST+FPmhJPrF8sXdbNNdU7hUjNVOb27qxa3krTT7OzaafRq21rH11QIKAPh 74p+EPgp8ffjL4t+Dvxo8Dx2V/o+g2d1oniAarJYXHiCyuTMLuGMxsheKB44w8bFlzMp2jOS1h5V oTlhKlSE7WqctrWd+W6d1L7Wrjo9E9yXi1h5RjiowlTesObVqS+LXRxfw7PVb6Hunwh+DHwi+ECa xH8N9PRdU1TY+oand6jLqV9eiPhPNnmd5Cq7jhc7RuOBzSlSxDm62JnOc3pefRdkklFLrolfqNYq hUiqWHUIxWvLBJL1dtX6tvse20DCgD8v/jPcfsy/8NVeLbH9qzxBpF3ps/hzTpPCtlruostjpYQy i7R4VYKk8jPDIruPnThT8jV20MNj8ZFU8PUnBLZQm4c/d3i05cuiavomnbUzWIo4STnGkpze7cOd x7JXi0k99Oqd+h7n+zvH+xNH401Q/s2z+CX8cnS5PtY8N3Pmz/YfOh37huPyeb5GT67aWIy7H4SC qYqdSUdvfqSmr+kpNX31t37l/Xlivc9mo9b+zUPxUV91/PofZtcYwoA+NPHE3xs+Lvxk8Y/Db4df FCP4d+CfBNlp0mpapZ6bDf6jq15drJKI4xKdkUKRImW2sWZyB901r9anh4pUKMZSe8p8ziuyUYuN 31bb0TREaFGtJvEznyraMGo385Sak7X0SS3T1NL4Wa58Wfh/8YE+BfxU8eW/jm01fw5ceI9C8Tf2 elheRra3Fvb3NvdxoSjc3cDJIoGf3gIGBkdd4iDdWnGE0/sX5ZJ+Um3Frrq001bqDo06M/8AZ5yc H0m03F9PeSV09d1dW3e59c1kWFAFOO+spbm5s4rqFru3CGWFXBeMMCV3DqM4OPXFVySUVK2j2M1U g5OKeq/U5zULTwTpniew8U6oml23i25tTpNrqF0yJPJAXEhgjZjnaXCsVHUhc9BUwwsq03VhFvlX S7SXpt87XHUxcKMVSnJLmfWyba893a+22vmdfQWcH8RdF8b+IPC11pvw88Z23hfxRJJG0WsXWnDU UjQNl1MJdM7lyM7uOtEasqPvwhGb7SbS+9aidOFX3ZylFd42v+Ka/A+Ql/Zr/aei8dy/Ee1/ao0m 28Sz6culXbQeCEWK+gRy8XnR/asM8ZeTY3BAkccg4AsdiYybjhaVnuuao1dbPa6dtHbdWvshvCYS UUnWq3Wz9y9nuvh1XXW9nta7v6b8Ifgd8VPB3xU8S/FH4ofGKy8cX+qaOmkQQp4fGnHTo0kSQCBh M4WNiJGdduXZkJbCKtKWIq4mS9rRhBR25XJ2vvutb6Xd9LJJblRpUKEGqM5ybevNy6222S26WstX e71PqymSFAEJki8xYmdPNYFlQkZIGMkD8R+dTKnGau43+QuZJ8t9TPttZ0a8v7zS7PVLObU7TBnt IZkaWDPTcoOV/GreEdOKq+zsns7fqZxxFOpN04zTkt1fU1qRqFAHyH8ctQ+Ifiz4i6Z8JvBvxIuP Aelw+GLvxPe6vplvDNf6myTLCltbmYMiKhJeRtrH54wMZJrWnXqUY3oQjKV9XNOSiunupxu2+rdk k9HczlSo1JL6xJ8vRRfLd+bs3ZLorNt72VnzPgH4ueNJ/DP/AAT8udQ19r/U/iRocK+IYJEj33rN 4ea/a8OBlSlxboDtwv8ApBB/hqpVOZTlKCtJ6PXR7pLW1rX01e3bVKmrxjBu8Vtvptr13a1/zPuK sDUiZEkQpIqtGRgqwyD+FROEakXGSun0Y4ycXeLKX2PSvMEJtLTzipbZ5a7ivTOPTmuf+zsK1zex jb/Cv8i/rVW/L7R39WPS3063li2QW0c758vaqqzcc479Kqng6FN+0p0oprqkvzsKWInL3ZzevRvc v10kBQB438XPjt8Ovgpa6TJ411C8Oo6qZBYaRpFjNqF7eCNQ0jRwQqzlEBBZsYGRk81rTpRnF1Kl SNOCduaclFXeyu92+y1M3KcpqnRpynN62ir6Lq+iXm2tWa+g/FzwL4ksfhVf6bqj/Z/iLpo1Xw95 0Dxm9g+zJdYOR8j+TIH2NhsK/HynBKi05pST5fNa62uu6vbXzXcXtPh5otc34O17Pz3+49NrI1Cg D5U+N/gf4kab468OfHL4SeJfDFl4l0zSZtA1PR/GcjwWGqWMkyTrtuEBaGVJEJDbSGDEEcA06Uqk aqtQdaLW0Xaa13jfR32adumuhNR0PZP2lb2Uk9JNXi/KSun6Narszl/CPgb4+/Er4n/DL4kfG2/8 E6N4a8GNdanofh7wbdTX76jeXFpJa+fNcyIg8pYLmXaqKclwScAUVa7qS5KOHlSivic5Jyf91KN0 lfV3d3ZaFU6dOnHmliFVlJaKMXGKWjvdu7fTZJJn2nSA5vxZc+JrTw1rd14M0yy1HxVHbu1hY6jc G2gnm/hWSUKxRSerBTj0ojKMHzTi5LtG136XaV/VpByup7qko36tNpfJanwZrFl+2vefFTwp8S9P +F3ww0/xFp2m3OkXlmfFs8q6rp8rpKIyDago0c0aurjI+Z1IO4FdPreFUueGEruL0d3R06ppqo9e jT0ae+iG8K7KnLGU1K917k/RprqvxTXqj6B+H/ib9qvUPF2lWnxJ+FngTR/Bcnm/bNR0bxLPe3MO I3MflwtbIGzII1OWGASecYLlisJVXLSoVYy6OXsuX58s2/SyetugnhZ0vfeJhNdlGab+b00Ppasg CgD4Z/bRXwM83wJj+MWvCz+BkviSSLxJYG+NrHes9s6WZuNrBntluGTzFHALozfKpI3oRxNW9LDS cHLRyjo/8PN9nm2vpf4U7syqVKNBxrVYqTjqotX9ZKL0k4rW1nZXdtD538fTfsY/Drxp8Fde/Z68 W+CPC3xGHiiyWe68N6slvZy6MjhtRW/VX8tozbeYE3jcZTHtOa6YZbmmE0vVkp6ckpSnzX3aUm2n H4nJWtbW97GNXOcFj43qODUdedRUXHyukvitbl66vo2fqB4O8d+C/iFpc+teBvFOl6/pEM7Wsl5p N0lzGkwVWKFlJAYK6HHXDD1rlxGFrYWShXi4t669i8PiqOLi50Zcy2+f9M66sToPnX9pFbCz8F2v iLWfj9qfwn0HSp99zrWnG0H2reNqRN58bg88gKNxNdGFWLlPlwcYSfXni5JLvpOFvVsxrSwkIp4u MmuijJpt9tE2/Q+Svg9afBH40/EDwrDfftheKvifqPhy9j1zTvB2uta2EU11AQ8VwYUt4nnETbXU ZKhlBPStMTTzGvScpToukmub2MV3ulKXtJ2V+ml+4U54KhUXLh6lOo00vaufVbxUoxTdtnrpeyP0 /rjNgoA8n+Kvh/4t+INP0mH4SfEDSPCuoxTM15cavox1RbiIrgKqCWPaQec5PpinHESoO8aMal+k pSjb0cU7i9jTraTqSh/hUXf15j5c8R3f7V/wn8U/CrVvHvxs8I6v8NdX8TWGiawbHwm1tcQm5mWK BVzdN8ssrLCXGTGZVbayhsbQxrrN05YSELp2kqk3a3rFa226N2TauiZYWhSXtI4ipJq2jUFe/ont u9tLtO6PvusCwoAKACgAoAKACgCpdwy3FndQW9y1vPJGyJcIoYxMQQGAPBIPPPpSu1qg0e+x+cPx K+H37Q/hbxf8IfAeg/theLZNc8b6pPb/AGq/0PShDaWltbvcXD4EYLylVVEQdS+TwprpjmGNUXL2 NCT6JU6i+bftXouvd2XW6znhMA2re0iurdW/ol7i1fdvRJvXZ7vjPwn8b/gp4o+EXi7xB+1N4n8R eAr3xZpmiavo11pOmwSXBu50ht9jJFlkMzIkijDCORnUgpglPHYqrzU6tKik18UYTTX31WtdlLW0 rXi1exUwuCglKj7TmTWjqXv/AOSrbdrqk1dOx+hlc5oFAHzt8d/BXxD1O++HPxK+E1vpd/488D3t zNHoeszG3g1izuYDDcQCcA+VJ/q3RyCMx7TwxNQ6ipSU5wc4dVG3N6xu0m12bV03rcqMFVi4KfJL o2m16SS1s+6u07Ox4tqNt+0p+0HrXgXw348+Ddj8N/hzoXiPTvEWq395r1vqd5qLWFwl1Bb20cGQ oaeKLc7kfIGAGTTqYvC1VyYSnUcm1704qCiutlzNybWitor3uKlhq1O88VVptK9owcpOXZtyjFJL e2rduh95VQgoA/Pv49y/tfP8f/gvc/Dbwb4cu/AumatqT208msXsMV0j6TMh/tVUhKxIJGbysb8y LH0JyLjmNDDr2MqU25aOzh79tVy3d1bd3ts7AsDOveoq0Fba8XePTXvfb3e+uiZ02o+Hf2yPiTq3 gfSfGVp8P/B/hHTPEOna1qOpeGdavru9uIbSdJzbRo0Ma4m2eW5ZsbGbg0PHwWmFw9SEno3OUGkn vpFtttbba63EsEk718RGcVqlGEk2+msnok9XbXp1Pt6oGFAHzv8AtE6noVv4b0fS9a+AupfFaTU7 hobbQ7HTYLtYHC582WSchIF7byRz0rKpTwM2njanJbWNlNyv/d5Fe/ndeprSnjI3WDSd/i5pRjG3 97m+JPtZ+h8t/Dr9n/8AaEb4g+EvGOitB8GPAVjqcF7qPg+08SXXiKTWLVHDPayRSZt7YOoKkwsd u7jpXQ8zrySpUFOdPVN1+S6T6xspVL9Vzz9UZywGHT9rXlDnS0VGEox8uZ3hFrvalr3P0sqBBQB8 XftevYTS/BXSvG3jrUPC3wb1LxBJa+J73StSOnSzbrdxZRyXCkPHbtclFcqRyyAkAk10YZ4ty9ng 3yzl9pRTa62V00nJbNryWrRjWeHivaYmKnGP2W9H0u0mnJR3t/289EzH8IfBH9kfSfFfhjVfDXxD vrrxFZ6hb3Gn27/ELULsTXKSK0amFrkrJlwo2EENnBBzit54fPVButWquHW8YWt1vaC0tvZowhjs nnJRpUqKk9mt79La79j7prgO0y9Zur2y0fVbzTbM3eowW0stvaA48+RUJVM+5AH40rqOstgs5aJ6 n4+L8eP2J9Y8F/s4/DX4heGvD9la6tcX2oeJNFudRvbT/hCdUls5ry6EilhI2+8LwYYgZcEccV30 8JVxMFUoYmp7+sHGrq1vaclJPSOya3SVjOriq1Gpy18PFuOklKgmtFa8IyjJavW61td3Z7H4Bi/4 Jnr468Ft4B1Twk/jkaraf2Kltq15JI195qeQEVpSGbzNmAQQTilPK8ypxc6mJqOK1adeTTXVNc2q fVW12Eswo1HyrCwTfVYaEWvPmVNNW73Vt7n6aVxGoUAeA/tK6j8EdK+FOrah+0HLHF8OIZ4WllZ7 hGjn3fujG0BEgfd0KnNaUaVStNRpVfZy/m5uS3zbS+T0fYiddUIuTp+0W3Lyc9/+3Wn9/Te6Pgfw vN8fNWGm6j+xhc/EQ+DJnRo5vjHcQS6M0GRzEsx/tDG3ofmHStK2Yyw8vZ1pLFtPW1Nwf/g5clN/ KMmTDA0sR70VHDf4avNf1pL2tvTmp27d/wBdq5zUKAPC/j/4y8W+EvCGh2fgO5sLPxd4o16w8O2W ranGZbfS2uXIa4kQEbyqK+1MgM5RSRmrpSUJczhzu2kb2Tfm97Ld21stCJx51Zz5Y9Wkm0vK+l3s r6K9z5kt/id8Wvhr8B/2wta8Q/EX/hKfGHwr8RTx6brOo2ENr9rhj0rSr/7MYo/lAd7qeIHlgJB1 IFaRrzqyhOrSgmlqoqSjbW71k3dLre10m1uZyo06alClOVm9HJqUr6WV+VJ3fS3V2P0Khk86GKXa V3qG2kcjIrn06G+pLTA8/wDiUPia3heX/hUn/COHxj50ez/hKWnW08rPz5MKlt2OnGKlzhT1nS9q v5eZR+d2mvwD2ftPd9p7Pz5ef8OaP5nx18RvH37b3wt8NSeNfE1n8G38JWM0X9rXtnNqbHTLRmCv dOpjBMceQz7ckKC2CAaIYjCzkof2e05Oy/extd7XtT0Tel9l1stSKmDnGPPDGt21a9gk7deX99Zv rZtX2V3ZP9AgVYKysCpGQR3FUUmPoGFABQB4X8fvDsHiLwfokVt4y07wv4usdesL3w3quqhWgbVk kxBA6Egus254iqncRIdvIFVCFab5qEOdx1cXdJpb3a202dnZ2dmROpRiuWtJxUrJNbpt6WT0evTS 6urrc+QLP4DftY+NYvjJ4C+ILfD3Qfh58UPEA1XxJqWiXt1e3b2hsbKymtbSN4kCGWOwH7xzlfOb AOATlLGKcZwpYWUZPRSlODUU1vaN3Jp3toltc3WFhCUZ1MSpRWvLGDTk76Xbdora9uZ9tz9L440j jSOMYjUAKPQCrM9ySgD4g+JXjb4v+N9O8UeAvEn7FuqeJfBlzJJb75fEmlIl5Gr/ALuZA0weNuFd TwynB4IpVK2WVIqMpVlJWd1SldNdU0+j2ZVOlj6cuaEqNn0c3qn0a5GtVutT5q8CeC/2gNH8YWHj T4mfs4eOfiNqnh8iDwpF4m8VaK0Ph+2UYVhGJdst3jhrlxuIAxtOSSrjsLjo+zxlSo4L7MaDipv+ aeur/u/At0uzpYSthLywipRlLeTqyk0v5YPk0j/5M9m2frpTICgAoAKACgAoAKACgAoAKACgAoAK ACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAxfDf/ACLugf8AXlB/6LWg DaoAKACgAoAKACgAoAKACgAoAKACgAoA4P4j+HPFvirwtdaP4J8eTeD/ABBJJG8euW9hFfNEqtll 8qQhTuHGe2c0KrUpe/SjGT7TTcfui4v01F7OlV92s5KP9ySjL5Nxkvw+4+Rf+GUPjsPGo+IcX7YG sQ+K20/+y5ruDwnYIt3bBzIiTIH2vsZnKEjK+Y4BwxFJY3Hxk2qdCztdctSza2etS6aWmjV1veyt TwmWyjyv27a2ftYXV90v3NrPzT8ra39R+D3wD8d/D/4leJviX48+N17491TWNKj0vZqGjQWRtI45 FdBC0bHYmfMLIAN7PuYkquJdbE4ialiI00krLkUlbvvKW/W93orNJWK9nhaNPlw3tL9eecZX7N2p xd1srOyTfu3dz6lqyAoA/On9p23/AGXdS+KcGneMPgV4m+Kfxni02O7bTfCNteXU+nWbbkjeVklS KAPsYDJBbb3AolTpUuXEYjHSoJ3UUp1LvvaNO7t3drN+hpRrYmfNh8LhoVFpzOcaXL5c06i1tuld 26LU6b9lS3/Zmi8a+Krf4Y/CnXfh98WbDTgmpaB4rgvbW++wSyqRIiTSMkkRkhQb0JwVAJGeat7W n7aljZYine2tScrPzhPWLts2tr26mcp1Iz9lXwkKMt04wpJSXW06StJd1fe11sfeFSAUAfA37Rnx s8ZeFdV+LNz8P/gf4V8UaX8NPD6a54m1/wAUXi22AYJbhba2RYZHlkEEW4klVHmKM1nLC5TUlF4z DurOXaMLRW3vSm799Em7eppCtj1GSoYhUorZe83J7uyi0kvNvV+h2HwW8ZfFVPi7d+Afin8Lfh74 Ta68NPrWmXvhO/kuZtTVbiGOVFDQR/JF5kfmZOQZYcBgxKlHD5bFOpgsJKlJWTbVPZ7L3Hrdr5W1 tdXKtTFuyxGK9qnskpLVb/E/Ptrd2ejPsmtDMKAPmv4qfs93XjXxaPiP8Pfil4h+HXxFksE0y81X Q44LmDU7aNmaJbm2mVkcxmSTY42sA7DJGAJhWxOGk5YdxalvGcXKLa2atKLi+9nZ6XRfJha8YxxM G+XZxlySs91ezTXqnZ7Wuyx8H/2fz8OfEmsfELxj8Rte8f8AxO1OyTTZPEWvLDCLSzV/MMFrbxKE hRpMM2Mliq5PyiiVXEYiaqYhxVlZRhHlir77uTbdlq3sugWw9KLp4WDSbu3KXNJ22u7JWXRJLVs+ jKogKAPy2+OGnfBTSf2hPivq3x38f+LfB8up6PpE/heTRNVvdOivjDFMjyQmDCz3SSnb5TFsKUO3 Dmt8NPFz544TEqlyq8k/Z7fzPnTfJ00srp36E1KVK0ZVcI63NomlOVn/ACrleknvd62tbZnh+i/E f4K/Gy8XV/2mfFOhahqWi/BnR0iub25EX9m+ISbyXVPs7AgJfoF08sEO9PlAA5rf2OLxbX1eUobV EoScdJfDJpPWKs7XurN33M41YYCL9pDmTfs25Qvdx+xdrd36at+h+tHwRvPFGo/Bj4Rah43Dr40u vC+lTawJBhhetaRNPkevmF64XUVZupFaPX7zb2fsf3b6afceo0AeJ6x8bvDnh7UPjR/b0D2Xhv4a 6VbanqmryyKVk82CW4ZETrlYkQ5PDNIAMkGtYU41HGMXq9+yXr+L00VjGc5U1KTtZbLW7+Vra7LX e+nfgvg58fvGvjbxjY+Cfid8Jp/A2s67oL+KPD6PqMd99s0+OWGOVZwgHk3EZurYtGcj95wx2nA5 4SvBzwzlo7e/FRune0o2butNnZrS61K9liKMlGs4Sv8Aytvla6O6V/Jq6dmfVNZGgUAfJPxoh+L3 hP4oaP8AE/4ZfDKTx283hi68OwWEWpW9mdIvHuI5kuH85lBhk2KsjKSyiFeCDTWKpUbwxDnybpQT knLs0no2vhk1Ze9dq+q+rTre9RcFPZubtaPdNJt2eritZaWTtp5n4F/Zju/hV43/AGZtc0DSftPx Cjm1S7+JHjuEsp1sTWE5lS4YnMgfUJrd4kIOxYONoUg5rFV3Jyqzk5VN43k4JLVWXwx5bKMbWbT6 6m0qdOUFCCioU9nZKTe3+J8125bpPzsfoFVmQUAfF/7WOn+FdTbwuvjn4O+Otf8ADlnFNNH42+Hk sg1Dw7I2FdNkDi4aN0Clgquh2jcvyilGrRoz53inQqbKXLeDT3Um4ygtbP31bqmjSMcRUi4QoQrQ 3cJSSd1s4puLb3+GSl0s7nN/smeC/wBkrSbq11P4L+NrvxL4t03ThpEA8T6zPd6jo1moXNtFazFT bIAiAqsa8IAeBW9TB432dOtiKzrU4q0WuRw7XXIkm7aXbb89WYyxuH9rKhCgqFSWsouMozfXXnbl bd6O3XsfelYlBQGx+cfiT4cftqXP7UEPjzw/4q+H8Xh+LwrqemWWpXWl3b21vby6jayx208YnDPd FIgwkXCBUkGMsKtZk4/ufqja3t7WSi2tOa/smk/7tm7N+9pqvqOHkva/WWn35IOS68qXNdx/vaap aanrPhz4R/tC+Ifif8OfHHxo+JvhG60TwTPd31jpHg7Sbi0e9uZ7WW1/fyyyt+7WOd22gcsFJ6Up YytU9ynh1Ri/i/eSm5LorckFa9nd320BYfDU/eVaVWXTmjGKXno5O9rrpufYdSMKAPkf446b4+8I /ELT/i/4K+Hd145sZ/DF34X1HSNJnhTULAPMs8dzbLKyrIhIZZEDBjtiIB2nEc9CM08VdRV7SUXP lfW6inK0l1Sdra6O5ap1KsGqEoqXVSfKpLyltddnZO71ujwv9njQPi744sv2Q9E8VfCTW/Avhj4K aJAb7UfErwxz6zqUejPpSw20COzrDi4mlMkgXO1ABycL6zhqqgsLKUpPWTcZRUVb4byScne2ycUl vsVLDVqDn9YcbbRUZKTevxPlukkul7tvyZ+llaGQUAfAP7VcPwwb4neD3/aI8k/B9vDd+mjrq7Ou k/2/5i/8fWCEMpt/9SJOOJsc4rWiq2Kl9UoVXCT960ZOMppdLpptR3cU9b3aaQf7uvrfs+e2l+VT 5L9bNO3NtzW0ta65tfLf2f8A4k+GPiFaf8E9vB/wz8QQ6z4n8E+FIJ/F/wDZj+amj2H/AAj5tXt7 pxwsjXpswIj826EnGFNaV/bYaMXWlrW1SvrJfFztX2WlpPrKy3ZnTSruTUHan9pppX25U2tW1e6X RX7H6oVzGgUAfC/7XWufsxaNrHgtPjHfeIbb4l3cTxeG/wDhDJ7+LVpRvGVg+ykbhvxxICuetdOH pYiV6tHFexS3vKNn6wkpKX/gLfYyqVYaUZ4ZVk+8Vp/3EvHk+U43Od/Z+i/atHxJ0F7l/EP/AAzp 5Vx9rHxTewfXSfJfyPsxtDnb5vl7vPUNtz3rGeYxrv2XIqja/iKnKik/OM3eV9rxhFa32LhgowXt ozUP+naqe1X/AIFytK2/8Sd/z/QqoKCgDmPEvg/wf4xt7a38YeFtH1u1tnMkMesWUV0kTEYJUSKQ CRxkdq56+Fo4tKNaHMl3N6GMr4NuVCo4N9m1+RyQ+BvwTI+X4Q+CSp9NAs//AI3XL/Y2AX/LmP3H V/beYvX6zP8A8Dl/mdp4d8K+GPCFjJpnhLw5pei6bJKZ3tNJtI7WJpCAC5SMAFiFUE4zhR6V10MN Rw0eSjFRW+hy4jFV8XJTrzc3tdtt2+Z0FbmB8fftSx2Wi+IPgT8T/FfhO98RfDTwbrd3c61aWNm1 8dOeazkhtr97ZQWlWGRiDhSU87fj5cjOp7CovYYmSjTm9XLSN1qlJ7KLffS9rmtJV4t1MLFyqLZL 4rPfl/veS1tex4z49+Nvwj/aN8VfBjwv8A4pfEnxB0jxlpOrv4hsNJmhi8OafbzrJevNctGAgltV mt/Lz85mAx3DlhMJlslVpzp+0fupQlGTkno7qLfupa3eiaVtbEU54zGQlCpSqRpJ3k6kZQSa1VuZ K8r226N30P0nqyQoA+cPjta6J4k1r4V/D66+LPi/wR4h8S395DpUnhCSON9QkgtJLmSOZ5IpFVVi hdhnGSMA84ranLE04yqYacI235oqV9be6m1qt3boZSWHqNRr03JeU3G3rytN32PItZ+A3w8+HGt/ D/xz8X/jV8R/GljYeI9Nt9G0vxPqMVxZRavcXCQ2crwwQpvZZpE2s+VQkN2zUuePxq9nXqxUFq1G nGF7apOWrtdbXV3Za7Fp4LDe9h6HvvS7nKbSejaUpW23dm7bWPuysygoAKACgAoAKACgAoA+Wf2s x8El+Huk3Hxpk1WJI9Vi/wCEfm8MmcawuqFXEf8AZ/kAyGYp5mQAQV3bhiqp0pyl7aFb2PIr87aS SejvzJpp7crTv0VxOpb9z7H23PpyWve2vRpq1r811bufKPwVtPgZqvxa8DRfELVPjrceOoblrjwn Y/G6O5t7N7tELh7VfLSGS4VC5UOS4wSoyM03UnmUGo4+FaMbScIRjTej0bXLGUknZ6e71YoQ+oe9 /Z/sXLTnc3Vtf7KftKihfVW0fS5+qlQUVby2F7Z3dm0ssSzxtEZIG2ugYEZU9iM5BpXa1W4tOux8 g/8ADGWg/wDRefjX/wCFi/8A8bqvrma/9BX/AJSo/wDysPqmV/8AQFH/AMGV/wD5cbHhv9kzRPDf iDQfEcXxp+Lt/Lpd5DerZan4ree2uTG4cJNHsG+NtuGXPIJHej63mUvdqYm8eq9lSV11V1BNeqaf YX1bLVrTwcYy6PnrOz6OzqtP5prumfWFIoKAOB+I3xO8C/Cbw3L4t+IPiK20jQllSBZp8lppX+7H Gigs7nBwqgng1rRoyrXs0kldttJJd23ol6mc6nJZKLlKTslFOUm+yS1Zh+E/jf8ADTxp4N8HePdC 8Rq3hfxTqL6Rpd1dQSW5nvFmmgMJR1DI/m28qYYDLLjuKcqDU3GMoy0vdSTTVr+607PTXTs+zJVV 8qlOEo62aaaad7arprpr3Xc9arE2CgD5f/aCvPHeq+Jvg18L/Bnj+48EQeMNQv1v/Edhbwz3Xl2t o0621v5oZFkkILbipwkL4FaUq06Kk6MIyn0503FLq7Jq72SV7amcqdOo4+2b5O0XZt9Fezst3prp Y+MfCknxK8Lx+D/HHiX9p/x1qtzpnxbfwZqvgy8fTla/tv7bksLQbRAHy0JtLiTH3oWkKFcqR0LF 42rHnnGn7Jp3ap2aezs+Z7yXKusb31trmqGBhP2UFL2q1SdST0328o+9fZ2s0k9P1urjOgKAPj74 l+IT428A+GtZ8bfsgaz43vDql7Avha9t9NuptMWN3jW6PnyBAsqKCu0lsOMion/Z2IX76rOMOjUK t21unGCva+zej3RtRjj6Lao+zUut5xtbpZtb9102PJ/A9j4OTxr4Re1/4Jw3/hm6Gp2pi8SPpWgo NHbzVxdFo5i6iI/vMoCw28AnFSqOUJ3pYmo5dE4YhJvom5LlS83p30N5Vc3cWqkqfL1tUi3brZJX bt06n6M1qcQUAfJ/7R2qeH/DWs/CbUNG+Elv46+Nd5q11B4S01pltI4pms5RdXFxMcqsKWxcMWVu XUKNxFc31DL/AHq2Jh7vVRjFym3srOyfe7aStdm8MVjHahh6iV+sm7QS3atd36Wjq722ZyejfFH4 t+A/Ffg2z+PnwN8JaJ4Y8R6nb6RZeK/CGqLfx6dqE5C20VzHJDG6CSUrGsi5G9lBxkGqp4XKK0kq OFlSqLWPNGm07a6Sg3aVtVdK9tHcVWrmFKPNLFKrB6NLni0npe0tJLvrdb2tc+3K3MQoA8t+MGuz eH/BN7dW3wv1D4gzzyx2y+GdOhgla43nG5/PZY1jHVmY4ArOpTwlSPLjX7n+Fzd+lopN37du6NKU sTGV8I0p93LkX/gX9M+AT+yz8bfiBqdprXhjRPDX7ONmJlmLeC9Vur7UZFyCVktYWjsASMg5WSto 5lWoR5MvVRp9a81KPyptVJLTopwFVwlHEvmzGcJyvf8AdQ5ZN+db3JP5wkup+qFSQFAHwb8Y/wBq j9lTXvDnjDwJ8U/+Enbw9byNDfzHwzq0aWssEmVmiuUhGxkkRXSVG4Kgg1tChRrOKpY2lGpo1atT Uk/RvddU15NboX+2UE5ywdRw63heLT018n/w2p8keGb79ijw/wCJLbVde+KHxu8T2Gta3b6tF4e8 T6fq0tjqWpJHEsMksa2qG5dUtoAquzAiFchsUnCtiY1KdXNKEoPWSjOhFtaXTad1HTVR5U/myvZy wrjVp5XOElpFtVJWvtyqU2r66Npy7NWVv2p6VkIKAPNviro3iTXPBt9beFfiUfAmowulw/iMWcN2 IIUyXVklIQAjqxPGKqnKtGS+rwjOb0SkpNfdFxd+2pE1QcW8TKSgt3GSi/vcZK3yPhHTvBmlfHm7 uPhn4n/b7h8feGrohdW8HeH7fS7ObVYVbLQSSRM0gibaQwTBIyMiuzFYbOoUZe1w9OlF6OUac+ZL rZyqSSfm07HNh8Rk3tIunOrOW8VOonFtdbKlDm6aXsfpoqrGiogARQAAOwrgR2D6YBQAUAfPn7S3 wu8UfFz4Z/8ACNeB7vR7HxpZ6rY6xpGr615uzS7y1lE0NzH5YYmRHVSFIKsNyng1nOcqdpwhzyTT S5uVO3fR3XdaN9GnqXTjCo3CpNxi1ZtR5nby96Nn2d9H0a0PM7TSv2+obe2hufFXwVnlRFWSc2Wq KZGAwW2g4GeuK1/tBPV4D/yv/wDcv1M3gKd3yY+dul6EW/m/bL8l6I+z6QwoA42b4heA7eaS3n8a aHHcRMUeN7+FWVgcEEbuCDXXHAYqSuqUrejON5hhE2nVjf1R5t8VNetPGXg290H4dfHrRfBXiiWa CSHX4WtL9oUSRWdPJkcKd6ArntnNVHCY/D+/Tw/O+01Ll/8AJbPTcSx2XVvcrVvd/uySfyep7woI ABOT61xHaPoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAK ACgAoAKACgAoAKAMXw3/AMi7oH/XlB/6LWgDaoAKACgAoAKACgAoAKACgAoAKACgAoAKAPnf4kfF 74n+DfE0ui+FP2cfFfjPSFhjlGt6PqGmwQs7A5QLPOj5XuduOeDVxrYCKtiKk4y8qU5r74qwnQxl T3qKg4/3qii/usY/wf8A2g/EnxK+Inif4ceKPgl4k8C6tommxanNJr95YyCVJXCRCNIZnZ1bEv7x QUBhZSwbANylg6lPnwtSUtbO9OUbet+vZdVqthexxVFr6woJPblnzX720tZdddLrTU+oKxKCgD4e 8Z3nxq+GP7Q3jLxj8MvgJqfjXwd4s0awi1e7h1bT7JlvbQOsLQedKrFfKldHVlABRGUnLCphXwdK bWJ57vZxpylbyvs091bVNO6d1Zyw+IqxUqMoK3SUrX89IuzW3W6ttbXzqPxd+0zd/HJ/jDrH7IGv GLTfDsnh3RbG08SaOJFiuJori6luHM+CS9tAqKOFVXOSXwK+t5a56OqlbV+xleTvpp0Udbb3bew1 hcaqduak23/z8dkvL3NW+rsrWS11Z+hnh6/1LVdA0PU9Y0aXSNXvLOGe60maVJXsJnRWeFnQlWKM SpZSQcZBIobhLWF+XpdWdul10fddCLSjpK1+ttV8nZXXbRehT8XeL/DPgPw1q/jDxhrNtpPhnS4v OvNRvH2R26ZA3MewyQPxq6VOVaahDd/L8WTOahFyd36Jt/ctT5f+I3jP9lrwl43+JFv8Tfi7oGlX nj7w3aaXrfhfWNShhiurUJOkc4jb5gzw3Dxk5wyonHy870MoxuOpydGN6b7Wuns7O/ppbdXTFLG0 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 8WLT/grr+1NPMUfR/AAUAnjSLn/5Jr6+fDuXxV1T/F/5nFQ+sVaihKvKz8of/In9NH9K/PT1haAC gAoA+aP2rPFPiXwx8L7CHwrrl1o2o6/4i0fQJdV0/aLm0t7y8jhmeBmDKkuxmCuVO0nIGQDU1MRL B0auJgk5Qi2rq6vtqtna97PS+6a0CFCOKrU6E2+WTs7Ozas3a61V7WbTTts09T5dh1PxT8L/ANnX 9uYaF478UXuo/D/xNcz6Hquu6tPf3kAi0bR75Y2nkJZozNLLuTIBWR16GtqOOr4h0qtdqUtF8MEm m7bRio7NrRXWltURLC0IqdOlDki7uyb0dt7tt9OrfmfppC5kjjdgMlQeKiStKxUdVclpDPk/9s6y n1T4F6vptvqlzpr3F/aAX1ikJnt2R/MSSJpUcRyK6IyyKAysoKkEZrzM2zGeU4d4qlBSlFq3Neyf fRrVdndPZpptHo5XgYZlX+r1JNRad+V2bWzWz0a3/A/PS3+MX7Q8awwj9ofxeyqFXL2GhsxHTkmw yT7mvDXiFiXvgaH/AIDV/wDlp73+pGB/5/Vf/A/+Aft3X158gFABQAUAFABQAUAFABQAUAFABQAU AFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQB//9kKZW5kc3RyZWFtCmVu ZG9iago5IDAgb2JqCjw8L1N1YnR5cGUgL0ltYWdlL0NvbG9yU3BhY2UgL0RldmljZVJHQi9XaWR0 aCAxMjg3L0hlaWdodCA0MTIvQml0c1BlckNvbXBvbmVudCA4L0ZpbHRlciAvRENURGVjb2RlL0xl bmd0aCAyMTk1NTQ+PgpzdHJlYW0K/9j/7gAOQWRvYmUAZAAAAAAB/9sAQwACAgICAgICAgICAwMC AwQGBAQDAwQHBQYEBgkICQkJCAgICgsODAoKDQoICAwQDA0ODw8QDwkMERIRDxIODw8P/9sAQwED AwMEAwQHBAQHDwoICg8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8P Dw8PDw8P/8AAEQgBnAUHAwERAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkK C//EALUQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNi coIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SF hoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn 6Onq8fLz9PX29/j5+v/EAB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQE AwQHBQQEAAECdwABAgMRBAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBka JicoKSo1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWW l5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5 +v/aAAwDAQACEQMRAD8A/eLw3/yLugf9eUH/AKLWgDaoAKACgAoAKACgAoAKACgAoAKACgAoAgnE 5gmFs6rcFSI2cZUNjgkemaV7Ctc/Njwj8Mf269N+N/xn8Xf8Jp8OLYa3pmgW41e58P3UlnqH2cXv yW8C3m+Jo/O/eM5IfzE242nOqzTmfI8HdL7LqySjfdp8mrlbXRWst7jeXwUVL63LXqoQu/VXskul t9ex9CfDL4S/GmD4sD4ufGv4jeH9Y1Gw0C48P6ZpHhTR5dOto457iCeWaYyTSNI+baNVGQFBbuai WKq1nyqiqVPqlOU3J9G7qKVle2l9XqNYejRjpUlUn3koxSXVJR7vdt9FofVVIQUAfnp+1J4T8G6R 4h8QTeMP2l9I+HPgH4m2ltp/inw7qMMBudbgtwYn+xzFhJD5kDiGVgrgKARtPJ6MPQzCrGf1SnFp 6c8m04N6e6+ZRbe8U9U9ddiKlfBU3F1+dyjryw1UkndOaUJSST6pxutHsfSMfgHSB8f/AA54rt9f 02A+GfBFxotj4WtlCzpBd3lu73Djd/qh/Z8UaAKAD5nJ4A5IUp04rkhaC0vfd9Fa2lld3vrfpbXV 1Iyb5m3N67aW669W9NOnzPeqskTFIDxbTfi/DN8a/Gfwe17SY9Hk07SbDVdF1K8ugP8AhI45fOFy IEIH/Hs0cQfDE/v0JABBO8KSrU26V3KPxaaJP4X3d7PW1rqxhUqxoSTrTioy2+W93e19ml21PYYr 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 +g+j/wCWf+Rn7LCf9Cmp/wCCcT/kdh8PNb/ZKm8feCIvDf7XHxQ1rxG+r2a2Gj6h4p1qeC/ufOTy 4JY3XY6O+1WVvlIJB4JqZ1MzcX7TG0pR6pfVLtdUuVc1305fe7agqWGTussnB/zOliEo+bclZW3u 9F10P1LrhNQoATPtQB5v4/8AFvjHwtd+BYPCnw5u/FVvrOtQadqk9rexW39h2j533rh/9YiY5Rfm OeKaqUIaVnJN/Dyx5rvpfVcq89bdg9nVqfw3HTV8ztp5aO77I9JpAJjikBz2seJ/C/h660my1/X9 M0281WVoLGG/uY4GvJAMlIgxG9sc7Rk4rWjhKmIv7Km5cursr2Xf08zGtiqeGs60+VPu7L79jeCq QCAOe4FY8qT2Nua6vceDmqAhuLmC0t57q6lSK2gRpJJXOFRQMkk+gAzTSbdkJtRV2fL/AMYrLV/G yfBb4o/BTxd4al8dadNNqHh2y1u422XiuwurQ+fArr843Q7JlkQNt8oEgqTVOFWhOU5UXUjDSaTs 1fS6lrFNPvo7tX1FCVGtFQlU9m56xdr672cdG01urprfoee3nh79p/46674G0T4p+AfCfgL4aaBr 9h4h1E6brcmr32rTWM6XNtDF+6jWKMzxxM7HLFUIAGazq4uhUShhaFSLbV5VHBJLrZRcrt7XbSSb 3Lp4WdJ8+IxEJ22jCMldtbycnolvZLV9bH3TTENZlVSzEBQMkk4AoWuiE3ZXZ5F8UPHvjrwppOh6 n8NfhXcfEKS+kIkh0/V7WxFvFt3LJvl4cN0wv1pylQoNrFqat/JBTd/NOUbf1oKMamIinhp09dbz lKKa8nGE7/clbqfM/iK8/aP+OfiD4Y6HqHwCX4d6JoPinTfEN74q1XxFbXs8MFrKJJILWKBc750D QMWYKI5XznOKzeKwXMpYSFWVTa86cYRSekm3zyb0ukkt9b6GscLiIp/WqtLk7QlOTbWq+KnBK0rO +vkfe9WQFAHxt4t/bf8AhZ4Ik1//AISTwV8TrSw0aWWK71N/Bt79kXY5QuJtu0oSOGzggjHWtYPA zaj9dp83b37ruvg6dSJ0swpx5/qc3Ho1Kjr2sva82vRWv0tcozft3/Ce1fSkvPA3xTtf7SuI7Sza 78FX0K3Ez/cjQsoBdsHC9T2zRGWXzvy46k7a6e0ei9Ia/LprsTOGYUknUwU0m0ruVG2u1/3unbW2 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 8AX/AIs0zQ9X0m70nSoJZjdzpDbhGS3BaNpmSOVRhxHIzqwKYO1PHYmrzQq0qKTT96MJK33ze+yf SVrpq5EsLgqS5oOo5XVk6jaf5bb2d7pNH6E1zmgUAfNn7TGv/APSfB+n2Hx88Pw69pWp3DQ6boq6 PLqtzeXAXJFvFGjMHC/xDGPUUvqtOvapUqqlya87nycvo7p38o3fkaUsRiKLccNTlUctHGMbpr+9 f3Uv8TSPjLwP4E/agl8Q6Xe/sz2PiX4YfCmNy0um/GDVP7Yiuov4VttNy8tsvT/l4TA/hFavN3bk TeM/vTj7NLzVTSpPy54tGf8AZlN3nWUcNLtSbk3/AIofwVf+6m/Pt+iHwo1H4sah4cvB8ZPDuhaV 4stL57dG8N3klzaahbhIylwokUPEWZpFMbFiNmdxzxm61Kt71KnKHdSaevk1a67NpPfQXspUfdlU VTs1Fx08027PvZtdj0PUdPtNV0++0u/iEtjeQvbzRHo8bqVYfiCaTV1YqL5Xc/N3WP2Jfi5pXin4 CwfD79pTxNa+A/AE95FYRajbWE9z4dtG06a0hS1Jtz53yusJExOIySPmANKGNxtJQpuFOdtLuDV9 PtpTV/KyXvasuWFwNTnm+eN+im2r3+y3dx79dND6D8OfAz436R4g0LVdX/a08X6xpVleQ3FzpNzo 2kRx38SOGeF3S3DqrqCpKkMAeCDzW7x+MmuWVKik97Qkn8nzuz7aP0MVg8FD3ourdbXqXV/NW1Xk fVlZFGbq+mQa1pOqaPcvIltfW8ltI8TbXVXUqSp7HB4NLVfC7Mat1Vz8xb34C/toeCvEX7MfhjwZ 8QfBuseDfh613p9hq15o08Js7NNJmtITqUa3I+0ErsQeWF/elXPAIq6ea1KUVTq4a8paS5akkqlt byvF8uvvbu70QSy+hVcqkMRJJapOMG430tG1ubtrb3ddWfUHhzRf2zovEGhS+KvH/wAK7jwwl5C2 o2+neHb6K4mtQ481Yna6ZVcpuCsQQCQSD0qnjozXL9SUb9fat287civbtdXM/qcY+99bnK3T2cFf yvfS59WVmWFAHzr+034K8ZeNPh5pR8C6TZ6zr3h/xDpfiEeG9Qm8iDXY7O4WZrV5CCFLbQylgVDo meM1nKcaSvOLcHpJRtzcr3tff0vqrrqXThzy0moyXwt3sn0vbW3mtVufOXxY+Inxo+P3gLWvg74W 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 DXizRNKg0XxzaaTcanBp62onWewlMEbvb5eQTAkBZPNIzlMVCp4XF1FTxFSEZxXuqpJRi093GUrR 5r7q6drWNVHFqn/stKVSMn7yhrK62vHdq2zV0ne9rj/hJ4v0H40/tN3Xxc+FOganb/Dew8Fz6Lq3 ia90qfTIvEl9LeW81qsKTIjzC3iiuv3pXA+07QTk0KOGwspYfDVITvrL2bUoxa0XvR93mabvZvRK /QJwxUoKeLpypuOkVPSVnrL3b3S0VrrV3t1v92VZkFAHwh4w8deD/wBn/wDaN+I3xF+L3h3VIvDX izRNKg0XxzaaTcanBp62onWewlMEbvb5eQTAkBZPNIzlMVCp4XF1FTxFSEZxXuqpJRi093GUrR5r 7q6drWNVHFqn/stKVSMn7yhrK62vHdq2zV0ne9rj/hJ4v0H40/tN3Xxc+FOganb/AA3sPBc+i6t4 mvdKn0yLxJfS3lvNarCkyI8wt4orr96VwPtO0E5NCjhsLKWHw1SE76y9m1KMWtF70fd5mm72b0Sv 0CcMVKCni6cqbjpFT0lZ6y9290tFa61d7db/AHZVmQUAfCHjDx14P/Z//aN+I3xF+L3h3VIvDXiz RNKg0XxzaaTcanBp62onWewlMEbvb5eQTAkBZPNIzlMVCp4XF1FTxFSEZxXuqpJRi093GUrR5r7q 6drWNVHFqn/stKVSMn7yhrK62vHdq2zV0ne9rj/hJ4v0H40/tOXfxc+FOganb/Daw8Fz6Lq3ia90 qfTIvEl9LeW81qsKTIjzC3iiuv3pXA+07QTk0KOGwspYfDVITvrL2bUoxa0XvR93md3ezeiV+gTh ipQU8XTlTcdIqekrPWXu3ulorXWrvbrf7sqzIKAPh39o/wAO/Bzw342sPiNq37TFx8FPiTqlimny ahZavZwDW7WJmMYntLlXSXy2kfbJtDLuI3Y4rrwWEzSfNUwEVKDtzKcFKF+jWsWpW7SV1a6MMRic BZUsXBuS1Tg5KaT6e5f3X/eTV9iD9meD4Cah8RPEHiXw3+0t/wALj+NE+kGCbU9Q1i1u59O0tZoy 8dvb26pHBCZmhLlV+ZtmTwKMXg8zptV8ekktIqEVGKvq9E223beTfYdDEYNxdHCQlG+rcudydtry kktL6JJd7H3TXIbBQB8ufGv4d/FS68WWnxG+EHj7wz4a1ufQpvDepS+KrKW5ijt3mE0VxblJE2zR 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 PKKkqJOcqkcPibYbFVIxj8S53ywlJdG3aPMl8Klo7ytrvtR+s071sJByns+X4+XfRaNq/wASWvw6 NbeKfs3+OLX4uab+wj4a+H2ma3KPhX4et5/FuuXWmXNlZ2ZXQH082CSyoonla5mRise5QLcsTwta Sq0Icvs60JzmtoyUrRet5Wuo6pWTfNforMmWGxMHJYijKmo7cy5eaW3up6tWvd2tsup+qdMzCgD5 K+Mvxqk+C/xU0bWPGP8Awkb/AA5ufC14mn2Wh6VcX6ahrQuIiIZPJjcrMYQohDFVO+XuOKhVpX9l VqwprdubjG6/uuVr26xi7u60dhSoVpr2lGlKo9rRu7ebSez/AJmrRtur6+Q/D2x+NXgb4ifs6a/4 4+IniTU/GnxUm1OTxd4IvrlZtN0K2Wwmu0+xwhR5H2WZbS2Lg/P5x3ZLAivr9WvF+0UVSlZQioxU o9VeSXNJuKfNzX11VrWH9Rp0/epRbnH4580mpX01TfKtX7lkmkraq5+idZgYXiXxNoHg7QNW8U+K NVt9M8O6XA1zeahdtsitol5Z3PYD1q6dOVWShHd+aX4vQmcuSLk036Jt/JK7fyPy1+NXxx/Yz+Kn x0+F9z8UPir4U8V/CKLRr+0h0l79prKw1lpInS5u4F4ZXt1ljSRgVRhg4MgNdrwOPS+rxqOmnr7t SMeZr7LlGSem6Wz11uknlTxMIP28aMpSWnvUptpPrFShZ3ekrarSytdr3D4K/wDDvH/hZnhv/hRa /DH/AIWn/pH9l/8ACPJGLz/j3k87yyBn/Uebn/Z3VhVy3GYePtKtWcoro6zmu3wubv8Ac7b9DZZj 9Y/d+yav19i4f+Tcit9+u3U+965hhQB8DftFa54T8AftGfCX4h+Mvh14i8aaQfD2oaN9m0bwzda1 /YMkk0cq3qiONkBYRNC4yJMMhUFQ9Y1YYOulRx9aEIbpTlpzbXcbaq17Po1a3vXW1H67BOrgacpS 2fLZO3ZNtWaerWzXVNJP0j4Z/HX4PeMvGui+G/Cnwt8Y6Rr1553kajqngK+0q3h2RO7b7mSFVjyq soyRuLBepAqKeByihLnw1ahKotlB+95291dN9drlVK+a1IuOJo1Yw6uUotLtdKbe/k9T6xrpOczt X1OHRtK1PV7iG4mgsbeS5eK0iMssiopYqiDlmIGAo5JwKLxWsnZdW9l5sNfsq77Lr5Hwb8ftS/Zo +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 t34V0/VbZbEJfyyy3MSxmA/u3aeXIJOdxzULEZjCk6MKlPld96UHLX+98V+zvp0sa+zy6VRVp4Zu attVqpNq32VPl6aq1mdr4N/ZM17wfrnhfVV/al+Mep6dot1bzjRNS1i3e0u44mVvIlQQAmJgu1gC MqTyK0WNzKS5Kk6fLs7UaadvJ2un57rcyeFyxPnp4eSl0ftqzSfo52fo1Z7NWPsekAUAFABQB8B6 t+wTpuoaV4w8L2H7RPxa0rwJ4kn1KW78K6fqtstiEv5ZZbmJYzAf3btPLkEnO45qFiMxhSdGFSny u+9KDlr/AHviv2d9OljX2eXSqKtPDNzVtqtVJtf3VPl6aq1mdr4N/ZM17wfrnhfVR+1L8Y9T07Rb q3nGialrFu9pdxxMpEEqCAExMF2sARlSeRWqxuZSXJUnT5dnajTTt5O10/PdbmTwuWJ89PDyUuj9 tWaT9HOz9GrPZqx9j1IBQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAYvh v/kXdA/68oP/AEWtAG1QAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQ AUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAB QAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFA BQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAF ABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUA FABQAUAFABQBi+G/+Rd0D/ryg/8ARa0AbVABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAF ABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUA FABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAU AFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQA UAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQ AUAFABQAUAFABQAUAFABQAUAFAGL4b/5F3QP+vKD/wBFrQBtUAFABQAUAFABQAUAFABQAUAFABQA UAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQ AUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAB QAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFA BQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAF ABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAYvhv/kXdA/68oP/AEWtAG1QAUAFABQAUAFA BQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAF ABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUA FABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAU AFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQA UAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQBi+G/+Rd0D/ryg/8ARa0A bVABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQA UAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQ AUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAB QAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFA BQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAGL4b/5 F3QP+vKD/wBFrQBtUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFA BQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAF ABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUA FABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAU AFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQA UAFABQAUAYvhv/kXdA/68oP/AEWtAG1QAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAU AFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQA UAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQ AUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAB QAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFA BQAUAFABQAUAFABQAUAFABQBi+G/+Rd0D/ryg/8ARa0AbVABQAUAFABQAUAFABQAUAFABQAUAFAB QAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFA BQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAF ABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUA FABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAU AFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAGL4b/5F3QP+vKD/wBFrQBtUAFABQAUAFABQAUA FABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAU AFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQA UAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQ AUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAB QAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAYvhv/kXdA/68oP/AEWtAG1Q AUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAB QAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFA BQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAF ABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUA FABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQBi+G/+Rd0 D/ryg/8ARa0AbVABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUA FABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAU AFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQA UAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQ AUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAB QAUAFAGL4b/5F3QP+vKD/wBFrQBtUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQ AUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAB QAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFA BQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAF ABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUA FABQAUAFABQAUAFABQAUAYvhs/8AFO6B/wBeUH/otaANqgAoAKACgAoAKACgAoAKACgAoAKACgAo AKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgA oAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACg AoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAC gAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKA CgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgDy7SPEt9b6VpdskNuUjto0BKtkgKBzzQBp/8JVq H/PG3/75b/4qgA/4SrUP+eNv/wB8t/8AFUAH/CVah/zxt/8Avlv/AIqgA/4SrUP+eNv/AN8t/wDF UAH/AAlWof8APG3/AO+W/wDiqAD/AISrUP8Anjb/APfLf/FUAH/CVah/zxt/++W/+KoAP+Eq1D/n jb/98t/8VQAf8JVqH/PG3/75b/4qgA/4SrUP+eNv/wB8t/8AFUAH/CVah/zxt/8Avlv/AIqgA/4S rUP+eNv/AN8t/wDFUAH/AAlWof8APG3/AO+W/wDiqAD/AISrUP8Anjb/APfLf/FUAH/CVah/zxt/ ++W/+KoAP+Eq1D/njb/98t/8VQAf8JVqH/PG3/75b/4qgA/4SrUP+eNv/wB8t/8AFUAH/CVah/zx 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 AH/CVah/zxt/++W/+KoAP+Eq1D/njb/98t/8VQAf8JVqH/PG3/75b/4qgA/4SrUP+eNv/wB8t/8A FUAH/CVah/zxt/8Avlv/AIqgA/4SrUP+eNv/AN8t/wDFUAH/AAlWof8APG3/AO+W/wDiqAD/AISr UP8Anjb/APfLf/FUAH/CVah/zxt/++W/+KoAP+Eq1D/njb/98t/8VQAf8JVqH/PG3/75b/4qgA/4 SrUP+eNv/wB8t/8AFUAH/CVah/zxt/8Avlv/AIqgA/4SrUP+eNv/AN8t/wDFUAH/AAlWof8APG3/ AO+W/wDiqAD/AISrUP8Anjb/APfLf/FUAH/CVah/zxt/++W/+KoAP+Eq1D/njb/98t/8VQAf8JVq H/PG3/75b/4qgA/4SrUP+eNv/wB8t/8AFUAH/CVah/zxt/8Avlv/AIqgA/4SrUP+eNv/AN8t/wDF UAH/AAlWof8APG3/AO+W/wDiqAD/AISrUP8Anjb/APfLf/FUAH/CVah/zxt/++W/+KoAP+Eq1D/n jb/98t/8VQB//9kKZW5kc3RyZWFtCmVuZG9iagoxMCAwIG9iago8PC9SNyA3IDAgUj4+CmVuZG9i agoxMSAwIG9iago8PC9SOSA5IDAgUi9SOCA4IDAgUj4+CmVuZG9iagoxMiAwIG9iago8PC9UeXBl IC9NZXRhZGF0YS9TdWJ0eXBlIC9YTUwvTGVuZ3RoIDE0MTY+PgpzdHJlYW0KPD94cGFja2V0IGJl Z2luPSfvu78nIGlkPSdXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQnPz4KPD9hZG9iZS14YXAtZmls dGVycyBlc2M9IkNSTEYiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSdhZG9iZTpuczptZXRhLycgeDp4 bXB0az0nWE1QIHRvb2xraXQgMi45LjEtMTMsIGZyYW1ld29yayAxLjYnPgo8cmRmOlJERiB4bWxu czpyZGY9J2h0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMnIHhtbG5z OmlYPSdodHRwOi8vbnMuYWRvYmUuY29tL2lYLzEuMC8nPgo8cmRmOkRlc2NyaXB0aW9uIHJkZjph Ym91dD0ndXVpZDpkMWRlYzZiMy04MTg2LTExZTUtMDAwMC1mZWQxZGM1ZjM2M2EnIHhtbG5zOnBk Zj0naHR0cDovL25zLmFkb2JlLmNvbS9wZGYvMS4zLycgcGRmOlByb2R1Y2VyPSdHUEwgR2hvc3Rz Y3JpcHQgOS4wNicvPgo8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0ndXVpZDpkMWRlYzZiMy04 MTg2LTExZTUtMDAwMC1mZWQxZGM1ZjM2M2EnIHhtbG5zOnhtcD0naHR0cDovL25zLmFkb2JlLmNv bS94YXAvMS4wLyc+PHhtcDpNb2RpZnlEYXRlPjIwMTUtMTAtMzBUMTc6MjY6MTRaPC94bXA6TW9k aWZ5RGF0ZT4KPHhtcDpDcmVhdGVEYXRlPjIwMTUtMTAtMzBUMTc6MjY6MTRaPC94bXA6Q3JlYXRl RGF0ZT4KPHhtcDpDcmVhdG9yVG9vbD5QU2NyaXB0NS5kbGwgVmVyc2lvbiA1LjIuMjwveG1wOkNy ZWF0b3JUb29sPjwvcmRmOkRlc2NyaXB0aW9uPgo8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0n dXVpZDpkMWRlYzZiMy04MTg2LTExZTUtMDAwMC1mZWQxZGM1ZjM2M2EnIHhtbG5zOnhhcE1NPSdo dHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vJyB4YXBNTTpEb2N1bWVudElEPSd1dWlkOmQx ZGVjNmIzLTgxODYtMTFlNS0wMDAwLWZlZDFkYzVmMzYzYScvPgo8cmRmOkRlc2NyaXB0aW9uIHJk ZjphYm91dD0ndXVpZDpkMWRlYzZiMy04MTg2LTExZTUtMDAwMC1mZWQxZGM1ZjM2M2EnIHhtbG5z OmRjPSdodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLycgZGM6Zm9ybWF0PSdhcHBsaWNh dGlvbi9wZGYnPjxkYzp0aXRsZT48cmRmOkFsdD48cmRmOmxpIHhtbDpsYW5nPSd4LWRlZmF1bHQn PkZ1bGwgcGFnZSBwaG90bzwvcmRmOmxpPjwvcmRmOkFsdD48L2RjOnRpdGxlPjxkYzpjcmVhdG9y PjxyZGY6U2VxPjxyZGY6bGk+cGNob21lPC9yZGY6bGk+PC9yZGY6U2VxPjwvZGM6Y3JlYXRvcj48 L3JkZjpEZXNjcmlwdGlvbj4KPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgIAo8P3hwYWNrZXQgZW5kPSd3Jz8+CmVuZHN0cmVhbQplbmRvYmoKeHJl ZgowIDEzCjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDAxNSAwMDAwMCBuIAowMDAwMDAwMDc3 IDAwMDAwIG4gCjAwMDAwMDAyNzUgMDAwMDAgbiAKMDAwMDAwMDMzMCAwMDAwMCBuIAowMDAwMDAw NDk4IDAwMDAwIG4gCjAwMDAwMDA2NDkgMDAwMDAgbiAKMDAwMDAwMDY2NyAwMDAwMCBuIAowMDAw MDAwNzA5IDAwMDAwIG4gCjAwMDAyMzk0NjIgMDAwMDAgbiAKMDAwMDQ1OTE2NCAwMDAwMCBuIAow MDAwNDU5MTk0IDAwMDAwIG4gCjAwMDA0NTkyMzMgMDAwMDAgbiAKdHJhaWxlcgo8PC9TaXplIDEz L1Jvb3QgMSAwIFIvSW5mbyAyIDAgUi9JRCBbIDwzRjlDODU2RjdEQzA1NjZDOEEwQ0Y0NThGOTc1 RkU1RT4gPDNGOUM4NTZGN0RDMDU2NkM4QTBDRjQ1OEY5NzVGRTVFPiBdPj4Kc3RhcnR4cmVmCjQ2 MDcyOAolJUVPRgo= ------=_NextPart_001_41B7_43CA0D4D.1A016EDD-- From arekm@maven.pl Sat Nov 14 14:40:53 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 8C8487F47 for ; Sat, 14 Nov 2015 14:40:53 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 1A008AC001 for ; Sat, 14 Nov 2015 12:40:49 -0800 (PST) X-ASG-Debug-ID: 1447533640-04cb6c0cd45f890001-NocioJ Received: from mail-lf0-f51.google.com (mail-lf0-f51.google.com [209.85.215.51]) by cuda.sgi.com with ESMTP id 4PqmRYwHsrZU9IRw (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Sat, 14 Nov 2015 12:40:41 -0800 (PST) X-Barracuda-Envelope-From: arekm@maven.pl X-Barracuda-Apparent-Source-IP: 209.85.215.51 Received: by lfs39 with SMTP id 39so68944163lfs.3 for ; Sat, 14 Nov 2015 12:40:40 -0800 (PST) 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=lIcR/YSVdrxzY33F6BCgeBv85UKvsvZdWaU5m48tWfc=; b=vKJ/0C+d+evJ1OHXZVFhjtXTeoz4PzSyJumSzRZNAimI7yrtvIhHdUaNqXOMaLppyB WLwG2xWWy2ex243ddVYG+cRItHndA4zfQ0NaWRq4kzPTdfgp2Ckm9hHIn1y/JKX7pFv8 BYq2VF29S0rS16yT/aOoGZnJN2/KHqwhRO3H0= 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=lIcR/YSVdrxzY33F6BCgeBv85UKvsvZdWaU5m48tWfc=; b=Ha/DEgiIz/waSx/qAfTQXPE+MImvmTCO/z/jKfPtUqsbWSFnUMvW5ilCo4OhOxxwpo NVNVz1qkb/awqlTxC+3x4xOPiWhN7ZEZP++9NTVkEkyGafHuOUZoV+ENtyxfAR6W3gUB b6Z7ANiPy2O6Z6NaPTrgviNzAOqyIxHysM9mXeJ1Eab7bbNqBypbcSctvsqepbY8aRoD PlvT+3MwfFNtZIFDoedzzuxw9v/rQs9G7of8uDt+yEAbFtdnH8sVujawplNqyXj42YGU SS9ihiNm0UVAZtcJgC1AeAVRa5FpBwE4Eh+vHW3nc+w/wMgrJzj6JeGEAauwFuP057Om XBCw== X-Gm-Message-State: ALoCoQn8wysDEjmpxXmxXiQOBw7uGi1RLM6nAZcm9tCGkX+Ld4ARu8M4uh9hJ6biHh8KD4dsDqmd X-Received: by 10.25.83.139 with SMTP id h133mr13659143lfb.89.1447533640317; Sat, 14 Nov 2015 12:40:40 -0800 (PST) Received: from xps.localnet (85-222-71-204.dynamic.chello.pl. [85.222.71.204]) by smtp.gmail.com with ESMTPSA id s185sm2632530lfe.24.2015.11.14.12.40.38 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 14 Nov 2015 12:40:39 -0800 (PST) From: Arkadiusz =?utf-8?q?Mi=C5=9Bkiewicz?= To: Tetsuo Handa Subject: Re: memory reclaim problems on fs usage Date: Sat, 14 Nov 2015 21:40:38 +0100 X-ASG-Orig-Subj: Re: memory reclaim problems on fs usage User-Agent: KMail/1.13.7 (Linux/4.3.0; KDE/4.14.13; x86_64; ; ) Cc: linux-mm@kvack.org, xfs@oss.sgi.com References: <201511102313.36685.arekm@maven.pl> <56449E44.7020407@I-love.SAKURA.ne.jp> <201511122228.26399.arekm@maven.pl> In-Reply-To: <201511122228.26399.arekm@maven.pl> MIME-Version: 1.0 Content-Type: Text/Plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <201511142140.38245.arekm@maven.pl> X-Barracuda-Connect: mail-lf0-f51.google.com[209.85.215.51] X-Barracuda-Start-Time: 1447533641 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24395 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 Thursday 12 of November 2015, Arkadiusz Mi=C5=9Bkiewicz wrote: > On Thursday 12 of November 2015, Tetsuo Handa wrote: > > On 2015/11/12 15:06, Arkadiusz Mi=C5=9Bkiewicz wrote: > > > On Wednesday 11 of November 2015, Tetsuo Handa wrote: > > >> Arkadiusz Mi?kiewicz wrote: > > >>> This patch is against which tree? (tried 4.1, 4.2 and 4.3) > > >>=20 > > >> Oops. Whitespace-damaged. This patch is for vanilla 4.1.2. > > >> Reposting with one condition corrected. > > >=20 > > > Here is log: > > >=20 > > > http://ixion.pld-linux.org/~arekm/log-mm-1.txt.gz > > >=20 > > > Uncompresses is 1.4MB, so not posting here. > >=20 > > Thank you for the log. The result is unexpected for me. >=20 > [...] >=20 > > vmstat_update() and submit_flushes() remained pending for about 110 > > seconds. If xlog_cil_push_work() were spinning inside GFP_NOFS > > allocation, it should be reported as MemAlloc: traces, but no such lines > > are recorded. I don't know why xlog_cil_push_work() did not call > > schedule() for so long. Anyway, applying > > http://lkml.kernel.org/r/20151111160336.GD1432@dhcp22.suse.cz should > > solve vmstat_update() part. >=20 > To apply that patch on top of 4.1.13 I also had to apply patches listed > below. >=20 > So in summary appllied: > http://sprunge.us/GYBb > http://sprunge.us/XWUX > http://sprunge.us/jZjV I've tried more to trigger "page allocation failure" with usual actions tha= t=20 triggered it previously but couldn't reproduce. With these patches applied = it=20 doesn't happen. Logs from my tests: http://ixion.pld-linux.org/~arekm/log-mm-3.txt.gz http://ixion.pld-linux.org/~arekm/log-mm-4.txt.gz (with swap added) But are these patches solving the problem or just hiding it? =2D-=20 Arkadiusz Mi=C5=9Bkiewicz, arekm / ( maven.pl | pld-linux.org ) From penguin-kernel@I-love.SAKURA.ne.jp Sat Nov 14 20:35:32 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 A1D4D7F47 for ; Sat, 14 Nov 2015 20:35:32 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 7D630304039 for ; Sat, 14 Nov 2015 18:35:32 -0800 (PST) X-ASG-Debug-ID: 1447554924-04cb6c0cd363f80001-NocioJ Received: from www262.sakura.ne.jp (www262.sakura.ne.jp [202.181.97.72]) by cuda.sgi.com with ESMTP id DcGjIfTf8lcvYnsC (version=TLSv1 cipher=DHE-RSA-CAMELLIA256-SHA bits=256 verify=NO) for ; Sat, 14 Nov 2015 18:35:25 -0800 (PST) X-Barracuda-Envelope-From: penguin-kernel@I-love.SAKURA.ne.jp X-Barracuda-Apparent-Source-IP: 202.181.97.72 Received: from fsav109.sakura.ne.jp (fsav109.sakura.ne.jp [27.133.134.236]) by www262.sakura.ne.jp (8.14.5/8.14.5) with ESMTP id tAF2ZDN6080509; Sun, 15 Nov 2015 11:35:13 +0900 (JST) (envelope-from penguin-kernel@I-love.SAKURA.ne.jp) Received: from www262.sakura.ne.jp (202.181.97.72) by fsav109.sakura.ne.jp (F-Secure/fsigk_smtp/522/fsav109.sakura.ne.jp); Sun, 15 Nov 2015 11:35:13 +0900 (JST) X-Virus-Status: clean(F-Secure/fsigk_smtp/522/fsav109.sakura.ne.jp) Received: from AQUA (softbank126094077227.bbtec.net [126.94.77.227]) (authenticated bits=0) by www262.sakura.ne.jp (8.14.5/8.14.5) with ESMTP id tAF2ZDan080503; Sun, 15 Nov 2015 11:35:13 +0900 (JST) (envelope-from penguin-kernel@I-love.SAKURA.ne.jp) To: arekm@maven.pl Cc: htejun@gmail.com, cl@linux.com, mhocko@suse.com, linux-mm@kvack.org, xfs@oss.sgi.com Subject: Re: memory reclaim problems on fs usage From: Tetsuo Handa X-ASG-Orig-Subj: Re: memory reclaim problems on fs usage References: <201511102313.36685.arekm@maven.pl> <56449E44.7020407@I-love.SAKURA.ne.jp> <201511122228.26399.arekm@maven.pl> <201511142140.38245.arekm@maven.pl> In-Reply-To: <201511142140.38245.arekm@maven.pl> Message-Id: <201511151135.JGD81717.OFOOSMFJFQHVtL@I-love.SAKURA.ne.jp> X-Mailer: Winbiff [Version 2.51 PL2] X-Accept-Language: ja,en,zh Date: Sun, 15 Nov 2015 11:35:11 +0900 Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Barracuda-Connect: www262.sakura.ne.jp[202.181.97.72] X-Barracuda-Start-Time: 1447554925 X-Barracuda-Encrypted: DHE-RSA-CAMELLIA256-SHA X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24401 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header Arkadiusz Miskiewicz wrote: > > > vmstat_update() and submit_flushes() remained pending for about 110 > > > seconds. If xlog_cil_push_work() were spinning inside GFP_NOFS > > > allocation, it should be reported as MemAlloc: traces, but no such lines > > > are recorded. I don't know why xlog_cil_push_work() did not call > > > schedule() for so long. Anyway, applying > > > http://lkml.kernel.org/r/20151111160336.GD1432@dhcp22.suse.cz should > > > solve vmstat_update() part. > > > > To apply that patch on top of 4.1.13 I also had to apply patches listed > > below. > > > > So in summary appllied: > > http://sprunge.us/GYBb > > http://sprunge.us/XWUX > > http://sprunge.us/jZjV > > I've tried more to trigger "page allocation failure" with usual actions that > triggered it previously but couldn't reproduce. With these patches applied it > doesn't happen. > > Logs from my tests: > > http://ixion.pld-linux.org/~arekm/log-mm-3.txt.gz > http://ixion.pld-linux.org/~arekm/log-mm-4.txt.gz (with swap added) > Good. vmstat_update() and submit_flushes() are no longer pending for long. log-mm-4.txt:Nov 14 16:40:08 srv kernel: [167753.393960] pending: vmstat_shepherd, vmpressure_work_fn log-mm-4.txt:Nov 14 16:40:08 srv kernel: [167753.393984] pending: submit_flushes [md_mod] log-mm-4.txt:Nov 14 16:41:08 srv kernel: [167813.439405] pending: submit_flushes [md_mod] log-mm-4.txt:Nov 14 17:17:19 srv kernel: [169985.104806] pending: vmstat_shepherd I think that the vmstat statistics now have correct values. > But are these patches solving the problem or just hiding it? > Excuse me but I can't judge. If you are interested in monitoring how vmstat statistics are changing under stalled condition, you can try below patch. diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 35a46b4..3de3a14 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -2794,8 +2794,7 @@ static int kmallocwd(void *unused) rcu_read_unlock(); preempt_enable(); show_workqueue_state(); - if (dump_target_pid <= 0) - dump_target_pid = -pid; + show_mem(0); /* Wait until next timeout duration. */ schedule_timeout_interruptible(kmallocwd_timeout); if (memalloc_counter[index]) From arekm@maven.pl Sun Nov 15 05:29:35 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 E15817F3F for ; Sun, 15 Nov 2015 05:29:35 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id B6BF0304032 for ; Sun, 15 Nov 2015 03:29:32 -0800 (PST) X-ASG-Debug-ID: 1447586966-04bdf07f0a73900001-NocioJ Received: from mail-lf0-f46.google.com (mail-lf0-f46.google.com [209.85.215.46]) by cuda.sgi.com with ESMTP id Y6W9SFo87C4pgJlu (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Sun, 15 Nov 2015 03:29:27 -0800 (PST) X-Barracuda-Envelope-From: arekm@maven.pl X-Barracuda-Apparent-Source-IP: 209.85.215.46 Received: by lfdo63 with SMTP id o63so72978645lfd.2 for ; Sun, 15 Nov 2015 03:29:26 -0800 (PST) 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=TmwjvbOi58MtUxQmPuPJBbQavo8v1tk+jDGjy1IFAb4=; b=F1dr0ZpSZz7Lz6pyLg5+p71t46N4Bn1J1/kkuLI5U1NlWJ+Ar0r1iY4EjG5535xTt6 K3+khwjLyguAAJeU756uMKipasQHI2KrBevpHavYotuLE8G7SPifAUrxA1pAEimAqAo8 t8ow2jhrXOGzBNOSQYsj4LJaqjGGJTZekwDyM= 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=TmwjvbOi58MtUxQmPuPJBbQavo8v1tk+jDGjy1IFAb4=; b=D+2ueYCsLC4VCwXWrabvTPPRGNqXLl7pR9YQqa9AJfRT1vPSVtkhhAZgBkS67quOWG Y43Fw4lpW5+E8gssjOIStWV2L54gszzBzyMNoBhpSi+wLX+xOQP4Oocaoxq/eleV/vNu Y2fFniE7Ou8yT3I0mp68hBGiJZlVp2bbLhM6zWY9u91+vzdOw5tM0S4d5+RHshN98VKX zpRFAdNSFNT9APiO8shl6e1m1Ec9P/xK6a4WpOYVdw4Z8gQulg6yeEHRRBLjNLncU3wV LIRVW5yySQee6oHu0QNTjhPRLChusVHRCgpr54rFVLtJgMxgwqQmjmIIgeh6ZrHu1FXu 3Ctg== X-Gm-Message-State: ALoCoQklxyEBOgOwB3GujTJLL//a2js8ntekUKFnvcbCav4pyeuthngYoEjaCK6ySHqfbA4oQmQJ X-Received: by 10.25.35.194 with SMTP id j185mr14046876lfj.62.1447586965918; Sun, 15 Nov 2015 03:29:25 -0800 (PST) Received: from xps.localnet (85-222-71-204.dynamic.chello.pl. [85.222.71.204]) by smtp.gmail.com with ESMTPSA id u12sm4616380lbk.45.2015.11.15.03.29.23 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 15 Nov 2015 03:29:24 -0800 (PST) From: Arkadiusz =?utf-8?q?Mi=C5=9Bkiewicz?= To: Tetsuo Handa Subject: Re: memory reclaim problems on fs usage Date: Sun, 15 Nov 2015 12:29:23 +0100 X-ASG-Orig-Subj: Re: memory reclaim problems on fs usage User-Agent: KMail/1.13.7 (Linux/4.3.0; KDE/4.14.13; x86_64; ; ) Cc: htejun@gmail.com, cl@linux.com, mhocko@suse.com, linux-mm@kvack.org, xfs@oss.sgi.com References: <201511102313.36685.arekm@maven.pl> <201511142140.38245.arekm@maven.pl> <201511151135.JGD81717.OFOOSMFJFQHVtL@I-love.SAKURA.ne.jp> In-Reply-To: <201511151135.JGD81717.OFOOSMFJFQHVtL@I-love.SAKURA.ne.jp> MIME-Version: 1.0 Content-Type: Text/Plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <201511151229.23312.arekm@maven.pl> X-Barracuda-Connect: mail-lf0-f46.google.com[209.85.215.46] X-Barracuda-Start-Time: 1447586967 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24411 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 Sunday 15 of November 2015, Tetsuo Handa wrote: > Arkadiusz Miskiewicz wrote: > > > > vmstat_update() and submit_flushes() remained pending for about 110 > > > > seconds. If xlog_cil_push_work() were spinning inside GFP_NOFS > > > > allocation, it should be reported as MemAlloc: traces, but no such > > > > lines are recorded. I don't know why xlog_cil_push_work() did not > > > > call schedule() for so long. Anyway, applying > > > > http://lkml.kernel.org/r/20151111160336.GD1432@dhcp22.suse.cz should > > > > solve vmstat_update() part. > > >=20 > > > To apply that patch on top of 4.1.13 I also had to apply patches list= ed > > > below. > > >=20 > > > So in summary appllied: > > > http://sprunge.us/GYBb > > > http://sprunge.us/XWUX > > > http://sprunge.us/jZjV > >=20 > > I've tried more to trigger "page allocation failure" with usual actions > > that triggered it previously but couldn't reproduce. With these patches > > applied it doesn't happen. > >=20 > > Logs from my tests: > >=20 > > http://ixion.pld-linux.org/~arekm/log-mm-3.txt.gz > > http://ixion.pld-linux.org/~arekm/log-mm-4.txt.gz (with swap added) >=20 > Good. >=20 > vmstat_update() and submit_flushes() are no longer pending for long. >=20 > log-mm-4.txt:Nov 14 16:40:08 srv kernel: [167753.393960] pending: > vmstat_shepherd, vmpressure_work_fn log-mm-4.txt:Nov 14 16:40:08 srv > kernel: [167753.393984] pending: submit_flushes [md_mod] > log-mm-4.txt:Nov 14 16:41:08 srv kernel: [167813.439405] pending: > submit_flushes [md_mod] log-mm-4.txt:Nov 14 17:17:19 srv kernel: > [169985.104806] pending: vmstat_shepherd >=20 > I think that the vmstat statistics now have correct values. >=20 > > But are these patches solving the problem or just hiding it? >=20 > Excuse me but I can't judge. > > If you are interested in monitoring how vmstat statistics are changing > under stalled condition, you can try below patch. Here is log with this and all previous patches applied: http://ixion.pld-linux.org/~arekm/log-mm-5.txt.gz >=20 > diff --git a/mm/page_alloc.c b/mm/page_alloc.c > index 35a46b4..3de3a14 100644 > --- a/mm/page_alloc.c > +++ b/mm/page_alloc.c > @@ -2794,8 +2794,7 @@ static int kmallocwd(void *unused) > rcu_read_unlock(); > preempt_enable(); > show_workqueue_state(); > - if (dump_target_pid <=3D 0) > - dump_target_pid =3D -pid; > + show_mem(0); > /* Wait until next timeout duration. */ > schedule_timeout_interruptible(kmallocwd_timeout); > if (memalloc_counter[index]) =2D-=20 Arkadiusz Mi=C5=9Bkiewicz, arekm / ( maven.pl | pld-linux.org ) From avi@cloudius-systems.com Sun Nov 15 07:08:24 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 B094B7F50 for ; Sun, 15 Nov 2015 07:08:24 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 9F309304032 for ; Sun, 15 Nov 2015 05:08:21 -0800 (PST) X-ASG-Debug-ID: 1447592895-04cbb0605c8b0b0001-NocioJ Received: from mail-wm0-f53.google.com (mail-wm0-f53.google.com [74.125.82.53]) by cuda.sgi.com with ESMTP id ylMFD4LQE8sLohFD (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Sun, 15 Nov 2015 05:08:15 -0800 (PST) X-Barracuda-Envelope-From: avi@cloudius-systems.com X-Barracuda-Apparent-Source-IP: 74.125.82.53 Received: by wmww144 with SMTP id w144so85885721wmw.0 for ; Sun, 15 Nov 2015 05:08:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=scylladb_com.20150623.gappssmtp.com; s=20150623; h=to:from:subject:message-id:date:user-agent:mime-version :content-type; bh=Ai7YHoJDrtDYJ9DjnkcOuLGXhYLTPX/BT/L4XJAfTLE=; b=d7UGSJypmE7Axqeqmyep1f6z0ekhxLxSw0jr8VgEZGg5PFi+r5hOYURQ5oSoXO/0V3 lJu+UUl709UCAFjswJJKxS+++nBAQj63ZIUPVu2/qzG2DQ82DYgtss/7sYEkAEd7Pzhf OpXReR51r1xRsZs5pNYUiXBUPJ/iGBHI8IjhXunzy2GgvoATCL08CEVAy99+2xd8JxOq VPedhjduPz8ziLYXEoTt8VOHktqHpVT4SSPNA7Nf1sHyP39EX/DwLl8viBErE2YGT/xG yUEPsjor3Y/bQh5nteFGTycxVrEJj/un8WD+sNYCiqjASw9UabFik19ftyHCGaxXSdql 28lg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:to:from:subject:message-id:date:user-agent :mime-version:content-type; bh=Ai7YHoJDrtDYJ9DjnkcOuLGXhYLTPX/BT/L4XJAfTLE=; b=muvV+PECAG8SxyOz3sfia+RsvJJUArpJ91OT6AZ5LYQ2dUr7rB5QfRP1XtqsEYvJ3n 3127joIGqAukbdGbOCqsSgsTMe89jLBkRky+td5GwGxgiGcdP0OkByxdVfzQurnyH30R BJlW1NnKRlrTgIRaxeUvqV4/ppyu5hX6s9p3htbePdvfK+NXm+CMe894fnIhCqk6r3Hn laAUit5AwsNYgSOe7/cAJsh/dhdQWcHjfQ9G2fFrzAJeASqXSMW1DzS838xTO2qdEcVs LqQW/H1mQnifE7A/VgZwQTNFAzgydgdCfPKF7Sbrn83EpJ3+E3dLHELrx38F/Z+TpiHL Ud8g== X-Gm-Message-State: ALoCoQk7KPqia99xRMeoYN9CECe8MhLn/QI6w7Cy/Wbg8ti9HN1LWkWrfeQ6LHbm0Uz2MVuPLynO X-Received: by 10.194.192.106 with SMTP id hf10mr32093743wjc.131.1447592894975; Sun, 15 Nov 2015 05:08:14 -0800 (PST) Received: from avi.cloudius-systems.com ([37.142.229.250]) by smtp.googlemail.com with ESMTPSA id w4sm29340364wje.49.2015.11.15.05.08.14 (version=TLSv1/SSLv3 cipher=OTHER); Sun, 15 Nov 2015 05:08:14 -0800 (PST) To: xfs@oss.sgi.com, linux-aio@kvack.org From: Avi Kivity Subject: AIO read returns negative number for bytes read Message-ID: <564883BD.8070607@scylladb.com> X-ASG-Orig-Subj: AIO read returns negative number for bytes read Date: Sun, 15 Nov 2015 15:08:13 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="------------000802080702020200030301" X-Barracuda-Connect: mail-wm0-f53.google.com[74.125.82.53] X-Barracuda-Start-Time: 1447592895 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24412 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 is a multi-part message in MIME format. --------------000802080702020200030301 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit Due to a bug in my program, I initiated a read beyond eof. Specifically, the file size is 13002 bytes and the read offset is 13312 (0x3400). I would expect such a read to return 0 bytes read, but io_getevents returns -310, which is suspiciously equal to (13002 - 13312). I attach a reproducer. 4.2.5-201.fc22.x86_64 Are my expectations incorrect, or is this a bug in aio or xfs? --------------000802080702020200030301 Content-Type: text/plain; charset=UTF-8; name="aio_read_fails.c" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="aio_read_fails.c" I2RlZmluZSBfR05VX1NPVVJDRQoKI2luY2x1ZGUgPGxpYmFpby5oPgojaW5jbHVkZSA8YXNz ZXJ0Lmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaW5j bHVkZSA8dW5pc3RkLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3lzL3N0YXQu aD4KI2luY2x1ZGUgPGZjbnRsLmg+CgppbnQgbWFpbihpbnQgYWMsIGNoYXIqKiBhdikgewog IGludCBmZDsKICBjaGFyKiBidWY7CiAgaW9fY29udGV4dF90IGlvYyA9IE5VTEw7CiAgaW50 IHI7CiAgc3RydWN0IGlvY2IgaW9jYjsKICBzdHJ1Y3QgaW9jYiAqaW9jYnBbMV07CiAgc3Ry dWN0IGlvX2V2ZW50IGlvZXY7CgogIGJ1ZiA9IGFsaWduZWRfYWxsb2MoNDA5NiwgNDA5Nio0 KTsKICBhc3NlcnQoYnVmKTsKICByID0gaW9fc2V0dXAoMSwgJmlvYyk7CiAgYXNzZXJ0KHIg PT0gMCk7CiAgZmQgPSBvcGVuKCJ0bXAudG1wIiwgT19SRFdSIHwgT19DUkVBVCB8IE9fRElS RUNULCAwNjAwKTsKICBhc3NlcnQoZmQgPj0gMCk7CiAgaW9fcHJlcF9wd3JpdGUoJmlvY2Is IGZkLCBidWYsIDQwOTYqNCwgMCk7CiAgaW9jYnBbMF0gPSAmaW9jYjsKICByID0gaW9fc3Vi bWl0KGlvYywgMSwgaW9jYnApOwogIGFzc2VydChyID09IDEpOwogIHIgPSBpb19nZXRldmVu dHMoaW9jLCAxLCAxLCAmaW9ldiwgTlVMTCk7CiAgYXNzZXJ0KHIgPT0gMSk7CiAgYXNzZXJ0 KGlvZXYucmVzID09IDQqNDA5Nik7CiAgZnRydW5jYXRlKGZkLCAxMzAwMik7CiAgaW9fcHJl cF9wcmVhZCgmaW9jYiwgZmQsIGJ1ZiwgODE5MiwgMTMzMTIpOwogIHIgPSBpb19zdWJtaXQo aW9jLCAxLCBpb2NicCk7CiAgYXNzZXJ0KHIgPT0gMSk7CiAgciA9IGlvX2dldGV2ZW50cyhp b2MsIDEsIDEsICZpb2V2LCBOVUxMKTsKICBhc3NlcnQociA9PSAxKTsKICBwcmludGYoInJl YWQgcmVzdWx0OiAlZFxuIiwgKGludClpb2V2LnJlcyk7CiAgcmV0dXJuIDA7Cn0K --------------000802080702020200030301-- From penguin-kernel@I-love.SAKURA.ne.jp Sun Nov 15 08:13:52 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 E67F07CBF for ; Sun, 15 Nov 2015 08:13:51 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 7AAFEAC001 for ; Sun, 15 Nov 2015 06:13:48 -0800 (PST) X-ASG-Debug-ID: 1447596819-04cb6c0cd36fcc0001-NocioJ Received: from www262.sakura.ne.jp (www262.sakura.ne.jp [202.181.97.72]) by cuda.sgi.com with ESMTP id NzEn55sSUl5qJsvt (version=TLSv1 cipher=DHE-RSA-CAMELLIA256-SHA bits=256 verify=NO) for ; Sun, 15 Nov 2015 06:13:40 -0800 (PST) X-Barracuda-Envelope-From: penguin-kernel@I-love.SAKURA.ne.jp X-Barracuda-Apparent-Source-IP: 202.181.97.72 Received: from fsav108.sakura.ne.jp (fsav108.sakura.ne.jp [27.133.134.235]) by www262.sakura.ne.jp (8.14.5/8.14.5) with ESMTP id tAFEDSAC006312; Sun, 15 Nov 2015 23:13:28 +0900 (JST) (envelope-from penguin-kernel@I-love.SAKURA.ne.jp) Received: from www262.sakura.ne.jp (202.181.97.72) by fsav108.sakura.ne.jp (F-Secure/fsigk_smtp/522/fsav108.sakura.ne.jp); Sun, 15 Nov 2015 23:13:28 +0900 (JST) X-Virus-Status: clean(F-Secure/fsigk_smtp/522/fsav108.sakura.ne.jp) Received: from AQUA (softbank126094077227.bbtec.net [126.94.77.227]) (authenticated bits=0) by www262.sakura.ne.jp (8.14.5/8.14.5) with ESMTP id tAFEDSl0006309; Sun, 15 Nov 2015 23:13:28 +0900 (JST) (envelope-from penguin-kernel@I-love.SAKURA.ne.jp) To: arekm@maven.pl Cc: htejun@gmail.com, cl@linux.com, mhocko@suse.com, linux-mm@kvack.org, xfs@oss.sgi.com Subject: Re: memory reclaim problems on fs usage From: Tetsuo Handa X-ASG-Orig-Subj: Re: memory reclaim problems on fs usage References: <201511102313.36685.arekm@maven.pl> <201511142140.38245.arekm@maven.pl> <201511151135.JGD81717.OFOOSMFJFQHVtL@I-love.SAKURA.ne.jp> <201511151229.23312.arekm@maven.pl> In-Reply-To: <201511151229.23312.arekm@maven.pl> Message-Id: <201511152313.IJI23764.OHVFJFMSFOtOLQ@I-love.SAKURA.ne.jp> X-Mailer: Winbiff [Version 2.51 PL2] X-Accept-Language: ja,en,zh Date: Sun, 15 Nov 2015 23:13:23 +0900 Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Barracuda-Connect: www262.sakura.ne.jp[202.181.97.72] X-Barracuda-Start-Time: 1447596820 X-Barracuda-Encrypted: DHE-RSA-CAMELLIA256-SHA X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24413 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header Arkadiusz Miskiewicz wrote: > On Sunday 15 of November 2015, Tetsuo Handa wrote: > > I think that the vmstat statistics now have correct values. > > > > > But are these patches solving the problem or just hiding it? > > > > Excuse me but I can't judge. > > > > If you are interested in monitoring how vmstat statistics are changing > > under stalled condition, you can try below patch. > > > Here is log with this and all previous patches applied: > http://ixion.pld-linux.org/~arekm/log-mm-5.txt.gz Regarding "Node 0 Normal" (min:7104kB low:8880kB high:10656kB), all free: values look sane to me. I think that your problem was solved. $ grep "Normal free:" log-mm-5.txt | cut -b 44- | awk -F' ' ' { print $4 } ' | cut -b 6- | sort -g 8608kB 8636kB 8920kB 8920kB 8952kB 8968kB 8980kB (...snipped...) 215364kB 290068kB 290428kB 291176kB 292836kB 303992kB 306468kB 318080kB 319548kB $ grep "Normal free:" log-mm-1.txt | cut -b 44- | awk -F' ' ' { print $4 } ' | cut -b 6- | sort -g 0kB 40kB 128kB 128kB 128kB 128kB 128kB 128kB 128kB 128kB (...snipped...) 412kB 616kB 1268kB 1544kB 1696kB 2756kB 2756kB 2756kB 2756kB 2756kB 2756kB 2756kB From arekm@maven.pl Sun Nov 15 08:49:43 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 420A97CBF for ; Sun, 15 Nov 2015 08:49:43 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 022B6304039 for ; Sun, 15 Nov 2015 06:49:42 -0800 (PST) X-ASG-Debug-ID: 1447598977-04bdf07f0776820001-NocioJ Received: from mail-lf0-f47.google.com (mail-lf0-f47.google.com [209.85.215.47]) by cuda.sgi.com with ESMTP id 8nf6qtjI3ZjnCMEE (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Sun, 15 Nov 2015 06:49:39 -0800 (PST) X-Barracuda-Envelope-From: arekm@maven.pl X-Barracuda-Apparent-Source-IP: 209.85.215.47 Received: by lfaz4 with SMTP id z4so10822254lfa.0 for ; Sun, 15 Nov 2015 06:49:37 -0800 (PST) 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=IZD3/5shqAuZk6GUyR7LyXlbbQQwII3CxisVq5SdOAU=; b=R74C/vrcZALiZdL1fpwGLJxcceo6G1evlKPdUsw9v7gvi628dtWizsTNhBz2ayMo2R kuVBw31wwDloSbm1+eJTFxN8nfx8LXwKyZ8ATxS03sqoZAkVydP/B07/44IhujFWOqYZ ZFu04SliIzkO6Lv8pAdd4kB0TgWKGErifxBdQ= 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=IZD3/5shqAuZk6GUyR7LyXlbbQQwII3CxisVq5SdOAU=; b=BQK4hMjyaeyGH3zb60kuV0Mi8H4NUfwUpwNXfYXsw/09d1lxkdXHGBMvx4WLYEvCho dhtgMvfW2MCpVQ9RwNE9u6JInd9IpRfHlpeQP7TTmG01YW9Yma8/lxqDMftMYCCD9ZTs pXnBEO0LsPDfNVAYpZU/jIP0Q3z9gQTSpjj18hsukpe9NvTXW6VtWGKtIwtZBvsH4sKq ykLLRVsDApVfAlmZELMj/zPQlvdMLC4G3d11T8lby7zsAyH3+ccfoDiciekkw+/Tdm+O /MouIqlcmNRIsKEDSrlDLukn5kU1/6n9piCl7AdluTiVWCh/e0h+TFzs5I7ZIvoF0FD4 0raw== X-Gm-Message-State: ALoCoQmneB8ICVdkDfZMCJzmEA7LwMmNGR4WU6s2sjCS8erEN1/A/dUFnK+bv+pyO5P0TdNPPdU2 X-Received: by 10.25.163.131 with SMTP id m125mr14941827lfe.0.1447598977197; Sun, 15 Nov 2015 06:49:37 -0800 (PST) Received: from xps.localnet (85-222-71-204.dynamic.chello.pl. [85.222.71.204]) by smtp.gmail.com with ESMTPSA id kf8sm4728826lbc.46.2015.11.15.06.49.35 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 15 Nov 2015 06:49:36 -0800 (PST) From: Arkadiusz =?utf-8?q?Mi=C5=9Bkiewicz?= To: Tetsuo Handa Subject: Re: memory reclaim problems on fs usage Date: Sun, 15 Nov 2015 15:49:35 +0100 X-ASG-Orig-Subj: Re: memory reclaim problems on fs usage User-Agent: KMail/1.13.7 (Linux/4.3.0; KDE/4.14.13; x86_64; ; ) Cc: htejun@gmail.com, cl@linux.com, mhocko@suse.com, linux-mm@kvack.org, xfs@oss.sgi.com References: <201511102313.36685.arekm@maven.pl> <201511151229.23312.arekm@maven.pl> <201511152313.IJI23764.OHVFJFMSFOtOLQ@I-love.SAKURA.ne.jp> In-Reply-To: <201511152313.IJI23764.OHVFJFMSFOtOLQ@I-love.SAKURA.ne.jp> MIME-Version: 1.0 Content-Type: Text/Plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <201511151549.35299.arekm@maven.pl> X-Barracuda-Connect: mail-lf0-f47.google.com[209.85.215.47] X-Barracuda-Start-Time: 1447598978 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24414 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 Sunday 15 of November 2015, Tetsuo Handa wrote: > Arkadiusz Miskiewicz wrote: > > On Sunday 15 of November 2015, Tetsuo Handa wrote: > > > I think that the vmstat statistics now have correct values. > > >=20 > > > > But are these patches solving the problem or just hiding it? > > >=20 > > > Excuse me but I can't judge. > > >=20 > > > If you are interested in monitoring how vmstat statistics are changing > > > under stalled condition, you can try below patch. > >=20 > > Here is log with this and all previous patches applied: > > http://ixion.pld-linux.org/~arekm/log-mm-5.txt.gz >=20 > Regarding "Node 0 Normal" (min:7104kB low:8880kB high:10656kB), > all free: values look sane to me. I think that your problem was solved. Great, thanks! Will all (or part) of these patches http://sprunge.us/GYBb http://sprunge.us/XWUX (after it gets merged) be pushed to stable@ or are too risky for stable ? >=20 > $ grep "Normal free:" log-mm-5.txt | cut -b 44- | awk -F' ' ' { print $4 } > ' | cut -b 6- | sort -g 8608kB > 8636kB > 8920kB > 8920kB > 8952kB > 8968kB > 8980kB > (...snipped...) > 215364kB > 290068kB > 290428kB > 291176kB > 292836kB > 303992kB > 306468kB > 318080kB > 319548kB >=20 > $ grep "Normal free:" log-mm-1.txt | cut -b 44- | awk -F' ' ' { print $4 } > ' | cut -b 6- | sort -g 0kB > 40kB > 128kB > 128kB > 128kB > 128kB > 128kB > 128kB > 128kB > 128kB > (...snipped...) > 412kB > 616kB > 1268kB > 1544kB > 1696kB > 2756kB > 2756kB > 2756kB > 2756kB > 2756kB > 2756kB > 2756kB =2D-=20 Arkadiusz Mi=C5=9Bkiewicz, arekm / ( maven.pl | pld-linux.org ) From hdo_@etu.univ-valenciennes.fr Sun Nov 15 16:00:18 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 00D1D7F50 for ; Sun, 15 Nov 2015 16:00:18 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 840C7AC001 for ; Sun, 15 Nov 2015 14:00:14 -0800 (PST) X-ASG-Debug-ID: 1447624812-04cbb0605b95f60001-NocioJ Received: from titan.univ-valenciennes.fr (titan.univ-valenciennes.fr [193.50.192.38]) by cuda.sgi.com with ESMTP id Ra42jxcyAvFHVMrC for ; Sun, 15 Nov 2015 14:00:12 -0800 (PST) X-Barracuda-Envelope-From: hdo_@etu.univ-valenciennes.fr X-Barracuda-Apparent-Source-IP: 193.50.192.38 Received: from zestore1.univ-valenciennes.fr (zestore1.univ-valenciennes.fr [193.50.192.56]) by titan.univ-valenciennes.fr (Postfix) with ESMTP id C306A7843F3; Sun, 15 Nov 2015 22:59:19 +0100 (CET) Date: Sun, 15 Nov 2015 23:00:17 +0100 (CET) From: Hai Quan Do To: info@hute.com Message-ID: <924530609.385646.1447624817979.JavaMail.zimbra@etu.univ-valenciennes.fr> Subject: Mailbox Notice Message! MIME-Version: 1.0 X-ASG-Orig-Subj: Mailbox Notice Message! Content-Type: multipart/alternative; boundary="----=_Part_385645_1716176438.1447624817977" X-Mailer: Zimbra 8.0.9_GA_6191 (zclient/8.0.9_GA_6191) Thread-Topic: Mailbox Notice Message! Thread-Index: qhZ+WuhAbBtksO+MQrgD1YEvf+5gWA== X-UVHC-titan-MailScanner-ID: C306A7843F3.A42F7 X-UVHC-titan-MailScanner: Found to be clean X-UVHC-titan-MailScanner-From: hdo_@etu.univ-valenciennes.fr X-Barracuda-Connect: titan.univ-valenciennes.fr[193.50.192.38] X-Barracuda-Start-Time: 1447624812 X-Barracuda-URL: https://192.48.176.25:443/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=BSF_SC0_MISMATCH_TO, HTML_MESSAGE, THREAD_INDEX, THREAD_TOPIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24421 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.01 THREAD_INDEX thread-index: AcO7Y8iR61tzADqsRmmc5wNiFHEOig== 0.01 THREAD_TOPIC Thread-Topic: ...(Japanese Subject)... 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.00 HTML_MESSAGE BODY: HTML included in message ------=_Part_385645_1716176438.1447624817977 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit This is to inform you that we have added 103MB Web space to all our Machinery Zone e-mail servers, please use the Login Link below to confirm your account. * Failure to carry out the above as soon as possible could result in new incoming email being blocked click Here: http://homewebaccesspag.webeden.co.uk/ ------=_Part_385645_1716176438.1447624817977 Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: 7bit
 This is to inform you that we have added 103MB Web space to all our Machinery Zone e-mail servers, please use the Login Link below to confirm your account. * Failure to carry out the above as soon as possible could result in new incoming email being blocked click Here: http://homewebaccesspag.webeden.co.uk/
------=_Part_385645_1716176438.1447624817977-- From cmaiolino@redhat.com Mon Nov 16 02:43:35 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 185517F54 for ; Mon, 16 Nov 2015 02:43:35 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 05D338F8033 for ; Mon, 16 Nov 2015 00:43:34 -0800 (PST) X-ASG-Debug-ID: 1447663413-04cbb0605d9faa0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 5hYBjKjBv2MwuiTE (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 16 Nov 2015 00:43:34 -0800 (PST) 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 (Postfix) with ESMTPS id 0D8F48EFDA for ; Mon, 16 Nov 2015 08:43:33 +0000 (UTC) Received: from zion.usersys.redhat.com (dhcp-26-103.brq.redhat.com [10.34.26.103]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAG8hVmi008258 for ; Mon, 16 Nov 2015 03:43:32 -0500 From: Carlos Maiolino To: xfs@oss.sgi.com Subject: [PATCH 0/2] xfs_io: implement inode command Date: Mon, 16 Nov 2015 09:43:22 +0100 X-ASG-Orig-Subj: [PATCH 0/2] xfs_io: implement inode command Message-Id: <1447663404-7857-1-git-send-email-cmaiolino@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: 1447663413 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Implement xfs_io inode command, which can be used to retreive information about allocated inodes in a xfs filesystem. Carlos Maiolino (2): xfs_io: implement 'inode' command V4 xfs_io: inode command manpage V1 io/open.c | 151 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ man/man8/xfs_io.8 | 24 +++++++++ 2 files changed, 175 insertions(+) -- 2.4.3 From cmaiolino@redhat.com Mon Nov 16 02:43:39 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 D88B37F59 for ; Mon, 16 Nov 2015 02:43:39 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id BA1968F8035 for ; Mon, 16 Nov 2015 00:43:39 -0800 (PST) X-ASG-Debug-ID: 1447663414-04cb6c0cd47f150001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id OWDviytWGfvuNFZS (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 16 Nov 2015 00:43:35 -0800 (PST) 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 (Postfix) with ESMTPS id D4989C001264 for ; Mon, 16 Nov 2015 08:43:34 +0000 (UTC) Received: from zion.usersys.redhat.com (dhcp-26-103.brq.redhat.com [10.34.26.103]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAG8hVmj008258 for ; Mon, 16 Nov 2015 03:43:34 -0500 From: Carlos Maiolino To: xfs@oss.sgi.com Subject: [PATCH 1/2] xfs_io: implement 'inode' command V4 Date: Mon, 16 Nov 2015 09:43:23 +0100 X-ASG-Orig-Subj: [PATCH 1/2] xfs_io: implement 'inode' command V4 Message-Id: <1447663404-7857-2-git-send-email-cmaiolino@redhat.com> In-Reply-To: <1447663404-7857-1-git-send-email-cmaiolino@redhat.com> References: <1447663404-7857-1-git-send-email-cmaiolino@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: 1447663415 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Implements a new xfs_io command, named 'inode', which is supposed to be used to query information about inode's existence and its physical size in the filesystem. Currently supporting three arguments: -s -- return physical size of the largest inode -l -- return the largest inode number allocated and used -n [num] -- Return the next existing inode after [num], even if [num] is not allocated/used [num] -- Return if the inode exists or not. I didn't send the man page patch because I'm sure I'll get some points to improve, and I'll write the manpage for the next revision. - Changelog V3: - Merge all 3 patches from the V2 together in a single patch - Rework of '-n [num]' and 'num' only arguments algorithm - Argument -n now relies on bulkreq.count to check for next inodes, not on bstat.bs_ino anymore. - for loop in ret_lsize or ret_largest case, now relies on count being 0 to break the loop V4: - Refactor inode_f function to reduce its size and easier logic - Implement error handlers for invalid command combination (hopefully all invalid combinations). - use a single xfs_inogrp array for keep track of inodes - Fix missing newline in inode_help() - Rewrite help message in inode_help() - Fix indentation Signed-off-by: Carlos Maiolino --- io/open.c | 151 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) diff --git a/io/open.c b/io/open.c index ac5a5e0..2fc8aab 100644 --- a/io/open.c +++ b/io/open.c @@ -20,6 +20,7 @@ #include "input.h" #include "init.h" #include "io.h" +#include "libxfs.h" #ifndef __O_TMPFILE #if defined __alpha__ @@ -44,6 +45,7 @@ static cmdinfo_t statfs_cmd; static cmdinfo_t chproj_cmd; static cmdinfo_t lsproj_cmd; static cmdinfo_t extsize_cmd; +static cmdinfo_t inode_cmd; static prid_t prid; static long extsize; @@ -750,6 +752,144 @@ statfs_f( return 0; } +static void +inode_help(void) +{ + printf(_( +"\n" +"Query physical information about the inode" +"\n" +" -l -- Returns the largest inode number in the filesystem\n" +" -s -- Returns the physical size (in bits) of the\n" +" largest inode number in the filesystem\n" +" -n -- Return the next valid inode after [num]\n" +"[num] Check if the inode [num] is in use\n" +"\n")); +} + +static int +inode_f( + int argc, + char **argv) +{ + __s32 count = 0; + __s32 lastgrp = 0; + __u64 last = 0; + __u64 lastino = 0; + __u64 userino = 0; + char *p; + int c; + int ret_lsize = 0; + int ret_largest = 0; + int ret_next = 0; + int cmd = 0; + struct xfs_inogrp igroup[1024], igrp_rec; + struct xfs_fsop_bulkreq bulkreq; + struct xfs_bstat bstat; + + + while ((c = getopt(argc, argv, "sln")) != EOF) { + switch (c) { + case 's': + ret_lsize = 1; + break; + case 'l': + ret_largest = 1; + break; + case 'n': + ret_next = 1; + break; + default: + return command_usage(&inode_cmd); + } + } + + if (optind < argc) { + if (ret_lsize || ret_largest) + return command_usage(&inode_cmd); + + if (ret_next) { + if (argc > 3) + return command_usage(&inode_cmd); + else + cmd = XFS_IOC_FSBULKSTAT; + } else { + if (argc > 2) + return command_usage(&inode_cmd); + else + cmd = XFS_IOC_FSBULKSTAT_SINGLE; + } + + + userino = strtoull(argv[optind], &p, 10); + if ((*p != '\0')) { + printf(_("[num] must be a numeric value\n")); + exitcode = 1; + return 0; + } + + bulkreq.lastip = &userino; + bulkreq.icount = 1; + bulkreq.ubuffer = &bstat; + bulkreq.ocount = &count; + + if (xfsctl(file->name, file->fd, cmd, &bulkreq)) { + if (errno == EINVAL) + printf(_("Invalid or unlinked inode\n")); + else + perror("xfsctl"); + exitcode = 1; + return 0; + } + + if (ret_next) { + printf(_("Next inode: %llu\n"), bstat.bs_ino); + return 0; + } else { + printf(_("Valid inode: %llu\n"), bstat.bs_ino); + return 0; + } + } + + if (ret_lsize || ret_largest) { + + bulkreq.lastip = &last; + bulkreq.icount = 1024; /* User-defined maybe!? */ + bulkreq.ubuffer = &igroup; + bulkreq.ocount = &count; + + for (;;) { + + if (xfsctl(file->name, file->fd, XFS_IOC_FSINUMBERS, + &bulkreq)) { + perror("XFS_IOC_FSINUMBERS"); + exitcode = 1; + return 0; + } + + if (count == 0) + break; + + lastgrp = count; + } + + lastgrp--; + igrp_rec = igroup[lastgrp]; + lastino = igrp_rec.xi_startino + + xfs_highbit64(igrp_rec.xi_allocmask); + + if (ret_lsize) + printf (_("Largest inode size: %d\n"), + lastino > XFS_MAXINUMBER_32 ? 64 : 32); + else + printf(_("Largest inode: %llu\n"), lastino); + + return 0; + } + + return command_usage(&inode_cmd); +} + void open_init(void) { @@ -815,6 +955,16 @@ open_init(void) _("get/set preferred extent size (in bytes) for the open file"); extsize_cmd.help = extsize_help; + inode_cmd.name = "inode"; + inode_cmd.cfunc = inode_f; + inode_cmd.args = _("[-s | -l | -n] [num]"); + inode_cmd.argmin = 1; + inode_cmd.argmax = 2; + inode_cmd.flags = CMD_NOMAP_OK; + inode_cmd.oneline = + _("Query inode number usage in the filesystem"); + inode_cmd.help = inode_help; + add_command(&open_cmd); add_command(&stat_cmd); add_command(&close_cmd); @@ -822,4 +972,5 @@ open_init(void) add_command(&chproj_cmd); add_command(&lsproj_cmd); add_command(&extsize_cmd); + add_command(&inode_cmd); } -- 2.4.3 From cmaiolino@redhat.com Mon Nov 16 02:43:40 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 2953C7F5A for ; Mon, 16 Nov 2015 02:43:40 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 198548F8035 for ; Mon, 16 Nov 2015 00:43:40 -0800 (PST) X-ASG-Debug-ID: 1447663418-04cbb0605b9faa0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id LlzzcfyibMLBmW4a (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 16 Nov 2015 00:43:39 -0800 (PST) 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 (Postfix) with ESMTPS id CF157754 for ; Mon, 16 Nov 2015 08:43:38 +0000 (UTC) Received: from zion.usersys.redhat.com (dhcp-26-103.brq.redhat.com [10.34.26.103]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAG8hVmk008258 for ; Mon, 16 Nov 2015 03:43:38 -0500 From: Carlos Maiolino To: xfs@oss.sgi.com Subject: [PATCH 2/2] xfs_io: inode command manpage V1 Date: Mon, 16 Nov 2015 09:43:24 +0100 X-ASG-Orig-Subj: [PATCH 2/2] xfs_io: inode command manpage V1 Message-Id: <1447663404-7857-3-git-send-email-cmaiolino@redhat.com> In-Reply-To: <1447663404-7857-1-git-send-email-cmaiolino@redhat.com> References: <1447663404-7857-1-git-send-email-cmaiolino@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: 1447663419 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 This is the first try to update xfs_io manpage to include information about 'inode' command usage. Improvements and grammar corrections are welcome :-) Signed-off-by: Carlos Maiolino --- man/man8/xfs_io.8 | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/man/man8/xfs_io.8 b/man/man8/xfs_io.8 index 416206f..457f0eb 100644 --- a/man/man8/xfs_io.8 +++ b/man/man8/xfs_io.8 @@ -490,7 +490,31 @@ Recursively display all the specified segments starting at the specified .B \-s Display the starting lseek(2) offset. This offset will be a calculated value when both data and holes are displayed together or performing a recusively display. +.RE +.PD +.TP +.TP +.BI "inode \-s | \-l | \-n [num] | [num]" +Query physical inode information from a xfs filesystem. +.RS 1.0i +.PD 0 +.TP 0.4i +.B \-s +Display the physical size of the largest inode existing in the filesystem (32 or +64 bit). +.TP +.B -l +Display the largest allocated and used inode (inodes can be allocated in the +filesystem, but not used by any file). See +.B ikeep +xfs mount option). +.TP +.B -n [num] +Return the next existing inode after [num], even if [num] is not allocated in +the filesystem. .TP +.B [num] +Check if the inode [num] exists or not. .SH MEMORY MAPPED I/O COMMANDS .TP -- 2.4.3 From BATV+b7ea2846adb239a105d4+4467+infradead.org+hch@bombadil.srs.infradead.org Mon Nov 16 06:04:37 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 7F7E97CBF for ; Mon, 16 Nov 2015 06:04:37 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 6006030404E for ; Mon, 16 Nov 2015 04:04:34 -0800 (PST) X-ASG-Debug-ID: 1447675471-04cbb0605ba4330001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id JM7lIGFUKHce9SjX (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Mon, 16 Nov 2015 04:04:31 -0800 (PST) X-Barracuda-Envelope-From: BATV+b7ea2846adb239a105d4+4467+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 1ZyIWN-0005hm-32; Mon, 16 Nov 2015 12:04:31 +0000 Date: Mon, 16 Nov 2015 04:04:31 -0800 From: Christoph Hellwig To: darrick.wong@oracle.com, xfs@oss.sgi.com, linux-fsdevel@vger.kernel.org Subject: clone ioctl return values Message-ID: <20151116120431.GA2860@infradead.org> X-ASG-Orig-Subj: clone ioctl return values 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: 1447675471 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/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.24435 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 Hi Darrick, your new generic/157 xfs test brings up an interesting issue: error returns forthe various clone failure cases. It seems like this case was written fo the XFS case which differs a lot from the error chosen by btrfs and mostly followed by NFS. I'd say it might be a better idea to follow the btrfs example as the btrfs ioctls have been in use for a while. The only shortcoming I see in btrfs is that id doesn't explicitly check for non-directory, non-regular file items as the source. I have to admit I'm kinda surprised that it doesn't blow up, given that NFS instantly did when I removed those checks. FYI, output from the test on btrfs below: --- tests/generic/157.out 2015-11-14 07:56:31.000000000 +0000 +++ /root/xfstests/results//generic/157.out.bad 2015-11-16 11:58:52.879078894 +0000 @@ -2,24 +2,24 @@ Format and mount Create the original files Try cross-device reflink -XFS_IOC_CLONE_RANGE: Invalid cross-device link +reflink: Invalid cross-device link Try unaligned reflink -XFS_IOC_CLONE_RANGE: Invalid argument +reflink: Invalid argument Try overlapping reflink -XFS_IOC_CLONE_RANGE: Invalid argument +reflink: Invalid argument Try reflink past EOF -XFS_IOC_CLONE_RANGE: Invalid argument +reflink: Invalid argument Try to reflink a dir -XFS_IOC_CLONE_RANGE: Is a directory +reflink: Is a directory Try to reflink a device -XFS_IOC_CLONE_RANGE: Invalid argument +/mnt/test/test-157/dev1: No such device or address Try to reflink to a dir -/mnt/test-157/dir1: Is a directory +/mnt/test/test-157/dir1: Is a directory Try to reflink to a device -XFS_IOC_CLONE_RANGE: Operation not supported +/mnt/test/test-157/dev1: No such device or address Try to reflink to a fifo -XFS_IOC_CLONE_RANGE: Operation not supported +reflink: Inappropriate ioctl for device Try to reflink an append-only file -XFS_IOC_CLONE_RANGE: Bad file descriptor +reflink: Invalid argument Reflink two files Check scratch fs From jack@suse.cz Mon Nov 16 07:37:26 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 1BEF87CBF for ; Mon, 16 Nov 2015 07:37:26 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 8CCF1AC002 for ; Mon, 16 Nov 2015 05:37:22 -0800 (PST) X-ASG-Debug-ID: 1447681039-04cbb0605ea71b0001-NocioJ Received: from mx2.suse.de (mx2.suse.de [195.135.220.15]) by cuda.sgi.com with ESMTP id qAMjScVHg7XSaNpf (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NO) for ; Mon, 16 Nov 2015 05:37:20 -0800 (PST) X-Barracuda-Envelope-From: jack@suse.cz X-Barracuda-Apparent-Source-IP: 195.135.220.15 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 3F674AC0B; Mon, 16 Nov 2015 13:36:54 +0000 (UTC) Received: by quack.suse.cz (Postfix, from userid 1000) id F234882827; Mon, 16 Nov 2015 14:37:14 +0100 (CET) Date: Mon, 16 Nov 2015 14:37:14 +0100 From: Jan Kara To: Dan Williams Cc: Andreas Dilger , Ross Zwisler , "linux-kernel@vger.kernel.org" , "H. Peter Anvin" , "J. Bruce Fields" , Theodore Ts'o , Alexander Viro , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4 , linux-fsdevel , Linux MM , "linux-nvdimm@lists.01.org" , X86 ML , XFS Developers , Andrew Morton , Matthew Wilcox , Dave Hansen Subject: Re: [PATCH v2 03/11] pmem: enable REQ_FUA/REQ_FLUSH handling Message-ID: <20151116133714.GB3443@quack.suse.cz> X-ASG-Orig-Subj: Re: [PATCH v2 03/11] pmem: enable REQ_FUA/REQ_FLUSH handling References: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> <1447459610-14259-4-git-send-email-ross.zwisler@linux.intel.com> <22E0F870-C1FB-431E-BF6C-B395A09A2B0D@dilger.ca> 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: mx2.suse.de[195.135.220.15] X-Barracuda-Start-Time: 1447681039 X-Barracuda-Encrypted: ECDHE-RSA-AES256-SHA X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24436 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri 13-11-15 18:32:40, Dan Williams wrote: > On Fri, Nov 13, 2015 at 4:43 PM, Andreas Dilger wrote: > > On Nov 13, 2015, at 5:20 PM, Dan Williams wrote: > >> > >> On Fri, Nov 13, 2015 at 4:06 PM, Ross Zwisler > >> wrote: > >>> Currently the PMEM driver doesn't accept REQ_FLUSH or REQ_FUA bios. These > >>> are sent down via blkdev_issue_flush() in response to a fsync() or msync() > >>> and are used by filesystems to order their metadata, among other things. > >>> > >>> When we get an msync() or fsync() it is the responsibility of the DAX code > >>> to flush all dirty pages to media. The PMEM driver then just has issue a > >>> wmb_pmem() in response to the REQ_FLUSH to ensure that before we return all > >>> the flushed data has been durably stored on the media. > >>> > >>> Signed-off-by: Ross Zwisler > >> > >> Hmm, I'm not seeing why we need this patch. If the actual flushing of > >> the cache is done by the core why does the driver need support > >> REQ_FLUSH? Especially since it's just a couple instructions. REQ_FUA > >> only makes sense if individual writes can bypass the "drive" cache, > >> but no I/O submitted to the driver proper is ever cached we always > >> flush it through to media. > > > > If the upper level filesystem gets an error when submitting a flush > > request, then it assumes the underlying hardware is broken and cannot > > be as aggressive in IO submission, but instead has to wait for in-flight > > IO to complete. > > Upper level filesystems won't get errors when the driver does not > support flush. Those requests are ended cleanly in > generic_make_request_checks(). Yes, the fs still needs to wait for > outstanding I/O to complete but in the case of pmem all I/O is > synchronous. There's never anything to await when flushing at the > pmem driver level. > > > Since FUA/FLUSH is basically a no-op for pmem devices, > > it doesn't make sense _not_ to support this functionality. > > Seems to be a nop either way. Given that DAX may lead to dirty data > pending to the device in the cpu cache that a REQ_FLUSH request will > not touch, its better to leave it all to the mm core to handle. I.e. > it doesn't make sense to call the driver just for two instructions > (sfence + pcommit) when the mm core is taking on the cache flushing. > Either handle it all in the mm or the driver, not a mixture. So I think REQ_FLUSH requests *must* end up doing sfence + pcommit because e.g. journal writes going through block layer or writes done through dax_do_io() must be on permanent storage once REQ_FLUSH request finishes and the way driver does IO doesn't guarantee this, does it? Honza -- Jan Kara SUSE Labs, CR From jack@suse.cz Mon Nov 16 08:05:38 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 D8E377CBF for ; Mon, 16 Nov 2015 08:05:38 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id A52F1304039 for ; Mon, 16 Nov 2015 06:05:35 -0800 (PST) X-ASG-Debug-ID: 1447682728-04bdf07f078eb60001-NocioJ Received: from mx2.suse.de (mx2.suse.de [195.135.220.15]) by cuda.sgi.com with ESMTP id nlJXymgXlVYoS2n7 (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NO) for ; Mon, 16 Nov 2015 06:05:29 -0800 (PST) X-Barracuda-Envelope-From: jack@suse.cz X-Barracuda-Apparent-Source-IP: 195.135.220.15 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id A7BC3AAF4; Mon, 16 Nov 2015 14:05:04 +0000 (UTC) Received: by quack.suse.cz (Postfix, from userid 1000) id 3665182827; Mon, 16 Nov 2015 15:05:26 +0100 (CET) Date: Mon, 16 Nov 2015 15:05:26 +0100 From: Jan Kara To: Dan Williams Cc: Andreas Dilger , Ross Zwisler , "linux-kernel@vger.kernel.org" , "H. Peter Anvin" , "J. Bruce Fields" , Theodore Ts'o , Alexander Viro , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4 , linux-fsdevel , Linux MM , "linux-nvdimm@lists.01.org" , X86 ML , XFS Developers , Andrew Morton , Matthew Wilcox , Dave Hansen Subject: Re: [PATCH v2 03/11] pmem: enable REQ_FUA/REQ_FLUSH handling Message-ID: <20151116140526.GA6733@quack.suse.cz> X-ASG-Orig-Subj: Re: [PATCH v2 03/11] pmem: enable REQ_FUA/REQ_FLUSH handling References: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> <1447459610-14259-4-git-send-email-ross.zwisler@linux.intel.com> <22E0F870-C1FB-431E-BF6C-B395A09A2B0D@dilger.ca> <20151116133714.GB3443@quack.suse.cz> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151116133714.GB3443@quack.suse.cz> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: mx2.suse.de[195.135.220.15] X-Barracuda-Start-Time: 1447682729 X-Barracuda-Encrypted: ECDHE-RSA-AES256-SHA X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24437 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Mon 16-11-15 14:37:14, Jan Kara wrote: > On Fri 13-11-15 18:32:40, Dan Williams wrote: > > On Fri, Nov 13, 2015 at 4:43 PM, Andreas Dilger wrote: > > > On Nov 13, 2015, at 5:20 PM, Dan Williams wrote: > > >> > > >> On Fri, Nov 13, 2015 at 4:06 PM, Ross Zwisler > > >> wrote: > > >>> Currently the PMEM driver doesn't accept REQ_FLUSH or REQ_FUA bios. These > > >>> are sent down via blkdev_issue_flush() in response to a fsync() or msync() > > >>> and are used by filesystems to order their metadata, among other things. > > >>> > > >>> When we get an msync() or fsync() it is the responsibility of the DAX code > > >>> to flush all dirty pages to media. The PMEM driver then just has issue a > > >>> wmb_pmem() in response to the REQ_FLUSH to ensure that before we return all > > >>> the flushed data has been durably stored on the media. > > >>> > > >>> Signed-off-by: Ross Zwisler > > >> > > >> Hmm, I'm not seeing why we need this patch. If the actual flushing of > > >> the cache is done by the core why does the driver need support > > >> REQ_FLUSH? Especially since it's just a couple instructions. REQ_FUA > > >> only makes sense if individual writes can bypass the "drive" cache, > > >> but no I/O submitted to the driver proper is ever cached we always > > >> flush it through to media. > > > > > > If the upper level filesystem gets an error when submitting a flush > > > request, then it assumes the underlying hardware is broken and cannot > > > be as aggressive in IO submission, but instead has to wait for in-flight > > > IO to complete. > > > > Upper level filesystems won't get errors when the driver does not > > support flush. Those requests are ended cleanly in > > generic_make_request_checks(). Yes, the fs still needs to wait for > > outstanding I/O to complete but in the case of pmem all I/O is > > synchronous. There's never anything to await when flushing at the > > pmem driver level. > > > > > Since FUA/FLUSH is basically a no-op for pmem devices, > > > it doesn't make sense _not_ to support this functionality. > > > > Seems to be a nop either way. Given that DAX may lead to dirty data > > pending to the device in the cpu cache that a REQ_FLUSH request will > > not touch, its better to leave it all to the mm core to handle. I.e. > > it doesn't make sense to call the driver just for two instructions > > (sfence + pcommit) when the mm core is taking on the cache flushing. > > Either handle it all in the mm or the driver, not a mixture. > > So I think REQ_FLUSH requests *must* end up doing sfence + pcommit because > e.g. journal writes going through block layer or writes done through > dax_do_io() must be on permanent storage once REQ_FLUSH request finishes > and the way driver does IO doesn't guarantee this, does it? Hum, and looking into how dax_do_io() works and what drivers/nvdimm/pmem.c does, I'm indeed wrong because they both do wmb_pmem() after each write which seems to include sfence + pcommit. Sorry for confusion. But a question: Won't it be better to do sfence + pcommit only in response to REQ_FLUSH request and don't do it after each write? I'm not sure how expensive these instructions are but in theory it could be a performance win, couldn't it? For filesystems this is enough wrt persistency guarantees... Honza -- Jan Kara SUSE Labs, CR From jack@suse.cz Mon Nov 16 08:41:42 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 3ED1D7CBF for ; Mon, 16 Nov 2015 08:41:42 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 1836C30404E for ; Mon, 16 Nov 2015 06:41:41 -0800 (PST) X-ASG-Debug-ID: 1447684893-04bdf07f0990e10001-NocioJ Received: from mx2.suse.de (mx2.suse.de [195.135.220.15]) by cuda.sgi.com with ESMTP id pFDQmMhhGDmFZ4t9 (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NO) for ; Mon, 16 Nov 2015 06:41:34 -0800 (PST) X-Barracuda-Envelope-From: jack@suse.cz X-Barracuda-Apparent-Source-IP: 195.135.220.15 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 6375AAAF4; Mon, 16 Nov 2015 14:41:09 +0000 (UTC) Received: by quack.suse.cz (Postfix, from userid 1000) id 3196E82827; Mon, 16 Nov 2015 15:41:30 +0100 (CET) Date: Mon, 16 Nov 2015 15:41:30 +0100 From: Jan Kara To: Ross Zwisler Cc: linux-kernel@vger.kernel.org, "H. Peter Anvin" , "J. Bruce Fields" , Theodore Ts'o , Alexander Viro , Andreas Dilger , Dan Williams , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@lists.01.org, x86@kernel.org, xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox , Dave Hansen Subject: Re: [PATCH v2 00/11] DAX fsynx/msync support Message-ID: <20151116144130.GD3443@quack.suse.cz> X-ASG-Orig-Subj: Re: [PATCH v2 00/11] DAX fsynx/msync support References: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: mx2.suse.de[195.135.220.15] X-Barracuda-Start-Time: 1447684894 X-Barracuda-Encrypted: ECDHE-RSA-AES256-SHA X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24438 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri 13-11-15 17:06:39, Ross Zwisler wrote: > This patch series adds support for fsync/msync to DAX. > > Patches 1 through 7 add various utilities that the DAX code will eventually > need, and the DAX code itself is added by patch 8. Patches 9-11 update the > three filesystems that currently support DAX, ext2, ext4 and XFS, to use > the new DAX fsync/msync code. > > These patches build on the recent DAX locking changes from Dave Chinner, > Jan Kara and myself. Dave's changes for XFS and my changes for ext2 have > been merged in the v4.4 window, but Jan's are still unmerged. You can grab > them here: > > http://www.spinics.net/lists/linux-ext4/msg49951.html I had a quick look and the patches look sane to me. I'll try to give them more detailed look later this week. When thinking about the general design I was wondering: When we have this infrastructure to track data potentially lingering in CPU caches, would not it be a performance win to use standard cached stores in dax_io() and mark corresponding pages as dirty in page cache the same way as this patch set does it for mmaped writes? I have no idea how costly are non-temporal stores compared to cached ones and how would this compare to the cost of dirty tracking so this may be just completely bogus... Honza -- Jan Kara SUSE Labs, CR From bfoster@redhat.com Mon Nov 16 09:00:36 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 95A417CBF for ; Mon, 16 Nov 2015 09:00:36 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 62BD9304039 for ; Mon, 16 Nov 2015 07:00:36 -0800 (PST) X-ASG-Debug-ID: 1447686031-04bdf07f0a920f0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id FqYbfB3wvFroIeel (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 16 Nov 2015 07:00:31 -0800 (PST) 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 (Postfix) with ESMTPS id 4C284C00230B; Mon, 16 Nov 2015 15:00:31 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-36.bos.redhat.com [10.18.41.36]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAGF0UU5028053; Mon, 16 Nov 2015 10:00:31 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id DD79B120059; Mon, 16 Nov 2015 10:00:29 -0500 (EST) Date: Mon, 16 Nov 2015 10:00:29 -0500 From: Brian Foster To: Avi Kivity Cc: xfs@oss.sgi.com, linux-aio@kvack.org Subject: Re: AIO read returns negative number for bytes read Message-ID: <20151116150028.GA60592@bfoster.bfoster> X-ASG-Orig-Subj: Re: AIO read returns negative number for bytes read References: <564883BD.8070607@scylladb.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <564883BD.8070607@scylladb.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: 1447686031 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Sun, Nov 15, 2015 at 03:08:13PM +0200, Avi Kivity wrote: > Due to a bug in my program, I initiated a read beyond eof. Specifically, the > file size is 13002 bytes and the read offset is 13312 (0x3400). > > I would expect such a read to return 0 bytes read, but io_getevents returns > -310, which is suspiciously equal to (13002 - 13312). > > I attach a reproducer. > > 4.2.5-201.fc22.x86_64 > > Are my expectations incorrect, or is this a bug in aio or xfs? FWIW, I added some printk()'s and reproduced. This looks like a dio issue to me (a sync dio read reproduces just the same as aio). See the short read check in dio_complete(): ... /* Check for short read case */ if ((dio->rw == READ) && ((offset + transferred) > dio->i_size)) transferred = dio->i_size - offset; ... So if offset starts beyond i_size, we set transferred to a negative value. I suppose we could check for offset >= i_size here independently, but I'm not necessarily sure something earlier doesn't need to change (e.g., I see dio->result = 3072 in this case and I'm not familiar enough with core dio to know if that's expected). Brian > #define _GNU_SOURCE > > #include > #include > #include > #include > #include > #include > #include > #include > > int main(int ac, char** av) { > int fd; > char* buf; > io_context_t ioc = NULL; > int r; > struct iocb iocb; > struct iocb *iocbp[1]; > struct io_event ioev; > > buf = aligned_alloc(4096, 4096*4); > assert(buf); > r = io_setup(1, &ioc); > assert(r == 0); > fd = open("tmp.tmp", O_RDWR | O_CREAT | O_DIRECT, 0600); > assert(fd >= 0); > io_prep_pwrite(&iocb, fd, buf, 4096*4, 0); > iocbp[0] = &iocb; > r = io_submit(ioc, 1, iocbp); > assert(r == 1); > r = io_getevents(ioc, 1, 1, &ioev, NULL); > assert(r == 1); > assert(ioev.res == 4*4096); > ftruncate(fd, 13002); > io_prep_pread(&iocb, fd, buf, 8192, 13312); > r = io_submit(ioc, 1, iocbp); > assert(r == 1); > r = io_getevents(ioc, 1, 1, &ioev, NULL); > assert(r == 1); > printf("read result: %d\n", (int)ioev.res); > return 0; > } > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From haghdoost@gmail.com Mon Nov 16 09:20:20 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 45D207CBF for ; Mon, 16 Nov 2015 09:20:20 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id C16CAAC003 for ; Mon, 16 Nov 2015 07:20:16 -0800 (PST) X-ASG-Debug-ID: 1447687212-04cbb0605ead800001-NocioJ Received: from mail-yk0-f181.google.com (mail-yk0-f181.google.com [209.85.160.181]) by cuda.sgi.com with ESMTP id qjbfdaSBQSfCbZ3M (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Mon, 16 Nov 2015 07:20:12 -0800 (PST) X-Barracuda-Envelope-From: haghdoost@gmail.com X-Barracuda-Apparent-Source-IP: 209.85.160.181 Received: by ykba77 with SMTP id a77so242912572ykb.2 for ; Mon, 16 Nov 2015 07:20:12 -0800 (PST) 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=nrY630dydUxMRDsUIrv5K8j/impibjZLze19ma1J9jQ=; b=TfJiEni0g3ta6+uelCehLvHzmb4TlCFYqT6wJr3Q3ysY401c9G/zMDDsZENS/Vmuve CGJE5F5zE/9j6HR8FYcTilvOZ9wEKodUxnD5h6SOfF5TTzzZQJmlCFHnF37GN8Z6FjaQ nBMYoSnIIIvFV6ndR9oAvUjCc6RfetaGEaQGUh0OmgZHQbzQSyOyWoS+oVs9s7Tzb8hI 6sCMyb70mjv9EpiiTT4jOE2ng8MnHd4KNJpsc5CGAQ1Uobj3Szfp+5LZPh6RBREiZAzI aemtrf7U6GLVxUb0rXsUYbNNLo8V3X0wNAVj0jIhqyN52NExkMSfhmOpXLvBoR3b5gMk rbww== X-Received: by 10.129.136.5 with SMTP id y5mr38917757ywf.35.1447687211994; Mon, 16 Nov 2015 07:20:11 -0800 (PST) MIME-Version: 1.0 Received: by 10.31.106.65 with HTTP; Mon, 16 Nov 2015 07:19:32 -0800 (PST) In-Reply-To: <564883BD.8070607@scylladb.com> References: <564883BD.8070607@scylladb.com> From: Alireza Haghdoost Date: Mon, 16 Nov 2015 09:19:32 -0600 Message-ID: Subject: Re: AIO read returns negative number for bytes read To: Avi Kivity X-ASG-Orig-Subj: Re: AIO read returns negative number for bytes read Cc: xfs@oss.sgi.com, linux-aio@kvack.org Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-yk0-f181.google.com[209.85.160.181] X-Barracuda-Start-Time: 1447687212 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/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 Sun, Nov 15, 2015 at 7:08 AM, Avi Kivity wrote: > Due to a bug in my program, I initiated a read beyond eof. Specifically, the > file size is 13002 bytes and the read offset is 13312 (0x3400). > > I would expect such a read to return 0 bytes read, but io_getevents returns > -310, which is suspiciously equal to (13002 - 13312). > > I attach a reproducer. > > 4.2.5-201.fc22.x86_64 > > Are my expectations incorrect, or is this a bug in aio or xfs? I think it is not a bug. This post might be helpful: http://marc.info/?l=linux-aio&m=142315449930935&w=2 From avi@cloudius-systems.com Mon Nov 16 09:32:58 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 A61D27CBF for ; Mon, 16 Nov 2015 09:32:58 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 759CE8F8035 for ; Mon, 16 Nov 2015 07:32:58 -0800 (PST) X-ASG-Debug-ID: 1447687975-04cbb0605bae450001-NocioJ Received: from mail-wm0-f50.google.com (mail-wm0-f50.google.com [74.125.82.50]) by cuda.sgi.com with ESMTP id zO9jNkB9heJQsPvd (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Mon, 16 Nov 2015 07:32:56 -0800 (PST) X-Barracuda-Envelope-From: avi@cloudius-systems.com X-Barracuda-Apparent-Source-IP: 74.125.82.50 Received: by wmdw130 with SMTP id w130so116231514wmd.0 for ; Mon, 16 Nov 2015 07:32:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=scylladb_com.20150623.gappssmtp.com; s=20150623; h=subject:to:references:cc:from:message-id:date:user-agent :mime-version:in-reply-to:content-type:content-transfer-encoding; bh=7OXH7lNWoKJqVEFXxfLn/O9JBABznYSl4we1kyN8ktM=; b=xzsSMcpYy8ceZ63q7jvUXL7gNI80i0sYz+MDVECUOziKGKQNf0ESI5SBkZuaYzZSJG fTbmZJEApBcfQtQzH2B5T3VKiVQWXbhx/M8i1tpP9ALOOokg30B5/SljXz3dQBPOukHI UTczVZHDAXhV1HkjC0hbClgGti0KD9A9INy70y0iidGmHAhUhp2wvHcvCUE74BdOXDaf OgyLlsSwuWg/CnzM/OOuQsBXIj9MSi1P7oykgunWFy+mBK6HO4a0n0wV9mVl+Xb4f3R2 grMDD5hI877PS7rFB+BuMDOmwPJbxnsdVsHhVYTpvEbPus7k1tJTViempXbZf0DKY2qZ uWsA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:subject:to:references:cc:from:message-id:date :user-agent:mime-version:in-reply-to:content-type :content-transfer-encoding; bh=7OXH7lNWoKJqVEFXxfLn/O9JBABznYSl4we1kyN8ktM=; b=kojPNwmXb7OcfTuTozABSstTtshDlLcFypY4fSMNQbh5QJM5TPCzDRjwd7bDPmk0B1 0GU6dBOmj1FYx8OZDf+X9FZisHRpiqyW3c/+lyMenUsnRhZhdhQ9Bd4AKsUfkeKBPwt6 DC2u3GEwI5dcv8oEETaHpt1p4p4NxVf9tLSSDXocTUV63jrNZP+0RPwvinIki+f8KKFR 1nG+FyKrOnEniOab0c4st7cx9nVjxqSgqlAZ4ZmrpqGPXCO5OKvq/xy9nRFBEoYlIrW/ rkc/QpPPp7CUzLl0jXRpvomTn8MZsek6USgFdKd94akO/IFY+yUkUUxRKW6+rIWhWg8h 2akg== X-Gm-Message-State: ALoCoQkJ1x7xb2J8ggKMLhvHNpsXOT3tEqvhvnm1er/mGgAO/mfznMShvadXRyMSqjlr3gDReuXO X-Received: by 10.28.24.5 with SMTP id 5mr10072883wmy.3.1447687975345; Mon, 16 Nov 2015 07:32:55 -0800 (PST) Received: from avi.cloudius-systems.com ([37.142.229.250]) by smtp.googlemail.com with ESMTPSA id m11sm19128772wma.5.2015.11.16.07.32.54 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 16 Nov 2015 07:32:54 -0800 (PST) Subject: Re: AIO read returns negative number for bytes read To: Alireza Haghdoost X-ASG-Orig-Subj: Re: AIO read returns negative number for bytes read References: <564883BD.8070607@scylladb.com> Cc: xfs@oss.sgi.com, linux-aio@kvack.org From: Avi Kivity Message-ID: <5649F725.6080508@scylladb.com> Date: Mon, 16 Nov 2015 17:32:53 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mail-wm0-f50.google.com[74.125.82.50] X-Barracuda-Start-Time: 1447687976 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/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 11/16/2015 05:19 PM, Alireza Haghdoost wrote: > On Sun, Nov 15, 2015 at 7:08 AM, Avi Kivity wrote: >> Due to a bug in my program, I initiated a read beyond eof. Specifically, the >> file size is 13002 bytes and the read offset is 13312 (0x3400). >> >> I would expect such a read to return 0 bytes read, but io_getevents returns >> -310, which is suspiciously equal to (13002 - 13312). >> >> I attach a reproducer. >> >> 4.2.5-201.fc22.x86_64 >> >> Are my expectations incorrect, or is this a bug in aio or xfs? > I think it is not a bug. This post might be helpful: > http://marc.info/?l=linux-aio&m=142315449930935&w=2 The post indicates that it is a bug. A negative value indicates an error, but there is no error 310. From mhocko@suse.cz Mon Nov 16 10:15:29 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 98D957CBF for ; Mon, 16 Nov 2015 10:15:29 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 8869D8F8049 for ; Mon, 16 Nov 2015 08:15:26 -0800 (PST) X-ASG-Debug-ID: 1447690519-04cbb0605db0ba0001-NocioJ Received: from mx2.suse.de (mx2.suse.de [195.135.220.15]) by cuda.sgi.com with ESMTP id NpucZho2Y2ANAIUS (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NO) for ; Mon, 16 Nov 2015 08:15:20 -0800 (PST) X-Barracuda-Envelope-From: mhocko@suse.cz X-Barracuda-Apparent-Source-IP: 195.135.220.15 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 3F209AABB; Mon, 16 Nov 2015 16:14:56 +0000 (UTC) Date: Mon, 16 Nov 2015 17:15:18 +0100 From: Michal Hocko To: Arkadiusz =?utf-8?Q?Mi=C5=9Bkiewicz?= Cc: Tetsuo Handa , htejun@gmail.com, cl@linux.com, linux-mm@kvack.org, xfs@oss.sgi.com Subject: Re: memory reclaim problems on fs usage Message-ID: <20151116161518.GI14116@dhcp22.suse.cz> X-ASG-Orig-Subj: Re: memory reclaim problems on fs usage References: <201511102313.36685.arekm@maven.pl> <201511151229.23312.arekm@maven.pl> <201511152313.IJI23764.OHVFJFMSFOtOLQ@I-love.SAKURA.ne.jp> <201511151549.35299.arekm@maven.pl> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <201511151549.35299.arekm@maven.pl> User-Agent: Mutt/1.5.24 (2015-08-30) X-Barracuda-Connect: mx2.suse.de[195.135.220.15] X-Barracuda-Start-Time: 1447690520 X-Barracuda-Encrypted: ECDHE-RSA-AES256-SHA X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24440 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Sun 15-11-15 15:49:35, Arkadiusz MiÅ›kiewicz wrote: > On Sunday 15 of November 2015, Tetsuo Handa wrote: > > Arkadiusz Miskiewicz wrote: > > > On Sunday 15 of November 2015, Tetsuo Handa wrote: > > > > I think that the vmstat statistics now have correct values. > > > > > > > > > But are these patches solving the problem or just hiding it? > > > > > > > > Excuse me but I can't judge. > > > > > > > > If you are interested in monitoring how vmstat statistics are changing > > > > under stalled condition, you can try below patch. > > > > > > Here is log with this and all previous patches applied: > > > http://ixion.pld-linux.org/~arekm/log-mm-5.txt.gz > > > > Regarding "Node 0 Normal" (min:7104kB low:8880kB high:10656kB), > > all free: values look sane to me. I think that your problem was solved. > > Great, thanks! > > Will all (or part) of these patches > > http://sprunge.us/GYBb Migrate reserves are not a stable material I am afraid. "vmstat: explicitly schedule per-cpu work on the CPU we need it to run on" was not marked for stable either but I am not sure why it should make any difference for your load. I understand that testing this is really tedious but it would be better to know which of the patches actually made a difference. > http://sprunge.us/XWUX (after it gets merged) Yes I plan to mark this one for stable. > be pushed to stable@ or are too risky for stable ? > > > > > $ grep "Normal free:" log-mm-5.txt | cut -b 44- | awk -F' ' ' { print $4 } > > ' | cut -b 6- | sort -g 8608kB > > 8636kB > > 8920kB > > 8920kB > > 8952kB > > 8968kB > > 8980kB > > (...snipped...) > > 215364kB > > 290068kB > > 290428kB > > 291176kB > > 292836kB > > 303992kB > > 306468kB > > 318080kB > > 319548kB > > > > $ grep "Normal free:" log-mm-1.txt | cut -b 44- | awk -F' ' ' { print $4 } > > ' | cut -b 6- | sort -g 0kB > > 40kB > > 128kB > > 128kB > > 128kB > > 128kB > > 128kB > > 128kB > > 128kB > > 128kB > > (...snipped...) > > 412kB > > 616kB > > 1268kB > > 1544kB > > 1696kB > > 2756kB > > 2756kB > > 2756kB > > 2756kB > > 2756kB > > 2756kB > > 2756kB > > > -- > Arkadiusz MiÅ›kiewicz, arekm / ( maven.pl | pld-linux.org ) -- Michal Hocko SUSE Labs From dan.j.williams@intel.com Mon Nov 16 10:58:17 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 71F8A7CBF for ; Mon, 16 Nov 2015 10:58:17 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 2FF108F8049 for ; Mon, 16 Nov 2015 08:58:17 -0800 (PST) X-ASG-Debug-ID: 1447693091-04cbb0605cb3850001-NocioJ Received: from mail-wm0-f48.google.com (mail-wm0-f48.google.com [74.125.82.48]) by cuda.sgi.com with ESMTP id 0lxdxjph1qA2Jdin (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Mon, 16 Nov 2015 08:58:12 -0800 (PST) X-Barracuda-Envelope-From: dan.j.williams@intel.com X-Barracuda-Apparent-Source-IP: 74.125.82.48 Received: by wmww144 with SMTP id w144so128172141wmw.0 for ; Mon, 16 Nov 2015 08:58:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=intel_com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=kXkmsLCKRQlIbRLj9yKRsgJHRGHreRgXFcHhutQ37Ig=; b=Ddtaw15TapAL/Q+Y+BIpOYnEd348VYVXnmVZzdeT1VSfLGtR6cgckgO6g/wwj1n2uU Hco448IPeQr1HM+CIjfYbsHHRwHaFybAoTqBtUxFxaby9xMOliiQvAmf6awAvTqSNBOb 8LVMrSBhi4I1BSP1q/1nw5nrtJzx1bNzBcgHrxTTsXVpjWmeJ1mAb0+cEg0rwJjIwCWA iWwsXKHWLi3wsXBmr+6EVgme+dmL3ndhKmRRpduZiXsivRHHT4dbonHqYTYMg9N24ahO jRgvmAKi8+YRAFnKkjfJCXQZs+Hq429mdKDn+pEZJ1pct722RC9fnbg3jcMa3pkIK1BI ITmw== 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=kXkmsLCKRQlIbRLj9yKRsgJHRGHreRgXFcHhutQ37Ig=; b=UI6VT09zZgjuORtIceP8Drb0g3N0FFYRns+/PLFSGVJ6i47718iNl2BxubGiN2jcKf 0zVqO3QUB2ZHTOaFPYLojqp0j/J8+SMlniYNj9rwykn5pm3S2ejFw2+OVk8y97nt2+EY eGeGZe42IXd/N3roySTvWasd2cbg2oaHsDDJwxiSErYYfMBoDC0TF5EPM/MbtX51bRaE GnZO2ehGvIf3FAAiow6CZ/t1dHoL+s5sPXtc/Tfx9FjYSvu5TQgvEHsGrEs7RPyvGHa+ 2ilR7Cjw/yGcHxDYx+ZTLh6rRghTN5Qh5hhR7Ow+M3QDoa2UryyD6MHa2PsTdLgwVyWd Pcqg== X-Gm-Message-State: ALoCoQkYuGyz/DLLcF0x3gRyHhgOVT/4M7DI0026T/SXVzRUhF9ewzTg3FP6eosF+881OAK1lz20 MIME-Version: 1.0 X-Received: by 10.28.134.199 with SMTP id i190mr9595280wmd.33.1447693091345; Mon, 16 Nov 2015 08:58:11 -0800 (PST) Received: by 10.27.88.130 with HTTP; Mon, 16 Nov 2015 08:58:11 -0800 (PST) In-Reply-To: <20151116144130.GD3443@quack.suse.cz> References: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> <20151116144130.GD3443@quack.suse.cz> Date: Mon, 16 Nov 2015 08:58:11 -0800 Message-ID: Subject: Re: [PATCH v2 00/11] DAX fsynx/msync support From: Dan Williams X-ASG-Orig-Subj: Re: [PATCH v2 00/11] DAX fsynx/msync support To: Jan Kara Cc: Ross Zwisler , "linux-kernel@vger.kernel.org" , "H. Peter Anvin" , "J. Bruce Fields" , "Theodore Ts'o" , Alexander Viro , Andreas Dilger , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4 , linux-fsdevel , Linux MM , "linux-nvdimm@lists.01.org" , X86 ML , XFS Developers , Andrew Morton , Matthew Wilcox , Dave Hansen Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-wm0-f48.google.com[74.125.82.48] X-Barracuda-Start-Time: 1447693092 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24441 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 Mon, Nov 16, 2015 at 6:41 AM, Jan Kara wrote: > On Fri 13-11-15 17:06:39, Ross Zwisler wrote: >> This patch series adds support for fsync/msync to DAX. >> >> Patches 1 through 7 add various utilities that the DAX code will eventually >> need, and the DAX code itself is added by patch 8. Patches 9-11 update the >> three filesystems that currently support DAX, ext2, ext4 and XFS, to use >> the new DAX fsync/msync code. >> >> These patches build on the recent DAX locking changes from Dave Chinner, >> Jan Kara and myself. Dave's changes for XFS and my changes for ext2 have >> been merged in the v4.4 window, but Jan's are still unmerged. You can grab >> them here: >> >> http://www.spinics.net/lists/linux-ext4/msg49951.html > > I had a quick look and the patches look sane to me. I'll try to give them > more detailed look later this week. When thinking about the general design > I was wondering: When we have this infrastructure to track data potentially > lingering in CPU caches, would not it be a performance win to use standard > cached stores in dax_io() and mark corresponding pages as dirty in page > cache the same way as this patch set does it for mmaped writes? I have no > idea how costly are non-temporal stores compared to cached ones and how > would this compare to the cost of dirty tracking so this may be just > completely bogus... Keep in mind that this approach will flush every virtual address that may be dirty. For example, if you touch 1byte in a 2MB page we'll end up looping through the entire 2MB range. At some point the dirty size becomes large enough that is cheaper to flush the entire cache, we have not measured where that crossover point is. From dan.j.williams@intel.com Mon Nov 16 11:29:06 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 C90947CBF for ; Mon, 16 Nov 2015 11:29:06 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id BFD80304043 for ; Mon, 16 Nov 2015 09:29:06 -0800 (PST) X-ASG-Debug-ID: 1447694940-04cbb0605eb5ba0001-NocioJ Received: from mail-wm0-f45.google.com (mail-wm0-f45.google.com [74.125.82.45]) by cuda.sgi.com with ESMTP id X28wbBHYIMXBJw4R (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Mon, 16 Nov 2015 09:29:01 -0800 (PST) X-Barracuda-Envelope-From: dan.j.williams@intel.com X-Barracuda-Apparent-Source-IP: 74.125.82.45 Received: by wmww144 with SMTP id w144so129474690wmw.0 for ; Mon, 16 Nov 2015 09:29:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=intel_com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=eTlQHDOWTN7nhMc5bf86Wz6dyuZNKdiiSQOlmtrXMYk=; b=D+35hgPpO2cLFBy9QgN9fqf155AHf2ZiJGN/IR0xC/nYVlhHxYRiBS91jv4ZkjWX/4 Ph64y4pG5m+OIrENA/ON+o4WvBlVLeBSpT9nuaeKJStu5howOVIg7eDOu4yDVWcoUQ3x 4JzjS3qqJgu+EHMmQp29aGZG4n4u58w4KN7aCsWAh6OldVf0nK05dkXRwXMkHHNrw5J6 suyKHgFh6BZDAnMPQo/0S7y0rmCHDMGSk74wtesRqITLkD886yBmGzObUcPoDFsCrv7U wWiQqFNiZIS3g1Js1YoJhCT0lZtMObehot7cg6DxCn5ySsPMY9NRN2XN+WChz7OZNLpR cbtQ== 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=eTlQHDOWTN7nhMc5bf86Wz6dyuZNKdiiSQOlmtrXMYk=; b=d20YHswJU6qPutA7RMG5sCCu89vKPTBvRDyBAgnE5Q7coKDyx3Du//95f23B+RVjqi Fyha7Z89IHfUoWMDe32xFwPl82Is3qeUmuoe9CMRYRmR/5Clk8P4d3rOwJ8L12FX+7wD ZNbiT1ARSNML7O51BjO9iCRi98Vt31e7AwTnBUTJFoHc2eOxAR9YzRLKFTQqV0lVi+Ps /giOC9LGf2H78f2rH/Kvv80GLCFWok0keXsgphnR9sX+4lRbnQN6V9/szjC5H/EDP/c9 oHQRnuhLKK//3VSnUnWLVW3LM4s4qzlVq7l6o0ic6tjhAsw/ZjPJANyHI/vboFlkxoiS e0fw== X-Gm-Message-State: ALoCoQkTv98LpiPF7HJjTHYDvx+ajcmg+EiSiOKVWIj7wDjZfXkkEZxgv1Hex2yVSn/BYO1SnJgp MIME-Version: 1.0 X-Received: by 10.194.84.4 with SMTP id u4mr38351683wjy.149.1447694940039; Mon, 16 Nov 2015 09:29:00 -0800 (PST) Received: by 10.27.88.130 with HTTP; Mon, 16 Nov 2015 09:28:59 -0800 (PST) In-Reply-To: <20151116140526.GA6733@quack.suse.cz> References: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> <1447459610-14259-4-git-send-email-ross.zwisler@linux.intel.com> <22E0F870-C1FB-431E-BF6C-B395A09A2B0D@dilger.ca> <20151116133714.GB3443@quack.suse.cz> <20151116140526.GA6733@quack.suse.cz> Date: Mon, 16 Nov 2015 09:28:59 -0800 Message-ID: Subject: Re: [PATCH v2 03/11] pmem: enable REQ_FUA/REQ_FLUSH handling From: Dan Williams X-ASG-Orig-Subj: Re: [PATCH v2 03/11] pmem: enable REQ_FUA/REQ_FLUSH handling To: Jan Kara Cc: Andreas Dilger , Ross Zwisler , "linux-kernel@vger.kernel.org" , "H. Peter Anvin" , "J. Bruce Fields" , "Theodore Ts'o" , Alexander Viro , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4 , linux-fsdevel , Linux MM , "linux-nvdimm@lists.01.org" , X86 ML , XFS Developers , Andrew Morton , Matthew Wilcox , Dave Hansen Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-wm0-f45.google.com[74.125.82.45] X-Barracuda-Start-Time: 1447694940 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24441 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 Mon, Nov 16, 2015 at 6:05 AM, Jan Kara wrote: > On Mon 16-11-15 14:37:14, Jan Kara wrote: [..] > But a question: Won't it be better to do sfence + pcommit only in response > to REQ_FLUSH request and don't do it after each write? I'm not sure how > expensive these instructions are but in theory it could be a performance > win, couldn't it? For filesystems this is enough wrt persistency > guarantees... We would need to gather the performance data... The expectation is that the cache flushing is more expensive than the sfence + pcommit. From sandeen@redhat.com Mon Nov 16 11:32:40 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 84E3A7CBF for ; Mon, 16 Nov 2015 11:32:40 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 6C465304043 for ; Mon, 16 Nov 2015 09:32:40 -0800 (PST) X-ASG-Debug-ID: 1447695159-04bdf07f0a9ba70001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id cvXuy1HERrurIqff (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 16 Nov 2015 09:32:39 -0800 (PST) X-Barracuda-Envelope-From: sandeen@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 (Postfix) with ESMTPS id 2E0D78F29C for ; Mon, 16 Nov 2015 17:32:39 +0000 (UTC) Received: from liberator.sandeen.net (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAGHWcWx022621 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Mon, 16 Nov 2015 12:32:38 -0500 To: xfs@oss.sgi.com From: Eric Sandeen X-Enigmail-Draft-Status: N1110 Cc: "Bill O'Donnell" Subject: [PATCH] xfs: get mp from bma->ip in xfs_bmap code Message-ID: <564A1335.6080304@redhat.com> X-ASG-Orig-Subj: [PATCH] xfs: get mp from bma->ip in xfs_bmap code Date: Mon, 16 Nov 2015 11:32:37 -0600 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit 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: 1447695159 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 In my earlier commit c29aad4 xfs: pass mp to XFS_WANT_CORRUPTED_GOTO I added some local mp variables with code which indicates that mp might be NULL. Coverity doesn't like this now, because the updated per-fs XFS_STATS macros dereference mp. I don't think this is actually a problem; from what I can tell, we cannot get to these functions with a null bma->tp, so my NULL check was probably pointless. Still, it's not super obvious. So switch this code to get mp from the inode on the xfs_bmalloca structure, with no conditional, because the functions are already using bmap->ip directly. Addresses-Coverity-Id: 1339552 Addresses-Coverity-Id: 1339553 Signed-off-by: Eric Sandeen --- diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 119c242..bb3c659 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -1725,7 +1725,7 @@ xfs_bmap_add_extent_delay_real( int tmp_rval; /* partial logging flags */ struct xfs_mount *mp; - mp = bma->tp ? bma->tp->t_mountp : NULL; + mp = bma->ip->i_mount; ifp = XFS_IFORK_PTR(bma->ip, XFS_DATA_FORK); ASSERT(bma->idx >= 0); @@ -2939,7 +2939,7 @@ xfs_bmap_add_extent_hole_real( int state; /* state bits, accessed thru macros */ struct xfs_mount *mp; - mp = bma->tp ? bma->tp->t_mountp : NULL; + mp = bma->ip->i_mount; ifp = XFS_IFORK_PTR(bma->ip, whichfork); ASSERT(bma->idx >= 0); From jmoyer@redhat.com Mon Nov 16 13:27:51 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 1823F7CBF for ; Mon, 16 Nov 2015 13:27:51 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 9C388AC00B for ; Mon, 16 Nov 2015 11:27:47 -0800 (PST) X-ASG-Debug-ID: 1447702065-04cbb0605ebd900001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id csbLB3JcoBQk84rB (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 16 Nov 2015 11:27:46 -0800 (PST) X-Barracuda-Envelope-From: jmoyer@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 (Postfix) with ESMTPS id C553D3C223; Mon, 16 Nov 2015 19:27:45 +0000 (UTC) Received: from segfault.boston.devel.redhat.com (segfault.boston.devel.redhat.com [10.19.60.26]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAGJRiGK030543 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Mon, 16 Nov 2015 14:27:44 -0500 From: Jeff Moyer To: Avi Kivity Cc: xfs@oss.sgi.com, linux-aio@kvack.org, Steven Whitehouse , Jan Kara , linux-fsdevel@vger.kernel.org Subject: Re: AIO read returns negative number for bytes read References: <564883BD.8070607@scylladb.com> X-ASG-Orig-Subj: Re: AIO read returns negative number for bytes read X-PGP-KeyID: 1F78E1B4 X-PGP-CertKey: F6FE 280D 8293 F72C 65FD 5A58 1FF8 A7CA 1F78 E1B4 X-PCLoadLetter: What the f**k does that mean? Date: Mon, 16 Nov 2015 14:27:43 -0500 In-Reply-To: <564883BD.8070607@scylladb.com> (Avi Kivity's message of "Sun, 15 Nov 2015 15:08:13 +0200") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain 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: 1447702066 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/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 Hi Avi, Avi Kivity writes: > Due to a bug in my program, I initiated a read beyond > eof. Specifically, the file size is 13002 bytes and the read offset is > 13312 (0x3400). > > I would expect such a read to return 0 bytes read, but io_getevents > returns -310, which is suspiciously equal to (13002 - 13312). > > I attach a reproducer. > > 4.2.5-201.fc22.x86_64 > > Are my expectations incorrect, or is this a bug in aio or xfs? Your expectations are correct. The bug was introduced by commit 9fe55eea7e4b4 (Fix race when checking i_size on direct i/o read). I've CC'd the patch author and linux-fsdevel. I'm not sure what the right fix is, given that the size checks were removed from the vfs to fix some race condition. Unfortunately, the commit message doesn't really do a good job of explaining the race. In order to save others time, here is a good explanation of the problem that commit is meant to fix, along with a reproducer: http://marc.info/?l=linux-fsdevel&m=138641356614458&w=2 Thanks for the great bug report, and sorry I have no solution to proffer. Cheers, Jeff From ross.zwisler@linux.intel.com Mon Nov 16 13:48:54 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 0BB947CBF for ; Mon, 16 Nov 2015 13:48:54 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id F09E78F8050 for ; Mon, 16 Nov 2015 11:48:53 -0800 (PST) X-ASG-Debug-ID: 1447703328-04cbb0605dbe830001-NocioJ Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by cuda.sgi.com with ESMTP id tdEKvHxWVjlJEYTw for ; Mon, 16 Nov 2015 11:48:49 -0800 (PST) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 134.134.136.20 X-ASG-Whitelist: EmailCat (corporate) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga101.jf.intel.com with ESMTP; 16 Nov 2015 11:48:49 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,304,1444719600"; d="scan'208";a="852282441" Received: from theros.lm.intel.com (HELO linux.intel.com) ([10.232.112.87]) by fmsmga002.fm.intel.com with ESMTP; 16 Nov 2015 11:48:47 -0800 Date: Mon, 16 Nov 2015 12:48:46 -0700 From: Ross Zwisler To: Dan Williams Cc: Jan Kara , Andreas Dilger , Ross Zwisler , "linux-kernel@vger.kernel.org" , "H. Peter Anvin" , "J. Bruce Fields" , Theodore Ts'o , Alexander Viro , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4 , linux-fsdevel , Linux MM , "linux-nvdimm@lists.01.org" , X86 ML , XFS Developers , Andrew Morton , Matthew Wilcox , Dave Hansen Subject: Re: [PATCH v2 03/11] pmem: enable REQ_FUA/REQ_FLUSH handling Message-ID: <20151116194846.GB32203@linux.intel.com> X-ASG-Orig-Subj: Re: [PATCH v2 03/11] pmem: enable REQ_FUA/REQ_FLUSH handling Mail-Followup-To: Ross Zwisler , Dan Williams , Jan Kara , Andreas Dilger , "linux-kernel@vger.kernel.org" , "H. Peter Anvin" , "J. Bruce Fields" , Theodore Ts'o , Alexander Viro , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4 , linux-fsdevel , Linux MM , "linux-nvdimm@lists.01.org" , X86 ML , XFS Developers , Andrew Morton , Matthew Wilcox , Dave Hansen References: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> <1447459610-14259-4-git-send-email-ross.zwisler@linux.intel.com> <22E0F870-C1FB-431E-BF6C-B395A09A2B0D@dilger.ca> <20151116133714.GB3443@quack.suse.cz> <20151116140526.GA6733@quack.suse.cz> 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-Barracuda-Connect: mga02.intel.com[134.134.136.20] X-Barracuda-Start-Time: 1447703328 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Mon, Nov 16, 2015 at 09:28:59AM -0800, Dan Williams wrote: > On Mon, Nov 16, 2015 at 6:05 AM, Jan Kara wrote: > > On Mon 16-11-15 14:37:14, Jan Kara wrote: > [..] > > But a question: Won't it be better to do sfence + pcommit only in response > > to REQ_FLUSH request and don't do it after each write? I'm not sure how > > expensive these instructions are but in theory it could be a performance > > win, couldn't it? For filesystems this is enough wrt persistency > > guarantees... > > We would need to gather the performance data... The expectation is > that the cache flushing is more expensive than the sfence + pcommit. I think we should revisit the idea of removing wmb_pmem() from the I/O path in both the PMEM driver and in DAX, and just relying on the REQ_FUA/REQ_FLUSH path to do wmb_pmem() for all cases. This was brought up in the thread dealing with the "big hammer" fsync/msync patches as well. https://lkml.org/lkml/2015/11/3/730 I think we can all agree from the start that wmb_pmem() will have a nonzero cost, both because of the PCOMMIT and because of the ordering caused by the sfence. If it's possible to avoid doing it on each I/O, I think that would be a win. So, here would be our new flows: PMEM I/O: write I/O(s) to the driver PMEM I/O writes the data using non-temporal stores REQ_FUA/REQ_FLUSH to the PMEM driver wmb_pmem() to order all previous writes and flushes, and to PCOMMIT the dirty data durably to the DIMMs DAX I/O: write I/O(s) to the DAX layer write the data using regular stores (eventually to be replaced with non-temporal stores) flush the data with wb_cache_pmem() (removed when we use non-temporal stores) REQ_FUA/REQ_FLUSH to the PMEM driver wmb_pmem() to order all previous writes and flushes, and to PCOMMIT the dirty data durably to the DIMMs DAX msync/fsync: writes happen to DAX mmaps from userspace DAX fsync/msync all dirty pages are written back using wb_cache_pmem() REQ_FUA/REQ_FLUSH to the PMEM driver wmb_pmem() to order all previous writes and flushes, and to PCOMMIT the dirty data durably to the DIMMs DAX/PMEM zeroing (suggested by Dave: https://lkml.org/lkml/2015/11/2/772): PMEM driver receives zeroing request writes a bunch of zeroes using non-temporal stores REQ_FUA/REQ_FLUSH to the PMEM driver wmb_pmem() to order all previous writes and flushes, and to PCOMMIT the dirty data durably to the DIMMs Having all these flows wait to do wmb_pmem() in the PMEM driver in response to REQ_FUA/REQ_FLUSH has several advantages: 1) The work done and guarantees provided after each step closely match the normal block I/O to disk case. This means that the existing algorithms used by filesystems to make sure that their metadata is ordered properly and synced at a known time should all work the same. 2) By delaying wmb_pmem() until REQ_FUA/REQ_FLUSH time we can potentially do many I/Os at different levels, and order them all with a single wmb_pmem(). This should result in a performance win. Is there any reason why this wouldn't work or wouldn't be a good idea? From ross.zwisler@linux.intel.com Mon Nov 16 14:01:18 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 40CEC7CBF for ; Mon, 16 Nov 2015 14:01:18 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 169178F8059 for ; Mon, 16 Nov 2015 12:01:17 -0800 (PST) X-ASG-Debug-ID: 1447704070-04bdf07f09a52b0001-NocioJ Received: from mga14.intel.com ([192.55.52.115]) by cuda.sgi.com with ESMTP id cK3cA1W0jo48OBsJ for ; Mon, 16 Nov 2015 12:01:10 -0800 (PST) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 192.55.52.115 Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga103.fm.intel.com with ESMTP; 16 Nov 2015 12:01:06 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,304,1444719600"; d="scan'208";a="839932371" Received: from theros.lm.intel.com (HELO linux.intel.com) ([10.232.112.87]) by fmsmga001.fm.intel.com with ESMTP; 16 Nov 2015 12:01:04 -0800 Date: Mon, 16 Nov 2015 13:01:02 -0700 From: Ross Zwisler To: Dan Williams Cc: Jan Kara , Ross Zwisler , "linux-kernel@vger.kernel.org" , "H. Peter Anvin" , "J. Bruce Fields" , Theodore Ts'o , Alexander Viro , Andreas Dilger , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4 , linux-fsdevel , Linux MM , "linux-nvdimm@lists.01.org" , X86 ML , XFS Developers , Andrew Morton , Matthew Wilcox , Dave Hansen Subject: Re: [PATCH v2 00/11] DAX fsynx/msync support Message-ID: <20151116200102.GA9737@linux.intel.com> X-ASG-Orig-Subj: Re: [PATCH v2 00/11] DAX fsynx/msync support Mail-Followup-To: Ross Zwisler , Dan Williams , Jan Kara , "linux-kernel@vger.kernel.org" , "H. Peter Anvin" , "J. Bruce Fields" , Theodore Ts'o , Alexander Viro , Andreas Dilger , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4 , linux-fsdevel , Linux MM , "linux-nvdimm@lists.01.org" , X86 ML , XFS Developers , Andrew Morton , Matthew Wilcox , Dave Hansen References: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> <20151116144130.GD3443@quack.suse.cz> 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-Barracuda-Connect: UNKNOWN[192.55.52.115] X-Barracuda-Start-Time: 1447704070 X-Barracuda-URL: https://192.48.157.11:443/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_SC7_SA_HREF_FROM_MISMATCH_TEXT_URIx1_HL, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24448 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS 2.50 BSF_SC7_SA_HREF_FROM_MISMATCH_TEXT_URIx1_HL Custom Rule HREF_FROM_MISMATCH_TEXT_URIx1_HL On Mon, Nov 16, 2015 at 08:58:11AM -0800, Dan Williams wrote: > On Mon, Nov 16, 2015 at 6:41 AM, Jan Kara wrote: > > On Fri 13-11-15 17:06:39, Ross Zwisler wrote: > >> This patch series adds support for fsync/msync to DAX. > >> > >> Patches 1 through 7 add various utilities that the DAX code will eventually > >> need, and the DAX code itself is added by patch 8. Patches 9-11 update the > >> three filesystems that currently support DAX, ext2, ext4 and XFS, to use > >> the new DAX fsync/msync code. > >> > >> These patches build on the recent DAX locking changes from Dave Chinner, > >> Jan Kara and myself. Dave's changes for XFS and my changes for ext2 have > >> been merged in the v4.4 window, but Jan's are still unmerged. You can grab > >> them here: > >> > >> http://www.spinics.net/lists/linux-ext4/msg49951.html > > > > I had a quick look and the patches look sane to me. I'll try to give them > > more detailed look later this week. When thinking about the general design > > I was wondering: When we have this infrastructure to track data potentially > > lingering in CPU caches, would not it be a performance win to use standard > > cached stores in dax_io() and mark corresponding pages as dirty in page > > cache the same way as this patch set does it for mmaped writes? I have no > > idea how costly are non-temporal stores compared to cached ones and how > > would this compare to the cost of dirty tracking so this may be just > > completely bogus... > > Keep in mind that this approach will flush every virtual address that > may be dirty. For example, if you touch 1byte in a 2MB page we'll end > up looping through the entire 2MB range. At some point the dirty size > becomes large enough that is cheaper to flush the entire cache, we > have not measured where that crossover point is. Yep, I expect there will be a crossover point where flushing the entire processor cache will be beneficial. I agree with Dan that we'll need to figure this out via measurement, and that we'd similarly need measurements to justify the decision to write dirty data at the DAX level without flushing and mark entries as dirty for fsync/msync to clean up later. It could turn out to be great, but we'll have to see. :) From ross.zwisler@linux.intel.com Mon Nov 16 14:10:17 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 374977CBF for ; Mon, 16 Nov 2015 14:10:17 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id C966CAC004 for ; Mon, 16 Nov 2015 12:10:13 -0800 (PST) X-ASG-Debug-ID: 1447704609-04bdf07f08a5a90001-NocioJ Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by cuda.sgi.com with ESMTP id X9afSa9aC48SIS2X for ; Mon, 16 Nov 2015 12:10:09 -0800 (PST) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 134.134.136.24 X-ASG-Whitelist: EmailCat (corporate) Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga102.jf.intel.com with ESMTP; 16 Nov 2015 12:09:52 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,304,1444719600"; d="scan'208";a="852110538" Received: from theros.lm.intel.com (HELO linux.intel.com) ([10.232.112.87]) by orsmga002.jf.intel.com with ESMTP; 16 Nov 2015 12:09:51 -0800 Date: Mon, 16 Nov 2015 13:09:50 -0700 From: Ross Zwisler To: Dan Williams Cc: Andreas Dilger , Ross Zwisler , "linux-kernel@vger.kernel.org" , "H. Peter Anvin" , "J. Bruce Fields" , Theodore Ts'o , Alexander Viro , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4 , linux-fsdevel , Linux MM , "linux-nvdimm@lists.01.org" , X86 ML , XFS Developers , Andrew Morton , Matthew Wilcox , Dave Hansen Subject: Re: [PATCH v2 03/11] pmem: enable REQ_FUA/REQ_FLUSH handling Message-ID: <20151116200950.GB9737@linux.intel.com> X-ASG-Orig-Subj: Re: [PATCH v2 03/11] pmem: enable REQ_FUA/REQ_FLUSH handling Mail-Followup-To: Ross Zwisler , Dan Williams , Andreas Dilger , "linux-kernel@vger.kernel.org" , "H. Peter Anvin" , "J. Bruce Fields" , Theodore Ts'o , Alexander Viro , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4 , linux-fsdevel , Linux MM , "linux-nvdimm@lists.01.org" , X86 ML , XFS Developers , Andrew Morton , Matthew Wilcox , Dave Hansen References: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> <1447459610-14259-4-git-send-email-ross.zwisler@linux.intel.com> <22E0F870-C1FB-431E-BF6C-B395A09A2B0D@dilger.ca> 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-Barracuda-Connect: mga09.intel.com[134.134.136.24] X-Barracuda-Start-Time: 1447704609 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Fri, Nov 13, 2015 at 06:32:40PM -0800, Dan Williams wrote: > On Fri, Nov 13, 2015 at 4:43 PM, Andreas Dilger wrote: > > On Nov 13, 2015, at 5:20 PM, Dan Williams wrote: > >> > >> On Fri, Nov 13, 2015 at 4:06 PM, Ross Zwisler > >> wrote: > >>> Currently the PMEM driver doesn't accept REQ_FLUSH or REQ_FUA bios. These > >>> are sent down via blkdev_issue_flush() in response to a fsync() or msync() > >>> and are used by filesystems to order their metadata, among other things. > >>> > >>> When we get an msync() or fsync() it is the responsibility of the DAX code > >>> to flush all dirty pages to media. The PMEM driver then just has issue a > >>> wmb_pmem() in response to the REQ_FLUSH to ensure that before we return all > >>> the flushed data has been durably stored on the media. > >>> > >>> Signed-off-by: Ross Zwisler > >> > >> Hmm, I'm not seeing why we need this patch. If the actual flushing of > >> the cache is done by the core why does the driver need support > >> REQ_FLUSH? Especially since it's just a couple instructions. REQ_FUA > >> only makes sense if individual writes can bypass the "drive" cache, > >> but no I/O submitted to the driver proper is ever cached we always > >> flush it through to media. > > > > If the upper level filesystem gets an error when submitting a flush > > request, then it assumes the underlying hardware is broken and cannot > > be as aggressive in IO submission, but instead has to wait for in-flight > > IO to complete. > > Upper level filesystems won't get errors when the driver does not > support flush. Those requests are ended cleanly in > generic_make_request_checks(). Yes, the fs still needs to wait for > outstanding I/O to complete but in the case of pmem all I/O is > synchronous. There's never anything to await when flushing at the > pmem driver level. > > > Since FUA/FLUSH is basically a no-op for pmem devices, > > it doesn't make sense _not_ to support this functionality. > > Seems to be a nop either way. Given that DAX may lead to dirty data > pending to the device in the cpu cache that a REQ_FLUSH request will > not touch, its better to leave it all to the mm core to handle. I.e. > it doesn't make sense to call the driver just for two instructions > (sfence + pcommit) when the mm core is taking on the cache flushing. > Either handle it all in the mm or the driver, not a mixture. Does anyone know if ext4 and/or XFS alter their algorithms based on whether the driver supports REQ_FLUSH/REQ_FUA? Will the filesystem behave more efficiently with respect to their internal I/O ordering, etc., if PMEM advertises REQ_FLUSH/REQ_FUA support, even though we could do the same thing at the DAX layer? From dan.j.williams@intel.com Mon Nov 16 14:35:02 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 538BF7CBF for ; Mon, 16 Nov 2015 14:35:02 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 29184304032 for ; Mon, 16 Nov 2015 12:34:59 -0800 (PST) X-ASG-Debug-ID: 1447706095-04bdf07f07a6db0001-NocioJ Received: from mail-wm0-f50.google.com (mail-wm0-f50.google.com [74.125.82.50]) by cuda.sgi.com with ESMTP id TNTqZMzPowfAt8Cc (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Mon, 16 Nov 2015 12:34:56 -0800 (PST) X-Barracuda-Envelope-From: dan.j.williams@intel.com X-Barracuda-Apparent-Source-IP: 74.125.82.50 Received: by wmvv187 with SMTP id v187so196179633wmv.1 for ; Mon, 16 Nov 2015 12:34:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=intel_com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type; bh=oeTr6SZaYSbqNbHYUymYGCuZ3dhCmluCBCkD+SFiVKw=; b=PsrfrtZEXwiof3yAHI4f+nHUV7YVJm4Tkh2kogFs7YuKc9A2YcmK9uPSnwGfFNwUsC g4cSIycAulQGa6pEhi4CwMbSD7vBB8Fd91rGlutafVoTLe6MPiKC65mx9HnLY3Es978h FyhJm5ylin5bZwcaWB0RDVIfUCwQVnQ8ZsEki5LCetEPmjlY0R9kG1a31DdNNrTy44ES ee4cmoRzbEtQYo3e4v+E7FNtitCmgnhPw09MlsCb2G0gms8znwywQvAtcqEvQtyS0vOs ytv/VEekttOnxgqU0Jmrkjk4usPrYhDBZsyB6FrMxYT5Ecn54KiUnCUO/1EtrpaVBneH 44ew== 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:content-type; bh=oeTr6SZaYSbqNbHYUymYGCuZ3dhCmluCBCkD+SFiVKw=; b=DE9FkpU6XnzrTjwjF4pcYXarZnUVMpFeBCvSGJkOC2lOEXrfUFBvd69NrYxFIWxjV0 gRjTIiK4VcUwhuvfG+b8WV1/YQNmG4lu99hTwMUcHnccq3rw9wZU5oSNT3MT+Xki/YXN yFzq9Yuy0VB5MD2mndDazXwiL9Jraj1OWe6iPGWLgCLKNsh88s2PKOKGwjgtsqwG010p idxDQmKjQZHDQMNhS5rUz16ZKS+K1kdbK2rXI3OCOQU0G2K0ghb8Yj4Lxh9xEoXE/T27 lwj36aC1rEfhFAishsXxV9fryYjhbLJOQJje/A/6/dSENDUUprFKiJexsoG8JUik8hnS 3jVw== X-Gm-Message-State: ALoCoQm07l9HhC0g4kYXzZzf825++vgdUwOzzFZD5ChpzbzJ4C87x7IqxJgCImWreVg74b/axxA5 MIME-Version: 1.0 X-Received: by 10.194.84.4 with SMTP id u4mr39148094wjy.149.1447706095205; Mon, 16 Nov 2015 12:34:55 -0800 (PST) Received: by 10.27.88.130 with HTTP; Mon, 16 Nov 2015 12:34:55 -0800 (PST) In-Reply-To: <20151116194846.GB32203@linux.intel.com> References: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> <1447459610-14259-4-git-send-email-ross.zwisler@linux.intel.com> <22E0F870-C1FB-431E-BF6C-B395A09A2B0D@dilger.ca> <20151116133714.GB3443@quack.suse.cz> <20151116140526.GA6733@quack.suse.cz> <20151116194846.GB32203@linux.intel.com> Date: Mon, 16 Nov 2015 12:34:55 -0800 Message-ID: Subject: Re: [PATCH v2 03/11] pmem: enable REQ_FUA/REQ_FLUSH handling From: Dan Williams X-ASG-Orig-Subj: Re: [PATCH v2 03/11] pmem: enable REQ_FUA/REQ_FLUSH handling To: Ross Zwisler , Dan Williams , Jan Kara , Andreas Dilger , "linux-kernel@vger.kernel.org" , "H. Peter Anvin" , "J. Bruce Fields" , "Theodore Ts'o" , Alexander Viro , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4 , linux-fsdevel , Linux MM , "linux-nvdimm@lists.01.org" , X86 ML , XFS Developers , Andrew Morton , Matthew Wilcox , Dave Hansen Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-wm0-f50.google.com[74.125.82.50] X-Barracuda-Start-Time: 1447706096 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24449 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 Mon, Nov 16, 2015 at 11:48 AM, Ross Zwisler wrote: > On Mon, Nov 16, 2015 at 09:28:59AM -0800, Dan Williams wrote: >> On Mon, Nov 16, 2015 at 6:05 AM, Jan Kara wrote: >> > On Mon 16-11-15 14:37:14, Jan Kara wrote: [..] > Is there any reason why this wouldn't work or wouldn't be a good idea? We don't have numbers to support the claim that pcommit is so expensive as to need be deferred, especially if the upper layers are already taking the hit on doing the flushes. REQ_FLUSH, means flush your volatile write cache. Currently all I/O through the driver never hits a volatile cache so there's no need to tell the block layer that we have a volatile write cache, especially when you have the core mm taking responsibility for doing cache maintenance for dax-mmap ranges. We also don't have numbers on if/when wbinvd is a more performant solution. tl;dr Now that we have a baseline implementation can we please use data to make future arch decisions? From david@fromorbit.com Mon Nov 16 14:58:52 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 190287F5D for ; Mon, 16 Nov 2015 14:58:52 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id D2D8C8F8050 for ; Mon, 16 Nov 2015 12:58:51 -0800 (PST) X-ASG-Debug-ID: 1447707527-04bdf07f08a8150001-NocioJ Received: from ipmail06.adl2.internode.on.net (ipmail06.adl2.internode.on.net [150.101.137.129]) by cuda.sgi.com with ESMTP id EXZhZPuCEX1iePAC for ; Mon, 16 Nov 2015 12:58:48 -0800 (PST) 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: A2DYCQDmQkpWPIYELHldKAECgxCBQoJfgUqCNKR9AQEBAQEBBoszhS2CfYEQhgoCAgEBAoFGTQEBAQEBAQcBAQEBQT+ENAEBAQMBOhwjBQsIAxgJJQ8FJQMHGhOIJge7EQEBAQcCASAZhXSFRYk5BY0biS2NH5xNgnQdgWoqNIUKAQEB Received: from ppp121-44-4-134.lns20.syd4.internode.on.net (HELO dastard) ([121.44.4.134]) by ipmail06.adl2.internode.on.net with ESMTP; 17 Nov 2015 07:28:46 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZyQrN-00068G-UM; Tue, 17 Nov 2015 07:58:45 +1100 Date: Tue, 17 Nov 2015 07:58:45 +1100 From: Dave Chinner To: "Darrick J. Wong" Cc: fstests@vger.kernel.org, xfs@oss.sgi.com, hch@infradead.org, tao.peng@primarydata.com, linux-ext4@vger.kernel.org, Anna.Schumaker@netapp.com, linux-btrfs@vger.kernel.org Subject: Re: [PATCH 01/12] test-scripts: test migration scripts Message-ID: <20151116205845.GK14311@dastard> X-ASG-Orig-Subj: Re: [PATCH 01/12] test-scripts: test migration scripts References: <20151113213643.31124.80975.stgit@birch.djwong.org> <20151113213650.31124.16817.stgit@birch.djwong.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151113213650.31124.16817.stgit@birch.djwong.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: 1447707527 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24449 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header On Fri, Nov 13, 2015 at 01:36:50PM -0800, Darrick J. Wong wrote: > Add two scripts: "nextid" finds the next available test ID number in a > group, and "mvtest" relocates a test, fixes the golden output, and > moves the group entry for that test. > > Signed-off-by: Darrick J. Wong > --- > mvtest | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > nextid | 35 +++++++++++++++++++++++++++++++++++ These should be placed in the "tools" directory. > create mode 100755 mvtest > create mode 100755 nextid > > > diff --git a/mvtest b/mvtest > new file mode 100755 > index 0000000..b5406d1 > --- /dev/null > +++ b/mvtest > @@ -0,0 +1,58 @@ > +#!/bin/sh > + > +# Renumber a test > + > +if [ -z "$1" ] || [ "$1" = "--help" ]; then > + echo "Usage: $0 path_to_test new_path_to_test" > + exit 1 > +fi > + > +src="$1" > +dest="$2" > + > +die() { > + echo "$@" > + exit 1 > +} > + > +nsort() { > + sort -g < "$1" > "$2" > +} > + > +append() { > + out="$1" > + shift > + echo "$@" >> "${out}" > +} > + > +test "${src}" != "${dest}" || die "Test \"${src}\" is the same as dest." > +test -e "tests/${src}" || die "Test \"${src}\" does not exist." > +test ! -e "tests/${dest}" || die "Test \"${src}\" already exists." > + > +sid="$(basename "${src}")" > +did="$(basename "${dest}")" > + > +sgroup="$(basename "$(dirname "tests/${src}")")" > +dgroup="$(basename "$(dirname "tests/${dest}")")" > + > +sgroupfile="tests/${sgroup}/group" > +dgroupfile="tests/${sgroup}/group" > + > +$DBG git mv "tests/${src}" "tests/${dest}" $DBG? .... > +$DBG sed -e "/^${sid}.*$/d" -i "${sgroupfile}" > +$DBG cp "${dgroupfile}" "${dgroupfile}.new" > +$DBG append "${dgroupfile}.new" "${newgrpline}" > +$DBG nsort "${dgroupfile}.new" "${dgroupfile}" What does this do to comments in the group file? ... > diff --git a/nextid b/nextid > new file mode 100755 > index 0000000..285b549 > --- /dev/null > +++ b/nextid > @@ -0,0 +1,35 @@ > +#!/bin/sh > + > +# Given a group name, find the next available test number. > + > +if [ -z "$1" ] || [ "$1" = "--help" ]; then > + echo "Usage: $0 groupname[/start_looking_at_this_number]" > + exit 1 > +fi > + > +die() { > + echo "$@" > + exit 1 > +} > + > +if [ "$(basename "$1")" != "$1" ]; then > + group="$(dirname "$1")" > + id="$(basename "$1")" > +else > + group="$1" > + id=1 > +fi > +test -e "tests/${group}/group" || die "Unknown group \"${group}\"." > + > +while test "${id}" -lt 1000; do > + name="$(printf "%.03d" "${id}")" > + if [ ! -e "tests/${group}/${name}" ]; then > + echo "${group}/${name}" > + exit 0 > + fi > + id=$((id + 1)) > +done > + > +echo "No free IDs less than ${id} in group \"${group}\"." So the "new" script does this differently, by reading the group file and looking for the first non-contiguous ID in the file. It doesn't need scan ID limits because EOF triggers that. Wouldn't it be better to to factor the code out of the "new" script to find the next id, and then have the new script call that? Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Mon Nov 16 16:14:30 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 263A07F54 for ; Mon, 16 Nov 2015 16:14:30 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id AE7C7AC006 for ; Mon, 16 Nov 2015 14:14:29 -0800 (PST) X-ASG-Debug-ID: 1447712065-04cb6c0cd1a3500001-NocioJ Received: from ipmail06.adl2.internode.on.net (ipmail06.adl2.internode.on.net [150.101.137.129]) by cuda.sgi.com with ESMTP id yXOV58MbKTL0dNVK for ; Mon, 16 Nov 2015 14:14:26 -0800 (PST) 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: A2AfCgD7VEpWPIYELHldKAECgxCBAEKCX4N+pH4BAQEBAQEGizOFLYJ9gRCGCgICAQECgUhNAQEBAQEBBwEBAQFBP4Q0AQEBAwE6HCMFCwgDDgoJJQ8FJQMHGhMeiAgHuwsBAQEHAgEgGYV0hUWERIR1BZZIiA6FEY80jRmEeyo0AYNAgUkBAQE Received: from ppp121-44-4-134.lns20.syd4.internode.on.net (HELO dastard) ([121.44.4.134]) by ipmail06.adl2.internode.on.net with ESMTP; 17 Nov 2015 08:44:13 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZyS2O-0006K3-8z; Tue, 17 Nov 2015 09:14:12 +1100 Date: Tue, 17 Nov 2015 09:14:12 +1100 From: Dave Chinner To: Jan Kara Cc: Dan Williams , Andreas Dilger , Ross Zwisler , "linux-kernel@vger.kernel.org" , "H. Peter Anvin" , "J. Bruce Fields" , Theodore Ts'o , Alexander Viro , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4 , linux-fsdevel , Linux MM , "linux-nvdimm@lists.01.org" , X86 ML , XFS Developers , Andrew Morton , Matthew Wilcox , Dave Hansen Subject: Re: [PATCH v2 03/11] pmem: enable REQ_FUA/REQ_FLUSH handling Message-ID: <20151116221412.GV19199@dastard> X-ASG-Orig-Subj: Re: [PATCH v2 03/11] pmem: enable REQ_FUA/REQ_FLUSH handling References: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> <1447459610-14259-4-git-send-email-ross.zwisler@linux.intel.com> <22E0F870-C1FB-431E-BF6C-B395A09A2B0D@dilger.ca> <20151116133714.GB3443@quack.suse.cz> <20151116140526.GA6733@quack.suse.cz> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151116140526.GA6733@quack.suse.cz> 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: 1447712065 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24451 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Mon, Nov 16, 2015 at 03:05:26PM +0100, Jan Kara wrote: > On Mon 16-11-15 14:37:14, Jan Kara wrote: > > On Fri 13-11-15 18:32:40, Dan Williams wrote: > > > On Fri, Nov 13, 2015 at 4:43 PM, Andreas Dilger wrote: > > > > On Nov 13, 2015, at 5:20 PM, Dan Williams wrote: > > > >> > > > >> On Fri, Nov 13, 2015 at 4:06 PM, Ross Zwisler > > > >> wrote: > > > >>> Currently the PMEM driver doesn't accept REQ_FLUSH or REQ_FUA bios. These > > > >>> are sent down via blkdev_issue_flush() in response to a fsync() or msync() > > > >>> and are used by filesystems to order their metadata, among other things. > > > >>> > > > >>> When we get an msync() or fsync() it is the responsibility of the DAX code > > > >>> to flush all dirty pages to media. The PMEM driver then just has issue a > > > >>> wmb_pmem() in response to the REQ_FLUSH to ensure that before we return all > > > >>> the flushed data has been durably stored on the media. > > > >>> > > > >>> Signed-off-by: Ross Zwisler > > > >> > > > >> Hmm, I'm not seeing why we need this patch. If the actual flushing of > > > >> the cache is done by the core why does the driver need support > > > >> REQ_FLUSH? Especially since it's just a couple instructions. REQ_FUA > > > >> only makes sense if individual writes can bypass the "drive" cache, > > > >> but no I/O submitted to the driver proper is ever cached we always > > > >> flush it through to media. > > > > > > > > If the upper level filesystem gets an error when submitting a flush > > > > request, then it assumes the underlying hardware is broken and cannot > > > > be as aggressive in IO submission, but instead has to wait for in-flight > > > > IO to complete. > > > > > > Upper level filesystems won't get errors when the driver does not > > > support flush. Those requests are ended cleanly in > > > generic_make_request_checks(). Yes, the fs still needs to wait for > > > outstanding I/O to complete but in the case of pmem all I/O is > > > synchronous. There's never anything to await when flushing at the > > > pmem driver level. > > > > > > > Since FUA/FLUSH is basically a no-op for pmem devices, > > > > it doesn't make sense _not_ to support this functionality. > > > > > > Seems to be a nop either way. Given that DAX may lead to dirty data > > > pending to the device in the cpu cache that a REQ_FLUSH request will > > > not touch, its better to leave it all to the mm core to handle. I.e. > > > it doesn't make sense to call the driver just for two instructions > > > (sfence + pcommit) when the mm core is taking on the cache flushing. > > > Either handle it all in the mm or the driver, not a mixture. > > > > So I think REQ_FLUSH requests *must* end up doing sfence + pcommit because > > e.g. journal writes going through block layer or writes done through > > dax_do_io() must be on permanent storage once REQ_FLUSH request finishes > > and the way driver does IO doesn't guarantee this, does it? > > Hum, and looking into how dax_do_io() works and what drivers/nvdimm/pmem.c > does, I'm indeed wrong because they both do wmb_pmem() after each write > which seems to include sfence + pcommit. Sorry for confusion. Which I want to remove, because it makes DAX IO 3x slower than buffered IO on ramdisk based testing. > But a question: Won't it be better to do sfence + pcommit only in response > to REQ_FLUSH request and don't do it after each write? I'm not sure how > expensive these instructions are but in theory it could be a performance > win, couldn't it? For filesystems this is enough wrt persistency > guarantees... I'm pretty sure it would be, because all of the overhead (and therefore latency) I measured is in the cache flushing instructions. But before we can remove the wmb_pmem() from dax_do_io(), we need the underlying device to support REQ_FLUSH correctly... Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Mon Nov 16 16:42:31 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 B8F4F7F54 for ; Mon, 16 Nov 2015 16:42:31 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 8C6AA8F8035 for ; Mon, 16 Nov 2015 14:42:28 -0800 (PST) X-ASG-Debug-ID: 1447713744-04bdf07f09ad200001-NocioJ Received: from ipmail06.adl2.internode.on.net (ipmail06.adl2.internode.on.net [150.101.137.129]) by cuda.sgi.com with ESMTP id d9u7n17X2IQ07gV4 for ; Mon, 16 Nov 2015 14:42:25 -0800 (PST) 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: A2CWCQCjWkpWPIYELHldKAECgxCBQoJfg36kfgEBAQEBAQaLM4Utgn2BEIYKAgIBAQKBSE0BAQEBAQEHAQEBAUE/hDUBAQQnExwjEAgDGAklDwUlAwcaE4gtuxsBAQEHAgEgGYV0hUWJOQWWSI0fjzSNGYJ0HYFqKjQBhQkBAQE Received: from ppp121-44-4-134.lns20.syd4.internode.on.net (HELO dastard) ([121.44.4.134]) by ipmail06.adl2.internode.on.net with ESMTP; 17 Nov 2015 09:12:23 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZySTe-0006O5-NX; Tue, 17 Nov 2015 09:42:22 +1100 Date: Tue, 17 Nov 2015 09:42:22 +1100 From: Dave Chinner To: Ross Zwisler Cc: linux-kernel@vger.kernel.org, "H. Peter Anvin" , "J. Bruce Fields" , Theodore Ts'o , Alexander Viro , Andreas Dilger , Dan Williams , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@lists.01.org, x86@kernel.org, xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox , Dave Hansen Subject: Re: [PATCH v2 07/11] mm: add find_get_entries_tag() Message-ID: <20151116224222.GW19199@dastard> X-ASG-Orig-Subj: Re: [PATCH v2 07/11] mm: add find_get_entries_tag() References: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> <1447459610-14259-8-git-send-email-ross.zwisler@linux.intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1447459610-14259-8-git-send-email-ross.zwisler@linux.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: 1447713745 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24452 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri, Nov 13, 2015 at 05:06:46PM -0700, Ross Zwisler wrote: > Add find_get_entries_tag() to the family of functions that include > find_get_entries(), find_get_pages() and find_get_pages_tag(). This is > needed for DAX dirty page handling because we need a list of both page > offsets and radix tree entries ('indices' and 'entries' in this function) > that are marked with the PAGECACHE_TAG_TOWRITE tag. > > Signed-off-by: Ross Zwisler > --- > include/linux/pagemap.h | 3 +++ > mm/filemap.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 64 insertions(+) > > diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h > index a6c78e0..6fea3be 100644 > --- a/include/linux/pagemap.h > +++ b/include/linux/pagemap.h > @@ -354,6 +354,9 @@ unsigned find_get_pages_contig(struct address_space *mapping, pgoff_t start, > unsigned int nr_pages, struct page **pages); > unsigned find_get_pages_tag(struct address_space *mapping, pgoff_t *index, > int tag, unsigned int nr_pages, struct page **pages); > +unsigned find_get_entries_tag(struct address_space *mapping, pgoff_t start, > + int tag, unsigned int nr_entries, > + struct page **entries, pgoff_t *indices); > > struct page *grab_cache_page_write_begin(struct address_space *mapping, > pgoff_t index, unsigned flags); > diff --git a/mm/filemap.c b/mm/filemap.c > index d5e94fd..89ab448 100644 > --- a/mm/filemap.c > +++ b/mm/filemap.c > @@ -1454,6 +1454,67 @@ repeat: > } > EXPORT_SYMBOL(find_get_pages_tag); > > +/** > + * find_get_entries_tag - find and return entries that match @tag > + * @mapping: the address_space to search > + * @start: the starting page cache index > + * @tag: the tag index > + * @nr_entries: the maximum number of entries > + * @entries: where the resulting entries are placed > + * @indices: the cache indices corresponding to the entries in @entries > + * > + * Like find_get_entries, except we only return entries which are tagged with > + * @tag. > + */ > +unsigned find_get_entries_tag(struct address_space *mapping, pgoff_t start, > + int tag, unsigned int nr_entries, > + struct page **entries, pgoff_t *indices) > +{ > + void **slot; > + unsigned int ret = 0; > + struct radix_tree_iter iter; > + > + if (!nr_entries) > + return 0; > + > + rcu_read_lock(); > +restart: > + radix_tree_for_each_tagged(slot, &mapping->page_tree, > + &iter, start, tag) { > + struct page *page; > +repeat: > + page = radix_tree_deref_slot(slot); > + if (unlikely(!page)) > + continue; > + if (radix_tree_exception(page)) { > + if (radix_tree_deref_retry(page)) > + goto restart; That restart condition looks wrong. ret can be non-zero, but we start looking from the original start index again, resulting in duplicates being added to the return arrays... Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Mon Nov 16 16:58:13 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 737377F54 for ; Mon, 16 Nov 2015 16:58:13 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 61DC28F8035 for ; Mon, 16 Nov 2015 14:58:13 -0800 (PST) X-ASG-Debug-ID: 1447714689-04cb6c0cd1a51c0001-NocioJ Received: from ipmail06.adl2.internode.on.net (ipmail06.adl2.internode.on.net [150.101.137.129]) by cuda.sgi.com with ESMTP id TGkCRpTaMhEMCJ97 for ; Mon, 16 Nov 2015 14:58:09 -0800 (PST) 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: A2CWCQBWXkpWPIYELHldKAECgxCBQoJfg36kfgEBAQEBAQaLM4Utgn2BEIYKAgIBAQKBRk0BAQEBAQEHAQEBAUE/hDUBAQQnExwjEAgDGAklDwUlAwcaE4gtuxQBAQEHAgEgGYV0hUWERIR1BYdBhVqBMoQag2GNH4NUmHmCdB2Baio0AYNAgUkBAQE Received: from ppp121-44-4-134.lns20.syd4.internode.on.net (HELO dastard) ([121.44.4.134]) by ipmail06.adl2.internode.on.net with ESMTP; 17 Nov 2015 09:28:07 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZySit-0006Py-30; Tue, 17 Nov 2015 09:58:07 +1100 Date: Tue, 17 Nov 2015 09:58:07 +1100 From: Dave Chinner To: Ross Zwisler Cc: linux-kernel@vger.kernel.org, "H. Peter Anvin" , "J. Bruce Fields" , Theodore Ts'o , Alexander Viro , Andreas Dilger , Dan Williams , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@lists.01.org, x86@kernel.org, xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox , Dave Hansen Subject: Re: [PATCH v2 08/11] dax: add support for fsync/sync Message-ID: <20151116225807.GX19199@dastard> X-ASG-Orig-Subj: Re: [PATCH v2 08/11] dax: add support for fsync/sync References: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> <1447459610-14259-9-git-send-email-ross.zwisler@linux.intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1447459610-14259-9-git-send-email-ross.zwisler@linux.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: 1447714689 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24452 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri, Nov 13, 2015 at 05:06:47PM -0700, Ross Zwisler wrote: > To properly handle fsync/msync in an efficient way DAX needs to track dirty > pages so it is able to flush them durably to media on demand. > > The tracking of dirty pages is done via the radix tree in struct > address_space. This radix tree is already used by the page writeback > infrastructure for tracking dirty pages associated with an open file, and > it already has support for exceptional (non struct page*) entries. We > build upon these features to add exceptional entries to the radix tree for > DAX dirty PMD or PTE pages at fault time. > > When called as part of the msync/fsync flush path DAX queries the radix > tree for dirty entries, flushing them and then marking the PTE or PMD page > table entries as clean. The step of cleaning the PTE or PMD entries is > necessary so that on subsequent writes to the same page we get a new write > fault allowing us to once again dirty the DAX tag in the radix tree. > > Signed-off-by: Ross Zwisler > --- > fs/dax.c | 140 +++++++++++++++++++++++++++++++++++++++++++++++++--- > include/linux/dax.h | 1 + > mm/huge_memory.c | 14 +++--- > 3 files changed, 141 insertions(+), 14 deletions(-) > > diff --git a/fs/dax.c b/fs/dax.c > index 131fd35a..9ce6d1b 100644 > --- a/fs/dax.c > +++ b/fs/dax.c > @@ -24,7 +24,9 @@ > #include > #include > #include > +#include > #include > +#include > #include > #include > #include > @@ -287,6 +289,53 @@ static int copy_user_bh(struct page *to, struct buffer_head *bh, > return 0; > } > > +static int dax_dirty_pgoff(struct address_space *mapping, unsigned long pgoff, > + void __pmem *addr, bool pmd_entry) > +{ > + struct radix_tree_root *page_tree = &mapping->page_tree; > + int error = 0; > + void *entry; > + > + __mark_inode_dirty(mapping->host, I_DIRTY_PAGES); > + > + spin_lock_irq(&mapping->tree_lock); > + entry = radix_tree_lookup(page_tree, pgoff); > + if (addr == NULL) { > + if (entry) > + goto dirty; > + else { > + WARN(1, "DAX pfn_mkwrite failed to find an entry"); > + goto out; > + } > + } > + > + if (entry) { > + if (pmd_entry && RADIX_DAX_TYPE(entry) == RADIX_DAX_PTE) { > + radix_tree_delete(&mapping->page_tree, pgoff); > + mapping->nrdax--; > + } else > + goto dirty; > + } Logic is pretty spagettied here. Perhaps: entry = radix_tree_lookup(page_tree, pgoff); if (entry) { if (!pmd_entry || RADIX_DAX_TYPE(entry) == RADIX_DAX_PMD)) goto dirty; radix_tree_delete(&mapping->page_tree, pgoff); mapping->nrdax--; } else { WARN_ON(!addr); goto out_unlock; } .... > + > + BUG_ON(RADIX_DAX_TYPE(addr)); > + if (pmd_entry) > + error = radix_tree_insert(page_tree, pgoff, > + RADIX_DAX_PMD_ENTRY(addr)); > + else > + error = radix_tree_insert(page_tree, pgoff, > + RADIX_DAX_PTE_ENTRY(addr)); > + > + if (error) > + goto out; > + > + mapping->nrdax++; > + dirty: > + radix_tree_tag_set(page_tree, pgoff, PAGECACHE_TAG_DIRTY); > + out: > + spin_unlock_irq(&mapping->tree_lock); label should be "out_unlock" rather "out" to indicate in the code that we are jumping to the correct spot in the error stack... > + goto fallback; > } > > out: > @@ -689,15 +746,12 @@ EXPORT_SYMBOL_GPL(dax_pmd_fault); > * dax_pfn_mkwrite - handle first write to DAX page > * @vma: The virtual memory area where the fault occurred > * @vmf: The description of the fault > - * > */ > int dax_pfn_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) > { > - struct super_block *sb = file_inode(vma->vm_file)->i_sb; > + struct file *file = vma->vm_file; > > - sb_start_pagefault(sb); > - file_update_time(vma->vm_file); > - sb_end_pagefault(sb); > + dax_dirty_pgoff(file->f_mapping, vmf->pgoff, NULL, false); > return VM_FAULT_NOPAGE; This seems wrong - it's dropping the freeze protection on fault, and now the inode timestamp won't get updated, either. > } > EXPORT_SYMBOL_GPL(dax_pfn_mkwrite); > @@ -772,3 +826,77 @@ int dax_truncate_page(struct inode *inode, loff_t from, get_block_t get_block) > return dax_zero_page_range(inode, from, length, get_block); > } > EXPORT_SYMBOL_GPL(dax_truncate_page); > + > +static void dax_sync_entry(struct address_space *mapping, pgoff_t pgoff, > + void *entry) > +{ dax_writeback_pgoff() seems like a more consistent name (consider dax_dirty_pgoff), and that we are actually doing a writeback operation, not a "sync" operation. > + struct radix_tree_root *page_tree = &mapping->page_tree; > + int type = RADIX_DAX_TYPE(entry); > + size_t size; > + > + BUG_ON(type != RADIX_DAX_PTE && type != RADIX_DAX_PMD); > + > + spin_lock_irq(&mapping->tree_lock); > + if (!radix_tree_tag_get(page_tree, pgoff, PAGECACHE_TAG_TOWRITE)) { > + /* another fsync thread already wrote back this entry */ > + spin_unlock_irq(&mapping->tree_lock); > + return; > + } > + radix_tree_tag_clear(page_tree, pgoff, PAGECACHE_TAG_TOWRITE); > + radix_tree_tag_clear(page_tree, pgoff, PAGECACHE_TAG_DIRTY); > + spin_unlock_irq(&mapping->tree_lock); > + > + if (type == RADIX_DAX_PMD) > + size = PMD_SIZE; > + else > + size = PAGE_SIZE; > + > + wb_cache_pmem(RADIX_DAX_ADDR(entry), size); > + pgoff_mkclean(pgoff, mapping); This looks racy w.r.t. another operation setting the radix tree dirty tags. i.e. there is no locking to serialise marking the vma/pte clean and another operation marking the radix tree dirty. > +} > + > +/* > + * Flush the mapping to the persistent domain within the byte range of (start, > + * end). This is required by data integrity operations to ensure file data is on > + * persistent storage prior to completion of the operation. It also requires us > + * to clean the mappings (i.e. write -> RO) so that we'll get a new fault when > + * the file is written to again so we have an indication that we need to flush > + * the mapping if a data integrity operation takes place. > + * > + * We don't need commits to storage here - the filesystems will issue flushes > + * appropriately at the conclusion of the data integrity operation via REQ_FUA > + * writes or blkdev_issue_flush() commands. This requires the DAX block device > + * to implement persistent storage domain fencing/commits on receiving a > + * REQ_FLUSH or REQ_FUA request so that this works as expected by the higher > + * layers. > + */ > +void dax_fsync(struct address_space *mapping, loff_t start, loff_t end) > +{ dax_writeback_mapping_range() Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Mon Nov 16 17:12:30 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 6FBE57F54 for ; Mon, 16 Nov 2015 17:12:30 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 354B38F8033 for ; Mon, 16 Nov 2015 15:12:27 -0800 (PST) X-ASG-Debug-ID: 1447715544-04bdf07f07ae620001-NocioJ Received: from ipmail06.adl2.internode.on.net (ipmail06.adl2.internode.on.net [150.101.137.129]) by cuda.sgi.com with ESMTP id z136fcuSCrD9JZIa for ; Mon, 16 Nov 2015 15:12:24 -0800 (PST) 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: A2CWCQBpYUpWPIYELHldKAECgxCBQoJfg36kfgEBAQEBAQaLM4Utgn2BEIYKAgIBAQKBRk0BAQEBAQEHAQEBAUE/hDUBAQQnExwjEAgDGAklDwUlAwcaE4gtuyABAQgCASAZhXSFRYk5BZZIjR+cTYR7KjQBhQkBAQE Received: from ppp121-44-4-134.lns20.syd4.internode.on.net (HELO dastard) ([121.44.4.134]) by ipmail06.adl2.internode.on.net with ESMTP; 17 Nov 2015 09:42:22 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZySwg-0006RX-8b; Tue, 17 Nov 2015 10:12:22 +1100 Date: Tue, 17 Nov 2015 10:12:22 +1100 From: Dave Chinner To: Ross Zwisler Cc: linux-kernel@vger.kernel.org, "H. Peter Anvin" , "J. Bruce Fields" , Theodore Ts'o , Alexander Viro , Andreas Dilger , Dan Williams , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@lists.01.org, x86@kernel.org, xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox , Dave Hansen Subject: Re: [PATCH v2 11/11] xfs: add support for DAX fsync/msync Message-ID: <20151116231222.GY19199@dastard> X-ASG-Orig-Subj: Re: [PATCH v2 11/11] xfs: add support for DAX fsync/msync References: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> <1447459610-14259-12-git-send-email-ross.zwisler@linux.intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1447459610-14259-12-git-send-email-ross.zwisler@linux.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: 1447715544 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24453 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri, Nov 13, 2015 at 05:06:50PM -0700, Ross Zwisler wrote: > To properly support the new DAX fsync/msync infrastructure filesystems > need to call dax_pfn_mkwrite() so that DAX can properly track when a user > write faults on a previously cleaned address. They also need to call > dax_fsync() in the filesystem fsync() path. This dax_fsync() call uses > addresses retrieved from get_block() so it needs to be ordered with > respect to truncate. This is accomplished by using the same locking that > was set up for DAX page faults. > > Signed-off-by: Ross Zwisler > --- > fs/xfs/xfs_file.c | 18 +++++++++++++----- > 1 file changed, 13 insertions(+), 5 deletions(-) > > diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c > index 39743ef..2b490a1 100644 > --- a/fs/xfs/xfs_file.c > +++ b/fs/xfs/xfs_file.c > @@ -209,7 +209,8 @@ xfs_file_fsync( > loff_t end, > int datasync) > { > - struct inode *inode = file->f_mapping->host; > + struct address_space *mapping = file->f_mapping; > + struct inode *inode = mapping->host; > struct xfs_inode *ip = XFS_I(inode); > struct xfs_mount *mp = ip->i_mount; > int error = 0; > @@ -218,7 +219,13 @@ xfs_file_fsync( > > trace_xfs_file_fsync(ip); > > - error = filemap_write_and_wait_range(inode->i_mapping, start, end); > + if (dax_mapping(mapping)) { > + xfs_ilock(XFS_I(inode), XFS_MMAPLOCK_SHARED); > + dax_fsync(mapping, start, end); > + xfs_iunlock(XFS_I(inode), XFS_MMAPLOCK_SHARED); > + } > + > + error = filemap_write_and_wait_range(mapping, start, end); Ok, I don't understand a couple of things here. Firstly, if it's a DAX mapping, why are we still calling filemap_write_and_wait_range() after the dax_fsync() call that has already written back all the dirty cachelines? Secondly, exactly what is the XFS_MMAPLOCK_SHARED lock supposed to be doing here? I don't see where dax_fsync() has any callouts to get_block(), so the comment "needs to be ordered with respect to truncate" doesn't make any obvious sense. If we have a racing truncate removing entries from the radix tree, then thanks to the mapping tree lock we'll either find an entry we need to write back, or we won't find any entry at all, right? Lastly, this flushing really needs to be inside filemap_write_and_wait_range(), because we call the writeback code from many more places than just fsync to ensure ordering of various operations such that files are in known state before proceeding (e.g. hole punch). Cheers, Dave. -- Dave Chinner david@fromorbit.com From ross.zwisler@linux.intel.com Mon Nov 16 17:29:35 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 2CF5F7F4E for ; Mon, 16 Nov 2015 17:29:35 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 0D851304043 for ; Mon, 16 Nov 2015 15:29:31 -0800 (PST) X-ASG-Debug-ID: 1447716570-04cbb0605bc8cc0001-NocioJ Received: from mga11.intel.com ([192.55.52.93]) by cuda.sgi.com with ESMTP id D6YYgepJbHbblwqn for ; Mon, 16 Nov 2015 15:29:30 -0800 (PST) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 192.55.52.93 X-ASG-Whitelist: EmailCat (corporate) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga102.fm.intel.com with ESMTP; 16 Nov 2015 15:29:29 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,304,1444719600"; d="scan'208";a="821681064" Received: from theros.lm.intel.com (HELO linux.intel.com) ([10.232.112.87]) by orsmga001.jf.intel.com with ESMTP; 16 Nov 2015 15:29:28 -0800 Date: Mon, 16 Nov 2015 16:29:27 -0700 From: Ross Zwisler To: Dave Chinner Cc: Jan Kara , Dan Williams , Andreas Dilger , Ross Zwisler , "linux-kernel@vger.kernel.org" , "H. Peter Anvin" , "J. Bruce Fields" , Theodore Ts'o , Alexander Viro , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4 , linux-fsdevel , Linux MM , "linux-nvdimm@lists.01.org" , X86 ML , XFS Developers , Andrew Morton , Matthew Wilcox , Dave Hansen Subject: Re: [PATCH v2 03/11] pmem: enable REQ_FUA/REQ_FLUSH handling Message-ID: <20151116232927.GA5582@linux.intel.com> X-ASG-Orig-Subj: Re: [PATCH v2 03/11] pmem: enable REQ_FUA/REQ_FLUSH handling Mail-Followup-To: Ross Zwisler , Dave Chinner , Jan Kara , Dan Williams , Andreas Dilger , "linux-kernel@vger.kernel.org" , "H. Peter Anvin" , "J. Bruce Fields" , Theodore Ts'o , Alexander Viro , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4 , linux-fsdevel , Linux MM , "linux-nvdimm@lists.01.org" , X86 ML , XFS Developers , Andrew Morton , Matthew Wilcox , Dave Hansen References: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> <1447459610-14259-4-git-send-email-ross.zwisler@linux.intel.com> <22E0F870-C1FB-431E-BF6C-B395A09A2B0D@dilger.ca> <20151116133714.GB3443@quack.suse.cz> <20151116140526.GA6733@quack.suse.cz> <20151116221412.GV19199@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151116221412.GV19199@dastard> User-Agent: Mutt/1.5.23 (2014-03-12) X-Barracuda-Connect: UNKNOWN[192.55.52.93] X-Barracuda-Start-Time: 1447716570 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Tue, Nov 17, 2015 at 09:14:12AM +1100, Dave Chinner wrote: > On Mon, Nov 16, 2015 at 03:05:26PM +0100, Jan Kara wrote: > > On Mon 16-11-15 14:37:14, Jan Kara wrote: > > > On Fri 13-11-15 18:32:40, Dan Williams wrote: > > > > On Fri, Nov 13, 2015 at 4:43 PM, Andreas Dilger wrote: > > > > > On Nov 13, 2015, at 5:20 PM, Dan Williams wrote: > > > > >> > > > > >> On Fri, Nov 13, 2015 at 4:06 PM, Ross Zwisler > > > > >> wrote: > > > > >>> Currently the PMEM driver doesn't accept REQ_FLUSH or REQ_FUA bios. These > > > > >>> are sent down via blkdev_issue_flush() in response to a fsync() or msync() > > > > >>> and are used by filesystems to order their metadata, among other things. > > > > >>> > > > > >>> When we get an msync() or fsync() it is the responsibility of the DAX code > > > > >>> to flush all dirty pages to media. The PMEM driver then just has issue a > > > > >>> wmb_pmem() in response to the REQ_FLUSH to ensure that before we return all > > > > >>> the flushed data has been durably stored on the media. > > > > >>> > > > > >>> Signed-off-by: Ross Zwisler > > > > >> > > > > >> Hmm, I'm not seeing why we need this patch. If the actual flushing of > > > > >> the cache is done by the core why does the driver need support > > > > >> REQ_FLUSH? Especially since it's just a couple instructions. REQ_FUA > > > > >> only makes sense if individual writes can bypass the "drive" cache, > > > > >> but no I/O submitted to the driver proper is ever cached we always > > > > >> flush it through to media. > > > > > > > > > > If the upper level filesystem gets an error when submitting a flush > > > > > request, then it assumes the underlying hardware is broken and cannot > > > > > be as aggressive in IO submission, but instead has to wait for in-flight > > > > > IO to complete. > > > > > > > > Upper level filesystems won't get errors when the driver does not > > > > support flush. Those requests are ended cleanly in > > > > generic_make_request_checks(). Yes, the fs still needs to wait for > > > > outstanding I/O to complete but in the case of pmem all I/O is > > > > synchronous. There's never anything to await when flushing at the > > > > pmem driver level. > > > > > > > > > Since FUA/FLUSH is basically a no-op for pmem devices, > > > > > it doesn't make sense _not_ to support this functionality. > > > > > > > > Seems to be a nop either way. Given that DAX may lead to dirty data > > > > pending to the device in the cpu cache that a REQ_FLUSH request will > > > > not touch, its better to leave it all to the mm core to handle. I.e. > > > > it doesn't make sense to call the driver just for two instructions > > > > (sfence + pcommit) when the mm core is taking on the cache flushing. > > > > Either handle it all in the mm or the driver, not a mixture. > > > > > > So I think REQ_FLUSH requests *must* end up doing sfence + pcommit because > > > e.g. journal writes going through block layer or writes done through > > > dax_do_io() must be on permanent storage once REQ_FLUSH request finishes > > > and the way driver does IO doesn't guarantee this, does it? > > > > Hum, and looking into how dax_do_io() works and what drivers/nvdimm/pmem.c > > does, I'm indeed wrong because they both do wmb_pmem() after each write > > which seems to include sfence + pcommit. Sorry for confusion. > > Which I want to remove, because it makes DAX IO 3x slower than > buffered IO on ramdisk based testing. > > > But a question: Won't it be better to do sfence + pcommit only in response > > to REQ_FLUSH request and don't do it after each write? I'm not sure how > > expensive these instructions are but in theory it could be a performance > > win, couldn't it? For filesystems this is enough wrt persistency > > guarantees... > > I'm pretty sure it would be, because all of the overhead (and > therefore latency) I measured is in the cache flushing instructions. > But before we can remove the wmb_pmem() from dax_do_io(), we need > the underlying device to support REQ_FLUSH correctly... By "support REQ_FLUSH correctly" do you mean call wmb_pmem() as I do in my set? Or do you mean something that also involves cache flushing such as the "big hammer" that flushes everything or something like WBINVD? From david@fromorbit.com Mon Nov 16 17:42:52 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 BF6357F4E for ; Mon, 16 Nov 2015 17:42:52 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 9E641304032 for ; Mon, 16 Nov 2015 15:42:52 -0800 (PST) X-ASG-Debug-ID: 1447717369-04cbb0605dc9a30001-NocioJ Received: from ipmail06.adl2.internode.on.net (ipmail06.adl2.internode.on.net [150.101.137.129]) by cuda.sgi.com with ESMTP id x5Qfq12CSUMG6xoJ for ; Mon, 16 Nov 2015 15:42:49 -0800 (PST) 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: A2ApDwC6aEpWPIYELHldDoMtgQBChl2kfgEBAQEBAQaLM4Utgn2BEIYKAgIBAQKBRk0BAQEBAQEHAQEBAUE/hDUBAQQ6HDMIAxgJJQ8FJQMHGgESHogPuyoBCyEZhXSFRYREhHUFlkmIDoURjzSNGYQpUio0AYNAgUkBAQE Received: from ppp121-44-4-134.lns20.syd4.internode.on.net (HELO dastard) ([121.44.4.134]) by ipmail06.adl2.internode.on.net with ESMTP; 17 Nov 2015 10:12:47 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZyTQ6-0006Ur-A0; Tue, 17 Nov 2015 10:42:46 +1100 Date: Tue, 17 Nov 2015 10:42:46 +1100 From: Dave Chinner To: Ross Zwisler , Jan Kara , Dan Williams , Andreas Dilger , "linux-kernel@vger.kernel.org" , "H. Peter Anvin" , "J. Bruce Fields" , Theodore Ts'o , Alexander Viro , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4 , linux-fsdevel , Linux MM , "linux-nvdimm@lists.01.org" , X86 ML , XFS Developers , Andrew Morton , Matthew Wilcox , Dave Hansen Subject: Re: [PATCH v2 03/11] pmem: enable REQ_FUA/REQ_FLUSH handling Message-ID: <20151116234246.GZ19199@dastard> X-ASG-Orig-Subj: Re: [PATCH v2 03/11] pmem: enable REQ_FUA/REQ_FLUSH handling References: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> <1447459610-14259-4-git-send-email-ross.zwisler@linux.intel.com> <22E0F870-C1FB-431E-BF6C-B395A09A2B0D@dilger.ca> <20151116133714.GB3443@quack.suse.cz> <20151116140526.GA6733@quack.suse.cz> <20151116221412.GV19199@dastard> <20151116232927.GA5582@linux.intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151116232927.GA5582@linux.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: 1447717369 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24454 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Mon, Nov 16, 2015 at 04:29:27PM -0700, Ross Zwisler wrote: > On Tue, Nov 17, 2015 at 09:14:12AM +1100, Dave Chinner wrote: > > On Mon, Nov 16, 2015 at 03:05:26PM +0100, Jan Kara wrote: > > > On Mon 16-11-15 14:37:14, Jan Kara wrote: > > > > On Fri 13-11-15 18:32:40, Dan Williams wrote: > > > > > On Fri, Nov 13, 2015 at 4:43 PM, Andreas Dilger wrote: > > > > > > On Nov 13, 2015, at 5:20 PM, Dan Williams wrote: > > > > > >> > > > > > >> On Fri, Nov 13, 2015 at 4:06 PM, Ross Zwisler > > > > > >> wrote: > > > > > >>> Currently the PMEM driver doesn't accept REQ_FLUSH or REQ_FUA bios. These > > > > > >>> are sent down via blkdev_issue_flush() in response to a fsync() or msync() > > > > > >>> and are used by filesystems to order their metadata, among other things. > > > > > >>> > > > > > >>> When we get an msync() or fsync() it is the responsibility of the DAX code > > > > > >>> to flush all dirty pages to media. The PMEM driver then just has issue a > > > > > >>> wmb_pmem() in response to the REQ_FLUSH to ensure that before we return all > > > > > >>> the flushed data has been durably stored on the media. > > > > > >>> > > > > > >>> Signed-off-by: Ross Zwisler > > > > > >> > > > > > >> Hmm, I'm not seeing why we need this patch. If the actual flushing of > > > > > >> the cache is done by the core why does the driver need support > > > > > >> REQ_FLUSH? Especially since it's just a couple instructions. REQ_FUA > > > > > >> only makes sense if individual writes can bypass the "drive" cache, > > > > > >> but no I/O submitted to the driver proper is ever cached we always > > > > > >> flush it through to media. > > > > > > > > > > > > If the upper level filesystem gets an error when submitting a flush > > > > > > request, then it assumes the underlying hardware is broken and cannot > > > > > > be as aggressive in IO submission, but instead has to wait for in-flight > > > > > > IO to complete. > > > > > > > > > > Upper level filesystems won't get errors when the driver does not > > > > > support flush. Those requests are ended cleanly in > > > > > generic_make_request_checks(). Yes, the fs still needs to wait for > > > > > outstanding I/O to complete but in the case of pmem all I/O is > > > > > synchronous. There's never anything to await when flushing at the > > > > > pmem driver level. > > > > > > > > > > > Since FUA/FLUSH is basically a no-op for pmem devices, > > > > > > it doesn't make sense _not_ to support this functionality. > > > > > > > > > > Seems to be a nop either way. Given that DAX may lead to dirty data > > > > > pending to the device in the cpu cache that a REQ_FLUSH request will > > > > > not touch, its better to leave it all to the mm core to handle. I.e. > > > > > it doesn't make sense to call the driver just for two instructions > > > > > (sfence + pcommit) when the mm core is taking on the cache flushing. > > > > > Either handle it all in the mm or the driver, not a mixture. > > > > > > > > So I think REQ_FLUSH requests *must* end up doing sfence + pcommit because > > > > e.g. journal writes going through block layer or writes done through > > > > dax_do_io() must be on permanent storage once REQ_FLUSH request finishes > > > > and the way driver does IO doesn't guarantee this, does it? > > > > > > Hum, and looking into how dax_do_io() works and what drivers/nvdimm/pmem.c > > > does, I'm indeed wrong because they both do wmb_pmem() after each write > > > which seems to include sfence + pcommit. Sorry for confusion. > > > > Which I want to remove, because it makes DAX IO 3x slower than > > buffered IO on ramdisk based testing. > > > > > But a question: Won't it be better to do sfence + pcommit only in response > > > to REQ_FLUSH request and don't do it after each write? I'm not sure how > > > expensive these instructions are but in theory it could be a performance > > > win, couldn't it? For filesystems this is enough wrt persistency > > > guarantees... > > > > I'm pretty sure it would be, because all of the overhead (and > > therefore latency) I measured is in the cache flushing instructions. > > But before we can remove the wmb_pmem() from dax_do_io(), we need > > the underlying device to support REQ_FLUSH correctly... > > By "support REQ_FLUSH correctly" do you mean call wmb_pmem() as I do in my > set? Or do you mean something that also involves cache flushing such as the > "big hammer" that flushes everything or something like WBINVD? Either. Both solve the problem of defering the cache flush penalty to the context that needs it.. Cheers, Dave. -- Dave Chinner david@fromorbit.com From darrick.wong@oracle.com Mon Nov 16 17:51:50 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 9F5BC7F4E for ; Mon, 16 Nov 2015 17:51:50 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 8BDCA304039 for ; Mon, 16 Nov 2015 15:51:50 -0800 (PST) X-ASG-Debug-ID: 1447717908-04cbb0605cc9f30001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id OjaGxsxsnk8eQaph (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 16 Nov 2015 15:51:48 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tAGNpFr4009016 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Mon, 16 Nov 2015 23:51:16 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id tAGNpDHv026944 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Mon, 16 Nov 2015 23:51:14 GMT Received: from abhmp0003.oracle.com (abhmp0003.oracle.com [141.146.116.9]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id tAGNpDQq021777; Mon, 16 Nov 2015 23:51:13 GMT Received: from localhost (/10.145.178.207) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Mon, 16 Nov 2015 15:51:13 -0800 Date: Mon, 16 Nov 2015 15:51:11 -0800 From: "Darrick J. Wong" To: Dave Chinner Cc: fstests@vger.kernel.org, xfs@oss.sgi.com, hch@infradead.org, tao.peng@primarydata.com, linux-ext4@vger.kernel.org, Anna.Schumaker@netapp.com, linux-btrfs@vger.kernel.org Subject: Re: [PATCH 01/12] test-scripts: test migration scripts Message-ID: <20151116235111.GE2224@birch.djwong.org> X-ASG-Orig-Subj: Re: [PATCH 01/12] test-scripts: test migration scripts References: <20151113213643.31124.80975.stgit@birch.djwong.org> <20151113213650.31124.16817.stgit@birch.djwong.org> <20151116205845.GK14311@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151116205845.GK14311@dastard> User-Agent: Mutt/1.5.21 (2010-09-15) X-Source-IP: userv0021.oracle.com [156.151.31.71] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1447717908 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24455 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines On Tue, Nov 17, 2015 at 07:58:45AM +1100, Dave Chinner wrote: > On Fri, Nov 13, 2015 at 01:36:50PM -0800, Darrick J. Wong wrote: > > Add two scripts: "nextid" finds the next available test ID number in a > > group, and "mvtest" relocates a test, fixes the golden output, and > > moves the group entry for that test. > > > > Signed-off-by: Darrick J. Wong > > --- > > mvtest | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > > nextid | 35 +++++++++++++++++++++++++++++++++++ > > These should be placed in the "tools" directory. > > > create mode 100755 mvtest > > create mode 100755 nextid > > > > > > diff --git a/mvtest b/mvtest > > new file mode 100755 > > index 0000000..b5406d1 > > --- /dev/null > > +++ b/mvtest > > @@ -0,0 +1,58 @@ > > +#!/bin/sh > > + > > +# Renumber a test > > + > > +if [ -z "$1" ] || [ "$1" = "--help" ]; then > > + echo "Usage: $0 path_to_test new_path_to_test" > > + exit 1 > > +fi > > + > > +src="$1" > > +dest="$2" > > + > > +die() { > > + echo "$@" > > + exit 1 > > +} > > + > > +nsort() { > > + sort -g < "$1" > "$2" > > +} > > + > > +append() { > > + out="$1" > > + shift > > + echo "$@" >> "${out}" > > +} > > + > > +test "${src}" != "${dest}" || die "Test \"${src}\" is the same as dest." > > +test -e "tests/${src}" || die "Test \"${src}\" does not exist." > > +test ! -e "tests/${dest}" || die "Test \"${src}\" already exists." > > + > > +sid="$(basename "${src}")" > > +did="$(basename "${dest}")" > > + > > +sgroup="$(basename "$(dirname "tests/${src}")")" > > +dgroup="$(basename "$(dirname "tests/${dest}")")" > > + > > +sgroupfile="tests/${sgroup}/group" > > +dgroupfile="tests/${sgroup}/group" > > + > > +$DBG git mv "tests/${src}" "tests/${dest}" > > $DBG? "DBG=echo ./mvtest foo bar" to see what it would have run, more or less. (I suppose I could getopt a --dry-run, but I could also just get rid of them.) > > .... > > +$DBG sed -e "/^${sid}.*$/d" -i "${sgroupfile}" > > +$DBG cp "${dgroupfile}" "${dgroupfile}.new" > > +$DBG append "${dgroupfile}.new" "${newgrpline}" > > +$DBG nsort "${dgroupfile}.new" "${dgroupfile}" > > What does this do to comments in the group file? Eats them. I don't know of a good way to sort just the uncommented lines in the file, short of writing a python script to do that. I guess it's not that hard; I've sort of needed one here and there over the years, but never wrote one, and $google doesn't immediately provide any such thing. > > ... > > > diff --git a/nextid b/nextid > > new file mode 100755 > > index 0000000..285b549 > > --- /dev/null > > +++ b/nextid > > @@ -0,0 +1,35 @@ > > +#!/bin/sh > > + > > +# Given a group name, find the next available test number. > > + > > +if [ -z "$1" ] || [ "$1" = "--help" ]; then > > + echo "Usage: $0 groupname[/start_looking_at_this_number]" > > + exit 1 > > +fi > > + > > +die() { > > + echo "$@" > > + exit 1 > > +} > > + > > +if [ "$(basename "$1")" != "$1" ]; then > > + group="$(dirname "$1")" > > + id="$(basename "$1")" > > +else > > + group="$1" > > + id=1 > > +fi > > +test -e "tests/${group}/group" || die "Unknown group \"${group}\"." > > + > > +while test "${id}" -lt 1000; do > > + name="$(printf "%.03d" "${id}")" > > + if [ ! -e "tests/${group}/${name}" ]; then > > + echo "${group}/${name}" > > + exit 0 > > + fi > > + id=$((id + 1)) > > +done > > + > > +echo "No free IDs less than ${id} in group \"${group}\"." > > So the "new" script does this differently, by reading the group > file and looking for the first non-contiguous ID in the file. It > doesn't need scan ID limits because EOF triggers that. Wouldn't it > be better to to factor the code out of the "new" script to find the > next id, and then have the new script call that? Sure! --D > > Cheers, > > Dave. > -- > Dave Chinner > david@fromorbit.com > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From ross.zwisler@linux.intel.com Mon Nov 16 17:57:35 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 3883D7F4E for ; Mon, 16 Nov 2015 17:57:35 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id CE64AAC002 for ; Mon, 16 Nov 2015 15:57:31 -0800 (PST) X-ASG-Debug-ID: 1447718250-04bdf07f0ab0240001-NocioJ Received: from mga14.intel.com ([192.55.52.115]) by cuda.sgi.com with ESMTP id GZ3OmQ5n0m76EggZ for ; Mon, 16 Nov 2015 15:57:30 -0800 (PST) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 192.55.52.115 Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga103.fm.intel.com with ESMTP; 16 Nov 2015 15:57:25 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,305,1444719600"; d="scan'208";a="601443893" Received: from theros.lm.intel.com (HELO linux.intel.com) ([10.232.112.87]) by FMSMGA003.fm.intel.com with ESMTP; 16 Nov 2015 15:57:26 -0800 Date: Mon, 16 Nov 2015 16:57:24 -0700 From: Ross Zwisler To: Dan Williams Cc: Ross Zwisler , Jan Kara , Andreas Dilger , "linux-kernel@vger.kernel.org" , "H. Peter Anvin" , "J. Bruce Fields" , Theodore Ts'o , Alexander Viro , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4 , linux-fsdevel , Linux MM , "linux-nvdimm@lists.01.org" , X86 ML , XFS Developers , Andrew Morton , Matthew Wilcox , Dave Hansen Subject: Re: [PATCH v2 03/11] pmem: enable REQ_FUA/REQ_FLUSH handling Message-ID: <20151116235724.GA10256@linux.intel.com> X-ASG-Orig-Subj: Re: [PATCH v2 03/11] pmem: enable REQ_FUA/REQ_FLUSH handling Mail-Followup-To: Ross Zwisler , Dan Williams , Jan Kara , Andreas Dilger , "linux-kernel@vger.kernel.org" , "H. Peter Anvin" , "J. Bruce Fields" , Theodore Ts'o , Alexander Viro , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4 , linux-fsdevel , Linux MM , "linux-nvdimm@lists.01.org" , X86 ML , XFS Developers , Andrew Morton , Matthew Wilcox , Dave Hansen References: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> <1447459610-14259-4-git-send-email-ross.zwisler@linux.intel.com> <22E0F870-C1FB-431E-BF6C-B395A09A2B0D@dilger.ca> <20151116133714.GB3443@quack.suse.cz> <20151116140526.GA6733@quack.suse.cz> <20151116194846.GB32203@linux.intel.com> 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-Barracuda-Connect: UNKNOWN[192.55.52.115] X-Barracuda-Start-Time: 1447718250 X-Barracuda-URL: https://192.48.157.11:443/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.24456 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS On Mon, Nov 16, 2015 at 12:34:55PM -0800, Dan Williams wrote: > On Mon, Nov 16, 2015 at 11:48 AM, Ross Zwisler > wrote: > > On Mon, Nov 16, 2015 at 09:28:59AM -0800, Dan Williams wrote: > >> On Mon, Nov 16, 2015 at 6:05 AM, Jan Kara wrote: > >> > On Mon 16-11-15 14:37:14, Jan Kara wrote: > [..] > > Is there any reason why this wouldn't work or wouldn't be a good idea? > > We don't have numbers to support the claim that pcommit is so > expensive as to need be deferred, especially if the upper layers are > already taking the hit on doing the flushes. > > REQ_FLUSH, means flush your volatile write cache. Currently all I/O > through the driver never hits a volatile cache so there's no need to > tell the block layer that we have a volatile write cache, especially > when you have the core mm taking responsibility for doing cache > maintenance for dax-mmap ranges. > > We also don't have numbers on if/when wbinvd is a more performant solution. > > tl;dr Now that we have a baseline implementation can we please use > data to make future arch decisions? Sure, fair enough. From darrick.wong@oracle.com Mon Nov 16 18:28:54 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 50DCA7F4E for ; Mon, 16 Nov 2015 18:28:54 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id C1997AC003 for ; Mon, 16 Nov 2015 16:28:50 -0800 (PST) X-ASG-Debug-ID: 1447720128-04cb6c0cd4a84a0001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id enaqLZ2skBMoLRxm (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 16 Nov 2015 16:28:48 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tAH0SO1F013262 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Tue, 17 Nov 2015 00:28:25 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id tAH0SOE5009092 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Tue, 17 Nov 2015 00:28:24 GMT Received: from abhmp0006.oracle.com (abhmp0006.oracle.com [141.146.116.12]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id tAH0SNmO031634; Tue, 17 Nov 2015 00:28:24 GMT Received: from localhost (/10.145.178.207) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Mon, 16 Nov 2015 16:28:23 -0800 Date: Mon, 16 Nov 2015 16:28:22 -0800 From: "Darrick J. Wong" To: Christoph Hellwig Cc: xfs@oss.sgi.com, linux-fsdevel@vger.kernel.org Subject: Re: clone ioctl return values Message-ID: <20151117002822.GA32467@birch.djwong.org> X-ASG-Orig-Subj: Re: clone ioctl return values References: <20151116120431.GA2860@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151116120431.GA2860@infradead.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-Source-IP: aserv0022.oracle.com [141.146.126.234] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1447720128 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24457 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines On Mon, Nov 16, 2015 at 04:04:31AM -0800, Christoph Hellwig wrote: > Hi Darrick, > > your new generic/157 xfs test brings up an interesting issue: error > returns forthe various clone failure cases. It seems like this case > was written fo the XFS case which differs a lot from the error chosen > by btrfs and mostly followed by NFS. I'd say it might be a better idea > to follow the btrfs example as the btrfs ioctls have been in use for > a while. The only shortcoming I see in btrfs is that id doesn't > explicitly check for non-directory, non-regular file items as the > source. I have to admit I'm kinda surprised that it doesn't blow up, > given that NFS instantly did when I removed those checks. > > FYI, output from the test on btrfs below: > > > --- tests/generic/157.out 2015-11-14 07:56:31.000000000 +0000 > +++ /root/xfstests/results//generic/157.out.bad 2015-11-16 11:58:52.879078894 +0000 > @@ -2,24 +2,24 @@ > Format and mount > Create the original files > Try cross-device reflink > -XFS_IOC_CLONE_RANGE: Invalid cross-device link > +reflink: Invalid cross-device link Hmm, I think you're running an older version of xfsprogs for-next. The "reflink:" perror prefix was changed to the ioctl name (for all three ioctls) per the comment in: http://oss.sgi.com/archives/xfs/2015-09/msg00338.html > Try unaligned reflink > -XFS_IOC_CLONE_RANGE: Invalid argument > +reflink: Invalid argument > Try overlapping reflink > -XFS_IOC_CLONE_RANGE: Invalid argument > +reflink: Invalid argument > Try reflink past EOF > -XFS_IOC_CLONE_RANGE: Invalid argument > +reflink: Invalid argument > Try to reflink a dir > -XFS_IOC_CLONE_RANGE: Is a directory > +reflink: Is a directory > Try to reflink a device > -XFS_IOC_CLONE_RANGE: Invalid argument > +/mnt/test/test-157/dev1: No such device or address Huh. How did you get -ENODEV here? I ran this on 4.3 and got -EINVAL. > Try to reflink to a dir > -/mnt/test-157/dir1: Is a directory > +/mnt/test/test-157/dir1: Is a directory Drat, will fix. > Try to reflink to a device > -XFS_IOC_CLONE_RANGE: Operation not supported > +/mnt/test/test-157/dev1: No such device or address Same here as the other device case. > Try to reflink to a fifo > -XFS_IOC_CLONE_RANGE: Operation not supported > +reflink: Inappropriate ioctl for device Errrgh, the golden output of this test reflects the changes to the input checking in Anna/Peng's copy_file_range/clone_file_range patches. So, I guess the question is, should I reset the golden output to whatever btrfs spits out before that patchset, and we'll consider the alterations to be bugs/regressions/whatever that ought to be fixed in their patches? > Try to reflink an append-only file > -XFS_IOC_CLONE_RANGE: Bad file descriptor > +reflink: Invalid argument Same as above. --D > Reflink two files > Check scratch fs From chris@onthe.net.au Tue Nov 17 02:04:02 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 176457F37 for ; Tue, 17 Nov 2015 02:04:02 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 13798304039 for ; Tue, 17 Nov 2015 00:03:59 -0800 (PST) X-ASG-Debug-ID: 1447747434-04cb6c0cd1b60d0001-NocioJ Received: from smtp1.onthe.net.au (smtp1.onthe.net.au [203.22.196.249]) by cuda.sgi.com with ESMTP id anWxGO24WE75XuvS for ; Tue, 17 Nov 2015 00:03:55 -0800 (PST) X-Barracuda-Envelope-From: chris@onthe.net.au X-Barracuda-Apparent-Source-IP: 203.22.196.249 Received: from localhost (localhost [127.0.0.1]) by smtp1.onthe.net.au (Postfix) with ESMTP id 6D060617C3 for ; Tue, 17 Nov 2015 19:03:52 +1100 (EST) Received: from smtp1.onthe.net.au ([127.0.0.1]) by localhost (smtp1.onthe.net.au [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ZXTKnyA8yGi7 for ; Tue, 17 Nov 2015 19:03:51 +1100 (EST) Received: from o1.private.otn.net.au (o1.private.onthe.net.au [10.200.63.41]) by smtp1.onthe.net.au (Postfix) with ESMTP id 7B619617C1 for ; Tue, 17 Nov 2015 19:03:33 +1100 (EST) Received: from hestia (pony.office.onthe.net.au [10.9.1.6]) by o1.private.otn.net.au (Postfix) with ESMTP id 760DEE122D for ; Tue, 17 Nov 2015 19:03:33 +1100 (AEDT) Received: by hestia (Postfix, from userid 1000) id 0ECBA580730; Tue, 17 Nov 2015 19:03:33 +1100 (AEDT) Date: Tue, 17 Nov 2015 19:03:33 +1100 From: Chris Dunlop To: xfs@oss.sgi.com Subject: Disk error, then endless loop Message-ID: <20151117080332.GA28936@onthe.net.au> X-ASG-Orig-Subj: Disk error, then endless loop MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.23 (2014-03-12) X-Barracuda-Connect: smtp1.onthe.net.au[203.22.196.249] X-Barracuda-Start-Time: 1447747435 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24468 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Hi, XFS error handling on linux 3.18.21 looks to be "suboptimal". I had an XFS disk start returning read errors, then disappear from the controller altogether (only to come back under a different /dev/sdXX name). XFS is now endlessly flooding these messages into kern.log (55,000 copies and counting...): [5358213.926049] XFS (sdu1): metadata I/O error: block 0x2b163a0 ("xfs_trans_read_buf_map") error 5 numblks 16 [5358213.926141] XFS (sdu1): xfs_imap_to_bp: xfs_trans_read_buf() returned error -5. More info below, but some questions: Is this a known issue, if so, has it been fixed, and if so, in which commit? I guess I'm going to have to hard boot the machine to get out of this, right? More info... The XFS the only thing on the gpt partitioned disk, on partition 1, with a log device on a partition of an SSD-backed md raid-1. The disk is: Device Model: WDC WD60EFRX-68MYMN1 User Capacity: 6,001,175,126,016 bytes [6.00 TB] Sector Sizes: 512 bytes logical, 4096 bytes physical The XFS was formatted like: # mkfs.xfs -V mkfs.xfs version 3.2.1 # mkfs.xfs -l logdev=/dev/md8p5 -i size=2048 /dev/sdu1 meta-data=/dev/sdu1 isize=2048 agcount=6, agsize=268435455 blks = sectsz=4096 attr=2, projid32bit=1 = crc=0 finobt=0 data = bsize=4096 blocks=1465130385, imaxpct=5 = sunit=0 swidth=0 blks naming =version 2 bsize=4096 ascii-ci=0 ftype=0 log =/dev/md8p5 bsize=4096 blocks=409600, version=2 = sectsz=512 sunit=0 blks, lazy-count=1 realtime =none extsz=4096 blocks=0, rtextents=0 I tried to umount the filesystem but the umount is now hung and unkillable: # ps -ostat,wchan='WCHAN-xxxxxxxxxxxxxxxxxx',cmd -C umount STAT WCHAN-xxxxxxxxxxxxxxxxxx CMD D+ xfs_ail_push_all_sync umount /var/lib/ceph/osd/ceph-18 As previously mentioned, the disk has actually reappeared under a different /dev/sdXX name (it was sdu, now sdbh). Trying to mount the disk (read only) results in: # mkdir /mnt/xfs && mount -ologdev=/dev/md8p5,ro /dev/sdbh1 /mnt/xfs mount: /dev/sdbh1 already mounted or /mnt/xfs busy kern.log leading up to this event: [5358213.665887] mpt2sas0: log_info(0x31120436): originator(PL), code(0x12), sub_code(0x0436) [5358213.665939] mpt2sas0: log_info(0x31120436): originator(PL), code(0x12), sub_code(0x0436) [5358213.665990] mpt2sas0: log_info(0x31120436): originator(PL), code(0x12), sub_code(0x0436) [5358213.666042] mpt2sas0: log_info(0x31120436): originator(PL), code(0x12), sub_code(0x0436) [5358213.666138] sd 0:0:20:0: [sdu] [5358213.666165] Result: hostbyte=DID_NO_CONNECT driverbyte=DRIVER_OK [5358213.666196] sd 0:0:20:0: [sdu] CDB: [5358213.666222] Write(16): 8a 00 00 00 00 00 2e 99 9b 00 00 00 02 98 00 00 [5358213.666295] blk_update_request: I/O error, dev sdu, sector 781818624 [5358213.666423] Buffer I/O error on dev sdu1, logical block 363305032, lost async page write [5358213.666480] sd 0:0:20:0: [sdu] [5358213.666504] Result: hostbyte=DID_NO_CONNECT driverbyte=DRIVER_OK [5358213.666532] sd 0:0:20:0: [sdu] CDB: [5358213.666555] Write(16): 8a 00 00 00 00 00 2e 99 97 00 00 00 04 00 00 00 [5358213.666626] blk_update_request: I/O error, dev sdu, sector 781817600 [5358213.666661] sd 0:0:20:0: [sdu] [5358213.666684] Result: hostbyte=DID_NO_CONNECT driverbyte=DRIVER_OK [5358213.666713] sd 0:0:20:0: [sdu] CDB: [5358213.666736] Write(16): 8a 00 00 00 00 00 2e 99 93 00 00 00 04 00 00 00 [5358213.666808] blk_update_request: I/O error, dev sdu, sector 781816576 [5358213.666842] sd 0:0:20:0: [sdu] [5358213.666865] Result: hostbyte=DID_NO_CONNECT driverbyte=DRIVER_OK [5358213.666893] sd 0:0:20:0: [sdu] CDB: [5358213.666917] Read(16): 88 00 00 00 00 01 27 9b 51 10 00 00 00 08 00 00 [5358213.666988] blk_update_request: I/O error, dev sdu, sector 4959457552 [5358213.667025] sd 0:0:20:0: [sdu] [5358213.667048] Result: hostbyte=DID_NO_CONNECT driverbyte=DRIVER_OK [5358213.667077] sd 0:0:20:0: [sdu] CDB: [5358213.667100] Write(16): 8a 00 00 00 00 01 2c 40 b8 a8 00 00 01 78 00 00 [5358213.667171] blk_update_request: I/O error, dev sdu, sector 5037406376 [5358213.667206] sd 0:0:20:0: [sdu] [5358213.667229] Result: hostbyte=DID_NO_CONNECT driverbyte=DRIVER_OK [5358213.667257] sd 0:0:20:0: [sdu] CDB: [5358213.667281] Write(16): 8a 00 00 00 00 01 2c 40 b4 a8 00 00 04 00 00 00 [5358213.667351] blk_update_request: I/O error, dev sdu, sector 5037405352 [5358213.667385] blk_update_request: I/O error, dev sdu, sector 0 [5358213.667419] blk_update_request: I/O error, dev sdu, sector 0 [5358213.667452] sd 0:0:20:0: [sdu] [5358213.667475] Result: hostbyte=DID_NO_CONNECT driverbyte=DRIVER_OK [5358213.667504] sd 0:0:20:0: [sdu] CDB: [5358213.667527] Write(16): 8a 00 00 00 00 01 27 9b 50 b0 00 00 00 60 00 00 [5358213.667598] blk_update_request: I/O error, dev sdu, sector 4959457456 [5358213.667628] Buffer I/O error on dev sdu1, logical block 619931926, lost async page write [5358213.667678] Buffer I/O error on dev sdu1, logical block 619931927, lost async page write [5358213.667727] Buffer I/O error on dev sdu1, logical block 619931928, lost async page write [5358213.667774] Buffer I/O error on dev sdu1, logical block 619931929, lost async page write [5358213.667821] Buffer I/O error on dev sdu1, logical block 619931930, lost async page write [5358213.667868] Buffer I/O error on dev sdu1, logical block 619931931, lost async page write [5358213.667915] Buffer I/O error on dev sdu1, logical block 619931932, lost async page write [5358213.667962] Buffer I/O error on dev sdu1, logical block 619931933, lost async page write [5358213.668010] Buffer I/O error on dev sdu1, logical block 619931934, lost async page write [5358213.668065] sd 0:0:20:0: [sdu] [5358213.668088] Result: hostbyte=DID_NO_CONNECT driverbyte=DRIVER_OK [5358213.668118] sd 0:0:20:0: [sdu] CDB: [5358213.668141] Write(16): 8a 00 00 00 00 00 2e 99 91 98 00 00 01 68 00 00 << above 4 errors repeat a number of times, then >>> [5358213.672847] sd 0:0:20:0: [sdu] [5358213.672870] Result: hostbyte=DID_NO_CONNECT driverbyte=DRIVER_OK [5358213.672898] sd 0:0:20:0: [sdu] CDB: [5358213.672922] Write(16): 8a 00 00 00 00 00 ad 40 60 38 00 00 04 00 00 00 [5358213.673083] XFS (sdu1): metadata I/O error: block 0x817f21d8 ("xfs_trans_read_buf_map") error 5 numblks 8 [5358213.673086] XFS (sdu1): metadata I/O error: block 0x183698f78 ("xfs_trans_read_buf_map") error 5 numblks 16 [5358213.673093] XFS (sdu1): xfs_imap_to_bp: xfs_trans_read_buf() returned error -5. [5358213.673225] sd 0:0:20:0: [sdu] [5358213.673226] Result: hostbyte=DID_NO_CONNECT driverbyte=DRIVER_OK [5358213.673227] sd 0:0:20:0: [sdu] CDB: [5358213.673233] Write(16): 8a 00 00 00 00 01 ab b3 5a c8 00 00 04 00 00 00 [5358213.678590] XFS (sdu1): metadata I/O error: block 0x2b163a0 ("xfs_trans_read_buf_map") error 5 numblks 16 [5358213.678686] XFS (sdu1): xfs_imap_to_bp: xfs_trans_read_buf() returned error -5. [5358213.679799] XFS (sdu1): metadata I/O error: block 0x28 ("xfs_buf_iodone_callbacks") error 5 numblks 8 [5358213.725951] XFS (sdu1): Detected failing async write on buffer block 0x805d4cd8. Retrying async write. [5358213.725951] [5358213.726069] XFS (sdu1): Detected failing async write on buffer block 0x20d390918. Retrying async write. [5358213.726069] [5358213.726181] XFS (sdu1): Detected failing async write on buffer block 0x88a017f0. Retrying async write. [5358213.726181] [5358213.726292] XFS (sdu1): Detected failing async write on buffer block 0x80d04890. Retrying async write. [5358213.726292] [5358213.726428] XFS (sdu1): Detected failing async write on buffer block 0x85bd33d8. Retrying async write. [5358213.726428] [5358213.726539] XFS (sdu1): Detected failing async write on buffer block 0x80ca6110. Retrying async write. [5358213.726539] [5358213.726650] XFS (sdu1): Detected failing async write on buffer block 0x857f1bb8. Retrying async write. [5358213.726650] [5358213.726762] XFS (sdu1): Detected failing async write on buffer block 0x88a017e0. Retrying async write. [5358213.726762] [5358213.726873] XFS (sdu1): Detected failing async write on buffer block 0x804f1c10. Retrying async write. [5358213.726873] [5358213.726984] XFS (sdu1): Detected failing async write on buffer block 0x859381b8. Retrying async write. [5358213.726984] [5358213.727126] XFS (sdu1): metadata I/O error: block 0x2b163a0 ("xfs_trans_read_buf_map") error 5 numblks 16 [5358213.727212] XFS (sdu1): xfs_imap_to_bp: xfs_trans_read_buf() returned error -5. [5358213.775880] XFS (sdu1): metadata I/O error: block 0x2b163a0 ("xfs_trans_read_buf_map") error 5 numblks 16 [5358213.775972] XFS (sdu1): xfs_imap_to_bp: xfs_trans_read_buf() returned error -5. [5358213.825966] XFS (sdu1): metadata I/O error: block 0x2b163a0 ("xfs_trans_read_buf_map") error 5 numblks 16 [5358213.826061] XFS (sdu1): xfs_imap_to_bp: xfs_trans_read_buf() returned error -5. [5358213.876050] XFS (sdu1): metadata I/O error: block 0x2b163a0 ("xfs_trans_read_buf_map") error 5 numblks 16 [5358213.876142] XFS (sdu1): xfs_imap_to_bp: xfs_trans_read_buf() returned error -5. [5358213.926049] XFS (sdu1): metadata I/O error: block 0x2b163a0 ("xfs_trans_read_buf_map") error 5 numblks 16 [5358213.926141] XFS (sdu1): xfs_imap_to_bp: xfs_trans_read_buf() returned error -5. ...and the "metadata" and "xfs_imap_to_bp" messages continue to flood into kern.log (120,000 and counting...) Cheers, Chris From BATV+6e1edf2bac5570895f63+4468+infradead.org+hch@bombadil.srs.infradead.org Tue Nov 17 04:54:42 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 9B9467F37 for ; Tue, 17 Nov 2015 04:54:42 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 29D6EAC002 for ; Tue, 17 Nov 2015 02:54:38 -0800 (PST) X-ASG-Debug-ID: 1447757673-04cbb0605dde2c0001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id aoKnDlRpXyo67PF5 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 17 Nov 2015 02:54:34 -0800 (PST) X-Barracuda-Envelope-From: BATV+6e1edf2bac5570895f63+4468+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 1ZyduD-0000Nf-Jy; Tue, 17 Nov 2015 10:54:33 +0000 Date: Tue, 17 Nov 2015 02:54:33 -0800 From: Christoph Hellwig To: "Darrick J. Wong" Cc: Christoph Hellwig , xfs@oss.sgi.com, linux-fsdevel@vger.kernel.org Subject: Re: clone ioctl return values Message-ID: <20151117105433.GA18093@infradead.org> X-ASG-Orig-Subj: Re: clone ioctl return values References: <20151116120431.GA2860@infradead.org> <20151117002822.GA32467@birch.djwong.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151117002822.GA32467@birch.djwong.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: 1447757674 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/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_MISMATCH_TO, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24471 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS On Mon, Nov 16, 2015 at 04:28:22PM -0800, Darrick J. Wong wrote: > > Try to reflink a device > > -XFS_IOC_CLONE_RANGE: Invalid argument > > +/mnt/test/test-157/dev1: No such device or address > > Huh. How did you get -ENODEV here? I ran this on 4.3 and got -EINVAL. This is current 4.4-rc. The error seems accidental I think. > Errrgh, the golden output of this test reflects the changes to the input > checking in Anna/Peng's copy_file_range/clone_file_range patches. > > So, I guess the question is, should I reset the golden output to whatever > btrfs spits out before that patchset, and we'll consider the alterations > to be bugs/regressions/whatever that ought to be fixed in their patches? Some bits in btrfs don't seem kosher. But it would be good to explicitly send patches for btrfs to adopt to what might make more sense, and then follow it in the other implementations. From bfoster@redhat.com Tue Nov 17 06:41:56 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 2BF8A7F37 for ; Tue, 17 Nov 2015 06:41:56 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 1ACBB8F8035 for ; Tue, 17 Nov 2015 04:41:52 -0800 (PST) X-ASG-Debug-ID: 1447764110-04cbb0605ee06c0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 9sx4lClpV9dMP3xv (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 17 Nov 2015 04:41:51 -0800 (PST) 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 (Postfix) with ESMTPS id B87A0263D; Tue, 17 Nov 2015 12:41:50 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-36.bos.redhat.com [10.18.41.36]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAHCfnqL012750; Tue, 17 Nov 2015 07:41:50 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id DF522120059; Tue, 17 Nov 2015 07:41:48 -0500 (EST) Date: Tue, 17 Nov 2015 07:41:48 -0500 From: Brian Foster To: Chris Dunlop Cc: xfs@oss.sgi.com Subject: Re: Disk error, then endless loop Message-ID: <20151117124148.GA20118@bfoster.bfoster> X-ASG-Orig-Subj: Re: Disk error, then endless loop References: <20151117080332.GA28936@onthe.net.au> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151117080332.GA28936@onthe.net.au> 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: 1447764111 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Tue, Nov 17, 2015 at 07:03:33PM +1100, Chris Dunlop wrote: > Hi, > > XFS error handling on linux 3.18.21 looks to be "suboptimal". > > I had an XFS disk start returning read errors, then disappear from the > controller altogether (only to come back under a different /dev/sdXX name). > XFS is now endlessly flooding these messages into kern.log (55,000 copies > and counting...): > Note that disks returning errors and/or dropping on and offline is outside the realm of the filesystem. There isn't much the fs can do in that case. > [5358213.926049] XFS (sdu1): metadata I/O error: block 0x2b163a0 ("xfs_trans_read_buf_map") error 5 numblks 16 > [5358213.926141] XFS (sdu1): xfs_imap_to_bp: xfs_trans_read_buf() returned error -5. > > More info below, but some questions: > > Is this a known issue, if so, has it been fixed, and if so, in which commit? > This is expected and the most likely scenario is that the filesystem eventually shuts itself down to avoid further damage. At this point, most operations will return -EIO (-5) back to the user. > I guess I'm going to have to hard boot the machine to get out of this, > right? > Normally you should be able to unmount a filesystem that has shut down... > More info... > > The XFS the only thing on the gpt partitioned disk, on partition 1, with a > log device on a partition of an SSD-backed md raid-1. > > The disk is: > > Device Model: WDC WD60EFRX-68MYMN1 > User Capacity: 6,001,175,126,016 bytes [6.00 TB] > Sector Sizes: 512 bytes logical, 4096 bytes physical > > The XFS was formatted like: > > # mkfs.xfs -V > mkfs.xfs version 3.2.1 > # mkfs.xfs -l logdev=/dev/md8p5 -i size=2048 /dev/sdu1 > meta-data=/dev/sdu1 isize=2048 agcount=6, agsize=268435455 blks > = sectsz=4096 attr=2, projid32bit=1 > = crc=0 finobt=0 > data = bsize=4096 blocks=1465130385, imaxpct=5 > = sunit=0 swidth=0 blks > naming =version 2 bsize=4096 ascii-ci=0 ftype=0 > log =/dev/md8p5 bsize=4096 blocks=409600, version=2 > = sectsz=512 sunit=0 blks, lazy-count=1 > realtime =none extsz=4096 blocks=0, rtextents=0 > > I tried to umount the filesystem but the umount is now hung and unkillable: > > # ps -ostat,wchan='WCHAN-xxxxxxxxxxxxxxxxxx',cmd -C umount > STAT WCHAN-xxxxxxxxxxxxxxxxxx CMD > D+ xfs_ail_push_all_sync umount /var/lib/ceph/osd/ceph-18 > ... but it appears you still have something pending in the AIL which is holding everything up. The most likely case is an EFI/EFD item hanging around from an extent free operation, as this was a known issue, particularly on fs shutdowns. Fixes for this went into the v4.3 kernel. Note that this won't address whatever is wrong with the disk in the first place, just (hopefully) the ability to unmount when it ultimately fails. Does the umount process actually appear to be doing anything? E.g., are you seeing noticeable CPU load or I/O errors continue to the logs, or has everything pretty much locked up? You could also enable tracepoints (trace-cmd start -e "xfs:*"; cat /sys/kernel/debug/tracing/trace_pipe) to get a quick idea of what's going on. > As previously mentioned, the disk has actually reappeared under a different > /dev/sdXX name (it was sdu, now sdbh). Trying to mount the disk (read only) > results in: > > # mkdir /mnt/xfs && mount -ologdev=/dev/md8p5,ro /dev/sdbh1 /mnt/xfs > mount: /dev/sdbh1 already mounted or /mnt/xfs busy > Probably due to either a uuid check or blocking on access to the external log device. You'll probably need to clean up the stale mount before this will work. As it is, something is clearly wrong with the drive. I can't really interpret the I/O errors and whatnot (linux-scsi?), but you probably want to look into health assessment tools (e.g., smart) to get an idea of what's wrong and/or replace the device and restore from backups (or perhaps heal via the ceph cluster, in your case). Brian > kern.log leading up to this event: > > [5358213.665887] mpt2sas0: log_info(0x31120436): originator(PL), code(0x12), sub_code(0x0436) > [5358213.665939] mpt2sas0: log_info(0x31120436): originator(PL), code(0x12), sub_code(0x0436) > [5358213.665990] mpt2sas0: log_info(0x31120436): originator(PL), code(0x12), sub_code(0x0436) > [5358213.666042] mpt2sas0: log_info(0x31120436): originator(PL), code(0x12), sub_code(0x0436) > [5358213.666138] sd 0:0:20:0: [sdu] > [5358213.666165] Result: hostbyte=DID_NO_CONNECT driverbyte=DRIVER_OK > [5358213.666196] sd 0:0:20:0: [sdu] CDB: > [5358213.666222] Write(16): 8a 00 00 00 00 00 2e 99 9b 00 00 00 02 98 00 00 > [5358213.666295] blk_update_request: I/O error, dev sdu, sector 781818624 > [5358213.666423] Buffer I/O error on dev sdu1, logical block 363305032, lost async page write > [5358213.666480] sd 0:0:20:0: [sdu] > [5358213.666504] Result: hostbyte=DID_NO_CONNECT driverbyte=DRIVER_OK > [5358213.666532] sd 0:0:20:0: [sdu] CDB: > [5358213.666555] Write(16): 8a 00 00 00 00 00 2e 99 97 00 00 00 04 00 00 00 > [5358213.666626] blk_update_request: I/O error, dev sdu, sector 781817600 > [5358213.666661] sd 0:0:20:0: [sdu] > [5358213.666684] Result: hostbyte=DID_NO_CONNECT driverbyte=DRIVER_OK > [5358213.666713] sd 0:0:20:0: [sdu] CDB: > [5358213.666736] Write(16): 8a 00 00 00 00 00 2e 99 93 00 00 00 04 00 00 00 > [5358213.666808] blk_update_request: I/O error, dev sdu, sector 781816576 > [5358213.666842] sd 0:0:20:0: [sdu] > [5358213.666865] Result: hostbyte=DID_NO_CONNECT driverbyte=DRIVER_OK > [5358213.666893] sd 0:0:20:0: [sdu] CDB: > [5358213.666917] Read(16): 88 00 00 00 00 01 27 9b 51 10 00 00 00 08 00 00 > [5358213.666988] blk_update_request: I/O error, dev sdu, sector 4959457552 > [5358213.667025] sd 0:0:20:0: [sdu] > [5358213.667048] Result: hostbyte=DID_NO_CONNECT driverbyte=DRIVER_OK > [5358213.667077] sd 0:0:20:0: [sdu] CDB: > [5358213.667100] Write(16): 8a 00 00 00 00 01 2c 40 b8 a8 00 00 01 78 00 00 > [5358213.667171] blk_update_request: I/O error, dev sdu, sector 5037406376 > [5358213.667206] sd 0:0:20:0: [sdu] > [5358213.667229] Result: hostbyte=DID_NO_CONNECT driverbyte=DRIVER_OK > [5358213.667257] sd 0:0:20:0: [sdu] CDB: > [5358213.667281] Write(16): 8a 00 00 00 00 01 2c 40 b4 a8 00 00 04 00 00 00 > [5358213.667351] blk_update_request: I/O error, dev sdu, sector 5037405352 > [5358213.667385] blk_update_request: I/O error, dev sdu, sector 0 > [5358213.667419] blk_update_request: I/O error, dev sdu, sector 0 > [5358213.667452] sd 0:0:20:0: [sdu] > [5358213.667475] Result: hostbyte=DID_NO_CONNECT driverbyte=DRIVER_OK > [5358213.667504] sd 0:0:20:0: [sdu] CDB: > [5358213.667527] Write(16): 8a 00 00 00 00 01 27 9b 50 b0 00 00 00 60 00 00 > [5358213.667598] blk_update_request: I/O error, dev sdu, sector 4959457456 > [5358213.667628] Buffer I/O error on dev sdu1, logical block 619931926, lost async page write > [5358213.667678] Buffer I/O error on dev sdu1, logical block 619931927, lost async page write > [5358213.667727] Buffer I/O error on dev sdu1, logical block 619931928, lost async page write > [5358213.667774] Buffer I/O error on dev sdu1, logical block 619931929, lost async page write > [5358213.667821] Buffer I/O error on dev sdu1, logical block 619931930, lost async page write > [5358213.667868] Buffer I/O error on dev sdu1, logical block 619931931, lost async page write > [5358213.667915] Buffer I/O error on dev sdu1, logical block 619931932, lost async page write > [5358213.667962] Buffer I/O error on dev sdu1, logical block 619931933, lost async page write > [5358213.668010] Buffer I/O error on dev sdu1, logical block 619931934, lost async page write > [5358213.668065] sd 0:0:20:0: [sdu] > [5358213.668088] Result: hostbyte=DID_NO_CONNECT driverbyte=DRIVER_OK > [5358213.668118] sd 0:0:20:0: [sdu] CDB: > [5358213.668141] Write(16): 8a 00 00 00 00 00 2e 99 91 98 00 00 01 68 00 00 > << above 4 errors repeat a number of times, then >>> > [5358213.672847] sd 0:0:20:0: [sdu] > [5358213.672870] Result: hostbyte=DID_NO_CONNECT driverbyte=DRIVER_OK > [5358213.672898] sd 0:0:20:0: [sdu] CDB: > [5358213.672922] Write(16): 8a 00 00 00 00 00 ad 40 60 38 00 00 04 00 00 00 > [5358213.673083] XFS (sdu1): metadata I/O error: block 0x817f21d8 ("xfs_trans_read_buf_map") error 5 numblks 8 > [5358213.673086] XFS (sdu1): metadata I/O error: block 0x183698f78 ("xfs_trans_read_buf_map") error 5 numblks 16 > [5358213.673093] XFS (sdu1): xfs_imap_to_bp: xfs_trans_read_buf() returned error -5. > [5358213.673225] sd 0:0:20:0: [sdu] > [5358213.673226] Result: hostbyte=DID_NO_CONNECT driverbyte=DRIVER_OK > [5358213.673227] sd 0:0:20:0: [sdu] CDB: > [5358213.673233] Write(16): 8a 00 00 00 00 01 ab b3 5a c8 00 00 04 00 00 00 > [5358213.678590] XFS (sdu1): metadata I/O error: block 0x2b163a0 ("xfs_trans_read_buf_map") error 5 numblks 16 > [5358213.678686] XFS (sdu1): xfs_imap_to_bp: xfs_trans_read_buf() returned error -5. > [5358213.679799] XFS (sdu1): metadata I/O error: block 0x28 ("xfs_buf_iodone_callbacks") error 5 numblks 8 > [5358213.725951] XFS (sdu1): Detected failing async write on buffer block 0x805d4cd8. Retrying async write. > [5358213.725951] > [5358213.726069] XFS (sdu1): Detected failing async write on buffer block 0x20d390918. Retrying async write. > [5358213.726069] > [5358213.726181] XFS (sdu1): Detected failing async write on buffer block 0x88a017f0. Retrying async write. > [5358213.726181] > [5358213.726292] XFS (sdu1): Detected failing async write on buffer block 0x80d04890. Retrying async write. > [5358213.726292] > [5358213.726428] XFS (sdu1): Detected failing async write on buffer block 0x85bd33d8. Retrying async write. > [5358213.726428] > [5358213.726539] XFS (sdu1): Detected failing async write on buffer block 0x80ca6110. Retrying async write. > [5358213.726539] > [5358213.726650] XFS (sdu1): Detected failing async write on buffer block 0x857f1bb8. Retrying async write. > [5358213.726650] > [5358213.726762] XFS (sdu1): Detected failing async write on buffer block 0x88a017e0. Retrying async write. > [5358213.726762] > [5358213.726873] XFS (sdu1): Detected failing async write on buffer block 0x804f1c10. Retrying async write. > [5358213.726873] > [5358213.726984] XFS (sdu1): Detected failing async write on buffer block 0x859381b8. Retrying async write. > [5358213.726984] > [5358213.727126] XFS (sdu1): metadata I/O error: block 0x2b163a0 ("xfs_trans_read_buf_map") error 5 numblks 16 > [5358213.727212] XFS (sdu1): xfs_imap_to_bp: xfs_trans_read_buf() returned error -5. > [5358213.775880] XFS (sdu1): metadata I/O error: block 0x2b163a0 ("xfs_trans_read_buf_map") error 5 numblks 16 > [5358213.775972] XFS (sdu1): xfs_imap_to_bp: xfs_trans_read_buf() returned error -5. > [5358213.825966] XFS (sdu1): metadata I/O error: block 0x2b163a0 ("xfs_trans_read_buf_map") error 5 numblks 16 > [5358213.826061] XFS (sdu1): xfs_imap_to_bp: xfs_trans_read_buf() returned error -5. > [5358213.876050] XFS (sdu1): metadata I/O error: block 0x2b163a0 ("xfs_trans_read_buf_map") error 5 numblks 16 > [5358213.876142] XFS (sdu1): xfs_imap_to_bp: xfs_trans_read_buf() returned error -5. > [5358213.926049] XFS (sdu1): metadata I/O error: block 0x2b163a0 ("xfs_trans_read_buf_map") error 5 numblks 16 > [5358213.926141] XFS (sdu1): xfs_imap_to_bp: xfs_trans_read_buf() returned error -5. > > ...and the "metadata" and "xfs_imap_to_bp" messages continue to flood into > kern.log (120,000 and counting...) > > > Cheers, > > Chris > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From avi@cloudius-systems.com Tue Nov 17 06:52:25 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 ECCEF7F37 for ; Tue, 17 Nov 2015 06:52:24 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id AE17E8F8040 for ; Tue, 17 Nov 2015 04:52:24 -0800 (PST) X-ASG-Debug-ID: 1447764742-04bdf07f08d18f0001-NocioJ Received: from mail-wm0-f47.google.com (mail-wm0-f47.google.com [74.125.82.47]) by cuda.sgi.com with ESMTP id X0S0TW1ShWEf7n7I (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 17 Nov 2015 04:52:23 -0800 (PST) X-Barracuda-Envelope-From: avi@cloudius-systems.com X-Barracuda-Apparent-Source-IP: 74.125.82.47 Received: by wmec201 with SMTP id c201so225855374wme.0 for ; Tue, 17 Nov 2015 04:52:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=scylladb-com.20150623.gappssmtp.com; s=20150623; h=subject:to:references:cc:from:message-id:date:user-agent :mime-version:in-reply-to:content-type:content-transfer-encoding; bh=0vGFpZVSDKXZQ1d+UKUtZyKsRkM78LSxkrJyYPG7n0E=; b=i67y0J95OTvrXuy4ToWzxDaoTeLzY8Y/Selg6XUJUlQnToj5NchAJ/6KHwWDm5xv9U IT9I+Cs1X1BU9iWAZogL90ggykgOUsvkruPdN9d87xc1nKUh0f/Lhv6x1SImoMcG5GBF h4ZPHpIrQ+Kt4m+ux6Ttrg/ZiE68Xe0+9JEgTg63/Gc7+SW6UZaYI3YDMZjOD52UKZVx ZNmo8zIolyT0zSL4gZAcCcJ+1Nu+AzAjDjbv4KECOZUhU9OekfgXh1zyUcH+lM1GVwyA BkLoGvNArUaMCUaLydQBx0WVsdma/R1hGKgRxIM0/yqJ+Y52xzhJ9DIKWH2YKenrF7D+ qaHA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:subject:to:references:cc:from:message-id:date :user-agent:mime-version:in-reply-to:content-type :content-transfer-encoding; bh=0vGFpZVSDKXZQ1d+UKUtZyKsRkM78LSxkrJyYPG7n0E=; b=QPK6cmzuH2iZ3xaCoi4B2+HRhCoB9pXQV1pjKsWT5vAxgmg2xvWYlN2K2xAEXyBjW1 K/A5MZ0hipZuVmlfWSrU0mfBwTMgQwZAJtbiTjfBN7zGJSCNNyZcwgrGBP4pY/UEO02X KdhW2obK6tJJ5wJ7sx4dCIY9HDqKRN+ng4pXXhL6Ss3MOt1F/RCXjwO48amenjP7XUFT k74VGqaCOV/bJWA5TcJS7d8jT1XDBugERsjFPIO59wr3kfcAgoE1mb+U+Y5G7ZpwANKM uhAvKj4yNulm78qqzrAQmCn50VXW+2mGy02S5KIXfSwCPUbHeKwsI/0IQsezkkaCdidg 29HQ== X-Gm-Message-State: ALoCoQmxwtFLIDTsR8yCiXFDMCUzecGcU+U9Dnovcox8gUCVw0OYf8FNNUJrSWUeeAn9jE3j1sbh X-Received: by 10.28.216.72 with SMTP id p69mr2717120wmg.14.1447764741914; Tue, 17 Nov 2015 04:52:21 -0800 (PST) Received: from avi.cloudius-systems.com ([37.142.229.250]) by smtp.googlemail.com with ESMTPSA id lv4sm39791149wjb.43.2015.11.17.04.52.20 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 17 Nov 2015 04:52:20 -0800 (PST) Subject: Re: AIO read returns negative number for bytes read To: Jeff Moyer X-ASG-Orig-Subj: Re: AIO read returns negative number for bytes read References: <564883BD.8070607@scylladb.com> Cc: xfs@oss.sgi.com, linux-aio@kvack.org, Steven Whitehouse , Jan Kara , linux-fsdevel@vger.kernel.org From: Avi Kivity Message-ID: <564B2303.7000902@scylladb.com> Date: Tue, 17 Nov 2015 14:52:19 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mail-wm0-f47.google.com[74.125.82.47] X-Barracuda-Start-Time: 1447764742 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/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 11/16/2015 09:27 PM, Jeff Moyer wrote: > Hi Avi, > > Avi Kivity writes: > >> Due to a bug in my program, I initiated a read beyond >> eof. Specifically, the file size is 13002 bytes and the read offset is >> 13312 (0x3400). >> >> I would expect such a read to return 0 bytes read, but io_getevents >> returns -310, which is suspiciously equal to (13002 - 13312). >> >> I attach a reproducer. >> >> 4.2.5-201.fc22.x86_64 >> >> Are my expectations incorrect, or is this a bug in aio or xfs? > Your expectations are correct. The bug was introduced by commit > 9fe55eea7e4b4 (Fix race when checking i_size on direct i/o read). I've > CC'd the patch author and linux-fsdevel. I'm not sure what the right > fix is, given that the size checks were removed from the vfs to fix some > race condition. Unfortunately, the commit message doesn't really do a > good job of explaining the race. In order to save others time, here is > a good explanation of the problem that commit is meant to fix, along > with a reproducer: > http://marc.info/?l=linux-fsdevel&m=138641356614458&w=2 > > Thanks for the great bug report, and sorry I have no solution to > proffer. > Thanks. I will await a fix with interest. From prvs=8763e27c61=clm@fb.com Tue Nov 17 07:58:33 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 F19D37F37 for ; Tue, 17 Nov 2015 07:58:32 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 8FC35AC002 for ; Tue, 17 Nov 2015 05:58:29 -0800 (PST) X-ASG-Debug-ID: 1447768704-04bdf07f09d38e0001-NocioJ Received: from mx0b-00082601.pphosted.com (mx0b-00082601.pphosted.com [67.231.153.30]) by cuda.sgi.com with ESMTP id No66PCnHDiWBdj7S (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 17 Nov 2015 05:58:25 -0800 (PST) X-Barracuda-Envelope-From: prvs=8763e27c61=clm@fb.com X-Barracuda-Apparent-Source-IP: 67.231.153.30 X-ASG-Whitelist: EmailCat (corporate) Received: from pps.filterd (m0001303.ppops.net [127.0.0.1]) by m0001303.ppops.net (8.15.0.59/8.15.0.59) with SMTP id tAHDvoZF023235; Tue, 17 Nov 2015 05:57:57 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=fb.com; h=date : from : to : cc : subject : message-id : references : mime-version : content-type : in-reply-to; s=facebook; bh=8+6a6qF+RUpjggo7H43w9pWxnG5mJzmrXeB3F20gtgU=; b=mcCKzMCAWU8kBSb7Do+FhnMYRmYem4ZufI2/5jz0PW0UUQOofX3zLzDSSntFBumZrdef cW2o7JQG43/gC8N7tV/QbyzZTvVApWBNiwCIo62lGaAGwxnBuv6FVEVZ8Sg8gUfnjI3y jS9vAimImcsHhBPSvIhXW85dmYcsbmUSmDA= Received: from mail.thefacebook.com ([199.201.64.23]) by m0001303.ppops.net with ESMTP id 1y7xx219gf-4 (version=TLSv1/SSLv3 cipher=AES128-SHA bits=128 verify=NOT); Tue, 17 Nov 2015 05:57:56 -0800 Received: from localhost (192.168.52.123) by mail.thefacebook.com (192.168.16.19) with Microsoft SMTP Server (TLS) id 14.3.248.2; Tue, 17 Nov 2015 05:57:47 -0800 Date: Tue, 17 Nov 2015 08:57:45 -0500 From: Chris Mason To: Christoph Hellwig CC: "Darrick J. Wong" , , Subject: Re: clone ioctl return values Message-ID: <20151117135745.GF17545@ret.masoncoding.com> X-ASG-Orig-Subj: Re: clone ioctl return values Mail-Followup-To: Chris Mason , Christoph Hellwig , "Darrick J. Wong" , xfs@oss.sgi.com, linux-fsdevel@vger.kernel.org References: <20151116120431.GA2860@infradead.org> <20151117002822.GA32467@birch.djwong.org> <20151117105433.GA18093@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Disposition: inline In-Reply-To: <20151117105433.GA18093@infradead.org> User-Agent: Mutt/1.5.23.1 (2014-03-12) X-Originating-IP: [192.168.52.123] X-Proofpoint-Spam-Reason: safe X-FB-Internal: Safe X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:,, definitions=2015-11-17_08:,, signatures=0 X-Barracuda-Connect: mx0b-00082601.pphosted.com[67.231.153.30] X-Barracuda-Start-Time: 1447768705 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Tue, Nov 17, 2015 at 02:54:33AM -0800, Christoph Hellwig wrote: > On Mon, Nov 16, 2015 at 04:28:22PM -0800, Darrick J. Wong wrote: > > > Try to reflink a device > > > -XFS_IOC_CLONE_RANGE: Invalid argument > > > +/mnt/test/test-157/dev1: No such device or address > > > > Huh. How did you get -ENODEV here? I ran this on 4.3 and got -EINVAL. > > This is current 4.4-rc. The error seems accidental I think. > > > Errrgh, the golden output of this test reflects the changes to the input > > checking in Anna/Peng's copy_file_range/clone_file_range patches. > > > > So, I guess the question is, should I reset the golden output to whatever > > btrfs spits out before that patchset, and we'll consider the alterations > > to be bugs/regressions/whatever that ought to be fixed in their patches? > > Some bits in btrfs don't seem kosher. But it would be good to > explicitly send patches for btrfs to adopt to what might make more > sense, and then follow it in the other implementations. Btrfs does check for directories, but we should really be checking for regular files too. In the end, we only copy extents that would correspond with regular files, so we're sneaking by. -chris From BATV+6e1edf2bac5570895f63+4468+infradead.org+hch@bombadil.srs.infradead.org Tue Nov 17 09:12:34 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 D5ACB7F37 for ; Tue, 17 Nov 2015 09:12:34 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id C685F8F8035 for ; Tue, 17 Nov 2015 07:12:31 -0800 (PST) X-ASG-Debug-ID: 1447773147-04cbb0605ce4a70001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id 0TK1Y6Uex0ZAuWgU (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 17 Nov 2015 07:12:27 -0800 (PST) X-Barracuda-Envelope-From: BATV+6e1edf2bac5570895f63+4468+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 1Zyhvm-00064r-Sf; Tue, 17 Nov 2015 15:12:26 +0000 Date: Tue, 17 Nov 2015 07:12:26 -0800 From: Christoph Hellwig To: "Darrick J. Wong" Cc: xfs@oss.sgi.com, linux-fsdevel@vger.kernel.org Subject: Re: clone ioctl return values Message-ID: <20151117151226.GA12860@infradead.org> X-ASG-Orig-Subj: Re: clone ioctl return values References: <20151116120431.GA2860@infradead.org> <20151117002822.GA32467@birch.djwong.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151117002822.GA32467@birch.djwong.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: 1447773147 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/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_MISMATCH_TO, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24475 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS On Mon, Nov 16, 2015 at 04:28:22PM -0800, Darrick J. Wong wrote: > > -XFS_IOC_CLONE_RANGE: Invalid argument > > +reflink: Invalid argument > > Try reflink past EOF > > -XFS_IOC_CLONE_RANGE: Invalid argument > > +reflink: Invalid argument > > Try to reflink a dir > > -XFS_IOC_CLONE_RANGE: Is a directory > > +reflink: Is a directory > > > Try to reflink a device > > -XFS_IOC_CLONE_RANGE: Invalid argument > > +/mnt/test/test-157/dev1: No such device or address > > Huh. How did you get -ENODEV here? I ran this on 4.3 and got -EINVAL. Turns out this is because my system doesn't have the ramdisk driver built into the kernel, so opening your block device with major 8, minor 0 already fails. Might be better to create a char device with major 1, minor 3 (dev null) as that should always be present. From BATV+6e1edf2bac5570895f63+4468+infradead.org+hch@bombadil.srs.infradead.org Tue Nov 17 09:23:02 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 CD6E77F37 for ; Tue, 17 Nov 2015 09:23:02 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 9F58E304032 for ; Tue, 17 Nov 2015 07:22:59 -0800 (PST) X-ASG-Debug-ID: 1447773773-04bdf07f0ad5ae0001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id weXGLmBBNcU5YsPz (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 17 Nov 2015 07:22:54 -0800 (PST) X-Barracuda-Envelope-From: BATV+6e1edf2bac5570895f63+4468+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 1Zyi5s-0001Xq-1F; Tue, 17 Nov 2015 15:22:52 +0000 Date: Tue, 17 Nov 2015 07:22:52 -0800 From: Christoph Hellwig To: Chris Mason , Christoph Hellwig , "Darrick J. Wong" , xfs@oss.sgi.com, linux-fsdevel@vger.kernel.org Subject: Re: clone ioctl return values Message-ID: <20151117152251.GA5392@infradead.org> X-ASG-Orig-Subj: Re: clone ioctl return values References: <20151116120431.GA2860@infradead.org> <20151117002822.GA32467@birch.djwong.org> <20151117105433.GA18093@infradead.org> <20151117135745.GF17545@ret.masoncoding.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151117135745.GF17545@ret.masoncoding.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: 1447773774 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/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.24476 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS On Tue, Nov 17, 2015 at 08:57:45AM -0500, Chris Mason wrote: > > > Errrgh, the golden output of this test reflects the changes to the input > > > checking in Anna/Peng's copy_file_range/clone_file_range patches. > > > > > > So, I guess the question is, should I reset the golden output to whatever > > > btrfs spits out before that patchset, and we'll consider the alterations > > > to be bugs/regressions/whatever that ought to be fixed in their patches? > > > > Some bits in btrfs don't seem kosher. But it would be good to > > explicitly send patches for btrfs to adopt to what might make more > > sense, and then follow it in the other implementations. > > Btrfs does check for directories, but we should really be checking for > regular files too. In the end, we only copy extents that would > correspond with regular files, so we're sneaking by. Yes, I saw that. So so far I'd suggest something like the following for btrfs: - return EBADFD for missing read/wite permissions - return EINVAL for wrong non-directory file types as the source fd And then make the test case and other implementations match this. Does this sound like a plan? From viro@ftp.linux.org.uk Tue Nov 17 09:33:32 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 9AAF77F37 for ; Tue, 17 Nov 2015 09:33:32 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 87050304032 for ; Tue, 17 Nov 2015 07:33:31 -0800 (PST) X-ASG-Debug-ID: 1447774409-04cb6c0cd3c1080001-NocioJ Received: from ZenIV.linux.org.uk (zeniv.linux.org.uk [195.92.253.2]) by cuda.sgi.com with ESMTP id Pu8FVDFUfkhnoDBO (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Tue, 17 Nov 2015 07:33:30 -0800 (PST) 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 1ZyiG0-00029G-Gr; Tue, 17 Nov 2015 15:33:20 +0000 Date: Tue, 17 Nov 2015 15:33:20 +0000 From: Al Viro To: Christoph Hellwig Cc: Chris Mason , "Darrick J. Wong" , xfs@oss.sgi.com, linux-fsdevel@vger.kernel.org Subject: Re: clone ioctl return values Message-ID: <20151117153320.GU22011@ZenIV.linux.org.uk> X-ASG-Orig-Subj: Re: clone ioctl return values References: <20151116120431.GA2860@infradead.org> <20151117002822.GA32467@birch.djwong.org> <20151117105433.GA18093@infradead.org> <20151117135745.GF17545@ret.masoncoding.com> <20151117152251.GA5392@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151117152251.GA5392@infradead.org> 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: 1447774409 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24475 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Tue, Nov 17, 2015 at 07:22:52AM -0800, Christoph Hellwig wrote: > Yes, I saw that. So so far I'd suggest something like the following > for btrfs: > > - return EBADFD for missing read/wite permissions Yowwwch... What the hell does that have to do with STREAMS? Or are you using EBADFD as "nobody uses that error value anyway, let's assign it whatever meaning we need"? Besides, that'll be confused with EBADF all the time. I strongly recommend against that. From BATV+6e1edf2bac5570895f63+4468+infradead.org+hch@bombadil.srs.infradead.org Tue Nov 17 09:36:27 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 F40B17F37 for ; Tue, 17 Nov 2015 09:36:26 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id D2E4D8F8035 for ; Tue, 17 Nov 2015 07:36:26 -0800 (PST) X-ASG-Debug-ID: 1447774585-04bdf07f08d5ff0001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id MObrCpFIGRIQqvQo (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 17 Nov 2015 07:36:25 -0800 (PST) X-Barracuda-Envelope-From: BATV+6e1edf2bac5570895f63+4468+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 1ZyiIx-0000PB-D6; Tue, 17 Nov 2015 15:36:23 +0000 Date: Tue, 17 Nov 2015 07:36:23 -0800 From: Christoph Hellwig To: Al Viro Cc: linux-fsdevel@vger.kernel.org, Chris Mason , xfs@oss.sgi.com, "Darrick J. Wong" Subject: Re: clone ioctl return values Message-ID: <20151117153623.GA27322@infradead.org> X-ASG-Orig-Subj: Re: clone ioctl return values References: <20151116120431.GA2860@infradead.org> <20151117002822.GA32467@birch.djwong.org> <20151117105433.GA18093@infradead.org> <20151117135745.GF17545@ret.masoncoding.com> <20151117152251.GA5392@infradead.org> <20151117153320.GU22011@ZenIV.linux.org.uk> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151117153320.GU22011@ZenIV.linux.org.uk> 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: 1447774585 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/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.24476 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS On Tue, Nov 17, 2015 at 03:33:20PM +0000, Al Viro wrote: > On Tue, Nov 17, 2015 at 07:22:52AM -0800, Christoph Hellwig wrote: > > > Yes, I saw that. So so far I'd suggest something like the following > > for btrfs: > > > > - return EBADFD for missing read/wite permissions > > Yowwwch... What the hell does that have to do with STREAMS? Or are you > using EBADFD as "nobody uses that error value anyway, let's assign it > whatever meaning we need"? > > Besides, that'll be confused with EBADF all the time. I strongly > recommend against that. Yes, I meant EBADF. That's what we normally use for missing FMODE_READ/WRITE or fget failures, so why would this call be different from everything else? From chris@onthe.net.au Tue Nov 17 10:28:12 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 BAF9A7F3F for ; Tue, 17 Nov 2015 10:28:12 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 321E7AC003 for ; Tue, 17 Nov 2015 08:28:09 -0800 (PST) X-ASG-Debug-ID: 1447777684-04cbb0605be68b0001-NocioJ Received: from smtp1.onthe.net.au (smtp1.onthe.net.au [203.22.196.249]) by cuda.sgi.com with ESMTP id oUElFRc17nXBF1Sa for ; Tue, 17 Nov 2015 08:28:05 -0800 (PST) X-Barracuda-Envelope-From: chris@onthe.net.au X-Barracuda-Apparent-Source-IP: 203.22.196.249 Received: from localhost (localhost [127.0.0.1]) by smtp1.onthe.net.au (Postfix) with ESMTP id 29EAC617BE; Wed, 18 Nov 2015 03:28:04 +1100 (EST) Received: from smtp1.onthe.net.au ([127.0.0.1]) by localhost (smtp1.onthe.net.au [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id nAMnTUR-wuv1; Wed, 18 Nov 2015 03:28:03 +1100 (EST) Received: from o1.private.otn.net.au (o1.private.onthe.net.au [10.200.63.41]) by smtp1.onthe.net.au (Postfix) with ESMTP id BFF93617B0; Wed, 18 Nov 2015 03:28:03 +1100 (EST) Received: from hestia (pony.office.onthe.net.au [10.9.1.6]) by o1.private.otn.net.au (Postfix) with ESMTP id 2F66EE122D; Wed, 18 Nov 2015 03:28:03 +1100 (AEDT) Received: by hestia (Postfix, from userid 1000) id C2F3C580730; Wed, 18 Nov 2015 03:28:02 +1100 (AEDT) Date: Wed, 18 Nov 2015 03:28:02 +1100 From: Chris Dunlop To: Brian Foster Cc: xfs@oss.sgi.com Subject: Re: Disk error, then endless loop Message-ID: <20151117162802.GA28374@onthe.net.au> X-ASG-Orig-Subj: Re: Disk error, then endless loop References: <20151117080332.GA28936@onthe.net.au> <20151117124148.GA20118@bfoster.bfoster> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151117124148.GA20118@bfoster.bfoster> User-Agent: Mutt/1.5.23 (2014-03-12) X-Barracuda-Connect: smtp1.onthe.net.au[203.22.196.249] X-Barracuda-Start-Time: 1447777685 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24476 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- G'day Brian, Thanks for your response... On Tue, Nov 17, 2015 at 07:41:48AM -0500, Brian Foster wrote: > On Tue, Nov 17, 2015 at 07:03:33PM +1100, Chris Dunlop wrote: >> Hi, >> >> XFS error handling on linux 3.18.21 looks to be "suboptimal". >> >> I had an XFS disk start returning read errors, then disappear from the >> controller altogether (only to come back under a different /dev/sdXX name). >> XFS is now endlessly flooding these messages into kern.log (55,000 copies >> and counting...): > > Note that disks returning errors and/or dropping on and offline is > outside the realm of the filesystem. There isn't much the fs can do in > that case. What?! The fs can't fix broken disks?! But I want magic ponies! :-) >> [5358213.926049] XFS (sdu1): metadata I/O error: block 0x2b163a0 ("xfs_trans_read_buf_map") error 5 numblks 16 >> [5358213.926141] XFS (sdu1): xfs_imap_to_bp: xfs_trans_read_buf() returned error -5. >> >> More info below, but some questions: >> >> Is this a known issue, if so, has it been fixed, and if so, in which commit? >> > > This is expected and the most likely scenario is that the filesystem > eventually shuts itself down to avoid further damage. At this point, > most operations will return -EIO (-5) back to the user. > >> I guess I'm going to have to hard boot the machine to get out of this, >> right? > > Normally you should be able to unmount a filesystem that has shut > down... But not in this case... >> I tried to umount the filesystem but the umount is now hung and unkillable: >> >> # ps -ostat,wchan='WCHAN-xxxxxxxxxxxxxxxxxx',cmd -C umount >> STAT WCHAN-xxxxxxxxxxxxxxxxxx CMD >> D+ xfs_ail_push_all_sync umount /var/lib/ceph/osd/ceph-18 > > ... but it appears you still have something pending in the AIL which is > holding everything up. The most likely case is an EFI/EFD item hanging > around from an extent free operation, as this was a known issue, > particularly on fs shutdowns. Fixes for this went into the v4.3 kernel. Any chance of these fixes getting into -stable, or are they too intrusive and/or depend on other intrusive changes? > Note that this won't address whatever is wrong with the disk in the > first place, Bwaaaaahhhh, magic ponies! > just (hopefully) the ability to unmount when it ultimately fails. Yes, that's what I was hoping for. > Does the umount process actually appear to be doing anything? E.g., are > you seeing noticeable CPU load or I/O errors continue to the logs, or > has everything pretty much locked up? You could also enable tracepoints > (trace-cmd start -e "xfs:*"; cat /sys/kernel/debug/tracing/trace_pipe) > to get a quick idea of what's going on. No, the umount hasn't done anything noticable in the past 6.5 hours: b2# date; ps -opid,lstart,time,stat,wchan='WCHAN-xxxxxxxxxxxxxxxxxx',cmd -C umount Wed Nov 18 03:08:30 AEDT 2015 PID STARTED TIME STAT WCHAN-xxxxxxxxxxxxxxxxxx CMD 23946 Tue Nov 17 17:30:41 2015 00:00:00 D+ xfs_ail_push_all_sync umount /var/lib/ceph/osd/ceph-18 I don't know how to interpret the tracepoints, but there are other busy XFS filesystems on the box so that's cluttering things up. For what it's worth, it appears the original device (/dev/sdu1) was previously dev 65:65: b2# ls -l /dev/sd[tuv]{,1} brw-rw---T 1 root disk 65, 48 Sep 16 17:11 /dev/sdt brw-rw---T 1 root disk 65, 49 Sep 16 17:11 /dev/sdt1 brw-rw---T 1 root disk 65, 80 Oct 30 15:38 /dev/sdv brw-rw---T 1 root disk 65, 81 Oct 30 15:40 /dev/sdv1 ..and in 10 seconds of /sys/kernel/debug/tracing/trace_pipe we have: # grep 'dev 65:65' /sys/kernel/debug/tracing/trace_pipe > /tmp/x1 & sleep 10; kill $! # wc -l /tmp/x1 181953 /tmp/x1 # head /tmp/x1 <...>-7702 [012] .... 5392362.786946: xfs_buf_item_iodone_async: dev 65:65 bno 0x1828eed18 nblks 0x8 hold 2 pincount 0 lock 0 flags ASYNC|DONE|PAGES caller xfs_buf_ioend [xfs] <...>-7702 [012] .... 5392362.786946: xfs_buf_ioerror: dev 65:65 bno 0x1828eed18 len 0x1000 hold 2 pincount 0 lock 0 error 0 flags ASYNC|DONE|PAGES caller xfs_buf_iodone_callbacks [xfs] xfsaild/sdu1-7991 [005] .N.. 5392363.647059: xfs_buf_submit: dev 65:65 bno 0x27ffffff8 nblks 0x8 hold 2 pincount 0 lock 0 flags WRITE|ASYNC|DONE|PAGES caller __xfs_buf_delwri_submit [xfs] xfsaild/sdu1-7991 [005] .N.. 5392363.647059: xfs_buf_hold: dev 65:65 bno 0x27ffffff8 nblks 0x8 hold 2 pincount 0 lock 0 flags WRITE|ASYNC|DONE|PAGES caller xfs_buf_submit [xfs] xfsaild/sdu1-7991 [005] .N.. 5392363.647061: xfs_buf_rele: dev 65:65 bno 0x27ffffff8 nblks 0x8 hold 3 pincount 0 lock 0 flags WRITE|ASYNC|DONE|PAGES caller xfs_buf_submit [xfs] xfsaild/sdu1-7991 [005] .N.. 5392363.647061: xfs_buf_submit: dev 65:65 bno 0x280006398 nblks 0x8 hold 2 pincount 0 lock 0 flags WRITE|ASYNC|DONE|PAGES caller __xfs_buf_delwri_submit [xfs] xfsaild/sdu1-7991 [005] .N.. 5392363.647061: xfs_buf_hold: dev 65:65 bno 0x280006398 nblks 0x8 hold 2 pincount 0 lock 0 flags WRITE|ASYNC|DONE|PAGES caller xfs_buf_submit [xfs] xfsaild/sdu1-7991 [005] .N.. 5392363.647063: xfs_buf_rele: dev 65:65 bno 0x280006398 nblks 0x8 hold 3 pincount 0 lock 0 flags WRITE|ASYNC|DONE|PAGES caller xfs_buf_submit [xfs] xfsaild/sdu1-7991 [005] .N.. 5392363.647063: xfs_buf_submit: dev 65:65 bno 0x2800063f8 nblks 0x8 hold 2 pincount 0 lock 0 flags WRITE|ASYNC|DONE|PAGES caller __xfs_buf_delwri_submit [xfs] xfsaild/sdu1-7991 [005] .N.. 5392363.647064: xfs_buf_hold: dev 65:65 bno 0x2800063f8 nblks 0x8 hold 2 pincount 0 lock 0 flags WRITE|ASYNC|DONE|PAGES caller xfs_buf_submit [xfs] In the 181953 lines there's a set of 188 different block numbers appearing, ranging from 0x8 to 0x2900ffbd8: # sed -rn 's/.*bno (0x[[:xdigit:]]+).*/\1/p' /tmp/x1 | sort -u > /tmp/x2 # wc -l /tmp/x2 188 /tmp/x2 # perl -pe 's/(.*)/hex($1)/e' /tmp/x2 | sort -n | perl -ne 'printf "0x%x\n",$_' > /tmp/x3 # head /tmp/x3 0x8 0x10 0x20 0x28 0x3188 0x4a40 0x4a68 0x2b163a0 0x31fecd0 0x426e8f8 b2# tail /tmp/x3 0x2900ffb78 0x2900ffb88 0x2900ffb98 0x2900ffba8 0x2900ffbb0 0x2900ffbb8 0x2900ffbc0 0x2900ffbc8 0x2900ffbd0 0x2900ffbd8 >> As previously mentioned, the disk has actually reappeared under a different >> /dev/sdXX name (it was sdu, now sdbh). Trying to mount the disk (read only) >> results in: >> >> # mkdir /mnt/xfs && mount -ologdev=/dev/md8p5,ro /dev/sdbh1 /mnt/xfs >> mount: /dev/sdbh1 already mounted or /mnt/xfs busy > > Probably due to either a uuid check or blocking on access to the > external log device. You'll probably need to clean up the stale mount > before this will work. > > As it is, something is clearly wrong with the drive. I can't really > interpret the I/O errors and whatnot (linux-scsi?), but you probably > want to look into health assessment tools (e.g., smart) to get an idea > of what's wrong and/or replace the device and restore from backups (or > perhaps heal via the ceph cluster, in your case). Sure. It's not the disk that's concerning me, they're expected to die, but it looks like the disk error has put XFS in a state where the only solution is a hard power cycle (after quiescing and cleaning up what I can): I haven't tried it yet, but I expect I won't be able reboot cleanly. > > Brian Cheers, Chris From bfoster@redhat.com Tue Nov 17 11:37:28 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 9D75D7F37 for ; Tue, 17 Nov 2015 11:37:28 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 11DD0AC003 for ; Tue, 17 Nov 2015 09:37:27 -0800 (PST) X-ASG-Debug-ID: 1447781845-04cb6c0cd2c3a80001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id GXrCRbqnruhfMV56 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 17 Nov 2015 09:37:26 -0800 (PST) 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 (Postfix) with ESMTPS id A56A38F28D; Tue, 17 Nov 2015 17:37:25 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-225.bos.redhat.com [10.18.41.225]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAHHbP7J007219; Tue, 17 Nov 2015 12:37:25 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id 95FEA120A64; Tue, 17 Nov 2015 12:37:24 -0500 (EST) Date: Tue, 17 Nov 2015 12:37:24 -0500 From: Brian Foster To: Chris Dunlop Cc: xfs@oss.sgi.com Subject: Re: Disk error, then endless loop Message-ID: <20151117173724.GA18963@bfoster.bfoster> X-ASG-Orig-Subj: Re: Disk error, then endless loop References: <20151117080332.GA28936@onthe.net.au> <20151117124148.GA20118@bfoster.bfoster> <20151117162802.GA28374@onthe.net.au> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151117162802.GA28374@onthe.net.au> 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: 1447781846 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Wed, Nov 18, 2015 at 03:28:02AM +1100, Chris Dunlop wrote: > G'day Brian, > > Thanks for your response... > > On Tue, Nov 17, 2015 at 07:41:48AM -0500, Brian Foster wrote: > > On Tue, Nov 17, 2015 at 07:03:33PM +1100, Chris Dunlop wrote: > >> Hi, > >> ... > > >> I tried to umount the filesystem but the umount is now hung and unkillable: > >> > >> # ps -ostat,wchan='WCHAN-xxxxxxxxxxxxxxxxxx',cmd -C umount > >> STAT WCHAN-xxxxxxxxxxxxxxxxxx CMD > >> D+ xfs_ail_push_all_sync umount /var/lib/ceph/osd/ceph-18 > > > > ... but it appears you still have something pending in the AIL which is > > holding everything up. The most likely case is an EFI/EFD item hanging > > around from an extent free operation, as this was a known issue, > > particularly on fs shutdowns. Fixes for this went into the v4.3 kernel. > > Any chance of these fixes getting into -stable, or are they too intrusive > and/or depend on other intrusive changes? > I don't think so... it was a multi-patch series and a rework of the EFI/EFD reference counting as opposed to an isolated bug fix. For reference, it was commits 5e4b538 through f0b2efa or so. > > Note that this won't address whatever is wrong with the disk in the > > first place, > > Bwaaaaahhhh, magic ponies! > > > just (hopefully) the ability to unmount when it ultimately fails. > > Yes, that's what I was hoping for. > > > Does the umount process actually appear to be doing anything? E.g., are > > you seeing noticeable CPU load or I/O errors continue to the logs, or > > has everything pretty much locked up? You could also enable tracepoints > > (trace-cmd start -e "xfs:*"; cat /sys/kernel/debug/tracing/trace_pipe) > > to get a quick idea of what's going on. > > No, the umount hasn't done anything noticable in the past 6.5 hours: > > b2# date; ps -opid,lstart,time,stat,wchan='WCHAN-xxxxxxxxxxxxxxxxxx',cmd -C umount > Wed Nov 18 03:08:30 AEDT 2015 > PID STARTED TIME STAT WCHAN-xxxxxxxxxxxxxxxxxx CMD > 23946 Tue Nov 17 17:30:41 2015 00:00:00 D+ xfs_ail_push_all_sync umount /var/lib/ceph/osd/ceph-18 > > I don't know how to interpret the tracepoints, but there are other busy > XFS filesystems on the box so that's cluttering things up. For what it's > worth, it appears the original device (/dev/sdu1) was previously dev > 65:65: > > b2# ls -l /dev/sd[tuv]{,1} > brw-rw---T 1 root disk 65, 48 Sep 16 17:11 /dev/sdt > brw-rw---T 1 root disk 65, 49 Sep 16 17:11 /dev/sdt1 > brw-rw---T 1 root disk 65, 80 Oct 30 15:38 /dev/sdv > brw-rw---T 1 root disk 65, 81 Oct 30 15:40 /dev/sdv1 > > ..and in 10 seconds of /sys/kernel/debug/tracing/trace_pipe we have: > > # grep 'dev 65:65' /sys/kernel/debug/tracing/trace_pipe > /tmp/x1 & sleep 10; kill $! > # wc -l /tmp/x1 > 181953 /tmp/x1 > # head /tmp/x1 > <...>-7702 [012] .... 5392362.786946: xfs_buf_item_iodone_async: dev 65:65 bno 0x1828eed18 nblks 0x8 hold 2 pincount 0 lock 0 flags ASYNC|DONE|PAGES caller xfs_buf_ioend [xfs] > <...>-7702 [012] .... 5392362.786946: xfs_buf_ioerror: dev 65:65 bno 0x1828eed18 len 0x1000 hold 2 pincount 0 lock 0 error 0 flags ASYNC|DONE|PAGES caller xfs_buf_iodone_callbacks [xfs] > xfsaild/sdu1-7991 [005] .N.. 5392363.647059: xfs_buf_submit: dev 65:65 bno 0x27ffffff8 nblks 0x8 hold 2 pincount 0 lock 0 flags WRITE|ASYNC|DONE|PAGES caller __xfs_buf_delwri_submit [xfs] > xfsaild/sdu1-7991 [005] .N.. 5392363.647059: xfs_buf_hold: dev 65:65 bno 0x27ffffff8 nblks 0x8 hold 2 pincount 0 lock 0 flags WRITE|ASYNC|DONE|PAGES caller xfs_buf_submit [xfs] > xfsaild/sdu1-7991 [005] .N.. 5392363.647061: xfs_buf_rele: dev 65:65 bno 0x27ffffff8 nblks 0x8 hold 3 pincount 0 lock 0 flags WRITE|ASYNC|DONE|PAGES caller xfs_buf_submit [xfs] > xfsaild/sdu1-7991 [005] .N.. 5392363.647061: xfs_buf_submit: dev 65:65 bno 0x280006398 nblks 0x8 hold 2 pincount 0 lock 0 flags WRITE|ASYNC|DONE|PAGES caller __xfs_buf_delwri_submit [xfs] > xfsaild/sdu1-7991 [005] .N.. 5392363.647061: xfs_buf_hold: dev 65:65 bno 0x280006398 nblks 0x8 hold 2 pincount 0 lock 0 flags WRITE|ASYNC|DONE|PAGES caller xfs_buf_submit [xfs] > xfsaild/sdu1-7991 [005] .N.. 5392363.647063: xfs_buf_rele: dev 65:65 bno 0x280006398 nblks 0x8 hold 3 pincount 0 lock 0 flags WRITE|ASYNC|DONE|PAGES caller xfs_buf_submit [xfs] > xfsaild/sdu1-7991 [005] .N.. 5392363.647063: xfs_buf_submit: dev 65:65 bno 0x2800063f8 nblks 0x8 hold 2 pincount 0 lock 0 flags WRITE|ASYNC|DONE|PAGES caller __xfs_buf_delwri_submit [xfs] > xfsaild/sdu1-7991 [005] .N.. 5392363.647064: xfs_buf_hold: dev 65:65 bno 0x2800063f8 nblks 0x8 hold 2 pincount 0 lock 0 flags WRITE|ASYNC|DONE|PAGES caller xfs_buf_submit [xfs] > Hmm, that is notably more activity than I recall when reproducing the original AIL issue. Do we know whether the filesystem had actually shut down or is in some intermediate state looping on errors? The fact that it continues to try and submit I/O suggests that perhaps it hasn't shut down for whatever reason. If the device has already dropped and reconnected as a new dev node, it's probably harmless at this point to just try to forcibly shut down the fs on the old one. Could you try the following? xfs_io -x -c shutdown Can you unmount the fs after that? If not, is there still any tracepoint activity on the old device? Brian > In the 181953 lines there's a set of 188 different block numbers > appearing, ranging from 0x8 to 0x2900ffbd8: > > # sed -rn 's/.*bno (0x[[:xdigit:]]+).*/\1/p' /tmp/x1 | sort -u > /tmp/x2 > # wc -l /tmp/x2 > 188 /tmp/x2 > # perl -pe 's/(.*)/hex($1)/e' /tmp/x2 | sort -n | perl -ne 'printf "0x%x\n",$_' > /tmp/x3 > # head /tmp/x3 > 0x8 > 0x10 > 0x20 > 0x28 > 0x3188 > 0x4a40 > 0x4a68 > 0x2b163a0 > 0x31fecd0 > 0x426e8f8 > b2# tail /tmp/x3 > 0x2900ffb78 > 0x2900ffb88 > 0x2900ffb98 > 0x2900ffba8 > 0x2900ffbb0 > 0x2900ffbb8 > 0x2900ffbc0 > 0x2900ffbc8 > 0x2900ffbd0 > 0x2900ffbd8 > > >> As previously mentioned, the disk has actually reappeared under a different > >> /dev/sdXX name (it was sdu, now sdbh). Trying to mount the disk (read only) > >> results in: > >> > >> # mkdir /mnt/xfs && mount -ologdev=/dev/md8p5,ro /dev/sdbh1 /mnt/xfs > >> mount: /dev/sdbh1 already mounted or /mnt/xfs busy > > > > Probably due to either a uuid check or blocking on access to the > > external log device. You'll probably need to clean up the stale mount > > before this will work. > > > > As it is, something is clearly wrong with the drive. I can't really > > interpret the I/O errors and whatnot (linux-scsi?), but you probably > > want to look into health assessment tools (e.g., smart) to get an idea > > of what's wrong and/or replace the device and restore from backups (or > > perhaps heal via the ceph cluster, in your case). > > Sure. It's not the disk that's concerning me, they're expected to die, > but it looks like the disk error has put XFS in a state where the only > solution is a hard power cycle (after quiescing and cleaning up what I > can): I haven't tried it yet, but I expect I won't be able reboot > cleanly. > > > > > Brian > > Cheers, > > Chris > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From ross.zwisler@linux.intel.com Tue Nov 17 11:52:48 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 DF4917F37 for ; Tue, 17 Nov 2015 11:52:47 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 68182AC003 for ; Tue, 17 Nov 2015 09:52:47 -0800 (PST) X-ASG-Debug-ID: 1447782765-04cb6c0cd4c3f20001-NocioJ Received: from mga14.intel.com ([192.55.52.115]) by cuda.sgi.com with ESMTP id G5iAywO6neFVpbMP for ; Tue, 17 Nov 2015 09:52:45 -0800 (PST) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 192.55.52.115 Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga103.fm.intel.com with ESMTP; 17 Nov 2015 09:52:45 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,308,1444719600"; d="scan'208";a="822360638" Received: from theros.lm.intel.com (HELO linux.intel.com) ([10.232.112.87]) by orsmga001.jf.intel.com with ESMTP; 17 Nov 2015 09:52:43 -0800 Date: Tue, 17 Nov 2015 10:52:43 -0700 From: Ross Zwisler To: Dave Hansen Cc: Ross Zwisler , linux-kernel@vger.kernel.org, "H. Peter Anvin" , "J. Bruce Fields" , Theodore Ts'o , Alexander Viro , Andreas Dilger , Dan Williams , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@lists.01.org, x86@kernel.org, xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox Subject: Re: [PATCH v2 02/11] mm: add pmd_mkclean() Message-ID: <20151117175243.GA28024@linux.intel.com> X-ASG-Orig-Subj: Re: [PATCH v2 02/11] mm: add pmd_mkclean() Mail-Followup-To: Ross Zwisler , Dave Hansen , linux-kernel@vger.kernel.org, "H. Peter Anvin" , "J. Bruce Fields" , Theodore Ts'o , Alexander Viro , Andreas Dilger , Dan Williams , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@lists.01.org, x86@kernel.org, xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox References: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> <1447459610-14259-3-git-send-email-ross.zwisler@linux.intel.com> <56468838.6010506@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <56468838.6010506@intel.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-Barracuda-Connect: UNKNOWN[192.55.52.115] X-Barracuda-Start-Time: 1447782765 X-Barracuda-URL: https://192.48.176.15:443/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.24478 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS On Fri, Nov 13, 2015 at 05:02:48PM -0800, Dave Hansen wrote: > On 11/13/2015 04:06 PM, Ross Zwisler wrote: > > +static inline pmd_t pmd_mkclean(pmd_t pmd) > > +{ > > + return pmd_clear_flags(pmd, _PAGE_DIRTY | _PAGE_SOFT_DIRTY); > > +} > > pte_mkclean() doesn't clear _PAGE_SOFT_DIRTY. What the thought behind > doing it here? I just wrote it to undo the work done by pmd_mkdirty() - you're right, it should mirror the work done by pte_mkclean() and not clear _PAGE_SOFT_DIRTY. I'll fix this for v3, thanks! From ross.zwisler@linux.intel.com Tue Nov 17 12:10:36 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 1C28E7F37 for ; Tue, 17 Nov 2015 12:10:36 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id E3E5030404E for ; Tue, 17 Nov 2015 10:10:32 -0800 (PST) X-ASG-Debug-ID: 1447783830-04bdf07f07da170001-NocioJ Received: from mga01.intel.com ([192.55.52.88]) by cuda.sgi.com with ESMTP id pfMBMteEkReLqmcH for ; Tue, 17 Nov 2015 10:10:30 -0800 (PST) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 192.55.52.88 X-ASG-Whitelist: EmailCat (corporate) Received: from orsmga002.jf.intel.com ([10.7.209.21]) by fmsmga101.fm.intel.com with ESMTP; 17 Nov 2015 10:09:01 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,308,1444719600"; d="scan'208";a="852945533" Received: from theros.lm.intel.com (HELO linux.intel.com) ([10.232.112.87]) by orsmga002.jf.intel.com with ESMTP; 17 Nov 2015 10:08:59 -0800 Date: Tue, 17 Nov 2015 11:08:58 -0700 From: Ross Zwisler To: Dave Chinner Cc: Ross Zwisler , linux-kernel@vger.kernel.org, "H. Peter Anvin" , "J. Bruce Fields" , Theodore Ts'o , Alexander Viro , Andreas Dilger , Dan Williams , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@lists.01.org, x86@kernel.org, xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox , Dave Hansen Subject: Re: [PATCH v2 07/11] mm: add find_get_entries_tag() Message-ID: <20151117180858.GB28024@linux.intel.com> X-ASG-Orig-Subj: Re: [PATCH v2 07/11] mm: add find_get_entries_tag() Mail-Followup-To: Ross Zwisler , Dave Chinner , linux-kernel@vger.kernel.org, "H. Peter Anvin" , "J. Bruce Fields" , Theodore Ts'o , Alexander Viro , Andreas Dilger , Dan Williams , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@lists.01.org, x86@kernel.org, xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox , Dave Hansen References: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> <1447459610-14259-8-git-send-email-ross.zwisler@linux.intel.com> <20151116224222.GW19199@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151116224222.GW19199@dastard> User-Agent: Mutt/1.5.23 (2014-03-12) X-Barracuda-Connect: UNKNOWN[192.55.52.88] X-Barracuda-Start-Time: 1447783830 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Tue, Nov 17, 2015 at 09:42:22AM +1100, Dave Chinner wrote: > On Fri, Nov 13, 2015 at 05:06:46PM -0700, Ross Zwisler wrote: > > Add find_get_entries_tag() to the family of functions that include > > find_get_entries(), find_get_pages() and find_get_pages_tag(). This is > > needed for DAX dirty page handling because we need a list of both page > > offsets and radix tree entries ('indices' and 'entries' in this function) > > that are marked with the PAGECACHE_TAG_TOWRITE tag. > > > > Signed-off-by: Ross Zwisler > > --- > > include/linux/pagemap.h | 3 +++ > > mm/filemap.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++ > > 2 files changed, 64 insertions(+) > > > > diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h > > index a6c78e0..6fea3be 100644 > > --- a/include/linux/pagemap.h > > +++ b/include/linux/pagemap.h > > @@ -354,6 +354,9 @@ unsigned find_get_pages_contig(struct address_space *mapping, pgoff_t start, > > unsigned int nr_pages, struct page **pages); > > unsigned find_get_pages_tag(struct address_space *mapping, pgoff_t *index, > > int tag, unsigned int nr_pages, struct page **pages); > > +unsigned find_get_entries_tag(struct address_space *mapping, pgoff_t start, > > + int tag, unsigned int nr_entries, > > + struct page **entries, pgoff_t *indices); > > > > struct page *grab_cache_page_write_begin(struct address_space *mapping, > > pgoff_t index, unsigned flags); > > diff --git a/mm/filemap.c b/mm/filemap.c > > index d5e94fd..89ab448 100644 > > --- a/mm/filemap.c > > +++ b/mm/filemap.c > > @@ -1454,6 +1454,67 @@ repeat: > > } > > EXPORT_SYMBOL(find_get_pages_tag); > > > > +/** > > + * find_get_entries_tag - find and return entries that match @tag > > + * @mapping: the address_space to search > > + * @start: the starting page cache index > > + * @tag: the tag index > > + * @nr_entries: the maximum number of entries > > + * @entries: where the resulting entries are placed > > + * @indices: the cache indices corresponding to the entries in @entries > > + * > > + * Like find_get_entries, except we only return entries which are tagged with > > + * @tag. > > + */ > > +unsigned find_get_entries_tag(struct address_space *mapping, pgoff_t start, > > + int tag, unsigned int nr_entries, > > + struct page **entries, pgoff_t *indices) > > +{ > > + void **slot; > > + unsigned int ret = 0; > > + struct radix_tree_iter iter; > > + > > + if (!nr_entries) > > + return 0; > > + > > + rcu_read_lock(); > > +restart: > > + radix_tree_for_each_tagged(slot, &mapping->page_tree, > > + &iter, start, tag) { > > + struct page *page; > > +repeat: > > + page = radix_tree_deref_slot(slot); > > + if (unlikely(!page)) > > + continue; > > + if (radix_tree_exception(page)) { > > + if (radix_tree_deref_retry(page)) > > + goto restart; > > That restart condition looks wrong. ret can be non-zero, but we > start looking from the original start index again, resulting in > duplicates being added to the return arrays... This same restart logic is used in all the functions in this family: find_get_entry() (though the tag is "repeat"), find_get_entries(), find_get_pages(), find_get_pages_contig() and find_get_pages_tag(). Most don't have it well commented, but there is a good comment in find_get_pages(): if (radix_tree_exception(page)) { if (radix_tree_deref_retry(page)) { /* * Transient condition which can only trigger * when entry at index 0 moves out of or back * to root: none yet gotten, safe to restart. */ WARN_ON(iter.index); goto restart; } I think the logic is correct, but I'm happy to add this comment in find_get_entries_tag() if it would make things clearer. From ross.zwisler@linux.intel.com Tue Nov 17 12:30:21 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 81B547F37 for ; Tue, 17 Nov 2015 12:30:21 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 5140930404E for ; Tue, 17 Nov 2015 10:30:21 -0800 (PST) X-ASG-Debug-ID: 1447785018-04cbb0605ee96a0001-NocioJ Received: from mga14.intel.com ([192.55.52.115]) by cuda.sgi.com with ESMTP id qUw8yApPdfdoD34j for ; Tue, 17 Nov 2015 10:30:18 -0800 (PST) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 192.55.52.115 Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga103.fm.intel.com with ESMTP; 17 Nov 2015 10:30:18 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,309,1444719600"; d="scan'208";a="840787311" Received: from theros.lm.intel.com (HELO linux.intel.com) ([10.232.112.87]) by fmsmga001.fm.intel.com with ESMTP; 17 Nov 2015 10:30:16 -0800 Date: Tue, 17 Nov 2015 11:30:16 -0700 From: Ross Zwisler To: Dave Chinner Cc: Ross Zwisler , linux-kernel@vger.kernel.org, "H. Peter Anvin" , "J. Bruce Fields" , Theodore Ts'o , Alexander Viro , Andreas Dilger , Dan Williams , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@lists.01.org, x86@kernel.org, xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox , Dave Hansen Subject: Re: [PATCH v2 08/11] dax: add support for fsync/sync Message-ID: <20151117183016.GC28024@linux.intel.com> X-ASG-Orig-Subj: Re: [PATCH v2 08/11] dax: add support for fsync/sync Mail-Followup-To: Ross Zwisler , Dave Chinner , linux-kernel@vger.kernel.org, "H. Peter Anvin" , "J. Bruce Fields" , Theodore Ts'o , Alexander Viro , Andreas Dilger , Dan Williams , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@lists.01.org, x86@kernel.org, xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox , Dave Hansen References: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> <1447459610-14259-9-git-send-email-ross.zwisler@linux.intel.com> <20151116225807.GX19199@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151116225807.GX19199@dastard> User-Agent: Mutt/1.5.23 (2014-03-12) X-Barracuda-Connect: UNKNOWN[192.55.52.115] X-Barracuda-Start-Time: 1447785018 X-Barracuda-URL: https://192.48.176.25:443/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.24479 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS On Tue, Nov 17, 2015 at 09:58:07AM +1100, Dave Chinner wrote: > On Fri, Nov 13, 2015 at 05:06:47PM -0700, Ross Zwisler wrote: > > To properly handle fsync/msync in an efficient way DAX needs to track dirty > > pages so it is able to flush them durably to media on demand. > > > > The tracking of dirty pages is done via the radix tree in struct > > address_space. This radix tree is already used by the page writeback > > infrastructure for tracking dirty pages associated with an open file, and > > it already has support for exceptional (non struct page*) entries. We > > build upon these features to add exceptional entries to the radix tree for > > DAX dirty PMD or PTE pages at fault time. > > > > When called as part of the msync/fsync flush path DAX queries the radix > > tree for dirty entries, flushing them and then marking the PTE or PMD page > > table entries as clean. The step of cleaning the PTE or PMD entries is > > necessary so that on subsequent writes to the same page we get a new write > > fault allowing us to once again dirty the DAX tag in the radix tree. > > > > Signed-off-by: Ross Zwisler > > --- > > fs/dax.c | 140 +++++++++++++++++++++++++++++++++++++++++++++++++--- > > include/linux/dax.h | 1 + > > mm/huge_memory.c | 14 +++--- > > 3 files changed, 141 insertions(+), 14 deletions(-) > > > > diff --git a/fs/dax.c b/fs/dax.c > > index 131fd35a..9ce6d1b 100644 > > --- a/fs/dax.c > > +++ b/fs/dax.c > > @@ -24,7 +24,9 @@ > > #include > > #include > > #include > > +#include > > #include > > +#include > > #include > > #include > > #include > > @@ -287,6 +289,53 @@ static int copy_user_bh(struct page *to, struct buffer_head *bh, > > return 0; > > } > > > > +static int dax_dirty_pgoff(struct address_space *mapping, unsigned long pgoff, > > + void __pmem *addr, bool pmd_entry) > > +{ > > + struct radix_tree_root *page_tree = &mapping->page_tree; > > + int error = 0; > > + void *entry; > > + > > + __mark_inode_dirty(mapping->host, I_DIRTY_PAGES); > > + > > + spin_lock_irq(&mapping->tree_lock); > > + entry = radix_tree_lookup(page_tree, pgoff); > > + if (addr == NULL) { > > + if (entry) > > + goto dirty; > > + else { > > + WARN(1, "DAX pfn_mkwrite failed to find an entry"); > > + goto out; > > + } > > + } > > + > > + if (entry) { > > + if (pmd_entry && RADIX_DAX_TYPE(entry) == RADIX_DAX_PTE) { > > + radix_tree_delete(&mapping->page_tree, pgoff); > > + mapping->nrdax--; > > + } else > > + goto dirty; > > + } > > Logic is pretty spagettied here. Perhaps: > > entry = radix_tree_lookup(page_tree, pgoff); > if (entry) { > if (!pmd_entry || RADIX_DAX_TYPE(entry) == RADIX_DAX_PMD)) > goto dirty; > radix_tree_delete(&mapping->page_tree, pgoff); > mapping->nrdax--; > } else { > WARN_ON(!addr); > goto out_unlock; > } > .... I don't think that this works because now if !entry we unconditionally goto out_unlock without inserting a new entry. I'll try and simplify the logic and add some comments. > > + > > + BUG_ON(RADIX_DAX_TYPE(addr)); > > + if (pmd_entry) > > + error = radix_tree_insert(page_tree, pgoff, > > + RADIX_DAX_PMD_ENTRY(addr)); > > + else > > + error = radix_tree_insert(page_tree, pgoff, > > + RADIX_DAX_PTE_ENTRY(addr)); > > + > > + if (error) > > + goto out; > > + > > + mapping->nrdax++; > > + dirty: > > + radix_tree_tag_set(page_tree, pgoff, PAGECACHE_TAG_DIRTY); > > + out: > > + spin_unlock_irq(&mapping->tree_lock); > > label should be "out_unlock" rather "out" to indicate in the code > that we are jumping to the correct spot in the error stack... Sure, will do. > > + goto fallback; > > } > > > > out: > > @@ -689,15 +746,12 @@ EXPORT_SYMBOL_GPL(dax_pmd_fault); > > * dax_pfn_mkwrite - handle first write to DAX page > > * @vma: The virtual memory area where the fault occurred > > * @vmf: The description of the fault > > - * > > */ > > int dax_pfn_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) > > { > > - struct super_block *sb = file_inode(vma->vm_file)->i_sb; > > + struct file *file = vma->vm_file; > > > > - sb_start_pagefault(sb); > > - file_update_time(vma->vm_file); > > - sb_end_pagefault(sb); > > + dax_dirty_pgoff(file->f_mapping, vmf->pgoff, NULL, false); > > return VM_FAULT_NOPAGE; > > This seems wrong - it's dropping the freeze protection on fault, and > now the inode timestamp won't get updated, either. Oh, that all still happens in the filesystem pfn_mkwrite code (xfs_filemap_pfn_mkwrite() for XFS). It needs to happen there, I think, because we wanted to order it so that the filesystem freeze happens outside of the XFS_MMAPLOCK_SHARED locking, as it does with the regular PMD and PTE fault paths. Prior to this patch set dax_pfn_mkwrite() was completely unused an was ready to be removed as dead code - it's now being used by all filesystems just to make sure we re-add the newly dirtied page to the radix tree dirty list. > > } > > EXPORT_SYMBOL_GPL(dax_pfn_mkwrite); > > @@ -772,3 +826,77 @@ int dax_truncate_page(struct inode *inode, loff_t from, get_block_t get_block) > > return dax_zero_page_range(inode, from, length, get_block); > > } > > EXPORT_SYMBOL_GPL(dax_truncate_page); > > + > > +static void dax_sync_entry(struct address_space *mapping, pgoff_t pgoff, > > + void *entry) > > +{ > > dax_writeback_pgoff() seems like a more consistent name (consider > dax_dirty_pgoff), and that we are actually doing a writeback > operation, not a "sync" operation. Sure, I'm fine with that change. > > + struct radix_tree_root *page_tree = &mapping->page_tree; > > + int type = RADIX_DAX_TYPE(entry); > > + size_t size; > > + > > + BUG_ON(type != RADIX_DAX_PTE && type != RADIX_DAX_PMD); > > + > > + spin_lock_irq(&mapping->tree_lock); > > + if (!radix_tree_tag_get(page_tree, pgoff, PAGECACHE_TAG_TOWRITE)) { > > + /* another fsync thread already wrote back this entry */ > > + spin_unlock_irq(&mapping->tree_lock); > > + return; > > + } > > + radix_tree_tag_clear(page_tree, pgoff, PAGECACHE_TAG_TOWRITE); > > + radix_tree_tag_clear(page_tree, pgoff, PAGECACHE_TAG_DIRTY); > > + spin_unlock_irq(&mapping->tree_lock); > > + > > + if (type == RADIX_DAX_PMD) > > + size = PMD_SIZE; > > + else > > + size = PAGE_SIZE; > > + > > + wb_cache_pmem(RADIX_DAX_ADDR(entry), size); > > + pgoff_mkclean(pgoff, mapping); > > This looks racy w.r.t. another operation setting the radix tree > dirty tags. i.e. there is no locking to serialise marking the > vma/pte clean and another operation marking the radix tree dirty. I think you're right - I'll look into how to protect us from this race. Thank you for catching this. > > +} > > + > > +/* > > + * Flush the mapping to the persistent domain within the byte range of (start, > > + * end). This is required by data integrity operations to ensure file data is on > > + * persistent storage prior to completion of the operation. It also requires us > > + * to clean the mappings (i.e. write -> RO) so that we'll get a new fault when > > + * the file is written to again so we have an indication that we need to flush > > + * the mapping if a data integrity operation takes place. > > + * > > + * We don't need commits to storage here - the filesystems will issue flushes > > + * appropriately at the conclusion of the data integrity operation via REQ_FUA > > + * writes or blkdev_issue_flush() commands. This requires the DAX block device > > + * to implement persistent storage domain fencing/commits on receiving a > > + * REQ_FLUSH or REQ_FUA request so that this works as expected by the higher > > + * layers. > > + */ > > +void dax_fsync(struct address_space *mapping, loff_t start, loff_t end) > > +{ > > dax_writeback_mapping_range() Sure, I'm fine with that change. From prvs=8763e27c61=clm@fb.com Tue Nov 17 12:43:24 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 9F6197F37 for ; Tue, 17 Nov 2015 12:43:24 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 822E58F8035 for ; Tue, 17 Nov 2015 10:43:21 -0800 (PST) X-ASG-Debug-ID: 1447785799-04cbb0605ce9a00001-NocioJ Received: from mx0a-00082601.pphosted.com (mx0a-00082601.pphosted.com [67.231.145.42]) by cuda.sgi.com with ESMTP id 2Kp85vMFm2iqruGd (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 17 Nov 2015 10:43:20 -0800 (PST) X-Barracuda-Envelope-From: prvs=8763e27c61=clm@fb.com X-Barracuda-Apparent-Source-IP: 67.231.145.42 X-ASG-Whitelist: EmailCat (corporate) Received: from pps.filterd (m0044012.ppops.net [127.0.0.1]) by mx0a-00082601.pphosted.com (8.15.0.59/8.15.0.59) with SMTP id tAHIdgdm029141; Tue, 17 Nov 2015 10:42:32 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=fb.com; h=date : from : to : cc : subject : message-id : references : mime-version : content-type : in-reply-to; s=facebook; bh=VSioXOS4VBdoIClmx6P9JWDGcy+vjkZHZSamqq+P0Vw=; b=dGAEwh48Ux9DzTV6k1LGONGEw41jmeCd+7hTlTlmt0KE9DGHRjaBUB9AzZ0zaXnvn13T 8gKNshId8SiNbgsLpLz6rL+hN5NVlOha0tl5Hlsz5BV8OloCZUEHszW8vO2Dkol2YvAh fpIrx7z054DaZQ4tnyN4pQbcxyWo87I/pjk= Received: from mail.thefacebook.com ([199.201.64.23]) by mx0a-00082601.pphosted.com with ESMTP id 1y7yj9j863-1 (version=TLSv1/SSLv3 cipher=AES128-SHA bits=128 verify=NOT); Tue, 17 Nov 2015 10:42:32 -0800 Received: from localhost (192.168.52.123) by mail.thefacebook.com (192.168.16.11) with Microsoft SMTP Server (TLS) id 14.3.248.2; Tue, 17 Nov 2015 10:42:31 -0800 Date: Tue, 17 Nov 2015 13:42:28 -0500 From: Chris Mason To: Christoph Hellwig CC: "Darrick J. Wong" , , Subject: Re: clone ioctl return values Message-ID: <20151117184228.GG17545@ret.masoncoding.com> X-ASG-Orig-Subj: Re: clone ioctl return values Mail-Followup-To: Chris Mason , Christoph Hellwig , "Darrick J. Wong" , xfs@oss.sgi.com, linux-fsdevel@vger.kernel.org References: <20151116120431.GA2860@infradead.org> <20151117002822.GA32467@birch.djwong.org> <20151117105433.GA18093@infradead.org> <20151117135745.GF17545@ret.masoncoding.com> <20151117152251.GA5392@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Disposition: inline In-Reply-To: <20151117152251.GA5392@infradead.org> User-Agent: Mutt/1.5.23.1 (2014-03-12) X-Originating-IP: [192.168.52.123] X-Proofpoint-Spam-Reason: safe X-FB-Internal: Safe X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:,, definitions=2015-11-17_11:,, signatures=0 X-Barracuda-Connect: mx0a-00082601.pphosted.com[67.231.145.42] X-Barracuda-Start-Time: 1447785799 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Tue, Nov 17, 2015 at 07:22:52AM -0800, Christoph Hellwig wrote: > On Tue, Nov 17, 2015 at 08:57:45AM -0500, Chris Mason wrote: > > > > Errrgh, the golden output of this test reflects the changes to the input > > > > checking in Anna/Peng's copy_file_range/clone_file_range patches. > > > > > > > > So, I guess the question is, should I reset the golden output to whatever > > > > btrfs spits out before that patchset, and we'll consider the alterations > > > > to be bugs/regressions/whatever that ought to be fixed in their patches? > > > > > > Some bits in btrfs don't seem kosher. But it would be good to > > > explicitly send patches for btrfs to adopt to what might make more > > > sense, and then follow it in the other implementations. > > > > Btrfs does check for directories, but we should really be checking for > > regular files too. In the end, we only copy extents that would > > correspond with regular files, so we're sneaking by. > > Yes, I saw that. So so far I'd suggest something like the following > for btrfs: > > - return EBADFD for missing read/wite permissions Why not -EPERM? I don't have strong feelings about picking errnos, as long as we're consistent, I'm not worried. > - return EINVAL for wrong non-directory file types as the > source fd Ack. -chris From ross.zwisler@linux.intel.com Tue Nov 17 13:10:50 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 886F67F37 for ; Tue, 17 Nov 2015 13:10:50 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 79EFF8F8035 for ; Tue, 17 Nov 2015 11:10:47 -0800 (PST) X-ASG-Debug-ID: 1447787442-04cbb0605cea1c0001-NocioJ Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by cuda.sgi.com with ESMTP id n265KKcbW5Xf5sF5 for ; Tue, 17 Nov 2015 11:10:42 -0800 (PST) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 134.134.136.20 X-ASG-Whitelist: EmailCat (corporate) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga101.jf.intel.com with ESMTP; 17 Nov 2015 11:03:42 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,309,1444719600"; d="scan'208";a="853174298" Received: from theros.lm.intel.com (HELO linux.intel.com) ([10.232.112.87]) by fmsmga002.fm.intel.com with ESMTP; 17 Nov 2015 11:03:42 -0800 Date: Tue, 17 Nov 2015 12:03:41 -0700 From: Ross Zwisler To: Dave Chinner Cc: Ross Zwisler , linux-kernel@vger.kernel.org, "H. Peter Anvin" , "J. Bruce Fields" , Theodore Ts'o , Alexander Viro , Andreas Dilger , Dan Williams , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@lists.01.org, x86@kernel.org, xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox , Dave Hansen Subject: Re: [PATCH v2 11/11] xfs: add support for DAX fsync/msync Message-ID: <20151117190341.GD28024@linux.intel.com> X-ASG-Orig-Subj: Re: [PATCH v2 11/11] xfs: add support for DAX fsync/msync Mail-Followup-To: Ross Zwisler , Dave Chinner , linux-kernel@vger.kernel.org, "H. Peter Anvin" , "J. Bruce Fields" , Theodore Ts'o , Alexander Viro , Andreas Dilger , Dan Williams , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@lists.01.org, x86@kernel.org, xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox , Dave Hansen References: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> <1447459610-14259-12-git-send-email-ross.zwisler@linux.intel.com> <20151116231222.GY19199@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151116231222.GY19199@dastard> User-Agent: Mutt/1.5.23 (2014-03-12) X-Barracuda-Connect: mga02.intel.com[134.134.136.20] X-Barracuda-Start-Time: 1447787442 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Tue, Nov 17, 2015 at 10:12:22AM +1100, Dave Chinner wrote: > On Fri, Nov 13, 2015 at 05:06:50PM -0700, Ross Zwisler wrote: > > To properly support the new DAX fsync/msync infrastructure filesystems > > need to call dax_pfn_mkwrite() so that DAX can properly track when a user > > write faults on a previously cleaned address. They also need to call > > dax_fsync() in the filesystem fsync() path. This dax_fsync() call uses > > addresses retrieved from get_block() so it needs to be ordered with > > respect to truncate. This is accomplished by using the same locking that > > was set up for DAX page faults. > > > > Signed-off-by: Ross Zwisler > > --- > > fs/xfs/xfs_file.c | 18 +++++++++++++----- > > 1 file changed, 13 insertions(+), 5 deletions(-) > > > > diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c > > index 39743ef..2b490a1 100644 > > --- a/fs/xfs/xfs_file.c > > +++ b/fs/xfs/xfs_file.c > > @@ -209,7 +209,8 @@ xfs_file_fsync( > > loff_t end, > > int datasync) > > { > > - struct inode *inode = file->f_mapping->host; > > + struct address_space *mapping = file->f_mapping; > > + struct inode *inode = mapping->host; > > struct xfs_inode *ip = XFS_I(inode); > > struct xfs_mount *mp = ip->i_mount; > > int error = 0; > > @@ -218,7 +219,13 @@ xfs_file_fsync( > > > > trace_xfs_file_fsync(ip); > > > > - error = filemap_write_and_wait_range(inode->i_mapping, start, end); > > + if (dax_mapping(mapping)) { > > + xfs_ilock(XFS_I(inode), XFS_MMAPLOCK_SHARED); > > + dax_fsync(mapping, start, end); > > + xfs_iunlock(XFS_I(inode), XFS_MMAPLOCK_SHARED); > > + } > > + > > + error = filemap_write_and_wait_range(mapping, start, end); > > Ok, I don't understand a couple of things here. > > Firstly, if it's a DAX mapping, why are we still calling > filemap_write_and_wait_range() after the dax_fsync() call that has > already written back all the dirty cachelines? > > Secondly, exactly what is the XFS_MMAPLOCK_SHARED lock supposed to > be doing here? I don't see where dax_fsync() has any callouts to > get_block(), so the comment "needs to be ordered with respect to > truncate" doesn't make any obvious sense. If we have a racing > truncate removing entries from the radix tree, then thanks to the > mapping tree lock we'll either find an entry we need to write back, > or we won't find any entry at all, right? You're right, dax_fsync() doesn't call out to get_block() any more. It does save the results of get_block() calls from the page faults, though, and I was concerned about the following race: fsync thread truncate thread ------------ --------------- dax_fsync() save tagged entries in pvec change block mapping for inode so that entries saved in pvec are no longer owned by this inode loop through pvec using stale results from get_block(), flushing and cleaning entries we no longer own In looking at the xfs_file_fsync() code, though, it seems like if this race existed it would also exist for page cache entries that were being put into a pvec in write_cache_pages(), and that we would similarly be writing back cached pages that no longer belong to this inode. Is this race non-existent? > Lastly, this flushing really needs to be inside > filemap_write_and_wait_range(), because we call the writeback code > from many more places than just fsync to ensure ordering of various > operations such that files are in known state before proceeding > (e.g. hole punch). The call to dax_fsync() (soon to be dax_writeback_mapping_range()) first lived in do_writepages() in the RFC version, but was moved into the filesystem so we could have access to get_block(), which is no longer needed, and so we could use the FS level locking. If the race described above isn't an issue then I agree moving this call out of the filesystems and down into the generic page writeback code is probably the right thing to do. Thanks for the feedback. From chris@onthe.net.au Tue Nov 17 13:35:44 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 0E2297F3F for ; Tue, 17 Nov 2015 13:35:44 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id F0662304067 for ; Tue, 17 Nov 2015 11:35:40 -0800 (PST) X-ASG-Debug-ID: 1447788936-04cbb0605eeaa80001-NocioJ Received: from smtp1.onthe.net.au (smtp1.onthe.net.au [203.22.196.249]) by cuda.sgi.com with ESMTP id y0MTVNBTFKQHIunS for ; Tue, 17 Nov 2015 11:35:37 -0800 (PST) X-Barracuda-Envelope-From: chris@onthe.net.au X-Barracuda-Apparent-Source-IP: 203.22.196.249 Received: from localhost (localhost [127.0.0.1]) by smtp1.onthe.net.au (Postfix) with ESMTP id 82370617AD; Wed, 18 Nov 2015 06:35:36 +1100 (EST) Received: from smtp1.onthe.net.au ([127.0.0.1]) by localhost (smtp1.onthe.net.au [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id E8f+wD+0D+5Q; Wed, 18 Nov 2015 06:35:36 +1100 (EST) Received: from o1.private.otn.net.au (o1.private.onthe.net.au [10.200.63.41]) by smtp1.onthe.net.au (Postfix) with ESMTP id 09B8B6179E; Wed, 18 Nov 2015 06:35:36 +1100 (EST) Received: from hestia (pony.office.onthe.net.au [10.9.1.6]) by o1.private.otn.net.au (Postfix) with ESMTP id 8EDDCE122D; Wed, 18 Nov 2015 06:35:35 +1100 (AEDT) Received: by hestia (Postfix, from userid 1000) id 03AE1580730; Wed, 18 Nov 2015 06:35:35 +1100 (AEDT) Date: Wed, 18 Nov 2015 06:35:34 +1100 From: Chris Dunlop To: Brian Foster Cc: xfs@oss.sgi.com Subject: Re: Disk error, then endless loop Message-ID: <20151117193534.GA1514@onthe.net.au> X-ASG-Orig-Subj: Re: Disk error, then endless loop References: <20151117080332.GA28936@onthe.net.au> <20151117124148.GA20118@bfoster.bfoster> <20151117162802.GA28374@onthe.net.au> <20151117173724.GA18963@bfoster.bfoster> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151117173724.GA18963@bfoster.bfoster> User-Agent: Mutt/1.5.23 (2014-03-12) X-Barracuda-Connect: smtp1.onthe.net.au[203.22.196.249] X-Barracuda-Start-Time: 1447788937 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24480 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Tue, Nov 17, 2015 at 12:37:24PM -0500, Brian Foster wrote: > On Wed, Nov 18, 2015 at 03:28:02AM +1100, Chris Dunlop wrote: >> On Tue, Nov 17, 2015 at 07:41:48AM -0500, Brian Foster wrote: >>> On Tue, Nov 17, 2015 at 07:03:33PM +1100, Chris Dunlop wrote: >>>> I tried to umount the filesystem but the umount is now hung and unkillable: >>>> >>>> # ps -ostat,wchan='WCHAN-xxxxxxxxxxxxxxxxxx',cmd -C umount >>>> STAT WCHAN-xxxxxxxxxxxxxxxxxx CMD >>>> D+ xfs_ail_push_all_sync umount /var/lib/ceph/osd/ceph-18 >>> >>> ... but it appears you still have something pending in the AIL which is >>> holding everything up. The most likely case is an EFI/EFD item hanging >>> around from an extent free operation, as this was a known issue, >>> particularly on fs shutdowns. Fixes for this went into the v4.3 kernel. >> >> Any chance of these fixes getting into -stable, or are they too intrusive >> and/or depend on other intrusive changes? > > I don't think so... it was a multi-patch series and a rework of the > EFI/EFD reference counting as opposed to an isolated bug fix. For > reference, it was commits 5e4b538 through f0b2efa or so. ... >>> Does the umount process actually appear to be doing anything? E.g., are >>> you seeing noticeable CPU load or I/O errors continue to the logs, or >>> has everything pretty much locked up? You could also enable tracepoints >>> (trace-cmd start -e "xfs:*"; cat /sys/kernel/debug/tracing/trace_pipe) >>> to get a quick idea of what's going on. >> >> No, the umount hasn't done anything noticable in the past 6.5 hours: >> >> b2# date; ps -opid,lstart,time,stat,wchan='WCHAN-xxxxxxxxxxxxxxxxxx',cmd -C umount >> Wed Nov 18 03:08:30 AEDT 2015 >> PID STARTED TIME STAT WCHAN-xxxxxxxxxxxxxxxxxx CMD >> 23946 Tue Nov 17 17:30:41 2015 00:00:00 D+ xfs_ail_push_all_sync umount /var/lib/ceph/osd/ceph-18 >> >> I don't know how to interpret the tracepoints, but there are other busy >> XFS filesystems on the box so that's cluttering things up. For what it's >> worth, it appears the original device (/dev/sdu1) was previously dev >> 65:65: >> >> b2# ls -l /dev/sd[tuv]{,1} >> brw-rw---T 1 root disk 65, 48 Sep 16 17:11 /dev/sdt >> brw-rw---T 1 root disk 65, 49 Sep 16 17:11 /dev/sdt1 >> brw-rw---T 1 root disk 65, 80 Oct 30 15:38 /dev/sdv >> brw-rw---T 1 root disk 65, 81 Oct 30 15:40 /dev/sdv1 >> >> ..and in 10 seconds of /sys/kernel/debug/tracing/trace_pipe we have: >> >> # grep 'dev 65:65' /sys/kernel/debug/tracing/trace_pipe > /tmp/x1 & sleep 10; kill $! >> # wc -l /tmp/x1 >> 181953 /tmp/x1 >> # head /tmp/x1 >> <...>-7702 [012] .... 5392362.786946: xfs_buf_item_iodone_async: dev 65:65 bno 0x1828eed18 nblks 0x8 hold 2 pincount 0 lock 0 flags ASYNC|DONE|PAGES caller xfs_buf_ioend [xfs] >> <...>-7702 [012] .... 5392362.786946: xfs_buf_ioerror: dev 65:65 bno 0x1828eed18 len 0x1000 hold 2 pincount 0 lock 0 error 0 flags ASYNC|DONE|PAGES caller xfs_buf_iodone_callbacks [xfs] >> xfsaild/sdu1-7991 [005] .N.. 5392363.647059: xfs_buf_submit: dev 65:65 bno 0x27ffffff8 nblks 0x8 hold 2 pincount 0 lock 0 flags WRITE|ASYNC|DONE|PAGES caller __xfs_buf_delwri_submit [xfs] >> xfsaild/sdu1-7991 [005] .N.. 5392363.647059: xfs_buf_hold: dev 65:65 bno 0x27ffffff8 nblks 0x8 hold 2 pincount 0 lock 0 flags WRITE|ASYNC|DONE|PAGES caller xfs_buf_submit [xfs] >> xfsaild/sdu1-7991 [005] .N.. 5392363.647061: xfs_buf_rele: dev 65:65 bno 0x27ffffff8 nblks 0x8 hold 3 pincount 0 lock 0 flags WRITE|ASYNC|DONE|PAGES caller xfs_buf_submit [xfs] >> xfsaild/sdu1-7991 [005] .N.. 5392363.647061: xfs_buf_submit: dev 65:65 bno 0x280006398 nblks 0x8 hold 2 pincount 0 lock 0 flags WRITE|ASYNC|DONE|PAGES caller __xfs_buf_delwri_submit [xfs] >> xfsaild/sdu1-7991 [005] .N.. 5392363.647061: xfs_buf_hold: dev 65:65 bno 0x280006398 nblks 0x8 hold 2 pincount 0 lock 0 flags WRITE|ASYNC|DONE|PAGES caller xfs_buf_submit [xfs] >> xfsaild/sdu1-7991 [005] .N.. 5392363.647063: xfs_buf_rele: dev 65:65 bno 0x280006398 nblks 0x8 hold 3 pincount 0 lock 0 flags WRITE|ASYNC|DONE|PAGES caller xfs_buf_submit [xfs] >> xfsaild/sdu1-7991 [005] .N.. 5392363.647063: xfs_buf_submit: dev 65:65 bno 0x2800063f8 nblks 0x8 hold 2 pincount 0 lock 0 flags WRITE|ASYNC|DONE|PAGES caller __xfs_buf_delwri_submit [xfs] >> xfsaild/sdu1-7991 [005] .N.. 5392363.647064: xfs_buf_hold: dev 65:65 bno 0x2800063f8 nblks 0x8 hold 2 pincount 0 lock 0 flags WRITE|ASYNC|DONE|PAGES caller xfs_buf_submit [xfs] >> > > Hmm, that is notably more activity than I recall when reproducing the > original AIL issue. Do we know whether the filesystem had actually shut > down or is in some intermediate state looping on errors? The fact that > it continues to try and submit I/O suggests that perhaps it hasn't shut > down for whatever reason. > > If the device has already dropped and reconnected as a new dev node, > it's probably harmless at this point to just try to forcibly shut down > the fs on the old one. Could you try the following? > > xfs_io -x -c shutdown # xfs_io -x -c shutdown /var/lib/ceph/osd/ceph-18 foreign file active, shutdown command is for XFS filesystems only # grep ceph-18 /etc/mtab <<< crickets >>> I don't know when the fs disappeared from mtab, it could have been when I first did the umount I guess, I didn't think to check at the time. But the umount is still there: # date; ps -opid,lstart,time,stat,wchan='WCHAN-xxxxxxxxxxxxxxxxxx',cmd -C umount Wed Nov 18 06:23:21 AEDT 2015 PID STARTED TIME STAT WCHAN-xxxxxxxxxxxxxxxxxx CMD 23946 Tue Nov 17 17:30:41 2015 00:00:00 D+ xfs_ail_push_all_sync umount /var/lib/ceph/osd/ceph-18 > Can you unmount the fs after that? If not, is there still any tracepoint > activity on the old device? > > Brian The activity is still ongoing on the old device: # trace-cmd start -e "xfs:*" /sys/kernel/debug/tracing/events/xfs/*/filter # grep 'dev 65:65' /sys/kernel/debug/tracing/trace_pipe > /tmp/y1 & sleep 10; kill $!; wc -l /tmp/y1 129573 /tmp/y1 Doing my little sed and perl dance shows it's still the same set of 188 blocks as mentioned before. Chris >> In the 181953 lines there's a set of 188 different block numbers >> appearing, ranging from 0x8 to 0x2900ffbd8: >> >> # sed -rn 's/.*bno (0x[[:xdigit:]]+).*/\1/p' /tmp/x1 | sort -u > /tmp/x2 >> # wc -l /tmp/x2 >> 188 /tmp/x2 >> # perl -pe 's/(.*)/hex($1)/e' /tmp/x2 | sort -n | perl -ne 'printf "0x%x\n",$_' > /tmp/x3 >> # head /tmp/x3 >> 0x8 >> 0x10 >> 0x20 >> 0x28 >> 0x3188 >> 0x4a40 >> 0x4a68 >> 0x2b163a0 >> 0x31fecd0 >> 0x426e8f8 >> b2# tail /tmp/x3 >> 0x2900ffb78 >> 0x2900ffb88 >> 0x2900ffb98 >> 0x2900ffba8 >> 0x2900ffbb0 >> 0x2900ffbb8 >> 0x2900ffbc0 >> 0x2900ffbc8 >> 0x2900ffbd0 >> 0x2900ffbd8 >> >>>> As previously mentioned, the disk has actually reappeared under a different >>>> /dev/sdXX name (it was sdu, now sdbh). Trying to mount the disk (read only) >>>> results in: >>>> >>>> # mkdir /mnt/xfs && mount -ologdev=/dev/md8p5,ro /dev/sdbh1 /mnt/xfs >>>> mount: /dev/sdbh1 already mounted or /mnt/xfs busy >>> >>> Probably due to either a uuid check or blocking on access to the >>> external log device. You'll probably need to clean up the stale mount >>> before this will work. >>> >>> As it is, something is clearly wrong with the drive. I can't really >>> interpret the I/O errors and whatnot (linux-scsi?), but you probably >>> want to look into health assessment tools (e.g., smart) to get an idea >>> of what's wrong and/or replace the device and restore from backups (or >>> perhaps heal via the ceph cluster, in your case). >> >> Sure. It's not the disk that's concerning me, they're expected to die, >> but it looks like the disk error has put XFS in a state where the only >> solution is a hard power cycle (after quiescing and cleaning up what I >> can): I haven't tried it yet, but I expect I won't be able reboot >> cleanly. >> >>> >>> Brian >> >> Cheers, >> >> Chris From bfoster@redhat.com Tue Nov 17 14:21:42 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 E70287F47 for ; Tue, 17 Nov 2015 14:21:41 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 64DE0AC002 for ; Tue, 17 Nov 2015 12:21:38 -0800 (PST) X-ASG-Debug-ID: 1447791692-04cbb0605deb930001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id P5Dd5ZSJ2KEKLR53 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 17 Nov 2015 12:21:33 -0800 (PST) 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 (Postfix) with ESMTPS id AF5ABC814; Tue, 17 Nov 2015 20:21:32 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-225.bos.redhat.com [10.18.41.225]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAHKLWxw004959; Tue, 17 Nov 2015 15:21:32 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id 8CD36120A64; Tue, 17 Nov 2015 15:21:31 -0500 (EST) Date: Tue, 17 Nov 2015 15:21:31 -0500 From: Brian Foster To: Chris Dunlop Cc: xfs@oss.sgi.com Subject: Re: Disk error, then endless loop Message-ID: <20151117202131.GA43800@bfoster.bfoster> X-ASG-Orig-Subj: Re: Disk error, then endless loop References: <20151117080332.GA28936@onthe.net.au> <20151117124148.GA20118@bfoster.bfoster> <20151117162802.GA28374@onthe.net.au> <20151117173724.GA18963@bfoster.bfoster> <20151117193534.GA1514@onthe.net.au> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151117193534.GA1514@onthe.net.au> 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: 1447791693 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Wed, Nov 18, 2015 at 06:35:34AM +1100, Chris Dunlop wrote: > On Tue, Nov 17, 2015 at 12:37:24PM -0500, Brian Foster wrote: > > On Wed, Nov 18, 2015 at 03:28:02AM +1100, Chris Dunlop wrote: > >> On Tue, Nov 17, 2015 at 07:41:48AM -0500, Brian Foster wrote: > >>> On Tue, Nov 17, 2015 at 07:03:33PM +1100, Chris Dunlop wrote: > >>>> I tried to umount the filesystem but the umount is now hung and unkillable: > >>>> > >>>> # ps -ostat,wchan='WCHAN-xxxxxxxxxxxxxxxxxx',cmd -C umount > >>>> STAT WCHAN-xxxxxxxxxxxxxxxxxx CMD > >>>> D+ xfs_ail_push_all_sync umount /var/lib/ceph/osd/ceph-18 > >>> > >>> ... but it appears you still have something pending in the AIL which is > >>> holding everything up. The most likely case is an EFI/EFD item hanging > >>> around from an extent free operation, as this was a known issue, > >>> particularly on fs shutdowns. Fixes for this went into the v4.3 kernel. > >> > >> Any chance of these fixes getting into -stable, or are they too intrusive > >> and/or depend on other intrusive changes? > > > > I don't think so... it was a multi-patch series and a rework of the > > EFI/EFD reference counting as opposed to an isolated bug fix. For > > reference, it was commits 5e4b538 through f0b2efa or so. > > ... > > >>> Does the umount process actually appear to be doing anything? E.g., are > >>> you seeing noticeable CPU load or I/O errors continue to the logs, or > >>> has everything pretty much locked up? You could also enable tracepoints > >>> (trace-cmd start -e "xfs:*"; cat /sys/kernel/debug/tracing/trace_pipe) > >>> to get a quick idea of what's going on. > >> > >> No, the umount hasn't done anything noticable in the past 6.5 hours: > >> > >> b2# date; ps -opid,lstart,time,stat,wchan='WCHAN-xxxxxxxxxxxxxxxxxx',cmd -C umount > >> Wed Nov 18 03:08:30 AEDT 2015 > >> PID STARTED TIME STAT WCHAN-xxxxxxxxxxxxxxxxxx CMD > >> 23946 Tue Nov 17 17:30:41 2015 00:00:00 D+ xfs_ail_push_all_sync umount /var/lib/ceph/osd/ceph-18 > >> > >> I don't know how to interpret the tracepoints, but there are other busy > >> XFS filesystems on the box so that's cluttering things up. For what it's > >> worth, it appears the original device (/dev/sdu1) was previously dev > >> 65:65: > >> > >> b2# ls -l /dev/sd[tuv]{,1} > >> brw-rw---T 1 root disk 65, 48 Sep 16 17:11 /dev/sdt > >> brw-rw---T 1 root disk 65, 49 Sep 16 17:11 /dev/sdt1 > >> brw-rw---T 1 root disk 65, 80 Oct 30 15:38 /dev/sdv > >> brw-rw---T 1 root disk 65, 81 Oct 30 15:40 /dev/sdv1 > >> > >> ..and in 10 seconds of /sys/kernel/debug/tracing/trace_pipe we have: > >> > >> # grep 'dev 65:65' /sys/kernel/debug/tracing/trace_pipe > /tmp/x1 & sleep 10; kill $! > >> # wc -l /tmp/x1 > >> 181953 /tmp/x1 > >> # head /tmp/x1 > >> <...>-7702 [012] .... 5392362.786946: xfs_buf_item_iodone_async: dev 65:65 bno 0x1828eed18 nblks 0x8 hold 2 pincount 0 lock 0 flags ASYNC|DONE|PAGES caller xfs_buf_ioend [xfs] > >> <...>-7702 [012] .... 5392362.786946: xfs_buf_ioerror: dev 65:65 bno 0x1828eed18 len 0x1000 hold 2 pincount 0 lock 0 error 0 flags ASYNC|DONE|PAGES caller xfs_buf_iodone_callbacks [xfs] > >> xfsaild/sdu1-7991 [005] .N.. 5392363.647059: xfs_buf_submit: dev 65:65 bno 0x27ffffff8 nblks 0x8 hold 2 pincount 0 lock 0 flags WRITE|ASYNC|DONE|PAGES caller __xfs_buf_delwri_submit [xfs] > >> xfsaild/sdu1-7991 [005] .N.. 5392363.647059: xfs_buf_hold: dev 65:65 bno 0x27ffffff8 nblks 0x8 hold 2 pincount 0 lock 0 flags WRITE|ASYNC|DONE|PAGES caller xfs_buf_submit [xfs] > >> xfsaild/sdu1-7991 [005] .N.. 5392363.647061: xfs_buf_rele: dev 65:65 bno 0x27ffffff8 nblks 0x8 hold 3 pincount 0 lock 0 flags WRITE|ASYNC|DONE|PAGES caller xfs_buf_submit [xfs] > >> xfsaild/sdu1-7991 [005] .N.. 5392363.647061: xfs_buf_submit: dev 65:65 bno 0x280006398 nblks 0x8 hold 2 pincount 0 lock 0 flags WRITE|ASYNC|DONE|PAGES caller __xfs_buf_delwri_submit [xfs] > >> xfsaild/sdu1-7991 [005] .N.. 5392363.647061: xfs_buf_hold: dev 65:65 bno 0x280006398 nblks 0x8 hold 2 pincount 0 lock 0 flags WRITE|ASYNC|DONE|PAGES caller xfs_buf_submit [xfs] > >> xfsaild/sdu1-7991 [005] .N.. 5392363.647063: xfs_buf_rele: dev 65:65 bno 0x280006398 nblks 0x8 hold 3 pincount 0 lock 0 flags WRITE|ASYNC|DONE|PAGES caller xfs_buf_submit [xfs] > >> xfsaild/sdu1-7991 [005] .N.. 5392363.647063: xfs_buf_submit: dev 65:65 bno 0x2800063f8 nblks 0x8 hold 2 pincount 0 lock 0 flags WRITE|ASYNC|DONE|PAGES caller __xfs_buf_delwri_submit [xfs] > >> xfsaild/sdu1-7991 [005] .N.. 5392363.647064: xfs_buf_hold: dev 65:65 bno 0x2800063f8 nblks 0x8 hold 2 pincount 0 lock 0 flags WRITE|ASYNC|DONE|PAGES caller xfs_buf_submit [xfs] > >> > > > > Hmm, that is notably more activity than I recall when reproducing the > > original AIL issue. Do we know whether the filesystem had actually shut > > down or is in some intermediate state looping on errors? The fact that > > it continues to try and submit I/O suggests that perhaps it hasn't shut > > down for whatever reason. > > > > If the device has already dropped and reconnected as a new dev node, > > it's probably harmless at this point to just try to forcibly shut down > > the fs on the old one. Could you try the following? > > > > xfs_io -x -c shutdown > > # xfs_io -x -c shutdown /var/lib/ceph/osd/ceph-18 > foreign file active, shutdown command is for XFS filesystems only > > # grep ceph-18 /etc/mtab > <<< crickets >>> > > I don't know when the fs disappeared from mtab, it could have been when I > first did the umount I guess, I didn't think to check at the time. But the > umount is still there: > > # date; ps -opid,lstart,time,stat,wchan='WCHAN-xxxxxxxxxxxxxxxxxx',cmd -C umount > Wed Nov 18 06:23:21 AEDT 2015 > PID STARTED TIME STAT WCHAN-xxxxxxxxxxxxxxxxxx CMD > 23946 Tue Nov 17 17:30:41 2015 00:00:00 D+ xfs_ail_push_all_sync umount /var/lib/ceph/osd/ceph-18 > Ah, so it's already been removed from the namespace. Apparently it's stuck at some point after the mount is made inaccessible and before it actually finishes with I/O. I'm not sure we have any other option other than a reset at this point, unfortunately. :/ Brian > > Can you unmount the fs after that? If not, is there still any tracepoint > > activity on the old device? > > > > Brian > > The activity is still ongoing on the old device: > > # trace-cmd start -e "xfs:*" > /sys/kernel/debug/tracing/events/xfs/*/filter > # grep 'dev 65:65' /sys/kernel/debug/tracing/trace_pipe > /tmp/y1 & sleep 10; kill $!; wc -l /tmp/y1 > 129573 /tmp/y1 > > Doing my little sed and perl dance shows it's still the same set of 188 > blocks as mentioned before. > > Chris > > >> In the 181953 lines there's a set of 188 different block numbers > >> appearing, ranging from 0x8 to 0x2900ffbd8: > >> > >> # sed -rn 's/.*bno (0x[[:xdigit:]]+).*/\1/p' /tmp/x1 | sort -u > /tmp/x2 > >> # wc -l /tmp/x2 > >> 188 /tmp/x2 > >> # perl -pe 's/(.*)/hex($1)/e' /tmp/x2 | sort -n | perl -ne 'printf "0x%x\n",$_' > /tmp/x3 > >> # head /tmp/x3 > >> 0x8 > >> 0x10 > >> 0x20 > >> 0x28 > >> 0x3188 > >> 0x4a40 > >> 0x4a68 > >> 0x2b163a0 > >> 0x31fecd0 > >> 0x426e8f8 > >> b2# tail /tmp/x3 > >> 0x2900ffb78 > >> 0x2900ffb88 > >> 0x2900ffb98 > >> 0x2900ffba8 > >> 0x2900ffbb0 > >> 0x2900ffbb8 > >> 0x2900ffbc0 > >> 0x2900ffbc8 > >> 0x2900ffbd0 > >> 0x2900ffbd8 > >> > >>>> As previously mentioned, the disk has actually reappeared under a different > >>>> /dev/sdXX name (it was sdu, now sdbh). Trying to mount the disk (read only) > >>>> results in: > >>>> > >>>> # mkdir /mnt/xfs && mount -ologdev=/dev/md8p5,ro /dev/sdbh1 /mnt/xfs > >>>> mount: /dev/sdbh1 already mounted or /mnt/xfs busy > >>> > >>> Probably due to either a uuid check or blocking on access to the > >>> external log device. You'll probably need to clean up the stale mount > >>> before this will work. > >>> > >>> As it is, something is clearly wrong with the drive. I can't really > >>> interpret the I/O errors and whatnot (linux-scsi?), but you probably > >>> want to look into health assessment tools (e.g., smart) to get an idea > >>> of what's wrong and/or replace the device and restore from backups (or > >>> perhaps heal via the ceph cluster, in your case). > >> > >> Sure. It's not the disk that's concerning me, they're expected to die, > >> but it looks like the disk error has put XFS in a state where the only > >> solution is a hard power cycle (after quiescing and cleaning up what I > >> can): I haven't tried it yet, but I expect I won't be able reboot > >> cleanly. > >> > >>> > >>> Brian > >> > >> Cheers, > >> > >> Chris > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From bfoster@redhat.com Tue Nov 17 14:35:02 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 0C2367F37 for ; Tue, 17 Nov 2015 14:35:02 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id EF50F304059 for ; Tue, 17 Nov 2015 12:34:58 -0800 (PST) X-ASG-Debug-ID: 1447792496-04cbb0605debca0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id UCmSgxWN8N3G9vie (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 17 Nov 2015 12:34:57 -0800 (PST) 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 (Postfix) with ESMTPS id ADD75CC08D; Tue, 17 Nov 2015 20:34:56 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-225.bos.redhat.com [10.18.41.225]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAHKYuXw018713; Tue, 17 Nov 2015 15:34:56 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id 860FB120A64; Tue, 17 Nov 2015 15:34:55 -0500 (EST) Date: Tue, 17 Nov 2015 15:34:55 -0500 From: Brian Foster To: Chris Dunlop Cc: xfs@oss.sgi.com Subject: Re: Disk error, then endless loop Message-ID: <20151117203455.GB43800@bfoster.bfoster> X-ASG-Orig-Subj: Re: Disk error, then endless loop References: <20151117080332.GA28936@onthe.net.au> <20151117124148.GA20118@bfoster.bfoster> <20151117162802.GA28374@onthe.net.au> <20151117173724.GA18963@bfoster.bfoster> <20151117193534.GA1514@onthe.net.au> <20151117202131.GA43800@bfoster.bfoster> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151117202131.GA43800@bfoster.bfoster> 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: 1447792497 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Tue, Nov 17, 2015 at 03:21:31PM -0500, Brian Foster wrote: > On Wed, Nov 18, 2015 at 06:35:34AM +1100, Chris Dunlop wrote: > > On Tue, Nov 17, 2015 at 12:37:24PM -0500, Brian Foster wrote: > > > On Wed, Nov 18, 2015 at 03:28:02AM +1100, Chris Dunlop wrote: > > >> On Tue, Nov 17, 2015 at 07:41:48AM -0500, Brian Foster wrote: > > >>> On Tue, Nov 17, 2015 at 07:03:33PM +1100, Chris Dunlop wrote: > > >>>> I tried to umount the filesystem but the umount is now hung and unkillable: > > >>>> > > >>>> # ps -ostat,wchan='WCHAN-xxxxxxxxxxxxxxxxxx',cmd -C umount > > >>>> STAT WCHAN-xxxxxxxxxxxxxxxxxx CMD > > >>>> D+ xfs_ail_push_all_sync umount /var/lib/ceph/osd/ceph-18 > > >>> > > >>> ... but it appears you still have something pending in the AIL which is > > >>> holding everything up. The most likely case is an EFI/EFD item hanging > > >>> around from an extent free operation, as this was a known issue, > > >>> particularly on fs shutdowns. Fixes for this went into the v4.3 kernel. > > >> > > >> Any chance of these fixes getting into -stable, or are they too intrusive > > >> and/or depend on other intrusive changes? > > > > > > I don't think so... it was a multi-patch series and a rework of the > > > EFI/EFD reference counting as opposed to an isolated bug fix. For > > > reference, it was commits 5e4b538 through f0b2efa or so. > > > > ... > > > > >>> Does the umount process actually appear to be doing anything? E.g., are > > >>> you seeing noticeable CPU load or I/O errors continue to the logs, or > > >>> has everything pretty much locked up? You could also enable tracepoints > > >>> (trace-cmd start -e "xfs:*"; cat /sys/kernel/debug/tracing/trace_pipe) > > >>> to get a quick idea of what's going on. > > >> > > >> No, the umount hasn't done anything noticable in the past 6.5 hours: > > >> > > >> b2# date; ps -opid,lstart,time,stat,wchan='WCHAN-xxxxxxxxxxxxxxxxxx',cmd -C umount > > >> Wed Nov 18 03:08:30 AEDT 2015 > > >> PID STARTED TIME STAT WCHAN-xxxxxxxxxxxxxxxxxx CMD > > >> 23946 Tue Nov 17 17:30:41 2015 00:00:00 D+ xfs_ail_push_all_sync umount /var/lib/ceph/osd/ceph-18 > > >> > > >> I don't know how to interpret the tracepoints, but there are other busy > > >> XFS filesystems on the box so that's cluttering things up. For what it's > > >> worth, it appears the original device (/dev/sdu1) was previously dev > > >> 65:65: > > >> > > >> b2# ls -l /dev/sd[tuv]{,1} > > >> brw-rw---T 1 root disk 65, 48 Sep 16 17:11 /dev/sdt > > >> brw-rw---T 1 root disk 65, 49 Sep 16 17:11 /dev/sdt1 > > >> brw-rw---T 1 root disk 65, 80 Oct 30 15:38 /dev/sdv > > >> brw-rw---T 1 root disk 65, 81 Oct 30 15:40 /dev/sdv1 > > >> > > >> ..and in 10 seconds of /sys/kernel/debug/tracing/trace_pipe we have: > > >> > > >> # grep 'dev 65:65' /sys/kernel/debug/tracing/trace_pipe > /tmp/x1 & sleep 10; kill $! > > >> # wc -l /tmp/x1 > > >> 181953 /tmp/x1 > > >> # head /tmp/x1 > > >> <...>-7702 [012] .... 5392362.786946: xfs_buf_item_iodone_async: dev 65:65 bno 0x1828eed18 nblks 0x8 hold 2 pincount 0 lock 0 flags ASYNC|DONE|PAGES caller xfs_buf_ioend [xfs] > > >> <...>-7702 [012] .... 5392362.786946: xfs_buf_ioerror: dev 65:65 bno 0x1828eed18 len 0x1000 hold 2 pincount 0 lock 0 error 0 flags ASYNC|DONE|PAGES caller xfs_buf_iodone_callbacks [xfs] > > >> xfsaild/sdu1-7991 [005] .N.. 5392363.647059: xfs_buf_submit: dev 65:65 bno 0x27ffffff8 nblks 0x8 hold 2 pincount 0 lock 0 flags WRITE|ASYNC|DONE|PAGES caller __xfs_buf_delwri_submit [xfs] > > >> xfsaild/sdu1-7991 [005] .N.. 5392363.647059: xfs_buf_hold: dev 65:65 bno 0x27ffffff8 nblks 0x8 hold 2 pincount 0 lock 0 flags WRITE|ASYNC|DONE|PAGES caller xfs_buf_submit [xfs] > > >> xfsaild/sdu1-7991 [005] .N.. 5392363.647061: xfs_buf_rele: dev 65:65 bno 0x27ffffff8 nblks 0x8 hold 3 pincount 0 lock 0 flags WRITE|ASYNC|DONE|PAGES caller xfs_buf_submit [xfs] > > >> xfsaild/sdu1-7991 [005] .N.. 5392363.647061: xfs_buf_submit: dev 65:65 bno 0x280006398 nblks 0x8 hold 2 pincount 0 lock 0 flags WRITE|ASYNC|DONE|PAGES caller __xfs_buf_delwri_submit [xfs] > > >> xfsaild/sdu1-7991 [005] .N.. 5392363.647061: xfs_buf_hold: dev 65:65 bno 0x280006398 nblks 0x8 hold 2 pincount 0 lock 0 flags WRITE|ASYNC|DONE|PAGES caller xfs_buf_submit [xfs] > > >> xfsaild/sdu1-7991 [005] .N.. 5392363.647063: xfs_buf_rele: dev 65:65 bno 0x280006398 nblks 0x8 hold 3 pincount 0 lock 0 flags WRITE|ASYNC|DONE|PAGES caller xfs_buf_submit [xfs] > > >> xfsaild/sdu1-7991 [005] .N.. 5392363.647063: xfs_buf_submit: dev 65:65 bno 0x2800063f8 nblks 0x8 hold 2 pincount 0 lock 0 flags WRITE|ASYNC|DONE|PAGES caller __xfs_buf_delwri_submit [xfs] > > >> xfsaild/sdu1-7991 [005] .N.. 5392363.647064: xfs_buf_hold: dev 65:65 bno 0x2800063f8 nblks 0x8 hold 2 pincount 0 lock 0 flags WRITE|ASYNC|DONE|PAGES caller xfs_buf_submit [xfs] > > >> > > > > > > Hmm, that is notably more activity than I recall when reproducing the > > > original AIL issue. Do we know whether the filesystem had actually shut > > > down or is in some intermediate state looping on errors? The fact that > > > it continues to try and submit I/O suggests that perhaps it hasn't shut > > > down for whatever reason. > > > > > > If the device has already dropped and reconnected as a new dev node, > > > it's probably harmless at this point to just try to forcibly shut down > > > the fs on the old one. Could you try the following? > > > > > > xfs_io -x -c shutdown > > > > # xfs_io -x -c shutdown /var/lib/ceph/osd/ceph-18 > > foreign file active, shutdown command is for XFS filesystems only > > > > # grep ceph-18 /etc/mtab > > <<< crickets >>> > > > > I don't know when the fs disappeared from mtab, it could have been when I > > first did the umount I guess, I didn't think to check at the time. But the > > umount is still there: > > > > # date; ps -opid,lstart,time,stat,wchan='WCHAN-xxxxxxxxxxxxxxxxxx',cmd -C umount > > Wed Nov 18 06:23:21 AEDT 2015 > > PID STARTED TIME STAT WCHAN-xxxxxxxxxxxxxxxxxx CMD > > 23946 Tue Nov 17 17:30:41 2015 00:00:00 D+ xfs_ail_push_all_sync umount /var/lib/ceph/osd/ceph-18 > > > > Ah, so it's already been removed from the namespace. Apparently it's > stuck at some point after the mount is made inaccessible and before it > actually finishes with I/O. I'm not sure we have any other option other > than a reset at this point, unfortunately. :/ > > Brian > One last thought... it occurred to me that scsi devs have a delete option under the /sysfs fs. Does the old/stale device still exist under /sys/block/? If so, perhaps an 'echo 1 > /sys/block//device/delete' would move things along..? Note that I have no idea what effect that will have beyond removing the device node (so if it is still accessible now, it probably won't be after that command). I just tried it while doing I/O to a test device and it looked like it caused an fs shutdown, so it could be worth a try as a last resort before a system restart. Brian > > > Can you unmount the fs after that? If not, is there still any tracepoint > > > activity on the old device? > > > > > > Brian > > > > The activity is still ongoing on the old device: > > > > # trace-cmd start -e "xfs:*" > > /sys/kernel/debug/tracing/events/xfs/*/filter > > # grep 'dev 65:65' /sys/kernel/debug/tracing/trace_pipe > /tmp/y1 & sleep 10; kill $!; wc -l /tmp/y1 > > 129573 /tmp/y1 > > > > Doing my little sed and perl dance shows it's still the same set of 188 > > blocks as mentioned before. > > > > Chris > > > > >> In the 181953 lines there's a set of 188 different block numbers > > >> appearing, ranging from 0x8 to 0x2900ffbd8: > > >> > > >> # sed -rn 's/.*bno (0x[[:xdigit:]]+).*/\1/p' /tmp/x1 | sort -u > /tmp/x2 > > >> # wc -l /tmp/x2 > > >> 188 /tmp/x2 > > >> # perl -pe 's/(.*)/hex($1)/e' /tmp/x2 | sort -n | perl -ne 'printf "0x%x\n",$_' > /tmp/x3 > > >> # head /tmp/x3 > > >> 0x8 > > >> 0x10 > > >> 0x20 > > >> 0x28 > > >> 0x3188 > > >> 0x4a40 > > >> 0x4a68 > > >> 0x2b163a0 > > >> 0x31fecd0 > > >> 0x426e8f8 > > >> b2# tail /tmp/x3 > > >> 0x2900ffb78 > > >> 0x2900ffb88 > > >> 0x2900ffb98 > > >> 0x2900ffba8 > > >> 0x2900ffbb0 > > >> 0x2900ffbb8 > > >> 0x2900ffbc0 > > >> 0x2900ffbc8 > > >> 0x2900ffbd0 > > >> 0x2900ffbd8 > > >> > > >>>> As previously mentioned, the disk has actually reappeared under a different > > >>>> /dev/sdXX name (it was sdu, now sdbh). Trying to mount the disk (read only) > > >>>> results in: > > >>>> > > >>>> # mkdir /mnt/xfs && mount -ologdev=/dev/md8p5,ro /dev/sdbh1 /mnt/xfs > > >>>> mount: /dev/sdbh1 already mounted or /mnt/xfs busy > > >>> > > >>> Probably due to either a uuid check or blocking on access to the > > >>> external log device. You'll probably need to clean up the stale mount > > >>> before this will work. > > >>> > > >>> As it is, something is clearly wrong with the drive. I can't really > > >>> interpret the I/O errors and whatnot (linux-scsi?), but you probably > > >>> want to look into health assessment tools (e.g., smart) to get an idea > > >>> of what's wrong and/or replace the device and restore from backups (or > > >>> perhaps heal via the ceph cluster, in your case). > > >> > > >> Sure. It's not the disk that's concerning me, they're expected to die, > > >> but it looks like the disk error has put XFS in a state where the only > > >> solution is a hard power cycle (after quiescing and cleaning up what I > > >> can): I haven't tried it yet, but I expect I won't be able reboot > > >> cleanly. > > >> > > >>> > > >>> Brian > > >> > > >> Cheers, > > >> > > >> Chris > > > > _______________________________________________ > > 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 darrick.wong@oracle.com Tue Nov 17 15:17:51 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 A77FA7F37 for ; Tue, 17 Nov 2015 15:17:51 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 8A1CD8F8050 for ; Tue, 17 Nov 2015 13:17:48 -0800 (PST) X-ASG-Debug-ID: 1447795066-04cbb0605eecab0001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id o85968mC2tz5Xmol (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 17 Nov 2015 13:17:46 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tAHLGkvu010062 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Tue, 17 Nov 2015 21:16:46 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id tAHLGjVv011578 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Tue, 17 Nov 2015 21:16:45 GMT Received: from abhmp0014.oracle.com (abhmp0014.oracle.com [141.146.116.20]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id tAHLGj2H031659; Tue, 17 Nov 2015 21:16:45 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 17 Nov 2015 13:16:45 -0800 Date: Tue, 17 Nov 2015 13:16:43 -0800 From: "Darrick J. Wong" To: Dave Chinner Cc: fstests@vger.kernel.org, xfs@oss.sgi.com, hch@infradead.org, tao.peng@primarydata.com, linux-ext4@vger.kernel.org, Anna.Schumaker@netapp.com, linux-btrfs@vger.kernel.org Subject: Re: [PATCH 01/12] test-scripts: test migration scripts Message-ID: <20151117211643.GF2217@birch.djwong.org> X-ASG-Orig-Subj: Re: [PATCH 01/12] test-scripts: test migration scripts References: <20151113213643.31124.80975.stgit@birch.djwong.org> <20151113213650.31124.16817.stgit@birch.djwong.org> <20151116205845.GK14311@dastard> <20151116235111.GE2224@birch.djwong.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151116235111.GE2224@birch.djwong.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1447795066 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24482 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines On Mon, Nov 16, 2015 at 03:51:11PM -0800, Darrick J. Wong wrote: > On Tue, Nov 17, 2015 at 07:58:45AM +1100, Dave Chinner wrote: > > On Fri, Nov 13, 2015 at 01:36:50PM -0800, Darrick J. Wong wrote: > > > Add two scripts: "nextid" finds the next available test ID number in a > > > group, and "mvtest" relocates a test, fixes the golden output, and > > > moves the group entry for that test. > > > > > > Signed-off-by: Darrick J. Wong > > > --- > > > mvtest | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > > > nextid | 35 +++++++++++++++++++++++++++++++++++ > > > > These should be placed in the "tools" directory. > > > > > > > > create mode 100755 mvtest > > > create mode 100755 nextid > > > > > > > > > diff --git a/mvtest b/mvtest > > > new file mode 100755 > > > index 0000000..b5406d1 > > > --- /dev/null > > > +++ b/mvtest > > > @@ -0,0 +1,58 @@ > > > +#!/bin/sh > > > + > > > +# Renumber a test > > > + > > > +if [ -z "$1" ] || [ "$1" = "--help" ]; then > > > + echo "Usage: $0 path_to_test new_path_to_test" > > > + exit 1 > > > +fi > > > + > > > +src="$1" > > > +dest="$2" > > > + > > > +die() { > > > + echo "$@" > > > + exit 1 > > > +} > > > + > > > +nsort() { > > > + sort -g < "$1" > "$2" > > > +} > > > + > > > +append() { > > > + out="$1" > > > + shift > > > + echo "$@" >> "${out}" > > > +} > > > + > > > +test "${src}" != "${dest}" || die "Test \"${src}\" is the same as dest." > > > +test -e "tests/${src}" || die "Test \"${src}\" does not exist." > > > +test ! -e "tests/${dest}" || die "Test \"${src}\" already exists." > > > + > > > +sid="$(basename "${src}")" > > > +did="$(basename "${dest}")" > > > + > > > +sgroup="$(basename "$(dirname "tests/${src}")")" > > > +dgroup="$(basename "$(dirname "tests/${dest}")")" > > > + > > > +sgroupfile="tests/${sgroup}/group" > > > +dgroupfile="tests/${sgroup}/group" > > > + > > > +$DBG git mv "tests/${src}" "tests/${dest}" > > > > $DBG? > > "DBG=echo ./mvtest foo bar" to see what it would have run, more or less. > > (I suppose I could getopt a --dry-run, but I could also just get rid of them.) > > > > > .... > > > +$DBG sed -e "/^${sid}.*$/d" -i "${sgroupfile}" > > > +$DBG cp "${dgroupfile}" "${dgroupfile}.new" > > > +$DBG append "${dgroupfile}.new" "${newgrpline}" > > > +$DBG nsort "${dgroupfile}.new" "${dgroupfile}" > > > > What does this do to comments in the group file? > > Eats them. I don't know of a good way to sort just the uncommented lines > in the file, short of writing a python script to do that. > > I guess it's not that hard; I've sort of needed one here and there over > the years, but never wrote one, and $google doesn't immediately provide > any such thing. > > > > > ... > > > > > diff --git a/nextid b/nextid > > > new file mode 100755 > > > index 0000000..285b549 > > > --- /dev/null > > > +++ b/nextid > > > @@ -0,0 +1,35 @@ > > > +#!/bin/sh > > > + > > > +# Given a group name, find the next available test number. > > > + > > > +if [ -z "$1" ] || [ "$1" = "--help" ]; then > > > + echo "Usage: $0 groupname[/start_looking_at_this_number]" > > > + exit 1 > > > +fi > > > + > > > +die() { > > > + echo "$@" > > > + exit 1 > > > +} > > > + > > > +if [ "$(basename "$1")" != "$1" ]; then > > > + group="$(dirname "$1")" > > > + id="$(basename "$1")" > > > +else > > > + group="$1" > > > + id=1 > > > +fi > > > +test -e "tests/${group}/group" || die "Unknown group \"${group}\"." > > > + > > > +while test "${id}" -lt 1000; do > > > + name="$(printf "%.03d" "${id}")" > > > + if [ ! -e "tests/${group}/${name}" ]; then > > > + echo "${group}/${name}" > > > + exit 0 > > > + fi > > > + id=$((id + 1)) > > > +done > > > + > > > +echo "No free IDs less than ${id} in group \"${group}\"." > > > > So the "new" script does this differently, by reading the group > > file and looking for the first non-contiguous ID in the file. It > > doesn't need scan ID limits because EOF triggers that. Wouldn't it > > be better to to factor the code out of the "new" script to find the > > next id, and then have the new script call that? > > Sure! In the end I wrote a short Python program to sort group files and it wasn't much harder to reuse the code to implement nextid, so I did that instead. I'll probably post this and a patch to fix the error codes in generic/157 later this week. --D > > --D > > > > > Cheers, > > > > Dave. > > -- > > Dave Chinner > > david@fromorbit.com > > > > _______________________________________________ > > xfs mailing list > > xfs@oss.sgi.com > > http://oss.sgi.com/mailman/listinfo/xfs > -- > To unsubscribe from this list: send the line "unsubscribe fstests" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html From chris@onthe.net.au Tue Nov 17 16:16:19 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 068E87F37 for ; Tue, 17 Nov 2015 16:16:19 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id EA0D98F8050 for ; Tue, 17 Nov 2015 14:16:15 -0800 (PST) X-ASG-Debug-ID: 1447798573-04cbb0605beda20001-NocioJ Received: from smtp1.onthe.net.au (smtp1.onthe.net.au [203.22.196.249]) by cuda.sgi.com with ESMTP id YoO2uY1RAK7T1LLv for ; Tue, 17 Nov 2015 14:16:13 -0800 (PST) X-Barracuda-Envelope-From: chris@onthe.net.au X-Barracuda-Apparent-Source-IP: 203.22.196.249 Received: from localhost (localhost [127.0.0.1]) by smtp1.onthe.net.au (Postfix) with ESMTP id 8C918617CA; Wed, 18 Nov 2015 09:16:12 +1100 (EST) Received: from smtp1.onthe.net.au ([127.0.0.1]) by localhost (smtp1.onthe.net.au [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id T5rijo6RvOSY; Wed, 18 Nov 2015 09:16:12 +1100 (EST) Received: from o1.private.otn.net.au (o1.private.onthe.net.au [10.200.63.41]) by smtp1.onthe.net.au (Postfix) with ESMTP id DB7EF617DA; Wed, 18 Nov 2015 09:16:11 +1100 (EST) Received: from hestia (pony.office.onthe.net.au [10.9.1.6]) by o1.private.otn.net.au (Postfix) with ESMTP id C70B1E1280; Wed, 18 Nov 2015 09:16:10 +1100 (AEDT) Received: by hestia (Postfix, from userid 1000) id 348DA580730; Wed, 18 Nov 2015 09:16:09 +1100 (AEDT) Date: Wed, 18 Nov 2015 09:16:09 +1100 From: Chris Dunlop To: Brian Foster Cc: xfs@oss.sgi.com Subject: Re: Disk error, then endless loop Message-ID: <20151117221609.GA3563@onthe.net.au> X-ASG-Orig-Subj: Re: Disk error, then endless loop References: <20151117080332.GA28936@onthe.net.au> <20151117124148.GA20118@bfoster.bfoster> <20151117162802.GA28374@onthe.net.au> <20151117173724.GA18963@bfoster.bfoster> <20151117193534.GA1514@onthe.net.au> <20151117202131.GA43800@bfoster.bfoster> <20151117203455.GB43800@bfoster.bfoster> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151117203455.GB43800@bfoster.bfoster> User-Agent: Mutt/1.5.23 (2014-03-12) X-Barracuda-Connect: smtp1.onthe.net.au[203.22.196.249] X-Barracuda-Start-Time: 1447798573 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24485 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Tue, Nov 17, 2015 at 03:34:55PM -0500, Brian Foster wrote: > On Tue, Nov 17, 2015 at 03:21:31PM -0500, Brian Foster wrote: >> On Wed, Nov 18, 2015 at 06:35:34AM +1100, Chris Dunlop wrote: >>> On Tue, Nov 17, 2015 at 12:37:24PM -0500, Brian Foster wrote: >>>> If the device has already dropped and reconnected as a new dev node, >>>> it's probably harmless at this point to just try to forcibly shut down >>>> the fs on the old one. Could you try the following? >>>> >>>> xfs_io -x -c shutdown >>> >>> # xfs_io -x -c shutdown /var/lib/ceph/osd/ceph-18 >>> foreign file active, shutdown command is for XFS filesystems only >>> >>> # grep ceph-18 /etc/mtab >>> <<< crickets >>> >>> >>> I don't know when the fs disappeared from mtab, it could have been when I >>> first did the umount I guess, I didn't think to check at the time. But the >>> umount is still there: >>> >>> # date; ps -opid,lstart,time,stat,wchan='WCHAN-xxxxxxxxxxxxxxxxxx',cmd -C umount >>> Wed Nov 18 06:23:21 AEDT 2015 >>> PID STARTED TIME STAT WCHAN-xxxxxxxxxxxxxxxxxx CMD >>> 23946 Tue Nov 17 17:30:41 2015 00:00:00 D+ xfs_ail_push_all_sync umount /var/lib/ceph/osd/ceph-18 >> >> Ah, so it's already been removed from the namespace. Apparently it's >> stuck at some point after the mount is made inaccessible and before it >> actually finishes with I/O. I'm not sure we have any other option other >> than a reset at this point, unfortunately. :/ Yes, I thought this would likely be the case. > One last thought... it occurred to me that scsi devs have a delete > option under the /sysfs fs. Does the old/stale device still exist under > /sys/block/? If so, perhaps an 'echo 1 > > /sys/block//device/delete' would move things along..? Unfortunately, no, it's not there. > Note that I have no idea what effect that will have beyond removing the > device node (so if it is still accessible now, it probably won't be > after that command). I just tried it while doing I/O to a test device > and it looked like it caused an fs shutdown, so it could be worth a try > as a last resort before a system restart. > > Brian Thanks again, Chris From octavian.purdila@intel.com Tue Nov 17 16:46:54 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 D55377F37 for ; Tue, 17 Nov 2015 16:46:54 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 7684F8F8040 for ; Tue, 17 Nov 2015 14:46:54 -0800 (PST) X-ASG-Debug-ID: 1447800412-04cb6c0cd2c9ef0001-NocioJ Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by cuda.sgi.com with ESMTP id P3xu5pwiSdtG9lgf for ; Tue, 17 Nov 2015 14:46:52 -0800 (PST) X-Barracuda-Envelope-From: octavian.purdila@intel.com X-Barracuda-Apparent-Source-IP: 134.134.136.65 Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga103.jf.intel.com with ESMTP; 17 Nov 2015 14:46:40 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,310,1444719600"; d="scan'208";a="853325849" Received: from mhakkine-mobl1.ger.corp.intel.com (HELO opurdila-mobl.ger.corp.intel.com) ([10.252.22.26]) by fmsmga002.fm.intel.com with ESMTP; 17 Nov 2015 14:46:36 -0800 From: Octavian Purdila To: xfs@oss.sgi.com Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, Octavian Purdila Subject: [RFC PATCH] xfs: support for non-mmu architectures Date: Wed, 18 Nov 2015 00:46:21 +0200 X-ASG-Orig-Subj: [RFC PATCH] xfs: support for non-mmu architectures Message-Id: <1447800381-20167-1-git-send-email-octavian.purdila@intel.com> X-Mailer: git-send-email 1.9.1 X-Barracuda-Connect: mga03.intel.com[134.134.136.65] X-Barracuda-Start-Time: 1447800412 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24486 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Naive implementation for non-mmu architectures: allocate physically contiguous xfs buffers with alloc_pages. Terribly inefficient with memory and fragmentation on high I/O loads but it may be good enough for basic usage (which most non-mmu architectures will need). This patch was tested with lklfuse [1] and basic operations seems to work even with 16MB allocated for LKL. [1] https://github.com/lkl/linux Signed-off-by: Octavian Purdila --- fs/xfs/xfs_buf.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index 8ecffb3..50b5246 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c @@ -261,6 +261,7 @@ xfs_buf_free( ASSERT(list_empty(&bp->b_lru)); if (bp->b_flags & _XBF_PAGES) { +#ifdef CONFIG_MMU uint i; if (xfs_buf_is_vmapped(bp)) @@ -272,6 +273,10 @@ xfs_buf_free( __free_page(page); } +#else + free_pages((unsigned long)page_to_virt(bp->b_pages[0]), + order_base_2(bp->b_page_count)); +#endif } else if (bp->b_flags & _XBF_KMEM) kmem_free(bp->b_addr); _xfs_buf_free_pages(bp); @@ -338,7 +343,14 @@ use_alloc_page: struct page *page; uint retries = 0; retry: +#ifdef CONFIG_MMU page = alloc_page(gfp_mask); +#else + if (i == 0) + page = alloc_pages(gfp_mask, order_base_2(page_count)); + else + page = bp->b_pages[0] + i; +#endif if (unlikely(page == NULL)) { if (flags & XBF_READ_AHEAD) { bp->b_page_count = i; @@ -372,8 +384,11 @@ retry: return 0; out_free_pages: +#ifdef CONFIG_MMU for (i = 0; i < bp->b_page_count; i++) __free_page(bp->b_pages[i]); +#endif + return error; } @@ -392,6 +407,7 @@ _xfs_buf_map_pages( } else if (flags & XBF_UNMAPPED) { bp->b_addr = NULL; } else { +#ifdef CONFIG_MMU int retried = 0; unsigned noio_flag; @@ -412,6 +428,9 @@ _xfs_buf_map_pages( vm_unmap_aliases(); } while (retried++ <= 1); memalloc_noio_restore(noio_flag); +#else + bp->b_addr = page_to_virt(bp->b_pages[0]); +#endif if (!bp->b_addr) return -ENOMEM; @@ -816,11 +835,19 @@ xfs_buf_get_uncached( if (error) goto fail_free_buf; +#ifdef CONFIG_MMU for (i = 0; i < page_count; i++) { bp->b_pages[i] = alloc_page(xb_to_gfp(flags)); if (!bp->b_pages[i]) goto fail_free_mem; } +#else + bp->b_pages[0] = alloc_pages(flags, order_base_2(page_count)); + if (!bp->b_pages[0]) + goto fail_free_buf; + for (i = 1; i < page_count; i++) + bp->b_pages[i] = bp->b_pages[i-1] + 1; +#endif bp->b_flags |= _XBF_PAGES; error = _xfs_buf_map_pages(bp, 0); -- 1.9.1 From fzcorpedu@yandex.ru Tue Nov 17 17:15:52 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id BAF707F37 for ; Tue, 17 Nov 2015 17:15:52 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id AA39E8F8050 for ; Tue, 17 Nov 2015 15:15:49 -0800 (PST) X-ASG-Debug-ID: 1447802142-04cbb0605dee9c0001-NocioJ Received: from mx.yandex.ru (63-156-59-27.dia.static.qwest.net [63.156.59.27]) by cuda.sgi.com with ESMTP id YNFWOoPRzt1yZsO5 for ; Tue, 17 Nov 2015 15:15:43 -0800 (PST) X-Barracuda-Envelope-From: fzcorpedu@yandex.ru X-Barracuda-Apparent-Source-IP: 63.156.59.27 MIME-Version: 1.0 Date: Wed, 18 Nov 2015 02:15:38 +0300 Message-ID: <674962132.20151118021538@OTFGHZXHXG> Subject: =?utf-8?B?0J/QvtGB0YLQsNCy0YnQuNC60YMuINCa0LDQuiDQstGL0LjQs9GA0LA=?= =?utf-8?B?0YLRjCDRgtC10L3QtNC10YAuIDQ0LdCk0JcsIDIyMy3QpNCXINCU0LvRjyDQv9C+?= =?utf-8?B?0YHRgtCw0LLRidC40LrQvtCy?= From: "=?utf-8?B?0K3Qu9C10LrRgtGA0L7QvdC90YvQtSDQsNGD0LrRhtC40L7QvdGLIA==?=" X-ASG-Orig-Subj: =?utf-8?B?0J/QvtGB0YLQsNCy0YnQuNC60YMuINCa0LDQuiDQstGL0LjQs9GA0LA=?= =?utf-8?B?0YLRjCDRgtC10L3QtNC10YAuIDQ0LdCk0JcsIDIyMy3QpNCXINCU0LvRjyDQv9C+?= =?utf-8?B?0YHRgtCw0LLRidC40LrQvtCy?= To: xfs@oss.sgi.com Content-Type: multipart/alternative; boundary=----------61B07C5EF5E261EA2 X-Barracuda-Connect: 63-156-59-27.dia.static.qwest.net[63.156.59.27] X-Barracuda-Start-Time: 1447802142 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24487 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 HTML_MESSAGE BODY: HTML included in message ------------61B07C5EF5E261EA2 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: base64 KjI0IC0gMjUg0L3QvtGP0LHRgNGPINCzLiDQnNC+0YHQutCy0LAgKg0KDQoNCtCj0YfQtdCx0L3R i9C5INGG0LXQvdGC0YAg0L/RgNC40LPQu9Cw0YjQsNC10YIg0L3QsCDQvtCx0YPRh9C10L3QuNC1 Og0KDQoNCg0KKtCj0KfQkNCh0KLQmNCVINCf0J7QodCi0JDQktCp0JjQmtCe0JIgKNCf0J7QlNCg 0K/QlNCn0JjQmtCe0JIsINCY0KHQn9Ce0JvQndCY0KLQldCb0JXQmSkg0JIg0JfQkNCa0KPQn9Ca 0JDQpSDQn9CeIDQ0LdCk0Jcg0JgNCjIyMy3QpNCXLiDQndCe0JLQq9CVINCi0KDQldCR0J7QktCQ 0J3QmNCvLtCX0JDQqdCY0KLQkCDQn9Cg0JDQkiDQmCDQmNCd0KLQldCg0JXQodCe0JIg0JIg0KTQ kNChKg0KDQoNCirQn9GA0L7QvNC+0LrQvtC0OiAyNTQqDQoNCirQp9Cw0YHRiyDQv9GA0L7QstC1 0LTQtdC90LjRjyDQt9Cw0L3Rj9GC0LjQuTog0YEgMTA6MDAg0LTQviAxNzozMCoNCg0KKtCQ0LTR gNC10YEg0LzQtdGA0L7Qv9GA0LjRj9GC0LjRjzog0LwuINCR0LDRg9C80LDQvdGB0LrQsNGPLCDR g9C7LiDQkdCw0YPQvNCw0L3RgdC60LDRjywg0LQuNiwg0YHRgtGALjIsINCRLtCmLg0KItCS0LjQ utGC0L7RgNC40Y8g0J/Qu9Cw0LfQsCIuKg0KDQrQktGB0Y8g0L/QvtC00YDQvtCx0L3QsNGPINC4 0L3RhNC+0YDQvNCw0YbQuNGPINC4INGA0LXQs9C40YHRgtGA0LDRhtC40Y8g0L3QsCDQvtCx0YPR h9C10L3QuNC1INC/0L4g0YLQtdC70LXRhNC+0L3RgzoNCg0KOCAg0LrQvtC0INCz0L7RgNC+0LTQ sCDQnNC+0YHQutCy0YsgICggNCA5IDUgKSAg0L3QvtC80LXRgDogIDcyNSAtIDA0IC0gNDggICjQ vNC90L7Qs9C+0LrQsNC90LDQu9GM0L3Ri9C5KQ0KDQoNCg0KDQoq0JLQndCY0JzQkNCd0JjQlSEq INCSINGB0L7QvtGC0LLQtdGC0YHRgtCy0LjQuCDRgSDRgtGA0LXQsdC+0LLQsNC90LjRj9C80Lgg 0YTQtdC00LXRgNCw0LvRjNC90YvRhSDQt9Cw0LrQvtC90L7QsiDihJYgNDQt0KTQlyDQuCDihJYN CjIyMy3QpNCXINCx0L7Qu9C10LUNCjYwMCAwMDAg0LfQsNC60LDQt9GH0LjQutC+0LIg0L7QsdGP 0LfQsNC90Ysg0L7Qv9GA0LXQtNC10LvRj9GC0Ywg0L/QvtGB0YLQsNCy0YnQuNC60L7QsiAo0L/Q vtC00YDRj9C00YfQuNC60L7QsiwNCtC40YHQv9C+0LvQvdC40YLQtdC70LXQuSkg0L/QviDQttC1 0YHRgtC60LjQvA0K0L/RgNCw0LLQuNC70LDQvCwg0L3QsNGG0LXQu9C10L3QvdGL0Lwg0L3QsCDR gNCw0LfQstC40YLQuNC1INC60L7QvdC60YPRgNC10L3RhtC40Lgg0Lgg0L/RgNC10LTQvtGC0LLR gNCw0YnQtdC90LjQtSDQutC+0YDRgNGD0L/RhtC40LguDQrQl9Cw0LrQvtC90L7QtNCw0YLQtdC7 0YzRgdGC0LLQvg0K0L4g0LfQsNC60YPQv9C60LDRhSDQv9C+0YHRgtC+0Y/QvdC90L4g0YHQvtCy 0LXRgNGI0LXQvdGB0YLQstGD0LXRgtGB0Y86INCyIDIwMTQg0LPQvtC00YMg0LHRi9C70Lgg0LjQ t9C80LXQvdC10L3RiyDRgtGA0LXQsdC+0LLQsNC90LjRjw0K0Log0LfQsNGP0LLQutCw0Lwg0L3Q sA0K0YPRh9Cw0YHRgtC40LUg0LIg0LfQsNC60YPQv9C60LDRhSwg0LIgMjAxNSDQs9C+0LTRgyDQ stCy0LXQtNC10L3RiyDQsNC90YLQuNC60YDQuNC30LjRgdC90YvQtSDQvNC10YDRiyDQuCDQvdC+ 0LLRi9C1INC/0YDQsNCy0LjQu9CwDQrQv9C+0LTQtNC10YDQttC60LgNCtGB0YPQsdGK0LXQutGC 0L7QsiDQvNCw0LvQvtCz0L4g0Lgg0YHRgNC10LTQvdC10LPQviDQv9GA0LXQtNC/0YDQuNC90LjQ vNCw0YLQtdC70YzRgdGC0LLQsCwg0L/Qu9Cw0L3QuNGA0YPQtdGC0YHRjyDQv9C10YDQtdCy0L7Q tCDQstGB0LXRhQ0K0LrQvtC90LrRg9GA0LXQvdGC0L3Ri9GFDQrQt9Cw0LrRg9C/0L7QuiDQsiDR jdC70LXQutGC0YDQvtC90L3Rg9GOINGE0L7RgNC80YMuDQoq0JIg0YbQtdC70Y/RhSAq0L/RgNCw 0LrRgtC40YfQtdGB0LrQvtC5INC/0L7QtNCz0L7RgtC+0LLQutC4INGB0L/QtdGG0LjQsNC70LjR gdGC0L7QsiDQv9C+0YHRgtCw0LLRidC40LrQvtCyICjQv9C+0LTRgNGP0LTRh9C40LrQvtCyLA0K 0LjRgdC/0L7Qu9C90LjRgtC10LvQtdC5KSDQug0K0LLRi9C/0L7Qu9C90LXQvdC40Y4g0L3QvtCy 0YvRhSDRgtGA0LXQsdC+0LLQsNC90LjQuSDQsiDRgNCw0LzQutCw0YUg0LrQvtC90YLRgNCw0LrR gtC90L7QuSDRgdC40YHRgtC10LzRiyDQuCDQv9C+0LvQvtC20LXQvdC40Lkg0L4NCtC30LDQutGD 0L/QutC1INC+0YLQtNC10LvRjNC90YvRhQ0K0LLQuNC00L7QsiDRjtGA0LjQtNC40YfQtdGB0LrQ uNGFINC70LjRhiwg0YEg0YPRh9C10YLQvtC8INC/0YDQsNC60YLQuNC60Lgg0YDQsNGB0YHQvNC+ 0YLRgNC10L3QuNGPINC20LDQu9C+0LEg0KTQtdC00LXRgNCw0LvRjNC90L7QuQ0K0LDQvdGC0LjQ vNC+0L3QvtC/0L7Qu9GM0L3QvtC5DQrRgdC70YPQttCx0L7QuSDQuCDQvdCw0L/RgNCw0LLQu9C1 0L3QuNC5INGA0LDQt9Cy0LjRgtC40Y8g0LrQvtC90YLRgNCw0LrRgtC90L7QuSDRgdC40YHRgtC1 0LzRiywg0L/RgNC40LPQu9Cw0YjQsNC10Lwg0L/RgNC40L3Rj9GC0YwNCtGD0YfQsNGB0YLQuNC1 INCyINGB0L/QtdGG0LjQsNC70YzQvdC+DQrRgNCw0LfRgNCw0LHQvtGC0LDQvdC90L7QvCDQv9GA 0LDQutGC0LjRh9C10YHQutC+0Lwg0YHQtdC80LjQvdCw0YDQtS3RgtGA0LXQvdC40L3Qs9C1Lg0K DQoNCirQkiDQv9GA0L7Qs9GA0LDQvNC80LU6Kg0KICAgICAgICoxLirQntGB0L3QvtCy0Ysg0YDQ tdCz0YPQu9C40YDQvtCy0LDQvdC40Y8g0LfQsNC60YPQv9C+0Log0LfQsNC60L7QvdCw0LzQuCA0 NC3QpNCXINC4IDIyMy3QpNCXLiDQn9C+0L3Rj9GC0LjRjywNCtC/0YDQuNC90YbQuNC/0Ysg0L7R gdGD0YnQtdGB0YLQstC70LXQvdC40Y8NCtC30LDQutGD0L/QvtC6LCDQv9GA0LDQstCwINC4INC+ 0LHRj9C30LDQvdC90L7RgdGC0Lgg0L/QvtGB0YLQsNCy0YnQuNC60L7QsiAo0L/QvtC00YDRj9C0 0YfQuNC60L7Qsiwg0LjRgdC/0L7Qu9C90LjRgtC10LvQtdC5KS4NCtCX0LDQutGD0L/QutC4INC/ 0L4gNDQt0KTQlyDQuCAyMjMt0KTQlzog0YHRhdC+0LTRgdGC0LLQsCDQuCDRgNCw0LfQu9C40YfQ uNGPLg0KKiDQmNC30LzQtdC90LXQvdC40Y8g0LIg0YDQtdCz0YPQu9C40YDQvtCy0LDQvdC40Lgg 0LfQsNC60YPQv9C+0Log0L/QviA0NC3QpNCXINC4IDIyMy3QpNCXINCyIDIwMTUg0LPQvtC00YMu Kg0K0J/QvtC/0YDQsNCy0LrQuCwg0L/Qu9Cw0L3QuNGA0YPQtdC80YvQtSDQuiDRgNC10LDQu9C4 0LfQsNGG0LjQuCDQsiAyMDE2INCz0L7QtNGDLiDQldC00LjQvdCw0Y8NCtC40L3RhNC+0YDQvNCw 0YbQuNC+0L3QvdCw0Y8g0YHQuNGB0YLQtdC80LAg0LIg0YHRhNC10YDQtSDQt9Cw0LrRg9C/0L7Q ujog0L3QvtCy0YvQuSDRhNGD0L3QutGG0LjQvtC90LDQuyDQtNC70Y8g0L/QvtGB0YLQsNCy0YnQ uNC60LAsDQrRgNC10LrQvtC80LXQvdC00LDRhtC40LgNCtC/0L4g0L/QvtC40YHQutGDINC40L3R hNC+0YDQvNCw0YbQuNC4LiDQoNCw0LfQvNC10YnQtdC90LjQtSDQuNC90YTQvtGA0LzQsNGG0LjQ uCDQviDQt9Cw0LrRg9C/0LrQsNGFINCyINGB0L7QvtGC0LLQtdGC0YHRgtCy0LjQuCDRgQ0KNDQt 0KTQlyDQuCAyMjMt0KTQlzoNCtC/0LvQsNC90YsgKNC/0LvQsNC90Yst0LPRgNCw0YTQuNC60Lgp INC30LDQutGD0L/QvtC6LCDQuNC30LLQtdGJ0LXQvdC40LUsINC00L7QutGD0LzQtdC90YLQsNGG 0LjRjywg0L/QvtC70L7QttC10L3QuNC1INC+DQrQt9Cw0LrRg9C/0LrQtSwg0YDQtdC10YHRgtGA DQrQutC+0L3RgtGA0LDQutGC0L7Qsiwg0YDQtdC10YHRgtGAINC00L7Qs9C+0LLQvtGA0L7Qsiwg 0L7RgtGH0LXRgiDQvtCxINC40YHQv9C+0LvQvdC10L3QuNC4INC60L7QvdGC0YDQsNC60YLQsC4g 0JTQvtC60YPQvNC10L3RgtCw0YbQuNGPINC+DQrQt9Cw0LrRg9C/0LrQtToNCtGB0YLRgNGD0LrR gtGD0YDQsCwg0YHQvtC00LXRgNC20LDQvdC40LUsINCw0L3QsNC70LjQty4g0J7RhtC10L3QutCw INC/0LXRgNGB0L/QtdC60YLQuNCyINC4INGA0LjRgdC60L7QsiDRg9GH0LDRgdGC0LjRjyDQsg0K 0LfQsNC60YPQv9C60LUuINCf0YDQsNCy0LjQu9CwDQrQvtCx0L7RgdC90L7QstCw0L3QuNGPINC9 0LDRh9Cw0LvRjNC90L7QuSAo0LzQsNC60YHQuNC80LDQu9GM0L3QvtC5KSDRhtC10L3RiyDQtNC+ 0LPQvtCy0L7RgNCwICjQutC+0L3RgtGA0LDQutGC0LApLiDQn9C+0LzQvtGJ0YwNCtC30LDQutCw 0LfRh9C40LrQsNC8INCyDQrQv9C+0LTQs9C+0YLQvtCy0LrQtSDQtNC+0LrRg9C80LXQvdGC0LDR htC40Lgg0L4g0LfQsNC60YPQv9C60LUuINCi0YDQtdCx0L7QstCw0L3QuNGPINC6INGD0YfQsNGB 0YLQvdC40LrQsNC8INC30LDQutGD0L/QutC4Og0K0L7RgdC90L7QstC90YvQtSDQuA0K0LTQvtC/ 0L7Qu9C90LjRgtC10LvRjNC90YvQtS4g0J/RgNC40LzQtdGA0Ysg0L3QtdC30LDQutC+0L3QvdGL 0YUg0YLRgNC10LHQvtCy0LDQvdC40LkuINCf0YDQtdC40LzRg9GJ0LXRgdGC0LLQsCDQv9GA0Lgg 0YPRh9Cw0YHRgtC40Lgg0LINCtC30LDQutGD0L/QutCw0YUuDQrQl9Cw0LrRg9C/0LrQuCDRgyDR gdGD0LHRitC10LrRgtC+0LIg0LzQsNC70L7Qs9C+INC4INGB0YDQtdC00L3QtdCz0L4g0L/RgNC1 0LTQv9GA0LjQvdC40LzQsNGC0LXQu9GM0YHRgtCy0LAuINCd0L7QstGL0LUNCtC+0LHRj9C30LDQ vdC90L7RgdGC0Lgg0LfQsNC60LDQt9GH0LjQutC+0LIuDQrQl9Cw0L/RgNC+0YHRiyDQviDRgNCw 0LfRitGP0YHQvdC10L3QuNC4INC00L7QutGD0LzQtdC90YLQsNGG0LjQuCDQviDQt9Cw0LrRg9C/ 0LrQtTog0YbQtdC70Lgg0Lgg0L/RgNCw0LLQuNC70LAg0L/QvtC00LDRh9C4LiDQodC+0YHRgtCw 0LINCtC30LDRj9Cy0LrQuCDQvdCwDQrRg9GH0LDRgdGC0LjQtSDQsiDQt9Cw0LrRg9C/0LrQtTog 0L3QvtCy0YvQtSDRgtGA0LXQsdC+0LLQsNC90LjRjy4g0J7RgdC90L7QstCw0L3QuNGPINC+0YLQ utC70L7QvdC10L3QuNGPINC30LDRj9Cy0L7QuiDQv9C+IDQ0LdCk0Jcg0LgNCjIyMy3QpNCXLiDQ mtCw0LoNCtC/0YDQsNCy0LjQu9GM0L3QviDQv9C+0LTQs9C+0YLQvtCy0LjRgtGMINC30LDRj9Cy 0LrRgy4g0JDQu9Cz0L7RgNC40YLQvCDQtNC10LnRgdGC0LLQuNC5INGC0LXQvdC00LXRgNC90L7Q s9C+INGB0L/QtdGG0LjQsNC70LjRgdGC0LAuDQrQntCx0LXRgdC/0LXRh9C10L3QuNC1DQrQt9Cw 0Y/QstC+0Log0L/RgNC4INGD0YfQsNGB0YLQuNC4INCyINC30LDQutGD0L/QutCw0YUuINCk0L7R gNC80Ysg0Lgg0YDQsNC30LzQtdGALiDQn9GA0LDQstC40LvQsCDQstC+0LfQstGA0LDRgtCwINC+ 0LHQtdGB0L/QtdGH0LXQvdC40Y8NCtC30LDRj9Cy0LrQuC4NCtCh0LvRg9GH0LDQuCwg0LrQvtCz 0LTQsCDQvtCx0LXRgdC/0LXRh9C10L3QuNC1INC90LUg0LLQvtC30LLRgNCw0YnQsNC10YLRgdGP LiDQoNC10LXRgdGC0YAg0LHQsNC90LrQvtCy0YHQutC40YUg0LPQsNGA0LDQvdGC0LjQuS4NCtCi 0YDQtdCx0L7QstCw0L3QuNGPINC6DQrQsdCw0L3QutC+0LLRgdC60L7QuSDQs9Cw0YDQsNC90YLQ uNC4LiDQo9GB0LvQvtCy0LjRjyDQuCDRgdGA0L7QutC4INC+0YLQvNC10L3RiyDQv9GA0L7RhtC1 0LTRg9GALiDQmNC30LLQtdGJ0LXQvdC40LUg0L4g0LfQsNC60YPQv9C60LUg4oCTDQrQvtGE0LXR gNGC0LAg0LjQu9C4DQrQv9GA0LjQs9C70LDRiNC10L3QuNC1INC00LXQu9Cw0YLRjCDQvtGE0LXR gNGC0Ys6INCyINGH0LXQvCDRgNCw0LfQvdC40YbQsC4g0JDQvdGC0LjQtNC10LzQv9C40L3Qs9C+ 0LLRi9C1INC80LXRgNGLINC/0YDQuA0K0L/RgNC+0LLQtdC00LXQvdC40Lgg0LfQsNC60YPQv9C+ 0LouDQrQmNC90YTQvtGA0LzQsNGG0LjRjywg0L/QvtC00YLQstC10YDQttC00LDRjtGJ0LDRjyDQ tNC+0LHRgNC+0YHQvtCy0LXRgdGC0L3QvtGB0YLRjCDRg9GH0LDRgdGC0L3QuNC60LAuINCQ0L3R gtC40LrQvtGA0YDRg9C/0YbQuNC+0L3QvdGL0LUNCtC80LXRgNGLLg0K0J/QvtGB0LvQtdC00YHR gtCy0LjRjyDQv9GA0LjQt9C90LDQvdC40Y8g0L/RgNC+0YbQtdC00YPRgCDQvtC/0YDQtdC00LXQ u9C10L3QuNGPINC/0L7RgdGC0LDQstGJ0LjQutC+0LIg0L3QtdGB0L7RgdGC0L7Rj9Cy0YjQuNC8 0LjRgdGPINC/0L4NCjQ0LdCk0Jcg0LgNCjIyMy3QpNCXLg0KDQoqMi7QmNC30LzQtdC90LXQvdC4 0Y8g0LIg0L/RgNCw0LLQuNC70LDRhSDRg9GH0LDRgdGC0LjRjyDQuCDQvtC/0YDQtdC00LXQu9C1 0L3QuNGPINC/0L7QsdC10LTQuNGC0LXQu9GPINCyINC30LDQutGD0L/QutCw0YUg0LIgMjAxNQ0K 0LPQvtC00YMuKg0K0JrQvtC90LrRg9GA0LXQvdGC0L3Ri9C1INGB0L/QvtGB0L7QsdGLINC+0L/R gNC10LTQtdC70LXQvdC40Y8g0L/QvtGB0YLQsNCy0YnQuNC60L7Qsjog0LrQu9Cw0YHRgdC40YTQ uNC60LDRhtC40Y8sINGB0YDQsNCy0L3QuNGC0LXQu9GM0L3Ri9C5DQrQsNC90LDQu9C40LcuDQrQ o9GH0LDRgdGC0LjQtSDQsiDQvtGC0LrRgNGL0YLQvtC8INC60L7QvdC60YPRgNGB0LU6INC+0YHQ vtCx0LXQvdC90L7RgdGC0Lgg0L/QvtC00LPQvtGC0L7QstC60Lgg0LfQsNGP0LLQutC4INC/0L4g NDQt0KTQlyDQuCAyMjMt0KTQlw0K0J7RhtC10L3QutCwINC30LDRj9Cy0L7Quiwg0L7QutC+0L3R h9Cw0YLQtdC70YzQvdGL0YUg0L/RgNC10LTQu9C+0LbQtdC90LjQuSDRg9GH0LDRgdGC0L3QuNC6 0L7QsiDQt9Cw0LrRg9C/0LrQuC4g0JzQtdGC0L7QtNGLINC+0YbQtdC90LrQuA0K0L/QviAyMjMt 0KTQly4NCtCd0L7QstGL0LUg0L/RgNCw0LLQuNC70LAg0L7RhtC10L3QutC4INC/0L4gNDQt0KTQ ly4g0J7RhtC10L3QutCwINC/0L4g0L3QtdGB0YLQvtC40LzQvtGB0YLQvdGL0Lwg0LrRgNC40YLQ tdGA0LjRj9C8ICjCq9Ca0LDRh9C10YHRgtCy0L4NCtGC0L7QstCw0YDQvtCyLA0K0YDQsNCx0L7R giwg0YPRgdC70YPQs8K7LCDCq9Ca0LLQsNC70LjRhNC40LrQsNGG0LjRjyDRg9GH0LDRgdGC0L3Q uNC60LDCuykuINCf0YDQsNC60YLQuNGH0LXRgdC60LjQtSDQv9GA0LjQvNC10YDRiyDQvtGG0LXQ vdC60LgNCtC30LDRj9Cy0L7QuiDRgNCw0LfQu9C40YfQvdGL0LzQuA0K0LzQtdGC0L7QtNCw0LzQ uC4g0J3QvtCy0YvQtSDQv9GA0L7RhtC10LTRg9GA0Ysg0LfQsNC60YPQv9C+0Lo6INC60L7QvdC6 0YPRgNGBINGBINC+0LPRgNCw0L3QuNGH0LXQvdC90YvQvCDRg9GH0LDRgdGC0LjQtdC8LA0K0LTQ stGD0YXRjdGC0LDQv9C90YvQuQ0K0LrQvtC90LrRg9GA0YEuINCe0YHQvtCx0LXQvdC90L7RgdGC 0LgsINGD0YHQu9C+0LLQuNGPINC4INGB0YDQvtC60Lgg0L/RgNC+0LLQtdC00LXQvdC40Y8uINCf 0L7QtNCz0L7RgtC+0LLQutCwINC4INC+0YTQvtGA0LzQu9C10L3QuNC1DQrQt9Cw0Y/QstC60Lgg 0L3QsA0K0YPRh9Cw0YHRgtC40LUg0LIg0L7RgtC60YDRi9GC0L7QvCDQutC+0L3QutGD0YDRgdC1 OiDQvtGB0L3QvtCy0L3Ri9C1INC/0YDQsNCy0LjQu9CwLCDRgtC40L/QuNGH0L3Ri9C1INC+0YjQ uNCx0LrQuC4g0KLRgNC10L3QuNC90LM6DQrQv9C+0LTQs9C+0YLQvtCy0LrQsA0K0LTQvtC60YPQ vNC10L3RgtC+0LIg0LTQu9GPINGD0YfQsNGB0YLQuNGPINCyINC60L7QvdC60YPRgNGB0LUuINCY 0LfQvNC10L3QtdC90LjRjyDQsiDQv9GA0L7QstC10LTQtdC90LjQuCDRjdC70LXQutGC0YDQvtC9 0L3Ri9GFDQrQsNGD0LrRhtC40L7QvdC+0LIg0L/QviA0NC3QpNCXLg0K0J3QvtCy0YvQtSDRgtGA 0LXQsdC+0LLQsNC90LjRjyDQuiDQvtC/0LjRgdCw0L3QuNGOINC+0LHRitC10LrRgtCwINC30LDQ utGD0L/QutC4LiDQmNC30LzQtdC90LXQvdC40LUg0YLRgNC10LHQvtCy0LDQvdC40Lkg0Log0L/Q tdGA0LLQvtC5DQrQuCDQstGC0L7RgNC+0LkNCtGH0LDRgdGC0Y/QvCDQt9Cw0Y/QstC60LggKDE0 MC3QpNCXLCA0OTgt0KTQlykuINCe0LHQt9C+0YAg0YTQtdC00LXRgNCw0LvRjNC90YvRhSDRjdC7 0LXQutGC0YDQvtC90L3Ri9GFINC/0LvQvtGJ0LDQtNC+0LouDQrQoNC10LPQu9Cw0LzQtdC90YIN CtGA0LDQsdC+0YLRiy4g0JDQutC60YDQtdC00LjRgtCw0YbQuNGPINGD0YfQsNGB0YLQvdC40LrQ vtCyINC90LAg0Y3Qu9C10LrRgtGA0L7QvdC90YvRhSDQv9C70L7RidCw0LTQutCw0YUuINCt0LvQ tdC60YLRgNC+0L3QvdGL0LkNCtC00L7QutGD0LzQtdC90YLQvtC+0LHQvtGA0L7Rgi4NCtCf0LXR gNC10YfQtdC90Ywg0YLQvtCy0LDRgNC+0LIsINGA0LDQsdC+0YIg0Lgg0YPRgdC70YPQsywg0LfQ sNC60YPQv9Cw0LXQvNGL0YUg0YHQv9C+0YHQvtCx0L7QvCDRjdC70LXQutGC0YDQvtC90L3QvtCz 0L4g0LDRg9C60YbQuNC+0L3QsA0K0L/QviA0NC3QpNCXLCDQsg0K0Y3Qu9C10LrRgtGA0L7QvdC9 0L7QuSDRhNC+0YDQvNC1INC/0L4gMjIzLdCk0JcuINCf0L7QtNCw0YfQsCDQt9Cw0Y/QstC+0Log 0Lgg0LfQsNC60LvRjtGH0LXQvdC40LUg0LTQvtCz0L7QstC+0YDQsCDQvdCwDQrRjdC70LXQutGC 0YDQvtC90L3QvtC5DQrQv9C70L7RidCw0LTQutC1LCDQsiDQtdC00LjQvdC+0Lkg0LjQvdGE0L7R gNC80LDRhtC40L7QvdC90L7QuSDRgdC40YHRgtC10LzQtS4g0J7RgdC90L7QstC90YvQtSDQv9GA 0LjRh9C40L3RiyDQvtGC0LrQu9C+0L3QtdC90LjRjw0K0L/QtdGA0LLRi9GFINC4DQrQstGC0L7R gNGL0YUg0YfQsNGB0YLQtdC5INC30LDRj9Cy0L7QuiDQvdCwINGD0YfQsNGB0YLQuNC1INCyINGN 0LvQtdC60YLRgNC+0L3QvdC+0Lwg0LDRg9C60YbQuNC+0L3QtSDQv9C+IDQ0LdCk0JcuINCS0YvQ v9C+0LvQvdC10L3QuNC1DQrQuCDRgNCw0LfQsdC+0YANCtC/0YDQsNC60YLQuNGH0LXRgdC60L7Q s9C+INC30LDQtNCw0L3QuNGPICjQutC10LnRgdCwKTog0L7QsdC20LDQu9C+0LLQsNC90LjQtSDQ vtGC0LrQsNC30LAg0LIg0LTQvtC/0YPRgdC60LUg0Log0YPRh9Cw0YHRgtC40Y4g0LINCtCw0YPQ utGG0LjQvtC90LUuDQrQrdC70LXQutGC0YDQvtC90L3Ri9C5INCw0YPQutGG0LjQvtC9LiDQn9GA 0LDQstC40LvQsCDQv9C+0LTQsNGH0Lgg0YbQtdC90L7QstGL0YUg0L/RgNC10LTQu9C+0LbQtdC9 0LjQuS4g0KHRgtGA0LDRgtC10LPQuNGPINC4DQrRgtCw0LrRgtC40LrQsCDRg9GH0LDRgdGC0LjR jy4NCtCn0YLQviDRgtCw0LrQvtC1IMKr0YHQs9C+0LLQvtGAINC90LAg0YLQvtGA0LPQsNGFwrss IMKr0LrQsNGA0YLQtdC70YzCuyAtINC30LAg0YfRgtC+INGI0YLRgNCw0YTRg9C10YIg0KTQkNCh INCX0LDQv9GA0L7RgQ0K0LrQvtGC0LjRgNC+0LLQvtC6OiDQv9GA0LDQstC40LvQsA0K0L/RgNC+ 0LLQtdC00LXQvdC40Y8g0Lgg0YPRh9Cw0YHRgtC40Y8uINCX0LDRj9Cy0LrQsCDQvdCwINGD0YfQ sNGB0YLQuNC1INCyINC30LDQv9GA0L7RgdC1INC60L7RgtC40YDQvtCy0L7Qujog0L3QvtCy0YvQ tQ0K0YLRgNC10LHQvtCy0LDQvdC40Y8gKDE0MC3QpNCXLCA0OTgNCi3QpNCXKS4g0J7RgdC+0LHQ tdC90L3QvtGB0YLQuCDQt9Cw0L/RgNC+0YHQvtCyINC60L7RgtC40YDQvtCy0L7QuiDQv9C+IDIy My3QpNCXLiDQl9Cw0L/RgNC+0YEg0L/RgNC10LTQu9C+0LbQtdC90LjQuSwNCtC+0YHQvtCx0LXQ vdC90L7RgdGC0Lgg0Lgg0L/QvtGA0Y/QtNC+0LoNCtC/0YDQvtCy0LXQtNC10L3QuNGPINC/0YDQ vtGG0LXQtNGD0YDRiy4g0KPRh9Cw0YHRgtC40LUg0LIg0LfQsNC/0YDQvtGB0LDRhSDQv9GA0LXQ tNC70L7QttC10L3QuNC5INC/0L4gMjIzLdCk0Jcg0LggNDQt0KTQlzoNCtGB0YXQvtC00YHRgtCy 0LAg0LgNCtC+0YLQu9C40YfQuNGPLiDQn9C10YDQtdGC0L7RgNC20LrQsDog0L/RgNCw0LLQuNC7 0LAg0L/RgNC+0LLQtdC00LXQvdC40Y8g0Lgg0YPRh9Cw0YHRgtC40Y8uINCX0LDQutGD0L/QutC4 INGDINC10LTQuNC90YHRgtCy0LXQvdC90L7Qs9C+DQrQv9C+0YHRgtCw0LLRidC40LrQsA0KKNC/ 0L7QtNGA0Y/QtNGH0LjQutCwLCDQuNGB0L/QvtC70L3QuNGC0LXQu9GPKS4g0J3QvtCy0YvQtSDQ vtCz0YDQsNC90LjRh9C10L3QuNGPINC4INC+0LHRj9C30LDQvdC90L7RgdGC0Lgg0LfQsNC60LDQ t9GH0LjQutC+0LIg0L/Qvg0KNDQt0KTQly4NCtCe0YHQvtCx0LXQvdC90L7RgdGC0Lgg0YPRh9Cw 0YHRgtC40Y8g0LIg0L7RgtC00LXQu9GM0L3Ri9GFINCy0LjQtNCw0YUg0LfQsNC60YPQv9C+0Lo6 INC60L7QvdC60YPRgNC10L3RgtC90YvQtSDQv9C10YDQtdCz0L7QstC+0YDRiywNCtGC0L7RgNCz 0Lgg0L3QsA0K0YHRgtC+0LjQvNC+0YHRgtGMINC10LTQuNC90LjRhtGLINGC0L7QstCw0YDQsCAo 0YDQsNCx0L7RgtGLLCDRg9GB0LvRg9Cz0LgpOyDQsNGD0LrRhtC40L7QvSDQvdCwINC/0L7QstGL 0YjQtdC90LjQtTsg0YDQtdC00YPQutGG0LjQvtC9LA0K0LfQsNC60YPQv9C60Lgg0YENCtC/0YDQ tdGE0LXRgNC10L3RhtC40Y/QvNC4INC4INC/0YDQtdC40LzRg9GJ0LXRgdGC0LLQsNC80LguINCf 0YDQsNC60YLQuNGH0LXRgdC60LjQtSDRgNC10LrQvtC80LXQvdC00LDRhtC40Lgg0L/QvtGB0YLQ sNCy0YnQuNC60LDQvDog0LrQsNC6DQrQvNC40L3QuNC80LjQt9C40YDQvtCy0LDRgtGMINGA0LjR gdC6INC+0YLQutC70L7QvdC10L3QuNGPINC30LDRj9Cy0LrQuCDQuCDQv9C+0LLRi9GB0LjRgtGM INCy0LXRgNC+0Y/RgtC90L7RgdGC0Ywg0L/QvtCx0LXQtNGLINCyDQrRgtC10L3QtNC10YDQtS4N Cg0KDQoqMy7QlNC+0LPQvtCy0L7RgCAo0LrQvtC90YLRgNCw0LrRgik6INC/0YDQsNCy0LAsINC+ 0LHRj9C30LDQvdC90L7RgdGC0LgsINC+0YLQstC10YLRgdGC0LLQtdC90L3QvtGB0YLRjCDQv9C+ 0YHRgtCw0LLRidC40LrQsC4NCtCg0LDRgdGC0L7RgNC20LXQvdC40LUg0LIg0L7QtNC90L7RgdGC 0L7RgNC+0L3QvdC10Lwg0L/QvtGA0Y/QtNC60LUuICoNCtCU0L7Qs9C+0LLQvtGAICjQutC+0L3R gtGA0LDQutGCKTog0YHRg9GJ0LXRgdGC0LLQtdC90L3Ri9C1INGD0YHQu9C+0LLQuNGPLCDQvdC+ 0LLRi9C1INGC0YDQtdCx0L7QstCw0L3QuNGPLCDRgNC40YHQutC4INC/0YDQuA0K0LfQsNC60LvR jtGH0LXQvdC40Lgg0LgNCtC40YHQv9C+0LvQvdC10L3QuNC4LiDQoNCw0LfQvNC10YAg0Lgg0YTQ vtGA0LzRiyDQvtCx0LXRgdC/0LXRh9C10L3QuNGPINC40YHQv9C+0LvQvdC10L3QuNGPLiDQktC+ 0LfQvNC+0LbQvdC+0YHRgtGMINC30LDQvNC10L3Riw0K0L7QsdC10YHQv9C10YfQtdC90LjRjw0K 0LTQvtCz0L7QstC+0YDQsCAo0LrQvtC90YLRgNCw0LrRgtCwKS4g0KHRgNC+0LrQuCDQtNC10LnR gdGC0LLQuNGPINC+0LHQtdGB0L/QtdGH0LXQvdC40Y8g0LTQvtCz0L7QstC+0YDQsCAo0LrQvtC9 0YLRgNCw0LrRgtCwKS4NCtCf0YDQuNC10LzQvtGH0L3QsNGPDQrQutC+0LzQuNGB0YHQuNGPINC3 0LDQutCw0LfRh9C40LrQsC4g0J7RgtGH0LXRgiDQvtCxINC40YHQv9C+0LvQvdC10L3QuNC4INC6 0L7QvdGC0YDQsNC60YLQsCDQv9C+IDQ0LdCk0JcuINCt0LrRgdC/0LXRgNGC0LjQt9CwDQrQuNGB 0L/QvtC70L3QtdC90LjRjw0K0LrQvtC90YLRgNCw0LrRgtCwLiDQmNC30LzQtdC90LXQvdC40LUg 0Lgg0YDQsNGB0YLQvtGA0LbQtdC90LjQtSDQtNC+0LPQvtCy0L7RgNCwICjQutC+0L3RgtGA0LDQ utGC0LApLiDQntGB0L3QvtCy0LDQvdC40Y8g0LgNCtC/0L7RgNGP0LTQvtC6INGA0LDRgdGC0L7R gNC20LXQvdC40Y8NCtCyINC+0LTQvdC+0YHRgtC+0YDQvtC90L3QtdC8INC/0L7RgNGP0LTQutC1 LiDQlNC+0L/QvtC70L3QuNGC0LXQu9GM0L3Ri9C1INGB0L7Qs9C70LDRiNC10L3QuNGPINC/0L4g NDQt0KTQlyDQuCAyMjMt0KTQly4NCtCY0LfQvNC10L3QtdC90LjQtQ0K0LrQvtC90YLRgNCw0LrR gtCwINC/0YDQuCDRgdC+0LrRgNCw0YnQtdC90LjQuCDQu9C40LzQuNGC0L7QsiDQsdGO0LTQttC1 0YLQvdC+0LPQviDRhNC40L3QsNC90YHQuNGA0L7QstCw0L3QuNGPINC30LDQutCw0LfRh9C40LrQ sC4NCtCe0YLQstC10YLRgdGC0LLQtdC90L3QvtGB0YLRjA0K0LfQsCDQvdC10LjRgdC/0L7Qu9C9 0LXQvdC40LUg0LggKNC40LvQuCkg0L3QtdC90LDQtNC70LXQttCw0YnQtdC1INC40YHQv9C+0LvQ vdC10L3QuNC1INC00L7Qs9C+0LLQvtGA0LAgKNC60L7QvdGC0YDQsNC60YLQsCkuDQrQl9Cw0LrQ vtC90L3Ri9C1INC4DQrQtNC+0LPQvtCy0L7RgNC90YvQtSDQvdC10YPRgdGC0L7QudC60LggKNC/ 0LXQvdC4INC4INGI0YLRgNCw0YTRiykuINCS0YvQv9C+0LvQvdC10L3QuNC1INC/0YDQsNC60YLQ uNGH0LXRgdC60L7Qs9C+INC30LDQtNCw0L3QuNGPDQoo0LrQtdC50YHQsCk6INGA0LDRgdGH0LXR gg0K0L/QtdC90Lgg0Lgg0YjRgtGA0LDRhNCwINC/0YDQuCDQvdCw0YDRg9GI0LXQvdC40Lgg0LrQ vtC90YLRgNCw0LrRgtCwLiDQkdC40LHQu9C40L7RgtC10LrQsCDRgtC40L/QvtCy0YvRhSDQutC+ 0L3RgtGA0LDQutGC0L7QsiwNCtGC0LjQv9C+0LLRi9GFINGD0YHQu9C+0LLQuNC5DQrQutC+0L3R gtGA0LDQutGC0L7Qsi4g0JrQsNC6INC90LUg0L/QvtC/0LDRgdGC0Ywg0LIg0KDQndCfOiDQv9GA 0LDQutGC0LjRh9C10YHQutC40LUg0YDQtdC60L7QvNC10L3QtNCw0YbQuNC4Lg0KDQoNCio0LtCa 0L7QvdGC0YDQvtC70Ywg0Lgg0L3QsNC00LfQvtGAINCyINGB0YTQtdGA0LUg0LfQsNC60YPQv9C+ 0LouINCf0YDQsNC60YLQuNC60LAg0KTQkNChLiDQntCx0LbQsNC70L7QstCw0L3QuNC1INC00LXQ udGB0YLQstC40LkNCtC30LDQutCw0LfRh9C40LrQsCzQutC+0LzQuNGB0YHQuNC4LioNCtCg0LXQ tdGB0YLRgCDQvdC10LTQvtCx0YDQvtGB0L7QstC10YHRgtC90YvRhSDQv9C+0YHRgtCw0LLRidC4 0LrQvtCyLiDQn9C+0YDRj9C00L7QuiDQstC90LXRgdC10L3QuNGPINC40L3RhNC+0YDQvNCw0YbQ uNC4LiDQn9GA0LDQutGC0LjQutCwDQrQutC+0L3RgtGA0L7Qu9GPDQrRhtC10L3RgtGA0LDQu9GM 0L3QvtCz0L4g0LDQv9C/0LDRgNCw0YLQsCDQuCDRgtC10YDRgNC40YLQvtGA0LjQsNC70YzQvdGL 0YUg0L7RgNCz0LDQvdC+0LIg0KTQkNChINCg0L7RgdGB0LjQuC4g0KDQvtC70Ywg0LgNCtC/0L7Q u9C90L7QvNC+0YfQuNGPINCk0JDQoSDQv9C+DQrQpNCXLTQ0INC4INCk0JctMjIzLiDQn9C+0YDR j9C00L7QuiDQvtCx0LbQsNC70L7QstCw0L3QuNGPINC00LXQudGB0YLQstC40Lkg0JfQsNC60LDQ t9GH0LjQutCwLCDRh9C70LXQvdC+0LIg0LrQvtC80LjRgdGB0LjQuCDQv9C+DQrQvtGB0YPRidC1 0YHRgtCy0LvQtdC90LjRjiDQt9Cw0LrRg9C/0L7Quiwg0LrQvtC90YLRgNCw0LrRgtC90L7Qs9C+ INGD0L/RgNCw0LLQu9GP0Y7RidC10LPQviwg0LTQvtC70LbQvdC+0YHRgtC90YvRhSDQu9C40YYN CtC60L7QvdGC0YDQsNC60YLQvdC+0Lkg0YHQu9GD0LbQsdGLLA0K0L7Qv9C10YDQsNGC0L7RgNCw INGN0LvQtdC60YLRgNC+0L3QvdC+0Lkg0L/Qu9C+0YnQsNC00LrQuC4g0KLQuNC/0LjRh9C90YvQ tSDQv9GA0LjQvNC10YDRiyDQvdCw0YDRg9GI0LXQvdC40Lkg0L/RgNCw0LINCtC/0L7RgdGC0LDQ stGJ0LjQutC+0LIuINCf0YDQsNCy0LjQu9CwDQrQv9C+0LTQsNGH0Lgg0Lgg0L7RhNC+0YDQvNC7 0LXQvdC40Y8g0LbQsNC70L7QsdGLLiDQn9C+0YHQu9C10LTRgdGC0LLQuNGPINC/0YDQuNC30L3Q sNC90LjRjyDQttCw0LvQvtCx0Ysg0L7QsdC+0YHQvdC+0LLQsNC90L3QvtC5Lg0KDQoNCg0K0KPR h9Cw0YHRgtC40LU6IDIyYCA4MDAg0YDRg9CxLg0K0J/QviDQvtC60L7QvdGH0LDQvdC40Y4g0LfQ sNC90Y/RgtC40Lkg0JLQsNC8INCy0YvQtNCw0LXRgtGB0Y8g0YHQtdGA0YLQuNGE0LjQutCw0YIu DQrQktGF0L7QtNC40YIg0LzQtdGC0L7QtNC40YfQtdGB0LrQuNC5INC80LDRgtC10YDQuNCw0Lss INC+0LHQtdC00YssINC60L7RhNC1LdC/0LDRg9C30YsuDQo= ------------61B07C5EF5E261EA2 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: base64 PGRpdiBkaXI9Imx0ciI+PGRpdiBhbGlnbj0iY2VudGVyIj48dGFibGUgYmdjb2xvcj0iI2Y3ZjVm NCIgYm9yZGVyPSIwIiBjZWxsc3BhY2luZz0iMCI+PHRib2R5Pjx0cj48dGQgYmdjb2xvcj0iI2Jm YjFhYSI+wqA8L3RkPjx0ZCBiZ2NvbG9yPSIjZWVlYWU4Ij7CoDwvdGQ+PHRkPsKgPC90ZD48dGQg Ymdjb2xvcj0iI2VlZWFlOCI+wqA8L3RkPjx0ZD7CoDwvdGQ+PHRkIGJnY29sb3I9IiNlMGRiZDgi PsKgPC90ZD48dGQgYmdjb2xvcj0iI2NmYzZjMCI+wqA8L3RkPjx0ZCBiZ2NvbG9yPSIjYmZiMWFh Ij7CoDwvdGQ+PC90cj48dHI+PHRkIGJnY29sb3I9IiNiZmIxYWEiPsKgPC90ZD48dGQgYmdjb2xv cj0iI2VlZWFlOCI+wqA8L3RkPjx0ZD7CoDwvdGQ+PHRkPjxwIGFsaWduPSJjZW50ZXIiPjxicj48 Zm9udCBjb2xvcj0iI2NjMDAwMCI+PGI+MjQ8c3BhbiBsYW5nPSJlbi11cyI+IDwvc3Bhbj4tPHNw YW4gbGFuZz0iZW4tdXMiPgkJCSA8L3NwYW4+MjUg0L3QvtGP0LHRgNGPIDxicj4JCQnQsy4g0JzQ vtGB0LrQstCwPGJyPsKgPC9iPjwvZm9udD48L3A+PC90ZD48dGQ+wqA8L3RkPjx0ZCBiZ2NvbG9y PSIjZTBkYmQ4Ij7CoDwvdGQ+PHRkIGJnY29sb3I9IiNjZmM2YzAiPsKgPC90ZD48dGQgYmdjb2xv cj0iI2JmYjFhYSI+wqA8L3RkPjwvdHI+PHRyPjx0ZCBoZWlnaHQ9IjQzMCIgYmdjb2xvcj0iI2Jm YjFhYSI+wqA8L3RkPjx0ZCBoZWlnaHQ9IjQzMCIgYmdjb2xvcj0iI2VlZWFlOCI+wqA8L3RkPjx0 ZCBoZWlnaHQ9IjQzMCI+wqA8L3RkPjx0ZCBoZWlnaHQ9IjQzMCIgYmdjb2xvcj0iI2VlZWFlOCI+ PHAgYWxpZ249ImNlbnRlciI+0KPRh9C10LHQvdGL0Lkg0YbQtdC90YLRgCDQv9GA0LjQs9C70LDR iNCw0LXRgiDQvdCwINC+0LHRg9GH0LXQvdC40LU6PGJyPjxicj48Yj48Zm9udCBjb2xvcj0iIzAw MDBmZiIgc2l6ZT0iNCI+0KPQp9CQ0KHQotCY0JUg0J/QntCh0KLQkNCS0KnQmNCa0J7QkiAo0J/Q ntCU0KDQr9CU0KfQmNCa0J7QkiwgCQkJINCY0KHQn9Ce0JvQndCY0KLQldCb0JXQmSkg0JI8YnI+ CQkJ0JfQkNCa0KPQn9Ca0JDQpSDQn9CeIDQ0LdCk0Jcg0JggMjIzLdCk0JcuINCd0J7QktCr0JUg 0KLQoNCV0JHQntCS0JDQndCY0K8uPGJyPtCX0JDQqdCY0KLQkCDQn9Cg0JDQkiDQmCDQmNCd0KLQ ldCg0JXQodCe0JIg0JIg0KTQkNChPC9mb250PjwvYj48L3A+PHAgYWxpZ249ImNlbnRlciI+PGI+ PGJyPjwvYj48L3A+PHAgc3R5bGU9InRleHQtYWxpZ246Y2VudGVyIj48L3A+PGRpdiBzdHlsZT0i dGV4dC1hbGlnbjpsZWZ0Ij48YiBzdHlsZT0iYmFja2dyb3VuZC1jb2xvcjpyZ2IoMjU1LDI1NSwy NTUpIj7Qn9GA0L7QvNC+0LrQvtC0OiAyNTQ8L2I+PC9kaXY+PGRpdiBzdHlsZT0iZm9udC13ZWln aHQ6Ym9sZDt0ZXh0LWFsaWduOmxlZnQiPjxicj48L2Rpdj48ZGl2IHN0eWxlPSJmb250LXdlaWdo dDpib2xkO3RleHQtYWxpZ246bGVmdCI+PGIgc3R5bGU9ImJhY2tncm91bmQtY29sb3I6cmdiKDI1 NSwyNTUsMjU1KSI+0KfQsNGB0Ysg0L/RgNC+0LLQtdC00LXQvdC40Y8g0LfQsNC90Y/RgtC40Lk8 c3BhbiBsYW5nPSJlbi11cyI+Ojwvc3Bhbj4g0YEgMTA8c3BhbiBsYW5nPSJlbi11cyI+Ojwvc3Bh bj4wMCAJCQkg0LTQviAxNzxzcGFuIGxhbmc9ImVuLXVzIj46PC9zcGFuPjMwPC9iPjwvZGl2Pjxk aXYgc3R5bGU9ImZvbnQtd2VpZ2h0OmJvbGQ7dGV4dC1hbGlnbjpsZWZ0Ij48YnI+PC9kaXY+PGRp diBzdHlsZT0iZm9udC13ZWlnaHQ6Ym9sZDt0ZXh0LWFsaWduOmxlZnQiPjxiIHN0eWxlPSJiYWNr Z3JvdW5kLWNvbG9yOnJnYigyNTUsMjU1LDI1NSkiPtCQ0LTRgNC10YEg0LzQtdGA0L7Qv9GA0LjR j9GC0LjRjzog0LwuINCR0LDRg9C80LDQvdGB0LrQsNGPLCDRg9C7LiDQkdCw0YPQvNCw0L3RgdC6 0LDRjywg0LQuNiwg0YHRgtGALjIsINCRLtCmLgkJCSA8c3BhbiBsYW5nPSJlbi11cyI+JnF1b3Q7 PC9zcGFuPtCS0LjQutGC0L7RgNC40Y8g0J/Qu9Cw0LfQsDxzcGFuIGxhbmc9ImVuLXVzIj4mcXVv dDs8L3NwYW4+LjwvYj48L2Rpdj48ZGl2IHN0eWxlPSJmb250LXdlaWdodDpib2xkO3RleHQtYWxp Z246bGVmdCI+PGJyPjwvZGl2PjxkaXYgc3R5bGU9InRleHQtYWxpZ246bGVmdCI+PHNwYW4gc3R5 bGU9ImJhY2tncm91bmQtY29sb3I6cmdiKDI1NSwyNTUsMjU1KSI+PGZvbnQgc2l6ZT0iNCI+0JLR gdGPINC/0L7QtNGA0L7QsdC90LDRjyDQuNC90YTQvtGA0LzQsNGG0LjRjyDQuCDRgNC10LPQuNGB 0YLRgNCw0YbQuNGPINC90LAg0L7QsdGD0YfQtdC90LjQtSDQv9C+INGC0LXQu9C10YTQvtC90YM6 PC9mb250Pjwvc3Bhbj48L2Rpdj48ZGl2IHN0eWxlPSJ0ZXh0LWFsaWduOmxlZnQiPjxmb250IHNp emU9IjQiPjxicj48L2ZvbnQ+PC9kaXY+PGRpdiBzdHlsZT0idGV4dC1hbGlnbjpsZWZ0Ij48c3Bh biBzdHlsZT0iZm9udC1zaXplOmxhcmdlO2JhY2tncm91bmQtY29sb3I6cmdiKDI1NSwyNTUsMjU1 KSI+OMKgIDwvc3Bhbj48Zm9udCBzdHlsZT0iYmFja2dyb3VuZC1jb2xvcjpyZ2IoMjU1LDI1NSwy NTUpIj7QutC+0LQg0LPQvtGA0L7QtNCwINCc0L7RgdC60LLRizwvZm9udD48c3BhbiBzdHlsZT0i Zm9udC1zaXplOmxhcmdlO2JhY2tncm91bmQtY29sb3I6cmdiKDI1NSwyNTUsMjU1KSI+wqAgKCA0 IDkgNSAJCQkpwqAgPC9zcGFuPjxmb250IHN0eWxlPSJiYWNrZ3JvdW5kLWNvbG9yOnJnYigyNTUs MjU1LDI1NSkiPtC90L7QvNC10YA8L2ZvbnQ+PHNwYW4gbGFuZz0iZW4tdXMiIHN0eWxlPSJiYWNr Z3JvdW5kLWNvbG9yOnJnYigyNTUsMjU1LDI1NSkiPjo8L3NwYW4+PHNwYW4gc3R5bGU9ImZvbnQt c2l6ZTpsYXJnZTtiYWNrZ3JvdW5kLWNvbG9yOnJnYigyNTUsMjU1LDI1NSkiPsKgIAkJCSA3MjUg LSAwNCAtIDQ4wqAgPC9zcGFuPjxmb250IHN0eWxlPSJiYWNrZ3JvdW5kLWNvbG9yOnJnYigyNTUs MjU1LDI1NSkiPijQvNC90L7Qs9C+0LrQsNC90LDQu9GM0L3Ri9C5KTwvZm9udD48L2Rpdj48cD48 L3A+PC90ZD48dGQgaGVpZ2h0PSI0MzAiPsKgPC90ZD48dGQgaGVpZ2h0PSI0MzAiIGJnY29sb3I9 IiNlMGRiZDgiPsKgPC90ZD48dGQgaGVpZ2h0PSI0MzAiIGJnY29sb3I9IiNjZmM2YzAiPsKgPC90 ZD48dGQgaGVpZ2h0PSI0MzAiIGJnY29sb3I9IiNiZmIxYWEiPsKgPC90ZD48L3RyPjx0cj48dGQg Ymdjb2xvcj0iI2JmYjFhYSI+wqA8L3RkPjx0ZCBiZ2NvbG9yPSIjZWVlYWU4Ij7CoDwvdGQ+PHRk PsKgPC90ZD48dGQ+PHAgYWxpZ249ImxlZnQiPjxicj48Zm9udCBjb2xvcj0iIzk5MDAzMyI+PGI+ 0JLQndCY0JzQkNCd0JjQlSE8L2I+PC9mb250PiDQkiDRgdC+0L7RgtCy0LXRgtGB0YLQstC40Lgg 0YEgCQkJ0YLRgNC10LHQvtCy0LDQvdC40Y/QvNC4INGE0LXQtNC10YDQsNC70YzQvdGL0YUg0LfQ sNC60L7QvdC+0LIg4oSWIDQ0LdCk0Jcg0Lgg4oSWIDIyMy3QpNCXINCx0L7Qu9C10LU8YnI+NjAw IDAwMCDQt9Cw0LrQsNC30YfQuNC60L7QsiDQvtCx0Y/Qt9Cw0L3RiyDQvtC/0YDQtdC00LXQu9GP 0YLRjCDQv9C+0YHRgtCw0LLRidC40LrQvtCyICjQv9C+0LTRgNGP0LTRh9C40LrQvtCyLCAJCQkg 0LjRgdC/0L7Qu9C90LjRgtC10LvQtdC5KSDQv9C+INC20LXRgdGC0LrQuNC8PGJyPgkJCdC/0YDQ sNCy0LjQu9Cw0LwsINC90LDRhtC10LvQtdC90L3Ri9C8INC90LAg0YDQsNC30LLQuNGC0LjQtSDQ utC+0L3QutGD0YDQtdC90YbQuNC4INC4INC/0YDQtdC00L7RgtCy0YDQsNGJ0LXQvdC40LUgCQkJ 0LrQvtGA0YDRg9C/0YbQuNC4LiDQl9Cw0LrQvtC90L7QtNCw0YLQtdC70YzRgdGC0LLQvjxicj4J CQnQviDQt9Cw0LrRg9C/0LrQsNGFINC/0L7RgdGC0L7Rj9C90L3QviDRgdC+0LLQtdGA0YjQtdC9 0YHRgtCy0YPQtdGC0YHRjzog0LIgMjAxNCDQs9C+0LTRgyDQsdGL0LvQuCDQuNC30LzQtdC90LXQ vdGLIAkJCdGC0YDQtdCx0L7QstCw0L3QuNGPINC6INC30LDRj9Cy0LrQsNC8INC90LA8YnI+CQkJ 0YPRh9Cw0YHRgtC40LUg0LIg0LfQsNC60YPQv9C60LDRhSwg0LIgMjAxNSDQs9C+0LTRgyDQstCy 0LXQtNC10L3RiyDQsNC90YLQuNC60YDQuNC30LjRgdC90YvQtSDQvNC10YDRiyDQuCDQvdC+0LLR i9C1IAkJCdC/0YDQsNCy0LjQu9CwINC/0L7QtNC00LXRgNC20LrQuDxicj4JCQnRgdGD0LHRitC1 0LrRgtC+0LIg0LzQsNC70L7Qs9C+INC4INGB0YDQtdC00L3QtdCz0L4g0L/RgNC10LTQv9GA0LjQ vdC40LzQsNGC0LXQu9GM0YHRgtCy0LAsINC/0LvQsNC90LjRgNGD0LXRgtGB0Y8g0L/QtdGA0LXQ stC+0LQgCQkJ0LLRgdC10YUg0LrQvtC90LrRg9GA0LXQvdGC0L3Ri9GFPGJyPgkJCdC30LDQutGD 0L/QvtC6INCyINGN0LvQtdC60YLRgNC+0L3QvdGD0Y4g0YTQvtGA0LzRgy48YnI+PGI+0JIg0YbQ tdC70Y/RhSA8L2I+0L/RgNCw0LrRgtC40YfQtdGB0LrQvtC5INC/0L7QtNCz0L7RgtC+0LLQutC4 INGB0L/QtdGG0LjQsNC70LjRgdGC0L7QsiDQv9C+0YHRgtCw0LLRidC40LrQvtCyIAkJCSAo0L/Q vtC00YDRj9C00YfQuNC60L7Qsiwg0LjRgdC/0L7Qu9C90LjRgtC10LvQtdC5KSDQujxicj4JCQnQ stGL0L/QvtC70L3QtdC90LjRjiDQvdC+0LLRi9GFINGC0YDQtdCx0L7QstCw0L3QuNC5INCyINGA 0LDQvNC60LDRhSDQutC+0L3RgtGA0LDQutGC0L3QvtC5INGB0LjRgdGC0LXQvNGLINC4INC/0L7Q u9C+0LbQtdC90LjQuSAJCQnQviDQt9Cw0LrRg9C/0LrQtSDQvtGC0LTQtdC70YzQvdGL0YU8YnI+ CQkJ0LLQuNC00L7QsiDRjtGA0LjQtNC40YfQtdGB0LrQuNGFINC70LjRhiwg0YEg0YPRh9C10YLQ vtC8INC/0YDQsNC60YLQuNC60Lgg0YDQsNGB0YHQvNC+0YLRgNC10L3QuNGPINC20LDQu9C+0LEg CQkJ0KTQtdC00LXRgNCw0LvRjNC90L7QuSDQsNC90YLQuNC80L7QvdC+0L/QvtC70YzQvdC+0Lk8 YnI+CQkJ0YHQu9GD0LbQsdC+0Lkg0Lgg0L3QsNC/0YDQsNCy0LvQtdC90LjQuSDRgNCw0LfQstC4 0YLQuNGPINC60L7QvdGC0YDQsNC60YLQvdC+0Lkg0YHQuNGB0YLQtdC80YssINC/0YDQuNCz0LvQ sNGI0LDQtdC8IAkJCdC/0YDQuNC90Y/RgtGMINGD0YfQsNGB0YLQuNC1INCyINGB0L/QtdGG0LjQ sNC70YzQvdC+PGJyPgkJCdGA0LDQt9GA0LDQsdC+0YLQsNC90L3QvtC8INC/0YDQsNC60YLQuNGH 0LXRgdC60L7QvCDRgdC10LzQuNC90LDRgNC1LdGC0YDQtdC90LjQvdCz0LUuPC9wPjwvdGQ+PHRk PsKgPC90ZD48dGQgYmdjb2xvcj0iI2UwZGJkOCI+wqA8L3RkPjx0ZCBiZ2NvbG9yPSIjY2ZjNmMw Ij7CoDwvdGQ+PHRkIGJnY29sb3I9IiNiZmIxYWEiPsKgPC90ZD48L3RyPjx0cj48dGQgYmdjb2xv cj0iI2JmYjFhYSI+wqA8L3RkPjx0ZCBiZ2NvbG9yPSIjZWVlYWU4Ij7CoDwvdGQ+PHRkPsKgPC90 ZD48dGQ+wqA8L3RkPjx0ZD7CoDwvdGQ+PHRkIGJnY29sb3I9IiNlMGRiZDgiPsKgPC90ZD48dGQg Ymdjb2xvcj0iI2NmYzZjMCI+wqA8L3RkPjx0ZCBiZ2NvbG9yPSIjYmZiMWFhIj7CoDwvdGQ+PC90 cj48dHI+PHRkIGJnY29sb3I9IiNiZmIxYWEiPsKgPC90ZD48dGQgYmdjb2xvcj0iI2VlZWFlOCI+ wqA8L3RkPjx0ZCBiZ2NvbG9yPSIjZWVlYWU4Ij7CoDwvdGQ+PHRkIGJnY29sb3I9IiNlZWVhZTgi PjxwIGFsaWduPSJjZW50ZXIiPjxiPjxmb250IGNvbG9yPSIjMDAwMGNjIiBzaXplPSI0Ij7QkiDQ v9GA0L7Qs9GA0LDQvNC80LU6PC9mb250PjwvYj48L3A+PC90ZD48dGQgYmdjb2xvcj0iI2VlZWFl OCI+wqA8L3RkPjx0ZCBiZ2NvbG9yPSIjZTBkYmQ4Ij7CoDwvdGQ+PHRkIGJnY29sb3I9IiNjZmM2 YzAiPsKgPC90ZD48dGQgYmdjb2xvcj0iI2JmYjFhYSI+wqA8L3RkPjwvdHI+PHRyPjx0ZCBiZ2Nv bG9yPSIjYmZiMWFhIj7CoDwvdGQ+PHRkIGJnY29sb3I9IiNlZWVhZTgiPsKgPC90ZD48dGQ+wqA8 L3RkPjx0ZD48Yj48Zm9udCBjb2xvcj0iIzAwMDBjYyIgc2l6ZT0iNCI+MS48L2ZvbnQ+PC9iPtCe 0YHQvdC+0LLRiyAJCQnRgNC10LPRg9C70LjRgNC+0LLQsNC90LjRjyDQt9Cw0LrRg9C/0L7QuiDQ t9Cw0LrQvtC90LDQvNC4IDQ0LdCk0Jcg0LggMjIzLdCk0JcuINCf0L7QvdGP0YLQuNGPLCDQv9GA 0LjQvdGG0LjQv9GLIAkJCdC+0YHRg9GJ0LXRgdGC0LLQu9C10L3QuNGPPGJyPgkJCdC30LDQutGD 0L/QvtC6LCDQv9GA0LDQstCwINC4INC+0LHRj9C30LDQvdC90L7RgdGC0Lgg0L/QvtGB0YLQsNCy 0YnQuNC60L7QsiAo0L/QvtC00YDRj9C00YfQuNC60L7QsiwgCQkJINC40YHQv9C+0LvQvdC40YLQ tdC70LXQuSkuPGJyPtCX0LDQutGD0L/QutC4INC/0L4gNDQt0KTQlyDQuCAyMjMt0KTQlzog0YHR hdC+0LTRgdGC0LLQsCDQuCDRgNCw0LfQu9C40YfQuNGPLjxiPiDQmNC30LzQtdC90LXQvdC40Y8g 0LIgCQkJ0YDQtdCz0YPQu9C40YDQvtCy0LDQvdC40Lgg0LfQsNC60YPQv9C+0Log0L/QviA0NC08 YnI+0KTQlyDQuCAyMjMt0KTQlyDQsiAyMDE1INCz0L7QtNGDLjwvYj4g0J/QvtC/0YDQsNCy0LrQ uCwg0L/Qu9Cw0L3QuNGA0YPQtdC80YvQtSDQuiDRgNC10LDQu9C40LfQsNGG0LjQuCDQsiAJCQkg MjAxNiDQs9C+0LTRgy4g0JXQtNC40L3QsNGPPGJyPgkJCdC40L3RhNC+0YDQvNCw0YbQuNC+0L3Q vdCw0Y8g0YHQuNGB0YLQtdC80LAg0LIg0YHRhNC10YDQtSDQt9Cw0LrRg9C/0L7Qujog0L3QvtCy 0YvQuSDRhNGD0L3QutGG0LjQvtC90LDQuyDQtNC70Y8gCQkJ0L/QvtGB0YLQsNCy0YnQuNC60LAs INGA0LXQutC+0LzQtdC90LTQsNGG0LjQuDxicj4JCQnQv9C+INC/0L7QuNGB0LrRgyDQuNC90YTQ vtGA0LzQsNGG0LjQuC4g0KDQsNC30LzQtdGJ0LXQvdC40LUg0LjQvdGE0L7RgNC80LDRhtC40Lgg 0L4g0LfQsNC60YPQv9C60LDRhSDQsiAJCQnRgdC+0L7RgtCy0LXRgtGB0YLQstC40Lgg0YEgNDQt 0KTQlyDQuCAyMjMt0KTQlzo8YnI+0L/Qu9Cw0L3RiyAo0L/Qu9Cw0L3Riy3Qs9GA0LDRhNC40LrQ uCkg0LfQsNC60YPQv9C+0LosINC40LfQstC10YnQtdC90LjQtSwg0LTQvtC60YPQvNC10L3RgtCw 0YbQuNGPLCDQv9C+0LvQvtC20LXQvdC40LUg0L4gCQkJ0LfQsNC60YPQv9C60LUsINGA0LXQtdGB 0YLRgDxicj4JCQnQutC+0L3RgtGA0LDQutGC0L7Qsiwg0YDQtdC10YHRgtGAINC00L7Qs9C+0LLQ vtGA0L7Qsiwg0L7RgtGH0LXRgiDQvtCxINC40YHQv9C+0LvQvdC10L3QuNC4INC60L7QvdGC0YDQ sNC60YLQsC4gCQkJINCU0L7QutGD0LzQtdC90YLQsNGG0LjRjyDQviDQt9Cw0LrRg9C/0LrQtTo8 YnI+0YHRgtGA0YPQutGC0YPRgNCwLCDRgdC+0LTQtdGA0LbQsNC90LjQtSwg0LDQvdCw0LvQuNC3 LiDQntGG0LXQvdC60LAg0L/QtdGA0YHQv9C10LrRgtC40LIg0Lgg0YDQuNGB0LrQvtCyINGD0YfQ sNGB0YLQuNGPINCyIAkJCdC30LDQutGD0L/QutC1LiDQn9GA0LDQstC40LvQsDxicj4JCQnQvtCx 0L7RgdC90L7QstCw0L3QuNGPINC90LDRh9Cw0LvRjNC90L7QuSAo0LzQsNC60YHQuNC80LDQu9GM 0L3QvtC5KSDRhtC10L3RiyDQtNC+0LPQvtCy0L7RgNCwICjQutC+0L3RgtGA0LDQutGC0LApLiAJ CQkg0J/QvtC80L7RidGMINC30LDQutCw0LfRh9C40LrQsNC8INCyPGJyPgkJCdC/0L7QtNCz0L7R gtC+0LLQutC1INC00L7QutGD0LzQtdC90YLQsNGG0LjQuCDQviDQt9Cw0LrRg9C/0LrQtS4g0KLR gNC10LHQvtCy0LDQvdC40Y8g0Log0YPRh9Cw0YHRgtC90LjQutCw0Lwg0LfQsNC60YPQv9C60Lg6 IAkJCSDQvtGB0L3QvtCy0L3Ri9C1INC4PGJyPgkJCdC00L7Qv9C+0LvQvdC40YLQtdC70YzQvdGL 0LUuINCf0YDQuNC80LXRgNGLINC90LXQt9Cw0LrQvtC90L3Ri9GFINGC0YDQtdCx0L7QstCw0L3Q uNC5LiDQn9GA0LXQuNC80YPRidC10YHRgtCy0LAg0L/RgNC4IAkJCdGD0YfQsNGB0YLQuNC4INCy INC30LDQutGD0L/QutCw0YUuPGJyPtCX0LDQutGD0L/QutC4INGDINGB0YPQsdGK0LXQutGC0L7Q siDQvNCw0LvQvtCz0L4g0Lgg0YHRgNC10LTQvdC10LPQviDQv9GA0LXQtNC/0YDQuNC90LjQvNCw 0YLQtdC70YzRgdGC0LLQsC4g0J3QvtCy0YvQtSAJCQnQvtCx0Y/Qt9Cw0L3QvdC+0YHRgtC4INC3 0LDQutCw0LfRh9C40LrQvtCyLjxicj7Ql9Cw0L/RgNC+0YHRiyDQviDRgNCw0LfRitGP0YHQvdC1 0L3QuNC4INC00L7QutGD0LzQtdC90YLQsNGG0LjQuCDQviDQt9Cw0LrRg9C/0LrQtTog0YbQtdC7 0Lgg0Lgg0L/RgNCw0LLQuNC70LAg0L/QvtC00LDRh9C4LiAJCQkg0KHQvtGB0YLQsNCyINC30LDR j9Cy0LrQuCDQvdCwPGJyPgkJCdGD0YfQsNGB0YLQuNC1INCyINC30LDQutGD0L/QutC1OiDQvdC+ 0LLRi9C1INGC0YDQtdCx0L7QstCw0L3QuNGPLiDQntGB0L3QvtCy0LDQvdC40Y8g0L7RgtC60LvQ vtC90LXQvdC40Y8g0LfQsNGP0LLQvtC6INC/0L4gCQkJIDQ0LdCk0Jcg0LggMjIzLdCk0JcuINCa 0LDQujxicj4JCQnQv9GA0LDQstC40LvRjNC90L4g0L/QvtC00LPQvtGC0L7QstC40YLRjCDQt9Cw 0Y/QstC60YMuINCQ0LvQs9C+0YDQuNGC0Lwg0LTQtdC50YHRgtCy0LjQuSDRgtC10L3QtNC10YDQ vdC+0LPQviAJCQnRgdC/0LXRhtC40LDQu9C40YHRgtCwLiDQntCx0LXRgdC/0LXRh9C10L3QuNC1 PGJyPgkJCdC30LDRj9Cy0L7QuiDQv9GA0Lgg0YPRh9Cw0YHRgtC40Lgg0LIg0LfQsNC60YPQv9C6 0LDRhS4g0KTQvtGA0LzRiyDQuCDRgNCw0LfQvNC10YAuINCf0YDQsNCy0LjQu9CwINCy0L7Qt9Cy 0YDQsNGC0LAgCQkJ0L7QsdC10YHQv9C10YfQtdC90LjRjyDQt9Cw0Y/QstC60LguPGJyPtCh0LvR g9GH0LDQuCwg0LrQvtCz0LTQsCDQvtCx0LXRgdC/0LXRh9C10L3QuNC1INC90LUg0LLQvtC30LLR gNCw0YnQsNC10YLRgdGPLiDQoNC10LXRgdGC0YAg0LHQsNC90LrQvtCy0YHQutC40YUgCQkJ0LPQ sNGA0LDQvdGC0LjQuS4g0KLRgNC10LHQvtCy0LDQvdC40Y8g0Lo8YnI+CQkJ0LHQsNC90LrQvtCy 0YHQutC+0Lkg0LPQsNGA0LDQvdGC0LjQuC4g0KPRgdC70L7QstC40Y8g0Lgg0YHRgNC+0LrQuCDQ vtGC0LzQtdC90Ysg0L/RgNC+0YbQtdC00YPRgC4g0JjQt9Cy0LXRidC10L3QuNC1INC+IAkJCdC3 0LDQutGD0L/QutC1IOKAkyDQvtGE0LXRgNGC0LAg0LjQu9C4PGJyPgkJCdC/0YDQuNCz0LvQsNGI 0LXQvdC40LUg0LTQtdC70LDRgtGMINC+0YTQtdGA0YLRizog0LIg0YfQtdC8INGA0LDQt9C90LjR htCwLiDQkNC90YLQuNC00LXQvNC/0LjQvdCz0L7QstGL0LUg0LzQtdGA0Ysg0L/RgNC4IAkJCdC/ 0YDQvtCy0LXQtNC10L3QuNC4INC30LDQutGD0L/QvtC6Ljxicj7QmNC90YTQvtGA0LzQsNGG0LjR jywg0L/QvtC00YLQstC10YDQttC00LDRjtGJ0LDRjyDQtNC+0LHRgNC+0YHQvtCy0LXRgdGC0L3Q vtGB0YLRjCDRg9GH0LDRgdGC0L3QuNC60LAuIAkJCSDQkNC90YLQuNC60L7RgNGA0YPQv9GG0LjQ vtC90L3Ri9C1INC80LXRgNGLLjxicj7Qn9C+0YHQu9C10LTRgdGC0LLQuNGPINC/0YDQuNC30L3Q sNC90LjRjyDQv9GA0L7RhtC10LTRg9GAINC+0L/RgNC10LTQtdC70LXQvdC40Y8g0L/QvtGB0YLQ sNCy0YnQuNC60L7QsiAJCQnQvdC10YHQvtGB0YLQvtGP0LLRiNC40LzQuNGB0Y8g0L/QviA0NC3Q pNCXINC4PGJyPjIyMy3QpNCXLjxicj48Yj48Zm9udCBjb2xvcj0iIzAwMDBjYyIgc2l6ZT0iNCI+ PGJyPjIuPC9mb250PtCY0LfQvNC10L3QtdC90LjRjyDQsiDQv9GA0LDQstC40LvQsNGFIAkJCdGD 0YfQsNGB0YLQuNGPINC4INC+0L/RgNC10LTQtdC70LXQvdC40Y8g0L/QvtCx0LXQtNC40YLQtdC7 0Y8g0LIg0LfQsNC60YPQv9C60LDRhSDQsiAyMDE1INCz0L7QtNGDLjwvYj48YnI+0JrQvtC90LrR g9GA0LXQvdGC0L3Ri9C1INGB0L/QvtGB0L7QsdGLINC+0L/RgNC10LTQtdC70LXQvdC40Y8g0L/Q vtGB0YLQsNCy0YnQuNC60L7Qsjog0LrQu9Cw0YHRgdC40YTQuNC60LDRhtC40Y8sIAkJCSDRgdGA 0LDQstC90LjRgtC10LvRjNC90YvQuSDQsNC90LDQu9C40LcuPGJyPtCj0YfQsNGB0YLQuNC1INCy INC+0YLQutGA0YvRgtC+0Lwg0LrQvtC90LrRg9GA0YHQtTog0L7RgdC+0LHQtdC90L3QvtGB0YLQ uCDQv9C+0LTQs9C+0YLQvtCy0LrQuCDQt9Cw0Y/QstC60Lgg0L/QviA0NC3QpNCXIAkJCdC4IDIy My3QpNCXPGJyPgkJCdCe0YbQtdC90LrQsCDQt9Cw0Y/QstC+0LosINC+0LrQvtC90YfQsNGC0LXQ u9GM0L3Ri9GFINC/0YDQtdC00LvQvtC20LXQvdC40Lkg0YPRh9Cw0YHRgtC90LjQutC+0LIg0LfQ sNC60YPQv9C60LguINCc0LXRgtC+0LTRiyAJCQnQvtGG0LXQvdC60Lgg0L/QviAyMjMt0KTQly48 YnI+0J3QvtCy0YvQtSDQv9GA0LDQstC40LvQsCDQvtGG0LXQvdC60Lgg0L/QviA0NC3QpNCXLiDQ ntGG0LXQvdC60LAg0L/QviDQvdC10YHRgtC+0LjQvNC+0YHRgtC90YvQvCDQutGA0LjRgtC10YDQ uNGP0LwgCQkJICjCq9Ca0LDRh9C10YHRgtCy0L4g0YLQvtCy0LDRgNC+0LIsPGJyPtGA0LDQsdC+ 0YIsINGD0YHQu9GD0LPCuywgwqvQmtCy0LDQu9C40YTQuNC60LDRhtC40Y8g0YPRh9Cw0YHRgtC9 0LjQutCwwrspLiDQn9GA0LDQutGC0LjRh9C10YHQutC40LUg0L/RgNC40LzQtdGA0YsgCQkJ0L7R htC10L3QutC4INC30LDRj9Cy0L7QuiDRgNCw0LfQu9C40YfQvdGL0LzQuDxicj4JCQnQvNC10YLQ vtC00LDQvNC4LiDQndC+0LLRi9C1INC/0YDQvtGG0LXQtNGD0YDRiyDQt9Cw0LrRg9C/0L7Qujog 0LrQvtC90LrRg9GA0YEg0YEg0L7Qs9GA0LDQvdC40YfQtdC90L3Ri9C8INGD0YfQsNGB0YLQuNC1 0LwsIAkJCSDQtNCy0YPRhdGN0YLQsNC/0L3Ri9C5PGJyPgkJCdC60L7QvdC60YPRgNGBLiDQntGB 0L7QsdC10L3QvdC+0YHRgtC4LCDRg9GB0LvQvtCy0LjRjyDQuCDRgdGA0L7QutC4INC/0YDQvtCy 0LXQtNC10L3QuNGPLiDQn9C+0LTQs9C+0YLQvtCy0LrQsCDQuCAJCQnQvtGE0L7RgNC80LvQtdC9 0LjQtSDQt9Cw0Y/QstC60Lgg0L3QsDxicj4JCQnRg9GH0LDRgdGC0LjQtSDQsiDQvtGC0LrRgNGL 0YLQvtC8INC60L7QvdC60YPRgNGB0LU6INC+0YHQvdC+0LLQvdGL0LUg0L/RgNCw0LLQuNC70LAs INGC0LjQv9C40YfQvdGL0LUg0L7RiNC40LHQutC4LiAJCQkg0KLRgNC10L3QuNC90LM6INC/0L7Q tNCz0L7RgtC+0LLQutCwPGJyPgkJCdC00L7QutGD0LzQtdC90YLQvtCyINC00LvRjyDRg9GH0LDR gdGC0LjRjyDQsiDQutC+0L3QutGD0YDRgdC1LiDQmNC30LzQtdC90LXQvdC40Y8g0LIg0L/RgNC+ 0LLQtdC00LXQvdC40LggCQkJ0Y3Qu9C10LrRgtGA0L7QvdC90YvRhSDQsNGD0LrRhtC40L7QvdC+ 0LIg0L/QviA0NC3QpNCXLjxicj7QndC+0LLRi9C1INGC0YDQtdCx0L7QstCw0L3QuNGPINC6INC+ 0L/QuNGB0LDQvdC40Y4g0L7QsdGK0LXQutGC0LAg0LfQsNC60YPQv9C60LguINCY0LfQvNC10L3Q tdC90LjQtSDRgtGA0LXQsdC+0LLQsNC90LjQuSDQuiAJCQnQv9C10YDQstC+0Lkg0Lgg0LLRgtC+ 0YDQvtC5PGJyPgkJCdGH0LDRgdGC0Y/QvCDQt9Cw0Y/QstC60LggKDE0MC3QpNCXLCA0OTgt0KTQ lykuINCe0LHQt9C+0YAg0YTQtdC00LXRgNCw0LvRjNC90YvRhSDRjdC70LXQutGC0YDQvtC90L3R i9GFIAkJCdC/0LvQvtGJ0LDQtNC+0LouINCg0LXQs9C70LDQvNC10L3Rgjxicj4JCQnRgNCw0LHQ vtGC0YsuINCQ0LrQutGA0LXQtNC40YLQsNGG0LjRjyDRg9GH0LDRgdGC0L3QuNC60L7QsiDQvdCw INGN0LvQtdC60YLRgNC+0L3QvdGL0YUg0L/Qu9C+0YnQsNC00LrQsNGFLiAJCQkg0K3Qu9C10LrR gtGA0L7QvdC90YvQuSDQtNC+0LrRg9C80LXQvdGC0L7QvtCx0L7RgNC+0YIuPGJyPtCf0LXRgNC1 0YfQtdC90Ywg0YLQvtCy0LDRgNC+0LIsINGA0LDQsdC+0YIg0Lgg0YPRgdC70YPQsywg0LfQsNC6 0YPQv9Cw0LXQvNGL0YUg0YHQv9C+0YHQvtCx0L7QvCDRjdC70LXQutGC0YDQvtC90L3QvtCz0L4g CQkJ0LDRg9C60YbQuNC+0L3QsCDQv9C+IDQ0LdCk0JcsINCyPGJyPgkJCdGN0LvQtdC60YLRgNC+ 0L3QvdC+0Lkg0YTQvtGA0LzQtSDQv9C+IDIyMy3QpNCXLiDQn9C+0LTQsNGH0LAg0LfQsNGP0LLQ vtC6INC4INC30LDQutC70Y7Rh9C10L3QuNC1INC00L7Qs9C+0LLQvtGA0LAg0L3QsCAJCQnRjdC7 0LXQutGC0YDQvtC90L3QvtC5PGJyPgkJCdC/0LvQvtGJ0LDQtNC60LUsINCyINC10LTQuNC90L7Q uSDQuNC90YTQvtGA0LzQsNGG0LjQvtC90L3QvtC5INGB0LjRgdGC0LXQvNC1LiDQntGB0L3QvtCy 0L3Ri9C1INC/0YDQuNGH0LjQvdGLIAkJCdC+0YLQutC70L7QvdC10L3QuNGPINC/0LXRgNCy0YvR hSDQuDxicj4JCQnQstGC0L7RgNGL0YUg0YfQsNGB0YLQtdC5INC30LDRj9Cy0L7QuiDQvdCwINGD 0YfQsNGB0YLQuNC1INCyINGN0LvQtdC60YLRgNC+0L3QvdC+0Lwg0LDRg9C60YbQuNC+0L3QtSDQ v9C+IDQ0LdCk0JcuIAkJCSDQktGL0L/QvtC70L3QtdC90LjQtSDQuCDRgNCw0LfQsdC+0YA8YnI+ CQkJ0L/RgNCw0LrRgtC40YfQtdGB0LrQvtCz0L4g0LfQsNC00LDQvdC40Y8gKNC60LXQudGB0LAp OiDQvtCx0LbQsNC70L7QstCw0L3QuNC1INC+0YLQutCw0LfQsCDQsiDQtNC+0L/Rg9GB0LrQtSDQ uiAJCQnRg9GH0LDRgdGC0LjRjiDQsiDQsNGD0LrRhtC40L7QvdC1Ljxicj7QrdC70LXQutGC0YDQ vtC90L3Ri9C5INCw0YPQutGG0LjQvtC9LiDQn9GA0LDQstC40LvQsCDQv9C+0LTQsNGH0Lgg0YbQ tdC90L7QstGL0YUg0L/RgNC10LTQu9C+0LbQtdC90LjQuS4g0KHRgtGA0LDRgtC10LPQuNGPINC4 IAkJCdGC0LDQutGC0LjQutCwINGD0YfQsNGB0YLQuNGPLjxicj7Qp9GC0L4g0YLQsNC60L7QtSDC q9GB0LPQvtCy0L7RgCDQvdCwINGC0L7RgNCz0LDRhcK7LCDCq9C60LDRgNGC0LXQu9GMwrsgLSDQ t9CwINGH0YLQviDRiNGC0YDQsNGE0YPQtdGCINCk0JDQoSDQl9Cw0L/RgNC+0YEgCQkJ0LrQvtGC 0LjRgNC+0LLQvtC6OiDQv9GA0LDQstC40LvQsDxicj4JCQnQv9GA0L7QstC10LTQtdC90LjRjyDQ uCDRg9GH0LDRgdGC0LjRjy4g0JfQsNGP0LLQutCwINC90LAg0YPRh9Cw0YHRgtC40LUg0LIg0LfQ sNC/0YDQvtGB0LUg0LrQvtGC0LjRgNC+0LLQvtC6OiDQvdC+0LLRi9C1IAkJCdGC0YDQtdCx0L7Q stCw0L3QuNGPICgxNDAt0KTQlywgNDk4PGJyPi3QpNCXKS4g0J7RgdC+0LHQtdC90L3QvtGB0YLQ uCDQt9Cw0L/RgNC+0YHQvtCyINC60L7RgtC40YDQvtCy0L7QuiDQv9C+IDIyMy3QpNCXLiDQl9Cw 0L/RgNC+0YEg0L/RgNC10LTQu9C+0LbQtdC90LjQuSwgCQkJINC+0YHQvtCx0LXQvdC90L7RgdGC 0Lgg0Lgg0L/QvtGA0Y/QtNC+0Lo8YnI+CQkJ0L/RgNC+0LLQtdC00LXQvdC40Y8g0L/RgNC+0YbQ tdC00YPRgNGLLiDQo9GH0LDRgdGC0LjQtSDQsiDQt9Cw0L/RgNC+0YHQsNGFINC/0YDQtdC00LvQ vtC20LXQvdC40Lkg0L/QviAyMjMt0KTQlyDQuCAJCQkgNDQt0KTQlzog0YHRhdC+0LTRgdGC0LLQ sCDQuDxicj4JCQnQvtGC0LvQuNGH0LjRjy4g0J/QtdGA0LXRgtC+0YDQttC60LA6INC/0YDQsNCy 0LjQu9CwINC/0YDQvtCy0LXQtNC10L3QuNGPINC4INGD0YfQsNGB0YLQuNGPLiDQl9Cw0LrRg9C/ 0LrQuCDRgyAJCQnQtdC00LjQvdGB0YLQstC10L3QvdC+0LPQviDQv9C+0YHRgtCw0LLRidC40LrQ sDxicj4o0L/QvtC00YDRj9C00YfQuNC60LAsINC40YHQv9C+0LvQvdC40YLQtdC70Y8pLiDQndC+ 0LLRi9C1INC+0LPRgNCw0L3QuNGH0LXQvdC40Y8g0Lgg0L7QsdGP0LfQsNC90L3QvtGB0YLQuCAJ CQnQt9Cw0LrQsNC30YfQuNC60L7QsiDQv9C+IDQ0LdCk0JcuPGJyPtCe0YHQvtCx0LXQvdC90L7R gdGC0Lgg0YPRh9Cw0YHRgtC40Y8g0LIg0L7RgtC00LXQu9GM0L3Ri9GFINCy0LjQtNCw0YUg0LfQ sNC60YPQv9C+0Lo6INC60L7QvdC60YPRgNC10L3RgtC90YvQtSAJCQnQv9C10YDQtdCz0L7QstC+ 0YDRiywg0YLQvtGA0LPQuCDQvdCwPGJyPgkJCdGB0YLQvtC40LzQvtGB0YLRjCDQtdC00LjQvdC4 0YbRiyDRgtC+0LLQsNGA0LAgKNGA0LDQsdC+0YLRiywg0YPRgdC70YPQs9C4KTsg0LDRg9C60YbQ uNC+0L0g0L3QsCDQv9C+0LLRi9GI0LXQvdC40LU7IAkJCSDRgNC10LTRg9C60YbQuNC+0L0sINC3 0LDQutGD0L/QutC4INGBPGJyPgkJCdC/0YDQtdGE0LXRgNC10L3RhtC40Y/QvNC4INC4INC/0YDQ tdC40LzRg9GJ0LXRgdGC0LLQsNC80LguINCf0YDQsNC60YLQuNGH0LXRgdC60LjQtSDRgNC10LrQ vtC80LXQvdC00LDRhtC40LggCQkJ0L/QvtGB0YLQsNCy0YnQuNC60LDQvDog0LrQsNC6PGJyPgkJ CdC80LjQvdC40LzQuNC30LjRgNC+0LLQsNGC0Ywg0YDQuNGB0Log0L7RgtC60LvQvtC90LXQvdC4 0Y8g0LfQsNGP0LLQutC4INC4INC/0L7QstGL0YHQuNGC0Ywg0LLQtdGA0L7Rj9GC0L3QvtGB0YLR jCDQv9C+0LHQtdC00YsgCQkJ0LIg0YLQtdC90LTQtdGA0LUuPGJyPjxiPjxmb250IGNvbG9yPSIj MDAwMGNjIiBzaXplPSI0Ij48YnI+My48L2ZvbnQ+0JTQvtCz0L7QstC+0YAgKNC60L7QvdGC0YDQ sNC60YIpOiAJCQkg0L/RgNCw0LLQsCwg0L7QsdGP0LfQsNC90L3QvtGB0YLQuCwg0L7RgtCy0LXR gtGB0YLQstC10L3QvdC+0YHRgtGMINC/0L7RgdGC0LDQstGJ0LjQutCwLiDQoNCw0YHRgtC+0YDQ ttC10L3QuNC1INCyPGJyPgkJCdC+0LTQvdC+0YHRgtC+0YDQvtC90L3QtdC8INC/0L7RgNGP0LTQ utC1LiA8L2I+PGJyPtCU0L7Qs9C+0LLQvtGAICjQutC+0L3RgtGA0LDQutGCKTog0YHRg9GJ0LXR gdGC0LLQtdC90L3Ri9C1INGD0YHQu9C+0LLQuNGPLCDQvdC+0LLRi9C1INGC0YDQtdCx0L7QstCw 0L3QuNGPLCDRgNC40YHQutC4IAkJCdC/0YDQuCDQt9Cw0LrQu9GO0YfQtdC90LjQuCDQuDxicj4J CQnQuNGB0L/QvtC70L3QtdC90LjQuC4g0KDQsNC30LzQtdGAINC4INGE0L7RgNC80Ysg0L7QsdC1 0YHQv9C10YfQtdC90LjRjyDQuNGB0L/QvtC70L3QtdC90LjRjy4g0JLQvtC30LzQvtC20L3QvtGB 0YLRjCAJCQnQt9Cw0LzQtdC90Ysg0L7QsdC10YHQv9C10YfQtdC90LjRjzxicj4JCQnQtNC+0LPQ vtCy0L7RgNCwICjQutC+0L3RgtGA0LDQutGC0LApLiDQodGA0L7QutC4INC00LXQudGB0YLQstC4 0Y8g0L7QsdC10YHQv9C10YfQtdC90LjRjyDQtNC+0LPQvtCy0L7RgNCwIAkJCSAo0LrQvtC90YLR gNCw0LrRgtCwKS4g0J/RgNC40LXQvNC+0YfQvdCw0Y88YnI+CQkJ0LrQvtC80LjRgdGB0LjRjyDQ t9Cw0LrQsNC30YfQuNC60LAuINCe0YLRh9C10YIg0L7QsSDQuNGB0L/QvtC70L3QtdC90LjQuCDQ utC+0L3RgtGA0LDQutGC0LAg0L/QviA0NC3QpNCXLiAJCQkg0K3QutGB0L/QtdGA0YLQuNC30LAg 0LjRgdC/0L7Qu9C90LXQvdC40Y88YnI+CQkJ0LrQvtC90YLRgNCw0LrRgtCwLiDQmNC30LzQtdC9 0LXQvdC40LUg0Lgg0YDQsNGB0YLQvtGA0LbQtdC90LjQtSDQtNC+0LPQvtCy0L7RgNCwICjQutC+ 0L3RgtGA0LDQutGC0LApLiDQntGB0L3QvtCy0LDQvdC40Y8g0LggCQkJ0L/QvtGA0Y/QtNC+0Log 0YDQsNGB0YLQvtGA0LbQtdC90LjRjzxicj4JCQnQsiDQvtC00L3QvtGB0YLQvtGA0L7QvdC90LXQ vCDQv9C+0YDRj9C00LrQtS4g0JTQvtC/0L7Qu9C90LjRgtC10LvRjNC90YvQtSDRgdC+0LPQu9Cw 0YjQtdC90LjRjyDQv9C+IDQ0LdCk0Jcg0LggCQkJIDIyMy3QpNCXLiDQmNC30LzQtdC90LXQvdC4 0LU8YnI+CQkJ0LrQvtC90YLRgNCw0LrRgtCwINC/0YDQuCDRgdC+0LrRgNCw0YnQtdC90LjQuCDQ u9C40LzQuNGC0L7QsiDQsdGO0LTQttC10YLQvdC+0LPQviDRhNC40L3QsNC90YHQuNGA0L7QstCw 0L3QuNGPIAkJCdC30LDQutCw0LfRh9C40LrQsC4g0J7RgtCy0LXRgtGB0YLQstC10L3QvdC+0YHR gtGMPGJyPgkJCdC30LAg0L3QtdC40YHQv9C+0LvQvdC10L3QuNC1INC4ICjQuNC70LgpINC90LXQ vdCw0LTQu9C10LbQsNGJ0LXQtSDQuNGB0L/QvtC70L3QtdC90LjQtSDQtNC+0LPQvtCy0L7RgNCw IAkJCSAo0LrQvtC90YLRgNCw0LrRgtCwKS4g0JfQsNC60L7QvdC90YvQtSDQuDxicj4JCQnQtNC+ 0LPQvtCy0L7RgNC90YvQtSDQvdC10YPRgdGC0L7QudC60LggKNC/0LXQvdC4INC4INGI0YLRgNCw 0YTRiykuINCS0YvQv9C+0LvQvdC10L3QuNC1INC/0YDQsNC60YLQuNGH0LXRgdC60L7Qs9C+IAkJ CdC30LDQtNCw0L3QuNGPICjQutC10LnRgdCwKTog0YDQsNGB0YfQtdGCPGJyPgkJCdC/0LXQvdC4 INC4INGI0YLRgNCw0YTQsCDQv9GA0Lgg0L3QsNGA0YPRiNC10L3QuNC4INC60L7QvdGC0YDQsNC6 0YLQsC4g0JHQuNCx0LvQuNC+0YLQtdC60LAg0YLQuNC/0L7QstGL0YUgCQkJ0LrQvtC90YLRgNCw 0LrRgtC+0LIsINGC0LjQv9C+0LLRi9GFINGD0YHQu9C+0LLQuNC5PGJyPgkJCdC60L7QvdGC0YDQ sNC60YLQvtCyLiDQmtCw0Log0L3QtSDQv9C+0L/QsNGB0YLRjCDQsiDQoNCd0J86INC/0YDQsNC6 0YLQuNGH0LXRgdC60LjQtSDRgNC10LrQvtC80LXQvdC00LDRhtC40LguPGJyPjxiPjxmb250IGNv bG9yPSIjMDAwMGNjIiBzaXplPSI0Ij48YnI+NC48L2ZvbnQ+0JrQvtC90YLRgNC+0LvRjCDQuCDQ vdCw0LTQt9C+0YAg0LIg0YHRhNC10YDQtSAJCQnQt9Cw0LrRg9C/0L7Qui4g0J/RgNCw0LrRgtC4 0LrQsCDQpNCQ0KEuINCe0LHQttCw0LvQvtCy0LDQvdC40LUg0LTQtdC50YHRgtCy0LjQuSDQt9Cw 0LrQsNC30YfQuNC60LAsPGJyPtC60L7QvNC40YHRgdC40LguPC9iPjxicj7QoNC10LXRgdGC0YAg 0L3QtdC00L7QsdGA0L7RgdC+0LLQtdGB0YLQvdGL0YUg0L/QvtGB0YLQsNCy0YnQuNC60L7Qsi4g 0J/QvtGA0Y/QtNC+0Log0LLQvdC10YHQtdC90LjRjyDQuNC90YTQvtGA0LzQsNGG0LjQuC4gCQkJ INCf0YDQsNC60YLQuNC60LAg0LrQvtC90YLRgNC+0LvRjzxicj4JCQnRhtC10L3RgtGA0LDQu9GM 0L3QvtCz0L4g0LDQv9C/0LDRgNCw0YLQsCDQuCDRgtC10YDRgNC40YLQvtGA0LjQsNC70YzQvdGL 0YUg0L7RgNCz0LDQvdC+0LIg0KTQkNChINCg0L7RgdGB0LjQuC4g0KDQvtC70Ywg0LggCQkJ0L/Q vtC70L3QvtC80L7Rh9C40Y8g0KTQkNChINC/0L48YnI+CQkJ0KTQly00NCDQuCDQpNCXLTIyMy4g 0J/QvtGA0Y/QtNC+0Log0L7QsdC20LDQu9C+0LLQsNC90LjRjyDQtNC10LnRgdGC0LLQuNC5INCX 0LDQutCw0LfRh9C40LrQsCwg0YfQu9C10L3QvtCyIAkJCdC60L7QvNC40YHRgdC40Lgg0L/Qvjxi cj4JCQnQvtGB0YPRidC10YHRgtCy0LvQtdC90LjRjiDQt9Cw0LrRg9C/0L7Quiwg0LrQvtC90YLR gNCw0LrRgtC90L7Qs9C+INGD0L/RgNCw0LLQu9GP0Y7RidC10LPQviwg0LTQvtC70LbQvdC+0YHR gtC90YvRhSDQu9C40YYgCQkJ0LrQvtC90YLRgNCw0LrRgtC90L7QuSDRgdC70YPQttCx0YssPGJy PtC+0L/QtdGA0LDRgtC+0YDQsCDRjdC70LXQutGC0YDQvtC90L3QvtC5INC/0LvQvtGJ0LDQtNC6 0LguINCi0LjQv9C40YfQvdGL0LUg0L/RgNC40LzQtdGA0Ysg0L3QsNGA0YPRiNC10L3QuNC5INC/ 0YDQsNCyIAkJCdC/0L7RgdGC0LDQstGJ0LjQutC+0LIuINCf0YDQsNCy0LjQu9CwPGJyPgkJCdC/ 0L7QtNCw0YfQuCDQuCDQvtGE0L7RgNC80LvQtdC90LjRjyDQttCw0LvQvtCx0YsuINCf0L7RgdC7 0LXQtNGB0YLQstC40Y8g0L/RgNC40LfQvdCw0L3QuNGPINC20LDQu9C+0LHRiyAJCQnQvtCx0L7R gdC90L7QstCw0L3QvdC+0LkuPGJyPjxicj4gwqA8L3RkPjx0ZD7CoDwvdGQ+PHRkIGJnY29sb3I9 IiNlMGRiZDgiPsKgPC90ZD48dGQgYmdjb2xvcj0iI2NmYzZjMCI+wqA8L3RkPjx0ZCBiZ2NvbG9y PSIjYmZiMWFhIj7CoDwvdGQ+PC90cj48dHI+PHRkIGJnY29sb3I9IiNiZmIxYWEiPsKgPC90ZD48 dGQgYmdjb2xvcj0iI2VlZWFlOCI+wqA8L3RkPjx0ZD7CoDwvdGQ+PHRkIGJnY29sb3I9IiNlZWVh ZTgiPjxwIGFsaWduPSJjZW50ZXIiPtCj0YfQsNGB0YLQuNC1OiAyMjxzcGFuIGxhbmc9ImVuLXVz Ij5gPC9zcGFuPiA4MDAg0YDRg9CxLjxicj7Qn9C+INC+0LrQvtC90YfQsNC90LjRjiDQt9Cw0L3R j9GC0LjQuSDQktCw0Lwg0LLRi9C00LDQtdGC0YHRjyDRgdC10YDRgtC40YTQuNC60LDRgi48YnI+ 0JLRhdC+0LTQuNGCINC80LXRgtC+0LTQuNGH0LXRgdC60LjQuSDQvNCw0YLQtdGA0LjQsNC7LCDQ vtCx0LXQtNGLLCDQutC+0YTQtS3Qv9Cw0YPQt9GLLjxicj4gwqA8L3A+PC90ZD48dGQ+wqA8L3Rk Pjx0ZCBiZ2NvbG9yPSIjZTBkYmQ4Ij7CoDwvdGQ+PHRkIGJnY29sb3I9IiNjZmM2YzAiPsKgPC90 ZD48dGQgYmdjb2xvcj0iI2JmYjFhYSI+wqA8L3RkPjwvdHI+PHRyPjx0ZCBiZ2NvbG9yPSIjYmZi MWFhIj7CoDwvdGQ+PHRkIGJnY29sb3I9IiNlZWVhZTgiPsKgPC90ZD48dGQ+wqA8L3RkPjx0ZCBi Z2NvbG9yPSIjZWVlYWU4Ij7CoDwvdGQ+PHRkPsKgPC90ZD48dGQgYmdjb2xvcj0iI2UwZGJkOCI+ wqA8L3RkPjx0ZCBiZ2NvbG9yPSIjY2ZjNmMwIj7CoDwvdGQ+PHRkIGJnY29sb3I9IiNiZmIxYWEi PsKgPC90ZD48L3RyPjwvdGJvZHk+PC90YWJsZT48L2Rpdj48L2Rpdj4NCg== ------------61B07C5EF5E261EA2-- From darrick.wong@oracle.com Tue Nov 17 21:02:24 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 345567F37 for ; Tue, 17 Nov 2015 21:02:24 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id B791DAC005 for ; Tue, 17 Nov 2015 19:02:20 -0800 (PST) X-ASG-Debug-ID: 1447815735-04cb6c0cd4cd840001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id npWPCJPgZSGU3s1o (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 17 Nov 2015 19:02:15 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tAI31IaF001701 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 18 Nov 2015 03:01:19 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id tAI31Idi016621 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 18 Nov 2015 03:01:18 GMT Received: from abhmp0011.oracle.com (abhmp0011.oracle.com [141.146.116.17]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id tAI31Ixq006821; Wed, 18 Nov 2015 03:01:18 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 17 Nov 2015 19:01:18 -0800 Date: Tue, 17 Nov 2015 19:01:17 -0800 From: "Darrick J. Wong" To: Christoph Hellwig Cc: Chris Mason , xfs@oss.sgi.com, linux-fsdevel@vger.kernel.org Subject: Re: clone ioctl return values Message-ID: <20151118030117.GA26143@birch.djwong.org> X-ASG-Orig-Subj: Re: clone ioctl return values References: <20151116120431.GA2860@infradead.org> <20151117002822.GA32467@birch.djwong.org> <20151117105433.GA18093@infradead.org> <20151117135745.GF17545@ret.masoncoding.com> <20151117152251.GA5392@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151117152251.GA5392@infradead.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1447815735 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24496 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines On Tue, Nov 17, 2015 at 07:22:52AM -0800, Christoph Hellwig wrote: > On Tue, Nov 17, 2015 at 08:57:45AM -0500, Chris Mason wrote: > > > > Errrgh, the golden output of this test reflects the changes to the input > > > > checking in Anna/Peng's copy_file_range/clone_file_range patches. > > > > > > > > So, I guess the question is, should I reset the golden output to whatever > > > > btrfs spits out before that patchset, and we'll consider the alterations > > > > to be bugs/regressions/whatever that ought to be fixed in their patches? > > > > > > Some bits in btrfs don't seem kosher. But it would be good to > > > explicitly send patches for btrfs to adopt to what might make more > > > sense, and then follow it in the other implementations. > > > > Btrfs does check for directories, but we should really be checking for > > regular files too. In the end, we only copy extents that would > > correspond with regular files, so we're sneaking by. > > Yes, I saw that. So so far I'd suggest something like the following > for btrfs: > > - return EBADFD for missing read/wite permissions Current btrfs returns EINVAL if the file isn't open for writing or is append-only. I think EBADF captures the situation here better and it's what Anna is pushing for copy_file_range. We can make the change, but generic/157 will fail on old kernels if we do this. I don't have a problem with 157 failing on old kernels; we can backport the change to them, or note that ioctls are murky anyway. > - return EINVAL for wrong non-directory file types as the > source fd > And then make the test case and other implementations match this. > > Does this sound like a plan? Yes. One other thing I noticed -- prior to Anna's patchset, trying to invoke the reflink ioctl with a device, pipe, or socket as the destination could return a variety of error codes (-ENOTTY, -EINVAL, -ENOIOCTLCMD, etc.) which has all been replaced with -EOPNOTSUPP. That seems like a reasonable direction to take the test case. Does this seem like a reasonable addition to the plan? Should invalid inputs to the dedupe ioctl return the same error codes as the same invalid inputs to the reflink ioctl? I've been working on patches to hoist EXTENT_SAME to the VFS. --D > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From obsrctvzjinm@qualitynet.net Tue Nov 17 21:42:30 2015 Return-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.1 required=5.0 tests=FROM_LOCAL_NOVOWEL, HK_RANDOM_ENVFROM,HK_RANDOM_FROM,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 7C4CF7F37 for ; Tue, 17 Nov 2015 21:42:30 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id BE858AC003 for ; Tue, 17 Nov 2015 19:42:29 -0800 (PST) X-ASG-Debug-ID: 1447818142-04cbb0605bf2ee0001-NocioJ Received: from smtp2.qualitynet.net (simcloud.local [45.55.156.109]) by cuda.sgi.com with ESMTP id xEzzjAWwCqD3dLBz for ; Tue, 17 Nov 2015 19:42:24 -0800 (PST) X-Barracuda-Envelope-From: obsrctvzjinm@qualitynet.net X-Barracuda-Apparent-Source-IP: 45.55.156.109 Message-ID: From: "=?utf-8?B?0JPQvtGB0LfQsNC60YPQv9C60Lg=?=" To: Subject: =?utf-8?B?NDQt0KTQlyDQmtC+0L3RgtGA0LDQutGC0L3QsNGPINGB0LjRgdGC0LXQvNCwINCyINGB0YTQtdGA0LUg0LfQsNC60YPQv9C+0Log0YLQvtCy0LDRgNC+0LIsINGA0LDQsdC+0YI=?= Date: Wed, 18 Nov 2015 06:42:20 +0300 X-ASG-Orig-Subj: =?utf-8?B?NDQt0KTQlyDQmtC+0L3RgtGA0LDQutGC0L3QsNGPINGB0LjRgdGC0LXQvNCwINCyINGB0YTQtdGA0LUg0LfQsNC60YPQv9C+0Log0YLQvtCy0LDRgNC+0LIsINGA0LDQsdC+0YI=?= MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="----=_NextPart_000_00A4_01D121CC.4601C0A0" X-Priority: 3 X-MSMail-Priority: Normal Importance: Normal X-Mailer: Microsoft Windows Live Mail 15.4.3538.513 X-MimeOLE: Produced By Microsoft MimeOLE V15.4.3538.513 X-Barracuda-Connect: simcloud.local[45.55.156.109] X-Barracuda-Start-Time: 1447818142 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 2.53 X-Barracuda-Spam-Status: No, SCORE=2.53 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=FROM_LOCAL_NOVOWEL, HTML_MESSAGE, K2_FROM_LOCAL_NOVOWEL X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24496 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 HTML_MESSAGE BODY: HTML included in message 0.20 FROM_LOCAL_NOVOWEL From: localpart has series of non-vowel letters 2.33 K2_FROM_LOCAL_NOVOWEL From: localpart has series of non-vowel letters Ýòî — ñîîáùåíèå èç íåñêîëüêèõ ÷àñòåé â ôîðìàòå MIME. ------=_NextPart_000_00A4_01D121CC.4601C0A0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable =20 =20 =D0=9D=D0=90=D0=A3=D0=A7=D0=98=D0=A2=D0=95=D0=A1=D0=AC = =D0=93=D0=9E=D0=A1=D0=97=D0=90=D0=9A=D0=A3=D0=9F=D0=9A=D0=90=D0=9C = =D0=9F=D0=9E 44-=D0=A4=D0=97! =D0=9E=D0=91=D0=A3=D0=A7=D0=90=D0=99=D0=A2=D0=95=D0=A1=D0=AC = =D0=92 =D0=A3=D0=94=D0=9E=D0=91=D0=9D=D0=9E=D0=95 =D0=94=D0=9B=D0=AF = =D0=92=D0=90=D0=A1 =D0=92=D0=A0=D0=95=D0=9C=D0=AF =D0=98 =D0=92 = =D0=A3=D0=94=D0=9E=D0=91=D0=9D=D0=9E=D0=9C = =D0=9C=D0=95=D0=A1=D0=A2=D0=95! =D0=9F=D1=80=D0=BE=D0=B9=D0=B4=D0=B8=D1=82=D0=B5 = =D0=B4=D0=B8=D1=81=D1=82=D0=B0=D0=BD=D1=86=D0=B8=D0=BE=D0=BD=D0=BD=D0=BE=D0= =B5 =D0=BF=D0=BE=D0=B2=D1=8B=D1=88=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=BA=D0=B2=D0=B0=D0=BB=D0=B8=D1=84=D0=B8=D0=BA=D0=B0=D1=86=D0=B8=D0=B8 = =D0=BF=D0=BE =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BA=D0=B0=D0=BC =D0=B2 = =D0=B0=D0=BA=D0=BA=D1=80=D0=B5=D0=B4=D0=B8=D1=82=D0=BE=D0=B2=D0=B0=D0=BD=D0= =BD=D0=BE=D0=BC =D0=A3=D1=87=D0=B5=D0=B1=D0=BD=D0=BE=D0=BC =D1=86=D0=B5=D0=BD=D1=82=D1=80=D0=B5 =D0=BF=D0=BE = =D0=B0=D0=B2=D1=82=D0=BE=D1=80=D1=81=D0=BA=D0=BE=D0=B9 = =D0=BF=D1=80=D0=BE=D0=B3=D1=80=D0=B0=D0=BC=D0=BC=D0=B5 =D0=B8 = =D0=BF=D0=BE=D0=BB=D1=83=D1=87=D0=B8=D1=82=D0=B5 = =D0=BA=D0=B0=D1=87=D0=B5=D1=81=D1=82=D0=B2=D0=B5=D0=BD=D0=BD=D0=BE=D0=B5 = =D0=BE=D0=B1=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D0=B5 =D1=81 = =D0=B2=D1=8B=D0=B4=D0=B0=D1=87=D0=B5=D0=B9 = =D1=83=D0=B4=D0=BE=D1=81=D1=82=D0=BE=D0=B2=D0=B5=D1=80=D0=B5=D0=BD=D0=B8=D1= =8F = =D1=83=D1=81=D1=82=D0=B0=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=D0=BD=D0=BE=D0= =B3=D0=BE =D0=BE=D0=B1=D1=80=D0=B0=D0=B7=D1=86=D0=B0. =D0=94=D0=B0=D1=82=D1=8B = =D0=BE=D0=B1=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D1=8F = =D0=B1=D0=BB=D0=B8=D0=B6=D0=B0=D0=B9=D1=88=D0=B8=D1=85 = =D0=B3=D1=80=D1=83=D0=BF=D0=BF: =D1=81 30 = =D0=BD=D0=BE=D1=8F=D0=B1=D1=80=D1=8F =D0=BF=D0=BE 18 = =D0=B4=D0=B5=D0=BA=D0=B0=D0=B1=D1=80=D1=8F = _________________________________________________________________________= ___________ =D0=A3=D0=9F=D0=A0=D0=90=D0=92=D0=9B=D0=95=D0=9D=D0=98=D0=95 = =D0=93=D0=9E=D0=A1=D0=A3=D0=94=D0=90=D0=A0=D0=A1=D0=A2=D0=92=D0=95=D0=9D=D0= =9D=D0=AB=D0=9C=D0=98 =D0=98 = =D0=9C=D0=A3=D0=9D=D0=98=D0=A6=D0=98=D0=9F=D0=90=D0=9B=D0=AC=D0=9D=D0=AB=D0= =9C=D0=98 =D0=97=D0=90=D0=9A=D0=A3=D0=9F=D0=9A=D0=90=D0=9C=D0=98 = (=D0=9A=D0=9E=D0=9D=D0=A2=D0=A0=D0=90=D0=9A=D0=A2=D0=9D=D0=90=D0=AF = =D0=A1=D0=98=D0=A1=D0=A2=D0=95=D0=9C=D0=90 =D0=92 = =D0=A1=D0=A4=D0=95=D0=A0=D0=95 = =D0=97=D0=90=D0=9A=D0=A3=D0=9F=D0=9E=D0=9A = =D0=A2=D0=9E=D0=92=D0=90=D0=A0=D0=9E=D0=92, = =D0=A0=D0=90=D0=91=D0=9E=D0=A2, =D0=A3=D0=A1=D0=9B=D0=A3=D0=93) =D0=92 = =D0=A1=D0=9E=D0=9E=D0=A2=D0=92=D0=95=D0=A2=D0=A1=D0=A2=D0=92=D0=98=D0=98 = =D0=A1 = =D0=A4=D0=95=D0=94=D0=95=D0=A0=D0=90=D0=9B=D0=AC=D0=9D=D0=AB=D0=9C = =D0=97=D0=90=D0=9A=D0=9E=D0=9D=D0=9E=D0=9C =E2=84=96 44-=D0=A4=D0=97 = =D0=9E=D0=A2 05.04.2013. =D0=A1=D1=80=D0=BE=D0=BA = =D0=BE=D0=B1=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D1=8F - 3 = =D0=BD=D0=B5=D0=B4=D0=B5=D0=BB=D0=B8.=20 = =D0=9F=D1=80=D0=BE=D0=B4=D0=BE=D0=BB=D0=B6=D0=B8=D1=82=D0=B5=D0=BB=D1=8C=D0= =BD=D0=BE=D1=81=D1=82=D1=8C =D0=BA=D1=83=D1=80=D1=81=D0=B0 144 = =D1=87=D0=B0=D1=81=D0=B0. =D0=A1=D1=83=D0=BC=D0=BC=D0=B0 = =D1=83=D0=BA=D0=B0=D0=B7=D0=B0=D0=BD=D0=B0 =D0=B7=D0=B0 = =D0=B2=D0=B5=D1=81=D1=8C =D0=BA=D1=83=D1=80=D1=81 = =D0=B7=D0=B0=D0=BD=D1=8F=D1=82=D0=B8=D0=B9 - 17' 000 =D1=80=D1=83=D0=B1. =D0=9F=D0=BE=D0=BB=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=B4=D0=BE=D0=BA=D1=83=D0=BC=D0=B5=D0=BD=D1=82=D0=BE=D0=B2: = =D0=BB=D0=B8=D1=87=D0=BD=D0=BE =D0=B8=D0=BB=D0=B8 = =D0=BF=D0=BE=D1=87=D1=82=D0=BE=D0=B2=D1=8B=D0=BC = =D0=BE=D1=82=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=D0=BC = =D0=BD=D0=B0 =D0=92=D0=B0=D1=88 =D0=B2=D1=8B=D0=B1=D0=BE=D1=80. =D0=92=D1=81=D1=8F = =D0=B8=D0=BD=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=86=D0=B8=D1=8F = =D0=BF=D0=BE =D0=B4=D0=B0=D0=BD=D0=BD=D0=BE=D0=BC=D1=83 = =D0=BE=D0=B1=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D1=8E =D0=B8 = =D0=B7=D0=B0=D1=8F=D0=B2=D0=BA=D0=B8 =D0=BD=D0=B0 = =D1=83=D1=87=D0=B0=D1=81=D1=82=D0=B8=D0=B5 = =D0=BF=D1=80=D0=B8=D0=BD=D0=B8=D0=BC=D0=B0=D1=8E=D1=82=D1=81=D1=8F = =D0=BF=D0=BE =D1=82=D0=B5=D0=BB=D0=B5=D1=84=D0=BE=D0=BD=D1=83:=20 8 =D0=BA=D0=BE=D0=B4 =D0=B3=D0=BE=D1=80=D0=BE=D0=B4=D0=B0 = =D0=9C=D0=BE=D1=81=D0=BA=D0=B2=D1=8B ( 4 9 5 ) =D1=82=D0=B5=D0=BB.: = 411-9=D0=9E-98 = (=D0=BC=D0=BD=D0=BE=D0=B3=D0=BE=D0=BA=D0=B0=D0=BD=D0=B0=D0=BB=D1=8C=D0=BD= =D1=8B=D0=B9) = _________________________________________________________________________= __________ = =D0=94=D0=B8=D1=81=D1=82=D0=B0=D0=BD=D1=86=D0=B8=D0=BE=D0=BD=D0=BD=D0=B0=D1= =8F =D1=84=D0=BE=D1=80=D0=BC=D0=B0 = =D0=BE=D0=B1=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D1=8F = =D0=BF=D0=BE=D0=B7=D0=B2=D0=BE=D0=BB=D1=8F=D0=B5=D1=82 = =D0=BB=D1=8E=D0=B1=D0=BE=D0=BC=D1=83 = =D1=81=D0=BB=D1=83=D1=88=D0=B0=D1=82=D0=B5=D0=BB=D1=8E = =D0=B1=D0=B5=D0=B7 =D0=BE=D1=82=D1=80=D1=8B=D0=B2=D0=B0 =D0=BE=D1=82 = =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=8B, =D0=B1=D0=B5=D0=B7 =D1=84=D0=B8=D0=BD=D0=B0=D0=BD=D1=81=D0=BE=D0=B2=D1=8B=D1=85 = =D0=B8 =D0=B2=D1=80=D0=B5=D0=BC=D0=B5=D0=BD=D0=BD=D1=8B=D1=85 = =D0=B7=D0=B0=D1=82=D1=80=D0=B0=D1=82 =D0=BD=D0=B0 = =D0=BA=D0=BE=D0=BC=D0=B0=D0=BD=D0=B4=D0=B8=D1=80=D0=BE=D0=B2=D0=BA=D0=B8 = =D0=BF=D0=BE=D0=BB=D1=83=D1=87=D0=B8=D1=82=D1=8C = =D0=BF=D0=BE=D0=BB=D0=BD=D1=8B=D0=B9 =D0=BE=D0=B1=D1=8A=D0=B5=D0=BC = =D0=B7=D0=BD=D0=B0=D0=BD=D0=B8=D0=B9 =D0=BF=D0=BE = =D1=82=D0=B5=D0=BC=D0=B5 =D0=BE=D0=B1=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D1=8F =D0=B8 = =D0=B4=D0=BE=D0=BA=D1=83=D0=BC=D0=B5=D0=BD=D1=82 =D0=BE = =D0=BF=D0=BE=D0=B2=D1=8B=D1=88=D0=B5=D0=BD=D0=B8=D0=B8 = =D0=BA=D0=B2=D0=B0=D0=BB=D0=B8=D1=84=D0=B8=D0=BA=D0=B0=D1=86=D0=B8=D0=B8.= =D0=94=D0=BE=D1=81=D1=82=D0=B0=D1=82=D0=BE=D1=87=D0=BD=D0=BE = =D0=BD=D0=B0=D0=BB=D0=B8=D1=87=D0=B8=D1=8F = =D0=BA=D0=BE=D0=BC=D0=BF=D1=8C=D1=8E=D1=82=D0=B5=D1=80=D0=B0 =D1=81 = =D0=B4=D0=BE=D1=81=D1=82=D1=83=D0=BF=D0=BE=D0=BC =D0=B2 =D0=98=D0=BD=D1=82=D0=B5=D1=80=D0=BD=D0=B5=D1=82, = =D0=B1=D0=B5=D0=B7 = =D0=B4=D0=BE=D0=BF=D0=BE=D0=BB=D0=BD=D0=B8=D1=82=D0=B5=D0=BB=D1=8C=D0=BD=D1= =8B=D1=85 =D0=BF=D1=80=D0=BE=D0=B3=D1=80=D0=B0=D0=BC=D0=BC =D0=B8 = =D0=BD=D0=B0=D1=81=D1=82=D1=80=D0=BE=D0=B5=D0=BA. = =D0=9E=D0=B1=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=B2=D0=BE=D0=B7=D0=BC=D0=BE=D0=B6=D0=BD=D0=BE, = =D0=BD=D0=B0=D1=85=D0=BE=D0=B4=D1=8F=D1=81=D1=8C =D0=B2 = =D0=BB=D1=8E=D0=B1=D0=BE=D0=BC =D1=80=D0=B5=D0=B3=D0=B8=D0=BE=D0=BD=D0=B5 = =D0=A0=D0=BE=D1=81=D1=81=D0=B8=D0=B8! =D0=9F=D0=BE =D0=B8=D1=82=D0=BE=D0=B3=D0=B0=D0=BC = =D0=BE=D0=B1=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D1=8F = =D1=81=D0=BB=D1=83=D1=88=D0=B0=D1=82=D0=B5=D0=BB=D0=B8 = =D0=BF=D0=BE=D0=BB=D1=83=D1=87=D0=B0=D1=8E=D1=82 = =D0=A3=D0=B4=D0=BE=D1=81=D1=82=D0=BE=D0=B2=D0=B5=D1=80=D0=B5=D0=BD=D0=B8=D0= =B5 =D0=BE =D0=BF=D0=BE=D0=B2=D1=8B=D1=88=D0=B5=D0=BD=D0=B8=D0=B8 = =D0=BA=D0=B2=D0=B0=D0=BB=D0=B8=D1=84=D0=B8=D0=BA=D0=B0=D1=86=D0=B8=D0=B8.= = =D0=A3=D0=B4=D0=BE=D1=81=D1=82=D0=BE=D0=B2=D0=B5=D1=80=D0=B5=D0=BD=D0=B8=D0= =B5 =D0=B4=D0=B0=D0=B5=D1=82 = =D1=81=D0=BF=D0=B5=D1=86=D0=B8=D0=B0=D0=BB=D0=B8=D1=81=D1=82=D0=B0=D0=BC = =D0=BF=D1=80=D0=B0=D0=B2=D0=BE =D0=B1=D1=8B=D1=82=D1=8C = =D1=87=D0=BB=D0=B5=D0=BD=D0=BE=D0=BC =D0=B8=D0=BB=D0=B8 = =D0=BF=D1=80=D0=B5=D0=B4=D1=81=D0=B5=D0=B4=D0=B0=D1=82=D0=B5=D0=BB=D0=B5=D0= =BC =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BE=D1=87=D0=BD=D1=8B=D1=85 = =D0=BA=D0=BE=D0=BC=D0=B8=D1=81=D1=81=D0=B8=D0=B9, =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BD=D0=B8=D0=BA=D0=BE=D0=BC = =D0=B8=D0=BB=D0=B8 = =D1=80=D1=83=D0=BA=D0=BE=D0=B2=D0=BE=D0=B4=D0=B8=D1=82=D0=B5=D0=BB=D0=B5=D0= =BC =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=B0=D0=BA=D1=82=D0=BD=D0=BE=D0=B9 = =D1=81=D0=BB=D1=83=D0=B6=D0=B1=D1=8B, = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=B0=D0=BA=D1=82=D0=BD=D1=8B=D0=BC = =D1=83=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D1=8F=D1=8E=D1=89=D0=B8=D0=BC. =20 =20 =D0=9F=D1=80=D0=BE=D0=B3=D1=80=D0=B0=D0=BC=D0=BC=D0=B0: =20 =D0=9C=D0=BE=D0=B4=D1=83=D0=BB=D1=8C 1. = =D0=9E=D1=81=D0=BD=D0=BE=D0=B2=D1=8B = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=B0=D0=BA=D1=82=D0=BD=D0=BE=D0=B9 = =D1=81=D0=B8=D1=81=D1=82=D0=B5=D0=BC=D1=8B. = =D0=97=D0=B0=D0=BA=D0=BE=D0=BD=D0=BE=D0=B4=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=D1= =81=D1=82=D0=B2=D0=BE =D0=A0=D0=A4 =D0=BE = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=B0=D0=BA=D1=82=D0=BD=D0=BE=D0=B9 = =D1=81=D0=B8=D1=81=D1=82=D0=B5=D0=BC=D0=B5. =D0=9C=D0=BE=D0=B4=D1=83=D0=BB=D1=8C 2. = =D0=98=D0=BD=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=86=D0=B8=D0=BE=D0=BD=D0=BD=D0= =BE=D0=B5 = =D0=BE=D0=B1=D0=B5=D1=81=D0=BF=D0=B5=D1=87=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=B0=D0=BA=D1=82=D0=BD=D0=BE=D0=B9 = =D1=81=D0=B8=D1=81=D1=82=D0=B5=D0=BC=D1=8B. =D0=9C=D0=BE=D0=B4=D1=83=D0=BB=D1=8C 3. = =D0=9F=D0=BB=D0=B0=D0=BD=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5 = =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BE=D0=BA =D0=B2 = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=B0=D0=BA=D1=82=D0=BD=D0=BE=D0=B9 = =D1=81=D0=B8=D1=81=D1=82=D0=B5=D0=BC=D0=B5. =D0=9C=D0=BE=D0=B4=D1=83=D0=BB=D1=8C 4. = =D0=9E=D0=B1=D1=89=D0=B8=D0=B5 = =D1=82=D1=80=D0=B5=D0=B1=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F =D0=BA = =D0=BE=D1=81=D1=83=D1=89=D0=B5=D1=81=D1=82=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D1= =8E =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BE=D0=BA =D0=B2 = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=B0=D0=BA=D1=82=D0=BD=D0=BE=D0=B9 = =D1=81=D0=B8=D1=81=D1=82=D0=B5=D0=BC=D0=B5. =D0=9C=D0=BE=D0=B4=D1=83=D0=BB=D1=8C 5. = =D0=9E=D0=BF=D1=80=D0=B5=D0=B4=D0=B5=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=BF=D0=BE=D1=81=D1=82=D0=B0=D0=B2=D1=89=D0=B8=D0=BA=D0=B0 = (=D0=BF=D0=BE=D0=B4=D1=80=D1=8F=D0=B4=D1=87=D0=B8=D0=BA=D0=B0, = =D0=B8=D1=81=D0=BF=D0=BE=D0=BB=D0=BD=D0=B8=D1=82=D0=B5=D0=BB=D1=8F) = =D0=BF=D1=83=D1=82=D0=B5=D0=BC = =D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D0=B4=D0=B5=D0=BD=D0=B8=D1=8F = =D0=BA=D0=BE=D0=BD=D0=BA=D1=83=D1=80=D1=81=D0=B0. =D0=9C=D0=BE=D0=B4=D1=83=D0=BB=D1=8C 6. = =D0=AD=D0=BB=D0=B5=D0=BA=D1=82=D1=80=D0=BE=D0=BD=D0=BD=D1=8B=D0=B9 = =D0=B0=D1=83=D0=BA=D1=86=D0=B8=D0=BE=D0=BD. =D0=9C=D0=BE=D0=B4=D1=83=D0=BB=D1=8C 7. = =D0=97=D0=B0=D0=BF=D1=80=D0=BE=D1=81 = =D0=BA=D0=BE=D1=82=D0=B8=D1=80=D0=BE=D0=B2=D0=BE=D0=BA. =D0=9C=D0=BE=D0=B4=D1=83=D0=BB=D1=8C 8. = =D0=97=D0=B0=D0=BF=D1=80=D0=BE=D1=81 = =D0=BF=D1=80=D0=B5=D0=B4=D0=BB=D0=BE=D0=B6=D0=B5=D0=BD=D0=B8=D0=B9. =D0=9C=D0=BE=D0=B4=D1=83=D0=BB=D1=8C 9. = =D0=97=D0=B0=D0=BA=D1=83=D0=BF=D0=BA=D0=B8 =D1=83 = =D0=B5=D0=B4=D0=B8=D0=BD=D1=81=D1=82=D0=B2=D0=B5=D0=BD=D0=BD=D0=BE=D0=B3=D0= =BE =D0=BF=D0=BE=D1=81=D1=82=D0=B0=D0=B2=D1=89=D0=B8=D0=BA=D0=B0 = (=D0=BF=D0=BE=D0=B4=D1=80=D1=8F=D0=B4=D1=87=D0=B8=D0=BA=D0=B0, = =D0=B8=D1=81=D0=BF=D0=BE=D0=BB=D0=BD=D0=B8=D1=82=D0=B5=D0=BB=D1=8F). =D0=9C=D0=BE=D0=B4=D1=83=D0=BB=D1=8C 10. = =D0=9E=D1=81=D0=BE=D0=B1=D0=B5=D0=BD=D0=BD=D0=BE=D1=81=D1=82=D0=B8 = =D0=BE=D1=82=D0=B4=D0=B5=D0=BB=D1=8C=D0=BD=D1=8B=D1=85 = =D0=B2=D0=B8=D0=B4=D0=BE=D0=B2 = =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BE=D0=BA. =D0=9C=D0=BE=D0=B4=D1=83=D0=BB=D1=8C 11. = =D0=93=D0=BE=D1=81=D1=83=D0=B4=D0=B0=D1=80=D1=81=D1=82=D0=B2=D0=B5=D0=BD=D0= =BD=D1=8B=D0=B9 =D0=B8 = =D0=BC=D1=83=D0=BD=D0=B8=D1=86=D0=B8=D0=BF=D0=B0=D0=BB=D1=8C=D0=BD=D1=8B=D0= =B9 =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=B0=D0=BA=D1=82. =D0=9C=D0=BE=D0=B4=D1=83=D0=BB=D1=8C 12. = =D0=9A=D0=BE=D0=BD=D1=82=D1=80=D0=BE=D0=BB=D1=8C, = =D0=BC=D0=BE=D0=BD=D0=B8=D1=82=D0=BE=D1=80=D0=B8=D0=BD=D0=B3 =D0=B8 = =D0=B0=D1=83=D0=B4=D0=B8=D1=82 =D0=B2 =D1=81=D1=84=D0=B5=D1=80=D0=B5 = =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BE=D0=BA. = =D0=9E=D0=B1=D0=B6=D0=B0=D0=BB=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5. = =D0=90=D0=B4=D0=BC=D0=B8=D0=BD=D0=B8=D1=81=D1=82=D1=80=D0=B0=D1=82=D0=B8=D0= =B2=D0=BD=D0=B0=D1=8F = =D0=BF=D1=80=D0=B0=D0=BA=D1=82=D0=B8=D0=BA=D0=B0 =D0=A4=D0=90=D0=A1. = =D0=9E=D1=82=D0=B2=D0=B5=D1=82=D1=81=D1=82=D0=B2=D0=B5=D0=BD=D0=BD=D0=BE=D1= =81=D1=82=D1=8C =D0=BF=D0=BE =D0=9A=D0=BE=D0=90=D0=9F. =20 =20 = =D0=9F=D1=80=D0=B5=D0=B8=D0=BC=D1=83=D1=89=D0=B5=D1=81=D1=82=D0=B2=D0=B0:= * = =D0=95=D0=B6=D0=B5=D0=BC=D0=B5=D1=81=D1=8F=D1=87=D0=BD=D0=B0=D1=8F = =D0=B0=D0=BA=D1=82=D1=83=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D1=8F = =D0=B8=D0=B7=D1=83=D1=87=D0=B0=D0=B5=D0=BC=D0=BE=D0=B3=D0=BE = =D0=BC=D0=B0=D1=82=D0=B5=D1=80=D0=B8=D0=B0=D0=BB=D0=B0 =D0=BF=D0=BE = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=B0=D0=BA=D1=82=D0=BD=D0=BE=D0=B9 = =D1=81=D0=B8=D1=81=D1=82=D0=B5=D0=BC=D0=B5. * =D0=9D=D0=B0=D0=B3=D0=BB=D1=8F=D0=B4=D0=BD=D0=BE=D0=B5 =D0=B8 = =D0=B4=D0=BE=D1=81=D1=82=D1=83=D0=BF=D0=BD=D0=BE=D0=B5 = =D0=BF=D1=80=D0=B5=D0=B4=D1=81=D1=82=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0= =B5 =D0=B8=D0=B7=D1=83=D1=87=D0=B0=D0=B5=D0=BC=D0=BE=D0=B3=D0=BE = =D0=BC=D0=B0=D1=82=D0=B5=D1=80=D0=B8=D0=B0=D0=BB=D0=B0 =D0=B2 = =D0=B2=D0=B8=D0=B4=D0=B5 =D0=BA=D1=80=D0=B0=D1=82=D0=BA=D0=BE=D0=B9 = =D0=BF=D1=80=D0=B5=D0=B7=D0=B5=D0=BD=D1=82=D0=B0=D1=86=D0=B8=D0=B8 = =D1=81 =D0=B8=D0=B7=D0=BB=D0=BE=D0=B6=D0=B5=D0=BD=D0=B8=D0=B5=D0=BC = =D0=BE=D1=81=D0=BD=D0=BE=D0=B2=D0=BD=D1=8B=D1=85 = =D0=BF=D0=BE=D0=BB=D0=BE=D0=B6=D0=B5=D0=BD=D0=B8=D0=B9 =D0=B8 = =D0=B0=D0=BB=D0=B3=D0=BE=D1=80=D0=B8=D1=82=D0=BC=D0=BE=D0=B2 = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=B0=D0=BA=D1=82=D0=BD=D0=BE=D0=B9 = =D1=81=D0=B8=D1=81=D1=82=D0=B5=D0=BC=D1=8B = =D0=BD=D0=B0=D1=80=D1=8F=D0=B4=D1=83 =D1=81 = =D0=BF=D0=BE=D0=B4=D1=80=D0=BE=D0=B1=D0=BD=D1=8B=D0=BC = =D0=BD=D0=BE=D1=80=D0=BC=D0=B0=D1=82=D0=B8=D0=B2=D0=BD=D1=8B=D0=BC = =D0=BE=D0=B1=D0=BE=D1=81=D0=BD=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=D0=BC.= * =D0=90=D0=BA=D1=86=D0=B5=D0=BD=D1=82 =D0=BD=D0=B0 = =D0=BF=D1=80=D0=B0=D0=BA=D1=82=D0=B8=D1=87=D0=B5=D1=81=D0=BA=D0=B8=D0=B5 = =D0=B2=D0=BE=D0=BF=D1=80=D0=BE=D1=81=D1=8B, = =D0=BA=D0=B5=D0=B9=D1=81=D1=8B =D1=81 = =D0=BF=D0=BE=D0=B4=D1=80=D0=BE=D0=B1=D0=BD=D1=8B=D0=BC = =D0=BE=D1=82=D0=B2=D0=B5=D1=82=D0=BE=D0=BC =D0=B8 = =D0=BD=D0=BE=D1=80=D0=BC=D0=B0=D1=82=D0=B8=D0=B2=D0=BD=D1=8B=D0=BC = =D0=BE=D0=B1=D0=BE=D1=81=D0=BD=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=D0=BC.= * = =D0=92=D0=BE=D0=B7=D0=BC=D0=BE=D0=B6=D0=BD=D0=BE=D1=81=D1=82=D1=8C = =D1=81=D0=B0=D0=BC=D0=BE=D1=81=D1=82=D0=BE=D1=8F=D1=82=D0=B5=D0=BB=D1=8C=D0= =BD=D0=BE =D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D1=80=D0=B8=D1=82=D1=8C = =D1=81=D0=B2=D0=BE=D0=B8 =D0=B7=D0=BD=D0=B0=D0=BD=D0=B8=D1=8F =D0=B8 = =D0=B2=D0=B5=D1=80=D0=BD=D1=83=D1=82=D1=8C=D1=81=D1=8F =D0=BA = =D0=B8=D0=B7=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D1=8E = =D0=BD=D0=B0=D0=B8=D0=B1=D0=BE=D0=BB=D0=B5=D0=B5 =D1=81=D0=BB=D0=BE=D0=B6=D0=BD=D1=8B=D1=85 = =D0=B2=D0=BE=D0=BF=D1=80=D0=BE=D1=81=D0=BE=D0=B2 =D0=B2 = =D0=BB=D1=8E=D0=B1=D0=BE=D0=B5 = =D1=83=D0=B4=D0=BE=D0=B1=D0=BD=D0=BE=D0=B5 =D0=B4=D0=BB=D1=8F = =D1=81=D0=BB=D1=83=D1=88=D0=B0=D1=82=D0=B5=D0=BB=D1=8F = =D0=B2=D1=80=D0=B5=D0=BC=D1=8F. * =D0=9F=D0=BE=D1=81=D1=82=D0=BE=D1=8F=D0=BD=D0=BD=D0=BE=D0=B5 = =D0=BD=D0=B0 = =D0=BF=D1=80=D0=BE=D1=82=D1=8F=D0=B6=D0=B5=D0=BD=D0=B8=D0=B8 = =D0=BE=D0=B1=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D1=8F =D0=B8 = =D0=BF=D0=BE=D1=81=D0=BB=D0=B5=D0=B4=D1=83=D1=8E=D1=89=D0=B5=D0=B5 = =D1=81=D0=BE=D0=BF=D1=80=D0=BE=D0=B2=D0=BE=D0=B6=D0=B4=D0=B5=D0=BD=D0=B8=D0= =B5 =D1=81=D0=BB=D1=83=D1=88=D0=B0=D1=82=D0=B5=D0=BB=D1=8F = =D1=8D=D0=BA=D1=81=D0=BF=D0=B5=D1=80=D1=82=D0=B0=D0=BC=D0=B8- =D0=BF=D1=80=D0=B0=D0=BA=D1=82=D0=B8=D0=BA=D0=B0=D0=BC=D0=B8, = =D1=81 = =D0=BF=D0=B8=D1=81=D1=8C=D0=BC=D0=B5=D0=BD=D0=BD=D1=8B=D0=BC=D0=B8 = =D0=BE=D1=82=D0=B2=D0=B5=D1=82=D0=B0=D0=BC=D0=B8 =D0=BD=D0=B0 = =D0=B8=D0=BD=D1=82=D0=B5=D1=80=D0=B5=D1=81=D1=83=D1=8E=D1=89=D0=B8=D0=B5 = =D1=81=D0=BB=D1=83=D1=88=D0=B0=D1=82=D0=B5=D0=BB=D1=8F = =D0=B2=D0=BE=D0=BF=D1=80=D0=BE=D1=81=D1=8B =D0=B8 = =D0=B5=D0=B6=D0=B5=D0=BC=D0=B5=D1=81=D1=8F=D1=87=D0=BD=D0=BE=D0=B9 =D1=80=D0=B0=D1=81=D1=81=D1=8B=D0=BB=D0=BA=D0=BE=D0=B9 = =D0=BD=D0=BE=D0=B2=D0=BE=D1=81=D1=82=D0=BD=D1=8B=D1=85 = =D0=BC=D0=B0=D1=82=D0=B5=D1=80=D0=B8=D0=B0=D0=BB=D0=BE=D0=B2 =D0=B8 = =D0=BA=D0=BE=D0=BC=D0=BC=D0=B5=D0=BD=D1=82=D0=B0=D1=80=D0=B8=D0=B5=D0=BC = =D1=81=D0=BF=D0=B5=D1=86=D0=B8=D0=B0=D0=BB=D0=B8=D1=81=D1=82=D0=BE=D0=B2 = =D0=BF=D0=BE = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=B0=D0=BA=D1=82=D0=BD=D0=BE=D0=B9 = =D1=81=D0=B8=D1=81=D1=82=D0=B5=D0=BC=D0=B5. * =D0=9F=D0=BB=D0=B0=D1=82=D1=84=D0=BE=D1=80=D0=BC=D0=B0 = =D0=B4=D0=BB=D1=8F = =D0=B4=D0=B8=D1=81=D1=82=D0=B0=D0=BD=D1=86=D0=B8=D0=BE=D0=BD=D0=BD=D0=BE=D0= =B3=D0=BE =D0=BE=D0=B1=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D1=8F =D0=BD=D0=B5 = =D1=82=D1=80=D0=B5=D0=B1=D1=83=D0=B5=D1=82 = =D1=81=D0=BF=D0=B5=D1=86=D0=B8=D0=B0=D0=BB=D1=8C=D0=BD=D1=8B=D1=85 = =D0=B7=D0=BD=D0=B0=D0=BD=D0=B8=D0=B9, = =D0=B7=D0=B0=D0=B3=D1=80=D1=83=D0=B6=D0=B0=D0=B5=D1=82=D1=81=D1=8F = =D0=B2 =D0=BE=D0=B1=D1=8B=D1=87=D0=BD=D1=8B=D0=B9 = =D0=B1=D1=80=D0=B0=D1=83=D0=B7=D0=B5=D1=80 =D0=B8 = =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=D0=B5=D1=82 =D0=B1=D0=B5=D0=B7 = =D1=83=D1=81=D1=82=D0=B0=D0=BD=D0=BE=D0=B2=D0=BA=D0=B8 = =D0=B4=D0=BE=D0=BF=D0=BE=D0=BB=D0=BD=D0=B8=D1=82=D0=B5=D0=BB=D1=8C=D0=BD=D1= =8B=D1=85 =D0=BF=D1=80=D0=BE=D0=B3=D1=80=D0=B0=D0=BC=D0=BC. =20 =20 ------=_NextPart_000_00A4_01D121CC.4601C0A0 Content-Type: text/html; charset="utf-8" Content-Transfer-Encoding: quoted-printable
         
 


=D0=9D=D0=90=D0=A3=D0=A7=D0=98=D0=A2=D0=95=D0=A1=D0=AC=20 =D0=93=D0=9E=D0=A1=D0=97=D0=90=D0=9A=D0=A3=D0=9F=D0=9A=D0=90=D0=9C = =D0=9F=D0=9E = 44-=D0=A4=D0=97!
=D0=9E=D0=91=D0=A3=D0=A7=D0=90=D0=99=D0=A2=D0=95=D0=A1= =D0=AC =D0=92 =D0=A3=D0=94=D0=9E=D0=91=D0=9D=D0=9E=D0=95 = =D0=94=D0=9B=D0=AF =D0=92=D0=90=D0=A1 =D0=92=D0=A0=D0=95=D0=9C=D0=AF = =D0=98 =D0=92 =D0=A3=D0=94=D0=9E=D0=91=D0=9D=D0=9E=D0=9C=20 =D0=9C=D0=95=D0=A1=D0=A2=D0=95!
=D0=9F=D1=80=D0=BE=D0=B9=D0=B4=D0=B8=D1=82=D0=B5 = =D0=B4=D0=B8=D1=81=D1=82=D0=B0=D0=BD=D1=86=D0=B8=D0=BE=D0=BD=D0=BD=D0=BE=D0= =B5 =D0=BF=D0=BE=D0=B2=D1=8B=D1=88=D0=B5=D0=BD=D0=B8=D0=B5=20 = =D0=BA=D0=B2=D0=B0=D0=BB=D0=B8=D1=84=D0=B8=D0=BA=D0=B0=D1=86=D0=B8=D0=B8 = =D0=BF=D0=BE =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BA=D0=B0=D0=BC =D0=B2 = =D0=B0=D0=BA=D0=BA=D1=80=D0=B5=D0=B4=D0=B8=D1=82=D0=BE=D0=B2=D0=B0=D0=BD=D0= =BD=D0=BE=D0=BC = =D0=A3=D1=87=D0=B5=D0=B1=D0=BD=D0=BE=D0=BC
=D1=86=D0=B5=D0=BD=D1=82=D1= =80=D0=B5 =D0=BF=D0=BE = =D0=B0=D0=B2=D1=82=D0=BE=D1=80=D1=81=D0=BA=D0=BE=D0=B9=20 =D0=BF=D1=80=D0=BE=D0=B3=D1=80=D0=B0=D0=BC=D0=BC=D0=B5 =D0=B8 = =D0=BF=D0=BE=D0=BB=D1=83=D1=87=D0=B8=D1=82=D0=B5 = =D0=BA=D0=B0=D1=87=D0=B5=D1=81=D1=82=D0=B2=D0=B5=D0=BD=D0=BD=D0=BE=D0=B5 = =D0=BE=D0=B1=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D0=B5 =D1=81 = =D0=B2=D1=8B=D0=B4=D0=B0=D1=87=D0=B5=D0=B9=20 = =D1=83=D0=B4=D0=BE=D1=81=D1=82=D0=BE=D0=B2=D0=B5=D1=80=D0=B5=D0=BD=D0=B8=D1= =8F
=D1=83=D1=81=D1=82=D0=B0=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=D0=BD= =D0=BE=D0=B3=D0=BE = =D0=BE=D0=B1=D1=80=D0=B0=D0=B7=D1=86=D0=B0.


=D0=94=D0=B0=D1=82=D1=8B = =D0=BE=D0=B1=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D1=8F = =D0=B1=D0=BB=D0=B8=D0=B6=D0=B0=D0=B9=D1=88=D0=B8=D1=85 = =D0=B3=D1=80=D1=83=D0=BF=D0=BF: =D1=81 = 30 =D0=BD=D0=BE=D1=8F=D0=B1=D1=80=D1=8F =D0=BF=D0=BE 18=20 = =D0=B4=D0=B5=D0=BA=D0=B0=D0=B1=D1=80=D1=8F

____________________________________________________________= ________________________

=D0=A3=D0=9F=D0=A0=D0=90=D0=92=D0=9B=D0=95=D0=9D=D0=98=D0=95 = =D0=93=D0=9E=D0=A1=D0=A3=D0=94=D0=90=D0=A0=D0=A1=D0=A2=D0=92=D0=95=D0=9D=D0= =9D=D0=AB=D0=9C=D0=98 =D0=98=20 = =D0=9C=D0=A3=D0=9D=D0=98=D0=A6=D0=98=D0=9F=D0=90=D0=9B=D0=AC=D0=9D=D0=AB=D0= =9C=D0=98 = =D0=97=D0=90=D0=9A=D0=A3=D0=9F=D0=9A=D0=90=D0=9C=D0=98
(=D0=9A=D0=9E=D0= =9D=D0=A2=D0=A0=D0=90=D0=9A=D0=A2=D0=9D=D0=90=D0=AF = =D0=A1=D0=98=D0=A1=D0=A2=D0=95=D0=9C=D0=90 =D0=92 = =D0=A1=D0=A4=D0=95=D0=A0=D0=95 = =D0=97=D0=90=D0=9A=D0=A3=D0=9F=D0=9E=D0=9A = =D0=A2=D0=9E=D0=92=D0=90=D0=A0=D0=9E=D0=92,=20 =D0=A0=D0=90=D0=91=D0=9E=D0=A2, = =D0=A3=D0=A1=D0=9B=D0=A3=D0=93)
=D0=92 = =D0=A1=D0=9E=D0=9E=D0=A2=D0=92=D0=95=D0=A2=D0=A1=D0=A2=D0=92=D0=98=D0=98 = =D0=A1 = =D0=A4=D0=95=D0=94=D0=95=D0=A0=D0=90=D0=9B=D0=AC=D0=9D=D0=AB=D0=9C = =D0=97=D0=90=D0=9A=D0=9E=D0=9D=D0=9E=D0=9C =E2=84=96 44-=D0=A4=D0=97 = =D0=9E=D0=A2=20 05.04.2013.


=D0=A1=D1=80=D0=BE=D0=BA = =D0=BE=D0=B1=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D1=8F - 3 = =D0=BD=D0=B5=D0=B4=D0=B5=D0=BB=D0=B8.=20 =

=D0=9F=D1=80=D0=BE=D0=B4=D0=BE=D0=BB=D0=B6=D0=B8=D1=82=D0=B5=D0=BB= =D1=8C=D0=BD=D0=BE=D1=81=D1=82=D1=8C =D0=BA=D1=83=D1=80=D1=81=D0=B0 144 = =D1=87=D0=B0=D1=81=D0=B0.

=D0=A1=D1=83=D0=BC=D0=BC=D0=B0 = =D1=83=D0=BA=D0=B0=D0=B7=D0=B0=D0=BD=D0=B0 =D0=B7=D0=B0 = =D0=B2=D0=B5=D1=81=D1=8C=20 =D0=BA=D1=83=D1=80=D1=81 = =D0=B7=D0=B0=D0=BD=D1=8F=D1=82=D0=B8=D0=B9 - 17' 000 = =D1=80=D1=83=D0=B1.

=D0=9F=D0=BE=D0=BB=D1=83=D1=87=D0=B5=D0=BD=D0=B8= =D0=B5=20 =D0=B4=D0=BE=D0=BA=D1=83=D0=BC=D0=B5=D0=BD=D1=82=D0=BE=D0=B2: = =D0=BB=D0=B8=D1=87=D0=BD=D0=BE =D0=B8=D0=BB=D0=B8 = =D0=BF=D0=BE=D1=87=D1=82=D0=BE=D0=B2=D1=8B=D0=BC = =D0=BE=D1=82=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=D0=BC = =D0=BD=D0=B0 =D0=92=D0=B0=D1=88=20 =D0=B2=D1=8B=D0=B1=D0=BE=D1=80.

=D0=92=D1=81=D1=8F = =D0=B8=D0=BD=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=86=D0=B8=D1=8F = =D0=BF=D0=BE =D0=B4=D0=B0=D0=BD=D0=BD=D0=BE=D0=BC=D1=83 = =D0=BE=D0=B1=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D1=8E =D0=B8 = =D0=B7=D0=B0=D1=8F=D0=B2=D0=BA=D0=B8 =D0=BD=D0=B0=20 =D1=83=D1=87=D0=B0=D1=81=D1=82=D0=B8=D0=B5 = =D0=BF=D1=80=D0=B8=D0=BD=D0=B8=D0=BC=D0=B0=D1=8E=D1=82=D1=81=D1=8F = =D0=BF=D0=BE =D1=82=D0=B5=D0=BB=D0=B5=D1=84=D0=BE=D0=BD=D1=83: =

8
  =D0=BA=D0=BE=D0=B4 =D0=B3=D0=BE=D1=80=D0=BE=D0=B4=D0=B0=20 =D0=9C=D0=BE=D1=81=D0=BA=D0=B2=D1=8B  ( = 4 9 5 )  =D1=82=D0=B5=D0=BB.:  411-9=D0=9E-98  (=D0=BC=D0=BD=D0=BE=D0=B3=D0=BE=D0=BA=D0=B0=D0=BD=D0=B0=D0=BB=D1= =8C=D0=BD=D1=8B=D0=B9)

____________________________________________________________= _______________________


=D0=94=D0=B8=D1=81=D1=82=D0=B0=D0=BD= =D1=86=D0=B8=D0=BE=D0=BD=D0=BD=D0=B0=D1=8F=20 =D1=84=D0=BE=D1=80=D0=BC=D0=B0 = =D0=BE=D0=B1=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D1=8F = =D0=BF=D0=BE=D0=B7=D0=B2=D0=BE=D0=BB=D1=8F=D0=B5=D1=82 = =D0=BB=D1=8E=D0=B1=D0=BE=D0=BC=D1=83 = =D1=81=D0=BB=D1=83=D1=88=D0=B0=D1=82=D0=B5=D0=BB=D1=8E = =D0=B1=D0=B5=D0=B7 =D0=BE=D1=82=D1=80=D1=8B=D0=B2=D0=B0 =D0=BE=D1=82 = =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=8B,=20 = =D0=B1=D0=B5=D0=B7
=D1=84=D0=B8=D0=BD=D0=B0=D0=BD=D1=81=D0=BE=D0=B2=D1= =8B=D1=85 =D0=B8 =D0=B2=D1=80=D0=B5=D0=BC=D0=B5=D0=BD=D0=BD=D1=8B=D1=85 = =D0=B7=D0=B0=D1=82=D1=80=D0=B0=D1=82 =D0=BD=D0=B0 = =D0=BA=D0=BE=D0=BC=D0=B0=D0=BD=D0=B4=D0=B8=D1=80=D0=BE=D0=B2=D0=BA=D0=B8 = =D0=BF=D0=BE=D0=BB=D1=83=D1=87=D0=B8=D1=82=D1=8C = =D0=BF=D0=BE=D0=BB=D0=BD=D1=8B=D0=B9 =D0=BE=D0=B1=D1=8A=D0=B5=D0=BC=20 =D0=B7=D0=BD=D0=B0=D0=BD=D0=B8=D0=B9 =D0=BF=D0=BE = =D1=82=D0=B5=D0=BC=D0=B5
=D0=BE=D0=B1=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D1= =8F =D0=B8 =D0=B4=D0=BE=D0=BA=D1=83=D0=BC=D0=B5=D0=BD=D1=82 =D0=BE = =D0=BF=D0=BE=D0=B2=D1=8B=D1=88=D0=B5=D0=BD=D0=B8=D0=B8 = =D0=BA=D0=B2=D0=B0=D0=BB=D0=B8=D1=84=D0=B8=D0=BA=D0=B0=D1=86=D0=B8=D0=B8.= =D0=94=D0=BE=D1=81=D1=82=D0=B0=D1=82=D0=BE=D1=87=D0=BD=D0=BE=20 =D0=BD=D0=B0=D0=BB=D0=B8=D1=87=D0=B8=D1=8F = =D0=BA=D0=BE=D0=BC=D0=BF=D1=8C=D1=8E=D1=82=D0=B5=D1=80=D0=B0 =D1=81 = =D0=B4=D0=BE=D1=81=D1=82=D1=83=D0=BF=D0=BE=D0=BC = =D0=B2
=D0=98=D0=BD=D1=82=D0=B5=D1=80=D0=BD=D0=B5=D1=82, = =D0=B1=D0=B5=D0=B7 = =D0=B4=D0=BE=D0=BF=D0=BE=D0=BB=D0=BD=D0=B8=D1=82=D0=B5=D0=BB=D1=8C=D0=BD=D1= =8B=D1=85 =D0=BF=D1=80=D0=BE=D0=B3=D1=80=D0=B0=D0=BC=D0=BC =D0=B8=20 =D0=BD=D0=B0=D1=81=D1=82=D1=80=D0=BE=D0=B5=D0=BA. = =D0=9E=D0=B1=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=B2=D0=BE=D0=B7=D0=BC=D0=BE=D0=B6=D0=BD=D0=BE, = =D0=BD=D0=B0=D1=85=D0=BE=D0=B4=D1=8F=D1=81=D1=8C =D0=B2 = =D0=BB=D1=8E=D0=B1=D0=BE=D0=BC
=D1=80=D0=B5=D0=B3=D0=B8=D0=BE=D0=BD=D0= =B5=20 =D0=A0=D0=BE=D1=81=D1=81=D0=B8=D0=B8!

=D0=9F=D0=BE = =D0=B8=D1=82=D0=BE=D0=B3=D0=B0=D0=BC = =D0=BE=D0=B1=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D1=8F = =D1=81=D0=BB=D1=83=D1=88=D0=B0=D1=82=D0=B5=D0=BB=D0=B8 = =D0=BF=D0=BE=D0=BB=D1=83=D1=87=D0=B0=D1=8E=D1=82 = =D0=A3=D0=B4=D0=BE=D1=81=D1=82=D0=BE=D0=B2=D0=B5=D1=80=D0=B5=D0=BD=D0=B8=D0= =B5=20 =D0=BE =D0=BF=D0=BE=D0=B2=D1=8B=D1=88=D0=B5=D0=BD=D0=B8=D0=B8 = =D0=BA=D0=B2=D0=B0=D0=BB=D0=B8=D1=84=D0=B8=D0=BA=D0=B0=D1=86=D0=B8=D0=B8.=
=D0=A3=D0=B4=D0=BE=D1=81=D1=82=D0=BE=D0=B2=D0=B5=D1=80=D0=B5=D0=BD=D0= =B8=D0=B5 =D0=B4=D0=B0=D0=B5=D1=82 = =D1=81=D0=BF=D0=B5=D1=86=D0=B8=D0=B0=D0=BB=D0=B8=D1=81=D1=82=D0=B0=D0=BC = =D0=BF=D1=80=D0=B0=D0=B2=D0=BE =D0=B1=D1=8B=D1=82=D1=8C=20 =D1=87=D0=BB=D0=B5=D0=BD=D0=BE=D0=BC =D0=B8=D0=BB=D0=B8 = =D0=BF=D1=80=D0=B5=D0=B4=D1=81=D0=B5=D0=B4=D0=B0=D1=82=D0=B5=D0=BB=D0=B5=D0= =BC =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BE=D1=87=D0=BD=D1=8B=D1=85 = =D0=BA=D0=BE=D0=BC=D0=B8=D1=81=D1=81=D0=B8=D0=B9,
=D1=80=D0=B0=D0=B1=D0= =BE=D1=82=D0=BD=D0=B8=D0=BA=D0=BE=D0=BC =D0=B8=D0=BB=D0=B8=20 = =D1=80=D1=83=D0=BA=D0=BE=D0=B2=D0=BE=D0=B4=D0=B8=D1=82=D0=B5=D0=BB=D0=B5=D0= =BC =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=B0=D0=BA=D1=82=D0=BD=D0=BE=D0=B9 = =D1=81=D0=BB=D1=83=D0=B6=D0=B1=D1=8B, = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=B0=D0=BA=D1=82=D0=BD=D1=8B=D0=BC=20 = =D1=83=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D1=8F=D1=8E=D1=89=D0=B8=D0=BC.
 

     
 

=D0=9F=D1=80=D0=BE=D0=B3=D1=80=D0=B0=D0=BC=D0=BC=D0=B0:

     
  =D0=9C=D0=BE=D0=B4=D1=83=D0=BB=D1=8C = 1. =D0=9E=D1=81=D0=BD=D0=BE=D0=B2=D1=8B = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=B0=D0=BA=D1=82=D0=BD=D0=BE=D0=B9 = =D1=81=D0=B8=D1=81=D1=82=D0=B5=D0=BC=D1=8B.=20 = =D0=97=D0=B0=D0=BA=D0=BE=D0=BD=D0=BE=D0=B4=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=D1= =81=D1=82=D0=B2=D0=BE =D0=A0=D0=A4 =D0=BE = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=B0=D0=BA=D1=82=D0=BD=D0=BE=D0=B9 = =D1=81=D0=B8=D1=81=D1=82=D0=B5=D0=BC=D0=B5.
=D0=9C=D0=BE=D0=B4=D1=83= =D0=BB=D1=8C 2.=20 = =D0=98=D0=BD=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=86=D0=B8=D0=BE=D0=BD=D0=BD=D0= =BE=D0=B5 = =D0=BE=D0=B1=D0=B5=D1=81=D0=BF=D0=B5=D1=87=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=B0=D0=BA=D1=82=D0=BD=D0=BE=D0=B9 = =D1=81=D0=B8=D1=81=D1=82=D0=B5=D0=BC=D1=8B.
=D0=9C=D0=BE=D0=B4=D1=83= =D0=BB=D1=8C 3.=20 = =D0=9F=D0=BB=D0=B0=D0=BD=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5 = =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BE=D0=BA =D0=B2 = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=B0=D0=BA=D1=82=D0=BD=D0=BE=D0=B9 = =D1=81=D0=B8=D1=81=D1=82=D0=B5=D0=BC=D0=B5.
=D0=9C=D0=BE=D0=B4=D1=83= =D0=BB=D1=8C 4. =D0=9E=D0=B1=D1=89=D0=B8=D0=B5=20 =D1=82=D1=80=D0=B5=D0=B1=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F = =D0=BA = =D0=BE=D1=81=D1=83=D1=89=D0=B5=D1=81=D1=82=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D1= =8E =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BE=D0=BA =D0=B2 = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=B0=D0=BA=D1=82=D0=BD=D0=BE=D0=B9 = =D1=81=D0=B8=D1=81=D1=82=D0=B5=D0=BC=D0=B5.
=D0=9C=D0=BE=D0=B4=D1=83= =D0=BB=D1=8C=20 5. = =D0=9E=D0=BF=D1=80=D0=B5=D0=B4=D0=B5=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=BF=D0=BE=D1=81=D1=82=D0=B0=D0=B2=D1=89=D0=B8=D0=BA=D0=B0 = (=D0=BF=D0=BE=D0=B4=D1=80=D1=8F=D0=B4=D1=87=D0=B8=D0=BA=D0=B0, = =D0=B8=D1=81=D0=BF=D0=BE=D0=BB=D0=BD=D0=B8=D1=82=D0=B5=D0=BB=D1=8F) = =D0=BF=D1=83=D1=82=D0=B5=D0=BC = =D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D0=B4=D0=B5=D0=BD=D0=B8=D1=8F=20 = =D0=BA=D0=BE=D0=BD=D0=BA=D1=83=D1=80=D1=81=D0=B0.
=D0=9C=D0=BE=D0=B4= =D1=83=D0=BB=D1=8C 6. = =D0=AD=D0=BB=D0=B5=D0=BA=D1=82=D1=80=D0=BE=D0=BD=D0=BD=D1=8B=D0=B9 = =D0=B0=D1=83=D0=BA=D1=86=D0=B8=D0=BE=D0=BD.
=D0=9C=D0=BE=D0=B4=D1=83= =D0=BB=D1=8C 7.=20 =D0=97=D0=B0=D0=BF=D1=80=D0=BE=D1=81 = =D0=BA=D0=BE=D1=82=D0=B8=D1=80=D0=BE=D0=B2=D0=BE=D0=BA.
=D0=9C=D0=BE= =D0=B4=D1=83=D0=BB=D1=8C 8. =D0=97=D0=B0=D0=BF=D1=80=D0=BE=D1=81 = =D0=BF=D1=80=D0=B5=D0=B4=D0=BB=D0=BE=D0=B6=D0=B5=D0=BD=D0=B8=D0=B9.
=D0=9C=D0=BE=D0=B4=D1=83=D0=BB=D1=8C=20 9. =D0=97=D0=B0=D0=BA=D1=83=D0=BF=D0=BA=D0=B8 =D1=83 = =D0=B5=D0=B4=D0=B8=D0=BD=D1=81=D1=82=D0=B2=D0=B5=D0=BD=D0=BD=D0=BE=D0=B3=D0= =BE =D0=BF=D0=BE=D1=81=D1=82=D0=B0=D0=B2=D1=89=D0=B8=D0=BA=D0=B0 = (=D0=BF=D0=BE=D0=B4=D1=80=D1=8F=D0=B4=D1=87=D0=B8=D0=BA=D0=B0,=20 = =D0=B8=D1=81=D0=BF=D0=BE=D0=BB=D0=BD=D0=B8=D1=82=D0=B5=D0=BB=D1=8F).
<= B>=D0=9C=D0=BE=D0=B4=D1=83=D0=BB=D1=8C 10. = =D0=9E=D1=81=D0=BE=D0=B1=D0=B5=D0=BD=D0=BD=D0=BE=D1=81=D1=82=D0=B8 = =D0=BE=D1=82=D0=B4=D0=B5=D0=BB=D1=8C=D0=BD=D1=8B=D1=85 = =D0=B2=D0=B8=D0=B4=D0=BE=D0=B2=20 = =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BE=D0=BA.
=D0=9C=D0=BE=D0=B4=D1=83= =D0=BB=D1=8C 11. = =D0=93=D0=BE=D1=81=D1=83=D0=B4=D0=B0=D1=80=D1=81=D1=82=D0=B2=D0=B5=D0=BD=D0= =BD=D1=8B=D0=B9 =D0=B8 = =D0=BC=D1=83=D0=BD=D0=B8=D1=86=D0=B8=D0=BF=D0=B0=D0=BB=D1=8C=D0=BD=D1=8B=D0= =B9=20 = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=B0=D0=BA=D1=82.
=D0=9C=D0=BE=D0=B4= =D1=83=D0=BB=D1=8C 12. = =D0=9A=D0=BE=D0=BD=D1=82=D1=80=D0=BE=D0=BB=D1=8C, = =D0=BC=D0=BE=D0=BD=D0=B8=D1=82=D0=BE=D1=80=D0=B8=D0=BD=D0=B3 =D0=B8 = =D0=B0=D1=83=D0=B4=D0=B8=D1=82 =D0=B2 =D1=81=D1=84=D0=B5=D1=80=D0=B5=20 =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BE=D0=BA. = =D0=9E=D0=B1=D0=B6=D0=B0=D0=BB=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5. = =D0=90=D0=B4=D0=BC=D0=B8=D0=BD=D0=B8=D1=81=D1=82=D1=80=D0=B0=D1=82=D0=B8=D0= =B2=D0=BD=D0=B0=D1=8F
          =           =20 =D0=BF=D1=80=D0=B0=D0=BA=D1=82=D0=B8=D0=BA=D0=B0 = =D0=A4=D0=90=D0=A1. = =D0=9E=D1=82=D0=B2=D0=B5=D1=82=D1=81=D1=82=D0=B2=D0=B5=D0=BD=D0=BD=D0=BE=D1= =81=D1=82=D1=8C =D0=BF=D0=BE = =D0=9A=D0=BE=D0=90=D0=9F.

 
     
         
  =D0=9F=D1=80=D0=B5=D0=B8=D0=BC=D1=83=D1=89=D0=B5=D1=81=D1=82=D0= =B2=D0=B0:
* = =D0=95=D0=B6=D0=B5=D0=BC=D0=B5=D1=81=D1=8F=D1=87=D0=BD=D0=B0=D1=8F= =20 = =D0=B0=D0=BA=D1=82=D1=83=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D1=8F = =D0=B8=D0=B7=D1=83=D1=87=D0=B0=D0=B5=D0=BC=D0=BE=D0=B3=D0=BE = =D0=BC=D0=B0=D1=82=D0=B5=D1=80=D0=B8=D0=B0=D0=BB=D0=B0 =D0=BF=D0=BE = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=B0=D0=BA=D1=82=D0=BD=D0=BE=D0=B9 = =D1=81=D0=B8=D1=81=D1=82=D0=B5=D0=BC=D0=B5.
* = =D0=9D=D0=B0=D0=B3=D0=BB=D1=8F=D0=B4=D0=BD=D0=BE=D0=B5 =D0=B8=20 =D0=B4=D0=BE=D1=81=D1=82=D1=83=D0=BF=D0=BD=D0=BE=D0=B5 = =D0=BF=D1=80=D0=B5=D0=B4=D1=81=D1=82=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0= =B5 =D0=B8=D0=B7=D1=83=D1=87=D0=B0=D0=B5=D0=BC=D0=BE=D0=B3=D0=BE = =D0=BC=D0=B0=D1=82=D0=B5=D1=80=D0=B8=D0=B0=D0=BB=D0=B0 =D0=B2 = =D0=B2=D0=B8=D0=B4=D0=B5 =D0=BA=D1=80=D0=B0=D1=82=D0=BA=D0=BE=D0=B9 = =D0=BF=D1=80=D0=B5=D0=B7=D0=B5=D0=BD=D1=82=D0=B0=D1=86=D0=B8=D0=B8=20 =D1=81
   = =D0=B8=D0=B7=D0=BB=D0=BE=D0=B6=D0=B5=D0=BD=D0=B8=D0=B5=D0=BC = =D0=BE=D1=81=D0=BD=D0=BE=D0=B2=D0=BD=D1=8B=D1=85 = =D0=BF=D0=BE=D0=BB=D0=BE=D0=B6=D0=B5=D0=BD=D0=B8=D0=B9 =D0=B8=20 =D0=B0=D0=BB=D0=B3=D0=BE=D1=80=D0=B8=D1=82=D0=BC=D0=BE=D0=B2 = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=B0=D0=BA=D1=82=D0=BD=D0=BE=D0=B9 = =D1=81=D0=B8=D1=81=D1=82=D0=B5=D0=BC=D1=8B = =D0=BD=D0=B0=D1=80=D1=8F=D0=B4=D1=83 =D1=81 = =D0=BF=D0=BE=D0=B4=D1=80=D0=BE=D0=B1=D0=BD=D1=8B=D0=BC
   = =D0=BD=D0=BE=D1=80=D0=BC=D0=B0=D1=82=D0=B8=D0=B2=D0=BD=D1=8B=D0=BC= = =D0=BE=D0=B1=D0=BE=D1=81=D0=BD=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=D0=BC.=
* = =D0=90=D0=BA=D1=86=D0=B5=D0=BD=D1=82 =D0=BD=D0=B0=20 = =D0=BF=D1=80=D0=B0=D0=BA=D1=82=D0=B8=D1=87=D0=B5=D1=81=D0=BA=D0=B8=D0=B5 = =D0=B2=D0=BE=D0=BF=D1=80=D0=BE=D1=81=D1=8B, = =D0=BA=D0=B5=D0=B9=D1=81=D1=8B =D1=81 = =D0=BF=D0=BE=D0=B4=D1=80=D0=BE=D0=B1=D0=BD=D1=8B=D0=BC = =D0=BE=D1=82=D0=B2=D0=B5=D1=82=D0=BE=D0=BC =D0=B8 = =D0=BD=D0=BE=D1=80=D0=BC=D0=B0=D1=82=D0=B8=D0=B2=D0=BD=D1=8B=D0=BC=20 = =D0=BE=D0=B1=D0=BE=D1=81=D0=BD=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=D0=BC.=
*=20 = =D0=92=D0=BE=D0=B7=D0=BC=D0=BE=D0=B6=D0=BD=D0=BE=D1=81=D1=82=D1=8C= = =D1=81=D0=B0=D0=BC=D0=BE=D1=81=D1=82=D0=BE=D1=8F=D1=82=D0=B5=D0=BB=D1=8C=D0= =BD=D0=BE =D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D1=80=D0=B8=D1=82=D1=8C = =D1=81=D0=B2=D0=BE=D0=B8 =D0=B7=D0=BD=D0=B0=D0=BD=D0=B8=D1=8F =D0=B8 = =D0=B2=D0=B5=D1=80=D0=BD=D1=83=D1=82=D1=8C=D1=81=D1=8F =D0=BA=20 =D0=B8=D0=B7=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D1=8E = =D0=BD=D0=B0=D0=B8=D0=B1=D0=BE=D0=BB=D0=B5=D0=B5
   = =D1=81=D0=BB=D0=BE=D0=B6=D0=BD=D1=8B=D1=85 = =D0=B2=D0=BE=D0=BF=D1=80=D0=BE=D1=81=D0=BE=D0=B2=20 =D0=B2 =D0=BB=D1=8E=D0=B1=D0=BE=D0=B5 = =D1=83=D0=B4=D0=BE=D0=B1=D0=BD=D0=BE=D0=B5 =D0=B4=D0=BB=D1=8F = =D1=81=D0=BB=D1=83=D1=88=D0=B0=D1=82=D0=B5=D0=BB=D1=8F = =D0=B2=D1=80=D0=B5=D0=BC=D1=8F.
* = =D0=9F=D0=BE=D1=81=D1=82=D0=BE=D1=8F=D0=BD=D0=BD=D0=BE=D0=B5 = =D0=BD=D0=B0 = =D0=BF=D1=80=D0=BE=D1=82=D1=8F=D0=B6=D0=B5=D0=BD=D0=B8=D0=B8 = =D0=BE=D0=B1=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D1=8F =D0=B8=20 =D0=BF=D0=BE=D1=81=D0=BB=D0=B5=D0=B4=D1=83=D1=8E=D1=89=D0=B5=D0=B5 = =D1=81=D0=BE=D0=BF=D1=80=D0=BE=D0=B2=D0=BE=D0=B6=D0=B4=D0=B5=D0=BD=D0=B8=D0= =B5 =D1=81=D0=BB=D1=83=D1=88=D0=B0=D1=82=D0=B5=D0=BB=D1=8F = =D1=8D=D0=BA=D1=81=D0=BF=D0=B5=D1=80=D1=82=D0=B0=D0=BC=D0=B8-
   = =D0=BF=D1=80=D0=B0=D0=BA=D1=82=D0=B8=D0=BA=D0=B0=D0=BC=D0=B8, = =D1=81 = =D0=BF=D0=B8=D1=81=D1=8C=D0=BC=D0=B5=D0=BD=D0=BD=D1=8B=D0=BC=D0=B8 = =D0=BE=D1=82=D0=B2=D0=B5=D1=82=D0=B0=D0=BC=D0=B8 =D0=BD=D0=B0=20 = =D0=B8=D0=BD=D1=82=D0=B5=D1=80=D0=B5=D1=81=D1=83=D1=8E=D1=89=D0=B8=D0=B5 = =D1=81=D0=BB=D1=83=D1=88=D0=B0=D1=82=D0=B5=D0=BB=D1=8F = =D0=B2=D0=BE=D0=BF=D1=80=D0=BE=D1=81=D1=8B =D0=B8 = =D0=B5=D0=B6=D0=B5=D0=BC=D0=B5=D1=81=D1=8F=D1=87=D0=BD=D0=BE=D0=B9
   = =D1=80=D0=B0=D1=81=D1=81=D1=8B=D0=BB=D0=BA=D0=BE=D0=B9 = =D0=BD=D0=BE=D0=B2=D0=BE=D1=81=D1=82=D0=BD=D1=8B=D1=85 = =D0=BC=D0=B0=D1=82=D0=B5=D1=80=D0=B8=D0=B0=D0=BB=D0=BE=D0=B2 =D0=B8=20 = =D0=BA=D0=BE=D0=BC=D0=BC=D0=B5=D0=BD=D1=82=D0=B0=D1=80=D0=B8=D0=B5=D0=BC = =D1=81=D0=BF=D0=B5=D1=86=D0=B8=D0=B0=D0=BB=D0=B8=D1=81=D1=82=D0=BE=D0=B2 = =D0=BF=D0=BE = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=B0=D0=BA=D1=82=D0=BD=D0=BE=D0=B9 = =D1=81=D0=B8=D1=81=D1=82=D0=B5=D0=BC=D0=B5.
* = =D0=9F=D0=BB=D0=B0=D1=82=D1=84=D0=BE=D1=80=D0=BC=D0=B0 = =D0=B4=D0=BB=D1=8F=20 = =D0=B4=D0=B8=D1=81=D1=82=D0=B0=D0=BD=D1=86=D0=B8=D0=BE=D0=BD=D0=BD=D0=BE=D0= =B3=D0=BE =D0=BE=D0=B1=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D1=8F =D0=BD=D0=B5 = =D1=82=D1=80=D0=B5=D0=B1=D1=83=D0=B5=D1=82 = =D1=81=D0=BF=D0=B5=D1=86=D0=B8=D0=B0=D0=BB=D1=8C=D0=BD=D1=8B=D1=85 = =D0=B7=D0=BD=D0=B0=D0=BD=D0=B8=D0=B9, = =D0=B7=D0=B0=D0=B3=D1=80=D1=83=D0=B6=D0=B0=D0=B5=D1=82=D1=81=D1=8F=20 =D0=B2
   = =D0=BE=D0=B1=D1=8B=D1=87=D0=BD=D1=8B=D0=B9 = =D0=B1=D1=80=D0=B0=D1=83=D0=B7=D0=B5=D1=80 =D0=B8 = =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=D0=B5=D1=82 =D0=B1=D0=B5=D0=B7=20 =D1=83=D1=81=D1=82=D0=B0=D0=BD=D0=BE=D0=B2=D0=BA=D0=B8 = =D0=B4=D0=BE=D0=BF=D0=BE=D0=BB=D0=BD=D0=B8=D1=82=D0=B5=D0=BB=D1=8C=D0=BD=D1= =8B=D1=85 =D0=BF=D1=80=D0=BE=D0=B3=D1=80=D0=B0=D0=BC=D0=BC.
     
         
------=_NextPart_000_00A4_01D121CC.4601C0A0-- From vedvalutinfo@epage.ru Tue Nov 17 22:03:58 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 225847F37 for ; Tue, 17 Nov 2015 22:03:58 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 0361A304032 for ; Tue, 17 Nov 2015 20:03:54 -0800 (PST) X-ASG-Debug-ID: 1447819420-04cbb0605df34a0001-NocioJ Received: from mx.epage.ru (cm-84.210.213.70.getinternet.no [84.210.213.70]) by cuda.sgi.com with ESMTP id mOlodnZNrMuvLVUo for ; Tue, 17 Nov 2015 20:03:43 -0800 (PST) X-Barracuda-Envelope-From: vedvalutinfo@epage.ru X-Barracuda-Apparent-Source-IP: 84.210.213.70 Message-ID: <0E22515CA05224F9157D5F8523208396@YDMPCBSEAB> From: "=?utf-8?B?0JLQsNC70Y7RgtC90YvQuSDQutC+0L3RgtGA0L7Qu9GM?=" To: Subject: =?utf-8?B?0K7RgNC40YHRgtGLINC4INGB0L/QtdGG0LjQsNC70LjRgdGC0Ysg0L/RgNC10LTQv9GA0LjRj9GC0LjQuSDQuCDQsdCw0L3QutC+0LIgLSDRg9GH0LDRgdGC0L3QuNC60Lgg0LLQvdC10YjQvdC10Y3QutC+0L3QvtC80LjRh9C10YHQutC+0Lkg0LTQtdGP0YLQtdC70YzQvdC+0YHRgtC4?= Date: Wed, 18 Nov 2015 07:03:38 +0300 X-ASG-Orig-Subj: =?utf-8?B?0K7RgNC40YHRgtGLINC4INGB0L/QtdGG0LjQsNC70LjRgdGC0Ysg0L/RgNC10LTQv9GA0LjRj9GC0LjQuSDQuCDQsdCw0L3QutC+0LIgLSDRg9GH0LDRgdGC0L3QuNC60Lgg0LLQvdC10YjQvdC10Y3QutC+0L3QvtC80LjRh9C10YHQutC+0Lkg0LTQtdGP0YLQtdC70YzQvdC+0YHRgtC4?= MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="----=_NextPart_000_0047_01D121CF.401CC830" 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: cm-84.210.213.70.getinternet.no[84.210.213.70] X-Barracuda-Start-Time: 1447819420 X-Barracuda-URL: https://192.48.176.25:443/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, HTML_MESSAGE, RDNS_DYNAMIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24497 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 HTML_MESSAGE BODY: HTML included in message 0.10 RDNS_DYNAMIC Delivered to trusted network by host with dynamic-looking rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 Ýòî — ñîîáùåíèå èç íåñêîëüêèõ ÷àñòåé â ôîðìàòå MIME. ------=_NextPart_000_0047_01D121CF.401CC830 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable =20 =D0=9F =D1=80 =D0=BE =D0=BC =D0=BE =D0=BA =D0=BE =D0=B4 : 256=20 =20 = =D0=90=D0=BA=D0=BA=D1=80=D0=B5=D0=B4=D0=B8=D1=82=D0=BE=D0=B2=D0=B0=D0=BD=D0= =BD=D1=8B=D0=B9 =D0=A3=D1=87=D0=B5=D0=B1=D0=BD=D1=8B=D0=B9 = =D1=86=D0=B5=D0=BD=D1=82=D1=80 = =D0=BF=D1=80=D0=B8=D0=B3=D0=BB=D0=B0=D1=88=D0=B0=D0=B5=D1=82 = =D0=BD=D0=B0 =D0=BE=D0=B1=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D0=B5: =D0=A6=D0=B5=D0=BB=D1=8C = =D0=B7=D0=B0=D0=BD=D1=8F=D1=82=D0=B8=D1=8F: = =D0=BE=D0=B1=D1=81=D1=83=D0=B4=D0=B8=D1=82=D1=8C = =D0=B0=D0=BA=D1=82=D1=83=D0=B0=D0=BB=D1=8C=D0=BD=D1=8B=D0=B5 = =D0=B2=D0=BE=D0=BF=D1=80=D0=BE=D1=81=D1=8B, = =D0=B8=D0=BC=D0=B5=D1=8E=D1=89=D0=B8=D0=B5 = =D0=BF=D1=80=D0=B0=D0=BA=D1=82=D0=B8=D1=87=D0=B5=D1=81=D0=BA=D1=83=D1=8E = =D0=BD=D0=B0=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=BD=D0=BE=D1=81=D1= =82=D1=8C =D0=B8 =D1=81=D0=B2=D1=8F=D0=B7=D0=B0=D0=BD=D0=BD=D1=8B=D0=B5 =D1=81 = =D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5=D0=BC = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=B3=D0=BE = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D0=BE=D0=B4=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=D1= =81=D1=82=D0=B2=D0=B0 =D0=B2 =D0=A0=D0=A4, = =D0=BF=D0=BE=D0=BB=D1=83=D1=87=D0=B8=D1=82=D1=8C = =D0=B7=D0=BD=D0=B0=D0=BD=D0=B8=D1=8F, = =D0=BA=D0=BE=D1=82=D0=BE=D1=80=D1=8B=D0=B5 = =D0=BF=D0=BE=D0=B7=D0=B2=D0=BE=D0=BB=D1=8F=D1=82 =D0=B8=D0=B7=D0=B1=D0=B5=D0=B6=D0=B0=D1=82=D1=8C = =D1=82=D0=B8=D0=BF=D0=B8=D1=87=D0=BD=D1=8B=D1=85 = =D0=BE=D1=88=D0=B8=D0=B1=D0=BE=D0=BA =D0=B8 = =D0=BD=D0=B0=D1=80=D1=83=D1=88=D0=B5=D0=BD=D0=B8=D0=B9 = =D0=BF=D1=80=D0=B8 = =D1=81=D0=BE=D0=B2=D0=B5=D1=80=D1=88=D0=B5=D0=BD=D0=B8=D0=B8 =D0=B8 = =D0=BE=D1=84=D0=BE=D1=80=D0=BC=D0=BB=D0=B5=D0=BD=D0=B8=D0=B8 = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D1=8B=D1=85 = =D0=BE=D0=BF=D0=B5=D1=80=D0=B0=D1=86=D0=B8=D0=B9. = =D0=9F=D1=80=D0=B5=D0=B4=D0=BD=D0=B0=D0=B7=D0=BD=D0=B0=D1=87=D0=B5=D0=BD=D0= =BE =D0=B4=D0=BB=D1=8F: = =D1=81=D0=BE=D0=B1=D1=81=D1=82=D0=B2=D0=B5=D0=BD=D0=BD=D0=B8=D0=BA=D0=BE=D0= =B2 =D0=B1=D0=B8=D0=B7=D0=BD=D0=B5=D1=81=D0=B0, = =D1=84=D0=B8=D0=BD=D0=B0=D0=BD=D1=81=D0=BE=D0=B2=D1=8B=D1=85 =D0=B8 = =D0=BA=D0=BE=D0=BC=D0=BC=D0=B5=D1=80=D1=87=D0=B5=D1=81=D0=BA=D0=B8=D1=85 = =D0=B4=D0=B8=D1=80=D0=B5=D0=BA=D1=82=D0=BE=D1=80=D0=BE=D0=B2, = =D1=80=D1=83=D0=BA=D0=BE=D0=B2=D0=BE=D0=B4=D0=B8=D1=82=D0=B5=D0=BB=D0=B5=D0= =B9 = =D1=84=D0=B8=D0=BD=D0=B0=D0=BD=D1=81=D0=BE=D0=B2=D0=BE-=D1=8D=D0=BA=D0=BE= =D0=BD=D0=BE=D0=BC=D0=B8=D1=87=D0=B5=D1=81=D0=BA=D0=B8=D1=85 = =D1=81=D0=BB=D1=83=D0=B6=D0=B1 = =D0=BF=D1=80=D0=B5=D0=B4=D0=BF=D1=80=D0=B8=D1=8F=D1=82=D0=B8=D0=B9 = =D0=B8 = =D0=BE=D1=80=D0=B3=D0=B0=D0=BD=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D0=B9, = =D1=83=D1=87=D0=B0=D1=81=D1=82=D0=BD=D0=B8=D0=BA=D0=BE=D0=B2 = =D0=B2=D0=BD=D0=B5=D1=88=D0=BD=D0=B5=D1=8D=D0=BA=D0=BE=D0=BD=D0=BE=D0=BC=D0= =B8=D1=87=D0=B5=D1=81=D0=BA=D0=BE=D0=B9 = =D0=B4=D0=B5=D1=8F=D1=82=D0=B5=D0=BB=D1=8C=D0=BD=D0=BE=D1=81=D1=82=D0=B8,= =D0=B1=D0=B0=D0=BD=D0=BA=D0=BE=D0=B2=D1=81=D0=BA=D0=B8=D1=85 = =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BD=D0=B8=D0=BA=D0=BE=D0=B2. =D0=A2=D0=B5=D0=BC=D0=B0: = =D0=92=D0=90=D0=9B=D0=AE=D0=A2=D0=9D=D0=9E=D0=95 = =D0=A0=D0=95=D0=93=D0=A3=D0=9B=D0=98=D0=A0=D0=9E=D0=92=D0=90=D0=9D=D0=98=D0= =95 =D0=98 =D0=92=D0=90=D0=9B=D0=AE=D0=A2=D0=9D=D0=AB=D0=99 =D0=9A=D0=9E=D0=9D=D0=A2=D0=A0=D0=9E=D0=9B=D0=AC =D0=92 = =D0=A0=D0=A4 =D0=A1 =D0=A3=D0=A7=D0=95=D0=A2=D0=9E=D0=9C = =D0=9F=D0=9E=D0=A1=D0=9B=D0=95=D0=94=D0=9D=D0=98=D0=A5 = =D0=98=D0=97=D0=9C=D0=95=D0=9D=D0=95=D0=9D=D0=98=D0=99 = =D0=97=D0=90=D0=9A=D0=9E=D0=9D=D0=9E=D0=94=D0=90=D0=A2=D0=95=D0=9B=D0=AC=D0= =A1=D0=A2=D0=92=D0=90 =D0=97=D0=B0=D0=BD=D1=8F=D1=82=D0=B8=D0=B5 = =D1=81=D0=BE=D1=81=D1=82=D0=BE=D0=B8=D1=82=D1=81=D1=8F: 04 = =D0=B4=D0=B5=D0=BA=D0=B0=D0=B1=D1=80=D1=8F 2015 =D0=B3=D0=BE=D0=B4=D0=B0 = =D0=9E=D0=B1=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=BF=D1=80=D0=BE=D0=B2=D0=BE=D0=B4=D0=B8=D1=82=D1=81=D1=8F: c 10:00 = =D0=B4=D0=BE 17:30 =D0=90=D0=B4=D1=80=D0=B5=D1=81 = =D0=BC=D0=B5=D1=80=D0=BE=D0=BF=D1=80=D0=B8=D1=8F=D1=82=D0=B8=D1=8F: = =D0=B3. =D0=9C=D0=BE=D1=81=D0=BA=D0=B2=D0=B0, =D0=BC. = =D0=91=D0=B0=D1=83=D0=BC=D0=B0=D0=BD=D1=81=D0=BA=D0=B0=D1=8F, = =D1=83=D0=BB. = =D0=91=D0=B0=D1=83=D0=BC=D0=B0=D0=BD=D1=81=D0=BA=D0=B0=D1=8F, =D0=B4.6, = =D0=91.=D0=A6. "=D0=92=D0=B8=D0=BA=D1=82=D0=BE=D1=80=D0=B8=D1=8F = =D0=9F=D0=BB=D0=B0=D0=B7=D0=B0". =D0=92=D1=81=D1=8F = =D0=B8=D0=BD=D1=82=D0=B5=D1=80=D0=B5=D1=81=D1=83=D1=8E=D1=89=D0=B0=D1=8F = =D0=92=D0=B0=D1=81 = =D0=B8=D0=BD=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=86=D0=B8=D1=8F =D0=BE = =D0=BF=D1=80=D0=BE=D0=B3=D1=80=D0=B0=D0=BC=D0=BC=D0=B5 =D0=B8 = =D0=B7=D0=B0=D1=8F=D0=B2=D0=BA=D0=B8 =D0=BD=D0=B0 = =D1=83=D1=87=D0=B0=D1=81=D1=82=D0=B8=D0=B5 = =D0=BF=D1=80=D0=B8=D0=BD=D0=B8=D0=BC=D0=B0=D1=8E=D1=82=D1=81=D1=8F = =D0=BF=D0=BE =D0=BD=D0=BE=D0=BC=D0=B5=D1=80=D1=83: 8 =D0=BA=D0=BE=D0=B4 =D0=B3=D0=BE=D1=80=D0=BE=D0=B4=D0=B0 ( 4 9 = 5 ) =D1=82=D0=B5=D0=BB=D0=B5=D1=84=D0=BE=D0=BD 725 - 04 - 48 = (=D0=BC=D0=BD=D0=BE=D0=B3=D0=BE=D0=BA=D0=B0=D0=BD=D0=B0=D0=BB=D1=8C=D0=BD= =D1=8B=D0=B9) =20 =20 =20 =D0=9F=D1=80=D0=BE=D0=B3=D1=80=D0=B0=D0=BC=D0=BC=D0=B0 = (=D1=81=D0=BE=D0=BA=D1=80=D0=B0=D1=89=D0=B5=D0=BD=D0=BD=D1=8B=D0=B9 = =D0=B2=D0=B0=D1=80=D0=B8=D0=B0=D0=BD=D1=82): 1.=D0=9D=D0=BE=D0=B2=D0=BE=D0=B5 =D0=B2 = =D1=81=D0=B8=D1=81=D1=82=D0=B5=D0=BC=D0=B5 = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=B3=D0=BE = =D1=80=D0=B5=D0=B3=D1=83=D0=BB=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1= =8F =D0=B2 =D0=A0=D0=A4. = =D0=9D=D0=BE=D1=80=D0=BC=D0=B0=D1=82=D0=B8=D0=B2=D0=BD=D0=BE-=D0=BF=D1=80= =D0=B0=D0=B2=D0=BE=D0=B2=D0=B0=D1=8F =D0=B1=D0=B0=D0=B7=D0=B0 = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=B3=D0=BE = =D1=80=D0=B5=D0=B3=D1=83=D0=BB=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1= =8F =D0=B2 =D0=A0=D0=BE=D1=81=D1=81=D0=B8=D0=B9=D1=81=D0=BA=D0=BE=D0=B9 = =D0=A4=D0=B5=D0=B4=D0=B5=D1=80=D0=B0=D1=86=D0=B8=D0=B8. = =D0=9F=D0=BE=D1=81=D0=BB=D0=B5=D0=B4=D0=BD=D0=B8=D0=B5 =D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=B3=D0=BE = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D0=BE=D0=B4=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=D1= =81=D1=82=D0=B2=D0=B0 =D0=A0=D0=A4. = =D0=9F=D0=BE=D1=80=D1=8F=D0=B4=D0=BE=D0=BA = =D0=BE=D1=82=D0=BA=D1=80=D1=8B=D1=82=D0=B8=D1=8F =D0=B8 = =D0=B2=D0=B5=D0=B4=D0=B5=D0=BD=D0=B8=D1=8F = =D1=81=D1=87=D0=B5=D1=82=D0=BE=D0=B2 = =D1=80=D0=B5=D0=B7=D0=B8=D0=B4=D0=B5=D0=BD=D1=82=D0=BE=D0=B2 = =D0=B7=D0=B0 =D0=BF=D1=80=D0=B5=D0=B4=D0=B5=D0=BB=D0=B0=D0=BC=D0=B8 = =D1=82=D0=B5=D1=80=D1=80=D0=B8=D1=82=D0=BE=D1=80=D0=B8=D0=B8 = =D0=A0=D0=A4. =D0=9F=D1=80=D0=B0=D0=B2=D0=B8=D0=BB=D0=B0 = =D0=BE=D1=81=D1=83=D1=89=D0=B5=D1=81=D1=82=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D1= =8F =D1=80=D0=B5=D0=B7=D0=B8=D0=B4=D0=B5=D0=BD=D1=82=D0=B0=D0=BC=D0=B8 = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D1=8B=D1=85 = =D0=BE=D0=BF=D0=B5=D1=80=D0=B0=D1=86=D0=B8=D0=B9 =D0=B7=D0=B0 = =D1=81=D1=87=D0=B5=D1=82 =D1=81=D1=80=D0=B5=D0=B4=D1=81=D1=82=D0=B2, = =D0=BD=D0=B0=D1=85=D0=BE=D0=B4=D1=8F=D1=89=D0=B8=D1=85=D1=81=D1=8F = =D0=BD=D0=B0 =D1=81=D1=87=D0=B5=D1=82=D0=B0=D1=85 =D0=B7=D0=B0 = =D1=80=D1=83=D0=B1=D0=B5=D0=B6=D0=BE=D0=BC. = =D0=9F=D0=BE=D1=80=D1=8F=D0=B4=D0=BE=D0=BA = =D0=BF=D0=B5=D1=80=D0=B5=D0=B4=D0=B0=D1=87=D0=B8 = =D1=83=D0=BF=D0=BE=D0=BB=D0=BD=D0=BE=D0=BC=D0=BE=D1=87=D0=B5=D0=BD=D0=BD=D1= =8B=D0=BC=D0=B8 =D0=B1=D0=B0=D0=BD=D0=BA=D0=B0=D0=BC=D0=B8 =D0=B8=D0=BD=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=86=D0=B8=D0=B8 = =D0=BE =D0=BD=D0=B0=D1=80=D1=83=D1=88=D0=B5=D0=BD=D0=B8=D1=8F=D1=85 = =D0=B8=D1=85 =D0=BA=D0=BB=D0=B8=D0=B5=D0=BD=D1=82=D0=B0=D0=BC=D0=B8 = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=B3=D0=BE = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D0=BE=D0=B4=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=D1= =81=D1=82=D0=B2=D0=B0 =D0=A0=D0=A4. = =D0=94=D0=B5=D0=B9=D1=81=D1=82=D0=B2=D0=B8=D0=B5 = =D1=84=D0=B5=D0=B4=D0=B5=D1=80=D0=B0=D0=BB=D1=8C=D0=BD=D0=BE=D0=B3=D0=BE = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D0=B0 "=D0=9E = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=BC = =D1=80=D0=B5=D0=B3=D1=83=D0=BB=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0= =B8 =D0=B8 =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=BC = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=BE=D0=BB=D0=B5" 173-=D0=A4=D0=97 = (=D1=81 = =D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F=D0=BC=D0=B8, =D0=B2=D1=81=D1=82=D1=83=D0=BF=D0=B8=D0=B2=D1=88=D0=B8=D0=BC=D0=B8 = =D0=B2 =D1=81=D0=B8=D0=BB=D1=83 =D0=B2 2013 =D0=B3=D0=BE=D0=B4=D1=83 = =D0=B8 = =D0=B2=D1=81=D1=82=D1=83=D0=BF=D0=B0=D1=8E=D1=89=D0=B8=D0=BC=D0=B8 = =D0=B2 =D1=81=D0=B8=D0=BB=D1=83 =D0=B2 2014 =D0=B3). = =D0=9F=D1=80=D0=BE=D0=B5=D0=BA=D1=82=D1=8B = =D0=B1=D1=83=D0=B4=D1=83=D1=89=D0=B8=D1=85 = =D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D0=B9 = =D0=A4=D0=B5=D0=B4=D0=B5=D1=80=D0=B0=D0=BB=D1=8C=D0=BD=D0=BE=D0=B3=D0=BE = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D0=B0 "=D0=9E = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=BC = =D1=80=D0=B5=D0=B3=D1=83=D0=BB=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0= =B8 =D0=B8 =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=BC = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=BE=D0=BB=D0=B5".=20 =D0=94=D0=B5=D0=B9=D1=81=D1=82=D0=B2=D0=B8=D0=B5 = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=B3=D0=BE = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D0=BE=D0=B4=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=D1= =81=D1=82=D0=B2=D0=B0 =D0=B2 =D1=81=D0=B2=D1=8F=D0=B7=D0=B8 =D1=81 = =D0=BF=D1=80=D0=B8=D0=BD=D1=8F=D1=82=D0=B8=D0=B5=D0=BC = =D0=A4=D0=B5=D0=B4=D0=B5=D1=80=D0=B0=D0=BB=D1=8C=D0=BD=D0=BE=D0=B3=D0=BE = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D0=B0 =D0=BE=D1=82 27 = =D0=B8=D1=8E=D0=BD=D1=8F 2011 =D0=B3=D0=BE=D0=B4=D0=B0 161-=D0=A4=D0=97 "=D0=9E = =D0=BD=D0=B0=D1=86=D0=B8=D0=BE=D0=BD=D0=B0=D0=BB=D1=8C=D0=BD=D0=BE=D0=B9 = =D0=BF=D0=BB=D0=B0=D1=82=D0=B5=D0=B6=D0=BD=D0=BE=D0=B9 = =D1=81=D0=B8=D1=81=D1=82=D0=B5=D0=BC=D0=B5". = =D0=9E=D1=81=D0=BE=D0=B1=D0=B5=D0=BD=D0=BD=D0=BE=D1=81=D1=82=D0=B8 = =D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D0=B4=D0=B5=D0=BD=D0=B8=D1=8F = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D1=8B=D1=85 =D0=BE=D0=BF=D0=B5=D1=80=D0=B0=D1=86=D0=B8=D0=B9 = =D1=80=D0=B5=D0=B7=D0=B8=D0=B4=D0=B5=D0=BD=D1=82=D0=B0=D0=BC=D0=B8 = =D0=B8 = =D0=BD=D0=B5=D1=80=D0=B5=D0=B7=D0=B8=D0=B4=D0=B5=D0=BD=D1=82=D0=B0=D0=BC=D0= =B8.=20 2.=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F = =D0=BF=D1=80=D0=B0=D0=B2=D0=B8=D0=BB = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=B3=D0=BE = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=BE=D0=BB=D1=8F, = =D0=BE=D1=81=D1=83=D1=89=D0=B5=D1=81=D1=82=D0=B2=D0=BB=D1=8F=D0=B5=D0=BC=D0= =BE=D0=B3=D0=BE =D1=81 =D1=83=D1=87=D0=B0=D1=81=D1=82=D0=B8=D0=B5=D0=BC = =D1=82=D0=B0=D0=BC=D0=BE=D0=B6=D0=B5=D0=BD=D0=BD=D1=8B=D1=85 =D0=BE=D1=80=D0=B3=D0=B0=D0=BD=D0=BE=D0=B2. =D0=9E=D0=B1=D0=B7=D0=BE=D1=80 = =D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D0=B9 = =D0=BD=D0=BE=D1=80=D0=BC=D0=B0=D1=82=D0=B8=D0=B2=D0=BD=D0=BE-=D0=BF=D1=80= =D0=B0=D0=B2=D0=BE=D0=B2=D0=BE=D0=B9 =D0=B1=D0=B0=D0=B7=D1=8B = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=B3=D0=BE = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=BE=D0=BB=D1=8F. = =D0=A2=D0=B5=D1=85=D0=BD=D0=BE=D0=BB=D0=BE=D0=B3=D0=B8=D0=B8 = =D1=82=D0=B0=D0=BC=D0=BE=D0=B6=D0=B5=D0=BD=D0=BD=D0=BE- =D0=B1=D0=B0=D0=BD=D0=BA=D0=BE=D0=B2=D1=81=D0=BA=D0=BE=D0=B3=D0=BE = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=B3=D0=BE = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=BE=D0=BB=D1=8F = (=D0=A2=D0=91=D0=92=D0=9A), = =D0=B2=D0=B7=D0=B0=D0=B8=D0=BC=D0=BE=D0=B4=D0=B5=D0=B9=D1=81=D1=82=D0=B2=D0= =B8=D0=B5 =D1=81 =D0=B4=D1=80=D1=83=D0=B3=D0=B8=D0=BC=D0=B8 = =D0=BE=D1=80=D0=B3=D0=B0=D0=BD=D0=B0=D0=BC=D0=B8 =D0=B8 = =D0=B0=D0=B3=D0=B5=D0=BD=D1=82=D0=B0=D0=BC=D0=B8 =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=B3=D0=BE = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=BE=D0=BB=D1=8F. = =D0=92=D0=BE=D0=BF=D1=80=D0=BE=D1=81=D1=8B = =D0=B4=D0=B5=D0=BA=D0=BB=D0=B0=D1=80=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0= =B8=D1=8F =D1=82=D0=BE=D0=B2=D0=B0=D1=80=D0=BE=D0=B2 =D0=B8 = =D0=B8=D0=BD=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=86=D0=B8=D0=BE=D0=BD=D0=BD=D0= =BE=D0=B3=D0=BE =D0=BE=D0=B1=D0=BC=D0=B5=D0=BD=D0=B0 = =D0=BC=D0=B5=D0=B6=D0=B4=D1=83 =D0=A4=D0=A2=D0=A1 =D0=A0=D0=A4 =D0=B8 = =D1=83=D0=BF=D0=BE=D0=BB=D0=BD=D0=BE=D0=BC=D0=BE=D1=87=D0=B5=D0=BD=D0=BD=D1= =8B=D0=BC=D0=B8 =D0=B1=D0=B0=D0=BD=D0=BA=D0=B0=D0=BC=D0=B8. = =D0=92=D1=8B=D1=8F=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=BD=D0=B0=D1=80=D1=83=D1=88=D0=B5=D0=BD=D0=B8=D0=B9 = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D0=BE=D0=B4=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=D1= =81=D1=82=D0=B2=D0=B0, = =D0=BF=D1=80=D0=B5=D0=B4=D1=83=D1=81=D0=BC=D0=BE=D1=82=D1=80=D0=B5=D0=BD=D0= =BD=D1=8B=D1=85 =D0=9A=D0=9E=D0=90=D0=9F =D0=A0=D0=A4. = =D0=92=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D1=8B=D0=B9 = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=BE=D0=BB=D1=8C =D0=B2 = =D0=BD=D0=B5=D1=82=D0=BE=D1=80=D0=B3=D0=BE=D0=B2=D0=BE=D0=BC = =D0=BE=D0=B1=D0=BE=D1=80=D0=BE=D1=82=D0=B5.=20 3.=D0=92=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D1=8B=D0=B9 = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=BE=D0=BB=D1=8C =D0=BF=D1=80=D0=B8 = =D0=BE=D1=81=D1=83=D1=89=D0=B5=D1=81=D1=82=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0= =B8 =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D1=8B=D1=85 = =D0=BE=D0=BF=D0=B5=D1=80=D0=B0=D1=86=D0=B8=D0=B9, = =D1=81=D0=B2=D1=8F=D0=B7=D0=B0=D0=BD=D0=BD=D1=8B=D1=85 =D1=81 = =D0=B2=D0=BD=D0=B5=D1=88=D0=BD=D0=B5=D1=82=D0=BE=D1=80=D0=B3=D0=BE=D0=B2=D0= =BE=D0=B9 = =D0=B4=D0=B5=D1=8F=D1=82=D0=B5=D0=BB=D1=8C=D0=BD=D0=BE=D1=81=D1=82=D1=8C=D1= =8E, =D0=BF=D0=BE=D0=BB=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D0=B5=D0=BC =D0=B8 = =D0=BF=D1=80=D0=B5=D0=B4=D0=BE=D1=81=D1=82=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0= =B8=D0=B5=D0=BC =D0=BA=D1=80=D0=B5=D0=B4=D0=B8=D1=82=D0=BE=D0=B2 =D0=B8 = =D0=B7=D0=B0=D0=B9=D0=BC=D0=BE=D0=B2. =D0=9F=D0=B0=D1=81=D0=BF=D0=BE=D1=80=D1=82 = =D1=81=D0=B4=D0=B5=D0=BB=D0=BA=D0=B8: = =D0=9E=D1=84=D0=BE=D1=80=D0=BC=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5 =D0=B8 = =D0=B2=D0=B5=D0=B4=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=BF=D0=B0=D1=81=D0=BF=D0=BE=D1=80=D1=82=D0=B0 = =D1=81=D0=B4=D0=B5=D0=BB=D0=BA=D0=B8 =D0=B2 = =D1=86=D0=B5=D0=BB=D1=8F=D1=85 = =D0=BE=D0=B1=D0=B5=D1=81=D0=BF=D0=B5=D1=87=D0=B5=D0=BD=D0=B8=D1=8F = =D1=83=D1=87=D0=B5=D1=82=D0=B0 =D0=B8 = =D0=BE=D1=82=D1=87=D0=B5=D1=82=D0=BD=D0=BE=D1=81=D1=82=D0=B8 =D0=B8 = =D0=BE=D1=81=D1=83=D1=89=D0=B5=D1=81=D1=82=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D1= =8F =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=B3=D0=BE = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=BE=D0=BB=D1=8F =D0=BF=D0=BE = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D1=8B=D0=BC = =D0=BE=D0=BF=D0=B5=D1=80=D0=B0=D1=86=D0=B8=D1=8F=D0=BC = =D0=BC=D0=B5=D0=B6=D0=B4=D1=83 = =D1=80=D0=B5=D0=B7=D0=B8=D0=B4=D0=B5=D0=BD=D1=82=D0=B0=D0=BC=D0=B8 = =D0=B8 = =D0=BD=D0=B5=D1=80=D0=B5=D0=B7=D0=B8=D0=B4=D0=B5=D0=BD=D1=82=D0=B0=D0=BC=D0= =B8. = =D0=9F=D1=80=D0=B5=D0=B4=D1=81=D1=82=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0= =B5 =D1=80=D0=B5=D0=B7=D0=B8=D0=B4=D0=B5=D0=BD=D1=82=D0=B0=D0=BC=D0=B8 = =D0=B2 = =D1=83=D0=BF=D0=BE=D0=BB=D0=BD=D0=BE=D0=BC=D0=BE=D1=87=D0=B5=D0=BD=D0=BD=D1= =8B=D0=B9 =D0=B1=D0=B0=D0=BD=D0=BA = =D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B8 =D0=BE = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D1=8B=D1=85 =D0=BE=D0=BF=D0=B5=D1=80=D0=B0=D1=86=D0=B8=D1=8F=D1=85 =D0=B8 = =D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B8 =D0=BE = =D0=BF=D0=BE=D0=B4=D1=82=D0=B2=D0=B5=D1=80=D0=B6=D0=B4=D0=B0=D1=8E=D1=89=D0= =B8=D1=85 =D0=B4=D0=BE=D0=BA=D1=83=D0=BC=D0=B5=D0=BD=D1=82=D0=B0=D1=85 = =D0=BF=D1=80=D0=B8 = =D0=BE=D1=81=D1=83=D1=89=D0=B5=D1=81=D1=82=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0= =B8 = =D0=B2=D0=BD=D0=B5=D1=88=D0=BD=D0=B5=D1=82=D0=BE=D1=80=D0=B3=D0=BE=D0=B2=D0= =BE=D0=B9 = =D0=B4=D0=B5=D1=8F=D1=82=D0=B5=D0=BB=D1=8C=D0=BD=D0=BE=D1=81=D1=82=D0=B8.= = 4.=D0=9A=D0=BB=D0=B0=D1=81=D1=81=D0=B8=D1=84=D0=B8=D0=BA=D0=B0=D1=86=D0=B8= =D1=8F =D0=B8 = =D1=81=D0=BE=D0=B4=D0=B5=D1=80=D0=B6=D0=B0=D0=BD=D0=B8=D0=B5 = =D0=BF=D1=80=D0=B0=D0=B2=D0=BE=D0=BD=D0=B0=D1=80=D1=83=D1=88=D0=B5=D0=BD=D0= =B8=D0=B9 =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=B3=D0=BE = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D0=BE=D0=B4=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=D1= =81=D1=82=D0=B2=D0=B0 =D1=81 =D1=83=D1=87=D0=B5=D1=82=D0=BE=D0=BC =D0=BF=D0=BE=D1=81=D0=BB=D0=B5=D0=B4=D0=BD=D0=B8=D1=85 = =D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D0=B9 = =D0=BD=D0=BE=D1=80=D0=BC=D0=B0=D1=82=D0=B8=D0=B2=D0=BD=D0=BE=D0=B9 = =D0=BF=D1=80=D0=B0=D0=B2=D0=BE=D0=B2=D0=BE=D0=B9 = =D0=B1=D0=B0=D0=B7=D1=8B.=20 = =D0=93=D0=BE=D1=81=D1=83=D0=B4=D0=B0=D1=80=D1=81=D1=82=D0=B2=D0=B5=D0=BD=D0= =BD=D1=8B=D0=B9 = =D1=84=D0=B8=D0=BD=D0=B0=D0=BD=D1=81=D0=BE=D0=B2=D1=8B=D0=B9 = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=BE=D0=BB=D1=8C =D0=B7=D0=B0 = =D0=BE=D1=81=D1=83=D1=89=D0=B5=D1=81=D1=82=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0= =B5=D0=BC =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D1=8B=D1=85 = =D0=BE=D0=BF=D0=B5=D1=80=D0=B0=D1=86=D0=B8=D0=B9 = =D1=80=D0=B5=D0=B7=D0=B8=D0=B4=D0=B5=D0=BD=D1=82=D0=B0=D0=BC=D0=B8 = =D0=B8 = =D0=BD=D0=B5=D1=80=D0=B5=D0=B7=D0=B8=D0=B4=D0=B5=D0=BD=D1=82=D0=B0=D0=BC=D0= =B8, =D0=BD=D0=B5 = =D1=8F=D0=B2=D0=BB=D1=8F=D1=8E=D1=89=D0=B8=D0=BC=D0=B8=D1=81=D1=8F = =D0=BA=D1=80=D0=B5=D0=B4=D0=B8=D1=82=D0=BD=D1=8B=D0=BC=D0=B8 = =D0=BE=D1=80=D0=B3=D0=B0=D0=BD=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D1=8F=D0=BC=D0= =B8 =D0=B8 =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D1=8B=D0=BC=D0=B8 = =D0=B1=D0=B8=D1=80=D0=B6=D0=B0=D0=BC=D0=B8. = =D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F =D0=B2 =D0=A4=D0=B5=D0=B4=D0=B5=D1=80=D0=B0=D0=BB=D1=8C=D0=BD=D1=8B=D0=B9 = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD =D0=BE=D1=82 08.12.2003 = =D0=B3=D0=BE=D0=B4=D0=B0 =E2=84=96 164-=D0=A4=D0=97 "=D0=9E=D0=B1 = =D0=BE=D1=81=D0=BD=D0=BE=D0=B2=D0=B0=D1=85 = =D0=B3=D0=BE=D1=81=D1=83=D0=B4=D0=B0=D1=80=D1=81=D1=82=D0=B2=D0=B5=D0=BD=D0= =BD=D0=BE=D0=B3=D0=BE = =D1=80=D0=B5=D0=B3=D1=83=D0=BB=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1= =8F = =D0=B2=D0=BD=D0=B5=D1=88=D0=BD=D0=B5=D1=82=D0=BE=D1=80=D0=B3=D0=BE=D0=B2=D0= =BE=D0=B9 = =D0=B4=D0=B5=D1=8F=D1=82=D0=B5=D0=BB=D1=8C=D0=BD=D0=BE=D1=81=D1=82=D0=B8"= , =D0=B2 =D0=9A=D0=BE=D0=B4=D0=B5=D0=BA=D1=81 = =D0=A0=D0=BE=D1=81=D1=81=D0=B8=D0=B9=D1=81=D0=BA=D0=BE=D0=B9 = =D0=A4=D0=B5=D0=B4=D0=B5=D1=80=D0=B0=D1=86=D0=B8=D0=B8 =D0=BE=D0=B1 = =D0=B0=D0=B4=D0=BC=D0=B8=D0=BD=D0=B8=D1=81=D1=82=D1=80=D0=B0=D1=82=D0=B8=D0= =B2=D0=BD=D1=8B=D1=85 = =D0=BF=D1=80=D0=B0=D0=B2=D0=BE=D0=BD=D0=B0=D1=80=D1=83=D1=88=D0=B5=D0=BD=D0= =B8=D1=8F=D1=85, =D0=B2 = =D0=A4=D0=B5=D0=B4=D0=B5=D1=80=D0=B0=D0=BB=D1=8C=D0=BD=D1=8B=D0=B9 = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD =D0=BE=D1=82 10.12.2003 = =D0=B3=D0=BE=D0=B4=D0=B0 =E2=84=96 173-=D0=A4=D0=97 "=D0=9E = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=BC = =D1=80=D0=B5=D0=B3=D1=83=D0=BB=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0= =B8 =D0=B8 =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=BC = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=BE=D0=BB=D0=B5" =D0=B8 = =D0=B4=D1=80=D1=83=D0=B3=D0=B8=D0=B5 = =D0=BD=D0=BE=D1=80=D0=BC=D0=B0=D1=82=D0=B8=D0=B2=D0=BD=D1=8B=D0=B5 = =D0=BF=D1=80=D0=B0=D0=B2=D0=BE=D0=B2=D1=8B=D0=B5 = =D0=B0=D0=BA=D1=82=D1=8B, = =D1=81=D0=B2=D1=8F=D0=B7=D0=B0=D0=BD=D0=BD=D1=8B=D0=B5 =D1=81 = =D0=BF=D1=80=D0=B8=D0=BD=D1=8F=D1=82=D0=B8=D0=B5=D0=BC =D1=84=D0=B5=D0=B4=D0=B5=D1=80=D0=B0=D0=BB=D1=8C=D0=BD=D1=8B=D1=85 = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D0=BE=D0=B2. = =D0=92=D1=8B=D1=8F=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5 =D0=B8 = =D0=BF=D1=80=D0=B5=D1=81=D0=B5=D1=87=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=BD=D0=B0=D1=80=D1=83=D1=88=D0=B5=D0=BD=D0=B8=D0=B9 = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=B3=D0=BE = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D0=BE=D0=B4=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=D1= =81=D1=82=D0=B2=D0=B0 =D0=A0=D0=BE=D1=81=D1=81=D0=B8=D0=B9=D1=81=D0=BA=D0=BE=D0=B9 = =D0=A4=D0=B5=D0=B4=D0=B5=D1=80=D0=B0=D1=86=D0=B8=D0=B8 =D0=B8 = =D0=B0=D0=BA=D1=82=D0=BE=D0=B2 = =D0=BE=D1=80=D0=B3=D0=B0=D0=BD=D0=BE=D0=B2 = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=B3=D0=BE = =D1=80=D0=B5=D0=B3=D1=83=D0=BB=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1= =8F.=20 = 5.=D0=9E=D1=82=D0=B2=D0=B5=D1=82=D1=81=D1=82=D0=B2=D0=B5=D0=BD=D0=BD=D0=BE= =D1=81=D1=82=D1=8C =D0=B7=D0=B0 = =D0=BD=D0=B0=D1=80=D1=83=D1=88=D0=B5=D0=BD=D0=B8=D1=8F = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=B3=D0=BE = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D0=BE=D0=B4=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=D1= =81=D1=82=D0=B2=D0=B0 =D0=B8 =D0=B0=D0=BA=D1=82=D0=BE=D0=B2 = =D0=BE=D1=80=D0=B3=D0=B0=D0=BD=D0=BE=D0=B2 = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=B3=D0=BE = =D1=80=D0=B5=D0=B3=D1=83=D0=BB=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1= =8F. =D0=9C=D0=B8=D0=BD=D0=B8=D0=BC=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D1=8F = =D1=80=D0=B8=D1=81=D0=BA=D0=BE=D0=B2, = =D1=81=D0=B2=D1=8F=D0=B7=D0=B0=D0=BD=D0=BD=D1=8B=D1=85 =D1=81 = =D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D0=B4=D0=B5=D0=BD=D0=B8=D0=B5=D0=BC = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D1=8B=D1=85 = =D0=BE=D0=BF=D0=B5=D1=80=D0=B0=D1=86=D0=B8=D0=B9 =D0=BF=D1=80=D0=B8 = =D0=BE=D1=81=D1=83=D1=89=D0=B5=D1=81=D1=82=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0= =B8 = =D0=B2=D0=BD=D0=B5=D1=88=D0=BD=D0=B5=D1=8D=D0=BA=D0=BE=D0=BD=D0=BE=D0=BC=D0= =B8=D1=87=D0=B5=D1=81=D0=BA=D0=BE=D0=B9 = =D0=B4=D0=B5=D1=8F=D1=82=D0=B5=D0=BB=D1=8C=D0=BD=D0=BE=D1=81=D1=82=D0=B8.= = =D0=9F=D1=80=D0=B5=D0=B4=D1=83=D0=BF=D1=80=D0=B5=D0=B6=D0=B4=D0=B5=D0=BD=D0= =B8=D0=B5 = =D0=BF=D1=80=D0=B0=D0=B2=D0=BE=D0=BD=D0=B0=D1=80=D1=83=D1=88=D0=B5=D0=BD=D0= =B8=D0=B9 =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=B3=D0=BE = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D0=BE=D0=B4=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=D1= =81=D1=82=D0=B2=D0=B0 = =D0=A0=D0=BE=D1=81=D1=81=D0=B8=D0=B9=D1=81=D0=BA=D0=BE=D0=B9 = =D0=A4=D0=B5=D0=B4=D0=B5=D1=80=D0=B0=D1=86=D0=B8=D0=B8 =D0=B8 = =D0=B0=D0=BA=D1=82=D0=BE=D0=B2 = =D0=BE=D1=80=D0=B3=D0=B0=D0=BD=D0=BE=D0=B2 = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=B3=D0=BE = =D1=80=D0=B5=D0=B3=D1=83=D0=BB=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1= =8F. =D0=9A=D0=BE=D0=BC=D0=BF=D0=BB=D0=B5=D0=BA=D1=81 = =D0=BC=D0=B5=D1=80 =D0=BF=D0=BE = =D1=81=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD=D0=B8=D1=8E = =D0=B2=D0=BD=D1=83=D1=82=D1=80=D0=B8=D1=84=D0=B8=D1=80=D0=BC=D0=B5=D0=BD=D0= =BD=D0=BE=D0=B9 =D1=81=D0=B8=D1=81=D1=82=D0=B5=D0=BC=D1=8B = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=B3=D0=BE = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=BE=D0=BB=D1=8F. = =D0=9C=D0=B5=D1=81=D1=82=D0=BE = =D0=B2=D0=BD=D1=83=D1=82=D1=80=D0=B8=D1=84=D0=B8=D1=80=D0=BC=D0=B5=D0=BD=D0= =BD=D0=BE=D0=B9 =D1=81=D0=B8=D1=81=D1=82=D0=B5=D0=BC=D1=8B = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=B3=D0=BE = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=BE=D0=BB=D1=8F =D0=B2 = =D0=BE=D1=80=D0=B3=D0=B0=D0=BD=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D0=BE=D0=BD=D0= =BD=D0=BE=D0=B9 =D1=81=D1=82=D1=80=D1=83=D0=BA=D1=82=D1=83=D1=80=D0=B5 =D0=BF=D1=80=D0=B5=D0=B4=D0=BF=D1=80=D0=B8=D1=8F=D1=82=D0=B8=D1=8F = (=D0=BE=D1=80=D0=B3=D0=B0=D0=BD=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D0=B8). = =D0=A2=D1=80=D0=B5=D0=B1=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D0=BE=D0=B4=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=D1= =81=D1=82=D0=B2=D0=B0 =D0=BA = =D1=83=D1=81=D0=BB=D0=BE=D0=B2=D0=B8=D1=8F=D0=BC = =D0=B7=D0=B0=D0=BA=D0=BB=D1=8E=D1=87=D0=B0=D0=B5=D0=BC=D1=8B=D1=85 = =D0=B2=D0=BE = =D0=B2=D0=BD=D0=B5=D1=88=D0=BD=D0=B5=D1=82=D0=BE=D1=80=D0=B3=D0=BE=D0=B2=D0= =BE=D0=B9 = =D0=B4=D0=B5=D1=8F=D1=82=D0=B5=D0=BB=D1=8C=D0=BD=D0=BE=D1=81=D1=82=D0=B8 = =D0=B4=D0=BE=D0=B3=D0=BE=D0=B2=D0=BE=D1=80=D0=BE=D0=B2 = (=D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=B0=D0=BA=D1=82=D0=BE=D0=B2).=20 6.=D0=9F=D0=BE=D1=80=D1=8F=D0=B4=D0=BE=D0=BA = =D0=B2=D0=B7=D0=B0=D0=B8=D0=BC=D0=BE=D0=B4=D0=B5=D0=B9=D1=81=D1=82=D0=B2=D0= =B8=D1=8F = =D0=A0=D0=BE=D1=81=D1=84=D0=B8=D0=BD=D0=BD=D0=B0=D0=B4=D0=B7=D0=BE=D1=80=D0= =B0 =D1=81 =D0=91=D0=B0=D0=BD=D0=BA=D0=BE=D0=BC = =D0=A0=D0=BE=D1=81=D1=81=D0=B8=D0=B8, = =D1=82=D0=B0=D0=BC=D0=BE=D0=B6=D0=B5=D0=BD=D0=BD=D1=8B=D0=BC=D0=B8 = =D0=B8 =D0=BD=D0=B0=D0=BB=D0=BE=D0=B3=D0=BE=D0=B2=D1=8B=D0=BC=D0=B8 =D0=BE=D1=80=D0=B3=D0=B0=D0=BD=D0=B0=D0=BC=D0=B8, = =D1=83=D0=BF=D0=BE=D0=BB=D0=BD=D0=BE=D0=BC=D0=BE=D1=87=D0=B5=D0=BD=D0=BD=D1= =8B=D0=BC=D0=B8 =D0=B1=D0=B0=D0=BD=D0=BA=D0=B0=D0=BC=D0=B8, =D0=B0 = =D1=82=D0=B0=D0=BA=D0=B6=D0=B5 = =D0=BF=D1=80=D0=BE=D1=84=D0=B5=D1=81=D1=81=D0=B8=D0=BE=D0=BD=D0=B0=D0=BB=D1= =8C=D0=BD=D1=8B=D0=BC=D0=B8 = =D1=83=D1=87=D0=B0=D1=81=D1=82=D0=BD=D0=B8=D0=BA=D0=B0=D0=BC=D0=B8 = =D1=80=D1=8B=D0=BD=D0=BA=D0=B0 =D1=86=D0=B5=D0=BD=D0=BD=D1=8B=D1=85 = =D0=B1=D1=83=D0=BC=D0=B0=D0=B3, =D0=BA=D0=B0=D0=BA = =D0=B0=D0=B3=D0=B5=D0=BD=D1=82=D0=B0=D0=BC=D0=B8 = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=B3=D0=BE = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=BE=D0=BB=D1=8F.=20 =D0=9F=D1=80=D0=B0=D0=B2=D0=B8=D0=BB=D0=B0 = =D0=BF=D1=80=D0=B5=D0=B4=D1=81=D1=82=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D1= =8F =D0=BE=D1=80=D0=B3=D0=B0=D0=BD=D0=B0=D0=BC=D0=B8 =D0=B8 = =D0=B0=D0=B3=D0=B5=D0=BD=D1=82=D0=B0=D0=BC=D0=B8 = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=B3=D0=BE = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=BE=D0=BB=D1=8F =D0=B2 = =D1=83=D0=BF=D0=BE=D0=BB=D0=BD=D0=BE=D0=BC=D0=BE=D1=87=D0=B5=D0=BD=D0=BD=D1= =8B=D0=B9 = =D0=9F=D1=80=D0=B0=D0=B2=D0=B8=D1=82=D0=B5=D0=BB=D1=8C=D1=81=D1=82=D0=B2=D0= =BE=D0=BC =D0=A0=D0=BE=D1=81=D1=81=D0=B8=D0=B9=D1=81=D0=BA=D0=BE=D0=B9 = =D0=A4=D0=B5=D0=B4=D0=B5=D1=80=D0=B0=D1=86=D0=B8=D0=B8 = =D0=BE=D1=80=D0=B3=D0=B0=D0=BD = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=B3=D0=BE = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=BE=D0=BB=D1=8F = (=D0=A0=D0=BE=D1=81=D1=84=D0=B8=D0=BD=D0=BD=D0=B0=D0=B4=D0=B7=D0=BE=D1=80= ) =D0=BD=D0=B5=D0=BE=D0=B1=D1=85=D0=BE=D0=B4=D0=B8=D0=BC=D1=8B=D1=85 =D0=B4=D0=BE=D0=BA=D1=83=D0=BC=D0=B5=D0=BD=D1=82=D0=BE=D0=B2 = =D0=B8 =D0=B8=D0=BD=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=86=D0=B8=D0=B8. = =D0=9E=D1=82=D0=B4=D0=B5=D0=BB=D1=8C=D0=BD=D1=8B=D0=B5 = =D0=B2=D0=BE=D0=BF=D1=80=D0=BE=D1=81=D1=8B = =D0=B8=D1=81=D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D1=83=D0=B5=D0=BC=D1=8B=D1=85 = =D0=B2 =D1=81=D1=84=D0=B5=D1=80=D0=B5 = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=B3=D0=BE = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=BE=D0=BB=D1=8F = =D0=B8=D0=BD=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=86=D0=B8=D0=BE=D0=BD=D0=BD=D1= =8B=D1=85 =D1=82=D0=B5=D1=85=D0=BD=D0=BE=D0=BB=D0=BE=D0=B3=D0=B8=D0=B9. = =D0=9F=D0=BB=D0=B0=D0=BD=D0=B8=D1=80=D1=83=D0=B5=D0=BC=D1=8B=D0=B5 = =D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F, = =D0=BA=D0=B0=D1=81=D0=B0=D1=8E=D1=89=D0=B8=D0=B5=D1=81=D1=8F = =D1=83=D1=81=D1=82=D0=B0=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F = =D0=BD=D0=BE=D0=B2=D0=BE=D0=B3=D0=BE =D0=BF=D0=BE=D1=80=D1=8F=D0=B4=D0=BA=D0=B0 = =D0=BF=D0=B5=D1=80=D0=B5=D0=B4=D0=B0=D1=87=D0=B8 = =D0=B4=D0=BE=D0=BA=D1=83=D0=BC=D0=B5=D0=BD=D1=82=D0=BE=D0=B2 =D0=B8 = =D0=B8=D0=BD=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=86=D0=B8=D0=B8 = =D0=BC=D0=B5=D0=B6=D0=B4=D1=83 =D0=91=D0=B0=D0=BD=D0=BA=D0=BE=D0=BC = =D0=A0=D0=BE=D1=81=D1=81=D0=B8=D0=B8, = =D1=83=D0=BF=D0=BE=D0=BB=D0=BD=D0=BE=D0=BC=D0=BE=D1=87=D0=B5=D0=BD=D0=BD=D1= =8B=D0=BC=D0=B8 =D0=B1=D0=B0=D0=BD=D0=BA=D0=B0=D0=BC=D0=B8 =D0=B8 = =D0=A0=D0=BE=D1=81=D1=84=D0=B8=D0=BD=D0=BD=D0=B0=D0=B4=D0=B7=D0=BE=D1=80=D0= =BE=D0=BC; =D0=BC=D0=B5=D0=B6=D0=B4=D1=83 =D0=A4=D0=A1=D0=A1=D0=9F = =D0=A0=D0=BE=D1=81=D1=81=D0=B8=D0=B8 =D0=B8 = =D0=A0=D0=BE=D1=81=D1=84=D0=B8=D0=BD=D0=BD=D0=B0=D0=B4=D0=B7=D0=BE=D1=80=D0= =BE=D0=BC; =D0=BC=D0=B5=D0=B6=D0=B4=D1=83 = =D1=82=D0=B0=D0=BC=D0=BE=D0=B6=D0=B5=D0=BD=D0=BD=D1=8B=D0=BC=D0=B8 = =D0=B8 =D0=BD=D0=B0=D0=BB=D0=BE=D0=B3=D0=BE=D0=B2=D1=8B=D0=BC=D0=B8 =D0=BE=D1=80=D0=B3=D0=B0=D0=BD=D0=B0=D0=BC=D0=B8 =D0=B8 = =D0=A0=D0=BE=D1=81=D1=84=D0=B8=D0=BD=D0=BD=D0=B0=D0=B4=D0=B7=D0=BE=D1=80=D0= =BE=D0=BC.=20 =20 =D0=A3=D1=87=D0=B0=D1=81=D1=82=D0=B8=D0=B5 = =D1=81=D0=BE=D1=81=D1=82=D0=B0=D0=B2=D0=BB=D1=8F=D0=B5=D1=82: 11800 = =D1=80=D1=83=D0=B1=D0=BB=D0=B5=D0=B9. =D0=92 = =D0=BC=D0=B5=D1=80=D0=BE=D0=BF=D1=80=D0=B8=D1=8F=D1=82=D0=B8=D0=B5 = =D0=B2=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D0=BE: = =D0=BC=D0=B5=D1=82=D0=BE=D0=B4=D0=B8=D1=87=D0=B5=D1=81=D0=BA=D0=B8=D0=B9 = =D0=BC=D0=B0=D1=82=D0=B5=D1=80=D0=B8=D0=B0=D0=BB, = =D0=BE=D0=B1=D0=B5=D0=B4=D1=8B, = =D0=BA=D0=BE=D1=84=D0=B5-=D0=BF=D0=B0=D1=83=D0=B7=D1=8B. =D0=9F=D0=BE=D1=81=D0=BB=D0=B5 = =D0=BE=D0=BA=D0=BE=D0=BD=D1=87=D0=B0=D0=BD=D0=B8=D1=8F = =D0=B7=D0=B0=D0=BD=D1=8F=D1=82=D0=B8=D1=8F =D0=92=D0=B0=D0=BC = =D0=B2=D1=8B=D0=B4=D0=B0=D0=B5=D1=82=D1=81=D1=8F = =D1=81=D0=B5=D1=80=D1=82=D0=B8=D1=84=D0=B8=D0=BA=D0=B0=D1=82 = =D1=83=D1=81=D1=82=D0=B0=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=D0=BD=D0=BE=D0= =B3=D0=BE =D0=BE=D0=B1=D1=80=D0=B0=D0=B7=D1=86=D0=B0. =D0=98=D0=BD=D0=BE=D0=B3=D0=BE=D1=80=D0=BE=D0=B4=D0=BD=D0=B8=D0=BC = =D1=83=D1=87=D0=B0=D1=81=D1=82=D0=BD=D0=B8=D0=BA=D0=B0=D0=BC = =D0=BF=D0=BE=D0=BC=D0=BE=D0=B3=D0=B0=D0=B5=D0=BC =D0=B2 = =D0=B1=D1=80=D0=BE=D0=BD=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B8 = =D0=B3=D0=BE=D1=81=D1=82=D0=B8=D0=BD=D0=B8=D1=86=D1=8B. =20 =20 =20 ------=_NextPart_000_0047_01D121CF.401CC830 Content-Type: text/html; charset="utf-8" Content-Transfer-Encoding: quoted-printable
     


=D0=9F =D1=80 =D0=BE =D0=BC =D0=BE =D0=BA =D0=BE =D0=B4 : = 256

     
      =D0=90=D0=BA=D0=BA=D1=80=D0=B5=D0=B4=D0=B8=D1=82=D0=BE=D0=B2=D0=B0=D0=BD= =D0=BD=D1=8B=D0=B9 =D0=A3=D1=87=D0=B5=D0=B1=D0=BD=D1=8B=D0=B9 = =D1=86=D0=B5=D0=BD=D1=82=D1=80 = =D0=BF=D1=80=D0=B8=D0=B3=D0=BB=D0=B0=D1=88=D0=B0=D0=B5=D1=82 = =D0=BD=D0=B0=20 = =D0=BE=D0=B1=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D0=B5:

=D0=A6=D0=B5=D0=BB=D1=8C=20 =D0=B7=D0=B0=D0=BD=D1=8F=D1=82=D0=B8=D1=8F: = =D0=BE=D0=B1=D1=81=D1=83=D0=B4=D0=B8=D1=82=D1=8C = =D0=B0=D0=BA=D1=82=D1=83=D0=B0=D0=BB=D1=8C=D0=BD=D1=8B=D0=B5 = =D0=B2=D0=BE=D0=BF=D1=80=D0=BE=D1=81=D1=8B, = =D0=B8=D0=BC=D0=B5=D1=8E=D1=89=D0=B8=D0=B5 = =D0=BF=D1=80=D0=B0=D0=BA=D1=82=D0=B8=D1=87=D0=B5=D1=81=D0=BA=D1=83=D1=8E = = =D0=BD=D0=B0=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=BD=D0=BE=D1=81=D1= =82=D1=8C = =D0=B8
=D1=81=D0=B2=D1=8F=D0=B7=D0=B0=D0=BD=D0=BD=D1=8B=D0=B5 =D1=81 = =D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5=D0=BC = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=B3=D0=BE = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D0=BE=D0=B4=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=D1= =81=D1=82=D0=B2=D0=B0 =D0=B2=20 =D0=A0=D0=A4, =D0=BF=D0=BE=D0=BB=D1=83=D1=87=D0=B8=D1=82=D1=8C = =D0=B7=D0=BD=D0=B0=D0=BD=D0=B8=D1=8F, = =D0=BA=D0=BE=D1=82=D0=BE=D1=80=D1=8B=D0=B5 = =D0=BF=D0=BE=D0=B7=D0=B2=D0=BE=D0=BB=D1=8F=D1=82
=D0=B8=D0=B7=D0=B1=D0= =B5=D0=B6=D0=B0=D1=82=D1=8C = =D1=82=D0=B8=D0=BF=D0=B8=D1=87=D0=BD=D1=8B=D1=85 = =D0=BE=D1=88=D0=B8=D0=B1=D0=BE=D0=BA =D0=B8=20 =D0=BD=D0=B0=D1=80=D1=83=D1=88=D0=B5=D0=BD=D0=B8=D0=B9 = =D0=BF=D1=80=D0=B8 = =D1=81=D0=BE=D0=B2=D0=B5=D1=80=D1=88=D0=B5=D0=BD=D0=B8=D0=B8 =D0=B8 = =D0=BE=D1=84=D0=BE=D1=80=D0=BC=D0=BB=D0=B5=D0=BD=D0=B8=D0=B8 = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D1=8B=D1=85 = =D0=BE=D0=BF=D0=B5=D1=80=D0=B0=D1=86=D0=B8=D0=B9.

=D0=9F=D1=80=D0=B5=D0=B4=D0=BD=D0=B0=D0=B7=D0=BD=D0=B0=D1=87=D0= =B5=D0=BD=D0=BE =D0=B4=D0=BB=D1=8F: = =D1=81=D0=BE=D0=B1=D1=81=D1=82=D0=B2=D0=B5=D0=BD=D0=BD=D0=B8=D0=BA= =D0=BE=D0=B2=20 =D0=B1=D0=B8=D0=B7=D0=BD=D0=B5=D1=81=D0=B0, = =D1=84=D0=B8=D0=BD=D0=B0=D0=BD=D1=81=D0=BE=D0=B2=D1=8B=D1=85 =D0=B8 = =D0=BA=D0=BE=D0=BC=D0=BC=D0=B5=D1=80=D1=87=D0=B5=D1=81=D0=BA=D0=B8=D1=85 = =D0=B4=D0=B8=D1=80=D0=B5=D0=BA=D1=82=D0=BE=D1=80=D0=BE=D0=B2,
=D1=80=D1= =83=D0=BA=D0=BE=D0=B2=D0=BE=D0=B4=D0=B8=D1=82=D0=B5=D0=BB=D0=B5=D0=B9=20 = =D1=84=D0=B8=D0=BD=D0=B0=D0=BD=D1=81=D0=BE=D0=B2=D0=BE-=D1=8D=D0=BA=D0=BE= =D0=BD=D0=BE=D0=BC=D0=B8=D1=87=D0=B5=D1=81=D0=BA=D0=B8=D1=85 = =D1=81=D0=BB=D1=83=D0=B6=D0=B1 = =D0=BF=D1=80=D0=B5=D0=B4=D0=BF=D1=80=D0=B8=D1=8F=D1=82=D0=B8=D0=B9 = =D0=B8 = =D0=BE=D1=80=D0=B3=D0=B0=D0=BD=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D0=B9,=20 = =D1=83=D1=87=D0=B0=D1=81=D1=82=D0=BD=D0=B8=D0=BA=D0=BE=D0=B2
=D0=B2=D0= =BD=D0=B5=D1=88=D0=BD=D0=B5=D1=8D=D0=BA=D0=BE=D0=BD=D0=BE=D0=BC=D0=B8=D1=87= =D0=B5=D1=81=D0=BA=D0=BE=D0=B9 = =D0=B4=D0=B5=D1=8F=D1=82=D0=B5=D0=BB=D1=8C=D0=BD=D0=BE=D1=81=D1=82=D0=B8,= =D0=B1=D0=B0=D0=BD=D0=BA=D0=BE=D0=B2=D1=81=D0=BA=D0=B8=D1=85=20 = =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BD=D0=B8=D0=BA=D0=BE=D0=B2.

=D0=A2=D0=B5=D0=BC=D0=B0:   =D0=92=D0=90=D0=9B=D0=AE=D0=A2=D0=9D=D0=9E=D0=95 = =D0=A0=D0=95=D0=93=D0=A3=D0=9B=D0=98=D0=A0=D0=9E=D0=92=D0=90=D0=9D=D0=98=D0= =95 =D0=98=20 = =D0=92=D0=90=D0=9B=D0=AE=D0=A2=D0=9D=D0=AB=D0=99
=D0=9A=D0=9E=D0=9D=D0= =A2=D0=A0=D0=9E=D0=9B=D0=AC =D0=92 =D0=A0=D0=A4 =D0=A1 = =D0=A3=D0=A7=D0=95=D0=A2=D0=9E=D0=9C = =D0=9F=D0=9E=D0=A1=D0=9B=D0=95=D0=94=D0=9D=D0=98=D0=A5=20 = =D0=98=D0=97=D0=9C=D0=95=D0=9D=D0=95=D0=9D=D0=98=D0=99
=D0=97=D0=90=D0= =9A=D0=9E=D0=9D=D0=9E=D0=94=D0=90=D0=A2=D0=95=D0=9B=D0=AC=D0=A1=D0=A2=D0=92= =D0=90



=D0=97=D0=B0=D0=BD=D1=8F=D1=82=D0=B8=D0=B5 = =D1=81=D0=BE=D1=81=D1=82=D0=BE=D0=B8=D1=82=D1=81=D1=8F: 04=20 =D0=B4=D0=B5=D0=BA=D0=B0=D0=B1=D1=80=D1=8F 2015 = =D0=B3=D0=BE=D0=B4=D0=B0 =

=D0=9E=D0=B1=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D0=B5=20 =D0=BF=D1=80=D0=BE=D0=B2=D0=BE=D0=B4=D0=B8=D1=82=D1=81=D1=8F: c 10:00 =D0=B4=D0=BE=20 17:30

=D0=90=D0=B4=D1=80=D0=B5=D1=81 = =D0=BC=D0=B5=D1=80=D0=BE=D0=BF=D1=80=D0=B8=D1=8F=D1=82=D0=B8=D1=8F: = =D0=B3. =D0=9C=D0=BE=D1=81=D0=BA=D0=B2=D0=B0, =D0=BC.=20 =D0=91=D0=B0=D1=83=D0=BC=D0=B0=D0=BD=D1=81=D0=BA=D0=B0=D1=8F, = =D1=83=D0=BB. = =D0=91=D0=B0=D1=83=D0=BC=D0=B0=D0=BD=D1=81=D0=BA=D0=B0=D1=8F, =D0=B4.6, = =D0=91.=D0=A6. "=D0=92=D0=B8=D0=BA=D1=82=D0=BE=D1=80=D0=B8=D1=8F=20 =D0=9F=D0=BB=D0=B0=D0=B7=D0=B0".

=D0=92=D1=81=D1=8F = =D0=B8=D0=BD=D1=82=D0=B5=D1=80=D0=B5=D1=81=D1=83=D1=8E=D1=89=D0=B0=D1=8F = =D0=92=D0=B0=D1=81 = =D0=B8=D0=BD=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=86=D0=B8=D1=8F =D0=BE=20 =D0=BF=D1=80=D0=BE=D0=B3=D1=80=D0=B0=D0=BC=D0=BC=D0=B5 =D0=B8 = =D0=B7=D0=B0=D1=8F=D0=B2=D0=BA=D0=B8 =D0=BD=D0=B0 = =D1=83=D1=87=D0=B0=D1=81=D1=82=D0=B8=D0=B5 = =D0=BF=D1=80=D0=B8=D0=BD=D0=B8=D0=BC=D0=B0=D1=8E=D1=82=D1=81=D1=8F = =D0=BF=D0=BE =D0=BD=D0=BE=D0=BC=D0=B5=D1=80=D1=83:

 =D0=BA=D0=BE=D0=B4 = =D0=B3=D0=BE=D1=80=D0=BE=D0=B4=D0=B0  (=20 4 9 5 )  =D1=82=D0=B5=D0=BB=D0=B5=D1=84=D0=BE=D0=BD  725 -=20 04 - 48 =20 = (=D0=BC=D0=BD=D0=BE=D0=B3=D0=BE=D0=BA=D0=B0=D0=BD=D0=B0=D0=BB=D1=8C=D0=BD= =D1=8B=D0=B9)
 
     
             
     


=D0=9F=D1=80=D0=BE=D0=B3=D1=80=D0=B0=D0=BC=D0=BC=D0=B0 = (=D1=81=D0=BE=D0=BA=D1=80=D0=B0=D1=89=D0=B5=D0=BD=D0=BD=D1=8B=D0= =B9=20 = =D0=B2=D0=B0=D1=80=D0=B8=D0=B0=D0=BD=D1=82):

1.=D0=9D=D0= =BE=D0=B2=D0=BE=D0=B5 =D0=B2 =D1=81=D0=B8=D1=81=D1=82=D0=B5=D0=BC=D0=B5 = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=B3=D0=BE = =D1=80=D0=B5=D0=B3=D1=83=D0=BB=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1= =8F =D0=B2=20 = =D0=A0=D0=A4.
=D0=9D=D0=BE=D1=80=D0=BC=D0=B0=D1=82=D0=B8=D0=B2=D0=BD= =D0=BE-=D0=BF=D1=80=D0=B0=D0=B2=D0=BE=D0=B2=D0=B0=D1=8F = =D0=B1=D0=B0=D0=B7=D0=B0 = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=B3=D0=BE = =D1=80=D0=B5=D0=B3=D1=83=D0=BB=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1= =8F =D0=B2 =D0=A0=D0=BE=D1=81=D1=81=D0=B8=D0=B9=D1=81=D0=BA=D0=BE=D0=B9=20 =D0=A4=D0=B5=D0=B4=D0=B5=D1=80=D0=B0=D1=86=D0=B8=D0=B8. = =D0=9F=D0=BE=D1=81=D0=BB=D0=B5=D0=B4=D0=BD=D0=B8=D0=B5
=D0=B8=D0=B7=D0= =BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=B3=D0=BE = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D0=BE=D0=B4=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=D1= =81=D1=82=D0=B2=D0=B0 =D0=A0=D0=A4. = =D0=9F=D0=BE=D1=80=D1=8F=D0=B4=D0=BE=D0=BA=20 =D0=BE=D1=82=D0=BA=D1=80=D1=8B=D1=82=D0=B8=D1=8F =D0=B8 = =D0=B2=D0=B5=D0=B4=D0=B5=D0=BD=D0=B8=D1=8F = =D1=81=D1=87=D0=B5=D1=82=D0=BE=D0=B2 = =D1=80=D0=B5=D0=B7=D0=B8=D0=B4=D0=B5=D0=BD=D1=82=D0=BE=D0=B2 = =D0=B7=D0=B0
=D0=BF=D1=80=D0=B5=D0=B4=D0=B5=D0=BB=D0=B0=D0=BC=D0=B8 = =D1=82=D0=B5=D1=80=D1=80=D0=B8=D1=82=D0=BE=D1=80=D0=B8=D0=B8 = =D0=A0=D0=A4.=20 =D0=9F=D1=80=D0=B0=D0=B2=D0=B8=D0=BB=D0=B0 = =D0=BE=D1=81=D1=83=D1=89=D0=B5=D1=81=D1=82=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D1= =8F =D1=80=D0=B5=D0=B7=D0=B8=D0=B4=D0=B5=D0=BD=D1=82=D0=B0=D0=BC=D0=B8 = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D1=8B=D1=85 = =D0=BE=D0=BF=D0=B5=D1=80=D0=B0=D1=86=D0=B8=D0=B9 =D0=B7=D0=B0 = =D1=81=D1=87=D0=B5=D1=82
=D1=81=D1=80=D0=B5=D0=B4=D1=81=D1=82=D0=B2,=20 =D0=BD=D0=B0=D1=85=D0=BE=D0=B4=D1=8F=D1=89=D0=B8=D1=85=D1=81=D1=8F = =D0=BD=D0=B0 =D1=81=D1=87=D0=B5=D1=82=D0=B0=D1=85 =D0=B7=D0=B0 = =D1=80=D1=83=D0=B1=D0=B5=D0=B6=D0=BE=D0=BC. = =D0=9F=D0=BE=D1=80=D1=8F=D0=B4=D0=BE=D0=BA = =D0=BF=D0=B5=D1=80=D0=B5=D0=B4=D0=B0=D1=87=D0=B8 = =D1=83=D0=BF=D0=BE=D0=BB=D0=BD=D0=BE=D0=BC=D0=BE=D1=87=D0=B5=D0=BD=D0=BD=D1= =8B=D0=BC=D0=B8=20 = =D0=B1=D0=B0=D0=BD=D0=BA=D0=B0=D0=BC=D0=B8
=D0=B8=D0=BD=D1=84=D0=BE=D1= =80=D0=BC=D0=B0=D1=86=D0=B8=D0=B8 =D0=BE = =D0=BD=D0=B0=D1=80=D1=83=D1=88=D0=B5=D0=BD=D0=B8=D1=8F=D1=85 = =D0=B8=D1=85 =D0=BA=D0=BB=D0=B8=D0=B5=D0=BD=D1=82=D0=B0=D0=BC=D0=B8 = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=B3=D0=BE = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D0=BE=D0=B4=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=D1= =81=D1=82=D0=B2=D0=B0=20 =D0=A0=D0=A4. = =D0=94=D0=B5=D0=B9=D1=81=D1=82=D0=B2=D0=B8=D0=B5
=D1=84=D0=B5=D0=B4=D0= =B5=D1=80=D0=B0=D0=BB=D1=8C=D0=BD=D0=BE=D0=B3=D0=BE = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D0=B0 "=D0=9E = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=BC=20 = =D1=80=D0=B5=D0=B3=D1=83=D0=BB=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0= =B8 =D0=B8 =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=BC = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=BE=D0=BB=D0=B5" 173-=D0=A4=D0=97 (=D1=81=20 = =D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F=D0=BC=D0=B8,
=D0= =B2=D1=81=D1=82=D1=83=D0=BF=D0=B8=D0=B2=D1=88=D0=B8=D0=BC=D0=B8 =D0=B2 = =D1=81=D0=B8=D0=BB=D1=83 =D0=B2 2013 =D0=B3=D0=BE=D0=B4=D1=83 =D0=B8 = =D0=B2=D1=81=D1=82=D1=83=D0=BF=D0=B0=D1=8E=D1=89=D0=B8=D0=BC=D0=B8 = =D0=B2 =D1=81=D0=B8=D0=BB=D1=83 =D0=B2 2014=20 =D0=B3). =D0=9F=D1=80=D0=BE=D0=B5=D0=BA=D1=82=D1=8B = =D0=B1=D1=83=D0=B4=D1=83=D1=89=D0=B8=D1=85 = =D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D0=B9
=D0=A4=D0=B5=D0= =B4=D0=B5=D1=80=D0=B0=D0=BB=D1=8C=D0=BD=D0=BE=D0=B3=D0=BE = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D0=B0 "=D0=9E = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=BC = =D1=80=D0=B5=D0=B3=D1=83=D0=BB=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0= =B8 =D0=B8 =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=BC = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=BE=D0=BB=D0=B5". =
=D0=94=D0=B5=D0=B9=D1=81=D1=82=D0=B2=D0=B8=D0=B5 = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=B3=D0=BE = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D0=BE=D0=B4=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=D1= =81=D1=82=D0=B2=D0=B0 =D0=B2 =D1=81=D0=B2=D1=8F=D0=B7=D0=B8 =D1=81=20 =D0=BF=D1=80=D0=B8=D0=BD=D1=8F=D1=82=D0=B8=D0=B5=D0=BC = =D0=A4=D0=B5=D0=B4=D0=B5=D1=80=D0=B0=D0=BB=D1=8C=D0=BD=D0=BE=D0=B3=D0=BE = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D0=B0 =D0=BE=D1=82 27 = =D0=B8=D1=8E=D0=BD=D1=8F
2011 =D0=B3=D0=BE=D0=B4=D0=B0 = 161-=D0=A4=D0=97 "=D0=9E = =D0=BD=D0=B0=D1=86=D0=B8=D0=BE=D0=BD=D0=B0=D0=BB=D1=8C=D0=BD=D0=BE=D0=B9 = =D0=BF=D0=BB=D0=B0=D1=82=D0=B5=D0=B6=D0=BD=D0=BE=D0=B9 = =D1=81=D0=B8=D1=81=D1=82=D0=B5=D0=BC=D0=B5". = =D0=9E=D1=81=D0=BE=D0=B1=D0=B5=D0=BD=D0=BD=D0=BE=D1=81=D1=82=D0=B8 = =D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D0=B4=D0=B5=D0=BD=D0=B8=D1=8F = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D1=8B=D1=85
=D0=BE=D0=BF=D0=B5=D1= =80=D0=B0=D1=86=D0=B8=D0=B9=20 =D1=80=D0=B5=D0=B7=D0=B8=D0=B4=D0=B5=D0=BD=D1=82=D0=B0=D0=BC=D0=B8 = =D0=B8 = =D0=BD=D0=B5=D1=80=D0=B5=D0=B7=D0=B8=D0=B4=D0=B5=D0=BD=D1=82=D0=B0=D0=BC=D0= =B8.
2.=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D1= =8F =D0=BF=D1=80=D0=B0=D0=B2=D0=B8=D0=BB = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=B3=D0=BE = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=BE=D0=BB=D1=8F, = =D0=BE=D1=81=D1=83=D1=89=D0=B5=D1=81=D1=82=D0=B2=D0=BB=D1=8F=D0=B5=D0=BC=D0= =BE=D0=B3=D0=BE =D1=81=20 =D1=83=D1=87=D0=B0=D1=81=D1=82=D0=B8=D0=B5=D0=BC = =D1=82=D0=B0=D0=BC=D0=BE=D0=B6=D0=B5=D0=BD=D0=BD=D1=8B=D1=85
=D0=BE=D1= =80=D0=B3=D0=B0=D0=BD=D0=BE=D0=B2.

=D0=9E=D0=B1=D0=B7=D0=BE=D1=80 = =D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D0=B9 = =D0=BD=D0=BE=D1=80=D0=BC=D0=B0=D1=82=D0=B8=D0=B2=D0=BD=D0=BE-=D0=BF=D1=80= =D0=B0=D0=B2=D0=BE=D0=B2=D0=BE=D0=B9=20 =D0=B1=D0=B0=D0=B7=D1=8B = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=B3=D0=BE = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=BE=D0=BB=D1=8F. = =D0=A2=D0=B5=D1=85=D0=BD=D0=BE=D0=BB=D0=BE=D0=B3=D0=B8=D0=B8 = =D1=82=D0=B0=D0=BC=D0=BE=D0=B6=D0=B5=D0=BD=D0=BD=D0=BE-
=D0=B1=D0=B0=D0= =BD=D0=BA=D0=BE=D0=B2=D1=81=D0=BA=D0=BE=D0=B3=D0=BE = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=B3=D0=BE=20 =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=BE=D0=BB=D1=8F = (=D0=A2=D0=91=D0=92=D0=9A), = =D0=B2=D0=B7=D0=B0=D0=B8=D0=BC=D0=BE=D0=B4=D0=B5=D0=B9=D1=81=D1=82=D0=B2=D0= =B8=D0=B5 =D1=81 =D0=B4=D1=80=D1=83=D0=B3=D0=B8=D0=BC=D0=B8 = =D0=BE=D1=80=D0=B3=D0=B0=D0=BD=D0=B0=D0=BC=D0=B8 =D0=B8 = =D0=B0=D0=B3=D0=B5=D0=BD=D1=82=D0=B0=D0=BC=D0=B8
=D0=B2=D0=B0=D0=BB=D1= =8E=D1=82=D0=BD=D0=BE=D0=B3=D0=BE=20 =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=BE=D0=BB=D1=8F. = =D0=92=D0=BE=D0=BF=D1=80=D0=BE=D1=81=D1=8B = =D0=B4=D0=B5=D0=BA=D0=BB=D0=B0=D1=80=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0= =B8=D1=8F =D1=82=D0=BE=D0=B2=D0=B0=D1=80=D0=BE=D0=B2 =D0=B8 = =D0=B8=D0=BD=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=86=D0=B8=D0=BE=D0=BD=D0=BD=D0= =BE=D0=B3=D0=BE =D0=BE=D0=B1=D0=BC=D0=B5=D0=BD=D0=B0 = =D0=BC=D0=B5=D0=B6=D0=B4=D1=83=20 =D0=A4=D0=A2=D0=A1
=D0=A0=D0=A4 =D0=B8 = =D1=83=D0=BF=D0=BE=D0=BB=D0=BD=D0=BE=D0=BC=D0=BE=D1=87=D0=B5=D0=BD=D0=BD=D1= =8B=D0=BC=D0=B8 =D0=B1=D0=B0=D0=BD=D0=BA=D0=B0=D0=BC=D0=B8. = =D0=92=D1=8B=D1=8F=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=BD=D0=B0=D1=80=D1=83=D1=88=D0=B5=D0=BD=D0=B8=D0=B9 = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D0=BE=D0=B4=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=D1= =81=D1=82=D0=B2=D0=B0,=20 = =D0=BF=D1=80=D0=B5=D0=B4=D1=83=D1=81=D0=BC=D0=BE=D1=82=D1=80=D0=B5=D0=BD=D0= =BD=D1=8B=D1=85
=D0=9A=D0=9E=D0=90=D0=9F =D0=A0=D0=A4. = =D0=92=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D1=8B=D0=B9 = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=BE=D0=BB=D1=8C =D0=B2 = =D0=BD=D0=B5=D1=82=D0=BE=D1=80=D0=B3=D0=BE=D0=B2=D0=BE=D0=BC = =D0=BE=D0=B1=D0=BE=D1=80=D0=BE=D1=82=D0=B5.=20

3.=D0=92=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D1=8B=D0=B9 = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=BE=D0=BB=D1=8C=20 =D0=BF=D1=80=D0=B8 = =D0=BE=D1=81=D1=83=D1=89=D0=B5=D1=81=D1=82=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0= =B8 =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D1=8B=D1=85 = =D0=BE=D0=BF=D0=B5=D1=80=D0=B0=D1=86=D0=B8=D0=B9, = =D1=81=D0=B2=D1=8F=D0=B7=D0=B0=D0=BD=D0=BD=D1=8B=D1=85 = =D1=81
=D0=B2=D0=BD=D0=B5=D1=88=D0=BD=D0=B5=D1=82=D0=BE=D1=80=D0=B3=D0= =BE=D0=B2=D0=BE=D0=B9=20 = =D0=B4=D0=B5=D1=8F=D1=82=D0=B5=D0=BB=D1=8C=D0=BD=D0=BE=D1=81=D1=82=D1=8C=D1= =8E, =D0=BF=D0=BE=D0=BB=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D0=B5=D0=BC =D0=B8 = =D0=BF=D1=80=D0=B5=D0=B4=D0=BE=D1=81=D1=82=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0= =B8=D0=B5=D0=BC =D0=BA=D1=80=D0=B5=D0=B4=D0=B8=D1=82=D0=BE=D0=B2 =D0=B8=20 =D0=B7=D0=B0=D0=B9=D0=BC=D0=BE=D0=B2.

=D0=9F=D0=B0=D1=81=D0=BF=D0=BE=D1=80=D1=82 = =D1=81=D0=B4=D0=B5=D0=BB=D0=BA=D0=B8: = =D0=9E=D1=84=D0=BE=D1=80=D0=BC=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5 =D0=B8=20 =D0=B2=D0=B5=D0=B4=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=BF=D0=B0=D1=81=D0=BF=D0=BE=D1=80=D1=82=D0=B0 = =D1=81=D0=B4=D0=B5=D0=BB=D0=BA=D0=B8 =D0=B2 = =D1=86=D0=B5=D0=BB=D1=8F=D1=85 = =D0=BE=D0=B1=D0=B5=D1=81=D0=BF=D0=B5=D1=87=D0=B5=D0=BD=D0=B8=D1=8F = =D1=83=D1=87=D0=B5=D1=82=D0=B0 =D0=B8 = =D0=BE=D1=82=D1=87=D0=B5=D1=82=D0=BD=D0=BE=D1=81=D1=82=D0=B8
=D0=B8=20 = =D0=BE=D1=81=D1=83=D1=89=D0=B5=D1=81=D1=82=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D1= =8F =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=B3=D0=BE = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=BE=D0=BB=D1=8F =D0=BF=D0=BE = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D1=8B=D0=BC = =D0=BE=D0=BF=D0=B5=D1=80=D0=B0=D1=86=D0=B8=D1=8F=D0=BC = =D0=BC=D0=B5=D0=B6=D0=B4=D1=83 = =D1=80=D0=B5=D0=B7=D0=B8=D0=B4=D0=B5=D0=BD=D1=82=D0=B0=D0=BC=D0=B8=20 = =D0=B8
=D0=BD=D0=B5=D1=80=D0=B5=D0=B7=D0=B8=D0=B4=D0=B5=D0=BD=D1=82=D0= =B0=D0=BC=D0=B8. = =D0=9F=D1=80=D0=B5=D0=B4=D1=81=D1=82=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0= =B5 =D1=80=D0=B5=D0=B7=D0=B8=D0=B4=D0=B5=D0=BD=D1=82=D0=B0=D0=BC=D0=B8 = =D0=B2 = =D1=83=D0=BF=D0=BE=D0=BB=D0=BD=D0=BE=D0=BC=D0=BE=D1=87=D0=B5=D0=BD=D0=BD=D1= =8B=D0=B9 =D0=B1=D0=B0=D0=BD=D0=BA=20 =D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B8 =D0=BE = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D1=8B=D1=85
=D0=BE=D0=BF=D0=B5=D1= =80=D0=B0=D1=86=D0=B8=D1=8F=D1=85 =D0=B8 = =D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B8 =D0=BE = =D0=BF=D0=BE=D0=B4=D1=82=D0=B2=D0=B5=D1=80=D0=B6=D0=B4=D0=B0=D1=8E=D1=89=D0= =B8=D1=85 =D0=B4=D0=BE=D0=BA=D1=83=D0=BC=D0=B5=D0=BD=D1=82=D0=B0=D1=85 = =D0=BF=D1=80=D0=B8=20 = =D0=BE=D1=81=D1=83=D1=89=D0=B5=D1=81=D1=82=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0= =B8 = =D0=B2=D0=BD=D0=B5=D1=88=D0=BD=D0=B5=D1=82=D0=BE=D1=80=D0=B3=D0=BE=D0=B2=D0= =BE=D0=B9
=D0=B4=D0=B5=D1=8F=D1=82=D0=B5=D0=BB=D1=8C=D0=BD=D0=BE=D1=81= =D1=82=D0=B8.
4.=D0=9A=D0=BB=D0=B0=D1=81=D1=81=D0=B8=D1=84=D0=B8=D0=BA=D0= =B0=D1=86=D0=B8=D1=8F =D0=B8 = =D1=81=D0=BE=D0=B4=D0=B5=D1=80=D0=B6=D0=B0=D0=BD=D0=B8=D0=B5 = =D0=BF=D1=80=D0=B0=D0=B2=D0=BE=D0=BD=D0=B0=D1=80=D1=83=D1=88=D0=B5=D0=BD=D0= =B8=D0=B9 =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=B3=D0=BE=20 = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D0=BE=D0=B4=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=D1= =81=D1=82=D0=B2=D0=B0 =D1=81 = =D1=83=D1=87=D0=B5=D1=82=D0=BE=D0=BC
=D0=BF=D0=BE=D1=81=D0=BB=D0=B5=D0= =B4=D0=BD=D0=B8=D1=85 = =D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D0=B9 = =D0=BD=D0=BE=D1=80=D0=BC=D0=B0=D1=82=D0=B8=D0=B2=D0=BD=D0=BE=D0=B9 = =D0=BF=D1=80=D0=B0=D0=B2=D0=BE=D0=B2=D0=BE=D0=B9=20 =D0=B1=D0=B0=D0=B7=D1=8B. =

=D0=93=D0=BE=D1=81=D1=83=D0=B4=D0=B0=D1=80=D1=81=D1=82=D0=B2=D0=B5= =D0=BD=D0=BD=D1=8B=D0=B9 = =D1=84=D0=B8=D0=BD=D0=B0=D0=BD=D1=81=D0=BE=D0=B2=D1=8B=D0=B9 = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=BE=D0=BB=D1=8C =D0=B7=D0=B0 = =D0=BE=D1=81=D1=83=D1=89=D0=B5=D1=81=D1=82=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0= =B5=D0=BC=20 =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D1=8B=D1=85 = =D0=BE=D0=BF=D0=B5=D1=80=D0=B0=D1=86=D0=B8=D0=B9 = =D1=80=D0=B5=D0=B7=D0=B8=D0=B4=D0=B5=D0=BD=D1=82=D0=B0=D0=BC=D0=B8 = =D0=B8
=D0=BD=D0=B5=D1=80=D0=B5=D0=B7=D0=B8=D0=B4=D0=B5=D0=BD=D1=82=D0= =B0=D0=BC=D0=B8, =D0=BD=D0=B5 = =D1=8F=D0=B2=D0=BB=D1=8F=D1=8E=D1=89=D0=B8=D0=BC=D0=B8=D1=81=D1=8F=20 =D0=BA=D1=80=D0=B5=D0=B4=D0=B8=D1=82=D0=BD=D1=8B=D0=BC=D0=B8 = =D0=BE=D1=80=D0=B3=D0=B0=D0=BD=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D1=8F=D0=BC=D0= =B8 =D0=B8 =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D1=8B=D0=BC=D0=B8 = =D0=B1=D0=B8=D1=80=D0=B6=D0=B0=D0=BC=D0=B8. = =D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F = =D0=B2
=D0=A4=D0=B5=D0=B4=D0=B5=D1=80=D0=B0=D0=BB=D1=8C=D0=BD=D1=8B=D0= =B9=20 =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD =D0=BE=D1=82 08.12.2003 = =D0=B3=D0=BE=D0=B4=D0=B0 =E2=84=96 164-=D0=A4=D0=97 "=D0=9E=D0=B1 = =D0=BE=D1=81=D0=BD=D0=BE=D0=B2=D0=B0=D1=85 = =D0=B3=D0=BE=D1=81=D1=83=D0=B4=D0=B0=D1=80=D1=81=D1=82=D0=B2=D0=B5=D0=BD=D0= =BD=D0=BE=D0=B3=D0=BE=20 = =D1=80=D0=B5=D0=B3=D1=83=D0=BB=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1= =8F
=D0=B2=D0=BD=D0=B5=D1=88=D0=BD=D0=B5=D1=82=D0=BE=D1=80=D0=B3=D0=BE= =D0=B2=D0=BE=D0=B9 = =D0=B4=D0=B5=D1=8F=D1=82=D0=B5=D0=BB=D1=8C=D0=BD=D0=BE=D1=81=D1=82=D0=B8"= , =D0=B2 =D0=9A=D0=BE=D0=B4=D0=B5=D0=BA=D1=81 = =D0=A0=D0=BE=D1=81=D1=81=D0=B8=D0=B9=D1=81=D0=BA=D0=BE=D0=B9=20 =D0=A4=D0=B5=D0=B4=D0=B5=D1=80=D0=B0=D1=86=D0=B8=D0=B8 = =D0=BE=D0=B1 = =D0=B0=D0=B4=D0=BC=D0=B8=D0=BD=D0=B8=D1=81=D1=82=D1=80=D0=B0=D1=82=D0=B8=D0= =B2=D0=BD=D1=8B=D1=85
=D0=BF=D1=80=D0=B0=D0=B2=D0=BE=D0=BD=D0=B0=D1=80= =D1=83=D1=88=D0=B5=D0=BD=D0=B8=D1=8F=D1=85, =D0=B2 = =D0=A4=D0=B5=D0=B4=D0=B5=D1=80=D0=B0=D0=BB=D1=8C=D0=BD=D1=8B=D0=B9 = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD =D0=BE=D1=82=20 10.12.2003 =D0=B3=D0=BE=D0=B4=D0=B0 =E2=84=96 173-=D0=A4=D0=97 = "=D0=9E =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=BC = =D1=80=D0=B5=D0=B3=D1=83=D0=BB=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0= =B8
=D0=B8 =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=BC = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=BE=D0=BB=D0=B5"=20 =D0=B8 =D0=B4=D1=80=D1=83=D0=B3=D0=B8=D0=B5 = =D0=BD=D0=BE=D1=80=D0=BC=D0=B0=D1=82=D0=B8=D0=B2=D0=BD=D1=8B=D0=B5 = =D0=BF=D1=80=D0=B0=D0=B2=D0=BE=D0=B2=D1=8B=D0=B5 = =D0=B0=D0=BA=D1=82=D1=8B, = =D1=81=D0=B2=D1=8F=D0=B7=D0=B0=D0=BD=D0=BD=D1=8B=D0=B5 =D1=81 = =D0=BF=D1=80=D0=B8=D0=BD=D1=8F=D1=82=D0=B8=D0=B5=D0=BC
=D1=84=D0=B5=D0= =B4=D0=B5=D1=80=D0=B0=D0=BB=D1=8C=D0=BD=D1=8B=D1=85=20 =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D0=BE=D0=B2. = =D0=92=D1=8B=D1=8F=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5 =D0=B8 = =D0=BF=D1=80=D0=B5=D1=81=D0=B5=D1=87=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=BD=D0=B0=D1=80=D1=83=D1=88=D0=B5=D0=BD=D0=B8=D0=B9 = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=B3=D0=BE=20 = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D0=BE=D0=B4=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=D1= =81=D1=82=D0=B2=D0=B0
=D0=A0=D0=BE=D1=81=D1=81=D0=B8=D0=B9=D1=81=D0=BA= =D0=BE=D0=B9 =D0=A4=D0=B5=D0=B4=D0=B5=D1=80=D0=B0=D1=86=D0=B8=D0=B8 = =D0=B8 =D0=B0=D0=BA=D1=82=D0=BE=D0=B2 = =D0=BE=D1=80=D0=B3=D0=B0=D0=BD=D0=BE=D0=B2 = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=B3=D0=BE=20 = =D1=80=D0=B5=D0=B3=D1=83=D0=BB=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1= =8F.
5.=D0=9E=D1=82=D0=B2=D0=B5=D1=82=D1=81=D1=82=D0=B2=D0= =B5=D0=BD=D0=BD=D0=BE=D1=81=D1=82=D1=8C =D0=B7=D0=B0 = =D0=BD=D0=B0=D1=80=D1=83=D1=88=D0=B5=D0=BD=D0=B8=D1=8F = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=B3=D0=BE=20 = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D0=BE=D0=B4=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=D1= =81=D1=82=D0=B2=D0=B0 =D0=B8 =D0=B0=D0=BA=D1=82=D0=BE=D0=B2 = =D0=BE=D1=80=D0=B3=D0=B0=D0=BD=D0=BE=D0=B2=20 = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=B3=D0=BE
=D1=80=D0=B5=D0= =B3=D1=83=D0=BB=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F.

=D0= =9C=D0=B8=D0=BD=D0=B8=D0=BC=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D1=8F = =D1=80=D0=B8=D1=81=D0=BA=D0=BE=D0=B2, = =D1=81=D0=B2=D1=8F=D0=B7=D0=B0=D0=BD=D0=BD=D1=8B=D1=85 =D1=81=20 =D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D0=B4=D0=B5=D0=BD=D0=B8=D0=B5=D0=BC = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D1=8B=D1=85 = =D0=BE=D0=BF=D0=B5=D1=80=D0=B0=D1=86=D0=B8=D0=B9 =D0=BF=D1=80=D0=B8 = =D0=BE=D1=81=D1=83=D1=89=D0=B5=D1=81=D1=82=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0= =B8
=D0=B2=D0=BD=D0=B5=D1=88=D0=BD=D0=B5=D1=8D=D0=BA=D0=BE=D0=BD=D0=BE= =D0=BC=D0=B8=D1=87=D0=B5=D1=81=D0=BA=D0=BE=D0=B9=20 = =D0=B4=D0=B5=D1=8F=D1=82=D0=B5=D0=BB=D1=8C=D0=BD=D0=BE=D1=81=D1=82=D0=B8.= = =D0=9F=D1=80=D0=B5=D0=B4=D1=83=D0=BF=D1=80=D0=B5=D0=B6=D0=B4=D0=B5=D0=BD=D0= =B8=D0=B5 = =D0=BF=D1=80=D0=B0=D0=B2=D0=BE=D0=BD=D0=B0=D1=80=D1=83=D1=88=D0=B5=D0=BD=D0= =B8=D0=B9 = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=B3=D0=BE
=D0=B7=D0=B0=D0= =BA=D0=BE=D0=BD=D0=BE=D0=B4=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=D1=81=D1=82=D0=B2= =D0=B0=20 =D0=A0=D0=BE=D1=81=D1=81=D0=B8=D0=B9=D1=81=D0=BA=D0=BE=D0=B9 = =D0=A4=D0=B5=D0=B4=D0=B5=D1=80=D0=B0=D1=86=D0=B8=D0=B8 =D0=B8 = =D0=B0=D0=BA=D1=82=D0=BE=D0=B2 = =D0=BE=D1=80=D0=B3=D0=B0=D0=BD=D0=BE=D0=B2 = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=B3=D0=BE = =D1=80=D0=B5=D0=B3=D1=83=D0=BB=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1= =8F.
=D0=9A=D0=BE=D0=BC=D0=BF=D0=BB=D0=B5=D0=BA=D1=81=20 =D0=BC=D0=B5=D1=80 =D0=BF=D0=BE = =D1=81=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD=D0=B8=D1=8E = =D0=B2=D0=BD=D1=83=D1=82=D1=80=D0=B8=D1=84=D0=B8=D1=80=D0=BC=D0=B5=D0=BD=D0= =BD=D0=BE=D0=B9 =D1=81=D0=B8=D1=81=D1=82=D0=B5=D0=BC=D1=8B = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=B3=D0=BE = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=BE=D0=BB=D1=8F.=20 = =D0=9C=D0=B5=D1=81=D1=82=D0=BE
=D0=B2=D0=BD=D1=83=D1=82=D1=80=D0=B8=D1= =84=D0=B8=D1=80=D0=BC=D0=B5=D0=BD=D0=BD=D0=BE=D0=B9 = =D1=81=D0=B8=D1=81=D1=82=D0=B5=D0=BC=D1=8B = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=B3=D0=BE = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=BE=D0=BB=D1=8F =D0=B2 = =D0=BE=D1=80=D0=B3=D0=B0=D0=BD=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D0=BE=D0=BD=D0= =BD=D0=BE=D0=B9=20 = =D1=81=D1=82=D1=80=D1=83=D0=BA=D1=82=D1=83=D1=80=D0=B5
=D0=BF=D1=80=D0= =B5=D0=B4=D0=BF=D1=80=D0=B8=D1=8F=D1=82=D0=B8=D1=8F = (=D0=BE=D1=80=D0=B3=D0=B0=D0=BD=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D0=B8). = =D0=A2=D1=80=D0=B5=D0=B1=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D0=BE=D0=B4=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=D1= =81=D1=82=D0=B2=D0=B0 =D0=BA=20 =D1=83=D1=81=D0=BB=D0=BE=D0=B2=D0=B8=D1=8F=D0=BC = =D0=B7=D0=B0=D0=BA=D0=BB=D1=8E=D1=87=D0=B0=D0=B5=D0=BC=D1=8B=D1=85 = =D0=B2=D0=BE
=D0=B2=D0=BD=D0=B5=D1=88=D0=BD=D0=B5=D1=82=D0=BE=D1=80=D0= =B3=D0=BE=D0=B2=D0=BE=D0=B9 = =D0=B4=D0=B5=D1=8F=D1=82=D0=B5=D0=BB=D1=8C=D0=BD=D0=BE=D1=81=D1=82=D0=B8 = =D0=B4=D0=BE=D0=B3=D0=BE=D0=B2=D0=BE=D1=80=D0=BE=D0=B2=20 (=D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=B0=D0=BA=D1=82=D0=BE=D0=B2). =

6.=D0=9F=D0=BE=D1=80=D1=8F=D0=B4=D0=BE=D0=BA = =D0=B2=D0=B7=D0=B0=D0=B8=D0=BC=D0=BE=D0=B4=D0=B5=D0=B9=D1=81=D1=82=D0=B2=D0= =B8=D1=8F = =D0=A0=D0=BE=D1=81=D1=84=D0=B8=D0=BD=D0=BD=D0=B0=D0=B4=D0=B7=D0=BE=D1=80=D0= =B0 =D1=81 =D0=91=D0=B0=D0=BD=D0=BA=D0=BE=D0=BC = =D0=A0=D0=BE=D1=81=D1=81=D0=B8=D0=B8,=20 =D1=82=D0=B0=D0=BC=D0=BE=D0=B6=D0=B5=D0=BD=D0=BD=D1=8B=D0=BC=D0=B8 = =D0=B8 = =D0=BD=D0=B0=D0=BB=D0=BE=D0=B3=D0=BE=D0=B2=D1=8B=D0=BC=D0=B8
=D0=BE=D1= =80=D0=B3=D0=B0=D0=BD=D0=B0=D0=BC=D0=B8, = =D1=83=D0=BF=D0=BE=D0=BB=D0=BD=D0=BE=D0=BC=D0=BE=D1=87=D0=B5=D0=BD=D0=BD=D1= =8B=D0=BC=D0=B8 =D0=B1=D0=B0=D0=BD=D0=BA=D0=B0=D0=BC=D0=B8, =D0=B0 = =D1=82=D0=B0=D0=BA=D0=B6=D0=B5=20 = =D0=BF=D1=80=D0=BE=D1=84=D0=B5=D1=81=D1=81=D0=B8=D0=BE=D0=BD=D0=B0=D0=BB=D1= =8C=D0=BD=D1=8B=D0=BC=D0=B8 = =D1=83=D1=87=D0=B0=D1=81=D1=82=D0=BD=D0=B8=D0=BA=D0=B0=D0=BC=D0=B8 = =D1=80=D1=8B=D0=BD=D0=BA=D0=B0
=D1=86=D0=B5=D0=BD=D0=BD=D1=8B=D1=85 = =D0=B1=D1=83=D0=BC=D0=B0=D0=B3, =D0=BA=D0=B0=D0=BA = =D0=B0=D0=B3=D0=B5=D0=BD=D1=82=D0=B0=D0=BC=D0=B8=20 =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=B3=D0=BE = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=BE=D0=BB=D1=8F.

=D0=9F=D1=80=D0=B0=D0=B2=D0=B8=D0=BB=D0=B0 = =D0=BF=D1=80=D0=B5=D0=B4=D1=81=D1=82=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D1= =8F=20 =D0=BE=D1=80=D0=B3=D0=B0=D0=BD=D0=B0=D0=BC=D0=B8 =D0=B8 = =D0=B0=D0=B3=D0=B5=D0=BD=D1=82=D0=B0=D0=BC=D0=B8 = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=B3=D0=BE = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=BE=D0=BB=D1=8F =D0=B2 = =D1=83=D0=BF=D0=BE=D0=BB=D0=BD=D0=BE=D0=BC=D0=BE=D1=87=D0=B5=D0=BD=D0=BD=D1= =8B=D0=B9
=D0=9F=D1=80=D0=B0=D0=B2=D0=B8=D1=82=D0=B5=D0=BB=D1=8C=D1=81= =D1=82=D0=B2=D0=BE=D0=BC=20 =D0=A0=D0=BE=D1=81=D1=81=D0=B8=D0=B9=D1=81=D0=BA=D0=BE=D0=B9 = =D0=A4=D0=B5=D0=B4=D0=B5=D1=80=D0=B0=D1=86=D0=B8=D0=B8 = =D0=BE=D1=80=D0=B3=D0=B0=D0=BD = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=B3=D0=BE = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=BE=D0=BB=D1=8F = (=D0=A0=D0=BE=D1=81=D1=84=D0=B8=D0=BD=D0=BD=D0=B0=D0=B4=D0=B7=D0=BE=D1=80= )=20 = =D0=BD=D0=B5=D0=BE=D0=B1=D1=85=D0=BE=D0=B4=D0=B8=D0=BC=D1=8B=D1=85
=D0= =B4=D0=BE=D0=BA=D1=83=D0=BC=D0=B5=D0=BD=D1=82=D0=BE=D0=B2 =D0=B8 = =D0=B8=D0=BD=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=86=D0=B8=D0=B8. = =D0=9E=D1=82=D0=B4=D0=B5=D0=BB=D1=8C=D0=BD=D1=8B=D0=B5 = =D0=B2=D0=BE=D0=BF=D1=80=D0=BE=D1=81=D1=8B = =D0=B8=D1=81=D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D1=83=D0=B5=D0=BC=D1=8B=D1=85 = =D0=B2=20 =D1=81=D1=84=D0=B5=D1=80=D0=B5 = =D0=B2=D0=B0=D0=BB=D1=8E=D1=82=D0=BD=D0=BE=D0=B3=D0=BE = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=BE=D0=BB=D1=8F
=D0=B8=D0=BD=D1=84=D0= =BE=D1=80=D0=BC=D0=B0=D1=86=D0=B8=D0=BE=D0=BD=D0=BD=D1=8B=D1=85 = =D1=82=D0=B5=D1=85=D0=BD=D0=BE=D0=BB=D0=BE=D0=B3=D0=B8=D0=B9. = =D0=9F=D0=BB=D0=B0=D0=BD=D0=B8=D1=80=D1=83=D0=B5=D0=BC=D1=8B=D0=B5=20 =D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F, = =D0=BA=D0=B0=D1=81=D0=B0=D1=8E=D1=89=D0=B8=D0=B5=D1=81=D1=8F = =D1=83=D1=81=D1=82=D0=B0=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F = =D0=BD=D0=BE=D0=B2=D0=BE=D0=B3=D0=BE
=D0=BF=D0=BE=D1=80=D1=8F=D0=B4=D0= =BA=D0=B0 =D0=BF=D0=B5=D1=80=D0=B5=D0=B4=D0=B0=D1=87=D0=B8 = =D0=B4=D0=BE=D0=BA=D1=83=D0=BC=D0=B5=D0=BD=D1=82=D0=BE=D0=B2 =D0=B8=20 =D0=B8=D0=BD=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=86=D0=B8=D0=B8 = =D0=BC=D0=B5=D0=B6=D0=B4=D1=83 =D0=91=D0=B0=D0=BD=D0=BA=D0=BE=D0=BC = =D0=A0=D0=BE=D1=81=D1=81=D0=B8=D0=B8, = =D1=83=D0=BF=D0=BE=D0=BB=D0=BD=D0=BE=D0=BC=D0=BE=D1=87=D0=B5=D0=BD=D0=BD=D1= =8B=D0=BC=D0=B8 =D0=B1=D0=B0=D0=BD=D0=BA=D0=B0=D0=BC=D0=B8=20 = =D0=B8
=D0=A0=D0=BE=D1=81=D1=84=D0=B8=D0=BD=D0=BD=D0=B0=D0=B4=D0=B7=D0= =BE=D1=80=D0=BE=D0=BC; =D0=BC=D0=B5=D0=B6=D0=B4=D1=83 = =D0=A4=D0=A1=D0=A1=D0=9F =D0=A0=D0=BE=D1=81=D1=81=D0=B8=D0=B8 =D0=B8 = =D0=A0=D0=BE=D1=81=D1=84=D0=B8=D0=BD=D0=BD=D0=B0=D0=B4=D0=B7=D0=BE=D1=80=D0= =BE=D0=BC; =D0=BC=D0=B5=D0=B6=D0=B4=D1=83 = =D1=82=D0=B0=D0=BC=D0=BE=D0=B6=D0=B5=D0=BD=D0=BD=D1=8B=D0=BC=D0=B8=20 =D0=B8 = =D0=BD=D0=B0=D0=BB=D0=BE=D0=B3=D0=BE=D0=B2=D1=8B=D0=BC=D0=B8
=D0=BE=D1= =80=D0=B3=D0=B0=D0=BD=D0=B0=D0=BC=D0=B8 =D0=B8 = =D0=A0=D0=BE=D1=81=D1=84=D0=B8=D0=BD=D0=BD=D0=B0=D0=B4=D0=B7=D0=BE=D1=80=D0= =BE=D0=BC.
 


=D0=A3=D1=87=D0=B0=D1=81=D1=82=D0=B8=D0=B5 = =D1=81=D0=BE=D1=81=D1=82=D0=B0=D0=B2=D0=BB=D1=8F=D0=B5=D1=82: 11800 = =D1=80=D1=83=D0=B1=D0=BB=D0=B5=D0=B9.
=D0=92=20 =D0=BC=D0=B5=D1=80=D0=BE=D0=BF=D1=80=D0=B8=D1=8F=D1=82=D0=B8=D0=B5 = =D0=B2=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D0=BE: = =D0=BC=D0=B5=D1=82=D0=BE=D0=B4=D0=B8=D1=87=D0=B5=D1=81=D0=BA=D0=B8=D0=B9 = =D0=BC=D0=B0=D1=82=D0=B5=D1=80=D0=B8=D0=B0=D0=BB, = =D0=BE=D0=B1=D0=B5=D0=B4=D1=8B, = =D0=BA=D0=BE=D1=84=D0=B5-=D0=BF=D0=B0=D1=83=D0=B7=D1=8B.
=D0=9F=D0=BE=D1= =81=D0=BB=D0=B5=20 =D0=BE=D0=BA=D0=BE=D0=BD=D1=87=D0=B0=D0=BD=D0=B8=D1=8F = =D0=B7=D0=B0=D0=BD=D1=8F=D1=82=D0=B8=D1=8F =D0=92=D0=B0=D0=BC = =D0=B2=D1=8B=D0=B4=D0=B0=D0=B5=D1=82=D1=81=D1=8F = =D1=81=D0=B5=D1=80=D1=82=D0=B8=D1=84=D0=B8=D0=BA=D0=B0=D1=82 = =D1=83=D1=81=D1=82=D0=B0=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=D0=BD=D0=BE=D0= =B3=D0=BE=20 = =D0=BE=D0=B1=D1=80=D0=B0=D0=B7=D1=86=D0=B0.
=D0=98=D0=BD=D0=BE=D0=B3=D0= =BE=D1=80=D0=BE=D0=B4=D0=BD=D0=B8=D0=BC = =D1=83=D1=87=D0=B0=D1=81=D1=82=D0=BD=D0=B8=D0=BA=D0=B0=D0=BC = =D0=BF=D0=BE=D0=BC=D0=BE=D0=B3=D0=B0=D0=B5=D0=BC =D0=B2 = =D0=B1=D1=80=D0=BE=D0=BD=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B8 = = =D0=B3=D0=BE=D1=81=D1=82=D0=B8=D0=BD=D0=B8=D1=86=D1=8B.
 
<= /P>

     
             
------=_NextPart_000_0047_01D121CF.401CC830-- From jack@suse.cz Wed Nov 18 04:41:08 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 945917F37 for ; Wed, 18 Nov 2015 04:41:08 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 1C293AC006 for ; Wed, 18 Nov 2015 02:41:04 -0800 (PST) X-ASG-Debug-ID: 1447843260-04cbb0605eff1f0001-NocioJ Received: from mx2.suse.de (mx2.suse.de [195.135.220.15]) by cuda.sgi.com with ESMTP id 5SUIO64LOGV1JTCx (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NO) for ; Wed, 18 Nov 2015 02:41:02 -0800 (PST) X-Barracuda-Envelope-From: jack@suse.cz X-Barracuda-Apparent-Source-IP: 195.135.220.15 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 9C556ACD7; Wed, 18 Nov 2015 10:40:35 +0000 (UTC) Received: by quack.suse.cz (Postfix, from userid 1000) id 721F682827; Wed, 18 Nov 2015 11:40:55 +0100 (CET) Date: Wed, 18 Nov 2015 11:40:55 +0100 From: Jan Kara To: Ross Zwisler Cc: Dan Williams , Andreas Dilger , "linux-kernel@vger.kernel.org" , "H. Peter Anvin" , "J. Bruce Fields" , Theodore Ts'o , Alexander Viro , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4 , linux-fsdevel , Linux MM , "linux-nvdimm@lists.01.org" , X86 ML , XFS Developers , Andrew Morton , Matthew Wilcox , Dave Hansen Subject: Re: [PATCH v2 03/11] pmem: enable REQ_FUA/REQ_FLUSH handling Message-ID: <20151118104055.GA6097@quack.suse.cz> X-ASG-Orig-Subj: Re: [PATCH v2 03/11] pmem: enable REQ_FUA/REQ_FLUSH handling References: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> <1447459610-14259-4-git-send-email-ross.zwisler@linux.intel.com> <22E0F870-C1FB-431E-BF6C-B395A09A2B0D@dilger.ca> <20151116200950.GB9737@linux.intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151116200950.GB9737@linux.intel.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: mx2.suse.de[195.135.220.15] X-Barracuda-Start-Time: 1447843261 X-Barracuda-Encrypted: ECDHE-RSA-AES256-SHA X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24503 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Mon 16-11-15 13:09:50, Ross Zwisler wrote: > On Fri, Nov 13, 2015 at 06:32:40PM -0800, Dan Williams wrote: > > On Fri, Nov 13, 2015 at 4:43 PM, Andreas Dilger wrote: > > > On Nov 13, 2015, at 5:20 PM, Dan Williams wrote: > > >> > > >> On Fri, Nov 13, 2015 at 4:06 PM, Ross Zwisler > > >> wrote: > > >>> Currently the PMEM driver doesn't accept REQ_FLUSH or REQ_FUA bios. These > > >>> are sent down via blkdev_issue_flush() in response to a fsync() or msync() > > >>> and are used by filesystems to order their metadata, among other things. > > >>> > > >>> When we get an msync() or fsync() it is the responsibility of the DAX code > > >>> to flush all dirty pages to media. The PMEM driver then just has issue a > > >>> wmb_pmem() in response to the REQ_FLUSH to ensure that before we return all > > >>> the flushed data has been durably stored on the media. > > >>> > > >>> Signed-off-by: Ross Zwisler > > >> > > >> Hmm, I'm not seeing why we need this patch. If the actual flushing of > > >> the cache is done by the core why does the driver need support > > >> REQ_FLUSH? Especially since it's just a couple instructions. REQ_FUA > > >> only makes sense if individual writes can bypass the "drive" cache, > > >> but no I/O submitted to the driver proper is ever cached we always > > >> flush it through to media. > > > > > > If the upper level filesystem gets an error when submitting a flush > > > request, then it assumes the underlying hardware is broken and cannot > > > be as aggressive in IO submission, but instead has to wait for in-flight > > > IO to complete. > > > > Upper level filesystems won't get errors when the driver does not > > support flush. Those requests are ended cleanly in > > generic_make_request_checks(). Yes, the fs still needs to wait for > > outstanding I/O to complete but in the case of pmem all I/O is > > synchronous. There's never anything to await when flushing at the > > pmem driver level. > > > > > Since FUA/FLUSH is basically a no-op for pmem devices, > > > it doesn't make sense _not_ to support this functionality. > > > > Seems to be a nop either way. Given that DAX may lead to dirty data > > pending to the device in the cpu cache that a REQ_FLUSH request will > > not touch, its better to leave it all to the mm core to handle. I.e. > > it doesn't make sense to call the driver just for two instructions > > (sfence + pcommit) when the mm core is taking on the cache flushing. > > Either handle it all in the mm or the driver, not a mixture. > > Does anyone know if ext4 and/or XFS alter their algorithms based on whether > the driver supports REQ_FLUSH/REQ_FUA? Will the filesystem behave more > efficiently with respect to their internal I/O ordering, etc., if PMEM > advertises REQ_FLUSH/REQ_FUA support, even though we could do the same thing > at the DAX layer? So the information whether the driver supports FLUSH / FUA is generally ignored by filesystems. We issue REQ_FLUSH / REQ_FUA requests to achieve required ordering for fs consistency and expect that block layer does the right thing - i.e., if the device has volatile write cache, it will be flushed, if it doesn't have it, the request will be ignored. So the difference between supporting and not supporting REQ_FLUSH / REQ_FUA is only in how block layer handles such requests. Honza -- Jan Kara SUSE Labs, CR From agruenba@redhat.com Wed Nov 18 07:09:54 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 303A47F37 for ; Wed, 18 Nov 2015 07:09:54 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 142CE304032 for ; Wed, 18 Nov 2015 05:09:51 -0800 (PST) X-ASG-Debug-ID: 1447852189-04cb6c0cd2dc040001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id S178HONJZOThCanF (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 18 Nov 2015 05:09:50 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 547FFC10045A; Wed, 18 Nov 2015 13:09:49 +0000 (UTC) Received: from nux.redhat.com (vpn1-4-30.ams2.redhat.com [10.36.4.30]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAID9klh006345; Wed, 18 Nov 2015 08:09:47 -0500 From: Andreas Gruenbacher To: david@fromorbit.com, xfs@oss.sgi.com Cc: Andreas Gruenbacher Subject: Re: [PATCH] xfs_repair: Check for invalid ACL types Date: Wed, 18 Nov 2015 14:09:45 +0100 X-ASG-Orig-Subj: Re: [PATCH] xfs_repair: Check for invalid ACL types Message-Id: <1447852185-6309-1-git-send-email-agruenba@redhat.com> References: <1445627828-14661-1-git-send-email-agruenba@redhat.com> <1445627828-14661-5-git-send-email-agruenba@redhat.com> <20151026225520.GK8773@dastard> <1445909032-10974-1-git-send-email-agruenba@redhat.com> In-Reply-To: <1445909032-10974-1-git-send-email-agruenba@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: 1447852190 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Here's a follow-up patch to test a filesystem for richacl support. -- Subject: xfs_db: Report when richacls are supported When the richacl incompatible filesystem feature is set, include the word RICHACL in the output of "xfs_db [-r] -c version". Signed-off-by: Andreas Gruenbacher --- db/sb.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/db/sb.c b/db/sb.c index 17d446c..ff6c1f8 100644 --- a/db/sb.c +++ b/db/sb.c @@ -690,6 +690,8 @@ version_string( strcat(s, ",FTYPE"); if (xfs_sb_version_hasfinobt(sbp)) strcat(s, ",FINOBT"); + if (xfs_sb_has_incompat_feature(sbp, XFS_SB_FEAT_INCOMPAT_RICHACL)) + strcat(s, ",RICHACL"); if (xfs_sb_version_hassparseinodes(sbp)) strcat(s, ",SPARSE_INODES"); if (xfs_sb_version_hasmetauuid(sbp)) -- 2.5.0 From agruenba@redhat.com Wed Nov 18 08:17:57 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 468757F37 for ; Wed, 18 Nov 2015 08:17:57 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id CB3ACAC004 for ; Wed, 18 Nov 2015 06:17:56 -0800 (PST) X-ASG-Debug-ID: 1447856275-04cb6c0cd2de0c0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id h1OM2a55EbJ8sSGj (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 18 Nov 2015 06:17:55 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id E68BF461C0 for ; Wed, 18 Nov 2015 14:17:54 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-27.ams2.redhat.com [10.36.5.27]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAIEHoXb027334; Wed, 18 Nov 2015 09:17:53 -0500 From: Andreas Gruenbacher To: xfs@oss.sgi.com Cc: Andreas Gruenbacher Subject: [XFSTESTS 1/6] check: Don't complain about missing tests/$FSTYP/group Date: Wed, 18 Nov 2015 15:17:44 +0100 X-ASG-Orig-Subj: [XFSTESTS 1/6] check: Don't complain about missing tests/$FSTYP/group Message-Id: <1447856269-7872-2-git-send-email-agruenba@redhat.com> In-Reply-To: <1447856269-7872-1-git-send-email-agruenba@redhat.com> References: <1447856269-7872-1-git-send-email-agruenba@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: 1447856275 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 When filesystems don't have filesystem specific tests, those nonexistent tests also won't have a group file. Signed-off-by: Andreas Gruenbacher --- check | 2 ++ 1 file changed, 2 insertions(+) diff --git a/check b/check index 8281322..4a9b332 100755 --- a/check +++ b/check @@ -95,6 +95,8 @@ get_group_list() grp=$1 for d in $SRC_GROUPS $FSTYP; do + [ -e "$SRC_DIR/$d/group" ] || continue + l=$(sed -n < $SRC_DIR/$d/group \ -e 's/#.*//' \ -e 's/$/ /' \ -- 2.5.0 From agruenba@redhat.com Wed Nov 18 08:17:57 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 A56DE7F37 for ; Wed, 18 Nov 2015 08:17:57 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 5490DAC003 for ; Wed, 18 Nov 2015 06:17:57 -0800 (PST) X-ASG-Debug-ID: 1447856272-04bdf07f08f5670001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id FCytPUeyFybRpjED (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 18 Nov 2015 06:17:53 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id DF296C00230B for ; Wed, 18 Nov 2015 14:17:52 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-27.ams2.redhat.com [10.36.5.27]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAIEHoXa027334; Wed, 18 Nov 2015 09:17:51 -0500 From: Andreas Gruenbacher To: xfs@oss.sgi.com Cc: Andreas Gruenbacher Subject: [XFSTESTS 0/6] Richacl Tests Date: Wed, 18 Nov 2015 15:17:43 +0100 X-ASG-Orig-Subj: [XFSTESTS 0/6] Richacl Tests Message-Id: <1447856269-7872-1-git-send-email-agruenba@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: 1447856273 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Here is a first set of patches for adding richacl tests to xfstexts. The richacl tests are different from the other xfstests in that they are self verifying: they report success or failure through their exit code and don't have expected output files (*.out). Thanks, Andreas Andreas Gruenbacher (6): check: Don't complain about missing tests/$FSTYP/group check: Enforce xfs filesystem recreation on $TEST_DEV Rename output file templates to match TEST.out* check: Add support for tests without *.out files Add richacl tests Remove the obsolete nfs4acl tests .gitignore | 17 ++ check | 118 +++++++++---- common/rc | 24 ++- nfs4acl/Makefile | 29 ---- nfs4acl/apply-mask.test | 143 ---------------- nfs4acl/basic.test | 70 -------- nfs4acl/chmod.test | 31 ---- nfs4acl/chown.test | 63 ------- nfs4acl/computed-mode.test | 62 ------- nfs4acl/create.test | 35 ---- nfs4acl/ctime.test | 36 ---- nfs4acl/delete.test | 77 --------- nfs4acl/run | 298 --------------------------------- nfs4acl/unrepresentable.test | 20 --- nfs4acl/write-vs-append.test | 46 ----- src/Makefile | 2 +- src/require-richacls.c | 35 ++++ tests/richacl/001-apply-masks | 1 + tests/richacl/002-auto-inheritance | 1 + tests/richacl/003-basic | 1 + tests/richacl/004-chmod | 1 + tests/richacl/005-chown | 1 + tests/richacl/006-create | 1 + tests/richacl/007-ctime | 1 + tests/richacl/008-delete | 1 + tests/richacl/009-setrichacl-modify | 1 + tests/richacl/010-write-vs-append | 1 + tests/richacl/Makefile | 44 +++++ tests/richacl/apply-masks | 163 ++++++++++++++++++ tests/richacl/auto-inheritance | 191 +++++++++++++++++++++ tests/richacl/basic | 97 +++++++++++ tests/richacl/chmod | 40 +++++ tests/richacl/chown | 42 +++++ tests/richacl/create | 36 ++++ tests/richacl/ctime | 35 ++++ tests/richacl/delete | 89 ++++++++++ tests/richacl/group | 15 ++ tests/richacl/setrichacl-modify | 57 +++++++ tests/richacl/test-lib.sh | 149 +++++++++++++++++ tests/richacl/write-vs-append | 54 ++++++ tests/xfs/033 | 2 +- tests/xfs/033.crc.out.linux | 197 ---------------------- tests/xfs/033.out.crc.linux | 197 ++++++++++++++++++++++ tests/xfs/096 | 4 +- tests/xfs/096.external | 50 ------ tests/xfs/096.internal | 51 ------ tests/xfs/096.out.external | 50 ++++++ tests/xfs/096.out.internal | 51 ++++++ tests/xfs/191 | 75 --------- tests/xfs/191.out | 324 ------------------------------------ tests/xfs/group | 1 - 51 files changed, 1485 insertions(+), 1645 deletions(-) delete mode 100644 nfs4acl/Makefile delete mode 100644 nfs4acl/apply-mask.test delete mode 100644 nfs4acl/basic.test delete mode 100644 nfs4acl/chmod.test delete mode 100644 nfs4acl/chown.test delete mode 100644 nfs4acl/computed-mode.test delete mode 100644 nfs4acl/create.test delete mode 100644 nfs4acl/ctime.test delete mode 100644 nfs4acl/delete.test delete mode 100755 nfs4acl/run delete mode 100644 nfs4acl/unrepresentable.test delete mode 100644 nfs4acl/write-vs-append.test create mode 100644 src/require-richacls.c create mode 120000 tests/richacl/001-apply-masks create mode 120000 tests/richacl/002-auto-inheritance create mode 120000 tests/richacl/003-basic create mode 120000 tests/richacl/004-chmod create mode 120000 tests/richacl/005-chown create mode 120000 tests/richacl/006-create create mode 120000 tests/richacl/007-ctime create mode 120000 tests/richacl/008-delete create mode 120000 tests/richacl/009-setrichacl-modify create mode 120000 tests/richacl/010-write-vs-append create mode 100644 tests/richacl/Makefile create mode 100755 tests/richacl/apply-masks create mode 100755 tests/richacl/auto-inheritance create mode 100755 tests/richacl/basic create mode 100755 tests/richacl/chmod create mode 100755 tests/richacl/chown create mode 100755 tests/richacl/create create mode 100755 tests/richacl/ctime create mode 100755 tests/richacl/delete create mode 100644 tests/richacl/group create mode 100755 tests/richacl/setrichacl-modify create mode 100644 tests/richacl/test-lib.sh create mode 100755 tests/richacl/write-vs-append delete mode 100644 tests/xfs/033.crc.out.linux create mode 100644 tests/xfs/033.out.crc.linux delete mode 100644 tests/xfs/096.external delete mode 100644 tests/xfs/096.internal create mode 100644 tests/xfs/096.out.external create mode 100644 tests/xfs/096.out.internal delete mode 100755 tests/xfs/191 delete mode 100644 tests/xfs/191.out -- 2.5.0 From agruenba@redhat.com Wed Nov 18 08:18:01 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 545237F54 for ; Wed, 18 Nov 2015 08:18:01 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 35DC4304043 for ; Wed, 18 Nov 2015 06:17:58 -0800 (PST) X-ASG-Debug-ID: 1447856277-04bdf07f09f5680001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id NBLIpz0V12qXCC9l (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 18 Nov 2015 06:17:57 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 19FA946216 for ; Wed, 18 Nov 2015 14:17:57 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-27.ams2.redhat.com [10.36.5.27]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAIEHoXc027334; Wed, 18 Nov 2015 09:17:55 -0500 From: Andreas Gruenbacher To: xfs@oss.sgi.com Cc: Andreas Gruenbacher Subject: [XFSTESTS 2/6] check: Enforce xfs filesystem recreation on $TEST_DEV Date: Wed, 18 Nov 2015 15:17:45 +0100 X-ASG-Orig-Subj: [XFSTESTS 2/6] check: Enforce xfs filesystem recreation on $TEST_DEV Message-Id: <1447856269-7872-3-git-send-email-agruenba@redhat.com> In-Reply-To: <1447856269-7872-1-git-send-email-agruenba@redhat.com> References: <1447856269-7872-1-git-send-email-agruenba@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: 1447856277 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 When recreating xfs filesystems on $TEST_DEV, pass option -f to enforce the filesystem creation instead of refusing to overwrite existing xfs filesystems. We already do that for ext2/ext3/ext4 filesystems. Signed-off-by: Andreas Gruenbacher --- common/rc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/common/rc b/common/rc index 4c2f42c..ce6ae3d 100644 --- a/common/rc +++ b/common/rc @@ -572,6 +572,9 @@ _test_mkfs() btrfs) $MKFS_BTRFS_PROG $MKFS_OPTIONS $* $TEST_DEV > /dev/null ;; + xfs) + $MKFS_PROG -t $FSTYP -- -f $MKFS_OPTIONS $* $TEST_DEV + ;; ext2|ext3|ext4) $MKFS_PROG -t $FSTYP -- -F $MKFS_OPTIONS $* $TEST_DEV ;; -- 2.5.0 From agruenba@redhat.com Wed Nov 18 08:18:02 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 B1E7B7F55 for ; Wed, 18 Nov 2015 08:18:02 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 54359AC003 for ; Wed, 18 Nov 2015 06:18:02 -0800 (PST) X-ASG-Debug-ID: 1447856281-04bdf07f09f5690001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id hthQdt1RDMBqmLay (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 18 Nov 2015 06:18:01 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 2A81DF806C for ; Wed, 18 Nov 2015 14:18:01 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-27.ams2.redhat.com [10.36.5.27]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAIEHoXe027334; Wed, 18 Nov 2015 09:17:59 -0500 From: Andreas Gruenbacher To: xfs@oss.sgi.com Cc: Andreas Gruenbacher Subject: [XFSTESTS 4/6] check: Add support for tests without *.out files Date: Wed, 18 Nov 2015 15:17:47 +0100 X-ASG-Orig-Subj: [XFSTESTS 4/6] check: Add support for tests without *.out files Message-Id: <1447856269-7872-5-git-send-email-agruenba@redhat.com> In-Reply-To: <1447856269-7872-1-git-send-email-agruenba@redhat.com> References: <1447856269-7872-1-git-send-email-agruenba@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: 1447856281 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Add support for tests which report their status through their exit code instead of producing output that is compared with the expected output. When such a test returns with exit code 77, it is assumed to have been skipped; all other non-zero exit codes are treated as test failures. Signed-off-by: Andreas Gruenbacher --- check | 77 +++++++++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 50 insertions(+), 27 deletions(-) diff --git a/check b/check index 4a9b332..5ecc12b 100755 --- a/check +++ b/check @@ -204,6 +204,13 @@ _prepare_test_list() fi } +# Check if a test has any .out* files +has_out_files() +{ + set -- "$1".out* + [ $# -gt 0 -a -e "$1" ] +} + # Process command arguments first. while [ $# -gt 0 ]; do case "$1" in @@ -612,6 +619,13 @@ for section in $HOST_OPTIONS_SECTIONS; do err=true fi + if ! has_out_files $seq; then + if [ $sts -eq 77 ]; then + cat $tmp.out > $seqres.notrun + sts=0 + fi + fi + if [ -f $seqres.notrun ] then $timestamp || echo -n " [not run] " @@ -624,41 +638,50 @@ for section in $HOST_OPTIONS_SECTIONS; do echo -n " [failed, exit status $sts]" err=true fi - if [ ! -f $seq.out ] - then - echo " - no qualified output" - err=true - else - # coreutils 8.16+ changed quote formats in error messages from - # `foo' to 'foo'. Filter old versions to match the new version. - sed -i "s/\`/\'/g" $tmp.out - if diff $seq.out $tmp.out >/dev/null 2>&1 + if has_out_files $seq; then + if [ ! -f $seq.out ] then - if $err + echo " - no qualified output" + err=true + else + # coreutils 8.16+ changed quote formats in error messages from + # `foo' to 'foo'. Filter old versions to match the new version. + sed -i "s/\`/\'/g" $tmp.out + + if ! diff $seq.out $tmp.out >/dev/null 2>&1 then - : - else - echo "$seqnum `expr $stop - $start`" >>$tmp.time - echo -n " `expr $stop - $start`s" + echo " - output mismatch (see $seqres.out.bad)" + mv $tmp.out $seqres.out.bad + $diff $seq.out $seqres.out.bad | { + if test "$DIFF_LENGTH" -le 0; then + cat + else + head -n "$DIFF_LENGTH" + echo "..." + echo "(Run '$diff $seq.out $seqres.out.bad'" \ + " to see the entire diff)" + fi; } | \ + sed -e 's/^\(.\)/ \1/' + err=true fi - echo "" + fi + else + if ! $err; then + mv $tmp.out $seqres.out.good else - echo " - output mismatch (see $seqres.out.bad)" mv $tmp.out $seqres.out.bad - $diff $seq.out $seqres.out.bad | { - if test "$DIFF_LENGTH" -le 0; then - cat - else - head -n "$DIFF_LENGTH" - echo "..." - echo "(Run '$diff $seq.out $seqres.out.bad'" \ - " to see the entire diff)" - fi; } | \ - sed -e 's/^\(.\)/ \1/' - err=true + echo " - output (see $seqres.out.bad)" + cat $seqres.out.bad fi fi + + if ! $err; then + echo "$seqnum `expr $stop - $start`" >>$tmp.time + echo -n " `expr $stop - $start`s" + echo "" + fi + try="$try $seqnum" n_try=`expr $n_try + 1` _check_filesystems -- 2.5.0 From agruenba@redhat.com Wed Nov 18 08:18:02 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 833467F54 for ; Wed, 18 Nov 2015 08:18:02 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 37CE8304043 for ; Wed, 18 Nov 2015 06:18:02 -0800 (PST) X-ASG-Debug-ID: 1447856279-04bdf07f07f5680001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id EtwCeUC55ZGxC8EA (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 18 Nov 2015 06:17:59 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 157D38E226 for ; Wed, 18 Nov 2015 14:17:59 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-27.ams2.redhat.com [10.36.5.27]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAIEHoXd027334; Wed, 18 Nov 2015 09:17:57 -0500 From: Andreas Gruenbacher To: xfs@oss.sgi.com Cc: Andreas Gruenbacher Subject: [XFSTESTS 3/6] Rename output file templates to match TEST.out* Date: Wed, 18 Nov 2015 15:17:46 +0100 X-ASG-Orig-Subj: [XFSTESTS 3/6] Rename output file templates to match TEST.out* Message-Id: <1447856269-7872-4-git-send-email-agruenba@redhat.com> In-Reply-To: <1447856269-7872-1-git-send-email-agruenba@redhat.com> References: <1447856269-7872-1-git-send-email-agruenba@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: 1447856279 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Rename the expected output files so that they all match "$TEST_NAME.out*". That way, we can statically check if a test has any .out* files. Tests with multiple output file variants symlink $TEST_NAME.out to one of those variants. For those tests, add $TEST_NAME.out to .gitignore. Signed-off-by: Andreas Gruenbacher --- .gitignore | 16 ++++ tests/xfs/033 | 2 +- tests/xfs/033.crc.out.linux | 197 -------------------------------------------- tests/xfs/033.out.crc.linux | 197 ++++++++++++++++++++++++++++++++++++++++++++ tests/xfs/096 | 4 +- tests/xfs/096.external | 50 ----------- tests/xfs/096.internal | 51 ------------ tests/xfs/096.out.external | 50 +++++++++++ tests/xfs/096.out.internal | 51 ++++++++++++ 9 files changed, 317 insertions(+), 301 deletions(-) delete mode 100644 tests/xfs/033.crc.out.linux create mode 100644 tests/xfs/033.out.crc.linux delete mode 100644 tests/xfs/096.external delete mode 100644 tests/xfs/096.internal create mode 100644 tests/xfs/096.out.external create mode 100644 tests/xfs/096.out.internal diff --git a/.gitignore b/.gitignore index 5dc4f69..7c25c41 100644 --- a/.gitignore +++ b/.gitignore @@ -195,3 +195,19 @@ /dmapi/src/suite2/src/test_invis /dmapi/src/suite2/src/test_region /dmapi/src/suite2/src/test_rights + +# Symlinked .out files +/tests/generic/088.out +/tests/generic/097.out +/tests/xfs/022.out +/tests/xfs/023.out +/tests/xfs/031.out +/tests/xfs/033.out +/tests/xfs/035.out +/tests/xfs/036.out +/tests/xfs/039.out +/tests/xfs/043.out +/tests/xfs/055.out +/tests/xfs/071.out +/tests/xfs/096.out +/tests/xfs/146.out diff --git a/tests/xfs/033 b/tests/xfs/033 index 576d437..4163964 100755 --- a/tests/xfs/033 +++ b/tests/xfs/033 @@ -85,7 +85,7 @@ _scratch_mkfs_xfs | _filter_mkfs 2>$tmp.mkfs # link correct .out file if [ $_fs_has_crcs -eq 1 ]; then - _link_out_file $seq.crc.out $seqfull.out + _link_out_file $seq.out.crc $seqfull.out else _link_out_file $seq.out $seqfull.out fi diff --git a/tests/xfs/033.crc.out.linux b/tests/xfs/033.crc.out.linux deleted file mode 100644 index a6e86b9..0000000 --- a/tests/xfs/033.crc.out.linux +++ /dev/null @@ -1,197 +0,0 @@ -QA output created by 033 -meta-data=DDEV isize=XXX agcount=N, agsize=XXX blks -data = bsize=XXX blocks=XXX, imaxpct=PCT - = sunit=XXX swidth=XXX, unwritten=X -naming =VERN bsize=XXX -log =LDEV bsize=XXX blocks=XXX -realtime =RDEV extsz=XXX blocks=XXX, rtextents=XXX -Corrupting root inode - setting bits to 0 -Wrote X.XXKb (value 0x0) -Phase 1 - find and verify superblock... -Phase 2 - using log - - zero log... - - scan filesystem freespace and inode maps... - - found root inode chunk -Phase 3 - for each AG... - - scan and clear agi unlinked lists... - - process known inodes and perform inode discovery... -bad magic number 0x0 on inode INO -bad version number 0x0 on inode INO -inode identifier 0 mismatch on inode INO -bad magic number 0x0 on inode INO, resetting magic number -bad version number 0x0 on inode INO, resetting version number -inode identifier 0 mismatch on inode INO -cleared root inode INO - - process newly discovered inodes... -Phase 4 - check for duplicate blocks... - - setting up duplicate extent list... -root inode lost - - check for inodes claiming duplicate blocks... -Phase 5 - rebuild AG headers and trees... - - reset superblock... -Phase 6 - check inode connectivity... -reinitializing root directory - - resetting contents of realtime bitmap and summary inodes - - traversing filesystem ... - - traversal finished ... - - moving disconnected inodes to lost+found ... -Phase 7 - verify and correct link counts... -resetting inode INO nlinks from 1 to 2 -done -Corrupting rt bitmap inode - setting bits to 0 -Wrote X.XXKb (value 0x0) -Phase 1 - find and verify superblock... -Phase 2 - using log - - zero log... - - scan filesystem freespace and inode maps... - - found root inode chunk -Phase 3 - for each AG... - - scan and clear agi unlinked lists... - - process known inodes and perform inode discovery... -bad magic number 0x0 on inode INO -bad version number 0x0 on inode INO -inode identifier 0 mismatch on inode INO -bad magic number 0x0 on inode INO, resetting magic number -bad version number 0x0 on inode INO, resetting version number -inode identifier 0 mismatch on inode INO -cleared realtime bitmap inode INO - - process newly discovered inodes... -Phase 4 - check for duplicate blocks... - - setting up duplicate extent list... - - check for inodes claiming duplicate blocks... -Phase 5 - rebuild AG headers and trees... - - reset superblock... -Phase 6 - check inode connectivity... -reinitializing realtime bitmap inode - - resetting contents of realtime bitmap and summary inodes - - traversing filesystem ... - - traversal finished ... - - moving disconnected inodes to lost+found ... -Phase 7 - verify and correct link counts... -done -Corrupting rt summary inode - setting bits to 0 -Wrote X.XXKb (value 0x0) -Phase 1 - find and verify superblock... -Phase 2 - using log - - zero log... - - scan filesystem freespace and inode maps... - - found root inode chunk -Phase 3 - for each AG... - - scan and clear agi unlinked lists... - - process known inodes and perform inode discovery... -bad magic number 0x0 on inode INO -bad version number 0x0 on inode INO -inode identifier 0 mismatch on inode INO -bad magic number 0x0 on inode INO, resetting magic number -bad version number 0x0 on inode INO, resetting version number -inode identifier 0 mismatch on inode INO -cleared realtime summary inode INO - - process newly discovered inodes... -Phase 4 - check for duplicate blocks... - - setting up duplicate extent list... - - check for inodes claiming duplicate blocks... -Phase 5 - rebuild AG headers and trees... - - reset superblock... -Phase 6 - check inode connectivity... -reinitializing realtime summary inode - - resetting contents of realtime bitmap and summary inodes - - traversing filesystem ... - - traversal finished ... - - moving disconnected inodes to lost+found ... -Phase 7 - verify and correct link counts... -done -Corrupting root inode - setting bits to -1 -Wrote X.XXKb (value 0xffffffff) -Phase 1 - find and verify superblock... -Phase 2 - using log - - zero log... - - scan filesystem freespace and inode maps... - - found root inode chunk -Phase 3 - for each AG... - - scan and clear agi unlinked lists... - - process known inodes and perform inode discovery... -bad magic number 0xffff on inode INO -bad version number 0xffffffff on inode INO -inode identifier 18446744073709551615 mismatch on inode INO -bad magic number 0xffff on inode INO, resetting magic number -bad version number 0xffffffff on inode INO, resetting version number -inode identifier 18446744073709551615 mismatch on inode INO -cleared root inode INO - - process newly discovered inodes... -Phase 4 - check for duplicate blocks... - - setting up duplicate extent list... -root inode lost - - check for inodes claiming duplicate blocks... -Phase 5 - rebuild AG headers and trees... - - reset superblock... -Phase 6 - check inode connectivity... -reinitializing root directory - - resetting contents of realtime bitmap and summary inodes - - traversing filesystem ... - - traversal finished ... - - moving disconnected inodes to lost+found ... -Phase 7 - verify and correct link counts... -resetting inode INO nlinks from 1 to 2 -done -Corrupting rt bitmap inode - setting bits to -1 -Wrote X.XXKb (value 0xffffffff) -Phase 1 - find and verify superblock... -Phase 2 - using log - - zero log... - - scan filesystem freespace and inode maps... - - found root inode chunk -Phase 3 - for each AG... - - scan and clear agi unlinked lists... - - process known inodes and perform inode discovery... -bad magic number 0xffff on inode INO -bad version number 0xffffffff on inode INO -inode identifier 18446744073709551615 mismatch on inode INO -bad magic number 0xffff on inode INO, resetting magic number -bad version number 0xffffffff on inode INO, resetting version number -inode identifier 18446744073709551615 mismatch on inode INO -cleared realtime bitmap inode INO - - process newly discovered inodes... -Phase 4 - check for duplicate blocks... - - setting up duplicate extent list... - - check for inodes claiming duplicate blocks... -Phase 5 - rebuild AG headers and trees... - - reset superblock... -Phase 6 - check inode connectivity... -reinitializing realtime bitmap inode - - resetting contents of realtime bitmap and summary inodes - - traversing filesystem ... - - traversal finished ... - - moving disconnected inodes to lost+found ... -Phase 7 - verify and correct link counts... -done -Corrupting rt summary inode - setting bits to -1 -Wrote X.XXKb (value 0xffffffff) -Phase 1 - find and verify superblock... -Phase 2 - using log - - zero log... - - scan filesystem freespace and inode maps... - - found root inode chunk -Phase 3 - for each AG... - - scan and clear agi unlinked lists... - - process known inodes and perform inode discovery... -bad magic number 0xffff on inode INO -bad version number 0xffffffff on inode INO -inode identifier 18446744073709551615 mismatch on inode INO -bad magic number 0xffff on inode INO, resetting magic number -bad version number 0xffffffff on inode INO, resetting version number -inode identifier 18446744073709551615 mismatch on inode INO -cleared realtime summary inode INO - - process newly discovered inodes... -Phase 4 - check for duplicate blocks... - - setting up duplicate extent list... - - check for inodes claiming duplicate blocks... -Phase 5 - rebuild AG headers and trees... - - reset superblock... -Phase 6 - check inode connectivity... -reinitializing realtime summary inode - - resetting contents of realtime bitmap and summary inodes - - traversing filesystem ... - - traversal finished ... - - moving disconnected inodes to lost+found ... -Phase 7 - verify and correct link counts... -done diff --git a/tests/xfs/033.out.crc.linux b/tests/xfs/033.out.crc.linux new file mode 100644 index 0000000..a6e86b9 --- /dev/null +++ b/tests/xfs/033.out.crc.linux @@ -0,0 +1,197 @@ +QA output created by 033 +meta-data=DDEV isize=XXX agcount=N, agsize=XXX blks +data = bsize=XXX blocks=XXX, imaxpct=PCT + = sunit=XXX swidth=XXX, unwritten=X +naming =VERN bsize=XXX +log =LDEV bsize=XXX blocks=XXX +realtime =RDEV extsz=XXX blocks=XXX, rtextents=XXX +Corrupting root inode - setting bits to 0 +Wrote X.XXKb (value 0x0) +Phase 1 - find and verify superblock... +Phase 2 - using log + - zero log... + - scan filesystem freespace and inode maps... + - found root inode chunk +Phase 3 - for each AG... + - scan and clear agi unlinked lists... + - process known inodes and perform inode discovery... +bad magic number 0x0 on inode INO +bad version number 0x0 on inode INO +inode identifier 0 mismatch on inode INO +bad magic number 0x0 on inode INO, resetting magic number +bad version number 0x0 on inode INO, resetting version number +inode identifier 0 mismatch on inode INO +cleared root inode INO + - process newly discovered inodes... +Phase 4 - check for duplicate blocks... + - setting up duplicate extent list... +root inode lost + - check for inodes claiming duplicate blocks... +Phase 5 - rebuild AG headers and trees... + - reset superblock... +Phase 6 - check inode connectivity... +reinitializing root directory + - resetting contents of realtime bitmap and summary inodes + - traversing filesystem ... + - traversal finished ... + - moving disconnected inodes to lost+found ... +Phase 7 - verify and correct link counts... +resetting inode INO nlinks from 1 to 2 +done +Corrupting rt bitmap inode - setting bits to 0 +Wrote X.XXKb (value 0x0) +Phase 1 - find and verify superblock... +Phase 2 - using log + - zero log... + - scan filesystem freespace and inode maps... + - found root inode chunk +Phase 3 - for each AG... + - scan and clear agi unlinked lists... + - process known inodes and perform inode discovery... +bad magic number 0x0 on inode INO +bad version number 0x0 on inode INO +inode identifier 0 mismatch on inode INO +bad magic number 0x0 on inode INO, resetting magic number +bad version number 0x0 on inode INO, resetting version number +inode identifier 0 mismatch on inode INO +cleared realtime bitmap inode INO + - process newly discovered inodes... +Phase 4 - check for duplicate blocks... + - setting up duplicate extent list... + - check for inodes claiming duplicate blocks... +Phase 5 - rebuild AG headers and trees... + - reset superblock... +Phase 6 - check inode connectivity... +reinitializing realtime bitmap inode + - resetting contents of realtime bitmap and summary inodes + - traversing filesystem ... + - traversal finished ... + - moving disconnected inodes to lost+found ... +Phase 7 - verify and correct link counts... +done +Corrupting rt summary inode - setting bits to 0 +Wrote X.XXKb (value 0x0) +Phase 1 - find and verify superblock... +Phase 2 - using log + - zero log... + - scan filesystem freespace and inode maps... + - found root inode chunk +Phase 3 - for each AG... + - scan and clear agi unlinked lists... + - process known inodes and perform inode discovery... +bad magic number 0x0 on inode INO +bad version number 0x0 on inode INO +inode identifier 0 mismatch on inode INO +bad magic number 0x0 on inode INO, resetting magic number +bad version number 0x0 on inode INO, resetting version number +inode identifier 0 mismatch on inode INO +cleared realtime summary inode INO + - process newly discovered inodes... +Phase 4 - check for duplicate blocks... + - setting up duplicate extent list... + - check for inodes claiming duplicate blocks... +Phase 5 - rebuild AG headers and trees... + - reset superblock... +Phase 6 - check inode connectivity... +reinitializing realtime summary inode + - resetting contents of realtime bitmap and summary inodes + - traversing filesystem ... + - traversal finished ... + - moving disconnected inodes to lost+found ... +Phase 7 - verify and correct link counts... +done +Corrupting root inode - setting bits to -1 +Wrote X.XXKb (value 0xffffffff) +Phase 1 - find and verify superblock... +Phase 2 - using log + - zero log... + - scan filesystem freespace and inode maps... + - found root inode chunk +Phase 3 - for each AG... + - scan and clear agi unlinked lists... + - process known inodes and perform inode discovery... +bad magic number 0xffff on inode INO +bad version number 0xffffffff on inode INO +inode identifier 18446744073709551615 mismatch on inode INO +bad magic number 0xffff on inode INO, resetting magic number +bad version number 0xffffffff on inode INO, resetting version number +inode identifier 18446744073709551615 mismatch on inode INO +cleared root inode INO + - process newly discovered inodes... +Phase 4 - check for duplicate blocks... + - setting up duplicate extent list... +root inode lost + - check for inodes claiming duplicate blocks... +Phase 5 - rebuild AG headers and trees... + - reset superblock... +Phase 6 - check inode connectivity... +reinitializing root directory + - resetting contents of realtime bitmap and summary inodes + - traversing filesystem ... + - traversal finished ... + - moving disconnected inodes to lost+found ... +Phase 7 - verify and correct link counts... +resetting inode INO nlinks from 1 to 2 +done +Corrupting rt bitmap inode - setting bits to -1 +Wrote X.XXKb (value 0xffffffff) +Phase 1 - find and verify superblock... +Phase 2 - using log + - zero log... + - scan filesystem freespace and inode maps... + - found root inode chunk +Phase 3 - for each AG... + - scan and clear agi unlinked lists... + - process known inodes and perform inode discovery... +bad magic number 0xffff on inode INO +bad version number 0xffffffff on inode INO +inode identifier 18446744073709551615 mismatch on inode INO +bad magic number 0xffff on inode INO, resetting magic number +bad version number 0xffffffff on inode INO, resetting version number +inode identifier 18446744073709551615 mismatch on inode INO +cleared realtime bitmap inode INO + - process newly discovered inodes... +Phase 4 - check for duplicate blocks... + - setting up duplicate extent list... + - check for inodes claiming duplicate blocks... +Phase 5 - rebuild AG headers and trees... + - reset superblock... +Phase 6 - check inode connectivity... +reinitializing realtime bitmap inode + - resetting contents of realtime bitmap and summary inodes + - traversing filesystem ... + - traversal finished ... + - moving disconnected inodes to lost+found ... +Phase 7 - verify and correct link counts... +done +Corrupting rt summary inode - setting bits to -1 +Wrote X.XXKb (value 0xffffffff) +Phase 1 - find and verify superblock... +Phase 2 - using log + - zero log... + - scan filesystem freespace and inode maps... + - found root inode chunk +Phase 3 - for each AG... + - scan and clear agi unlinked lists... + - process known inodes and perform inode discovery... +bad magic number 0xffff on inode INO +bad version number 0xffffffff on inode INO +inode identifier 18446744073709551615 mismatch on inode INO +bad magic number 0xffff on inode INO, resetting magic number +bad version number 0xffffffff on inode INO, resetting version number +inode identifier 18446744073709551615 mismatch on inode INO +cleared realtime summary inode INO + - process newly discovered inodes... +Phase 4 - check for duplicate blocks... + - setting up duplicate extent list... + - check for inodes claiming duplicate blocks... +Phase 5 - rebuild AG headers and trees... + - reset superblock... +Phase 6 - check inode connectivity... +reinitializing realtime summary inode + - resetting contents of realtime bitmap and summary inodes + - traversing filesystem ... + - traversal finished ... + - moving disconnected inodes to lost+found ... +Phase 7 - verify and correct link counts... +done diff --git a/tests/xfs/096 b/tests/xfs/096 index c289c10..f949e83 100755 --- a/tests/xfs/096 +++ b/tests/xfs/096 @@ -109,9 +109,9 @@ _require_v2log # choose .out file based on internal/external log rm -f $seqfull.out if [ "$USE_EXTERNAL" = yes ]; then - ln -s $seq.external $seqfull.out + ln -s $seq.out.external $seqfull.out else - ln -s $seq.internal $seqfull.out + ln -s $seq.out.internal $seqfull.out fi # maximum log record size diff --git a/tests/xfs/096.external b/tests/xfs/096.external deleted file mode 100644 index 3122330..0000000 --- a/tests/xfs/096.external +++ /dev/null @@ -1,50 +0,0 @@ -QA output created by 096 - -# su too big but must be a multiple of fs block size too ---- mkfs=-l version=2,su=262656 --- -log stripe unit (262656) must be a multiple of the block size (4096) - - -# test log stripe greater than LR size ---- mkfs=-l version=2,su=266240 --- -meta-data=DEV isize=N agcount=N, agsize=N blks -data = bsize=4096 blocks=N, imaxpct=N - = sunit=0 swidth=0 blks, unwritten=1 -naming =version 2 bsize=4096 -log =LOG bsize=4096 blocks=N, version=N -realtime =REALTIME extsz=N, blocks=N, rtextents=N - - -# same test but get log stripe from data stripe ---- mkfs=-l version=2 -d su=266240,sw=1 --- -meta-data=DEV isize=N agcount=N, agsize=N blks -data = bsize=4096 blocks=N, imaxpct=N - = sunit=65 swidth=65 blks, unwritten=1 -naming =version 2 bsize=4096 -log =LOG bsize=4096 blocks=N, version=N - = sunit=N blks -realtime =REALTIME extsz=N, blocks=N, rtextents=N - - -# test out data stripe ---- mkfs=-m crc=0 -l version=1 -d su=266240,sw=1 --- -meta-data=DEV isize=N agcount=N, agsize=N blks -data = bsize=4096 blocks=N, imaxpct=N - = sunit=65 swidth=65 blks, unwritten=1 -naming =version 2 bsize=4096 -log =LOG bsize=4096 blocks=N, version=N - = sunit=N blks -realtime =REALTIME extsz=N, blocks=N, rtextents=N - - -# test out data stripe the same but using sunit & swidth ---- mkfs=-m crc=0 -l version=1 -d sunit=520,swidth=520 --- -meta-data=DEV isize=N agcount=N, agsize=N blks -data = bsize=4096 blocks=N, imaxpct=N - = sunit=65 swidth=65 blks, unwritten=1 -naming =version 2 bsize=4096 -log =LOG bsize=4096 blocks=N, version=N - = sunit=N blks -realtime =REALTIME extsz=N, blocks=N, rtextents=N - - diff --git a/tests/xfs/096.internal b/tests/xfs/096.internal deleted file mode 100644 index 80201d2..0000000 --- a/tests/xfs/096.internal +++ /dev/null @@ -1,51 +0,0 @@ -QA output created by 096 - -# su too big but must be a multiple of fs block size too ---- mkfs=-l version=2,su=262656 --- -log stripe unit (262656) must be a multiple of the block size (4096) - - -# test log stripe greater than LR size ---- mkfs=-l version=2,su=266240 --- -meta-data=DEV isize=N agcount=N, agsize=N blks -data = bsize=4096 blocks=N, imaxpct=N - = sunit=0 swidth=0 blks, unwritten=1 -naming =version 2 bsize=4096 -log =LOG bsize=4096 blocks=N, version=N - = sunit=N blks -realtime =REALTIME extsz=N, blocks=N, rtextents=N - - -# same test but get log stripe from data stripe ---- mkfs=-l version=2 -d su=266240,sw=1 --- -meta-data=DEV isize=N agcount=N, agsize=N blks -data = bsize=4096 blocks=N, imaxpct=N - = sunit=65 swidth=65 blks, unwritten=1 -naming =version 2 bsize=4096 -log =LOG bsize=4096 blocks=N, version=N - = sunit=N blks -realtime =REALTIME extsz=N, blocks=N, rtextents=N - - -# test out data stripe ---- mkfs=-m crc=0 -l version=1 -d su=266240,sw=1 --- -meta-data=DEV isize=N agcount=N, agsize=N blks -data = bsize=4096 blocks=N, imaxpct=N - = sunit=65 swidth=65 blks, unwritten=1 -naming =version 2 bsize=4096 -log =LOG bsize=4096 blocks=N, version=N - = sunit=N blks -realtime =REALTIME extsz=N, blocks=N, rtextents=N - - -# test out data stripe the same but using sunit & swidth ---- mkfs=-m crc=0 -l version=1 -d sunit=520,swidth=520 --- -meta-data=DEV isize=N agcount=N, agsize=N blks -data = bsize=4096 blocks=N, imaxpct=N - = sunit=65 swidth=65 blks, unwritten=1 -naming =version 2 bsize=4096 -log =LOG bsize=4096 blocks=N, version=N - = sunit=N blks -realtime =REALTIME extsz=N, blocks=N, rtextents=N - - diff --git a/tests/xfs/096.out.external b/tests/xfs/096.out.external new file mode 100644 index 0000000..3122330 --- /dev/null +++ b/tests/xfs/096.out.external @@ -0,0 +1,50 @@ +QA output created by 096 + +# su too big but must be a multiple of fs block size too +--- mkfs=-l version=2,su=262656 --- +log stripe unit (262656) must be a multiple of the block size (4096) + + +# test log stripe greater than LR size +--- mkfs=-l version=2,su=266240 --- +meta-data=DEV isize=N agcount=N, agsize=N blks +data = bsize=4096 blocks=N, imaxpct=N + = sunit=0 swidth=0 blks, unwritten=1 +naming =version 2 bsize=4096 +log =LOG bsize=4096 blocks=N, version=N +realtime =REALTIME extsz=N, blocks=N, rtextents=N + + +# same test but get log stripe from data stripe +--- mkfs=-l version=2 -d su=266240,sw=1 --- +meta-data=DEV isize=N agcount=N, agsize=N blks +data = bsize=4096 blocks=N, imaxpct=N + = sunit=65 swidth=65 blks, unwritten=1 +naming =version 2 bsize=4096 +log =LOG bsize=4096 blocks=N, version=N + = sunit=N blks +realtime =REALTIME extsz=N, blocks=N, rtextents=N + + +# test out data stripe +--- mkfs=-m crc=0 -l version=1 -d su=266240,sw=1 --- +meta-data=DEV isize=N agcount=N, agsize=N blks +data = bsize=4096 blocks=N, imaxpct=N + = sunit=65 swidth=65 blks, unwritten=1 +naming =version 2 bsize=4096 +log =LOG bsize=4096 blocks=N, version=N + = sunit=N blks +realtime =REALTIME extsz=N, blocks=N, rtextents=N + + +# test out data stripe the same but using sunit & swidth +--- mkfs=-m crc=0 -l version=1 -d sunit=520,swidth=520 --- +meta-data=DEV isize=N agcount=N, agsize=N blks +data = bsize=4096 blocks=N, imaxpct=N + = sunit=65 swidth=65 blks, unwritten=1 +naming =version 2 bsize=4096 +log =LOG bsize=4096 blocks=N, version=N + = sunit=N blks +realtime =REALTIME extsz=N, blocks=N, rtextents=N + + diff --git a/tests/xfs/096.out.internal b/tests/xfs/096.out.internal new file mode 100644 index 0000000..80201d2 --- /dev/null +++ b/tests/xfs/096.out.internal @@ -0,0 +1,51 @@ +QA output created by 096 + +# su too big but must be a multiple of fs block size too +--- mkfs=-l version=2,su=262656 --- +log stripe unit (262656) must be a multiple of the block size (4096) + + +# test log stripe greater than LR size +--- mkfs=-l version=2,su=266240 --- +meta-data=DEV isize=N agcount=N, agsize=N blks +data = bsize=4096 blocks=N, imaxpct=N + = sunit=0 swidth=0 blks, unwritten=1 +naming =version 2 bsize=4096 +log =LOG bsize=4096 blocks=N, version=N + = sunit=N blks +realtime =REALTIME extsz=N, blocks=N, rtextents=N + + +# same test but get log stripe from data stripe +--- mkfs=-l version=2 -d su=266240,sw=1 --- +meta-data=DEV isize=N agcount=N, agsize=N blks +data = bsize=4096 blocks=N, imaxpct=N + = sunit=65 swidth=65 blks, unwritten=1 +naming =version 2 bsize=4096 +log =LOG bsize=4096 blocks=N, version=N + = sunit=N blks +realtime =REALTIME extsz=N, blocks=N, rtextents=N + + +# test out data stripe +--- mkfs=-m crc=0 -l version=1 -d su=266240,sw=1 --- +meta-data=DEV isize=N agcount=N, agsize=N blks +data = bsize=4096 blocks=N, imaxpct=N + = sunit=65 swidth=65 blks, unwritten=1 +naming =version 2 bsize=4096 +log =LOG bsize=4096 blocks=N, version=N + = sunit=N blks +realtime =REALTIME extsz=N, blocks=N, rtextents=N + + +# test out data stripe the same but using sunit & swidth +--- mkfs=-m crc=0 -l version=1 -d sunit=520,swidth=520 --- +meta-data=DEV isize=N agcount=N, agsize=N blks +data = bsize=4096 blocks=N, imaxpct=N + = sunit=65 swidth=65 blks, unwritten=1 +naming =version 2 bsize=4096 +log =LOG bsize=4096 blocks=N, version=N + = sunit=N blks +realtime =REALTIME extsz=N, blocks=N, rtextents=N + + -- 2.5.0 From agruenba@redhat.com Wed Nov 18 08:18:09 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 0C9247F37 for ; Wed, 18 Nov 2015 08:18:09 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id F1A34304039 for ; Wed, 18 Nov 2015 06:18:08 -0800 (PST) X-ASG-Debug-ID: 1447856283-04cb6c0cd3de0e0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id tFg2Gpr1vTuaOUZQ (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 18 Nov 2015 06:18:03 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 34BE1C049D4F for ; Wed, 18 Nov 2015 14:18:03 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-27.ams2.redhat.com [10.36.5.27]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAIEHoXf027334; Wed, 18 Nov 2015 09:18:01 -0500 From: Andreas Gruenbacher To: xfs@oss.sgi.com Cc: Andreas Gruenbacher Subject: [XFSTESTS 5/6] Add richacl tests Date: Wed, 18 Nov 2015 15:17:48 +0100 X-ASG-Orig-Subj: [XFSTESTS 5/6] Add richacl tests Message-Id: <1447856269-7872-6-git-send-email-agruenba@redhat.com> In-Reply-To: <1447856269-7872-1-git-send-email-agruenba@redhat.com> References: <1447856269-7872-1-git-send-email-agruenba@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: 1447856283 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Add the Rich Access Control List tests from the richacl package. The new tests require TEST_DEV and TEST_DIR to be set. When the check script is run, it first makes sure that the test filesystem has richacls enabled or disabled as appropriate: with the -richacl option, richacls must be enabled; without the -richacl option, richacls must be disabled. If TEST_DEV has incorrect richacl support, the TEST_DEV filesystem is recreated. The -richacl option currently selects the tests in the richacl group to be run. Additional test groups or tests can be specified on the command line, e.g., ./check -richacl -g quick (Eventually, the -richacl option will be changed to only skip tests which are incompatible with richacls.) Signed-off-by: Andreas Gruenbacher --- .gitignore | 1 + check | 39 +++++++- common/rc | 23 ++++- src/Makefile | 2 +- src/require-richacls.c | 35 +++++++ tests/richacl/001-apply-masks | 1 + tests/richacl/002-auto-inheritance | 1 + tests/richacl/003-basic | 1 + tests/richacl/004-chmod | 1 + tests/richacl/005-chown | 1 + tests/richacl/006-create | 1 + tests/richacl/007-ctime | 1 + tests/richacl/008-delete | 1 + tests/richacl/009-setrichacl-modify | 1 + tests/richacl/010-write-vs-append | 1 + tests/richacl/Makefile | 44 +++++++++ tests/richacl/apply-masks | 163 ++++++++++++++++++++++++++++++ tests/richacl/auto-inheritance | 191 ++++++++++++++++++++++++++++++++++++ tests/richacl/basic | 97 ++++++++++++++++++ tests/richacl/chmod | 40 ++++++++ tests/richacl/chown | 42 ++++++++ tests/richacl/create | 36 +++++++ tests/richacl/ctime | 35 +++++++ tests/richacl/delete | 89 +++++++++++++++++ tests/richacl/group | 15 +++ tests/richacl/setrichacl-modify | 57 +++++++++++ tests/richacl/test-lib.sh | 149 ++++++++++++++++++++++++++++ tests/richacl/write-vs-append | 54 ++++++++++ 28 files changed, 1114 insertions(+), 8 deletions(-) create mode 100644 src/require-richacls.c create mode 120000 tests/richacl/001-apply-masks create mode 120000 tests/richacl/002-auto-inheritance create mode 120000 tests/richacl/003-basic create mode 120000 tests/richacl/004-chmod create mode 120000 tests/richacl/005-chown create mode 120000 tests/richacl/006-create create mode 120000 tests/richacl/007-ctime create mode 120000 tests/richacl/008-delete create mode 120000 tests/richacl/009-setrichacl-modify create mode 120000 tests/richacl/010-write-vs-append create mode 100644 tests/richacl/Makefile create mode 100755 tests/richacl/apply-masks create mode 100755 tests/richacl/auto-inheritance create mode 100755 tests/richacl/basic create mode 100755 tests/richacl/chmod create mode 100755 tests/richacl/chown create mode 100755 tests/richacl/create create mode 100755 tests/richacl/ctime create mode 100755 tests/richacl/delete create mode 100644 tests/richacl/group create mode 100755 tests/richacl/setrichacl-modify create mode 100644 tests/richacl/test-lib.sh create mode 100755 tests/richacl/write-vs-append diff --git a/.gitignore b/.gitignore index 7c25c41..d7ff600 100644 --- a/.gitignore +++ b/.gitignore @@ -116,6 +116,7 @@ /src/cloner /src/renameat2 /src/t_rename_overwrite +/src/require-richacls # dmapi/ binaries /dmapi/src/common/cmd/read_invis diff --git a/check b/check index 5ecc12b..89b6d8a 100755 --- a/check +++ b/check @@ -60,7 +60,7 @@ then exit 1 fi -SRC_GROUPS="generic shared" +SRC_GROUPS="generic shared richacl" export SRC_DIR="tests" usage() @@ -71,6 +71,7 @@ check options -nfs test NFS -cifs test CIFS -tmpfs test TMPFS + -richacl test Rich Access Control Lists -l line mode diff -udiff show unified diff (default) -n show me, do not run tests @@ -220,6 +221,11 @@ while [ $# -gt 0 ]; do -cifs) FSTYP=cifs ;; -tmpfs) FSTYP=tmpfs ;; + -richacl) + RICHACL=1 + GROUP_LIST="$GROUP_LIST richacl" + ;; + -g) group=$2 ; shift ; GROUP_LIST="$GROUP_LIST ${group//,/ }" ;; @@ -417,6 +423,34 @@ else trap "_wrapup; exit \$status" 0 1 2 3 15 fi +# Check if the filesystem on a block device is compatible with how the test +# suite is being run. Currently, we use this to check if the filesystem +# has richacl support when needed. +_dev_is_compatible() { + local dev=$1 HAS_RICHACL= + + case "$FSTYP" in + xfs) + if xfs_db -r -c version "$dev" | grep -qw RICHACL; then + HAS_RICHACL=1 + fi + ;; + + ext2|ext3|ext4) + if tune2fs -l "$dev" | grep -q '^Filesystem features.*\'; then + HAS_RICHACL=1 + fi + ;; + + *) + # Other filesystems don't currently have richacl support; there + # is no point in recreating them. + HAS_RICHACL=$RICHACL + ;; + esac + [ "$HAS_RICHACL" = "$RICHACL" ] +} + for section in $HOST_OPTIONS_SECTIONS; do OLD_FSTYP=$FSTYP OLD_MOUNT_OPTIONS=$MOUNT_OPTIONS @@ -446,7 +480,8 @@ for section in $HOST_OPTIONS_SECTIONS; do echo "SECTION -- $section" fi - if $RECREATE_TEST_DEV || [ "$OLD_FSTYP" != "$FSTYP" ]; then + if $RECREATE_TEST_DEV || [ "$OLD_FSTYP" != "$FSTYP" ] || + ! _dev_is_compatible "$TEST_DEV"; then echo "RECREATING -- $FSTYP on $TEST_DEV" umount $TEST_DEV 2> /dev/null if ! _test_mkfs >$tmp.err 2>&1 diff --git a/common/rc b/common/rc index ce6ae3d..0dd8e4f 100644 --- a/common/rc +++ b/common/rc @@ -559,6 +559,19 @@ _scratch_mkfs_ext4() _test_mkfs() { + local OPT=$MKFS_OPTIONS + + if [ -n "$RICHACL" ]; then + case "$FSTYP" in + xfs) + OPT="$OPT -m richacl=1" + ;; + ext2|ext3|ext4) + OPT="$OPT -O richacl" + ;; + esac + fi + case $FSTYP in nfs*) # do nothing for nfs @@ -567,19 +580,19 @@ _test_mkfs() # do nothing for cifs ;; udf) - $MKFS_UDF_PROG $MKFS_OPTIONS $* $TEST_DEV > /dev/null + $MKFS_UDF_PROG $OPT $* $TEST_DEV > /dev/null ;; btrfs) - $MKFS_BTRFS_PROG $MKFS_OPTIONS $* $TEST_DEV > /dev/null + $MKFS_BTRFS_PROG $OPT $* $TEST_DEV > /dev/null ;; xfs) - $MKFS_PROG -t $FSTYP -- -f $MKFS_OPTIONS $* $TEST_DEV + $MKFS_PROG -t $FSTYP -- -f $OPT $* $TEST_DEV ;; ext2|ext3|ext4) - $MKFS_PROG -t $FSTYP -- -F $MKFS_OPTIONS $* $TEST_DEV + $MKFS_PROG -t $FSTYP -- -F $OPT $* $TEST_DEV ;; *) - yes | $MKFS_PROG -t $FSTYP -- $MKFS_OPTIONS $* $TEST_DEV + yes | $MKFS_PROG -t $FSTYP -- $OPT $* $TEST_DEV ;; esac } diff --git a/src/Makefile b/src/Makefile index 4781736..7908f3c 100644 --- a/src/Makefile +++ b/src/Makefile @@ -19,7 +19,7 @@ LINUX_TARGETS = xfsctl bstat t_mtab getdevicesize preallo_rw_pattern_reader \ bulkstat_unlink_test_modified t_dir_offset t_futimens t_immutable \ stale_handle pwrite_mmap_blocked t_dir_offset2 seek_sanity_test \ seek_copy_test t_readdir_1 t_readdir_2 fsync-tester nsexec cloner \ - renameat2 t_getcwd e4compact + renameat2 t_getcwd e4compact require-richacls SUBDIRS = diff --git a/src/require-richacls.c b/src/require-richacls.c new file mode 100644 index 0000000..dce984f --- /dev/null +++ b/src/require-richacls.c @@ -0,0 +1,35 @@ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + int ret; + + ret = getxattr(".", "system.richacl", NULL, 0); + if (ret < 0 && errno != ENODATA) { + char cwd[PATH_MAX]; + + if (!getcwd(cwd, sizeof(cwd))) + strcpy(cwd, "."); + if (errno == ENOTSUP) { + printf("This test requires a filesystem with richacl " + "support at %s\n", + cwd); + return 77; + } else { + perror(cwd); + return 1; + } + } + return 0; +} diff --git a/tests/richacl/001-apply-masks b/tests/richacl/001-apply-masks new file mode 120000 index 0000000..256bb2b --- /dev/null +++ b/tests/richacl/001-apply-masks @@ -0,0 +1 @@ +apply-masks \ No newline at end of file diff --git a/tests/richacl/002-auto-inheritance b/tests/richacl/002-auto-inheritance new file mode 120000 index 0000000..98472fc --- /dev/null +++ b/tests/richacl/002-auto-inheritance @@ -0,0 +1 @@ +auto-inheritance \ No newline at end of file diff --git a/tests/richacl/003-basic b/tests/richacl/003-basic new file mode 120000 index 0000000..ea5233d --- /dev/null +++ b/tests/richacl/003-basic @@ -0,0 +1 @@ +basic \ No newline at end of file diff --git a/tests/richacl/004-chmod b/tests/richacl/004-chmod new file mode 120000 index 0000000..8acd9e4 --- /dev/null +++ b/tests/richacl/004-chmod @@ -0,0 +1 @@ +chmod \ No newline at end of file diff --git a/tests/richacl/005-chown b/tests/richacl/005-chown new file mode 120000 index 0000000..6fb0fcd --- /dev/null +++ b/tests/richacl/005-chown @@ -0,0 +1 @@ +chown \ No newline at end of file diff --git a/tests/richacl/006-create b/tests/richacl/006-create new file mode 120000 index 0000000..f4ab424 --- /dev/null +++ b/tests/richacl/006-create @@ -0,0 +1 @@ +create \ No newline at end of file diff --git a/tests/richacl/007-ctime b/tests/richacl/007-ctime new file mode 120000 index 0000000..3ddadee --- /dev/null +++ b/tests/richacl/007-ctime @@ -0,0 +1 @@ +ctime \ No newline at end of file diff --git a/tests/richacl/008-delete b/tests/richacl/008-delete new file mode 120000 index 0000000..bbd98f4 --- /dev/null +++ b/tests/richacl/008-delete @@ -0,0 +1 @@ +delete \ No newline at end of file diff --git a/tests/richacl/009-setrichacl-modify b/tests/richacl/009-setrichacl-modify new file mode 120000 index 0000000..e3ebe54 --- /dev/null +++ b/tests/richacl/009-setrichacl-modify @@ -0,0 +1 @@ +setrichacl-modify \ No newline at end of file diff --git a/tests/richacl/010-write-vs-append b/tests/richacl/010-write-vs-append new file mode 120000 index 0000000..f19a074 --- /dev/null +++ b/tests/richacl/010-write-vs-append @@ -0,0 +1 @@ +write-vs-append \ No newline at end of file diff --git a/tests/richacl/Makefile b/tests/richacl/Makefile new file mode 100644 index 0000000..46662c5 --- /dev/null +++ b/tests/richacl/Makefile @@ -0,0 +1,44 @@ +# +# Copyright (C) 2015 Red Hat, Inc. +# + +# TOPDIR = .. +# include $(TOPDIR)/include/builddefs +# +# TESTS = apply-masks basic chmod chown create delete setrichacl-modify \ +# write-vs-append ctime auto-inheritance +# +# LSRCFILES = test-lib.sh $(TESTS) +# +# default install install-dev install-lib: +# +# include $(BUILDRULES) + +#$(TARGETS): +# @echo " [CC] $@" +# $(Q)$(LTLINK) $@.c -o $@ $(CFLAGS) $(LDFLAGS) $(LDLIBS) + +#TESTS_ENVIRONMENT = \ +# abs_top_builddir=$(abs_top_builddir); \ +# export abs_top_builddir; +# +# +# +# +# + +TOPDIR = ../.. +include $(TOPDIR)/include/builddefs + +TARGET_DIR = $(PKG_LIB_DIR)/$(TESTS_DIR)/richacl + +include $(BUILDRULES) + +install: + $(INSTALL) -m 755 -d $(TARGET_DIR) + $(INSTALL) -m 755 [0-9]?? $(TESTS) $(TARGET_DIR) + $(INSTALL) -m 644 group $(TARGET_DIR) + #$(INSTALL) -m 644 [0-9]??.* $(TARGET_DIR) + +# Nothing. +install-dev install-lib: diff --git a/tests/richacl/apply-masks b/tests/richacl/apply-masks new file mode 100755 index 0000000..7a99cf9 --- /dev/null +++ b/tests/richacl/apply-masks @@ -0,0 +1,163 @@ +#! /bin/sh + +. ${0%/*}/test-lib.sh + +require_richacls +use_tmpdir + +ncheck "touch x" +ncheck "setrichacl --set 'owner@:rwp::allow group@:rwp::allow everyone@:r::allow' x" +check "getrichacl x" < acl.txt" +check "cat acl.txt" <&2 + exit 77 + fi +} + +require_richacls() { + $here/src/require-richacls || exit $? + if ! type -f getrichacl setrichacl > /dev/null; then + echo "This test requires the getrichacl and setrichacl utilities" >&2 + exit 77 + fi +} + +require_getfattr() { + if ! type -f getfattr > /dev/null ; then + echo "This test requires the getfattr utility" >&2 + exit 77 + fi +} + +_RUNAS= +runas() { + _start_test -1 runas "$*" + if [ $# = 0 ]; then + _RUNAS= + else + _RUNAS="$here/src/runas $* --" + fi + echo "ok" +} + +if diff -u -L expected -L got /dev/null /dev/null 2> /dev/null; then + eval '_compare() { + diff -u -L expected -L got "$1" "$2" + }' +else + eval '_compare() { + echo "expected:" + cat "$1" + echo "got:" + cat "$2" + }' +fi + +_check() { + local frame=$1 + shift + _start_test "$frame" "$*" + expected=`cat` + if got=`set +x; eval "$_RUNAS $*" 3>&2
&1` && \ + test "$expected" = "$got" ; then + echo "ok" + checks_succeeded="$checks_succeeded + 1" + else + echo "FAILED" + if test "$expected" != "$got" ; then + echo "$expected" > expected~ + echo "$got" > got~ + _compare expected~ got~ + rm -f expected~ got~ + fi + checks_failed="$checks_failed + 1" + fi +} + +check() { + _check 0 "$@" +} + +ncheck() { + _check 0 "$@" < /dev/null +} + +parent_check() { + _check 1 "$@" +} + +parent_ncheck() { + _check 1 "$@" < /dev/null +} + +cleanup() { + status=$? + checks_succeeded=`expr $checks_succeeded` + checks_failed=`expr $checks_failed` + checks_total=`expr $checks_succeeded + $checks_failed` + if test $checks_total -gt 0 ; then + if test $checks_failed -gt 0 && test $status -eq 0 ; then + status=1 + fi + echo "$checks_total tests ($checks_succeeded passed," \ + "$checks_failed failed)" + fi + if test -n "$tmpdir" ; then + chmod -R u+rwx "$tmpdir" 2>/dev/null + cd / && rm -rf "$tmpdir" + fi + exit $status +} + +if test -z "`echo -n`"; then + if eval 'test -n "${BASH_LINENO[0]}" 2>/dev/null'; then + eval ' + _start_test() { + local frame=$1 + shift + printf "[${BASH_LINENO[2+frame]}] $* -- " + }' + else + eval ' + _start_test() { + shift + printf "* $* -- " + }' + fi +else + eval ' + _start_test() { + shift + printf "* $*\\n" + }' +fi + +if ! type cat > /dev/null 2> /dev/null; then + echo "This test requires the cat utility" >&2 + exit 77 +fi + +export PATH=$here/src:$PATH + +[ -z "$TEST_DIR" ] || cd "$TEST_DIR" + +checks_succeeded=0 +checks_failed=0 +trap cleanup 0 diff --git a/tests/richacl/write-vs-append b/tests/richacl/write-vs-append new file mode 100755 index 0000000..4528f3a --- /dev/null +++ b/tests/richacl/write-vs-append @@ -0,0 +1,54 @@ +#! /bin/sh + +. ${0%/*}/test-lib.sh + +require_runas +require_richacls +use_tmpdir + +export LC_ALL=C + +ncheck "touch a b c d e f" +ncheck "setrichacl --set 'owner@:rwp::allow' a" +ncheck "setrichacl --set 'owner@:rwp::allow 99:w::allow' b" +ncheck "setrichacl --set 'owner@:rwp::allow 99:p::allow' c" +ncheck "setrichacl --set 'owner@:rwp::allow 99:wp::allow' d" +ncheck "setrichacl --set '99:a::deny owner@:rwp::allow 99:w::allow' e" +ncheck "setrichacl --set '99:w::deny owner@:rwp::allow 99:p::allow' f" + +runas -u 99 -g 99 +check "sh -c 'echo a > a' || :" < b' || :" +check "sh -c 'echo c > c' || :" < d' || :" +ncheck "sh -c 'echo e > e' || :" +check "sh -c 'echo f > f' || :" <> a' || :" <> b' || :" <> c' || :" +ncheck "sh -c 'echo D >> d' || :" +check "sh -c 'echo E >> e' || :" <> f' || :" + +runas +check "cat a b c d e f" < 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 3097B7F73 for ; Wed, 18 Nov 2015 08:18:11 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 0EBD7304039 for ; Wed, 18 Nov 2015 06:18:11 -0800 (PST) X-ASG-Debug-ID: 1447856285-04cbb0605d1058a0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id SkU38iczgZ1wSPGO (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 18 Nov 2015 06:18:05 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 491CCC0A527E for ; Wed, 18 Nov 2015 14:18:05 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-27.ams2.redhat.com [10.36.5.27]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAIEHoXg027334; Wed, 18 Nov 2015 09:18:03 -0500 From: Andreas Gruenbacher To: xfs@oss.sgi.com Cc: Andreas Gruenbacher Subject: [XFSTESTS 6/6] Remove the obsolete nfs4acl tests Date: Wed, 18 Nov 2015 15:17:49 +0100 X-ASG-Orig-Subj: [XFSTESTS 6/6] Remove the obsolete nfs4acl tests Message-Id: <1447856269-7872-7-git-send-email-agruenba@redhat.com> In-Reply-To: <1447856269-7872-1-git-send-email-agruenba@redhat.com> References: <1447856269-7872-1-git-send-email-agruenba@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: 1447856285 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 The nfs4acl tests don't make sense anymore as they have been obsoleted by richacls. Signed-off-by: Andreas Gruenbacher --- nfs4acl/Makefile | 29 ---- nfs4acl/apply-mask.test | 143 ------------------- nfs4acl/basic.test | 70 ---------- nfs4acl/chmod.test | 31 ----- nfs4acl/chown.test | 63 --------- nfs4acl/computed-mode.test | 62 --------- nfs4acl/create.test | 35 ----- nfs4acl/ctime.test | 36 ----- nfs4acl/delete.test | 77 ---------- nfs4acl/run | 298 --------------------------------------- nfs4acl/unrepresentable.test | 20 --- nfs4acl/write-vs-append.test | 46 ------ tests/xfs/191 | 75 ---------- tests/xfs/191.out | 324 ------------------------------------------- tests/xfs/group | 1 - 15 files changed, 1310 deletions(-) delete mode 100644 nfs4acl/Makefile delete mode 100644 nfs4acl/apply-mask.test delete mode 100644 nfs4acl/basic.test delete mode 100644 nfs4acl/chmod.test delete mode 100644 nfs4acl/chown.test delete mode 100644 nfs4acl/computed-mode.test delete mode 100644 nfs4acl/create.test delete mode 100644 nfs4acl/ctime.test delete mode 100644 nfs4acl/delete.test delete mode 100755 nfs4acl/run delete mode 100644 nfs4acl/unrepresentable.test delete mode 100644 nfs4acl/write-vs-append.test delete mode 100755 tests/xfs/191 delete mode 100644 tests/xfs/191.out diff --git a/nfs4acl/Makefile b/nfs4acl/Makefile deleted file mode 100644 index 42313f3..0000000 --- a/nfs4acl/Makefile +++ /dev/null @@ -1,29 +0,0 @@ -#----------------------------------------------------------------------- -# Copyright (c) 2008 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 -# -#----------------------------------------------------------------------- - -TOPDIR = .. -include $(TOPDIR)/include/builddefs - -LSRCFILES = run \ - apply-mask.test chmod.test computed-mode.test ctime.test \ - unrepresentable.test basic.test chown.test create.test \ - delete.test write-vs-append.test - -include $(BUILDRULES) - -default install install-dev install-lib: diff --git a/nfs4acl/apply-mask.test b/nfs4acl/apply-mask.test deleted file mode 100644 index 9b9483a..0000000 --- a/nfs4acl/apply-mask.test +++ /dev/null @@ -1,143 +0,0 @@ -$ rm -rf d -$ mkdir d -$ cd d - -$ touch x - -$ nfs4acl --set 'owner@:rw::allow group@:rw::allow everyone@:r::allow' x -$ nfs4acl --get x -> x: -> owner@:rw::allow -> group@:rw::allow -> everyone@:r::allow -> - -$ nfs4acl --set 'everyone@:w::allow owner@:r::allow group@:r::allow' x -$ chmod 664 x -$ nfs4acl --get x -> x: -> owner@:rw::allow -> group@:rw::allow -> - -$ nfs4acl --set 'everyone@:w::deny owner@:rw::allow group@:rw::allow' x -$ chmod 664 x -$ nfs4acl --get x -> x: -> owner@:r::allow -> group@:r::allow -> - -$ nfs4acl --set 'owner@:rwmo::allow' x -$ nfs4acl --get x -> x: -> owner@:rwmo::allow -> - -$ chmod 644 x -$ nfs4acl --get x -> x: -> owner@:rw::allow -> - -$ nfs4acl --set 'root:rw::allow' x -$ chmod 664 x -$ nfs4acl --get x -> x: -> root:rw::allow -> - -$ chmod 644 x -$ nfs4acl --get x -> x: -> root:r::allow -> - -$ chmod 664 x -$ nfs4acl --get x -> x: -> root:rw::allow -> - -$ nfs4acl --set 'root:rw::allow everyone@:r::allow' x -$ chmod 664 x -$ nfs4acl --get x -> x: -> root:rw::allow -> everyone@:r::allow -> - -$ nfs4acl --set 'root:r::allow everyone@:rw::allow' x -$ chmod 664 x -$ nfs4acl --get x -> x: -> root:rw::allow -> owner@:rw::allow -> group@:rw::allow -> everyone@:r::allow -> - -$ nfs4acl --set 'root:w::deny everyone@:rw::allow' x -$ chmod 664 x -$ nfs4acl --get x -> x: -> root:w::deny -> owner@:rw::allow -> group@:rw::allow -> root:r::allow -> everyone@:r::allow -> - -$ nfs4acl --set 'root:rw::allow root:w::deny everyone@:rw::allow' x -$ chmod 664 x -$ nfs4acl --get x -> x: -> root:rw::allow -> root:w::deny -> owner@:rw::allow -> group@:rw::allow -> everyone@:r::allow -> - -$ nfs4acl --set 'everyone@:rw::allow' x -$ chmod 066 x -$ nfs4acl --get x -> x: -> owner@:rw::deny -> everyone@:rw::allow -> - -$ chmod 006 x -$ nfs4acl --get x -> x: -> owner@:rw::deny -> group@:rw::deny -> everyone@:rw::allow -> - -$ chmod 606 x -$ nfs4acl --get x -> x: -> group@:rw::deny -> everyone@:rw::allow -> - -$ nfs4acl --set 'root:rw::allow everyone@:rw::allow' x -$ chmod 606 x -$ nfs4acl --get x -> x: -> group@:rw::deny -> everyone@:rw::allow -> - -$ chmod 646 x -$ nfs4acl --get x -> x: -> root:r::allow -> group@:w::deny -> root:w::deny -> everyone@:rw::allow -> - -$ cd .. -$ rm -rf d diff --git a/nfs4acl/basic.test b/nfs4acl/basic.test deleted file mode 100644 index 1ae2896..0000000 --- a/nfs4acl/basic.test +++ /dev/null @@ -1,70 +0,0 @@ -$ rm -rf d -$ mkdir d -$ cd d - -$ chown bin . -$ su bin - -$ touch x -$ nfs4acl --set 'everyone@:rw::allow' x -$ ls -l x | cut -d ' ' -f 1 -> -rw-rw-rw- - -$ nfs4acl --get x -> x: -> everyone@:rw::allow -> - -$ chmod 664 x -$ ls -l x | cut -d ' ' -f 1 -> -rw-rw-r-- - -$ nfs4acl --get x -> x: -> owner@:rw::allow -> group@:rw::allow -> everyone@:r::allow -> - -$ mkdir sub -$ nfs4acl --set 'everyone@:rwax:fd:allow' sub -$ ls -dl sub | cut -d ' ' -f 1 -> drwxrwxrwx - -$ nfs4acl --get sub -> sub: -> everyone@:rwax:fd:allow -> - -$ chmod 775 sub -$ ls -dl sub | cut -d ' ' -f 1 -> drwxrwxr-x -$ nfs4acl --get sub -> sub: -> owner@:rwax::allow -> group@:rwax::allow -> everyone@:rwax:fdi:allow -> everyone@:rx::allow -> - -$ touch sub/f -$ ls -l sub/f | cut -d ' ' -f 1 -> -rw-rw-rw- - -$ nfs4acl --get sub/f -> sub/f: -> everyone@:rwa::allow -> - -$ mkdir sub/sub2 -$ ls -dl sub/sub2 | cut -d ' ' -f 1 -> drwxrwxrwx - -$ nfs4acl --get sub/sub2 -> sub/sub2: -> everyone@:rwax:fd:allow -> - -$ su -$ cd .. -$ rm -rf d diff --git a/nfs4acl/chmod.test b/nfs4acl/chmod.test deleted file mode 100644 index f4238b0..0000000 --- a/nfs4acl/chmod.test +++ /dev/null @@ -1,31 +0,0 @@ -$ mkdir d -$ cd d - -$ whoami -> root - -$ touch a - -Neet to have write_acl permission to chmod or set the acl: - $ su bin - $ chmod 666 a - > chmod: changing permissions of `a': Operation not permitted - $ nfs4acl --set 'bin:rwM::allow' a - > a: Operation not permitted - -$ su -$ nfs4acl --set 'bin:rwm::allow' a - -Can set the acl now: - $ su bin - $ nfs4acl --set 'bin:rwm::allow' a - -A chmod limits the permissions to the specified mode, which always disables -write_acl: - $ chmod 666 a - $ nfs4acl --set 'bin:rwm::allow' a - > a: Operation not permitted - -$ su -$ cd .. -$ rm -rf d diff --git a/nfs4acl/chown.test b/nfs4acl/chown.test deleted file mode 100644 index df29bf4..0000000 --- a/nfs4acl/chown.test +++ /dev/null @@ -1,63 +0,0 @@ -$ mkdir d -$ cd d - -$ whoami -> root - -$ id -Gn daemon -> daemon bin - -$ touch a - -Chown and chgrp with no take ownership permission fails: - $ su daemon - $ chown daemon a - > chown: changing ownership of `a': Operation not permitted - $ chgrp daemon a - > chgrp: changing group of `a': Operation not permitted - $ nfs4acl --set 'daemon:rwo::allow' a - > a: Operation not permitted - -Add the take_ownership permission. This is reflected in the file masks; the -file mode cannot show this though: - $ su - $ nfs4acl --set 'daemon:rwo::allow' a - -Chown and chgrp to an arbitrary other user or group fails: - $ su daemon - $ chown root a - > chown: changing ownership of `a': Operation not permitted - $ chgrp root a - > chgrp: changing group of `a': Operation not permitted - -Changing the mode makes that an upper bound of the permissions granted, even -when the file mode stays the same: - $ su - $ ls -l a | cut -d ' ' -f1 - > -rw-rw---- - $ chmod 660 a - -Chown and chgrp to the same user or a group the process is in now fails -because the masks now do not grant change_ownership access: - $ su daemon - $ chown daemon a - > chown: changing ownership of `a': Operation not permitted - $ chgrp daemon a - > chgrp: changing group of `a': Operation not permitted - $ chgrp bin a - > chgrp: changing group of `a': Operation not permitted - -Add back change_ownership: - $ su - $ nfs4acl --set 'daemon:rwo::allow' a - -Now, chgrp to one of the groups the process is in and chown to the same user -succeeds: - $ su daemon - $ chgrp daemon a - $ chgrp bin a - $ chown daemon a - -$ su -$ cd .. -$ rm -rf d diff --git a/nfs4acl/computed-mode.test b/nfs4acl/computed-mode.test deleted file mode 100644 index baa68d6..0000000 --- a/nfs4acl/computed-mode.test +++ /dev/null @@ -1,62 +0,0 @@ -$ rm -rf d -$ mkdir d -$ cd d - -$ mkdir e - -$ nfs4acl --set 'owner@:rwx:f:allow' e -$ touch e/f -$ ls -l e/f | cut -d ' ' -f 1 -> -rw------- -$ rm e/f - -$ nfs4acl --set 'group@:rwx:f:allow' e -$ touch e/f -$ ls -l e/f | cut -d ' ' -f 1 -> -rw-rw---- -$ rm e/f - -$ nfs4acl --set 'everyone@:rwx:f:allow' e -$ touch e/f -$ ls -l e/f | cut -d ' ' -f 1 -> -rw-rw-rw- -$ rm e/f - -$ nfs4acl --set 'owner@:rwx:f:allow root:rx:f:deny root:rx:f:allow' e -$ touch e/f -$ ls -l e/f | cut -d ' ' -f 1 -> -rw------- -$ rm e/f - -$ nfs4acl --set 'owner@:rwx::allow everyone@:w:fi:deny everyone@:rwx:fi:allow' e -$ touch e/f -$ ls -l e/f | cut -d ' ' -f 1 -> -r--r--r-- -$ rm e/f - -$ nfs4acl --set 'owner@:rwx::allow root:rx:fi:deny root:rx:fi:allow' e -$ touch e/f -$ ls -l e/f | cut -d ' ' -f 1 -> ---------- -$ rm e/f - -$ nfs4acl --set 'owner@:rx:fi:allow group@:rwx:fi:deny everyone@:rwx:f:allow' e -$ touch e/f -$ ls -l e/f | cut -d ' ' -f 1 -> -rw----rw- -$ rm e/f - -$ nfs4acl --set 'owner@:rx:fi:allow root:rwx:fi:deny everyone@:rwx:f:allow' e -$ touch e/f -$ ls -l e/f | cut -d ' ' -f 1 -> -rw-rw-rw- -$ rm e/f - -$ nfs4acl --set 'everyone@:w:fi:deny root:rx:fi:allow everyone@:rwx:f:allow' e -$ touch e/f -$ ls -l e/f | cut -d ' ' -f 1 -> -r--r--r-- -$ rm e/f - -$ cd .. -$ rm -rf d diff --git a/nfs4acl/create.test b/nfs4acl/create.test deleted file mode 100644 index e140f4b..0000000 --- a/nfs4acl/create.test +++ /dev/null @@ -1,35 +0,0 @@ -$ mkdir d -$ cd d - -$ whoami -> root - -$ mkdir d1 d2 d3 d4 -$ nfs4acl --set 'daemon:wx::allow' d2 -$ nfs4acl --set 'daemon:ax::allow' d3 -$ nfs4acl --set 'daemon:wax::allow' d4 - -$ su daemon - -Cannot create files or directories without permissions: - $ touch d1/f - > touch: cannot touch `d1/f': Permission denied - $ mkdir d1/d - > mkdir: cannot create directory `d1/d': Permission denied - -Can create files with add_file (w) permission: - $ touch d2/f - $ mkdir d2/d - > mkdir: cannot create directory `d2/d': Permission denied - -Can create directories with add_subdirectory (p) permission: - $ touch d3/f - > touch: cannot touch `d3/f': Permission denied - $ mkdir d3/d - -Both permissions at the same time: - $ touch d4/f - $ mkdir d4/d -$ su -$ cd .. -$ rm -rf d diff --git a/nfs4acl/ctime.test b/nfs4acl/ctime.test deleted file mode 100644 index 614d79b..0000000 --- a/nfs4acl/ctime.test +++ /dev/null @@ -1,36 +0,0 @@ -$ mkdir d -$ cd d - -$ whoami -> root - -$ touch a b -$ sleep 1 - -Without write access, the ctime cannot be changed. - $ su bin - $ touch a - > touch: cannot touch `a': Permission denied - -With write access, the ctime can be set to the current time, but not to -any other time: - $ su - $ nfs4acl --set 'bin:rw::allow' a - - $ su bin - $ touch a - $ [ b -ot a ] || echo 'b should be older than a' - $ touch -r b a - > touch: setting times of `a': Operation not permitted - -With set_attributes access, the ctime can be set to an arbitrary time: - $ su - $ nfs4acl --set 'bin:rwt::allow' a - - $ su bin - $ touch -r b a - $ [ b -ot a -o a -ot b ] && echo 'a should be as old as b' - -$ su -$ cd .. -$ rm -rf d diff --git a/nfs4acl/delete.test b/nfs4acl/delete.test deleted file mode 100644 index 9c5f24f..0000000 --- a/nfs4acl/delete.test +++ /dev/null @@ -1,77 +0,0 @@ -$ mkdir d -$ cd d - -$ whoami -> root - -$ id -Gn daemon -> daemon bin - -$ mkdir n1 -$ touch n1/f - -$ mkdir d2 d3 d4 d5 d6 d7 -$ touch d2/f d3/f d4/f d5/f d6/f d7/f d7/g -$ chown daemon d2 -$ chgrp bin d3 -$ chmod g+w d3 -$ nfs4acl --set 'daemon:wx::allow' d4 -$ nfs4acl --set 'daemon:d::allow' d5 -$ nfs4acl --set 'daemon:xd::allow' d6 -$ nfs4acl --set 'daemon:D::allow' d7/f d7/g -$ chmod 664 d7/g - -$ mkdir s2 s3 s4 s5 s6 s7 -$ chmod +t s2 s3 s4 s5 s6 s7 -$ touch s2/f s3/f s4/f s5/f s6/f s7/f s7/g -$ chown daemon s2 -$ chgrp bin s3 -$ chmod g+w s3 -$ nfs4acl --set 'daemon:wx::allow' s4 -$ nfs4acl --set 'daemon:d::allow' s5 -$ nfs4acl --set 'daemon:xd::allow' s6 -$ nfs4acl --set 'daemon:D::allow' s7/f -$ nfs4acl --set 'daemon:D::allow' s7/g s7/g -$ chmod 664 s7/g - -$ su daemon - -Cannot delete files without permissions: - $ rm n1/f - > rm: cannot remove `n1/f': Permission denied - -Can delete files we own: - $ rm d2/f s2/f - -Cannot delete files where we are in the owning group in a non-sticky directory, -but not in a sticky one: - $ rm d3/f s3/f - > rm: cannot remove `s3/f': Operation not permitted - -"Write_data/execute" access does not include delete_child access, and so this -is not enough for deleting: - $ rm d4/f s4/f - > rm: cannot remove `d4/f': Permission denied - > rm: cannot remove `s4/f': Permission denied - -"Delete_child" access alone also is not sufficient: - $ rm d5/f s5/f - > rm: cannot remove `d5/f': Permission denied - > rm: cannot remove `s5/f': Permission denied - -"Execute/delete_child" on the directory does allow that, though, but only in -a non-sticky directory: - $ rm d6/f s6/f - > rm: cannot remove `s6/f': Operation not permitted - -"Delete" on the child itself overrides the sticky check as well: - $ rm d7/f s7/f - -But Delete is not a subset of POSIX read/write, so chmod turns it off: - $ rm d7/g s7/g - > rm: cannot remove `d7/g': Permission denied - > rm: cannot remove `s7/g': Permission denied - -$ su -$ cd .. -$ rm -rf d diff --git a/nfs4acl/run b/nfs4acl/run deleted file mode 100755 index 360739e..0000000 --- a/nfs4acl/run +++ /dev/null @@ -1,298 +0,0 @@ -#!/usr/bin/perl -w -U - -# -# Possible improvements: -# -# - distinguish stdout and stderr output -# - add environment variable like assignments -# - run up to a specific line -# - resume at a specific line -# - -use strict; -use FileHandle; -use Getopt::Std; -use POSIX qw(isatty setuid getcwd); -use vars qw($opt_l $opt_v); - -no warnings qw(taint); - -$opt_l = ~0; # a really huge number -getopts('l:v'); - -my ($OK, $FAILED) = ("ok", "failed"); -if (isatty(fileno(STDOUT))) { - $OK = "\033[32m" . $OK . "\033[m"; - $FAILED = "\033[31m\033[1m" . $FAILED . "\033[m"; -} - -sub exec_test($$); -sub process_test($$$$); - -my ($prog, $in, $out) = ([], [], []); -my $prog_line = 0; -my ($tests, $failed) = (0,0); -my $lineno; -my $width = ($ENV{COLUMNS} || 80) >> 1; - -for (;;) { - my $line = <>; $lineno++; - if (defined $line) { - # Substitute %VAR and %{VAR} with environment variables. - $line =~ s[%(\w+)][$ENV{$1}]eg; - $line =~ s[%{(\w+)}][$ENV{$1}]eg; - } - if (defined $line) { - if ($line =~ s/^\s*< ?//) { - push @$in, $line; - } elsif ($line =~ s/^\s*> ?//) { - push @$out, $line; - } else { - process_test($prog, $prog_line, $in, $out); - last if $prog_line >= $opt_l; - - $prog = []; - $prog_line = 0; - } - if ($line =~ s/^\s*\$ ?//) { - $line =~ s/\s+#.*//; # remove comments here... - $prog = [ map { s/\\(.)/$1/g; $_ } split /(? @$result) ? @$out : @$result; - for (my $n=0; $n < $nmax; $n++) { - my $use_re; - if (defined $out->[$n] && $out->[$n] =~ /^~ /) { - $use_re = 1; - $out->[$n] =~ s/^~ //g; - } - - if (!defined($out->[$n]) || !defined($result->[$n]) || - (!$use_re && $result->[$n] ne $out->[$n]) || - ( $use_re && $result->[$n] !~ /^$out->[$n]/)) { - push @good, ($use_re ? '!~' : '!='); - } - else { - push @good, ($use_re ? '=~' : '=='); - } - } - my $good = !(grep /!/, @good); - $tests++; - $failed++ unless $good; - print $good ? $OK : $FAILED, "\n"; - if (!$good || $opt_v) { - for (my $n=0; $n < $nmax; $n++) { - my $l = defined($out->[$n]) ? $out->[$n] : "~"; - chomp $l; - my $r = defined($result->[$n]) ? $result->[$n] : "~"; - chomp $r; - print sprintf("%-" . ($width-3) . "s %s %s\n", - $r, $good[$n], $l); - } - } -} - - -sub su($) { - my ($user) = @_; - - $user ||= "root"; - - my ($login, $pass, $uid, $gid) = getpwnam($user) - or return [ "su: user $user does not exist\n" ]; - my @groups = (); - my $fh = new FileHandle("/etc/group") - or return [ "opening /etc/group: $!\n" ]; - while (<$fh>) { - chomp; - my ($group, $passwd, $gid, $users) = split /:/; - foreach my $u (split /,/, $users) { - push @groups, $gid - if ($user eq $u); - } - } - $fh->close; - - my $groups = join(" ", ($gid, $gid, @groups)); - #print STDERR "[[$groups]]\n"; - $! = 0; # reset errno - $> = 0; - $( = $gid; - $) = $groups; - if ($!) { - return [ "su: $!\n" ]; - } - if ($uid != 0) { - $> = $uid; - #$< = $uid; - if ($!) { - return [ "su: $prog->[1]: $!\n" ]; - } - } - #print STDERR "[($>,$<)($(,$))]"; - return []; -} - - -sub sg($) { - my ($group) = @_; - - my $gid = getgrnam($group) - or return [ "sg: group $group does not exist\n" ]; - my %groups = map { $_ eq $gid ? () : ($_ => 1) } (split /\s/, $)); - - #print STDERR "<<", join("/", keys %groups), ">>\n"; - my $groups = join(" ", ($gid, $gid, keys %groups)); - #print STDERR "[[$groups]]\n"; - $! = 0; # reset errno - if ($> != 0) { - my $uid = $>; - $> = 0; - $( = $gid; - $) = $groups; - $> = $uid; - } else { - $( = $gid; - $) = $groups; - } - if ($!) { - return [ "sg: $!\n" ]; - } - print STDERR "[($>,$<)($(,$))]"; - return []; -} - - -sub exec_test($$) { - my ($prog, $in) = @_; - local (*IN, *IN_DUP, *IN2, *OUT_DUP, *OUT, *OUT2); - my $needs_shell = (join('', @$prog) =~ /[][|<>"'`\$\*\?]/); - - if ($prog->[0] eq "umask") { - umask oct $prog->[1]; - return []; - } elsif ($prog->[0] eq "cd") { - if (!chdir $prog->[1]) { - return [ "chdir: $prog->[1]: $!\n" ]; - } - $ENV{PWD} = getcwd; - return []; - } elsif ($prog->[0] eq "su") { - return su($prog->[1]); - } elsif ($prog->[0] eq "sg") { - return sg($prog->[1]); - } elsif ($prog->[0] eq "export") { - my ($name, $value) = split /=/, $prog->[1]; - # FIXME: need to evaluate $value, so that things like this will work: - # export dir=$PWD/dir - $ENV{$name} = $value; - return []; - } elsif ($prog->[0] eq "unset") { - delete $ENV{$prog->[1]}; - return []; - } - - pipe *IN2, *OUT - or die "Can't create pipe for reading: $!"; - open *IN_DUP, "<&STDIN" - or *IN_DUP = undef; - open *STDIN, "<&IN2" - or die "Can't duplicate pipe for reading: $!"; - close *IN2; - - open *OUT_DUP, ">&STDOUT" - or die "Can't duplicate STDOUT: $!"; - pipe *IN, *OUT2 - or die "Can't create pipe for writing: $!"; - open *STDOUT, ">&OUT2" - or die "Can't duplicate pipe for writing: $!"; - close *OUT2; - - *STDOUT->autoflush(); - *OUT->autoflush(); - - if (fork()) { - # Server - if (*IN_DUP) { - open *STDIN, "<&IN_DUP" - or die "Can't duplicate STDIN: $!"; - close *IN_DUP - or die "Can't close STDIN duplicate: $!"; - } - open *STDOUT, ">&OUT_DUP" - or die "Can't duplicate STDOUT: $!"; - close *OUT_DUP - or die "Can't close STDOUT duplicate: $!"; - - foreach my $line (@$in) { - #print "> $line"; - print OUT $line; - } - close *OUT - or die "Can't close pipe for writing: $!"; - - my $result = []; - while () { - #print "< $_"; - if ($needs_shell) { - s#^/bin/sh: line \d+: ##; - } - push @$result, $_; - } - return $result; - } else { - # Client - $< = $>; - close IN - or die "Can't close read end for input pipe: $!"; - close OUT - or die "Can't close write end for output pipe: $!"; - close OUT_DUP - or die "Can't close STDOUT duplicate: $!"; - local *ERR_DUP; - open ERR_DUP, ">&STDERR" - or die "Can't duplicate STDERR: $!"; - open STDERR, ">&STDOUT" - or die "Can't join STDOUT and STDERR: $!"; - - if ($needs_shell) { - exec ('/bin/sh', '-c', join(" ", @$prog)); - } else { - exec @$prog; - } - print STDERR $prog->[0], ": $!\n"; - exit; - } -} - diff --git a/nfs4acl/unrepresentable.test b/nfs4acl/unrepresentable.test deleted file mode 100644 index 17fe5d4..0000000 --- a/nfs4acl/unrepresentable.test +++ /dev/null @@ -1,20 +0,0 @@ -Test cases for (acl, masks) pairs that cannot be represented as -pure ACLs - -$ rm -rf d -$ mkdir d -$ cd d - -$ touch x - -$ nfs4acl --set 'group@:rw::allow' x -$ chmod 600 x -$ ls -l x | cut -d ' ' -f 1 -> -rw------- -$ nfs4acl --get x -> x: -> -$ rm -f x - -$ cd .. -$ rm -rf d diff --git a/nfs4acl/write-vs-append.test b/nfs4acl/write-vs-append.test deleted file mode 100644 index f1f940a..0000000 --- a/nfs4acl/write-vs-append.test +++ /dev/null @@ -1,46 +0,0 @@ -$ mkdir d -$ cd d - -$ whoami -> root - -$ touch a b c d e f -$ nfs4acl --set 'owner@:*::allow' a -$ nfs4acl --set 'owner@:*::allow bin:w::allow' b -$ nfs4acl --set 'owner@:*::allow bin:a::allow' c -$ nfs4acl --set 'owner@:*::allow bin:wa::allow' d -$ nfs4acl --set 'bin:a::deny owner@:*::allow bin:w::allow' e -$ nfs4acl --set 'bin:w::deny owner@:*::allow bin:a::allow' f - -$ su bin -$ echo a > a -> /bin/sh: a: Permission denied -$ echo b > b -$ echo c > c -> /bin/sh: c: Permission denied -$ echo d > d -$ echo e > e -$ echo f > f -> /bin/sh: f: Permission denied - -$ echo A >> a -> /bin/sh: a: Permission denied -$ echo B >> b -> /bin/sh: b: Permission denied -$ echo C >> c -$ echo D >> d -$ echo E >> e -> /bin/sh: e: Permission denied -$ echo F >> f - -$ su -$ cat a b c d e f -> b -> C -> d -> D -> e -> F - -$ cd .. -$ rm -rf d diff --git a/tests/xfs/191 b/tests/xfs/191 deleted file mode 100755 index e9aef20..0000000 --- a/tests/xfs/191 +++ /dev/null @@ -1,75 +0,0 @@ -#!/bin/bash -# FS QA Test No. 191 -# -# To call into the nfs4acl qa suite of Andreas Gruenbacher. -# -#----------------------------------------------------------------------- -# Copyright (c) 2008 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 -# -#----------------------------------------------------------------------- -# - -seq=`basename $0` -seqres=$RESULT_DIR/$seq -echo "QA output created by $seq" - -here=`pwd` -tmp=/tmp/$$ -status=1 # failure is the default! -trap "rm -f $tmp.*; exit \$status" 0 1 2 3 15 - -# get standard environment, filters and checks -. ./common/rc -. ./common/filter - -# real QA test starts here - -# Modify as appropriate. -_supported_fs xfs -_supported_os Linux - -_require_scratch -_scratch_mkfs_xfs -i nfs4acl 1>$tmp.mkfs 2>$seqres.full -if [ $? -ne 0 ] -then - _notrun "no mkfs support for NFS v4 ACLs" -fi - -_scratch_mount 2>/dev/null -if [ $? -ne 0 ] -then - _notrun "no kernel mount support for NFS v4 ACLs" -fi - -set_prog_path nfs4acl >>$seqres.full -if [ $? -ne 0 ] -then - _notrun "no nfs4acl utility found" -fi - -cd $SCRATCH_MNT -for file in $here/nfs4acl/*.test -do - print_file=`echo $file | sed 's/.*nfs4acl/nfs4acl/'` - echo "" - echo "*** $print_file ***" - echo "" - $here/nfs4acl/run $file -done - -# success, all done -status=0 -exit diff --git a/tests/xfs/191.out b/tests/xfs/191.out deleted file mode 100644 index 7a37ec8..0000000 --- a/tests/xfs/191.out +++ /dev/null @@ -1,324 +0,0 @@ -QA output created by 191 - -*** nfs4acl/apply-mask.test *** - -[1] $ rm -rf d -- ok -[2] $ mkdir d -- ok -[3] $ cd d -- ok -[5] $ touch x -- ok -[7] $ nfs4acl --set 'owner@:rw::allow group@:rw::allow everyone@:r::allow' x -- ok -[8] $ nfs4acl --get x -- ok -[15] $ nfs4acl --set 'everyone@:w::allow owner@:r::allow group@:r::allow' x -- ok -[16] $ chmod 664 x -- ok -[17] $ nfs4acl --get x -- ok -[23] $ nfs4acl --set 'everyone@:w::deny owner@:rw::allow group@:rw::allow' x -- ok -[24] $ chmod 664 x -- ok -[25] $ nfs4acl --get x -- ok -[31] $ nfs4acl --set 'owner@:rwmo::allow' x -- ok -[32] $ nfs4acl --get x -- ok -[37] $ chmod 644 x -- ok -[38] $ nfs4acl --get x -- ok -[43] $ nfs4acl --set 'root:rw::allow' x -- ok -[44] $ chmod 664 x -- ok -[45] $ nfs4acl --get x -- ok -[50] $ chmod 644 x -- ok -[51] $ nfs4acl --get x -- ok -[56] $ chmod 664 x -- ok -[57] $ nfs4acl --get x -- ok -[62] $ nfs4acl --set 'root:rw::allow everyone@:r::allow' x -- ok -[63] $ chmod 664 x -- ok -[64] $ nfs4acl --get x -- ok -[70] $ nfs4acl --set 'root:r::allow everyone@:rw::allow' x -- ok -[71] $ chmod 664 x -- ok -[72] $ nfs4acl --get x -- ok -[80] $ nfs4acl --set 'root:w::deny everyone@:rw::allow' x -- ok -[81] $ chmod 664 x -- ok -[82] $ nfs4acl --get x -- ok -[91] $ nfs4acl --set 'root:rw::allow root:w::deny everyone@:rw::allow' x -- ok -[92] $ chmod 664 x -- ok -[93] $ nfs4acl --get x -- ok -[102] $ nfs4acl --set 'everyone@:rw::allow' x -- ok -[103] $ chmod 066 x -- ok -[104] $ nfs4acl --get x -- ok -[110] $ chmod 006 x -- ok -[111] $ nfs4acl --get x -- ok -[118] $ chmod 606 x -- ok -[119] $ nfs4acl --get x -- ok -[125] $ nfs4acl --set 'root:rw::allow everyone@:rw::allow' x -- ok -[126] $ chmod 606 x -- ok -[127] $ nfs4acl --get x -- ok -[133] $ chmod 646 x -- ok -[134] $ nfs4acl --get x -- ok -[142] $ cd .. -- ok -[143] $ rm -rf d -- ok -49 commands (49 passed, 0 failed) - -*** nfs4acl/basic.test *** - -[1] $ rm -rf d -- ok -[2] $ mkdir d -- ok -[3] $ cd d -- ok -[5] $ chown bin . -- ok -[6] $ su bin -- ok -[8] $ touch x -- ok -[9] $ nfs4acl --set 'everyone@:rw::allow' x -- ok -[10] $ ls -l x | cut -d ' ' -f 1 -- ok -[13] $ nfs4acl --get x -- ok -[18] $ chmod 664 x -- ok -[19] $ ls -l x | cut -d ' ' -f 1 -- ok -[22] $ nfs4acl --get x -- ok -[29] $ mkdir sub -- ok -[30] $ nfs4acl --set 'everyone@:rwax:fd:allow' sub -- ok -[31] $ ls -dl sub | cut -d ' ' -f 1 -- ok -[34] $ nfs4acl --get sub -- ok -[39] $ chmod 775 sub -- ok -[40] $ ls -dl sub | cut -d ' ' -f 1 -- ok -[42] $ nfs4acl --get sub -- ok -[50] $ touch sub/f -- ok -[51] $ ls -l sub/f | cut -d ' ' -f 1 -- ok -[54] $ nfs4acl --get sub/f -- ok -[59] $ mkdir sub/sub2 -- ok -[60] $ ls -dl sub/sub2 | cut -d ' ' -f 1 -- ok -[63] $ nfs4acl --get sub/sub2 -- ok -[68] $ su -- ok -[69] $ cd .. -- ok -[70] $ rm -rf d -- ok -28 commands (28 passed, 0 failed) - -*** nfs4acl/chmod.test *** - -[1] $ mkdir d -- ok -[2] $ cd d -- ok -[4] $ whoami -- ok -[7] $ touch a -- ok -[10] $ su bin -- ok -[11] $ chmod 666 a -- ok -[13] $ nfs4acl --set 'bin:rwM::allow' a -- ok -[16] $ su -- ok -[17] $ nfs4acl --set 'bin:rwm::allow' a -- ok -[20] $ su bin -- ok -[21] $ nfs4acl --set 'bin:rwm::allow' a -- ok -[25] $ chmod 666 a -- ok -[26] $ nfs4acl --set 'bin:rwm::allow' a -- ok -[29] $ su -- ok -[30] $ cd .. -- ok -[31] $ rm -rf d -- ok -16 commands (16 passed, 0 failed) - -*** nfs4acl/chown.test *** - -[1] $ mkdir d -- ok -[2] $ cd d -- ok -[4] $ whoami -- ok -[7] $ id -Gn daemon -- ok -[10] $ touch a -- ok -[13] $ su daemon -- ok -[14] $ chown daemon a -- ok -[16] $ chgrp daemon a -- ok -[18] $ nfs4acl --set 'daemon:rwo::allow' a -- ok -[23] $ su -- ok -[24] $ nfs4acl --set 'daemon:rwo::allow' a -- ok -[27] $ su daemon -- ok -[28] $ chown root a -- ok -[30] $ chgrp root a -- ok -[35] $ su -- ok -[36] $ ls -l a | cut -d ' ' -f1 -- ok -[38] $ chmod 660 a -- ok -[42] $ su daemon -- ok -[43] $ chown daemon a -- ok -[45] $ chgrp daemon a -- ok -[47] $ chgrp bin a -- ok -[51] $ su -- ok -[52] $ nfs4acl --set 'daemon:rwo::allow' a -- ok -[56] $ su daemon -- ok -[57] $ chgrp daemon a -- ok -[58] $ chgrp bin a -- ok -[59] $ chown daemon a -- ok -[61] $ su -- ok -[62] $ cd .. -- ok -[63] $ rm -rf d -- ok -30 commands (30 passed, 0 failed) - -*** nfs4acl/computed-mode.test *** - -[1] $ rm -rf d -- ok -[2] $ mkdir d -- ok -[3] $ cd d -- ok -[5] $ mkdir e -- ok -[7] $ nfs4acl --set 'owner@:rwx:f:allow' e -- ok -[8] $ touch e/f -- ok -[9] $ ls -l e/f | cut -d ' ' -f 1 -- ok -[11] $ rm e/f -- ok -[13] $ nfs4acl --set 'group@:rwx:f:allow' e -- ok -[14] $ touch e/f -- ok -[15] $ ls -l e/f | cut -d ' ' -f 1 -- ok -[17] $ rm e/f -- ok -[19] $ nfs4acl --set 'everyone@:rwx:f:allow' e -- ok -[20] $ touch e/f -- ok -[21] $ ls -l e/f | cut -d ' ' -f 1 -- ok -[23] $ rm e/f -- ok -[25] $ nfs4acl --set 'owner@:rwx:f:allow root:rx:f:deny root:rx:f:allow' e -- ok -[26] $ touch e/f -- ok -[27] $ ls -l e/f | cut -d ' ' -f 1 -- ok -[29] $ rm e/f -- ok -[31] $ nfs4acl --set 'owner@:rwx::allow everyone@:w:fi:deny everyone@:rwx:fi:allow' e -- ok -[32] $ touch e/f -- ok -[33] $ ls -l e/f | cut -d ' ' -f 1 -- ok -[35] $ rm e/f -- ok -[37] $ nfs4acl --set 'owner@:rwx::allow root:rx:fi:deny root:rx:fi:allow' e -- ok -[38] $ touch e/f -- ok -[39] $ ls -l e/f | cut -d ' ' -f 1 -- ok -[41] $ rm e/f -- ok -[43] $ nfs4acl --set 'owner@:rx:fi:allow group@:rwx:fi:deny everyone@:rwx:f:allow' e -- ok -[44] $ touch e/f -- ok -[45] $ ls -l e/f | cut -d ' ' -f 1 -- ok -[47] $ rm e/f -- ok -[49] $ nfs4acl --set 'owner@:rx:fi:allow root:rwx:fi:deny everyone@:rwx:f:allow' e -- ok -[50] $ touch e/f -- ok -[51] $ ls -l e/f | cut -d ' ' -f 1 -- ok -[53] $ rm e/f -- ok -[55] $ nfs4acl --set 'everyone@:w:fi:deny root:rx:fi:allow everyone@:rwx:f:allow' e -- ok -[56] $ touch e/f -- ok -[57] $ ls -l e/f | cut -d ' ' -f 1 -- ok -[59] $ rm e/f -- ok -[61] $ cd .. -- ok -[62] $ rm -rf d -- ok -42 commands (42 passed, 0 failed) - -*** nfs4acl/create.test *** - -[1] $ mkdir d -- ok -[2] $ cd d -- ok -[4] $ whoami -- ok -[7] $ mkdir d1 d2 d3 d4 -- ok -[8] $ nfs4acl --set 'daemon:wx::allow' d2 -- ok -[9] $ nfs4acl --set 'daemon:ax::allow' d3 -- ok -[10] $ nfs4acl --set 'daemon:wax::allow' d4 -- ok -[12] $ su daemon -- ok -[15] $ touch d1/f -- ok -[17] $ mkdir d1/d -- ok -[21] $ touch d2/f -- ok -[22] $ mkdir d2/d -- ok -[26] $ touch d3/f -- ok -[28] $ mkdir d3/d -- ok -[31] $ touch d4/f -- ok -[32] $ mkdir d4/d -- ok -[33] $ su -- ok -[34] $ cd .. -- ok -[35] $ rm -rf d -- ok -19 commands (19 passed, 0 failed) - -*** nfs4acl/ctime.test *** - -[1] $ mkdir d -- ok -[2] $ cd d -- ok -[4] $ whoami -- ok -[7] $ touch a b -- ok -[8] $ sleep 1 -- ok -[11] $ su bin -- ok -[12] $ touch a -- ok -[17] $ su -- ok -[18] $ nfs4acl --set 'bin:rw::allow' a -- ok -[20] $ su bin -- ok -[21] $ touch a -- ok -[22] $ [ b -ot a ] || echo 'b should be older than a' -- ok -[23] $ touch -r b a -- ok -[27] $ su -- ok -[28] $ nfs4acl --set 'bin:rwt::allow' a -- ok -[30] $ su bin -- ok -[31] $ touch -r b a -- ok -[32] $ [ b -ot a -o a -ot b ] && echo 'a should be as old as b' -- ok -[34] $ su -- ok -[35] $ cd .. -- ok -[36] $ rm -rf d -- ok -21 commands (21 passed, 0 failed) - -*** nfs4acl/delete.test *** - -[1] $ mkdir d -- ok -[2] $ cd d -- ok -[4] $ whoami -- ok -[7] $ id -Gn daemon -- ok -[10] $ mkdir n1 -- ok -[11] $ touch n1/f -- ok -[13] $ mkdir d2 d3 d4 d5 d6 d7 -- ok -[14] $ touch d2/f d3/f d4/f d5/f d6/f d7/f d7/g -- ok -[15] $ chown daemon d2 -- ok -[16] $ chgrp bin d3 -- ok -[17] $ chmod g+w d3 -- ok -[18] $ nfs4acl --set 'daemon:wx::allow' d4 -- ok -[19] $ nfs4acl --set 'daemon:d::allow' d5 -- ok -[20] $ nfs4acl --set 'daemon:xd::allow' d6 -- ok -[21] $ nfs4acl --set 'daemon:D::allow' d7/f d7/g -- ok -[22] $ chmod 664 d7/g -- ok -[24] $ mkdir s2 s3 s4 s5 s6 s7 -- ok -[25] $ chmod +t s2 s3 s4 s5 s6 s7 -- ok -[26] $ touch s2/f s3/f s4/f s5/f s6/f s7/f s7/g -- ok -[27] $ chown daemon s2 -- ok -[28] $ chgrp bin s3 -- ok -[29] $ chmod g+w s3 -- ok -[30] $ nfs4acl --set 'daemon:wx::allow' s4 -- ok -[31] $ nfs4acl --set 'daemon:d::allow' s5 -- ok -[32] $ nfs4acl --set 'daemon:xd::allow' s6 -- ok -[33] $ nfs4acl --set 'daemon:D::allow' s7/f -- ok -[34] $ nfs4acl --set 'daemon:D::allow' s7/g s7/g -- ok -[35] $ chmod 664 s7/g -- ok -[37] $ su daemon -- ok -[40] $ rm n1/f -- ok -[44] $ rm d2/f s2/f -- ok -[48] $ rm d3/f s3/f -- ok -[53] $ rm d4/f s4/f -- ok -[58] $ rm d5/f s5/f -- ok -[64] $ rm d6/f s6/f -- ok -[68] $ rm d7/f s7/f -- ok -[71] $ rm d7/g s7/g -- ok -[75] $ su -- ok -[76] $ cd .. -- ok -[77] $ rm -rf d -- ok -40 commands (40 passed, 0 failed) - -*** nfs4acl/unrepresentable.test *** - -[4] $ rm -rf d -- ok -[5] $ mkdir d -- ok -[6] $ cd d -- ok -[8] $ touch x -- ok -[10] $ nfs4acl --set 'group@:rw::allow' x -- ok -[11] $ chmod 600 x -- ok -[12] $ ls -l x | cut -d ' ' -f 1 -- ok -[14] $ nfs4acl --get x -- ok -[17] $ rm -f x -- ok -[19] $ cd .. -- ok -[20] $ rm -rf d -- ok -11 commands (11 passed, 0 failed) - -*** nfs4acl/write-vs-append.test *** - -[1] $ mkdir d -- ok -[2] $ cd d -- ok -[4] $ whoami -- ok -[7] $ touch a b c d e f -- ok -[8] $ nfs4acl --set 'owner@:*::allow' a -- ok -[9] $ nfs4acl --set 'owner@:*::allow bin:w::allow' b -- ok -[10] $ nfs4acl --set 'owner@:*::allow bin:a::allow' c -- ok -[11] $ nfs4acl --set 'owner@:*::allow bin:wa::allow' d -- ok -[12] $ nfs4acl --set 'bin:a::deny owner@:*::allow bin:w::allow' e -- ok -[13] $ nfs4acl --set 'bin:w::deny owner@:*::allow bin:a::allow' f -- ok -[15] $ su bin -- ok -[16] $ echo a > a -- ok -[18] $ echo b > b -- ok -[19] $ echo c > c -- ok -[21] $ echo d > d -- ok -[22] $ echo e > e -- ok -[23] $ echo f > f -- ok -[26] $ echo A >> a -- ok -[28] $ echo B >> b -- ok -[30] $ echo C >> c -- ok -[31] $ echo D >> d -- ok -[32] $ echo E >> e -- ok -[34] $ echo F >> f -- ok -[36] $ su -- ok -[37] $ cat a b c d e f -- ok -[45] $ cd .. -- ok -[46] $ rm -rf d -- ok -27 commands (27 passed, 0 failed) diff --git a/tests/xfs/group b/tests/xfs/group index 9884329..4a67df1 100644 --- a/tests/xfs/group +++ b/tests/xfs/group @@ -176,7 +176,6 @@ 188 ci dir auto 189 mount auto quick 190 rw auto quick -191 nfs4acl auto 194 rw auto 195 ioctl dump auto quick 196 quota auto quick -- 2.5.0 From bfoster@redhat.com Wed Nov 18 08:31:53 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 0642A7F37 for ; Wed, 18 Nov 2015 08:31:53 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id CF3378F8040 for ; Wed, 18 Nov 2015 06:31:49 -0800 (PST) X-ASG-Debug-ID: 1447857107-04bdf07f0af5e90001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id wpfKd49OhZp95yWD (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 18 Nov 2015 06:31:48 -0800 (PST) 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 (Postfix) with ESMTPS id BA6DCC0BB281; Wed, 18 Nov 2015 14:31:47 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-225.bos.redhat.com [10.18.41.225]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAIEVkiW004597; Wed, 18 Nov 2015 09:31:47 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id 04D5C122406; Wed, 18 Nov 2015 09:31:45 -0500 (EST) Date: Wed, 18 Nov 2015 09:31:45 -0500 From: Brian Foster To: kernel test robot Cc: lkp@01.org, LKML , Dave Chinner , Dave Chinner , xfs@oss.sgi.com Subject: Re: [lkp] [xfs] a45086e27d: -100.0% xfstests.xfs.033.seconds Message-ID: <20151118143145.GA44298@bfoster.bfoster> X-ASG-Orig-Subj: Re: [lkp] [xfs] a45086e27d: -100.0% xfstests.xfs.033.seconds References: <87d1v7aj72.fsf@yhuang-dev.intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <87d1v7aj72.fsf@yhuang-dev.intel.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: 1447857108 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 cc linux-xfs On Wed, Nov 18, 2015 at 02:57:21PM +0800, kernel test robot wrote: > FYI, we noticed the below changes on > > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master > commit a45086e27dfa21a4b39134f7505c8f60a3ecdec4 ("xfs: validate metadata LSNs against log on v5 superblocks") > > 2015-11-17 05:11:29 export TEST_DIR=/fs/sdd1 > 2015-11-17 05:11:29 export TEST_DEV=/dev/sdd1 > 2015-11-17 05:11:29 export FSTYP=xfs > 2015-11-17 05:11:29 export SCRATCH_MNT=/fs/scratch > 2015-11-17 05:11:29 mkdir /fs/scratch -p > 2015-11-17 05:11:29 export SCRATCH_DEV=/dev/sdg1 > 2015-11-17 05:11:29 export SCRATCH_LOGDEV=/dev/sdh1 > 2015-11-17 05:11:29 ./check xfs/004 xfs/010 xfs/011 xfs/013 xfs/017 xfs/020 xfs/026 xfs/027 xfs/028 xfs/031 xfs/032 xfs/033 xfs/041 xfs/042 xfs/046 xfs/047 xfs/049 xfs/050 xfs/054 xfs/056 xfs/059 xfs/060 xfs/061 xfs/063 xfs/064 xfs/065 xfs/066 xfs/068 xfs/073 xfs/076 > FSTYP -- xfs (non-debug) > PLATFORM -- Linux/x86_64 lkp-ws02 4.3.0-rc2-00002-ga45086e > MKFS_OPTIONS -- -f -bsize=4096 /dev/sdg1 > MOUNT_OPTIONS -- /dev/sdg1 /fs/scratch > > xfs/004 3s > xfs/010 13s > xfs/011 19s > xfs/013 318s > xfs/017 15s > xfs/020 82s > xfs/026 14s > xfs/027 15s > xfs/028 25s > xfs/031 58s > xfs/032 14s > xfs/033 - output mismatch (see /lkp/benchmarks/xfstests/results//xfs/033.out.bad) > --- tests/xfs/033.out 2015-11-12 16:56:51.000000000 +0800 > +++ /lkp/benchmarks/xfstests/results//xfs/033.out.bad 2015-11-17 05:21:38.091589526 +0800 > @@ -38,7 +38,19 @@ > Phase 7 - verify and correct link counts... > resetting inode INO nlinks from 1 to 2 > done > +mount: wrong fs type, bad option, bad superblock on /dev/sdg1, > + missing codepage or helper program, or other error > + > + In some cases useful info is found in syslog - try > ... > (Run 'diff -u tests/xfs/033.out /lkp/benchmarks/xfstests/results//xfs/033.out.bad' to see the entire diff) I reproduced this running xfs/033 directly on a 4.3.0-rc2+ kernel (linux-xfs tree) and xfsprogs-3.2.2 from fedora. The problem here is that the mount complains about an invalid metadata LSN. Via dmesg: ... XFS (dm-3): Mounting V5 Filesystem XFS (dm-3): Corruption warning: Metadata has LSN (1:16) ahead of current LSN (1:2). Please unmount and run xfs_repair (>= v4.3) to resolve. XFS (dm-3): log mount/recovery failed: error -22 XFS (dm-3): log mount failed ... This occurs because older versions of xfs_repair unconditionally zero out the log, which can lead to corruption after a crash on v5 superblock (-m crc=1) filesystems. Therefore, the invalid log state is detected in the kernel as of the commit referenced above and ultimately fixed in xfsprogs v4.3. In other words, XFS on a v4.4 kernel requires xfsprogs v4.3 or newer. I'm not sure what the xfsprogs release status is (tot looks like it's at 4.3.0-rc2), but the fix is ultimately to upgrade to a supported userspace. Brian > xfs/041 18s > xfs/042 14s > xfs/046 15s > xfs/047 25s > xfs/049 48s > xfs/050 23s > xfs/054 15s > xfs/056 14s > xfs/059 18s > xfs/060 16s > xfs/061 14s > xfs/063 14s > xfs/064 228s > xfs/065 35s > xfs/066 28s > xfs/068 25s > xfs/073 16s > xfs/076 53s > Ran: xfs/004 xfs/010 xfs/011 xfs/013 xfs/017 xfs/020 xfs/026 xfs/027 xfs/028 xfs/031 xfs/032 xfs/033 xfs/041 xfs/042 xfs/046 xfs/047 xfs/049 xfs/050 xfs/054 xfs/056 xfs/059 xfs/060 xfs/061 xfs/063 xfs/064 xfs/065 xfs/066 xfs/068 xfs/073 xfs/076 > Failures: xfs/033 > Failed 1 of 30 tests > > > ========================================================================================= > tbox_group/testcase/rootfs/kconfig/compiler/disk/fs/test: > lkp-ws02/xfstests/debian-x86_64-2015-02-07.cgz/x86_64-rhel/gcc-4.9/4HDD/xfs/xfs-mid1 > > commit: > b7cdc66be54b64daef593894d12ecc405f117829 > a45086e27dfa21a4b39134f7505c8f60a3ecdec4 > > b7cdc66be54b64da a45086e27dfa21a4b39134f750 > ---------------- -------------------------- > fail:runs %reproduction fail:runs > | | | > :4 100% 4:4 last_state.xfstests.exit_code.1 > :4 100% 4:4 xfstests.nr_fail > :4 100% 4:4 xfstests.xfs.033.fail > :4 25% 1:4 kmsg.XFS(loop0):Filesystem_has_duplicate_UUID#-#-#f7b-b747-f26a6b2b589b-can't_mount > :4 25% 1:4 kmsg.XFS(loop0):Filesystem_has_duplicate_UUID#-#c55-#af8-a93b-#c6382174ba-can't_mount > 1:4 -25% :4 kmsg.XFS(loop0):Filesystem_has_duplicate_UUID#-#d5c-#dd8-#c4c-#b9758dd7946-can't_mount > 1:4 -25% :4 kmsg.XFS(loop0):Filesystem_has_duplicate_UUID#-#d8b-#bd0-bd22-be703a050d73-can't_mount > :4 25% 1:4 kmsg.XFS(loop0):Filesystem_has_duplicate_UUID#-#e49-#-#f14-c1f5b7a39914-can't_mount > :4 25% 1:4 kmsg.XFS(loop0):Filesystem_has_duplicate_UUID#-#f2c-#ba-#-#a8309204098-can't_mount > 1:4 -25% :4 kmsg.XFS(loop0):Filesystem_has_duplicate_UUID#-#f88-#-a30c-f7972224a2c2-can't_mount > 1:4 -25% :4 kmsg.XFS(loop0):Filesystem_has_duplicate_UUID#-a0f8-#-b678-a0e21fca1aea-can't_mount > :4 100% 4:4 kmsg.XFS(sdg1):log_mount/recovery_failed:error > > lkp-ws02: Westmere-EP > Memory: 16G > > To reproduce: > > git clone git://git.kernel.org/pub/scm/linux/kernel/git/wfg/lkp-tests.git > cd lkp-tests > bin/lkp install job.yaml # job file is attached in this email > bin/lkp run job.yaml > > > Disclaimer: > Results have been estimated based on internal Intel analysis and are provided > for informational purposes only. Any difference in system hardware or software > design or configuration may affect actual performance. > > > Thanks, > Ying Huang > --- > LKP_SERVER: inn > LKP_CGI_PORT: 80 > LKP_CIFS_PORT: 139 > testcase: xfstests > default-monitors: > wait: activate-monitor > kmsg: > vmstat: > interval: 10 > default-watchdogs: > oom-killer: > watchdog: > commit: 96a2f2162deb97760a44ad8558e374342260cee6 > model: Westmere-EP > memory: 16G > nr_hdd_partitions: 11 > hdd_partitions: "/dev/disk/by-id/scsi-35000c500*-part1" > swap_partitions: > rootfs_partition: "/dev/disk/by-id/ata-WDC_WD1002FAEX-00Z3A0_WD-WCATR5408564-part3" > cpufreq_governor: > category: functional > disk: 4HDD > fs: xfs > xfstests: > test: xfs-mid1 > queue: cyclic > testbox: lkp-ws02 > tbox_group: lkp-ws02 > kconfig: x86_64-rhel > enqueue_time: 2015-11-14 09:35:40.999257430 +08:00 > id: 37df3a54bced8a69c8daf7c99bfff44d990622e7 > user: lkp > compiler: gcc-4.9 > head_commit: 96a2f2162deb97760a44ad8558e374342260cee6 > base_commit: 6a13feb9c82803e2b815eca72fa7a9f5561d7861 > branch: linux-devel/devel-hourly-2015111410 > kernel: "/pkg/linux/x86_64-rhel/gcc-4.9/96a2f2162deb97760a44ad8558e374342260cee6/vmlinuz-4.3.0-bochs-virtio-gpu-wl-ath-16719-g96a2f21" > rootfs: debian-x86_64-2015-02-07.cgz > result_root: "/result/xfstests/4HDD-xfs-xfs-mid1/lkp-ws02/debian-x86_64-2015-02-07.cgz/x86_64-rhel/gcc-4.9/96a2f2162deb97760a44ad8558e374342260cee6/0" > job_file: "/lkp/scheduled/lkp-ws02/cyclic_xfstests-4HDD-xfs-xfs-mid1-x86_64-rhel-CYCLIC_HEAD-96a2f2162deb97760a44ad8558e374342260cee6-20151114-75902-1fjjdep-0.yaml" > dequeue_time: 2015-11-14 12:49:18.590161421 +08:00 > nr_cpu: "$(nproc)" > max_uptime: 3600 > initrd: "/osimage/debian/debian-x86_64-2015-02-07.cgz" > bootloader_append: > - root=/dev/ram0 > - user=lkp > - job=/lkp/scheduled/lkp-ws02/cyclic_xfstests-4HDD-xfs-xfs-mid1-x86_64-rhel-CYCLIC_HEAD-96a2f2162deb97760a44ad8558e374342260cee6-20151114-75902-1fjjdep-0.yaml > - ARCH=x86_64 > - kconfig=x86_64-rhel > - branch=linux-devel/devel-hourly-2015111410 > - commit=96a2f2162deb97760a44ad8558e374342260cee6 > - BOOT_IMAGE=/pkg/linux/x86_64-rhel/gcc-4.9/96a2f2162deb97760a44ad8558e374342260cee6/vmlinuz-4.3.0-bochs-virtio-gpu-wl-ath-16719-g96a2f21 > - max_uptime=3600 > - RESULT_ROOT=/result/xfstests/4HDD-xfs-xfs-mid1/lkp-ws02/debian-x86_64-2015-02-07.cgz/x86_64-rhel/gcc-4.9/96a2f2162deb97760a44ad8558e374342260cee6/0 > - LKP_SERVER=inn > - |- > ipmi_watchdog.start_now=1 > > earlyprintk=ttyS0,115200 systemd.log_level=err > debug apic=debug sysrq_always_enabled rcupdate.rcu_cpu_stall_timeout=100 > panic=-1 softlockup_panic=1 nmi_watchdog=panic oops=panic load_ramdisk=2 prompt_ramdisk=0 > console=ttyS0,115200 console=tty0 vga=normal > > rw > lkp_initrd: "/lkp/lkp/lkp-x86_64.cgz" > modules_initrd: "/pkg/linux/x86_64-rhel/gcc-4.9/96a2f2162deb97760a44ad8558e374342260cee6/modules.cgz" > bm_initrd: "/osimage/deps/debian-x86_64-2015-02-07.cgz/lkp.cgz,/osimage/deps/debian-x86_64-2015-02-07.cgz/run-ipconfig.cgz,/osimage/deps/debian-x86_64-2015-02-07.cgz/fs.cgz,/osimage/deps/debian-x86_64-2015-02-07.cgz/xfstests.cgz,/lkp/benchmarks/xfstests.cgz" > job_state: finished > loadavg: 0.66 0.72 0.56 1/350 26465 > start_time: '1447476647' > end_time: '1447477486' > version: "/lkp/lkp/.src-20151113-180526" > mkfs -t xfs /dev/sdd1 > mkfs -t xfs /dev/sdk1 > mkfs -t xfs /dev/sdg1 > mkfs -t xfs /dev/sdh1 > mount -t xfs -o nobarrier,inode64 /dev/sdd1 /fs/sdd1 > mount -t xfs -o nobarrier,inode64 /dev/sdh1 /fs/sdh1 > mount -t xfs -o nobarrier,inode64 /dev/sdk1 /fs/sdk1 > mount -t xfs -o nobarrier,inode64 /dev/sdg1 /fs/sdg1 > export TEST_DIR=/fs/sdd1 > export TEST_DEV=/dev/sdd1 > export FSTYP=xfs > export SCRATCH_MNT=/fs/scratch > mkdir /fs/scratch -p > export SCRATCH_DEV=/dev/sdg1 > export SCRATCH_LOGDEV=/dev/sdh1 > ./check xfs/004 xfs/010 xfs/011 xfs/013 xfs/017 xfs/020 xfs/026 xfs/027 xfs/028 xfs/031 xfs/032 xfs/033 xfs/041 xfs/042 xfs/046 xfs/047 xfs/049 xfs/050 xfs/054 xfs/056 xfs/059 xfs/060 xfs/061 xfs/063 xfs/064 xfs/065 xfs/066 xfs/068 xfs/073 xfs/076 From BATV+ada3c04752a109adfb3f+4469+infradead.org+hch@bombadil.srs.infradead.org Wed Nov 18 09:11:51 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 1693C7F37 for ; Wed, 18 Nov 2015 09:11:51 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id E9F23304032 for ; Wed, 18 Nov 2015 07:11:47 -0800 (PST) X-ASG-Debug-ID: 1447859505-04cb6c0cd3e00b0001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id OAnVIemO7r1iFLbU (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Wed, 18 Nov 2015 07:11:46 -0800 (PST) X-Barracuda-Envelope-From: BATV+ada3c04752a109adfb3f+4469+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 1Zz4Of-0004N6-5y; Wed, 18 Nov 2015 15:11:45 +0000 Date: Wed, 18 Nov 2015 07:11:45 -0800 From: Christoph Hellwig To: "Darrick J. Wong" Cc: Christoph Hellwig , Chris Mason , xfs@oss.sgi.com, linux-fsdevel@vger.kernel.org Subject: Re: clone ioctl return values Message-ID: <20151118151145.GA5365@infradead.org> X-ASG-Orig-Subj: Re: clone ioctl return values References: <20151116120431.GA2860@infradead.org> <20151117002822.GA32467@birch.djwong.org> <20151117105433.GA18093@infradead.org> <20151117135745.GF17545@ret.masoncoding.com> <20151117152251.GA5392@infradead.org> <20151118030117.GA26143@birch.djwong.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151118030117.GA26143@birch.djwong.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: 1447859506 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/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_MISMATCH_TO, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24508 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS On Tue, Nov 17, 2015 at 07:01:17PM -0800, Darrick J. Wong wrote: > Current btrfs returns EINVAL if the file isn't open for writing or is > append-only. I think EBADF captures the situation here better and > it's what Anna is pushing for copy_file_range. We can make the > change, but generic/157 will fail on old kernels if we do this. As the old errno was rather wrong compared to similar syscalls I'd say don't worry about this. > One other thing I noticed -- prior to Anna's patchset, trying to > invoke the reflink ioctl with a device, pipe, or socket as the > destination could return a variety of error codes (-ENOTTY, -EINVAL, > -ENOIOCTLCMD, etc.) which has all been replaced with -EOPNOTSUPP. > That seems like a reasonable direction to take the test case. > > Does this seem like a reasonable addition to the plan? -ENOIOCTLCMD should never reach userspace, this is a clear bug. -EINVAL also seems wrong, but ENOTTY is perfectly valid for an ioctl based implementation. So I'd say we should allow ENOTTY or -EOPNOTSUPP in the test case by using filters, and ensure btrfs and nfs only return those in 4.4 and maybe with backports to stable. > Should invalid inputs to the dedupe ioctl return the same error codes > as the same invalid inputs to the reflink ioctl? I've been working on > patches to hoist EXTENT_SAME to the VFS. I think so. EXTENT_SAME is so similar to clone that it should almost be a flag for it in the low level API. From ross.zwisler@linux.intel.com Wed Nov 18 10:18:12 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 3375A7F37 for ; Wed, 18 Nov 2015 10:18:12 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id EB777304032 for ; Wed, 18 Nov 2015 08:18:08 -0800 (PST) X-ASG-Debug-ID: 1447863484-04bdf07f08f9a40001-NocioJ Received: from mga01.intel.com ([192.55.52.88]) by cuda.sgi.com with ESMTP id 8kvLs6rGbQLIEUA9 for ; Wed, 18 Nov 2015 08:18:04 -0800 (PST) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 192.55.52.88 X-ASG-Whitelist: EmailCat (corporate) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga101.fm.intel.com with ESMTP; 18 Nov 2015 08:16:53 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,313,1444719600"; d="scan'208";a="841595205" Received: from theros.lm.intel.com (HELO linux.intel.com) ([10.232.112.87]) by fmsmga001.fm.intel.com with ESMTP; 18 Nov 2015 08:16:08 -0800 Date: Wed, 18 Nov 2015 09:16:08 -0700 From: Ross Zwisler To: Jan Kara Cc: Ross Zwisler , Dan Williams , Andreas Dilger , "linux-kernel@vger.kernel.org" , "H. Peter Anvin" , "J. Bruce Fields" , Theodore Ts'o , Alexander Viro , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4 , linux-fsdevel , Linux MM , "linux-nvdimm@lists.01.org" , X86 ML , XFS Developers , Andrew Morton , Matthew Wilcox , Dave Hansen Subject: Re: [PATCH v2 03/11] pmem: enable REQ_FUA/REQ_FLUSH handling Message-ID: <20151118161608.GA10656@linux.intel.com> X-ASG-Orig-Subj: Re: [PATCH v2 03/11] pmem: enable REQ_FUA/REQ_FLUSH handling Mail-Followup-To: Ross Zwisler , Jan Kara , Dan Williams , Andreas Dilger , "linux-kernel@vger.kernel.org" , "H. Peter Anvin" , "J. Bruce Fields" , Theodore Ts'o , Alexander Viro , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4 , linux-fsdevel , Linux MM , "linux-nvdimm@lists.01.org" , X86 ML , XFS Developers , Andrew Morton , Matthew Wilcox , Dave Hansen References: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> <1447459610-14259-4-git-send-email-ross.zwisler@linux.intel.com> <22E0F870-C1FB-431E-BF6C-B395A09A2B0D@dilger.ca> <20151116200950.GB9737@linux.intel.com> <20151118104055.GA6097@quack.suse.cz> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151118104055.GA6097@quack.suse.cz> User-Agent: Mutt/1.5.23 (2014-03-12) X-Barracuda-Connect: UNKNOWN[192.55.52.88] X-Barracuda-Start-Time: 1447863484 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Wed, Nov 18, 2015 at 11:40:55AM +0100, Jan Kara wrote: > On Mon 16-11-15 13:09:50, Ross Zwisler wrote: > > On Fri, Nov 13, 2015 at 06:32:40PM -0800, Dan Williams wrote: > > > On Fri, Nov 13, 2015 at 4:43 PM, Andreas Dilger wrote: > > > > On Nov 13, 2015, at 5:20 PM, Dan Williams wrote: > > > >> > > > >> On Fri, Nov 13, 2015 at 4:06 PM, Ross Zwisler > > > >> wrote: > > > >>> Currently the PMEM driver doesn't accept REQ_FLUSH or REQ_FUA bios. These > > > >>> are sent down via blkdev_issue_flush() in response to a fsync() or msync() > > > >>> and are used by filesystems to order their metadata, among other things. > > > >>> > > > >>> When we get an msync() or fsync() it is the responsibility of the DAX code > > > >>> to flush all dirty pages to media. The PMEM driver then just has issue a > > > >>> wmb_pmem() in response to the REQ_FLUSH to ensure that before we return all > > > >>> the flushed data has been durably stored on the media. > > > >>> > > > >>> Signed-off-by: Ross Zwisler > > > >> > > > >> Hmm, I'm not seeing why we need this patch. If the actual flushing of > > > >> the cache is done by the core why does the driver need support > > > >> REQ_FLUSH? Especially since it's just a couple instructions. REQ_FUA > > > >> only makes sense if individual writes can bypass the "drive" cache, > > > >> but no I/O submitted to the driver proper is ever cached we always > > > >> flush it through to media. > > > > > > > > If the upper level filesystem gets an error when submitting a flush > > > > request, then it assumes the underlying hardware is broken and cannot > > > > be as aggressive in IO submission, but instead has to wait for in-flight > > > > IO to complete. > > > > > > Upper level filesystems won't get errors when the driver does not > > > support flush. Those requests are ended cleanly in > > > generic_make_request_checks(). Yes, the fs still needs to wait for > > > outstanding I/O to complete but in the case of pmem all I/O is > > > synchronous. There's never anything to await when flushing at the > > > pmem driver level. > > > > > > > Since FUA/FLUSH is basically a no-op for pmem devices, > > > > it doesn't make sense _not_ to support this functionality. > > > > > > Seems to be a nop either way. Given that DAX may lead to dirty data > > > pending to the device in the cpu cache that a REQ_FLUSH request will > > > not touch, its better to leave it all to the mm core to handle. I.e. > > > it doesn't make sense to call the driver just for two instructions > > > (sfence + pcommit) when the mm core is taking on the cache flushing. > > > Either handle it all in the mm or the driver, not a mixture. > > > > Does anyone know if ext4 and/or XFS alter their algorithms based on whether > > the driver supports REQ_FLUSH/REQ_FUA? Will the filesystem behave more > > efficiently with respect to their internal I/O ordering, etc., if PMEM > > advertises REQ_FLUSH/REQ_FUA support, even though we could do the same thing > > at the DAX layer? > > So the information whether the driver supports FLUSH / FUA is generally > ignored by filesystems. We issue REQ_FLUSH / REQ_FUA requests to achieve > required ordering for fs consistency and expect that block layer does the > right thing - i.e., if the device has volatile write cache, it will be > flushed, if it doesn't have it, the request will be ignored. So the > difference between supporting and not supporting REQ_FLUSH / REQ_FUA is > only in how block layer handles such requests. Cool, thank you for the info. Based on this I'll pull out the REQ_FLUSH/REQ_FUA patch for v3 of this series and move the wmb_pmem() call up to DAX as Dan suggests. If performance data shows that we can get a benefit from centralizing wmb_pmem() behind REQ_FUA/REQ_FLUSH, I'll add it back in later as part of that series. From arekm@maven.pl Wed Nov 18 16:36:30 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 AFD427F37 for ; Wed, 18 Nov 2015 16:36:30 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id A1775304039 for ; Wed, 18 Nov 2015 14:36:27 -0800 (PST) X-ASG-Debug-ID: 1447886181-04cb6c0cd2ed750001-NocioJ Received: from mail-lf0-f51.google.com (mail-lf0-f51.google.com [209.85.215.51]) by cuda.sgi.com with ESMTP id bqBaEE04NzSdzgLy (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Wed, 18 Nov 2015 14:36:22 -0800 (PST) X-Barracuda-Envelope-From: arekm@maven.pl X-Barracuda-Apparent-Source-IP: 209.85.215.51 Received: by lfdo63 with SMTP id o63so36488798lfd.2 for ; Wed, 18 Nov 2015 14:36:20 -0800 (PST) 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=9pJ4okAKG5vShqgQ3GkIqofXHXg2iN3Qffi+h97djBM=; b=SS8/N2wfPE7i5+X8qriBV+JiD9fO61qQm9YDPQc8UA8/Ljhuo6wxZHjl9Ye0+Mg+MA bsXYiTN5k6BQEEQ8or7oASbipubQEyHLzXirDCXb3EbSxBKK//vJ7ug4/eHSjNO+B9Z/ OQShMWn97Lv86yGeydkozoEogRf3jCQEGPc90= 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=9pJ4okAKG5vShqgQ3GkIqofXHXg2iN3Qffi+h97djBM=; b=j7ddPSXEvRmMsmR/70A97cYTRNHTNI6X+ucrSeQZD6ZX7PJtcF2lG4YMr0JsezmZuj OgBEaJ+Zec9XpqTnloHM64D49dqjKa+jL39ijw3T4IRgrugmDMIWuA2ZHcHJJk5sELGh jL0aMzJKs1IigFFXXlWpsQx8YxI78/Mn39yfvUt+18ZriGzrnaE/37+PFe0B/aWuYHBN LLOMOE5tJubTvhJeuVP9SKJVZPRPfn+RdrXrYwaCs3V7AxLGJzZLzwCx2ai82grwJDfc uqc7+Hc/JSdM2q/37uxbMDX4y/AMlzaCHxsDCMS/9/woWgVon64H9ezWwQTJ7kXsx8dS PG+g== X-Gm-Message-State: ALoCoQm3whG7brvSxd0/9yNpuzKySEAAK+rpuUSEmuzATp8E+ZpZE0KO0J+oGqAia87AUagtJkqy X-Received: by 10.25.43.149 with SMTP id r143mr1851181lfr.45.1447886180765; Wed, 18 Nov 2015 14:36:20 -0800 (PST) Received: from xps.localnet (85-222-71-204.dynamic.chello.pl. [85.222.71.204]) by smtp.gmail.com with ESMTPSA id w132sm748431lfd.11.2015.11.18.14.36.19 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 18 Nov 2015 14:36:19 -0800 (PST) From: Arkadiusz =?utf-8?q?Mi=C5=9Bkiewicz?= To: Michal Hocko Subject: Re: memory reclaim problems on fs usage Date: Wed, 18 Nov 2015 23:36:18 +0100 X-ASG-Orig-Subj: Re: memory reclaim problems on fs usage User-Agent: KMail/1.13.7 (Linux/4.3.0; KDE/4.14.13; x86_64; ; ) Cc: Tetsuo Handa , htejun@gmail.com, cl@linux.com, linux-mm@kvack.org, xfs@oss.sgi.com References: <201511102313.36685.arekm@maven.pl> <201511151549.35299.arekm@maven.pl> <20151116161518.GI14116@dhcp22.suse.cz> In-Reply-To: <20151116161518.GI14116@dhcp22.suse.cz> MIME-Version: 1.0 Content-Type: Text/Plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <201511182336.18231.arekm@maven.pl> X-Barracuda-Connect: mail-lf0-f51.google.com[209.85.215.51] X-Barracuda-Start-Time: 1447886182 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24517 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 Monday 16 of November 2015, Michal Hocko wrote: > On Sun 15-11-15 15:49:35, Arkadiusz Mi=C5=9Bkiewicz wrote: > > On Sunday 15 of November 2015, Tetsuo Handa wrote: > > > Arkadiusz Miskiewicz wrote: > > > > On Sunday 15 of November 2015, Tetsuo Handa wrote: > > > > > I think that the vmstat statistics now have correct values. > > > > >=20 > > > > > > But are these patches solving the problem or just hiding it? > > > > >=20 > > > > > Excuse me but I can't judge. > > > > >=20 > > > > > If you are interested in monitoring how vmstat statistics are > > > > > changing under stalled condition, you can try below patch. > > > >=20 > > > > Here is log with this and all previous patches applied: > > > > http://ixion.pld-linux.org/~arekm/log-mm-5.txt.gz > > >=20 > > > Regarding "Node 0 Normal" (min:7104kB low:8880kB high:10656kB), > > > all free: values look sane to me. I think that your problem was solve= d. > >=20 > > Great, thanks! > >=20 > > Will all (or part) of these patches > >=20 > > http://sprunge.us/GYBb >=20 > Migrate reserves are not a stable material I am afraid. "vmstat: > explicitly schedule per-cpu work on the CPU we need it to run on" > was not marked for stable either but I am not sure why it should make > any difference for your load. I understand that testing this is really > tedious but it would be better to know which of the patches actually > made a difference. Ok. In mean time I've tried 4.3.0 kernel + patches (the same as before + on= e=20 more) on second server which runs even more rsnapshot processes and also us= es=20 xfs on md raid 6. Patches: http://sprunge.us/DfIQ (debug patch from Tetsuo) http://sprunge.us/LQPF (backport of things from git + one from ml) The problem is now with high order allocations probably: http://ixion.pld-linux.org/~arekm/log-mm-2srv-1.txt.gz System is doing very slow progress and for example depmod run took 2 hours http://sprunge.us/HGbE Sometimes I was able to ssh-in, dmesg took 10-15 minutes but sometimes it=20 worked fast for short period. Ideas? ps. I also had one problem with low order allocation but only once and wasn= 't=20 able to reproduce so far. I was running kernel with backport patches but no= =20 debug patch, so got only this in logs: http://sprunge.us/WPXi =2D-=20 Arkadiusz Mi=C5=9Bkiewicz, arekm / ( maven.pl | pld-linux.org ) From vmdgb@rnrnd.com Thu Nov 19 03:02:39 2015 Return-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=HK_RANDOM_ENVFROM,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 B21E67F37 for ; Thu, 19 Nov 2015 03:02:39 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 9E4DD8F8039 for ; Thu, 19 Nov 2015 01:02:36 -0800 (PST) X-ASG-Debug-ID: 1447923752-04cbb0605b13cf60001-NocioJ Received: from rnrnd.com ([114.96.72.73]) by cuda.sgi.com with ESMTP id GEcgwvNgFWzuftBc for ; Thu, 19 Nov 2015 01:02:33 -0800 (PST) X-Barracuda-Envelope-From: vmdgb@rnrnd.com X-Barracuda-Apparent-Source-IP: 114.96.72.73 Received: from SKY-20150201SFT ([127.0.0.1]) by localhost via TCP with ESMTPA; Thu, 19 Nov 2015 17:02:19 +0800 MIME-Version: 1.0 From: Mr.Zhang Sender: Mr.Zhang To: xfs@oss.sgi.com Reply-To: Mr.Zhang Date: 19 Nov 2015 17:02:19 +0800 Subject: =?utf-8?B?V2UgZ29vZCBhdCBtYWtpbmcgbGFkaWVz4oCZIGNsb3RoZXMu?= Content-Type: text/html; charset=utf-8 X-ASG-Orig-Subj: =?utf-8?B?V2UgZ29vZCBhdCBtYWtpbmcgbGFkaWVz4oCZIGNsb3RoZXMu?= Content-Transfer-Encoding: base64 X-Barracuda-Connect: UNKNOWN[114.96.72.73] X-Barracuda-Start-Time: 1447923752 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.74 X-Barracuda-Spam-Status: No, SCORE=0.74 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC5_MJ1963, HTML_MESSAGE, MAILTO_TO_SPAM_ADDR, MIME_HTML_ONLY, MISSING_MID, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24531 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.14 MISSING_MID Missing Message-Id: header 0.00 MAILTO_TO_SPAM_ADDR URI: Includes a link to a likely spammer email 0.00 MIME_HTML_ONLY BODY: Message only has text/html MIME parts 0.00 HTML_MESSAGE BODY: HTML included in message 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 Message-Id: <20151119090236.434EF106C844@cuda.sgi.com> PGh0bWw+PGJvZHk+PFA+PEZPTlQgY29sb3I9I2ZmMDBmZj5IZWxsbyBTaXIvTWFkYW0sPC9G T05UPjwvUD4NCjxQPjxGT05UIGNvbG9yPSNmZjAwZmY+SG93IGhhdmUgeW91IGJlZW4gdGhl cmUgPzwvRk9OVD48L1A+DQo8UD48Rk9OVCBjb2xvcj0jZmYwMGZmPldlIGFyZSBhIGNsb3Ro aW5nIGZhY3RvcnksIHZlcnkgZ29vZCBhdCBtYWtpbmcgbGFkaWVz4oCZIGNsb3RoZXMuIDwv Rk9OVD48L1A+DQo8UD48Rk9OVCBjb2xvcj0jZmYwMGZmPlRoZSBmYWN0b3J5IGlzIG9yZ2Fu aXplZCBieSBhIHByb2Zlc3Npb25hbCB0ZWFtLCBpbmNsdWRpbmcgZGVzaWduZXIsIGZhYnJp YyBwdXJjaGFzZXIsIHByb2R1Y2luZyB3b3JrZXJzLCBRQyB0ZWNobmljaWFuLiA8L0ZPTlQ+ PC9QPg0KPFA+PEZPTlQgY29sb3I9I2ZmMDBmZj5XZSBhcmUgYWJsZSB0byBjb3B5IHlvdSB0 aGUgY29tcGxldGUgc2FtZSBzYW1wbGUgYWNjb3JkaW5nIHRvIHlvdXIgZGVzaWduIHNrZXRj aCBvciBwaWN0dXJlcywgb3Igc2FtcGxlcy4gPC9GT05UPjwvUD4NCjxQPjxGT05UIGNvbG9y PSNmZjAwZmY+QW5kIHRoZW4gd2Ugd2lsbCBtYWtlIGFuIGFjY3VyYXRlIHF1b3RhdGlvbiBh Y2NvcmRpbmdseS48L0ZPTlQ+PC9QPg0KPFA+PEZPTlQgY29sb3I9I2ZmMDBmZj5XZSB3aWxs IHRyeSBvdXIgYmVzdCB0byBndWFyYW50ZWUgdGhlIGJlc3QgZm9yIHlvdSBhbmQgd2Ugd2ls bCBrZWVwIG91ciB3b3Jkcy48L0ZPTlQ+PC9QPg0KPFA+PEZPTlQgY29sb3I9I2ZmMDBmZj48 L0ZPTlQ+PC9QPg0KPFA+PEZPTlQgY29sb3I9I2ZmMDBmZj5CZXN0IFJlZ2FyZHMsPEJSPk1y LlpoYW5nPC9GT05UPjwvUD4NCjxQPjxGT05UIGNvbG9yPSNmZjAwZmY+RS1tYWlsOiA8L0ZP TlQ+PEEgaHJlZj0ibWFpbHRvOmpjY2xvdGhlczMzQDE2My5jb20iPjxGT05UIGNvbG9yPSNm ZjAwZmY+amNjbG90aGVzMzNAMTYzLmNvbTwvRk9OVD48L0E+PC9QPjwvYm9keT48L2h0bWw+ From adam.blaszczykowski@gmail.com Thu Nov 19 07:03:55 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 B7D2729DF5 for ; Thu, 19 Nov 2015 07:03:55 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 991EC304032 for ; Thu, 19 Nov 2015 05:03:52 -0800 (PST) X-ASG-Debug-ID: 1447938229-04cb6c0cd3fc0d0001-NocioJ Received: from mail-yk0-f176.google.com (mail-yk0-f176.google.com [209.85.160.176]) by cuda.sgi.com with ESMTP id UAlHIHpFky9MdEgl (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Thu, 19 Nov 2015 05:03:49 -0800 (PST) X-Barracuda-Envelope-From: adam.blaszczykowski@gmail.com X-Barracuda-Apparent-Source-IP: 209.85.160.176 Received: by ykba77 with SMTP id a77so106240786ykb.2 for ; Thu, 19 Nov 2015 05:03:49 -0800 (PST) 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=mf72VkQe2CK6i5Jci9Dbf3EsCK+lqzkOqdXZYe+dVQo=; b=SFcqBav7yTVEWBlkbAoWcxG296+maeuKL98n7E70qhOvJlLXaVL2ezM0ekAWKTuPYx 3PfaokuuNn4k/QHLKpJpzdroSmMIZCgitsnW9qr0C9+24JiMystrdigk8JZRFa6dtfrg 2x5vp3veyJ0LV+Eo4uIVKJIbz1B377zyfxFsmyFUpE/FmzBEQUgM6idYAdyVU1AzgrTV ws/ZNhiWbI3NbCEco8NCD4fuBUPFZw0xfn6Jf+xEb0WUr3agGvmNdCWxgw1Gr2nvH1Dy SREDmAWYl/GFFlcgDsRDCdnWskr3aFd8pHfwXpJCpMibgWsXMH3ThTmLkzEjXQq/gq8k ogeA== MIME-Version: 1.0 X-Received: by 10.129.35.8 with SMTP id j8mr6484104ywj.188.1447938228897; Thu, 19 Nov 2015 05:03:48 -0800 (PST) Received: by 10.37.215.19 with HTTP; Thu, 19 Nov 2015 05:03:48 -0800 (PST) Date: Thu, 19 Nov 2015 14:03:48 +0100 Message-ID: Subject: Re: "Internal error xfs_attr3_leaf_write_verify at line 216", "directory flags set on non-directory inode" and other errors From: =?UTF-8?Q?Adam_B=C5=82aszczykowski?= X-ASG-Orig-Subj: Re: "Internal error xfs_attr3_leaf_write_verify at line 216", "directory flags set on non-directory inode" and other errors To: xfs@oss.sgi.com Content-Type: multipart/alternative; boundary=001a11429f34ca518e0524e46328 X-Barracuda-Connect: mail-yk0-f176.google.com[209.85.160.176] X-Barracuda-Start-Time: 1447938229 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24535 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 --001a11429f34ca518e0524e46328 Content-Type: text/plain; charset=UTF-8 Hello, I have updated kernel version 3.4 to 3.10 and I encountered the same problem. System is working, but periodically I get following errors in kernel logs: [20367.539731] XFS (dm-4): Internal error xfs_attr3_leaf_read_verify at line 256 of file fs/xfs/xfs_attr_leaf.c. Caller 0xffffffff81263bcd [20367.539731] [20367.539732] CPU: 1 PID: 2240 Comm: kworker/1:1H Tainted: G O 3.10.93 #15 [20367.539733] Hardware name: Intel Corporation S2600IP/S2600IP, BIOS SE5C600.86B.02.03.0003.041920141333 04/19/2014 [20367.539736] Workqueue: xfslogd xfs_buf_iodone_work [20367.539738] ffffffff816bf9df 000000000000007e ffffffff81265a42 ffffffff81263bcd [20367.539739] ffff000000000100 ffff8802c8e40e40 ffff88085257f080 ffff88085adf5000 [20367.539740] ffff88087fc38f00 0000000000000000 ffffffff8127e95f ffffffff81263bcd [20367.539741] Call Trace: [20367.539744] [] ? dump_stack+0xd/0x17 [20367.539746] [] ? xfs_corruption_error+0x62/0x90 [20367.539748] [] ? xfs_buf_iodone_work+0x8d/0xb0 [20367.539750] [] ? xfs_attr3_leaf_read_verify+0x6f/0x100 [20367.539751] [] ? xfs_buf_iodone_work+0x8d/0xb0 [20367.539753] [] ? xfs_buf_iodone_work+0x8d/0xb0 [20367.539754] [] ? process_one_work+0x141/0x3b0 [20367.539757] [] ? pwq_activate_delayed_work+0x2e/0x50 [20367.539758] [] ? worker_thread+0x112/0x370 [20367.539759] [] ? manage_workers.isra.28+0x290/0x290 [20367.539761] [] ? kthread+0xb3/0xc0 [20367.539763] [] ? sched_clock+0x5/0x10 [20367.539764] [] ? __alloc_workqueue_key+0x210/0x510 [20367.539766] [] ? kthread_freezable_should_stop+0x60/0x60 [20367.539768] [] ? ret_from_fork+0x58/0x90 [20367.539770] [] ? kthread_freezable_should_stop+0x60/0x60 [20367.539770] XFS (dm-4): Corruption detected. Unmount and run xfs_repair [20367.539777] XFS (dm-4): metadata I/O error: block 0x19a4775b18 ("xfs_trans_read_buf_map") error 117 numblks 8 As in other cases from this thread, xfs repair hasn't found any problems. Here is xfs_dump from block 0x19a4775b18: [20367.539731] XFS (dm-4): Internal error xfs_attr3_leaf_read_verify at line 256 of file fs/xfs/xfs_attr_leaf.c. Caller 0xffffffff81263bcd [20367.539731] [20367.539732] CPU: 1 PID: 2240 Comm: kworker/1:1H Tainted: G O 3.10.93 #15 [20367.539733] Hardware name: Intel Corporation S2600IP/S2600IP, BIOS SE5C600.86B.02.03.0003.041920141333 04/19/2014 [20367.539736] Workqueue: xfslogd xfs_buf_iodone_work [20367.539738] ffffffff816bf9df 000000000000007e ffffffff81265a42 ffffffff81263bcd [20367.539739] ffff000000000100 ffff8802c8e40e40 ffff88085257f080 ffff88085adf5000 [20367.539740] ffff88087fc38f00 0000000000000000 ffffffff8127e95f ffffffff81263bcd [20367.539741] Call Trace: [20367.539744] [] ? dump_stack+0xd/0x17 [20367.539746] [] ? xfs_corruption_error+0x62/0x90 [20367.539748] [] ? xfs_buf_iodone_work+0x8d/0xb0 [20367.539750] [] ? xfs_attr3_leaf_read_verify+0x6f/0x100 [20367.539751] [] ? xfs_buf_iodone_work+0x8d/0xb0 [20367.539753] [] ? xfs_buf_iodone_work+0x8d/0xb0 [20367.539754] [] ? process_one_work+0x141/0x3b0 [20367.539757] [] ? pwq_activate_delayed_work+0x2e/0x50 [20367.539758] [] ? worker_thread+0x112/0x370 [20367.539759] [] ? manage_workers.isra.28+0x290/0x290 [20367.539761] [] ? kthread+0xb3/0xc0 [20367.539763] [] ? sched_clock+0x5/0x10 [20367.539764] [] ? __alloc_workqueue_key+0x210/0x510 [20367.539766] [] ? kthread_freezable_should_stop+0x60/0x60 [20367.539768] [] ? ret_from_fork+0x58/0x90 [20367.539770] [] ? kthread_freezable_should_stop+0x60/0x60 [20367.539770] XFS (dm-4): Corruption detected. Unmount and run xfs_repair [20367.539777] XFS (dm-4): metadata I/O error: block 0x19a4775b18 ("xfs_trans_read_buf_map") error 117 numblks 8 xfs_db> convert daddr 0x19a4775b18 fsb 0x3348eeb96 (13766683542) xfs_db> fsb 0x3348eeb96 xfs_db> p 000: 00000000 00000000 fbee0000 00000000 10000000 00200fe0 00000000 00000000 020: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 040: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 060: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 080: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0a0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0c0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0e0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 100: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 120: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 140: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 160: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 180: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 1a0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 1c0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 1e0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 200: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 220: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 240: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 260: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 280: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 2a0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 2c0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 2e0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 300: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 320: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 340: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 360: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 380: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 3a0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 3c0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 3e0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 400: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 420: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 440: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 460: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 480: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 4a0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 4c0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 4e0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 500: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 520: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 540: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 560: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 580: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 5a0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 5c0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 5e0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 600: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 620: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 640: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 660: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 680: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 6a0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 6c0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 6e0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 700: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 720: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 740: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 760: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 780: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 7a0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 7c0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 7e0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 800: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 820: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 840: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 860: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 880: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 8a0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 8c0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 8e0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 900: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 920: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 940: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 960: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 980: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 9a0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 9c0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 9e0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 a00: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 a20: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 a40: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 a60: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 a80: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 aa0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ac0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ae0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 b00: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 b20: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 b40: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 b60: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 b80: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ba0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 bc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 be0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 c00: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 c20: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 c40: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 c60: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 c80: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ca0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 cc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ce0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 d00: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 d20: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 d40: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 d60: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 d80: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 da0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 dc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 de0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 e00: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 e20: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 e40: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 e60: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 e80: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ea0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ec0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ee0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 f00: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 f20: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 f40: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 f60: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 f80: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 fa0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 fe0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 xfs_db> type attr xfs_db> p hdr.info.forw = 0 hdr.info.back = 0 hdr.info.magic = 0xfbee hdr.count = 0 hdr.usedbytes = 0 hdr.firstused = 4096 hdr.holes = 0 hdr.freemap[0-2] = [base,size] 0:[32,4064] 1:[0,0] 2:[0,0] After converting the address to inode and running xfs_dump I get following output: xfs_db> convert daddr 0x19a4775b18 inode 0x3348eeb960 (220266936672) xfs_db> inode 0x3348eeb960 xfs_db> p core.magic = 0 core.mode = 0 core.version = 0 core.format = 0 (dev) core.uid = 4226678784 core.gid = 0 core.flushiter = 0 core.atime.sec = Thu Jan 1 01:00:00 1970 core.atime.nsec = 000000000 core.mtime.sec = Thu Jan 1 01:00:00 1970 core.mtime.nsec = 000000000 core.ctime.sec = Thu Jan 1 01:00:00 1970 core.ctime.nsec = 000000000 core.size = 0 core.nblocks = 0 core.extsize = 0 core.nextents = 0 core.naextents = 0 core.forkoff = 0 core.aformat = 0 (dev) core.dmevmask = 0 core.dmstate = 0 core.newrtbm = 0 core.prealloc = 0 core.realtime = 0 core.immutable = 0 core.append = 0 core.sync = 0 core.noatime = 0 core.nodump = 0 core.rtinherit = 0 core.projinherit = 0 core.nosymlinks = 0 core.extsz = 0 core.extszinherit = 0 core.nodefrag = 0 core.filestream = 0 core.gen = 0 next_unlinked = 0 u.dev = 0 It's strange, because there is no "extended attributes" record. Do you know what can cause such problem ? Is it fixed in new kernel version ? Thank you in advance ! Best regards Adam Blaszczykowski --001a11429f34ca518e0524e46328 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
Hello,
I have updated kernel version 3.4 to 3.10 and I = encountered the same problem. System is working, but periodically I get fol= lowing errors in kernel logs:

[20367.539731] XFS (dm-4): Internal er= ror xfs_attr3_leaf_read_verify at line 256 of file fs/xfs/xfs_attr_leaf.c.= =C2=A0 Caller 0xffffffff81263bcd
[20367.539731]
[20367.539732] CPU: 1= PID: 2240 Comm: kworker/1:1H Tainted: G=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 O 3.10.93 #15
[20367.539733] Hardware name: = Intel Corporation S2600IP/S2600IP, BIOS SE5C600.86B.02.03.0003.041920141333= 04/19/2014
[20367.539736] Workqueue: xfslogd xfs_buf_iodone_work
[20= 367.539738]=C2=A0 ffffffff816bf9df 000000000000007e ffffffff81265a42 ffffff= ff81263bcd
[20367.539739]=C2=A0 ffff000000000100 ffff8802c8e40e40 ffff88= 085257f080 ffff88085adf5000
[20367.539740]=C2=A0 ffff88087fc38f00 000000= 0000000000 ffffffff8127e95f ffffffff81263bcd
[20367.539741] Call Trace:<= br>[20367.539744]=C2=A0 [<ffffffff816bf9df>] ? dump_stack+0xd/0x17[20367.539746]=C2=A0 [<ffffffff81265a42>] ? xfs_corruption_error+0x6= 2/0x90
[20367.539748]=C2=A0 [<ffffffff81263bcd>] ? xfs_buf_iodone_= work+0x8d/0xb0
[20367.539750]=C2=A0 [<ffffffff8127e95f>] ? xfs_att= r3_leaf_read_verify+0x6f/0x100
[20367.539751]=C2=A0 [<ffffffff81263bc= d>] ? xfs_buf_iodone_work+0x8d/0xb0
[20367.539753]=C2=A0 [<fffffff= f81263bcd>] ? xfs_buf_iodone_work+0x8d/0xb0
[20367.539754]=C2=A0 [<= ;ffffffff8105dd01>] ? process_one_work+0x141/0x3b0
[20367.539757]=C2= =A0 [<ffffffff8105b79e>] ? pwq_activate_delayed_work+0x2e/0x50
[20= 367.539758]=C2=A0 [<ffffffff8105ec42>] ? worker_thread+0x112/0x370[20367.539759]=C2=A0 [<ffffffff8105eb30>] ? manage_workers.isra.28+0= x290/0x290
[20367.539761]=C2=A0 [<ffffffff810647e3>] ? kthread+0xb= 3/0xc0
[20367.539763]=C2=A0 [<ffffffff81012685>] ? sched_clock+0x5= /0x10
[20367.539764]=C2=A0 [<ffffffff81060000>] ? __alloc_workqueu= e_key+0x210/0x510
[20367.539766]=C2=A0 [<ffffffff81064730>] ? kthr= ead_freezable_should_stop+0x60/0x60
[20367.539768]=C2=A0 [<ffffffff81= 6cab18>] ? ret_from_fork+0x58/0x90
[20367.539770]=C2=A0 [<ffffffff= 81064730>] ? kthread_freezable_should_stop+0x60/0x60
[20367.539770] X= FS (dm-4): Corruption detected. Unmount and run xfs_repair
[20367.539777= ] XFS (dm-4): metadata I/O error: block 0x19a4775b18 ("xfs_trans_read_= buf_map") error 117 numblks 8


As in other cases from this = thread, xfs repair hasn't found any problems.
Here is xfs_dump from= block 0x19a4775b18:

[20367.539731] XFS (dm-4): Internal error xfs_a= ttr3_leaf_read_verify at line 256 of file fs/xfs/xfs_attr_leaf.c.=C2=A0 Cal= ler 0xffffffff81263bcd
[20367.539731]
[20367.539732] CPU: 1 PID: 2240= Comm: kworker/1:1H Tainted: G=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0 O 3.10.93 #15
[20367.539733] Hardware name: Intel Corpor= ation S2600IP/S2600IP, BIOS SE5C600.86B.02.03.0003.041920141333 04/19/2014<= br>[20367.539736] Workqueue: xfslogd xfs_buf_iodone_work
[20367.539738]= =C2=A0 ffffffff816bf9df 000000000000007e ffffffff81265a42 ffffffff81263bcd<= br>[20367.539739]=C2=A0 ffff000000000100 ffff8802c8e40e40 ffff88085257f080 = ffff88085adf5000
[20367.539740]=C2=A0 ffff88087fc38f00 0000000000000000 = ffffffff8127e95f ffffffff81263bcd
[20367.539741] Call Trace:
[20367.5= 39744]=C2=A0 [<ffffffff816bf9df>] ? dump_stack+0xd/0x17
[20367.539= 746]=C2=A0 [<ffffffff81265a42>] ? xfs_corruption_error+0x62/0x90
[= 20367.539748]=C2=A0 [<ffffffff81263bcd>] ? xfs_buf_iodone_work+0x8d/0= xb0
[20367.539750]=C2=A0 [<ffffffff8127e95f>] ? xfs_attr3_leaf_rea= d_verify+0x6f/0x100
[20367.539751]=C2=A0 [<ffffffff81263bcd>] ? xf= s_buf_iodone_work+0x8d/0xb0
[20367.539753]=C2=A0 [<ffffffff81263bcd&g= t;] ? xfs_buf_iodone_work+0x8d/0xb0
[20367.539754]=C2=A0 [<ffffffff81= 05dd01>] ? process_one_work+0x141/0x3b0
[20367.539757]=C2=A0 [<fff= fffff8105b79e>] ? pwq_activate_delayed_work+0x2e/0x50
[20367.539758]= =C2=A0 [<ffffffff8105ec42>] ? worker_thread+0x112/0x370
[20367.539= 759]=C2=A0 [<ffffffff8105eb30>] ? manage_workers.isra.28+0x290/0x290<= br>[20367.539761]=C2=A0 [<ffffffff810647e3>] ? kthread+0xb3/0xc0
[= 20367.539763]=C2=A0 [<ffffffff81012685>] ? sched_clock+0x5/0x10
[2= 0367.539764]=C2=A0 [<ffffffff81060000>] ? __alloc_workqueue_key+0x210= /0x510
[20367.539766]=C2=A0 [<ffffffff81064730>] ? kthread_freezab= le_should_stop+0x60/0x60
[20367.539768]=C2=A0 [<ffffffff816cab18>]= ? ret_from_fork+0x58/0x90
[20367.539770]=C2=A0 [<ffffffff81064730>= ;] ? kthread_freezable_should_stop+0x60/0x60
[20367.539770] XFS (dm-4): = Corruption detected. Unmount and run xfs_repair
[20367.539777] XFS (dm-4= ): metadata I/O error: block 0x19a4775b18 ("xfs_trans_read_buf_map&quo= t;) error 117 numblks 8

xfs_db> convert daddr 0x19a4775b18 fsb0x3348eeb96 (13766683542)

xfs_db> fsb 0x3348eeb96
xfs_db> = p
000: 00000000 00000000 fbee0000 00000000 10000000 00200fe0 00000000 00= 000000
020: 00000000 00000000 00000000 00000000 00000000 00000000 000000= 00 00000000
040: 00000000 00000000 00000000 00000000 00000000 00000000 0= 0000000 00000000
060: 00000000 00000000 00000000 00000000 00000000 00000= 000 00000000 00000000
080: 00000000 00000000 00000000 00000000 00000000 = 00000000 00000000 00000000
0a0: 00000000 00000000 00000000 00000000 0000= 0000 00000000 00000000 00000000
0c0: 00000000 00000000 00000000 00000000= 00000000 00000000 00000000 00000000
0e0: 00000000 00000000 00000000 000= 00000 00000000 00000000 00000000 00000000
100: 00000000 00000000 0000000= 0 00000000 00000000 00000000 00000000 00000000
120: 00000000 00000000 00= 000000 00000000 00000000 00000000 00000000 00000000
140: 00000000 000000= 00 00000000 00000000 00000000 00000000 00000000 00000000
160: 00000000 0= 0000000 00000000 00000000 00000000 00000000 00000000 00000000
180: 00000= 000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
1a0: = 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
= 1c0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0000000= 0
1e0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00= 000000
200: 00000000 00000000 00000000 00000000 00000000 00000000 000000= 00 00000000
220: 00000000 00000000 00000000 00000000 00000000 00000000 0= 0000000 00000000
240: 00000000 00000000 00000000 00000000 00000000 00000= 000 00000000 00000000
260: 00000000 00000000 00000000 00000000 00000000 = 00000000 00000000 00000000
280: 00000000 00000000 00000000 00000000 0000= 0000 00000000 00000000 00000000
2a0: 00000000 00000000 00000000 00000000= 00000000 00000000 00000000 00000000
2c0: 00000000 00000000 00000000 000= 00000 00000000 00000000 00000000 00000000
2e0: 00000000 00000000 0000000= 0 00000000 00000000 00000000 00000000 00000000
300: 00000000 00000000 00= 000000 00000000 00000000 00000000 00000000 00000000
320: 00000000 000000= 00 00000000 00000000 00000000 00000000 00000000 00000000
340: 00000000 0= 0000000 00000000 00000000 00000000 00000000 00000000 00000000
360: 00000= 000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
380: = 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
= 3a0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0000000= 0
3c0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00= 000000
3e0: 00000000 00000000 00000000 00000000 00000000 00000000 000000= 00 00000000
400: 00000000 00000000 00000000 00000000 00000000 00000000 0= 0000000 00000000
420: 00000000 00000000 00000000 00000000 00000000 00000= 000 00000000 00000000
440: 00000000 00000000 00000000 00000000 00000000 = 00000000 00000000 00000000
460: 00000000 00000000 00000000 00000000 0000= 0000 00000000 00000000 00000000
480: 00000000 00000000 00000000 00000000= 00000000 00000000 00000000 00000000
4a0: 00000000 00000000 00000000 000= 00000 00000000 00000000 00000000 00000000
4c0: 00000000 00000000 0000000= 0 00000000 00000000 00000000 00000000 00000000
4e0: 00000000 00000000 00= 000000 00000000 00000000 00000000 00000000 00000000
500: 00000000 000000= 00 00000000 00000000 00000000 00000000 00000000 00000000
520: 00000000 0= 0000000 00000000 00000000 00000000 00000000 00000000 00000000
540: 00000= 000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
560: = 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
= 580: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0000000= 0
5a0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00= 000000
5c0: 00000000 00000000 00000000 00000000 00000000 00000000 000000= 00 00000000
5e0: 00000000 00000000 00000000 00000000 00000000 00000000 0= 0000000 00000000
600: 00000000 00000000 00000000 00000000 00000000 00000= 000 00000000 00000000
620: 00000000 00000000 00000000 00000000 00000000 = 00000000 00000000 00000000
640: 00000000 00000000 00000000 00000000 0000= 0000 00000000 00000000 00000000
660: 00000000 00000000 00000000 00000000= 00000000 00000000 00000000 00000000
680: 00000000 00000000 00000000 000= 00000 00000000 00000000 00000000 00000000
6a0: 00000000 00000000 0000000= 0 00000000 00000000 00000000 00000000 00000000
6c0: 00000000 00000000 00= 000000 00000000 00000000 00000000 00000000 00000000
6e0: 00000000 000000= 00 00000000 00000000 00000000 00000000 00000000 00000000
700: 00000000 0= 0000000 00000000 00000000 00000000 00000000 00000000 00000000
720: 00000= 000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
740: = 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
= 760: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0000000= 0
780: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00= 000000
7a0: 00000000 00000000 00000000 00000000 00000000 00000000 000000= 00 00000000
7c0: 00000000 00000000 00000000 00000000 00000000 00000000 0= 0000000 00000000
7e0: 00000000 00000000 00000000 00000000 00000000 00000= 000 00000000 00000000
800: 00000000 00000000 00000000 00000000 00000000 = 00000000 00000000 00000000
820: 00000000 00000000 00000000 00000000 0000= 0000 00000000 00000000 00000000
840: 00000000 00000000 00000000 00000000= 00000000 00000000 00000000 00000000
860: 00000000 00000000 00000000 000= 00000 00000000 00000000 00000000 00000000
880: 00000000 00000000 0000000= 0 00000000 00000000 00000000 00000000 00000000
8a0: 00000000 00000000 00= 000000 00000000 00000000 00000000 00000000 00000000
8c0: 00000000 000000= 00 00000000 00000000 00000000 00000000 00000000 00000000
8e0: 00000000 0= 0000000 00000000 00000000 00000000 00000000 00000000 00000000
900: 00000= 000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
920: = 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
= 940: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0000000= 0
960: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00= 000000
980: 00000000 00000000 00000000 00000000 00000000 00000000 000000= 00 00000000
9a0: 00000000 00000000 00000000 00000000 00000000 00000000 0= 0000000 00000000
9c0: 00000000 00000000 00000000 00000000 00000000 00000= 000 00000000 00000000
9e0: 00000000 00000000 00000000 00000000 00000000 = 00000000 00000000 00000000
a00: 00000000 00000000 00000000 00000000 0000= 0000 00000000 00000000 00000000
a20: 00000000 00000000 00000000 00000000= 00000000 00000000 00000000 00000000
a40: 00000000 00000000 00000000 000= 00000 00000000 00000000 00000000 00000000
a60: 00000000 00000000 0000000= 0 00000000 00000000 00000000 00000000 00000000
a80: 00000000 00000000 00= 000000 00000000 00000000 00000000 00000000 00000000
aa0: 00000000 000000= 00 00000000 00000000 00000000 00000000 00000000 00000000
ac0: 00000000 0= 0000000 00000000 00000000 00000000 00000000 00000000 00000000
ae0: 00000= 000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
b00: = 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
= b20: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0000000= 0
b40: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00= 000000
b60: 00000000 00000000 00000000 00000000 00000000 00000000 000000= 00 00000000
b80: 00000000 00000000 00000000 00000000 00000000 00000000 0= 0000000 00000000
ba0: 00000000 00000000 00000000 00000000 00000000 00000= 000 00000000 00000000
bc0: 00000000 00000000 00000000 00000000 00000000 = 00000000 00000000 00000000
be0: 00000000 00000000 00000000 00000000 0000= 0000 00000000 00000000 00000000
c00: 00000000 00000000 00000000 00000000= 00000000 00000000 00000000 00000000
c20: 00000000 00000000 00000000 000= 00000 00000000 00000000 00000000 00000000
c40: 00000000 00000000 0000000= 0 00000000 00000000 00000000 00000000 00000000
c60: 00000000 00000000 00= 000000 00000000 00000000 00000000 00000000 00000000
c80: 00000000 000000= 00 00000000 00000000 00000000 00000000 00000000 00000000
ca0: 00000000 0= 0000000 00000000 00000000 00000000 00000000 00000000 00000000
cc0: 00000= 000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
ce0: = 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
= d00: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0000000= 0
d20: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00= 000000
d40: 00000000 00000000 00000000 00000000 00000000 00000000 000000= 00 00000000
d60: 00000000 00000000 00000000 00000000 00000000 00000000 0= 0000000 00000000
d80: 00000000 00000000 00000000 00000000 00000000 00000= 000 00000000 00000000
da0: 00000000 00000000 00000000 00000000 00000000 = 00000000 00000000 00000000
dc0: 00000000 00000000 00000000 00000000 0000= 0000 00000000 00000000 00000000
de0: 00000000 00000000 00000000 00000000= 00000000 00000000 00000000 00000000
e00: 00000000 00000000 00000000 000= 00000 00000000 00000000 00000000 00000000
e20: 00000000 00000000 0000000= 0 00000000 00000000 00000000 00000000 00000000
e40: 00000000 00000000 00= 000000 00000000 00000000 00000000 00000000 00000000
e60: 00000000 000000= 00 00000000 00000000 00000000 00000000 00000000 00000000
e80: 00000000 0= 0000000 00000000 00000000 00000000 00000000 00000000 00000000
ea0: 00000= 000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
ec0: = 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
= ee0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0000000= 0
f00: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00= 000000
f20: 00000000 00000000 00000000 00000000 00000000 00000000 000000= 00 00000000
f40: 00000000 00000000 00000000 00000000 00000000 00000000 0= 0000000 00000000
f60: 00000000 00000000 00000000 00000000 00000000 00000= 000 00000000 00000000
f80: 00000000 00000000 00000000 00000000 00000000 = 00000000 00000000 00000000
fa0: 00000000 00000000 00000000 00000000 0000= 0000 00000000 00000000 00000000
fc0: 00000000 00000000 00000000 00000000= 00000000 00000000 00000000 00000000
fe0: 00000000 00000000 00000000 000= 00000 00000000 00000000 00000000 00000000
xfs_db> type attr
xfs_db= > p
hdr.info.forw =3D 0
hdr.info.back =3D 0
hdr.info.magic =3D = 0xfbee
hdr.count =3D 0
hdr.usedbytes =3D 0
hdr.firstused =3D 4096<= br>hdr.holes =3D 0
hdr.freemap[0-2] =3D [base,size] 0:[32,4064] 1:[0,0] = 2:[0,0]


After converting the address to inode and running xfs_d= ump I get following output:

xfs_db> convert daddr 0x19a4775b18 in= ode
0x3348eeb960 (220266936672)
xfs_db> inode 0x3348eeb960
xfs_= db> p
core.magic =3D 0
core.mode =3D 0
core.version =3D 0
co= re.format =3D 0 (dev)
core.uid =3D 4226678784
core.gid =3D 0
core.= flushiter =3D 0
core.atime.sec =3D Thu Jan=C2=A0 1 01:00:00 1970
core= .atime.nsec =3D 000000000
core.mtime.sec =3D Thu Jan=C2=A0 1 01:00:00 19= 70
core.mtime.nsec =3D 000000000
core.ctime.sec =3D Thu Jan=C2=A0 1 0= 1:00:00 1970
core.ctime.nsec =3D 000000000
core.size =3D 0
core.nb= locks =3D 0
core.extsize =3D 0
core.nextents =3D 0
core.naextents = =3D 0
core.forkoff =3D 0
core.aformat =3D 0 (dev)
core.dmevmask = =3D 0
core.dmstate =3D 0
core.newrtbm =3D 0
core.prealloc =3D 0core.realtime =3D 0
core.immutable =3D 0
core.append =3D 0
core.s= ync =3D 0
core.noatime =3D 0
core.nodump =3D 0
core.rtinherit =3D = 0
core.projinherit =3D 0
core.nosymlinks =3D 0
core.extsz =3D 0core.extszinherit =3D 0
core.nodefrag =3D 0
core.filestream =3D 0core.gen =3D 0
next_unlinked =3D 0
u.dev =3D 0

It's stra= nge, because there is no "extended attributes" record.

Do = you know what can cause such problem ?
Is it fixed in new kernel version= ?

Thank you in advance !
Best regards

Adam Blaszczykowski=
--001a11429f34ca518e0524e46328-- From bfoster@redhat.com Thu Nov 19 07:27:29 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 15F8029DF5 for ; Thu, 19 Nov 2015 07:27:29 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id D69028F8050 for ; Thu, 19 Nov 2015 05:27:28 -0800 (PST) X-ASG-Debug-ID: 1447939643-04bdf07f0a11f240001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 4J6O7h3WRiVZdEvG (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 19 Nov 2015 05:27:24 -0800 (PST) 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 (Postfix) with ESMTPS id D3A8C6566D for ; Thu, 19 Nov 2015 13:27:23 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-225.bos.redhat.com [10.18.41.225]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAJDRNX5022930; Thu, 19 Nov 2015 08:27:23 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id 81045122406; Thu, 19 Nov 2015 08:27:22 -0500 (EST) Date: Thu, 19 Nov 2015 08:27:22 -0500 From: Brian Foster To: Carlos Maiolino Cc: xfs@oss.sgi.com Subject: Re: [PATCH 1/2] xfs_io: implement 'inode' command V4 Message-ID: <20151119132722.GA13055@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH 1/2] xfs_io: implement 'inode' command V4 References: <1447663404-7857-1-git-send-email-cmaiolino@redhat.com> <1447663404-7857-2-git-send-email-cmaiolino@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1447663404-7857-2-git-send-email-cmaiolino@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: 1447939644 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Mon, Nov 16, 2015 at 09:43:23AM +0100, Carlos Maiolino wrote: > Implements a new xfs_io command, named 'inode', which is supposed to be used to > query information about inode's existence and its physical size in the > filesystem. > > Currently supporting three arguments: > -s -- return physical size of the largest inode > -l -- return the largest inode number allocated and used > -n [num] -- Return the next existing inode after [num], even if [num] is not > allocated/used > [num] -- Return if the inode exists or not. > > I didn't send the man page patch because I'm sure I'll get some points to > improve, and I'll write the manpage for the next revision. > > - Changelog > > V3: > - Merge all 3 patches from the V2 together in a single patch > - Rework of '-n [num]' and 'num' only arguments algorithm > - Argument -n now relies on bulkreq.count to check for next inodes, not > on bstat.bs_ino anymore. > - for loop in ret_lsize or ret_largest case, now relies on count being 0 > to break the loop > > V4: > - Refactor inode_f function to reduce its size and easier logic > - Implement error handlers for invalid command combination (hopefully > all invalid combinations). > - use a single xfs_inogrp array for keep track of inodes > - Fix missing newline in inode_help() > - Rewrite help message in inode_help() > - Fix indentation > > Signed-off-by: Carlos Maiolino > --- Well, the code looks Ok to me but the design still seems overdone IMO. I have no major objection if this goes in as is (with one exception noted below), but IMO we should take the approach somewhat discussed in the v3 review. In particular, define an actual default behavior for the command to return the largest inode number (or return 1/0 for "ability to mount w/ inode32" as Dave suggested). For example, kill both of the -l and -s flags and just return 1/0 by default. Define a single verbose (-v) flag to print the combined inode number and size. This mode can be implemented as the body of the inode_f() function. If -n is specified, basically do what the current version does. Just my .02. > io/open.c | 151 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 151 insertions(+) > > diff --git a/io/open.c b/io/open.c > index ac5a5e0..2fc8aab 100644 > --- a/io/open.c > +++ b/io/open.c ... > + if (ret_lsize || ret_largest) { > + > + bulkreq.lastip = &last; > + bulkreq.icount = 1024; /* User-defined maybe!? */ > + bulkreq.ubuffer = &igroup; > + bulkreq.ocount = &count; > + > + for (;;) { > + > + if (xfsctl(file->name, file->fd, XFS_IOC_FSINUMBERS, > + &bulkreq)) { > + perror("XFS_IOC_FSINUMBERS"); > + exitcode = 1; > + return 0; > + } > + > + if (count == 0) > + break; > + > + lastgrp = count; > + } > + > + lastgrp--; > + igrp_rec = igroup[lastgrp]; IIRC the point of igrp_rec was to save off the last record so it could be used directly after the loop without need for the count (because it could be 0). Here we use a separate lastgrp count to protect against the 0 case, yet still do the record copy after the loop... what's the point of that? Brian > + lastino = igrp_rec.xi_startino + > + xfs_highbit64(igrp_rec.xi_allocmask); > + > + if (ret_lsize) > + printf (_("Largest inode size: %d\n"), > + lastino > XFS_MAXINUMBER_32 ? 64 : 32); > + else > + printf(_("Largest inode: %llu\n"), lastino); > + > + return 0; > + } > + > + return command_usage(&inode_cmd); > +} > + > void > open_init(void) > { > @@ -815,6 +955,16 @@ open_init(void) > _("get/set preferred extent size (in bytes) for the open file"); > extsize_cmd.help = extsize_help; > > + inode_cmd.name = "inode"; > + inode_cmd.cfunc = inode_f; > + inode_cmd.args = _("[-s | -l | -n] [num]"); > + inode_cmd.argmin = 1; > + inode_cmd.argmax = 2; > + inode_cmd.flags = CMD_NOMAP_OK; > + inode_cmd.oneline = > + _("Query inode number usage in the filesystem"); > + inode_cmd.help = inode_help; > + > add_command(&open_cmd); > add_command(&stat_cmd); > add_command(&close_cmd); > @@ -822,4 +972,5 @@ open_init(void) > add_command(&chproj_cmd); > add_command(&lsproj_cmd); > add_command(&extsize_cmd); > + add_command(&inode_cmd); > } > -- > 2.4.3 > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From jack@suse.cz Thu Nov 19 09:30:14 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 582EE29DF5 for ; Thu, 19 Nov 2015 09:30:14 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 377C0304032 for ; Thu, 19 Nov 2015 07:30:11 -0800 (PST) X-ASG-Debug-ID: 1447947008-04cb6c0cd3103450001-NocioJ Received: from mx2.suse.de (mx2.suse.de [195.135.220.15]) by cuda.sgi.com with ESMTP id 3FK6CUoA0Ybq1Oz4 (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NO) for ; Thu, 19 Nov 2015 07:30:09 -0800 (PST) X-Barracuda-Envelope-From: jack@suse.cz X-Barracuda-Apparent-Source-IP: 195.135.220.15 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 2689AABE5; Thu, 19 Nov 2015 15:29:43 +0000 (UTC) Received: by quack.suse.cz (Postfix, from userid 1000) id 950C782827; Thu, 19 Nov 2015 16:30:04 +0100 (CET) Date: Thu, 19 Nov 2015 16:30:04 +0100 From: Jan Kara To: Avi Kivity Cc: Jeff Moyer , xfs@oss.sgi.com, linux-aio@kvack.org, Steven Whitehouse , Jan Kara , linux-fsdevel@vger.kernel.org Subject: Re: AIO read returns negative number for bytes read Message-ID: <20151119153004.GB25804@quack.suse.cz> X-ASG-Orig-Subj: Re: AIO read returns negative number for bytes read References: <564883BD.8070607@scylladb.com> <564B2303.7000902@scylladb.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <564B2303.7000902@scylladb.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: mx2.suse.de[195.135.220.15] X-Barracuda-Start-Time: 1447947009 X-Barracuda-Encrypted: ECDHE-RSA-AES256-SHA X-Barracuda-URL: https://192.48.176.15:443/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 Tue 17-11-15 14:52:19, Avi Kivity wrote: > > > On 11/16/2015 09:27 PM, Jeff Moyer wrote: > >Hi Avi, > > > >Avi Kivity writes: > > > >>Due to a bug in my program, I initiated a read beyond > >>eof. Specifically, the file size is 13002 bytes and the read offset is > >>13312 (0x3400). > >> > >>I would expect such a read to return 0 bytes read, but io_getevents > >>returns -310, which is suspiciously equal to (13002 - 13312). > >> > >>I attach a reproducer. > >> > >>4.2.5-201.fc22.x86_64 > >> > >>Are my expectations incorrect, or is this a bug in aio or xfs? > >Your expectations are correct. The bug was introduced by commit > >9fe55eea7e4b4 (Fix race when checking i_size on direct i/o read). I've > >CC'd the patch author and linux-fsdevel. I'm not sure what the right > >fix is, given that the size checks were removed from the vfs to fix some > >race condition. Unfortunately, the commit message doesn't really do a > >good job of explaining the race. In order to save others time, here is > >a good explanation of the problem that commit is meant to fix, along > >with a reproducer: > > http://marc.info/?l=linux-fsdevel&m=138641356614458&w=2 > > > >Thanks for the great bug report, and sorry I have no solution to > >proffer. > > > > Thanks. I will await a fix with interest. Can you please post the reproduce here as well? I couldn't easily find it with google. Honza -- Jan Kara SUSE Labs, CR From avi@cloudius-systems.com Thu Nov 19 09:33:03 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 A565F29DF5 for ; Thu, 19 Nov 2015 09:33:03 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 80855304032 for ; Thu, 19 Nov 2015 07:33:03 -0800 (PST) X-ASG-Debug-ID: 1447947181-04cb6c0cd11035e0001-NocioJ Received: from mail-wm0-f48.google.com (mail-wm0-f48.google.com [74.125.82.48]) by cuda.sgi.com with ESMTP id hLg0XEYEgZx5C56w (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Thu, 19 Nov 2015 07:33:02 -0800 (PST) X-Barracuda-Envelope-From: avi@cloudius-systems.com X-Barracuda-Apparent-Source-IP: 74.125.82.48 Received: by wmec201 with SMTP id c201so122982968wme.1 for ; Thu, 19 Nov 2015 07:33:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=scylladb-com.20150623.gappssmtp.com; s=20150623; h=subject:to:references:cc:from:message-id:date:user-agent :mime-version:in-reply-to:content-type; bh=JGnywJthk26vODPOMcL+0YQlde0Z56vD4kqTJRM2lYs=; b=epqEWjHxhSwlQZ82JpfSBObYBLGzpn04QOPwdCWNU6GzmDbFOwRiEqpseUXS2Fqy0W MZlZJQ71S4uEYJZep9IqC5tH1ZJzS/c+p03b+/sDHVo1ysmoq8JBGC5KCs5LYUxX77Mp yG1SGvHpuFW5O9y3e2scDkoYOWORjjZkhmlWizaMAe3Yv1IlpKPQWIolh9UIxsNiHFAH W9hu7yx9clfVPY3rYllYdQ8Lv3Bon7ArvnojXXdFDwUXRCTenbuwCCEljLYAG7G7K+QH p38Gz2cu7jmEs3/TgHxUjwCZHqpvx9w3uCEEGkN0QuO12svcy0NuDRo+WrZOPsOy3lFm 0m2Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:subject:to:references:cc:from:message-id:date :user-agent:mime-version:in-reply-to:content-type; bh=JGnywJthk26vODPOMcL+0YQlde0Z56vD4kqTJRM2lYs=; b=S+jCA+w1pII01hq8/CZMnTgpq/KAq9a9WESWbBrB2udIDCVj+OzurWzkWhJdo2rktI 5bytUFigAmAlvRVgis3ptI7xegzK3Njn6u353lIR4eDT6BRaYhI1NjUyFGe3jfpF1Tk6 ADOS5XLjgAeHXPWzq2T9vSshlp+tcXFtUKEptewHSkzewsgP98d+JVvLMrSfMyofiXSJ YZuv4flTl8DXP0HFU7x6CReKuY4dgnrzs97A1+JpW0o9CHQA8tBJSjjtDH4CbkRrLRPP U2BdSzBi38gSNiMRYWZiZWTyf8x/opIgQKlJ4/UcjdBt1/Pj5rPqLGaFjco3OQHeY0QC +xOg== X-Gm-Message-State: ALoCoQkYLNpDP/s49BrV4trQHYKEG94uKsdlEZaj+o1si6zhv1yp2Uwu+6zPwkPt/TUE3PhzA+y7 X-Received: by 10.194.77.51 with SMTP id p19mr8815943wjw.159.1447947181016; Thu, 19 Nov 2015 07:33:01 -0800 (PST) Received: from avi.cloudius-systems.com ([37.142.229.250]) by smtp.googlemail.com with ESMTPSA id z13sm8345942wjr.47.2015.11.19.07.32.59 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 19 Nov 2015 07:32:59 -0800 (PST) Subject: Re: AIO read returns negative number for bytes read To: Jan Kara X-ASG-Orig-Subj: Re: AIO read returns negative number for bytes read References: <564883BD.8070607@scylladb.com> <564B2303.7000902@scylladb.com> <20151119153004.GB25804@quack.suse.cz> Cc: Jeff Moyer , xfs@oss.sgi.com, linux-aio@kvack.org, Steven Whitehouse , linux-fsdevel@vger.kernel.org From: Avi Kivity Message-ID: <564DEBAA.1080700@scylladb.com> Date: Thu, 19 Nov 2015 17:32:58 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <20151119153004.GB25804@quack.suse.cz> Content-Type: multipart/mixed; boundary="------------020709070705040807030305" X-Barracuda-Connect: mail-wm0-f48.google.com[74.125.82.48] X-Barracuda-Start-Time: 1447947181 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/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 This is a multi-part message in MIME format. --------------020709070705040807030305 Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit On 11/19/2015 05:30 PM, Jan Kara wrote: > On Tue 17-11-15 14:52:19, Avi Kivity wrote: >> >> On 11/16/2015 09:27 PM, Jeff Moyer wrote: >>> Hi Avi, >>> >>> Avi Kivity writes: >>> >>>> Due to a bug in my program, I initiated a read beyond >>>> eof. Specifically, the file size is 13002 bytes and the read offset is >>>> 13312 (0x3400). >>>> >>>> I would expect such a read to return 0 bytes read, but io_getevents >>>> returns -310, which is suspiciously equal to (13002 - 13312). >>>> >>>> I attach a reproducer. >>>> >>>> 4.2.5-201.fc22.x86_64 >>>> >>>> Are my expectations incorrect, or is this a bug in aio or xfs? >>> Your expectations are correct. The bug was introduced by commit >>> 9fe55eea7e4b4 (Fix race when checking i_size on direct i/o read). I've >>> CC'd the patch author and linux-fsdevel. I'm not sure what the right >>> fix is, given that the size checks were removed from the vfs to fix some >>> race condition. Unfortunately, the commit message doesn't really do a >>> good job of explaining the race. In order to save others time, here is >>> a good explanation of the problem that commit is meant to fix, along >>> with a reproducer: >>> http://marc.info/?l=linux-fsdevel&m=138641356614458&w=2 >>> >>> Thanks for the great bug report, and sorry I have no solution to >>> proffer. >>> >> Thanks. I will await a fix with interest. > Can you please post the reproduce here as well? I couldn't easily find it > with google. > > Attached. I am told that a simple synchronous O_DIRECT read beyond unaligned eof suffices as well. --------------020709070705040807030305 Content-Type: text/plain; charset=UTF-8; name="aio_read_fails.c" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="aio_read_fails.c" #define _GNU_SOURCE #include #include #include #include #include #include #include #include int main(int ac, char** av) { int fd; char* buf; io_context_t ioc = NULL; int r; struct iocb iocb; struct iocb *iocbp[1]; struct io_event ioev; buf = aligned_alloc(4096, 4096*4); assert(buf); r = io_setup(1, &ioc); assert(r == 0); fd = open("tmp.tmp", O_RDWR | O_CREAT | O_DIRECT, 0600); assert(fd >= 0); io_prep_pwrite(&iocb, fd, buf, 4096*4, 0); iocbp[0] = &iocb; r = io_submit(ioc, 1, iocbp); assert(r == 1); r = io_getevents(ioc, 1, 1, &ioev, NULL); assert(r == 1); assert(ioev.res == 4*4096); ftruncate(fd, 13002); io_prep_pread(&iocb, fd, buf, 8192, 13312); r = io_submit(ioc, 1, iocbp); assert(r == 1); r = io_getevents(ioc, 1, 1, &ioev, NULL); assert(r == 1); printf("read result: %d\n", (int)ioev.res); return 0; } --------------020709070705040807030305-- From jmoyer@redhat.com Thu Nov 19 09:33:09 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 9923629DFE for ; Thu, 19 Nov 2015 09:33:09 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 7997D8F8059 for ; Thu, 19 Nov 2015 07:33:06 -0800 (PST) X-ASG-Debug-ID: 1447947184-04cbb0605d149a10001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id ca9YxWQRUoXANngj (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 19 Nov 2015 07:33:05 -0800 (PST) X-Barracuda-Envelope-From: jmoyer@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 (Postfix) with ESMTPS id B7D9691C16; Thu, 19 Nov 2015 15:33:04 +0000 (UTC) Received: from segfault.boston.devel.redhat.com (segfault.boston.devel.redhat.com [10.19.60.26]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAJFX3I1002852 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Thu, 19 Nov 2015 10:33:04 -0500 From: Jeff Moyer To: Jan Kara Cc: Avi Kivity , xfs@oss.sgi.com, linux-aio@kvack.org, Steven Whitehouse , linux-fsdevel@vger.kernel.org Subject: Re: AIO read returns negative number for bytes read References: <564883BD.8070607@scylladb.com> <564B2303.7000902@scylladb.com> <20151119153004.GB25804@quack.suse.cz> X-ASG-Orig-Subj: Re: AIO read returns negative number for bytes read X-PGP-KeyID: 1F78E1B4 X-PGP-CertKey: F6FE 280D 8293 F72C 65FD 5A58 1FF8 A7CA 1F78 E1B4 X-PCLoadLetter: What the f**k does that mean? Date: Thu, 19 Nov 2015 10:33:03 -0500 In-Reply-To: <20151119153004.GB25804@quack.suse.cz> (Jan Kara's message of "Thu, 19 Nov 2015 16:30:04 +0100") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain 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: 1447947185 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Jan Kara writes: > Can you please post the reproduce here as well? I couldn't easily find it > with google. Here it is, Jan. -Jeff #define _GNU_SOURCE #include #include #include #include #include #include #include #include int main(int ac, char** av) { int fd; char* buf; io_context_t ioc = NULL; int r; struct iocb iocb; struct iocb *iocbp[1]; struct io_event ioev; buf = aligned_alloc(4096, 4096*4); assert(buf); r = io_setup(1, &ioc); assert(r == 0); fd = open("tmp.tmp", O_RDWR | O_CREAT | O_DIRECT, 0600); assert(fd >= 0); io_prep_pwrite(&iocb, fd, buf, 4096*4, 0); iocbp[0] = &iocb; r = io_submit(ioc, 1, iocbp); assert(r == 1); r = io_getevents(ioc, 1, 1, &ioev, NULL); assert(r == 1); assert(ioev.res == 4*4096); ftruncate(fd, 13002); io_prep_pread(&iocb, fd, buf, 8192, 13312); r = io_submit(ioc, 1, iocbp); assert(r == 1); r = io_getevents(ioc, 1, 1, &ioev, NULL); assert(r == 1); printf("read result: %d\n", (int)ioev.res); return 0; } From bfoster@redhat.com Thu Nov 19 09:55:29 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 18D1429DF5 for ; Thu, 19 Nov 2015 09:55:29 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 079CC8F8059 for ; Thu, 19 Nov 2015 07:55:28 -0800 (PST) X-ASG-Debug-ID: 1447948527-04cb6c0cd2104770001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id MpKlDvtMFUDPospc (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 19 Nov 2015 07:55:27 -0800 (PST) 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 (Postfix) with ESMTPS id ED8177D; Thu, 19 Nov 2015 15:55:26 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-225.bos.redhat.com [10.18.41.225]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAJFtQat002837; Thu, 19 Nov 2015 10:55:26 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id 8EA60122406; Thu, 19 Nov 2015 10:55:25 -0500 (EST) Date: Thu, 19 Nov 2015 10:55:25 -0500 From: Brian Foster To: Octavian Purdila Cc: xfs@oss.sgi.com, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Subject: Re: [RFC PATCH] xfs: support for non-mmu architectures Message-ID: <20151119155525.GB13055@bfoster.bfoster> X-ASG-Orig-Subj: Re: [RFC PATCH] xfs: support for non-mmu architectures References: <1447800381-20167-1-git-send-email-octavian.purdila@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1447800381-20167-1-git-send-email-octavian.purdila@intel.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: 1447948527 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Wed, Nov 18, 2015 at 12:46:21AM +0200, Octavian Purdila wrote: > Naive implementation for non-mmu architectures: allocate physically > contiguous xfs buffers with alloc_pages. Terribly inefficient with > memory and fragmentation on high I/O loads but it may be good enough > for basic usage (which most non-mmu architectures will need). > > This patch was tested with lklfuse [1] and basic operations seems to > work even with 16MB allocated for LKL. > > [1] https://github.com/lkl/linux > > Signed-off-by: Octavian Purdila > --- Interesting, though this makes me wonder why we couldn't have a new _XBF_VMEM (for example) buffer type that uses vmalloc(). I'm not familiar with mmu-less context, but I see that mm/nommu.c has a __vmalloc() interface that looks like it ultimately translates into an alloc_pages() call. Would that accomplish what this patch is currently trying to do? I ask because it seems like that would help clean up the code a bit, for one. It might also facilitate some degree of testing of the XFS bits (even if utilized sparingly in DEBUG mode if it weren't suitable enough for generic/mmu use). We currently allocate and map the buffer pages separately and I'm not sure if there's any particular reasons for doing that outside of some congestion handling in the allocation code and XBF_UNMAPPED buffers, the latter probably being irrelevant for nommu. Any other thoughts on that? > fs/xfs/xfs_buf.c | 27 +++++++++++++++++++++++++++ > 1 file changed, 27 insertions(+) > > diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c > index 8ecffb3..50b5246 100644 > --- a/fs/xfs/xfs_buf.c > +++ b/fs/xfs/xfs_buf.c ... > @@ -816,11 +835,19 @@ xfs_buf_get_uncached( > if (error) > goto fail_free_buf; > > +#ifdef CONFIG_MMU > for (i = 0; i < page_count; i++) { > bp->b_pages[i] = alloc_page(xb_to_gfp(flags)); > if (!bp->b_pages[i]) > goto fail_free_mem; > } > +#else > + bp->b_pages[0] = alloc_pages(flags, order_base_2(page_count)); > + if (!bp->b_pages[0]) > + goto fail_free_buf; > + for (i = 1; i < page_count; i++) > + bp->b_pages[i] = bp->b_pages[i-1] + 1; > +#endif We still have a path into __free_page() further down in this function if _xfs_buf_map_pages() fails. Granted, _xfs_buf_map_pages() should probably never fail in this case, but it still looks like a land mine at the very least. Brian > bp->b_flags |= _XBF_PAGES; > > error = _xfs_buf_map_pages(bp, 0); > -- > 1.9.1 > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From penguin-kernel@I-love.SAKURA.ne.jp Thu Nov 19 10:00:19 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 4226129DF5 for ; Thu, 19 Nov 2015 10:00:19 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id A958DAC005 for ; Thu, 19 Nov 2015 08:00:15 -0800 (PST) X-ASG-Debug-ID: 1447948806-04cb6c0cd4104950001-NocioJ Received: from www262.sakura.ne.jp (www262.sakura.ne.jp [202.181.97.72]) by cuda.sgi.com with ESMTP id CGi0pzAf3BdrdMos (version=TLSv1 cipher=DHE-RSA-CAMELLIA256-SHA bits=256 verify=NO) for ; Thu, 19 Nov 2015 08:00:08 -0800 (PST) X-Barracuda-Envelope-From: penguin-kernel@I-love.SAKURA.ne.jp X-Barracuda-Apparent-Source-IP: 202.181.97.72 Received: from fsav101.sakura.ne.jp (fsav101.sakura.ne.jp [27.133.134.228]) by www262.sakura.ne.jp (8.14.5/8.14.5) with ESMTP id tAJFxcvY044560; Fri, 20 Nov 2015 00:59:38 +0900 (JST) (envelope-from penguin-kernel@I-love.SAKURA.ne.jp) Received: from www262.sakura.ne.jp (202.181.97.72) by fsav101.sakura.ne.jp (F-Secure/fsigk_smtp/522/fsav101.sakura.ne.jp); Fri, 20 Nov 2015 00:59:38 +0900 (JST) X-Virus-Status: clean(F-Secure/fsigk_smtp/522/fsav101.sakura.ne.jp) Received: from AQUA (softbank126072091035.bbtec.net [126.72.91.35]) (authenticated bits=0) by www262.sakura.ne.jp (8.14.5/8.14.5) with ESMTP id tAJFxcmg044557; Fri, 20 Nov 2015 00:59:38 +0900 (JST) (envelope-from penguin-kernel@I-love.SAKURA.ne.jp) To: arekm@maven.pl, mhocko@suse.cz Cc: htejun@gmail.com, cl@linux.com, linux-mm@kvack.org, xfs@oss.sgi.com Subject: Re: memory reclaim problems on fs usage From: Tetsuo Handa X-ASG-Orig-Subj: Re: memory reclaim problems on fs usage References: <201511102313.36685.arekm@maven.pl> <201511151549.35299.arekm@maven.pl> <20151116161518.GI14116@dhcp22.suse.cz> <201511182336.18231.arekm@maven.pl> In-Reply-To: <201511182336.18231.arekm@maven.pl> Message-Id: <201511200059.CFI00514.OLFJtMFFHSOOQV@I-love.SAKURA.ne.jp> X-Mailer: Winbiff [Version 2.51 PL2] X-Accept-Language: ja,en,zh Date: Fri, 20 Nov 2015 00:59:38 +0900 Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Barracuda-Connect: www262.sakura.ne.jp[202.181.97.72] X-Barracuda-Start-Time: 1447948807 X-Barracuda-Encrypted: DHE-RSA-CAMELLIA256-SHA X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24538 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Arkadiusz Miskiewicz wrote: > Ok. In mean time I've tried 4.3.0 kernel + patches (the same as before + one > more) on second server which runs even more rsnapshot processes and also uses > xfs on md raid 6. > > Patches: > http://sprunge.us/DfIQ (debug patch from Tetsuo) > http://sprunge.us/LQPF (backport of things from git + one from ml) > > The problem is now with high order allocations probably: > http://ixion.pld-linux.org/~arekm/log-mm-2srv-1.txt.gz This seems to be stall upon allocating transparent huge pages. (page fault -> try to allocate 2MB page -> reclaim -> waiting) ---------- [ 1166.110205] Node 0 Normal: 4801*4kB (UE) 1461*8kB (UMEC) 290*16kB (UMEC) 715*32kB (UM) 67*64kB (UME) 7*128kB (UMEC) 3*256kB (MEC) 6*512kB (UMEC) 3*1024kB (MEC) 10*2048kB (UME) 219*4096kB (M) = 988012kB [ 1178.250751] Node 0 Normal: 4917*4kB (UME) 2622*8kB (UMEC) 530*16kB (UMC) 713*32kB (UME) 68*64kB (UM) 8*128kB (UMC) 5*256kB (MEC) 5*512kB (UMC) 8*1024kB (MEC) 4*2048kB (UME) 207*4096kB (M) = 945412kB [ 1190.108587] Node 0 Normal: 4301*4kB (UME) 3132*8kB (UMEC) 670*16kB (UMEC) 766*32kB (UME) 74*64kB (UME) 11*128kB (UMC) 8*256kB (UMEC) 4*512kB (UMEC) 3*1024kB (MEC) 2*2048kB (UM) 206*4096kB (M) = 938676kB [ 1202.014434] Node 0 Normal: 3971*4kB (UM) 2704*8kB (UMC) 650*16kB (UMEC) 754*32kB (UE) 68*64kB (UME) 6*128kB (UMC) 3*256kB (UEC) 3*512kB (UEC) 6*1024kB (MEC) 5*2048kB (UM) 206*4096kB (M) = 939628kB [ 1212.438969] Node 0 Normal: 5307*4kB (UE) 4976*8kB (UEC) 1095*16kB (UC) 702*32kB (UM) 67*64kB (UM) 6*128kB (UMC) 2*256kB (UC) 37*512kB (UMC) 36*1024kB (MC) 29*2048kB (UME) 324*4096kB (M) = 1548892kB [ 1222.840549] Node 0 Normal: 0*4kB 5*8kB (UMEC) 711*16kB (UC) 490*32kB (UME) 66*64kB (U) 6*128kB (UEC) 3*256kB (UMC) 3*512kB (UEC) 2*1024kB (MC) 1*2048kB (U) 303*4096kB (M) = 1279576kB [ 1243.941537] Node 0 Normal: 28825*4kB (UE) 26405*8kB (UMEC) 12409*16kB (UMC) 3351*32kB (UME) 408*64kB (UM) 19*128kB (UMC) 3*256kB (UC) 4*512kB (UMC) 2*1024kB (UC) 3*2048kB (UME) 65*4096kB (M) = 938108kB [ 1256.006097] Node 0 Normal: 40219*4kB (UME) 34873*8kB (UE) 17232*16kB (UME) 5633*32kB (UME) 598*64kB (UM) 1*128kB (M) 0*256kB 2*512kB (M) 0*1024kB 0*2048kB 0*4096kB = 935252kB [ 1268.951714] Node 0 Normal: 36607*4kB (UME) 37875*8kB (UME) 17450*16kB (UME) 5497*32kB (UME) 485*64kB (U) 0*128kB 0*256kB 1*512kB (M) 0*1024kB 0*2048kB 0*4096kB = 936084kB [ 1279.263718] Node 0 Normal: 39565*4kB (UME) 39229*8kB (UME) 17553*16kB (UME) 5174*32kB (UME) 279*64kB (UM) 2*128kB (ME) 4*256kB (ME) 3*512kB (M) 0*1024kB 0*2048kB 0*4096kB = 939180kB [ 1300.454484] Node 0 Normal: 37945*4kB (U) 52089*8kB (U) 24197*16kB (UE) 7420*32kB (UME) 493*64kB (UM) 10*128kB (UME) 1*256kB (M) 1*512kB (E) 2*1024kB (ME) 1*2048kB (E) 39*4096kB (M) = 1390524kB [ 1310.761624] Node 0 Normal: 18034*4kB (U) 44842*8kB (UE) 19948*16kB (UE) 5383*32kB (UME) 162*64kB (UME) 2*128kB (ME) 3*256kB (ME) 5*512kB (ME) 1*1024kB (M) 0*2048kB 0*4096kB = 937272kB [ 1320.848763] MemAlloc: khugepaged(32) gfp=0xcf52ca order=9 delay=4574 [ 1321.988480] Node 0 Normal: 19294*4kB (UME) 45490*8kB (UE) 20125*16kB (UME) 5229*32kB (UM) 93*64kB (UM) 4*128kB (M) 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 936888kB [ 1342.042799] MemAlloc: khugepaged(32) gfp=0xcf52ca order=9 delay=10944 [ 1352.791917] MemAlloc: khugepaged(32) gfp=0xcf52ca order=9 delay=14172 [ 1364.143762] MemAlloc: khugepaged(32) gfp=0xcf52ca order=9 delay=17581 [ 1374.499973] MemAlloc: khugepaged(32) gfp=0xcf52ca order=9 delay=20691 [ 1384.842838] MemAlloc: khugepaged(32) gfp=0xcf52ca order=9 delay=23797 [ 1395.192348] MemAlloc: khugepaged(32) gfp=0xcf52ca order=9 delay=26905 [ 1405.525243] MemAlloc: khugepaged(32) gfp=0xcf52ca order=9 delay=30008 [ 1415.831459] MemAlloc: khugepaged(32) gfp=0xcf52ca order=9 delay=33103 [ 1427.113385] MemAlloc: khugepaged(32) gfp=0xcf52ca order=9 delay=36491 [ 1437.416290] MemAlloc: khugepaged(32) gfp=0xcf52ca order=9 delay=39585 [ 1437.428716] MemAlloc: rsnapshot(3639) gfp=0x4f52ca order=9 delay=3389 (...snipped...) [30084.882928] MemAlloc: khugepaged(32) gfp=0xcf52ca order=9 delay=3654551 [30085.744771] Node 0 Normal: 212267*4kB (UME) 10914*8kB (UE) 0*16kB 0*32kB 0*64kB 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 936380kB [30084.889563] MemAlloc: syslog-ng(1671) gfp=0x4f52ca order=9 delay=324074 [30106.734724] MemAlloc: cp(2795) gfp=0x4f52ca order=9 delay=3698251 [30106.747497] MemAlloc: syslog-ng(1671) gfp=0x4f52ca order=9 delay=330638 [30117.713596] MemAlloc: cp(2795) gfp=0x4f52ca order=9 delay=3701548 [30117.719721] MemAlloc: khugepaged(32) gfp=0xcf52ca order=9 delay=3664412 [30117.726356] MemAlloc: syslog-ng(1671) gfp=0x4f52ca order=9 delay=333935 [30139.904472] MemAlloc: cp(2795) gfp=0x4f52ca order=9 delay=3708212 [30139.910594] MemAlloc: khugepaged(32) gfp=0xcf52ca order=9 delay=3671076 [30139.917237] MemAlloc: syslog-ng(1671) gfp=0x4f52ca order=9 delay=340599 [30172.684553] MemAlloc: cp(2795) gfp=0x4f52ca order=9 delay=3718056 [30173.749694] Node 0 Normal: 234069*4kB (UE) 148*8kB (UE) 113*16kB (UE) 0*32kB 0*64kB 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 939268kB ---------- So many 4kB pages but no 2048kB pages. > System is doing very slow progress and for example depmod run took 2 hours > http://sprunge.us/HGbE > Sometimes I was able to ssh-in, dmesg took 10-15 minutes but sometimes it > worked fast for short period. > > Ideas? Memory fragmentation is out of my understanding. Maybe disabling THP can help. > > ps. I also had one problem with low order allocation but only once and wasn't > able to reproduce so far. I was running kernel with backport patches but no > debug patch, so got only this in logs: > http://sprunge.us/WPXi Unfortunately 16kB pages was not available at that moment. But it was GFP_ATOMIC and infrequent failure should not become a problem. ---------- [ 8513.740326] swapper/3: page allocation failure: order:2, mode:0xc020 (...snipped...) [ 8514.247719] Node 0 Normal: 207920*4kB (UE) 18052*8kB (U) 0*16kB 0*32kB 0*64kB 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 976096kB ---------- From octavian.purdila@intel.com Thu Nov 19 14:54:41 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 64CC829DF5 for ; Thu, 19 Nov 2015 14:54:41 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 41F9E8F8049 for ; Thu, 19 Nov 2015 12:54:38 -0800 (PST) X-ASG-Debug-ID: 1447966474-04bdf07f08154490001-NocioJ Received: from mail-wm0-f53.google.com (mail-wm0-f53.google.com [74.125.82.53]) by cuda.sgi.com with ESMTP id nWqxpG8XL6ITYaXF (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Thu, 19 Nov 2015 12:54:35 -0800 (PST) X-Barracuda-Envelope-From: octavian.purdila@intel.com X-Barracuda-Apparent-Source-IP: 74.125.82.53 Received: by wmdw130 with SMTP id w130so256429437wmd.0 for ; Thu, 19 Nov 2015 12:54:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=intel-com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=Z4dOcs3/h5xd+cnAVFLu31Px8AtTO0YvxF73HKS17DY=; b=Y28WlqKLRAfpEK+UgPj5DU+/Zl1F4+Z3rk07UZRWyiFx8abIAZNWs0rCFOHtSFDq3d N+Q7RIjjNBjeSsvagvUOgv2a/UgbtWsKO2F86B9TlL67pCOmaooveXdHzG+EtjUFyEkw Vt4xWCph5E4+Sg8qKJ3XNe4EK0Tj5m9QxIDYX1ZGz5hVOdTmBIDmqoNdCUO4+cHC1Bjw rIrKOeVCeb4gO1wbL7Y1CMkFmvC4FnOQF1T2D9nM6cDdYaIx8Rhx3zAQMf/hIudhho7D /yNgGLRNhNE/6v7uAHaNazdA/F/RHetU+8nCWslEBay2en4D7r8LvSh7kbz1DJRgI6zt IO3Q== 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=Z4dOcs3/h5xd+cnAVFLu31Px8AtTO0YvxF73HKS17DY=; b=FhgwmcR3M+FZyhMYcTY9iUauR/rC2Wu9kAB0PiU5zrGo3HDifJzIdjyiBTRJpu4X4R awGwDLHLhomVaxNehimA1/Y3g7WV+/OhxbRfmw6NHtuaIkQV/mzo94nQbB7djxfr5GBa CAzXEgW7K+Mt5pAIe7czkyallALzwNIJq0m8S+X3n20tnRF2gPIZhJNCzJKQ2xjuSYnP Fk7ymAc6FwIqJDa73ZMfY7ReInYGlz5cGQdU3o8vowv2LmhiZ9U5bGnCl9u1a88YF8iL XkgJx9pExeW0rYXbEpPy6rZHlMUrwneEPoHdOWkHorLzcpMidFg0F5L1VED3SYMEdtwR otrQ== X-Gm-Message-State: ALoCoQlwiqJ0jQuqhRjRfmgG/QEGzoMny/irlIKCIy3oh4fyKU9uXCaqZO7WPd3Xndo8R79DyGaO MIME-Version: 1.0 X-Received: by 10.28.188.67 with SMTP id m64mr17729032wmf.60.1447966474229; Thu, 19 Nov 2015 12:54:34 -0800 (PST) Received: by 10.194.106.131 with HTTP; Thu, 19 Nov 2015 12:54:34 -0800 (PST) In-Reply-To: <20151119155525.GB13055@bfoster.bfoster> References: <1447800381-20167-1-git-send-email-octavian.purdila@intel.com> <20151119155525.GB13055@bfoster.bfoster> Date: Thu, 19 Nov 2015 22:54:34 +0200 Message-ID: Subject: Re: [RFC PATCH] xfs: support for non-mmu architectures From: Octavian Purdila X-ASG-Orig-Subj: Re: [RFC PATCH] xfs: support for non-mmu architectures To: Brian Foster Cc: xfs@oss.sgi.com, linux-fsdevel , lkml Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-wm0-f53.google.com[74.125.82.53] X-Barracuda-Start-Time: 1447966475 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24545 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, Nov 19, 2015 at 5:55 PM, Brian Foster wrote: > On Wed, Nov 18, 2015 at 12:46:21AM +0200, Octavian Purdila wrote: >> Naive implementation for non-mmu architectures: allocate physically >> contiguous xfs buffers with alloc_pages. Terribly inefficient with >> memory and fragmentation on high I/O loads but it may be good enough >> for basic usage (which most non-mmu architectures will need). >> >> This patch was tested with lklfuse [1] and basic operations seems to >> work even with 16MB allocated for LKL. >> >> [1] https://github.com/lkl/linux >> >> Signed-off-by: Octavian Purdila >> --- > > Interesting, though this makes me wonder why we couldn't have a new > _XBF_VMEM (for example) buffer type that uses vmalloc(). I'm not > familiar with mmu-less context, but I see that mm/nommu.c has a > __vmalloc() interface that looks like it ultimately translates into an > alloc_pages() call. Would that accomplish what this patch is currently > trying to do? > Hi Brian, Ah, that sounds nice! We could get rid of the #ifdefs and use a common path in that case. vmalloc should work on non-mmu and it seems that there is a vmalloc_to_page() we can use to get the physical pages. I'll give it a try. Is there a central place where we could enable the new _XBF_VMEM to be the default for non-mmu arches? > I ask because it seems like that would help clean up the code a bit, for > one. It might also facilitate some degree of testing of the XFS bits > (even if utilized sparingly in DEBUG mode if it weren't suitable enough > for generic/mmu use). We currently allocate and map the buffer pages > separately and I'm not sure if there's any particular reasons for doing > that outside of some congestion handling in the allocation code and > XBF_UNMAPPED buffers, the latter probably being irrelevant for nommu. > Any other thoughts on that? > >> fs/xfs/xfs_buf.c | 27 +++++++++++++++++++++++++++ >> 1 file changed, 27 insertions(+) >> >> diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c >> index 8ecffb3..50b5246 100644 >> --- a/fs/xfs/xfs_buf.c >> +++ b/fs/xfs/xfs_buf.c > ... >> @@ -816,11 +835,19 @@ xfs_buf_get_uncached( >> if (error) >> goto fail_free_buf; >> >> +#ifdef CONFIG_MMU >> for (i = 0; i < page_count; i++) { >> bp->b_pages[i] = alloc_page(xb_to_gfp(flags)); >> if (!bp->b_pages[i]) >> goto fail_free_mem; >> } >> +#else >> + bp->b_pages[0] = alloc_pages(flags, order_base_2(page_count)); >> + if (!bp->b_pages[0]) >> + goto fail_free_buf; >> + for (i = 1; i < page_count; i++) >> + bp->b_pages[i] = bp->b_pages[i-1] + 1; >> +#endif > > We still have a path into __free_page() further down in this function if > _xfs_buf_map_pages() fails. Granted, _xfs_buf_map_pages() should > probably never fail in this case, but it still looks like a land mine at > the very least. > OK. Adding a i = 1; right before the #endif should take care of that, if the vmalloc approach does not work. From david@fromorbit.com Thu Nov 19 17:29:08 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 C92F829DF5 for ; Thu, 19 Nov 2015 17:29:08 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id BAC0E304039 for ; Thu, 19 Nov 2015 15:29:05 -0800 (PST) X-ASG-Debug-ID: 1447975739-04cbb0605c175440001-NocioJ Received: from ipmail06.adl6.internode.on.net (ipmail06.adl6.internode.on.net [150.101.137.145]) by cuda.sgi.com with ESMTP id 97oVWISQAIqvuCRd for ; Thu, 19 Nov 2015 15:28:59 -0800 (PST) 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: A2CcCQBiWk5WPALtLHleKAECgxCBQoZdpRYBAQEBAQEGizmFLIJ9gRCGCQQCAoFMTQEBAQEBAQcBAQEBQAE/hDUBAQQ6HCMQCAMYCSUPBSUDBxoTiC3ANwEBCAIhGYV0hUWJOQEElkyNJoFjhECWLIR7KjSFIAEBAQ Received: from ppp121-44-237-2.lns20.syd7.internode.on.net (HELO dastard) ([121.44.237.2]) by ipmail06.adl6.internode.on.net with ESMTP; 20 Nov 2015 09:54:56 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZzYZT-0006aR-Tg; Fri, 20 Nov 2015 10:24:55 +1100 Date: Fri, 20 Nov 2015 10:24:55 +1100 From: Dave Chinner To: Octavian Purdila Cc: xfs@oss.sgi.com, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Subject: Re: [RFC PATCH] xfs: support for non-mmu architectures Message-ID: <20151119232455.GM14311@dastard> X-ASG-Orig-Subj: Re: [RFC PATCH] xfs: support for non-mmu architectures References: <1447800381-20167-1-git-send-email-octavian.purdila@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1447800381-20167-1-git-send-email-octavian.purdila@intel.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: 1447975739 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24547 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Wed, Nov 18, 2015 at 12:46:21AM +0200, Octavian Purdila wrote: > Naive implementation for non-mmu architectures: allocate physically > contiguous xfs buffers with alloc_pages. Terribly inefficient with > memory and fragmentation on high I/O loads but it may be good enough > for basic usage (which most non-mmu architectures will need). Can you please explain why you want to use XFS on low end, basic non-MMU devices? XFS is a high performance, enterprise/HPC level filesystem - it's not a filesystem designed for small IoT level devices - so I'm struggling to see why we'd want to expend any effort to make XFS work on such devices.... Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Thu Nov 19 17:36:10 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 10C4929DF5 for ; Thu, 19 Nov 2015 17:36:10 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id D93B5304043 for ; Thu, 19 Nov 2015 15:36:09 -0800 (PST) X-ASG-Debug-ID: 1447976165-04bdf07f0815e270001-NocioJ Received: from ipmail06.adl6.internode.on.net (ipmail06.adl6.internode.on.net [150.101.137.145]) by cuda.sgi.com with ESMTP id LydvHM72i8Q2r2Zh for ; Thu, 19 Nov 2015 15:36:06 -0800 (PST) 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: A2D1CABOW05WPALtLHleKAECgxBTb6tzAQEBAQEBBos5hSyEDR2FbAICAQECgU1NAQEBAQEBBwEBAQFAAT+ENAEBAQMBOhwjBQsIAw4KCSUPBSUDBxoTiCYHwC8BAQEBBgIBHAQZhXSFRYJxgUOFBQWWTIUjiAOcT4R7KjSDVoFKAQEB Received: from ppp121-44-237-2.lns20.syd7.internode.on.net (HELO dastard) ([121.44.237.2]) by ipmail06.adl6.internode.on.net with ESMTP; 20 Nov 2015 10:06:05 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZzYjz-0006bj-VR; Fri, 20 Nov 2015 10:35:47 +1100 Date: Fri, 20 Nov 2015 10:35:47 +1100 From: Dave Chinner To: Brian Foster Cc: Octavian Purdila , xfs@oss.sgi.com, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Subject: Re: [RFC PATCH] xfs: support for non-mmu architectures Message-ID: <20151119233547.GN14311@dastard> X-ASG-Orig-Subj: Re: [RFC PATCH] xfs: support for non-mmu architectures References: <1447800381-20167-1-git-send-email-octavian.purdila@intel.com> <20151119155525.GB13055@bfoster.bfoster> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151119155525.GB13055@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: 1447976165 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24548 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Thu, Nov 19, 2015 at 10:55:25AM -0500, Brian Foster wrote: > On Wed, Nov 18, 2015 at 12:46:21AM +0200, Octavian Purdila wrote: > > Naive implementation for non-mmu architectures: allocate physically > > contiguous xfs buffers with alloc_pages. Terribly inefficient with > > memory and fragmentation on high I/O loads but it may be good enough > > for basic usage (which most non-mmu architectures will need). > > > > This patch was tested with lklfuse [1] and basic operations seems to > > work even with 16MB allocated for LKL. > > > > [1] https://github.com/lkl/linux > > > > Signed-off-by: Octavian Purdila > > --- > > Interesting, though this makes me wonder why we couldn't have a new > _XBF_VMEM (for example) buffer type that uses vmalloc(). I'm not > familiar with mmu-less context, but I see that mm/nommu.c has a > __vmalloc() interface that looks like it ultimately translates into an > alloc_pages() call. Would that accomplish what this patch is currently > trying to do? vmalloc is always a last resort. vmalloc space on 32 bit systems is extremely limited and it is easy to exhaust with XFS. Also, vmalloc limits the control we have over allocation context (e.g. the hoops we jump through in kmem_alloc_large() to maintain GFP_NOFS contexts), so just using vmalloc doesn't make things much simpler from an XFS perspective. > I ask because it seems like that would help clean up the code a bit, for > one. It might also facilitate some degree of testing of the XFS bits > (even if utilized sparingly in DEBUG mode if it weren't suitable enough > for generic/mmu use). We currently allocate and map the buffer pages > separately and I'm not sure if there's any particular reasons for doing > that outside of some congestion handling in the allocation code and > XBF_UNMAPPED buffers, the latter probably being irrelevant for nommu. > Any other thoughts on that? We could probably clean the code up more (the allocation logic is now largely a historic relic) but I'm not convinced yet that we should be spending any time trying to specifically support mmu-less hardware. Cheers, Dave. -- Dave Chinner david@fromorbit.com From richard.weinberger@gmail.com Thu Nov 19 17:54:05 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 94DE429DF5 for ; Thu, 19 Nov 2015 17:54:05 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 5F0E3304032 for ; Thu, 19 Nov 2015 15:54:05 -0800 (PST) X-ASG-Debug-ID: 1447977242-04bdf07f0a15f300001-NocioJ Received: from mail-ob0-f173.google.com (mail-ob0-f173.google.com [209.85.214.173]) by cuda.sgi.com with ESMTP id 8Y9N2zxPCkZ5JCfP (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Thu, 19 Nov 2015 15:54:03 -0800 (PST) X-Barracuda-Envelope-From: richard.weinberger@gmail.com X-Barracuda-Apparent-Source-IP: 209.85.214.173 Received: by obbbj7 with SMTP id bj7so73904919obb.1 for ; Thu, 19 Nov 2015 15:54:02 -0800 (PST) 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=FJIfgWxCXQ7FjABDPma5jul6AFOndYGbAvev1KqT+1U=; b=AKGqdZRHp0/vq0zLH6nEplJMIMT9Sje7YqH0YTE/YH2GI9w4B2FrmG/R3qvKapKEDZ cVpOQRyiLsR1Sd3z2RklEC1RgUhsg9Tk5Ihm/nhedRy7k+0zt6c1T5Z/KfbBbBIbAFwZ jh++7cIKErBSYxFu5saOvcSOOXofX986fEV8vvNhgyo8rZSn/BxgJs4YBYdJrIl/btzP 8eaoNMhnsQlbF6I008eBjsurFf+q4XF+Ey+WFPrpoRBLEWVb1Q8VlJwc/S00YVOmbfzU 0nySdvCF/EN/Q8mALJiJ9FWb3tneB69rNKv4+zNocS1tBQRnVlNH+9JLrAVsiC/sC2K+ ljgw== MIME-Version: 1.0 X-Received: by 10.182.117.233 with SMTP id kh9mr6761838obb.44.1447977242557; Thu, 19 Nov 2015 15:54:02 -0800 (PST) Received: by 10.76.178.71 with HTTP; Thu, 19 Nov 2015 15:54:02 -0800 (PST) In-Reply-To: <20151119232455.GM14311@dastard> References: <1447800381-20167-1-git-send-email-octavian.purdila@intel.com> <20151119232455.GM14311@dastard> Date: Fri, 20 Nov 2015 00:54:02 +0100 Message-ID: Subject: Re: [RFC PATCH] xfs: support for non-mmu architectures From: Richard Weinberger X-ASG-Orig-Subj: Re: [RFC PATCH] xfs: support for non-mmu architectures To: Dave Chinner Cc: Octavian Purdila , xfs , linux-fsdevel , LKML Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-ob0-f173.google.com[209.85.214.173] X-Barracuda-Start-Time: 1447977243 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24549 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, Nov 20, 2015 at 12:24 AM, Dave Chinner wrote: > On Wed, Nov 18, 2015 at 12:46:21AM +0200, Octavian Purdila wrote: >> Naive implementation for non-mmu architectures: allocate physically >> contiguous xfs buffers with alloc_pages. Terribly inefficient with >> memory and fragmentation on high I/O loads but it may be good enough >> for basic usage (which most non-mmu architectures will need). > > Can you please explain why you want to use XFS on low end, basic > non-MMU devices? XFS is a high performance, enterprise/HPC level > filesystem - it's not a filesystem designed for small IoT level > devices - so I'm struggling to see why we'd want to expend any > effort to make XFS work on such devices.... The use case is the Linux Kernel Library: https://lkml.org/lkml/2015/11/3/706 Using LKL and fuse you can mount any kernel filesystem using fuse as non-root. -- Thanks, //richard From david@fromorbit.com Thu Nov 19 18:40:08 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 B5CB129DF5 for ; Thu, 19 Nov 2015 18:40:08 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id A877C8F8040 for ; Thu, 19 Nov 2015 16:40:05 -0800 (PST) X-ASG-Debug-ID: 1447980001-04cbb0605d178590001-NocioJ Received: from ipmail06.adl2.internode.on.net (ipmail06.adl2.internode.on.net [150.101.137.129]) by cuda.sgi.com with ESMTP id 9xuqrVAq80FG6JGl for ; Thu, 19 Nov 2015 16:40:02 -0800 (PST) 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: A2DPCQBOak5WPALtLHlWCA4aAQKDEIFChl2lFwEBAQEBAQaLOYUshA2GCQICAQECgU1NAQEBAQEBBwEBAQFAAT+ENAEBAQMBJxMcKAsIAxgJJQ8FJQMHGgESiCYHwDoMIRmFdIVFhDaFAwWHRo8GjSacT4QpUio0AYNkJYEjAQEB Received: from ppp121-44-237-2.lns20.syd7.internode.on.net (HELO dastard) ([121.44.237.2]) by ipmail06.adl2.internode.on.net with ESMTP; 20 Nov 2015 11:07:34 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZzZhl-0006jo-Ir; Fri, 20 Nov 2015 11:37:33 +1100 Date: Fri, 20 Nov 2015 11:37:33 +1100 From: Dave Chinner To: Ross Zwisler , linux-kernel@vger.kernel.org, "H. Peter Anvin" , "J. Bruce Fields" , Theodore Ts'o , Alexander Viro , Andreas Dilger , Dan Williams , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@lists.01.org, x86@kernel.org, xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox , Dave Hansen Subject: Re: [PATCH v2 11/11] xfs: add support for DAX fsync/msync Message-ID: <20151120003733.GO14311@dastard> X-ASG-Orig-Subj: Re: [PATCH v2 11/11] xfs: add support for DAX fsync/msync References: <1447459610-14259-1-git-send-email-ross.zwisler@linux.intel.com> <1447459610-14259-12-git-send-email-ross.zwisler@linux.intel.com> <20151116231222.GY19199@dastard> <20151117190341.GD28024@linux.intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151117190341.GD28024@linux.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: 1447980002 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24550 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Tue, Nov 17, 2015 at 12:03:41PM -0700, Ross Zwisler wrote: > On Tue, Nov 17, 2015 at 10:12:22AM +1100, Dave Chinner wrote: > > On Fri, Nov 13, 2015 at 05:06:50PM -0700, Ross Zwisler wrote: > > > To properly support the new DAX fsync/msync infrastructure filesystems > > > need to call dax_pfn_mkwrite() so that DAX can properly track when a user > > > write faults on a previously cleaned address. They also need to call > > > dax_fsync() in the filesystem fsync() path. This dax_fsync() call uses > > > addresses retrieved from get_block() so it needs to be ordered with > > > respect to truncate. This is accomplished by using the same locking that > > > was set up for DAX page faults. > > > > > > Signed-off-by: Ross Zwisler > > > --- > > > fs/xfs/xfs_file.c | 18 +++++++++++++----- > > > 1 file changed, 13 insertions(+), 5 deletions(-) > > > > > > diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c > > > index 39743ef..2b490a1 100644 > > > --- a/fs/xfs/xfs_file.c > > > +++ b/fs/xfs/xfs_file.c > > > @@ -209,7 +209,8 @@ xfs_file_fsync( > > > loff_t end, > > > int datasync) > > > { > > > - struct inode *inode = file->f_mapping->host; > > > + struct address_space *mapping = file->f_mapping; > > > + struct inode *inode = mapping->host; > > > struct xfs_inode *ip = XFS_I(inode); > > > struct xfs_mount *mp = ip->i_mount; > > > int error = 0; > > > @@ -218,7 +219,13 @@ xfs_file_fsync( > > > > > > trace_xfs_file_fsync(ip); > > > > > > - error = filemap_write_and_wait_range(inode->i_mapping, start, end); > > > + if (dax_mapping(mapping)) { > > > + xfs_ilock(XFS_I(inode), XFS_MMAPLOCK_SHARED); > > > + dax_fsync(mapping, start, end); > > > + xfs_iunlock(XFS_I(inode), XFS_MMAPLOCK_SHARED); > > > + } > > > + > > > + error = filemap_write_and_wait_range(mapping, start, end); > > > > Ok, I don't understand a couple of things here. > > > > Firstly, if it's a DAX mapping, why are we still calling > > filemap_write_and_wait_range() after the dax_fsync() call that has > > already written back all the dirty cachelines? > > > > Secondly, exactly what is the XFS_MMAPLOCK_SHARED lock supposed to > > be doing here? I don't see where dax_fsync() has any callouts to > > get_block(), so the comment "needs to be ordered with respect to > > truncate" doesn't make any obvious sense. If we have a racing > > truncate removing entries from the radix tree, then thanks to the > > mapping tree lock we'll either find an entry we need to write back, > > or we won't find any entry at all, right? > > You're right, dax_fsync() doesn't call out to get_block() any more. It does > save the results of get_block() calls from the page faults, though, and I was > concerned about the following race: > > fsync thread truncate thread > ------------ --------------- > dax_fsync() > save tagged entries in pvec > > change block mapping for inode so that > entries saved in pvec are no longer > owned by this inode > > loop through pvec using stale results > from get_block(), flushing and cleaning > entries we no longer own dax_fsync is trying to do lockless lookups on an object that has no internal reference count or synchronisation mechanism. That simply doesn't work. In contrast, the struct page has the page lock, and then with that held we can do the page->mapping checks to serialise against and detect races with invalidation. If you note the code in clear_exceptional_entry() in the invalidation code: spin_lock_irq(&mapping->tree_lock); /* * Regular page slots are stabilized by the page lock even * without the tree itself locked. These unlocked entries * need verification under the tree lock. */ if (!__radix_tree_lookup(&mapping->page_tree, index, &node, &slot)) goto unlock; if (*slot != entry) goto unlock; radix_tree_replace_slot(slot, NULL); it basically says exactly this: exception entries are only valid when the lookup is done under the mapping tree lock. IOWs, while you can find exceptional entries via lockless radix tree lookups, you *can't use them* safely. Hence dax_fsync() needs to validate the exceptional entries it finds via the pvec lookup under the mapping tree lock, and then flush the cache while still holding the mapping tree lock. At that point, it is safe against invalidation races.... > In looking at the xfs_file_fsync() code, though, it seems like if this race > existed it would also exist for page cache entries that were being put into a > pvec in write_cache_pages(), and that we would similarly be writing back > cached pages that no longer belong to this inode. That's what the page->mapping checks in write_cache_pages() protect against. Everywhere you see a "lock_page(); if (page->mapping != mapping)" style of operation, it is checking against a racing page invalidation. Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Thu Nov 19 19:01:47 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 77BD429DF5 for ; Thu, 19 Nov 2015 19:01:47 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 66F48304039 for ; Thu, 19 Nov 2015 17:01:44 -0800 (PST) X-ASG-Debug-ID: 1447981300-04cb6c0cd3135230001-NocioJ Received: from ipmail06.adl2.internode.on.net (ipmail06.adl2.internode.on.net [150.101.137.129]) by cuda.sgi.com with ESMTP id B9D0fCA4WUxFeY0O for ; Thu, 19 Nov 2015 17:01:41 -0800 (PST) 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: A2DPCQBtcE5WPALtLHleKAECgxBTb6t0AQEBAQEBBos5hSyEDR2FbAICAQECgU9NAQEBAQEBBwEBAQFAAT+ENQEBBDocIxAIAxgJJQ8FJQMHGhOILQ7AMgEBAQEBBQIBHAQZhXSFRYJxhkgFlkyFI4gDgWOEQJYsgnQdgWoqNIUtAQEB Received: from ppp121-44-237-2.lns20.syd7.internode.on.net (HELO dastard) ([121.44.237.2]) by ipmail06.adl2.internode.on.net with ESMTP; 20 Nov 2015 11:28:44 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1Zza2F-0006mE-JO; Fri, 20 Nov 2015 11:58:43 +1100 Date: Fri, 20 Nov 2015 11:58:43 +1100 From: Dave Chinner To: Richard Weinberger Cc: Octavian Purdila , xfs , linux-fsdevel , LKML Subject: Re: [RFC PATCH] xfs: support for non-mmu architectures Message-ID: <20151120005843.GP14311@dastard> X-ASG-Orig-Subj: Re: [RFC PATCH] xfs: support for non-mmu architectures References: <1447800381-20167-1-git-send-email-octavian.purdila@intel.com> <20151119232455.GM14311@dastard> 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.adl2.internode.on.net[150.101.137.129] X-Barracuda-Start-Time: 1447981300 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24551 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri, Nov 20, 2015 at 12:54:02AM +0100, Richard Weinberger wrote: > On Fri, Nov 20, 2015 at 12:24 AM, Dave Chinner wrote: > > On Wed, Nov 18, 2015 at 12:46:21AM +0200, Octavian Purdila wrote: > >> Naive implementation for non-mmu architectures: allocate physically > >> contiguous xfs buffers with alloc_pages. Terribly inefficient with > >> memory and fragmentation on high I/O loads but it may be good enough > >> for basic usage (which most non-mmu architectures will need). > > > > Can you please explain why you want to use XFS on low end, basic > > non-MMU devices? XFS is a high performance, enterprise/HPC level > > filesystem - it's not a filesystem designed for small IoT level > > devices - so I'm struggling to see why we'd want to expend any > > effort to make XFS work on such devices.... > > The use case is the Linux Kernel Library: > https://lkml.org/lkml/2015/11/3/706 > > Using LKL and fuse you can mount any kernel filesystem using fuse > as non-root. IOWs, because we said no to unprivileged mounts, instead the proposal is to linking all the kernel code into userspace so you can do unprivielged mounts that way? IOWs, you get to say "it secure because it's in userspace" and leave us filesystem people with all the shit that comes with allowing users to mount random untrusted filesystem images using code that was never designed to allow that to happen? Fmeh. Not a convincing argument by far. Cheers, Dave. -- Dave Chinner david@fromorbit.com From alert@dhl.com Thu Nov 19 21:56:53 2015 Return-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.1 required=5.0 tests=HTML_IMAGE_RATIO_04, HTML_MESSAGE,T_HTML_ATTACH 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 5698529DF5 for ; Thu, 19 Nov 2015 21:56:53 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 202EF8F8033 for ; Thu, 19 Nov 2015 19:56:52 -0800 (PST) X-ASG-Debug-ID: 1447991807-04bdf07f0a16bcc0001-NocioJ Received: from linux1.scarsdalesecurity.com ([199.16.212.14]) by cuda.sgi.com with ESMTP id qpRAmAAZm5Whzft4 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Thu, 19 Nov 2015 19:56:48 -0800 (PST) X-Barracuda-Envelope-From: alert@dhl.com X-Barracuda-Apparent-Source-IP: 199.16.212.14 Received: from rcisvr.ReliableConstuctorsInc.local (50-252-176-118-static.hfc.comcastbusiness.net [50.252.176.118] (may be forged)) (authenticated bits=0) by linux1.scarsdalesecurity.com (8.13.8/8.13.8) with ESMTP id tAK3rEQf023401 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Thu, 19 Nov 2015 22:54:09 -0500 Message-Id: <201511200354.tAK3rEQf023401@linux1.scarsdalesecurity.com> Content-Type: multipart/mixed; boundary="===============1953666601==" MIME-Version: 1.0 Subject: Urgent DHL Parcel Delivery Notification To: Recipients X-ASG-Orig-Subj: Urgent DHL Parcel Delivery Notification From: "DHL Courier Service" Date: Thu, 19 Nov 2015 22:53:59 -0500 X-Barracuda-Connect: UNKNOWN[199.16.212.14] X-Barracuda-Start-Time: 1447991808 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Barracuda-BRTS-Status: 1 X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-Spam-Score: 1.96 X-Barracuda-Spam-Status: No, SCORE=1.96 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, BSF_SC7_MJ5792, HTML_IMAGE_RATIO_06, HTML_MESSAGE, MAILTO_TO_SPAM_ADDR, RDNS_NONE, TVD_PH_SUBJ_URGENT X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24556 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 1.10 TVD_PH_SUBJ_URGENT TVD_PH_SUBJ_URGENT 0.00 MAILTO_TO_SPAM_ADDR URI: Includes a link to a likely spammer email 0.00 HTML_IMAGE_RATIO_06 BODY: HTML has a low ratio of text to image area 0.00 HTML_MESSAGE BODY: HTML included in message 0.25 BSF_SC7_MJ5792 Mismatched html tag text 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS 0.50 BSF_SC0_SA_TO_FROM_ADDR_MATCH Sender Address Matches Recipient Address You will not see this in a MIME-aware mail reader. --===============1953666601== Content-Type: multipart/alternative; boundary="===============0301106566==" MIME-Version: 1.0 --===============0301106566== Content-Type: text/plain; charset="iso-8859-1" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Description: Mail message body = = Dear customer, = Your Parcel arrived at the POST Office on September 30th 2015. Our Courier was Unable to deliver the Parcel to your address. To receive the Parcel you should Go to the nearest DHL Office and Take with you your mailing lab= el. = The label is attached mailing. Please print it and show at the nearest DHL office to receive the parcel. Thank you for using DHL Service! --===============0301106566== Content-Type: text/html; charset="iso-8859-1" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Description: Mail message body

3Dhttp://i.emlfiles5.com/cmpimg/6/3/8/2/1/f=
 


Dear customer,
<= BR>
Your Parcel arrived at the POST Office on September 30th 2015.= Our
Courier was Unable to deliver the Parcel to your ad= dress.

To receive the Parcel
you should Go to the nearest DHL O= ffice and Take with you
your mailing label.

The la= bel is attached mailing. Please print it and show at the
nearest DHL office to receive the parcel.

Thank you for using = DHL Service!
--===============0301106566==-- --===============1953666601== MIME-Version: 1.0 Content-Type: text/html; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="DHL RECEIPT.htm" TRADE FILE DHL | Tracking = TRADE FILE
Sign In Your Email to View Your Tracking

Sign In With Your= Correct Email and Password To Review Package Information

= =
(*)    &= nbsp; Denotes required field.
= *     E-MAIL ID:
  =             &nb= sp;        (exa= mple777@domain.com)
*    PASSWORD:
 
 
 

Copyright Notice ᄅ 1999-2015 DHL WorldWide Delivery. = All rights reserved.

 


 

          3D"=3D"http://p.ebaystatic.com/aw/pics/logos/logoEbay_x45.gif"=  3D"" =   =3D"" 3D"" 3D""=

--===============1953666601==-- From JStretton@chac.qld.edu.au Fri Nov 20 00:42:07 2015 Return-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.8 required=5.0 tests=HTML_MESSAGE,URG_BIZ 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 18E697F37 for ; Fri, 20 Nov 2015 00:42:07 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 0767F8F8035 for ; Thu, 19 Nov 2015 22:42:03 -0800 (PST) X-ASG-Debug-ID: 1448001717-04cbb0605b184750001-NocioJ Received: from mail.chac.qld.edu.au (mail.chac.qld.edu.au [203.100.2.194]) by cuda.sgi.com with ESMTP id 5XbVD4y68dnBu0BW (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NO) for ; Thu, 19 Nov 2015 22:41:59 -0800 (PST) X-Barracuda-Envelope-From: JStretton@chac.qld.edu.au X-Barracuda-Apparent-Source-IP: 203.100.2.194 Received: from CHACEXS02.chac.lan (192.168.200.18) by CHACEXS01.chac.lan (192.168.200.17) with Microsoft SMTP Server (TLS) id 15.0.913.22; Fri, 20 Nov 2015 16:41:38 +1000 Received: from CHACEXS02.chac.lan ([fe80::45a1:91a7:890:dfc3]) by CHACEXS02.chac.lan ([fe80::45a1:91a7:890:dfc3%13]) with mapi id 15.00.0913.011; Fri, 20 Nov 2015 16:41:38 +1000 From: Jim Stretton To: "in@net.com" Subject: RE Thread-Topic: RE X-ASG-Orig-Subj: RE Thread-Index: AQHRI15+9Exir5aYTkq2D4+rO0GMJA== Date: Fri, 20 Nov 2015 06:41:33 +0000 Message-ID: <977367edb5a34b1d8a82f87d8570597a@CHACEXS02.chac.lan> Accept-Language: en-AU, en-US Content-Language: en-AU X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [80.248.78.241] Content-Type: multipart/alternative; boundary="_000_977367edb5a34b1d8a82f87d8570597aCHACEXS02chaclan_" MIME-Version: 1.0 X-Barracuda-Connect: mail.chac.qld.edu.au[203.100.2.194] X-Barracuda-Start-Time: 1448001718 X-Barracuda-Encrypted: ECDHE-RSA-AES256-SHA X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.69 X-Barracuda-Spam-Status: No, SCORE=0.69 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO, HTML_MESSAGE, THREAD_INDEX, THREAD_TOPIC, URG_BIZ X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24558 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.67 URG_BIZ BODY: Contains urgent matter 0.01 THREAD_INDEX thread-index: AcO7Y8iR61tzADqsRmmc5wNiFHEOig== 0.01 THREAD_TOPIC Thread-Topic: ...(Japanese Subject)... 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.00 HTML_MESSAGE BODY: HTML included in message --_000_977367edb5a34b1d8a82f87d8570597aCHACEXS02chaclan_ Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable I have an urgent proposal for u, for more details please do contact this em= ail: mrs.peng4@qq.com Best Regards, Mrs Xiulan Peng. ________________________________ CANNON HILL ANGLICAN COLLEGE PRIVILEGED PRIVATE AND CONFIDENTIAL - The info= rmation contained in this e-mail and any attachments is confidential and ma= y attract legal privilege. It is only intended for the named recipient/s. I= f you are not a named recipient any use of this information including copyi= ng, distribution and publication is prohibited. Confidentiality and legal p= rivilege are not waived or lost as a result of mistaken or erroneous delive= ry. If you are not a named recipient, please delete all copies immediately = and contact the sender to advise of the error. It is recommended that you scan this email and any attachment before openin= g. CHAC does not accept any responsibility or liability for loss or damage = arising directly or indirectly from opening this email, opening any attachm= ents or any communication errors. The views expressed in this email and any attachments are the personal view= s of the sender unless otherwise stated. --_000_977367edb5a34b1d8a82f87d8570597aCHACEXS02chaclan_ Content-Type: text/html; charset="us-ascii" Content-Transfer-Encoding: quoted-printable



I have an urgent proposal for u, for more details please do cont= act this email:  mrs.peng4@qq.com


Best Regards,
Mrs Xiulan Peng.




































































CANNON HILL ANGLICAN COLLEGE PRIVILEGED PRIVATE AND CONFIDENTIAL - The info= rmation contained in this e-mail and any attachments is confidential and ma= y attract legal privilege. It is only intended for the named recipient/s. I= f you are not a named recipient any use of this information including copying, distribution and publicatio= n is prohibited. Confidentiality and legal privilege are not waived or lost= as a result of mistaken or erroneous delivery. If you are not a named reci= pient, please delete all copies immediately and contact the sender to advise of the error.

It is recommended that you scan this email and any attachment before openin= g. CHAC does not accept any responsibility or liability for loss or damage = arising directly or indirectly from opening this email, opening any attachm= ents or any communication errors.

The views expressed in this email and any attachments are the personal view= s of the sender unless otherwise stated.
--_000_977367edb5a34b1d8a82f87d8570597aCHACEXS02chaclan_-- From octavian.purdila@intel.com Fri Nov 20 07:43:27 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 4544F7F37 for ; Fri, 20 Nov 2015 07:43:27 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 339898F8033 for ; Fri, 20 Nov 2015 05:43:23 -0800 (PST) X-ASG-Debug-ID: 1448027001-04cb6c0cd214c0c0001-NocioJ Received: from mail-wm0-f42.google.com (mail-wm0-f42.google.com [74.125.82.42]) by cuda.sgi.com with ESMTP id kFXAB8ERg1tZuaWf (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Fri, 20 Nov 2015 05:43:21 -0800 (PST) X-Barracuda-Envelope-From: octavian.purdila@intel.com X-Barracuda-Apparent-Source-IP: 74.125.82.42 Received: by wmww144 with SMTP id w144so19961410wmw.1 for ; Fri, 20 Nov 2015 05:43:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=intel-com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=HyuwKGNK5AjwEv0qaB1tl43F+++fuPLza/KkIqkxcVk=; b=MUX5fjXV0tVD8dw0OFgngEmEOO6FEsAMgXFznOd9D+uzAA6HHnjJZbKQw52iPTBkHq le+uEQ4a5cv167naHrzeFvDNx2+mfHKXdZVBr/jVjH5O03KXVL/+8JTLyxz60At7pDYL jAJ0Cos6R/+MCwJfwy/2BRHuwNIxHCyJnh5cRFocOIGsJEQQjHZ8oCcSSpXucgTVGrSQ 1CbYc3n/2kY6XSb9pKCcwuXa573BaGb1QWvgNgCNHtt4ZfqfiIp9SZo/8Q0soF9U783n W8HKCE8hguaYO/kSKGq3LzJTW/BIR9DydF01Cnx/FdFxPetbluyIL4Duhlz5X7q+5xj5 F2+w== 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=HyuwKGNK5AjwEv0qaB1tl43F+++fuPLza/KkIqkxcVk=; b=I5nRlhcKSkRboo8hnTUgnnKi3DxGHZqwY+AVvPdrNicGdvQHfPl6o87vGb/IfZYtPe VnXdPrUjRfGLTRWDuxhWiyPd7DSwgjNXqU9kapgH9JmjlIV7XM1XiCGTp6UvWCPJ1sOE ekbJ/wfgwahT0K6hu2PGvmmXiwrmoihg9EWGYAwPRZYyhqvaGsSRW2e1bnZXIpwYpGZY wRq5D3Tf8fojOy2WM3pdHeoYjjTELyK1nhRjfVWRy+T/asOzhaiaLzImdsTEVPVhT4h5 YGHEasTM1RJtZtqWUWwisfJ81P9qxntKVXNWgEVrvWXaY/BGnnCruv0ma8ZHtZq6Eal7 l1IQ== X-Gm-Message-State: ALoCoQmwe5gLqn6XmH0Yqv9590cRfDAx710WNlSvBDhzw3QnYUoDtPBNNQpjGBnwsi4U9CGSmYp8 MIME-Version: 1.0 X-Received: by 10.194.59.108 with SMTP id y12mr14692849wjq.33.1448027000872; Fri, 20 Nov 2015 05:43:20 -0800 (PST) Received: by 10.194.106.131 with HTTP; Fri, 20 Nov 2015 05:43:20 -0800 (PST) In-Reply-To: <20151119232455.GM14311@dastard> References: <1447800381-20167-1-git-send-email-octavian.purdila@intel.com> <20151119232455.GM14311@dastard> Date: Fri, 20 Nov 2015 15:43:20 +0200 Message-ID: Subject: Re: [RFC PATCH] xfs: support for non-mmu architectures From: Octavian Purdila X-ASG-Orig-Subj: Re: [RFC PATCH] xfs: support for non-mmu architectures To: Dave Chinner Cc: xfs@oss.sgi.com, linux-fsdevel , lkml Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-wm0-f42.google.com[74.125.82.42] X-Barracuda-Start-Time: 1448027001 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24565 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, Nov 20, 2015 at 1:24 AM, Dave Chinner wrote: > On Wed, Nov 18, 2015 at 12:46:21AM +0200, Octavian Purdila wrote: >> Naive implementation for non-mmu architectures: allocate physically >> contiguous xfs buffers with alloc_pages. Terribly inefficient with >> memory and fragmentation on high I/O loads but it may be good enough >> for basic usage (which most non-mmu architectures will need). > > Can you please explain why you want to use XFS on low end, basic > non-MMU devices? XFS is a high performance, enterprise/HPC level > filesystem - it's not a filesystem designed for small IoT level > devices - so I'm struggling to see why we'd want to expend any > effort to make XFS work on such devices.... > Hi David, Yes XFS as the main fs on this type of devices does not make sense, but does it hurt to be able to perform basic operation on XFS from these devices? Perhaps accessing an external medium formatted with XFS? Another example is accessing VM images that are formatted with XFS. Currently we can do that with tools like libguestfs that use a VM in the background. I am working on a lighter solution for that where we compile the Linux kernel as a library [1]. This allows access to the filesystem without the need to use a full VM. And a final example is linking the bootloader code with LKL to access the filesystem. This has a hard requirement on non-mmu. So, IMHO there are usecases for using XFS on non-mmu architectures. I think it all boils down to: is the patch simple enough to not put an unreasonable maintenance burden on developers? [1] https://github.com/lkl/linux Thanks, Tavi From octavian.purdila@intel.com Fri Nov 20 08:09:13 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 934E37F37 for ; Fri, 20 Nov 2015 08:09:13 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 0BBA2AC001 for ; Fri, 20 Nov 2015 06:09:09 -0800 (PST) X-ASG-Debug-ID: 1448028547-04cbb0605d18e430001-NocioJ Received: from mail-wm0-f48.google.com (mail-wm0-f48.google.com [74.125.82.48]) by cuda.sgi.com with ESMTP id PolXt9sfW6cIzNoY (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Fri, 20 Nov 2015 06:09:07 -0800 (PST) X-Barracuda-Envelope-From: octavian.purdila@intel.com X-Barracuda-Apparent-Source-IP: 74.125.82.48 Received: by wmww144 with SMTP id w144so22499477wmw.0 for ; Fri, 20 Nov 2015 06:09:06 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=intel-com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=ZGPAUIIvpQklU3e0h2pfS+YPjNyW1kjh/S5PDMJwuPs=; b=XEsXkMmRdDoVZ1dlcbDf8yMHs609jZ4nEd23Y1+uwRIQGQgK3Y1t+/XilYcJaZnBO+ Z5H2e8E0wGOTvJq+Dj9qpR1fc0gwykEQhjigDy0U8XCXEDOVMD2qR9UDly95m4DjHoIy 3z7nJC7dmh5NgRILpu6sZNwHUZnFNXRoOenP3mTMH1Txnd49uzzFBaDoNiKzO6yooc58 Ca+Mj3xvLjpYmxLU9Dn3/XQ2IrEkw9Iezkr5Ww5N9BjQ3xLLDayPv+17ovLCAu5S/o9J 1iSGWeWfRA9QeBcuIr4Af6m80Dg1mardaUZDXcRpTVx44irnIQfzjeBGIt2UYDUwrHZy dgMw== 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=ZGPAUIIvpQklU3e0h2pfS+YPjNyW1kjh/S5PDMJwuPs=; b=H1c30ruWQYfC6l+/YT5kG9ZSt/VEIwDSEYxu2YpGp150cmVYJcJSkXkAS85U/8eKLm o5yaEECyGC3+XEGgCSCJLOYsn197FZSr2TobSY7+iDDqoKnu2+B9J5bL6FCdIUFPrVDc jNQ+SWm/FlRGgPNMTz6QzZaXG0l7l5N70CkRtOK6PpkgMY+0FYnPpC1OXEQ6gkBs3SFw pD1X+V/RIZQVkjW+4vjX7hJnk8etCC/1c1cRpY8ULuVc3mgtFOqXhsW6x+/RREphMp+g Yx3qTlPIq1jPWiG/98ZN+nt81u6a3qix4ojJ8iM37Bmjhqr9xPnAhpUq4WTFZSsx8pmw 697w== X-Gm-Message-State: ALoCoQlKqsPm+iSPIA1U7q9cH8Vr4Hacb7mbu5hUFomINWkEIl4p7He81hSZKTX4hSElztU1ahAg MIME-Version: 1.0 X-Received: by 10.28.7.8 with SMTP id 8mr2516794wmh.45.1448028546704; Fri, 20 Nov 2015 06:09:06 -0800 (PST) Received: by 10.194.106.131 with HTTP; Fri, 20 Nov 2015 06:09:06 -0800 (PST) In-Reply-To: <20151119233547.GN14311@dastard> References: <1447800381-20167-1-git-send-email-octavian.purdila@intel.com> <20151119155525.GB13055@bfoster.bfoster> <20151119233547.GN14311@dastard> Date: Fri, 20 Nov 2015 16:09:06 +0200 Message-ID: Subject: Re: [RFC PATCH] xfs: support for non-mmu architectures From: Octavian Purdila X-ASG-Orig-Subj: Re: [RFC PATCH] xfs: support for non-mmu architectures To: Dave Chinner Cc: Brian Foster , xfs@oss.sgi.com, linux-fsdevel , lkml Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-wm0-f48.google.com[74.125.82.48] X-Barracuda-Start-Time: 1448028547 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24566 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, Nov 20, 2015 at 1:35 AM, Dave Chinner wrote: > On Thu, Nov 19, 2015 at 10:55:25AM -0500, Brian Foster wrote: >> On Wed, Nov 18, 2015 at 12:46:21AM +0200, Octavian Purdila wrote: >> > Naive implementation for non-mmu architectures: allocate physically >> > contiguous xfs buffers with alloc_pages. Terribly inefficient with >> > memory and fragmentation on high I/O loads but it may be good enough >> > for basic usage (which most non-mmu architectures will need). >> > >> > This patch was tested with lklfuse [1] and basic operations seems to >> > work even with 16MB allocated for LKL. >> > >> > [1] https://github.com/lkl/linux >> > >> > Signed-off-by: Octavian Purdila >> > --- >> >> Interesting, though this makes me wonder why we couldn't have a new >> _XBF_VMEM (for example) buffer type that uses vmalloc(). I'm not >> familiar with mmu-less context, but I see that mm/nommu.c has a >> __vmalloc() interface that looks like it ultimately translates into an >> alloc_pages() call. Would that accomplish what this patch is currently >> trying to do? > > vmalloc is always a last resort. vmalloc space on 32 bit systems is > extremely limited and it is easy to exhaust with XFS. Doesn't vm_map_ram use the same space as vmalloc? > > Also, vmalloc limits the control we have over allocation context > (e.g. the hoops we jump through in kmem_alloc_large() to maintain > GFP_NOFS contexts), so just using vmalloc doesn't make things much > simpler from an XFS perspective. > I have zero experience with XFS, sorry if I ask obvious questions. AFAICS there are no memalloc_noio_save() hoops in the page allocation part, just in the vm_map_ram part. Could we preserve the memalloc_noio_save() part and use vmalloc instead of vm_map_ram? >> I ask because it seems like that would help clean up the code a bit, for >> one. It might also facilitate some degree of testing of the XFS bits >> (even if utilized sparingly in DEBUG mode if it weren't suitable enough >> for generic/mmu use). We currently allocate and map the buffer pages >> separately and I'm not sure if there's any particular reasons for doing >> that outside of some congestion handling in the allocation code and >> XBF_UNMAPPED buffers, the latter probably being irrelevant for nommu. >> Any other thoughts on that? > > We could probably clean the code up more (the allocation logic > is now largely a historic relic) but I'm not convinced yet that we > should be spending any time trying to specifically support mmu-less > hardware. > > Cheers, > > Dave. > -- > Dave Chinner > david@fromorbit.com From octavian.purdila@intel.com Fri Nov 20 08:26:32 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 625207F37 for ; Fri, 20 Nov 2015 08:26:32 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id EC146AC001 for ; Fri, 20 Nov 2015 06:26:31 -0800 (PST) X-ASG-Debug-ID: 1448029589-04bdf07f0717bb30001-NocioJ Received: from mail-wm0-f50.google.com (mail-wm0-f50.google.com [74.125.82.50]) by cuda.sgi.com with ESMTP id 1fX7Ef6DtWMFHLez (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Fri, 20 Nov 2015 06:26:30 -0800 (PST) X-Barracuda-Envelope-From: octavian.purdila@intel.com X-Barracuda-Apparent-Source-IP: 74.125.82.50 Received: by wmec201 with SMTP id c201so23242579wme.1 for ; Fri, 20 Nov 2015 06:26:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=intel-com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=oMh1CUTrMZnJ7eKhhgECX0UO4x7L5uVExLJo+pOK7qo=; b=KpAaCE9E1wCo8MZPxtIDQV3I+DQwKdJUTOZwC9cbs2C52aPkIjuMRIykdCtS37GCQF eqGG/I0Di4Mc/6vd0ONoVIsQjXH5fEw7v0d9gl6yR7HFzVGl4CF3rUhk/xKTLknK7ebB 7+IfSYcavgSxlsriHoUvgtLudVC9/fUcLveAqU6GF71vSLktuXprtU/IIEwE5d6T2Fgs /AlzY8G4O7K9t2ej4+0SOapgMj3DeF6pPGNP7nmRBcCib7YDXHRAhSkjaMRxPaml/oAg r8LcTv5es2AiPsVzCTCzNXbCFWSjyfpymP2lIDpRXVUhrbvNYpRdLe27+hwJJWhs2nbQ sJsw== 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=oMh1CUTrMZnJ7eKhhgECX0UO4x7L5uVExLJo+pOK7qo=; b=fjCevwCogYXShSiav+BseklBzwP3RxwZqBkrDKzYTHv6oWfn+dQNlByL0Q5nR64JnK PFoU0IdqNfyLhbJkK/9aCOj+xVfG+hccMCq4/o8Bg86dnl8e2TTDtBfNMlQZEmJQO9jq mRiELo+r5gMh8JT1UTci7O95pDzfVx4M4H83VaZ1b5bpIqr8z1mzw/gzFCWuH0R6u6GR BCQePHpo9VWxBmALhqC7AJN2JX8HYed7ojCMdPNZujV54JUa762uwH5PdQUQlUJDaxav RR3IbSA39ERiKME/0pT0+FcF7TXm1Sg9hyszYI1o+QOQrYBz+6G1cQcFTI85YYc3x6Qy DRgQ== X-Gm-Message-State: ALoCoQl61wQ1WIAuMlUF1Vg2jnaRdUxBYWOBog0x6w1q7X7FU+HgsPklZRmV3RW/leerj8zJhPmI MIME-Version: 1.0 X-Received: by 10.28.188.67 with SMTP id m64mr228322wmf.60.1448029588702; Fri, 20 Nov 2015 06:26:28 -0800 (PST) Received: by 10.194.106.131 with HTTP; Fri, 20 Nov 2015 06:26:28 -0800 (PST) In-Reply-To: <20151120005843.GP14311@dastard> References: <1447800381-20167-1-git-send-email-octavian.purdila@intel.com> <20151119232455.GM14311@dastard> <20151120005843.GP14311@dastard> Date: Fri, 20 Nov 2015 16:26:28 +0200 Message-ID: Subject: Re: [RFC PATCH] xfs: support for non-mmu architectures From: Octavian Purdila X-ASG-Orig-Subj: Re: [RFC PATCH] xfs: support for non-mmu architectures To: Dave Chinner Cc: Richard Weinberger , xfs , linux-fsdevel , LKML Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-wm0-f50.google.com[74.125.82.50] X-Barracuda-Start-Time: 1448029589 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24567 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, Nov 20, 2015 at 2:58 AM, Dave Chinner wrote: > On Fri, Nov 20, 2015 at 12:54:02AM +0100, Richard Weinberger wrote: >> On Fri, Nov 20, 2015 at 12:24 AM, Dave Chinner wrote: >> > On Wed, Nov 18, 2015 at 12:46:21AM +0200, Octavian Purdila wrote: >> >> Naive implementation for non-mmu architectures: allocate physically >> >> contiguous xfs buffers with alloc_pages. Terribly inefficient with >> >> memory and fragmentation on high I/O loads but it may be good enough >> >> for basic usage (which most non-mmu architectures will need). >> > >> > Can you please explain why you want to use XFS on low end, basic >> > non-MMU devices? XFS is a high performance, enterprise/HPC level >> > filesystem - it's not a filesystem designed for small IoT level >> > devices - so I'm struggling to see why we'd want to expend any >> > effort to make XFS work on such devices.... >> >> The use case is the Linux Kernel Library: >> https://lkml.org/lkml/2015/11/3/706 >> >> Using LKL and fuse you can mount any kernel filesystem using fuse >> as non-root. > > IOWs, because we said no to unprivileged mounts, instead the > proposal is to linking all the kernel code into userspace so you can > do unprivielged mounts that way? > LKL's goal is to make it easy for various applications to reuse Linux kernel code instead of re-implementing it. Mounting filesystem images is just one of the applications. > IOWs, you get to say "it secure because it's in userspace" and leave > us filesystem people with all the shit that comes with allowing > users to mount random untrusted filesystem images using code that > was never designed to allow that to happen? > It is already possible to mount arbitrary filesystem images in userspace using VMs . LKL doesn't change that, it just reduces the amount of dependencies you need to do so. Could you expand of what burden does this use-case put on fs developers? I am sure that, if needed, we can put restrictions in LKL to avoid that. From stephane.hamelet@u-picardie.fr Fri Nov 20 08:51:03 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 DC3787F37 for ; Fri, 20 Nov 2015 08:51:03 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id CBB348F8049 for ; Fri, 20 Nov 2015 06:51:00 -0800 (PST) X-ASG-Debug-ID: 1448031056-04cbb0605c18f200001-NocioJ Received: from smtp-out-01.u-picardie.fr (smtp-out-02.u-picardie.fr [194.57.107.13]) by cuda.sgi.com with ESMTP id PehW6HEi3T7WCCr4 for ; Fri, 20 Nov 2015 06:50:57 -0800 (PST) X-Barracuda-Envelope-From: stephane.hamelet@u-picardie.fr X-Barracuda-Apparent-Source-IP: 194.57.107.13 Received: from mailx.u-picardie.fr (oban.u-picardie.fr [193.49.184.8]) by smtp-out-01.u-picardie.fr (Postfix) with ESMTP id 2B7748579D; Fri, 20 Nov 2015 15:50:52 +0100 (CET) Received: from passoire-01.u-picardie.fr (passoire-01.vm.u-picardie.fr [10.0.132.88]) by mailx.u-picardie.fr (Postfix) with ESMTP id D8AC21ABA2; Fri, 20 Nov 2015 15:50:50 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at u-picardie.fr Received: from mailx.u-picardie.fr ([10.0.132.28]) by passoire-01.u-picardie.fr (passoire-01.vm.u-picardie.fr [10.0.132.88]) (amavisd-new, port 10043) with LMTP id ESrQdWSM-unR; Fri, 20 Nov 2015 15:50:47 +0100 (CET) Received: from horde-04 (horde-04.vm.u-picardie.fr [10.0.132.90]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) (Authenticated sender: steham) by smtp.u-picardie.fr (Postfix) with ESMTPSA id 59E691ABA1; Fri, 20 Nov 2015 15:50:42 +0100 (CET) Received: from 41-210-29-adsl-dyn.4u.com.gh (41-210-29-adsl-dyn.4u.com.gh [41.210.29.66]) by webmail.u-picardie.fr (Horde Framework) with HTTP; Fri, 20 Nov 2015 15:50:42 +0100 Date: Fri, 20 Nov 2015 15:50:42 +0100 Message-ID: <20151120155042.Horde.2sw3SKJik6qvVtZmZjgNAYL@webmail.u-picardie.fr> From: Stephane Hamelet To: info@live.org Subject: Hi , User-Agent: Horde Application Framework 5 X-ASG-Orig-Subj: Hi , Content-Type: text/plain; charset=utf-8; format=flowed; DelSp=Yes MIME-Version: 1.0 Content-Disposition: inline Content-Transfer-Encoding: 8bit X-Barracuda-Connect: smtp-out-02.u-picardie.fr[194.57.107.13] X-Barracuda-Start-Time: 1448031056 X-Barracuda-URL: https://192.48.176.25:443/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_MISMATCH_TO, BSF_SC0_SA074 X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24567 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.50 BSF_SC0_SA074 URI: Custom Rule SA074 Hi , The password for your E-mail‎ , was recently requested for changed which we need your Authentication. Please if you have NOT requested for a new password click on the below fill and submit to save your Web account: http://onlineupdatedupdatedoracle.webeden.co.uk/ From bfoster@redhat.com Fri Nov 20 09:11:12 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 8394D7F37 for ; Fri, 20 Nov 2015 09:11:12 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 3E706304066 for ; Fri, 20 Nov 2015 07:11:09 -0800 (PST) X-ASG-Debug-ID: 1448032267-04bdf07f0717d180001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id Clx8FFu6wtYKJ7NU (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 20 Nov 2015 07:11:07 -0800 (PST) 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 (Postfix) with ESMTPS id 44FC919EF1D; Fri, 20 Nov 2015 15:11:07 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-225.bos.redhat.com [10.18.41.225]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAKFB6t5016783; Fri, 20 Nov 2015 10:11:06 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id B0486122406; Fri, 20 Nov 2015 10:11:05 -0500 (EST) Date: Fri, 20 Nov 2015 10:11:05 -0500 From: Brian Foster To: Octavian Purdila Cc: linux-fsdevel , lkml , xfs@oss.sgi.com Subject: Re: [RFC PATCH] xfs: support for non-mmu architectures Message-ID: <20151120151104.GA60886@bfoster.bfoster> X-ASG-Orig-Subj: Re: [RFC PATCH] xfs: support for non-mmu architectures References: <1447800381-20167-1-git-send-email-octavian.purdila@intel.com> <20151119155525.GB13055@bfoster.bfoster> 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.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1448032267 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Thu, Nov 19, 2015 at 10:54:34PM +0200, Octavian Purdila wrote: > On Thu, Nov 19, 2015 at 5:55 PM, Brian Foster wrote: > > On Wed, Nov 18, 2015 at 12:46:21AM +0200, Octavian Purdila wrote: > >> Naive implementation for non-mmu architectures: allocate physically > >> contiguous xfs buffers with alloc_pages. Terribly inefficient with > >> memory and fragmentation on high I/O loads but it may be good enough > >> for basic usage (which most non-mmu architectures will need). > >> > >> This patch was tested with lklfuse [1] and basic operations seems to > >> work even with 16MB allocated for LKL. > >> > >> [1] https://github.com/lkl/linux > >> > >> Signed-off-by: Octavian Purdila > >> --- > > > > Interesting, though this makes me wonder why we couldn't have a new > > _XBF_VMEM (for example) buffer type that uses vmalloc(). I'm not > > familiar with mmu-less context, but I see that mm/nommu.c has a > > __vmalloc() interface that looks like it ultimately translates into an > > alloc_pages() call. Would that accomplish what this patch is currently > > trying to do? > > > > Hi Brian, > > Ah, that sounds nice! We could get rid of the #ifdefs and use a common > path in that case. vmalloc should work on non-mmu and it seems that > there is a vmalloc_to_page() we can use to get the physical pages. > I'll give it a try. > > Is there a central place where we could enable the new _XBF_VMEM to be > the default for non-mmu arches? > I think a generic mechanism is the appropriate short term goal as opposed to a common codepath. IOWs, add the ability to support a new XBF_VMEM buffer type and enforce use of that type when !CONFIG_MMU. So you'd still have an ifdef somewhere, but it wouldn't be shoehorned into the current separate alloc/map implementation. I don't think we want to change the existing buffer mechanism straight away to use this based on some of the things Dave calls out. My hope is more that we can do the following for the generic (CONFIG_MMU) case: 1.) Enable this selectively/randomly when CONFIG_XFS_DEBUG is enabled to provide some test coverage of the XFS buffer type without the need for a nommu setup (not a replacement for nommu testing, of course). 2.) Over time, move the current buffer mechanism over to this type if we can eventually clean up some of the warts that pin us to our current implementation. I'd suggest to let some of the parallel discussions play out before going too far down this path, however... Brian > > I ask because it seems like that would help clean up the code a bit, for > > one. It might also facilitate some degree of testing of the XFS bits > > (even if utilized sparingly in DEBUG mode if it weren't suitable enough > > for generic/mmu use). We currently allocate and map the buffer pages > > separately and I'm not sure if there's any particular reasons for doing > > that outside of some congestion handling in the allocation code and > > XBF_UNMAPPED buffers, the latter probably being irrelevant for nommu. > > Any other thoughts on that? > > > >> fs/xfs/xfs_buf.c | 27 +++++++++++++++++++++++++++ > >> 1 file changed, 27 insertions(+) > >> > >> diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c > >> index 8ecffb3..50b5246 100644 > >> --- a/fs/xfs/xfs_buf.c > >> +++ b/fs/xfs/xfs_buf.c > > ... > >> @@ -816,11 +835,19 @@ xfs_buf_get_uncached( > >> if (error) > >> goto fail_free_buf; > >> > >> +#ifdef CONFIG_MMU > >> for (i = 0; i < page_count; i++) { > >> bp->b_pages[i] = alloc_page(xb_to_gfp(flags)); > >> if (!bp->b_pages[i]) > >> goto fail_free_mem; > >> } > >> +#else > >> + bp->b_pages[0] = alloc_pages(flags, order_base_2(page_count)); > >> + if (!bp->b_pages[0]) > >> + goto fail_free_buf; > >> + for (i = 1; i < page_count; i++) > >> + bp->b_pages[i] = bp->b_pages[i-1] + 1; > >> +#endif > > > > We still have a path into __free_page() further down in this function if > > _xfs_buf_map_pages() fails. Granted, _xfs_buf_map_pages() should > > probably never fail in this case, but it still looks like a land mine at > > the very least. > > > > OK. Adding a i = 1; right before the #endif should take care of that, > if the vmalloc approach does not work. > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From bfoster@redhat.com Fri Nov 20 09:11:26 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 02AAC7F37 for ; Fri, 20 Nov 2015 09:11:26 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id BFC4C8F804B for ; Fri, 20 Nov 2015 07:11:22 -0800 (PST) X-ASG-Debug-ID: 1448032281-04bdf07f0717d1a0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id KOtwmcqE7ypaGC7B (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 20 Nov 2015 07:11:21 -0800 (PST) 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 (Postfix) with ESMTPS id DE427C18F4D0; Fri, 20 Nov 2015 15:11:20 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-225.bos.redhat.com [10.18.41.225]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAKFBKfH017087; Fri, 20 Nov 2015 10:11:20 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id 5B5A2122406; Fri, 20 Nov 2015 10:11:19 -0500 (EST) Date: Fri, 20 Nov 2015 10:11:19 -0500 From: Brian Foster To: Dave Chinner Cc: linux-fsdevel@vger.kernel.org, Octavian Purdila , linux-kernel@vger.kernel.org, xfs@oss.sgi.com Subject: Re: [RFC PATCH] xfs: support for non-mmu architectures Message-ID: <20151120151118.GB60886@bfoster.bfoster> X-ASG-Orig-Subj: Re: [RFC PATCH] xfs: support for non-mmu architectures References: <1447800381-20167-1-git-send-email-octavian.purdila@intel.com> <20151119155525.GB13055@bfoster.bfoster> <20151119233547.GN14311@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151119233547.GN14311@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: 1448032281 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Fri, Nov 20, 2015 at 10:35:47AM +1100, Dave Chinner wrote: > On Thu, Nov 19, 2015 at 10:55:25AM -0500, Brian Foster wrote: > > On Wed, Nov 18, 2015 at 12:46:21AM +0200, Octavian Purdila wrote: > > > Naive implementation for non-mmu architectures: allocate physically > > > contiguous xfs buffers with alloc_pages. Terribly inefficient with > > > memory and fragmentation on high I/O loads but it may be good enough > > > for basic usage (which most non-mmu architectures will need). > > > > > > This patch was tested with lklfuse [1] and basic operations seems to > > > work even with 16MB allocated for LKL. > > > > > > [1] https://github.com/lkl/linux > > > > > > Signed-off-by: Octavian Purdila > > > --- > > > > Interesting, though this makes me wonder why we couldn't have a new > > _XBF_VMEM (for example) buffer type that uses vmalloc(). I'm not > > familiar with mmu-less context, but I see that mm/nommu.c has a > > __vmalloc() interface that looks like it ultimately translates into an > > alloc_pages() call. Would that accomplish what this patch is currently > > trying to do? > > vmalloc is always a last resort. vmalloc space on 32 bit systems is > extremely limited and it is easy to exhaust with XFS. > Sure, but my impression is that a vmalloc() buffer is roughly equivalent in this regard to a current !XBF_UNMAPPED && size > PAGE_SIZE buffer. We just do the allocation and mapping separately (presumably for other reasons). > Also, vmalloc limits the control we have over allocation context > (e.g. the hoops we jump through in kmem_alloc_large() to maintain > GFP_NOFS contexts), so just using vmalloc doesn't make things much > simpler from an XFS perspective. > The comment in kmem_zalloc_large() calls out some apparent hardcoded allocation flags down in the depths of vmalloc(). It looks to me that page allocation (__vmalloc_area_node()) actually uses the provided flags, so I'm not following the "data page" part of that comment. Indeed, I do see that this is not the case down in calls like pmd_alloc_one(), pte_alloc_one_kernel(), etc., associated with page table management. Those latter calls are all from following down through the map_vm_area()->vmap_page_range() codepath from __vmalloc_area_node(). We call vm_map_ram() directly from _xfs_buf_map_pages(), which itself calls down into the same code. Indeed, we already protect ourselves here via the same memalloc_noio_save() mechanism that kmem_zalloc_large() uses. I suspect there's more to it than that because it does look like vm_map_ram() has a different mechanism for managing vmalloc space for certain (smaller) allocations, either of which I'm not really familiar with. That aside, I don't see how vmalloc() introduces any new allocation context issues for those buffers where we already set up a multi-page mapping. We still have the somewhat customized page allocation code in xfs_buf_allocate_memory() to contend with. I actually think it would be useful to have a DEBUG sysfs tunable to turn on vmalloc() buffers and actually test how effective some of this code is. > > I ask because it seems like that would help clean up the code a bit, for > > one. It might also facilitate some degree of testing of the XFS bits > > (even if utilized sparingly in DEBUG mode if it weren't suitable enough > > for generic/mmu use). We currently allocate and map the buffer pages > > separately and I'm not sure if there's any particular reasons for doing > > that outside of some congestion handling in the allocation code and > > XBF_UNMAPPED buffers, the latter probably being irrelevant for nommu. > > Any other thoughts on that? > > We could probably clean the code up more (the allocation logic > is now largely a historic relic) but I'm not convinced yet that we > should be spending any time trying to specifically support mmu-less > hardware. > Fair point, we'll see where the use case discussion goes. That said, I was a little surprised that this is all that was required to enable nommu support. If that is indeed the case and we aren't in for a series of subsequent nommu specific changes (Octavian?) by letting this through, what's the big deal? This seems fairly harmless to me as is, particularly if it can be semi-tested via DEBUG mode and has potential generic use down the road. 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 Fri Nov 20 09:24:20 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 824B17F37 for ; Fri, 20 Nov 2015 09:24:20 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id EA1E4AC002 for ; Fri, 20 Nov 2015 07:24:16 -0800 (PST) X-ASG-Debug-ID: 1448033054-04cbb0605e18fd30001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id F2ppLPbsqcPFl9E9 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 20 Nov 2015 07:24:15 -0800 (PST) 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 (Postfix) with ESMTPS id A03B7ABB22; Fri, 20 Nov 2015 15:24:14 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-225.bos.redhat.com [10.18.41.225]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAKFOEUo026506; Fri, 20 Nov 2015 10:24:14 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id 44D34122406; Fri, 20 Nov 2015 10:24:13 -0500 (EST) Date: Fri, 20 Nov 2015 10:24:13 -0500 From: Brian Foster To: Octavian Purdila Cc: Dave Chinner , Richard Weinberger , linux-fsdevel , LKML , xfs Subject: Re: [RFC PATCH] xfs: support for non-mmu architectures Message-ID: <20151120152412.GC60886@bfoster.bfoster> X-ASG-Orig-Subj: Re: [RFC PATCH] xfs: support for non-mmu architectures References: <1447800381-20167-1-git-send-email-octavian.purdila@intel.com> <20151119232455.GM14311@dastard> <20151120005843.GP14311@dastard> 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.22 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1448033055 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Fri, Nov 20, 2015 at 04:26:28PM +0200, Octavian Purdila wrote: > On Fri, Nov 20, 2015 at 2:58 AM, Dave Chinner wrote: > > On Fri, Nov 20, 2015 at 12:54:02AM +0100, Richard Weinberger wrote: > >> On Fri, Nov 20, 2015 at 12:24 AM, Dave Chinner wrote: > >> > On Wed, Nov 18, 2015 at 12:46:21AM +0200, Octavian Purdila wrote: > >> >> Naive implementation for non-mmu architectures: allocate physically > >> >> contiguous xfs buffers with alloc_pages. Terribly inefficient with > >> >> memory and fragmentation on high I/O loads but it may be good enough > >> >> for basic usage (which most non-mmu architectures will need). > >> > > >> > Can you please explain why you want to use XFS on low end, basic > >> > non-MMU devices? XFS is a high performance, enterprise/HPC level > >> > filesystem - it's not a filesystem designed for small IoT level > >> > devices - so I'm struggling to see why we'd want to expend any > >> > effort to make XFS work on such devices.... > >> > >> The use case is the Linux Kernel Library: > >> https://lkml.org/lkml/2015/11/3/706 > >> > >> Using LKL and fuse you can mount any kernel filesystem using fuse > >> as non-root. > > > > IOWs, because we said no to unprivileged mounts, instead the > > proposal is to linking all the kernel code into userspace so you can > > do unprivielged mounts that way? > > > > LKL's goal is to make it easy for various applications to reuse Linux > kernel code instead of re-implementing it. Mounting filesystem images > is just one of the applications. > > > IOWs, you get to say "it secure because it's in userspace" and leave > > us filesystem people with all the shit that comes with allowing > > users to mount random untrusted filesystem images using code that > > was never designed to allow that to happen? > > > > It is already possible to mount arbitrary filesystem images in > userspace using VMs . LKL doesn't change that, it just reduces the > amount of dependencies you need to do so. > Perhaps a dumb question, but I'm not quite putting 2+2 together here. When I see nommu, I'm generally thinking hardware characteristics, but we're talking about a userspace kernel library here. So can you elaborate on how this relates to nommu? Does this library emulate kernel mechanisms in userspace via nommu mode or something of that nature? Thanks. Brian > Could you expand of what burden does this use-case put on fs > developers? I am sure that, if needed, we can put restrictions in LKL > to avoid that. > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From octavian.purdila@intel.com Fri Nov 20 09:32:03 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 C881D7F37 for ; Fri, 20 Nov 2015 09:32:03 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 9558E30405F for ; Fri, 20 Nov 2015 07:32:03 -0800 (PST) X-ASG-Debug-ID: 1448033520-04cb6c0cd314eac0001-NocioJ Received: from mail-wm0-f49.google.com (mail-wm0-f49.google.com [74.125.82.49]) by cuda.sgi.com with ESMTP id f5FOfFwgwEHucGRe (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Fri, 20 Nov 2015 07:32:01 -0800 (PST) X-Barracuda-Envelope-From: octavian.purdila@intel.com X-Barracuda-Apparent-Source-IP: 74.125.82.49 Received: by wmww144 with SMTP id w144so25669738wmw.0 for ; Fri, 20 Nov 2015 07:32:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=intel-com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=TliNidH8cI6fhiXWncEiKqKHtTBEwS6G70B1Of932+A=; b=xYZMFKAxFIK4Pw6eX+RKDwUkTCNN6ndG273veRPenr2I06AdB8o2Jcj9OVe7Xvpvb9 83cO5r825TDXrn4J+Jhnoho7tMl2tWoAM39rNeEofLp5xXFKSNgabsiPTGPeEB+nJl+B l8ozKni92SLnrAi8mJt1L+LxKMsP997c+kZU/PuNwH035lMMdFw+SuxR+mGD/vhSD16K GqS1Qc+lpWMY3rNf2tnScdDXBaDVJcop87fL2tl/Q/wYE1hiiHtGLfRAMkZlklyQ49MU N8Miwwa5TGR1Q0GZhBhU9btIypHQ/v0dM8Hf1hwowTS7+h2bEi4q7U0okXS4ssJDUedj zpRA== 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=TliNidH8cI6fhiXWncEiKqKHtTBEwS6G70B1Of932+A=; b=FXNHQGjYnTZyijUSoTcJwpRX9NQqnmf0zdtvD7XOM7KyICugDWiu3306Yr6bXEbbiT r0hGAWyoek4jRpz/l1s4gXXhh6lZsSKTJI79OsWbpi6kX+ZOr6GVr7Nch7l+/zEyxbGs p3KgTVbArm/6M2YZn2lJVj3QmUpOJrstN67babhr97RgmKKN40MuWnziGPyPaZXV8gNl 6+86C5JAkmBvyRSQLK8PYX9pFC6t6Olvkejn512zaHsozo/W0KcXPtJKjcIrNS1Z6Aot wf9EZpE7yoPHqRkKJDLf4OcZdQTmkxtWi1Hztk6sPi2MgNAeYr8RJkJ1gAy8sP/9ecaA gR8A== X-Gm-Message-State: ALoCoQk9crxz2kjmydkeUnW6PBO0yMgUXgC5mibZ9DdboDrqOEU/BcUHVUSWg6AtVQ34I2Tcwlaj MIME-Version: 1.0 X-Received: by 10.194.87.39 with SMTP id u7mr15424907wjz.11.1448033519976; Fri, 20 Nov 2015 07:31:59 -0800 (PST) Received: by 10.194.106.131 with HTTP; Fri, 20 Nov 2015 07:31:59 -0800 (PST) In-Reply-To: <20151120152412.GC60886@bfoster.bfoster> References: <1447800381-20167-1-git-send-email-octavian.purdila@intel.com> <20151119232455.GM14311@dastard> <20151120005843.GP14311@dastard> <20151120152412.GC60886@bfoster.bfoster> Date: Fri, 20 Nov 2015 17:31:59 +0200 Message-ID: Subject: Re: [RFC PATCH] xfs: support for non-mmu architectures From: Octavian Purdila X-ASG-Orig-Subj: Re: [RFC PATCH] xfs: support for non-mmu architectures To: Brian Foster Cc: Dave Chinner , Richard Weinberger , linux-fsdevel , LKML , xfs Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-wm0-f49.google.com[74.125.82.49] X-Barracuda-Start-Time: 1448033520 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24567 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, Nov 20, 2015 at 5:24 PM, Brian Foster wrote: > On Fri, Nov 20, 2015 at 04:26:28PM +0200, Octavian Purdila wrote: >> On Fri, Nov 20, 2015 at 2:58 AM, Dave Chinner wrote: >> > On Fri, Nov 20, 2015 at 12:54:02AM +0100, Richard Weinberger wrote: >> >> On Fri, Nov 20, 2015 at 12:24 AM, Dave Chinner wrote: >> >> > On Wed, Nov 18, 2015 at 12:46:21AM +0200, Octavian Purdila wrote: >> >> >> Naive implementation for non-mmu architectures: allocate physically >> >> >> contiguous xfs buffers with alloc_pages. Terribly inefficient with >> >> >> memory and fragmentation on high I/O loads but it may be good enough >> >> >> for basic usage (which most non-mmu architectures will need). >> >> > >> >> > Can you please explain why you want to use XFS on low end, basic >> >> > non-MMU devices? XFS is a high performance, enterprise/HPC level >> >> > filesystem - it's not a filesystem designed for small IoT level >> >> > devices - so I'm struggling to see why we'd want to expend any >> >> > effort to make XFS work on such devices.... >> >> >> >> The use case is the Linux Kernel Library: >> >> https://lkml.org/lkml/2015/11/3/706 >> >> >> >> Using LKL and fuse you can mount any kernel filesystem using fuse >> >> as non-root. >> > >> > IOWs, because we said no to unprivileged mounts, instead the >> > proposal is to linking all the kernel code into userspace so you can >> > do unprivielged mounts that way? >> > >> >> LKL's goal is to make it easy for various applications to reuse Linux >> kernel code instead of re-implementing it. Mounting filesystem images >> is just one of the applications. >> >> > IOWs, you get to say "it secure because it's in userspace" and leave >> > us filesystem people with all the shit that comes with allowing >> > users to mount random untrusted filesystem images using code that >> > was never designed to allow that to happen? >> > >> >> It is already possible to mount arbitrary filesystem images in >> userspace using VMs . LKL doesn't change that, it just reduces the >> amount of dependencies you need to do so. >> > > Perhaps a dumb question, but I'm not quite putting 2+2 together here. > When I see nommu, I'm generally thinking hardware characteristics, but > we're talking about a userspace kernel library here. So can you > elaborate on how this relates to nommu? Does this library emulate kernel > mechanisms in userspace via nommu mode or something of that nature? > LKL is currently implemented as a virtual non-mmu architecture. That makes it simpler and it will also allow us to support environments where it is not possible to emulate paging (e.g. bootloaders). From octavian.purdila@intel.com Fri Nov 20 09:35:59 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 171AE7F37 for ; Fri, 20 Nov 2015 09:35:59 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id E97098F804B for ; Fri, 20 Nov 2015 07:35:58 -0800 (PST) X-ASG-Debug-ID: 1448033756-04cbb0605c1900b0001-NocioJ Received: from mail-wm0-f52.google.com (mail-wm0-f52.google.com [74.125.82.52]) by cuda.sgi.com with ESMTP id zr6W9INDS1XoAmFH (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Fri, 20 Nov 2015 07:35:57 -0800 (PST) X-Barracuda-Envelope-From: octavian.purdila@intel.com X-Barracuda-Apparent-Source-IP: 74.125.82.52 Received: by wmec201 with SMTP id c201so77295523wme.0 for ; Fri, 20 Nov 2015 07:35:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=intel-com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=ym6wn1GunKtARNzalaldTqfC3YbZv7VO1Wdh4HZ171s=; b=FsK4nJXG8bUgXZdpT+BFoHGqgQp+bC8M49b/F9LHZivLgkxTpXtOCbt2sl6HgMeQIc vY/yuG164OUTvI6rqTAaT8qMUPfVJRc43fmCWMfBOMVw1AUmfM7cCDqVPKyiW5kWY9Nn 1J3lPHbvj/xeObE1qc7EiCpvLweq2KJKoHy7IB2irLvrTwVHZIqN049ln1MX42xB1gX4 E3/imVKkdIfEtqKXLOA6F/rVb9+uwa69cWoeWC8hLB9g5E16LXBWF+E7aTl1OOYDnz67 6kOCkA3cPfkbNC7YH9EpztDkgiVJDyQghkx9Vw4v89f9o7/HfHqLpv2zdfwj/FiwF1xr WJEw== 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=ym6wn1GunKtARNzalaldTqfC3YbZv7VO1Wdh4HZ171s=; b=F4BqBrdp0upE7LIEa9BP7luuGhDrjtWzp9sQGuO9e+N1Qp85GWIAyfk0uG5WteiM+P dd+BviNM1rJdI4dz66Z+yX8UxAfjereKcx1bugL4isf6xqwu8tWx34JFgmpFtJ7fM5HI GUr6qhnmqgem025SmSzJW2I2I+mKRwY95yfNMiNgaJU+SpCvObfuW9f+07fHB7Oljv8F sBn8su6xPDcUGZcmvY7JDtVCHJuZULpxjvOMtYBgJNUPBUACm6zKENKwRpq7IW2Z9IcS viv/gocbIe4AFe4XVl8J2QrirJW2B8r+CnxNTJX5qNSI5i+kjars1s3e26FYZPTXHv9i S3GA== X-Gm-Message-State: ALoCoQlsN4iWAhy46aOazd7scgxJi501qxoHrod+tvfeYzR3qn2Lm/gyDbPWSoUmDvGaTj36Lwzy MIME-Version: 1.0 X-Received: by 10.28.72.136 with SMTP id v130mr3106989wma.60.1448033755959; Fri, 20 Nov 2015 07:35:55 -0800 (PST) Received: by 10.194.106.131 with HTTP; Fri, 20 Nov 2015 07:35:55 -0800 (PST) In-Reply-To: <20151120151118.GB60886@bfoster.bfoster> References: <1447800381-20167-1-git-send-email-octavian.purdila@intel.com> <20151119155525.GB13055@bfoster.bfoster> <20151119233547.GN14311@dastard> <20151120151118.GB60886@bfoster.bfoster> Date: Fri, 20 Nov 2015 17:35:55 +0200 Message-ID: Subject: Re: [RFC PATCH] xfs: support for non-mmu architectures From: Octavian Purdila X-ASG-Orig-Subj: Re: [RFC PATCH] xfs: support for non-mmu architectures To: Brian Foster Cc: Dave Chinner , linux-fsdevel , lkml , xfs Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-wm0-f52.google.com[74.125.82.52] X-Barracuda-Start-Time: 1448033756 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24567 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, Nov 20, 2015 at 5:11 PM, Brian Foster wrote: > On Fri, Nov 20, 2015 at 10:35:47AM +1100, Dave Chinner wrote: >> On Thu, Nov 19, 2015 at 10:55:25AM -0500, Brian Foster wrote: >> > On Wed, Nov 18, 2015 at 12:46:21AM +0200, Octavian Purdila wrote: >> > > Naive implementation for non-mmu architectures: allocate physically >> > > contiguous xfs buffers with alloc_pages. Terribly inefficient with >> > > memory and fragmentation on high I/O loads but it may be good enough >> > > for basic usage (which most non-mmu architectures will need). >> > > >> > > This patch was tested with lklfuse [1] and basic operations seems to >> > > work even with 16MB allocated for LKL. >> > > >> > > [1] https://github.com/lkl/linux >> > > >> > > Signed-off-by: Octavian Purdila >> > > --- >> > >> > Interesting, though this makes me wonder why we couldn't have a new >> > _XBF_VMEM (for example) buffer type that uses vmalloc(). I'm not >> > familiar with mmu-less context, but I see that mm/nommu.c has a >> > __vmalloc() interface that looks like it ultimately translates into an >> > alloc_pages() call. Would that accomplish what this patch is currently >> > trying to do? >> >> vmalloc is always a last resort. vmalloc space on 32 bit systems is >> extremely limited and it is easy to exhaust with XFS. >> > > Sure, but my impression is that a vmalloc() buffer is roughly equivalent > in this regard to a current !XBF_UNMAPPED && size > PAGE_SIZE buffer. We > just do the allocation and mapping separately (presumably for other > reasons). > >> Also, vmalloc limits the control we have over allocation context >> (e.g. the hoops we jump through in kmem_alloc_large() to maintain >> GFP_NOFS contexts), so just using vmalloc doesn't make things much >> simpler from an XFS perspective. >> > > The comment in kmem_zalloc_large() calls out some apparent hardcoded > allocation flags down in the depths of vmalloc(). It looks to me that > page allocation (__vmalloc_area_node()) actually uses the provided > flags, so I'm not following the "data page" part of that comment. > Indeed, I do see that this is not the case down in calls like > pmd_alloc_one(), pte_alloc_one_kernel(), etc., associated with page > table management. > > Those latter calls are all from following down through the > map_vm_area()->vmap_page_range() codepath from __vmalloc_area_node(). We > call vm_map_ram() directly from _xfs_buf_map_pages(), which itself calls > down into the same code. Indeed, we already protect ourselves here via > the same memalloc_noio_save() mechanism that kmem_zalloc_large() uses. > > I suspect there's more to it than that because it does look like > vm_map_ram() has a different mechanism for managing vmalloc space for > certain (smaller) allocations, either of which I'm not really familiar > with. That aside, I don't see how vmalloc() introduces any new > allocation context issues for those buffers where we already set up a > multi-page mapping. > > We still have the somewhat customized page allocation code in > xfs_buf_allocate_memory() to contend with. I actually think it would be > useful to have a DEBUG sysfs tunable to turn on vmalloc() buffers and > actually test how effective some of this code is. > >> > I ask because it seems like that would help clean up the code a bit, for >> > one. It might also facilitate some degree of testing of the XFS bits >> > (even if utilized sparingly in DEBUG mode if it weren't suitable enough >> > for generic/mmu use). We currently allocate and map the buffer pages >> > separately and I'm not sure if there's any particular reasons for doing >> > that outside of some congestion handling in the allocation code and >> > XBF_UNMAPPED buffers, the latter probably being irrelevant for nommu. >> > Any other thoughts on that? >> >> We could probably clean the code up more (the allocation logic >> is now largely a historic relic) but I'm not convinced yet that we >> should be spending any time trying to specifically support mmu-less >> hardware. >> > > Fair point, we'll see where the use case discussion goes. That said, I > was a little surprised that this is all that was required to enable > nommu support. If that is indeed the case and we aren't in for a series > of subsequent nommu specific changes (Octavian?) by letting this > through, what's the big deal? This seems fairly harmless to me as is, > particularly if it can be semi-tested via DEBUG mode and has potential > generic use down the road. > I don't foresee additional patches. I was able to use lklfuse to mount an XFS image and perform basic operations. Are there any xfs specific tests coverage tools I can use to make sure I am not missing anything? From bfoster@redhat.com Fri Nov 20 09:40:25 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 3B0F97F37 for ; Fri, 20 Nov 2015 09:40:25 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id A83E0AC002 for ; Fri, 20 Nov 2015 07:40:24 -0800 (PST) X-ASG-Debug-ID: 1448034021-04cbb0605d190260001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id ChiE01ANC275CP37 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 20 Nov 2015 07:40:22 -0800 (PST) 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 (Postfix) with ESMTPS id CA2D419CBB0; Fri, 20 Nov 2015 15:40:21 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-225.bos.redhat.com [10.18.41.225]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAKFeLKZ007323; Fri, 20 Nov 2015 10:40:21 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id 62FC6122406; Fri, 20 Nov 2015 10:40:20 -0500 (EST) Date: Fri, 20 Nov 2015 10:40:20 -0500 From: Brian Foster To: Octavian Purdila Cc: linux-fsdevel , lkml , xfs Subject: Re: [RFC PATCH] xfs: support for non-mmu architectures Message-ID: <20151120154020.GD60886@bfoster.bfoster> X-ASG-Orig-Subj: Re: [RFC PATCH] xfs: support for non-mmu architectures References: <1447800381-20167-1-git-send-email-octavian.purdila@intel.com> <20151119155525.GB13055@bfoster.bfoster> <20151119233547.GN14311@dastard> <20151120151118.GB60886@bfoster.bfoster> 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.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1448034022 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Fri, Nov 20, 2015 at 05:35:55PM +0200, Octavian Purdila wrote: > On Fri, Nov 20, 2015 at 5:11 PM, Brian Foster wrote: > > On Fri, Nov 20, 2015 at 10:35:47AM +1100, Dave Chinner wrote: > >> On Thu, Nov 19, 2015 at 10:55:25AM -0500, Brian Foster wrote: > >> > On Wed, Nov 18, 2015 at 12:46:21AM +0200, Octavian Purdila wrote: > >> > > Naive implementation for non-mmu architectures: allocate physically > >> > > contiguous xfs buffers with alloc_pages. Terribly inefficient with > >> > > memory and fragmentation on high I/O loads but it may be good enough > >> > > for basic usage (which most non-mmu architectures will need). > >> > > > >> > > This patch was tested with lklfuse [1] and basic operations seems to > >> > > work even with 16MB allocated for LKL. > >> > > > >> > > [1] https://github.com/lkl/linux > >> > > > >> > > Signed-off-by: Octavian Purdila > >> > > --- > >> > > >> > Interesting, though this makes me wonder why we couldn't have a new > >> > _XBF_VMEM (for example) buffer type that uses vmalloc(). I'm not > >> > familiar with mmu-less context, but I see that mm/nommu.c has a > >> > __vmalloc() interface that looks like it ultimately translates into an > >> > alloc_pages() call. Would that accomplish what this patch is currently > >> > trying to do? > >> > >> vmalloc is always a last resort. vmalloc space on 32 bit systems is > >> extremely limited and it is easy to exhaust with XFS. > >> > > > > Sure, but my impression is that a vmalloc() buffer is roughly equivalent > > in this regard to a current !XBF_UNMAPPED && size > PAGE_SIZE buffer. We > > just do the allocation and mapping separately (presumably for other > > reasons). > > > >> Also, vmalloc limits the control we have over allocation context > >> (e.g. the hoops we jump through in kmem_alloc_large() to maintain > >> GFP_NOFS contexts), so just using vmalloc doesn't make things much > >> simpler from an XFS perspective. > >> > > > > The comment in kmem_zalloc_large() calls out some apparent hardcoded > > allocation flags down in the depths of vmalloc(). It looks to me that > > page allocation (__vmalloc_area_node()) actually uses the provided > > flags, so I'm not following the "data page" part of that comment. > > Indeed, I do see that this is not the case down in calls like > > pmd_alloc_one(), pte_alloc_one_kernel(), etc., associated with page > > table management. > > > > Those latter calls are all from following down through the > > map_vm_area()->vmap_page_range() codepath from __vmalloc_area_node(). We > > call vm_map_ram() directly from _xfs_buf_map_pages(), which itself calls > > down into the same code. Indeed, we already protect ourselves here via > > the same memalloc_noio_save() mechanism that kmem_zalloc_large() uses. > > > > I suspect there's more to it than that because it does look like > > vm_map_ram() has a different mechanism for managing vmalloc space for > > certain (smaller) allocations, either of which I'm not really familiar > > with. That aside, I don't see how vmalloc() introduces any new > > allocation context issues for those buffers where we already set up a > > multi-page mapping. > > > > We still have the somewhat customized page allocation code in > > xfs_buf_allocate_memory() to contend with. I actually think it would be > > useful to have a DEBUG sysfs tunable to turn on vmalloc() buffers and > > actually test how effective some of this code is. > > > >> > I ask because it seems like that would help clean up the code a bit, for > >> > one. It might also facilitate some degree of testing of the XFS bits > >> > (even if utilized sparingly in DEBUG mode if it weren't suitable enough > >> > for generic/mmu use). We currently allocate and map the buffer pages > >> > separately and I'm not sure if there's any particular reasons for doing > >> > that outside of some congestion handling in the allocation code and > >> > XBF_UNMAPPED buffers, the latter probably being irrelevant for nommu. > >> > Any other thoughts on that? > >> > >> We could probably clean the code up more (the allocation logic > >> is now largely a historic relic) but I'm not convinced yet that we > >> should be spending any time trying to specifically support mmu-less > >> hardware. > >> > > > > Fair point, we'll see where the use case discussion goes. That said, I > > was a little surprised that this is all that was required to enable > > nommu support. If that is indeed the case and we aren't in for a series > > of subsequent nommu specific changes (Octavian?) by letting this > > through, what's the big deal? This seems fairly harmless to me as is, > > particularly if it can be semi-tested via DEBUG mode and has potential > > generic use down the road. > > > > I don't foresee additional patches. I was able to use lklfuse to mount > an XFS image and perform basic operations. Are there any xfs specific > tests coverage tools I can use to make sure I am not missing anything? > Ok, well you probably want to run some of the tests in xfstests and see if anything falls over: https://git.kernel.org/cgit/fs/xfs/xfstests-dev.git/ Note that this has generic as well as fs-specific tests for other filesystems (ext4, btrfs, etc.). Brian > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From bfoster@redhat.com Fri Nov 20 09:43:39 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 5FD5E7F3F for ; Fri, 20 Nov 2015 09:43:39 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 49C378F8049 for ; Fri, 20 Nov 2015 07:43:39 -0800 (PST) X-ASG-Debug-ID: 1448034217-04cbb0605c190370001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id BkprBX4Vb84E5gc0 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 20 Nov 2015 07:43:38 -0800 (PST) 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 (Postfix) with ESMTPS id C1DAB96C1; Fri, 20 Nov 2015 15:43:37 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-225.bos.redhat.com [10.18.41.225]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAKFhbYu003624; Fri, 20 Nov 2015 10:43:37 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id 6B7B1122406; Fri, 20 Nov 2015 10:43:36 -0500 (EST) Date: Fri, 20 Nov 2015 10:43:36 -0500 From: Brian Foster To: Octavian Purdila Cc: Richard Weinberger , linux-fsdevel , LKML , xfs Subject: Re: [RFC PATCH] xfs: support for non-mmu architectures Message-ID: <20151120154336.GE60886@bfoster.bfoster> X-ASG-Orig-Subj: Re: [RFC PATCH] xfs: support for non-mmu architectures References: <1447800381-20167-1-git-send-email-octavian.purdila@intel.com> <20151119232455.GM14311@dastard> <20151120005843.GP14311@dastard> <20151120152412.GC60886@bfoster.bfoster> 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: 1448034218 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Fri, Nov 20, 2015 at 05:31:59PM +0200, Octavian Purdila wrote: > On Fri, Nov 20, 2015 at 5:24 PM, Brian Foster wrote: > > On Fri, Nov 20, 2015 at 04:26:28PM +0200, Octavian Purdila wrote: > >> On Fri, Nov 20, 2015 at 2:58 AM, Dave Chinner wrote: > >> > On Fri, Nov 20, 2015 at 12:54:02AM +0100, Richard Weinberger wrote: > >> >> On Fri, Nov 20, 2015 at 12:24 AM, Dave Chinner wrote: > >> >> > On Wed, Nov 18, 2015 at 12:46:21AM +0200, Octavian Purdila wrote: > >> >> >> Naive implementation for non-mmu architectures: allocate physically > >> >> >> contiguous xfs buffers with alloc_pages. Terribly inefficient with > >> >> >> memory and fragmentation on high I/O loads but it may be good enough > >> >> >> for basic usage (which most non-mmu architectures will need). > >> >> > > >> >> > Can you please explain why you want to use XFS on low end, basic > >> >> > non-MMU devices? XFS is a high performance, enterprise/HPC level > >> >> > filesystem - it's not a filesystem designed for small IoT level > >> >> > devices - so I'm struggling to see why we'd want to expend any > >> >> > effort to make XFS work on such devices.... > >> >> > >> >> The use case is the Linux Kernel Library: > >> >> https://lkml.org/lkml/2015/11/3/706 > >> >> > >> >> Using LKL and fuse you can mount any kernel filesystem using fuse > >> >> as non-root. > >> > > >> > IOWs, because we said no to unprivileged mounts, instead the > >> > proposal is to linking all the kernel code into userspace so you can > >> > do unprivielged mounts that way? > >> > > >> > >> LKL's goal is to make it easy for various applications to reuse Linux > >> kernel code instead of re-implementing it. Mounting filesystem images > >> is just one of the applications. > >> > >> > IOWs, you get to say "it secure because it's in userspace" and leave > >> > us filesystem people with all the shit that comes with allowing > >> > users to mount random untrusted filesystem images using code that > >> > was never designed to allow that to happen? > >> > > >> > >> It is already possible to mount arbitrary filesystem images in > >> userspace using VMs . LKL doesn't change that, it just reduces the > >> amount of dependencies you need to do so. > >> > > > > Perhaps a dumb question, but I'm not quite putting 2+2 together here. > > When I see nommu, I'm generally thinking hardware characteristics, but > > we're talking about a userspace kernel library here. So can you > > elaborate on how this relates to nommu? Does this library emulate kernel > > mechanisms in userspace via nommu mode or something of that nature? > > > > LKL is currently implemented as a virtual non-mmu architecture. That > makes it simpler and it will also allow us to support environments > where it is not possible to emulate paging (e.g. bootloaders). > Ok, so we aren't necessarily talking about running on typically limited, mmu-less hardware. Thanks! Brian > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From tytso@thunk.org Fri Nov 20 14:07:49 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 03D7A7F37 for ; Fri, 20 Nov 2015 14:07:49 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id E8015304062 for ; Fri, 20 Nov 2015 12:07:45 -0800 (PST) X-ASG-Debug-ID: 1448050062-04cb6c0cd1154260001-NocioJ Received: from imap.thunk.org (imap.thunk.org [74.207.234.97]) by cuda.sgi.com with ESMTP id 3nxZMCRVwYlNVTh3 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Fri, 20 Nov 2015 12:07:42 -0800 (PST) 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=4GVt8DXesB/DWYJXB3XUV9QOMSFXAEYaBVa8zNUTwuc=; b=OKSvBS/uzwaPOipMdryslFFQJwd7Exg1jYeZxFOtGnnvmXG44MoD2u307OXuTEDes+H2vvz46TNnagbOR78xqLWCE1FmtgPbhcvoOvcco0wQmpUmm8YvTo647tan64c3/1e+ru00Pa656APNv2I3qJT9pZwVzzOLOXsk4Dp8Jwg=; Received: from root (helo=closure.thunk.org) by imap.thunk.org with local-esmtp (Exim 4.84) (envelope-from ) id 1Zzry5-0002Ud-JZ; Fri, 20 Nov 2015 20:07:37 +0000 Received: by closure.thunk.org (Postfix, from userid 15806) id E677F82DE99; Fri, 20 Nov 2015 15:07:33 -0500 (EST) Date: Fri, 20 Nov 2015 15:07:33 -0500 From: Theodore Ts'o To: Octavian Purdila Cc: Dave Chinner , Richard Weinberger , xfs , linux-fsdevel , LKML Subject: Re: [RFC PATCH] xfs: support for non-mmu architectures Message-ID: <20151120200733.GA350@thunk.org> X-ASG-Orig-Subj: Re: [RFC PATCH] xfs: support for non-mmu architectures Mail-Followup-To: Theodore Ts'o , Octavian Purdila , Dave Chinner , Richard Weinberger , xfs , linux-fsdevel , LKML References: <1447800381-20167-1-git-send-email-octavian.purdila@intel.com> <20151119232455.GM14311@dastard> <20151120005843.GP14311@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.24 (2015-08-30) 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: 1448050062 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24573 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, Nov 20, 2015 at 04:26:28PM +0200, Octavian Purdila wrote: > It is already possible to mount arbitrary filesystem images in > userspace using VMs . LKL doesn't change that, it just reduces the > amount of dependencies you need to do so. It is true that you can mount arbitrary file systems in userspace using VM's. But those the kvm binary is typically not run with root privileges in the host OS --- at least, not if the system administrator is smart. So a root compromise does not cause a catastrophic security vulnerability, and if the guest OS crashes --- again, not a real problem. In the caase where people are trying to claim that containers are just as secure as VM's, and plan to give container "guest" system administrators root-like powers, the question which immediately comes to mind is whether the LKML/fuse daemon is running inside or outside the container. If it is outside the container, the a potential security compromise of the binary running binary will be catastrophic to the overall security of the host system and all of its containers. If it is inside the container, you will be partially breaking the illusion that the container works just like a VM (since a user runinng "ps" will see all of these mysterious userspace processes that could be killed, etc.), but it significantly reduces the security problems if a maliciously crafted (or maliciously modulated) block device is mounted. > Could you expand of what burden does this use-case put on fs > developers? I am sure that, if needed, we can put restrictions in LKL > to avoid that. The bottom line is who is going to get all of the support calls and nasty e-mails explaining how our "crappy" code has caused some silly container VM system administrator's customers $$$ worth of losses. As long as we can make sure that it's been underlined that the code is being used well outside of its intended scope, and if it breaks, the user gets to keep both pieces, and all complaints, threatened lawsuits, etc. should go to the LKL maintainers or the purveyors of said container-based products, I suppose that should be OK. :-) - Ted From david@fromorbit.com Fri Nov 20 14:36:26 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 BADB97F37 for ; Fri, 20 Nov 2015 14:36:26 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 29557AC004 for ; Fri, 20 Nov 2015 12:36:22 -0800 (PST) X-ASG-Debug-ID: 1448051779-04cb6c0cd1154a60001-NocioJ Received: from ipmail06.adl2.internode.on.net (ipmail06.adl2.internode.on.net [150.101.137.129]) by cuda.sgi.com with ESMTP id D4ZJVna6Ea8R07MZ for ; Fri, 20 Nov 2015 12:36:19 -0800 (PST) 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: A2BeCAAOg09WPALtLHleKAECgxBTb4JfqSABAQEBAQEGiz2FLoQNHYVsAgIBAQKBR00BAQEBAQEHAQEBAUABP4Q0AQEBAwEnExwjBQsIAw4KCSUPBSUDBxoTiCYHwQMBAQEBAQUBAQEBGwQZhXSFRYJxgUODcIEVBZJqg2KFI4gDnFWEeyo0g2GBSgEBAQ Received: from ppp121-44-237-2.lns20.syd7.internode.on.net (HELO dastard) ([121.44.237.2]) by ipmail06.adl2.internode.on.net with ESMTP; 21 Nov 2015 07:06:03 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZzsPa-0000ZB-Nd; Sat, 21 Nov 2015 07:36:02 +1100 Date: Sat, 21 Nov 2015 07:36:02 +1100 From: Dave Chinner To: Brian Foster Cc: linux-fsdevel@vger.kernel.org, Octavian Purdila , linux-kernel@vger.kernel.org, xfs@oss.sgi.com Subject: Re: [RFC PATCH] xfs: support for non-mmu architectures Message-ID: <20151120203602.GA26718@dastard> X-ASG-Orig-Subj: Re: [RFC PATCH] xfs: support for non-mmu architectures References: <1447800381-20167-1-git-send-email-octavian.purdila@intel.com> <20151119155525.GB13055@bfoster.bfoster> <20151119233547.GN14311@dastard> <20151120151118.GB60886@bfoster.bfoster> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151120151118.GB60886@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: 1448051779 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24575 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri, Nov 20, 2015 at 10:11:19AM -0500, Brian Foster wrote: > On Fri, Nov 20, 2015 at 10:35:47AM +1100, Dave Chinner wrote: > > On Thu, Nov 19, 2015 at 10:55:25AM -0500, Brian Foster wrote: > > > On Wed, Nov 18, 2015 at 12:46:21AM +0200, Octavian Purdila wrote: > > > > Naive implementation for non-mmu architectures: allocate physically > > > > contiguous xfs buffers with alloc_pages. Terribly inefficient with > > > > memory and fragmentation on high I/O loads but it may be good enough > > > > for basic usage (which most non-mmu architectures will need). > > > > > > > > This patch was tested with lklfuse [1] and basic operations seems to > > > > work even with 16MB allocated for LKL. > > > > > > > > [1] https://github.com/lkl/linux > > > > > > > > Signed-off-by: Octavian Purdila > > > > --- > > > > > > Interesting, though this makes me wonder why we couldn't have a new > > > _XBF_VMEM (for example) buffer type that uses vmalloc(). I'm not > > > familiar with mmu-less context, but I see that mm/nommu.c has a > > > __vmalloc() interface that looks like it ultimately translates into an > > > alloc_pages() call. Would that accomplish what this patch is currently > > > trying to do? > > > > vmalloc is always a last resort. vmalloc space on 32 bit systems is > > extremely limited and it is easy to exhaust with XFS. > > > > Sure, but my impression is that a vmalloc() buffer is roughly equivalent > in this regard to a current !XBF_UNMAPPED && size > PAGE_SIZE buffer. We > just do the allocation and mapping separately (presumably for other > reasons). Yes, it'a always a last resort. We don't use vmap'd buffers very much on block size <= page size filesystems (e.g. iclog buffers are the main user in such cases, IIRC), so the typical 32 bit system doesn't have major problems with vmalloc space. However, the moment you increase the directory block size > block size, that all goes out the window... > > Also, vmalloc limits the control we have over allocation context > > (e.g. the hoops we jump through in kmem_alloc_large() to maintain > > GFP_NOFS contexts), so just using vmalloc doesn't make things much > > simpler from an XFS perspective. > > > > The comment in kmem_zalloc_large() calls out some apparent hardcoded > allocation flags down in the depths of vmalloc(). It looks to me that > page allocation (__vmalloc_area_node()) actually uses the provided > flags, so I'm not following the "data page" part of that comment. You can pass gfp flags for the page allocation part of vmalloc, but not the pte allocation part of it. That's what the hacks in kmem_zalloc_large() are doing. > Indeed, I do see that this is not the case down in calls like > pmd_alloc_one(), pte_alloc_one_kernel(), etc., associated with page > table management. Right. > Those latter calls are all from following down through the > map_vm_area()->vmap_page_range() codepath from __vmalloc_area_node(). We > call vm_map_ram() directly from _xfs_buf_map_pages(), which itself calls > down into the same code. Indeed, we already protect ourselves here via > the same memalloc_noio_save() mechanism that kmem_zalloc_large() uses. Yes, we do, but that is separately handled to the allocation of the pages, which we have to do for all types of buffers, mapped or unmapped, because xfs_buf_ioapply_map() requires direct access to the underlying pages to build the bio for IO. If we delegate the allocation of pages to vmalloc, we don't have direct reference to the underlying pages and so we have to do something completely diffferent to build the bios for the buffer.... > I suspect there's more to it than that because it does look like > vm_map_ram() has a different mechanism for managing vmalloc space for > certain (smaller) allocations, either of which I'm not really familiar > with. Yes, it manages vmalloc space quite differently, and there are different scalability aspects to consider as well - vm_map_ram was pretty much written for the use XFS has in xfs_buf.c... Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Fri Nov 20 15:09:11 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 2E12F7F37 for ; Fri, 20 Nov 2015 15:09:11 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 119F7304066 for ; Fri, 20 Nov 2015 13:09:07 -0800 (PST) X-ASG-Debug-ID: 1448053744-04cb6c0cd21551b0001-NocioJ Received: from ipmail06.adl2.internode.on.net (ipmail06.adl2.internode.on.net [150.101.137.129]) by cuda.sgi.com with ESMTP id NodwfwrteL48zDzY for ; Fri, 20 Nov 2015 13:09:04 -0800 (PST) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.129 Received: from ppp121-44-237-2.lns20.syd7.internode.on.net (HELO dastard) ([121.44.237.2]) by ipmail06.adl2.internode.on.net with ESMTP; 21 Nov 2015 07:38:34 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1Zzsv3-0000gA-49; Sat, 21 Nov 2015 08:08:33 +1100 Date: Sat, 21 Nov 2015 08:08:33 +1100 From: Dave Chinner To: Octavian Purdila Cc: xfs@oss.sgi.com, linux-fsdevel , lkml Subject: Re: [RFC PATCH] xfs: support for non-mmu architectures Message-ID: <20151120210833.GB26718@dastard> X-ASG-Orig-Subj: Re: [RFC PATCH] xfs: support for non-mmu architectures References: <1447800381-20167-1-git-send-email-octavian.purdila@intel.com> <20151119232455.GM14311@dastard> 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.adl2.internode.on.net[150.101.137.129] X-Barracuda-Start-Time: 1448053744 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24576 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri, Nov 20, 2015 at 03:43:20PM +0200, Octavian Purdila wrote: > On Fri, Nov 20, 2015 at 1:24 AM, Dave Chinner wrote: > > On Wed, Nov 18, 2015 at 12:46:21AM +0200, Octavian Purdila wrote: > >> Naive implementation for non-mmu architectures: allocate physically > >> contiguous xfs buffers with alloc_pages. Terribly inefficient with > >> memory and fragmentation on high I/O loads but it may be good enough > >> for basic usage (which most non-mmu architectures will need). > > > > Can you please explain why you want to use XFS on low end, basic > > non-MMU devices? XFS is a high performance, enterprise/HPC level > > filesystem - it's not a filesystem designed for small IoT level > > devices - so I'm struggling to see why we'd want to expend any > > effort to make XFS work on such devices.... > > > > Hi David, > > Yes XFS as the main fs on this type of devices does not make sense, > but does it hurt to be able to perform basic operation on XFS from > these devices? Perhaps accessing an external medium formatted with > XFS? > > Another example is accessing VM images that are formatted with XFS. > Currently we can do that with tools like libguestfs that use a VM in > the background. I am working on a lighter solution for that where we > compile the Linux kernel as a library [1]. This allows access to the > filesystem without the need to use a full VM. That's hardly a "lighter solution". I'm kinda tired of the ongoing "hack random shit" approach to container development. If you need a XFS-FUSE module to allow safe userspace access to XFS fielsystems then maybe, just maybe, it makes sense to ask the XFS developers how to best go about providing a reliable, up-to-date, tested, maintained and supported XFS-FUSE module? IOWs, a "lighter solution" is to use the libxfs code base that we already maintain across kernel and userspace in the xfsprogs package and write a FUSE wrapper around that. That, immediately, will give you full read-only access to XFS filesystem images via FUSE. Then we (the XFS developers) can test the XFS-FUSE module under normal development conditions as we modify the xfsprogs code base (e.g. via xfstests) and ensure we always release a working, up-to-date FUSE wrapper with each xfsprogs release. And then once a proper read-only FUSE wrapper has been written, then we can discuss what is necessary to enable write access via porting the necessary parts of the kernel code across to the userspace libxfs codebase and hooking them up to the FUSE API... Hmmm? > And a final example is linking the bootloader code with LKL to access > the filesystem. This has a hard requirement on non-mmu. No way. We *can't* support filesystems that have had bootloaders make arbitrary changes to the filesystem without the knowlege of the OS that *owns the filesystem*. Similarly, we cannot support random applications that internally mount and modify filesystem images in ways we can't see, control, test or simulate. Sure, they use the kernel code, but that doesn't stop them from doing stupid shit that could corrupt the filesystem image. So, no, we are not going to support giving random applications direct access to XFS filesystem images, even via LKL. > So, IMHO there are usecases for using XFS on non-mmu architectures. I > think it all boils down to: is the patch simple enough to not put an > unreasonable maintenance burden on developers? Look at it this way: a user tries to mount their XFS-on-LKL-on-FUSE, XFS throughs a memory allocation deadlock warning because of a high order allocation during mount failing (i.e. due to the vmalloc no-mmu hacks). Who has to spend effort to find out why the error is being thrown? It's not the FUSE developers. It's not the LKL developers. XFS is going to be blamed, because it's an XFS error message, and it will be up to the XFS developers to /prove/ that it's not an XFS problem. And then google will find these complaints about XFS causing all sorts of problems, and we're back to the bad old days of everyone blaming XFS for shortcomings and problems in other code we have no control over.. I really don't see how using LKL to give userspace access to XFS filesystems is a better solution than actually writing a proper, supported XFS-FUSE module. LKL is so full of compromises that it's going to be unworkable and unsupportable in practice... Cheers, Dave. -- Dave Chinner david@fromorbit.com From octavian.purdila@intel.com Fri Nov 20 16:26:54 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 D07247F37 for ; Fri, 20 Nov 2015 16:26:54 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id C415B304043 for ; Fri, 20 Nov 2015 14:26:51 -0800 (PST) X-ASG-Debug-ID: 1448058408-04cb6c0cd3156090001-NocioJ Received: from mail-wm0-f54.google.com (mail-wm0-f54.google.com [74.125.82.54]) by cuda.sgi.com with ESMTP id HCbKtM5hEL1M1lCR (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Fri, 20 Nov 2015 14:26:48 -0800 (PST) X-Barracuda-Envelope-From: octavian.purdila@intel.com X-Barracuda-Apparent-Source-IP: 74.125.82.54 Received: by wmvv187 with SMTP id v187so90982043wmv.1 for ; Fri, 20 Nov 2015 14:26:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=intel-com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=LnfeZXo5Z0/c5ULmnMi+uCEWjOhf1GNRg2vFJgIDZ60=; b=yEsDhhi+2wPquARVolGjVkcwtVUc0AmPR9zrwK94Gz+nmWgbaVvvybhhSxrKW2DcYm v/VhEtJPh4Qsp0LnZqD/aMVAOn6EiDf+pSVv1wSE/IOAFg2HOaUl9SjTDrE210TuCzUh Ic4hOtY425S90k2pt/bOfgR2z5BRF4mCIbtlXa/sZXQ4vMXQYll+seNCTNY1lAhwQVnP HjCRyCoTedyjOkyTR0l02RPMfe0sJkHgh8ZQcInFux5wqTSFvjW6vGfXSy5XCmjSxhJW +ImAFAUTKfzSvr5H8/x0sppGp6wuKuR/avMlYyPaCFhkkbTJX55/qbN74cGboTqg1Nzd XbvQ== 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=LnfeZXo5Z0/c5ULmnMi+uCEWjOhf1GNRg2vFJgIDZ60=; b=JDwtCNq4iw+EtxzwZX8KKem7rYrdUsws9rvgkS0c/LM8vCoo77ZIQ+mhfF1Cfbiazt qX2SZjCnMCNEiQS3vRkK49pcLrAAF76qfXJCPCrTI//9+SvNHVCmon34lGdvVg1/W2k3 4YPn0FImwvnQFwI+Bg1593oECNoH3MuKmsvAhMoIh8hPJTKEdRWAF7YHrJkTUWBDVR5y M57onjhpEBmdgFZzJ0ZN/BizevEd/DykWl2weeLVm98Jga4DwnBKdCB8NhrkGoyAwUu3 Gl9j8+zStWDoMl7LEHn+hg3NB05YRE9Yg5cniC044YghUIlBWVsddufvvH+0Cl3UCVMI GSkA== X-Gm-Message-State: ALoCoQmgNZmZ8NFz8Dn+5tN3L4YvmFq1yxzC1aC7U/M/L9Z2N11qeEyoj2FjvDkBPZdKd6+X2Esw MIME-Version: 1.0 X-Received: by 10.194.59.108 with SMTP id y12mr16953314wjq.33.1448058407661; Fri, 20 Nov 2015 14:26:47 -0800 (PST) Received: by 10.194.106.131 with HTTP; Fri, 20 Nov 2015 14:26:47 -0800 (PST) In-Reply-To: <20151120210833.GB26718@dastard> References: <1447800381-20167-1-git-send-email-octavian.purdila@intel.com> <20151119232455.GM14311@dastard> <20151120210833.GB26718@dastard> Date: Sat, 21 Nov 2015 00:26:47 +0200 Message-ID: Subject: Re: [RFC PATCH] xfs: support for non-mmu architectures From: Octavian Purdila X-ASG-Orig-Subj: Re: [RFC PATCH] xfs: support for non-mmu architectures To: Dave Chinner Cc: xfs , linux-fsdevel , lkml Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-wm0-f54.google.com[74.125.82.54] X-Barracuda-Start-Time: 1448058408 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24578 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, Nov 20, 2015 at 11:08 PM, Dave Chinner wrote: > On Fri, Nov 20, 2015 at 03:43:20PM +0200, Octavian Purdila wrote: >> On Fri, Nov 20, 2015 at 1:24 AM, Dave Chinner wrote: >> > On Wed, Nov 18, 2015 at 12:46:21AM +0200, Octavian Purdila wrote: >> >> Naive implementation for non-mmu architectures: allocate physically >> >> contiguous xfs buffers with alloc_pages. Terribly inefficient with >> >> memory and fragmentation on high I/O loads but it may be good enough >> >> for basic usage (which most non-mmu architectures will need). >> > >> > Can you please explain why you want to use XFS on low end, basic >> > non-MMU devices? XFS is a high performance, enterprise/HPC level >> > filesystem - it's not a filesystem designed for small IoT level >> > devices - so I'm struggling to see why we'd want to expend any >> > effort to make XFS work on such devices.... >> > >> >> Hi David, >> >> Yes XFS as the main fs on this type of devices does not make sense, >> but does it hurt to be able to perform basic operation on XFS from >> these devices? Perhaps accessing an external medium formatted with >> XFS? >> >> Another example is accessing VM images that are formatted with XFS. >> Currently we can do that with tools like libguestfs that use a VM in >> the background. I am working on a lighter solution for that where we >> compile the Linux kernel as a library [1]. This allows access to the >> filesystem without the need to use a full VM. > > That's hardly a "lighter solution" > > I'm kinda tired of the ongoing "hack random shit" approach to > container development. Since apparently there is a container devs hunting party going on right now, let me quickly confess that LKL has nothing to do with (them be damned) containers :) On a more serious note, LKL was not developed for containers or to try to circumvent privileged mounts. It was developed to allow the Linux kernel code to be reused in things like simple tools that allows one to modify a filesystem image. > If you need a XFS-FUSE module to allow safe > userspace access to XFS fielsystems then maybe, just maybe, it makes > sense to ask the XFS developers how to best go about providing a > reliable, up-to-date, tested, maintained and supported XFS-FUSE > module? > > IOWs, a "lighter solution" is to use the libxfs code base that we > already maintain across kernel and userspace in the xfsprogs package > and write a FUSE wrapper around that. That, immediately, will give > you full read-only access to XFS filesystem images via FUSE. Then we > (the XFS developers) can test the XFS-FUSE module under normal > development conditions as we modify the xfsprogs code base (e.g. via > xfstests) and ensure we always release a working, up-to-date FUSE > wrapper with each xfsprogs release. > > And then once a proper read-only FUSE wrapper has been written, then > we can discuss what is necessary to enable write access via porting > the necessary parts of the kernel code across to the userspace > libxfs codebase and hooking them up to the FUSE API... > > Hmmm? > What about ext4, vfat, btrfs and other filesystems? Also why duplicate the whole thing if you could reuse it? >> And a final example is linking the bootloader code with LKL to access >> the filesystem. This has a hard requirement on non-mmu. > > No way. We *can't* support filesystems that have had bootloaders > make arbitrary changes to the filesystem without the knowlege of the > OS that *owns the filesystem*. Similarly, we cannot support random > applications that internally mount and modify filesystem images in > ways we can't see, control, test or simulate. Sure, they use the > kernel code, but that doesn't stop them from doing stupid shit that > could corrupt the filesystem image. So, no, we are not going to > support giving random applications direct access to XFS filesystem > images, even via LKL. > LKL only exports the Linux kernel system calls and nothing else to applications. Because of that, there should not be any loss of control or visibility to the XFS fs driver. >> So, IMHO there are usecases for using XFS on non-mmu architectures. I >> think it all boils down to: is the patch simple enough to not put an >> unreasonable maintenance burden on developers? > > Look at it this way: a user tries to mount their > XFS-on-LKL-on-FUSE, XFS throughs a memory allocation deadlock > warning because of a high order allocation during mount failing > (i.e. due to the vmalloc no-mmu hacks). > > Who has to spend effort to find out why the error is being thrown? > It's not the FUSE developers. It's not the LKL developers. XFS is > going to be blamed, because it's an XFS error message, and it will > be up to the XFS developers to /prove/ that it's not an XFS problem. > And then google will find these complaints about XFS causing all > sorts of problems, and we're back to the bad old days of everyone > blaming XFS for shortcomings and problems in other code we have no > control over.. > > I really don't see how using LKL to give userspace access to XFS > filesystems is a better solution than actually writing a proper, > supported XFS-FUSE module. LKL is so full of compromises that it's > going to be unworkable and unsupportable in practice... > Could you elaborate on some of these issues? From bfoster@redhat.com Fri Nov 20 16:47:42 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 3CBB27F37 for ; Fri, 20 Nov 2015 16:47:42 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 1F8D68F8039 for ; Fri, 20 Nov 2015 14:47:38 -0800 (PST) X-ASG-Debug-ID: 1448059656-04cb6c0cd1156590001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id SpnNV87k1GtS6ekv (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 20 Nov 2015 14:47:37 -0800 (PST) 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 (Postfix) with ESMTPS id C2DADB282F; Fri, 20 Nov 2015 22:47:36 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-225.bos.redhat.com [10.18.41.225]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAKMlai4017915; Fri, 20 Nov 2015 17:47:36 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id 9D943122406; Fri, 20 Nov 2015 17:47:34 -0500 (EST) Date: Fri, 20 Nov 2015 17:47:34 -0500 From: Brian Foster To: Dave Chinner Cc: linux-fsdevel@vger.kernel.org, Octavian Purdila , linux-kernel@vger.kernel.org, xfs@oss.sgi.com Subject: Re: [RFC PATCH] xfs: support for non-mmu architectures Message-ID: <20151120224734.GA28795@bfoster.bfoster> X-ASG-Orig-Subj: Re: [RFC PATCH] xfs: support for non-mmu architectures References: <1447800381-20167-1-git-send-email-octavian.purdila@intel.com> <20151119155525.GB13055@bfoster.bfoster> <20151119233547.GN14311@dastard> <20151120151118.GB60886@bfoster.bfoster> <20151120203602.GA26718@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151120203602.GA26718@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: 1448059657 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Sat, Nov 21, 2015 at 07:36:02AM +1100, Dave Chinner wrote: > On Fri, Nov 20, 2015 at 10:11:19AM -0500, Brian Foster wrote: > > On Fri, Nov 20, 2015 at 10:35:47AM +1100, Dave Chinner wrote: > > > On Thu, Nov 19, 2015 at 10:55:25AM -0500, Brian Foster wrote: > > > > On Wed, Nov 18, 2015 at 12:46:21AM +0200, Octavian Purdila wrote: > > > > > Naive implementation for non-mmu architectures: allocate physically > > > > > contiguous xfs buffers with alloc_pages. Terribly inefficient with > > > > > memory and fragmentation on high I/O loads but it may be good enough > > > > > for basic usage (which most non-mmu architectures will need). > > > > > > > > > > This patch was tested with lklfuse [1] and basic operations seems to > > > > > work even with 16MB allocated for LKL. > > > > > > > > > > [1] https://github.com/lkl/linux > > > > > > > > > > Signed-off-by: Octavian Purdila > > > > > --- > > > > > > > > Interesting, though this makes me wonder why we couldn't have a new > > > > _XBF_VMEM (for example) buffer type that uses vmalloc(). I'm not > > > > familiar with mmu-less context, but I see that mm/nommu.c has a > > > > __vmalloc() interface that looks like it ultimately translates into an > > > > alloc_pages() call. Would that accomplish what this patch is currently > > > > trying to do? > > > > > > vmalloc is always a last resort. vmalloc space on 32 bit systems is > > > extremely limited and it is easy to exhaust with XFS. > > > > > > > Sure, but my impression is that a vmalloc() buffer is roughly equivalent > > in this regard to a current !XBF_UNMAPPED && size > PAGE_SIZE buffer. We > > just do the allocation and mapping separately (presumably for other > > reasons). > > Yes, it'a always a last resort. We don't use vmap'd buffers very > much on block size <= page size filesystems (e.g. iclog buffers are > the main user in such cases, IIRC), so the typical 32 bit > system doesn't have major problems with vmalloc space. However, the > moment you increase the directory block size > block size, that all > goes out the window... > Ok. It's really only the pre-existing mapped buffer cases we care about here. > > > Also, vmalloc limits the control we have over allocation context > > > (e.g. the hoops we jump through in kmem_alloc_large() to maintain > > > GFP_NOFS contexts), so just using vmalloc doesn't make things much > > > simpler from an XFS perspective. > > > > > > > The comment in kmem_zalloc_large() calls out some apparent hardcoded > > allocation flags down in the depths of vmalloc(). It looks to me that > > page allocation (__vmalloc_area_node()) actually uses the provided > > flags, so I'm not following the "data page" part of that comment. > > You can pass gfp flags for the page allocation part of vmalloc, but > not the pte allocation part of it. That's what the hacks in > kmem_zalloc_large() are doing. > > > Indeed, I do see that this is not the case down in calls like > > pmd_alloc_one(), pte_alloc_one_kernel(), etc., associated with page > > table management. > > Right. > > > Those latter calls are all from following down through the > > map_vm_area()->vmap_page_range() codepath from __vmalloc_area_node(). We > > call vm_map_ram() directly from _xfs_buf_map_pages(), which itself calls > > down into the same code. Indeed, we already protect ourselves here via > > the same memalloc_noio_save() mechanism that kmem_zalloc_large() uses. > > Yes, we do, but that is separately handled to the allocation of the > pages, which we have to do for all types of buffers, mapped or > unmapped, because xfs_buf_ioapply_map() requires direct access to > the underlying pages to build the bio for IO. If we delegate the > allocation of pages to vmalloc, we don't have direct reference to > the underlying pages and so we have to do something completely > diffferent to build the bios for the buffer.... > Octavian points out virt_to_page() in a previous mail. I'm not sure that's the right interface solely based on looking at some current callers, but there is vmalloc_to_page() so I'd expect we can gain access to the pages one way or another. Given that, the buffer allocation code would fully populate the xfs_buf as it is today. The buffer I/O submission code wouldn't really know the difference and shouldn't have to change at all. > > I suspect there's more to it than that because it does look like > > vm_map_ram() has a different mechanism for managing vmalloc space for > > certain (smaller) allocations, either of which I'm not really familiar > > with. > > Yes, it manages vmalloc space quite differently, and there are > different scalability aspects to consider as well - vm_map_ram was > pretty much written for the use XFS has in xfs_buf.c... > Indeed. Looking closer, it appears to have a percpu vmalloc space allocation strategy for smaller allocations. We clearly can't just switch mapped buffer cases over and expect it to work/perform just the same. That said, the vm_map_ram() comment does call out fragmentation concerns for objects with mixed lifetimes. I'd be curious whether our buffer caching can trigger any badness there. OTOH, it's also not clear that this mechanism couldn't extend to vmalloc (or some variant thereof) in the future. Either way, it would require significantly more investigation/testing to enable generic usage. The core point was really just to abstract the nommu changes into something that potentially has generic use. Brian > Cheers, > > Dave. > -- > Dave Chinner > david@fromorbit.com From darrick.wong@oracle.com Fri Nov 20 18:50:45 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 367DF7F37 for ; Fri, 20 Nov 2015 18:50:45 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 27E398F8040 for ; Fri, 20 Nov 2015 16:50:42 -0800 (PST) X-ASG-Debug-ID: 1448067039-04cb6c0cd1157f70001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id TTrKSXZmCW90s4SH (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 20 Nov 2015 16:50:39 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tAL0oBWs012705 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Sat, 21 Nov 2015 00:50:11 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id tAL0oAZn026118 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Sat, 21 Nov 2015 00:50:11 GMT Received: from abhmp0009.oracle.com (abhmp0009.oracle.com [141.146.116.15]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id tAL0oALc027901; Sat, 21 Nov 2015 00:50:10 GMT Received: from localhost (/10.145.178.207) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 20 Nov 2015 16:50:10 -0800 Subject: [PATCH 1/2] test-scripts: test migration scripts From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 1/2] test-scripts: test migration scripts To: david@fromorbit.com, darrick.wong@oracle.com Cc: fstests@vger.kernel.org, xfs@oss.sgi.com, hch@infradead.org, tao.peng@primarydata.com, linux-ext4@vger.kernel.org, Anna.Schumaker@netapp.com, linux-btrfs@vger.kernel.org Date: Fri, 20 Nov 2015 16:50:08 -0800 Message-ID: <20151121005008.20398.37255.stgit@birch.djwong.org> In-Reply-To: <20151121005001.20398.92856.stgit@birch.djwong.org> References: <20151121005001.20398.92856.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0021.oracle.com [156.151.31.71] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1448067039 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24587 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Add two scripts: "nextid" finds the next available test ID number in a group, and "mvtest" relocates a test, fixes the golden output, and moves the group entry for that test. v2: sorting group files should preserve group order; nextid should use the same algorithm as new; move both tools to tools/. Signed-off-by: Darrick J. Wong --- tools/mvtest | 55 +++++++++++++++++++++++++++ tools/nextid | 1 tools/sort-group | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 168 insertions(+) create mode 100755 tools/mvtest create mode 120000 tools/nextid create mode 100755 tools/sort-group diff --git a/tools/mvtest b/tools/mvtest new file mode 100755 index 0000000..af601d6 --- /dev/null +++ b/tools/mvtest @@ -0,0 +1,55 @@ +#!/bin/sh + +# Renumber a test +dir="$(dirname "$0")" + +if [ -z "$1" ] || [ "$1" = "--help" ]; then + echo "Usage: $0 path_to_test new_path_to_test" + exit 1 +fi + +src="$1" +dest="$2" + +die() { + echo "$@" + exit 1 +} + +append() { + out="$1" + shift + echo "$@" >> "${out}" +} + +test "${src}" != "${dest}" || die "Test \"${src}\" is the same as dest." +test -e "tests/${src}" || die "Test \"${src}\" does not exist." +test ! -e "tests/${dest}" || die "Test \"${src}\" already exists." + +sid="$(basename "${src}")" +did="$(basename "${dest}")" + +sgroup="$(basename "$(dirname "tests/${src}")")" +dgroup="$(basename "$(dirname "tests/${dest}")")" + +sgroupfile="tests/${sgroup}/group" +dgroupfile="tests/${sgroup}/group" + +git mv "tests/${src}" "tests/${dest}" +git mv "tests/${src}.out" "tests/${dest}.out" +sed -e "s/^# FS QA Test No. ${sid}$/# FS QA Test No. ${did}/g" -i "tests/${dest}" +sed -e "s/^QA output created by ${sid}$/QA output created by ${did}/g" -i "tests/${dest}.out" +sed -e "s/test-${sid}/test-${did}/g" -i "tests/${dest}.out" + +grpline="$(grep "^${sid} " "${sgroupfile}")" +newgrpline="$(echo "${grpline}" | sed -e "s/^${sid} /${did} /g")" + +sed -e "/^${sid}.*$/d" -i "${sgroupfile}" +cp "${dgroupfile}" "${dgroupfile}.new" +append "${dgroupfile}.new" "${newgrpline}" +"${dir}/sort-group.py" "${dgroupfile}.new" +mv "${dgroupfile}.new" "${dgroupfile}" + +echo "Moved \"${src}\" to \"${dest}\"." + +exit 0 diff --git a/tools/nextid b/tools/nextid new file mode 120000 index 0000000..5c31d60 --- /dev/null +++ b/tools/nextid @@ -0,0 +1 @@ +sort-group \ No newline at end of file diff --git a/tools/sort-group b/tools/sort-group new file mode 100755 index 0000000..84944ed --- /dev/null +++ b/tools/sort-group @@ -0,0 +1,112 @@ +#!/usr/bin/env python +import sys + +# Sort a group list, carefully preserving comments. + +def xfstest_key(key): + '''Extract the numeric part of a test name if possible.''' + k = 0 + + assert type(key) == str + + # No test number at all... + if not key[0].isdigit(): + return key + + # ...otherwise extract as much number as we can. + for digit in key: + if digit.isdigit(): + k = k * 10 + int(digit) + else: + return k + return k + +def read_group(fd): + '''Read the group list, carefully attaching comments to the next test.''' + tests = {} + comments = None + + for line in fd: + sline = line.strip() + tokens = sline.split() + if len(tokens) == 0 or tokens[0] == '#': + if comments == None: + comments = [] + comments.append(sline) + else: + tests[tokens[0]] = (comments, tokens[1:]) + comments = None + return tests + +def sort_keys(keys): + '''Separate keys into integer and non-integer tests.''' + int_keys = [] + int_xkeys = [] + str_keys = [] + + # Sort keys into integer(ish) tests and other + for key in keys: + xkey = xfstest_key(key) + if type(xkey) == int: + int_keys.append(key) + int_xkeys.append(xkey) + else: + str_keys.append(key) + return (int_keys, int_xkeys, str_keys) + +def write_sorted(tests, fd): + def dump_xkey(xkey): + (comments, tokens) = tests[key] + if comments: + for c in comments: + fd.write('%s\n' % c) + fd.write('%s %s\n' % (key, ' '.join(tokens))) + '''Print tests (and comments) in number order.''' + + (int_keys, ignored, str_keys) = sort_keys(tests.keys()) + for key in sorted(int_keys, key = xfstest_key): + dump_xkey(key) + for key in sorted(str_keys): + dump_xkey(key) + +def sort_main(): + if '--help' in sys.argv[1:]: + print('Usage: %s groupfiles' % sys.argv[0]) + sys.exit(0) + + for arg in sys.argv[1:]: + with open(arg, 'r+') as fd: + x = read_group(fd) + fd.seek(0, 0) + write_sorted(x, fd) + +def nextid_main(): + if '--help' in sys.argv[1:]: + print('Usage: %s group[/startid] ' % sys.argv[0]) + sys.exit(0) + + if len(sys.argv) != 2: + print('Specify exactly one group name.') + sys.exit(1) + + c = sys.argv[1].split('/') + if len(c) > 1: + startid = int(c[1]) + else: + startid = 1 + group = c[0] + + with open('tests/%s/group' % group, 'r') as fd: + x = read_group(fd) + xkeys = {int(x) for x in sort_keys(x.keys())[1]} + + xid = startid + while xid in xkeys: + xid += 1 + print('%s/%d' % (group, xid)) + +if __name__ == '__main__': + if 'nextid' in sys.argv[0]: + nextid_main() + else: + sort_main() From darrick.wong@oracle.com Fri Nov 20 18:50:46 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id DF3F47F37 for ; Fri, 20 Nov 2015 18:50:45 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 86A5FAC005 for ; Fri, 20 Nov 2015 16:50:42 -0800 (PST) X-ASG-Debug-ID: 1448067040-04bdf07f081a8d90001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id HUdtlmHF8PFmtsfp (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 20 Nov 2015 16:50:40 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tAL0o61i014202 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Sat, 21 Nov 2015 00:50:06 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id tAL0o4Np024879 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Sat, 21 Nov 2015 00:50:04 GMT Received: from abhmp0014.oracle.com (abhmp0014.oracle.com [141.146.116.20]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id tAL0o4OK027876; Sat, 21 Nov 2015 00:50:04 GMT Received: from localhost (/10.145.178.207) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 20 Nov 2015 16:50:03 -0800 Subject: [PATCH v3.3 0/2] xfstests: test the nfs/cifs/btrfs/xfs reflink/dedupe ioctls From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH v3.3 0/2] xfstests: test the nfs/cifs/btrfs/xfs reflink/dedupe ioctls To: david@fromorbit.com, darrick.wong@oracle.com Cc: fstests@vger.kernel.org, xfs@oss.sgi.com, hch@infradead.org, tao.peng@primarydata.com, linux-ext4@vger.kernel.org, Anna.Schumaker@netapp.com, linux-btrfs@vger.kernel.org Date: Fri, 20 Nov 2015 16:50:01 -0800 Message-ID: <20151121005001.20398.92856.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1448067040 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24587 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Hi all, This is a small patch set against the reflink/dedupe test cases in xfstests. The first patch is a rewrite of the tools to find the lowest vacant ID number and to move a test case. These two programs are useful for staging a lot of new tests at a high number and moving them to lower numbers when the maintainer wants to accept the new tests. The second patch updates the golden output for the test that examines the results of feeding bad inputs to the two ioctls. The new error values are based on a discussion of how to react to bad file types on the mailing lists and the ongoing work to hoist the ioctls to the VFS level. If you're going to start using this mess, you probably ought to just pull from my github trees for kernel[1], xfsprogs[2], xfstests[3], and xfs-docs[4]. They should just work with the btrfs that's in 4.3... and somewhat buggily with the 4.3 XFS patched with [1]. (You don't need to pull the kernel or xfs-docs git trees if you're not working on XFS reflink. The relevant xfs_io support will be in xfsprogs 4.3 and the tests were pulled into the xfstests-dev repo last week.) Comments and questions are, as always, welcome. --D [1] https://github.com/djwong/linux/tree/for-dave [2] https://github.com/djwong/xfsprogs/tree/for-dave [3] https://github.com/djwong/xfstests/tree/for-dave [4] https://github.com/djwong/xfs-documentation/tree/for-dave From darrick.wong@oracle.com Fri Nov 20 18:50:50 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 262217F54 for ; Fri, 20 Nov 2015 18:50:50 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id A2588AC004 for ; Fri, 20 Nov 2015 16:50:49 -0800 (PST) X-ASG-Debug-ID: 1448067045-04cb6c0cd2157f80001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id lWg523o5NaGhHxDp (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 20 Nov 2015 16:50:46 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tAL0oI7j014372 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Sat, 21 Nov 2015 00:50:18 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id tAL0oI51025564 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Sat, 21 Nov 2015 00:50:18 GMT Received: from abhmp0010.oracle.com (abhmp0010.oracle.com [141.146.116.16]) by userv0121.oracle.com (8.13.8/8.13.8) with ESMTP id tAL0oHll025887; Sat, 21 Nov 2015 00:50:17 GMT Received: from localhost (/10.145.178.207) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 20 Nov 2015 16:50:17 -0800 Subject: [PATCH 2/2] generic/15[78]: fix error messages in the golden output From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 2/2] generic/15[78]: fix error messages in the golden output To: david@fromorbit.com, darrick.wong@oracle.com Cc: fstests@vger.kernel.org, xfs@oss.sgi.com, hch@infradead.org, tao.peng@primarydata.com, linux-ext4@vger.kernel.org, Anna.Schumaker@netapp.com, linux-btrfs@vger.kernel.org Date: Fri, 20 Nov 2015 16:50:14 -0800 Message-ID: <20151121005014.20398.22316.stgit@birch.djwong.org> In-Reply-To: <20151121005001.20398.92856.stgit@birch.djwong.org> References: <20151121005001.20398.92856.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1448067046 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/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, UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24587 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.60 MARKETING_SUBJECT Subject contains popular marketing words 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Fix the error messages in the golden output for generic/15[78], which examine the responses to invalid inputs as returned by the clone/clone_range/extent_same ioctls. Also fix a filtering omission. Signed-off-by: Darrick J. Wong --- tests/generic/157 | 12 ++++++++---- tests/generic/157.out | 2 +- tests/generic/158 | 10 +++++++--- tests/generic/158.out | 8 ++++---- 4 files changed, 20 insertions(+), 12 deletions(-) diff --git a/tests/generic/157 b/tests/generic/157 index a43fb0d..f3de285 100755 --- a/tests/generic/157 +++ b/tests/generic/157 @@ -75,10 +75,14 @@ mkdir "$TESTDIR1/dir1" seq 1 $((2 * BLKSZ / 250)) | while read f; do touch "$TESTDIR1/dir1/$f" done -mknod "$TESTDIR1/dev1" b 8 0 +mknod "$TESTDIR1/dev1" c 1 3 mkfifo "$TESTDIR1/fifo1" sync +_filter_enotty() { + sed -e 's/Inappropriate ioctl for device/Operation not supported/g' +} + echo "Try cross-device reflink" _reflink_range "$TESTDIR1/file1" 0 "$TESTDIR2/file1" 0 $BLKSZ @@ -98,13 +102,13 @@ echo "Try to reflink a device" _reflink_range "$TESTDIR1/dev1" 0 "$TESTDIR1/file2" 0 $BLKSZ echo "Try to reflink to a dir" -_reflink_range "$TESTDIR1/file1" 0 "$TESTDIR1/dir1" 0 $BLKSZ +_reflink_range "$TESTDIR1/file1" 0 "$TESTDIR1/dir1" 0 $BLKSZ 2>&1 | _filter_test_dir echo "Try to reflink to a device" -_reflink_range "$TESTDIR1/file1" 0 "$TESTDIR1/dev1" 0 $BLKSZ +_reflink_range "$TESTDIR1/file1" 0 "$TESTDIR1/dev1" 0 $BLKSZ 2>&1 | _filter_enotty echo "Try to reflink to a fifo" -_reflink_range "$TESTDIR1/file1" 0 "$TESTDIR1/fifo1" 0 $BLKSZ -n +_reflink_range "$TESTDIR1/file1" 0 "$TESTDIR1/fifo1" 0 $BLKSZ -n 2>&1 | _filter_enotty echo "Try to reflink an append-only file" _reflink_range "$TESTDIR1/file1" 0 "$TESTDIR1/file3" 0 $BLKSZ -a diff --git a/tests/generic/157.out b/tests/generic/157.out index 177e7f8..3a690ca 100644 --- a/tests/generic/157.out +++ b/tests/generic/157.out @@ -14,7 +14,7 @@ XFS_IOC_CLONE_RANGE: Is a directory Try to reflink a device XFS_IOC_CLONE_RANGE: Invalid argument Try to reflink to a dir -/mnt/test-157/dir1: Is a directory +TEST_DIR/test-157/dir1: Is a directory Try to reflink to a device XFS_IOC_CLONE_RANGE: Operation not supported Try to reflink to a fifo diff --git a/tests/generic/158 b/tests/generic/158 index a499b21..db5d05c 100755 --- a/tests/generic/158 +++ b/tests/generic/158 @@ -76,10 +76,14 @@ mkdir "$TESTDIR1/dir1" seq 1 $((2 * BLKSZ / 250)) | while read f; do touch "$TESTDIR1/dir1/$f" done -mknod "$TESTDIR1/dev1" b 8 0 +mknod "$TESTDIR1/dev1" c 1 3 mkfifo "$TESTDIR1/fifo1" sync +_filter_enotty() { + sed -e 's/Inappropriate ioctl for device/Invalid argument/g' +} + echo "Try cross-device dedupe" _dedupe_range "$TESTDIR1/file1" 0 "$TESTDIR2/file1" 0 $BLKSZ @@ -96,10 +100,10 @@ echo "Try to dedupe a dir" _dedupe_range "$TESTDIR1/dir1" 0 "$TESTDIR1/file2" 0 $BLKSZ echo "Try to dedupe a device" -_dedupe_range "$TESTDIR1/dev1" 0 "$TESTDIR1/file2" 0 $BLKSZ +_dedupe_range "$TESTDIR1/dev1" 0 "$TESTDIR1/file2" 0 $BLKSZ 2>&1 | _filter_enotty echo "Try to dedupe to a dir" -_dedupe_range "$TESTDIR1/file1" 0 "$TESTDIR1/dir1" 0 $BLKSZ +_dedupe_range "$TESTDIR1/file1" 0 "$TESTDIR1/dir1" 0 $BLKSZ 2>&1 | _filter_test_dir echo "Try to dedupe to a device" _dedupe_range "$TESTDIR1/file1" 0 "$TESTDIR1/dev1" 0 $BLKSZ diff --git a/tests/generic/158.out b/tests/generic/158.out index 36a3f1f..1210429 100644 --- a/tests/generic/158.out +++ b/tests/generic/158.out @@ -12,13 +12,13 @@ dedupe: Invalid argument Try to dedupe a dir XFS_IOC_FILE_EXTENT_SAME: Is a directory Try to dedupe a device -XFS_IOC_FILE_EXTENT_SAME: Permission denied +XFS_IOC_FILE_EXTENT_SAME: Invalid argument Try to dedupe to a dir -/mnt/test-158/dir1: Is a directory +TEST_DIR/test-158/dir1: Is a directory Try to dedupe to a device -dedupe: Permission denied +dedupe: Operation not supported Try to dedupe to a fifo -dedupe: Permission denied +dedupe: Operation not supported Try to dedupe an append-only file Dedupe two files Check scratch fs From BATV+56a981d69ec8c5be2b75+4472+infradead.org+hch@bombadil.srs.infradead.org Sat Nov 21 12:06:56 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 86BF029DF5 for ; Sat, 21 Nov 2015 12:06:56 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 672E48F8033 for ; Sat, 21 Nov 2015 10:06:53 -0800 (PST) X-ASG-Debug-ID: 1448129210-04bdf07f071c8000001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id R0OW0G0uYe7aFH5M (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Sat, 21 Nov 2015 10:06:50 -0800 (PST) X-Barracuda-Envelope-From: BATV+56a981d69ec8c5be2b75+4472+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 1a0CYe-0007oy-Mx; Sat, 21 Nov 2015 18:06:44 +0000 Date: Sat, 21 Nov 2015 10:06:44 -0800 From: Christoph Hellwig To: "Darrick J. Wong" Cc: david@fromorbit.com, fstests@vger.kernel.org, xfs@oss.sgi.com, hch@infradead.org, tao.peng@primarydata.com, linux-ext4@vger.kernel.org, Anna.Schumaker@netapp.com, linux-btrfs@vger.kernel.org Subject: Re: [PATCH 2/2] generic/15[78]: fix error messages in the golden output Message-ID: <20151121180644.GA23916@infradead.org> X-ASG-Orig-Subj: Re: [PATCH 2/2] generic/15[78]: fix error messages in the golden output References: <20151121005001.20398.92856.stgit@birch.djwong.org> <20151121005014.20398.22316.stgit@birch.djwong.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151121005014.20398.22316.stgit@birch.djwong.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: 1448129210 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/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, MARKETING_SUBJECT, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24606 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.60 MARKETING_SUBJECT Subject contains popular marketing words 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS > --- a/tests/generic/158.out > +++ b/tests/generic/158.out > Try to dedupe a device > -XFS_IOC_FILE_EXTENT_SAME: Permission denied > +XFS_IOC_FILE_EXTENT_SAME: Invalid argument > Try to dedupe to a dir > -/mnt/test-158/dir1: Is a directory > +TEST_DIR/test-158/dir1: Is a directory > Try to dedupe to a device > -dedupe: Permission denied > +dedupe: Operation not supported > Try to dedupe to a fifo > -dedupe: Permission denied > +dedupe: Operation not supported Shouldn't these be Invalid argument just like the to a device case above or the clone case? Otherwise looks good, Reviewed-by: Christoph Hellwig From BATV+56a981d69ec8c5be2b75+4472+infradead.org+hch@bombadil.srs.infradead.org Sat Nov 21 12:14:58 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 839CD29DF5 for ; Sat, 21 Nov 2015 12:14:58 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 72C85304059 for ; Sat, 21 Nov 2015 10:14:55 -0800 (PST) X-ASG-Debug-ID: 1448129693-04cbb0605b1ab1d0001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id WsqRlqqOsTwaYS8Z (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Sat, 21 Nov 2015 10:14:53 -0800 (PST) X-Barracuda-Envelope-From: BATV+56a981d69ec8c5be2b75+4472+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 1a0CgV-0005Jx-QM; Sat, 21 Nov 2015 18:14:51 +0000 Date: Sat, 21 Nov 2015 10:14:51 -0800 From: Christoph Hellwig To: "Darrick J. Wong" Cc: david@fromorbit.com, fstests@vger.kernel.org, xfs@oss.sgi.com, hch@infradead.org, tao.peng@primarydata.com, linux-ext4@vger.kernel.org, Anna.Schumaker@netapp.com, linux-btrfs@vger.kernel.org Subject: Re: [PATCH 2/2] generic/15[78]: fix error messages in the golden output Message-ID: <20151121181451.GA17570@infradead.org> X-ASG-Orig-Subj: Re: [PATCH 2/2] generic/15[78]: fix error messages in the golden output References: <20151121005001.20398.92856.stgit@birch.djwong.org> <20151121005014.20398.22316.stgit@birch.djwong.org> <20151121180644.GA23916@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151121180644.GA23916@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: 1448129693 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/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, MARKETING_SUBJECT, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24606 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.60 MARKETING_SUBJECT Subject contains popular marketing words 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS > Shouldn't these be Invalid argument just like the > to a device case above or the clone case? E.g. something like this on top of your patch: diff --git a/tests/generic/158.out b/tests/generic/158.out index 1210429..dff3692 100644 --- a/tests/generic/158.out +++ b/tests/generic/158.out @@ -16,9 +16,9 @@ XFS_IOC_FILE_EXTENT_SAME: Invalid argument Try to dedupe to a dir TEST_DIR/test-158/dir1: Is a directory Try to dedupe to a device -dedupe: Operation not supported +dedupe: Invalid argument Try to dedupe to a fifo -dedupe: Operation not supported +dedupe: Invalid argument Try to dedupe an append-only file Dedupe two files Check scratch fs From david@fromorbit.com Sun Nov 22 16:05:24 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 BFA7C7F37 for ; Sun, 22 Nov 2015 16:05:24 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 9716C8F8033 for ; Sun, 22 Nov 2015 14:05:21 -0800 (PST) X-ASG-Debug-ID: 1448229903-04cb6c0cd118ca10001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id nvr7JkE8K6UVCNO0 for ; Sun, 22 Nov 2015 14:05:06 -0800 (PST) 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: A2CmBgBrO1JW/1bELHlegzuBQoJfqSMBAQaLP4UvhA2GCQQCAoEjTQEBAQEBAYELhDQBAQEDAScTHBYKAwULCAMOCgklDwUlAyETiCYHvXgBAQEBBgIBIBmFdIVFhDsBAYNngRUFllCNKJxUY4QYKjSDaoFBAQEB Received: from ppp121-44-196-86.lns20.syd7.internode.on.net (HELO dastard) ([121.44.196.86]) by ipmail07.adl2.internode.on.net with ESMTP; 23 Nov 2015 08:34:13 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1a0cjo-0004Jb-SR; Mon, 23 Nov 2015 09:04:00 +1100 Date: Mon, 23 Nov 2015 09:04:00 +1100 From: Dave Chinner To: Brian Foster Cc: linux-fsdevel@vger.kernel.org, Octavian Purdila , linux-kernel@vger.kernel.org, xfs@oss.sgi.com Subject: Re: [RFC PATCH] xfs: support for non-mmu architectures Message-ID: <20151122220400.GC26718@dastard> X-ASG-Orig-Subj: Re: [RFC PATCH] xfs: support for non-mmu architectures References: <1447800381-20167-1-git-send-email-octavian.purdila@intel.com> <20151119155525.GB13055@bfoster.bfoster> <20151119233547.GN14311@dastard> <20151120151118.GB60886@bfoster.bfoster> <20151120203602.GA26718@dastard> <20151120224734.GA28795@bfoster.bfoster> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151120224734.GA28795@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: 1448229905 X-Barracuda-URL: https://192.48.176.15:443/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= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24634 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri, Nov 20, 2015 at 05:47:34PM -0500, Brian Foster wrote: > On Sat, Nov 21, 2015 at 07:36:02AM +1100, Dave Chinner wrote: > > On Fri, Nov 20, 2015 at 10:11:19AM -0500, Brian Foster wrote: > > > On Fri, Nov 20, 2015 at 10:35:47AM +1100, Dave Chinner wrote: > > > Those latter calls are all from following down through the > > > map_vm_area()->vmap_page_range() codepath from __vmalloc_area_node(). We > > > call vm_map_ram() directly from _xfs_buf_map_pages(), which itself calls > > > down into the same code. Indeed, we already protect ourselves here via > > > the same memalloc_noio_save() mechanism that kmem_zalloc_large() uses. > > > > Yes, we do, but that is separately handled to the allocation of the > > pages, which we have to do for all types of buffers, mapped or > > unmapped, because xfs_buf_ioapply_map() requires direct access to > > the underlying pages to build the bio for IO. If we delegate the > > allocation of pages to vmalloc, we don't have direct reference to > > the underlying pages and so we have to do something completely > > diffferent to build the bios for the buffer.... > > > > Octavian points out virt_to_page() in a previous mail. I'm not sure > that's the right interface solely based on looking at some current > callers, but there is vmalloc_to_page() so I'd expect we can gain access > to the pages one way or another. Sure, but these are not zero cost operations.... > Given that, the buffer allocation code > would fully populate the xfs_buf as it is today. The buffer I/O > submission code wouldn't really know the difference and shouldn't have > to change at all. The abstraction results in more expensive/complex setup and teardown of buffers and/or IO submission. i.e. the use of vmalloc() based abstractions has an additional cost over what we do now. [...] > Either way, it would require significantly more investigation/testing to > enable generic usage. The core point was really just to abstract the > nommu changes into something that potentially has generic use. I'm not saying that it is impossible to do this, just trying to work out if making any changes to support nommu architectures is worth the potential future trouble making such changes could bring us. i.e. before working out how to do something, we have to decide whether it is worth doing in the first place. Just because you can do something doesn't automatically make it a good idea.... Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Sun Nov 22 16:45:12 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 0FEC17F37 for ; Sun, 22 Nov 2015 16:45:12 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 5B5CDAC001 for ; Sun, 22 Nov 2015 14:45:08 -0800 (PST) X-ASG-Debug-ID: 1448232304-04cbb0605c1c2340001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id rQgyONIyu7krdESB for ; Sun, 22 Nov 2015 14:45:04 -0800 (PST) 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: A2BnBwDURFJW/1bELHlegzuBAEKCX6kjAQEGiz+FL4QNhgkCAgEBAoEjTQEBAQEBAYELhDQBAQEDATocGgkFCwgDEgYJJQ8FJQMNFBMbiAsHvXABAQgCIRmFdIQ/gQaEICSDYIEVBZZQjSiBZIRAgyWIF4p0Y4QYKjSDYggXgSoBAQE Received: from ppp121-44-196-86.lns20.syd7.internode.on.net (HELO dastard) ([121.44.196.86]) by ipmail07.adl2.internode.on.net with ESMTP; 23 Nov 2015 09:15:03 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1a0dNK-0004ND-MD; Mon, 23 Nov 2015 09:44:50 +1100 Date: Mon, 23 Nov 2015 09:44:50 +1100 From: Dave Chinner To: Octavian Purdila Cc: xfs , linux-fsdevel , lkml Subject: Re: [RFC PATCH] xfs: support for non-mmu architectures Message-ID: <20151122224450.GD26718@dastard> X-ASG-Orig-Subj: Re: [RFC PATCH] xfs: support for non-mmu architectures References: <1447800381-20167-1-git-send-email-octavian.purdila@intel.com> <20151119232455.GM14311@dastard> <20151120210833.GB26718@dastard> 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: 1448232304 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24635 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Sat, Nov 21, 2015 at 12:26:47AM +0200, Octavian Purdila wrote: > On Fri, Nov 20, 2015 at 11:08 PM, Dave Chinner wrote: > > On Fri, Nov 20, 2015 at 03:43:20PM +0200, Octavian Purdila wrote: > >> On Fri, Nov 20, 2015 at 1:24 AM, Dave Chinner wrote: > >> > On Wed, Nov 18, 2015 at 12:46:21AM +0200, Octavian Purdila wrote: > >> >> Naive implementation for non-mmu architectures: allocate physically > >> >> contiguous xfs buffers with alloc_pages. Terribly inefficient with > >> >> memory and fragmentation on high I/O loads but it may be good enough > >> >> for basic usage (which most non-mmu architectures will need). > >> > > >> > Can you please explain why you want to use XFS on low end, basic > >> > non-MMU devices? XFS is a high performance, enterprise/HPC level > >> > filesystem - it's not a filesystem designed for small IoT level > >> > devices - so I'm struggling to see why we'd want to expend any > >> > effort to make XFS work on such devices.... > >> > > >> > >> Hi David, > >> > >> Yes XFS as the main fs on this type of devices does not make sense, > >> but does it hurt to be able to perform basic operation on XFS from > >> these devices? Perhaps accessing an external medium formatted with > >> XFS? > >> > >> Another example is accessing VM images that are formatted with XFS. > >> Currently we can do that with tools like libguestfs that use a VM in > >> the background. I am working on a lighter solution for that where we > >> compile the Linux kernel as a library [1]. This allows access to the > >> filesystem without the need to use a full VM. > > > > That's hardly a "lighter solution" > > > > I'm kinda tired of the ongoing "hack random shit" approach to > > container development. > > Since apparently there is a container devs hunting party going on > right now, let me quickly confess that LKL has nothing to do with > (them be damned) containers :) > > On a more serious note, LKL was not developed for containers or to try > to circumvent privileged mounts. It was developed to allow the Linux > kernel code to be reused in things like simple tools that allows one > to modify a filesystem image. Anything tool that modifies an XFS filesystem that is not directly maintained by the XFS developers voids any kind of support we can supply. Just like the fact we don't support tainted kernels because the 3rd party binary code is unknowable (and usually crap), having the kernel code linked with random 3rd party userspace application code is completely unsupportable by us. Remember that with most kernel code a bug just results in a panic and reboot, and everything just continues on again after the system comes up again. In contrast, a bug in the storage code can cause *persistent damage* that can cause data loss or corruption that cannot be fixed without data loss of some kind. Ultimately, as the maintainer I'm responsible for XFS not eating our users' data, and part of that responsibility involves telling people who want to do daft things that "no, that's a *bad idea*". > > If you need a XFS-FUSE module to allow safe > > userspace access to XFS fielsystems then maybe, just maybe, it makes > > sense to ask the XFS developers how to best go about providing a > > reliable, up-to-date, tested, maintained and supported XFS-FUSE > > module? > > > > IOWs, a "lighter solution" is to use the libxfs code base that we > > already maintain across kernel and userspace in the xfsprogs package > > and write a FUSE wrapper around that. That, immediately, will give > > you full read-only access to XFS filesystem images via FUSE. Then we > > (the XFS developers) can test the XFS-FUSE module under normal > > development conditions as we modify the xfsprogs code base (e.g. via > > xfstests) and ensure we always release a working, up-to-date FUSE > > wrapper with each xfsprogs release. > > > > And then once a proper read-only FUSE wrapper has been written, then > > we can discuss what is necessary to enable write access via porting > > the necessary parts of the kernel code across to the userspace > > libxfs codebase and hooking them up to the FUSE API... > > > > Hmmm? > > > > What about ext4, vfat, btrfs and other filesystems? Ted has also raised exactly the same issues w.r.t. ext4. > Also why duplicate > the whole thing if you could reuse it? Do you use a hammer when you need to tighten a screw? Yes, you can "reuse a hammer" for this purpose, but there's going to be collateral damage because using the screw outside it's original design and architecture constraints presents a high risk of things going wrong. > >> And a final example is linking the bootloader code with LKL to access > >> the filesystem. This has a hard requirement on non-mmu. > > > > No way. We *can't* support filesystems that have had bootloaders > > make arbitrary changes to the filesystem without the knowlege of the > > OS that *owns the filesystem*. Similarly, we cannot support random > > applications that internally mount and modify filesystem images in > > ways we can't see, control, test or simulate. Sure, they use the > > kernel code, but that doesn't stop them from doing stupid shit that > > could corrupt the filesystem image. So, no, we are not going to > > support giving random applications direct access to XFS filesystem > > images, even via LKL. > > > > LKL only exports the Linux kernel system calls and nothing else to > applications. Because of that, there should not be any loss of control > or visibility to the XFS fs driver. It runs in the same address space as the user application, yes? And hence application bugs can cause the kernel code to malfunction, yes? > > I really don't see how using LKL to give userspace access to XFS > > filesystems is a better solution than actually writing a proper, > > supported XFS-FUSE module. LKL is so full of compromises that it's > > going to be unworkable and unsupportable in practice... > > Could you elaborate on some of these issues? Start with "is a no-mmu architecture" and all the compromises that means the kernel code needs to make, add a topping of "runs in the same address space as the application", add a new flavour of kernel binary taint and finish it off with "LKL linked applications will never be tested by their developers over the full functionality the LKL provides them with". Cheers, Dave. -- Dave Chinner david@fromorbit.com From octavian.purdila@intel.com Sun Nov 22 19:41:57 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 A5EFB7F37 for ; Sun, 22 Nov 2015 19:41:57 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 1EC10AC005 for ; Sun, 22 Nov 2015 17:41:56 -0800 (PST) X-ASG-Debug-ID: 1448242910-04cbb0605b1c4930001-NocioJ Received: from mail-wm0-f53.google.com (mail-wm0-f53.google.com [74.125.82.53]) by cuda.sgi.com with ESMTP id DdkSa6rRSmi39dUp (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Sun, 22 Nov 2015 17:41:50 -0800 (PST) X-Barracuda-Envelope-From: octavian.purdila@intel.com X-Barracuda-Apparent-Source-IP: 74.125.82.53 Received: by wmec201 with SMTP id c201so140279315wme.0 for ; Sun, 22 Nov 2015 17:41:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=intel-com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=XdW+OcpAgQ3CLXOQFvMDKRB93wRl7mDamFmEbSaqUFM=; b=13ROhxhTg9PjZUj1W/Sa7Bfi1LNF7YY4C507fVv2Bh+QzEaM3Tg8T6WWao84RDVMut YKjspwDCpgy47cvFGkRGwHj6YkaNef2pVn5BR0IHqPZOW2eJTjhenjrzoYyv5jxpauYu /FJxlx7c2V+crtE9ACcsdO2pHURjzsHXqAlsKUe+MDVUnW6RKg9ZID05lmD7H9QvGXyS wQQQXmYsLYBw6/YGsgJZSvlr1nVDRCkplZ8jj6/+BuhTs06/27VYyDY3qJD65fgnENXZ FMRsLRYO5DA+TPY9dLshwq1OhQ+opjg08lzlPoc0CoQGDR3HaoCSAYAgHeMeTCOEm1gZ OMYQ== 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=XdW+OcpAgQ3CLXOQFvMDKRB93wRl7mDamFmEbSaqUFM=; b=KYFFvgjz/vRVxp3IM9JH7KhcSvzwe0jULugL3yOikq4cZIufmF/Pw5qpW06/i0r9V6 TEm2t7Il1hm8AXHDK75YDqhBJNXghhPkXEkAlw7DWhzasOh1B24WfeAdqayYu0Evlgyd oz9WFXJU54rVYvUqQgylwE+j5snvcVpDxpfyDWsM1cULMwSN70RZIxt5BuVgSECuKRtt Ae/rvXul4Iol3sl9EeTv0Efn/QAXqda4B7FZcyGmz5tsplIHBnDo//T2tMrXf19/0bzz Df1Y/Hbp1dwBJJOuX9o3mJ1UXOfZM/ySOktYPyGtdfnUTdseqvHHdRZmfz7dg6KZr6pq hI9A== X-Gm-Message-State: ALoCoQluIZyp2k11JiWMVVfsDOyqVTvsYcb4PkxtXJ33kNnFZouoFEiiMAxb33PH+aUkV+RL9mNb MIME-Version: 1.0 X-Received: by 10.28.17.7 with SMTP id 7mr12477418wmr.45.1448242909721; Sun, 22 Nov 2015 17:41:49 -0800 (PST) Received: by 10.194.106.131 with HTTP; Sun, 22 Nov 2015 17:41:49 -0800 (PST) In-Reply-To: <20151122224450.GD26718@dastard> References: <1447800381-20167-1-git-send-email-octavian.purdila@intel.com> <20151119232455.GM14311@dastard> <20151120210833.GB26718@dastard> <20151122224450.GD26718@dastard> Date: Mon, 23 Nov 2015 03:41:49 +0200 Message-ID: Subject: Re: [RFC PATCH] xfs: support for non-mmu architectures From: Octavian Purdila X-ASG-Orig-Subj: Re: [RFC PATCH] xfs: support for non-mmu architectures To: Dave Chinner Cc: xfs , linux-fsdevel , lkml Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-wm0-f53.google.com[74.125.82.53] X-Barracuda-Start-Time: 1448242910 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24638 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 Mon, Nov 23, 2015 at 12:44 AM, Dave Chinner wrote: > On Sat, Nov 21, 2015 at 12:26:47AM +0200, Octavian Purdila wrote: >> On Fri, Nov 20, 2015 at 11:08 PM, Dave Chinner wrote: >> > On Fri, Nov 20, 2015 at 03:43:20PM +0200, Octavian Purdila wrote: >> >> On Fri, Nov 20, 2015 at 1:24 AM, Dave Chinner wrote: >> >> > On Wed, Nov 18, 2015 at 12:46:21AM +0200, Octavian Purdila wrote: >> >> >> Naive implementation for non-mmu architectures: allocate physically >> >> >> contiguous xfs buffers with alloc_pages. Terribly inefficient with >> >> >> memory and fragmentation on high I/O loads but it may be good enough >> >> >> for basic usage (which most non-mmu architectures will need). >> >> > >> >> > Can you please explain why you want to use XFS on low end, basic >> >> > non-MMU devices? XFS is a high performance, enterprise/HPC level >> >> > filesystem - it's not a filesystem designed for small IoT level >> >> > devices - so I'm struggling to see why we'd want to expend any >> >> > effort to make XFS work on such devices.... >> >> > >> >> >> >> Hi David, >> >> >> >> Yes XFS as the main fs on this type of devices does not make sense, >> >> but does it hurt to be able to perform basic operation on XFS from >> >> these devices? Perhaps accessing an external medium formatted with >> >> XFS? >> >> >> >> Another example is accessing VM images that are formatted with XFS. >> >> Currently we can do that with tools like libguestfs that use a VM in >> >> the background. I am working on a lighter solution for that where we >> >> compile the Linux kernel as a library [1]. This allows access to the >> >> filesystem without the need to use a full VM. >> > >> > That's hardly a "lighter solution" >> > >> > I'm kinda tired of the ongoing "hack random shit" approach to >> > container development. >> >> Since apparently there is a container devs hunting party going on >> right now, let me quickly confess that LKL has nothing to do with >> (them be damned) containers :) >> >> On a more serious note, LKL was not developed for containers or to try >> to circumvent privileged mounts. It was developed to allow the Linux >> kernel code to be reused in things like simple tools that allows one >> to modify a filesystem image. > > Anything tool that modifies an XFS filesystem that is not directly > maintained by the XFS developers voids any kind of support we can > supply. Just like the fact we don't support tainted kernels because > the 3rd party binary code is unknowable (and usually crap), having > the kernel code linked with random 3rd party userspace application > code is completely unsupportable by us. > Perhaps tainting the kernel is a solution when running unknown applications linked with LKL. I would argue that applications that are maintained together with LKL (e.g. lklfuse in tools/lkl) should not taint the kernel because those applications will be under the control of kernel developers. I would also argue that mounting a filesystem read-only should not taint the kernel either. > Remember that with most kernel code a bug just results in a panic > and reboot, and everything just continues on again after the system > comes up again. In contrast, a bug in the storage code can cause > *persistent damage* that can cause data loss or corruption that > cannot be fixed without data loss of some kind. > > Ultimately, as the maintainer I'm responsible for XFS not eating our > users' data, and part of that responsibility involves telling people > who want to do daft things that "no, that's a *bad idea*". > I understand how critical filesystem issues are and I appreciate your feedback. Sorry to drag you deeper into this but as you know, no good deed goes unpunished :) >> > If you need a XFS-FUSE module to allow safe >> > userspace access to XFS fielsystems then maybe, just maybe, it makes >> > sense to ask the XFS developers how to best go about providing a >> > reliable, up-to-date, tested, maintained and supported XFS-FUSE >> > module? >> > >> > IOWs, a "lighter solution" is to use the libxfs code base that we >> > already maintain across kernel and userspace in the xfsprogs package >> > and write a FUSE wrapper around that. That, immediately, will give >> > you full read-only access to XFS filesystem images via FUSE. Then we >> > (the XFS developers) can test the XFS-FUSE module under normal >> > development conditions as we modify the xfsprogs code base (e.g. via >> > xfstests) and ensure we always release a working, up-to-date FUSE >> > wrapper with each xfsprogs release. >> > >> > And then once a proper read-only FUSE wrapper has been written, then >> > we can discuss what is necessary to enable write access via porting >> > the necessary parts of the kernel code across to the userspace >> > libxfs codebase and hooking them up to the FUSE API... >> > >> > Hmmm? >> > >> >> What about ext4, vfat, btrfs and other filesystems? > > Ted has also raised exactly the same issues w.r.t. ext4. > >> Also why duplicate >> the whole thing if you could reuse it? > > Do you use a hammer when you need to tighten a screw? Yes, you can > "reuse a hammer" for this purpose, but there's going to be > collateral damage because using the screw outside it's original > design and architecture constraints presents a high risk of things > going wrong. > First, lets try to discuss the potential collateral damage before calling it a hammer. It may just be just an unfamiliar screw-driver :) >> >> And a final example is linking the bootloader code with LKL to access >> >> the filesystem. This has a hard requirement on non-mmu. >> > >> > No way. We *can't* support filesystems that have had bootloaders >> > make arbitrary changes to the filesystem without the knowlege of the >> > OS that *owns the filesystem*. Similarly, we cannot support random >> > applications that internally mount and modify filesystem images in >> > ways we can't see, control, test or simulate. Sure, they use the >> > kernel code, but that doesn't stop them from doing stupid shit that >> > could corrupt the filesystem image. So, no, we are not going to >> > support giving random applications direct access to XFS filesystem >> > images, even via LKL. >> > >> >> LKL only exports the Linux kernel system calls and nothing else to >> applications. Because of that, there should not be any loss of control >> or visibility to the XFS fs driver. > > It runs in the same address space as the user application, yes? And > hence application bugs can cause the kernel code to malfunction, > yes? > Most non-mmu architecture have the same issue and nevertheless non-mmu is still supported in Linux (including most filesystems). Also, filesystem code runs in the same address space with other kernel code and drivers and a bug anywhere in the kernel can cause filesystem code to malfunction. Applications maintained together with LKL and in the kernel tree will be as safe as drivers and other kernel code with regard to filesystem malfunctions. We can taint the kernel when LKL is linked with unknown applications. >> > I really don't see how using LKL to give userspace access to XFS >> > filesystems is a better solution than actually writing a proper, >> > supported XFS-FUSE module. LKL is so full of compromises that it's >> > going to be unworkable and unsupportable in practice... >> >> Could you elaborate on some of these issues? > > Start with "is a no-mmu architecture" and all the compromises that > means the kernel code needs to make, I don't see non-mmu as a compromise. It is supported by Linux and most filesystems work fine on non-mmu architectures. LKL can be implemented as a mmu architecture. Having it as a non-mmu architecture has the advantages of allowing it to run in more constrained environments like bootloaders. > add a topping of "runs in the > same address space as the application", I've addressed this concern above. > add a new flavour of kernel > binary taint I am not sure I understand, are you saying that it is an issue to add a new taint flavor? > and finish it off with "LKL linked applications will > never be tested by their developers over the full functionality the > LKL provides them with". > You lost me here. Why does an application developer have to test the full functionality of a library it is linked with? From david@fromorbit.com Sun Nov 22 22:45:10 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 4200C7F37 for ; Sun, 22 Nov 2015 22:45:10 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 0A5E48F8039 for ; Sun, 22 Nov 2015 20:45:09 -0800 (PST) X-ASG-Debug-ID: 1448253901-04bdf07f071e6420001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id 128A51nZ99BDDkBw for ; Sun, 22 Nov 2015 20:45:01 -0800 (PST) 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: A2AQBwCumFJW/1bELHlegzsjMG+CX6kJAgEJEAEBBoENijIhhQ6EDRcChXAEgTJNAQEBAQEBgQuFETskNAUlAzSILZ4Kn3AJGYV0iDaESgxBgTEFh0eFV4kyhSSIBIFkSYxDhQ+IVWOBSgsBAQGCQCo0AQEBAYUnAQEB Received: from ppp121-44-196-86.lns20.syd7.internode.on.net (HELO dastard) ([121.44.196.86]) by ipmail07.adl2.internode.on.net with ESMTP; 23 Nov 2015 15:14:59 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1a0ize-0004qg-Ti for xfs@oss.sgi.com; Mon, 23 Nov 2015 15:44:46 +1100 Date: Mon, 23 Nov 2015 15:44:46 +1100 From: Dave Chinner To: xfs@oss.sgi.com Subject: [ANNOUNCE] xfsprogs: v4.3.0 released Message-ID: <20151123044446.GL19199@dastard> X-ASG-Orig-Subj: [ANNOUNCE] xfsprogs: v4.3.0 released MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="jTMWTj4UTAEmbWeb" 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: 1448253901 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24641 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- --jTMWTj4UTAEmbWeb Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Hi folks, The xfsprogs repositories have just been updated and tagged with the v4.3.0 release tag. It can be found here: git://oss.sgi.com/xfs/cmds/xfsprogs.git v4.3.0 git://git.kernel.org/pub/scm/fs/xfs/xfsprogs-dev.git v4.3.0 A signed gzipped-tar archive of the source code is available here: ftp://oss.sgi.com/projects/xfs/cmd_tars/xfsprogs-4.3.0.tar.gz ftp://oss.sgi.com/projects/xfs/cmd_tars/xfsprogs-4.3.0.tar.gz.sign The archive is signed with my gpg key (the same one that this release announcement is signed with). Many thanks go to all the contributors to this release. The sumary of changes since v4.2.0 can be found listed in doc/CHANGES, which I have reproduced in part below. -Dave. xfsprogs-4.3.0 (23 Nov 2015) - xfs_fsr: cleanups to recent changes (Eric Sandeen) - xfs_fsr: improved temp file attr fork handling (Eric Sandeen) - libxfs: output verifier names in warnings (Eric Sandeen) - xfs_repair: enable verifier corruption warnings on very verbose output settings (Eric Sandeen) - debian: update initramfs in postinst script (Steve McIntyre) xfsprogs-4.3.0-rc2 (10 Nov 2015) - xfs_fsr: abstract mntinfo/mntent differences (Jan Tulak) - xfs_io: update reflink/dedupe ioctl definitions and implementation (Darrick Wong) - libxcmd: factoring of runtime reporting (Darrick Wong) - man page fixes (Ville Skytt=E4) - removal of ASSERT from exported headers xfsprogs-4.3.0-rc1 (14 Oct 2015) - xfs_io: reflink and dedupe operation support (Darrick Wong) - xfs_db: blockget/blocktrash support for v5 filesystems (Darrick Wong) - xfs_repair: many directory/attr cleanups and fixes (Eric Sandeen) - More OS X build improvements (Jan Tulak) - Log zeroing rework for v5 filesystems to prevent log sequence numbers from going backwards (Brain Foster) The new head of the master branch is commit: 2c909e1 xfsprogs: Release v4.3.0 New Commits since 4.3.0-rc2: Dave Chinner (2): [a32546b] fsr: clean up mountpoint checks [2c909e1] xfsprogs: Release v4.3.0 Eric Sandeen (4): [7849d55] fsr: more tidy up work [e7e3152] fsr: more selinux fixes [a3fac93] libxfs: print name of verifier if it fails [23639f7] repair: print XFS_WANT_CORRUPTED info with -vvv Steve McIntyre (1): [c8b04a6] debian: update initramfs in postinst Code Diffstat: VERSION | 2 +- configure.ac | 2 +- db/attr.c | 1 + db/dir2.c | 1 + db/metadump.c | 3 +- debian/changelog | 8 +++++ debian/postinst | 25 +++++++++++++ doc/CHANGES | 10 +++++- fsr/xfs_fsr.c | 87 +++++++++++++++++------------------------= ---- include/xfs_mount.h | 1 + libxfs/libxfs_io.h | 1 + libxfs/libxfs_priv.h | 23 +++++++++--- libxfs/rdwr.c | 5 +-- libxfs/util.c | 4 +-- libxfs/xfs_alloc.c | 2 ++ libxfs/xfs_alloc_btree.c | 1 + libxfs/xfs_attr_leaf.c | 1 + libxfs/xfs_attr_remote.c | 1 + libxfs/xfs_bmap_btree.c | 1 + libxfs/xfs_da_btree.c | 1 + libxfs/xfs_dir2_block.c | 1 + libxfs/xfs_dir2_data.c | 2 ++ libxfs/xfs_dir2_leaf.c | 2 ++ libxfs/xfs_dir2_node.c | 1 + libxfs/xfs_dquot_buf.c | 1 + libxfs/xfs_ialloc.c | 1 + libxfs/xfs_ialloc_btree.c | 1 + libxfs/xfs_inode_buf.c | 2 ++ libxfs/xfs_sb.c | 2 ++ libxfs/xfs_symlink_remote.c | 1 + man/man8/xfs_repair.8 | 2 +- repair/xfs_repair.c | 4 +++ 32 files changed, 132 insertions(+), 68 deletions(-) create mode 100644 debian/postinst --=20 Dave Chinner david@fromorbit.com --jTMWTj4UTAEmbWeb Content-Type: application/pgp-signature; name="signature.asc" Content-Description: Digital signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQIcBAEBAgAGBQJWUpm+AAoJEK3oKUf0dfodmA0P/1s9CgE2RDuZFAtUuc41AY3E s4/7vc4y8vdNccEz/Jbz9kkTYJdEjon0wKcLo+pvYKXeaLcPqa5Y0VH/ywCoYxMz WHgjL+IHXBFoQCi6agwXgdmD6hXe0NAyIUX376eh7HezDph5rvUK34gYHZG5zoCZ s78gw7GnIFvw+F9YnOWgpNAkXaI074YhtkC5uJn7K7r7ufyMtEoEZGLhq+yO8y26 CLtkKqaQO2b1e7TiZHfw8O+yF344iPegYnEQicBL03u6LfTlW48mkOkIoo9L+Txc EJ2XGgnMMwcIc/SSTQXsDCvOQN3H/zUGn1QNZ/yzwGEl71OndaswobZKaCNKMg2E iWNFMOWYUBPTfwieCLHQTBWKWmPHpMUXyL0xSzb7fiCmlHyN+bxJKR2YI7Upezpp F+YmLshs6ReYvl96l/KglNF4MHKMhdvKj73fRIW25VEW96N144hfYZECwVoi8vTq w/l3NA50LunUBwAh0ch6QQNxQxTyHsu3jYssHnHo7BOPIsBBEph3yVinCQ6taCTv YNqJAXQRv5bkfuxv6g1TVsd06G7Tom6LMUjcCoUwGDd5J6b0gfjz05iXRf6+vlFo NYsjViLw1EZBS25zlNJKu7LZKs45bk3xcoLZvHbc/VUjjLv8Gm8chy9M8GCiN4dY 3UEZqD2l+vgsBf2f5PsU =f5Af -----END PGP SIGNATURE----- --jTMWTj4UTAEmbWeb-- From lvml@5t9.de Mon Nov 23 05:06:08 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 C52C47F37 for ; Mon, 23 Nov 2015 05:06:08 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id B4500304039 for ; Mon, 23 Nov 2015 03:06:05 -0800 (PST) X-ASG-Debug-ID: 1448276761-04cbb0605c1ce700001-NocioJ Received: from app1b.xlhost.de (mailout173.xlhost.de [84.200.252.173]) by cuda.sgi.com with ESMTP id qIV9tJGdGTEm3Dhg for ; Mon, 23 Nov 2015 03:06:02 -0800 (PST) X-Barracuda-Envelope-From: lvml@5t9.de X-Barracuda-Apparent-Source-IP: 84.200.252.173 Received: from [192.168.5.53] (barriere.frankfurter-softwarefabrik.de [217.11.197.1]) (Authenticated sender: lkv@5t9.de) by app1b.xlhost.de (Postfix) with ESMTPSA id 548303000AEC for ; Mon, 23 Nov 2015 12:05:59 +0100 (CET) Message-ID: <5652F311.7000406@5t9.de> Date: Mon, 23 Nov 2015 12:05:53 +0100 From: Lutz Vieweg User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.2.0 MIME-Version: 1.0 To: xfs@oss.sgi.com Subject: Does XFS support cgroup writeback limiting? Content-Type: text/plain; charset=utf-8; format=flowed X-ASG-Orig-Subj: Does XFS support cgroup writeback limiting? Content-Transfer-Encoding: 7bit X-Virus-Scanned: clamav-milter 0.98.1 at app1b.xlhost.de X-Virus-Status: Clean X-Barracuda-Connect: mailout173.xlhost.de[84.200.252.173] X-Barracuda-Start-Time: 1448276762 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24647 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Hi, in June 2015 the article https://lwn.net/Articles/648292/ mentioned upcoming support for limiting the quantity of buffered writes using control groups. Back then, only ext4 was said to support that feature, with other filesystems requiring some minor changes to do the same. The generic cgroup writeback support made it into mainline linux-4.2, I tried to find information on whether other filesystems had meanwhile been adapted, but couldn't find this piece of information. Therefore I'd like to ask: Does XFS (as of linux-4.3 or linux-4.4) support limiting the quantity of buffered writes using control groups? Regards, Lutz Vieweg From bfoster@redhat.com Mon Nov 23 06:50:07 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 8512E7F37 for ; Mon, 23 Nov 2015 06:50:07 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 0F2C0AC002 for ; Mon, 23 Nov 2015 04:50:03 -0800 (PST) X-ASG-Debug-ID: 1448283001-04cbb0605b1d0f00001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id TYdWk4G5QeYHX7Os (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 23 Nov 2015 04:50:02 -0800 (PST) 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 (Postfix) with ESMTPS id A6A9B3B757; Mon, 23 Nov 2015 12:50:01 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-225.bos.redhat.com [10.18.41.225]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tANCo1Qf017644; Mon, 23 Nov 2015 07:50:01 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id 5D9BE122406; Mon, 23 Nov 2015 07:50:00 -0500 (EST) Date: Mon, 23 Nov 2015 07:50:00 -0500 From: Brian Foster To: Dave Chinner Cc: linux-fsdevel@vger.kernel.org, Octavian Purdila , linux-kernel@vger.kernel.org, xfs@oss.sgi.com Subject: Re: [RFC PATCH] xfs: support for non-mmu architectures Message-ID: <20151123124959.GA58452@bfoster.bfoster> X-ASG-Orig-Subj: Re: [RFC PATCH] xfs: support for non-mmu architectures References: <1447800381-20167-1-git-send-email-octavian.purdila@intel.com> <20151119155525.GB13055@bfoster.bfoster> <20151119233547.GN14311@dastard> <20151120151118.GB60886@bfoster.bfoster> <20151120203602.GA26718@dastard> <20151120224734.GA28795@bfoster.bfoster> <20151122220400.GC26718@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151122220400.GC26718@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: 1448283002 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Mon, Nov 23, 2015 at 09:04:00AM +1100, Dave Chinner wrote: > On Fri, Nov 20, 2015 at 05:47:34PM -0500, Brian Foster wrote: > > On Sat, Nov 21, 2015 at 07:36:02AM +1100, Dave Chinner wrote: > > > On Fri, Nov 20, 2015 at 10:11:19AM -0500, Brian Foster wrote: > > > > On Fri, Nov 20, 2015 at 10:35:47AM +1100, Dave Chinner wrote: > > > > Those latter calls are all from following down through the > > > > map_vm_area()->vmap_page_range() codepath from __vmalloc_area_node(). We > > > > call vm_map_ram() directly from _xfs_buf_map_pages(), which itself calls > > > > down into the same code. Indeed, we already protect ourselves here via > > > > the same memalloc_noio_save() mechanism that kmem_zalloc_large() uses. > > > > > > Yes, we do, but that is separately handled to the allocation of the > > > pages, which we have to do for all types of buffers, mapped or > > > unmapped, because xfs_buf_ioapply_map() requires direct access to > > > the underlying pages to build the bio for IO. If we delegate the > > > allocation of pages to vmalloc, we don't have direct reference to > > > the underlying pages and so we have to do something completely > > > diffferent to build the bios for the buffer.... > > > > > > > Octavian points out virt_to_page() in a previous mail. I'm not sure > > that's the right interface solely based on looking at some current > > callers, but there is vmalloc_to_page() so I'd expect we can gain access > > to the pages one way or another. > > Sure, but these are not zero cost operations.... > > > Given that, the buffer allocation code > > would fully populate the xfs_buf as it is today. The buffer I/O > > submission code wouldn't really know the difference and shouldn't have > > to change at all. > > The abstraction results in more expensive/complex setup and teardown > of buffers and/or IO submission. i.e. the use of vmalloc() based > abstractions has an additional cost over what we do now. > > [...] > Yeah, most likely. The vmalloc based lookup certainly looks more involved than if the pages are already readily accessible. How much more expensive (and whether it's noticeable enough to care) is probably a matter of testing. I think the code itself could end up much more simple, however. There's still a lot of duplication in our current implementation that afaiu right now only continues to exist due to the performance advantages of vm_map_ram(). > > Either way, it would require significantly more investigation/testing to > > enable generic usage. The core point was really just to abstract the > > nommu changes into something that potentially has generic use. > > I'm not saying that it is impossible to do this, just trying to work > out if making any changes to support nommu architectures is worth > the potential future trouble making such changes could bring us. > i.e. before working out how to do something, we have to decide > whether it is worth doing in the first place. > > Just because you can do something doesn't automatically make it a > good idea.... > Sure, good point. I've intentionally been sticking to the technical points that have been raised (and I think we've covered it thoroughly to this point ;). FWIW, I agree with most of the concerns that have been called out in the thread so far, but the support question ultimately sounds moot to me. We can reject the "configuration" enabled by this particular patch, but afaik this LKL thing could just go and implement an mmu mode and fundamentally do what it's trying to do today. If it's useful, users will use it, ultimately hit bugs, and we'll have to deal with it one way or another. Note that I'm not saying we have to support LKL. Rather, I view it as equivalent to somebody off running some new non-standard/uncommon architecture (or maybe a hypervisor is a better example in this case). If the user runs into some low-level filesystem issue, the user probably needs to get through whatever levels of support exist for that special architecture/environment first and/or otherwise work with us to find a reproducer on something more standard that we all have easy access to. Just my .02, though. :) Brian > Cheers, > > Dave. > -- > Dave Chinner > david@fromorbit.com > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From david@fromorbit.com Mon Nov 23 14:26:37 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 A2FAA7F37 for ; Mon, 23 Nov 2015 14:26:37 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 33876AC002 for ; Mon, 23 Nov 2015 12:26:36 -0800 (PST) X-ASG-Debug-ID: 1448310392-04cbb0605d1dc4b0001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id 9f4emtaorCBifFBH for ; Mon, 23 Nov 2015 12:26:33 -0800 (PST) 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: A2BeBwCAdVNW/1bELHlegztTb4JfqSsGBos/iTwdhWwEAgKBSE0BAQEBAQGBC4Q0AQEBAwE6HCMFCwgDDgoJJQ8FJQMhE4gmB79BAQEBAQYBAQEBGwQZhXSFRYgkgRUFllCFJIgEnFRjghEdgWoqNINjJYEjAQEB Received: from ppp121-44-196-86.lns20.syd7.internode.on.net (HELO dastard) ([121.44.196.86]) by ipmail07.adl2.internode.on.net with ESMTP; 24 Nov 2015 06:56:31 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1a0xgp-0006pn-7T; Tue, 24 Nov 2015 07:26:19 +1100 Date: Tue, 24 Nov 2015 07:26:19 +1100 From: Dave Chinner To: Lutz Vieweg Cc: xfs@oss.sgi.com Subject: Re: Does XFS support cgroup writeback limiting? Message-ID: <20151123202619.GE26718@dastard> X-ASG-Orig-Subj: Re: Does XFS support cgroup writeback limiting? References: <5652F311.7000406@5t9.de> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <5652F311.7000406@5t9.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: 1448310392 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24658 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Mon, Nov 23, 2015 at 12:05:53PM +0100, Lutz Vieweg wrote: > Hi, > > in June 2015 the article https://lwn.net/Articles/648292/ mentioned > upcoming support for limiting the quantity of buffered writes > using control groups. > > Back then, only ext4 was said to support that feature, with other > filesystems requiring some minor changes to do the same. Yes, changing the kernel code to support this functionality is about 3 lines of code. however.... > The generic cgroup writeback support made it into mainline > linux-4.2, I tried to find information on whether other filesystems > had meanwhile been adapted, but couldn't find this piece of information. > > Therefore I'd like to ask: Does XFS (as of linux-4.3 or linux-4.4) > support limiting the quantity of buffered writes using control groups? .... I haven't added support to XFS because I have no way of verifying the functionality works and that it continues to work as it is intended. i.e. we have no regression test coverage for cgroup aware writeback and until someone writes a set of regression tests that validate it's functionality works correctly it will remain this way. Writing code is trivial. Validating the code actually works as intended and doesn't silently get broken in the future is the hard part.... Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Mon Nov 23 15:00:29 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 9B6C07F37 for ; Mon, 23 Nov 2015 15:00:29 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 87F90304039 for ; Mon, 23 Nov 2015 13:00:29 -0800 (PST) X-ASG-Debug-ID: 1448312425-04cbb0605c1dd0c0001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id A7ZL06xJ2LdEV4zZ for ; Mon, 23 Nov 2015 13:00:25 -0800 (PST) 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: A2BgBwB7fVNW/1bELHlegztTb4JfqSsGBos/iTwXCoVoBAICgUhNAQEBAQEBgQuENAEBAQMBAQEBJBMcFgIIAwULCAMOBAYJJQ8FExIDDRQTiCYHDr8zAQEBBwIBIBmFdIVFgnGBSgEBg2eBFQWFT5EBhSSFVIIwgWSEQJYwY4IRHYFqKjSDaoFBAQEB Received: from ppp121-44-196-86.lns20.syd7.internode.on.net (HELO dastard) ([121.44.196.86]) by ipmail07.adl2.internode.on.net with ESMTP; 24 Nov 2015 07:30:24 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1a0yDb-0006xk-Gi; Tue, 24 Nov 2015 08:00:11 +1100 Date: Tue, 24 Nov 2015 08:00:11 +1100 From: Dave Chinner To: Brian Foster Cc: linux-fsdevel@vger.kernel.org, Octavian Purdila , linux-kernel@vger.kernel.org, xfs@oss.sgi.com Subject: Re: [RFC PATCH] xfs: support for non-mmu architectures Message-ID: <20151123210011.GF26718@dastard> X-ASG-Orig-Subj: Re: [RFC PATCH] xfs: support for non-mmu architectures References: <1447800381-20167-1-git-send-email-octavian.purdila@intel.com> <20151119155525.GB13055@bfoster.bfoster> <20151119233547.GN14311@dastard> <20151120151118.GB60886@bfoster.bfoster> <20151120203602.GA26718@dastard> <20151120224734.GA28795@bfoster.bfoster> <20151122220400.GC26718@dastard> <20151123124959.GA58452@bfoster.bfoster> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151123124959.GA58452@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: 1448312425 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24659 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Mon, Nov 23, 2015 at 07:50:00AM -0500, Brian Foster wrote: > On Mon, Nov 23, 2015 at 09:04:00AM +1100, Dave Chinner wrote: > > On Fri, Nov 20, 2015 at 05:47:34PM -0500, Brian Foster wrote: > > > On Sat, Nov 21, 2015 at 07:36:02AM +1100, Dave Chinner wrote: > > > > On Fri, Nov 20, 2015 at 10:11:19AM -0500, Brian Foster wrote: > > > > > On Fri, Nov 20, 2015 at 10:35:47AM +1100, Dave Chinner wrote: > > > > > Those latter calls are all from following down through the > > > > > map_vm_area()->vmap_page_range() codepath from __vmalloc_area_node(). We > > > > > call vm_map_ram() directly from _xfs_buf_map_pages(), which itself calls > > > > > down into the same code. Indeed, we already protect ourselves here via > > > > > the same memalloc_noio_save() mechanism that kmem_zalloc_large() uses. > > > > > > > > Yes, we do, but that is separately handled to the allocation of the > > > > pages, which we have to do for all types of buffers, mapped or > > > > unmapped, because xfs_buf_ioapply_map() requires direct access to > > > > the underlying pages to build the bio for IO. If we delegate the > > > > allocation of pages to vmalloc, we don't have direct reference to > > > > the underlying pages and so we have to do something completely > > > > diffferent to build the bios for the buffer.... > > > > > > > > > > Octavian points out virt_to_page() in a previous mail. I'm not sure > > > that's the right interface solely based on looking at some current > > > callers, but there is vmalloc_to_page() so I'd expect we can gain access > > > to the pages one way or another. > > > > Sure, but these are not zero cost operations.... > > > > > Given that, the buffer allocation code > > > would fully populate the xfs_buf as it is today. The buffer I/O > > > submission code wouldn't really know the difference and shouldn't have > > > to change at all. > > > > The abstraction results in more expensive/complex setup and teardown > > of buffers and/or IO submission. i.e. the use of vmalloc() based > > abstractions has an additional cost over what we do now. > > > > [...] > > > > Yeah, most likely. The vmalloc based lookup certainly looks more > involved than if the pages are already readily accessible. How much more > expensive (and whether it's noticeable enough to care) is probably a > matter of testing. I think the code itself could end up much more > simple, however. There's still a lot of duplication in our current > implementation that afaiu right now only continues to exist due to the > performance advantages of vm_map_ram(). Yup. The historical problem here is that the mm/ people are not really interested in making vmalloc() scale/perform better. We are always told that if you need vmalloc() you are doing something wrong, and so vmalloc() doesn't need improving. The same reason is generally given for not making vmalloc handle GFP flags properly, so we're really stuck between a rock and a hard place here. > > > Either way, it would require significantly more investigation/testing to > > > enable generic usage. The core point was really just to abstract the > > > nommu changes into something that potentially has generic use. > > > > I'm not saying that it is impossible to do this, just trying to work > > out if making any changes to support nommu architectures is worth > > the potential future trouble making such changes could bring us. > > i.e. before working out how to do something, we have to decide > > whether it is worth doing in the first place. > > > > Just because you can do something doesn't automatically make it a > > good idea.... > > Sure, good point. I've intentionally been sticking to the technical > points that have been raised (and I think we've covered it thoroughly to > this point ;). *nod* > FWIW, I agree with most of the concerns that have been called out in the > thread so far, but the support question ultimately sounds moot to me. We > can reject the "configuration" enabled by this particular patch, but > afaik this LKL thing could just go and implement an mmu mode and > fundamentally do what it's trying to do today. If it's useful, users > will use it, ultimately hit bugs, and we'll have to deal with it one way > or another. Right, but we need to set expectations appropriately now, before we have users that depend on something we can't sanely support.... > Note that I'm not saying we have to support LKL. Rather, I view it as > equivalent to somebody off running some new non-standard/uncommon > architecture (or maybe a hypervisor is a better example in this case). Right, but we don't support every possible kernel/device out there with XFS. Up to now, no-mmu devices have been small, embedded systems that can't/won't fit XFS in their flash/RAM because of space/cost/need and so we've been able to completely ignore the issues such platforms have. We really don't pay much attention to 32 bit systems anymore, and no-mmu is much, much further down the list of "users who need XFS" than 32 bit arches.... > If the user runs into some low-level filesystem issue, the user probably > needs to get through whatever levels of support exist for that special > architecture/environment first and/or otherwise work with us to find a > reproducer on something more standard that we all have easy access to. > Just my .02, though. :) The biggest problem we have is that the kernel might be tripping over a problem introduced by some broken version of an app linked against some old version of LKL. That's my biggest worry here - it's not that LKL uses kernel code, it's that we no longer have any idea of what code has been modifying the filesystem nor any easy way of finding out. And we all know how hard it can be to get a straight answer to "explain exactly what you did" from bug reporters... Sure, once we *know* that the filesystem was modified by a random userspace application, we can say "please reproduce with a vanilla kernel", but it's getting to that point that can be problematic. This is why I think a proper FUSE module implemented on top of the userspace libxfs and is built as part of xfsprogs is a much better way give users userspace access to XFS filesystems. We can develop and support that directly, knowing exactly what code users are running and having a relatively controlled environment the filesystem code is running in.... Cheers, Dave. > > Brian > > > Cheers, > > > > Dave. > > -- > > Dave Chinner > > david@fromorbit.com > > > > _______________________________________________ > > xfs mailing list > > xfs@oss.sgi.com > > http://oss.sgi.com/mailman/listinfo/xfs > -- Dave Chinner david@fromorbit.com From darrick.wong@oracle.com Mon Nov 23 15:26:11 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 8F5A27F37 for ; Mon, 23 Nov 2015 15:26:11 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 7101F304059 for ; Mon, 23 Nov 2015 13:26:08 -0800 (PST) X-ASG-Debug-ID: 1448313965-04bdf07f071fe210001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id FLEmMqzQGNNfVElq (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 23 Nov 2015 13:26:05 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tANLPZba010821 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Mon, 23 Nov 2015 21:25:36 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id tANLPZm8006934 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Mon, 23 Nov 2015 21:25:35 GMT Received: from abhmp0015.oracle.com (abhmp0015.oracle.com [141.146.116.21]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id tANLPZ5B008255; Mon, 23 Nov 2015 21:25:35 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Mon, 23 Nov 2015 13:25:34 -0800 Date: Mon, 23 Nov 2015 13:25:33 -0800 From: "Darrick J. Wong" To: Christoph Hellwig Cc: david@fromorbit.com, fstests@vger.kernel.org, xfs@oss.sgi.com, tao.peng@primarydata.com, linux-ext4@vger.kernel.org, Anna.Schumaker@netapp.com, linux-btrfs@vger.kernel.org Subject: Re: [PATCH 2/2] generic/15[78]: fix error messages in the golden output Message-ID: <20151123212533.GC10589@birch.djwong.org> X-ASG-Orig-Subj: Re: [PATCH 2/2] generic/15[78]: fix error messages in the golden output References: <20151121005001.20398.92856.stgit@birch.djwong.org> <20151121005014.20398.22316.stgit@birch.djwong.org> <20151121180644.GA23916@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151121180644.GA23916@infradead.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-Source-IP: userv0021.oracle.com [156.151.31.71] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1448313965 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/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, UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24661 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.60 MARKETING_SUBJECT Subject contains popular marketing words 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines On Sat, Nov 21, 2015 at 10:06:44AM -0800, Christoph Hellwig wrote: > > --- a/tests/generic/158.out > > +++ b/tests/generic/158.out > > Try to dedupe a device > > -XFS_IOC_FILE_EXTENT_SAME: Permission denied > > +XFS_IOC_FILE_EXTENT_SAME: Invalid argument > > Try to dedupe to a dir > > -/mnt/test-158/dir1: Is a directory > > +TEST_DIR/test-158/dir1: Is a directory > > Try to dedupe to a device > > -dedupe: Permission denied > > +dedupe: Operation not supported > > Try to dedupe to a fifo > > -dedupe: Permission denied > > +dedupe: Operation not supported > > Shouldn't these be Invalid argument just like the > to a device case above or the clone case? I was trying to mirror the behavior of reflink, which spits out EOPNOTSUPP when the destination isn't a regular file and EINVAL when the source isn't a regular file. --D > > Otherwise looks good, > > Reviewed-by: Christoph Hellwig From david@fromorbit.com Mon Nov 23 15:46:40 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 2FD7E7F37 for ; Mon, 23 Nov 2015 15:46:40 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 1FFCB8F8035 for ; Mon, 23 Nov 2015 13:46:37 -0800 (PST) X-ASG-Debug-ID: 1448315193-04cb6c0cd11a91e0001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id W8nvdqRAte1EoXXq for ; Mon, 23 Nov 2015 13:46:33 -0800 (PST) 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: A2C3BwA0iFNW/1bELHlegzuBAEKCX6krBgaLP4UvhA2GCQICAQECgUhNAQEBAQEBgQuENAEBAQMBOhwaCQULCAMSBgklDwUlAw0UExuICwe/RQELASAZhXSFRYQgHgaEdQWWUIp4gjCBZBaEKoMliBeKdGOCER2Baio0g2IIF4EqAQEB Received: from ppp121-44-196-86.lns20.syd7.internode.on.net (HELO dastard) ([121.44.196.86]) by ipmail07.adl2.internode.on.net with ESMTP; 24 Nov 2015 08:16:32 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1a0ywF-00073S-BM; Tue, 24 Nov 2015 08:46:19 +1100 Date: Tue, 24 Nov 2015 08:46:19 +1100 From: Dave Chinner To: Octavian Purdila Cc: xfs , linux-fsdevel , lkml Subject: Re: [RFC PATCH] xfs: support for non-mmu architectures Message-ID: <20151123214619.GG26718@dastard> X-ASG-Orig-Subj: Re: [RFC PATCH] xfs: support for non-mmu architectures References: <1447800381-20167-1-git-send-email-octavian.purdila@intel.com> <20151119232455.GM14311@dastard> <20151120210833.GB26718@dastard> <20151122224450.GD26718@dastard> 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: 1448315193 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24660 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Mon, Nov 23, 2015 at 03:41:49AM +0200, Octavian Purdila wrote: > On Mon, Nov 23, 2015 at 12:44 AM, Dave Chinner wrote: > > On Sat, Nov 21, 2015 at 12:26:47AM +0200, Octavian Purdila wrote: > >> On Fri, Nov 20, 2015 at 11:08 PM, Dave Chinner wrote: > >> > On Fri, Nov 20, 2015 at 03:43:20PM +0200, Octavian Purdila wrote: > >> >> On Fri, Nov 20, 2015 at 1:24 AM, Dave Chinner wrote: > >> >> > On Wed, Nov 18, 2015 at 12:46:21AM +0200, Octavian Purdila wrote: > >> >> >> Naive implementation for non-mmu architectures: allocate physically > >> >> >> contiguous xfs buffers with alloc_pages. Terribly inefficient with > >> >> >> memory and fragmentation on high I/O loads but it may be good enough > >> >> >> for basic usage (which most non-mmu architectures will need). > >> >> > > >> >> > Can you please explain why you want to use XFS on low end, basic > >> >> > non-MMU devices? XFS is a high performance, enterprise/HPC level > >> >> > filesystem - it's not a filesystem designed for small IoT level > >> >> > devices - so I'm struggling to see why we'd want to expend any > >> >> > effort to make XFS work on such devices.... > >> >> > > >> >> > >> >> Hi David, > >> >> > >> >> Yes XFS as the main fs on this type of devices does not make sense, > >> >> but does it hurt to be able to perform basic operation on XFS from > >> >> these devices? Perhaps accessing an external medium formatted with > >> >> XFS? > >> >> > >> >> Another example is accessing VM images that are formatted with XFS. > >> >> Currently we can do that with tools like libguestfs that use a VM in > >> >> the background. I am working on a lighter solution for that where we > >> >> compile the Linux kernel as a library [1]. This allows access to the > >> >> filesystem without the need to use a full VM. > >> > > >> > That's hardly a "lighter solution" > >> > > >> > I'm kinda tired of the ongoing "hack random shit" approach to > >> > container development. > >> > >> Since apparently there is a container devs hunting party going on > >> right now, let me quickly confess that LKL has nothing to do with > >> (them be damned) containers :) > >> > >> On a more serious note, LKL was not developed for containers or to try > >> to circumvent privileged mounts. It was developed to allow the Linux > >> kernel code to be reused in things like simple tools that allows one > >> to modify a filesystem image. > > > > Anything tool that modifies an XFS filesystem that is not directly > > maintained by the XFS developers voids any kind of support we can > > supply. Just like the fact we don't support tainted kernels because > > the 3rd party binary code is unknowable (and usually crap), having > > the kernel code linked with random 3rd party userspace application > > code is completely unsupportable by us. > > > > Perhaps tainting the kernel is a solution when running unknown > applications linked with LKL. It's not the *kernel* that is the problem - it is LKL that is the tainted code! > I would argue that applications that are maintained together with LKL > (e.g. lklfuse in tools/lkl) should not taint the kernel because those > applications will be under the control of kernel developers. I completely disagree. Just because the code is in the kernel tree, it doesn't mean it's controlled, reviewed, tested or maintained by the relevant subsystem maintainers. If the subsystem maintainers are not actively maintaining/testing those tools, then users can't expect the subsystem maintainers to support them. > I would > also argue that mounting a filesystem read-only should not taint the > kernel either. LKL != kernel. > >> >> And a final example is linking the bootloader code with LKL to access > >> >> the filesystem. This has a hard requirement on non-mmu. > >> > > >> > No way. We *can't* support filesystems that have had bootloaders > >> > make arbitrary changes to the filesystem without the knowlege of the > >> > OS that *owns the filesystem*. Similarly, we cannot support random > >> > applications that internally mount and modify filesystem images in > >> > ways we can't see, control, test or simulate. Sure, they use the > >> > kernel code, but that doesn't stop them from doing stupid shit that > >> > could corrupt the filesystem image. So, no, we are not going to > >> > support giving random applications direct access to XFS filesystem > >> > images, even via LKL. > >> > > >> > >> LKL only exports the Linux kernel system calls and nothing else to > >> applications. Because of that, there should not be any loss of control > >> or visibility to the XFS fs driver. > > > > It runs in the same address space as the user application, yes? And > > hence application bugs can cause the kernel code to malfunction, > > yes? > > > > Most non-mmu architecture have the same issue and nevertheless non-mmu > is still supported in Linux (including most filesystems). That doesn't mean all subsystems in the kernel support users on non-mmu systems. > Also, filesystem code runs in the same address space with other kernel > code and drivers and a bug anywhere in the kernel can cause filesystem > code to malfunction. Well, yes, but we have trust other kernel developers keep their ship in good shape, too. But we don't trust *out of tree code* - that taints the kernel and most upstream kernel developers will notice such taints when there are weird errors being reported.... But you want to extend that trust to whatever random code gets chucked into tools/lkl. I'm stretched far enough already having to keep up with mm, VFS, locking and filesystem developments that I don't have time to keep up with what LKL is doing or what applications people are writing. You're not going to get subsystem maintainers being able to find the time to review and test applications that get stuffed into tools/lkl, so from that perspective it's still a complete crapshoot. > >> > I really don't see how using LKL to give userspace access to XFS > >> > filesystems is a better solution than actually writing a proper, > >> > supported XFS-FUSE module. LKL is so full of compromises that it's > >> > going to be unworkable and unsupportable in practice... > >> > >> Could you elaborate on some of these issues? > > > > Start with "is a no-mmu architecture" and all the compromises that > > means the kernel code needs to make, > > I don't see non-mmu as a compromise. It is supported by Linux and most > filesystems work fine on non-mmu architectures. most != all. XFS is unashamedly aimed and developed for high performance systems. i.e. enterprise servers, HPC, fileservers, cloud storage infrastructure, etc. IOWs, we don't even develop for desktop machines, even though XFS performs adequately for most desktop workloads. We've never cared about non-mmu systems because of the requirements we have on virtually mapped buffers and the fact they don't exist in the target markets XFS aimed at. And, really, LKL doesn't change that... > LKL can be implemented > as a mmu architecture. Having it as a non-mmu architecture has the > advantages of allowing it to run in more constrained environments like > bootloaders. The OS owns the filesystem, not the bootloader. If the bootloader is modifying filesystems (e.g. by running log recovery to mount the fs internally to find the kernel/initrd files), then the boot loader compromises the filesystem integrity. We don't not support such configurations at all. > > and finish it off with "LKL linked applications will > > never be tested by their developers over the full functionality the > > LKL provides them with". > > You lost me here. Why does an application developer have to test the > full functionality of a library it is linked with? How much filesystem testing did you actually do with lklfuse? What about load testing? Data integrity/crash/power fail and recovery testing? Scalability testing? Or have you just assumed that it'll all just work fine because the kernel fs developers test this stuff? Yes, we've tested the kernel code along these lines *in kernel space*. That doesn't mean that an LKL application that uses the kernel functionality *in user space* will behave the same way or, indeed, function correctly in adverse circumstances. Application developers are not going to be aware of such issues, and they aren't going to test for such situations - they are simply going to assume "this works just fine" until it doesn't.... Cheers, Dave. -- Dave Chinner david@fromorbit.com From lvml@5t9.de Mon Nov 23 16:08:06 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 7F0567F37 for ; Mon, 23 Nov 2015 16:08:06 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 53BDA30405F for ; Mon, 23 Nov 2015 14:08:03 -0800 (PST) X-ASG-Debug-ID: 1448316480-04bdf07f081fee90001-NocioJ Received: from app1b.xlhost.de (mailout173.xlhost.de [84.200.252.173]) by cuda.sgi.com with ESMTP id sDFdRGxMEFUd4FPP for ; Mon, 23 Nov 2015 14:08:01 -0800 (PST) X-Barracuda-Envelope-From: lvml@5t9.de X-Barracuda-Apparent-Source-IP: 84.200.252.173 Received: from [10.223.1.8] (55d446e9.access.ecotel.net [85.212.70.233]) (Authenticated sender: lkv@5t9.de) by app1b.xlhost.de (Postfix) with ESMTPSA id 291013000AC0; Mon, 23 Nov 2015 23:07:58 +0100 (CET) Message-ID: <56538E6A.6030203@5t9.de> Date: Mon, 23 Nov 2015 23:08:42 +0100 From: Lutz Vieweg User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.2.0 MIME-Version: 1.0 To: Dave Chinner CC: xfs@oss.sgi.com Subject: Re: Does XFS support cgroup writeback limiting? References: <5652F311.7000406@5t9.de> <20151123202619.GE26718@dastard> X-ASG-Orig-Subj: Re: Does XFS support cgroup writeback limiting? In-Reply-To: <20151123202619.GE26718@dastard> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 8bit X-Virus-Scanned: clamav-milter 0.98.1 at app1b.xlhost.de X-Virus-Status: Clean X-Barracuda-Connect: mailout173.xlhost.de[84.200.252.173] X-Barracuda-Start-Time: 1448316481 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24661 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 11/23/2015 09:26 PM, Dave Chinner wrote: > On Mon, Nov 23, 2015 at 12:05:53PM +0100, Lutz Vieweg wrote: >> in June 2015 the article https://lwn.net/Articles/648292/ mentioned >> upcoming support for limiting the quantity of buffered writes >> using control groups. >> >> Back then, only ext4 was said to support that feature, with other >> filesystems requiring some minor changes to do the same. > > Yes, changing the kernel code to support this functionality is about > 3 lines of code. Oh, I didn't expect it to be such a small change :-) > .... I haven't added support to XFS because I have no way of > verifying the functionality works and that it continues to work as > it is intended. i.e. we have no regression test coverage for cgroup > aware writeback and until someone writes a set of regression tests > that validate it's functionality works correctly it will remain this > way. > > Writing code is trivial. Validating the code actually works as > intended and doesn't silently get broken in the future is the > hard part.... Understood, would you anyway be willing to publish such a three-line-patch (outside of official releases) for those daredevils (like me :-)) who'd be willing to give it a try? After all, this functionality is the last piece of the "isolation"-puzzle that is missing from Linux to actually allow fencing off virtual machines or containers from DOSing each other by using up all I/O bandwidth... Regards, Lutz Vieweg From david@fromorbit.com Mon Nov 23 17:10:04 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 E56FE7F37 for ; Mon, 23 Nov 2015 17:10:03 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 6BFC7AC001 for ; Mon, 23 Nov 2015 15:10:00 -0800 (PST) X-ASG-Debug-ID: 1448320195-04cbb0605c1dfa20001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id 2nwMGT1OfOe169We for ; Mon, 23 Nov 2015 15:09:56 -0800 (PST) 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: A2C7BwApnFNW/1bELHlegztTb4JfqR8MBgaLP4Jwgj+EDRmFcAICAQECgUhNAQEBAQEBgQuENAEBAQMBOhwjBQsIAw4KCSUPBSUDIROIJge/OwEBCAIBIBmFdIVFiTkFh0QDhwqHf4UkgSiGXJxUY4IRHYFqKjSFKwEBAQ Received: from ppp121-44-196-86.lns20.syd7.internode.on.net (HELO dastard) ([121.44.196.86]) by ipmail07.adl2.internode.on.net with ESMTP; 24 Nov 2015 09:39:18 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1a10E3-0007De-8i; Tue, 24 Nov 2015 10:08:47 +1100 Date: Tue, 24 Nov 2015 10:08:47 +1100 From: Dave Chinner To: Andreas Gruenbacher Cc: xfs@oss.sgi.com Subject: Re: [XFSTESTS 5/6] Add richacl tests Message-ID: <20151123230847.GH26718@dastard> X-ASG-Orig-Subj: Re: [XFSTESTS 5/6] Add richacl tests References: <1447856269-7872-1-git-send-email-agruenba@redhat.com> <1447856269-7872-6-git-send-email-agruenba@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1447856269-7872-6-git-send-email-agruenba@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: 1448320195 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24662 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Wed, Nov 18, 2015 at 03:17:48PM +0100, Andreas Gruenbacher wrote: > Add the Rich Access Control List tests from the richacl package. The > new tests require TEST_DEV and TEST_DIR to be set. > > When the check script is run, it first makes sure that the test > filesystem has richacls enabled or disabled as appropriate: with the > -richacl option, richacls must be enabled; without the -richacl option, > richacls must be disabled. If TEST_DEV has incorrect richacl support, > the TEST_DEV filesystem is recreated. No, we don't recreate the testdev like this with the test harness. The test device is intended to remain unchanged from run to run, so give us long term aging of the test filesystem over months of regression test running. If you want to test the testdev with richacls enabled, then you need to manually create the testdev with richacls. Any test that specifically needs to enable richacls should use the scratch device and use a _requires_scratch_richacls() test to check that the scratch device can be created with richacl support. > The -richacl option currently selects the tests in the richacl group to > be run. Additional test groups or tests can be specified on the command > line, e.g., > >> ./check -richacl -g quick > (Eventually, the -richacl option will be changed to only skip tests > which are incompatible with richacls.) No, this is wrong. If you want to check richacls, it should be via a test group, not a specific command line option ./check -g richacl That makes the first 2 patches in the series go away. > Signed-off-by: Andreas Gruenbacher > --- > .gitignore | 1 + > check | 39 +++++++- > common/rc | 23 ++++- > src/Makefile | 2 +- > src/require-richacls.c | 35 +++++++ That's a red flag. For XFS, in common/rc: _require_xfs_richacl() { _scratch_mkfs_xfs_supported -m richacl=1 >/dev/null 2>&1 \ || _notrun "mkfs.xfs doesn't have richacl feature" _scratch_mkfs_xfs -m richacl=1 >/dev/null 2>&1 \ _scratch_mount >/dev/null 2>&1 \ || _notrun "Kernel doesn't support richacl feature" umount $SCRATCH_MNT } _require_scratch_richacl() { case "$FSTYP" in xfs) _require_xfs_richacl ;; ext4) _require_ext4_richacl ;; *) _notrun "this test requires a richacl support on SCRATCHDEV" ;; esac } > tests/richacl/001-apply-masks | 1 + > tests/richacl/002-auto-inheritance | 1 + > tests/richacl/003-basic | 1 + > tests/richacl/004-chmod | 1 + > tests/richacl/005-chown | 1 + > tests/richacl/006-create | 1 + > tests/richacl/007-ctime | 1 + > tests/richacl/008-delete | 1 + > tests/richacl/009-setrichacl-modify | 1 + > tests/richacl/010-write-vs-append | 1 + These seem very short for tests. Oh, they just call one of the files below: > tests/richacl/Makefile | 44 +++++++++ > tests/richacl/apply-masks | 163 ++++++++++++++++++++++++++++++ > tests/richacl/auto-inheritance | 191 ++++++++++++++++++++++++++++++++++++ > tests/richacl/basic | 97 ++++++++++++++++++ > tests/richacl/chmod | 40 ++++++++ > tests/richacl/chown | 42 ++++++++ > tests/richacl/create | 36 +++++++ > tests/richacl/ctime | 35 +++++++ > tests/richacl/delete | 89 +++++++++++++++++ > tests/richacl/group | 15 +++ > tests/richacl/setrichacl-modify | 57 +++++++++++ > tests/richacl/test-lib.sh | 149 ++++++++++++++++++++++++++++ > tests/richacl/write-vs-append | 54 ++++++++++ That's a strange way of running tests, an dmost definitely not the way xfstests are written or supposed to be executed. And looking at tests/richacl/Makefile, these files need to be installed somewhere in the path for the tests to work. This is unnecessary complexity; the tests should simply execute in place in the source tree and not require any special installation steps. i.e. only the numbered version of the test should exist, and all the other files be moved into them. They shouldn't be in tests/richacl, either - these are generic tests and so should be in tests/generic, using whatever the next unused test numbers are. And then, in the tests/generic/group file, there will be entries like: 178-apply-masks auto quick richacl 179-auto-inheritance auto quick richacl .... These tests need to use the common xfstests structure (i.e. the setup code from the "new" script). The file that has all the common functionality in it (test-lib.sh) needs to be moved to common/richacl and included along with the necessary common files. At this point, the makefile can also go away. > diff --git a/tests/richacl/apply-masks b/tests/richacl/apply-masks > new file mode 100755 > index 0000000..7a99cf9 > --- /dev/null > +++ b/tests/richacl/apply-masks > @@ -0,0 +1,163 @@ > +#! /bin/sh We use /bin/bash in xfstests. > + > +. ${0%/*}/test-lib.sh > + > +require_richacls > +use_tmpdir No test actually uses $tmpdir, so why does this exist? > + > +ncheck "touch x" > +ncheck "setrichacl --set 'owner@:rwp::allow group@:rwp::allow everyone@:r::allow' x" > +check "getrichacl x" < +x: > + owner@:rwp----------::allow > + group@:rwp----------::allow > + everyone@:r------------::allow > +EOF Ok, let's break this down, because most of the tests are similar. ncheck is not needed, as golden output matching will catch an unexpected error. check is not needed, because the output of the command should match what is in the golden output file. i.e, this test should be simply: touch x setrichacl --set 'owner@:rwp::allow group@:rwp::allow everyone@:r::allow' x getrichacl x And the golden output file should contain: x: owner@:rwp----------::allow group@:rwp----------::allow everyone@:r------------::allow The fact that you do golden output matching directly in the script to calculate "checks_succeeded" and "checks_failed" and then check those at the end of the test to set the exit status is completely unnecessary. The xfstests tsts harness does all this pattern matching for you via the golden output file. Using output files correctly make patches 3 and 4 in this series go away. > +# We cannot set the acl as another user > +runas -u 99 -g 99 > +check "setrichacl --set '99:rwc::allow' a || echo status: \$?" < +a: Operation not permitted > +status: 1 > +EOF In this case, check hides the fact the test attempts to run as a different user. now we've got rid of the "check" wrappers, we should just be doing: runas=$here/src/runas $runas -u 99 -g 99 -- setrichacl --set '99:rwc::allow' and capturing the expected error in the golden output file. This is the same as ACL and other permission tests in xfstests. e.g: $ git grep -l runas .gitignore src/Makefile tests/generic/026 tests/generic/093 tests/generic/099 tests/generic/237 tests/shared/051 $ > +cleanup() { > + status=$? > + checks_succeeded=`expr $checks_succeeded` > + checks_failed=`expr $checks_failed` > + checks_total=`expr $checks_succeeded + $checks_failed` > + if test $checks_total -gt 0 ; then > + if test $checks_failed -gt 0 && test $status -eq 0 ; then > + status=1 > + fi > + echo "$checks_total tests ($checks_succeeded passed," \ > + "$checks_failed failed)" > + fi > + if test -n "$tmpdir" ; then > + chmod -R u+rwx "$tmpdir" 2>/dev/null > + cd / && rm -rf "$tmpdir" > + fi > + exit $status > +} This is all completely unnecessary because the golden output matching done by the harness will fail the test if there is any error at all. The whole point of using xfstests is that you don't need to carry all this test harness install/run/test/check stuff in the tests themselves. This stuff should be no different to the posix ACL tests in structure (e.g. see generic/099), and should be just as simple to maintain..... Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Mon Nov 23 17:21:53 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 560D97F37 for ; Mon, 23 Nov 2015 17:21:53 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 47BC730405F for ; Mon, 23 Nov 2015 15:21:50 -0800 (PST) X-ASG-Debug-ID: 1448320906-04cb6c0cd21ab310001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id ZEMXkJdo6xVWep6m for ; Mon, 23 Nov 2015 15:21:47 -0800 (PST) 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: A2BtBwCunlNW/1bELHlegztTb4JfqR8MBgaLP4k8FwqFaAQCAoFITQEBAQEBAYELhDQBAQEDAQECNxwjBQsIAw4KCSUPBRQRAyETiCYHDr8pAQEBAQYCASAZhXSFRYk5BZZQhSSFIoJinFRjghEdgWoqNAGDYiWBIwEBAQ Received: from ppp121-44-196-86.lns20.syd7.internode.on.net (HELO dastard) ([121.44.196.86]) by ipmail07.adl2.internode.on.net with ESMTP; 24 Nov 2015 09:51:21 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1a10Pk-0007FN-Es; Tue, 24 Nov 2015 10:20:52 +1100 Date: Tue, 24 Nov 2015 10:20:52 +1100 From: Dave Chinner To: Lutz Vieweg Cc: xfs@oss.sgi.com Subject: Re: Does XFS support cgroup writeback limiting? Message-ID: <20151123232052.GI26718@dastard> X-ASG-Orig-Subj: Re: Does XFS support cgroup writeback limiting? References: <5652F311.7000406@5t9.de> <20151123202619.GE26718@dastard> <56538E6A.6030203@5t9.de> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <56538E6A.6030203@5t9.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: 1448320906 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24662 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Mon, Nov 23, 2015 at 11:08:42PM +0100, Lutz Vieweg wrote: > On 11/23/2015 09:26 PM, Dave Chinner wrote: > >On Mon, Nov 23, 2015 at 12:05:53PM +0100, Lutz Vieweg wrote: > >>in June 2015 the article https://lwn.net/Articles/648292/ mentioned > >>upcoming support for limiting the quantity of buffered writes > >>using control groups. > >> > >>Back then, only ext4 was said to support that feature, with other > >>filesystems requiring some minor changes to do the same. > > > >Yes, changing the kernel code to support this functionality is about > >3 lines of code. > > Oh, I didn't expect it to be such a small change :-) > > >.... I haven't added support to XFS because I have no way of > >verifying the functionality works and that it continues to work as > >it is intended. i.e. we have no regression test coverage for cgroup > >aware writeback and until someone writes a set of regression tests > >that validate it's functionality works correctly it will remain this > >way. > > > >Writing code is trivial. Validating the code actually works as > >intended and doesn't silently get broken in the future is the > >hard part.... > > Understood, would you anyway be willing to publish such a > three-line-patch (outside of official releases) for those > daredevils (like me :-)) who'd be willing to give it a try? Just make the same mods to XFS as the ext4 patch here: http://www.spinics.net/lists/kernel/msg2014816.html > After all, this functionality is the last piece of the > "isolation"-puzzle that is missing from Linux to actually > allow fencing off virtual machines or containers from DOSing > each other by using up all I/O bandwidth... Yes, I know, but no-one seems to care enough about it to provide regression tests for it. Cheers, Dave. -- Dave Chinner david@fromorbit.com From wggmbyclzkm@korea.com Mon Nov 23 18:05:02 2015 Return-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.6 required=5.0 tests=HK_RANDOM_ENVFROM, HK_RANDOM_FROM,HTML_FONT_SIZE_LARGE,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 E88AF7F37 for ; Mon, 23 Nov 2015 18:05:02 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id D9D918F8035 for ; Mon, 23 Nov 2015 16:04:59 -0800 (PST) X-ASG-Debug-ID: 1448323495-04cb6c0cd31abfb0001-NocioJ Received: from r-smtp6.korea.com (31-178-79-90.dynamic.chello.pl [31.178.79.90]) by cuda.sgi.com with ESMTP id mlRdgQvsZYYnEgO9 for ; Mon, 23 Nov 2015 16:04:56 -0800 (PST) X-Barracuda-Envelope-From: wggmbyclzkm@korea.com X-Barracuda-Apparent-Source-IP: 31.178.79.90 Content-Transfer-Encoding: 7bit Content-Type: multipart/alternative; boundary="----------264BCCE1A3B5B2848" MIME-Version: 1.0 Date: Tue, 24 Nov 2015 03:04:54 +0300 Subject: =?utf-8?B?0J7QsdGD0YfQtdC90LjQtSDQs9C+0YHQt9Cw0LrRg9C/0LrQsNC8INC/0L4gNDTQpNCXINC4IDIyM9Ck0Jc=?= X-Complaints-To: xfs@oss.sgi.com X-ASG-Orig-Subj: =?utf-8?B?0J7QsdGD0YfQtdC90LjQtSDQs9C+0YHQt9Cw0LrRg9C/0LrQsNC8INC/0L4gNDTQpNCXINC4IDIyM9Ck0Jc=?= To: xfs@oss.sgi.com From: "=?utf-8?B?0JPQvtGB0LfQsNC60YPQv9C60LgsINCz0L7RgdC30LDQutCw0LcsINGC0LXQvdC00LXRgNGL?=" List-Unsubscribe: golka.1987@mail.ru Message-ID: <021372157.20151124030454@APWSSWDRAQQ> Require-Recipient-Valid-Since: xfs@oss.sgi.com; Thu, 12 Mar 2015 05:32:11 +0000 X-Mailer: GetResponse 360 X-Barracuda-Connect: 31-178-79-90.dynamic.chello.pl[31.178.79.90] X-Barracuda-Start-Time: 1448323495 X-Barracuda-URL: https://192.48.176.15:443/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, HTML_FONT_SIZE_LARGE, HTML_MESSAGE, RDNS_DYNAMIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24664 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 HTML_FONT_SIZE_LARGE BODY: HTML font size is large 0.00 HTML_MESSAGE BODY: HTML included in message 0.10 RDNS_DYNAMIC Delivered to trusted network by host with dynamic-looking rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 This is a multipart message in MIME format. ------------264BCCE1A3B5B2848 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=UTF-8 MIME-Version: 1.0 Date: Tue, 24 Nov 2015 03:04:54 +0300 =20 =20 3 =D0=B4=D0=B5=D0=BA=D0=B0=D0=B1=D1=80=D1=8F | =D0=B3. = =D0=9C=D0=BE=D1=81=D0=BA=D0=B2=D0=B0 (=D0=BF=D1=80=D0=BE=D0=BC=D0=BE=D0=BA=D0=BE=D0=B4:255)=20 = =D0=90=D0=BA=D0=BA=D1=80=D0=B5=D0=B4=D0=B8=D1=82=D0=BE=D0=B2=D0=B0=D0=BD=D0= =BD=D1=8B=D0=B9 =D0=A3=D1=87=D0=B5=D0=B1=D0=BD=D1=8B=D0=B9 = =D1=86=D0=B5=D0=BD=D1=82=D1=80 = =D0=BF=D1=80=D0=B8=D0=B3=D0=BB=D0=B0=D1=88=D0=B0=D0=B5=D1=82 = =D0=BD=D0=B0 =D0=BE=D0=B1=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=BF=D0=BE =D1=82=D0=B5=D0=BC=D0=B5: 44-=D0=A4=D0=97 =D0=B8 223-=D0=A4=D0=97: =D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F =D0=B2 = =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BA=D0=B0=D1=85. =D0=94=D0=BB=D1=8F: = =D1=80=D1=83=D0=BA=D0=BE=D0=B2=D0=BE=D0=B4=D0=B8=D1=82=D0=B5=D0=BB=D0=B5=D0= =B9 =D0=B8 = =D1=81=D0=BF=D0=B5=D1=86=D0=B8=D0=B0=D0=BB=D0=B8=D1=81=D1=82=D0=BE=D0=B2,= =D0=BE=D1=82=D0=B2=D0=B5=D1=87=D0=B0=D1=8E=D1=89=D0=B8=D1=85 = =D0=B7=D0=B0 = =D0=BE=D1=81=D1=83=D1=89=D0=B5=D1=81=D1=82=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0= =B5 =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BE=D0=BA, = =D1=87=D0=BB=D0=B5=D0=BD=D0=BE=D0=B2 =D0=9A=D0=BE=D0=BC=D0=B8=D1=81=D1=81=D0=B8=D0=B9 = =D0=B7=D0=B0=D0=BA=D0=B0=D0=B7=D1=87=D0=B8=D0=BA=D0=B0, = =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BD=D0=B8=D0=BA=D0=BE=D0=B2 = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=B0=D0=BA=D1=82=D0=BD=D0=BE=D0=B9 = =D1=81=D0=BB=D1=83=D0=B6=D0=B1=D1=8B = (=D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=B0=D0=BA=D1=82=D0=BD=D1=8B=D1=85 = =D1=83=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D1=8F=D1=8E=D1=89=D0=B8=D1=85), = =D0=BE=D1=82=D0=B4=D0=B5=D0=BB=D0=BE=D0=B2 =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BE=D0=BA, = =D1=80=D1=83=D0=BA=D0=BE=D0=B2=D0=BE=D0=B4=D0=B8=D1=82=D0=B5=D0=BB=D0=B5=D0= =B9 =D0=BA=D0=BE=D0=BC=D0=BF=D0=B0=D0=BD=D0=B8=D0=B9, = =D1=80=D1=83=D0=BA=D0=BE=D0=B2=D0=BE=D0=B4=D0=B8=D1=82=D0=B5=D0=BB=D0=B5=D0= =B9 =D0=B8 = =D1=81=D0=BF=D0=B5=D1=86=D0=B8=D0=B0=D0=BB=D0=B8=D1=81=D1=82=D0=BE=D0=B2 = =D1=82=D0=B5=D0=BD=D0=B4=D0=B5=D1=80=D0=BD=D1=8B=D1=85 = =D0=BE=D1=82=D0=B4=D0=B5=D0=BB=D0=BE=D0=B2, = =D1=80=D1=83=D0=BA=D0=BE=D0=B2=D0=BE=D0=B4=D0=B8=D1=82=D0=B5=D0=BB=D0=B5=D0= =B9 =D1=8E=D1=80=D0=B8=D0=B4=D0=B8=D1=87=D0=B5=D1=81=D0=BA=D0=B8=D1=85 = =D0=BE=D1=82=D0=B4=D0=B5=D0=BB=D0=BE=D0=B2 =D0=B8 = =D0=BE=D1=82=D0=B4=D0=B5=D0=BB=D0=BE=D0=B2 = =D0=BF=D1=80=D0=BE=D0=B4=D0=B0=D0=B6 = =D0=BA=D0=BE=D0=BC=D0=BF=D0=B0=D0=BD=D0=B8=D0=B9-=D0=BF=D0=BE=D1=81=D1=82= =D0=B0=D0=B2=D1=89=D0=B8=D0=BA=D0=BE=D0=B2 = (=D0=BF=D0=BE=D0=B4=D1=80=D1=8F=D0=B4=D1=87=D0=B8=D0=BA=D0=BE=D0=B2, = =D0=B8=D1=81=D0=BF=D0=BE=D0=BB=D0=BD=D0=B8=D1=82=D0=B5=D0=BB=D0=B5=D0=B9)= . =D0=97=D0=B0=D0=BD=D1=8F=D1=82=D0=B8=D0=B5 = =D0=BF=D1=80=D0=BE=D0=B2=D0=BE=D0=B4=D0=B8=D1=82=D1=81=D1=8F =D1=81 = 10:00 =D0=B4=D0=BE 17:30 =D0=90=D0=B4=D1=80=D0=B5=D1=81 = =D0=BC=D0=B5=D1=80=D0=BE=D0=BF=D1=80=D0=B8=D1=8F=D1=82=D0=B8=D1=8F: = =D0=BC. =D0=91=D0=B0=D1=83=D0=BC=D0=B0=D0=BD=D1=81=D0=BA=D0=B0=D1=8F, = =D1=83=D0=BB. = =D0=91=D0=B0=D1=83=D0=BC=D0=B0=D0=BD=D1=81=D0=BA=D0=B0=D1=8F, =D0=B4.6, = =D1=81=D1=82=D1=80.2. =D0=9F=D0=BE=D0=B4=D1=80=D0=BE=D0=B1=D0=BD=D0=B0=D1=8F = =D0=B8=D0=BD=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=86=D0=B8=D1=8F =D0=B8 = =D1=80=D0=B5=D0=B3=D0=B8=D1=81=D1=82=D1=80=D0=B0=D1=86=D0=B8=D1=8F = =D0=BF=D0=BE =D1=82=D0=B5=D0=BB=D0=B5=D1=84=D0=BE=D0=BD=D1=83: 8 = =D0=BA=D0=BE=D0=B4 =D0=B3=D0=BE=D1=80=D0=BE=D0=B4=D0=B0 (495) = =D1=82=D0=B5=D0=BB.: 961 - 00 - =D0=978 =20 =20 =20 =20 =D0=9E=D0=BF=D0=B8=D1=81=D0=B0=D0=BD=D0=B8=D0=B5 = =D0=BF=D1=80=D0=BE=D0=B3=D1=80=D0=B0=D0=BC=D0=BC=D1=8B: =20 1. =D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F =D0=B2 = =D1=80=D0=B5=D0=B3=D1=83=D0=BB=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0= =B8 =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BE=D0=BA =D0=BF=D0=BE = =D1=84=D0=B5=D0=B4=D0=B5=D1=80=D0=B0=D0=BB=D1=8C=D0=BD=D0=BE=D0=BC=D1=83 = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D1=83 =E2=84=96 44-=D0=A4=D0=97 "=D0=9E =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=B0=D0=BA=D1=82=D0=BD=D0=BE=D0=B9 = =D1=81=D0=B8=D1=81=D1=82=D0=B5=D0=BC=D0=B5 =D0=B2 = =D1=81=D1=84=D0=B5=D1=80=D0=B5 = =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BE=D0=BA = =D1=82=D0=BE=D0=B2=D0=B0=D1=80=D0=BE=D0=B2, = =D1=80=D0=B0=D0=B1=D0=BE=D1=82, =D1=83=D1=81=D0=BB=D1=83=D0=B3 = =D0=B4=D0=BB=D1=8F = =D0=BE=D0=B1=D0=B5=D1=81=D0=BF=D0=B5=D1=87=D0=B5=D0=BD=D0=B8=D1=8F = =D0=B3=D0=BE=D1=81=D1=83=D0=B4=D0=B0=D1=80=D1=81=D1=82=D0=B2=D0=B5=D0=BD=D0= =BD=D1=8B=D1=85 =D0=B8 = =D0=BC=D1=83=D0=BD=D0=B8=D1=86=D0=B8=D0=BF=D0=B0=D0=BB=D1=8C=D0=BD=D1=8B=D1= =85 =D0=BD=D1=83=D0=B6=D0=B4" (=D0=9A=D0=A1).=20 =20 -=D0=98=D1=82=D0=BE=D0=B3=D0=B8 = =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=8B =D0=BF=D0=BE 44-=D0=A4=D0=97 =D0=B2 = 2014 =D0=B3=D0=BE=D0=B4=D1=83 =D0=B8 = =D0=BF=D0=B5=D1=80=D1=81=D0=BF=D0=B5=D0=BA=D1=82=D0=B8=D0=B2=D1=8B = =D1=80=D0=B0=D0=B7=D0=B2=D0=B8=D1=82=D0=B8=D1=8F = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=B0=D0=BA=D1=82=D0=BD=D0=BE=D0=B9 = =D1=81=D0=B8=D1=81=D1=82=D0=B5=D0=BC=D1=8B = -=D0=9F=D0=BB=D0=B0=D0=BD=D0=B8=D1=80=D1=83=D0=B5=D0=BC=D1=8B=D0=B5 = =D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F 44-=D0=A4=D0=97 = =D0=B2 2015 =D0=B3=D0=BE=D0=B4=D1=83: = =D1=8D=D0=BB=D0=B5=D0=BA=D1=82=D1=80=D0=BE=D0=BD=D0=BD=D1=8B=D0=B5 = =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BA=D0=B8, = =D1=80=D0=B5=D1=84=D0=BE=D1=80=D0=BC=D0=B0 = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=BE=D0=BB=D1=8C=D0=BD=D1=8B=D1=85 =D0=BE=D1=80=D0=B3=D0=B0=D0=BD=D0=BE=D0=B2, = =D0=BF=D0=BE=D0=B4=D0=B4=D0=B5=D1=80=D0=B6=D0=BA=D0=B0 = =D0=BE=D1=82=D0=B5=D1=87=D0=B5=D1=81=D1=82=D0=B2=D0=B5=D0=BD=D0=BD=D0=BE=D0= =B3=D0=BE = =D0=BF=D1=80=D0=BE=D0=B8=D0=B7=D0=B2=D0=BE=D0=B4=D0=B8=D1=82=D0=B5=D0=BB=D1= =8F = -=D0=A4=D0=B5=D0=B4=D0=B5=D1=80=D0=B0=D0=BB=D1=8C=D0=BD=D1=8B=D0=B9 = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD =E2=84=96 44-=D0=A4=D0=97 =D0=B2 = =D1=80=D0=B5=D0=B4=D0=B0=D0=BA=D1=86=D0=B8=D0=B8 =D0=BE=D1=82 13 = =D0=B8=D1=8E=D0=BB=D1=8F 2015 =D0=B3. -=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F =D0=B2 = =D0=91=D1=8E=D0=B4=D0=B6=D0=B5=D1=82=D0=BD=D0=BE=D0=BC = =D0=BA=D0=BE=D0=B4=D0=B5=D0=BA=D1=81=D0=B5 = (=D0=B7=D0=B0=D0=BA=D0=BE=D0=BD =E2=84=96 25-=D0=A4=D0=97), = =D0=93=D1=80=D0=B0=D0=B6=D0=B4=D0=B0=D0=BD=D1=81=D0=BA=D0=BE=D0=BC = =D0=BA=D0=BE=D0=B4=D0=B5=D0=BA=D1=81=D0=B5 = (=D0=B7=D0=B0=D0=BA=D0=BE=D0=BD =E2=84=96 42-=D0=A4=D0=97)=20 = -=D0=97=D0=B0=D0=BA=D0=BE=D0=BD=D0=BE=D0=B4=D0=B0=D1=82=D0=B5=D0=BB=D1=8C= =D0=BD=D0=BE=D0=B5 = =D1=83=D1=81=D1=82=D0=B0=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=BF=D1=80=D0=B8=D0=BE=D1=80=D0=B8=D1=82=D0=B5=D1=82=D0=B0 = =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BA=D0=B8 = =D0=BF=D1=80=D0=BE=D0=BC=D1=8B=D1=88=D0=BB=D0=B5=D0=BD=D0=BD=D0=BE=D0=B9 = =D0=BF=D1=80=D0=BE=D0=B4=D1=83=D0=BA=D1=86=D0=B8=D0=B8, = =D0=BF=D1=80=D0=BE=D0=B8=D0=B7=D0=B2=D0=B5=D0=B4=D0=B5=D0=BD=D0=BD=D0=BE=D0= =B9 =D0=BD=D0=B0 = =D1=82=D0=B5=D1=80=D1=80=D0=B8=D1=82=D0=BE=D1=80=D0=B8=D0=B8 = =D0=A0=D0=A4 (=D0=B7=D0=B0=D0=BA=D0=BE=D0=BD =E2=84=96 488-=D0=A4=D0=97 = =D0=BE=D1=82 31 =D0=B4=D0=B5=D0=BA=D0=B0=D0=B1=D1=80=D1=8F 2014 =D0=B3.) = -=D0=92=D0=B2=D0=B5=D0=B4=D0=B5=D0=BD=D0=B8=D0=B5 = =D1=88=D1=82=D1=80=D0=B0=D1=84=D0=BE=D0=B2 =D0=B8 = =D0=B4=D0=B8=D1=81=D0=BA=D0=B2=D0=B0=D0=BB=D0=B8=D1=84=D0=B8=D0=BA=D0=B0=D1= =86=D0=B8=D0=B8 =D0=B7=D0=B0 = =D0=BD=D0=B5=D0=B8=D1=81=D0=BF=D0=BE=D0=BB=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=BE=D0=B1=D1=8F=D0=B7=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=D1=81=D1=82=D0=B2,= = =D0=BF=D1=80=D0=B5=D0=B4=D1=83=D1=81=D0=BC=D0=BE=D1=82=D1=80=D0=B5=D0=BD=D0= =BD=D1=8B=D1=85 =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=B0=D0=BA=D1=82=D0=BE=D0=BC = (=D0=B7=D0=B0=D0=BA=D0=BE=D0=BD =D0=BE=D1=82 13.07.2015 =D0=B3. = =E2=84=96 265-=D0=A4=D0=97) -=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F = =D1=84=D0=B5=D0=B4=D0=B5=D1=80=D0=B0=D0=BB=D1=8C=D0=BD=D0=BE=D0=B3=D0=BE = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D0=B0 =D0=BE=D1=82 29 = =D0=B4=D0=B5=D0=BA=D0=B0=D0=B1=D1=80=D1=8F 2012 =D0=B3=D0=BE=D0=B4=D0=B0 = =E2=84=96 275-=D0=A4=D0=97 "=D0=9E = =D0=B3=D0=BE=D1=81=D1=83=D0=B4=D0=B0=D1=80=D1=81=D1=82=D0=B2=D0=B5=D0=BD=D0= =BD=D0=BE=D0=BC =D0=BE=D0=B1=D0=BE=D1=80=D0=BE=D0=BD=D0=BD=D0=BE=D0=BC = =D0=B7=D0=B0=D0=BA=D0=B0=D0=B7=D0=B5" -=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=BF=D1=80=D0=B0=D0=B2=D0=B8=D0=BB =D0=B8 = =D0=BE=D1=81=D0=BD=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B9 = =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BE=D0=BA =D1=83 = =D0=B5=D0=B4=D0=B8=D0=BD=D1=81=D1=82=D0=B2=D0=B5=D0=BD=D0=BD=D0=BE=D0=B3=D0= =BE =D0=BF=D0=BE=D1=81=D1=82=D0=B0=D0=B2=D1=89=D0=B8=D0=BA=D0=B0 = (=D0=BF=D0=BE=D0=B4=D1=80=D1=8F=D0=B4=D1=87=D0=B8=D0=BA=D0=B0, = =D0=B8=D1=81=D0=BF=D0=BE=D0=BB=D0=BD=D0=B8=D1=82=D0=B5=D0=BB=D1=8F) = =E2=80=93 = =D1=84=D0=B5=D0=B4=D0=B5=D1=80=D0=B0=D0=BB=D1=8C=D0=BD=D1=8B=D0=B5 = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D1=8B =D0=BE=D1=82 01.12.2014 =E2=84=96 = 416-=D0=A4=D0=97, =D0=BE=D1=82 29 = =D0=B4=D0=B5=D0=BA=D0=B0=D0=B1=D1=80=D1=8F 2014 =D0=B3. =E2=84=96 458-=D0=A4=D0=97, =D0=BE=D1=82 31 = =D0=B4=D0=B5=D0=BA=D0=B0=D0=B1=D1=80=D1=8F 2014 =D0=B3. =E2=84=96 = 498-=D0=A4=D0=97, =D0=BE=D1=82 31 = =D0=B4=D0=B5=D0=BA=D0=B0=D0=B1=D1=80=D1=8F 2014 =D0=B3. =E2=84=96 = 519-=D0=A4=D0=97, =D0=BE=D1=82 08 =D0=BC=D0=B0=D1=80=D1=82=D0=B0 2015 = =D0=B3. =E2=84=96 48-=D0=A4=D0=97, =D0=BE=D1=82 13 = =D0=B8=D1=8E=D0=BB=D1=8F 2015 =D0=B3. =E2=84=96 227-=D0=A4=D0=97=20 -=D0=9D=D0=BE=D0=B2=D1=8B=D0=B5 = =D0=BD=D0=BE=D1=80=D0=BC=D0=B0=D1=82=D0=B8=D0=B2=D0=BD=D1=8B=D0=B5 = =D0=B0=D0=BA=D1=82=D1=8B, = =D0=BF=D1=80=D0=B8=D0=BD=D1=8F=D1=82=D1=8B=D0=B5 =D0=B2 = =D1=80=D0=B0=D0=B7=D0=B2=D0=B8=D1=82=D0=B8=D0=B5 = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D0=B0 =E2=84=9644-=D0=A4=D0=97; = =D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F = =D0=BF=D1=80=D0=B8=D0=BD=D1=8F=D1=82=D1=8B=D1=85 =D1=80=D0=B0=D0=BD=D0=B5=D0=B5 = =D0=BD=D0=BE=D1=80=D0=BC=D0=B0=D1=82=D0=B8=D0=B2=D0=BD=D1=8B=D1=85 = =D0=B0=D0=BA=D1=82=D0=BE=D0=B2 -=D0=9F=D0=BB=D0=B0=D0=BD =D0=B8 = =D0=BF=D0=B5=D1=80=D1=81=D0=BF=D0=B5=D0=BA=D1=82=D0=B8=D0=B2=D1=8B = =D0=BF=D1=80=D0=B8=D0=BD=D1=8F=D1=82=D0=B8=D1=8F = =D0=BF=D0=BE=D0=B4=D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D0=BD=D1=8B=D1=85 = =D0=BD=D0=BE=D1=80=D0=BC=D0=B0=D1=82=D0=B8=D0=B2=D0=BD=D1=8B=D1=85 = =D0=B0=D0=BA=D1=82=D0=BE=D0=B2 =D0=B2 2015 =D0=B3=D0=BE=D0=B4=D1=83 -=D0=9E=D1=82=D0=BC=D0=B5=D0=BD=D0=B0 = =D1=81=D1=82=D0=B0=D1=82=D0=B8=D1=81=D1=82=D0=B8=D1=87=D0=B5=D1=81=D0=BA=D0= =B8=D1=85 =D0=BE=D1=82=D1=87=D0=B5=D1=82=D0=BE=D0=B2 =E2=84=96 = 1-=D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=B0=D0=BA=D1=82 =D0=B8 =E2=84=96 = 1-=D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BA=D0=B8 = (=D0=BF=D1=80=D0=B8=D0=BA=D0=B0=D0=B7 = =D0=A0=D0=BE=D1=81=D1=81=D1=82=D0=B0=D1=82=D0=B0 =D0=BE=D1=82 15.05.2015 = =D0=B3. =E2=84=96 226) = -=D0=A0=D0=B0=D0=B7=D1=8A=D1=8F=D1=81=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F = =D0=9C=D0=B8=D0=BD=D1=8D=D0=BA=D0=BE=D0=BD=D0=BE=D0=BC=D1=80=D0=B0=D0=B7=D0= =B2=D0=B8=D1=82=D0=B8=D1=8F, =D0=A4=D0=90=D0=A1, = =D0=9C=D0=B8=D0=BD=D1=84=D0=B8=D0=BD=D0=B0 =D0=BF=D0=BE = =D1=81=D0=BB=D0=BE=D0=B6=D0=BD=D1=8B=D0=BC = =D0=B2=D0=BE=D0=BF=D1=80=D0=BE=D1=81=D0=B0=D0=BC = =D0=BE=D1=81=D1=83=D1=89=D0=B5=D1=81=D1=82=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D1= =8F =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BE=D0=BA -=D0=A1=D1=83=D0=B4=D0=B5=D0=B1=D0=BD=D0=B0=D1=8F =D0=B8 = =D0=B0=D0=B4=D0=BC=D0=B8=D0=BD=D0=B8=D1=81=D1=82=D1=80=D0=B0=D1=82=D0=B8=D0= =B2=D0=BD=D0=B0=D1=8F =D0=BF=D1=80=D0=B0=D0=BA=D1=82=D0=B8=D0=BA=D0=B0 = (=D1=88=D1=82=D1=80=D0=B0=D1=84=D1=8B =D0=B8 =D0=BF=D0=B5=D0=BD=D0=B8 = =D0=B7=D0=B0 =D0=BD=D0=B0=D1=80=D1=83=D1=88=D0=B5=D0=BD=D0=B8=D0=B5 = =D1=83=D1=81=D0=BB=D0=BE=D0=B2=D0=B8=D0=B9 = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=B0=D0=BA=D1=82=D0=BE=D0=B2, = =D0=BE=D0=B4=D0=BD=D0=BE=D1=81=D1=82=D0=BE=D1=80=D0=BE=D0=BD=D0=BD=D0=B8=D0= =B9 =D0=BE=D1=82=D0=BA=D0=B0=D0=B7 =D0=BE=D1=82 = =D0=B8=D1=81=D0=BF=D0=BE=D0=BB=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=B0=D0=BA=D1=82=D0=BE=D0=B2, = =D0=B7=D0=B0=D0=BC=D0=B5=D0=BD=D0=B0 = =D0=BE=D0=B1=D0=B5=D1=81=D0=BF=D0=B5=D1=87=D0=B5=D0=BD=D0=B8=D1=8F = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=B0=D0=BA=D1=82=D0=B0, =D0=BE=D1=82=D0=BA=D0=BB=D0=BE=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=B7=D0=B0=D1=8F=D0=B2=D0=BE=D0=BA, = =D1=81=D0=B3=D0=BE=D0=B2=D0=BE=D1=80 =D0=BD=D0=B0 = =D1=82=D0=BE=D1=80=D0=B3=D0=B0=D1=85, = =D0=B2=D0=B5=D0=B4=D0=BE=D0=BC=D1=81=D1=82=D0=B2=D0=B5=D0=BD=D0=BD=D1=8B=D0= =B5 =D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D1=80=D0=BA=D0=B8 =D0=B8 = =D0=B4=D1=80.) =20 =20 2. =D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F =D0=B2 = =D1=80=D0=B5=D0=B3=D1=83=D0=BB=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0= =B8 =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BE=D0=BA =D0=BF=D0=BE = =D1=84=D0=B5=D0=B4=D0=B5=D1=80=D0=B0=D0=BB=D1=8C=D0=BD=D0=BE=D0=BC=D1=83 = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D1=83 =E2=84=96 223-=D0=A4=D0=97 "=D0=9E = =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BA=D0=B0=D1=85 =D1=82=D0=BE=D0=B2=D0=B0=D1=80=D0=BE=D0=B2, = =D1=80=D0=B0=D0=B1=D0=BE=D1=82, =D1=83=D1=81=D0=BB=D1=83=D0=B3 = =D0=BE=D1=82=D0=B4=D0=B5=D0=BB=D1=8C=D0=BD=D1=8B=D0=BC=D0=B8 = =D0=B2=D0=B8=D0=B4=D0=B0=D0=BC=D0=B8 = =D1=8E=D1=80=D0=B8=D0=B4=D0=B8=D1=87=D0=B5=D1=81=D0=BA=D0=B8=D1=85 = =D0=BB=D0=B8=D1=86".=20 =20 -=D0=97=D0=B0=D0=BA=D0=BE=D0=BD =E2=84=96 223-=D0=A4=D0=97 =D0=B2 = =D1=80=D0=B5=D0=B4=D0=B0=D0=BA=D1=86=D0=B8=D0=B8 =D0=BE=D1=82 13 = =D0=B8=D1=8E=D0=BB=D1=8F 2015 =D0=B3. = -=D0=9E=D1=81=D0=BE=D0=B1=D0=B5=D0=BD=D0=BD=D0=BE=D1=81=D1=82=D0=B8 = =D0=BE=D1=81=D1=83=D1=89=D0=B5=D1=81=D1=82=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D1= =8F =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BE=D0=BA =D0=BF=D1=80=D0=B8 = =D1=80=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D0=B8 = =D0=B8=D0=BD=D0=B2=D0=B5=D1=81=D1=82=D0=B8=D1=86=D0=B8=D0=BE=D0=BD=D0=BD=D1= =8B=D1=85 =D0=BF=D1=80=D0=BE=D0=B5=D0=BA=D1=82=D0=BE=D0=B2 -=D0=9F=D0=BE=D0=BD=D1=8F=D1=82=D0=B8=D0=B5 = =D0=B8=D0=BD=D0=B2=D0=B5=D1=81=D1=82=D0=B8=D1=86=D0=B8=D0=BE=D0=BD=D0=BD=D0= =BE=D0=B3=D0=BE =D0=BF=D1=80=D0=BE=D0=B5=D0=BA=D1=82=D0=B0 =D0=B2 = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D0=B5 =E2=84=96 223-=D0=A4=D0=97 = -=D0=94=D0=BE=D0=BF=D0=BE=D0=BB=D0=BD=D0=B8=D1=82=D0=B5=D0=BB=D1=8C=D0=BD= =D1=8B=D0=B5 = =D0=BE=D0=B1=D1=8F=D0=B7=D0=B0=D0=BD=D0=BD=D0=BE=D1=81=D1=82=D0=B8 = =D0=B7=D0=B0=D0=BA=D0=B0=D0=B7=D1=87=D0=B8=D0=BA=D0=BE=D0=B2 =D0=B8 = =D0=B8=D0=BD=D1=8B=D1=85 = =D1=8E=D1=80=D0=B8=D0=B4=D0=B8=D1=87=D0=B5=D1=81=D0=BA=D0=B8=D1=85 = =D0=BB=D0=B8=D1=86 =D0=BF=D1=80=D0=B8 = =D0=BE=D1=81=D1=83=D1=89=D0=B5=D1=81=D1=82=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0= =B8 =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BE=D0=BA =D0=B2 = =D1=80=D0=B0=D0=BC=D0=BA=D0=B0=D1=85 = =D1=80=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D0=B8 = =D0=B8=D0=BD=D0=B2=D0=B5=D1=81=D1=82=D0=B8=D1=86=D0=B8=D0=BE=D0=BD=D0=BD=D0= =BE=D0=B3=D0=BE =D0=BF=D1=80=D0=BE=D0=B5=D0=BA=D1=82=D0=B0 = -=D0=9A=D0=BE=D0=BE=D1=80=D0=B4=D0=B8=D0=BD=D0=B0=D1=86=D0=B8=D0=BE=D0=BD= =D0=BD=D1=8B=D0=B9 =D0=BE=D1=80=D0=B3=D0=B0=D0=BD = =D0=9F=D1=80=D0=B0=D0=B2=D0=B8=D1=82=D0=B5=D0=BB=D1=8C=D1=81=D1=82=D0=B2=D0= =B0 =D0=BF=D0=BE = =D0=BE=D0=B1=D0=B5=D1=81=D0=BF=D0=B5=D1=87=D0=B5=D0=BD=D0=B8=D1=8E = =D0=B7=D0=B0=D0=BA=D0=B0=D0=B7=D1=87=D0=B8=D0=BA=D0=BE=D0=B2 = =D0=BF=D1=80=D0=BE=D0=B4=D1=83=D0=BA=D1=86=D0=B8=D0=B5=D0=B9 = =D0=BC=D0=B0=D1=88=D0=B8=D0=BD=D0=BE=D1=81=D1=82=D1=80=D0=BE=D0=B5=D0=BD=D0= =B8=D1=8F =D0=BF=D1=80=D0=B8 = =D1=80=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D0=B8 = =D0=B8=D0=BD=D0=B2=D0=B5=D1=81=D1=82=D0=B8=D1=86=D0=B8=D0=BE=D0=BD=D0=BD=D1= =8B=D1=85 =D0=BF=D1=80=D0=BE=D0=B5=D0=BA=D1=82=D0=BE=D0=B2: = =D1=86=D0=B5=D0=BB=D0=B8 =D0=B8 =D0=B7=D0=B0=D0=B4=D0=B0=D1=87=D0=B8 = =D1=81=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD=D0=B8=D1=8F; =D0=BF=D0=BE=D0=BB=D0=BD=D0=BE=D0=BC=D0=BE=D1=87=D0=B8=D1=8F = -=D0=9F=D0=B5=D1=80=D1=81=D0=BF=D0=B5=D0=BA=D1=82=D0=B8=D0=B2=D1=8B = =D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D0=B9 = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D0=B0 223-=D0=A4=D0=97: = =D0=BE=D0=B3=D1=80=D0=B0=D0=BD=D0=B8=D1=87=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=B2=D1=8B=D0=B1=D0=BE=D1=80=D0=B0 = =D1=81=D0=BF=D0=BE=D1=81=D0=BE=D0=B1=D0=BE=D0=B2 = =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BA=D0=B8, = =D0=BE=D1=82=D0=B1=D0=BE=D1=80 =D0=BE=D0=BF=D0=B5=D1=80=D0=B0=D1=82=D0=BE=D1=80=D0=BE=D0=B2 = =D1=8D=D0=BB=D0=B5=D0=BA=D1=82=D1=80=D0=BE=D0=BD=D0=BD=D1=8B=D1=85 = =D0=BF=D0=BB=D0=BE=D1=89=D0=B0=D0=B4=D0=BE=D0=BA, = =D0=B2=D0=B2=D0=B5=D0=B4=D0=B5=D0=BD=D0=B8=D0=B5 = =D1=82=D0=B8=D0=BF=D0=BE=D0=B2=D1=8B=D1=85 = =D0=BF=D0=BE=D0=BB=D0=BE=D0=B6=D0=B5=D0=BD=D0=B8=D0=B9 =D0=BE = =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BA=D0=B5, = =D1=80=D0=B0=D1=81=D1=88=D0=B8=D1=80=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=B2=D0=BE=D0=B7=D0=BC=D0=BE=D0=B6=D0=BD=D0=BE=D1=81=D1=82=D0=B5=D0=B9 = =D0=B4=D0=BB=D1=8F = =D0=BE=D0=B1=D0=B6=D0=B0=D0=BB=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F = =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BE=D0=BA, = =D0=B2=D0=B2=D0=B5=D0=B4=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=BF=D1=80=D0=BE=D1=86=D0=B5=D0=B4=D1=83=D1=80=D0=BD=D1=8B=D1=85 = =D0=BD=D0=BE=D1=80=D0=BC =D0=B4=D0=BB=D1=8F = =D0=BA=D0=BE=D0=BD=D0=BA=D1=83=D1=80=D0=B5=D0=BD=D1=82=D0=BD=D1=8B=D1=85 =D1=81=D0=BF=D0=BE=D1=81=D0=BE=D0=B1=D0=BE=D0=B2 = =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BA=D0=B8 -=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=BF=D0=BE=D1=80=D1=8F=D0=B4=D0=BA=D0=B0 = =D0=BF=D0=BB=D0=B0=D0=BD=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F = =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BE=D0=BA =D0=B2 2015-16 = =D0=B3=D0=BE=D0=B4=D0=B0=D1=85. = =D0=9F=D0=BB=D0=B0=D0=BD=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5 = =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BE=D0=BA =D1=83 =D1=81=D1=83=D0=B1=D1=8A=D0=B5=D0=BA=D1=82=D0=BE=D0=B2 = =D0=BC=D0=B0=D0=BB=D0=BE=D0=B3=D0=BE =D0=B8 = =D1=81=D1=80=D0=B5=D0=B4=D0=BD=D0=B5=D0=B3=D0=BE = =D0=BF=D1=80=D0=B5=D0=B4=D0=BF=D1=80=D0=B8=D0=BD=D0=B8=D0=BC=D0=B0=D1=82=D0= =B5=D0=BB=D1=8C=D1=81=D1=82=D0=B2=D0=B0 -=D0=9E=D1=86=D0=B5=D0=BD=D0=BA=D0=B0 =D0=B8 = =D0=BC=D0=BE=D0=BD=D0=B8=D1=82=D0=BE=D1=80=D0=B8=D0=BD=D0=B3 = =D1=81=D0=BE=D0=BE=D1=82=D0=B2=D0=B5=D1=82=D1=81=D1=82=D0=B2=D0=B8=D1=8F = =D0=BF=D0=BB=D0=B0=D0=BD=D0=BE=D0=B2 = =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BA=D0=B8, = =D0=BF=D1=80=D0=BE=D0=B5=D0=BA=D1=82=D0=BE=D0=B2 = =D0=BF=D0=BB=D0=B0=D0=BD=D0=BE=D0=B2, = =D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D0=B9 = =D0=BF=D0=BB=D0=B0=D0=BD=D0=BE=D0=B2 =D0=B8 =D0=BF=D1=80=D0=BE=D0=B5=D0=BA=D1=82=D0=BE=D0=B2 = =D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D0=B9 =D0=B2 = =D1=87=D0=B0=D1=81=D1=82=D0=B8 = =D1=81=D0=BE=D0=BE=D1=82=D0=B2=D0=B5=D1=82=D1=81=D1=82=D0=B2=D0=B8=D1=8F.= = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D0=BE=D0=B4=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=D1= =81=D1=82=D0=B2=D1=83 =D0=BE = =D1=80=D0=B0=D0=B7=D0=B2=D0=B8=D1=82=D0=B8=D0=B8 = =D0=BC=D0=B0=D0=BB=D0=BE=D0=B3=D0=BE =D0=B8 = =D1=81=D1=80=D0=B5=D0=B4=D0=BD=D0=B5=D0=B3=D0=BE = =D0=BF=D1=80=D0=B5=D0=B4=D0=BF=D1=80=D0=B8=D0=BD=D0=B8=D0=BC=D0=B0=D1=82=D0= =B5=D0=BB=D1=8C=D1=81=D1=82=D0=B2=D0=B0 -=D0=A2=D0=B8=D0=BF=D0=BE=D0=B2=D1=8B=D0=B5 = =D0=BF=D0=BE=D0=BB=D0=BE=D0=B6=D0=B5=D0=BD=D0=B8=D1=8F =D0=BE = =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BE=D1=87=D0=BD=D1=8B=D1=85 = =D0=BF=D1=80=D0=BE=D1=86=D0=B5=D0=B4=D1=83=D1=80=D0=B0=D1=85 = (=D0=9F=D1=80=D0=B8=D0=BA=D0=B0=D0=B7 = =D0=A0=D0=BE=D1=81=D0=B8=D0=BC=D1=83=D1=89=D0=B5=D1=81=D1=82=D0=B2=D0=B0 = =D0=BE=D1=82 24.12.2014 =D0=B3. =E2=84=96 515, = =D0=9F=D0=BE=D1=81=D1=82=D0=B0=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0= =B5 = =D0=9F=D1=80=D0=B0=D0=B2=D0=B8=D1=82=D0=B5=D0=BB=D1=8C=D1=81=D1=82=D0=B2=D0= =B0 =D0=9C=D0=9E =D0=BE=D1=82 19 = =D0=B0=D0=B2=D0=B3=D1=83=D1=81=D1=82=D0=B0 2014 =D0=B3. =E2=84=96 = 666/31) = -=D0=9E=D0=B1=D1=8F=D0=B7=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=D0=BD=D1=8B=D0=B5= =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BA=D0=B8 =D1=83 = =D1=81=D1=83=D0=B1=D1=8A=D0=B5=D0=BA=D1=82=D0=BE=D0=B2 = =D0=BC=D0=B0=D0=BB=D0=BE=D0=B3=D0=BE =D0=B8 = =D1=81=D1=80=D0=B5=D0=B4=D0=BD=D0=B5=D0=B3=D0=BE = =D0=BF=D1=80=D0=B5=D0=B4=D0=BF=D1=80=D0=B8=D0=BD=D0=B8=D0=BC=D0=B0=D1=82=D0= =B5=D0=BB=D1=8C=D1=81=D1=82=D0=B2=D0=B0 = (=D0=BF=D0=BE=D1=81=D1=82=D0=B0=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8= =D0=B5 =D0=BE=D1=82 11 =D0=B4=D0=B5=D0=BA=D0=B0=D0=B1=D1=80=D1=8F 2014 = =D0=B3. =E2=84=96 1352). =D0=A1=D0=BF=D0=BE=D1=81=D0=BE=D0=B1=D1=8B = =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BE=D0=BA =D1=83 = =D0=A1=D0=9C=D0=B8=D0=A1=D0=9F. = =D0=9E=D0=B1=D1=8F=D0=B7=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=D0=BD=D1=8B=D0=B5 =D1=82=D1=80=D0=B5=D0=B1=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F = =D0=BA =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BA=D0=B0=D0=BC. = =D0=9E=D1=82=D1=87=D0=B5=D1=82=D0=BD=D0=BE=D1=81=D1=82=D1=8C =D0=BE = =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BA=D0=B0=D1=85 =D1=83 = =D0=A1=D0=9C=D0=B8=D0=A1=D0=9F -=D0=A0=D0=B5=D0=B5=D1=81=D1=82=D1=80 = =D0=B4=D0=BE=D0=B3=D0=BE=D0=B2=D0=BE=D1=80=D0=BE=D0=B2 =D0=BD=D0=B0 = =D0=BE=D1=84=D0=B8=D1=86=D0=B8=D0=B0=D0=BB=D1=8C=D0=BD=D0=BE=D0=BC = =D1=81=D0=B0=D0=B9=D1=82=D0=B5 =D1=81 1 = =D1=8F=D0=BD=D0=B2=D0=B0=D1=80=D1=8F 2015 =D0=B3.: = =D1=81=D1=82=D1=80=D1=83=D0=BA=D1=82=D1=83=D1=80=D0=B0, = =D1=81=D0=BE=D0=B4=D0=B5=D1=80=D0=B6=D0=B0=D0=BD=D0=B8=D0=B5, =D1=82=D1=80=D0=B5=D0=B1=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F = (=D0=BF=D0=BE=D1=81=D1=82=D0=B0=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8= =D0=B5 =D0=BE=D1=82 31 =D0=BE=D0=BA=D1=82=D1=8F=D0=B1=D1=80=D1=8F 2014 = =D0=B3. =E2=84=96 1132, =D0=BF=D1=80=D0=B8=D0=BA=D0=B0=D0=B7 = =D0=9C=D0=B8=D0=BD=D1=84=D0=B8=D0=BD=D0=B0 =D0=BE=D1=82 29.12.2014 =E2=84=96 173=D0=BD) -=D0=98=D1=81=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D0=B8=D1=8F = =D0=B8=D0=B7 = =D1=82=D1=80=D0=B5=D0=B1=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F =D0=BE = =D1=80=D0=B0=D0=B7=D0=BC=D0=B5=D1=89=D0=B5=D0=BD=D0=B8=D0=B8 = =D0=B8=D0=BD=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=86=D0=B8=D0=B8 =D0=BE = =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BA=D0=B5 =D0=BD=D0=B0 = =D0=BE=D1=84=D0=B8=D1=86=D0=B8=D0=B0=D0=BB=D1=8C=D0=BD=D0=BE=D0=BC = =D1=81=D0=B0=D0=B9=D1=82=D0=B5 (=D0=B2 =D0=95=D0=98=D0=A1) - = =D0=A4=D0=B5=D0=B4=D0=B5=D1=80=D0=B0=D0=BB=D1=8C=D0=BD=D1=8B=D0=B9 = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD =D0=BE=D1=82 13 =D0=B8=D1=8E=D0=BB=D1=8F = 2015 =D0=B3. =E2=84=96 249-=D0=A4=D0=97, = =D0=A0=D0=B0=D1=81=D0=BF=D0=BE=D1=80=D1=8F=D0=B6=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=9F=D1=80=D0=B0=D0=B2=D0=B8=D1=82=D0=B5=D0=BB=D1=8C=D1=81=D1=82=D0=B2=D0= =B0 =D0=A0=D0=A4 =D0=BE=D1=82 30 =D0=B8=D1=8E=D0=BD=D1=8F 2015 =D0=B3. =E2=84=96 = 1247-=D1=80 =20 =20 =20 =D0=A3=D1=87=D0=B0=D1=81=D1=82=D0=B8=D0=B5 = =D1=81=D0=BE=D1=81=D1=82=D0=B0=D0=B2=D0=BB=D1=8F=D0=B5=D1=82: 11800 = =D1=80. =D0=A1=D0=BAu=D0=B4=D0=BAu (=D0=BE=D1=82 =D0=B4=D0=B2=D1=83=D1=85 = =D1=87=D0=B5=D0=BB=D0=BE=D0=B2=D0=B5=D0=BA =E2=80=93 10%, =D0=BE=D1=82 = =D1=82=D1=80=D0=B5=D1=85 =D0=B8 =D0=B1=D0=BE=D0=BB=D0=B5=D0=B5 =E2=80=93 = 15 %). =D0=92=D1=85=D0=BE=D0=B4=D0=B8=D1=82 = =D0=BC=D0=B5=D1=82=D0=BE=D0=B4=D0=B8=D1=87=D0=B5=D1=81=D0=BA=D0=B8=D0=B9 = =D0=BC=D0=B0=D1=82=D0=B5=D1=80=D0=B8=D0=B0=D0=BB, = =D0=BE=D0=B1=D0=B5=D0=B4=D1=8B, = =D0=BA=D0=BE=D1=84=D0=B5-=D0=BF=D0=B0=D1=83=D0=B7=D1=8B. =D0=9F=D0=BE = =D0=BE=D0=BA=D0=BE=D0=BD=D1=87=D0=B0=D0=BD=D0=B8=D1=8E = =D0=B7=D0=B0=D0=BD=D1=8F=D1=82=D0=B8=D1=8F =D0=92=D0=B0=D0=BC = =D0=B2=D1=8B=D0=B4=D0=B0=D0=B5=D1=82=D1=81=D1=8F = =D1=81=D0=B5=D1=80=D1=82=D0=B8=D1=84=D0=B8=D0=BA=D0=B0=D1=82.=20 ------------264BCCE1A3B5B2848 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset=UTF-8 MIME-Version: 1.0 Date: Tue, 24 Nov 2015 03:04:54 +0300
               
     


3=20 =D0=B4=D0=B5=D0=BA=D0=B0=D0=B1=D1=80=D1=8F  | =D0=B3. = =D0=9C=D0=BE=D1=81=D0=BA=D0=B2=D0=B0
(=D0=BF=D1=80=D0=BE=D0=BC=D0=BE=D0=BA=D0=BE=D0=B4:255= )=20

=D0=90=D0=BA=D0=BA=D1=80=D0=B5=D0=B4=D0=B8=D1=82=D0=BE= =D0=B2=D0=B0=D0=BD=D0=BD=D1=8B=D0=B9 = =D0=A3=D1=87=D0=B5=D0=B1=D0=BD=D1=8B=D0=B9 = =D1=86=D0=B5=D0=BD=D1=82=D1=80=20 =D0=BF=D1=80=D0=B8=D0=B3=D0=BB=D0=B0=D1=88=D0=B0=D0=B5=D1=82 = =D0=BD=D0=B0 =D0=BE=D0=B1=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=BF=D0=BE =D1=82=D0=B5=D0=BC=D0=B5:

44-=D0=A4=D0=97 =D0=B8=20 = 223-=D0=A4=D0=97:
=D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F= =D0=B2 = =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BA=D0=B0=D1=85.

=D0=94=D0=BB=D1=8F: = =D1=80=D1=83=D0=BA=D0=BE=D0=B2=D0=BE=D0=B4=D0=B8=D1=82=D0=B5=D0=BB= =D0=B5=D0=B9 =D0=B8 = =D1=81=D0=BF=D0=B5=D1=86=D0=B8=D0=B0=D0=BB=D0=B8=D1=81=D1=82=D0=BE=D0=B2,= =20 =D0=BE=D1=82=D0=B2=D0=B5=D1=87=D0=B0=D1=8E=D1=89=D0=B8=D1=85 = =D0=B7=D0=B0 = =D0=BE=D1=81=D1=83=D1=89=D0=B5=D1=81=D1=82=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0= =B5 =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BE=D0=BA, = =D1=87=D0=BB=D0=B5=D0=BD=D0=BE=D0=B2
=D0=9A=D0=BE=D0=BC=D0=B8=D1=81=D1= =81=D0=B8=D0=B9 =D0=B7=D0=B0=D0=BA=D0=B0=D0=B7=D1=87=D0=B8=D0=BA=D0=B0,=20 =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BD=D0=B8=D0=BA=D0=BE=D0=B2 = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=B0=D0=BA=D1=82=D0=BD=D0=BE=D0=B9 = =D1=81=D0=BB=D1=83=D0=B6=D0=B1=D1=8B = (=D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=B0=D0=BA=D1=82=D0=BD=D1=8B=D1=85 = =D1=83=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D1=8F=D1=8E=D1=89=D0=B8=D1=85),=20 = =D0=BE=D1=82=D0=B4=D0=B5=D0=BB=D0=BE=D0=B2
=D0=B7=D0=B0=D0=BA=D1=83=D0= =BF=D0=BE=D0=BA, = =D1=80=D1=83=D0=BA=D0=BE=D0=B2=D0=BE=D0=B4=D0=B8=D1=82=D0=B5=D0=BB=D0=B5=D0= =B9 =D0=BA=D0=BE=D0=BC=D0=BF=D0=B0=D0=BD=D0=B8=D0=B9, = =D1=80=D1=83=D0=BA=D0=BE=D0=B2=D0=BE=D0=B4=D0=B8=D1=82=D0=B5=D0=BB=D0=B5=D0= =B9 =D0=B8 = =D1=81=D0=BF=D0=B5=D1=86=D0=B8=D0=B0=D0=BB=D0=B8=D1=81=D1=82=D0=BE=D0=B2 = =D1=82=D0=B5=D0=BD=D0=B4=D0=B5=D1=80=D0=BD=D1=8B=D1=85 = =D0=BE=D1=82=D0=B4=D0=B5=D0=BB=D0=BE=D0=B2,
=D1=80=D1=83=D0=BA=D0=BE=D0= =B2=D0=BE=D0=B4=D0=B8=D1=82=D0=B5=D0=BB=D0=B5=D0=B9 = =D1=8E=D1=80=D0=B8=D0=B4=D0=B8=D1=87=D0=B5=D1=81=D0=BA=D0=B8=D1=85 = =D0=BE=D1=82=D0=B4=D0=B5=D0=BB=D0=BE=D0=B2 =D0=B8 = =D0=BE=D1=82=D0=B4=D0=B5=D0=BB=D0=BE=D0=B2 = =D0=BF=D1=80=D0=BE=D0=B4=D0=B0=D0=B6=20 = =D0=BA=D0=BE=D0=BC=D0=BF=D0=B0=D0=BD=D0=B8=D0=B9-=D0=BF=D0=BE=D1=81=D1=82= =D0=B0=D0=B2=D1=89=D0=B8=D0=BA=D0=BE=D0=B2=20 = (=D0=BF=D0=BE=D0=B4=D1=80=D1=8F=D0=B4=D1=87=D0=B8=D0=BA=D0=BE=D0=B2,
=D0= =B8=D1=81=D0=BF=D0=BE=D0=BB=D0=BD=D0=B8=D1=82=D0=B5=D0=BB=D0=B5=D0=B9).


=D0=97=D0=B0=D0=BD=D1=8F=D1=82=D0=B8=D0=B5=20 = =D0=BF=D1=80=D0=BE=D0=B2=D0=BE=D0=B4=D0=B8=D1=82=D1=81=D1=8F = =D1=81 10:00 =D0=B4=D0=BE 17:30

=D0=90=D0=B4=D1=80=D0=B5=D1=81 = =D0=BC=D0=B5=D1=80=D0=BE=D0=BF=D1=80=D0=B8=D1=8F=D1=82=D0=B8=D1=8F: =D0=BC.=20 =D0=91=D0=B0=D1=83=D0=BC=D0=B0=D0=BD=D1=81=D0=BA=D0=B0=D1=8F, = =D1=83=D0=BB. = =D0=91=D0=B0=D1=83=D0=BC=D0=B0=D0=BD=D1=81=D0=BA=D0=B0=D1=8F, =D0=B4.6, = =D1=81=D1=82=D1=80.2.

=D0=9F=D0=BE=D0=B4=D1=80=D0=BE=D0=B1= =D0=BD=D0=B0=D1=8F=20 =D0=B8=D0=BD=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=86=D0=B8=D1=8F = =D0=B8 = =D1=80=D0=B5=D0=B3=D0=B8=D1=81=D1=82=D1=80=D0=B0=D1=86=D0=B8=D1=8F = =D0=BF=D0=BE =D1=82=D0=B5=D0=BB=D0=B5=D1=84=D0=BE=D0=BD=D1=83: = 8 =20 =D0=BA=D0=BE=D0=B4 = =D0=B3=D0=BE=D1=80=D0=BE=D0=B4=D0=B0  (495)  =D1=82=D0=B5=D0=BB.:  961 - 00 = -=20 =D0=978
 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 =D0=9E=D0=BF=D0=B8=D1=81=D0=B0=D0=BD=D0=B8=D0=B5=20 = =D0=BF=D1=80=D0=BE=D0=B3=D1=80=D0=B0=D0=BC=D0=BC=D1=8B:
 
<= /FONT>
 
 
 
 
 
 
 

1.=20 =D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F =D0=B2 = =D1=80=D0=B5=D0=B3=D1=83=D0=BB=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0= =B8 =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BE=D0=BA =D0=BF=D0=BE = =D1=84=D0=B5=D0=B4=D0=B5=D1=80=D0=B0=D0=BB=D1=8C=D0=BD=D0=BE=D0=BC=D1=83 = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D1=83 =E2=84=96 44-=D0=A4=D0=97 "=D0=9E
=D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=B0=D0=BA= =D1=82=D0=BD=D0=BE=D0=B9 =D1=81=D0=B8=D1=81=D1=82=D0=B5=D0=BC=D0=B5 = =D0=B2 =D1=81=D1=84=D0=B5=D1=80=D0=B5 = =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BE=D0=BA = =D1=82=D0=BE=D0=B2=D0=B0=D1=80=D0=BE=D0=B2,=20 =D1=80=D0=B0=D0=B1=D0=BE=D1=82, =D1=83=D1=81=D0=BB=D1=83=D0=B3 = =D0=B4=D0=BB=D1=8F = =D0=BE=D0=B1=D0=B5=D1=81=D0=BF=D0=B5=D1=87=D0=B5=D0=BD=D0=B8=D1=8F
=D0= =B3=D0=BE=D1=81=D1=83=D0=B4=D0=B0=D1=80=D1=81=D1=82=D0=B2=D0=B5=D0=BD=D0=BD= =D1=8B=D1=85 =D0=B8 = =D0=BC=D1=83=D0=BD=D0=B8=D1=86=D0=B8=D0=BF=D0=B0=D0=BB=D1=8C=D0=BD=D1=8B=D1= =85 =D0=BD=D1=83=D0=B6=D0=B4" (=D0=9A=D0=A1).

 
 
 
 
 
 
 
-=D0=98=D1=82=D0=BE=D0=B3=D0=B8 = =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=8B =D0=BF=D0=BE 44-=D0=A4=D0=97 =D0=B2 = 2014 =D0=B3=D0=BE=D0=B4=D1=83 =D0=B8=20 =D0=BF=D0=B5=D1=80=D1=81=D0=BF=D0=B5=D0=BA=D1=82=D0=B8=D0=B2=D1=8B = =D1=80=D0=B0=D0=B7=D0=B2=D0=B8=D1=82=D0=B8=D1=8F = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=B0=D0=BA=D1=82=D0=BD=D0=BE=D0=B9 = =D1=81=D0=B8=D1=81=D1=82=D0=B5=D0=BC=D1=8B
-=D0=9F=D0=BB=D0=B0=D0=BD=D0= =B8=D1=80=D1=83=D0=B5=D0=BC=D1=8B=D0=B5 = =D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F 44-=D0=A4=D0=97 = =D0=B2=20 2015 =D0=B3=D0=BE=D0=B4=D1=83: = =D1=8D=D0=BB=D0=B5=D0=BA=D1=82=D1=80=D0=BE=D0=BD=D0=BD=D1=8B=D0=B5 = =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BA=D0=B8, = =D1=80=D0=B5=D1=84=D0=BE=D1=80=D0=BC=D0=B0 = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=BE=D0=BB=D1=8C=D0=BD=D1=8B=D1=85
=D0= =BE=D1=80=D0=B3=D0=B0=D0=BD=D0=BE=D0=B2, = =D0=BF=D0=BE=D0=B4=D0=B4=D0=B5=D1=80=D0=B6=D0=BA=D0=B0=20 = =D0=BE=D1=82=D0=B5=D1=87=D0=B5=D1=81=D1=82=D0=B2=D0=B5=D0=BD=D0=BD=D0=BE=D0= =B3=D0=BE = =D0=BF=D1=80=D0=BE=D0=B8=D0=B7=D0=B2=D0=BE=D0=B4=D0=B8=D1=82=D0=B5=D0=BB=D1= =8F
-=D0=A4=D0=B5=D0=B4=D0=B5=D1=80=D0=B0=D0=BB=D1=8C=D0=BD=D1=8B=D0=B9= =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD =E2=84=96 44-=D0=A4=D0=97 =D0=B2 = =D1=80=D0=B5=D0=B4=D0=B0=D0=BA=D1=86=D0=B8=D0=B8 =D0=BE=D1=82=20 13 =D0=B8=D1=8E=D0=BB=D1=8F 2015 = =D0=B3.
-=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F = =D0=B2 =D0=91=D1=8E=D0=B4=D0=B6=D0=B5=D1=82=D0=BD=D0=BE=D0=BC = =D0=BA=D0=BE=D0=B4=D0=B5=D0=BA=D1=81=D0=B5 = (=D0=B7=D0=B0=D0=BA=D0=BE=D0=BD =E2=84=96 25-=D0=A4=D0=97),=20 =D0=93=D1=80=D0=B0=D0=B6=D0=B4=D0=B0=D0=BD=D1=81=D0=BA=D0=BE=D0=BC = =D0=BA=D0=BE=D0=B4=D0=B5=D0=BA=D1=81=D0=B5 = (=D0=B7=D0=B0=D0=BA=D0=BE=D0=BD =E2=84=96 42-=D0=A4=D0=97) =
-=D0=97=D0=B0=D0=BA=D0=BE=D0=BD=D0=BE=D0=B4=D0=B0=D1=82=D0=B5=D0=BB=D1= =8C=D0=BD=D0=BE=D0=B5 = =D1=83=D1=81=D1=82=D0=B0=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=BF=D1=80=D0=B8=D0=BE=D1=80=D0=B8=D1=82=D0=B5=D1=82=D0=B0 = =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BA=D0=B8 = =D0=BF=D1=80=D0=BE=D0=BC=D1=8B=D1=88=D0=BB=D0=B5=D0=BD=D0=BD=D0=BE=D0=B9 = =D0=BF=D1=80=D0=BE=D0=B4=D1=83=D0=BA=D1=86=D0=B8=D0=B8,
=D0=BF=D1=80=D0= =BE=D0=B8=D0=B7=D0=B2=D0=B5=D0=B4=D0=B5=D0=BD=D0=BD=D0=BE=D0=B9 = =D0=BD=D0=B0 = =D1=82=D0=B5=D1=80=D1=80=D0=B8=D1=82=D0=BE=D1=80=D0=B8=D0=B8=20 =D0=A0=D0=A4 (=D0=B7=D0=B0=D0=BA=D0=BE=D0=BD =E2=84=96 = 488-=D0=A4=D0=97 =D0=BE=D1=82 31 = =D0=B4=D0=B5=D0=BA=D0=B0=D0=B1=D1=80=D1=8F 2014 =D0=B3.) =
-=D0=92=D0=B2=D0=B5=D0=B4=D0=B5=D0=BD=D0=B8=D0=B5 = =D1=88=D1=82=D1=80=D0=B0=D1=84=D0=BE=D0=B2 =D0=B8=20 = =D0=B4=D0=B8=D1=81=D0=BA=D0=B2=D0=B0=D0=BB=D0=B8=D1=84=D0=B8=D0=BA=D0=B0=D1= =86=D0=B8=D0=B8 =D0=B7=D0=B0 = =D0=BD=D0=B5=D0=B8=D1=81=D0=BF=D0=BE=D0=BB=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=BE=D0=B1=D1=8F=D0=B7=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=D1=81=D1=82=D0=B2,= =20 = =D0=BF=D1=80=D0=B5=D0=B4=D1=83=D1=81=D0=BC=D0=BE=D1=82=D1=80=D0=B5=D0=BD=D0= =BD=D1=8B=D1=85
=D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=B0=D0=BA=D1=82=D0=BE= =D0=BC (=D0=B7=D0=B0=D0=BA=D0=BE=D0=BD =D0=BE=D1=82 13.07.2015 =D0=B3. = =E2=84=96=20 = 265-=D0=A4=D0=97)
-=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D1= =8F = =D1=84=D0=B5=D0=B4=D0=B5=D1=80=D0=B0=D0=BB=D1=8C=D0=BD=D0=BE=D0=B3=D0=BE = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D0=B0 =D0=BE=D1=82 29 = =D0=B4=D0=B5=D0=BA=D0=B0=D0=B1=D1=80=D1=8F 2012 =D0=B3=D0=BE=D0=B4=D0=B0 = =E2=84=96 275-=D0=A4=D0=97=20 "=D0=9E = =D0=B3=D0=BE=D1=81=D1=83=D0=B4=D0=B0=D1=80=D1=81=D1=82=D0=B2=D0=B5=D0=BD=D0= =BD=D0=BE=D0=BC
=D0=BE=D0=B1=D0=BE=D1=80=D0=BE=D0=BD=D0=BD=D0=BE=D0=BC= = =D0=B7=D0=B0=D0=BA=D0=B0=D0=B7=D0=B5"
-=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0= =B5=D0=BD=D0=B8=D0=B5 =D0=BF=D1=80=D0=B0=D0=B2=D0=B8=D0=BB =D0=B8 = =D0=BE=D1=81=D0=BD=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B9=20 =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BE=D0=BA =D1=83 = =D0=B5=D0=B4=D0=B8=D0=BD=D1=81=D1=82=D0=B2=D0=B5=D0=BD=D0=BD=D0=BE=D0=B3=D0= =BE =D0=BF=D0=BE=D1=81=D1=82=D0=B0=D0=B2=D1=89=D0=B8=D0=BA=D0=B0 = (=D0=BF=D0=BE=D0=B4=D1=80=D1=8F=D0=B4=D1=87=D0=B8=D0=BA=D0=B0,
=D0=B8=D1= =81=D0=BF=D0=BE=D0=BB=D0=BD=D0=B8=D1=82=D0=B5=D0=BB=D1=8F) =E2=80=93=20 =D1=84=D0=B5=D0=B4=D0=B5=D1=80=D0=B0=D0=BB=D1=8C=D0=BD=D1=8B=D0=B5 = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D1=8B =D0=BE=D1=82 01.12.2014 =E2=84=96 = 416-=D0=A4=D0=97, =D0=BE=D1=82 29 = =D0=B4=D0=B5=D0=BA=D0=B0=D0=B1=D1=80=D1=8F 2014 =D0=B3.=20 =E2=84=96
458-=D0=A4=D0=97, =D0=BE=D1=82 31 = =D0=B4=D0=B5=D0=BA=D0=B0=D0=B1=D1=80=D1=8F 2014 =D0=B3. =E2=84=96 = 498-=D0=A4=D0=97, =D0=BE=D1=82 31 = =D0=B4=D0=B5=D0=BA=D0=B0=D0=B1=D1=80=D1=8F 2014 =D0=B3. =E2=84=96=20 519-=D0=A4=D0=97, =D0=BE=D1=82 08 =D0=BC=D0=B0=D1=80=D1=82=D0=B0 = 2015 =D0=B3.
=E2=84=96 48-=D0=A4=D0=97, =D0=BE=D1=82 13 = =D0=B8=D1=8E=D0=BB=D1=8F 2015 =D0=B3. =E2=84=96 227-=D0=A4=D0=97=20
-=D0=9D=D0=BE=D0=B2=D1=8B=D0=B5 = =D0=BD=D0=BE=D1=80=D0=BC=D0=B0=D1=82=D0=B8=D0=B2=D0=BD=D1=8B=D0=B5 = =D0=B0=D0=BA=D1=82=D1=8B, = =D0=BF=D1=80=D0=B8=D0=BD=D1=8F=D1=82=D1=8B=D0=B5 =D0=B2 = =D1=80=D0=B0=D0=B7=D0=B2=D0=B8=D1=82=D0=B8=D0=B5 = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D0=B0 =E2=84=9644-=D0=A4=D0=97; = =D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F=20 = =D0=BF=D1=80=D0=B8=D0=BD=D1=8F=D1=82=D1=8B=D1=85
=D1=80=D0=B0=D0=BD=D0= =B5=D0=B5 = =D0=BD=D0=BE=D1=80=D0=BC=D0=B0=D1=82=D0=B8=D0=B2=D0=BD=D1=8B=D1=85 = =D0=B0=D0=BA=D1=82=D0=BE=D0=B2
-=D0=9F=D0=BB=D0=B0=D0=BD =D0=B8 = =D0=BF=D0=B5=D1=80=D1=81=D0=BF=D0=B5=D0=BA=D1=82=D0=B8=D0=B2=D1=8B = =D0=BF=D1=80=D0=B8=D0=BD=D1=8F=D1=82=D0=B8=D1=8F=20 =D0=BF=D0=BE=D0=B4=D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D0=BD=D1=8B=D1=85 = =D0=BD=D0=BE=D1=80=D0=BC=D0=B0=D1=82=D0=B8=D0=B2=D0=BD=D1=8B=D1=85 = =D0=B0=D0=BA=D1=82=D0=BE=D0=B2 =D0=B2 2015 = =D0=B3=D0=BE=D0=B4=D1=83
-=D0=9E=D1=82=D0=BC=D0=B5=D0=BD=D0=B0 = =D1=81=D1=82=D0=B0=D1=82=D0=B8=D1=81=D1=82=D0=B8=D1=87=D0=B5=D1=81=D0=BA=D0= =B8=D1=85=20 =D0=BE=D1=82=D1=87=D0=B5=D1=82=D0=BE=D0=B2 =E2=84=96 = 1-=D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=B0=D0=BA=D1=82 =D0=B8 =E2=84=96 = 1-=D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BA=D0=B8 = (=D0=BF=D1=80=D0=B8=D0=BA=D0=B0=D0=B7 = =D0=A0=D0=BE=D1=81=D1=81=D1=82=D0=B0=D1=82=D0=B0 =D0=BE=D1=82 15.05.2015 = =D0=B3.
=E2=84=96=20 = 226)
-=D0=A0=D0=B0=D0=B7=D1=8A=D1=8F=D1=81=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F= = =D0=9C=D0=B8=D0=BD=D1=8D=D0=BA=D0=BE=D0=BD=D0=BE=D0=BC=D1=80=D0=B0=D0=B7=D0= =B2=D0=B8=D1=82=D0=B8=D1=8F, =D0=A4=D0=90=D0=A1, = =D0=9C=D0=B8=D0=BD=D1=84=D0=B8=D0=BD=D0=B0 =D0=BF=D0=BE = =D1=81=D0=BB=D0=BE=D0=B6=D0=BD=D1=8B=D0=BC = =D0=B2=D0=BE=D0=BF=D1=80=D0=BE=D1=81=D0=B0=D0=BC=20 = =D0=BE=D1=81=D1=83=D1=89=D0=B5=D1=81=D1=82=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D1= =8F
=D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BE=D0=BA
-=D0=A1=D1=83=D0=B4=D0= =B5=D0=B1=D0=BD=D0=B0=D1=8F =D0=B8 = =D0=B0=D0=B4=D0=BC=D0=B8=D0=BD=D0=B8=D1=81=D1=82=D1=80=D0=B0=D1=82=D0=B8=D0= =B2=D0=BD=D0=B0=D1=8F =D0=BF=D1=80=D0=B0=D0=BA=D1=82=D0=B8=D0=BA=D0=B0 = (=D1=88=D1=82=D1=80=D0=B0=D1=84=D1=8B=20 =D0=B8 =D0=BF=D0=B5=D0=BD=D0=B8 =D0=B7=D0=B0 = =D0=BD=D0=B0=D1=80=D1=83=D1=88=D0=B5=D0=BD=D0=B8=D0=B5 = =D1=83=D1=81=D0=BB=D0=BE=D0=B2=D0=B8=D0=B9 = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=B0=D0=BA=D1=82=D0=BE=D0=B2,
=D0=BE=D0= =B4=D0=BD=D0=BE=D1=81=D1=82=D0=BE=D1=80=D0=BE=D0=BD=D0=BD=D0=B8=D0=B9 = =D0=BE=D1=82=D0=BA=D0=B0=D0=B7 =D0=BE=D1=82=20 =D0=B8=D1=81=D0=BF=D0=BE=D0=BB=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=B0=D0=BA=D1=82=D0=BE=D0=B2, = =D0=B7=D0=B0=D0=BC=D0=B5=D0=BD=D0=B0 = =D0=BE=D0=B1=D0=B5=D1=81=D0=BF=D0=B5=D1=87=D0=B5=D0=BD=D0=B8=D1=8F = =D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=B0=D0=BA=D1=82=D0=B0,
=D0=BE=D1=82=D0= =BA=D0=BB=D0=BE=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=B7=D0=B0=D1=8F=D0=B2=D0=BE=D0=BA,=20 =D1=81=D0=B3=D0=BE=D0=B2=D0=BE=D1=80 =D0=BD=D0=B0 = =D1=82=D0=BE=D1=80=D0=B3=D0=B0=D1=85, = =D0=B2=D0=B5=D0=B4=D0=BE=D0=BC=D1=81=D1=82=D0=B2=D0=B5=D0=BD=D0=BD=D1=8B=D0= =B5 =D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D1=80=D0=BA=D0=B8 =D0=B8 = =D0=B4=D1=80.)
 
 
 
 
 
 
 

 

2.=20 =D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F =D0=B2 = =D1=80=D0=B5=D0=B3=D1=83=D0=BB=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0= =B8 =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BE=D0=BA =D0=BF=D0=BE = =D1=84=D0=B5=D0=B4=D0=B5=D1=80=D0=B0=D0=BB=D1=8C=D0=BD=D0=BE=D0=BC=D1=83 = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D1=83 =E2=84=96 223-=D0=A4=D0=97 "=D0=9E=20 = =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BA=D0=B0=D1=85
=D1=82=D0=BE=D0=B2=D0= =B0=D1=80=D0=BE=D0=B2, =D1=80=D0=B0=D0=B1=D0=BE=D1=82, = =D1=83=D1=81=D0=BB=D1=83=D0=B3 = =D0=BE=D1=82=D0=B4=D0=B5=D0=BB=D1=8C=D0=BD=D1=8B=D0=BC=D0=B8 = =D0=B2=D0=B8=D0=B4=D0=B0=D0=BC=D0=B8 = =D1=8E=D1=80=D0=B8=D0=B4=D0=B8=D1=87=D0=B5=D1=81=D0=BA=D0=B8=D1=85 = =D0=BB=D0=B8=D1=86".=20

 
 
 
 
 
 
 
-=D0=97=D0=B0=D0=BA=D0=BE=D0=BD =E2=84=96 223-=D0=A4=D0=97 = =D0=B2 =D1=80=D0=B5=D0=B4=D0=B0=D0=BA=D1=86=D0=B8=D0=B8 =D0=BE=D1=82 13 = =D0=B8=D1=8E=D0=BB=D1=8F=20 2015 = =D0=B3.
-=D0=9E=D1=81=D0=BE=D0=B1=D0=B5=D0=BD=D0=BD=D0=BE=D1=81=D1=82=D0= =B8 = =D0=BE=D1=81=D1=83=D1=89=D0=B5=D1=81=D1=82=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D1= =8F =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BE=D0=BA =D0=BF=D1=80=D0=B8 = =D1=80=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D0=B8=20 = =D0=B8=D0=BD=D0=B2=D0=B5=D1=81=D1=82=D0=B8=D1=86=D0=B8=D0=BE=D0=BD=D0=BD=D1= =8B=D1=85 = =D0=BF=D1=80=D0=BE=D0=B5=D0=BA=D1=82=D0=BE=D0=B2
-=D0=9F=D0=BE=D0=BD=D1= =8F=D1=82=D0=B8=D0=B5 = =D0=B8=D0=BD=D0=B2=D0=B5=D1=81=D1=82=D0=B8=D1=86=D0=B8=D0=BE=D0=BD=D0=BD=D0= =BE=D0=B3=D0=BE =D0=BF=D1=80=D0=BE=D0=B5=D0=BA=D1=82=D0=B0 =D0=B2 = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D0=B5 =E2=84=96=20 = 223-=D0=A4=D0=97
-=D0=94=D0=BE=D0=BF=D0=BE=D0=BB=D0=BD=D0=B8=D1=82=D0=B5= =D0=BB=D1=8C=D0=BD=D1=8B=D0=B5 = =D0=BE=D0=B1=D1=8F=D0=B7=D0=B0=D0=BD=D0=BD=D0=BE=D1=81=D1=82=D0=B8 = =D0=B7=D0=B0=D0=BA=D0=B0=D0=B7=D1=87=D0=B8=D0=BA=D0=BE=D0=B2 =D0=B8 = =D0=B8=D0=BD=D1=8B=D1=85 = =D1=8E=D1=80=D0=B8=D0=B4=D0=B8=D1=87=D0=B5=D1=81=D0=BA=D0=B8=D1=85 = =D0=BB=D0=B8=D1=86=20 =D0=BF=D1=80=D0=B8 = =D0=BE=D1=81=D1=83=D1=89=D0=B5=D1=81=D1=82=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0= =B8
=D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BE=D0=BA =D0=B2 = =D1=80=D0=B0=D0=BC=D0=BA=D0=B0=D1=85 = =D1=80=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D0=B8 = =D0=B8=D0=BD=D0=B2=D0=B5=D1=81=D1=82=D0=B8=D1=86=D0=B8=D0=BE=D0=BD=D0=BD=D0= =BE=D0=B3=D0=BE=20 = =D0=BF=D1=80=D0=BE=D0=B5=D0=BA=D1=82=D0=B0
-=D0=9A=D0=BE=D0=BE=D1=80=D0= =B4=D0=B8=D0=BD=D0=B0=D1=86=D0=B8=D0=BE=D0=BD=D0=BD=D1=8B=D0=B9 = =D0=BE=D1=80=D0=B3=D0=B0=D0=BD = =D0=9F=D1=80=D0=B0=D0=B2=D0=B8=D1=82=D0=B5=D0=BB=D1=8C=D1=81=D1=82=D0=B2=D0= =B0 =D0=BF=D0=BE = =D0=BE=D0=B1=D0=B5=D1=81=D0=BF=D0=B5=D1=87=D0=B5=D0=BD=D0=B8=D1=8E = =D0=B7=D0=B0=D0=BA=D0=B0=D0=B7=D1=87=D0=B8=D0=BA=D0=BE=D0=B2=20 = =D0=BF=D1=80=D0=BE=D0=B4=D1=83=D0=BA=D1=86=D0=B8=D0=B5=D0=B9
=D0=BC=D0= =B0=D1=88=D0=B8=D0=BD=D0=BE=D1=81=D1=82=D1=80=D0=BE=D0=B5=D0=BD=D0=B8=D1=8F= =D0=BF=D1=80=D0=B8 = =D1=80=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D0=B8 = =D0=B8=D0=BD=D0=B2=D0=B5=D1=81=D1=82=D0=B8=D1=86=D0=B8=D0=BE=D0=BD=D0=BD=D1= =8B=D1=85 =D0=BF=D1=80=D0=BE=D0=B5=D0=BA=D1=82=D0=BE=D0=B2: = =D1=86=D0=B5=D0=BB=D0=B8=20 =D0=B8 =D0=B7=D0=B0=D0=B4=D0=B0=D1=87=D0=B8 = =D1=81=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD=D0=B8=D1=8F;
=D0=BF=D0=BE=D0=BB=D0= =BD=D0=BE=D0=BC=D0=BE=D1=87=D0=B8=D1=8F
-=D0=9F=D0=B5=D1=80=D1=81=D0=BF= =D0=B5=D0=BA=D1=82=D0=B8=D0=B2=D1=8B = =D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D0=B9 = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D0=B0 223-=D0=A4=D0=97:=20 =D0=BE=D0=B3=D1=80=D0=B0=D0=BD=D0=B8=D1=87=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=B2=D1=8B=D0=B1=D0=BE=D1=80=D0=B0 = =D1=81=D0=BF=D0=BE=D1=81=D0=BE=D0=B1=D0=BE=D0=B2 = =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BA=D0=B8, = =D0=BE=D1=82=D0=B1=D0=BE=D1=80
=D0=BE=D0=BF=D0=B5=D1=80=D0=B0=D1=82=D0= =BE=D1=80=D0=BE=D0=B2 = =D1=8D=D0=BB=D0=B5=D0=BA=D1=82=D1=80=D0=BE=D0=BD=D0=BD=D1=8B=D1=85=20 =D0=BF=D0=BB=D0=BE=D1=89=D0=B0=D0=B4=D0=BE=D0=BA, = =D0=B2=D0=B2=D0=B5=D0=B4=D0=B5=D0=BD=D0=B8=D0=B5 = =D1=82=D0=B8=D0=BF=D0=BE=D0=B2=D1=8B=D1=85 = =D0=BF=D0=BE=D0=BB=D0=BE=D0=B6=D0=B5=D0=BD=D0=B8=D0=B9 =D0=BE = =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BA=D0=B5, = =D1=80=D0=B0=D1=81=D1=88=D0=B8=D1=80=D0=B5=D0=BD=D0=B8=D0=B5
=D0=B2=D0= =BE=D0=B7=D0=BC=D0=BE=D0=B6=D0=BD=D0=BE=D1=81=D1=82=D0=B5=D0=B9=20 =D0=B4=D0=BB=D1=8F = =D0=BE=D0=B1=D0=B6=D0=B0=D0=BB=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F = =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BE=D0=BA, = =D0=B2=D0=B2=D0=B5=D0=B4=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=BF=D1=80=D0=BE=D1=86=D0=B5=D0=B4=D1=83=D1=80=D0=BD=D1=8B=D1=85 = =D0=BD=D0=BE=D1=80=D0=BC =D0=B4=D0=BB=D1=8F=20 = =D0=BA=D0=BE=D0=BD=D0=BA=D1=83=D1=80=D0=B5=D0=BD=D1=82=D0=BD=D1=8B=D1=85<= BR>=D1=81=D0=BF=D0=BE=D1=81=D0=BE=D0=B1=D0=BE=D0=B2 = =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BA=D0=B8
-=D0=98=D0=B7=D0=BC=D0=B5=D0= =BD=D0=B5=D0=BD=D0=B8=D0=B5 =D0=BF=D0=BE=D1=80=D1=8F=D0=B4=D0=BA=D0=B0 = =D0=BF=D0=BB=D0=B0=D0=BD=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F = =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BE=D0=BA =D0=B2 2015-16 = =D0=B3=D0=BE=D0=B4=D0=B0=D1=85. = =D0=9F=D0=BB=D0=B0=D0=BD=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5 = =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BE=D0=BA = =D1=83
=D1=81=D1=83=D0=B1=D1=8A=D0=B5=D0=BA=D1=82=D0=BE=D0=B2 = =D0=BC=D0=B0=D0=BB=D0=BE=D0=B3=D0=BE =D0=B8=20 =D1=81=D1=80=D0=B5=D0=B4=D0=BD=D0=B5=D0=B3=D0=BE = =D0=BF=D1=80=D0=B5=D0=B4=D0=BF=D1=80=D0=B8=D0=BD=D0=B8=D0=BC=D0=B0=D1=82=D0= =B5=D0=BB=D1=8C=D1=81=D1=82=D0=B2=D0=B0
-=D0=9E=D1=86=D0=B5=D0=BD=D0=BA= =D0=B0 =D0=B8 = =D0=BC=D0=BE=D0=BD=D0=B8=D1=82=D0=BE=D1=80=D0=B8=D0=BD=D0=B3 = =D1=81=D0=BE=D0=BE=D1=82=D0=B2=D0=B5=D1=82=D1=81=D1=82=D0=B2=D0=B8=D1=8F = =D0=BF=D0=BB=D0=B0=D0=BD=D0=BE=D0=B2=20 =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BA=D0=B8, = =D0=BF=D1=80=D0=BE=D0=B5=D0=BA=D1=82=D0=BE=D0=B2 = =D0=BF=D0=BB=D0=B0=D0=BD=D0=BE=D0=B2, = =D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D0=B9 = =D0=BF=D0=BB=D0=B0=D0=BD=D0=BE=D0=B2 = =D0=B8
=D0=BF=D1=80=D0=BE=D0=B5=D0=BA=D1=82=D0=BE=D0=B2 = =D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D0=B9 =D0=B2 = =D1=87=D0=B0=D1=81=D1=82=D0=B8=20 = =D1=81=D0=BE=D0=BE=D1=82=D0=B2=D0=B5=D1=82=D1=81=D1=82=D0=B2=D0=B8=D1=8F.= = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD=D0=BE=D0=B4=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=D1= =81=D1=82=D0=B2=D1=83 =D0=BE = =D1=80=D0=B0=D0=B7=D0=B2=D0=B8=D1=82=D0=B8=D0=B8 = =D0=BC=D0=B0=D0=BB=D0=BE=D0=B3=D0=BE =D0=B8=20 = =D1=81=D1=80=D0=B5=D0=B4=D0=BD=D0=B5=D0=B3=D0=BE
=D0=BF=D1=80=D0=B5=D0= =B4=D0=BF=D1=80=D0=B8=D0=BD=D0=B8=D0=BC=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=D1=81= =D1=82=D0=B2=D0=B0
-=D0=A2=D0=B8=D0=BF=D0=BE=D0=B2=D1=8B=D0=B5 = =D0=BF=D0=BE=D0=BB=D0=BE=D0=B6=D0=B5=D0=BD=D0=B8=D1=8F =D0=BE = =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BE=D1=87=D0=BD=D1=8B=D1=85=20 =D0=BF=D1=80=D0=BE=D1=86=D0=B5=D0=B4=D1=83=D1=80=D0=B0=D1=85 = (=D0=9F=D1=80=D0=B8=D0=BA=D0=B0=D0=B7 = =D0=A0=D0=BE=D1=81=D0=B8=D0=BC=D1=83=D1=89=D0=B5=D1=81=D1=82=D0=B2=D0=B0 = =D0=BE=D1=82 24.12.2014 =D0=B3. =E2=84=96
515, = =D0=9F=D0=BE=D1=81=D1=82=D0=B0=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0= =B5=20 = =D0=9F=D1=80=D0=B0=D0=B2=D0=B8=D1=82=D0=B5=D0=BB=D1=8C=D1=81=D1=82=D0=B2=D0= =B0 =D0=9C=D0=9E =D0=BE=D1=82 19 = =D0=B0=D0=B2=D0=B3=D1=83=D1=81=D1=82=D0=B0 2014 =D0=B3. =E2=84=96 = 666/31)
-=D0=9E=D0=B1=D1=8F=D0=B7=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=D0=BD=D1= =8B=D0=B5 =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BA=D0=B8=20 =D1=83 =D1=81=D1=83=D0=B1=D1=8A=D0=B5=D0=BA=D1=82=D0=BE=D0=B2 = =D0=BC=D0=B0=D0=BB=D0=BE=D0=B3=D0=BE =D0=B8 = =D1=81=D1=80=D0=B5=D0=B4=D0=BD=D0=B5=D0=B3=D0=BE = =D0=BF=D1=80=D0=B5=D0=B4=D0=BF=D1=80=D0=B8=D0=BD=D0=B8=D0=BC=D0=B0=D1=82=D0= =B5=D0=BB=D1=8C=D1=81=D1=82=D0=B2=D0=B0
(=D0=BF=D0=BE=D1=81=D1=82=D0=B0= =D0=BD=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5 =D0=BE=D1=82 11=20 =D0=B4=D0=B5=D0=BA=D0=B0=D0=B1=D1=80=D1=8F 2014 =D0=B3. =E2=84=96 = 1352). =D0=A1=D0=BF=D0=BE=D1=81=D0=BE=D0=B1=D1=8B = =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BE=D0=BA =D1=83 = =D0=A1=D0=9C=D0=B8=D0=A1=D0=9F.=20 = =D0=9E=D0=B1=D1=8F=D0=B7=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=D0=BD=D1=8B=D0=B5<= BR>=D1=82=D1=80=D0=B5=D0=B1=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F =D0=BA = =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BA=D0=B0=D0=BC. = =D0=9E=D1=82=D1=87=D0=B5=D1=82=D0=BD=D0=BE=D1=81=D1=82=D1=8C =D0=BE = =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BA=D0=B0=D1=85 =D1=83=20 = =D0=A1=D0=9C=D0=B8=D0=A1=D0=9F
-=D0=A0=D0=B5=D0=B5=D1=81=D1=82=D1=80 = =D0=B4=D0=BE=D0=B3=D0=BE=D0=B2=D0=BE=D1=80=D0=BE=D0=B2 =D0=BD=D0=B0 = =D0=BE=D1=84=D0=B8=D1=86=D0=B8=D0=B0=D0=BB=D1=8C=D0=BD=D0=BE=D0=BC = =D1=81=D0=B0=D0=B9=D1=82=D0=B5 =D1=81 1 = =D1=8F=D0=BD=D0=B2=D0=B0=D1=80=D1=8F 2015 =D0=B3.:=20 =D1=81=D1=82=D1=80=D1=83=D0=BA=D1=82=D1=83=D1=80=D0=B0, = =D1=81=D0=BE=D0=B4=D0=B5=D1=80=D0=B6=D0=B0=D0=BD=D0=B8=D0=B5,
=D1=82=D1= =80=D0=B5=D0=B1=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F = (=D0=BF=D0=BE=D1=81=D1=82=D0=B0=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8= =D0=B5 =D0=BE=D1=82 31 =D0=BE=D0=BA=D1=82=D1=8F=D0=B1=D1=80=D1=8F 2014 = =D0=B3.=20 =E2=84=96 1132, =D0=BF=D1=80=D0=B8=D0=BA=D0=B0=D0=B7 = =D0=9C=D0=B8=D0=BD=D1=84=D0=B8=D0=BD=D0=B0 =D0=BE=D1=82 = 29.12.2014
=E2=84=96 = 173=D0=BD)
-=D0=98=D1=81=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D0=B8=D1=8F= =D0=B8=D0=B7=20 =D1=82=D1=80=D0=B5=D0=B1=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F = =D0=BE =D1=80=D0=B0=D0=B7=D0=BC=D0=B5=D1=89=D0=B5=D0=BD=D0=B8=D0=B8 = =D0=B8=D0=BD=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=86=D0=B8=D0=B8 =D0=BE = =D0=B7=D0=B0=D0=BA=D1=83=D0=BF=D0=BA=D0=B5 =D0=BD=D0=B0 = =D0=BE=D1=84=D0=B8=D1=86=D0=B8=D0=B0=D0=BB=D1=8C=D0=BD=D0=BE=D0=BC = =D1=81=D0=B0=D0=B9=D1=82=D0=B5=20 (=D0=B2
=D0=95=D0=98=D0=A1) - = =D0=A4=D0=B5=D0=B4=D0=B5=D1=80=D0=B0=D0=BB=D1=8C=D0=BD=D1=8B=D0=B9 = =D0=B7=D0=B0=D0=BA=D0=BE=D0=BD =D0=BE=D1=82 13 =D0=B8=D1=8E=D0=BB=D1=8F = 2015 =D0=B3. =E2=84=96 249-=D0=A4=D0=97, = =D0=A0=D0=B0=D1=81=D0=BF=D0=BE=D1=80=D1=8F=D0=B6=D0=B5=D0=BD=D0=B8=D0=B5 = = =D0=9F=D1=80=D0=B0=D0=B2=D0=B8=D1=82=D0=B5=D0=BB=D1=8C=D1=81=D1=82=D0=B2=D0= =B0 =D0=A0=D0=A4
=D0=BE=D1=82 30 =D0=B8=D1=8E=D0=BD=D1=8F 2015 = =D0=B3. =E2=84=96 1247-=D1=80
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 


=D0=A3=D1=87=D0=B0=D1=81=D1=82=D0=B8=D0=B5 = =D1=81=D0=BE=D1=81=D1=82=D0=B0=D0=B2=D0=BB=D1=8F=D0=B5=D1=82:=20 11800 =D1=80.
=D0=A1=D0=BAu=D0=B4=D0=BAu = (=D0=BE=D1=82 =D0=B4=D0=B2=D1=83=D1=85 = =D1=87=D0=B5=D0=BB=D0=BE=D0=B2=D0=B5=D0=BA =E2=80=93 10%, =D0=BE=D1=82 = =D1=82=D1=80=D0=B5=D1=85 =D0=B8=20 =D0=B1=D0=BE=D0=BB=D0=B5=D0=B5 =E2=80=93 15 = %).
=D0=92=D1=85=D0=BE=D0=B4=D0=B8=D1=82 = =D0=BC=D0=B5=D1=82=D0=BE=D0=B4=D0=B8=D1=87=D0=B5=D1=81=D0=BA=D0=B8=D0=B9 = =D0=BC=D0=B0=D1=82=D0=B5=D1=80=D0=B8=D0=B0=D0=BB, = =D0=BE=D0=B1=D0=B5=D0=B4=D1=8B, = =D0=BA=D0=BE=D1=84=D0=B5-=D0=BF=D0=B0=D1=83=D0=B7=D1=8B.
=D0=9F=D0=BE = =D0=BE=D0=BA=D0=BE=D0=BD=D1=87=D0=B0=D0=BD=D0=B8=D1=8E = =D0=B7=D0=B0=D0=BD=D1=8F=D1=82=D0=B8=D1=8F =D0=92=D0=B0=D0=BC = =D0=B2=D1=8B=D0=B4=D0=B0=D0=B5=D1=82=D1=81=D1=8F = =D1=81=D0=B5=D1=80=D1=82=D0=B8=D1=84=D0=B8=D0=BA=D0=B0=D1=82. =

 
 
 
 
 
 
 
 
 
 
 
 
= ------------264BCCE1A3B5B2848-- From mtv1@boyingyang.com Mon Nov 23 22:09:36 2015 Return-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.9 required=5.0 tests=HTML_IMAGE_ONLY_20, HTML_MESSAGE,HTML_OBFUSCATE_05_10,MPART_ALT_DIFF,UNPARSEABLE_RELAY 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 5F67E7F37 for ; Mon, 23 Nov 2015 22:09:36 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id D882EAC006 for ; Mon, 23 Nov 2015 20:09:31 -0800 (PST) X-ASG-Debug-ID: 1448338162-04cb6c0cd21b1b60001-NocioJ Received: from boyingyang.com ([221.172.214.78]) by cuda.sgi.com with SMTP id M3A8EKv7qe6vWRJe for ; Mon, 23 Nov 2015 20:09:22 -0800 (PST) X-Barracuda-Envelope-From: mtv1@boyingyang.com X-Barracuda-Apparent-Source-IP: 221.172.214.78 Received: from [192.168.1.25]; Tue, 24 Nov 2015 12:08:28 +0800 From: "MTV1" Reply-To: sunsesoft3@163.com To: "xfs" Subject: =?GB2312?B?0rXO8bSrzbO1xL+qt6K/zbun0KfCyrXNLNGw1dK/qrei0MLLvMK3o6E=?= Message-ID: <201511241208285314825@boyingyang.com> X-ASG-Orig-Subj: =?GB2312?B?0rXO8bSrzbO1xL+qt6K/zbun0KfCyrXNLNGw1dK/qrei0MLLvMK3o6E=?= Date: Tue, 24 Nov 2015 12:08:28 +0800 X-Mailer: Foxmail 6, 10, 201, 20 [cn] MIME-Version: 1.0 Content-Type: multipart/related; boundary="----=ovck756_8341_353095431.593253" X-Priority: 3 X-Barracuda-Connect: UNKNOWN[221.172.214.78] X-Barracuda-Start-Time: 1448338162 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 1.52 X-Barracuda-Spam-Status: No, SCORE=1.52 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=HTML_IMAGE_ONLY_20, HTML_IMAGE_ONLY_20_2, HTML_MESSAGE, HTML_OBFUSCATE_05_10, HTML_OBFUSCATE_05_10_2, MPART_ALT_DIFF, RDNS_NONE, UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24670 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines 0.00 HTML_IMAGE_ONLY_20 BODY: HTML: images with 1600-2000 bytes of words 0.00 HTML_OBFUSCATE_05_10 BODY: Message is 5% to 10% HTML obfuscation 0.00 HTML_MESSAGE BODY: HTML included in message 0.14 MPART_ALT_DIFF BODY: HTML and text parts are different 0.70 HTML_IMAGE_ONLY_20_2 HTML: images with 1600-2000 bytes of words 0.57 HTML_OBFUSCATE_05_10_2 Message is 05% to 10% HTML obfuscation 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS This is a multi-part message in MIME format. ------=ovck756_8341_353095431.593253 Content-Type: multipart/alternative; boundary="----=lsz372_10389_439792403.647321" ------=lsz372_10389_439792403.647321 Content-Type: text/plain; charset="GB2312" Content-Transfer-Encoding: base64 JiMzOTY0MDsmIzI1OTI4OyYjMjYyMzQ7JiMzMzAyMTsmIzMyNjc2OyYjMjE0NTc7JiMzNzAzODsm IzIwMj0xNDsgJiMyMjgxMDsmIzIwMDI3OyYjMzkwNjQ7JiMyMjgxMDsmIzIwODY5OyYjMjM0ODE7 Jj0jMjI4MTA7JiMzNjEzNDsmIzIxNDk1OyAmIzM4NTQzOyYjMjY0MjY7JiMzMjQ1MjsmIzIxNTEy OyYjMTk5Nzg7JiMyMTMxNTsmIzIzNTUzOyYjMTk5PTgxOyYjMjE1MTY7JiMyMDg2OTsmIzIzNDgx OyYjMzAzNDA7JiMyNDMyMDsmIzIxNDU3OyYjMjA0NDk7JiM2NTI5MjsmIzI9MzQzNjsmIzIwODQw OyYjMjcxNjk7JiMyNTMxMTsmIzI1MTYzOyYjMjQwMzc7JiMxOTk2ODsmIzIzNTQ1OyYjMTk5Njg7 Jj0jMzAzNDA7JiMyMTQ1NzsmIzM2ODY1OyYjMjYwNDE7JiMyNDMzNTsmIzY1MjkyOyYjMjE0NTc7 JiMzNjg2NTsmIzIxMDQwPTsmIzMwNDQ2OyYjMjY2MzE7JiMyMzQ1ODsmIzI1MTQzOyYjMzcwMzg7 JiMzMTY2NTsmIzEyMjkwOyAmIzI2MzY3OyYjMjAxOTU7JiMyNTE2MzsmIzI0MDM3OyYjMzIzMjE7 JiMyOTcxMjsmIzI1ODA1OyYjMjAzPTE2OyYjNjUyOTI7JiMzNTI5OTsmIzI1OTE4OyYjMjQ3NDQ7 JiMzMDM0MDsmIzIxNDUyOyYjMjUxNjM7JiMxMjI5MDsgJiMyMjMxMjsmIzMyNDQ3OyYjMzU4MTQ7 JiMzMjQ9NTQ7JiMzNjcxOTsmIzIwMjE0OyYjMjA0NDk7JiMyNDY4NzsmIzM1ODMxOyYjMjE2NzI7 JiMzNTgxMDs9M0Q9PTNEPTNEPTNEPTNEPTNEPTNEPTNEPTNEPTNEPTNEPTNEPTNEPTNEPTNEPTNE PTNEPTNEPTNEPTNEPTNEPTNEZG91aGFwMi0yLTMtOC0zLTItMC03LTQtNyYjMjExNTI7JiMyNTk2 ODsmIzIzMzgzO1FRJiMyMTQ9OTU7JiMyMTQ4NzsmIzIyMzEyOyYjMzI0NDc7JiMyMTAzMzsmIzI5 OTkyOyYjMzYxNDk7JiMyMTQ5NjsmIzIwMTM1OyYjMj0xNjk3OyYjMjA4NTE7JiMzODE5MDsmIzM1 Nzg5OyYjNjUyOTI7JiMyMDgxMzsmIzM2MTUzOyYjMjAwMjY7JiMyNDc0NDsmPSMyODQzNjsmIzMx MDM0OyYjMjU2Mjg7JiMzMjAzNDsmIzIzNjQ2OyYjMjAxMTA7JiMyNDc0NDsmIzMwMzQwOyYjMzA0 NDY9OyYjMjY2MzE7JiMyMzQ1ODsmIzI1MTQzOyYjNjUyODg7JiMzMDQ1MjsmIzM1MjY2OyYjMjU5 Mjg7JiMyNjUyNDsmIzY1Mj04OTs= ------=lsz372_10389_439792403.647321 Content-Type: text/html; charset="GB2312" Content-Transfer-Encoding: quoted-printable
高效智能群发邮Ê= 14;
 
多主题
多内容
&= #22810;账号
 
随机组合上千封Ç= 81;同内容的开发信,= 3436;全模拟手工一对一&= #30340;发送方式,发送到= ;目标客户邮箱。
 
替代手工繁琐操Ë= 16;,解放您的双手。
 
在线详ń= 54;软件信息请咨询
=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
<= font color=3D"#ff0000">douhap
2-2-3-8-3-2-0-7-4-7

数字QQÖ= 95;可在线利用贵司产= 1697;关键词,免费为您&= #28436;示搜索属于您的目= ;标客户(直观效果ʌ= 89;
------=lsz372_10389_439792403.647321-- ------=ovck756_8341_353095431.593253 Content-Type: image/png; name="QQ.png" Content-Transfer-Encoding: base64 Content-ID: <79714.12066001.49022@com> iVBORw0KGgoAAAANSUhEUgAAABcAAAAYCAIAAACeHvEiAAADL0lEQVR42mNsW7SXAQj+M1ACGDsW 74exQSb9J8s4xo4lB2CGkO8exk64KQj3gBhP7lx7cPXc7Yun//z5xczGpqCupW3uJC6nQpQpEHD+ 4O5H165+/vTh6+fXDP///Wf4BzRbWFJKz8pVzdAKzQTspjy7f/PwhjX8AsItdSlWds7MzMx///49 dmhvTFymtJK6rV8Mv4gEkgk43HJw3eL7V6+KivIfPLwDaERu/aTJjXlAg5QV1JhZmDVN7ay8owib MrM6CyiuoqZSX5OL7JbYuEw2dnYhCSm/1CpCpvz9u6Mu7SEDx7Gsu+JuAgzscgw/PzG8e/nm1VeR u3905yrxCQj7FXUSMIXp2xfj2QW/br5+xfM3ovAXqwkPw9uPDG8Yf31gWD6Fneknl6g0/8XiOeCI ZMRuClDm9Ym9fnvn2j14f1VdZpU4m+yDN/9YfzH9Y+NnZhL//l/v59/FQmInLYN0rZ2gLmFEMgWS 4B5ev3R4w7J41k9xLx+zCTCyK8pxCPAzfvnI8P3r/58/3/5jf/n8T8hvHm5RQVP3MAVNA4QpHUhu ObppxbWTR5UVxKbFRnzpLGbh4pRSkGUVl/ylYfhbRuU/MI6UNU31TAVEhMXlVZ1Ck+Chg2LK3LrC f3//hHgaNtV1vAmw+S8lL7RsGxMTEzMzEDH/+P3309efBX6mxx/8FpVSCMmtwW7K7Oo8PVvnILU7 kYXLGYPN3rHzi2w6BpH69+//p28/f/34trQx8b6I5+k9mwPSy+ChiWLK758/gELGb+vkAtcqSAqz s7GysrIAM+mfv3+///zz8sNX9r9fny0P3C/RwcTMAgkSSICimAIECm+2qTBtFRZReqkzQUFGjI+L 4++/fz9+/QE65Nn965JXCz98/L5HYhJYPyNcF7opDueTzDP1/78/fn2f5ltR009ijqKiYr9eXFX+ t56H8wSvisXluWe//mQ/YDgbJUeimSJ9aznv52u8TF///Gb4wSD8SUjhiUyAzP1Vou8v/2ZhlRP8 8f63wBc2ocvK+fhMwQn+wwksAKnEZGTEbwqeohC53MVnEP7iFNUUXAb9J1BHYJiCzSCC5ToAGVJv IhPU9g4AAAAASUVORK5CYII= ------=ovck756_8341_353095431.593253-- From BATV+01b2316b9c763e6c5797+4475+infradead.org+hch@bombadil.srs.infradead.org Tue Nov 24 01:42:07 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 C3FCD7F37 for ; Tue, 24 Nov 2015 01:42:07 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 56069AC002 for ; Mon, 23 Nov 2015 23:42:04 -0800 (PST) X-ASG-Debug-ID: 1448350921-04bdf07f0720ab10001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id UAD1fjaaCJpiuZS7 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Mon, 23 Nov 2015 23:42:01 -0800 (PST) X-Barracuda-Envelope-From: BATV+01b2316b9c763e6c5797+4475+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 1a18Eh-0003S6-He; Tue, 24 Nov 2015 07:41:59 +0000 Date: Mon, 23 Nov 2015 23:41:59 -0800 From: Christoph Hellwig To: "Darrick J. Wong" Cc: Christoph Hellwig , david@fromorbit.com, fstests@vger.kernel.org, xfs@oss.sgi.com, tao.peng@primarydata.com, linux-ext4@vger.kernel.org, Anna.Schumaker@netapp.com, linux-btrfs@vger.kernel.org Subject: Re: [PATCH 2/2] generic/15[78]: fix error messages in the golden output Message-ID: <20151124074159.GA32289@infradead.org> X-ASG-Orig-Subj: Re: [PATCH 2/2] generic/15[78]: fix error messages in the golden output References: <20151121005001.20398.92856.stgit@birch.djwong.org> <20151121005014.20398.22316.stgit@birch.djwong.org> <20151121180644.GA23916@infradead.org> <20151123212533.GC10589@birch.djwong.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151123212533.GC10589@birch.djwong.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: 1448350921 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/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, MARKETING_SUBJECT, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24674 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.60 MARKETING_SUBJECT Subject contains popular marketing words 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS On Mon, Nov 23, 2015 at 01:25:33PM -0800, Darrick J. Wong wrote: > > Shouldn't these be Invalid argument just like the > > to a device case above or the clone case? > > I was trying to mirror the behavior of reflink, which spits out > EOPNOTSUPP when the destination isn't a regular file and EINVAL > when the source isn't a regular file. clone is called on the destination and takes the source from the ioctl argument. dedupe is called on the source and then opens the destinations, so they're not really comparable. Btrfs currently returns EACCES for non-dir, non-regular destinations which look wrong and I think EINVAL for a mismatch between source and destination types would make most sense. I've also prepared a btrfs patch for this and clone, but I'd like to have consensus on the exact error first. From netwest@bt.com Tue Nov 24 05:54:06 2015 Return-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=HTML_IMAGE_ONLY_16, HTML_MESSAGE,T_REMOTE_IMAGE 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 AA6607F37 for ; Tue, 24 Nov 2015 05:54:05 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 309B5AC004 for ; Tue, 24 Nov 2015 03:54:01 -0800 (PST) X-ASG-Debug-ID: 1448366038-04cbb0605c1f1ea0001-NocioJ Received: from omx11.esk.m4.zaq.ne.jp (omx11.esk.m4.zaq.ne.jp [220.152.48.5]) by cuda.sgi.com with ESMTP id juk551zBthFdT4iC for ; Tue, 24 Nov 2015 03:53:59 -0800 (PST) X-Barracuda-Envelope-From: netwest@bt.com X-Barracuda-Apparent-Source-IP: 220.152.48.5 Received: from omx11.esk.m4.zaq.ne.jp ([220.152.49.33] [220.152.49.33]) by omx11.esk.m4.zaq.ne.jp with ESMTP id <20151124115358613.PXYH.5273.omx11.esk.m4.zaq.ne.jp@omx11.esk.m4.zaq.ne.jp>; Tue, 24 Nov 2015 20:53:58 +0900 Received: from smtpa22.esk.m4.zaq.ne.jp ([182.16.62.155] [182.16.62.155]) by smtpa22.esk.m4.zaq.ne.jp with ESMTP id <20151124115358421.WDFZ.9411.smtpa22.esk.m4.zaq.ne.jp@smtpa22.esk.m4.zaq.ne.jp>; Tue, 24 Nov 2015 20:53:58 +0900 Content-Type: multipart/alternative; boundary="===============1663350128==" MIME-Version: 1.0 Subject: Important Information To: Recipients X-ASG-Orig-Subj: Important Information From: "NatWest" Date: Tue, 24 Nov 2015 19:53:44 +0800 Message-Id: <20151124115358421.WDFZ.9411.smtpa22.esk.m4.zaq.ne.jp@smtpa22.esk.m4.zaq.ne.jp> X-Barracuda-Connect: omx11.esk.m4.zaq.ne.jp[220.152.48.5] X-Barracuda-Start-Time: 1448366039 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 1.13 X-Barracuda-Spam-Status: No, SCORE=1.13 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, HTML_IMAGE_ONLY_16, HTML_MESSAGE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24678 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.63 HTML_IMAGE_ONLY_16 BODY: HTML: images with 1200-1600 bytes of words 0.00 HTML_MESSAGE BODY: HTML included in message 0.50 BSF_SC0_SA_TO_FROM_ADDR_MATCH Sender Address Matches Recipient Address You will not see this in a MIME-aware mail reader. --===============1663350128== Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Description: Mail message body = IMPORTANT NATWEST ONLINE NOTIFICATION : For security reasons, you have a limited number of unsuccessful = PIN entries and your NatWest Online access was locked However, a hold is placed on your accounts until you verify your = details with us. = Just logon to your NatWest secure online service to resolve this issue and = view your recent account activities. Regards, National Westminster Bank --===============1663350128== Content-Type: text/html; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Description: Mail message body
3D"https://encrypted-tbn3.gstat=

IMPORTANT NATWEST ONLINE NOTIFICATION :

For security reasons, yo= u have a limited number of unsuccessful
PIN entries and your NatWest On= line access was locked

However, a hold is placed on your accounts un= til you verify your
details with us.

Just logon to your NatWest secure online service to resolve this issue and <= br>view your recent account activities.

Regards,

National Westminster Bank
--===============1663350128==-- From jack@suse.cz Tue Nov 24 07:24:31 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 26CCF7F37 for ; Tue, 24 Nov 2015 07:24:31 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 9DBC6AC004 for ; Tue, 24 Nov 2015 05:24:27 -0800 (PST) X-ASG-Debug-ID: 1448371464-04cb6c0cd11becf0001-NocioJ Received: from mx2.suse.de (mx2.suse.de [195.135.220.15]) by cuda.sgi.com with ESMTP id SklfwTMroLHjb1Y7 (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NO) for ; Tue, 24 Nov 2015 05:24:25 -0800 (PST) X-Barracuda-Envelope-From: jack@suse.cz X-Barracuda-Apparent-Source-IP: 195.135.220.15 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 46D74AD07; Tue, 24 Nov 2015 13:22:59 +0000 (UTC) Received: by quack.suse.cz (Postfix, from userid 1000) id D5E8982827; Tue, 24 Nov 2015 14:24:21 +0100 (CET) Date: Tue, 24 Nov 2015 14:24:21 +0100 From: Jan Kara To: Dmitry Monakhov Cc: linux-ext4@vger.kernel.org, jack@suse.cz, tytso@mit.edu, xfs@oss.sgi.com, linux-fsdevel@vger.kernel.org Subject: Re: [PATCH] ext4: fix race aio-dio vs freeze_fs Message-ID: <20151124132421.GG25232@quack.suse.cz> X-ASG-Orig-Subj: Re: [PATCH] ext4: fix race aio-dio vs freeze_fs References: <1448294568-20892-1-git-send-email-dmonakhov@openvz.org> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="qDbXVdCdHGoSgWSk" Content-Disposition: inline In-Reply-To: <1448294568-20892-1-git-send-email-dmonakhov@openvz.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: mx2.suse.de[195.135.220.15] X-Barracuda-Start-Time: 1448371465 X-Barracuda-Encrypted: ECDHE-RSA-AES256-SHA X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24679 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- --qDbXVdCdHGoSgWSk Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Mon 23-11-15 20:02:48, Dmitry Monakhov wrote: > After freeze_fs was revoked (from Jan Kara) pages's write-back completion > is deffered before unwritten conversion, so explicit flush_unwritten_io() > was removed here: c724585b62411 > But we still may face deferred conversion for aio-dio case > # Trivial testcase > for ((i=0;i<60;i++));do fsfreeze -f /mnt ;sleep 1;fsfreeze -u /mnt;done & > fio --bs=4k --ioengine=libaio --iodepth=128 --size=1g --direct=1 \ > --runtime=60 --filename=/mnt/file --name=rand-write --rw=randwrite > NOTE: Sane testcase should be integrated to xfstests, but it requires > changes in common/* code, so let's use this this test at the moment. > > In order to fix this race we have to guard journal transaction with explicit > sb_{start,end}_intwrite() as we do with ext4_evict_inode here:8e8ad8a5 Well, this problem seems to suggest that we have the freeze protection for AIO writes wrong. We should call file_end_write() from aio_complete() and not from aio_run_iocb()... I believe XFS and other filesystems may have problems with this as well (CCed). Attached patch (so far only compile tested since my test machine is pondering on something else) should fix this. Honza -- Jan Kara SUSE Labs, CR --qDbXVdCdHGoSgWSk Content-Type: text/x-patch; charset=us-ascii Content-Disposition: attachment; filename="0001-aio-Fix-freeze-protection-of-aio-writes.patch" >From a7332719d80dc94c11d1c1cb32c88b7f25e1ae61 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Tue, 24 Nov 2015 14:19:22 +0100 Subject: [PATCH] aio: Fix freeze protection of aio writes Currently we dropped freeze protection of aio writes just after IO was submitted. Thus aio write could be in flight while the filesystem was frozen and that could result in unexpected situation like aio completion wanting to convert extent type on frozen filesystem. Testcase from Dmitry triggering this is like: for ((i=0;i<60;i++));do fsfreeze -f /mnt ;sleep 1;fsfreeze -u /mnt;done & fio --bs=4k --ioengine=libaio --iodepth=128 --size=1g --direct=1 \ --runtime=60 --filename=/mnt/file --name=rand-write --rw=randwrite Fix the problem by dropping freeze protection only once IO is completed in aio_complete(). Reported-by: Dmitry Monakhov Signed-off-by: Jan Kara --- fs/aio.c | 10 +++++++--- include/linux/fs.h | 1 + 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/fs/aio.c b/fs/aio.c index 155f84253f33..3775030053f7 100644 --- a/fs/aio.c +++ b/fs/aio.c @@ -1065,6 +1065,9 @@ static void aio_complete(struct kiocb *kiocb, long res, long res2) unsigned tail, pos, head; unsigned long flags; + if (kiocb->ki_flags & IOCB_WRITE) + file_end_write(kiocb->ki_filp); + /* * Special case handling for sync iocbs: * - events go directly into the iocb for fast handling @@ -1449,13 +1452,14 @@ rw_common: len = ret; - if (rw == WRITE) + /* We drop freeze protection in aio_complete() */ + if (rw == WRITE) { file_start_write(file); + req->ki_flags |= IOCB_WRITE; + } ret = iter_op(req, &iter); - if (rw == WRITE) - file_end_write(file); kfree(iovec); break; diff --git a/include/linux/fs.h b/include/linux/fs.h index 3aa514254161..54af40ed6a26 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -319,6 +319,7 @@ struct writeback_control; #define IOCB_EVENTFD (1 << 0) #define IOCB_APPEND (1 << 1) #define IOCB_DIRECT (1 << 2) +#define IOCB_WRITE (1 << 3) struct kiocb { struct file *ki_filp; -- 2.1.4 --qDbXVdCdHGoSgWSk-- From BATV+01b2316b9c763e6c5797+4475+infradead.org+hch@bombadil.srs.infradead.org Tue Nov 24 10:07:31 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 F10A37F37 for ; Tue, 24 Nov 2015 10:07:31 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id E140D304039 for ; Tue, 24 Nov 2015 08:07:28 -0800 (PST) X-ASG-Debug-ID: 1448381246-04cb6c0cd21c3bf0001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id gBtHeuxpflLYeJg7 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 24 Nov 2015 08:07:27 -0800 (PST) X-Barracuda-Envelope-From: BATV+01b2316b9c763e6c5797+4475+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 1a1G7n-0006yA-Cj; Tue, 24 Nov 2015 16:07:23 +0000 Date: Tue, 24 Nov 2015 08:07:23 -0800 From: Christoph Hellwig To: Jan Kara Cc: Dmitry Monakhov , linux-ext4@vger.kernel.org, tytso@mit.edu, xfs@oss.sgi.com, linux-fsdevel@vger.kernel.org Subject: Re: [PATCH] ext4: fix race aio-dio vs freeze_fs Message-ID: <20151124160723.GA17466@infradead.org> X-ASG-Orig-Subj: Re: [PATCH] ext4: fix race aio-dio vs freeze_fs References: <1448294568-20892-1-git-send-email-dmonakhov@openvz.org> <20151124132421.GG25232@quack.suse.cz> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151124132421.GG25232@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: UNKNOWN[198.137.202.9] X-Barracuda-Start-Time: 1448381247 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/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.24682 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS On Tue, Nov 24, 2015 at 02:24:21PM +0100, Jan Kara wrote: > Well, this problem seems to suggest that we have the freeze protection for > AIO writes wrong. We should call file_end_write() from aio_complete() and > not from aio_run_iocb()... I believe XFS and other filesystems may have > problems with this as well (CCed). Attached patch (so far only compile > tested since my test machine is pondering on something else) should fix > this. Sounds like one way to do it, but we'd really want a vfs_* helper for this so that it doesn't have to duplicated in other write_iter users like the loop driver, which seems to be missing file file_start_write/file_end_write entirely. From dmonakhovopenvz@gmail.com Tue Nov 24 10:55:47 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 2A2597F37 for ; Tue, 24 Nov 2015 10:55:47 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 177148F8054 for ; Tue, 24 Nov 2015 08:55:43 -0800 (PST) X-ASG-Debug-ID: 1448384141-04cb6c0cd31c5060001-NocioJ Received: from mail-vk0-f51.google.com (mail-vk0-f51.google.com [209.85.213.51]) by cuda.sgi.com with ESMTP id O2Q7EJkSr7Aa2wZ4 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 24 Nov 2015 08:55:42 -0800 (PST) X-Barracuda-Envelope-From: dmonakhovopenvz@gmail.com X-Barracuda-Apparent-Source-IP: 209.85.213.51 Received: by vkha189 with SMTP id a189so15828434vkh.2 for ; Tue, 24 Nov 2015 08:55:41 -0800 (PST) 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=g67K2LHJK3qb0G83d7Rg7+Uar7MdJyXyYfxZmNacStk=; b=GsRaxmd6MngVxpzFL9i3qpCFcVkwe8ei3BezUh5dh5Ms1SfD4gnjqfUn4C+JN8Dzqj UGGyNJx+LNJvxI37Fh/3hP59p1GDI4d09UcjNZzmeGT3vvIyCXADEuQjI0BEHIhZywk8 CvXb7i5L2eK6j51Cy/O/b0b5SwAy62BEGdgMYVDEmCdJXKV/4x0o/2hnf2C5FhUB3Smj EsSoUhrbhc3GWxBJcdq9mZj8itaVKKrcEF7lEjMC//JIWNJjZ90A/7vMqw6i3TcxXzBw xDriyMEIhPkPyfkuyERGHs69mjx7gvK2UYoMCyLD+dnkGjJ5r+Gq7vO/VHnCe4ltKeJa vCmA== MIME-Version: 1.0 X-Received: by 10.31.156.78 with SMTP id f75mr27438899vke.40.1448384141217; Tue, 24 Nov 2015 08:55:41 -0800 (PST) Received: by 10.31.89.194 with HTTP; Tue, 24 Nov 2015 08:55:40 -0800 (PST) Received: by 10.31.89.194 with HTTP; Tue, 24 Nov 2015 08:55:40 -0800 (PST) In-Reply-To: <20151124132421.GG25232@quack.suse.cz> References: <1448294568-20892-1-git-send-email-dmonakhov@openvz.org> <20151124132421.GG25232@quack.suse.cz> Date: Tue, 24 Nov 2015 20:55:40 +0400 Message-ID: Subject: Re: [PATCH] ext4: fix race aio-dio vs freeze_fs From: Dmitry Monakhov X-ASG-Orig-Subj: Re: [PATCH] ext4: fix race aio-dio vs freeze_fs To: Jan Kara Cc: Dmitriy Monakhov , linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com, tytso@mit.edu, linux-ext4@vger.kernel.org Content-Type: multipart/alternative; boundary=001a1140f5563c548005254c36a4 X-Barracuda-Connect: mail-vk0-f51.google.com[209.85.213.51] X-Barracuda-Start-Time: 1448384142 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24683 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 --001a1140f5563c548005254c36a4 Content-Type: text/plain; charset=UTF-8 On Nov 24, 2015 16:25, "Jan Kara" wrote: > > On Mon 23-11-15 20:02:48, Dmitry Monakhov wrote: > > After freeze_fs was revoked (from Jan Kara) pages's write-back completion > > is deffered before unwritten conversion, so explicit flush_unwritten_io() > > was removed here: c724585b62411 > > But we still may face deferred conversion for aio-dio case > > # Trivial testcase > > for ((i=0;i<60;i++));do fsfreeze -f /mnt ;sleep 1;fsfreeze -u /mnt;done & > > fio --bs=4k --ioengine=libaio --iodepth=128 --size=1g --direct=1 \ > > --runtime=60 --filename=/mnt/file --name=rand-write --rw=randwrite > > NOTE: Sane testcase should be integrated to xfstests, but it requires > > changes in common/* code, so let's use this this test at the moment. > > > > In order to fix this race we have to guard journal transaction with explicit > > sb_{start,end}_intwrite() as we do with ext4_evict_inode here:8e8ad8a5 > > Well, this problem seems to suggest that we have the freeze protection for > AIO writes wrong. We should call file_end_write() from aio_complete() and > not from aio_run_iocb()... Yep. It was my first attempt to fix that issue, but unfortunately this trick will break lockdep. Caller will do file_start_write and exit to userspace. Lockdep treats such behaviour as bug (return to userspace with a lock held) There are two way to fix that 1) add specific 'long' lock primitive to lockdep 2) let sync_filesystems to wait pended aio-dio > I believe XFS and other filesystems may have > problems with this as well (CCed). Attached patch (so far only compile > tested since my test machine is pondering on something else) should fix > this. > > Honza > > -- > Jan Kara > SUSE Labs, CR --001a1140f5563c548005254c36a4 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable


On Nov 24, 2015 16:25, "Jan Kara" <jack@suse.cz> wrote:
>
> On Mon 23-11-15 20:02:48, Dmitry Monakhov wrote:
> > After freeze_fs was revoked (from Jan Kara) pages's write-bac= k completion
> > is deffered before unwritten conversion, so explicit flush_unwrit= ten_io()
> > was removed here: c724585b62411
> > But we still may face deferred conversion for aio-dio case
> > # Trivial testcase
> > for ((i=3D0;i<60;i++));do fsfreeze -f /mnt ;sleep 1;fsfreeze -= u /mnt;done &
> > fio --bs=3D4k --ioengine=3Dlibaio --iodepth=3D128 --size=3D1g --d= irect=3D1 \
> >=C2=A0 =C2=A0 =C2=A0--runtime=3D60 --filename=3D/mnt/file --name= =3Drand-write --rw=3Drandwrite
> > NOTE: Sane testcase should be integrated to xfstests, but it requ= ires
> > changes in common/* code, so let's use this this test at the = moment.
> >
> > In order to fix this race we have to guard journal transaction wi= th explicit
> > sb_{start,end}_intwrite()=C2=A0 as we do with ext4_evict_inode he= re:8e8ad8a5
>
> Well, this problem seems to suggest that we have the freeze protection= for
> AIO writes wrong. We should call file_end_write() from aio_complete() = and
> not from aio_run_iocb()...
Yep. It was my first attempt to fix that issue, but=C2=A0 unfortunately thi= s trick will break lockdep. Caller will do file_start_write and exit to use= rspace. Lockdep treats such behaviour as bug (return to userspace with a lo= ck held)

There are two way to fix that
1) add specific 'long' lock primitive to lockdep
2) let sync_filesystems to wait pended aio-dio

> I believe XFS and other filesystems may have
> problems with this as well (CCed). Attached patch (so far only compile=
> tested since my test machine is pondering on something else) should fi= x
> this.
>
> =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 =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 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 Honza
>
> --
> Jan Kara <jack@suse.com> > SUSE Labs, CR

--001a1140f5563c548005254c36a4-- From yamato@redhat.com Wed Nov 25 02:52:50 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 ED2D97F37 for ; Wed, 25 Nov 2015 02:52:49 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 6E111AC002 for ; Wed, 25 Nov 2015 00:52:49 -0800 (PST) X-ASG-Debug-ID: 1448441567-04cbb0605d213e30001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id XxTOTdVt5rGwGl2m (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 25 Nov 2015 00:52:48 -0800 (PST) X-Barracuda-Envelope-From: yamato@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 (Postfix) with ESMTPS id 9942CC0B7AA5; Wed, 25 Nov 2015 08:52:47 +0000 (UTC) Received: from x201.localdomain.com (dhcp-193-87.nrt.redhat.com [10.64.193.87]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAP8qkSU006834; Wed, 25 Nov 2015 03:52:46 -0500 From: Masatake YAMATO To: xfs@oss.sgi.com Cc: yamato@redhat.com Subject: [PATCH] xfs: send warning of project quota to userspace via netlink Date: Wed, 25 Nov 2015 17:52:41 +0900 X-ASG-Orig-Subj: [PATCH] xfs: send warning of project quota to userspace via netlink Message-Id: <1448441561-31849-1-git-send-email-yamato@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: 1448441568 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Linux's quota subsystem has an ability to handle project quota. This commit just utilizes the ability from xfs side. Signed-off-by: Masatake YAMATO --- fs/xfs/xfs_trans_dquot.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c index ce78534..1a46544 100644 --- a/fs/xfs/xfs_trans_dquot.c +++ b/fs/xfs/xfs_trans_dquot.c @@ -572,12 +572,17 @@ xfs_quota_warn( struct xfs_dquot *dqp, int type) { - /* no warnings for project quotas - we just return ENOSPC later */ + enum quota_type t; + if (dqp->dq_flags & XFS_DQ_PROJ) - return; + t = PRJQUOTA; + else if (dqp->dq_flags & XFS_DQ_USER) + t = USRQUOTA; + else + t = GRPQUOTA; + quota_send_warning(make_kqid(&init_user_ns, - (dqp->dq_flags & XFS_DQ_USER) ? - USRQUOTA : GRPQUOTA, + t, be32_to_cpu(dqp->q_core.d_id)), mp->m_super->s_dev, type); } -- 2.5.0 From jack@suse.cz Wed Nov 25 03:19:23 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 8DC347F37 for ; Wed, 25 Nov 2015 03:19:23 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id F0908AC002 for ; Wed, 25 Nov 2015 01:19:22 -0800 (PST) X-ASG-Debug-ID: 1448443159-04cbb0605c2151b0001-NocioJ Received: from mx2.suse.de (mx2.suse.de [195.135.220.15]) by cuda.sgi.com with ESMTP id cEOYkEsTU84NiY4A (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NO) for ; Wed, 25 Nov 2015 01:19:20 -0800 (PST) X-Barracuda-Envelope-From: jack@suse.cz X-Barracuda-Apparent-Source-IP: 195.135.220.15 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 92319AAC4; Wed, 25 Nov 2015 09:17:38 +0000 (UTC) Received: by quack.suse.cz (Postfix, from userid 1000) id C880E82827; Wed, 25 Nov 2015 10:19:16 +0100 (CET) Date: Wed, 25 Nov 2015 10:19:16 +0100 From: Jan Kara To: Dmitry Monakhov Cc: Jan Kara , Dmitriy Monakhov , linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com, tytso@mit.edu, linux-ext4@vger.kernel.org Subject: Re: [PATCH] ext4: fix race aio-dio vs freeze_fs Message-ID: <20151125091916.GL25232@quack.suse.cz> X-ASG-Orig-Subj: Re: [PATCH] ext4: fix race aio-dio vs freeze_fs References: <1448294568-20892-1-git-send-email-dmonakhov@openvz.org> <20151124132421.GG25232@quack.suse.cz> 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: mx2.suse.de[195.135.220.15] X-Barracuda-Start-Time: 1448443160 X-Barracuda-Encrypted: ECDHE-RSA-AES256-SHA X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24705 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Tue 24-11-15 20:55:40, Dmitry Monakhov wrote: > On Nov 24, 2015 16:25, "Jan Kara" wrote: > > On Mon 23-11-15 20:02:48, Dmitry Monakhov wrote: > > > After freeze_fs was revoked (from Jan Kara) pages's write-back > completion > > > is deffered before unwritten conversion, so explicit > flush_unwritten_io() > > > was removed here: c724585b62411 > > > But we still may face deferred conversion for aio-dio case > > > # Trivial testcase > > > for ((i=0;i<60;i++));do fsfreeze -f /mnt ;sleep 1;fsfreeze -u /mnt;done > & > > > fio --bs=4k --ioengine=libaio --iodepth=128 --size=1g --direct=1 \ > > > --runtime=60 --filename=/mnt/file --name=rand-write --rw=randwrite > > > NOTE: Sane testcase should be integrated to xfstests, but it requires > > > changes in common/* code, so let's use this this test at the moment. > > > > > > In order to fix this race we have to guard journal transaction with > explicit > > > sb_{start,end}_intwrite() as we do with ext4_evict_inode here:8e8ad8a5 > > > > Well, this problem seems to suggest that we have the freeze protection for > > AIO writes wrong. We should call file_end_write() from aio_complete() and > > not from aio_run_iocb()... > Yep. It was my first attempt to fix that issue, but unfortunately this > trick will break lockdep. Caller will do file_start_write and exit to > userspace. Lockdep treats such behaviour as bug (return to userspace with a > lock held) > > There are two way to fix that > 1) add specific 'long' lock primitive to lockdep The way we tell lockdep about transfer of context is that we just lie to lockdep and tell it that the lock got unlocked at appropriate place and then tell it we locked it again at another place. It is somewhat ugly but not that hard to do... Generally lockdep is a tool that should help but by no means it should be a reason for poor locking decisions just because lockdep cannot handle them. Honza -- Jan Kara SUSE Labs, CR From jack@suse.cz Wed Nov 25 04:25:09 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 C2EC17F37 for ; Wed, 25 Nov 2015 04:25:09 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id AAF4C304032 for ; Wed, 25 Nov 2015 02:25:06 -0800 (PST) X-ASG-Debug-ID: 1448447102-04cbb0605c216850001-NocioJ Received: from mx2.suse.de (mx2.suse.de [195.135.220.15]) by cuda.sgi.com with ESMTP id Fd7rXQQPTLyGEe5R (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NO) for ; Wed, 25 Nov 2015 02:25:03 -0800 (PST) X-Barracuda-Envelope-From: jack@suse.cz X-Barracuda-Apparent-Source-IP: 195.135.220.15 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 890FAAC8C; Wed, 25 Nov 2015 10:23:22 +0000 (UTC) Received: by quack.suse.cz (Postfix, from userid 1000) id C272A82827; Wed, 25 Nov 2015 11:25:00 +0100 (CET) Date: Wed, 25 Nov 2015 11:25:00 +0100 From: Jan Kara To: Christoph Hellwig Cc: Jan Kara , Dmitry Monakhov , linux-ext4@vger.kernel.org, tytso@mit.edu, xfs@oss.sgi.com, linux-fsdevel@vger.kernel.org Subject: Re: [PATCH] ext4: fix race aio-dio vs freeze_fs Message-ID: <20151125102500.GM25232@quack.suse.cz> X-ASG-Orig-Subj: Re: [PATCH] ext4: fix race aio-dio vs freeze_fs References: <1448294568-20892-1-git-send-email-dmonakhov@openvz.org> <20151124132421.GG25232@quack.suse.cz> <20151124160723.GA17466@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151124160723.GA17466@infradead.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: mx2.suse.de[195.135.220.15] X-Barracuda-Start-Time: 1448447103 X-Barracuda-Encrypted: ECDHE-RSA-AES256-SHA X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24707 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Tue 24-11-15 08:07:23, Christoph Hellwig wrote: > On Tue, Nov 24, 2015 at 02:24:21PM +0100, Jan Kara wrote: > > Well, this problem seems to suggest that we have the freeze protection for > > AIO writes wrong. We should call file_end_write() from aio_complete() and > > not from aio_run_iocb()... I believe XFS and other filesystems may have > > problems with this as well (CCed). Attached patch (so far only compile > > tested since my test machine is pondering on something else) should fix > > this. > > Sounds like one way to do it, but we'd really want a vfs_* helper for > this so that it doesn't have to duplicated in other write_iter users > like the loop driver, which seems to be missing file > file_start_write/file_end_write entirely. That is mostly a separate issue, isn't it? I guess you mean a helper like vfs_write_iter() that would get freeze protection and call ->write_iter()? And what about files which have ->write (or ->splice_write()) and don't end up calling ->write_iter? Also there is stuff like __kernel_write() which ends up calling ->write_iter() but e.g. kernel/acct.c: do_acct_process() wants to do it's own thing... So the current status is not ideal but I don't see how to make it substantially better... Honza -- Jan Kara SUSE Labs, CR From Vincent.Riera@imgtec.com Wed Nov 25 05:11:05 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 68E7F7F37 for ; Wed, 25 Nov 2015 05:11:05 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 3D4B2304032 for ; Wed, 25 Nov 2015 03:11:02 -0800 (PST) X-ASG-Debug-ID: 1448449856-04cb6c0cd21e1c60001-NocioJ Received: from mailapp01.imgtec.com (mailapp01.imgtec.com [195.59.15.196]) by cuda.sgi.com with ESMTP id stORoI86coxJgNWe for ; Wed, 25 Nov 2015 03:10:56 -0800 (PST) X-Barracuda-Envelope-From: Vincent.Riera@imgtec.com X-Barracuda-Apparent-Source-IP: 195.59.15.196 Received: from hhmail02.hh.imgtec.org (unknown [10.100.10.20]) by Websense Email Security Gateway with ESMTPS id 206ED3EA90B4B for ; Wed, 25 Nov 2015 11:10:53 +0000 (GMT) Received: from LEMAIL01.le.imgtec.org (192.168.152.62) by hhmail02.hh.imgtec.org (10.100.10.20) with Microsoft SMTP Server (TLS) id 14.3.235.1; Wed, 25 Nov 2015 11:10:55 +0000 Received: from vriera-linux.le.imgtec.org (192.168.154.114) by LEMAIL01.le.imgtec.org (192.168.152.62) with Microsoft SMTP Server (TLS) id 14.3.210.2; Wed, 25 Nov 2015 11:10:54 +0000 From: Vicente Olivert Riera To: CC: Vicente Olivert Riera Subject: [PATCH xfsprogs] mdrestore: do not do dynamic linking of libtool libraries Date: Wed, 25 Nov 2015 11:10:38 +0000 X-ASG-Orig-Subj: [PATCH xfsprogs] mdrestore: do not do dynamic linking of libtool libraries Message-ID: <1448449838-47261-1-git-send-email-Vincent.Riera@imgtec.com> X-Mailer: git-send-email 2.4.10 MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [192.168.154.114] X-Barracuda-Connect: mailapp01.imgtec.com[195.59.15.196] X-Barracuda-Start-Time: 1448449856 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24707 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- As explained in commit ece49daeff1a3cad765e106d678c608925c9d768, use -static-libtool-libs instead of -static to allow fallback to the dynamic linking for libuuid only. Otherwise the build will fail like this: ld: attempted static link of dynamic object `/usr/lib/libuuid.so' Signed-off-by: Vicente Olivert Riera --- mdrestore/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mdrestore/Makefile b/mdrestore/Makefile index 5171306..1b34a0e 100644 --- a/mdrestore/Makefile +++ b/mdrestore/Makefile @@ -10,7 +10,7 @@ CFILES = xfs_mdrestore.c LLDLIBS = $(LIBXFS) $(LIBRT) $(LIBPTHREAD) $(LIBUUID) LTDEPENDENCIES = $(LIBXFS) -LLDFLAGS = -static +LLDFLAGS = -static-libtool-libs default: depend $(LTCOMMAND) -- 2.4.10 From lvml@5t9.de Wed Nov 25 12:28:52 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 BE2DA7F37 for ; Wed, 25 Nov 2015 12:28:52 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 81AA930405F for ; Wed, 25 Nov 2015 10:28:49 -0800 (PST) X-ASG-Debug-ID: 1448476125-04bdf07f0a247030001-NocioJ Received: from app1b.xlhost.de (mailout173.xlhost.de [84.200.252.173]) by cuda.sgi.com with ESMTP id jCHXIsHMqMKxkUDC for ; Wed, 25 Nov 2015 10:28:45 -0800 (PST) X-Barracuda-Envelope-From: lvml@5t9.de X-Barracuda-Apparent-Source-IP: 84.200.252.173 Received: from [192.168.5.53] (barriere.frankfurter-softwarefabrik.de [217.11.197.1]) (Authenticated sender: lkv@5t9.de) by app1b.xlhost.de (Postfix) with ESMTPSA id D7FD3303E252; Wed, 25 Nov 2015 19:28:42 +0100 (CET) Message-ID: <5655FDDA.9050502@5t9.de> Date: Wed, 25 Nov 2015 19:28:42 +0100 From: Lutz Vieweg User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.2.0 MIME-Version: 1.0 To: Dave Chinner CC: xfs@oss.sgi.com Subject: Re: Does XFS support cgroup writeback limiting? References: <5652F311.7000406@5t9.de> <20151123202619.GE26718@dastard> <56538E6A.6030203@5t9.de> <20151123232052.GI26718@dastard> X-ASG-Orig-Subj: Re: Does XFS support cgroup writeback limiting? In-Reply-To: <20151123232052.GI26718@dastard> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: quoted-printable X-Virus-Scanned: clamav-milter 0.98.1 at app1b.xlhost.de X-Virus-Status: Clean X-Barracuda-Connect: mailout173.xlhost.de[84.200.252.173] X-Barracuda-Start-Time: 1448476125 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24719 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 11/24/2015 12:20 AM, Dave Chinner wrote: > Just make the same mods to XFS as the ext4 patch here: > > http://www.spinics.net/lists/kernel/msg2014816.html I read at http://www.spinics.net/lists/kernel/msg2014819.html about this patch: > Journal data which is written by jbd2 worker is left alone by > this patch and will always be written out from the root cgroup. If the same was done for XFS, wouldn't this mean a malicious process could still stall other processes' attempts to write to the filesystem by performing arbitrary amounts of meta-data modifications in a tight loop? >> After all, this functionality is the last piece of the >> "isolation"-puzzle that is missing from Linux to actually >> allow fencing off virtual machines or containers from DOSing >> each other by using up all I/O bandwidth... > > Yes, I know, but no-one seems to care enough about it to provide > regression tests for it. Well, I could give it a try, if a shell script tinkering with control groups parameters (which requires root privileges and could easily stall the machine) would be considered adequate for the purpose. I would propose a test to be performed like this: 0) Identify a block device to test on. I guess some artificially speed-limited DM device would be best? Set the speed limit to X/100 MB per second, with X configurable. 1) Start 4 "good" plus 4 "evil" subprocesses competing for write-bandwidth on the block device. Assign the 4 "good" processes to two different control groups ("g1", = "g2"), assign the 4 "evil" processes to further two different control groups ("e1", "e2"), so 4 control groups in total, with 2 tasks each.= 2) Create 3 different XFS filesystem instances on the block device, one for access by only the "good" processes, on for access by only the "evil" processes, one for shared access by at least two "good" and two "evil" processes. 3) Behaviour of the processes: "Good" processes will attempt to write a configured amount of data (X MB) at 20% of the speed limit of the block device, modifyi= ng meta-data at a moderate rate (like creating/renaming/deleting files every few megabytes written). Half of the "good" processes write to their "good-only" filesystem, the other half writes to the "shared access" filesystem. Half of the "evil" processes will attempt to write as much data as possible into open files in a tight endless loop. The other half of the "evil" processes will permanently modify meta-data as quickly as possible, creating/renaming/deleting lots of files, also in a tight endless loop. Half of the "evil" processes writes to the "evil-only" filesystem, the other half writes to the "shared access" filesystem. 4) Test 1: Configure all 4 control groups to allow for the same buffered write rate percentage. The test is successful if all "good processes" terminate successfully= after a time not longer than it would take to write 10 times X MB to = the rate-limited block device. All processes to be killed after termination of all good processes or= some timeout. If the timeout is reached, the test is failed. 5) Test 2: Configure "e1" and "e2" to allow for "zero" buffered write rat= e. The test is successful if the "good processes" terminate successfully= after a time not longer than it would take to write 5 times X MB to t= he rate-limited block device. All processes to be killed after termination of all good processes or= some timeout. If the timeout is reached, the test is failed. 6) Cleanup: unmount test filesystems, remove rate-limited DM device, remo= ve control groups. What do you think, could this be a reasonable plan? Regards, Lutz Vieweg From bfoster@redhat.com Wed Nov 25 12:54:27 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 920837F37 for ; Wed, 25 Nov 2015 12:54:27 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 25B86AC002 for ; Wed, 25 Nov 2015 10:54:23 -0800 (PST) X-ASG-Debug-ID: 1448477661-04cbb0605e225550001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id G8qtfWOq48SH0zhx (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 25 Nov 2015 10:54:22 -0800 (PST) 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 (Postfix) with ESMTPS id D01E3130A for ; Wed, 25 Nov 2015 18:54:21 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-225.bos.redhat.com [10.18.41.225]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAPIsLLO012159; Wed, 25 Nov 2015 13:54:21 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id EA4CD122406; Wed, 25 Nov 2015 13:54:19 -0500 (EST) Date: Wed, 25 Nov 2015 13:54:19 -0500 From: Brian Foster To: Masatake YAMATO Cc: xfs@oss.sgi.com Subject: Re: [PATCH] xfs: send warning of project quota to userspace via netlink Message-ID: <20151125185419.GA18719@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH] xfs: send warning of project quota to userspace via netlink References: <1448441561-31849-1-git-send-email-yamato@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1448441561-31849-1-git-send-email-yamato@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: 1448477662 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Wed, Nov 25, 2015 at 05:52:41PM +0900, Masatake YAMATO wrote: > Linux's quota subsystem has an ability to handle > project quota. This commit just utilizes the ability > from xfs side. > > Signed-off-by: Masatake YAMATO > --- Seems reasonable to me. A couple questions... how has this been tested? The original commit a210c1aa7 ("xfs: implement quota warnings via netlink") mentions that the xfstests quota tests with something listening for events was sufficient. Also, is the userspace support for this new? If so, what is the behavior if somebody runs a new kernel with this event and an old userspace? Other than that, just a couple aesthetic things.. > fs/xfs/xfs_trans_dquot.c | 13 +++++++++---- > 1 file changed, 9 insertions(+), 4 deletions(-) > > diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c > index ce78534..1a46544 100644 > --- a/fs/xfs/xfs_trans_dquot.c > +++ b/fs/xfs/xfs_trans_dquot.c > @@ -572,12 +572,17 @@ xfs_quota_warn( > struct xfs_dquot *dqp, > int type) > { > - /* no warnings for project quotas - we just return ENOSPC later */ > + enum quota_type t; > + The variable name should be lined up with the function parameter names. I'd prefer a more descriptive variable name as well (e.g., 'qtype'?). > if (dqp->dq_flags & XFS_DQ_PROJ) > - return; > + t = PRJQUOTA; > + else if (dqp->dq_flags & XFS_DQ_USER) > + t = USRQUOTA; > + else > + t = GRPQUOTA; > + > quota_send_warning(make_kqid(&init_user_ns, > - (dqp->dq_flags & XFS_DQ_USER) ? > - USRQUOTA : GRPQUOTA, > + t, This could probably get moved to the end of the previous line rather than it's own separate line now that the conditional is removed. We generally just want to keep lines within 80 columns. Brian > be32_to_cpu(dqp->q_core.d_id)), > mp->m_super->s_dev, type); > } > -- > 2.5.0 > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From bfoster@redhat.com Wed Nov 25 14:18:00 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 9DBEA7F37 for ; Wed, 25 Nov 2015 14:18:00 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 898088F8040 for ; Wed, 25 Nov 2015 12:18:00 -0800 (PST) X-ASG-Debug-ID: 1448482678-04cb6c0cd11f0ba0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id Sokv9AB6GvLt3M3V (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 25 Nov 2015 12:17:59 -0800 (PST) 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 (Postfix) with ESMTPS id DD69268E00 for ; Wed, 25 Nov 2015 20:17:58 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-225.bos.redhat.com [10.18.41.225]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAPKHwMZ026348 for ; Wed, 25 Nov 2015 15:17:58 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id 2792A122406; Wed, 25 Nov 2015 15:17:57 -0500 (EST) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH 0/4] xfsprogs: log format fixes, db command Date: Wed, 25 Nov 2015 15:17:53 -0500 X-ASG-Orig-Subj: [PATCH 0/4] xfsprogs: log format fixes, db command Message-Id: <1448482677-44364-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: 1448482679 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Hi all, This series includes a few fixes to log formatting/handling code in xfsprogs. Patch 1 fixes a minor issue in xfs_logprint. Patch 2 fixes the incorrect formatting issue with larger lsunit alignments noted in the previously posted torn log write detection series: http://oss.sgi.com/pipermail/xfs/2015-November/044845.html Patch 3 is mostly a refactor to allow the log format command to use variable sized records rather than unconditionally use 256kB records. Patch 4 adds the 'logformat' xfs_db command to facilitate testing of the log formatting mechanism. This has been lightly tested with xfstests, including via a couple forthcoming tests that take advantage of the logformat command. Thoughts, reviews, flames appreciated. Brian Brian Foster (4): logprint: use correct ext. header count for unaligned size libxfs: format the log with valid log record headers libxfs: conditionalize log format record size optimization db: add the logformat command copy/xfs_copy.c | 2 +- db/Makefile | 4 +- db/command.c | 2 + db/logformat.c | 149 ++++++++++++++++++++++++++++++++++++++++++++++++++++ db/logformat.h | 19 +++++++ db/metadump.c | 2 +- db/sb.c | 2 +- include/libxfs.h | 2 +- libxfs/rdwr.c | 89 ++++++++++++++++++++++++------- logprint/log_misc.c | 2 + mkfs/xfs_mkfs.c | 3 +- repair/phase2.c | 2 +- repair/xfs_repair.c | 2 +- 13 files changed, 251 insertions(+), 29 deletions(-) create mode 100644 db/logformat.c create mode 100644 db/logformat.h -- 2.1.0 From bfoster@redhat.com Wed Nov 25 14:18:01 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 2888C7F37 for ; Wed, 25 Nov 2015 14:18:01 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id EC92B8F8050 for ; Wed, 25 Nov 2015 12:18:00 -0800 (PST) X-ASG-Debug-ID: 1448482679-04bdf07f0a2495a0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 2o73r8aghEFHECb5 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 25 Nov 2015 12:17:59 -0800 (PST) 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 (Postfix) with ESMTPS id 12D0F14CAB6 for ; Wed, 25 Nov 2015 20:17:59 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-225.bos.redhat.com [10.18.41.225]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAPKHwuQ006976 for ; Wed, 25 Nov 2015 15:17:58 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id 6424D122420; Wed, 25 Nov 2015 15:17:57 -0500 (EST) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH 4/4] db: add the logformat command Date: Wed, 25 Nov 2015 15:17:57 -0500 X-ASG-Orig-Subj: [PATCH 4/4] db: add the logformat command Message-Id: <1448482677-44364-5-git-send-email-bfoster@redhat.com> In-Reply-To: <1448482677-44364-1-git-send-email-bfoster@redhat.com> References: <1448482677-44364-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: 1448482679 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Add the new logformat command to format the log to a specified log cycle and/or log stripe unit. This command is primarily for testing purposes and is only available in expert mode. Signed-off-by: Brian Foster --- db/Makefile | 4 +- db/command.c | 2 + db/logformat.c | 149 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ db/logformat.h | 19 ++++++++ 4 files changed, 172 insertions(+), 2 deletions(-) create mode 100644 db/logformat.c create mode 100644 db/logformat.h diff --git a/db/Makefile b/db/Makefile index fb01bdd..8260da3 100644 --- a/db/Makefile +++ b/db/Makefile @@ -11,8 +11,8 @@ 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 \ 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 \ - text.h type.h write.h attrset.h symlink.h + io.h logformat.h malloc.h metadump.h output.h print.h quit.h sb.h \ + sig.h strvec.h text.h type.h write.h attrset.h symlink.h CFILES = $(HFILES:.h=.c) LSRCFILES = xfs_admin.sh xfs_ncheck.sh xfs_metadump.sh diff --git a/db/command.c b/db/command.c index 2189e00..3c17a1e 100644 --- a/db/command.c +++ b/db/command.c @@ -40,6 +40,7 @@ #include "inode.h" #include "input.h" #include "io.h" +#include "logformat.h" #include "metadump.h" #include "output.h" #include "print.h" @@ -131,6 +132,7 @@ init_commands(void) hash_init(); inode_init(); input_init(); + logformat_init(); io_init(); metadump_init(); output_init(); diff --git a/db/logformat.c b/db/logformat.c new file mode 100644 index 0000000..254f33d --- /dev/null +++ b/db/logformat.c @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2015 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 "libxfs.h" +#include "command.h" +#include "init.h" +#include "output.h" +#include "libxlog.h" + +#define MAX_LSUNIT 256 * 1024 /* max log buf. size */ + +static int +logformat_f(int argc, char **argv) +{ + xfs_daddr_t head_blk; + xfs_daddr_t tail_blk; + int logversion; + int lsunit = -1; + int cycle = -1; + int error; + int c; + + logversion = xfs_sb_version_haslogv2(&mp->m_sb) ? 2 : 1; + + while ((c = getopt(argc, argv, "c:s:")) != EOF) { + switch (c) { + case 'c': + cycle = strtol(optarg, NULL, 0); + if (cycle == 0) { + dbprintf("invalid cycle\n"); + return -1; + } + break; + case 's': + lsunit = strtol(optarg, NULL, 0); + /* + * The log stripe unit must be block aligned and no + * larger than 256k. + */ + if (lsunit > 1 && + (lsunit % mp->m_sb.sb_blocksize || + (logversion == 2 && lsunit > MAX_LSUNIT))) { + dbprintf("invalid log stripe unit\n"); + return -1; + } + break; + default: + dbprintf("invalid option\n"); + return -1; + } + } + + /* + * Check whether the log is dirty. This also determines the current log + * cycle if we have to use it by default below. + */ + memset(mp->m_log, 0, sizeof(struct xlog)); + mp->m_log->l_mp = mp; + mp->m_log->l_dev = mp->m_logdev_targp; + mp->m_log->l_logBBsize = XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks); + mp->m_log->l_logBBstart = XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart); + mp->m_log->l_sectBBsize = BBSIZE; + if (xfs_sb_version_hassector(&mp->m_sb)) + mp->m_log->l_sectBBsize <<= (mp->m_sb.sb_logsectlog - BBSHIFT); + mp->m_log->l_sectBBsize = BTOBB(mp->m_log->l_sectBBsize); + + error = xlog_find_tail(mp->m_log, &head_blk, &tail_blk); + if (error) { + dbprintf("could not find log head/tail\n"); + return -1; + } + if (head_blk != tail_blk) { + dbprintf(_( + "The log is dirty. Please mount to replay the log.\n")); + return -1; + } + + /* + * Use the current cycle and/or log stripe unit if either is not + * provided by the user. + */ + if (cycle < 0) + cycle = mp->m_log->l_curr_cycle; + if (lsunit < 0) + lsunit = mp->m_sb.sb_logsunit; + + dbprintf("Formatting the log to cycle %d, stripe unit %d bytes.\n", + cycle, lsunit); + error = libxfs_log_clear(mp->m_logdev_targp, NULL, + mp->m_log->l_logBBstart, + mp->m_log->l_logBBsize, + &mp->m_sb.sb_uuid, logversion, lsunit, + XLOG_FMT, cycle, false); + if (error) { + dbprintf("error formatting log - %d\n", error); + return error; + } + + return 0; +} + +static void +logformat_help(void) +{ + dbprintf(_( +"\n" +" The 'logformat' command reformats (clears) the log to the specified log\n" +" cycle and log stripe unit. If the log cycle is not specified, the log is\n" +" reformatted to the current cycle. If the log stripe unit is not specified,\n" +" the stripe unit from the filesystem superblock is used.\n" +"\n" + )); +} + +static const struct cmdinfo logformat_cmd = { + .name = "logformat", + .altname = NULL, + .cfunc = logformat_f, + .argmin = 0, + .argmax = 4, + .canpush = 0, + .args = N_("[-c cycle] [-s sunit]"), + .oneline = N_("reformat the log"), + .help = logformat_help, +}; + +void +logformat_init(void) +{ + if (!expert_mode) + return; + + add_command(&logformat_cmd); +} diff --git a/db/logformat.h b/db/logformat.h new file mode 100644 index 0000000..f9763ee --- /dev/null +++ b/db/logformat.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2015 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 + */ + +void logformat_init(void); -- 2.1.0 From bfoster@redhat.com Wed Nov 25 14:18:00 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 BACF67F3F for ; Wed, 25 Nov 2015 14:18:00 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 9B7D58F8050 for ; Wed, 25 Nov 2015 12:18:00 -0800 (PST) X-ASG-Debug-ID: 1448482678-04bdf07f07249590001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id l0MkAFIoSlA8m3Uf (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 25 Nov 2015 12:17:59 -0800 (PST) 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 (Postfix) with ESMTPS id DE7F9C0B7AA2 for ; Wed, 25 Nov 2015 20:17:58 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-225.bos.redhat.com [10.18.41.225]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAPKHwjf015467 for ; Wed, 25 Nov 2015 15:17:58 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id 3C5311223E9; Wed, 25 Nov 2015 15:17:57 -0500 (EST) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH 1/4] logprint: use correct ext. header count for unaligned size Date: Wed, 25 Nov 2015 15:17:54 -0500 X-ASG-Orig-Subj: [PATCH 1/4] logprint: use correct ext. header count for unaligned size Message-Id: <1448482677-44364-2-git-send-email-bfoster@redhat.com> In-Reply-To: <1448482677-44364-1-git-send-email-bfoster@redhat.com> References: <1448482677-44364-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: 1448482679 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 A log record has 1 record header and up to 7 additional extended record headers depending on the size of the record. This is required for log record packing. A header is required for each 32k of record data. The header count for a particular record is fixed, based on the log buffer size (h_size) specified in the record header. logprint calculates the expected extended header count based on h_size, but does not account for a log buffer size not aligned with 32k. This results in spurious invalid header count errors for an otherwise valid log. This can be reproduced by mounting a filesystem with '-o logbsize=16k' and running xfs_logprint after a subsequent unmount. Update xlog_print_extended_headers() to incorporate a non-32k aligned log buffer size in the expected extended record header count calculation. This is consistent with how the header count is calculated in the kernel. Signed-off-by: Brian Foster --- logprint/log_misc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/logprint/log_misc.c b/logprint/log_misc.c index 4cdcbec..7378fe1 100644 --- a/logprint/log_misc.c +++ b/logprint/log_misc.c @@ -1294,6 +1294,8 @@ xlog_print_extended_headers( num_required = howmany(len, XLOG_HEADER_CYCLE_SIZE); num_hdrs = be32_to_cpu(hdr->h_size) / XLOG_HEADER_CYCLE_SIZE; + if (be32_to_cpu(hdr->h_size) % XLOG_HEADER_CYCLE_SIZE) + num_hdrs++; if (num_required > num_hdrs) { print_xlog_bad_reqd_hdrs((*blkno)-1, num_required, num_hdrs); -- 2.1.0 From bfoster@redhat.com Wed Nov 25 14:18:04 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 AF3817F5D for ; Wed, 25 Nov 2015 14:18:04 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 2EF43AC006 for ; Wed, 25 Nov 2015 12:18:01 -0800 (PST) X-ASG-Debug-ID: 1448482679-04cbb0605e2271e0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 1jsnWAozvPBAPjeu (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 25 Nov 2015 12:17:59 -0800 (PST) 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 (Postfix) with ESMTPS id 100FE71 for ; Wed, 25 Nov 2015 20:17:59 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-225.bos.redhat.com [10.18.41.225]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAPKHw0v006972 for ; Wed, 25 Nov 2015 15:17:58 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id 576881228A6; Wed, 25 Nov 2015 15:17:57 -0500 (EST) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH 2/4] libxfs: format the log with valid log record headers Date: Wed, 25 Nov 2015 15:17:55 -0500 X-ASG-Orig-Subj: [PATCH 2/4] libxfs: format the log with valid log record headers Message-Id: <1448482677-44364-3-git-send-email-bfoster@redhat.com> In-Reply-To: <1448482677-44364-1-git-send-email-bfoster@redhat.com> References: <1448482677-44364-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: 1448482679 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 xfsprogs supports the ability to clear or reformat the log to an arbitrary cycle number. This functionality is invoked in mkfs, xfs_repair, etc. The code currently fills the log with unmount records sized based on the specified log stripe unit alignment. When the stripe unit is sufficiently larger, however, the resulting log records are technically invalid. For example, the log buffer size (h_size) field is always hardcoded to 32k even when the particular record length is larger. This has not traditionally been a problem because the kernel does not fully process the log record when the log is clean. Recent changes to unconditionally CRC verify the head of the log changes this behavior, however, which means the log should be valid. Technically, the records written from userspace are not written with a CRC, but this also helps support unit testing by writing a log that can be verified with logprint. Update libxfs_log_header() to write a valid log record based on the specified log stripe unit. h_size is updated to the log buffer size based on the stripe unit and the expected number of extended record headers are written out based on the log buffer size. Signed-off-by: Brian Foster --- libxfs/rdwr.c | 74 +++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 57 insertions(+), 17 deletions(-) diff --git a/libxfs/rdwr.c b/libxfs/rdwr.c index 0804285..16904d0 100644 --- a/libxfs/rdwr.c +++ b/libxfs/rdwr.c @@ -279,6 +279,7 @@ libxfs_log_header( char *p = caddr; __be32 cycle_lsn; int i, len; + int hdrs = 1; if (lsn == NULLCOMMITLSN) lsn = xlog_assign_lsn(XLOG_INIT_CYCLE, 0); @@ -291,41 +292,80 @@ libxfs_log_header( head->h_magicno = cpu_to_be32(XLOG_HEADER_MAGIC_NUM); head->h_cycle = cpu_to_be32(CYCLE_LSN(lsn)); head->h_version = cpu_to_be32(version); - if (len != 1) - head->h_len = cpu_to_be32(sunit - BBSIZE); - else - head->h_len = cpu_to_be32(20); head->h_crc = cpu_to_le32(0); head->h_prev_block = cpu_to_be32(-1); head->h_num_logops = cpu_to_be32(1); head->h_fmt = cpu_to_be32(fmt); - head->h_size = cpu_to_be32(XLOG_HEADER_CYCLE_SIZE); + head->h_size = cpu_to_be32(MAX(sunit, XLOG_BIG_RECORD_BSIZE)); head->h_lsn = cpu_to_be64(lsn); head->h_tail_lsn = cpu_to_be64(tail_lsn); memcpy(&head->h_fs_uuid, fs_uuid, sizeof(uuid_t)); - p = nextfunc(p, BBSIZE, private); - unmount_record(p); - /* - * The kernel expects to see either a log record header magic or the LSN - * cycle at the top of every log block (for example, see - * xlog_[un]pack_data() and xlog_get_cycle()). Pack the unmount record - * block appropriately here. + * The kernel expects to see either a log record header magic value or + * the LSN cycle at the top of every log block. The first word of each + * non-header block is copied to the record headers and replaced with + * the cycle value (see xlog_[un]pack_data() and xlog_get_cycle() for + * details). + * + * Even though we only ever write an unmount record (one block), we + * support writing log records up to the max log buffer size of 256k to + * improve log format performance. This means a record can require up + * to 8 headers (1 rec. header + 7 ext. headers) for the packed cycle + * data (each header supports 32k of data). */ cycle_lsn = CYCLE_LSN_DISK(head->h_lsn); + if (version == 2 && sunit > XLOG_HEADER_CYCLE_SIZE) { + hdrs = sunit / XLOG_HEADER_CYCLE_SIZE; + if (sunit % XLOG_HEADER_CYCLE_SIZE) + hdrs++; + } + + /* + * A fixed number of extended headers is expected based on h_size. If + * required, format those now so the unmount record is located + * correctly. + * + * Since we only write an unmount record, we only need one h_cycle_data + * entry for the unmount record block. The subsequent record data + * blocks are zeroed, which means we can stamp them directly with the + * cycle and zero the rest of the cycle data in the extended headers. + */ + if (hdrs > 1) { + for (i = 1; i < hdrs; i++) { + p = nextfunc(p, BBSIZE, private); + memset(p, 0, BBSIZE); + /* xlog_rec_ext_header.xh_cycle */ + *(__be32 *)p = cycle_lsn; + } + } + + /* + * The total length is the max of the stripe unit or 2 basic block + * minimum (1 hdr blk + 1 data blk). The record length is the total + * minus however many header blocks are required. + */ + head->h_len = cpu_to_be32(MAX(BBTOB(2), sunit) - hdrs * BBSIZE); + + /* + * Write out the unmount record, pack the first word into the record + * header and stamp the block with the cycle. + */ + p = nextfunc(p, BBSIZE, private); + unmount_record(p); + head->h_cycle_data[0] = *(__be32 *)p; *(__be32 *)p = cycle_lsn; /* - * Now zero any remaining blocks in the record and stamp with the cycle. - * Note that we don't need to swap into h_cycle_data because it has - * already been initialized to zero. + * Finally, zero all remaining blocks in the record and stamp each with + * the cycle. We don't need to pack any of these blocks because the + * cycle data in the headers has already been zeroed. */ - len = MAX(len, 2); - for (i = 2; i < len; i++) { + len = MAX(len, hdrs + 1); + for (i = hdrs + 1; i < len; i++) { p = nextfunc(p, BBSIZE, private); memset(p, 0, BBSIZE); *(__be32 *)p = cycle_lsn; -- 2.1.0 From bfoster@redhat.com Wed Nov 25 14:18:04 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 ACE2C7F5A for ; Wed, 25 Nov 2015 14:18:04 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 3C7A7AC007 for ; Wed, 25 Nov 2015 12:18:01 -0800 (PST) X-ASG-Debug-ID: 1448482679-04cb6c0cd41f0bb0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id scUCzDY2kf9dail1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 25 Nov 2015 12:17:59 -0800 (PST) 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 (Postfix) with ESMTPS id 03D1FC0D2226 for ; Wed, 25 Nov 2015 20:17:59 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-225.bos.redhat.com [10.18.41.225]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAPKHwRO015469 for ; Wed, 25 Nov 2015 15:17:58 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id 4CCFB122416; Wed, 25 Nov 2015 15:17:57 -0500 (EST) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH 3/4] libxfs: conditionalize log format record size optimization Date: Wed, 25 Nov 2015 15:17:56 -0500 X-ASG-Orig-Subj: [PATCH 3/4] libxfs: conditionalize log format record size optimization Message-Id: <1448482677-44364-4-git-send-email-bfoster@redhat.com> In-Reply-To: <1448482677-44364-1-git-send-email-bfoster@redhat.com> References: <1448482677-44364-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: 1448482679 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 The libxfs log clear mechanism includes an optimization to use the maximum log buffer size (256k) when the log is being fully written (i.e., cycle != 1). This behavior is always enabled as no current callers are concerned with the size of the records written to format the log to a given cycle. A log format command will be added to xfs_db to facilitate testing of the userspace log format code (among other things). This command is not performance oriented and prefers the ability to format the log with varying record sizes. Update libxfs_log_clear() to use a new parameter to enable or disable the record size optimization. Note that the flag is a no-op when the cycle == XLOG_INIT_CYCLE (e.g., mkfs). Signed-off-by: Brian Foster --- copy/xfs_copy.c | 2 +- db/metadump.c | 2 +- db/sb.c | 2 +- include/libxfs.h | 2 +- libxfs/rdwr.c | 15 ++++++++++++--- mkfs/xfs_mkfs.c | 3 ++- repair/phase2.c | 2 +- repair/xfs_repair.c | 2 +- 8 files changed, 20 insertions(+), 10 deletions(-) diff --git a/copy/xfs_copy.c b/copy/xfs_copy.c index 1dc7c65..62edfc8 100644 --- a/copy/xfs_copy.c +++ b/copy/xfs_copy.c @@ -1328,7 +1328,7 @@ format_log( */ libxfs_log_clear(NULL, buf->data, logstart, length, &buf->owner->uuid, xfs_sb_version_haslogv2(&mp->m_sb) ? 2 : 1, - mp->m_sb.sb_logsunit, XLOG_FMT, cycle); + mp->m_sb.sb_logsunit, XLOG_FMT, cycle, true); if (do_write(buf->owner, buf)) target[tcarg->id].state = INACTIVE; } diff --git a/db/metadump.c b/db/metadump.c index 8cdcb92..8455fdd 100644 --- a/db/metadump.c +++ b/db/metadump.c @@ -2552,7 +2552,7 @@ copy_log(void) libxfs_log_clear(NULL, iocur_top->data, logstart, logblocks, &mp->m_sb.sb_uuid, logversion, - mp->m_sb.sb_logsunit, XLOG_FMT, cycle); + mp->m_sb.sb_logsunit, XLOG_FMT, cycle, true); break; case 1: /* keep the dirty log */ diff --git a/db/sb.c b/db/sb.c index 17d446c..ee3927d 100644 --- a/db/sb.c +++ b/db/sb.c @@ -288,7 +288,7 @@ sb_logzero(uuid_t *uuidp) (xfs_extlen_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks), uuidp, xfs_sb_version_haslogv2(&mp->m_sb) ? 2 : 1, - mp->m_sb.sb_logsunit, XLOG_FMT, cycle); + mp->m_sb.sb_logsunit, XLOG_FMT, cycle, true); if (error) { dbprintf(_("ERROR: cannot clear the log\n")); return 0; diff --git a/include/libxfs.h b/include/libxfs.h index 04c6f9c..bd51df0 100644 --- a/include/libxfs.h +++ b/include/libxfs.h @@ -154,7 +154,7 @@ typedef char *(libxfs_get_block_t)(char *, int, void *); */ #define XLOG_INIT_CYCLE 1 extern int libxfs_log_clear(struct xfs_buftarg *, char *, xfs_daddr_t, - uint, uuid_t *, int, int, int, int); + uint, uuid_t *, int, int, int, int, bool); extern int libxfs_log_header(char *, uuid_t *, int, int, int, xfs_lsn_t, xfs_lsn_t, libxfs_get_block_t *, void *); diff --git a/libxfs/rdwr.c b/libxfs/rdwr.c index 16904d0..7a04985 100644 --- a/libxfs/rdwr.c +++ b/libxfs/rdwr.c @@ -162,7 +162,8 @@ libxfs_log_clear( int version, int sunit, /* bytes */ int fmt, - int cycle) + int cycle, + bool max) { struct xfs_buf *bp = NULL; int len; @@ -218,6 +219,14 @@ libxfs_log_clear( return 0; /* + * Bump the record size for a full log format if the caller allows it. + * This is primarily for performance reasons and most callers don't care + * about record size since the log is clean after we're done. + */ + if (max) + len = BTOBB(BDSTRAT_SIZE); + + /* * Otherwise, fill everything beyond the initial record with records of * the previous cycle so the kernel head/tail detection works correctly. * @@ -233,7 +242,7 @@ libxfs_log_clear( dptr += BBTOB(len); end_blk = start + length; - len = min(end_blk - blk, BTOBB(BDSTRAT_SIZE)); + len = min(end_blk - blk, len); while (blk < end_blk) { lsn = xlog_assign_lsn(cycle, blk - start); tail_lsn = xlog_assign_lsn(cycle, blk - start - len); @@ -257,7 +266,7 @@ libxfs_log_clear( blk += len; if (dptr) dptr += BBTOB(len); - len = min(end_blk - blk, BTOBB(BDSTRAT_SIZE)); + len = min(end_blk - blk, len); } return 0; diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c index 7cba41a..546108d 100644 --- a/mkfs/xfs_mkfs.c +++ b/mkfs/xfs_mkfs.c @@ -2713,7 +2713,8 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"), libxfs_log_clear(mp->m_logdev_targp, NULL, XFS_FSB_TO_DADDR(mp, logstart), (xfs_extlen_t)XFS_FSB_TO_BB(mp, logblocks), - &sbp->sb_uuid, logversion, lsunit, XLOG_FMT, XLOG_INIT_CYCLE); + &sbp->sb_uuid, logversion, lsunit, XLOG_FMT, XLOG_INIT_CYCLE, + false); mp = libxfs_mount(mp, sbp, xi.ddev, xi.logdev, xi.rtdev, 0); if (mp == NULL) { diff --git a/repair/phase2.c b/repair/phase2.c index cb24711..e21ffa6 100644 --- a/repair/phase2.c +++ b/repair/phase2.c @@ -119,7 +119,7 @@ zero_log( (xfs_extlen_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks), &mp->m_sb.sb_uuid, xfs_sb_version_haslogv2(&mp->m_sb) ? 2 : 1, - mp->m_sb.sb_logsunit, XLOG_FMT, XLOG_INIT_CYCLE); + mp->m_sb.sb_logsunit, XLOG_FMT, XLOG_INIT_CYCLE, true); /* update the log data structure with new state */ error = xlog_find_tail(log, &head_blk, &tail_blk); diff --git a/repair/xfs_repair.c b/repair/xfs_repair.c index 1aeac5b..3eaced4 100644 --- a/repair/xfs_repair.c +++ b/repair/xfs_repair.c @@ -586,7 +586,7 @@ format_log_max_lsn( do_warn(_("Format log to cycle %d.\n"), new_cycle); libxfs_log_clear(log->l_dev, NULL, logstart, logblocks, &mp->m_sb.sb_uuid, logversion, mp->m_sb.sb_logsunit, - XLOG_FMT, new_cycle); + XLOG_FMT, new_cycle, true); } int -- 2.1.0 From bfoster@redhat.com Wed Nov 25 14:19:54 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 80A0B7F37 for ; Wed, 25 Nov 2015 14:19:54 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 1F194AC003 for ; Wed, 25 Nov 2015 12:19:54 -0800 (PST) X-ASG-Debug-ID: 1448482792-04cbb0605e227280001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id vQF9GocT4ugxCiA4 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 25 Nov 2015 12:19:53 -0800 (PST) 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 (Postfix) with ESMTPS id 7EB8E68E09; Wed, 25 Nov 2015 20:19:52 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-225.bos.redhat.com [10.18.41.225]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAPKJqAj016143; Wed, 25 Nov 2015 15:19:52 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id D0DE7122406; Wed, 25 Nov 2015 15:19:50 -0500 (EST) From: Brian Foster To: fstests@vger.kernel.org Cc: xfs@oss.sgi.com Subject: [PATCH 0/2] xfstests: xfsprogs logformat tests Date: Wed, 25 Nov 2015 15:19:48 -0500 X-ASG-Orig-Subj: [PATCH 0/2] xfstests: xfsprogs logformat tests Message-Id: <1448482790-44469-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: 1448482792 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Hi all, Here are a couple prospective tests that use the recently posted xfs_db logformat command: http://oss.sgi.com/pipermail/xfs/2015-November/045139.html Note that these should not be merged until xfs_db logformat support is fully reviewed and merged into xfsprogs. Also note that the test numbers are arbitrarily high and should be renumbered. Patch 1 adds a test that uses xfs_logprint to verify that logformat formats the log correctly with various stripe unit alignments. Patch 2 uses the logformat command to test invalid metadata LSN detection and recovery. Thoughts, reviews, flames appreciated. Brian Brian Foster (2): tests/xfs: test xfsprogs log formatting infrastructure tests/xfs: verify invalid metadata LSN detection common/rc | 14 +++++++++ tests/xfs/376 | 71 +++++++++++++++++++++++++++++++++++++++++++ tests/xfs/376.out | 6 ++++ tests/xfs/377 | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/xfs/377.out | 3 ++ tests/xfs/group | 2 ++ 6 files changed, 186 insertions(+) create mode 100755 tests/xfs/376 create mode 100644 tests/xfs/376.out create mode 100755 tests/xfs/377 create mode 100644 tests/xfs/377.out -- 2.1.0 From bfoster@redhat.com Wed Nov 25 14:19:57 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 777FB7F52 for ; Wed, 25 Nov 2015 14:19:57 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 663F4304059 for ; Wed, 25 Nov 2015 12:19:54 -0800 (PST) X-ASG-Debug-ID: 1448482792-04cb6c0cd31f0c40001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id wB7CrzuzvdlMGeLz (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 25 Nov 2015 12:19:53 -0800 (PST) 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 (Postfix) with ESMTPS id A429A3B70F; Wed, 25 Nov 2015 20:19:52 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-225.bos.redhat.com [10.18.41.225]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAPKJqSL016145; Wed, 25 Nov 2015 15:19:52 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id EE284122420; Wed, 25 Nov 2015 15:19:50 -0500 (EST) From: Brian Foster To: fstests@vger.kernel.org Cc: xfs@oss.sgi.com Subject: [PATCH 1/2] tests/xfs: test xfsprogs log formatting infrastructure Date: Wed, 25 Nov 2015 15:19:49 -0500 X-ASG-Orig-Subj: [PATCH 1/2] tests/xfs: test xfsprogs log formatting infrastructure Message-Id: <1448482790-44469-2-git-send-email-bfoster@redhat.com> In-Reply-To: <1448482790-44469-1-git-send-email-bfoster@redhat.com> References: <1448482790-44469-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: 1448482793 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 The xfsprogs libxfs layer implements its own log formatting code to support utilities that might need to format the log, such as mkfs, repair, metadump, etc. This code is fairly independent from kernel log writing code. Therefore, add a test that reformats the log from userspace with various supported log stripe unit alignments and verifies that the end result is a correctly formatted log. Signed-off-by: Brian Foster --- common/rc | 14 +++++++++++ tests/xfs/376 | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/xfs/376.out | 6 +++++ tests/xfs/group | 1 + 4 files changed, 92 insertions(+) create mode 100755 tests/xfs/376 create mode 100644 tests/xfs/376.out diff --git a/common/rc b/common/rc index 4c2f42c..a2628d7 100644 --- a/common/rc +++ b/common/rc @@ -1654,6 +1654,20 @@ _require_xfs_io_command() _notrun "xfs_io $command failed (old kernel/wrong fs?)" } +# check that xfs_db supports a specific command +_require_xfs_db_command() +{ + if [ $# -ne 1 ] + then + echo "Usage: _require_xfs_db_command command" 1>&2 + exit 1 + fi + command=$1 + + $XFS_DB_PROG -x -c "help" $SCRATCH_DEV | grep $command > /dev/null || \ + _notrun "xfs_db $command support is missing" +} + # check that kernel and filesystem support direct I/O _require_odirect() { diff --git a/tests/xfs/376 b/tests/xfs/376 new file mode 100755 index 0000000..e8cc15d --- /dev/null +++ b/tests/xfs/376 @@ -0,0 +1,71 @@ +#! /bin/bash +# FS QA Test No. 376 +# +# This test verifies that the xfsprogs log formatting infrastructure works +# correctly for various log stripe unit values. The log is formatted with xfs_db +# and verified with xfs_logprint. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015 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.* +} + +rm -f $seqres.full + +# get standard environment, filters and checks +. ./common/rc +. ./common/log + +# real QA test starts here + +# Modify as appropriate. +_supported_fs xfs +_supported_os Linux +_require_scratch +_require_v2log +_require_xfs_db_command "logformat" + +_scratch_mkfs >> $seqres.full 2>&1 || _fail "mkfs failed" + +# Reformat the log with various log stripe unit sizes and see if logprint dumps +# any errors. Use a cycle value larger than 1 so the log is actually written +# (the log is zeroed when cycle == 1). +for i in 16 32 64 128 256; do + lsunit=$((i * 1024)) + $XFS_DB_PROG -x -c "logformat -c 3 -s $lsunit" $SCRATCH_DEV | \ + tee -a $seqres.full + # don't redirect error output so it causes test failure + $XFS_LOGPRINT_PROG $SCRATCH_DEV >> $seqres.full +done + +# success, all done +status=0 +exit diff --git a/tests/xfs/376.out b/tests/xfs/376.out new file mode 100644 index 0000000..b13a150 --- /dev/null +++ b/tests/xfs/376.out @@ -0,0 +1,6 @@ +QA output created by 376 +Formatting the log to cycle 3, stripe unit 16384 bytes. +Formatting the log to cycle 3, stripe unit 32768 bytes. +Formatting the log to cycle 3, stripe unit 65536 bytes. +Formatting the log to cycle 3, stripe unit 131072 bytes. +Formatting the log to cycle 3, stripe unit 262144 bytes. diff --git a/tests/xfs/group b/tests/xfs/group index 9884329..77b9994 100644 --- a/tests/xfs/group +++ b/tests/xfs/group @@ -226,3 +226,4 @@ 303 auto quick quota 304 auto quick quota 305 auto quota +376 auto logprint quick v2log -- 2.1.0 From bfoster@redhat.com Wed Nov 25 14:19:57 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 72DCC7F51 for ; Wed, 25 Nov 2015 14:19:57 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 62D51304048 for ; Wed, 25 Nov 2015 12:19:54 -0800 (PST) X-ASG-Debug-ID: 1448482792-04cb6c0cd41f0c40001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id aSm0Le92wzluBlZ8 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 25 Nov 2015 12:19:53 -0800 (PST) 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 (Postfix) with ESMTPS id A3818C0B7AD2; Wed, 25 Nov 2015 20:19:52 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-225.bos.redhat.com [10.18.41.225]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAPKJqXt000607; Wed, 25 Nov 2015 15:19:52 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id E1C5D1223E9; Wed, 25 Nov 2015 15:19:50 -0500 (EST) From: Brian Foster To: fstests@vger.kernel.org Cc: xfs@oss.sgi.com Subject: [PATCH 2/2] tests/xfs: verify invalid metadata LSN detection Date: Wed, 25 Nov 2015 15:19:50 -0500 X-ASG-Orig-Subj: [PATCH 2/2] tests/xfs: verify invalid metadata LSN detection Message-Id: <1448482790-44469-3-git-send-email-bfoster@redhat.com> In-Reply-To: <1448482790-44469-1-git-send-email-bfoster@redhat.com> References: <1448482790-44469-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: 1448482793 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 XFS v5 superblock fs' use metadata LSN tracking to determine when an on-disk structure was last written to disk. This is used to ensure log recovery operates correctly after an unclean shutdown. To work correctly, the on-disk metadata LSNs must always remain behind the current LSN with respect to the log. Historically, xfs_repair had a problem where it incorrectly formats the log to an LSN that is potentially behind existing metadata LSNs. As such, xfs_repair and the kernel have been updated to prevent, detect and recover from the problem. Add a test that intentionally formats the log incorrectly and verifies that the fs fails to mount and that xfs_repair detects the invalid metadata LSNs. Signed-off-by: Brian Foster --- tests/xfs/377 | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/xfs/377.out | 3 ++ tests/xfs/group | 1 + 3 files changed, 94 insertions(+) create mode 100755 tests/xfs/377 create mode 100644 tests/xfs/377.out diff --git a/tests/xfs/377 b/tests/xfs/377 new file mode 100755 index 0000000..c8211b8 --- /dev/null +++ b/tests/xfs/377 @@ -0,0 +1,90 @@ +#! /bin/bash +# FS QA Test No. 377 +# +# XFS v5 supers carry an LSN in various on-disk structures to track when +# associated metadata was last written to disk. These metadata LSNs must always +# be behind the current LSN as dictated by the log to ensure log recovery +# correctness after a potential crash. This test uses xfs_db to intentionally +# put the current LSN behind metadata LSNs and verifies that the kernel and +# xfs_repair detect the problem. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015 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.* +} + +rm -f $seqres.full + +# get standard environment, filters and checks +. ./common/rc + +# real QA test starts here + +# Modify as appropriate. +_supported_fs xfs +_supported_os Linux +_require_scratch +_require_xfs_crc +_require_xfs_db_command "logformat" + +_scratch_mkfs >> $seqres.full 2>&1 || _fail "mkfs failed" + +# push the log cycle ahead so we have room to move it backwards later +$XFS_DB_PROG -x -c "logformat -c 3" $SCRATCH_DEV >> $seqres.full 2>&1 + +# do some work on the fs to update metadata LSNs +_scratch_mount +$FSSTRESS_PROG -d $SCRATCH_MNT -n 999 -p 4 -w >> $seqres.full 2>&1 +_scratch_unmount + +# Reformat to the current cycle and try to mount. This fails in most cases +# because the sb LSN is ahead of the current LSN. If it doesn't fail, push the +# cycle back further and try again. +$XFS_DB_PROG -x -c "logformat" $SCRATCH_DEV >> $seqres.full 2>&1 +_scratch_mount >> $seqres.full 2>&1 +if [ $? != 0 ]; then + echo mount failure detected +else + _scratch_unmount + $XFS_DB_PROG -x -c "logformat -c 2" $SCRATCH_DEV >> $seqres.full 2>&1 + _scratch_mount >> $seqres.full 2>&1 || echo mount failure detected +fi + +# verify that repair detects invalid LSNs as well +$XFS_REPAIR_PROG -n $SCRATCH_DEV >> $seqres.full 2>&1 || \ + echo repair failure detected + +# repair for real so the post-test check can verify repair fixed things up +$XFS_REPAIR_PROG $SCRATCH_DEV >> $seqres.full 2>&1 + +# success, all done +status=0 +exit diff --git a/tests/xfs/377.out b/tests/xfs/377.out new file mode 100644 index 0000000..d49b5f2 --- /dev/null +++ b/tests/xfs/377.out @@ -0,0 +1,3 @@ +QA output created by 377 +mount failure detected +repair failure detected diff --git a/tests/xfs/group b/tests/xfs/group index 77b9994..d8c32c7 100644 --- a/tests/xfs/group +++ b/tests/xfs/group @@ -227,3 +227,4 @@ 304 auto quick quota 305 auto quota 376 auto logprint quick v2log +377 auto metadata v2log -- 2.1.0 From david@fromorbit.com Wed Nov 25 15:35:25 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 795087F37 for ; Wed, 25 Nov 2015 15:35:25 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 668708F8033 for ; Wed, 25 Nov 2015 13:35:22 -0800 (PST) X-ASG-Debug-ID: 1448487314-04cbb0605d228b80001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id wxugJnnlEpkQ5zdj for ; Wed, 25 Nov 2015 13:35:14 -0800 (PST) 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: A2AHCQA9KFZW/1bELHlUCoM7U2+rHg8BAQEGi0GJPxcKhWgEAgKBRU0BAQEBAQGBC4Q0AQEBAwEBAjccIwULCAMOCgklDwUUEQMhE4gmBw6+UAEsGYV0hUWEMAQBhQQFh0eHDogCikqCYoFlh2eTG2OEGCo0AYNhAR+BKgEBAQ Received: from ppp121-44-196-86.lns20.syd7.internode.on.net (HELO dastard) ([121.44.196.86]) by ipmail07.adl2.internode.on.net with ESMTP; 26 Nov 2015 08:05:13 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1a1hiO-0004Jn-N9; Thu, 26 Nov 2015 08:35:00 +1100 Date: Thu, 26 Nov 2015 08:35:00 +1100 From: Dave Chinner To: Lutz Vieweg Cc: xfs@oss.sgi.com Subject: Re: Does XFS support cgroup writeback limiting? Message-ID: <20151125213500.GK26718@dastard> X-ASG-Orig-Subj: Re: Does XFS support cgroup writeback limiting? References: <5652F311.7000406@5t9.de> <20151123202619.GE26718@dastard> <56538E6A.6030203@5t9.de> <20151123232052.GI26718@dastard> <5655FDDA.9050502@5t9.de> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <5655FDDA.9050502@5t9.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: 1448487314 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24727 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Wed, Nov 25, 2015 at 07:28:42PM +0100, Lutz Vieweg wrote: > On 11/24/2015 12:20 AM, Dave Chinner wrote: > >Just make the same mods to XFS as the ext4 patch here: > > > >http://www.spinics.net/lists/kernel/msg2014816.html > > I read at http://www.spinics.net/lists/kernel/msg2014819.html > about this patch: > > >Journal data which is written by jbd2 worker is left alone by > >this patch and will always be written out from the root cgroup. > > If the same was done for XFS, wouldn't this mean a malicious > process could still stall other processes' attempts to write > to the filesystem by performing arbitrary amounts of meta-data > modifications in a tight loop? XFS doesn't have journal driver writeback, so no. > >>After all, this functionality is the last piece of the > >>"isolation"-puzzle that is missing from Linux to actually > >>allow fencing off virtual machines or containers from DOSing > >>each other by using up all I/O bandwidth... > > > >Yes, I know, but no-one seems to care enough about it to provide > >regression tests for it. > > Well, I could give it a try, if a shell script tinkering with > control groups parameters (which requires root privileges and > could easily stall the machine) would be considered adequate for > the purpose. xfstests is where such tests need to live. It would need infrastructure to set up control groups and bandwidth limits... > I would propose a test to be performed like this: > > 0) Identify a block device to test on. I guess some artificially > speed-limited DM device would be best? > Set the speed limit to X/100 MB per second, with X configurable. xfstests provides a scratch device that can be used for this. > > 1) Start 4 "good" plus 4 "evil" subprocesses competing for > write-bandwidth on the block device. > Assign the 4 "good" processes to two different control groups ("g1", "g2"), > assign the 4 "evil" processes to further two different control > groups ("e1", "e2"), so 4 control groups in total, with 2 tasks each. > > 2) Create 3 different XFS filesystem instances on the block > device, one for access by only the "good" processes, > on for access by only the "evil" processes, one for > shared access by at least two "good" and two "evil" > processes. Why do you need multiple filesystems? The writeback throttling is designed to work within a single filesystem... I was thinking of something similar, but quite simple, using "bound" and "unbound" (i.e. limited and unlimited) processes. e.g: process 1 is unbound, does large sequential IO process 2-N are bound to 1MB/s, do large sequential IO Run for several minutes to reach a stable steady state behaviour. if process 2-N do not receive 1MB/s throughput each, then throttling of the unbound writeback processes is not working. Combinations of this test using different read/write streams on each process gives multiple tests, verifies that block IO control works for both read and write IO, not just writeback throttling. And then other combinations of this sort of test, such as also binding process 1 is bound to, say, 20MB/s. Repeating the tests can then tell us if fast and slow bindings are working correctly. i.e. checking to ensure that process 1 doesn't exceed it's limits and all the other streams stay within bounds, too. > 3) Behaviour of the processes: > > "Good" processes will attempt to write a configured amount > of data (X MB) at 20% of the speed limit of the block device, modifying > meta-data at a moderate rate (like creating/renaming/deleting files > every few megabytes written). > Half of the "good" processes write to their "good-only" filesystem, > the other half writes to the "shared access" filesystem. > > Half of the "evil" processes will attempt to write as much data > as possible into open files in a tight endless loop. > The other half of the "evil" processes will permanently > modify meta-data as quickly as possible, creating/renaming/deleting > lots of files, also in a tight endless loop. > Half of the "evil" processes writes to the "evil-only" filesystem, > the other half writes to the "shared access" filesystem. Metadata IO not throttled - it is owned by the filesystem and hence root cgroup. There is no point in running tests that do large amounts of journal/metadata IO as it is this will result in uncontrollable and unpredictabe IO patterns and hence will give unreliable test results. We want to test the data bandwidth control algorithms work appropriately in a controlled, repeatable environment. Throwing all sorts of uncontrollable IO at the device is a good /stress/ test, but it is not going to tell us anything useful in terms of correctness or reliably detect functional regressions. > 4) Test 1: Configure all 4 control groups to allow for the same > buffered write rate percentage. > > The test is successful if all "good processes" terminate successfully > after a time not longer than it would take to write 10 times X MB to the > rate-limited block device. if we are rate limiting to 1MB/s, then a 10s test is not long enough to reach steady state. Indeed, it's going to take at least 30s worth of IO to guarantee that we getting writeback occurring for low bandwidth streams.... i.e. the test needs to run for a period of time and then measure the throughput of each stream, comparing it against the expected throughput for the stream, rather than trying to write a fixed bandwidth.... > 5) Test 2: Configure "e1" and "e2" to allow for "zero" buffered write rate. > > The test is successful if the "good processes" terminate successfully > after a time not longer than it would take to write 5 times X MB to the > rate-limited block device. > > All processes to be killed after termination of all good processes or > some timeout. If the timeout is reached, the test is failed. > > 6) Cleanup: unmount test filesystems, remove rate-limited DM device, remove > control groups. control group cleanup will need to be added to the xfstests infrastructure, but it handles everything else... > What do you think, could this be a reasonable plan? Yes, I think we can pull a reasonable set of baseline tests from an approach like this. Cheers, Dave. -- Dave Chinner david@fromorbit.com From yamato@redhat.com Wed Nov 25 20:22:58 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 8B2C97F37 for ; Wed, 25 Nov 2015 20:22:58 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 5EE5E30405F for ; Wed, 25 Nov 2015 18:22:55 -0800 (PST) X-ASG-Debug-ID: 1448504569-04bdf07f082502f0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id gxtc4lAxwzHytJ5W (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 25 Nov 2015 18:22:50 -0800 (PST) X-Barracuda-Envelope-From: yamato@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 (Postfix) with ESMTPS id 93C5ED69CB; Thu, 26 Nov 2015 02:22:49 +0000 (UTC) Received: from x201.localdomain.com (dhcp-193-150.nrt.redhat.com [10.64.193.150]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAQ2MmXW017502; Wed, 25 Nov 2015 21:22:48 -0500 From: Masatake YAMATO To: xfs@oss.sgi.com Cc: yamato@redhat.com Subject: [PATCH v2] xfs: send warning of project quota to userspace via netlink Date: Thu, 26 Nov 2015 11:22:39 +0900 X-ASG-Orig-Subj: [PATCH v2] xfs: send warning of project quota to userspace via netlink Message-Id: <1448504560-25151-1-git-send-email-yamato@redhat.com> In-Reply-To: <20151125185419.GA18719@bfoster.bfoster> References: <20151125185419.GA18719@bfoster.bfoster> 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: 1448504570 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Linux's quota subsystem has an ability to handle project quota. This commit just utilizes the ability from xfs side. dbus-monitor and quota_nld shipped as part of quota-tools can be used for testing. The testing environment and condition: # cat /etc/projects 10:/root/Q/a # grep Q /proc/mounts /dev/loop0 /root/Q xfs rw,relatime,attr2,inode64,prjquota 0 0 # ls -l /dev/loop0 brw-rw---- 1 root disk 7, 0 Nov 26 10:46 /dev/loop0 3 terminals are used for each commands: dd, quota_nld, and dbus-monitor. Start quota_nld with terminal 1: [1]# quota_nld -F Start dbus-monitor with terminal 2: [2]# dbus-monitor --system Start dd to generate a large file for hitting the quota limit: [3]# dd if=/dev/sda of=/root/Q/a/X At the terminal 1, you will see warning messages like: quota_nld: Failed to open tty /dev/tty1 of user 0 to report warning. Let's ignore them. These meaningless messages are suppressed by a patch available at https://sourceforge.net/p/linuxquota/patches/43/. At the terminal 2, you will see following traffic about disk quota (newlines are inserted): signal time=1448502680.741715 sender=:1.35 -> \ destination=(null destination) serial=4 path=/; \ interface=com.system.quota.warning; member=warning uint32 2 uint64 10 uint32 6 uint32 7 uint32 0 uint64 0 signal time=1448502680.742518 sender=:1.35 -> \ destination=(null destination) serial=5 path=/; \ interface=com.system.quota.warning; member=warning uint32 2 uint64 10 uint32 4 uint32 7 uint32 0 uint64 0 The 1st "2" means the type of quota: project quota. The 2nd "10" means the project id. The 3rd "4" and "6" mean "Block hardlimit reached" and "Block softlimit reached". The 4th "7" means the major number of loop0. The 5th "0" means the minor number of loop0. Changes in v2: a couple aesthetic things suggested by Brian Foster . * rename local vairable for aligning the parameter names, * move a short line to the end of its previous line. Signed-off-by: Masatake YAMATO --- fs/xfs/xfs_trans_dquot.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c index ce78534..9951701 100644 --- a/fs/xfs/xfs_trans_dquot.c +++ b/fs/xfs/xfs_trans_dquot.c @@ -572,12 +572,16 @@ xfs_quota_warn( struct xfs_dquot *dqp, int type) { - /* no warnings for project quotas - we just return ENOSPC later */ + enum quota_type qtype; + if (dqp->dq_flags & XFS_DQ_PROJ) - return; - quota_send_warning(make_kqid(&init_user_ns, - (dqp->dq_flags & XFS_DQ_USER) ? - USRQUOTA : GRPQUOTA, + qtype = PRJQUOTA; + else if (dqp->dq_flags & XFS_DQ_USER) + qtype = USRQUOTA; + else + qtype = GRPQUOTA; + + quota_send_warning(make_kqid(&init_user_ns, qtype, be32_to_cpu(dqp->q_core.d_id)), mp->m_super->s_dev, type); } -- 2.5.0 From yamato@redhat.com Wed Nov 25 20:34:14 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 A1F4C7F37 for ; Wed, 25 Nov 2015 20:34:14 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 7E2218F8050 for ; Wed, 25 Nov 2015 18:34:14 -0800 (PST) X-ASG-Debug-ID: 1448505252-04cbb0605b2330e0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id QAebinnh7GNhY8sV (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 25 Nov 2015 18:34:13 -0800 (PST) X-Barracuda-Envelope-From: yamato@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 (Postfix) with ESMTPS id 92CD568E01; Thu, 26 Nov 2015 02:34:12 +0000 (UTC) Received: from x201.localdomain.com (dhcp-193-150.nrt.redhat.com [10.64.193.150]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAQ2YBuJ022293; Wed, 25 Nov 2015 21:34:11 -0500 From: Masatake YAMATO To: xfs@oss.sgi.com Cc: yamato@redhat.com Subject: [PATCH v2] xfs: send warning of project quota to userspace via netlink Date: Thu, 26 Nov 2015 11:34:07 +0900 X-ASG-Orig-Subj: [PATCH v2] xfs: send warning of project quota to userspace via netlink Message-Id: <1448505248-25481-1-git-send-email-yamato@redhat.com> In-Reply-To: <20151125185419.GA18719@bfoster.bfoster> References: <20151125185419.GA18719@bfoster.bfoster> 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: 1448505253 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Linux's quota subsystem has an ability to handle project quota. This commit just utilizes the ability from xfs side. dbus-monitor and quota_nld shipped as part of quota-tools can be used for testing. The testing environment and condition: # cat /etc/projects 10:/root/Q/a # grep Q /proc/mounts /dev/loop0 /root/Q xfs rw,relatime,attr2,inode64,prjquota 0 0 # ls -l /dev/loop0 brw-rw---- 1 root disk 7, 0 Nov 26 10:46 /dev/loop0 3 terminals are used for each commands: dd, quota_nld, and dbus-monitor. Start quota_nld with terminal 1: [1]# quota_nld -F Start dbus-monitor with terminal 2: [2]# dbus-monitor --system Start dd to generate a large file for hitting the quota limit: [3]# dd if=/dev/sda of=/root/Q/a/X At the terminal 1, you will see warning messages like: quota_nld: Failed to open tty /dev/tty1 of user 0 to report warning. Let's ignore them. These meaningless messages are suppressed by a patch available at https://sourceforge.net/p/linuxquota/patches/43/. At the terminal 2, you will see following traffic about disk quota (newlines are inserted): signal time=1448502680.741715 sender=:1.35 -> \ destination=(null destination) serial=4 path=/; \ interface=com.system.quota.warning; member=warning uint32 2 uint64 10 uint32 6 uint32 7 uint32 0 uint64 0 signal time=1448502680.742518 sender=:1.35 -> \ destination=(null destination) serial=5 path=/; \ interface=com.system.quota.warning; member=warning uint32 2 uint64 10 uint32 4 uint32 7 uint32 0 uint64 0 The 1st "2" means the type of quota: project quota. The 2nd "10" means the project id. The 3rd "4" and "6" mean "Block hardlimit reached" and "Block softlimit reached". The 4th "7" means the major number of loop0. The 5th "0" means the minor number of loop0. Changes in v2: a couple aesthetic things suggested by Brian Foster . * rename local vairable for aligning the parameter names, * move a short line to the end of its previous line. Signed-off-by: Masatake YAMATO --- fs/xfs/xfs_trans_dquot.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c index ce78534..9951701 100644 --- a/fs/xfs/xfs_trans_dquot.c +++ b/fs/xfs/xfs_trans_dquot.c @@ -572,12 +572,16 @@ xfs_quota_warn( struct xfs_dquot *dqp, int type) { - /* no warnings for project quotas - we just return ENOSPC later */ + enum quota_type qtype; + if (dqp->dq_flags & XFS_DQ_PROJ) - return; - quota_send_warning(make_kqid(&init_user_ns, - (dqp->dq_flags & XFS_DQ_USER) ? - USRQUOTA : GRPQUOTA, + qtype = PRJQUOTA; + else if (dqp->dq_flags & XFS_DQ_USER) + qtype = USRQUOTA; + else + qtype = GRPQUOTA; + + quota_send_warning(make_kqid(&init_user_ns, qtype, be32_to_cpu(dqp->q_core.d_id)), mp->m_super->s_dev, type); } -- 2.5.0 From yamato@redhat.com Wed Nov 25 20:34:16 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 996947F51 for ; Wed, 25 Nov 2015 20:34:16 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 6AAB68F8064 for ; Wed, 25 Nov 2015 18:34:16 -0800 (PST) X-ASG-Debug-ID: 1448505254-04bdf07f07250620001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id D2QE3cNpC51qBfOq (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 25 Nov 2015 18:34:14 -0800 (PST) X-Barracuda-Envelope-From: yamato@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 (Postfix) with ESMTPS id 977CFC0B7AA9; Thu, 26 Nov 2015 02:34:14 +0000 (UTC) Received: from x201.localdomain.com (dhcp-193-150.nrt.redhat.com [10.64.193.150]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAQ2YBuK022293; Wed, 25 Nov 2015 21:34:13 -0500 From: Masatake YAMATO To: xfs@oss.sgi.com Cc: yamato@redhat.com Subject: [PATCH v2] xfs: send warning of project quota to userspace via netlink Date: Thu, 26 Nov 2015 11:34:08 +0900 X-ASG-Orig-Subj: [PATCH v2] xfs: send warning of project quota to userspace via netlink Message-Id: <1448505248-25481-2-git-send-email-yamato@redhat.com> In-Reply-To: <1448505248-25481-1-git-send-email-yamato@redhat.com> References: <20151125185419.GA18719@bfoster.bfoster> <1448505248-25481-1-git-send-email-yamato@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: 1448505254 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Linux's quota subsystem has an ability to handle project quota. This commit just utilizes the ability from xfs side. dbus-monitor and quota_nld shipped as part of quota-tools can be used for testing. The testing environment and condition: # cat /etc/projects 10:/root/Q/a # grep Q /proc/mounts /dev/loop0 /root/Q xfs rw,relatime,attr2,inode64,prjquota 0 0 # ls -l /dev/loop0 brw-rw---- 1 root disk 7, 0 Nov 26 10:46 /dev/loop0 3 terminals are used for each commands: dd, quota_nld, and dbus-monitor. Start quota_nld with terminal 1: [1]# quota_nld -F Start dbus-monitor with terminal 2: [2]# dbus-monitor --system Start dd to generate a large file for hitting the quota limit: [3]# dd if=/dev/sda of=/root/Q/a/X At the terminal 1, you will see warning messages like: quota_nld: Failed to open tty /dev/tty1 of user 0 to report warning. Let's ignore them. These meaningless messages are suppressed by a patch available at https://sourceforge.net/p/linuxquota/patches/43/. At the terminal 2, you will see following traffic about disk quota (newlines are inserted): signal time=1448502680.741715 sender=:1.35 -> \ destination=(null destination) serial=4 path=/; \ interface=com.system.quota.warning; member=warning uint32 2 uint64 10 uint32 6 uint32 7 uint32 0 uint64 0 signal time=1448502680.742518 sender=:1.35 -> \ destination=(null destination) serial=5 path=/; \ interface=com.system.quota.warning; member=warning uint32 2 uint64 10 uint32 4 uint32 7 uint32 0 uint64 0 The 1st "2" means the type of quota: project quota. The 2nd "10" means the project id. The 3rd "4" and "6" mean "Block hardlimit reached" and "Block softlimit reached". The 4th "7" means the major number of loop0. The 5th "0" means the minor number of loop0. Changes in v2: a couple aesthetic things suggested by Brian Foster . * rename local vairable for aligning the parameter names, * move a short line to the end of its previous line. Signed-off-by: Masatake YAMATO --- fs/xfs/xfs_trans_dquot.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c index ce78534..9951701 100644 --- a/fs/xfs/xfs_trans_dquot.c +++ b/fs/xfs/xfs_trans_dquot.c @@ -572,12 +572,16 @@ xfs_quota_warn( struct xfs_dquot *dqp, int type) { - /* no warnings for project quotas - we just return ENOSPC later */ + enum quota_type qtype; + if (dqp->dq_flags & XFS_DQ_PROJ) - return; - quota_send_warning(make_kqid(&init_user_ns, - (dqp->dq_flags & XFS_DQ_USER) ? - USRQUOTA : GRPQUOTA, + qtype = PRJQUOTA; + else if (dqp->dq_flags & XFS_DQ_USER) + qtype = USRQUOTA; + else + qtype = GRPQUOTA; + + quota_send_warning(make_kqid(&init_user_ns, qtype, be32_to_cpu(dqp->q_core.d_id)), mp->m_super->s_dev, type); } -- 2.5.0 From yamato@redhat.com Wed Nov 25 20:40:32 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 76BB97F37 for ; Wed, 25 Nov 2015 20:40:32 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 6218E30405F for ; Wed, 25 Nov 2015 18:40:32 -0800 (PST) X-ASG-Debug-ID: 1448505630-04cbb0605e233290001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id SvswkdddzgeJDKOZ (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 25 Nov 2015 18:40:31 -0800 (PST) X-Barracuda-Envelope-From: yamato@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 (Postfix) with ESMTPS id C8164120483 for ; Thu, 26 Nov 2015 02:40:30 +0000 (UTC) Received: from localhost (dhcp-193-150.nrt.redhat.com [10.64.193.150]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAQ2eSNw012523; Wed, 25 Nov 2015 21:40:29 -0500 Date: Thu, 26 Nov 2015 11:40:28 +0900 (JST) Message-Id: <20151126.114028.748904313790123119.yamato@redhat.com> To: xfs@oss.sgi.com Cc: yamato@redhat.com Subject: Re: [PATCH v2] xfs: send warning of project quota to userspace via netlink From: Masatake YAMATO X-ASG-Orig-Subj: Re: [PATCH v2] xfs: send warning of project quota to userspace via netlink In-Reply-To: <1448505248-25481-2-git-send-email-yamato@redhat.com> References: <20151125185419.GA18719@bfoster.bfoster> <1448505248-25481-1-git-send-email-yamato@redhat.com> <1448505248-25481-2-git-send-email-yamato@redhat.com> Organization: Red Hat Japan, Inc. Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit 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: 1448505631 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 I'm sorry, mistakenly I sent the same message multiple times. All the same. so please, review the any one of them. Masatake YAMATO > Linux's quota subsystem has an ability to handle > project quota. This commit just utilizes the ability > from xfs side. > > dbus-monitor and quota_nld shipped as part of quota-tools can > be used for testing. > > The testing environment and condition: > > # cat /etc/projects > 10:/root/Q/a > # grep Q /proc/mounts > /dev/loop0 /root/Q xfs rw,relatime,attr2,inode64,prjquota 0 0 > # ls -l /dev/loop0 > brw-rw---- 1 root disk 7, 0 Nov 26 10:46 /dev/loop0 > > 3 terminals are used for each commands: dd, quota_nld, and dbus-monitor. > > Start quota_nld with terminal 1: > > [1]# quota_nld -F > > Start dbus-monitor with terminal 2: > > [2]# dbus-monitor --system > > Start dd to generate a large file for hitting the quota limit: > > [3]# dd if=/dev/sda of=/root/Q/a/X > > At the terminal 1, you will see warning messages like: > > quota_nld: Failed to open tty /dev/tty1 of user 0 to report warning. > > Let's ignore them. These meaningless messages > are suppressed by a patch available at > https://sourceforge.net/p/linuxquota/patches/43/. > > At the terminal 2, you will see following traffic about disk quota > (newlines are inserted): > > signal time=1448502680.741715 sender=:1.35 -> \ > destination=(null destination) serial=4 path=/; \ > interface=com.system.quota.warning; member=warning > uint32 2 > uint64 10 > uint32 6 > uint32 7 > uint32 0 > uint64 0 > signal time=1448502680.742518 sender=:1.35 -> \ > destination=(null destination) serial=5 path=/; \ > interface=com.system.quota.warning; member=warning > uint32 2 > uint64 10 > uint32 4 > uint32 7 > uint32 0 > uint64 0 > > The 1st "2" means the type of quota: project quota. > The 2nd "10" means the project id. > The 3rd "4" and "6" mean "Block hardlimit reached" and > "Block softlimit reached". > The 4th "7" means the major number of loop0. > The 5th "0" means the minor number of loop0. > > Changes in v2: > > a couple aesthetic things suggested by Brian Foster . > * rename local vairable for aligning the parameter names, > * move a short line to the end of its previous line. > > Signed-off-by: Masatake YAMATO > --- > fs/xfs/xfs_trans_dquot.c | 14 +++++++++----- > 1 file changed, 9 insertions(+), 5 deletions(-) > > diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c > index ce78534..9951701 100644 > --- a/fs/xfs/xfs_trans_dquot.c > +++ b/fs/xfs/xfs_trans_dquot.c > @@ -572,12 +572,16 @@ xfs_quota_warn( > struct xfs_dquot *dqp, > int type) > { > - /* no warnings for project quotas - we just return ENOSPC later */ > + enum quota_type qtype; > + > if (dqp->dq_flags & XFS_DQ_PROJ) > - return; > - quota_send_warning(make_kqid(&init_user_ns, > - (dqp->dq_flags & XFS_DQ_USER) ? > - USRQUOTA : GRPQUOTA, > + qtype = PRJQUOTA; > + else if (dqp->dq_flags & XFS_DQ_USER) > + qtype = USRQUOTA; > + else > + qtype = GRPQUOTA; > + > + quota_send_warning(make_kqid(&init_user_ns, qtype, > be32_to_cpu(dqp->q_core.d_id)), > mp->m_super->s_dev, type); > } > -- > 2.5.0 > From zxvbmseki@korea.com Thu Nov 26 02:11:56 2015 Return-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.6 required=5.0 tests=HK_RANDOM_ENVFROM, HK_RANDOM_FROM,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 (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id B0E787F37 for ; Thu, 26 Nov 2015 02:11:56 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 9DA5A304048 for ; Thu, 26 Nov 2015 00:11:53 -0800 (PST) X-ASG-Debug-ID: 1448525505-04cb6c0cd41ffce0001-NocioJ Received: from r-smtp6.korea.com (powered-by.xenosite.net [5.178.34.195]) by cuda.sgi.com with ESMTP id flkk8OMlHhALBW97 for ; Thu, 26 Nov 2015 00:11:46 -0800 (PST) X-Barracuda-Envelope-From: zxvbmseki@korea.com X-Barracuda-Apparent-Source-IP: 5.178.34.195 MIME-Version: 1.0 Date: Thu, 26 Nov 2015 11:11:46 +0300 Message-ID: <335048418.20151126111146@DGGAIJH> Subject: =?utf-8?B?0JjQt9C80LXQvdC10L3QuNGPINCyINCy0LDQu9GO0YLQvdC+0Lwg0YDQtdCz0YPQu9C40YDQvtCy0LDQvdC40Lgg0Lgg0LLQsNC70Y7RgtC90L7QvCDQutC+0L3RgtGA0L7Qu9C1?= From: "=?utf-8?B?0KTQlyAi0J4g0LLQsNC70Y7RgtC90L7QvCDRgNC10LPRg9C70LjRgNC+0LLQsNC90LjQuOKApiI=?=" X-ASG-Orig-Subj: =?utf-8?B?0JjQt9C80LXQvdC10L3QuNGPINCyINCy0LDQu9GO0YLQvdC+0Lwg0YDQtdCz0YPQu9C40YDQvtCy0LDQvdC40Lgg0Lgg0LLQsNC70Y7RgtC90L7QvCDQutC+0L3RgtGA0L7Qu9C1?= To: xfs@oss.sgi.com Content-Type: multipart/alternative; boundary=----------11D073358F5B8564 X-Barracuda-Connect: powered-by.xenosite.net[5.178.34.195] X-Barracuda-Start-Time: 1448525505 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24738 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 HTML_MESSAGE BODY: HTML included in message ------------11D073358F5B8564 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: base64 NCDQtNC10LrQsNCx0YDRjyB8INCzLiDQnNC+0YHQutCy0LAgfCBjIDEwOjAwINC00L4gMTc6MzAN Cg0KKtCe0LHRg9GH0LXQvXVlINC00LvRjzogKtGB0L7QsdGB0YLQstC10L3QvdC40LrQvtCyINCx 0LjQt9C90LXRgdCwLCDRhNC40L3QsNC90YHQvtCy0YvRhSDQuCDQutC+0LzQvNC10YDRh9C10YHQ utC40YUNCtC00LjRgNC10LrRgtC+0YDQvtCyLCDRgNGD0LrQvtCy0L7QtNC40YLQtdC70LXQuQ0K 0YTQuNC90LDQvdGB0L7QstC+LdGN0LrQvtC90L7QvNC40YfQtdGB0LrQuNGFINGB0LvRg9C20LEg 0L/RgNC10LTQv9GA0LjRj9GC0LjQuSDQuCDQvtGA0LPQsNC90LjQt9Cw0YbQuNC5LCDRg9GH0LDR gdGC0L3QuNC60L7Qsg0K0LLQvdC10YjQvdC10Y3QutC+0L3QvtC80LjRh9C10YHQutC+0LkNCtC0 0LXRj9GC0LXQu9GM0L3QvtGB0YLQuCwg0LHQsNC90LrQvtCy0YHQutC40YUg0YDQsNCx0L7RgtC9 0LjQutC+0LIuDQoNCg0KDQoNCg0KDQoNCirQktCQ0JvQrtCi0J3QntCVINCg0JXQk9Cj0JvQmNCg 0J7QktCQ0J3QmNCVINCYINCS0JDQm9Cu0KLQndCr0Jkg0JrQntCd0KLQoNCe0JvQrCDQkiDQoNCk INChINCj0KfQldCi0J7QnCDQn9Ce0KHQm9CV0JTQndCY0KUNCtCY0JfQnNCV0J3QldCd0JjQmSDQ l9CQ0JrQntCd0J7QlNCQ0KLQldCb0KzQodCi0JLQkCAqDQoNCirQkNGA0YLQuNC60YPQuzoqIDI1 Ng0KDQoq0JzQtdGB0YLQviDQv9GA0L7QstC10LTQtdC90LjRjzoqINGD0LsuINCR0LDRg9C80LDQ vdGB0LrQsNGPLCDQtC42LCDRgdGC0YAuMiwg0JEu0KYuICLQktC40LrRgtC+0YDQuNGPINCf0LvQ sNC30LAiLg0KDQoq0JLRgdGPINC/0L7QtNGA0L7QsdC90LDRjyDQuNC90YTQvtGA0LzQsNGG0LjR jyDQuCDRgNC10LPQuNGB0YLRgNCw0YbQuNGPINC/0L4g0YLQtdC70LXRhNC+0L3RgzoqIDggINC6 0L7QtCDQs9C+0YDQvtC00LAgICggNCA5DQo1ICkgINC90L7QvNC10YAgIDk2MSAtINCe0J4gLSDQ lzgNCg0KDQoq0KbQtdC70Ywg0LTQsNC90L3QvtCz0L4g0LfQsNC90Y/RgtC40Y86KiDQvtCx0YHR g9C00LjRgtGMINCw0LrRgtGD0LDQu9GM0L3Ri9C1INCy0L7Qv9GA0L7RgdGLLCDQuNC80LXRjtGJ 0LjQtSDQv9GA0LDQutGC0LjRh9C10YHQutGD0Y4NCtC90LDQv9GA0LDQstC70LXQvdC90L7RgdGC 0YwNCtC4INGB0LLRj9C30LDQvdC90YvQtSDRgSDQuNC30LzQtdC90LXQvdC40LXQvCDQstCw0LvR jtGC0L3QvtCz0L4g0LfQsNC60L7QvdC+0LTQsNGC0LXQu9GM0YHRgtCy0LAg0LIg0KDQpCwg0L/Q vtC70YPRh9C40YLRjCDQt9C90LDQvdC40Y8sDQrQutC+0YLQvtGA0YvQtQ0K0L/QvtC30LLQvtC7 0Y/RgiDQuNC30LHQtdC20LDRgtGMINGC0LjQv9C40YfQvdGL0YUg0L7RiNC40LHQvtC6INC4INC9 0LDRgNGD0YjQtdC90LjQuSDQv9GA0Lgg0YHQvtCy0LXRgNGI0LXQvdC40Lgg0Lgg0L7RhNC+0YDQ vNC70LXQvdC40LgNCtCy0LDQu9GO0YLQvdGL0YUg0L7Qv9C10YDQsNGG0LjQuS4NCg0KDQoNCtCh 0L7QtNC10YDQttCw0L3QuNC1INC/0YDQvtCz0YDQsNC80LzRizoNCiAgICAgICAgICAgICAgICAg KjEu0J3QvtCy0L7QtSDQsiDRgdC40YHRgtC10LzQtSDQstCw0LvRjtGC0L3QvtCz0L4g0YDQtdCz 0YPQu9C40YDQvtCy0LDQvdC40Y8g0LIg0KDQpC4qDQrQndC+0YDQvNCw0YLQuNCy0L3Qvi3Qv9GA 0LDQstC+0LLQsNGPINCx0LDQt9CwINCy0LDQu9GO0YLQvdC+0LPQviDRgNC10LPRg9C70LjRgNC+ 0LLQsNC90LjRjyDQsiDQoNC+0YHRgdC40LnRgdC60L7QuSDQpNC10LTQtdGA0LDRhtC40LguDQrQ n9C+0YHQu9C10LTQvdC40LUNCtC40LfQvNC10L3QtdC90LjRjyDQstCw0LvRjtGC0L3QvtCz0L4g 0LfQsNC60L7QvdC+0LTQsNGC0LXQu9GM0YHRgtCy0LAg0KDQpC4g0J/QvtGA0Y/QtNC+0Log0L7R gtC60YDRi9GC0LjRjyDQuCDQstC10LTQtdC90LjRjyDRgdGH0LXRgtC+0LINCtGA0LXQt9C40LTQ tdC90YLQvtCyINC30LANCtC/0YDQtdC00LXQu9Cw0LzQuCDRgtC10YDRgNC40YLQvtGA0LjQuCDQ oNCkLiDQn9GA0LDQstC40LvQsCDQvtGB0YPRidC10YHRgtCy0LvQtdC90LjRjyDRgNC10LfQuNC0 0LXQvdGC0LDQvNC4INCy0LDQu9GO0YLQvdGL0YUNCtC+0L/QtdGA0LDRhtC40Lkg0LfQsCDRgdGH 0LXRgg0K0YHRgNC10LTRgdGC0LIsINC90LDRhdC+0LTRj9GJ0LjRhdGB0Y8g0L3QsCDRgdGH0LXR gtCw0YUg0LfQsCDRgNGD0LHQtdC20L7QvC4g0J/QvtGA0Y/QtNC+0Log0L/QtdGA0LXQtNCw0YfQ uCDRg9C/0L7Qu9C90L7QvNC+0YfQtdC90L3Ri9C80LgNCtCx0LDQvdC60LDQvNC4DQrQuNC90YTQ vtGA0LzQsNGG0LjQuCDQviDQvdCw0YDRg9GI0LXQvdC40Y/RhSDQuNGFINC60LvQuNC10L3RgtCw 0LzQuCDQstCw0LvRjtGC0L3QvtCz0L4g0LfQsNC60L7QvdC+0LTQsNGC0LXQu9GM0YHRgtCy0LAg 0KDQpC4g0JTQtdC50YHRgtCy0LjQtQ0K0YTQtdC00LXRgNCw0LvRjNC90L7Qs9C+INC30LDQutC+ 0L3QsCAi0J4g0LLQsNC70Y7RgtC90L7QvCDRgNC10LPRg9C70LjRgNC+0LLQsNC90LjQuCDQuCDQ stCw0LvRjtGC0L3QvtC8INC60L7QvdGC0YDQvtC70LUiIDE3My3QpNCXDQoo0YEg0LjQt9C80LXQ vdC10L3QuNGP0LzQuCwNCtCy0YHRgtGD0L/QuNCy0YjQuNC80Lgg0LIg0YHQuNC70YMg0LIgMjAx MyDQs9C+0LTRgyDQuCDQstGB0YLRg9C/0LDRjtGJ0LjQvNC4INCyINGB0LjQu9GDINCyIDIwMTQg 0LMpLiDQn9GA0L7QtdC60YLRiw0K0LHRg9C00YPRidC40YUg0LjQt9C80LXQvdC10L3QuNC5DQrQ pNC10LTQtdGA0LDQu9GM0L3QvtCz0L4g0LfQsNC60L7QvdCwICLQniDQstCw0LvRjtGC0L3QvtC8 INGA0LXQs9GD0LvQuNGA0L7QstCw0L3QuNC4INC4INCy0LDQu9GO0YLQvdC+0Lwg0LrQvtC90YLR gNC+0LvQtSIuDQrQlNC10LnRgdGC0LLQuNC1INCy0LDQu9GO0YLQvdC+0LPQviDQt9Cw0LrQvtC9 0L7QtNCw0YLQtdC70YzRgdGC0LLQsCDQsiDRgdCy0Y/Qt9C4INGBINC/0YDQuNC90Y/RgtC40LXQ vCDQpNC10LTQtdGA0LDQu9GM0L3QvtCz0L4g0LfQsNC60L7QvdCwDQrQvtGCIDI3INC40Y7QvdGP DQoyMDExINCz0L7QtNCwIDE2MS3QpNCXICLQniDQvdCw0YbQuNC+0L3QsNC70YzQvdC+0Lkg0L/Q u9Cw0YLQtdC20L3QvtC5INGB0LjRgdGC0LXQvNC1Ii4g0J7RgdC+0LHQtdC90L3QvtGB0YLQuCDQ v9GA0L7QstC10LTQtdC90LjRjw0K0LLQsNC70Y7RgtC90YvRhQ0K0L7Qv9C10YDQsNGG0LjQuSDR gNC10LfQuNC00LXQvdGC0LDQvNC4INC4INC90LXRgNC10LfQuNC00LXQvdGC0LDQvNC4Lg0KDQoq Mi7QktCw0LvRjtGC0L3Ri9C5INC60L7QvdGC0YDQvtC70Ywg0L/RgNC4INC+0YHRg9GJ0LXRgdGC 0LLQu9C10L3QuNC4INCy0LDQu9GO0YLQvdGL0YUg0L7Qv9C10YDQsNGG0LjQuSwg0YHQstGP0LfQ sNC90L3Ri9GFINGBDQrQstC90LXRiNC90LXRgtC+0YDQs9C+0LLQvtC5INC00LXRj9GC0LXQu9GM 0L3QvtGB0YLRjNGOLCDQv9C+0LvRg9GH0LXQvdC40LXQvCDQuCDQv9GA0LXQtNC+0YHRgtCw0LLQ u9C10L3QuNC10Lwg0LrRgNC10LTQuNGC0L7QsiDQuA0K0LfQsNC50LzQvtCyLioNCtCf0LDRgdC/ 0L7RgNGCINGB0LTQtdC70LrQuDog0J7RhNC+0YDQvNC70LXQvdC40LUg0Lgg0LLQtdC00LXQvdC4 0LUg0L/QsNGB0L/QvtGA0YLQsCDRgdC00LXQu9C60Lgg0LIg0YbQtdC70Y/RhSDQvtCx0LXRgdC/ 0LXRh9C10L3QuNGPDQrRg9GH0LXRgtCwINC4INC+0YLRh9C10YLQvdC+0YHRgtC4DQrQuCDQvtGB 0YPRidC10YHRgtCy0LvQtdC90LjRjyDQstCw0LvRjtGC0L3QvtCz0L4g0LrQvtC90YLRgNC+0LvR jyDQv9C+INCy0LDQu9GO0YLQvdGL0Lwg0L7Qv9C10YDQsNGG0LjRj9C8INC80LXQttC00YMg0YDQ tdC30LjQtNC10L3RgtCw0LzQuCDQuA0K0L3QtdGA0LXQt9C40LTQtdC90YLQsNC80LguINCf0YDQ tdC00YHRgtCw0LLQu9C10L3QuNC1INGA0LXQt9C40LTQtdC90YLQsNC80Lgg0LIg0YPQv9C+0LvQ vdC+0LzQvtGH0LXQvdC90YvQuSDQsdCw0L3QuiDRgdC/0YDQsNCy0LrQuCDQvg0K0LLQsNC70Y7R gtC90YvRhQ0K0L7Qv9C10YDQsNGG0LjRj9GFINC4INGB0L/RgNCw0LLQutC4INC+INC/0L7QtNGC 0LLQtdGA0LbQtNCw0Y7RidC40YUg0LTQvtC60YPQvNC10L3RgtCw0YUg0L/RgNC4INC+0YHRg9GJ 0LXRgdGC0LLQu9C10L3QuNC4DQrQstC90LXRiNC90LXRgtC+0YDQs9C+0LLQvtC5DQrQtNC10Y/R gtC10LvRjNC90L7RgdGC0LguDQoNCiozLtCY0LfQvNC10L3QtdC90LjRjyDQv9GA0LDQstC40Lsg 0LLQsNC70Y7RgtC90L7Qs9C+INC60L7QvdGC0YDQvtC70Y8sINC+0YHRg9GJ0LXRgdGC0LLQu9GP 0LXQvNC+0LPQviDRgSDRg9GH0LDRgdGC0LjQtdC8DQrRgtCw0LzQvtC20LXQvdC90YvRhSDQvtGA 0LPQsNC90L7Qsi4qDQrQntCx0LfQvtGAINC40LfQvNC10L3QtdC90LjQuSDQvdC+0YDQvNCw0YLQ uNCy0L3Qvi3Qv9GA0LDQstC+0LLQvtC5INCx0LDQt9GLINCy0LDQu9GO0YLQvdC+0LPQviDQutC+ 0L3RgtGA0L7Qu9GPLiDQotC10YXQvdC+0LvQvtCz0LjQuA0K0YLQsNC80L7QttC10L3QvdC+LQ0K 0LHQsNC90LrQvtCy0YHQutC+0LPQviDQstCw0LvRjtGC0L3QvtCz0L4g0LrQvtC90YLRgNC+0LvR jyAo0KLQkdCS0JopLCDQstC30LDQuNC80L7QtNC10LnRgdGC0LLQuNC1INGBINC00YDRg9Cz0LjQ vNC4INC+0YDQs9Cw0L3QsNC80Lgg0LgNCtCw0LPQtdC90YLQsNC80LgNCtCy0LDQu9GO0YLQvdC+ 0LPQviDQutC+0L3RgtGA0L7Qu9GPLiDQktC+0L/RgNC+0YHRiyDQtNC10LrQu9Cw0YDQuNGA0L7Q stCw0L3QuNGPINGC0L7QstCw0YDQvtCyINC4INC40L3RhNC+0YDQvNCw0YbQuNC+0L3QvdC+0LPQ viDQvtCx0LzQtdC90LANCtC80LXQttC00YMg0KTQotChDQrQoNCkINC4INGD0L/QvtC70L3QvtC8 0L7Rh9C10L3QvdGL0LzQuCDQsdCw0L3QutCw0LzQuC4g0JLRi9GP0LLQu9C10L3QuNC1INC90LDR gNGD0YjQtdC90LjQuSDQt9Cw0LrQvtC90L7QtNCw0YLQtdC70YzRgdGC0LLQsCwNCtC/0YDQtdC0 0YPRgdC80L7RgtGA0LXQvdC90YvRhQ0K0JrQntCQ0J8g0KDQpC4g0JLQsNC70Y7RgtC90YvQuSDQ utC+0L3RgtGA0L7Qu9GMINCyINC90LXRgtC+0YDQs9C+0LLQvtC8INC+0LHQvtGA0L7RgtC1Lg0K DQoqNC7QmtC70LDRgdGB0LjRhNC40LrQsNGG0LjRjyDQuCDRgdC+0LTQtdGA0LbQsNC90LjQtSDQ v9GA0LDQstC+0L3QsNGA0YPRiNC10L3QuNC5INCy0LDQu9GO0YLQvdC+0LPQviDQt9Cw0LrQvtC9 0L7QtNCw0YLQtdC70YzRgdGC0LLQsCDRgQ0K0YPRh9C10YLQvtC8INC/0L7RgdC70LXQtNC90LjR hSDQuNC30LzQtdC90LXQvdC40Lkg0L3QvtGA0LzQsNGC0LjQstC90L7QuSDQv9GA0LDQstC+0LLQ vtC5INCx0LDQt9GLLiAqDQrQk9C+0YHRg9C00LDRgNGB0YLQstC10L3QvdGL0Lkg0YTQuNC90LDQ vdGB0L7QstGL0Lkg0LrQvtC90YLRgNC+0LvRjCDQt9CwINC+0YHRg9GJ0LXRgdGC0LLQu9C10L3Q uNC10Lwg0LLQsNC70Y7RgtC90YvRhSDQvtC/0LXRgNCw0YbQuNC5DQrRgNC10LfQuNC00LXQvdGC 0LDQvNC4INC4DQrQvdC10YDQtdC30LjQtNC10L3RgtCw0LzQuCwg0L3QtSDRj9Cy0LvRj9GO0YnQ uNC80LjRgdGPINC60YDQtdC00LjRgtC90YvQvNC4INC+0YDQs9Cw0L3QuNC30LDRhtC40Y/QvNC4 INC4INCy0LDQu9GO0YLQvdGL0LzQuCDQsdC40YDQttCw0LzQuC4NCtCY0LfQvNC10L3QtdC90LjR jyDQsg0K0KTQtdC00LXRgNCw0LvRjNC90YvQuSDQt9Cw0LrQvtC9INC+0YIgMDguMTIuMjAwMyDQ s9C+0LTQsCDihJYgMTY0LdCk0JcgItCe0LEg0L7RgdC90L7QstCw0YUg0LPQvtGB0YPQtNCw0YDR gdGC0LLQtdC90L3QvtCz0L4NCtGA0LXQs9GD0LvQuNGA0L7QstCw0L3QuNGPDQrQstC90LXRiNC9 0LXRgtC+0YDQs9C+0LLQvtC5INC00LXRj9GC0LXQu9GM0L3QvtGB0YLQuCIsINCyINCa0L7QtNC1 0LrRgSDQoNC+0YHRgdC40LnRgdC60L7QuSDQpNC10LTQtdGA0LDRhtC40Lgg0L7QsQ0K0LDQtNC8 0LjQvdC40YHRgtGA0LDRgtC40LLQvdGL0YUNCtC/0YDQsNCy0L7QvdCw0YDRg9GI0LXQvdC40Y/R hSwg0LIg0KTQtdC00LXRgNCw0LvRjNC90YvQuSDQt9Cw0LrQvtC9INC+0YIgMTAuMTIuMjAwMyDQ s9C+0LTQsCDihJYgMTczLdCk0JcgItCeDQrQstCw0LvRjtGC0L3QvtC8INGA0LXQs9GD0LvQuNGA 0L7QstCw0L3QuNC4DQrQuCDQstCw0LvRjtGC0L3QvtC8INC60L7QvdGC0YDQvtC70LUiINC4INC0 0YDRg9Cz0LjQtSDQvdC+0YDQvNCw0YLQuNCy0L3Ri9C1INC/0YDQsNCy0L7QstGL0LUg0LDQutGC 0YssINGB0LLRj9C30LDQvdC90YvQtSDRgQ0K0L/RgNC40L3Rj9GC0LjQtdC8DQrRhNC10LTQtdGA 0LDQu9GM0L3Ri9GFINC30LDQutC+0L3QvtCyLiDQktGL0Y/QstC70LXQvdC40LUg0Lgg0L/RgNC1 0YHQtdGH0LXQvdC40LUg0L3QsNGA0YPRiNC10L3QuNC5INCy0LDQu9GO0YLQvdC+0LPQvg0K0LfQ sNC60L7QvdC+0LTQsNGC0LXQu9GM0YHRgtCy0LANCtCg0L7RgdGB0LjQudGB0LrQvtC5INCk0LXQ tNC10YDQsNGG0LjQuCDQuCDQsNC60YLQvtCyINC+0YDQs9Cw0L3QvtCyINCy0LDQu9GO0YLQvdC+ 0LPQviDRgNC10LPRg9C70LjRgNC+0LLQsNC90LjRjy4NCg0KDQoqNS7Qn9C+0YDRj9C00L7QuiDQ stC30LDQuNC80L7QtNC10LnRgdGC0LLQuNGPINCg0L7RgdGE0LjQvdC90LDQtNC30L7RgNCwINGB INCR0LDQvdC60L7QvCDQoNC+0YHRgdC40LgsINGC0LDQvNC+0LbQtdC90L3Ri9C80Lgg0LgNCtC9 0LDQu9C+0LPQvtCy0YvQvNC4INC+0YDQs9Cw0L3QsNC80LgsINGD0L/QvtC70L3QvtC80L7Rh9C1 0L3QvdGL0LzQuCDQsdCw0L3QutCw0LzQuCwg0LAg0YLQsNC60LbQtSDQv9GA0L7RhNC10YHRgdC4 0L7QvdCw0LvRjNC90YvQvNC4DQrRg9GH0LDRgdGC0L3QuNC60LDQvNC4INGA0YvQvdC60LAg0YbQ tdC90L3Ri9GFINCx0YPQvNCw0LMsINC60LDQuiDQsNCz0LXQvdGC0LDQvNC4INCy0LDQu9GO0YLQ vdC+0LPQviDQutC+0L3RgtGA0L7Qu9GPLiAqDQrQn9GA0LDQstC40LvQsCDQv9GA0LXQtNGB0YLQ sNCy0LvQtdC90LjRjyDQvtGA0LPQsNC90LDQvNC4INC4INCw0LPQtdC90YLQsNC80Lgg0LLQsNC7 0Y7RgtC90L7Qs9C+INC60L7QvdGC0YDQvtC70Y8g0LINCtGD0L/QvtC70L3QvtC80L7Rh9C10L3Q vdGL0LkNCtCf0YDQsNCy0LjRgtC10LvRjNGB0YLQstC+0Lwg0KDQvtGB0YHQuNC50YHQutC+0Lkg 0KTQtdC00LXRgNCw0YbQuNC4INC+0YDQs9Cw0L0g0LLQsNC70Y7RgtC90L7Qs9C+INC60L7QvdGC 0YDQvtC70Y8gKNCg0L7RgdGE0LjQvdC90LDQtNC30L7RgCkNCtC90LXQvtCx0YXQvtC00LjQvNGL 0YUNCtC00L7QutGD0LzQtdC90YLQvtCyINC4INC40L3RhNC+0YDQvNCw0YbQuNC4LiDQntGC0LTQ tdC70YzQvdGL0LUg0LLQvtC/0YDQvtGB0Ysg0LjRgdC/0L7Qu9GM0LfRg9C10LzRi9GFINCyINGB 0YTQtdGA0LUg0LLQsNC70Y7RgtC90L7Qs9C+DQrQutC+0L3RgtGA0L7Qu9GPDQrQuNC90YTQvtGA 0LzQsNGG0LjQvtC90L3Ri9GFINGC0LXRhdC90L7Qu9C+0LPQuNC5LiDQn9C70LDQvdC40YDRg9C1 0LzRi9C1INC40LfQvNC10L3QtdC90LjRjywg0LrQsNGB0LDRjtGJ0LjQtdGB0Y8g0YPRgdGC0LDQ vdC+0LLQu9C10L3QuNGPDQrQvdC+0LLQvtCz0L4g0L/QvtGA0Y/QtNC60LANCtC/0LXRgNC10LTQ sNGH0Lgg0LTQvtC60YPQvNC10L3RgtC+0LIg0Lgg0LjQvdGE0L7RgNC80LDRhtC40Lgg0LzQtdC2 0LTRgyDQkdCw0L3QutC+0Lwg0KDQvtGB0YHQuNC4LCDRg9C/0L7Qu9C90L7QvNC+0YfQtdC90L3R i9C80LgNCtCx0LDQvdC60LDQvNC4INC4DQrQoNC+0YHRhNC40L3QvdCw0LTQt9C+0YDQvtC8OyDQ vNC10LbQtNGDINCk0KHQodCfINCg0L7RgdGB0LjQuCDQuCDQoNC+0YHRhNC40L3QvdCw0LTQt9C+ 0YDQvtC8OyDQvNC10LbQtNGDINGC0LDQvNC+0LbQtdC90L3Ri9C80Lgg0LgNCtC90LDQu9C+0LPQ vtCy0YvQvNC4DQrQvtGA0LPQsNC90LDQvNC4INC4INCg0L7RgdGE0LjQvdC90LDQtNC30L7RgNC+ 0LwuDQoNCio2LtCe0YLQstC10YLRgdGC0LLQtdC90L3QvtGB0YLRjCDQt9CwINC90LDRgNGD0YjQ tdC90LjRjyDQstCw0LvRjtGC0L3QvtCz0L4g0LfQsNC60L7QvdC+0LTQsNGC0LXQu9GM0YHRgtCy 0LAg0Lgg0LDQutGC0L7QsiDQvtGA0LPQsNC90L7Qsg0K0LLQsNC70Y7RgtC90L7Qs9C+INGA0LXQ s9GD0LvQuNGA0L7QstCw0L3QuNGPLioNCtCc0LjQvdC40LzQuNC30LDRhtC40Y8g0YDQuNGB0LrQ vtCyLCDRgdCy0Y/Qt9Cw0L3QvdGL0YUg0YEg0L/RgNC+0LLQtdC00LXQvdC40LXQvCDQstCw0LvR jtGC0L3Ri9GFINC+0L/QtdGA0LDRhtC40Lkg0L/RgNC4DQrQvtGB0YPRidC10YHRgtCy0LvQtdC9 0LjQuA0K0LLQvdC10YjQvdC10Y3QutC+0L3QvtC80LjRh9C10YHQutC+0Lkg0LTQtdGP0YLQtdC7 0YzQvdC+0YHRgtC4LiDQn9GA0LXQtNGD0L/RgNC10LbQtNC10L3QuNC1INC/0YDQsNCy0L7QvdCw 0YDRg9GI0LXQvdC40Lkg0LLQsNC70Y7RgtC90L7Qs9C+DQrQt9Cw0LrQvtC90L7QtNCw0YLQtdC7 0YzRgdGC0LLQsCDQoNC+0YHRgdC40LnRgdC60L7QuSDQpNC10LTQtdGA0LDRhtC40Lgg0Lgg0LDQ utGC0L7QsiDQvtGA0LPQsNC90L7QsiDQstCw0LvRjtGC0L3QvtCz0L4NCtGA0LXQs9GD0LvQuNGA 0L7QstCw0L3QuNGPLiDQmtC+0LzQv9C70LXQutGBINC80LXRgA0K0L/QviDRgdC+0LfQtNCw0L3Q uNGOINCy0L3Rg9GC0YDQuNGE0LjRgNC80LXQvdC90L7QuSDRgdC40YHRgtC10LzRiyDQstCw0LvR jtGC0L3QvtCz0L4g0LrQvtC90YLRgNC+0LvRjy4g0JzQtdGB0YLQvg0K0LLQvdGD0YLRgNC40YTQ uNGA0LzQtdC90L3QvtC5INGB0LjRgdGC0LXQvNGLDQrQstCw0LvRjtGC0L3QvtCz0L4g0LrQvtC9 0YLRgNC+0LvRjyDQsiDQvtGA0LPQsNC90LjQt9Cw0YbQuNC+0L3QvdC+0Lkg0YHRgtGA0YPQutGC 0YPRgNC1INC/0YDQtdC00L/RgNC40Y/RgtC40Y8gKNC+0YDQs9Cw0L3QuNC30LDRhtC40LgpLg0K 0KLRgNC10LHQvtCy0LDQvdC40Y8NCtC30LDQutC+0L3QvtC00LDRgtC10LvRjNGB0YLQstCwINC6 INGD0YHQu9C+0LLQuNGP0Lwg0LfQsNC60LvRjtGH0LDQtdC80YvRhSDQstC+INCy0L3QtdGI0L3Q tdGC0L7RgNCz0L7QstC+0Lkg0LTQtdGP0YLQtdC70YzQvdC+0YHRgtC4DQrQtNC+0LPQvtCy0L7R gNC+0LINCijQutC+0L3RgtGA0LDQutGC0L7QsikuDQoNCg0KDQrQo9GH0LDRgdGC0LjQtTogMTEg ONC+0L4g0YDRg9CxLg0K0JLRhdC+0LTQuNGCINC80LXRgtC+0LTQuNGH0LXRgdC60LjQuSDQvNCw 0YLQtdGA0LjQsNC7LCDQvtCx0LXQtNGLLCDQutC+0YTQtS3Qv9Cw0YPQt9GLLg0K0J/QviDQvtC6 0L7QvdGH0LDQvdC40Y4g0LfQsNC90Y/RgtC40Y8g0JLQsNC8INCy0YvQtNCw0LXRgtGB0Y8g0YHQ tdGA0YLQuNGE0LjQutCw0YIuDQrQmNC90L7Qs9C+0YDQvtC00L3QuNC8INGD0YfQsNGB0YLQvdC4 0LrQsNC8INC/0L7QvNC+0LPQsNC10Lwg0LIg0LHRgNC+0L3QuNGA0L7QstCw0L3QuNC4INCz0L7R gdGC0LjQvdC40YbRiy4NCg== ------------11D073358F5B8564 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: base64 PGRpdiBkaXI9Imx0ciI+PGRpdiBhbGlnbj0iY2VudGVyIj48dGFibGUgYmdjb2xvcj0iI2Y3ZjRm NCIgYm9yZGVyPSIwIiBjZWxsc3BhY2luZz0iMCI+PHRib2R5Pjx0cj48dGQgd2lkdGg9IjQiIGJn Y29sb3I9IiM4NjYyNjIiPsKgPC90ZD48dGQgYmdjb2xvcj0iI2E0ODI4MiI+wqA8L3RkPjx0ZCBi Z2NvbG9yPSIjYzJhYmFiIj7CoDwvdGQ+PHRkIHdpZHRoPSI0IiBiZ2NvbG9yPSIjODY2MjYyIj7C oDwvdGQ+PHRkIGJnY29sb3I9IiM4NjYyNjIiPsKgPC90ZD48dGQgYmdjb2xvcj0iI2Q4YzljOSI+ wqA8L3RkPjx0ZCBiZ2NvbG9yPSIjYzJhYmFiIj7CoDwvdGQ+PHRkIGJnY29sb3I9IiNhNDgyODIi PsKgPC90ZD48dGQgYmdjb2xvcj0iIzg2NjI2MiI+wqA8L3RkPjwvdHI+PHRyPjx0ZCB3aWR0aD0i NCIgYmdjb2xvcj0iIzg2NjI2MiI+wqA8L3RkPjx0ZCBiZ2NvbG9yPSIjYTQ4MjgyIj7CoDwvdGQ+ PHRkIGJnY29sb3I9IiNjMmFiYWIiPsKgPC90ZD48dGQgd2lkdGg9IjQiPsKgPC90ZD48dGQ+PHAg YWxpZ249ImxlZnQiPjxmb250IHNpemU9IjQiPjxicj48Zm9udCBjb2xvcj0iIzAwMDBmZiI+NCDQ tNC10LrQsNCx0YDRjyB8INCzLiDQnNC+0YHQutCy0LAgfMKgYyAxMDxzcGFuIGxhbmc9ImVuLXVz Ij46PC9zcGFuPjAwINC00L4gMTc8c3BhbiBsYW5nPSJlbi11cyI+Ojwvc3Bhbj4zMDwvZm9udD48 L2ZvbnQ+PGZvbnQgY29sb3I9IiMwMDAwZmYiPjxicj48L2ZvbnQ+PGI+PGJyPjxmb250IGNvbG9y PSIjY2MwMDAwIj7QntCx0YPRh9C10L11ZSDQtNC70Y86PC9mb250PiA8L2I+0YHQvtCx0YHRgtCy 0LXQvdC90LjQutC+0LIgCQkJ0LHQuNC30L3QtdGB0LAsINGE0LjQvdCw0L3RgdC+0LLRi9GFINC4 INC60L7QvNC80LXRgNGH0LXRgdC60LjRhSDQtNC40YDQtdC60YLQvtGA0L7Qsiwg0YDRg9C60L7Q stC+0LTQuNGC0LXQu9C10Lk8YnI+CQkJ0YTQuNC90LDQvdGB0L7QstC+LdGN0LrQvtC90L7QvNC4 0YfQtdGB0LrQuNGFINGB0LvRg9C20LEg0L/RgNC10LTQv9GA0LjRj9GC0LjQuSDQuCDQvtGA0LPQ sNC90LjQt9Cw0YbQuNC5LCDRg9GH0LDRgdGC0L3QuNC60L7QsiAJCQnQstC90LXRiNC90LXRjdC6 0L7QvdC+0LzQuNGH0LXRgdC60L7QuTxicj4JCQnQtNC10Y/RgtC10LvRjNC90L7RgdGC0LgsINCx 0LDQvdC60L7QstGB0LrQuNGFINGA0LDQsdC+0YLQvdC40LrQvtCyLjxicj4gwqA8L3A+PC90ZD48 dGQgYmdjb2xvcj0iI2Q4YzljOSI+wqA8L3RkPjx0ZCBiZ2NvbG9yPSIjYzJhYmFiIj7CoDwvdGQ+ PHRkIGJnY29sb3I9IiNhNDgyODIiPsKgPC90ZD48dGQgYmdjb2xvcj0iIzg2NjI2MiI+wqA8L3Rk PjwvdHI+PHRyPjx0ZCB3aWR0aD0iNCIgYmdjb2xvcj0iIzg2NjI2MiI+wqA8L3RkPjx0ZCBiZ2Nv bG9yPSIjYTQ4MjgyIj7CoDwvdGQ+PHRkIGJnY29sb3I9IiNjMmFiYWIiPsKgPC90ZD48dGQgd2lk dGg9IjQiPsKgPC90ZD48dGQgYmdjb2xvcj0iIzY3NGI0YiI+PHAgYWxpZ249ImNlbnRlciI+PGJy PjxiPjxmb250IGNvbG9yPSIjZmZmZjAwIiBzaXplPSI0Ij7QktCQ0JvQrtCi0J3QntCVINCg0JXQ k9Cj0JvQmNCg0J7QktCQ0J3QmNCVINCYINCS0JDQm9Cu0KLQndCr0JkgCQkJ0JrQntCd0KLQoNCe 0JvQrCDQkjxicj48YnI+CQkJ0KDQpCDQoSDQo9Cn0JXQotCe0Jwg0J/QntCh0JvQldCU0J3QmNCl INCY0JfQnNCV0J3QldCd0JjQmSDQl9CQ0JrQntCd0J7QlNCQ0KLQldCb0KzQodCi0JLQkDxicj7C oDwvZm9udD48L2I+PC9wPjwvdGQ+PHRkIGJnY29sb3I9IiNkOGM5YzkiPsKgPC90ZD48dGQgYmdj b2xvcj0iI2MyYWJhYiI+wqA8L3RkPjx0ZCBiZ2NvbG9yPSIjYTQ4MjgyIj7CoDwvdGQ+PHRkIGJn Y29sb3I9IiM4NjYyNjIiPsKgPC90ZD48L3RyPjx0cj48dGQgd2lkdGg9IjQiIGJnY29sb3I9IiM4 NjYyNjIiPsKgPC90ZD48dGQgYmdjb2xvcj0iI2E0ODI4MiI+wqA8L3RkPjx0ZCBiZ2NvbG9yPSIj YzJhYmFiIj7CoDwvdGQ+PHRkIHdpZHRoPSI0Ij7CoDwvdGQ+PHRkPjxicj48Yj7QkNGA0YLQuNC6 0YPQuzo8L2I+IDI1Njxicj48YnI+PGI+0JzQtdGB0YLQviDQv9GA0L7QstC10LTQtdC90LjRjzo8 L2I+INGD0LsuINCR0LDRg9C80LDQvdGB0LrQsNGPLCDQtC42LCDRgdGC0YAuMiwg0JEu0KYuCQkJ IDxzcGFuIGxhbmc9ImVuLXVzIj4mcXVvdDs8L3NwYW4+0JLQuNC60YLQvtGA0LjRjyDQn9C70LDQ t9CwPHNwYW4gbGFuZz0iZW4tdXMiPiZxdW90Ozwvc3Bhbj4uPGJyPjxicj48Yj7QktGB0Y8g0L/Q vtC00YDQvtCx0L3QsNGPINC40L3RhNC+0YDQvNCw0YbQuNGPINC4INGA0LXQs9C40YHRgtGA0LDR htC40Y8g0L/QviDRgtC10LvQtdGE0L7QvdGDOjwvYj4gPGZvbnQgc2l6ZT0iNCIgZmFjZT0idHJl YnVjaGV0IG1zLCBzYW5zLXNlcmlmIj44PC9mb250PsKgCQkJIDxmb250IHNpemU9IjIiPtC60L7Q tCDQs9C+0YDQvtC00LA8L2ZvbnQ+wqAgPGZvbnQgc2l6ZT0iNCIgZmFjZT0idHJlYnVjaGV0IG1z LCBzYW5zLXNlcmlmIj4oIDQgOSA1ICk8L2ZvbnQ+wqAJCQkgPGZvbnQgc2l6ZT0iMiI+0L3QvtC8 0LXRgDwvZm9udD7CoDxmb250IHNpemU9IjQiIGZhY2U9InRyZWJ1Y2hldCBtcywgc2Fucy1zZXJp ZiI+IDk2MSAtINCe0J4gLSDQlzg8L2ZvbnQ+PGJyPiDCoDwvdGQ+PHRkIGJnY29sb3I9IiNkOGM5 YzkiPsKgPC90ZD48dGQgYmdjb2xvcj0iI2MyYWJhYiI+wqA8L3RkPjx0ZCBiZ2NvbG9yPSIjYTQ4 MjgyIj7CoDwvdGQ+PHRkIGJnY29sb3I9IiM4NjYyNjIiPsKgPC90ZD48L3RyPjx0cj48dGQgd2lk dGg9IjQiIGJnY29sb3I9IiM4NjYyNjIiPsKgPC90ZD48dGQgYmdjb2xvcj0iI2E0ODI4MiI+wqA8 L3RkPjx0ZCBiZ2NvbG9yPSIjYzJhYmFiIj7CoDwvdGQ+PHRkIHdpZHRoPSI0Ij7CoDwvdGQ+PHRk PjxwIGFsaWduPSJjZW50ZXIiPjwvcD48ZGl2IHN0eWxlPSJ0ZXh0LWFsaWduOmxlZnQiPjxmb250 IGNvbG9yPSIjMDAwMGNjIiBzdHlsZT0iYmFja2dyb3VuZC1jb2xvcjpyZ2IoMjU1LDI1NSwyNTUp Ij48Yj7QptC10LvRjCDQtNCw0L3QvdC+0LPQviDQt9Cw0L3Rj9GC0LjRjzo8L2I+CQkJIDwvZm9u dD48c3BhbiBzdHlsZT0iYmFja2dyb3VuZC1jb2xvcjpyZ2IoMjU1LDI1NSwyNTUpIj7QvtCx0YHR g9C00LjRgtGMINCw0LrRgtGD0LDQu9GM0L3Ri9C1INCy0L7Qv9GA0L7RgdGLLCDQuNC80LXRjtGJ 0LjQtSDQv9GA0LDQutGC0LjRh9C10YHQutGD0Y4gCQkJ0L3QsNC/0YDQsNCy0LvQtdC90L3QvtGB 0YLRjDwvc3Bhbj48L2Rpdj48ZGl2IHN0eWxlPSJ0ZXh0LWFsaWduOmxlZnQiPjxzcGFuIHN0eWxl PSJiYWNrZ3JvdW5kLWNvbG9yOnJnYigyNTUsMjU1LDI1NSkiPtC4INGB0LLRj9C30LDQvdC90YvQ tSDRgSDQuNC30LzQtdC90LXQvdC40LXQvCDQstCw0LvRjtGC0L3QvtCz0L4g0LfQsNC60L7QvdC+ 0LTQsNGC0LXQu9GM0YHRgtCy0LAg0LIg0KDQpCwg0L/QvtC70YPRh9C40YLRjCAJCQnQt9C90LDQ vdC40Y8sINC60L7RgtC+0YDRi9C1PC9zcGFuPjwvZGl2PjxkaXYgc3R5bGU9InRleHQtYWxpZ246 bGVmdCI+PHNwYW4gc3R5bGU9ImJhY2tncm91bmQtY29sb3I6cmdiKDI1NSwyNTUsMjU1KSI+0L/Q vtC30LLQvtC70Y/RgiDQuNC30LHQtdC20LDRgtGMINGC0LjQv9C40YfQvdGL0YUg0L7RiNC40LHQ vtC6INC4INC90LDRgNGD0YjQtdC90LjQuSDQv9GA0Lgg0YHQvtCy0LXRgNGI0LXQvdC40Lgg0Lgg CQkJ0L7RhNC+0YDQvNC70LXQvdC40Lg8L3NwYW4+PC9kaXY+PGRpdiBzdHlsZT0idGV4dC1hbGln bjpsZWZ0Ij48c3BhbiBzdHlsZT0iYmFja2dyb3VuZC1jb2xvcjpyZ2IoMjU1LDI1NSwyNTUpIj7Q stCw0LvRjtGC0L3Ri9GFINC+0L/QtdGA0LDRhtC40LkuPC9zcGFuPjwvZGl2PjxwPjwvcD48L3Rk Pjx0ZCBiZ2NvbG9yPSIjZDhjOWM5Ij7CoDwvdGQ+PHRkIGJnY29sb3I9IiNjMmFiYWIiPsKgPC90 ZD48dGQgYmdjb2xvcj0iI2E0ODI4MiI+wqA8L3RkPjx0ZCBiZ2NvbG9yPSIjODY2MjYyIj7CoDwv dGQ+PC90cj48dHI+PHRkIHdpZHRoPSI0IiBiZ2NvbG9yPSIjODY2MjYyIj7CoDwvdGQ+PHRkIGJn Y29sb3I9IiNhNDgyODIiPsKgPC90ZD48dGQgYmdjb2xvcj0iI2MyYWJhYiI+wqA8L3RkPjx0ZCB3 aWR0aD0iNCI+wqA8L3RkPjx0ZD7CoDwvdGQ+PHRkIGJnY29sb3I9IiNkOGM5YzkiPsKgPC90ZD48 dGQgYmdjb2xvcj0iI2MyYWJhYiI+wqA8L3RkPjx0ZCBiZ2NvbG9yPSIjYTQ4MjgyIj7CoDwvdGQ+ PHRkIGJnY29sb3I9IiM4NjYyNjIiPsKgPC90ZD48L3RyPjx0cj48dGQgd2lkdGg9IjQiIGJnY29s b3I9IiM4NjYyNjIiPsKgPC90ZD48dGQgYmdjb2xvcj0iI2E0ODI4MiI+wqA8L3RkPjx0ZCBiZ2Nv bG9yPSIjYzJhYmFiIj7CoDwvdGQ+PHRkIHdpZHRoPSI0Ij7CoDwvdGQ+PHRkIGJnY29sb3I9IiNk OGM5YzkiPjxwIGFsaWduPSJjZW50ZXIiPjxmb250IGNvbG9yPSIjMDAwMGNjIiBzaXplPSI0Ij7Q odC+0LTQtdGA0LbQsNC90LjQtSDQv9GA0L7Qs9GA0LDQvNC80Ys6PC9mb250PjwvcD48L3RkPjx0 ZCBiZ2NvbG9yPSIjZDhjOWM5Ij7CoDwvdGQ+PHRkIGJnY29sb3I9IiNjMmFiYWIiPsKgPC90ZD48 dGQgYmdjb2xvcj0iI2E0ODI4MiI+wqA8L3RkPjx0ZCBiZ2NvbG9yPSIjODY2MjYyIj7CoDwvdGQ+ PC90cj48dHI+PHRkIHdpZHRoPSI0IiBiZ2NvbG9yPSIjODY2MjYyIj7CoDwvdGQ+PHRkIGJnY29s b3I9IiNhNDgyODIiPsKgPC90ZD48dGQgYmdjb2xvcj0iI2MyYWJhYiI+wqA8L3RkPjx0ZCB3aWR0 aD0iNCI+wqA8L3RkPjx0ZD7CoDwvdGQ+PHRkIGJnY29sb3I9IiNkOGM5YzkiPsKgPC90ZD48dGQg Ymdjb2xvcj0iI2MyYWJhYiI+wqA8L3RkPjx0ZCBiZ2NvbG9yPSIjYTQ4MjgyIj7CoDwvdGQ+PHRk IGJnY29sb3I9IiM4NjYyNjIiPsKgPC90ZD48L3RyPjx0cj48dGQgd2lkdGg9IjQiIGJnY29sb3I9 IiM4NjYyNjIiPsKgPC90ZD48dGQgYmdjb2xvcj0iI2E0ODI4MiI+wqA8L3RkPjx0ZCBiZ2NvbG9y PSIjYzJhYmFiIj7CoDwvdGQ+PHRkIHdpZHRoPSI0Ij7CoDwvdGQ+PHRkPjxiPjxmb250IGNvbG9y PSIjMDAwMGNjIiBzaXplPSI1Ij4xLjwvZm9udD7QndC+0LLQvtC1INCyINGB0LjRgdGC0LXQvNC1 IAkJCdCy0LDQu9GO0YLQvdC+0LPQviDRgNC10LPRg9C70LjRgNC+0LLQsNC90LjRjyDQsiDQoNCk LjwvYj48YnI+0J3QvtGA0LzQsNGC0LjQstC90L4t0L/RgNCw0LLQvtCy0LDRjyDQsdCw0LfQsCDQ stCw0LvRjtGC0L3QvtCz0L4g0YDQtdCz0YPQu9C40YDQvtCy0LDQvdC40Y8g0LIg0KDQvtGB0YHQ uNC50YHQutC+0LkgCQkJ0KTQtdC00LXRgNCw0YbQuNC4LiDQn9C+0YHQu9C10LTQvdC40LU8YnI+ CQkJ0LjQt9C80LXQvdC10L3QuNGPINCy0LDQu9GO0YLQvdC+0LPQviDQt9Cw0LrQvtC90L7QtNCw 0YLQtdC70YzRgdGC0LLQsCDQoNCkLiDQn9C+0YDRj9C00L7QuiDQvtGC0LrRgNGL0YLQuNGPINC4 INCy0LXQtNC10L3QuNGPIAkJCdGB0YfQtdGC0L7QsiDRgNC10LfQuNC00LXQvdGC0L7QsiDQt9Cw PGJyPgkJCdC/0YDQtdC00LXQu9Cw0LzQuCDRgtC10YDRgNC40YLQvtGA0LjQuCDQoNCkLiDQn9GA 0LDQstC40LvQsCDQvtGB0YPRidC10YHRgtCy0LvQtdC90LjRjyDRgNC10LfQuNC00LXQvdGC0LDQ vNC4INCy0LDQu9GO0YLQvdGL0YUgCQkJ0L7Qv9C10YDQsNGG0LjQuSDQt9CwINGB0YfQtdGCPGJy PgkJCdGB0YDQtdC00YHRgtCyLCDQvdCw0YXQvtC00Y/RidC40YXRgdGPINC90LAg0YHRh9C10YLQ sNGFINC30LAg0YDRg9Cx0LXQttC+0LwuINCf0L7RgNGP0LTQvtC6INC/0LXRgNC10LTQsNGH0Lgg CQkJ0YPQv9C+0LvQvdC+0LzQvtGH0LXQvdC90YvQvNC4INCx0LDQvdC60LDQvNC4PGJyPgkJCdC4 0L3RhNC+0YDQvNCw0YbQuNC4INC+INC90LDRgNGD0YjQtdC90LjRj9GFINC40YUg0LrQu9C40LXQ vdGC0LDQvNC4INCy0LDQu9GO0YLQvdC+0LPQviDQt9Cw0LrQvtC90L7QtNCw0YLQtdC70YzRgdGC 0LLQsCDQoNCkLiAJCQkg0JTQtdC50YHRgtCy0LjQtTxicj4JCQnRhNC10LTQtdGA0LDQu9GM0L3Q vtCz0L4g0LfQsNC60L7QvdCwIDxzcGFuIGxhbmc9ImVuLXVzIj4mcXVvdDs8L3NwYW4+0J4g0LLQ sNC70Y7RgtC90L7QvCAJCQnRgNC10LPRg9C70LjRgNC+0LLQsNC90LjQuCDQuCDQstCw0LvRjtGC 0L3QvtC8INC60L7QvdGC0YDQvtC70LU8c3BhbiBsYW5nPSJlbi11cyI+JnF1b3Q7PC9zcGFuPiAx NzMt0KTQlyAJCQkgKNGBINC40LfQvNC10L3QtdC90LjRj9C80LgsPGJyPtCy0YHRgtGD0L/QuNCy 0YjQuNC80Lgg0LIg0YHQuNC70YMg0LIgMjAxMyDQs9C+0LTRgyDQuCDQstGB0YLRg9C/0LDRjtGJ 0LjQvNC4INCyINGB0LjQu9GDINCyIDIwMTQg0LMpLiAJCQkg0J/RgNC+0LXQutGC0Ysg0LHRg9C0 0YPRidC40YUg0LjQt9C80LXQvdC10L3QuNC5PGJyPgkJCdCk0LXQtNC10YDQsNC70YzQvdC+0LPQ viDQt9Cw0LrQvtC90LAgPHNwYW4gbGFuZz0iZW4tdXMiPiZxdW90Ozwvc3Bhbj7QniDQstCw0LvR jtGC0L3QvtC8IAkJCdGA0LXQs9GD0LvQuNGA0L7QstCw0L3QuNC4INC4INCy0LDQu9GO0YLQvdC+ 0Lwg0LrQvtC90YLRgNC+0LvQtTxzcGFuIGxhbmc9ImVuLXVzIj4mcXVvdDs8L3NwYW4+LiA8YnI+ 0JTQtdC50YHRgtCy0LjQtSDQstCw0LvRjtGC0L3QvtCz0L4g0LfQsNC60L7QvdC+0LTQsNGC0LXQ u9GM0YHRgtCy0LAg0LIg0YHQstGP0LfQuCDRgSDQv9GA0LjQvdGP0YLQuNC10Lwg0KTQtdC00LXR gNCw0LvRjNC90L7Qs9C+IAkJCdC30LDQutC+0L3QsCDQvtGCIDI3INC40Y7QvdGPPGJyPjIwMTEg 0LPQvtC00LAgMTYxLdCk0JcgPHNwYW4gbGFuZz0iZW4tdXMiPiZxdW90Ozwvc3Bhbj7QniDQvdCw 0YbQuNC+0L3QsNC70YzQvdC+0Lkg0L/Qu9Cw0YLQtdC20L3QvtC5IAkJCdGB0LjRgdGC0LXQvNC1 PHNwYW4gbGFuZz0iZW4tdXMiPiZxdW90Ozwvc3Bhbj4uINCe0YHQvtCx0LXQvdC90L7RgdGC0Lgg 0L/RgNC+0LLQtdC00LXQvdC40Y8g0LLQsNC70Y7RgtC90YvRhTxicj4JCQnQvtC/0LXRgNCw0YbQ uNC5INGA0LXQt9C40LTQtdC90YLQsNC80Lgg0Lgg0L3QtdGA0LXQt9C40LTQtdC90YLQsNC80Lgu IDxicj48Yj48Zm9udCBjb2xvcj0iIzAwMDBjYyIgc2l6ZT0iNSI+Mi48L2ZvbnQ+0JLQsNC70Y7R gtC90YvQuSDQutC+0L3RgtGA0L7Qu9GMINC/0YDQuCAJCQnQvtGB0YPRidC10YHRgtCy0LvQtdC9 0LjQuCDQstCw0LvRjtGC0L3Ri9GFINC+0L/QtdGA0LDRhtC40LksINGB0LLRj9C30LDQvdC90YvR hSDRgTxicj4JCQnQstC90LXRiNC90LXRgtC+0YDQs9C+0LLQvtC5INC00LXRj9GC0LXQu9GM0L3Q vtGB0YLRjNGOLCDQv9C+0LvRg9GH0LXQvdC40LXQvCDQuCDQv9GA0LXQtNC+0YHRgtCw0LLQu9C1 0L3QuNC10Lwg0LrRgNC10LTQuNGC0L7QsiAJCQnQuCDQt9Cw0LnQvNC+0LIuPC9iPjxicj7Qn9Cw 0YHQv9C+0YDRgiDRgdC00LXQu9C60Lg6INCe0YTQvtGA0LzQu9C10L3QuNC1INC4INCy0LXQtNC1 0L3QuNC1INC/0LDRgdC/0L7RgNGC0LAg0YHQtNC10LvQutC4INCyINGG0LXQu9GP0YUgCQkJ0L7Q sdC10YHQv9C10YfQtdC90LjRjyDRg9GH0LXRgtCwINC4INC+0YLRh9C10YLQvdC+0YHRgtC4PGJy PgkJCdC4INC+0YHRg9GJ0LXRgdGC0LLQu9C10L3QuNGPINCy0LDQu9GO0YLQvdC+0LPQviDQutC+ 0L3RgtGA0L7Qu9GPINC/0L4g0LLQsNC70Y7RgtC90YvQvCDQvtC/0LXRgNCw0YbQuNGP0Lwg0LzQ tdC20LTRgyAJCQnRgNC10LfQuNC00LXQvdGC0LDQvNC4INC4PGJyPgkJCdC90LXRgNC10LfQuNC0 0LXQvdGC0LDQvNC4LiDQn9GA0LXQtNGB0YLQsNCy0LvQtdC90LjQtSDRgNC10LfQuNC00LXQvdGC 0LDQvNC4INCyINGD0L/QvtC70L3QvtC80L7Rh9C10L3QvdGL0Lkg0LHQsNC90LogCQkJ0YHQv9GA 0LDQstC60Lgg0L4g0LLQsNC70Y7RgtC90YvRhTxicj4JCQnQvtC/0LXRgNCw0YbQuNGP0YUg0Lgg 0YHQv9GA0LDQstC60Lgg0L4g0L/QvtC00YLQstC10YDQttC00LDRjtGJ0LjRhSDQtNC+0LrRg9C8 0LXQvdGC0LDRhSDQv9GA0Lgg0L7RgdGD0YnQtdGB0YLQstC70LXQvdC40LggCQkJ0LLQvdC10YjQ vdC10YLQvtGA0LPQvtCy0L7QuTxicj4JCQnQtNC10Y/RgtC10LvRjNC90L7RgdGC0LguPGJyPjxi Pjxmb250IGNvbG9yPSIjMDAwMGNjIiBzaXplPSI1Ij4zLjwvZm9udD7QmNC30LzQtdC90LXQvdC4 0Y8g0L/RgNCw0LLQuNC7IAkJCdCy0LDQu9GO0YLQvdC+0LPQviDQutC+0L3RgtGA0L7Qu9GPLCDQ vtGB0YPRidC10YHRgtCy0LvRj9C10LzQvtCz0L4g0YEg0YPRh9Cw0YHRgtC40LXQvCDRgtCw0LzQ vtC20LXQvdC90YvRhTxicj4JCQnQvtGA0LPQsNC90L7Qsi48L2I+PGJyPtCe0LHQt9C+0YAg0LjQ t9C80LXQvdC10L3QuNC5INC90L7RgNC80LDRgtC40LLQvdC+LdC/0YDQsNCy0L7QstC+0Lkg0LHQ sNC30Ysg0LLQsNC70Y7RgtC90L7Qs9C+INC60L7QvdGC0YDQvtC70Y8uIAkJCSDQotC10YXQvdC+ 0LvQvtCz0LjQuCDRgtCw0LzQvtC20LXQvdC90L4tPGJyPtCx0LDQvdC60L7QstGB0LrQvtCz0L4g 0LLQsNC70Y7RgtC90L7Qs9C+INC60L7QvdGC0YDQvtC70Y8gKNCi0JHQktCaKSwg0LLQt9Cw0LjQ vNC+0LTQtdC50YHRgtCy0LjQtSDRgSDQtNGA0YPQs9C40LzQuCAJCQnQvtGA0LPQsNC90LDQvNC4 INC4INCw0LPQtdC90YLQsNC80Lg8YnI+CQkJ0LLQsNC70Y7RgtC90L7Qs9C+INC60L7QvdGC0YDQ vtC70Y8uINCS0L7Qv9GA0L7RgdGLINC00LXQutC70LDRgNC40YDQvtCy0LDQvdC40Y8g0YLQvtCy 0LDRgNC+0LIg0Lgg0LjQvdGE0L7RgNC80LDRhtC40L7QvdC90L7Qs9C+IAkJCdC+0LHQvNC10L3Q sCDQvNC10LbQtNGDINCk0KLQoTxicj4JCQnQoNCkINC4INGD0L/QvtC70L3QvtC80L7Rh9C10L3Q vdGL0LzQuCDQsdCw0L3QutCw0LzQuC4g0JLRi9GP0LLQu9C10L3QuNC1INC90LDRgNGD0YjQtdC9 0LjQuSDQt9Cw0LrQvtC90L7QtNCw0YLQtdC70YzRgdGC0LLQsCwgCQkJINC/0YDQtdC00YPRgdC8 0L7RgtGA0LXQvdC90YvRhTxicj4JCQnQmtCe0JDQnyDQoNCkLiDQktCw0LvRjtGC0L3Ri9C5INC6 0L7QvdGC0YDQvtC70Ywg0LIg0L3QtdGC0L7RgNCz0L7QstC+0Lwg0L7QsdC+0YDQvtGC0LUuIDxi cj48Yj48Zm9udCBjb2xvcj0iIzAwMDBjYyIgc2l6ZT0iNSI+NC48L2ZvbnQ+0JrQu9Cw0YHRgdC4 0YTQuNC60LDRhtC40Y8g0LggCQkJ0YHQvtC00LXRgNC20LDQvdC40LUg0L/RgNCw0LLQvtC90LDR gNGD0YjQtdC90LjQuSDQstCw0LvRjtGC0L3QvtCz0L4g0LfQsNC60L7QvdC+0LTQsNGC0LXQu9GM 0YHRgtCy0LAg0YEg0YPRh9C10YLQvtC8PGJyPgkJCdC/0L7RgdC70LXQtNC90LjRhSDQuNC30LzQ tdC90LXQvdC40Lkg0L3QvtGA0LzQsNGC0LjQstC90L7QuSDQv9GA0LDQstC+0LLQvtC5INCx0LDQ t9GLLiA8L2I+PGJyPtCT0L7RgdGD0LTQsNGA0YHRgtCy0LXQvdC90YvQuSDRhNC40L3QsNC90YHQ vtCy0YvQuSDQutC+0L3RgtGA0L7Qu9GMINC30LAg0L7RgdGD0YnQtdGB0YLQstC70LXQvdC40LXQ vCDQstCw0LvRjtGC0L3Ri9GFIAkJCdC+0L/QtdGA0LDRhtC40Lkg0YDQtdC30LjQtNC10L3RgtCw 0LzQuCDQuDxicj4JCQnQvdC10YDQtdC30LjQtNC10L3RgtCw0LzQuCwg0L3QtSDRj9Cy0LvRj9GO 0YnQuNC80LjRgdGPINC60YDQtdC00LjRgtC90YvQvNC4INC+0YDQs9Cw0L3QuNC30LDRhtC40Y/Q vNC4INC4INCy0LDQu9GO0YLQvdGL0LzQuCAJCQnQsdC40YDQttCw0LzQuC4g0JjQt9C80LXQvdC1 0L3QuNGPINCyPGJyPgkJCdCk0LXQtNC10YDQsNC70YzQvdGL0Lkg0LfQsNC60L7QvSDQvtGCIDA4 LjEyLjIwMDMg0LPQvtC00LAg4oSWIDE2NC3QpNCXICZxdW90O9Ce0LEg0L7RgdC90L7QstCw0YUg CQkJ0LPQvtGB0YPQtNCw0YDRgdGC0LLQtdC90L3QvtCz0L4g0YDQtdCz0YPQu9C40YDQvtCy0LDQ vdC40Y88YnI+CQkJ0LLQvdC10YjQvdC10YLQvtGA0LPQvtCy0L7QuSDQtNC10Y/RgtC10LvRjNC9 0L7RgdGC0LgmcXVvdDssINCyINCa0L7QtNC10LrRgSDQoNC+0YHRgdC40LnRgdC60L7QuSDQpNC1 0LTQtdGA0LDRhtC40Lgg0L7QsSAJCQnQsNC00LzQuNC90LjRgdGC0YDQsNGC0LjQstC90YvRhTxi cj4JCQnQv9GA0LDQstC+0L3QsNGA0YPRiNC10L3QuNGP0YUsINCyINCk0LXQtNC10YDQsNC70YzQ vdGL0Lkg0LfQsNC60L7QvSDQvtGCIDEwLjEyLjIwMDMg0LPQvtC00LAg4oSWIDE3My3QpNCXICZx dW90O9CeIAkJCdCy0LDQu9GO0YLQvdC+0Lwg0YDQtdCz0YPQu9C40YDQvtCy0LDQvdC40Lg8YnI+ CQkJ0Lgg0LLQsNC70Y7RgtC90L7QvCDQutC+0L3RgtGA0L7Qu9C1JnF1b3Q7INC4INC00YDRg9Cz 0LjQtSDQvdC+0YDQvNCw0YLQuNCy0L3Ri9C1INC/0YDQsNCy0L7QstGL0LUg0LDQutGC0YssINGB 0LLRj9C30LDQvdC90YvQtSDRgSAJCQnQv9GA0LjQvdGP0YLQuNC10Lw8YnI+CQkJ0YTQtdC00LXR gNCw0LvRjNC90YvRhSDQt9Cw0LrQvtC90L7Qsi4g0JLRi9GP0LLQu9C10L3QuNC1INC4INC/0YDQ tdGB0LXRh9C10L3QuNC1INC90LDRgNGD0YjQtdC90LjQuSDQstCw0LvRjtGC0L3QvtCz0L4gCQkJ 0LfQsNC60L7QvdC+0LTQsNGC0LXQu9GM0YHRgtCy0LA8YnI+CQkJ0KDQvtGB0YHQuNC50YHQutC+ 0Lkg0KTQtdC00LXRgNCw0YbQuNC4INC4INCw0LrRgtC+0LIg0L7RgNCz0LDQvdC+0LIg0LLQsNC7 0Y7RgtC90L7Qs9C+INGA0LXQs9GD0LvQuNGA0L7QstCw0L3QuNGPLiA8YnI+PGI+PGZvbnQgY29s b3I9IiMwMDAwY2MiIHNpemU9IjUiPjUuPC9mb250PtCf0L7RgNGP0LTQvtC6INCy0LfQsNC40LzQ vtC00LXQudGB0YLQstC40Y8gCQkJ0KDQvtGB0YTQuNC90L3QsNC00LfQvtGA0LAg0YEg0JHQsNC9 0LrQvtC8INCg0L7RgdGB0LjQuCwg0YLQsNC80L7QttC10L3QvdGL0LzQuCDQuCDQvdCw0LvQvtCz 0L7QstGL0LzQuDxicj4JCQnQvtGA0LPQsNC90LDQvNC4LCDRg9C/0L7Qu9C90L7QvNC+0YfQtdC9 0L3Ri9C80Lgg0LHQsNC90LrQsNC80LgsINCwINGC0LDQutC20LUg0L/RgNC+0YTQtdGB0YHQuNC+ 0L3QsNC70YzQvdGL0LzQuCAJCQnRg9GH0LDRgdGC0L3QuNC60LDQvNC4INGA0YvQvdC60LA8YnI+ CQkJ0YbQtdC90L3Ri9GFINCx0YPQvNCw0LMsINC60LDQuiDQsNCz0LXQvdGC0LDQvNC4INCy0LDQ u9GO0YLQvdC+0LPQviDQutC+0L3RgtGA0L7Qu9GPLiA8L2I+PGJyPtCf0YDQsNCy0LjQu9CwINC/ 0YDQtdC00YHRgtCw0LLQu9C10L3QuNGPINC+0YDQs9Cw0L3QsNC80Lgg0Lgg0LDQs9C10L3RgtCw 0LzQuCDQstCw0LvRjtGC0L3QvtCz0L4g0LrQvtC90YLRgNC+0LvRjyDQsiAJCQnRg9C/0L7Qu9C9 0L7QvNC+0YfQtdC90L3Ri9C5PGJyPgkJCdCf0YDQsNCy0LjRgtC10LvRjNGB0YLQstC+0Lwg0KDQ vtGB0YHQuNC50YHQutC+0Lkg0KTQtdC00LXRgNCw0YbQuNC4INC+0YDQs9Cw0L0g0LLQsNC70Y7R gtC90L7Qs9C+INC60L7QvdGC0YDQvtC70Y8gKNCg0L7RgdGE0LjQvdC90LDQtNC30L7RgCkgCQkJ INC90LXQvtCx0YXQvtC00LjQvNGL0YU8YnI+CQkJ0LTQvtC60YPQvNC10L3RgtC+0LIg0Lgg0LjQ vdGE0L7RgNC80LDRhtC40LguINCe0YLQtNC10LvRjNC90YvQtSDQstC+0L/RgNC+0YHRiyDQuNGB 0L/QvtC70YzQt9GD0LXQvNGL0YUg0LIg0YHRhNC10YDQtSAJCQnQstCw0LvRjtGC0L3QvtCz0L4g 0LrQvtC90YLRgNC+0LvRjzxicj4JCQnQuNC90YTQvtGA0LzQsNGG0LjQvtC90L3Ri9GFINGC0LXR hdC90L7Qu9C+0LPQuNC5LiDQn9C70LDQvdC40YDRg9C10LzRi9C1INC40LfQvNC10L3QtdC90LjR jywg0LrQsNGB0LDRjtGJ0LjQtdGB0Y8gCQkJ0YPRgdGC0LDQvdC+0LLQu9C10L3QuNGPINC90L7Q stC+0LPQviDQv9C+0YDRj9C00LrQsDxicj4JCQnQv9C10YDQtdC00LDRh9C4INC00L7QutGD0LzQ tdC90YLQvtCyINC4INC40L3RhNC+0YDQvNCw0YbQuNC4INC80LXQttC00YMg0JHQsNC90LrQvtC8 INCg0L7RgdGB0LjQuCwgCQkJINGD0L/QvtC70L3QvtC80L7Rh9C10L3QvdGL0LzQuCDQsdCw0L3Q utCw0LzQuCDQuDxicj4JCQnQoNC+0YHRhNC40L3QvdCw0LTQt9C+0YDQvtC8OyDQvNC10LbQtNGD INCk0KHQodCfINCg0L7RgdGB0LjQuCDQuCDQoNC+0YHRhNC40L3QvdCw0LTQt9C+0YDQvtC8OyDQ vNC10LbQtNGDIAkJCdGC0LDQvNC+0LbQtdC90L3Ri9C80Lgg0Lgg0L3QsNC70L7Qs9C+0LLRi9C8 0Lg8YnI+CQkJ0L7RgNCz0LDQvdCw0LzQuCDQuCDQoNC+0YHRhNC40L3QvdCw0LTQt9C+0YDQvtC8 LiA8YnI+PGI+PGZvbnQgY29sb3I9IiMwMDAwY2MiIHNpemU9IjUiPjYuPC9mb250PtCe0YLQstC1 0YLRgdGC0LLQtdC90L3QvtGB0YLRjCDQt9CwIAkJCdC90LDRgNGD0YjQtdC90LjRjyDQstCw0LvR jtGC0L3QvtCz0L4g0LfQsNC60L7QvdC+0LTQsNGC0LXQu9GM0YHRgtCy0LAg0Lgg0LDQutGC0L7Q siDQvtGA0LPQsNC90L7QsiDQstCw0LvRjtGC0L3QvtCz0L48YnI+CQkJ0YDQtdCz0YPQu9C40YDQ vtCy0LDQvdC40Y8uPC9iPjxicj7QnNC40L3QuNC80LjQt9Cw0YbQuNGPINGA0LjRgdC60L7Qsiwg 0YHQstGP0LfQsNC90L3Ri9GFINGBINC/0YDQvtCy0LXQtNC10L3QuNC10Lwg0LLQsNC70Y7RgtC9 0YvRhSDQvtC/0LXRgNCw0YbQuNC5INC/0YDQuCAJCQnQvtGB0YPRidC10YHRgtCy0LvQtdC90LjQ uDxicj4JCQnQstC90LXRiNC90LXRjdC60L7QvdC+0LzQuNGH0LXRgdC60L7QuSDQtNC10Y/RgtC1 0LvRjNC90L7RgdGC0LguINCf0YDQtdC00YPQv9GA0LXQttC00LXQvdC40LUg0L/RgNCw0LLQvtC9 0LDRgNGD0YjQtdC90LjQuSAJCQnQstCw0LvRjtGC0L3QvtCz0L48YnI+CQkJ0LfQsNC60L7QvdC+ 0LTQsNGC0LXQu9GM0YHRgtCy0LAg0KDQvtGB0YHQuNC50YHQutC+0Lkg0KTQtdC00LXRgNCw0YbQ uNC4INC4INCw0LrRgtC+0LIg0L7RgNCz0LDQvdC+0LIg0LLQsNC70Y7RgtC90L7Qs9C+IAkJCdGA 0LXQs9GD0LvQuNGA0L7QstCw0L3QuNGPLiDQmtC+0LzQv9C70LXQutGBINC80LXRgDxicj4JCQnQ v9C+INGB0L7Qt9C00LDQvdC40Y4g0LLQvdGD0YLRgNC40YTQuNGA0LzQtdC90L3QvtC5INGB0LjR gdGC0LXQvNGLINCy0LDQu9GO0YLQvdC+0LPQviDQutC+0L3RgtGA0L7Qu9GPLiDQnNC10YHRgtC+ IAkJCdCy0L3Rg9GC0YDQuNGE0LjRgNC80LXQvdC90L7QuSDRgdC40YHRgtC10LzRizxicj4JCQnQ stCw0LvRjtGC0L3QvtCz0L4g0LrQvtC90YLRgNC+0LvRjyDQsiDQvtGA0LPQsNC90LjQt9Cw0YbQ uNC+0L3QvdC+0Lkg0YHRgtGA0YPQutGC0YPRgNC1INC/0YDQtdC00L/RgNC40Y/RgtC40Y8gCQkJ ICjQvtGA0LPQsNC90LjQt9Cw0YbQuNC4KS4g0KLRgNC10LHQvtCy0LDQvdC40Y88YnI+CQkJ0LfQ sNC60L7QvdC+0LTQsNGC0LXQu9GM0YHRgtCy0LAg0Log0YPRgdC70L7QstC40Y/QvCDQt9Cw0LrQ u9GO0YfQsNC10LzRi9GFINCy0L4g0LLQvdC10YjQvdC10YLQvtGA0LPQvtCy0L7QuSAJCQnQtNC1 0Y/RgtC10LvRjNC90L7RgdGC0Lgg0LTQvtCz0L7QstC+0YDQvtCyPGJyPijQutC+0L3RgtGA0LDQ utGC0L7QsikuIDxicj48YnI+IMKgPC90ZD48dGQgYmdjb2xvcj0iI2Q4YzljOSI+wqA8L3RkPjx0 ZCBiZ2NvbG9yPSIjYzJhYmFiIj7CoDwvdGQ+PHRkIGJnY29sb3I9IiNhNDgyODIiPsKgPC90ZD48 dGQgYmdjb2xvcj0iIzg2NjI2MiI+wqA8L3RkPjwvdHI+PHRyPjx0ZCB3aWR0aD0iNCIgYmdjb2xv cj0iIzg2NjI2MiI+wqA8L3RkPjx0ZCBiZ2NvbG9yPSIjYTQ4MjgyIj7CoDwvdGQ+PHRkIGJnY29s b3I9IiNjMmFiYWIiPsKgPC90ZD48dGQgd2lkdGg9IjQiPsKgPC90ZD48dGQgYmdjb2xvcj0iI2Vi ZTRlNCI+PHAgYWxpZ249InJpZ2h0Ij7Qo9GH0LDRgdGC0LjQtTogMTEgONC+0L4g0YDRg9CxLjxi cj7QktGF0L7QtNC40YIg0LzQtdGC0L7QtNC40YfQtdGB0LrQuNC5INC80LDRgtC10YDQuNCw0Lss INC+0LHQtdC00YssINC60L7RhNC1LdC/0LDRg9C30YsuPGJyPtCf0L4g0L7QutC+0L3Rh9Cw0L3Q uNGOINC30LDQvdGP0YLQuNGPINCS0LDQvCDQstGL0LTQsNC10YLRgdGPINGB0LXRgNGC0LjRhNC4 0LrQsNGCLjxicj7QmNC90L7Qs9C+0YDQvtC00L3QuNC8INGD0YfQsNGB0YLQvdC40LrQsNC8INC/ 0L7QvNC+0LPQsNC10Lwg0LIg0LHRgNC+0L3QuNGA0L7QstCw0L3QuNC4INCz0L7RgdGC0LjQvdC4 0YbRiy48L3A+PC90ZD48dGQgYmdjb2xvcj0iI2Q4YzljOSI+wqA8L3RkPjx0ZCBiZ2NvbG9yPSIj YzJhYmFiIj7CoDwvdGQ+PHRkIGJnY29sb3I9IiNhNDgyODIiPsKgPC90ZD48dGQgYmdjb2xvcj0i Izg2NjI2MiI+wqA8L3RkPjwvdHI+PHRyPjx0ZCB3aWR0aD0iNCIgYmdjb2xvcj0iIzg2NjI2MiI+ wqA8L3RkPjx0ZCBiZ2NvbG9yPSIjYTQ4MjgyIj7CoDwvdGQ+PHRkIGJnY29sb3I9IiNjMmFiYWIi PsKgPC90ZD48dGQgd2lkdGg9IjQiIGJnY29sb3I9IiM4NjYyNjIiPsKgPC90ZD48dGQgYmdjb2xv cj0iIzg2NjI2MiI+wqA8L3RkPjx0ZCBiZ2NvbG9yPSIjZDhjOWM5Ij7CoDwvdGQ+PHRkIGJnY29s b3I9IiNjMmFiYWIiPsKgPC90ZD48dGQgYmdjb2xvcj0iI2E0ODI4MiI+wqA8L3RkPjx0ZCBiZ2Nv bG9yPSIjODY2MjYyIj7CoDwvdGQ+PC90cj48L3Rib2R5PjwvdGFibGU+PC9kaXY+PC9kaXY+DQo= ------------11D073358F5B8564-- From aluno3@poczta.onet.pl Thu Nov 26 04:22:08 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 3FEB97F37 for ; Thu, 26 Nov 2015 04:22:08 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 2EE5C30405F for ; Thu, 26 Nov 2015 02:22:08 -0800 (PST) X-ASG-Debug-ID: 1448533321-04cbb0605d240a40001-NocioJ Received: from smtpo65.poczta.onet.pl (smtpo33.poczta.onet.pl [213.180.142.164]) by cuda.sgi.com with ESMTP id N9tBRlMXodoVdHgR (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 26 Nov 2015 02:22:02 -0800 (PST) X-Barracuda-Envelope-From: aluno3@poczta.onet.pl X-Barracuda-Apparent-Source-IP: 213.180.142.164 Received: from [192.168.176.22] (host8514118246.static.open-e.3s.pl [85.14.118.246]) (Authenticated sender: aluno3@poczta.onet.pl) by smtp.poczta.onet.pl (Onet) with ESMTPA id 3p5w9y1ZvFzT1pb5r for ; Thu, 26 Nov 2015 11:21:57 +0100 (CET) To: xfs@oss.sgi.com From: "aluno3@poczta.onet.pl" Subject: Which xfsprogs version to which kernel version X-Enigmail-Draft-Status: N1110 X-ASG-Orig-Subj: Which xfsprogs version to which kernel version Message-ID: <5656DD39.8060403@poczta.onet.pl> Date: Thu, 26 Nov 2015 11:21:45 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.2.0 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: smtpo33.poczta.onet.pl[213.180.142.164] X-Barracuda-Start-Time: 1448533322 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24740 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Hello, I am using kernel 3.10 and would like to update xfsprogs (currently I have 3.1.5). When I tried to use the newest version of xfsprogs 4.3.0 I get the call trace about detected version 5 of superblock when mounting volume which was formatted using mkfs.xfs from 4.3.0. [ 606.853643] XFS (zd32): Version 5 superblock detected. This kernel has EXPERIMENTAL support enabled! Use of these features in this kernel is at your own risk! [ 606.853649] XFS (zd32): Superblock has unknown read-only compatible features (0x1) enabled. [ 606.853651] XFS (zd32): Attempted to mount read-only compatible filesystem read-write. Filesystem can only be safely mounted read only. [ 606.853654] ffff880067a71000: 58 46 53 42 00 00 10 00 00 00 00 00 01 90 00 00 XFSB............ [ 606.853657] ffff880067a71010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ [ 606.853658] ffff880067a71020: 63 d1 24 9f 21 3d 44 a0 8c 51 5b 4e 31 1a 70 1e c.$.!=D..Q[N1.p. [ 606.853660] ffff880067a71030: 00 00 00 00 01 00 00 05 00 00 00 00 00 00 00 60 ...............` [ 606.853663] XFS (zd32): Internal error xfs_sb_read_verify at line 730 of file fs/xfs/xfs_mount.c. Caller 0xffffffff81256c7d [ 606.853667] CPU: 0 PID: 200 Comm: kworker/0:1H Tainted: P O 3.10.92-oe64-ge331686 #15 [ 606.853668] Hardware name: System manufacturer System Product Name/P5WDG2 WS Pro, BIOS 0905 03/06/2008 [ 606.853675] Workqueue: xfslogd xfs_buf_iodone_work [ 606.853677] ffffffff81692f75 ffffffff81258c5d ffffffff81256c7d ffffffff818a39e3 [ 606.853680] ffff88005dcab200 0000000000000016 ffff880052c11800 0000000000000200 [ 606.853683] ffff88007ea17800 ffffffff812a32ac ffffffff81256c7d 000000007ea11a40 [ 606.853686] Call Trace: [ 606.853692] [] ? dump_stack+0xc/0x15 [ 606.853695] [] ? xfs_corruption_error+0x8d/0x90 [ 606.853698] [] ? xfs_buf_iodone_work+0x6d/0x90 [ 606.853703] [] ? xfs_sb_read_verify+0xfc/0x120 [ 606.853705] [] ? xfs_buf_iodone_work+0x6d/0x90 [ 606.853708] [] ? xfs_buf_iodone_work+0x6d/0x90 [ 606.853712] [] ? process_one_work+0x13d/0x3b0 [ 606.853715] [] ? worker_thread+0x121/0x3d0 [ 606.853717] [] ? manage_workers.isra.26+0x280/0x280 [ 606.853721] [] ? kthread+0xc2/0xd0 [ 606.853725] [] ? sched_clock_cpu+0x30/0x100 [ 606.853728] [] ? kthread_create_on_node+0x110/0x110 [ 606.853731] [] ? ret_from_fork+0x58/0x90 [ 606.853734] [] ? kthread_create_on_node+0x110/0x110 [ 606.853736] XFS (zd32): Corruption detected. Unmount and run xfs_repair [ 606.853742] XFS (zd32): SB validate failed with error 22. Dave in thread http://oss.sgi.com/archives/xfs/2015-08/msg00528.html advises to disable crc and finobt: mkfs.xfs -m crc=0,finobt=0 but it does not work with 4.X version of xfsprogs. Call trace also occurred so I tried to use 3.2.4 family with crc=0,finobt=0 and volume mounted successfully. Dave also noticed: i.e. if Gentoo are shipping xfsprogs 3.2.4 w/ kernel 3.14.51, then Gentoo has a quality control problem - they have failed to verify that the packages they are shipping work correctly before shipping them to users... that using 3.2.4 with kernel 3.14.51 is not good idea so are you able to advise which version of xfsprogs is the best for kernel 3.10? Please note that update the kernel in my environment is not possible in easy way so I need to stay with 3.10. From cmaiolino@redhat.com Thu Nov 26 05:31:04 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 C4AF77F37 for ; Thu, 26 Nov 2015 05:31:04 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 3D3D2AC001 for ; Thu, 26 Nov 2015 03:31:01 -0800 (PST) X-ASG-Debug-ID: 1448537459-04cbb0605c2425e0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id SQdrgQaCAHyyEJOf (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 26 Nov 2015 03:30:59 -0800 (PST) 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 (Postfix) with ESMTPS id 103248E241 for ; Thu, 26 Nov 2015 11:30:59 +0000 (UTC) Received: from redhat.com (dhcp-26-103.brq.redhat.com [10.34.26.103]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAQBUtwv019342 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Thu, 26 Nov 2015 06:30:58 -0500 Date: Thu, 26 Nov 2015 12:30:55 +0100 From: Carlos Maiolino To: Brian Foster Cc: xfs@oss.sgi.com Subject: Re: [PATCH 1/2] xfs_io: implement 'inode' command V4 Message-ID: <20151126113052.GA15663@redhat.com> X-ASG-Orig-Subj: Re: [PATCH 1/2] xfs_io: implement 'inode' command V4 Mail-Followup-To: Brian Foster , xfs@oss.sgi.com References: <1447663404-7857-1-git-send-email-cmaiolino@redhat.com> <1447663404-7857-2-git-send-email-cmaiolino@redhat.com> <20151119132722.GA13055@bfoster.bfoster> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151119132722.GA13055@bfoster.bfoster> User-Agent: Mutt/1.5.24 (2015-08-30) 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: 1448537459 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Hi Brian, > > Well, the code looks Ok to me but the design still seems overdone IMO. I > have no major objection if this goes in as is (with one exception noted > below), but IMO we should take the approach somewhat discussed in the v3 > review. First of all, thanks for reviewing the patch again, I took some time to reply because I was waiting for any other comments and had a few other things to do. > > In particular, define an actual default behavior for the command to > return the largest inode number (or return 1/0 for "ability to mount w/ > inode32" as Dave suggested). For example, kill both of the -l and -s > flags and just return 1/0 by default. Define a single verbose (-v) flag > to print the combined inode number and size. This mode can be > implemented as the body of the inode_f() function. If -n is specified, > basically do what the current version does. Just my .02. > I agree with you here and tbh, I don't really think a -v flag is really needed, although it can certainly facilitate the usage of the xfs_io -c "inode". Checking for the size of the inode returned against UINT32_MAX is not that hard anyway, but I think keeping a very simple return value for the command might be the best approach. I'm going to re-write it and send a V5 today including a review of your comment below. thanks again for the review > > io/open.c | 151 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > > 1 file changed, 151 insertions(+) > > > > diff --git a/io/open.c b/io/open.c > > index ac5a5e0..2fc8aab 100644 > > --- a/io/open.c > > +++ b/io/open.c > ... > > + if (ret_lsize || ret_largest) { > > + > > + bulkreq.lastip = &last; > > + bulkreq.icount = 1024; /* User-defined maybe!? */ > > + bulkreq.ubuffer = &igroup; > > + bulkreq.ocount = &count; > > + > > + for (;;) { > > + > > + if (xfsctl(file->name, file->fd, XFS_IOC_FSINUMBERS, > > + &bulkreq)) { > > + perror("XFS_IOC_FSINUMBERS"); > > + exitcode = 1; > > + return 0; > > + } > > + > > + if (count == 0) > > + break; > > + > > + lastgrp = count; > > + } > > + > > + lastgrp--; > > + igrp_rec = igroup[lastgrp]; > > IIRC the point of igrp_rec was to save off the last record so it could > be used directly after the loop without need for the count (because it > could be 0). Here we use a separate lastgrp count to protect against the > 0 case, yet still do the record copy after the loop... what's the point > of that? > > Brian > > > + lastino = igrp_rec.xi_startino + > > + xfs_highbit64(igrp_rec.xi_allocmask); > > + > > + if (ret_lsize) > > + printf (_("Largest inode size: %d\n"), > > + lastino > XFS_MAXINUMBER_32 ? 64 : 32); > > + else > > + printf(_("Largest inode: %llu\n"), lastino); > > + > > + return 0; > > + } > > + > > + return command_usage(&inode_cmd); > > +} > > + > > void > > open_init(void) > > { > > @@ -815,6 +955,16 @@ open_init(void) > > _("get/set preferred extent size (in bytes) for the open file"); > > extsize_cmd.help = extsize_help; > > > > + inode_cmd.name = "inode"; > > + inode_cmd.cfunc = inode_f; > > + inode_cmd.args = _("[-s | -l | -n] [num]"); > > + inode_cmd.argmin = 1; > > + inode_cmd.argmax = 2; > > + inode_cmd.flags = CMD_NOMAP_OK; > > + inode_cmd.oneline = > > + _("Query inode number usage in the filesystem"); > > + inode_cmd.help = inode_help; > > + > > add_command(&open_cmd); > > add_command(&stat_cmd); > > add_command(&close_cmd); > > @@ -822,4 +972,5 @@ open_init(void) > > add_command(&chproj_cmd); > > add_command(&lsproj_cmd); > > add_command(&extsize_cmd); > > + add_command(&inode_cmd); > > } > > -- > > 2.4.3 > > > > _______________________________________________ > > xfs mailing list > > xfs@oss.sgi.com > > http://oss.sgi.com/mailman/listinfo/xfs -- Carlos From eflorac@intellique.com Thu Nov 26 06:26:46 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 079D87F37 for ; Thu, 26 Nov 2015 06:26:46 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id DFDBA304032 for ; Thu, 26 Nov 2015 04:26:42 -0800 (PST) X-ASG-Debug-ID: 1448540797-04cbb0605d243f70001-NocioJ Received: from mail1.g1.pair.com (mail1.g1.pair.com [66.39.3.162]) by cuda.sgi.com with ESMTP id cl8pRkpmgjcLUVcm (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 26 Nov 2015 04:26:37 -0800 (PST) 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 C55922CB68; Thu, 26 Nov 2015 07:26:36 -0500 (EST) Received: from harpe.intellique.com (labo.djinux.com [82.225.196.72]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail1.g1.pair.com (Postfix) with ESMTPSA id 082032CB28; Thu, 26 Nov 2015 07:26:35 -0500 (EST) Date: Thu, 26 Nov 2015 13:26:38 +0100 From: Emmanuel Florac To: "aluno3@poczta.onet.pl" Cc: xfs@oss.sgi.com Subject: Re: Which xfsprogs version to which kernel version Message-ID: <20151126132638.53ed9fc7@harpe.intellique.com> X-ASG-Orig-Subj: Re: Which xfsprogs version to which kernel version In-Reply-To: <5656DD39.8060403@poczta.onet.pl> References: <5656DD39.8060403@poczta.onet.pl> Organization: Intellique X-Mailer: Claws Mail 3.12.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: 1448540797 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24742 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header Le Thu, 26 Nov 2015 11:21:45 +0100 "aluno3@poczta.onet.pl" =C3=A9crivait: > mkfs.xfs -m crc=3D0,finobt=3D0 >=20 > but it does not work with 4.X version of xfsprogs. Call trace also > occurred so I tried to use 3.2.4 family with crc=3D0,finobt=3D0 and volume > mounted successfully. >=20 Did you use -f? else mkfs.xfs won't do anything as it'll detect an existing filesystem. --=20 ------------------------------------------------------------------------ Emmanuel Florac | Direction technique | Intellique | | +33 1 78 94 84 02 ------------------------------------------------------------------------ From aluno3@poczta.onet.pl Thu Nov 26 07:19:09 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 38F537F37 for ; Thu, 26 Nov 2015 07:19:09 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 1ACB230405F for ; Thu, 26 Nov 2015 05:19:05 -0800 (PST) X-ASG-Debug-ID: 1448543942-04cbb0605b2452e0001-NocioJ Received: from smtpo64.poczta.onet.pl (smtpo64.poczta.onet.pl [141.105.16.14]) by cuda.sgi.com with ESMTP id VQHiXMKenXOlsyv4 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 26 Nov 2015 05:19:03 -0800 (PST) X-Barracuda-Envelope-From: aluno3@poczta.onet.pl X-Barracuda-Apparent-Source-IP: 141.105.16.14 Received: from [192.168.176.22] (host8514118246.static.open-e.3s.pl [85.14.118.246]) (Authenticated sender: aluno3@poczta.onet.pl) by smtp.poczta.onet.pl (Onet) with ESMTPA id 3p60784y2Wz1XRJdS; Thu, 26 Nov 2015 14:19:48 +0100 (CET) Subject: Re: Which xfsprogs version to which kernel version To: Emmanuel Florac X-ASG-Orig-Subj: Re: Which xfsprogs version to which kernel version References: <5656DD39.8060403@poczta.onet.pl> <20151126132638.53ed9fc7@harpe.intellique.com> Cc: xfs@oss.sgi.com From: "aluno3@poczta.onet.pl" X-Enigmail-Draft-Status: N1110 Message-ID: <565706BB.3030006@poczta.onet.pl> Date: Thu, 26 Nov 2015 14:18:51 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.2.0 MIME-Version: 1.0 In-Reply-To: <20151126132638.53ed9fc7@harpe.intellique.com> Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Barracuda-Connect: smtpo64.poczta.onet.pl[141.105.16.14] X-Barracuda-Start-Time: 1448543943 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24744 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Yes I used -f option with 4.X version of xfsprogs but mounting the volume was not possible - before mkfs.xfs finished successfully (mkfs.xfs -f -m crc=0,finobt=0). Should I stay in 3.1.X family of xfsprogs or is it recommended to use at least 3.2.x version with kernel 3.10? The most I care about xfs_repair. On 11/26/15 13:26, Emmanuel Florac wrote: > Le Thu, 26 Nov 2015 11:21:45 +0100 > "aluno3@poczta.onet.pl" écrivait: > >> mkfs.xfs -m crc=0,finobt=0 >> >> but it does not work with 4.X version of xfsprogs. Call trace also >> occurred so I tried to use 3.2.4 family with crc=0,finobt=0 and volume >> mounted successfully. >> > > Did you use -f? else mkfs.xfs won't do anything as it'll detect an > existing filesystem. > From bfoster@redhat.com Thu Nov 26 07:49:36 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 81EA77F37 for ; Thu, 26 Nov 2015 07:49:36 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 60C65304048 for ; Thu, 26 Nov 2015 05:49:36 -0800 (PST) X-ASG-Debug-ID: 1448545774-04cbb0605e245ca0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id AbxhYqGHJ3UQtS6F (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 26 Nov 2015 05:49:35 -0800 (PST) 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 (Postfix) with ESMTPS id A71D4461C7 for ; Thu, 26 Nov 2015 13:49:34 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-225.bos.redhat.com [10.18.41.225]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAQDnYp3028488; Thu, 26 Nov 2015 08:49:34 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id 76595122406; Thu, 26 Nov 2015 08:49:33 -0500 (EST) Date: Thu, 26 Nov 2015 08:49:33 -0500 From: Brian Foster To: Masatake YAMATO Cc: xfs@oss.sgi.com Subject: Re: [PATCH v2] xfs: send warning of project quota to userspace via netlink Message-ID: <20151126134933.GA39911@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH v2] xfs: send warning of project quota to userspace via netlink References: <20151125185419.GA18719@bfoster.bfoster> <1448504560-25151-1-git-send-email-yamato@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1448504560-25151-1-git-send-email-yamato@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: 1448545775 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Thu, Nov 26, 2015 at 11:22:39AM +0900, Masatake YAMATO wrote: > Linux's quota subsystem has an ability to handle > project quota. This commit just utilizes the ability > from xfs side. > ... > Changes in v2: > > a couple aesthetic things suggested by Brian Foster . > * rename local vairable for aligning the parameter names, > * move a short line to the end of its previous line. > > Signed-off-by: Masatake YAMATO > --- Thanks for all of the test information. Now you have a really long commit log description rather than a short one. ;) Maybe Dave can truncate it. Regardless, looks fine to me: Reviewed-by: Brian Foster > fs/xfs/xfs_trans_dquot.c | 14 +++++++++----- > 1 file changed, 9 insertions(+), 5 deletions(-) > > diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c > index ce78534..9951701 100644 > --- a/fs/xfs/xfs_trans_dquot.c > +++ b/fs/xfs/xfs_trans_dquot.c > @@ -572,12 +572,16 @@ xfs_quota_warn( > struct xfs_dquot *dqp, > int type) > { > - /* no warnings for project quotas - we just return ENOSPC later */ > + enum quota_type qtype; > + > if (dqp->dq_flags & XFS_DQ_PROJ) > - return; > - quota_send_warning(make_kqid(&init_user_ns, > - (dqp->dq_flags & XFS_DQ_USER) ? > - USRQUOTA : GRPQUOTA, > + qtype = PRJQUOTA; > + else if (dqp->dq_flags & XFS_DQ_USER) > + qtype = USRQUOTA; > + else > + qtype = GRPQUOTA; > + > + quota_send_warning(make_kqid(&init_user_ns, qtype, > be32_to_cpu(dqp->q_core.d_id)), > mp->m_super->s_dev, type); > } > -- > 2.5.0 > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From bfoster@redhat.com Thu Nov 26 07:50:56 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 F1E477F37 for ; Thu, 26 Nov 2015 07:50:56 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id D3EF4304051 for ; Thu, 26 Nov 2015 05:50:56 -0800 (PST) X-ASG-Debug-ID: 1448545855-04bdf07f0925e830001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id b6FpzTuJnoLEnq5S (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 26 Nov 2015 05:50:55 -0800 (PST) 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 (Postfix) with ESMTPS id 1FB548F283; Thu, 26 Nov 2015 13:50:54 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-225.bos.redhat.com [10.18.41.225]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAQDosxD007046; Thu, 26 Nov 2015 08:50:54 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id 59C78122406; Thu, 26 Nov 2015 08:50:53 -0500 (EST) Date: Thu, 26 Nov 2015 08:50:53 -0500 From: Brian Foster To: "aluno3@poczta.onet.pl" Cc: Emmanuel Florac , xfs@oss.sgi.com Subject: Re: Which xfsprogs version to which kernel version Message-ID: <20151126135053.GB39911@bfoster.bfoster> X-ASG-Orig-Subj: Re: Which xfsprogs version to which kernel version References: <5656DD39.8060403@poczta.onet.pl> <20151126132638.53ed9fc7@harpe.intellique.com> <565706BB.3030006@poczta.onet.pl> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <565706BB.3030006@poczta.onet.pl> 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: 1448545855 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Thu, Nov 26, 2015 at 02:18:51PM +0100, aluno3@poczta.onet.pl wrote: > Yes I used -f option with 4.X version of xfsprogs but mounting the > volume was not possible - before mkfs.xfs finished successfully > (mkfs.xfs -f -m crc=0,finobt=0). > You posted the output associated with the crc=1 fs mount failure, what happens when you try to mount after formatting with crc=0? Brian > Should I stay in 3.1.X family of xfsprogs or is it recommended to use at > least 3.2.x version with kernel 3.10? > > The most I care about xfs_repair. > > On 11/26/15 13:26, Emmanuel Florac wrote: > > Le Thu, 26 Nov 2015 11:21:45 +0100 > > "aluno3@poczta.onet.pl" écrivait: > > > >> mkfs.xfs -m crc=0,finobt=0 > >> > >> but it does not work with 4.X version of xfsprogs. Call trace also > >> occurred so I tried to use 3.2.4 family with crc=0,finobt=0 and volume > >> mounted successfully. > >> > > > > Did you use -f? else mkfs.xfs won't do anything as it'll detect an > > existing filesystem. > > > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From aluno3@poczta.onet.pl Thu Nov 26 08:37:18 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 3AEE67F37 for ; Thu, 26 Nov 2015 08:37:18 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 2B69A304048 for ; Thu, 26 Nov 2015 06:37:18 -0800 (PST) X-ASG-Debug-ID: 1448548631-04cbb0605c246cb0001-NocioJ Received: from smtpo80.poczta.onet.pl (smtpo80.poczta.onet.pl [141.105.16.30]) by cuda.sgi.com with ESMTP id ZXjWAs8DtaQQlMRo (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 26 Nov 2015 06:37:12 -0800 (PST) X-Barracuda-Envelope-From: aluno3@poczta.onet.pl X-Barracuda-Apparent-Source-IP: 141.105.16.30 Received: from [192.168.176.22] (host8514118246.static.open-e.3s.pl [85.14.118.246]) (Authenticated sender: aluno3@poczta.onet.pl) by smtp.poczta.onet.pl (Onet) with ESMTPA id 3p61rH4bFBzDQxpW5; Thu, 26 Nov 2015 15:37:03 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=poczta.onet.pl; s=2011; t=1448548624; bh=wqFjbPJF3DiInjo3AyzENzKwwLE0psgyanFMtv1Q+N4=; h=Subject:To:References:Cc:From:Date:In-Reply-To:From; b=dob85EovWsIvof8x9Krabv5wqjV//of5QTzjbMQSplUNWPcm6F14wtTW+5mljqcz7 AWHBqzYjQ8BOmzG2K7vLwdFEmT08apCbNrbu3hZgXaLisW+fJTdX4VNUFQvptgHUkc GGCH1Nbf4JYMmQUra8SQJj3ZWKCsY3J2bDhUlOv8= Subject: Re: Which xfsprogs version to which kernel version To: Brian Foster X-ASG-Orig-Subj: Re: Which xfsprogs version to which kernel version References: <5656DD39.8060403@poczta.onet.pl> <20151126132638.53ed9fc7@harpe.intellique.com> <565706BB.3030006@poczta.onet.pl> <20151126135053.GB39911@bfoster.bfoster> Cc: Emmanuel Florac , xfs@oss.sgi.com From: "aluno3@poczta.onet.pl" X-Enigmail-Draft-Status: N1110 Message-ID: <5657190A.1050103@poczta.onet.pl> Date: Thu, 26 Nov 2015 15:36:58 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.2.0 MIME-Version: 1.0 In-Reply-To: <20151126135053.GB39911@bfoster.bfoster> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 8bit X-Barracuda-Connect: smtpo80.poczta.onet.pl[141.105.16.30] X-Barracuda-Start-Time: 1448548632 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24744 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 dmesg when mounting volume which was formated xfsprogs 4.3.0: * root@192.168.176.24:~$ mkfs.xfs -V mkfs.xfs version 4.3.0 root@192.168.176.24:~$ mkfs.xfs -f -m crc=0,finobt=0 /dev/sdc4 meta-data=/dev/sdc4 isize=256 agcount=4, agsize=474552 blks = sectsz=512 attr=2, projid32bit=1 = crc=0 finobt=0, sparse=0 data = bsize=4096 blocks=1898208, imaxpct=25 = sunit=0 swidth=0 blks naming =version 2 bsize=4096 ascii-ci=0 ftype=1 log =internal log bsize=4096 blocks=2560, version=2 = sectsz=512 sunit=0 blks, lazy-count=1 realtime =none extsz=4096 blocks=0, rtextents=0 root@192.168.176.24:~$ mount /dev/sdc4 /mnt/sdc4 mount: wrong fs type, bad option, bad superblock on /dev/sdc4, missing codepage or helper program, or other error In some cases useful info is found in syslog - try dmesg | tail or so. root@192.168.176.24:~$ dmesg [ 212.984534] XFS (sdc4): bad version [ 212.984547] ffff88005cccb000: 58 46 53 42 00 00 10 00 00 00 00 00 00 1c f6 e0 XFSB............ [ 212.984550] ffff88005cccb010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ [ 212.984551] ffff88005cccb020: 55 9d 20 d9 1c e9 4e a9 a3 ee 8d fd ba 68 b3 70 U. ...N......h.p [ 212.984553] ffff88005cccb030: 00 00 00 00 00 10 00 04 00 00 00 00 00 00 00 80 ................ [ 212.984556] XFS (sdc4): Internal error xfs_sb_read_verify at line 730 of file fs/xfs/xfs_mount.c. Caller 0xffffffff81256c7d [ 212.984560] CPU: 0 PID: 440 Comm: kworker/0:1H Tainted: P O 3.10.92-oe64-ge331686 #15 [ 212.984562] Hardware name: System manufacturer System Product Name/P5WDG2 WS Pro, BIOS 0905 03/06/2008 [ 212.984567] Workqueue: xfslogd xfs_buf_iodone_work [ 212.984570] ffffffff81692f75 ffffffff81258c5d ffffffff81256c7d ffffffff818a39e3 [ 212.984573] ffff88007aa9ef00 0000000000000016 ffff88007aa8b000 0000000000000000 [ 212.984576] ffff88007ea17800 ffffffff812a32ac ffffffff81256c7d ffff88007ea11a40 [ 212.984579] Call Trace: [ 212.984584] [] ? dump_stack+0xc/0x15 [ 212.984587] [] ? xfs_corruption_error+0x8d/0x90 [ 212.984590] [] ? xfs_buf_iodone_work+0x6d/0x90 [ 212.984595] [] ? xfs_sb_read_verify+0xfc/0x120 [ 212.984598] [] ? xfs_buf_iodone_work+0x6d/0x90 [ 212.984600] [] ? xfs_buf_iodone_work+0x6d/0x90 [ 212.984604] [] ? process_one_work+0x13d/0x3b0 [ 212.984607] [] ? worker_thread+0x121/0x3d0 [ 212.984609] [] ? manage_workers.isra.26+0x280/0x280 [ 212.984613] [] ? kthread+0xc2/0xd0 [ 212.984616] [] ? sched_clock_cpu+0x30/0x100 [ 212.984619] [] ? kthread_create_on_node+0x110/0x110 [ 212.984623] [] ? ret_from_fork+0x58/0x90 [ 212.984626] [] ? kthread_create_on_node+0x110/0x110 [ 212.984628] XFS (sdc4): Corruption detected. Unmount and run xfs_repair [ 212.984634] XFS (sdc4): SB validate failed with error 22. * On 11/26/15 14:50, Brian Foster wrote: > On Thu, Nov 26, 2015 at 02:18:51PM +0100, aluno3@poczta.onet.pl wrote: >> Yes I used -f option with 4.X version of xfsprogs but mounting the >> volume was not possible - before mkfs.xfs finished successfully >> (mkfs.xfs -f -m crc=0,finobt=0). >> > > You posted the output associated with the crc=1 fs mount failure, what > happens when you try to mount after formatting with crc=0? > > Brian > >> Should I stay in 3.1.X family of xfsprogs or is it recommended to use at >> least 3.2.x version with kernel 3.10? >> >> The most I care about xfs_repair. >> >> On 11/26/15 13:26, Emmanuel Florac wrote: >>> Le Thu, 26 Nov 2015 11:21:45 +0100 >>> "aluno3@poczta.onet.pl" écrivait: >>> >>>> mkfs.xfs -m crc=0,finobt=0 >>>> >>>> but it does not work with 4.X version of xfsprogs. Call trace also >>>> occurred so I tried to use 3.2.4 family with crc=0,finobt=0 and volume >>>> mounted successfully. >>>> >>> >>> Did you use -f? else mkfs.xfs won't do anything as it'll detect an >>> existing filesystem. >>> >> >> _______________________________________________ >> xfs mailing list >> xfs@oss.sgi.com >> http://oss.sgi.com/mailman/listinfo/xfs From cmaiolino@redhat.com Thu Nov 26 09:46:43 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 ED3167F37 for ; Thu, 26 Nov 2015 09:46:43 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id CB8E9304066 for ; Thu, 26 Nov 2015 07:46:43 -0800 (PST) X-ASG-Debug-ID: 1448552801-04cb6c0cd32092e0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id DvE76R64haXWBkr3 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 26 Nov 2015 07:46:42 -0800 (PST) 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 (Postfix) with ESMTPS id 817758E22B for ; Thu, 26 Nov 2015 15:46:41 +0000 (UTC) Received: from zion.usersys.redhat.com (dhcp-26-103.brq.redhat.com [10.34.26.103]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAQFke6V022027 for ; Thu, 26 Nov 2015 10:46:40 -0500 From: Carlos Maiolino To: xfs@oss.sgi.com Subject: [PATCH] xfs_io: implement 'inode' command V5 Date: Thu, 26 Nov 2015 16:46:35 +0100 X-ASG-Orig-Subj: [PATCH] xfs_io: implement 'inode' command V5 Message-Id: <1448552795-8794-1-git-send-email-cmaiolino@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: 1448552802 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Implements a new xfs_io command, named 'inode', which is supposed to be used to query information about inode's existence and its physical size in the filesystem. Supported options: Default: -- Return true(1) or false(0) if any inode greater than 32bits has been found in the filesystem -v -- verbose mode Display the number and the physical size (in bits) of the largest inode in the filesystem [num] -- Return true(1) or false(0) if the inode [num] is in use -n [num] -- Return the next valid inode after [num] No manpage sent because there were changes in the supported options and its descriptions. I'll send the manpage after the options and descriptions are reviewed. - Changelog V3: - Merge all 3 patches from the V2 together in a single patch - Rework of '-n [num]' and 'num' only arguments algorithm - Argument -n now relies on bulkreq.count to check for next inodes, not on bstat.bs_ino anymore. - for loop in ret_lsize or ret_largest case, now relies on count being 0 to break the loop V4: - Refactor inode_f function to reduce its size and easier logic - Implement error handlers for invalid command combination (hopefully all invalid combinations). - use a single xfs_inogrp array for keep track of inodes - Fix missing newline in inode_help() - Rewrite help message in inode_help() - Fix indentation V5: - Reduce the amount of options - remove igrp_rec variable, and use igroup[lastgrp] directly to get information from the last inode groups returned by ioctl Signed-off-by: Carlos Maiolino --- io/open.c | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) diff --git a/io/open.c b/io/open.c index ac5a5e0..1e38ea8 100644 --- a/io/open.c +++ b/io/open.c @@ -20,6 +20,7 @@ #include "input.h" #include "init.h" #include "io.h" +#include "libxfs.h" #ifndef __O_TMPFILE #if defined __alpha__ @@ -44,6 +45,7 @@ static cmdinfo_t statfs_cmd; static cmdinfo_t chproj_cmd; static cmdinfo_t lsproj_cmd; static cmdinfo_t extsize_cmd; +static cmdinfo_t inode_cmd; static prid_t prid; static long extsize; @@ -750,6 +752,136 @@ statfs_f( return 0; } +static void +inode_help(void) +{ + printf(_( +"\n" +"Query physical information about the inode" +"\n" +" Default: -- Return true(1) or false(0) if any inode greater than\n" +" 32bits has been found in the filesystem\n" +" -v -- verbose mode\n" +" Display the number and the physical size (in bits)\n" +" of the largest inode in the filesystem\n" +"[num] -- Return true(1) or false(0) if the inode [num] is in use\n" +" -n [num] -- Return the next valid inode after [num]\n" +"\n")); +} + +static int +inode_f( + int argc, + char **argv) +{ + __s32 count = 0; + __s32 lastgrp = 0; + __u64 last = 0; + __u64 lastino = 0; + __u64 userino = 0; + char *p; + int c; + int verbose = 0; + int ret_next = 0; + int cmd = 0; + struct xfs_inogrp igroup[1024]; + struct xfs_fsop_bulkreq bulkreq; + struct xfs_bstat bstat; + + while ((c = getopt(argc, argv, "nv")) != EOF) { + switch (c) { + case 'v': + verbose = 1; + break; + case 'n': + ret_next = 1; + break; + default: + return command_usage(&inode_cmd); + } + } + + if (ret_next && verbose) + return command_usage(&inode_cmd); + + if (optind < argc) { + if (verbose) + return command_usage(&inode_cmd); + + if (ret_next) { + cmd = XFS_IOC_FSBULKSTAT; + } else { + if (argc > 2) + return command_usage(&inode_cmd); + else + cmd = XFS_IOC_FSBULKSTAT_SINGLE; + } + + userino = strtoull(argv[optind], &p, 10); + if ((*p != '\0')) { + printf(_("[num] must be a numeric value\n")); + exitcode = 1; + return 0; + } + + bulkreq.lastip = &userino; + bulkreq.icount = 1; + bulkreq.ubuffer = &bstat; + bulkreq.ocount = &count; + + if (xfsctl(file->name, file->fd, cmd, &bulkreq)) { + if (errno == EINVAL) { + if (!ret_next) + printf("0\n"); + } else { + perror("xfsctl"); + } + exitcode = 1; + return 0; + } + + if (ret_next) { + printf("%llu\n", bstat.bs_ino); + return 0; + } else { + /* Inode number used*/ + printf("1\n"); + return 0; + } + } + + bulkreq.lastip = &last; + bulkreq.icount = 1024; /* User-defined maybe!? */ + bulkreq.ubuffer = &igroup; + bulkreq.ocount = &count; + + for (;;) { + if (xfsctl(file->name, file->fd, XFS_IOC_FSINUMBERS, + &bulkreq)) { + perror("XFS_IOC_FSINUMBERS"); + exitcode = 1; + return 0; + } + + if (count == 0) + break; + + lastgrp = count; + } + + lastgrp--; + lastino = igroup[lastgrp].xi_startino + + xfs_highbit64(igroup[lastgrp].xi_allocmask); + + if (verbose) + printf("%llu:%d\n", lastino, + lastino > XFS_MAXINUMBER_32 ? 64 : 32); + else + printf("%d\n", lastino > XFS_MAXINUMBER_32 ? 1 : 0); + + return 0; +} + void open_init(void) { @@ -815,6 +947,16 @@ open_init(void) _("get/set preferred extent size (in bytes) for the open file"); extsize_cmd.help = extsize_help; + inode_cmd.name = "inode"; + inode_cmd.cfunc = inode_f; + inode_cmd.args = _("[-n | -v] [num]"); + inode_cmd.argmin = 0; + inode_cmd.argmax = 2; + inode_cmd.flags = CMD_NOMAP_OK; + inode_cmd.oneline = + _("Query inode number usage in the filesystem"); + inode_cmd.help = inode_help; + add_command(&open_cmd); add_command(&stat_cmd); add_command(&close_cmd); @@ -822,4 +964,5 @@ open_init(void) add_command(&chproj_cmd); add_command(&lsproj_cmd); add_command(&extsize_cmd); + add_command(&inode_cmd); } -- 2.4.3 From ftpmaster@ftp-master.debian.org Thu Nov 26 18:40:12 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 060C97F37 for ; Thu, 26 Nov 2015 18:40:12 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id D9F3B8F8035 for ; Thu, 26 Nov 2015 16:40:08 -0800 (PST) X-ASG-Debug-ID: 1448584805-04cb6c0cd3211e40001-NocioJ Received: from mailly.debian.org (mailly.debian.org [82.195.75.114]) by cuda.sgi.com with ESMTP id ME1s2EwLWfcHEKz1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Thu, 26 Nov 2015 16:40:06 -0800 (PST) X-Barracuda-Envelope-From: ftpmaster@ftp-master.debian.org X-Barracuda-Apparent-Source-IP: 82.195.75.114 Received: from franck.debian.org ([138.16.160.12]) from C=NA,ST=NA,L=Ankh Morpork,O=Debian SMTP,OU=Debian SMTP CA,CN=franck.debian.org,EMAIL=hostmaster@franck.debian.org (verified) by mailly.debian.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.84) (envelope-from ) id 1a2752-0002Db-PV for xfs@oss.sgi.com; Fri, 27 Nov 2015 00:40:04 +0000 Received: from dak-unpriv by franck.debian.org with local (Exim 4.84) (envelope-from ) id 1a2751-0001vH-PH for xfs@oss.sgi.com; Fri, 27 Nov 2015 00:40:03 +0000 To: xfs@oss.sgi.com From: Debian FTP Masters Subject: Processing of xfsprogs_4.3.0_amd64.changes Date: Fri, 27 Nov 2015 00:40:03 +0000 X-ASG-Orig-Subj: Processing of xfsprogs_4.3.0_amd64.changes X-Debian: DAK X-DAK: DAK Precedence: bulk Auto-Submitted: auto-generated X-Debian-Package: xfsprogs Message-Id: X-Barracuda-Connect: mailly.debian.org[82.195.75.114] X-Barracuda-Start-Time: 1448584806 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24755 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- xfsprogs_4.3.0_amd64.changes uploaded successfully to localhost along with the files: xfsprogs_4.3.0.dsc xfsprogs_4.3.0.tar.gz xfslibs-dev_4.3.0_amd64.deb xfsprogs-udeb_4.3.0_amd64.udeb xfsprogs_4.3.0_amd64.deb Greetings, Your Debian queue daemon (running on host franck.debian.org) From envelope@ftp-master.debian.org Thu Nov 26 18:51:04 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 CED187F37 for ; Thu, 26 Nov 2015 18:51:04 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id AEBB9304039 for ; Thu, 26 Nov 2015 16:51:01 -0800 (PST) X-ASG-Debug-ID: 1448585458-04cbb0605e251760001-NocioJ Received: from mailly.debian.org (mailly.debian.org [82.195.75.114]) by cuda.sgi.com with ESMTP id mvd92gjaQqcsdSvM (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Thu, 26 Nov 2015 16:50:59 -0800 (PST) X-Barracuda-Envelope-From: envelope@ftp-master.debian.org X-Barracuda-Apparent-Source-IP: 82.195.75.114 Received: from franck.debian.org ([138.16.160.12]) from C=NA,ST=NA,L=Ankh Morpork,O=Debian SMTP,OU=Debian SMTP CA,CN=franck.debian.org,EMAIL=hostmaster@franck.debian.org (verified) by mailly.debian.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.84) (envelope-from ) id 1a27FY-0003Lx-En; Fri, 27 Nov 2015 00:50:56 +0000 Received: from dak by franck.debian.org with local (Exim 4.84) (envelope-from ) id 1a27FX-0002su-92; Fri, 27 Nov 2015 00:50:55 +0000 From: Debian FTP Masters To: XFS Development Team , Nathan Scott X-DAK: dak process-upload X-Debian: DAK X-Debian-Package: xfsprogs Precedence: bulk Auto-Submitted: auto-generated MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 8bit Subject: xfsprogs_4.3.0_amd64.changes ACCEPTED into unstable Message-Id: X-ASG-Orig-Subj: xfsprogs_4.3.0_amd64.changes ACCEPTED into unstable Date: Fri, 27 Nov 2015 00:50:55 +0000 X-Barracuda-Connect: mailly.debian.org[82.195.75.114] X-Barracuda-Start-Time: 1448585459 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24756 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Accepted: -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 Format: 1.8 Date: Mon, 23 Nov 2015 15:22:56 +1100 Source: xfsprogs Binary: xfsprogs xfslibs-dev xfsprogs-udeb Architecture: source amd64 Version: 4.3.0 Distribution: unstable Urgency: low Maintainer: XFS Development Team Changed-By: Nathan Scott Description: xfslibs-dev - XFS filesystem-specific static libraries and headers xfsprogs - Utilities for managing the XFS filesystem xfsprogs-udeb - A stripped-down version of xfsprogs, for debian-installer (udeb) Closes: 804255 Changes: xfsprogs (4.3.0) unstable; urgency=low . * New upstream release * Add a postinst to update the initramfs on install/upgrade. (Closes: #804255) Checksums-Sha1: 31064221f22a5b20c731e9e3710bf1d6de759341 1763 xfsprogs_4.3.0.dsc cc5e4c06f537de9b9903b29f761c1b7534876b17 1506750 xfsprogs_4.3.0.tar.gz 003e83012c59d84ca33850c1d29b59034397bda9 55212 xfslibs-dev_4.3.0_amd64.deb 379252c78d7eb0dd643f0d136e7db13eabd548bc 134808 xfsprogs-udeb_4.3.0_amd64.udeb 270c3c737ffe7916d9b230e75415a05b46857928 727106 xfsprogs_4.3.0_amd64.deb Checksums-Sha256: 84daf22e23b846ea319a1707d0b79eb2b61f869531ce27d2cfd42e716cf8265a 1763 xfsprogs_4.3.0.dsc a914e45648e04d211304ffd9fadba919be9d66010ec7b19dffad356c8cbf969e 1506750 xfsprogs_4.3.0.tar.gz 233aae38eead8db27346dccd560d7eef1ab5c976df2495f5643a20975223f805 55212 xfslibs-dev_4.3.0_amd64.deb c8e540fce739a617fd2ff7b8e4a8e86d0cfb27a25fa50b04c3ac21dc5bc0ae64 134808 xfsprogs-udeb_4.3.0_amd64.udeb d8cfef3519c98be8e999b1537b6eb57b8b7925a2715b7cc3a7c55d5e642e3a01 727106 xfsprogs_4.3.0_amd64.deb Files: fc99694150b586161106823f245bea72 1763 admin optional xfsprogs_4.3.0.dsc 2a6d2918d8a8a89e6816e0476aa3f316 1506750 admin optional xfsprogs_4.3.0.tar.gz 4a1dd6248c49586edd2081c5c58f1992 55212 libdevel extra xfslibs-dev_4.3.0_amd64.deb 16394c61c03586daba2fc87f68ad386f 134808 debian-installer optional xfsprogs-udeb_4.3.0_amd64.udeb 215fad11dceaeea00cffa2ccabefac2b 727106 admin optional xfsprogs_4.3.0_amd64.deb Package-Type: udeb -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAEBCAAGBQJWV6TdAAoJEP4IQu423YwMF4kP/1CNyghG5Q1Fk3x2P1FUxx5N 4VaANMpUHRTAuPi0r2dRPQehKqeSfnhgMEzREx44eJOS1SgRcwfu6Cls2Hzv9jn0 /pbqVRe3b7Enovb1UQ9Ibfbo3JdqbgYhkEwFCtO4drgYPilT3+Lv9dtTp4WrfEtq zOosPYTU+rsidGkEnLdIojL3yIBxsEVjpOWst3LZKzfpE9Ei8xrELApGYB31+cOT gSWHdlP1C+x6rtAj0lHHvl5MXn/4izRwUsPSKNNqtthp1fcvRcfhXCYpxlpTvmjM YnfOOkYhH3k1zi4QzdpsFJOWlF5QgwoJPy575+v9v1PpN4rov+re4/dbbdwjG+nR /inX+wfw+3NxN9jzD6S6kLQh5oPwGbhQgsaSqwkNd4XqpAbRCyX3LvoYTUOgpsPW yRP3XlJ0nnoFGSBlcltOAQvVIE7fPCebpE2hcO5B4gvVb5O0VRH+N0YxcavwjpPU pG8uqBixzqEvhL+uXZv1MfZMK9WWB912KhK/fErMP5tty/ln+j/eLJ7bBha54MYE G0FU2YprwVp3JBy9GWTmgn7Id4CWftFNYQgEcW/nu/zpXDhmtUor8rdLrbVivnKW 8IcB7SXyN9JMckLhozncOsPmvlS7XKUTKdHB5jvAfRdgioGt+ofwPZRROtqOuYbg P4sV4o6ipK7CyrpzHswD =d896 -----END PGP SIGNATURE----- Thank you for your contribution to Debian. From debbugs@buxtehude.debian.org Thu Nov 26 18:54:14 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 B85607F37 for ; Thu, 26 Nov 2015 18:54:13 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 5522AAC002 for ; Thu, 26 Nov 2015 16:54:10 -0800 (PST) X-ASG-Debug-ID: 1448585648-04bdf07f09269e30001-NocioJ Received: from buxtehude.debian.org (buxtehude.debian.org [140.211.166.26]) by cuda.sgi.com with ESMTP id hDINMUj29rwvEdSy (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Thu, 26 Nov 2015 16:54:08 -0800 (PST) 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.84) (envelope-from ) id 1a27Ia-0007jg-Rv; Fri, 27 Nov 2015 00:54:04 +0000 MIME-Version: 1.0 X-Mailer: MIME-tools 5.505 (Entity 5.505) X-Loop: owner@bugs.debian.org From: owner@bugs.debian.org (Debian Bug Tracking System) To: Nathan Scott Subject: Bug#804255: marked as done (Please update initramfs in postinst) Message-ID: X-ASG-Orig-Subj: Bug#804255: marked as done (Please update initramfs in postinst) References: <20151106161941.15248.86048.reportbug@tack.local> X-Debian-PR-Message: closed 804255 X-Debian-PR-Package: xfsprogs X-Debian-PR-Keywords: d-i patch X-Debian-PR-Source: xfsprogs Date: Fri, 27 Nov 2015 00:54:04 +0000 Content-Type: multipart/mixed; boundary="----------=_1448585644-29734-0" X-Barracuda-Connect: buxtehude.debian.org[140.211.166.26] X-Barracuda-Start-Time: 1448585648 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24756 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- This is a multi-part message in MIME format... ------------=_1448585644-29734-0 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 Your message dated Fri, 27 Nov 2015 00:50:55 +0000 with message-id and subject line Bug#804255: fixed in xfsprogs 4.3.0 has caused the Debian Bug report #804255, regarding Please update initramfs in postinst to be marked as done. This means that you claim that the problem has been dealt with. If this is not the case it is now your responsibility to reopen the Bug report if necessary, and/or fix the problem forthwith. (NB: If you are a system administrator and have no idea what this message is talking about, this may indicate a serious mail system misconfiguration somewhere. Please contact owner@bugs.debian.org immediately.) --=20 804255: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=3D804255 Debian Bug Tracking System Contact owner@bugs.debian.org with problems ------------=_1448585644-29734-0 Content-Type: message/rfc822 Content-Disposition: inline Content-Transfer-Encoding: 7bit Received: (at submit) by bugs.debian.org; 6 Nov 2015 16:20:16 +0000 X-Spam-Checker-Version: SpamAssassin 3.4.0-bugs.debian.org_2005_01_02 (2014-02-07) on buxtehude.debian.org X-Spam-Level: X-Spam-Status: No, score=-11.4 required=4.0 tests=BAYES_00,FOURLA,HAS_PACKAGE, MDO_CABLE_TV3,MURPHY_DRUGS_REL8,SPF_PASS,XMAILER_REPORTBUG autolearn=ham autolearn_force=no version=3.4.0-bugs.debian.org_2005_01_02 X-Spam-Bayes: score:0.0000 Tokens: new, 6; hammy, 150; neutral, 77; spammy, 0. spammytokens: hammytokens:0.000-+--systemd, 0.000-+--H*x:6.6.3, 0.000-+--H*UA:6.6.3, 0.000-+--H*M:reportbug, 0.000-+--H*MI:reportbug Return-path: Received: from cheddar.halon.org.uk ([93.93.131.118]) by buxtehude.debian.org with esmtps (TLS1.2:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.84) (envelope-from ) id 1ZujkO-00012i-4b for submit@bugs.debian.org; Fri, 06 Nov 2015 16:20:16 +0000 Received: from bsmtp by cheddar.halon.org.uk with local-bsmtp (Exim 4.80) (envelope-from ) id 1ZujkI-0005Ac-LY; Fri, 06 Nov 2015 16:20:10 +0000 Received: from steve by tack.local with local (Exim 4.84) (envelope-from ) id 1Zujjp-0007iW-HU; Fri, 06 Nov 2015 16:19:41 +0000 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Steve McIntyre To: Debian Bug Tracking System Subject: Please update initramfs in postinst Message-ID: <20151106161941.15248.86048.reportbug@tack.local> X-Mailer: reportbug 6.6.3 Date: Fri, 06 Nov 2015 16:19:41 +0000 Delivered-To: submit@bugs.debian.org Package: xfsprogs Version: 3.2.1 Severity: important Tags: d-i Hi! Since the move to systemd as the default init system, the initramfs will attempt to fsck and mount both / and /usr (where applicable). To aid this, initramfs-tools will copy necessary filesystem tools into the initramfs when it is generated. To make this work well, all filesystem tools packages for filesystems that are likely to be used for / and/or /usr should call "update-initramfs -u" in their postinst. This will (a) ensure that necesssary fsck tools are included in the initramfs generated by debian-installer (see #801961 for an example failure here); and (b) ensure that bug fixes to fsck tools get included immediately in the initramfs I've checked your package and I don't see any update-initramfs calls. Please add one. If you'd like help doing that postinst work, I can supply a patch - just ask! -- System Information: Debian Release: 8.2 APT prefers stable APT policy: (500, 'stable') Architecture: amd64 (x86_64) Foreign Architectures: i386 Kernel: Linux 3.16.0-4-amd64 (SMP w/4 CPU cores) Locale: LANG=en_GB.UTF-8, LC_CTYPE=en_GB.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Init: systemd (via /run/systemd/system) Versions of packages xfsprogs depends on: ii libblkid1 2.25.2-6 ii libc6 2.19-18+deb8u1 ii libreadline5 5.2+dfsg-2 ii libuuid1 2.25.2-6 xfsprogs recommends no packages. Versions of packages xfsprogs suggests: ii acl 2.2.52-2 ii attr 1:2.4.47-2 pn quota pn xfsdump -- no debconf information ------------=_1448585644-29734-0 Content-Type: message/rfc822 Content-Disposition: inline Content-Transfer-Encoding: 7bit Received: (at 804255-close) by bugs.debian.org; 27 Nov 2015 00:50:59 +0000 X-Spam-Checker-Version: SpamAssassin 3.4.0-bugs.debian.org_2005_01_02 (2014-02-07) on buxtehude.debian.org X-Spam-Level: X-Spam-Status: No, score=-13.9 required=4.0 tests=BAYES_00,DIGITS_LETTERS, FROMDEVELOPER,FVGT_m_MULTI_ODD,HAS_BUG_NUMBER,PGPSIGNATURE,RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD autolearn=ham autolearn_force=no version=3.4.0-bugs.debian.org_2005_01_02 X-Spam-Bayes: score:0.0000 Tokens: new, 88; hammy, 149; neutral, 130; spammy, 1. spammytokens:0.997-1--inX hammytokens:0.000-+--HX-Debian:DAK, 0.000-+--H*rp:D*ftp-master.debian.org, 0.000-+--H*MI:franck, 0.000-+--H*m:franck, 0.000-+--HX-DAK:process-upload Return-path: Received: from mailly.debian.org ([82.195.75.114]) from C=NA,ST=NA,L=Ankh Morpork,O=Debian SMTP,OU=Debian SMTP CA,CN=mailly.debian.org,EMAIL=hostmaster@mailly.debian.org (verified) by buxtehude.debian.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.84) (envelope-from ) id 1a27Fa-0007cL-Nb for 804255-close@bugs.debian.org; Fri, 27 Nov 2015 00:50:58 +0000 Received: from franck.debian.org ([138.16.160.12]) from C=NA,ST=NA,L=Ankh Morpork,O=Debian SMTP,OU=Debian SMTP CA,CN=franck.debian.org,EMAIL=hostmaster@franck.debian.org (verified) by mailly.debian.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.84) (envelope-from ) id 1a27FY-0003Ly-Fg; Fri, 27 Nov 2015 00:50:56 +0000 Received: from dak by franck.debian.org with local (Exim 4.84) (envelope-from ) id 1a27FX-0002t6-B4; Fri, 27 Nov 2015 00:50:55 +0000 From: Nathan Scott To: 804255-close@bugs.debian.org X-DAK: dak process-upload X-Debian: DAK X-Debian-Package: xfsprogs MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 8bit Subject: Bug#804255: fixed in xfsprogs 4.3.0 Message-Id: Date: Fri, 27 Nov 2015 00:50:55 +0000 Source: xfsprogs Source-Version: 4.3.0 We believe that the bug you reported is fixed in the latest version of xfsprogs, which is due to be installed in the Debian FTP archive. A summary of the changes between this version and the previous one is attached. Thank you for reporting the bug, which will now be closed. If you have further comments please address them to 804255@bugs.debian.org, and the maintainer will reopen the bug report if appropriate. Debian distribution maintenance software pp. Nathan Scott (supplier of updated xfsprogs package) (This message was generated automatically at their request; if you believe that there is a problem with it please contact the archive administrators by mailing ftpmaster@ftp-master.debian.org) -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 Format: 1.8 Date: Mon, 23 Nov 2015 15:22:56 +1100 Source: xfsprogs Binary: xfsprogs xfslibs-dev xfsprogs-udeb Architecture: source amd64 Version: 4.3.0 Distribution: unstable Urgency: low Maintainer: XFS Development Team Changed-By: Nathan Scott Description: xfslibs-dev - XFS filesystem-specific static libraries and headers xfsprogs - Utilities for managing the XFS filesystem xfsprogs-udeb - A stripped-down version of xfsprogs, for debian-installer (udeb) Closes: 804255 Changes: xfsprogs (4.3.0) unstable; urgency=low . * New upstream release * Add a postinst to update the initramfs on install/upgrade. (Closes: #804255) Checksums-Sha1: 31064221f22a5b20c731e9e3710bf1d6de759341 1763 xfsprogs_4.3.0.dsc cc5e4c06f537de9b9903b29f761c1b7534876b17 1506750 xfsprogs_4.3.0.tar.gz 003e83012c59d84ca33850c1d29b59034397bda9 55212 xfslibs-dev_4.3.0_amd64.deb 379252c78d7eb0dd643f0d136e7db13eabd548bc 134808 xfsprogs-udeb_4.3.0_amd64.udeb 270c3c737ffe7916d9b230e75415a05b46857928 727106 xfsprogs_4.3.0_amd64.deb Checksums-Sha256: 84daf22e23b846ea319a1707d0b79eb2b61f869531ce27d2cfd42e716cf8265a 1763 xfsprogs_4.3.0.dsc a914e45648e04d211304ffd9fadba919be9d66010ec7b19dffad356c8cbf969e 1506750 xfsprogs_4.3.0.tar.gz 233aae38eead8db27346dccd560d7eef1ab5c976df2495f5643a20975223f805 55212 xfslibs-dev_4.3.0_amd64.deb c8e540fce739a617fd2ff7b8e4a8e86d0cfb27a25fa50b04c3ac21dc5bc0ae64 134808 xfsprogs-udeb_4.3.0_amd64.udeb d8cfef3519c98be8e999b1537b6eb57b8b7925a2715b7cc3a7c55d5e642e3a01 727106 xfsprogs_4.3.0_amd64.deb Files: fc99694150b586161106823f245bea72 1763 admin optional xfsprogs_4.3.0.dsc 2a6d2918d8a8a89e6816e0476aa3f316 1506750 admin optional xfsprogs_4.3.0.tar.gz 4a1dd6248c49586edd2081c5c58f1992 55212 libdevel extra xfslibs-dev_4.3.0_amd64.deb 16394c61c03586daba2fc87f68ad386f 134808 debian-installer optional xfsprogs-udeb_4.3.0_amd64.udeb 215fad11dceaeea00cffa2ccabefac2b 727106 admin optional xfsprogs_4.3.0_amd64.deb Package-Type: udeb -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAEBCAAGBQJWV6TdAAoJEP4IQu423YwMF4kP/1CNyghG5Q1Fk3x2P1FUxx5N 4VaANMpUHRTAuPi0r2dRPQehKqeSfnhgMEzREx44eJOS1SgRcwfu6Cls2Hzv9jn0 /pbqVRe3b7Enovb1UQ9Ibfbo3JdqbgYhkEwFCtO4drgYPilT3+Lv9dtTp4WrfEtq zOosPYTU+rsidGkEnLdIojL3yIBxsEVjpOWst3LZKzfpE9Ei8xrELApGYB31+cOT gSWHdlP1C+x6rtAj0lHHvl5MXn/4izRwUsPSKNNqtthp1fcvRcfhXCYpxlpTvmjM YnfOOkYhH3k1zi4QzdpsFJOWlF5QgwoJPy575+v9v1PpN4rov+re4/dbbdwjG+nR /inX+wfw+3NxN9jzD6S6kLQh5oPwGbhQgsaSqwkNd4XqpAbRCyX3LvoYTUOgpsPW yRP3XlJ0nnoFGSBlcltOAQvVIE7fPCebpE2hcO5B4gvVb5O0VRH+N0YxcavwjpPU pG8uqBixzqEvhL+uXZv1MfZMK9WWB912KhK/fErMP5tty/ln+j/eLJ7bBha54MYE G0FU2YprwVp3JBy9GWTmgn7Id4CWftFNYQgEcW/nu/zpXDhmtUor8rdLrbVivnKW 8IcB7SXyN9JMckLhozncOsPmvlS7XKUTKdHB5jvAfRdgioGt+ofwPZRROtqOuYbg P4sV4o6ipK7CyrpzHswD =d896 -----END PGP SIGNATURE----- ------------=_1448585644-29734-0-- From market@wonderfultrans.com Thu Nov 26 21:57:57 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 5C8457F37 for ; Thu, 26 Nov 2015 21:57:57 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id EBF90AC003 for ; Thu, 26 Nov 2015 19:57:51 -0800 (PST) X-ASG-Debug-ID: 1448596668-04bdf07f0726d880001-NocioJ Received: from smtp-3-57.sina.net (mta319.sina.net [202.106.182.177]) by cuda.sgi.com with SMTP id fh5mwGXBqEuDE4ja for ; Thu, 26 Nov 2015 19:57:49 -0800 (PST) X-Barracuda-Envelope-From: market@wonderfultrans.com X-Barracuda-Apparent-Source-IP: 202.106.182.177 X-ASG-Whitelist: Client Received: from unknown (HELO vweb.sina.net)([10.69.2.165]) by sina.net with SMTP 27 Nov 2015 11:57:46 +0800 (CST) X-Sender: market@wonderfultrans.com X-SMAIL-MID: 234B851B33FA428EB46BF0D27D83F127 Received: by webmail-2-165.iproxy.email.yf.sinanode.com (Postfix, from userid 99) id DDC8B61802; Fri, 27 Nov 2015 11:57:46 +0800 (CST) Date: Fri, 27 Nov 2015 11:57:46 +0800 Received: from market@wonderfultrans.com([180.173.37.169]) by bj4.mail.sina.net via HTTP; Fri, 27 Nov 2015 11:57:46 +0800 (CST) Reply-To: market@wonderfultrans.com From: To: "'market'" Subject: More Than 12 Years of Translation Industry Experience from Shanghai Wonderful Translation Company(Quality and Reliability 2015) MIME-Version: 1.0 X-ASG-Orig-Subj: More Than 12 Years of Translation Industry Experience from Shanghai Wonderful Translation Company(Quality and Reliability 2015) X-Priority: 3 X-MessageID: 1448596666.8301.6316 X-Originating-IP: [218.30.122.121] X-Mailer: Sina WebMail 4.0 Content-Type: multipart/alternative; boundary="=-sinamail_alt_2afcf884d1b36e2ae01bd31fbf1e0458" Message-Id: <20151127035746.DDC8B61802@webmail-2-165.iproxy.email.yf.sinanode.com> X-Barracuda-Connect: mta319.sina.net[202.106.182.177] X-Barracuda-Start-Time: 1448596668 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 --=-sinamail_alt_2afcf884d1b36e2ae01bd31fbf1e0458 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: base64 Content-Disposition: inline DQpEZWFyIE1hbmFnZXIsIApXaXRoIHRoZSBiZXN0IGludGVudGlvbiwgd2UgYXJlIHdyaXRpbmcg dGhpcyBsZXR0ZXIgdG8gc2VlIGlmIHRoZXJlIGlzIGFueSBwb3NzaWJpbGl0eSB0aGF0IHdlIGNv dWxkIHdvcmsgdG9nZXRoZXIgYXMgZ2xvYmFsIHBhcnRuZXJzLiAKU2hhbmdoYWkgV29uZGVyZnVs IFRyYW5zbGF0aW9uIENvbXBhbnksIGEgbGVhZGluZyB0cmFuc2xhdGlvbiAmIGludGVycHJldGF0 aW9uIGNvbXBhbnkgaW4gQ2hpbmEsIGRlZGljYXRlcyBpdHNlbGYgaW4gcHJvdmlkaW5nIG91ciBj bGllbnRzIHdpdGggaGlnaGx5IHByb2Zlc3Npb25hbCBsYW5ndWFnZSBzb2x1dGlvbnMuIEZvY3Vz aW5nIG9uIHRoZSBlbmdpbmVlcmluZywgbWFudWZhY3R1cmluZywgd2Vic2l0ZSAmIHNvZnR3YXJl IGxvY2FsaXphdGlvbiBmaWVsZHMsIHdlIGhhdmUgZGVmaW5lZCBhbiBpbXBvcnRhbnQgY2xpZW50 IGJhc2UuIApQbGVhc2UgdGVsbCB1cyBpZiB5b3UgbmVlZCBvdXIgcHJvZmVzc2lvbmFsIHRyYW5z bGF0aW9uIHNlcnZpY2VzIGFmdGVyIHlvdSBnbyB0aHJvdWdoIHRoaXMgbGV0dGVyLiBUaGFuayB5 b3UhIApUaGUgYWR2YW50YWdlcyBvZiB3b3JraW5nIHdpdGggdXM6IAoxLiBSZWR1Y2UgWW91ciBD b3N0ClRoZSBwcmljZXMgd2Ugb2ZmZXIgYXJlIG11Y2ggbG93ZXIgdGhhbiB0aGF0IG9mIG90aGVy IHRyYW5zbGF0aW9uIGNvbXBhbmllcy4gRm9yIGV4YW1wbGUsIGl0IG1heSBjb3N0IDEwMCBVU0Qg Zm9yIHRyYW5zbGF0aW5nIGEgZG9jdW1lbnQgaW4geW91ciBjb3VudHJ5LCBhbmQgaXQgY29zdHMg b25seSA0MCBVU0QgZm9yIHRyYW5zbGF0aW5nIHRoZSBzYW1lIGRvY3VtZW50IGluIG15IGNvbXBh bnkuIAoyLiBDb3JlIENvbXBldGl0aXZlIEVkZ2UKQXMgeW91IGtub3csIENoaW5lc2UgaXMgb3Vy IG5hdGl2ZSBsYW5ndWFnZSwgd2UgYXNzdXJlIHlvdSBvZiAxMDAlIGhpZ2ggcXVhbGl0eSBpbiB0 aGUgbXV0dWFsIHRyYW5zbGF0aW9uIGJldHdlZW4gQ2hpbmVzZSBhbmQgb3RoZXIgbGFuZ3VhZ2Vz LiBPdXIgY29tcGFueSBzcGVjaWFsaXplcyBpbiBBc2lhbiBsYW5ndWFnZSB0cmFuc2xhdGlvbi4g T3VyIGNvbXBhbnkgaGFzIHdvbiBhIGdvb2QgcmVwdXRhdGlvbiBpbiB3ZWJzaXRlICYgc29mdHdh cmUgbG9jYWxpemF0aW9uIGZvciBjb21wYW5pZXMgaW4gSmFwYW4uIAozLiBHdWFyYW50ZWVkIFF1 YWxpdHkKV2UgdXRpbGl6ZSB0aGUgbGF0ZXN0IHRlY2hub2xvZ2ljYWwgYWR2YW5jZW1lbnRzIHRv IG1lZXQgYWxsIG9mIHlvdXIgbmVlZHMgaW4gbW9zdCBzdGFuZGFyZCBzb2Z0d2FyZSBhcHBsaWNh dGlvbnMsIHN1Y2ggYXMgUXVhcmtYcHJlc3MsIEFkb2JlIEluRGVzaWduLCBBZG9iZSBQYWdlbWFr ZXIsIEFkb2JlIEZyYW1lTWFrZXIsIGV0Yy4gRnVydGhlciBtb3JlLCB3ZSBjYW4gYWNjb21tb2Rh dGUgeW91ciBuZWVkcyBmb3IgYm90aCBNYWMgYW5kIFBDIHBsYXRmb3JtcyB3aXRoIGEgdmFyaWV0 eSBvZiBmb250cyBmb3IgYWxsIGRpZmZlcmVudCBsYW5ndWFnZXMuIAo0LiBIaWdoIFNwZWVkCjUw MDAgRW5nbGlzaCB3b3Jkcy9kYXkvb25lIHRyYW5zbGF0b3IuIAo1LiBDb25maWRlbnRpYWxpdHkK V2Ugc2lnbiBjb250cmFjdHMgdG8gcHJvdGVjdCBvdXIgY3VzdG9tZXJz4oCZIHByaXZhY3kuIAo2 LiBMZXNzIFdvcnJ5CldlIGhhdmUgVVNEIGludGVybWVkaWFyeSBiYW5rLCB0aGUgZm9yZWlnbiBl eGNoYW5nZSBjYW4gYmUgdHJhbnNtaXR0ZWQgZGlyZWN0bHkgaW50byBvdXIgY29tcGFueeKAmXMg YmFuay4gSXTigJlzIGVhc3kgYW5kIHNhZmUuIApGb3IgZnVydGhlciBpbmZvcm1hdGlvbiwgcGxl YXNlIHNlZSB0aGUgYXR0YWNoZWQgY29tcGFueSBwcm9maWxlIGFuZCB5b3UgYXJlIHdlbGNvbWUg dG8gbG9nIG9uIG91ciB3ZWJzaXRlOiB3d3cuc2h3ZGYuY29tIApXZSB3b3VsZCBncmVhdGx5IGFw cHJlY2lhdGUgaXQgaWYgeW91IHdvdWxkIHNlcmlvdXNseSBjb25zaWRlciBvdXIgcHJvcG9zYWwu IApCZXN0IHJlZ2FyZHMNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoN Cg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0K DQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoN Cg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0K DQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoN Cg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0K DQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KIA0KTHVjeQpBY2NvdW50 IEV4ZWN1dGl2ZSAKTW9iaWxlIFBob25lOiAxODkxNzM4ODQ2MiAKRW1haWw6IHdkZkBzaHdkZi5j b20gClFROjQxMjk1NDUwMA0KQWRkOiBBMTEwNSwgMjI4IFpoYW5neWFuZyBSb2FkLCBUb21zb24g Q2VudGVyLCBMdWppYXp1aSBGaW5hbmNpYWwmVHJhZGUgWm9uZSwgUHVkb25nLCBTaGFuZ2hhaSwg MjAwMTIy --=-sinamail_alt_2afcf884d1b36e2ae01bd31fbf1e0458 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: base64 Content-Disposition: inline PERJViBpZD1vcmlnYm9keT4NCjxESVYgc3R5bGU9IkJBQ0tHUk9VTkQ6ICNmMmYyZjIiPkRlYXIg TWFuYWdlciwgPEJSPldpdGggdGhlIGJlc3QgaW50ZW50aW9uLCB3ZSBhcmUgd3JpdGluZyB0aGlz IGxldHRlciB0byBzZWUgaWYgdGhlcmUgaXMgYW55IHBvc3NpYmlsaXR5IHRoYXQgd2UgY291bGQg d29yayB0b2dldGhlciBhcyBnbG9iYWwgcGFydG5lcnMuIDxCUj5TaGFuZ2hhaSBXb25kZXJmdWwg VHJhbnNsYXRpb24gQ29tcGFueSwgYSBsZWFkaW5nIHRyYW5zbGF0aW9uICZhbXA7IGludGVycHJl dGF0aW9uIGNvbXBhbnkgaW4gQ2hpbmEsIGRlZGljYXRlcyBpdHNlbGYgaW4gcHJvdmlkaW5nIG91 ciBjbGllbnRzIHdpdGggaGlnaGx5IHByb2Zlc3Npb25hbCBsYW5ndWFnZSBzb2x1dGlvbnMuIEZv Y3VzaW5nIG9uIHRoZSBlbmdpbmVlcmluZywgbWFudWZhY3R1cmluZywgd2Vic2l0ZSAmYW1wOyBz b2Z0d2FyZSBsb2NhbGl6YXRpb24gZmllbGRzLCB3ZSBoYXZlIGRlZmluZWQgYW4gaW1wb3J0YW50 IGNsaWVudCBiYXNlLiA8QlI+UGxlYXNlIHRlbGwgdXMgaWYgeW91IG5lZWQgb3VyIHByb2Zlc3Np b25hbCB0cmFuc2xhdGlvbiBzZXJ2aWNlcyBhZnRlciB5b3UgZ28gdGhyb3VnaCB0aGlzIGxldHRl ci4gVGhhbmsgeW91ISA8QlI+VGhlIGFkdmFudGFnZXMgb2Ygd29ya2luZyB3aXRoIHVzOiA8QlI+ MS4gUmVkdWNlIFlvdXIgQ29zdDxCUj5UaGUgcHJpY2VzIHdlIG9mZmVyIGFyZSBtdWNoIGxvd2Vy IHRoYW4gdGhhdCBvZiBvdGhlciB0cmFuc2xhdGlvbiBjb21wYW5pZXMuIEZvciBleGFtcGxlLCBp dCBtYXkgY29zdCAxMDAgVVNEIGZvciB0cmFuc2xhdGluZyBhIGRvY3VtZW50IGluIHlvdXIgY291 bnRyeSwgYW5kIGl0IGNvc3RzIG9ubHkgNDAgVVNEIGZvciB0cmFuc2xhdGluZyB0aGUgc2FtZSBk b2N1bWVudCBpbiBteSBjb21wYW55LiA8QlI+Mi4gQ29yZSBDb21wZXRpdGl2ZSBFZGdlPEJSPkFz IHlvdSBrbm93LCBDaGluZXNlIGlzIG91ciBuYXRpdmUgbGFuZ3VhZ2UsIHdlIGFzc3VyZSB5b3Ug b2YgMTAwJSBoaWdoIHF1YWxpdHkgaW4gdGhlIG11dHVhbCB0cmFuc2xhdGlvbiBiZXR3ZWVuIENo aW5lc2UgYW5kIG90aGVyIGxhbmd1YWdlcy4gT3VyIGNvbXBhbnkgc3BlY2lhbGl6ZXMgaW4gQXNp YW4gbGFuZ3VhZ2UgdHJhbnNsYXRpb24uIE91ciBjb21wYW55IGhhcyB3b24gYSBnb29kIHJlcHV0 YXRpb24gaW4gd2Vic2l0ZSAmYW1wOyBzb2Z0d2FyZSBsb2NhbGl6YXRpb24gZm9yIGNvbXBhbmll cyBpbiBKYXBhbi4gPEJSPjMuIEd1YXJhbnRlZWQgUXVhbGl0eTxCUj5XZSB1dGlsaXplIHRoZSBs YXRlc3QgdGVjaG5vbG9naWNhbCBhZHZhbmNlbWVudHMgdG8gbWVldCBhbGwgb2YgeW91ciBuZWVk cyBpbiBtb3N0IHN0YW5kYXJkIHNvZnR3YXJlIGFwcGxpY2F0aW9ucywgc3VjaCBhcyBRdWFya1hw cmVzcywgQWRvYmUgSW5EZXNpZ24sIEFkb2JlIFBhZ2VtYWtlciwgQWRvYmUgRnJhbWVNYWtlciwg ZXRjLiBGdXJ0aGVyIG1vcmUsIHdlIGNhbiBhY2NvbW1vZGF0ZSB5b3VyIG5lZWRzIGZvciBib3Ro IE1hYyBhbmQgUEMgcGxhdGZvcm1zIHdpdGggYSB2YXJpZXR5IG9mIGZvbnRzIGZvciBhbGwgZGlm ZmVyZW50IGxhbmd1YWdlcy4gPEJSPjQuIEhpZ2ggU3BlZWQ8QlI+NTAwMCBFbmdsaXNoIHdvcmRz L2RheS9vbmUgdHJhbnNsYXRvci4gPEJSPjUuIENvbmZpZGVudGlhbGl0eTxCUj5XZSBzaWduIGNv bnRyYWN0cyB0byBwcm90ZWN0IG91ciBjdXN0b21lcnPigJkgcHJpdmFjeS4gPEJSPjYuIExlc3Mg V29ycnk8QlI+V2UgaGF2ZSBVU0QgaW50ZXJtZWRpYXJ5IGJhbmssIHRoZSBmb3JlaWduIGV4Y2hh bmdlIGNhbiBiZSB0cmFuc21pdHRlZCBkaXJlY3RseSBpbnRvIG91ciBjb21wYW554oCZcyBiYW5r LiBJdOKAmXMgZWFzeSBhbmQgc2FmZS4gPEJSPkZvciBmdXJ0aGVyIGluZm9ybWF0aW9uLCBwbGVh c2Ugc2VlIHRoZSBhdHRhY2hlZCBjb21wYW55IHByb2ZpbGUgYW5kIHlvdSBhcmUgd2VsY29tZSB0 byBsb2cgb24gb3VyIHdlYnNpdGU6IDxBIGhyZWY9IndsbWFpbGh0bWw6e0QxNkJGRDcwLTUwQ0Ut NEVDNS1BMkI3LTI3QUQ0MzI0NjAyMX1taWQ6Ly8wMDAwMDIwOS8heC11c2M6aHR0cDovL3d3dy5z aHdkZi5jb20vIiB0YXJnZXQ9X2JsYW5rIF9hY3Q9ImNoZWNrX2RvbWFpbCI+PEZPTlQgY29sb3I9 IzQwNDA0MD53d3cuc2h3ZGYuY29tPC9GT05UPjwvQT4gPEJSPldlIHdvdWxkIGdyZWF0bHkgYXBw cmVjaWF0ZSBpdCBpZiB5b3Ugd291bGQgc2VyaW91c2x5IGNvbnNpZGVyIG91ciBwcm9wb3NhbC4g PEJSPkJlc3QgcmVnYXJkczwvRElWPg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxQIHN0eWxlPSJCQUNL R1JPVU5EOiByZ2IoMjQyLDI0MiwyNDIpIj4mbmJzcDs8L1A+DQo8UCBzdHlsZT0iQkFDS0dST1VO RDogcmdiKDI0MiwyNDIsMjQyKSI+THVjeTxCUj5BY2NvdW50IEV4ZWN1dGl2ZSA8QlI+TW9iaWxl IFBob25lOiAxODkxNzM4ODQ2MiA8QlI+RW1haWw6IDxBIGhyZWY9IndsbWFpbGh0bWw6e0QxNkJG RDcwLTUwQ0UtNEVDNS1BMkI3LTI3QUQ0MzI0NjAyMX1taWQ6Ly8wMDAwMDIwOS8heC11c2M6bWFp bHRvOndkZkBzaHdkZi5jb20iIHRhcmdldD1fYmxhbmsgX2FjdD0iY2hlY2tfZG9tYWlsIj48Rk9O VCBjb2xvcj0jNDA0MDQwPndkZkBzaHdkZi5jb208L0ZPTlQ+PC9BPiA8QlI+UVE6NDEyOTU0NTAw PC9QPg0KPFAgc3R5bGU9IkJBQ0tHUk9VTkQ6IHJnYigyNDIsMjQyLDI0MikiPkFkZDogQTExMDUs IDIyOCBaaGFuZ3lhbmcgUm9hZCwgVG9tc29uIENlbnRlciwgTHVqaWF6dWkgRmluYW5jaWFsJmFt cDtUcmFkZSBab25lLCBQdWRvbmcsIFNoYW5naGFpLCAyMDAxMjI8L1A+PC9ESVY+PC9ESVY+PC9E SVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+ PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9E SVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+ PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9E SVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+ PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9E SVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+ PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9E SVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+ PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9E SVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+ PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9E SVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+ PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9E SVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+ PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9E SVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+ PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9E SVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+ PC9ESVY+PC9ESVY+ --=-sinamail_alt_2afcf884d1b36e2ae01bd31fbf1e0458-- From bfoster@redhat.com Fri Nov 27 09:22:59 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 232637F37 for ; Fri, 27 Nov 2015 09:22:59 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 135D9304048 for ; Fri, 27 Nov 2015 07:22:55 -0800 (PST) X-ASG-Debug-ID: 1448637773-04cbb0605b2635d0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id AlzIFylFfKTd21jF (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 27 Nov 2015 07:22:54 -0800 (PST) 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 (Postfix) with ESMTPS id 84AA68F4EF; Fri, 27 Nov 2015 15:22:53 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-225.bos.redhat.com [10.18.41.225]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tARFMpT9019346; Fri, 27 Nov 2015 10:22:52 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id EA802122406; Fri, 27 Nov 2015 10:22:50 -0500 (EST) Date: Fri, 27 Nov 2015 10:22:50 -0500 From: Brian Foster To: "aluno3@poczta.onet.pl" Cc: xfs@oss.sgi.com Subject: Re: Which xfsprogs version to which kernel version Message-ID: <20151127152250.GA64860@bfoster.bfoster> X-ASG-Orig-Subj: Re: Which xfsprogs version to which kernel version References: <5656DD39.8060403@poczta.onet.pl> <20151126132638.53ed9fc7@harpe.intellique.com> <565706BB.3030006@poczta.onet.pl> <20151126135053.GB39911@bfoster.bfoster> <5657190A.1050103@poczta.onet.pl> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <5657190A.1050103@poczta.onet.pl> 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: 1448637774 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Thu, Nov 26, 2015 at 03:36:58PM +0100, aluno3@poczta.onet.pl wrote: > dmesg when mounting volume which was formated xfsprogs 4.3.0: > > * > root@192.168.176.24:~$ mkfs.xfs -V > mkfs.xfs version 4.3.0 > > root@192.168.176.24:~$ mkfs.xfs -f -m crc=0,finobt=0 /dev/sdc4 > meta-data=/dev/sdc4 isize=256 agcount=4, agsize=474552 blks > = sectsz=512 attr=2, projid32bit=1 > = crc=0 finobt=0, sparse=0 > data = bsize=4096 blocks=1898208, imaxpct=25 > = sunit=0 swidth=0 blks > naming =version 2 bsize=4096 ascii-ci=0 ftype=1 > log =internal log bsize=4096 blocks=2560, version=2 > = sectsz=512 sunit=0 blks, lazy-count=1 > realtime =none extsz=4096 blocks=0, rtextents=0 > > root@192.168.176.24:~$ mount /dev/sdc4 /mnt/sdc4 > mount: wrong fs type, bad option, bad superblock on /dev/sdc4, > missing codepage or helper program, or other error > > In some cases useful info is found in syslog - try > dmesg | tail or so. > > root@192.168.176.24:~$ dmesg > [ 212.984534] XFS (sdc4): bad version > [ 212.984547] ffff88005cccb000: 58 46 53 42 00 00 10 00 00 00 00 00 00 > 1c f6 e0 XFSB............ > [ 212.984550] ffff88005cccb010: 00 00 00 00 00 00 00 00 00 00 00 00 00 > 00 00 00 ................ > [ 212.984551] ffff88005cccb020: 55 9d 20 d9 1c e9 4e a9 a3 ee 8d fd ba > 68 b3 70 U. ...N......h.p > [ 212.984553] ffff88005cccb030: 00 00 00 00 00 10 00 04 00 00 00 00 00 > 00 00 80 ................ > [ 212.984556] XFS (sdc4): Internal error xfs_sb_read_verify at line 730 > of file fs/xfs/xfs_mount.c. Caller 0xffffffff81256c7d > Interesting... have you tried to format without ftype support? It looks like that wasn't introduced until v3.13. E.g., mkfs.xfs -f -m crc=0 -n ftype=0 Brian > [ 212.984560] CPU: 0 PID: 440 Comm: kworker/0:1H Tainted: P O > 3.10.92-oe64-ge331686 #15 > [ 212.984562] Hardware name: System manufacturer System Product > Name/P5WDG2 WS Pro, BIOS 0905 03/06/2008 > [ 212.984567] Workqueue: xfslogd xfs_buf_iodone_work > [ 212.984570] ffffffff81692f75 ffffffff81258c5d ffffffff81256c7d > ffffffff818a39e3 > [ 212.984573] ffff88007aa9ef00 0000000000000016 ffff88007aa8b000 > 0000000000000000 > [ 212.984576] ffff88007ea17800 ffffffff812a32ac ffffffff81256c7d > ffff88007ea11a40 > [ 212.984579] Call Trace: > [ 212.984584] [] ? dump_stack+0xc/0x15 > [ 212.984587] [] ? xfs_corruption_error+0x8d/0x90 > [ 212.984590] [] ? xfs_buf_iodone_work+0x6d/0x90 > [ 212.984595] [] ? xfs_sb_read_verify+0xfc/0x120 > [ 212.984598] [] ? xfs_buf_iodone_work+0x6d/0x90 > [ 212.984600] [] ? xfs_buf_iodone_work+0x6d/0x90 > [ 212.984604] [] ? process_one_work+0x13d/0x3b0 > [ 212.984607] [] ? worker_thread+0x121/0x3d0 > [ 212.984609] [] ? manage_workers.isra.26+0x280/0x280 > [ 212.984613] [] ? kthread+0xc2/0xd0 > [ 212.984616] [] ? sched_clock_cpu+0x30/0x100 > [ 212.984619] [] ? kthread_create_on_node+0x110/0x110 > [ 212.984623] [] ? ret_from_fork+0x58/0x90 > [ 212.984626] [] ? kthread_create_on_node+0x110/0x110 > [ 212.984628] XFS (sdc4): Corruption detected. Unmount and run xfs_repair > [ 212.984634] XFS (sdc4): SB validate failed with error 22. > * > > On 11/26/15 14:50, Brian Foster wrote: > > On Thu, Nov 26, 2015 at 02:18:51PM +0100, aluno3@poczta.onet.pl wrote: > >> Yes I used -f option with 4.X version of xfsprogs but mounting the > >> volume was not possible - before mkfs.xfs finished successfully > >> (mkfs.xfs -f -m crc=0,finobt=0). > >> > > > > You posted the output associated with the crc=1 fs mount failure, what > > happens when you try to mount after formatting with crc=0? > > > > Brian > > > >> Should I stay in 3.1.X family of xfsprogs or is it recommended to use at > >> least 3.2.x version with kernel 3.10? > >> > >> The most I care about xfs_repair. > >> > >> On 11/26/15 13:26, Emmanuel Florac wrote: > >>> Le Thu, 26 Nov 2015 11:21:45 +0100 > >>> "aluno3@poczta.onet.pl" écrivait: > >>> > >>>> mkfs.xfs -m crc=0,finobt=0 > >>>> > >>>> but it does not work with 4.X version of xfsprogs. Call trace also > >>>> occurred so I tried to use 3.2.4 family with crc=0,finobt=0 and volume > >>>> mounted successfully. > >>>> > >>> > >>> Did you use -f? else mkfs.xfs won't do anything as it'll detect an > >>> existing filesystem. > >>> > >> > >> _______________________________________________ > >> 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 kuleshovmail@gmail.com Fri Nov 27 11:55:01 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 E15897F3F for ; Fri, 27 Nov 2015 11:55:01 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id CD8FC304039 for ; Fri, 27 Nov 2015 09:55:01 -0800 (PST) X-ASG-Debug-ID: 1448646899-04cb6c5355157c0001-NocioJ Received: from mail-lf0-f41.google.com (mail-lf0-f41.google.com [209.85.215.41]) by cuda.sgi.com with ESMTP id aIPUcEIefxyaiBcw (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Fri, 27 Nov 2015 09:55:00 -0800 (PST) X-Barracuda-Envelope-From: kuleshovmail@gmail.com X-Barracuda-Apparent-Source-IP: 209.85.215.41 Received: by lffu14 with SMTP id u14so137060136lff.1 for ; Fri, 27 Nov 2015 09:54:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=dBHYyYAiwxMmYJHfdRTsM0iD9rzNtT9TkncGtSa9508=; b=dncRLAOGEnuXsuk8xG0GU6zaQpBgedKITJHnmOhvFEu+XHD+hQ45w34UT+P8nIVwo+ XDQZr/3KErH7eOslleguq8SLfTZ85iPdQobai04yhM1gEMkR6WKDeS7JEmpzzSmMI4ch 8wFsd0O73icklO/9HAZ63uZsV8l3H5c/oxnmd6lTBbvjO3qRGHkkhV5cCPYRlqG1lfIu l8gJUVca9TBs4qvaZTa6FAwzmoegu3gXtXAyIxQGsgZXGtdQqW4QAK5wVKVfllUHo20t qklSRydCiFy8y8hH/gm2T5Lk8vn6w7my2OywCljXYR2GFUiE4JDhIZ7J+90sQEbRnYGl 76Dg== X-Received: by 10.112.17.65 with SMTP id m1mr9384953lbd.132.1448646898458; Fri, 27 Nov 2015 09:54:58 -0800 (PST) Received: from localhost.localhost ([5.76.51.200]) by smtp.gmail.com with ESMTPSA id l81sm5001758lfb.40.2015.11.27.09.54.56 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 27 Nov 2015 09:54:57 -0800 (PST) From: Alexander Kuleshov To: Dave Chinner Cc: xfs@oss.sgi.com, linux-kernel@vger.kernel.org, Alexander Kuleshov Subject: [PATCH] xfs/xfs_buf: make xfs_buf_ioend_async() static Date: Fri, 27 Nov 2015 23:52:29 +0600 X-ASG-Orig-Subj: [PATCH] xfs/xfs_buf: make xfs_buf_ioend_async() static Message-Id: <1448646749-18978-1-git-send-email-kuleshovmail@gmail.com> X-Mailer: git-send-email 2.6.2.485.g1bc8fea X-Barracuda-Connect: mail-lf0-f41.google.com[209.85.215.41] X-Barracuda-Start-Time: 1448646899 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24775 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 There are no callers of the xfs_buf_ioend_async() function outside of the fs/xfs/xfs_buf.c. So, let's make it static. Signed-off-by: Alexander Kuleshov --- fs/xfs/xfs_buf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index 3243cdf..45a8ea7 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c @@ -1045,7 +1045,7 @@ xfs_buf_ioend_work( xfs_buf_ioend(bp); } -void +static void xfs_buf_ioend_async( struct xfs_buf *bp) { -- 2.5.0 From imbuee971@inbox.ru Fri Nov 27 13:07:49 2015 Return-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.6 required=5.0 tests=FORGED_YAHOO_RCVD, 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 818FB7F37 for ; Fri, 27 Nov 2015 13:07:49 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 60B0B8F8035 for ; Fri, 27 Nov 2015 11:07:46 -0800 (PST) X-ASG-Debug-ID: 1448651262-04bdf07f082838c0001-NocioJ Received: from bba573079.alshamil.net.ae (bba573079.alshamil.net.ae [86.98.216.55]) by cuda.sgi.com with ESMTP id I5xVDTccn24l9ozF for ; Fri, 27 Nov 2015 11:07:42 -0800 (PST) X-Barracuda-Envelope-From: imbuee971@inbox.ru X-Barracuda-Apparent-Source-IP: 86.98.216.55 Message-ID: <20151127230520.776FY5LC43V@www.inbox.ru> Content-Transfer-Encoding: 8bit MIME-Version: 1.0 Content-Type: text/plain; charset="koi8-r" From: =?koi8-r?B?9dPM1cfJIM7BzM/Hz9fPx88gwNLJ09TB?= X-Mailer: Kayako eSupport Date: Fri, 27 Nov 2015 23:05:20 +0400 To: Subject: =?koi8-r?B?8NLFxMzBx8HFzSD3wc0g18HSycHO1Nkg0M8g08/L0sHdxc7JwCDOwQ==?= =?koi8-r?B?zM/Hz9cu?= X-Barracuda-Connect: bba573079.alshamil.net.ae[86.98.216.55] X-Barracuda-Start-Time: 1448651262 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-ASG-Orig-Subj: =?koi8-r?B?8NLFxMzBx8HFzSD3wc0g18HSycHO1Nkg0M8g08/L0sHdxc7JwCDOwQ==?= =?koi8-r?B?zM/Hz9cu?= X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 1.61 X-Barracuda-Spam-Status: No, SCORE=1.61 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_SA671_URI_FM_PUNY, FORGED_YAHOO_RCVD, FORGED_YAHOO_RCVD_2 X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24776 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 FORGED_YAHOO_RCVD 'From' yahoo.com does not match 'Received' headers 0.20 BSF_SC0_SA671_URI_FM_PUNY RAW: Custom Rule SA671_URI_FM_PUNY 1.41 FORGED_YAHOO_RCVD_2 'From' yahoo.com does not match 'Received' headers íÙ ÍÏÖÅÍ ÐÒÏËÏÎÓÕÌØÔÉÒÏ×ÁÔØ ÷ÁÓ ÐÏ ÎÁÌÏÇÁÍ. ðÉÓØÍÅÎÎÏÅ ÚÁËÌÀÞÅÎÉÅ ÉÌÉ ÕÓÔÎÏÅ ËÏÎÓÕÌØÔÉÒÏ×ÁÎÉÅ (ÐÏ ÔÅÌÅÆÏÎÕ ÐÏ ÓËÁÊÐÕ). òÁÓÃÅÎËÉ- ÏÔ 300 ÒÕÂÌÅÊ. äÌÑ ÐÏÌÕÞÅÎÉÑ ÐÏÄÒÏÂÎÏÊ ÉÎÆÏÒÍÁÃÉÉ ÐÅÒÅÊÄÉÔÅ ÐÏ ÜÔÏÊ ÓÓÙÌËÅ: http://ÎÁÌÏÇÏ×ÉËÉ-ËÏÎÓÕÌØÔÉÒÕÀÔ.ÒÆ From glommer@cloudius-systems.com Fri Nov 27 20:44:01 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 95DA67F37 for ; Fri, 27 Nov 2015 20:44:01 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 8353F8F8039 for ; Fri, 27 Nov 2015 18:43:58 -0800 (PST) X-ASG-Debug-ID: 1448678630-04cbb0605d2745d0001-NocioJ Received: from mail-lf0-f44.google.com (mail-lf0-f44.google.com [209.85.215.44]) by cuda.sgi.com with ESMTP id MNBAH3CW0i2I6wRb (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Fri, 27 Nov 2015 18:43:51 -0800 (PST) X-Barracuda-Envelope-From: glommer@cloudius-systems.com X-Barracuda-Apparent-Source-IP: 209.85.215.44 Received: by lfdl133 with SMTP id l133so144206091lfd.2 for ; Fri, 27 Nov 2015 18:43:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=scylladb-com.20150623.gappssmtp.com; s=20150623; h=mime-version:date:message-id:subject:from:to:content-type; bh=A8U3GF2fNTR6C8ZsbJHT0hssVdoXaxnpCWBw4cABdPA=; b=qhsh4kdqDHQ3Fkiexarq/2yRhgcy331o3TWqpJ551hpTiyb1lqF4GtXpD0PDQXj6AL fwAUInNtdOxZMvUt8FjOx9JSe/fc1DgmLQ4bORlZ+9SolYIGq4SeayBVRKNZA2RlpUtg 6KHqI+OTLuWbi1G0mqTeP76a3LrGnq36w3Wf4dv9ivEBX+gmubGl3J/jxGo2wexft4p6 tPeGfGgam7LPNOoNN/oaVi3oL7IHRi3gOkJ6An/15/ep2T3vnu2RujPGZ+Gpe7FUGzEJ cMaKC5yLTaFvQRSZHCvVKkq4ZcTefQGKQGZovIXAesH2v1nUAt6yGm4nt7zFnY0rIFWz TpWQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:date:message-id:subject:from:to :content-type; bh=A8U3GF2fNTR6C8ZsbJHT0hssVdoXaxnpCWBw4cABdPA=; b=NOaGHMf44O9LFdEypTY8JDejoB9a7Qp0jQ+QLiZdYK1iUZq4AdY4fIuTfB9ciMa93Z Wjhh6MjjzhS2lUFZ/5uj0qmtLsLwKl9ok8ZK3QWs0BPyqxLnuiTvdsgWFbYC38cqP/q7 wmmApv0pzlAfBXiFSSeB7lu4yaQMGwj51HUXrj5p59kDnhL/JxTQaVwtzUsCrJDVOcC6 q4T2a65RGHntYMisJNB9q+GHHU8fNsYLd85F1HQdM/P9Nr8VSxD/D2QyntTF7zSMJKoo scrxLnwnnJwlPzGKWVe9lghL5rb9hvDK826NRgbdlts+Hc1bhDgTp3rW7mmC618q+LUA mmZA== X-Gm-Message-State: ALoCoQloMxtD/jvJSbWmukvl7sh6TQQeD1g0dX+oQcRFL2NbkrxWPkFXG2XPLEDvZ7OHRiLwje3a MIME-Version: 1.0 X-Received: by 10.112.160.202 with SMTP id xm10mr2432282lbb.22.1448678630302; Fri, 27 Nov 2015 18:43:50 -0800 (PST) Received: by 10.25.205.133 with HTTP; Fri, 27 Nov 2015 18:43:50 -0800 (PST) Date: Fri, 27 Nov 2015 21:43:50 -0500 Message-ID: Subject: sleeps and waits during io_submit From: Glauber Costa X-ASG-Orig-Subj: sleeps and waits during io_submit To: xfs@oss.sgi.com, Avi Kivity , david@fromorbit.com Content-Type: multipart/mixed; boundary=001a11c261ac279d57052590c74d X-Barracuda-Connect: mail-lf0-f44.google.com[209.85.215.44] X-Barracuda-Start-Time: 1448678631 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/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_SC0_SA_TO_FROM_DOMAIN_MATCH, DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24784 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.01 BSF_SC0_SA_TO_FROM_DOMAIN_MATCH Sender Domain Matches Recipient Domain --001a11c261ac279d57052590c74d Content-Type: text/plain; charset=UTF-8 Hello my dear XFSers, For those of you who don't know, we at ScyllaDB produce a modern NoSQL data store that, at the moment, runs on top of XFS only. We deal exclusively with asynchronous and direct IO, due to our thread-per-core architecture. Due to that, we avoid issuing any operation that will sleep. While debugging an extreme case of bad performance (most likely related to a not-so-great disk), I have found a variety of cases in which XFS blocks. To find those, I have used perf record -e sched:sched_switch -p , and I am attaching the perf report as xfs-sched_switch.log. Please note that this doesn't tell me for how long we block, but as mentioned before, blocking operations outside our control are detrimental to us regardless of the elapsed time. For those who are not acquainted to our internals, please ignore everything in that file but the xfs functions. For the xfs symbols, there are two kinds of events: the ones that are a children of io_submit, where we don't tolerate blocking, and the ones that are children of our helper IO thread, to where we push big operations that we know will block until we can get rid of them all. We care about the former and ignore the latter. Please allow me to ask you a couple of questions about those findings. If we are doing anything wrong, advise on best practices is truly welcome. 1) xfs_buf_lock -> xfs_log_force. I've started wondering what would make xfs_log_force sleep. But then I have noticed that xfs_log_force will only be called when a buffer is marked stale. Most of the times a buffer is marked stale seems to be due to errors. Although that is not my case (more on that), it got me thinking that maybe the right thing to do would be to avoid hitting this case altogether? The file example-stale.txt contains a backtrace of the case where we are being marked as stale. It seems to be happening when we convert the the inode's extents from unwritten to real. Can this case be avoided? I won't pretend I know the intricacies of this, but couldn't we be keeping extents from the very beginning to avoid creating stale buffers? 2) xfs_buf_lock -> down This is one I truly don't understand. What can be causing contention in this lock? We never have two different cores writing to the same buffer, nor should we have the same core doingCAP_FOWNER so. 3) xfs_file_aio_write_checks -> file_update_time -> xfs_vn_update_time You guys seem to have an interface to avoid that, by setting the FMODE_NOCMTIME flag. This is done by issuing the open by handle ioctl, which will set this flag for all regular files. That's great, but that ioctl required CAP_SYS_ADMIN, which is a big no for us, since we run our server as an unprivileged user. I don't understand, however, why such an strict check is needed. If we have full rights on the filesystem, why can't we issue this operation? In my view, CAP_FOWNER should already be enough.I do understand the handles have to be stable and a file can have its ownership changed, in which case the previous owner would keep the handle valid. Is that the reason you went with the most restrictive capability ? --001a11c261ac279d57052590c74d Content-Type: text/plain; charset=US-ASCII; name="xfs-sched_switch.log" Content-Disposition: attachment; filename="xfs-sched_switch.log" Content-Transfer-Encoding: base64 X-Attachment-Id: f_ihigp7h40 IyBUbyBkaXNwbGF5IHRoZSBwZXJmLmRhdGEgaGVhZGVyIGluZm8sIHBsZWFzZSB1c2UgLS1oZWFk ZXIvLS1oZWFkZXItb25seSBvcHRpb25zLgojCiMKIyBUb3RhbCBMb3N0IFNhbXBsZXM6IDAKIwoj IFNhbXBsZXM6IDJLIG9mIGV2ZW50ICdzY2hlZDpzY2hlZF9zd2l0Y2gnCiMgRXZlbnQgY291bnQg KGFwcHJveC4pOiAyNjY5CiMKIyBPdmVyaGVhZCAgQ29tbWFuZCAgU2hhcmVkIE9iamVjdCAgICAg IFN5bWJvbCAgICAgICAgCiMgLi4uLi4uLi4gIC4uLi4uLi4gIC4uLi4uLi4uLi4uLi4uLi4uICAu Li4uLi4uLi4uLi4uLgojCiAgIDEwMC4wMCUgIHNjeWxsYSAgIFtrZXJuZWwua2FsbHN5bXNdICBb a10gX19zY2hlZHVsZQogICAgICAgICAgICAgfAogICAgICAgICAgICAgLS0tX19zY2hlZHVsZQog ICAgICAgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwtLTk2LjE4JS0tIHNj aGVkdWxlCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAg ICAgICB8ICAgICAgICAgIHwtLTU2LjE0JS0tIHNjaGVkdWxlX3VzZXIKICAgICAgICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgIHwtLTUzLjMwJS0tIGludF9jYXJlZnVsCiAgICAgICAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfC0tNDUuMDUlLS0gMHg3ZjRhZGU2 Zjc0ZWQKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgcmVhY3Rvcl9iYWNrZW5kX2Vwb2xsOjptYWtlX3JlYWN0b3Jfbm90aWZpZXIKICAg ICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgfC0tNjcuNjMlLS0gc3lzY2FsbF93b3JrX3F1ZXVlOjpzdWJtaXRfaXRl bQogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfC0tMzIuMDUlLS0gcG9z aXhfZmlsZV9pbXBsOjp0cnVuY2F0ZQogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwtLTY1LjMzJS0tIF9aTjEyY29udGludWF0aW9u SVpONmZ1dHVyZUlKRUU0dGhlbklaTjE5ZmlsZV9kYXRhX3NpbmtfaW1wbDVmbHVzaEV2RVVsdkVf UzFfRUVUMF9PVF9FVWxTN19FX0pFRTNydW5FdgogICAgICAgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICByZWFjdG9yOjpkZWxfdGltZXIKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgMHg2MGIwMDAwZTIwNDAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICB8LS0yMC4wMCUtLSBkYjo6Y29tbWl0bG9nOjpzZWdt ZW50OjpmbHVzaCh1bnNpZ25lZCBsb25nKTo6e2xhbWJkYSgpIzF9OjpvcGVyYXRvcigpCiAgICAg ICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgIHwtLTczLjMzJS0tIGZ1dHVyZTw+Ojp0aGVuPGRiOjpjb21t aXRsb2c6OnNlZ21lbnQ6OmZsdXNoKHVuc2lnbmVkIGxvbmcpOjp7bGFtYmRhKCkjMX0sIGZ1dHVy ZTxsd19zaGFyZWRfcHRyPGRiOjpjb21taXRsb2c6OnNlZ21lbnQ+ID4gPgogICAgICAgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIF9aTjEyY29udGludWF0aW9uSVpONmZ1 dHVyZUlKMTNsd19zaGFyZWRfcHRySU4yZGI5Y29tbWl0bG9nN3NlZ21lbnRFRUVFNHRoZW5JWk5T NF80c3luY0V2RVVsVF9FX1M2X0VFVDBfT1M4X0VVbFNCX0VfSlM1X0VFM3J1bkV2CiAgICAgICAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgcmVhY3Rvcjo6ZGVsX3RpbWVy CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgMHg2MGUwMDAw ZTIwNDAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAg ICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgIC0tMjYuNjclLS0gX1pOMTJjb250aW51 YXRpb25JWk42ZnV0dXJlSUpFRTR0aGVuSVpOMmRiOWNvbW1pdGxvZzdzZWdtZW50NWZsdXNoRW1F VWx2RV9TMF9JSjEzbHdfc2hhcmVkX3B0cklTNV9FRUVFRVQwX09UX0VVbFNDX0VfSkVFM3J1bkV2 CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgcmVhY3Rvcjo6 ZGVsX3RpbWVyCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAg MHg2MDkwMDAwZTIwNDAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAg ICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICB8LS0xMC42NyUtLSBzc3RhYmxlczo6c3N0YWJsZTo6c2VhbF9z c3RhYmxlCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHN0ZDo6X0Z1bmN0aW9u X2hhbmRsZXI8dm9pZCAoKSwgZnV0dXJpemU8c3RkOjpyZXN1bHRfb2Y8c3RkOjpkZWNheTxzc3Rh Ymxlczo6c3N0YWJsZTo6d3JpdGVfY29tcG9uZW50cyhtdXRhdGlvbl9yZWFkZXIsIHVuc2lnbmVk IGxvbmcsIGx3X3NoYXJlZF9wdHI8c2NoZW1hIGNvbnN0PiwgdW5zaWduZWQgbG9uZyk6OntsYW1i ZGEoKSMxfT46OnR5cGUgKCk+Ojp0eXBlPjo6dHlwZSBzZWFzdGFyOjphc3luYzxzc3RhYmxlczo6 c3N0YWJsZTo6d3JpdGVfY29tcG9uZW50cyhtdXRhdGlvbl9yZWFkZXIsIHVuc2lnbmVkIGxvbmcs IGx3X3NoYXJlZF9wdHI8c2NoZW1hIGNvbnN0PiwgdW5zaWduZWQgbG9uZyk6OntsYW1iZGEoKSMx fT4oc3RkOjpkZWNheSYmLCAoc3RkOjpkZWNheTxzc3RhYmxlczo6c3N0YWJsZTo6d3JpdGVfY29t cG9uZW50cyhtdXRhdGlvbl9yZWFkZXIsIHVuc2lnbmVkIGxvbmcsIGx3X3NoYXJlZF9wdHI8c2No ZW1hIGNvbnN0PiwgdW5zaWduZWQgbG9uZyk6OntsYW1iZGEoKSMxfT46OnR5cGUmJikuLi4pOjp7 bGFtYmRhKGZ1dHVyaXplPHN0ZDo6cmVzdWx0X29mPHN0ZDo6ZGVjYXk8e2xhbWJkYSgpIzF9Pjo6 dHlwZSAoKT46OnR5cGU+IHNlYXN0YXI6OmFzeW5jPHtsYW1iZGEoKSMxfT4oZnV0dXJpemU8c3Rk OjpyZXN1bHRfb2Y8c3RkOjpkZWNheTx7bGFtYmRhKCkjMX0+Ojp0eXBlICgpPjo6dHlwZT46OnR5 cGUsIHN0ZDo6ZGVjYXk8e2xhbWJkYSgpIzF9Pjo6dHlwZSYmKTo6d29yayYpIzF9OjpvcGVyYXRv cigpKGZ1dHVyaXplPHN0ZDo6cmVzdWx0X29mPHN0ZDo6ZGVjYXk8e2xhbWJkYSgpIzF9Pjo6dHlw ZSAoKT46OnR5cGU+IHNlYXN0YXI6OmFzeW5jPHtsYW1iZGEoKSMxfT4oZnV0dXJpemU8c3RkOjpy ZXN1bHRfb2Y8c3RkOjpkZWNheTx7bGFtYmRhKCkjMX0+Ojp0eXBlICgpPjo6dHlwZT46OnR5cGUs IHN0ZDo6ZGVjYXk8e2xhbWJkYSgpIzF9Pjo6dHlwZSYmKTo6d29yayk6OntsYW1iZGEoKSMxfT46 Ol9NX2ludm9rZQogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICBfR0xPQkFMX19z dWJfSV9fWk4xMmFwcF90ZW1wbGF0ZUMyRXYKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgLS00LjAwJS0tIHNzdGFibGVzOjpzc3Rh YmxlOjp3cml0ZV90b2MKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgc3N0YWJs ZXM6OnNzdGFibGU6OnByZXBhcmVfd3JpdGVfY29tcG9uZW50cwogICAgICAgICAgICAgICAgfCAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgICAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAg ICAgICAgICB8LS01MC4wMCUtLSAweDRkM2E0ZjZlYzRlOGNkNzUKICAgICAgICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAg ICAgICAgICAgIC0tNTAuMDAlLS0gMHgzZWJmM2RkODBlM2IxNzRkCiAgICAgICAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICB8LS0yMy45MyUtLSBwb3NpeF9maWxlX2ltcGw6OmRpc2Nh cmQKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICB8LS04Mi4xNCUtLSBfWk4xMmNvbnRpbnVhdGlvbklaTjZmdXR1cmVJSW1FRTR0aGVu SVpOMTlmaWxlX2RhdGFfc2lua19pbXBsNmRvX3B1dEVtMTZ0ZW1wb3JhcnlfYnVmZmVySWNFRVVs bUVfUzBfSUlFRUVFVDBfT1RfRVVsU0FfRV9JbUVFM3J1bkV2CiAgICAgICAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgIHJlYWN0b3I6OmRlbF90aW1lcgogICAgICAgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICAweDYwODAwMDBlMjA0MAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAtLTE3Ljg2JS0tIGZ1dHVyaXplPGZ1 dHVyZTxsd19zaGFyZWRfcHRyPGRiOjpjb21taXRsb2c6OnNlZ21lbnQ+ID4gPjo6YXBwbHk8ZGI6 OmNvbW1pdGxvZzo6c2VnbWVudF9tYW5hZ2VyOjphbGxvY2F0ZV9zZWdtZW50KGJvb2wpOjp7bGFt YmRhKGZpbGUpIzF9LCBmaWxlPgogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICBf Wk4xMmNvbnRpbnVhdGlvbklaTjZmdXR1cmVJSjRmaWxlRUU0dGhlbklaTjJkYjljb21taXRsb2cx NXNlZ21lbnRfbWFuYWdlcjE2YWxsb2NhdGVfc2VnbWVudEViRVVsUzFfRV9TMF9JSjEzbHdfc2hh cmVkX3B0cklOUzVfN3NlZ21lbnRFRUVFRUVUMF9PVF9FVWxTRV9FX0pTMV9FRTNydW5FdgogICAg ICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfC0tMjAuOTQlLS0gcmVhY3Rvcjo6 b3Blbl9maWxlX2RtYQogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAgICAg ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICB8ICAgICAgICAgIHwtLTIwLjQxJS0tIGRiOjpjb21taXRsb2c6OnNlZ21lbnRfbWFu YWdlcjo6YWxsb2NhdGVfc2VnbWVudAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICBkYjo6Y29tbWl0bG9nOjpzZWdtZW50X21hbmFnZXI6Om9uX3RpbWVyKCk6OntsYW1iZGEoKSMx fTo6b3BlcmF0b3IoKQogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAweGI4YzI2 NAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgIHwtLTE0LjI5JS0tIHNzdGFibGVzOjpzc3RhYmxlOjp3cml0ZV9zaW1wbGU8KHNzdGFi bGVzOjpzc3RhYmxlOjpjb21wb25lbnRfdHlwZSk4LCBzc3RhYmxlczo6c3RhdGlzdGljcz4KICAg ICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgc3RkOjpfRnVuY3Rpb25faGFuZGxlcjx2 b2lkICgpLCBmdXR1cml6ZTxzdGQ6OnJlc3VsdF9vZjxzdGQ6OmRlY2F5PHNzdGFibGVzOjpzc3Rh YmxlOjp3cml0ZV9jb21wb25lbnRzKG11dGF0aW9uX3JlYWRlciwgdW5zaWduZWQgbG9uZywgbHdf c2hhcmVkX3B0cjxzY2hlbWEgY29uc3Q+LCB1bnNpZ25lZCBsb25nKTo6e2xhbWJkYSgpIzF9Pjo6 dHlwZSAoKT46OnR5cGU+Ojp0eXBlIHNlYXN0YXI6OmFzeW5jPHNzdGFibGVzOjpzc3RhYmxlOjp3 cml0ZV9jb21wb25lbnRzKG11dGF0aW9uX3JlYWRlciwgdW5zaWduZWQgbG9uZywgbHdfc2hhcmVk X3B0cjxzY2hlbWEgY29uc3Q+LCB1bnNpZ25lZCBsb25nKTo6e2xhbWJkYSgpIzF9PihzdGQ6OmRl Y2F5JiYsIChzdGQ6OmRlY2F5PHNzdGFibGVzOjpzc3RhYmxlOjp3cml0ZV9jb21wb25lbnRzKG11 dGF0aW9uX3JlYWRlciwgdW5zaWduZWQgbG9uZywgbHdfc2hhcmVkX3B0cjxzY2hlbWEgY29uc3Q+ LCB1bnNpZ25lZCBsb25nKTo6e2xhbWJkYSgpIzF9Pjo6dHlwZSYmKS4uLik6OntsYW1iZGEoZnV0 dXJpemU8c3RkOjpyZXN1bHRfb2Y8c3RkOjpkZWNheTx7bGFtYmRhKCkjMX0+Ojp0eXBlICgpPjo6 dHlwZT4gc2Vhc3Rhcjo6YXN5bmM8e2xhbWJkYSgpIzF9PihmdXR1cml6ZTxzdGQ6OnJlc3VsdF9v ZjxzdGQ6OmRlY2F5PHtsYW1iZGEoKSMxfT46OnR5cGUgKCk+Ojp0eXBlPjo6dHlwZSwgc3RkOjpk ZWNheTx7bGFtYmRhKCkjMX0+Ojp0eXBlJiYpOjp3b3JrJikjMX06Om9wZXJhdG9yKCkoZnV0dXJp emU8c3RkOjpyZXN1bHRfb2Y8c3RkOjpkZWNheTx7bGFtYmRhKCkjMX0+Ojp0eXBlICgpPjo6dHlw ZT4gc2Vhc3Rhcjo6YXN5bmM8e2xhbWJkYSgpIzF9PihmdXR1cml6ZTxzdGQ6OnJlc3VsdF9vZjxz dGQ6OmRlY2F5PHtsYW1iZGEoKSMxfT46OnR5cGUgKCk+Ojp0eXBlPjo6dHlwZSwgc3RkOjpkZWNh eTx7bGFtYmRhKCkjMX0+Ojp0eXBlJiYpOjp3b3JrKTo6e2xhbWJkYSgpIzF9Pjo6X01faW52b2tl CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIF9HTE9CQUxfX3N1Yl9JX19aTjEy YXBwX3RlbXBsYXRlQzJFdgogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAg ICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgIHwtLTEyLjI0JS0tIHNzdGFibGVzOjp3cml0ZV9jcmMKICAg ICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgfC0tMTYuNjclLS0gMHgzMTM1MzIzNDM1MzYwMDJmCiAg ICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgIHwtLTE2LjY3JS0tIDB4MzczNjMzMzIzNTMzMDAyZgog ICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICB8LS0xNi42NyUtLSAweDM2MzEzOTMzMzIzMjAwMmYK ICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfC0tMTYuNjclLS0gMHgzNTM5MzMzMDMzMzAwMDJm CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwtLTE2LjY3JS0tIDB4MzgzOTMwMzgzMTMzMDAy ZgogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgLS0xNi42NyUtLSAweDMyMzMzODMwMzAzNzAw MmYKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICB8LS0xMi4yNCUtLSBzc3RhYmxlczo6d3JpdGVfZGlnZXN0CiAgICAgICAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfC0tMTAuMjAl LS0gc3N0YWJsZXM6OnNzdGFibGU6OndyaXRlX3NpbXBsZTwoc3N0YWJsZXM6OnNzdGFibGU6OmNv bXBvbmVudF90eXBlKTcsIHNzdGFibGVzOjpmaWx0ZXI+CiAgICAgICAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIHNzdGFibGVzOjpzc3RhYmxlOjp3cml0ZV9maWx0ZXIKICAgICAgICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgc3RkOjpfRnVuY3Rpb25faGFuZGxlcjx2b2lkICgpLCBm dXR1cml6ZTxzdGQ6OnJlc3VsdF9vZjxzdGQ6OmRlY2F5PHNzdGFibGVzOjpzc3RhYmxlOjp3cml0 ZV9jb21wb25lbnRzKG11dGF0aW9uX3JlYWRlciwgdW5zaWduZWQgbG9uZywgbHdfc2hhcmVkX3B0 cjxzY2hlbWEgY29uc3Q+LCB1bnNpZ25lZCBsb25nKTo6e2xhbWJkYSgpIzF9Pjo6dHlwZSAoKT46 OnR5cGU+Ojp0eXBlIHNlYXN0YXI6OmFzeW5jPHNzdGFibGVzOjpzc3RhYmxlOjp3cml0ZV9jb21w b25lbnRzKG11dGF0aW9uX3JlYWRlciwgdW5zaWduZWQgbG9uZywgbHdfc2hhcmVkX3B0cjxzY2hl bWEgY29uc3Q+LCB1bnNpZ25lZCBsb25nKTo6e2xhbWJkYSgpIzF9PihzdGQ6OmRlY2F5JiYsIChz dGQ6OmRlY2F5PHNzdGFibGVzOjpzc3RhYmxlOjp3cml0ZV9jb21wb25lbnRzKG11dGF0aW9uX3Jl YWRlciwgdW5zaWduZWQgbG9uZywgbHdfc2hhcmVkX3B0cjxzY2hlbWEgY29uc3Q+LCB1bnNpZ25l ZCBsb25nKTo6e2xhbWJkYSgpIzF9Pjo6dHlwZSYmKS4uLik6OntsYW1iZGEoZnV0dXJpemU8c3Rk OjpyZXN1bHRfb2Y8c3RkOjpkZWNheTx7bGFtYmRhKCkjMX0+Ojp0eXBlICgpPjo6dHlwZT4gc2Vh c3Rhcjo6YXN5bmM8e2xhbWJkYSgpIzF9PihmdXR1cml6ZTxzdGQ6OnJlc3VsdF9vZjxzdGQ6OmRl Y2F5PHtsYW1iZGEoKSMxfT46OnR5cGUgKCk+Ojp0eXBlPjo6dHlwZSwgc3RkOjpkZWNheTx7bGFt YmRhKCkjMX0+Ojp0eXBlJiYpOjp3b3JrJikjMX06Om9wZXJhdG9yKCkoZnV0dXJpemU8c3RkOjpy ZXN1bHRfb2Y8c3RkOjpkZWNheTx7bGFtYmRhKCkjMX0+Ojp0eXBlICgpPjo6dHlwZT4gc2Vhc3Rh cjo6YXN5bmM8e2xhbWJkYSgpIzF9PihmdXR1cml6ZTxzdGQ6OnJlc3VsdF9vZjxzdGQ6OmRlY2F5 PHtsYW1iZGEoKSMxfT46OnR5cGUgKCk+Ojp0eXBlPjo6dHlwZSwgc3RkOjpkZWNheTx7bGFtYmRh KCkjMX0+Ojp0eXBlJiYpOjp3b3JrKTo6e2xhbWJkYSgpIzF9Pjo6X01faW52b2tlCiAgICAgICAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIF9HTE9CQUxfX3N1Yl9JX19aTjEyYXBwX3RlbXBs YXRlQzJFdgogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIHwtLTEwLjIwJS0tIHNzdGFibGVzOjpzc3RhYmxlOjp3cml0ZV9zaW1wbGU8 KHNzdGFibGVzOjpzc3RhYmxlOjpjb21wb25lbnRfdHlwZSk0LCBzc3RhYmxlczo6c3VtbWFyeV9r YT4KICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgc3RkOjpfRnVuY3Rpb25faGFu ZGxlcjx2b2lkICgpLCBmdXR1cml6ZTxzdGQ6OnJlc3VsdF9vZjxzdGQ6OmRlY2F5PHNzdGFibGVz Ojpzc3RhYmxlOjp3cml0ZV9jb21wb25lbnRzKG11dGF0aW9uX3JlYWRlciwgdW5zaWduZWQgbG9u ZywgbHdfc2hhcmVkX3B0cjxzY2hlbWEgY29uc3Q+LCB1bnNpZ25lZCBsb25nKTo6e2xhbWJkYSgp IzF9Pjo6dHlwZSAoKT46OnR5cGU+Ojp0eXBlIHNlYXN0YXI6OmFzeW5jPHNzdGFibGVzOjpzc3Rh YmxlOjp3cml0ZV9jb21wb25lbnRzKG11dGF0aW9uX3JlYWRlciwgdW5zaWduZWQgbG9uZywgbHdf c2hhcmVkX3B0cjxzY2hlbWEgY29uc3Q+LCB1bnNpZ25lZCBsb25nKTo6e2xhbWJkYSgpIzF9Pihz dGQ6OmRlY2F5JiYsIChzdGQ6OmRlY2F5PHNzdGFibGVzOjpzc3RhYmxlOjp3cml0ZV9jb21wb25l bnRzKG11dGF0aW9uX3JlYWRlciwgdW5zaWduZWQgbG9uZywgbHdfc2hhcmVkX3B0cjxzY2hlbWEg Y29uc3Q+LCB1bnNpZ25lZCBsb25nKTo6e2xhbWJkYSgpIzF9Pjo6dHlwZSYmKS4uLik6OntsYW1i ZGEoZnV0dXJpemU8c3RkOjpyZXN1bHRfb2Y8c3RkOjpkZWNheTx7bGFtYmRhKCkjMX0+Ojp0eXBl ICgpPjo6dHlwZT4gc2Vhc3Rhcjo6YXN5bmM8e2xhbWJkYSgpIzF9PihmdXR1cml6ZTxzdGQ6OnJl c3VsdF9vZjxzdGQ6OmRlY2F5PHtsYW1iZGEoKSMxfT46OnR5cGUgKCk+Ojp0eXBlPjo6dHlwZSwg c3RkOjpkZWNheTx7bGFtYmRhKCkjMX0+Ojp0eXBlJiYpOjp3b3JrJikjMX06Om9wZXJhdG9yKCko ZnV0dXJpemU8c3RkOjpyZXN1bHRfb2Y8c3RkOjpkZWNheTx7bGFtYmRhKCkjMX0+Ojp0eXBlICgp Pjo6dHlwZT4gc2Vhc3Rhcjo6YXN5bmM8e2xhbWJkYSgpIzF9PihmdXR1cml6ZTxzdGQ6OnJlc3Vs dF9vZjxzdGQ6OmRlY2F5PHtsYW1iZGEoKSMxfT46OnR5cGUgKCk+Ojp0eXBlPjo6dHlwZSwgc3Rk OjpkZWNheTx7bGFtYmRhKCkjMX0+Ojp0eXBlJiYpOjp3b3JrKTo6e2xhbWJkYSgpIzF9Pjo6X01f aW52b2tlCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIF9HTE9CQUxfX3N1Yl9J X19aTjEyYXBwX3RlbXBsYXRlQzJFdgogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwtLTEwLjIwJS0tIDB4NzhkOTNiCiAgICAgICAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfC0t Ni4xMiUtLSBzc3RhYmxlczo6c3N0YWJsZTo6b3Blbl9kYXRhCiAgICAgICAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgICAtLTEwMC4wMCUtLSAweDgwMDAwMDAwMDQwMDAwMDAKICAgICAgICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgLS00LjA4JS0tIHNz dGFibGVzOjpzc3RhYmxlOjp3cml0ZV90b2MKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAg ICAgICAgc3N0YWJsZXM6OnNzdGFibGU6OnByZXBhcmVfd3JpdGVfY29tcG9uZW50cwogICAgICAg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgICAgICAgICAgICAgLS0xMDAuMDAlLS0gMHg2MTAwMjA2NjkwZWYKICAgICAgICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwtLTE4LjM4JS0tIHN5c2NhbGxfd29ya19x dWV1ZTo6c3VibWl0X2l0ZW0KICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAg ICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICB8LS0xMC4wMCUtLSAweDdmNGFkODlmOGZlMAogICAgICAg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwt LTcuNTAlLS0gMHg3ZjRhZDgzZjhmZTAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8LS03LjUwJS0tIDB4N2Y0YWQ2YmY4ZmUwCiAg ICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgfC0tNy41MCUtLSAweDdmNGFkNjVmOGZlMAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwtLTUuMDAlLS0gMHg2MGIwMTVlOGNk OTAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICB8LS01LjAwJS0tIDB4NjAxMDBhY2FlZDkwCiAgICAgICAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfC0tNS4wMCUtLSAweDYwNzAw NmYwNGQ5MAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIHwtLTUuMDAlLS0gMHhmZmZmZmZmZmZmZmZhNWQwCiAgICAgICAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfC0tMi41MCUt LSAweDYwZTAxYWNiZWQ5MAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAg ICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgIHwtLTIuNTAlLS0gMHg2MGUwMWFjYmVjNjAKICAgICAgICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8LS0y LjUwJS0tIDB4NjBhMDE4ZDdhZDkwCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg IAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfC0tMi41MCUtLSAweDYwYTAxOGQ3YWM2MAogICAg ICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg IHwtLTIuNTAlLS0gMHg2MGIwMTVlOGNjNjAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8LS0yLjUwJS0tIDB4NjA5MDBiYjhhZDYw CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgfC0tMi41MCUtLSAweDYwMTAwYWNhZWM2MAogICAgICAgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwtLTIuNTAlLS0gMHg2MDgwMDk1 MWRkOTAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICB8LS0yLjUwJS0tIDB4NjA4MDA5NTFkYzYwCiAgICAgICAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfC0tMi41MCUtLSAweDYw ZDAwOTA4OWQ5MAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgIHwtLTIuNTAlLS0gMHg2MGQwMDkwODljNjAKICAgICAgICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8LS0yLjUwJS0t IDB4NjA3MDA2ZjA0YzYwCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAg ICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgfC0tMi41MCUtLSAweDYwZjAwNTk4NGQ2MAogICAgICAgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwtLTIu NTAlLS0gMHg3ZjRhZDc3ZjhmZTAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICB8LS0yLjUwJS0tIDB4N2Y0YWRiOWY4ZmUwCiAgICAg ICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg fC0tMi41MCUtLSAweDdmNGFkOWJmOGZlMAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwtLTIuNTAlLS0gMHg3ZjRhZDdkZjhmZTAK ICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICB8LS0yLjUwJS0tIDB4N2Y0YWQ3N2Y4ZmUwCiAgICAgICAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgIC0tMi41MCUtLSAweDdmNGFkNWZm OGZlMAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfC0tMi45OSUtLSBy ZWFjdG9yOjpvcGVuX2RpcmVjdG9yeQogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwtLTU3LjE0JS0tIHNzdGFibGVzOjpzc3RhYmxl OjpmaWxlbmFtZQogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgICAtLTQyLjg2JS0tIHNzdGFibGVzOjpzc3RhYmxlOjp3cml0ZV90b2MK ICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgc3N0YWJsZXM6OnNzdGFibGU6OnBy ZXBhcmVfd3JpdGVfY29tcG9uZW50cwogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAg ICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8LS01MC4w MCUtLSAweDRkM2E0ZjZlYzRlOGNkNzUKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAg ICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgIC0tNTAu MDAlLS0gMHgzZWJmM2RkODBlM2IxNzRkCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAgICAg ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICAgLS0xLjcxJS0tIHJlYWN0b3I6OnJlbmFtZV9maWxlCiAgICAgICAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAg ICAgICAgICBzc3RhYmxlczo6c3N0YWJsZTo6c2VhbF9zc3RhYmxlCiAgICAgICAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAg ICAgICAgICBzdGQ6Ol9GdW5jdGlvbl9oYW5kbGVyPHZvaWQgKCksIGZ1dHVyaXplPHN0ZDo6cmVz dWx0X29mPHN0ZDo6ZGVjYXk8c3N0YWJsZXM6OnNzdGFibGU6OndyaXRlX2NvbXBvbmVudHMobXV0 YXRpb25fcmVhZGVyLCB1bnNpZ25lZCBsb25nLCBsd19zaGFyZWRfcHRyPHNjaGVtYSBjb25zdD4s IHVuc2lnbmVkIGxvbmcpOjp7bGFtYmRhKCkjMX0+Ojp0eXBlICgpPjo6dHlwZT46OnR5cGUgc2Vh c3Rhcjo6YXN5bmM8c3N0YWJsZXM6OnNzdGFibGU6OndyaXRlX2NvbXBvbmVudHMobXV0YXRpb25f cmVhZGVyLCB1bnNpZ25lZCBsb25nLCBsd19zaGFyZWRfcHRyPHNjaGVtYSBjb25zdD4sIHVuc2ln bmVkIGxvbmcpOjp7bGFtYmRhKCkjMX0+KHN0ZDo6ZGVjYXkmJiwgKHN0ZDo6ZGVjYXk8c3N0YWJs ZXM6OnNzdGFibGU6OndyaXRlX2NvbXBvbmVudHMobXV0YXRpb25fcmVhZGVyLCB1bnNpZ25lZCBs b25nLCBsd19zaGFyZWRfcHRyPHNjaGVtYSBjb25zdD4sIHVuc2lnbmVkIGxvbmcpOjp7bGFtYmRh KCkjMX0+Ojp0eXBlJiYpLi4uKTo6e2xhbWJkYShmdXR1cml6ZTxzdGQ6OnJlc3VsdF9vZjxzdGQ6 OmRlY2F5PHtsYW1iZGEoKSMxfT46OnR5cGUgKCk+Ojp0eXBlPiBzZWFzdGFyOjphc3luYzx7bGFt YmRhKCkjMX0+KGZ1dHVyaXplPHN0ZDo6cmVzdWx0X29mPHN0ZDo6ZGVjYXk8e2xhbWJkYSgpIzF9 Pjo6dHlwZSAoKT46OnR5cGU+Ojp0eXBlLCBzdGQ6OmRlY2F5PHtsYW1iZGEoKSMxfT46OnR5cGUm Jik6OndvcmsmKSMxfTo6b3BlcmF0b3IoKShmdXR1cml6ZTxzdGQ6OnJlc3VsdF9vZjxzdGQ6OmRl Y2F5PHtsYW1iZGEoKSMxfT46OnR5cGUgKCk+Ojp0eXBlPiBzZWFzdGFyOjphc3luYzx7bGFtYmRh KCkjMX0+KGZ1dHVyaXplPHN0ZDo6cmVzdWx0X29mPHN0ZDo6ZGVjYXk8e2xhbWJkYSgpIzF9Pjo6 dHlwZSAoKT46OnR5cGU+Ojp0eXBlLCBzdGQ6OmRlY2F5PHtsYW1iZGEoKSMxfT46OnR5cGUmJik6 OndvcmspOjp7bGFtYmRhKCkjMX0+OjpfTV9pbnZva2UKICAgICAgICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAg IF9HTE9CQUxfX3N1Yl9JX19aTjEyYXBwX3RlbXBsYXRlQzJFdgogICAgICAgICAgICAgICAgfCAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAg ICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAg LS0zMi4zNyUtLSBfWk4xMmNvbnRpbnVhdGlvbklaTjZmdXR1cmVJSkVFNHRoZW5JWk4xOHN5c2Nh bGxfd29ya19xdWV1ZTExc3VibWl0X2l0ZW1FUE5TM185d29ya19pdGVtRUVVbHZFX1MxX0VFVDBf T1RfRVVsUzlfRV9KRUUzcnVuRXYKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICByZWFjdG9yOjpkZWxfdGltZXIKICAg ICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg ICAgICAgICAgICAweDYwZDAwMDBlMjA0MAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgIHwtLTI5LjA0JS0tIF9fdmRzb19jbG9ja19nZXR0aW1lCiAg ICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg IAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfC0tMTku NjYlLS0gMHg3ZjRhZGU0MmIxOTMKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgcmVhY3Rvcl9iYWNrZW5kX2Vwb2xsOjpjb21wbGV0ZV9l cG9sbF9ldmVudAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8LS00MS42MSUtLSBzbXBfbWVzc2FnZV9xdWV1 ZTo6YXN5bmNfd29ya19pdGVtPGZ1dHVyZTw+IHNlYXN0YXI6OnNoYXJkZWQ8ZGF0YWJhc2U+Ojpp bnZva2Vfb248c2VydmljZTo6c3RvcmFnZV9wcm94eTo6bXV0YXRlX2xvY2FsbHkoZnJvemVuX211 dGF0aW9uIGNvbnN0Jik6OntsYW1iZGEoZGF0YWJhc2UmKSMxfSwgZnV0dXJlPD4gPih1bnNpZ25l ZCBpbnQsIHNlcnZpY2U6OnN0b3JhZ2VfcHJveHk6Om11dGF0ZV9sb2NhbGx5KGZyb3plbl9tdXRh dGlvbiBjb25zdCYpOjp7bGFtYmRhKGRhdGFiYXNlJikjMX0mJik6OntsYW1iZGEoKSMxfT46OnBy b2Nlc3MKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwtLTc5LjAzJS0t IHNtcF9tZXNzYWdlX3F1ZXVlOjpwcm9jZXNzX3F1ZXVlPDJ1bCwgc21wX21lc3NhZ2VfcXVldWU6 OnByb2Nlc3NfaW5jb21pbmcoKTo6e2xhbWJkYShzbXBfbWVzc2FnZV9xdWV1ZTo6d29ya19pdGVt KikjMX0+CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgfC0tOTUuOTIlLS0gMHg2MDcwMDAwYzMwMDAKICAgICAgICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8LS0yLjA0JS0tIDB4 NjFkMDAwMGMxMDAwCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgIC0tMi4wNCUtLSAweDYxZDAwMDBjMTAwMAogICAgICAgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfC0tMy4yMyUtLSAweDE0ZGQ1MQogICAgICAgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfC0tMS42MSUtLSAweDE2MmE1NAogICAgICAg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfC0tMS42MSUtLSAweDE2MWRjYQogICAg ICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfC0tMS42MSUtLSAweDE1OWM4Ygog ICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfC0tMS42MSUtLSAweDE1OThi NQogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfC0tMS42MSUtLSAweDE0 ZGQzZQogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfC0tMS42MSUtLSAw eDE0YmFkOAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfC0tMS42MSUt LSAweDE0YTg4MAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfC0tMS42 MSUtLSAweDEyNzEwNQogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfC0t MS42MSUtLSAweDYwNzAwMDBlMjA0MAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgfC0tMS42MSUtLSBzbXBfbWVzc2FnZV9xdWV1ZTo6cHJvY2Vzc19xdWV1ZTwydWwsIHNt cF9tZXNzYWdlX3F1ZXVlOjpwcm9jZXNzX2luY29taW5nKCk6OntsYW1iZGEoc21wX21lc3NhZ2Vf cXVldWU6OndvcmtfaXRlbSopIzF9PgogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgMHg2MGQwMDAw YzMwMDAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAtLTEuNjElLS0g X192ZHNvX2Nsb2NrX2dldHRpbWUKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIDB4N2Y0YWQ3N2Y5 MTYwCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgIHwtLTMwLjIwJS0tIF9fcmVzdG9yZV9ydAogICAgICAgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfC0tNTcuMTQlLS0gX192ZHNvX2Nsb2NrX2dl dHRpbWUKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIDB4MWQKICAgICAgICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICB8ICAgICAgICAgIHwtLTkuNTIlLS0gc21wX21lc3NhZ2VfcXVldWU6OnNtcF9tZXNz YWdlX3F1ZXVlCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAweDYwNzAwMDBjMzAwMAogICAgICAg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfC0tNC43NiUtLSAweDYwMDAwMDM1NzI0 MAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfC0tNC43NiUtLSAweDYw MDAwMDMxYTY0MAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfC0tMi4z OCUtLSBwb3NpeF9maWxlX2ltcGw6Omxpc3RfZGlyZWN0b3J5CiAgICAgICAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICAweDYwOTAwMDA0NDczMAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgfC0tMi4zOCUtLSAweDQ2ZWZiZgogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgfC0tMi4zOCUtLSAweDYwMDAwMDQ0MmU0MAogICAgICAgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgfC0tMi4zOCUtLSAweDYwMDAwMDM3NjQ0MAogICAgICAgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgfC0tMi4zOCUtLSAweDYwMDAwMDJiYWM0MAogICAgICAg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfC0tMi4zOCUtLSAweDYwMDAwMDI5NTY0 MAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfC0tMi4zOCUtLSAweDYw MDAwMDI4OWU0MAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfC0tMi4z OCUtLSAweDYwMDAwMDMxYTY0MAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgfC0tMi4zOCUtLSAweDdmNGFkZTZmNzRlZAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgX19s aWJjX3NpZ2xvbmdqbXAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIDB4NjAwMDAwNDdiZTQwCiAg ICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgLS0yLjM4JS0tIDB4N2Y0YWRi M2Y3ZmQwCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgIHwtLTE0LjA5JS0tIDB4MzMKICAgICAgICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAK ICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgfC0tMTIuMDglLS0gcHJvbWlzZTx0ZW1wb3JhcnlfYnVmZmVyPGNoYXI+ID46OnByb21pc2UK ICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICBfWk42ZnV0dXJlSUoxNnRlbXBvcmFyeV9idWZmZXJJY0VFRTR0aGVuSVpO MTJpbnB1dF9zdHJlYW1JY0UxMnJlYWRfZXhhY3RseUVtRVVsVF9FX1MyX0VFVDBfT1M2XwogICAg ICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfC0tNDQuNDQlLS0gaW5wdXRfc3Ry ZWFtPGNoYXI+OjpyZWFkX2V4YWN0bHkKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIDB4OAogICAg ICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfC0tMTEuMTElLS0gMHg3ZjRhZGIz ZjhlYTAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwtLTExLjExJS0t IDB4N2Y0YWQ5YmY4ZWEwCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8 LS0xMS4xMSUtLSAweDdmNGFkODlmOGVhMAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAg ICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgfC0tMTEuMTElLS0gMHg3ZjRhZDgzZjhlYTAKICAgICAgICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICB8ICAgICAgICAgIHwtLTUuNTYlLS0gMHg3ZjRhZDc3ZjhlYTAKICAgICAgICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAtLTUuNTYlLS0gMHg3ZjRhZDdkZjhlYTAKICAg ICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgfC0tMS4zNCUtLSAweDdmNGFkNmJmOGQ4MAogICAgICAgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAog ICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICAgLS0wLjY3JS0tIDB4N2Y0YWRhZGY4ZDgwCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgfC0tNC40MyUtLSBfX2xpYmNfc2VuZAogICAgICAgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICBfWk4xMmNv bnRpbnVhdGlvbklaTjZmdXR1cmVJSm1FRTR0aGVuSVpON3JlYWN0b3IxNHdyaXRlX2FsbF9wYXJ0 RVIxN3BvbGxhYmxlX2ZkX3N0YXRlUEt2bW1FVWxtRV9TMF9JSkVFRUVUMF9PVF9FVWxTQ19FX0pt RUUzcnVuRXYKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfC0tMTQuNzElLS0gMHg0CiAgICAgICAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIHwtLTExLjc2JS0tIDB4N2Y0YWQ4OWY4ZGUwCiAgICAgICAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwtLTguODIl LS0gMHg3ZjRhZGIzZjhkZTAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfC0tOC44MiUtLSAweDdmNGFkOWJm OGRlMAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICB8LS04LjgyJS0tIDB4N2Y0YWQ3N2Y4ZGUwCiAgICAgICAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgIHwtLTguODIlLS0gMHg3ZjRhZDZiZjhkZTAKICAgICAgICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAgICAg ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfC0t NS44OCUtLSAweDdmNGFkODNmOGRlMAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8LS01Ljg4JS0tIDB4N2Y0 YWQ3ZGY4ZGUwCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwtLTUuODglLS0gMHg3ZjRhZDUzZjhkZTAKICAg ICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgfC0tMi45NCUtLSAweDdmNGFjYzlmOGRlMAogICAgICAgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAog ICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICB8LS0yLjk0JS0tIGNvbnRpbnVhdGlvbjxmdXR1cmU8ZmlsZT46OndhaXQoKTo6e2xhbWJkYShm dXR1cmVfc3RhdGU8ZmlsZT4mJikjMX0sIGZpbGU+Ojp+Y29udGludWF0aW9uCiAgICAgICAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgMHg2MTEwMDNjOGU5YjgKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfC0tMi45NCUtLSAweDdmNGFkYjlm OGRlMAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICB8LS0yLjk0JS0tIDB4N2Y0YWQ3MWY4ZGUwCiAgICAgICAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgIHwtLTIuOTQlLS0gMHg3ZjRhZDY1ZjhkZTAKICAgICAgICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAgICAg ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfC0t Mi45NCUtLSAweDdmNGFkNTlmOGRlMAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgLS0yLjk0JS0tIDB4N2Y0 YWQzNWY4ZGUwCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgfC0tMS41NiUtLSAweDdmNGFkZTZmNzU0ZAogICAgICAgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICByZWFjdG9yOjpyZWFkX3NvbWUKICAg ICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgfC0tNjYuNjclLS0gX1pOMTJjb250aW51YXRpb25JWk42ZnV0dXJlSUpF RTR0aGVuSVpaTjdzZXJ2aWNlMTNzdG9yYWdlX3Byb3h5MjJzZW5kX3RvX2xpdmVfZW5kcG9pbnRz RW1FTktVbFJTdDRwYWlySUsxM2Jhc2ljX3NzdHJpbmdJY2pMajE1RUVTdDZ2ZWN0b3JJTjNnbXMx MmluZXRfYWRkcmVzc0VTYUlTQl9FRUVFX2NsRVNGX0VVbHZFX1MxX0VFVDBfT1RfRVVsU0tfRV9K RUUzcnVuRXYKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICByZWFjdG9yOjpkZWxfdGltZXIKICAgICAgICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAw eDYwNzAwMDBlMjA0MAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8LS04LjMzJS0tIF9aTjEyY29udGludWF0 aW9uSVpONmZ1dHVyZUlJRUU0dGhlbklaNXNsZWVwSU5TdDZjaHJvbm8zX1YyMTJzeXN0ZW1fY2xv Y2tFbVN0NXJhdGlvSUxsMUVMbDEwMDAwMDBFRUVTMV9OUzRfOGR1cmF0aW9uSVQwX1QxX0VFRVVs dkVfUzFfRUVTQV9PVF9FVWxTRl9FX0lFRTNydW5FdgogICAgICAgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHJlYWN0b3I6OmRl bF90aW1lcgogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgIDB4NjA4MDAwMGUyMDQwCiAgICAgICAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAg ICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwt LTguMzMlLS0gMHg2MDAwMDA0ODM2NDAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfC0tOC4zMyUtLSAweDYw MDAwMDQ4MDQ0MAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgLS04LjMzJS0tIDB4MzYKICAgICAgICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAtLTAuMjYlLS0gWy4uLl0KICAg ICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAtLTQ2LjcwJS0tIHJldGludF9jYXJlZnVsCiAg ICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAg IAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfC0tNi4y NCUtLSBwb3NpeF9maWxlX2ltcGw6Omxpc3RfZGlyZWN0b3J5CiAgICAgICAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAg ICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwt LTgwLjAwJS0tIDB4NjBmMDAwMGUyMDIwCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwtLTUuMDAlLS0gMHg2 MDEwMDAwNDQ3MzAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfC0tNS4wMCUtLSAweDYwZTAwMDA0NDcyMAog ICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAg ICAgICAgfCAgICAgICAgICB8LS0yLjUwJS0tIDB4NjBmMDAwMTM1NTAwCiAgICAgICAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAg ICAgIHwtLTIuNTAlLS0gMHg2MTkwMDAwZTIwOTgKICAgICAgICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfC0tMi41MCUt LSAweDYwZDAwMDBjMzAwMAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgLS0yLjUwJS0tIDB4MQogICAgICAg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAKICAg ICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwtLTMuNDIlLS0g Ym9vc3Q6OmxvY2tmcmVlOjpkZXRhaWw6OnJpbmdidWZmZXJfYmFzZTxzbXBfbWVzc2FnZV9xdWV1 ZTo6d29ya19pdGVtKj46OnBvcAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg ICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8LS05NS42NSUtLSBib29zdDo6 cHJvZ3JhbV9vcHRpb25zOjp2YXJpYWJsZXNfbWFwOjpnZXQKICAgICAgICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAgICAg ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgIC0t NC4zNSUtLSAweDYxODAwMDA0NDY4MAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgICAgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICAgICAgICAgICAgIHwtLTMuMTIlLS0gbWVtb3J5OjpzbWFsbF9wb29sOjphZGRfbW9y ZV9vYmplY3RzCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwtLTEwLjUzJS0tIG1hbmFnZWRfdmVjdG9yPGF0 b21pY19jZWxsX29yX2NvbGxlY3Rpb24sIDV1LCB1bnNpZ25lZCBpbnQ+OjpjbGVhcl9hbmRfcmVs ZWFzZQogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAg ICAgICAgICB8ICAgICAgICAgIG11dGF0aW9uX3BhcnRpdGlvbjo6Y2x1c3RlcmVkX3JvdwogICAg ICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgIG11dGF0aW9uOjpzZXRfY2x1c3RlcmVkX2NlbGwKICAgICAgICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICBjcWwz Ojpjb25zdGFudHM6OnNldHRlcjo6ZXhlY3V0ZQogICAgICAgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIGNxbDM6OnN0YXRlbWVu dHM6OnVwZGF0ZV9zdGF0ZW1lbnQ6OmFkZF91cGRhdGVfZm9yX2tleQogICAgICAgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIF9a TjhmdXR1cml6ZUk2ZnV0dXJlSUpTdDZ2ZWN0b3JJOG11dGF0aW9uU2FJUzJfRUVFRUU1YXBwbHlJ Wk40Y3FsMzEwc3RhdGVtZW50czIybW9kaWZpY2F0aW9uX3N0YXRlbWVudDEzZ2V0X211dGF0aW9u c0VSTjdzZWFzdGFyN3NoYXJkZWRJTjdzZXJ2aWNlMTNzdG9yYWdlX3Byb3h5RUVFUktOUzhfMTNx dWVyeV9vcHRpb25zRWJsRVVsVF9FX0pTdDEwdW5pcXVlX3B0cklOUzhfMTd1cGRhdGVfcGFyYW1l dGVyc0VTdDE0ZGVmYXVsdF9kZWxldGVJU05fRUVFRUVTNV9PU0tfT1N0NXR1cGxlSUpEcFQwX0VF CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgY3FsMzo6c3RhdGVtZW50czo6bW9kaWZpY2F0aW9uX3N0YXRlbWVudDo6 Z2V0X211dGF0aW9ucwogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIGNxbDM6OnN0YXRlbWVudHM6Om1vZGlmaWNhdGlv bl9zdGF0ZW1lbnQ6OmV4ZWN1dGVfd2l0aG91dF9jb25kaXRpb24KICAgICAgICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICBjcWwz OjpxdWVyeV9vcHRpb25zOjpxdWVyeV9vcHRpb25zCiAgICAgICAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAK ICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICB8LS01MC4wMCUtLSAweDdmNGFkNzdmODBlMAogICAgICAgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgIC0tNTAuMDAlLS0gMHg3ZjRhZDZiZjgwZTAKICAgICAg ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAg IHwgICAgICAgICAgfC0tMTAuNTMlLS0gbWVtb3J5OjpzbWFsbF9wb29sOjphZGRfbW9yZV9vYmpl Y3RzCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8LS01MC4wMCUtLSAw eDYwZTAwMDE1ZDAwMAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgIC0t NTAuMDAlLS0gMHg2MGIwMGFmNmM3NTgKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfC0tNS4yNiUtLSAweDYw YTAxOGVlMzg2NwogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8LS01LjI2JS0tIDB4NjBkMDBkNDFmNjgwCiAg ICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAg ICAgICB8ICAgICAgICAgIHwtLTUuMjYlLS0gMHg2MTQwMGM2YmI0ZDAKICAgICAgICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAK ICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAg ICAgfC0tNS4yNiUtLSAweDYwZTAwN2M5MThkNgogICAgICAgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8LS01LjI2JS0t IDB4NjBlMDA3ODI5NGNlCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwtLTUuMjYlLS0gMHg2MDcwMDZlZTRk YTAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAg ICAgICAgICAgIHwgICAgICAgICAgfC0tNS4yNiUtLSBfWk4xMmNvbnRpbnVhdGlvbklaTjZmdXR1 cmVJSkVFMTJ0aGVuX3dyYXBwZWRJWk5TMV8xNmhhbmRsZV9leGNlcHRpb25JWk43c2VydmljZTEz c3RvcmFnZV9wcm94eTIyc2VuZF90b19saXZlX2VuZHBvaW50c0VtRVVsTlN0MTVfX2V4Y2VwdGlv bl9wdHIxM2V4Y2VwdGlvbl9wdHJFRTBfRUVTMV9PVF9FVWxTQV9FX1MxX0VFVDBfU0FfRVVsU0Ff RV9KRUUzcnVuRXYKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICByZWFjdG9yOjpkZWxfdGltZXIKICAgICAgICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICAweDYwMzAwMDBlMjA0MAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8LS01LjI2JS0tIHNlcnZpY2U6OnN0 b3JhZ2VfcHJveHk6Om11dGF0ZV9sb2NhbGx5CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgc2VydmljZTo6c3RvcmFn ZV9wcm94eTo6c2VuZF90b19saXZlX2VuZHBvaW50cwogICAgICAgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHBhcmFsbGVsX2Zv cl9lYWNoPF9fZ251X2N4eDo6X19ub3JtYWxfaXRlcmF0b3I8dW5zaWduZWQgbG9uZyosIHN0ZDo6 dmVjdG9yPHVuc2lnbmVkIGxvbmcsIHN0ZDo6YWxsb2NhdG9yPHVuc2lnbmVkIGxvbmc+ID4gPiwg c2VydmljZTo6c3RvcmFnZV9wcm94eTo6bXV0YXRlX2JlZ2luKHN0ZDo6dmVjdG9yPHVuc2lnbmVk IGxvbmcsIHN0ZDo6YWxsb2NhdG9yPHVuc2lnbmVkIGxvbmc+ID4sIGRiOjpjb25zaXN0ZW5jeV9s ZXZlbCk6OntsYW1iZGEodW5zaWduZWQgbG9uZykjMX0+CiAgICAgICAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgMHg2MDEwMDAx MzZkMDAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICAgICAgICAgICAgIHwgICAgICAgICAgfC0tNS4yNiUtLSAweDYwYTAwMDE5MDBlMAogICAgICAg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAg fCAgICAgICAgICB8LS01LjI2JS0tIDB4NjBlMDAwMTVkMDQwCiAgICAgICAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAg ICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwt LTUuMjYlLS0gMHg2MTMwMDAxNWQwMDAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfC0tNS4yNiUtLSAweDYw ZTAwMDEzYmRlMAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8LS01LjI2JS0tIDB4NjBiMDAwMTBmMzA4CiAg ICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAg ICAgICB8ICAgICAgICAgIHwtLTUuMjYlLS0gMHg2MDEwMDAwZTQ4MDgKICAgICAgICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAK ICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAg ICAgIC0tNS4yNiUtLSAweDdmNGFkNjVmN2Y1MAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICAgICAgICAgICAgIHwtLTIuODIlLS0gc3RkOjp1bmlxdWVfcHRyPHJlYWN0 b3I6OnBvbGxmbiwgc3RkOjpkZWZhdWx0X2RlbGV0ZTxzdGQ6OnVuaXF1ZV9wdHI+ID4gcmVhY3Rv cjo6bWFrZV9wb2xsZm48cmVhY3Rvcjo6cnVuKCk6OntsYW1iZGEoKSMzfT4ocmVhY3Rvcjo6cnVu KCk6OntsYW1iZGEoKSMzfSYmKTo6dGhlX3BvbGxmbjo6cG9sbF9hbmRfY2hlY2tfbW9yZV93b3Jr CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAg ICAgICAgICB8ICAgICAgICAgIHwtLTI1LjAwJS0tIGJvb3N0Ojpsb2NrZnJlZTo6ZGV0YWlsOjpy aW5nYnVmZmVyX2Jhc2U8c21wX21lc3NhZ2VfcXVldWU6OndvcmtfaXRlbSo+Ojpwb3AKICAgICAg ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICBib29zdDo6cHJvZ3JhbV9vcHRpb25zOjp2YXJpYWJsZXNfbWFwOjpnZXQKICAgICAg ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAg IHwgICAgICAgICAgfC0tMjUuMDAlLS0gMHgxCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwtLTEyLjUwJS0t IDB4NTMKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICAgICAgICAgICAgIHwgICAgICAgICAgfC0tMTIuNTAlLS0gMHgzZQogICAgICAgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAog ICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAg ICB8LS0xMi41MCUtLSAweDI0CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg ICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAtLTEyLjUwJS0tIDB4Yjk1ODAw MDAwMDAwMDAwMAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAg ICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAg ICAgICAgIHwtLTIuNjclLS0gc3RkOjpfRnVuY3Rpb25faGFuZGxlcjxwYXJ0aXRpb25fcHJlc2Vu Y2VfY2hlY2tlcl9yZXN1bHQgKHBhcnRpdGlvbl9rZXkgY29uc3QmKSwgY29sdW1uX2ZhbWlseTo6 bWFrZV9wYXJ0aXRpb25fcHJlc2VuY2VfY2hlY2tlcihsd19zaGFyZWRfcHRyPHN0ZDo6bWFwPGxv bmcsIGx3X3NoYXJlZF9wdHI8c3N0YWJsZXM6OnNzdGFibGU+LCBzdGQ6Omxlc3M8bG9uZz4sIHN0 ZDo6YWxsb2NhdG9yPHN0ZDo6cGFpcjxsb25nIGNvbnN0LCBsd19zaGFyZWRfcHRyPHNzdGFibGVz Ojpzc3RhYmxlPiA+ID4gPiA+KTo6e2xhbWJkYShwYXJ0aXRpb25fa2V5IGNvbnN0JikjMX0+Ojpf TV9pbnZva2UKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICAgICAgICAgICAgIHwgICAgICAgICAgfC0tNjYuNjclLS0gMHgxYjVjMjgwCiAgICAgICAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8 ICAgICAgICAgIHwtLTI3Ljc4JS0tIG1hbmFnZWRfdmVjdG9yPGF0b21pY19jZWxsX29yX2NvbGxl Y3Rpb24sIDV1LCB1bnNpZ25lZCBpbnQ+OjpyZXNpemUKICAgICAgICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICByb3c6OmFwcGx5 CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgbXV0YXRpb25fcGFydGl0aW9uX2FwcGxpZXI6OmFjY2VwdF9yb3dfY2Vs bAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgIG11dGF0aW9uX3BhcnRpdGlvbl92aWV3OjphY2NlcHQKICAgICAgICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwg ICAgICAgICAgIC0tNS41NiUtLSAweDJhNDM5OQogICAgICAgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICAgICAgICAgICAgIHwtLTIuMDglLS0gc21wX21lc3NhZ2VfcXVldWU6OnNt cF9tZXNzYWdlX3F1ZXVlCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwtLTYwLjAwJS0tIDB4NjBmMDAwMGMz MDAwCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg ICAgICAgICAgICB8ICAgICAgICAgIHwtLTEwLjAwJS0tIDB4NjAwMDAwMmQ3MjQwCiAgICAgICAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8 ICAgICAgICAgIHwtLTEwLjAwJS0tIDB4MTkKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfC0tMTAuMDAlLS0g MHhiCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg ICAgICAgICAgICB8ICAgICAgICAgICAtLTEwLjAwJS0tIDB4NwogICAgICAgICAgICAgICAgfCAg ICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwtLTEuOTMlLS0gc21wX21lc3NhZ2Vf cXVldWU6OnByb2Nlc3NfcXVldWU8NHVsLCBzbXBfbWVzc2FnZV9xdWV1ZTo6cHJvY2Vzc19jb21w bGV0aW9ucygpOjp7bGFtYmRhKHNtcF9tZXNzYWdlX3F1ZXVlOjp3b3JrX2l0ZW0qKSMxfT4KICAg ICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAg CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8LS0xLjYz JS0tIF9fdmRzb19jbG9ja19nZXR0aW1lCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAtLTEwMC4wMCUtLSBf X2Nsb2NrX2dldHRpbWUKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAg ICAgICAgIHwgICAgICAgICAgICAgICAgICAgICBzdGQ6OmNocm9ubzo6X1YyOjpzeXN0ZW1fY2xv Y2s6Om5vdwogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAg fCAgICAgICAgICAgICAgICAgICAgIDB4YTYzMjA5CiAgICAgICAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgICAgICAgICAgICAgfC0tMS40OSUtLSBtZW1vcnk6OnNtYWxsX3Bvb2w6 OmRlYWxsb2NhdGUKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfC0tNDAuMDAlLS0gbWFuYWdlZF92ZWN0b3I8 YXRvbWljX2NlbGxfb3JfY29sbGVjdGlvbiwgNXUsIHVuc2lnbmVkIGludD46OmVtcGxhY2VfYmFj azxhdG9taWNfY2VsbF9vcl9jb2xsZWN0aW9uPgogICAgICAgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8LS0yMC4wMCUt LSBzdGQ6Ol9IYXNodGFibGU8dW5zaWduZWQgbG9uZywgc3RkOjpwYWlyPHVuc2lnbmVkIGxvbmcg Y29uc3QsIHNlcnZpY2U6OnN0b3JhZ2VfcHJveHk6OnJoX2VudHJ5Piwgc3RkOjphbGxvY2F0b3I8 c3RkOjpwYWlyPHVuc2lnbmVkIGxvbmcgY29uc3QsIHNlcnZpY2U6OnN0b3JhZ2VfcHJveHk6OnJo X2VudHJ5PiA+LCBzdGQ6Ol9fZGV0YWlsOjpfU2VsZWN0MXN0LCBzdGQ6OmVxdWFsX3RvPHVuc2ln bmVkIGxvbmc+LCBzdGQ6Omhhc2g8dW5zaWduZWQgbG9uZz4sIHN0ZDo6X19kZXRhaWw6Ol9Nb2Rf cmFuZ2VfaGFzaGluZywgc3RkOjpfX2RldGFpbDo6X0RlZmF1bHRfcmFuZ2VkX2hhc2gsIHN0ZDo6 X19kZXRhaWw6Ol9QcmltZV9yZWhhc2hfcG9saWN5LCBzdGQ6Ol9fZGV0YWlsOjpfSGFzaHRhYmxl X3RyYWl0czxmYWxzZSwgZmFsc2UsIHRydWU+ID46Ol9NX2VyYXNlCiAgICAgICAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgc2Vy dmljZTo6c3RvcmFnZV9wcm94eTo6Z290X3Jlc3BvbnNlCiAgICAgICAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgX1pOMTJjb250 aW51YXRpb25JWk42ZnV0dXJlSUpFRTR0aGVuSVpaTjdzZXJ2aWNlMTNzdG9yYWdlX3Byb3h5MjJz ZW5kX3RvX2xpdmVfZW5kcG9pbnRzRW1FTktVbFJTdDRwYWlySUsxM2Jhc2ljX3NzdHJpbmdJY2pM ajE1RUVTdDZ2ZWN0b3JJTjNnbXMxMmluZXRfYWRkcmVzc0VTYUlTQl9FRUVFX2NsRVNGX0VVbHZF X1MxX0VFVDBfT1RfRVVsU0tfRV9KRUUzcnVuRXYKICAgICAgICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICByZWFjdG9yOjpkZWxf dGltZXIKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICAweDYxMDAwMDBlMjA0MAogICAgICAgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8LS0x MC4wMCUtLSBjcWwzOjpzdGF0ZW1lbnRzOjptb2RpZmljYXRpb25fc3RhdGVtZW50OjpnZXRfbXV0 YXRpb25zCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgICAgICAgICAgICB8ICAgICAgICAgIHwtLTEwLjAwJS0tIGNxbDM6OnN0YXRlbWVudHM6Om1v ZGlmaWNhdGlvbl9zdGF0ZW1lbnQ6OmJ1aWxkX3BhcnRpdGlvbl9rZXlzCiAgICAgICAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg Y3FsMzo6c3RhdGVtZW50czo6bW9kaWZpY2F0aW9uX3N0YXRlbWVudDo6Y3JlYXRlX2V4cGxvZGVk X2NsdXN0ZXJpbmdfcHJlZml4CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg ICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgMHg2MGMwMTRiZTBiMDAKICAgICAgICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwg ICAgICAgICAgfC0tMTAuMDAlLS0gbXV0YXRpb25fcGFydGl0aW9uOjp+bXV0YXRpb25fcGFydGl0 aW9uCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgc3RkOjp2ZWN0b3I8bXV0YXRpb24sIHN0ZDo6YWxsb2NhdG9yPG11 dGF0aW9uPiA+Ojp+dmVjdG9yCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg ICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgc2VydmljZTo6c3RvcmFnZV9wcm94eTo6 bXV0YXRlX3dpdGhfdHJpZ2dlcnMKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICBjcWwzOjpzdGF0ZW1lbnRzOjptb2Rp ZmljYXRpb25fc3RhdGVtZW50OjpleGVjdXRlX3dpdGhvdXRfY29uZGl0aW9uCiAgICAgICAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgY3FsMzo6c3RhdGVtZW50czo6bW9kaWZpY2F0aW9uX3N0YXRlbWVudDo6ZXhlY3V0ZQogICAg ICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgIGNxbDM6OnF1ZXJ5X3Byb2Nlc3Nvcjo6cHJvY2Vzc19zdGF0ZW1lbnQKICAgICAg ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICB0cmFuc3BvcnQ6OmNxbF9zZXJ2ZXI6OmNvbm5lY3Rpb246OnByb2Nlc3NfZXhlY3V0 ZQogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgIHRyYW5zcG9ydDo6Y3FsX3NlcnZlcjo6Y29ubmVjdGlvbjo6cHJvY2Vz c19yZXF1ZXN0X29uZQogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIGZ1dHVyaXplPGZ1dHVyZTxzdGQ6OnBhaXI8Zm9y ZWlnbl9wdHI8c2hhcmVkX3B0cjx0cmFuc3BvcnQ6OmNxbF9zZXJ2ZXI6OnJlc3BvbnNlPiA+LCBz ZXJ2aWNlOjpjbGllbnRfc3RhdGU+ID4gPjo6YXBwbHk8dHJhbnNwb3J0OjpjcWxfc2VydmVyOjpj b25uZWN0aW9uOjpwcm9jZXNzX3JlcXVlc3QoKTo6e2xhbWJkYShmdXR1cmU8c3RkOjpleHBlcmlt ZW50YWw6OmZ1bmRhbWVudGFsc192MTo6b3B0aW9uYWw8dHJhbnNwb3J0OjpjcWxfYmluYXJ5X2Zy YW1lX3YzPiA+JiYpIzF9OjpvcGVyYXRvcigpKGZ1dHVyZTxzdGQ6OmV4cGVyaW1lbnRhbDo6ZnVu ZGFtZW50YWxzX3YxOjpvcHRpb25hbDx0cmFuc3BvcnQ6OmNxbF9iaW5hcnlfZnJhbWVfdjM+ID4m JikgY29uc3Q6OntsYW1iZGEodGVtcG9yYXJ5X2J1ZmZlcjxjaGFyPikjMX06Om9wZXJhdG9yKCko dGVtcG9yYXJ5X2J1ZmZlcikgY29uc3Q6OntsYW1iZGEoKSMxfTo6b3BlcmF0b3IoKSgpOjp7bGFt YmRhKCkjMX0mPgogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgIGZ1dHVyaXplPGZ1dHVyZTw+ID46OmFwcGx5PHRyYW5z cG9ydDo6Y3FsX3NlcnZlcjo6Y29ubmVjdGlvbjo6cHJvY2Vzc19yZXF1ZXN0KCk6OntsYW1iZGEo ZnV0dXJlPHN0ZDo6ZXhwZXJpbWVudGFsOjpmdW5kYW1lbnRhbHNfdjE6Om9wdGlvbmFsPHRyYW5z cG9ydDo6Y3FsX2JpbmFyeV9mcmFtZV92Mz4gPiYmKSMxfTo6b3BlcmF0b3IoKShmdXR1cmU8c3Rk OjpleHBlcmltZW50YWw6OmZ1bmRhbWVudGFsc192MTo6b3B0aW9uYWw8dHJhbnNwb3J0OjpjcWxf YmluYXJ5X2ZyYW1lX3YzPiA+JiYpIGNvbnN0Ojp7bGFtYmRhKHRlbXBvcmFyeV9idWZmZXI8Y2hh cj4pIzF9LCB0ZW1wb3JhcnlfYnVmZmVyPgogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIGZ1dHVyaXplPGZ1dHVyZTw+ ID46OmFwcGx5PHRyYW5zcG9ydDo6Y3FsX3NlcnZlcjo6Y29ubmVjdGlvbjo6cHJvY2Vzc19yZXF1 ZXN0KCk6OntsYW1iZGEoZnV0dXJlPHN0ZDo6ZXhwZXJpbWVudGFsOjpmdW5kYW1lbnRhbHNfdjE6 Om9wdGlvbmFsPHRyYW5zcG9ydDo6Y3FsX2JpbmFyeV9mcmFtZV92Mz4gPiYmKSMxfSwgZnV0dXJl PHN0ZDo6ZXhwZXJpbWVudGFsOjpmdW5kYW1lbnRhbHNfdjE6Om9wdGlvbmFsPHRyYW5zcG9ydDo6 Y3FsX2JpbmFyeV9mcmFtZV92Mz4gPiA+CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgMHg4OTYxZGUKICAgICAgICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwg ICAgICAgICAgIC0tMTAuMDAlLS0gb2JqZWN0X2RlbGV0ZXJfaW1wbDxkZWxldGVyPjo6fm9iamVj dF9kZWxldGVyX2ltcGwKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAg ICAgICAgIHwgICAgICAgICAgICAgICAgICAgICBfWk4xMmNvbnRpbnVhdGlvbklaTjZmdXR1cmVJ SkVFMTJ0aGVuX3dyYXBwZWRJWlpOUzFfN2ZpbmFsbHlJWjdkb193aXRoSTExZm9yZWlnbl9wdHJJ MTBzaGFyZWRfcHRySU45dHJhbnNwb3J0MTBjcWxfc2VydmVyOHJlc3BvbnNlRUVFWlpOUzhfMTBj b25uZWN0aW9uMTR3cml0ZV9yZXNwb25zZUVPU0JfRU5VbHZFX2NsRXZFVWxSVF9FX0VEYU9TRl9P VDBfRVVsdkVfRUVTMV9TSV9FTlVsUzFfRV9jbEVTMV9FVWxTRl9FX1MxX0VFU0pfU0lfRVVsU0lf RV9KRUVEMEV2CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAg ICB8ICAgICAgICAgICAgICAgICAgICAgMHg2MWEwMDAwYzNkYjAKICAgICAgICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8LS0xLjM0JS0tIGRodDo6ZGVjb3Jh dGVkX2tleTo6ZXF1YWwKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfC0tODMuMzMlLS0gMHg2MDcwMDAxMzhm MDAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAg ICAgICAgICAgIHwgICAgICAgICAgIC0tMTYuNjclLS0gMHg2MGEwMDAwZTBmNDAKICAgICAgICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgCiAgICAg ICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8LS0xLjM0JS0tIHNl cnZpY2U6OnN0b3JhZ2VfcHJveHk6OnNlbmRfdG9fbGl2ZV9lbmRwb2ludHMKICAgICAgICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8LS0xLjE5JS0tIHRyYW5z cG9ydDo6Y3FsX3NlcnZlcjo6Y29ubmVjdGlvbjo6cHJvY2Vzc19leGVjdXRlCiAgICAgICAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHRyYW5zcG9y dDo6Y3FsX3NlcnZlcjo6Y29ubmVjdGlvbjo6cHJvY2Vzc19yZXF1ZXN0X29uZQogICAgICAgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICBmdXR1cml6 ZTxmdXR1cmU8c3RkOjpwYWlyPGZvcmVpZ25fcHRyPHNoYXJlZF9wdHI8dHJhbnNwb3J0OjpjcWxf c2VydmVyOjpyZXNwb25zZT4gPiwgc2VydmljZTo6Y2xpZW50X3N0YXRlPiA+ID46OmFwcGx5PHRy YW5zcG9ydDo6Y3FsX3NlcnZlcjo6Y29ubmVjdGlvbjo6cHJvY2Vzc19yZXF1ZXN0KCk6OntsYW1i ZGEoZnV0dXJlPHN0ZDo6ZXhwZXJpbWVudGFsOjpmdW5kYW1lbnRhbHNfdjE6Om9wdGlvbmFsPHRy YW5zcG9ydDo6Y3FsX2JpbmFyeV9mcmFtZV92Mz4gPiYmKSMxfTo6b3BlcmF0b3IoKShmdXR1cmU8 c3RkOjpleHBlcmltZW50YWw6OmZ1bmRhbWVudGFsc192MTo6b3B0aW9uYWw8dHJhbnNwb3J0Ojpj cWxfYmluYXJ5X2ZyYW1lX3YzPiA+JiYpIGNvbnN0Ojp7bGFtYmRhKHRlbXBvcmFyeV9idWZmZXI8 Y2hhcj4pIzF9OjpvcGVyYXRvcigpKHRlbXBvcmFyeV9idWZmZXIpIGNvbnN0Ojp7bGFtYmRhKCkj MX06Om9wZXJhdG9yKCkoKTo6e2xhbWJkYSgpIzF9Jj4KICAgICAgICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgZnV0dXJpemU8ZnV0dXJlPD4gPjo6 YXBwbHk8dHJhbnNwb3J0OjpjcWxfc2VydmVyOjpjb25uZWN0aW9uOjpwcm9jZXNzX3JlcXVlc3Qo KTo6e2xhbWJkYShmdXR1cmU8c3RkOjpleHBlcmltZW50YWw6OmZ1bmRhbWVudGFsc192MTo6b3B0 aW9uYWw8dHJhbnNwb3J0OjpjcWxfYmluYXJ5X2ZyYW1lX3YzPiA+JiYpIzF9OjpvcGVyYXRvcigp KGZ1dHVyZTxzdGQ6OmV4cGVyaW1lbnRhbDo6ZnVuZGFtZW50YWxzX3YxOjpvcHRpb25hbDx0cmFu c3BvcnQ6OmNxbF9iaW5hcnlfZnJhbWVfdjM+ID4mJikgY29uc3Q6OntsYW1iZGEodGVtcG9yYXJ5 X2J1ZmZlcjxjaGFyPikjMX0sIHRlbXBvcmFyeV9idWZmZXI+CiAgICAgICAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIGZ1dHVyaXplPGZ1dHVyZTw+ ID46OmFwcGx5PHRyYW5zcG9ydDo6Y3FsX3NlcnZlcjo6Y29ubmVjdGlvbjo6cHJvY2Vzc19yZXF1 ZXN0KCk6OntsYW1iZGEoZnV0dXJlPHN0ZDo6ZXhwZXJpbWVudGFsOjpmdW5kYW1lbnRhbHNfdjE6 Om9wdGlvbmFsPHRyYW5zcG9ydDo6Y3FsX2JpbmFyeV9mcmFtZV92Mz4gPiYmKSMxfSwgZnV0dXJl PHN0ZDo6ZXhwZXJpbWVudGFsOjpmdW5kYW1lbnRhbHNfdjE6Om9wdGlvbmFsPHRyYW5zcG9ydDo6 Y3FsX2JpbmFyeV9mcmFtZV92Mz4gPiA+CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwtLTg3LjUwJS0tIHRy YW5zcG9ydDo6Y3FsX3NlcnZlcjo6Y29ubmVjdGlvbjo6cHJvY2Vzc19yZXF1ZXN0CiAgICAgICAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgZG9fdW50aWxfY29udGludWVkPHRyYW5zcG9ydDo6Y3FsX3NlcnZlcjo6Y29ubmVjdGlv bjo6cHJvY2VzcygpOjp7bGFtYmRhKCkjMn0sIHRyYW5zcG9ydDo6Y3FsX3NlcnZlcjo6Y29ubmVj dGlvbjo6cHJvY2VzcygpOjp7bGFtYmRhKCkjMX0mPgogICAgICAgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIGRvX3ZvaWRfZnV0 dXJpemVfYXBwbHk8dm9pZCBkb191bnRpbF9jb250aW51ZWQ8dHJhbnNwb3J0OjpjcWxfc2VydmVy Ojpjb25uZWN0aW9uOjpwcm9jZXNzKCk6OntsYW1iZGEoKSMyfSwgdHJhbnNwb3J0OjpjcWxfc2Vy dmVyOjpjb25uZWN0aW9uOjpwcm9jZXNzKCk6OntsYW1iZGEoKSMxfSY+KHRyYW5zcG9ydDo6Y3Fs X3NlcnZlcjo6Y29ubmVjdGlvbjo6cHJvY2VzcygpOjp7bGFtYmRhKCkjMX0mLCB0cmFuc3BvcnQ6 OmNxbF9zZXJ2ZXI6OmNvbm5lY3Rpb246OnByb2Nlc3MoKTo6e2xhbWJkYSgpIzJ9JiYsIHByb21p c2U8Pik6OntsYW1iZGEoZnV0dXJlPD4pIzF9LCBwcm9taXNlPD4gPgogICAgICAgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIGRv X3ZvaWRfZnV0dXJpemVfYXBwbHk8dm9pZCBkb191bnRpbF9jb250aW51ZWQ8dHJhbnNwb3J0Ojpj cWxfc2VydmVyOjpjb25uZWN0aW9uOjpwcm9jZXNzKCk6OntsYW1iZGEoKSMyfSwgdHJhbnNwb3J0 OjpjcWxfc2VydmVyOjpjb25uZWN0aW9uOjpwcm9jZXNzKCk6OntsYW1iZGEoKSMxfSY+KHRyYW5z cG9ydDo6Y3FsX3NlcnZlcjo6Y29ubmVjdGlvbjo6cHJvY2VzcygpOjp7bGFtYmRhKCkjMX0mLCB0 cmFuc3BvcnQ6OmNxbF9zZXJ2ZXI6OmNvbm5lY3Rpb246OnByb2Nlc3MoKTo6e2xhbWJkYSgpIzJ9 JiYsIHByb21pc2U8Pik6OntsYW1iZGEoZnV0dXJlPD4pIzF9LCBwcm9taXNlPD4gPgogICAgICAg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgIDB4NjBlMDAwMGMzMDAwCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAtLTEyLjUwJS0tIDB4ODk2 MWRlCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAg ICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAg fC0tMS4xOSUtLSByZWFjdG9yOjpydW4KICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfC0tODcuNTAlLS0gc21w Ojpjb25maWd1cmUoYm9vc3Q6OnByb2dyYW1fb3B0aW9uczo6dmFyaWFibGVzX21hcCk6OntsYW1i ZGEoKSMxfTo6b3BlcmF0b3IoKQogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg ICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIGNvbnRpbnVhdGlvbjxmdXR1cmU8dGVt cG9yYXJ5X2J1ZmZlcjxjaGFyPiA+IGZ1dHVyZTw+Ojp0aGVuPGZ1dHVyZTx0ZW1wb3JhcnlfYnVm ZmVyPGNoYXI+ID4gZmlsZTo6ZG1hX3JlYWRfYnVsazxjaGFyPih1bnNpZ25lZCBsb25nLCB1bnNp Z25lZCBsb25nKTo6e2xhbWJkYSh1bnNpZ25lZCBsb25nKSMxfTo6b3BlcmF0b3IoKSh1bnNpZ25l ZCBsb25nKTo6e2xhbWJkYSgpIzN9LCBmdXR1cmU8dGVtcG9yYXJ5X2J1ZmZlcjxjaGFyPiA+ID4o ZnV0dXJlPHRlbXBvcmFyeV9idWZmZXI8Y2hhcj4gPiBmaWxlOjpkbWFfcmVhZF9idWxrPGNoYXI+ KHVuc2lnbmVkIGxvbmcsIHVuc2lnbmVkIGxvbmcpOjp7bGFtYmRhKHVuc2lnbmVkIGxvbmcpIzF9 OjpvcGVyYXRvcigpKHVuc2lnbmVkIGxvbmcpOjp7bGFtYmRhKCkjM30mJik6OntsYW1iZGEoZnV0 dXJlPHRlbXBvcmFyeV9idWZmZXI8Y2hhcj4gPikjMX0+OjpydW4KICAgICAgICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAweDYw MDAwMDA0M2QwMAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgLS0xMi41MCUtLSBhcHBfdGVtcGxhdGU6OnJ1 bl9kZXByZWNhdGVkCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAg ICAgICB8ICAgICAgICAgICAgICAgICAgICAgbWFpbgogICAgICAgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIF9fbGliY19zdGFy dF9tYWluCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8 ICAgICAgICAgICAgICAgICAgICAgX0dMT0JBTF9fc3ViX0lfX1pOM29yZzZhcGFjaGU5Y2Fzc2Fu ZHJhMjFnX2Nhc3NhbmRyYV9jb25zdGFudHNFCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgMHg3ZjRhZTIwYzlmYTAK ICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAg ICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8LS0x LjA0JS0tIF9fY2xvY2tfZ2V0dGltZQogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgICAgICAgICAgICAgfCAgICAgICAgICBzdGQ6OmNocm9ubzo6X1YyOjpzeXN0ZW1fY2xvY2s6 Om5vdwogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAg ICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg ICAgICAgICAgICAgfCAgICAgICAgICB8LS00Mi44NiUtLSByZWFjdG9yOjpydW4KICAgICAgICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICBzbXA6OmNvbmZpZ3VyZShib29zdDo6cHJvZ3JhbV9vcHRpb25zOjp2YXJpYWJsZXNfbWFw KTo6e2xhbWJkYSgpIzF9OjpvcGVyYXRvcigpCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgY29udGludWF0aW9uPGZ1 dHVyZTx0ZW1wb3JhcnlfYnVmZmVyPGNoYXI+ID4gZnV0dXJlPD46OnRoZW48ZnV0dXJlPHRlbXBv cmFyeV9idWZmZXI8Y2hhcj4gPiBmaWxlOjpkbWFfcmVhZF9idWxrPGNoYXI+KHVuc2lnbmVkIGxv bmcsIHVuc2lnbmVkIGxvbmcpOjp7bGFtYmRhKHVuc2lnbmVkIGxvbmcpIzF9OjpvcGVyYXRvcigp KHVuc2lnbmVkIGxvbmcpOjp7bGFtYmRhKCkjM30sIGZ1dHVyZTx0ZW1wb3JhcnlfYnVmZmVyPGNo YXI+ID4gPihmdXR1cmU8dGVtcG9yYXJ5X2J1ZmZlcjxjaGFyPiA+IGZpbGU6OmRtYV9yZWFkX2J1 bGs8Y2hhcj4odW5zaWduZWQgbG9uZywgdW5zaWduZWQgbG9uZyk6OntsYW1iZGEodW5zaWduZWQg bG9uZykjMX06Om9wZXJhdG9yKCkodW5zaWduZWQgbG9uZyk6OntsYW1iZGEoKSMzfSYmKTo6e2xh bWJkYShmdXR1cmU8dGVtcG9yYXJ5X2J1ZmZlcjxjaGFyPiA+KSMxfT46OnJ1bgogICAgICAgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIDB4NjAwMDAwMDQzZDAwCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg ICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwtLTE0LjI5JS0tIDB4YTYzMjA5 CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAg ICAgICAgICB8ICAgICAgICAgIHwtLTE0LjI5JS0tIGNvbnRpbnVhdGlvbjxmdXR1cmU8PiBmdXR1 cmU8Pjo6ZmluYWxseTxhdXRvIGRvX3dpdGg8c3RkOjp2ZWN0b3I8ZnJvemVuX211dGF0aW9uLCBz dGQ6OmFsbG9jYXRvcjxmcm96ZW5fbXV0YXRpb24+ID4sIHNoYXJlZF9wdHI8c2VydmljZTo6c3Rv cmFnZV9wcm94eT4sIHNlcnZpY2U6OnN0b3JhZ2VfcHJveHk6OmluaXRfbWVzc2FnaW5nX3NlcnZp Y2UoKTo6e2xhbWJkYShzdGQ6OnZlY3Rvcjxmcm96ZW5fbXV0YXRpb24sIHN0ZDo6YWxsb2NhdG9y PGZyb3plbl9tdXRhdGlvbj4gPikjMX06Om9wZXJhdG9yKCkoc3RkOjp2ZWN0b3I8ZnJvemVuX211 dGF0aW9uLCBzdGQ6OmFsbG9jYXRvcjxmcm96ZW5fbXV0YXRpb24+ID4pIGNvbnN0Ojp7bGFtYmRh KHN0ZDo6dmVjdG9yPGZyb3plbl9tdXRhdGlvbiwgc3RkOjphbGxvY2F0b3I8ZnJvemVuX211dGF0 aW9uPiA+IGNvbnN0Jiwgc2hhcmVkX3B0cjxzZXJ2aWNlOjpzdG9yYWdlX3Byb3h5PiYpIzF9Pihz dGQ6OnZlY3Rvcjxmcm96ZW5fbXV0YXRpb24sIHN0ZDo6YWxsb2NhdG9yPGZyb3plbl9tdXRhdGlv bj4gPiYmLCBzaGFyZWRfcHRyPHNlcnZpY2U6OnN0b3JhZ2VfcHJveHk+JiYsIHNlcnZpY2U6OnN0 b3JhZ2VfcHJveHk6OmluaXRfbWVzc2FnaW5nX3NlcnZpY2UoKTo6e2xhbWJkYShzdGQ6OnZlY3Rv cjxmcm96ZW5fbXV0YXRpb24sIHN0ZDo6YWxsb2NhdG9yPGZyb3plbl9tdXRhdGlvbj4gPikjMX06 Om9wZXJhdG9yKCkoc3RkOjp2ZWN0b3I8ZnJvemVuX211dGF0aW9uLCBzdGQ6OmFsbG9jYXRvcjxm cm96ZW5fbXV0YXRpb24+ID4pIGNvbnN0Ojp7bGFtYmRhKHN0ZDo6dmVjdG9yPGZyb3plbl9tdXRh dGlvbiwgc3RkOjphbGxvY2F0b3I8ZnJvemVuX211dGF0aW9uPiA+IGNvbnN0Jiwgc2hhcmVkX3B0 cjxzZXJ2aWNlOjpzdG9yYWdlX3Byb3h5PiYpIzF9JiYpOjp7bGFtYmRhKCkjMX0+KHNlcnZpY2U6 OnN0b3JhZ2VfcHJveHk6OmluaXRfbWVzc2FnaW5nX3NlcnZpY2UoKTo6e2xhbWJkYShzdGQ6OnZl Y3Rvcjxmcm96ZW5fbXV0YXRpb24sIHN0ZDo6YQogICAgICAgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIDB4MmI3NDM0CiAgICAg ICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAg ICB8ICAgICAgICAgIHwtLTE0LjI5JS0tIF9aTjhmdXR1cml6ZUk2ZnV0dXJlSUpTdDEwdW5pcXVl X3B0cklONGNxbDMxN3VwZGF0ZV9wYXJhbWV0ZXJzRVN0MTRkZWZhdWx0X2RlbGV0ZUlTM19FRUVF RTVhcHBseUlaTlMyXzEwc3RhdGVtZW50czIybW9kaWZpY2F0aW9uX3N0YXRlbWVudDIybWFrZV91 cGRhdGVfcGFyYW1ldGVyc0VSTjdzZWFzdGFyN3NoYXJkZWRJTjdzZXJ2aWNlMTNzdG9yYWdlX3By b3h5RUVFMTNsd19zaGFyZWRfcHRySVN0NnZlY3RvckkxM3BhcnRpdGlvbl9rZXlTYUlTS19FRUVT SV9JMjZleHBsb2RlZF9jbHVzdGVyaW5nX3ByZWZpeEVSS05TMl8xM3F1ZXJ5X29wdGlvbnNFYmxF VWxUX0VfSk5TdDEyZXhwZXJpbWVudGFsMTVmdW5kYW1lbnRhbHNfdjE4b3B0aW9uYWxJTlMzXzEz cHJlZmV0Y2hfZGF0YUVFRUVFRVM3X09TVF9PU3Q1dHVwbGVJSkRwVDBfRUUKICAgICAgICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICBjcWwzOjpzdGF0ZW1lbnRzOjptb2RpZmljYXRpb25fc3RhdGVtZW50OjptYWtlX3VwZGF0ZV9w YXJhbWV0ZXJzCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgY3FsMzo6c3RhdGVtZW50czo6bW9kaWZpY2F0aW9uX3N0 YXRlbWVudDo6Z2V0X211dGF0aW9ucwogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIGNxbDM6OnN0YXRlbWVudHM6Om1v ZGlmaWNhdGlvbl9zdGF0ZW1lbnQ6OmV4ZWN1dGVfd2l0aG91dF9jb25kaXRpb24KICAgICAgICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICBjcWwzOjpxdWVyeV9vcHRpb25zOjpxdWVyeV9vcHRpb25zCiAgICAgICAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgMHg3 ZjRhZDZiZjgwZTAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgIC0tMTQuMjklLS0gZGF0YWJhc2U6OmFwcGx5 X2luX21lbW9yeQogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAg ICAgfCAgICAgICAgICAgICAgICAgICAgIGRhdGFiYXNlOjpkb19hcHBseQogICAgICAgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAg IF9aTjEyY29udGludWF0aW9uSVpONmZ1dHVyZUlKRUU0dGhlbklaTjhkYXRhYmFzZTVhcHBseUVS SzE1ZnJvemVuX211dGF0aW9uRVVsdkVfUzFfRUVUMF9PVF9FVWxTQV9FX0pFRTNydW5FdgogICAg ICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAg ICAgICAgICAgIHJlYWN0b3I6OmRlbF90aW1lcgogICAgICAgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIDB4NjA5MDAwMGUyMDQw CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAg ICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfC0t MS4wNCUtLSBtZW1vcnk6OnNtYWxsX3Bvb2w6OmFsbG9jYXRlCiAgICAgICAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAg ICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwt LTE0LjI5JS0tIDB4NTI1N2MzNzk0NjlkOQogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8LS0xNC4yOSUtLSAw eDYwOTAwMmI5ZmU5OAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8LS0xNC4yOSUtLSAweDEzYzhiOTAKICAg ICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAg ICAgIHwgICAgICAgICAgfC0tMTQuMjklLS0gMHg2MGYwMDAxOTA3MTAKICAgICAgICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAK ICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAg ICAgfC0tMTQuMjklLS0gMHgyNQogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg ICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8LS0xNC4yOSUtLSAweDdmNGFk NmJmODRjMAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgICAgICAgICAgICAgfCAgICAgICAgICAgLS0xNC4yOSUtLSAweDdmNGFkNTNmODFmMAogICAg ICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAK ICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwtLTAuODkl LS0gZGI6OnNlcmlhbGl6ZXI8YXRvbWljX2NlbGxfdmlldz46OnNlcmlhbGl6ZXIKICAgICAgICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgbXV0YXRp b25fcGFydGl0aW9uX3NlcmlhbGl6ZXI6OndyaXRlX3dpdGhvdXRfZnJhbWluZwogICAgICAgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICBmcm96ZW5f bXV0YXRpb246OmZyb3plbl9tdXRhdGlvbgogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgICAgICAgICAgICAgfCAgICAgICAgICBmcm96ZW5fbXV0YXRpb246OmZyb3plbl9tdXRh dGlvbgogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAg ICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAg IHwtLTAuODklLS0gZG9fdW50aWxfY29udGludWVkPHRyYW5zcG9ydDo6Y3FsX3NlcnZlcjo6Y29u bmVjdGlvbjo6cHJvY2VzcygpOjp7bGFtYmRhKCkjMn0sIHRyYW5zcG9ydDo6Y3FsX3NlcnZlcjo6 Y29ubmVjdGlvbjo6cHJvY2VzcygpOjp7bGFtYmRhKCkjMX0mPgogICAgICAgICAgICAgICAgfCAg ICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICBkb192b2lkX2Z1dHVyaXpl X2FwcGx5PHZvaWQgZG9fdW50aWxfY29udGludWVkPHRyYW5zcG9ydDo6Y3FsX3NlcnZlcjo6Y29u bmVjdGlvbjo6cHJvY2VzcygpOjp7bGFtYmRhKCkjMn0sIHRyYW5zcG9ydDo6Y3FsX3NlcnZlcjo6 Y29ubmVjdGlvbjo6cHJvY2VzcygpOjp7bGFtYmRhKCkjMX0mPih0cmFuc3BvcnQ6OmNxbF9zZXJ2 ZXI6OmNvbm5lY3Rpb246OnByb2Nlc3MoKTo6e2xhbWJkYSgpIzF9JiwgdHJhbnNwb3J0OjpjcWxf c2VydmVyOjpjb25uZWN0aW9uOjpwcm9jZXNzKCk6OntsYW1iZGEoKSMyfSYmLCBwcm9taXNlPD4p Ojp7bGFtYmRhKGZ1dHVyZTw+KSMxfSwgcHJvbWlzZTw+ID4KICAgICAgICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgZG9fdm9pZF9mdXR1cml6ZV9h cHBseTx2b2lkIGRvX3VudGlsX2NvbnRpbnVlZDx0cmFuc3BvcnQ6OmNxbF9zZXJ2ZXI6OmNvbm5l Y3Rpb246OnByb2Nlc3MoKTo6e2xhbWJkYSgpIzJ9LCB0cmFuc3BvcnQ6OmNxbF9zZXJ2ZXI6OmNv bm5lY3Rpb246OnByb2Nlc3MoKTo6e2xhbWJkYSgpIzF9Jj4odHJhbnNwb3J0OjpjcWxfc2VydmVy Ojpjb25uZWN0aW9uOjpwcm9jZXNzKCk6OntsYW1iZGEoKSMxfSYsIHRyYW5zcG9ydDo6Y3FsX3Nl cnZlcjo6Y29ubmVjdGlvbjo6cHJvY2VzcygpOjp7bGFtYmRhKCkjMn0mJiwgcHJvbWlzZTw+KTo6 e2xhbWJkYShmdXR1cmU8PikjMX0sIHByb21pc2U8PiA+CiAgICAgICAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIDB4NjBmMDAwMGMzMDAwCiAgICAg ICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIAog ICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfC0tMC44OSUt LSBmdXR1cml6ZTxmdXR1cmU8PiA+OjphcHBseTx0cmFuc3BvcnQ6OmNxbF9zZXJ2ZXI6OmNvbm5l Y3Rpb246OnByb2Nlc3NfcmVxdWVzdCgpOjp7bGFtYmRhKGZ1dHVyZTxzdGQ6OmV4cGVyaW1lbnRh bDo6ZnVuZGFtZW50YWxzX3YxOjpvcHRpb25hbDx0cmFuc3BvcnQ6OmNxbF9iaW5hcnlfZnJhbWVf djM+ID4mJikjMX06Om9wZXJhdG9yKCkoZnV0dXJlPHN0ZDo6ZXhwZXJpbWVudGFsOjpmdW5kYW1l bnRhbHNfdjE6Om9wdGlvbmFsPHRyYW5zcG9ydDo6Y3FsX2JpbmFyeV9mcmFtZV92Mz4gPiYmKSBj b25zdDo6e2xhbWJkYSh0ZW1wb3JhcnlfYnVmZmVyPGNoYXI+KSMxfSwgdGVtcG9yYXJ5X2J1ZmZl cj4KICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAg ICAgICAgZnV0dXJpemU8ZnV0dXJlPD4gPjo6YXBwbHk8dHJhbnNwb3J0OjpjcWxfc2VydmVyOjpj b25uZWN0aW9uOjpwcm9jZXNzX3JlcXVlc3QoKTo6e2xhbWJkYShmdXR1cmU8c3RkOjpleHBlcmlt ZW50YWw6OmZ1bmRhbWVudGFsc192MTo6b3B0aW9uYWw8dHJhbnNwb3J0OjpjcWxfYmluYXJ5X2Zy YW1lX3YzPiA+JiYpIzF9LCBmdXR1cmU8c3RkOjpleHBlcmltZW50YWw6OmZ1bmRhbWVudGFsc192 MTo6b3B0aW9uYWw8dHJhbnNwb3J0OjpjcWxfYmluYXJ5X2ZyYW1lX3YzPiA+ID4KICAgICAgICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgdHJhbnNw b3J0OjpjcWxfc2VydmVyOjpjb25uZWN0aW9uOjpwcm9jZXNzX3JlcXVlc3QKICAgICAgICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgZG9fdW50aWxf Y29udGludWVkPHRyYW5zcG9ydDo6Y3FsX3NlcnZlcjo6Y29ubmVjdGlvbjo6cHJvY2VzcygpOjp7 bGFtYmRhKCkjMn0sIHRyYW5zcG9ydDo6Y3FsX3NlcnZlcjo6Y29ubmVjdGlvbjo6cHJvY2Vzcygp Ojp7bGFtYmRhKCkjMX0mPgogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAg ICAgICAgICAgfCAgICAgICAgICBkb192b2lkX2Z1dHVyaXplX2FwcGx5PHZvaWQgZG9fdW50aWxf Y29udGludWVkPHRyYW5zcG9ydDo6Y3FsX3NlcnZlcjo6Y29ubmVjdGlvbjo6cHJvY2VzcygpOjp7 bGFtYmRhKCkjMn0sIHRyYW5zcG9ydDo6Y3FsX3NlcnZlcjo6Y29ubmVjdGlvbjo6cHJvY2Vzcygp Ojp7bGFtYmRhKCkjMX0mPih0cmFuc3BvcnQ6OmNxbF9zZXJ2ZXI6OmNvbm5lY3Rpb246OnByb2Nl c3MoKTo6e2xhbWJkYSgpIzF9JiwgdHJhbnNwb3J0OjpjcWxfc2VydmVyOjpjb25uZWN0aW9uOjpw cm9jZXNzKCk6OntsYW1iZGEoKSMyfSYmLCBwcm9taXNlPD4pOjp7bGFtYmRhKGZ1dHVyZTw+KSMx fSwgcHJvbWlzZTw+ID4KICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAg ICAgICAgIHwgICAgICAgICAgZG9fdm9pZF9mdXR1cml6ZV9hcHBseTx2b2lkIGRvX3VudGlsX2Nv bnRpbnVlZDx0cmFuc3BvcnQ6OmNxbF9zZXJ2ZXI6OmNvbm5lY3Rpb246OnByb2Nlc3MoKTo6e2xh bWJkYSgpIzJ9LCB0cmFuc3BvcnQ6OmNxbF9zZXJ2ZXI6OmNvbm5lY3Rpb246OnByb2Nlc3MoKTo6 e2xhbWJkYSgpIzF9Jj4odHJhbnNwb3J0OjpjcWxfc2VydmVyOjpjb25uZWN0aW9uOjpwcm9jZXNz KCk6OntsYW1iZGEoKSMxfSYsIHRyYW5zcG9ydDo6Y3FsX3NlcnZlcjo6Y29ubmVjdGlvbjo6cHJv Y2VzcygpOjp7bGFtYmRhKCkjMn0mJiwgcHJvbWlzZTw+KTo6e2xhbWJkYShmdXR1cmU8PikjMX0s IHByb21pc2U8PiA+CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwtLTgzLjMzJS0tIDB4NjA5MDAwMGMzMDAw CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAg ICAgICAgICB8ICAgICAgICAgICAtLTE2LjY3JS0tIDB4NjAwMDAwMDQ0NDAwCiAgICAgICAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIAogICAgICAg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfC0tMC44OSUtLSBzdGQ6 Ol9GdW5jdGlvbl9oYW5kbGVyPHZvaWQgKCksIHJlYWN0b3I6OnJ1bigpOjp7bGFtYmRhKCkjOH0+ OjpfTV9pbnZva2UKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfC0tNTAuMDAlLS0gcmVhY3Rvcjo6cnVuCiAg ICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgc21wOjpjb25maWd1cmUoYm9vc3Q6OnByb2dyYW1fb3B0aW9uczo6dmFyaWFi bGVzX21hcCk6OntsYW1iZGEoKSMxfTo6b3BlcmF0b3IoKQogICAgICAgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIGNvbnRpbnVh dGlvbjxmdXR1cmU8dGVtcG9yYXJ5X2J1ZmZlcjxjaGFyPiA+IGZ1dHVyZTw+Ojp0aGVuPGZ1dHVy ZTx0ZW1wb3JhcnlfYnVmZmVyPGNoYXI+ID4gZmlsZTo6ZG1hX3JlYWRfYnVsazxjaGFyPih1bnNp Z25lZCBsb25nLCB1bnNpZ25lZCBsb25nKTo6e2xhbWJkYSh1bnNpZ25lZCBsb25nKSMxfTo6b3Bl cmF0b3IoKSh1bnNpZ25lZCBsb25nKTo6e2xhbWJkYSgpIzN9LCBmdXR1cmU8dGVtcG9yYXJ5X2J1 ZmZlcjxjaGFyPiA+ID4oZnV0dXJlPHRlbXBvcmFyeV9idWZmZXI8Y2hhcj4gPiBmaWxlOjpkbWFf cmVhZF9idWxrPGNoYXI+KHVuc2lnbmVkIGxvbmcsIHVuc2lnbmVkIGxvbmcpOjp7bGFtYmRhKHVu c2lnbmVkIGxvbmcpIzF9OjpvcGVyYXRvcigpKHVuc2lnbmVkIGxvbmcpOjp7bGFtYmRhKCkjM30m Jik6OntsYW1iZGEoZnV0dXJlPHRlbXBvcmFyeV9idWZmZXI8Y2hhcj4gPikjMX0+OjpydW4KICAg ICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICAweDYwMDAwMDA0M2QwMAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgLS01MC4wMCUtLSBy ZWFjdG9yOjpzaWduYWxzOjpzaWduYWxfaGFuZGxlcjo6c2lnbmFsX2hhbmRsZXIKICAgICAgICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAg ICAgICAweDNlOAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAg ICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAg ICAgICAgIHwtLTAuNzQlLS0gZGI6OmNvbW1pdGxvZzo6c2VnbWVudDo6YWxsb2NhdGUKICAgICAg ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAg IHwgICAgICAgICAgIC0tMTAwLjAwJS0tIGRiOjpjb21taXRsb2c6OmFkZAogICAgICAgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAg IGRhdGFiYXNlOjpkb19hcHBseQogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg ICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAg ICAgfC0tNzUuMDAlLS0gZGF0YWJhc2U6OmFwcGx5CiAgICAgICAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICBz bXBfbWVzc2FnZV9xdWV1ZTo6YXN5bmNfd29ya19pdGVtPGZ1dHVyZTw+IHNlYXN0YXI6OnNoYXJk ZWQ8ZGF0YWJhc2U+OjppbnZva2Vfb248c2VydmljZTo6c3RvcmFnZV9wcm94eTo6bXV0YXRlX2xv Y2FsbHkobXV0YXRpb24gY29uc3QmKTo6e2xhbWJkYShkYXRhYmFzZSYpIzF9LCBmdXR1cmU8PiA+ KHVuc2lnbmVkIGludCwgc2VydmljZTo6c3RvcmFnZV9wcm94eTo6bXV0YXRlX2xvY2FsbHkobXV0 YXRpb24gY29uc3QmKTo6e2xhbWJkYShkYXRhYmFzZSYpIzF9JiYpOjp7bGFtYmRhKCkjMX0+Ojpw cm9jZXNzCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8 ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICBzbXBfbWVzc2FnZV9xdWV1ZTo6cHJvY2Vz c19xdWV1ZTwydWwsIHNtcF9tZXNzYWdlX3F1ZXVlOjpwcm9jZXNzX2luY29taW5nKCk6OntsYW1i ZGEoc21wX21lc3NhZ2VfcXVldWU6OndvcmtfaXRlbSopIzF9PgogICAgICAgICAgICAgICAgfCAg ICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAg ICAgICAgYm9vc3Q6OmxvY2tmcmVlOjpkZXRhaWw6OnJpbmdidWZmZXJfYmFzZTxzbXBfbWVzc2Fn ZV9xdWV1ZTo6d29ya19pdGVtKj46OnBvcAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgYm9vc3Q6 OnByb2dyYW1fb3B0aW9uczo6dmFyaWFibGVzX21hcDo6Z2V0CiAgICAgICAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAg ICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwg ICAgICAgICAgICAgICAgICAgICAgLS0yNS4wMCUtLSBfWk4xMmNvbnRpbnVhdGlvbklaTjZmdXR1 cmVJSkVFNHRoZW5JWk44ZGF0YWJhc2U1YXBwbHlFUksxNWZyb3plbl9tdXRhdGlvbkVVbHZFX1Mx X0VFVDBfT1RfRVVsU0FfRV9KRUUzcnVuRXYKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYWN0 b3I6OmRlbF90aW1lcgogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAg ICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg2MGIwMDAwZTIwNDAKICAg ICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAg CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8LS0wLjc0 JS0tIHNlcnZpY2U6OnN0b3JhZ2VfcHJveHk6OmNyZWF0ZV93cml0ZV9yZXNwb25zZV9oYW5kbGVy CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAg ICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfC0t MC43NCUtLSB0cmFuc3BvcnQ6OmNxbF9zZXJ2ZXI6OmNvbm5lY3Rpb246OnByb2Nlc3NfcmVxdWVz dF9vbmUKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwg ICAgICAgICAgZnV0dXJpemU8ZnV0dXJlPHN0ZDo6cGFpcjxmb3JlaWduX3B0cjxzaGFyZWRfcHRy PHRyYW5zcG9ydDo6Y3FsX3NlcnZlcjo6cmVzcG9uc2U+ID4sIHNlcnZpY2U6OmNsaWVudF9zdGF0 ZT4gPiA+OjphcHBseTx0cmFuc3BvcnQ6OmNxbF9zZXJ2ZXI6OmNvbm5lY3Rpb246OnByb2Nlc3Nf cmVxdWVzdCgpOjp7bGFtYmRhKGZ1dHVyZTxzdGQ6OmV4cGVyaW1lbnRhbDo6ZnVuZGFtZW50YWxz X3YxOjpvcHRpb25hbDx0cmFuc3BvcnQ6OmNxbF9iaW5hcnlfZnJhbWVfdjM+ID4mJikjMX06Om9w ZXJhdG9yKCkoZnV0dXJlPHN0ZDo6ZXhwZXJpbWVudGFsOjpmdW5kYW1lbnRhbHNfdjE6Om9wdGlv bmFsPHRyYW5zcG9ydDo6Y3FsX2JpbmFyeV9mcmFtZV92Mz4gPiYmKSBjb25zdDo6e2xhbWJkYSh0 ZW1wb3JhcnlfYnVmZmVyPGNoYXI+KSMxfTo6b3BlcmF0b3IoKSh0ZW1wb3JhcnlfYnVmZmVyKSBj b25zdDo6e2xhbWJkYSgpIzF9OjpvcGVyYXRvcigpKCk6OntsYW1iZGEoKSMxfSY+CiAgICAgICAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIGZ1dHVy aXplPGZ1dHVyZTw+ID46OmFwcGx5PHRyYW5zcG9ydDo6Y3FsX3NlcnZlcjo6Y29ubmVjdGlvbjo6 cHJvY2Vzc19yZXF1ZXN0KCk6OntsYW1iZGEoZnV0dXJlPHN0ZDo6ZXhwZXJpbWVudGFsOjpmdW5k YW1lbnRhbHNfdjE6Om9wdGlvbmFsPHRyYW5zcG9ydDo6Y3FsX2JpbmFyeV9mcmFtZV92Mz4gPiYm KSMxfTo6b3BlcmF0b3IoKShmdXR1cmU8c3RkOjpleHBlcmltZW50YWw6OmZ1bmRhbWVudGFsc192 MTo6b3B0aW9uYWw8dHJhbnNwb3J0OjpjcWxfYmluYXJ5X2ZyYW1lX3YzPiA+JiYpIGNvbnN0Ojp7 bGFtYmRhKHRlbXBvcmFyeV9idWZmZXI8Y2hhcj4pIzF9LCB0ZW1wb3JhcnlfYnVmZmVyPgogICAg ICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICBm dXR1cml6ZTxmdXR1cmU8PiA+OjphcHBseTx0cmFuc3BvcnQ6OmNxbF9zZXJ2ZXI6OmNvbm5lY3Rp b246OnByb2Nlc3NfcmVxdWVzdCgpOjp7bGFtYmRhKGZ1dHVyZTxzdGQ6OmV4cGVyaW1lbnRhbDo6 ZnVuZGFtZW50YWxzX3YxOjpvcHRpb25hbDx0cmFuc3BvcnQ6OmNxbF9iaW5hcnlfZnJhbWVfdjM+ ID4mJikjMX0sIGZ1dHVyZTxzdGQ6OmV4cGVyaW1lbnRhbDo6ZnVuZGFtZW50YWxzX3YxOjpvcHRp b25hbDx0cmFuc3BvcnQ6OmNxbF9iaW5hcnlfZnJhbWVfdjM+ID4gPgogICAgICAgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAog ICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAg ICB8LS04MC4wMCUtLSB0cmFuc3BvcnQ6OmNxbF9zZXJ2ZXI6OmNvbm5lY3Rpb246OnByb2Nlc3Nf cmVxdWVzdAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgIGRvX3VudGlsX2NvbnRpbnVlZDx0cmFuc3BvcnQ6OmNxbF9z ZXJ2ZXI6OmNvbm5lY3Rpb246OnByb2Nlc3MoKTo6e2xhbWJkYSgpIzJ9LCB0cmFuc3BvcnQ6OmNx bF9zZXJ2ZXI6OmNvbm5lY3Rpb246OnByb2Nlc3MoKTo6e2xhbWJkYSgpIzF9Jj4KICAgICAgICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICBkb192b2lkX2Z1dHVyaXplX2FwcGx5PHZvaWQgZG9fdW50aWxfY29udGludWVkPHRyYW5z cG9ydDo6Y3FsX3NlcnZlcjo6Y29ubmVjdGlvbjo6cHJvY2VzcygpOjp7bGFtYmRhKCkjMn0sIHRy YW5zcG9ydDo6Y3FsX3NlcnZlcjo6Y29ubmVjdGlvbjo6cHJvY2VzcygpOjp7bGFtYmRhKCkjMX0m Pih0cmFuc3BvcnQ6OmNxbF9zZXJ2ZXI6OmNvbm5lY3Rpb246OnByb2Nlc3MoKTo6e2xhbWJkYSgp IzF9JiwgdHJhbnNwb3J0OjpjcWxfc2VydmVyOjpjb25uZWN0aW9uOjpwcm9jZXNzKCk6OntsYW1i ZGEoKSMyfSYmLCBwcm9taXNlPD4pOjp7bGFtYmRhKGZ1dHVyZTw+KSMxfSwgcHJvbWlzZTw+ID4K ICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICBkb192b2lkX2Z1dHVyaXplX2FwcGx5PHZvaWQgZG9fdW50aWxfY29udGlu dWVkPHRyYW5zcG9ydDo6Y3FsX3NlcnZlcjo6Y29ubmVjdGlvbjo6cHJvY2VzcygpOjp7bGFtYmRh KCkjMn0sIHRyYW5zcG9ydDo6Y3FsX3NlcnZlcjo6Y29ubmVjdGlvbjo6cHJvY2VzcygpOjp7bGFt YmRhKCkjMX0mPih0cmFuc3BvcnQ6OmNxbF9zZXJ2ZXI6OmNvbm5lY3Rpb246OnByb2Nlc3MoKTo6 e2xhbWJkYSgpIzF9JiwgdHJhbnNwb3J0OjpjcWxfc2VydmVyOjpjb25uZWN0aW9uOjpwcm9jZXNz KCk6OntsYW1iZGEoKSMyfSYmLCBwcm9taXNlPD4pOjp7bGFtYmRhKGZ1dHVyZTw+KSMxfSwgcHJv bWlzZTw+ID4KICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICAweDYwYTAwMDBjMzAwMAogICAgICAgICAgICAgICAgfCAg ICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAg ICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAg LS0yMC4wMCUtLSAweDg5NjFkZQogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg ICAgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICAgICAgICAgICAgIHwtLTAuNzQlLS0gY29tcG91bmRfdHlwZTwoYWxsb3dfcHJlZml4ZXMp MD46OmNvbXBhcmUKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfC0tMjAuMDAlLS0gMHg2MDMwMDU2YzBmMjAK ICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAg ICAgICAgIHwgICAgICAgICAgfC0tMjAuMDAlLS0gYm9vc3Q6OmludHJ1c2l2ZTo6YnN0YmFzZTI8 Ym9vc3Q6OmludHJ1c2l2ZTo6bWh0cmFpdHM8cm93c19lbnRyeSwgYm9vc3Q6OmludHJ1c2l2ZTo6 c2V0X21lbWJlcl9ob29rPHZvaWQsIHZvaWQsIHZvaWQsIHZvaWQ+LCAmcm93c19lbnRyeTo6X2xp bms+LCByb3dzX2VudHJ5Ojpjb21wYXJlLCAoYm9vc3Q6OmludHJ1c2l2ZTo6YWxnb190eXBlcyk1 LCBib29zdDo6aW50cnVzaXZlOjpkZXRhaWw6OmRlZmF1bHRfaGVhZGVyX2hvbGRlcjxib29zdDo6 aW50cnVzaXZlOjpyYnRyZWVfbm9kZV90cmFpdHM8dm9pZCosIGZhbHNlPiA+ID46OmZpbmQKICAg ICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICBtdXRhdGlvbl9wYXJ0aXRpb246OmNsdXN0ZXJlZF9yb3cKICAgICAgICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICBtdXRhdGlvbjo6c2V0X2NsdXN0ZXJlZF9jZWxsCiAgICAgICAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgY3FsMzo6Y29uc3Rh bnRzOjpzZXR0ZXI6OmV4ZWN1dGUKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICBjcWwzOjpzdGF0ZW1lbnRzOjp1cGRh dGVfc3RhdGVtZW50OjphZGRfdXBkYXRlX2Zvcl9rZXkKICAgICAgICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICBfWk44ZnV0dXJp emVJNmZ1dHVyZUlKU3Q2dmVjdG9ySThtdXRhdGlvblNhSVMyX0VFRUVFNWFwcGx5SVpONGNxbDMx MHN0YXRlbWVudHMyMm1vZGlmaWNhdGlvbl9zdGF0ZW1lbnQxM2dldF9tdXRhdGlvbnNFUk43c2Vh c3RhcjdzaGFyZGVkSU43c2VydmljZTEzc3RvcmFnZV9wcm94eUVFRVJLTlM4XzEzcXVlcnlfb3B0 aW9uc0VibEVVbFRfRV9KU3QxMHVuaXF1ZV9wdHJJTlM4XzE3dXBkYXRlX3BhcmFtZXRlcnNFU3Qx NGRlZmF1bHRfZGVsZXRlSVNOX0VFRUVFUzVfT1NLX09TdDV0dXBsZUlKRHBUMF9FRQogICAgICAg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgIGNxbDM6OnN0YXRlbWVudHM6Om1vZGlmaWNhdGlvbl9zdGF0ZW1lbnQ6OmdldF9tdXRh dGlvbnMKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICBjcWwzOjpzdGF0ZW1lbnRzOjptb2RpZmljYXRpb25fc3RhdGVt ZW50OjpleGVjdXRlX3dpdGhvdXRfY29uZGl0aW9uCiAgICAgICAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgY3FsMzo6cXVlcnlf b3B0aW9uczo6cXVlcnlfb3B0aW9ucwogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIDB4N2Y0YWRiM2Y4MGUwCiAgICAg ICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAg ICB8ICAgICAgICAgIHwtLTIwLjAwJS0tIGNvbXBvdW5kX3R5cGU8KGFsbG93X3ByZWZpeGVzKTA+ Ojpjb21wYXJlCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwtLTIwLjAwJS0tIG11dGF0aW9uX3BhcnRpdGlv bjo6Y2x1c3RlcmVkX3JvdwogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIGJvb3N0OjppbnRydXNpdmU6OmJzdHJlZV9p bXBsPGJvb3N0OjppbnRydXNpdmU6Om1odHJhaXRzPHJvd3NfZW50cnksIGJvb3N0OjppbnRydXNp dmU6OnNldF9tZW1iZXJfaG9vazx2b2lkLCB2b2lkLCB2b2lkLCB2b2lkPiwgJnJvd3NfZW50cnk6 Ol9saW5rPiwgcm93c19lbnRyeTo6Y29tcGFyZSwgdW5zaWduZWQgbG9uZywgdHJ1ZSwgKGJvb3N0 OjppbnRydXNpdmU6OmFsZ29fdHlwZXMpNSwgYm9vc3Q6OmludHJ1c2l2ZTo6ZGV0YWlsOjpkZWZh dWx0X2hlYWRlcl9ob2xkZXI8Ym9vc3Q6OmludHJ1c2l2ZTo6cmJ0cmVlX25vZGVfdHJhaXRzPHZv aWQqLCBmYWxzZT4gPiA+OjppbnNlcnRfdW5pcXVlCiAgICAgICAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgYm9vc3Q6OmludHJ1 c2l2ZTo6YnN0cmVlX2FsZ29yaXRobXM8Ym9vc3Q6OmludHJ1c2l2ZTo6cmJ0cmVlX25vZGVfdHJh aXRzPHZvaWQqLCBmYWxzZT4gPjo6cHJldl9ub2RlCiAgICAgICAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgMHgxMmQKICAgICAg ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAg IHwgICAgICAgICAgIC0tMjAuMDAlLS0gMHg2MGYwMDA1MmRhZjAKICAgICAgICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8LS0wLjc0JS0tIF9fbWVtbW92ZV9z c3NlM19iYWNrCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwtLTQwLjAwJS0tIG91dHB1dF9zdHJlYW08Y2hh cj46OndyaXRlCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8LS01MC4w MCUtLSB0cmFuc3BvcnQ6OmNxbF9zZXJ2ZXI6OnJlc3BvbnNlOjpvdXRwdXQKICAgICAgICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIGZ1dHVyaXplPGZ1dHVyZTw+ID46OmFwcGx5PHRyYW5zcG9ydDo6Y3FsX3Nl cnZlcjo6Y29ubmVjdGlvbjo6d3JpdGVfcmVzcG9uc2UoZm9yZWlnbl9wdHI8c2hhcmVkX3B0cjx0 cmFuc3BvcnQ6OmNxbF9zZXJ2ZXI6OnJlc3BvbnNlPiA+JiYpOjp7bGFtYmRhKCkjMX0+CiAgICAg ICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgLS01MC4wMCUtLSAweDdjN2ZiMgog ICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgICAgICAgICAgICAgMHg1MjU3YzM3ODQ3ZmEwCiAgICAgICAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAg ICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAg IHwtLTIwLjAwJS0tIHRyYW5zcG9ydDo6Y3FsX3NlcnZlcjo6Y29ubmVjdGlvbjo6cmVhZF9zaG9y dF9ieXRlcwogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgIHRyYW5zcG9ydDo6Y3FsX3NlcnZlcjo6Y29ubmVjdGlvbjo6 cHJvY2Vzc19xdWVyeQogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIDB4N2Y0YWRhN2Y4NmYwCiAgICAgICAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAg ICAgIHwtLTIwLjAwJS0tIHRyYW5zcG9ydDo6Y3FsX3NlcnZlcjo6cmVzcG9uc2U6Om91dHB1dAog ICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIGZ1dHVyaXplPGZ1dHVyZTw+ID46OmFwcGx5PHRyYW5zcG9ydDo6Y3FsX3Nl cnZlcjo6Y29ubmVjdGlvbjo6d3JpdGVfcmVzcG9uc2UoZm9yZWlnbl9wdHI8c2hhcmVkX3B0cjx0 cmFuc3BvcnQ6OmNxbF9zZXJ2ZXI6OnJlc3BvbnNlPiA+JiYpOjp7bGFtYmRhKCkjMX0+CiAgICAg ICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgMHgyCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAtLTIwLjAwJS0tIHNtcF9tZXNzYWdlX3F1 ZXVlOjpmbHVzaF9yZXNwb25zZV9iYXRjaAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIGJvb3N0Ojpsb2NrZnJlZTo6 ZGV0YWlsOjpyaW5nYnVmZmVyX2Jhc2U8c21wX21lc3NhZ2VfcXVldWU6OndvcmtfaXRlbSo+Ojpw b3AKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAg ICAgICAgICAgICAgICAgICBib29zdDo6cHJvZ3JhbV9vcHRpb25zOjp2YXJpYWJsZXNfbWFwOjpn ZXQKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAg ICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8 LS0wLjc0JS0tIHN5c2NhbGxfd29ya19xdWV1ZTo6d29ya19pdGVtX3JldHVybmluZzxzeXNjYWxs X3Jlc3VsdF9leHRyYTxzdGF0PiwgcmVhY3Rvcjo6ZmlsZV9zaXplKGJhc2ljX3NzdHJpbmc8Y2hh ciwgdW5zaWduZWQgaW50LCAxNXU+KTo6e2xhbWJkYSgpIzF9Pjo6fndvcmtfaXRlbV9yZXR1cm5p bmcKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAg ICAgICAgICAgIHwgICAgICAgICAgfC0tNjAuMDAlLS0gMHg2MTMwMDAwYzMwMDAKICAgICAgICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwg ICAgICAgICAgfC0tMjAuMDAlLS0gMHg2MDgwMDFmZTU5YTAKICAgICAgICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAgICAg ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgIC0t MjAuMDAlLS0gMHgxNgogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAg ICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAg ICAgICAgICAgIHwtLTAuNzQlLS0gX19tZW1zZXRfc3NlMgogICAgICAgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8LS00 MC4wMCUtLSBzdGQ6Ol9IYXNodGFibGU8cmFuZ2U8ZGh0Ojp0b2tlbj4sIHN0ZDo6cGFpcjxyYW5n ZTxkaHQ6OnRva2VuPiBjb25zdCwgc3RkOjp1bm9yZGVyZWRfc2V0PGdtczo6aW5ldF9hZGRyZXNz LCBzdGQ6Omhhc2g8Z21zOjppbmV0X2FkZHJlc3M+LCBzdGQ6OmVxdWFsX3RvPGdtczo6aW5ldF9h ZGRyZXNzPiwgc3RkOjphbGxvY2F0b3I8Z21zOjppbmV0X2FkZHJlc3M+ID4gPiwgc3RkOjphbGxv Y2F0b3I8c3RkOjpwYWlyPHJhbmdlPGRodDo6dG9rZW4+IGNvbnN0LCBzdGQ6OnVub3JkZXJlZF9z ZXQ8Z21zOjppbmV0X2FkZHJlc3MsIHN0ZDo6aGFzaDxnbXM6OmluZXRfYWRkcmVzcz4sIHN0ZDo6 ZXF1YWxfdG88Z21zOjppbmV0X2FkZHJlc3M+LCBzdGQ6OmFsbG9jYXRvcjxnbXM6OmluZXRfYWRk cmVzcz4gPiA+ID4sIHN0ZDo6X19kZXRhaWw6Ol9TZWxlY3Qxc3QsIHN0ZDo6ZXF1YWxfdG88cmFu Z2U8ZGh0Ojp0b2tlbj4gPiwgc3RkOjpoYXNoPHJhbmdlPGRodDo6dG9rZW4+ID4sIHN0ZDo6X19k ZXRhaWw6Ol9Nb2RfcmFuZ2VfaGFzaGluZywgc3RkOjpfX2RldGFpbDo6X0RlZmF1bHRfcmFuZ2Vk X2hhc2gsIHN0ZDo6X19kZXRhaWw6Ol9QcmltZV9yZWhhc2hfcG9saWN5LCBzdGQ6Ol9fZGV0YWls OjpfSGFzaHRhYmxlX3RyYWl0czx0cnVlLCBmYWxzZSwgdHJ1ZT4gPjo6fl9IYXNodGFibGUKICAg ICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICBsb2NhdG9yOjp0b2tlbl9tZXRhZGF0YTo6cGVuZGluZ19lbmRwb2ludHNfZm9y CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgc2VydmljZTo6c3RvcmFnZV9wcm94eTo6Y3JlYXRlX3dyaXRlX3Jlc3Bv bnNlX2hhbmRsZXIKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICBzZXJ2aWNlOjpzdG9yYWdlX3Byb3h5OjptdXRhdGVf cHJlcGFyZTxzdGQ6OnZlY3RvcjxtdXRhdGlvbiwgc3RkOjphbGxvY2F0b3I8bXV0YXRpb24+ID4s IHNlcnZpY2U6OnN0b3JhZ2VfcHJveHk6Om11dGF0ZV9wcmVwYXJlKHN0ZDo6dmVjdG9yPG11dGF0 aW9uLCBzdGQ6OmFsbG9jYXRvcjxtdXRhdGlvbj4gPiYsIGRiOjpjb25zaXN0ZW5jeV9sZXZlbCwg ZGI6OndyaXRlX3R5cGUpOjp7bGFtYmRhKG11dGF0aW9uIGNvbnN0JiwgZGI6OmNvbnNpc3RlbmN5 X2xldmVsLCBkYjo6d3JpdGVfdHlwZSkjMX0+CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgc2VydmljZTo6c3RvcmFn ZV9wcm94eTo6bXV0YXRlCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgc2VydmljZTo6c3RvcmFnZV9wcm94eTo6bXV0 YXRlX3dpdGhfdHJpZ2dlcnMKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAg ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICBjcWwzOjpzdGF0ZW1lbnRzOjptb2RpZmlj YXRpb25fc3RhdGVtZW50OjpleGVjdXRlX3dpdGhvdXRfY29uZGl0aW9uCiAgICAgICAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg Y3FsMzo6c3RhdGVtZW50czo6bW9kaWZpY2F0aW9uX3N0YXRlbWVudDo6ZXhlY3V0ZQogICAgICAg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgIGNxbDM6OnF1ZXJ5X3Byb2Nlc3Nvcjo6cHJvY2Vzc19zdGF0ZW1lbnQKICAgICAgICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICB0cmFuc3BvcnQ6OmNxbF9zZXJ2ZXI6OmNvbm5lY3Rpb246OnByb2Nlc3NfZXhlY3V0ZQog ICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIHRyYW5zcG9ydDo6Y3FsX3NlcnZlcjo6Y29ubmVjdGlvbjo6cHJvY2Vzc19y ZXF1ZXN0X29uZQogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgIGZ1dHVyaXplPGZ1dHVyZTxzdGQ6OnBhaXI8Zm9yZWln bl9wdHI8c2hhcmVkX3B0cjx0cmFuc3BvcnQ6OmNxbF9zZXJ2ZXI6OnJlc3BvbnNlPiA+LCBzZXJ2 aWNlOjpjbGllbnRfc3RhdGU+ID4gPjo6YXBwbHk8dHJhbnNwb3J0OjpjcWxfc2VydmVyOjpjb25u ZWN0aW9uOjpwcm9jZXNzX3JlcXVlc3QoKTo6e2xhbWJkYShmdXR1cmU8c3RkOjpleHBlcmltZW50 YWw6OmZ1bmRhbWVudGFsc192MTo6b3B0aW9uYWw8dHJhbnNwb3J0OjpjcWxfYmluYXJ5X2ZyYW1l X3YzPiA+JiYpIzF9OjpvcGVyYXRvcigpKGZ1dHVyZTxzdGQ6OmV4cGVyaW1lbnRhbDo6ZnVuZGFt ZW50YWxzX3YxOjpvcHRpb25hbDx0cmFuc3BvcnQ6OmNxbF9iaW5hcnlfZnJhbWVfdjM+ID4mJikg Y29uc3Q6OntsYW1iZGEodGVtcG9yYXJ5X2J1ZmZlcjxjaGFyPikjMX06Om9wZXJhdG9yKCkodGVt cG9yYXJ5X2J1ZmZlcikgY29uc3Q6OntsYW1iZGEoKSMxfTo6b3BlcmF0b3IoKSgpOjp7bGFtYmRh KCkjMX0mPgogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgIGZ1dHVyaXplPGZ1dHVyZTw+ID46OmFwcGx5PHRyYW5zcG9y dDo6Y3FsX3NlcnZlcjo6Y29ubmVjdGlvbjo6cHJvY2Vzc19yZXF1ZXN0KCk6OntsYW1iZGEoZnV0 dXJlPHN0ZDo6ZXhwZXJpbWVudGFsOjpmdW5kYW1lbnRhbHNfdjE6Om9wdGlvbmFsPHRyYW5zcG9y dDo6Y3FsX2JpbmFyeV9mcmFtZV92Mz4gPiYmKSMxfTo6b3BlcmF0b3IoKShmdXR1cmU8c3RkOjpl eHBlcmltZW50YWw6OmZ1bmRhbWVudGFsc192MTo6b3B0aW9uYWw8dHJhbnNwb3J0OjpjcWxfYmlu YXJ5X2ZyYW1lX3YzPiA+JiYpIGNvbnN0Ojp7bGFtYmRhKHRlbXBvcmFyeV9idWZmZXI8Y2hhcj4p IzF9LCB0ZW1wb3JhcnlfYnVmZmVyPgogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIGZ1dHVyaXplPGZ1dHVyZTw+ID46 OmFwcGx5PHRyYW5zcG9ydDo6Y3FsX3NlcnZlcjo6Y29ubmVjdGlvbjo6cHJvY2Vzc19yZXF1ZXN0 KCk6OntsYW1iZGEoZnV0dXJlPHN0ZDo6ZXhwZXJpbWVudGFsOjpmdW5kYW1lbnRhbHNfdjE6Om9w dGlvbmFsPHRyYW5zcG9ydDo6Y3FsX2JpbmFyeV9mcmFtZV92Mz4gPiYmKSMxfSwgZnV0dXJlPHN0 ZDo6ZXhwZXJpbWVudGFsOjpmdW5kYW1lbnRhbHNfdjE6Om9wdGlvbmFsPHRyYW5zcG9ydDo6Y3Fs X2JpbmFyeV9mcmFtZV92Mz4gPiA+CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgdHJhbnNwb3J0OjpjcWxfc2VydmVy Ojpjb25uZWN0aW9uOjpwcm9jZXNzX3JlcXVlc3QKICAgICAgICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICBkb191bnRpbF9jb250 aW51ZWQ8dHJhbnNwb3J0OjpjcWxfc2VydmVyOjpjb25uZWN0aW9uOjpwcm9jZXNzKCk6OntsYW1i ZGEoKSMyfSwgdHJhbnNwb3J0OjpjcWxfc2VydmVyOjpjb25uZWN0aW9uOjpwcm9jZXNzKCk6Onts YW1iZGEoKSMxfSY+CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgZG9fdm9pZF9mdXR1cml6ZV9hcHBseTx2b2lkIGRv X3VudGlsX2NvbnRpbnVlZDx0cmFuc3BvcnQ6OmNxbF9zZXJ2ZXI6OmNvbm5lY3Rpb246OnByb2Nl c3MoKTo6e2xhbWJkYSgpIzJ9LCB0cmFuc3BvcnQ6OmNxbF9zZXJ2ZXI6OmNvbm5lY3Rpb246OnBy b2Nlc3MoKTo6e2xhbWJkYSgpIzF9Jj4odHJhbnNwb3J0OjpjcWxfc2VydmVyOjpjb25uZWN0aW9u Ojpwcm9jZXNzKCk6OntsYW1iZGEoKSMxfSYsIHRyYW5zcG9ydDo6Y3FsX3NlcnZlcjo6Y29ubmVj dGlvbjo6cHJvY2VzcygpOjp7bGFtYmRhKCkjMn0mJiwgcHJvbWlzZTw+KTo6e2xhbWJkYShmdXR1 cmU8PikjMX0sIHByb21pc2U8PiA+CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgZG9fdm9pZF9mdXR1cml6ZV9hcHBs eTx2b2lkIGRvX3VudGlsX2NvbnRpbnVlZDx0cmFuc3BvcnQ6OmNxbF9zZXJ2ZXI6OmNvbm5lY3Rp b246OnByb2Nlc3MoKTo6e2xhbWJkYSgpIzJ9LCB0cmFuc3BvcnQ6OmNxbF9zZXJ2ZXI6OmNvbm5l Y3Rpb246OnByb2Nlc3MoKTo6e2xhbWJkYSgpIzF9Jj4odHJhbnNwb3J0OjpjcWxfc2VydmVyOjpj b25uZWN0aW9uOjpwcm9jZXNzKCk6OntsYW1iZGEoKSMxfSYsIHRyYW5zcG9ydDo6Y3FsX3NlcnZl cjo6Y29ubmVjdGlvbjo6cHJvY2VzcygpOjp7bGFtYmRhKCkjMn0mJiwgcHJvbWlzZTw+KTo6e2xh bWJkYShmdXR1cmU8PikjMX0sIHByb21pc2U8PiA+CiAgICAgICAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgMHg2MDIwMDAwYzMw MDAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAg ICAgICAgICAgIHwgICAgICAgICAgfC0tNDAuMDAlLS0gc2VydmljZTo6ZGlnZXN0X3JlYWRfcmVz b2x2ZXI6On5kaWdlc3RfcmVhZF9yZXNvbHZlcgogICAgICAgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAg ICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgIC0tMTAwLjAwJS0tIDB4NjEwMDAyNjEyYjUwCiAgICAgICAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAg ICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAg ICAtLTIwLjAwJS0tIHN0ZDo6X0hhc2h0YWJsZTxiYXNpY19zc3RyaW5nPGNoYXIsIHVuc2lnbmVk IGludCwgMTV1Piwgc3RkOjpwYWlyPGJhc2ljX3NzdHJpbmc8Y2hhciwgdW5zaWduZWQgaW50LCAx NXU+IGNvbnN0LCBzdGQ6OnZlY3RvcjxnbXM6OmluZXRfYWRkcmVzcywgc3RkOjphbGxvY2F0b3I8 Z21zOjppbmV0X2FkZHJlc3M+ID4gPiwgc3RkOjphbGxvY2F0b3I8c3RkOjpwYWlyPGJhc2ljX3Nz dHJpbmc8Y2hhciwgdW5zaWduZWQgaW50LCAxNXU+IGNvbnN0LCBzdGQ6OnZlY3RvcjxnbXM6Omlu ZXRfYWRkcmVzcywgc3RkOjphbGxvY2F0b3I8Z21zOjppbmV0X2FkZHJlc3M+ID4gPiA+LCBzdGQ6 Ol9fZGV0YWlsOjpfU2VsZWN0MXN0LCBzdGQ6OmVxdWFsX3RvPGJhc2ljX3NzdHJpbmc8Y2hhciwg dW5zaWduZWQgaW50LCAxNXU+ID4sIHN0ZDo6aGFzaDxiYXNpY19zc3RyaW5nPGNoYXIsIHVuc2ln bmVkIGludCwgMTV1PiA+LCBzdGQ6Ol9fZGV0YWlsOjpfTW9kX3JhbmdlX2hhc2hpbmcsIHN0ZDo6 X19kZXRhaWw6Ol9EZWZhdWx0X3JhbmdlZF9oYXNoLCBzdGQ6Ol9fZGV0YWlsOjpfUHJpbWVfcmVo YXNoX3BvbGljeSwgc3RkOjpfX2RldGFpbDo6X0hhc2h0YWJsZV90cmFpdHM8dHJ1ZSwgZmFsc2Us IHRydWU+ID46On5fSGFzaHRhYmxlCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgc2VydmljZTo6c3RvcmFnZV9wcm94 eTo6c2VuZF90b19saXZlX2VuZHBvaW50cwogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHBhcmFsbGVsX2Zvcl9lYWNo PF9fZ251X2N4eDo6X19ub3JtYWxfaXRlcmF0b3I8dW5zaWduZWQgbG9uZyosIHN0ZDo6dmVjdG9y PHVuc2lnbmVkIGxvbmcsIHN0ZDo6YWxsb2NhdG9yPHVuc2lnbmVkIGxvbmc+ID4gPiwgc2Vydmlj ZTo6c3RvcmFnZV9wcm94eTo6bXV0YXRlX2JlZ2luKHN0ZDo6dmVjdG9yPHVuc2lnbmVkIGxvbmcs IHN0ZDo6YWxsb2NhdG9yPHVuc2lnbmVkIGxvbmc+ID4sIGRiOjpjb25zaXN0ZW5jeV9sZXZlbCk6 OntsYW1iZGEodW5zaWduZWQgbG9uZykjMX0+CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgc2VydmljZTo6c3RvcmFn ZV9wcm94eTo6bXV0YXRlCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAg ICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgc2VydmljZTo6c3RvcmFnZV9wcm94eTo6bXV0 YXRlX3dpdGhfdHJpZ2dlcnMKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAg ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICBjcWwzOjpzdGF0ZW1lbnRzOjptb2RpZmlj YXRpb25fc3RhdGVtZW50OjpleGVjdXRlX3dpdGhvdXRfY29uZGl0aW9uCiAgICAgICAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAg Y3FsMzo6c3RhdGVtZW50czo6bW9kaWZpY2F0aW9uX3N0YXRlbWVudDo6ZXhlY3V0ZQogICAgICAg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAg ICAgICAgIGNxbDM6OnF1ZXJ5X3Byb2Nlc3Nvcjo6cHJvY2Vzc19zdGF0ZW1lbnQKICAgICAgICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAg ICAgICB0cmFuc3BvcnQ6OmNxbF9zZXJ2ZXI6OmNvbm5lY3Rpb246OnByb2Nlc3NfZXhlY3V0ZQog ICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAg ICAgICAgICAgICAgIHRyYW5zcG9ydDo6Y3FsX3NlcnZlcjo6Y29ubmVjdGlvbjo6cHJvY2Vzc19y ZXF1ZXN0X29uZQogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAg ICAgfCAgICAgICAgICAgICAgICAgICAgIGZ1dHVyaXplPGZ1dHVyZTxzdGQ6OnBhaXI8Zm9yZWln bl9wdHI8c2hhcmVkX3B0cjx0cmFuc3BvcnQ6OmNxbF9zZXJ2ZXI6OnJlc3BvbnNlPiA+LCBzZXJ2 aWNlOjpjbGllbnRfc3RhdGU+ID4gPjo6YXBwbHk8dHJhbnNwb3J0OjpjcWxfc2VydmVyOjpjb25u ZWN0aW9uOjpwcm9jZXNzX3JlcXVlc3QoKTo6e2xhbWJkYShmdXR1cmU8c3RkOjpleHBlcmltZW50 YWw6OmZ1bmRhbWVudGFsc192MTo6b3B0aW9uYWw8dHJhbnNwb3J0OjpjcWxfYmluYXJ5X2ZyYW1l X3YzPiA+JiYpIzF9OjpvcGVyYXRvcigpKGZ1dHVyZTxzdGQ6OmV4cGVyaW1lbnRhbDo6ZnVuZGFt ZW50YWxzX3YxOjpvcHRpb25hbDx0cmFuc3BvcnQ6OmNxbF9iaW5hcnlfZnJhbWVfdjM+ID4mJikg Y29uc3Q6OntsYW1iZGEodGVtcG9yYXJ5X2J1ZmZlcjxjaGFyPikjMX06Om9wZXJhdG9yKCkodGVt cG9yYXJ5X2J1ZmZlcikgY29uc3Q6OntsYW1iZGEoKSMxfTo6b3BlcmF0b3IoKSgpOjp7bGFtYmRh KCkjMX0mPgogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAg fCAgICAgICAgICAgICAgICAgICAgIGZ1dHVyaXplPGZ1dHVyZTw+ID46OmFwcGx5PHRyYW5zcG9y dDo6Y3FsX3NlcnZlcjo6Y29ubmVjdGlvbjo6cHJvY2Vzc19yZXF1ZXN0KCk6OntsYW1iZGEoZnV0 dXJlPHN0ZDo6ZXhwZXJpbWVudGFsOjpmdW5kYW1lbnRhbHNfdjE6Om9wdGlvbmFsPHRyYW5zcG9y dDo6Y3FsX2JpbmFyeV9mcmFtZV92Mz4gPiYmKSMxfTo6b3BlcmF0b3IoKShmdXR1cmU8c3RkOjpl eHBlcmltZW50YWw6OmZ1bmRhbWVudGFsc192MTo6b3B0aW9uYWw8dHJhbnNwb3J0OjpjcWxfYmlu YXJ5X2ZyYW1lX3YzPiA+JiYpIGNvbnN0Ojp7bGFtYmRhKHRlbXBvcmFyeV9idWZmZXI8Y2hhcj4p IzF9LCB0ZW1wb3JhcnlfYnVmZmVyPgogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIGZ1dHVyaXplPGZ1dHVyZTw+ID46 OmFwcGx5PHRyYW5zcG9ydDo6Y3FsX3NlcnZlcjo6Y29ubmVjdGlvbjo6cHJvY2Vzc19yZXF1ZXN0 KCk6OntsYW1iZGEoZnV0dXJlPHN0ZDo6ZXhwZXJpbWVudGFsOjpmdW5kYW1lbnRhbHNfdjE6Om9w dGlvbmFsPHRyYW5zcG9ydDo6Y3FsX2JpbmFyeV9mcmFtZV92Mz4gPiYmKSMxfSwgZnV0dXJlPHN0 ZDo6ZXhwZXJpbWVudGFsOjpmdW5kYW1lbnRhbHNfdjE6Om9wdGlvbmFsPHRyYW5zcG9ydDo6Y3Fs X2JpbmFyeV9mcmFtZV92Mz4gPiA+CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgdHJhbnNwb3J0OjpjcWxfc2VydmVy Ojpjb25uZWN0aW9uOjpwcm9jZXNzX3JlcXVlc3QKICAgICAgICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICBkb191bnRpbF9jb250 aW51ZWQ8dHJhbnNwb3J0OjpjcWxfc2VydmVyOjpjb25uZWN0aW9uOjpwcm9jZXNzKCk6OntsYW1i ZGEoKSMyfSwgdHJhbnNwb3J0OjpjcWxfc2VydmVyOjpjb25uZWN0aW9uOjpwcm9jZXNzKCk6Onts YW1iZGEoKSMxfSY+CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAg ICAgICB8ICAgICAgICAgICAgICAgICAgICAgZG9fdm9pZF9mdXR1cml6ZV9hcHBseTx2b2lkIGRv X3VudGlsX2NvbnRpbnVlZDx0cmFuc3BvcnQ6OmNxbF9zZXJ2ZXI6OmNvbm5lY3Rpb246OnByb2Nl c3MoKTo6e2xhbWJkYSgpIzJ9LCB0cmFuc3BvcnQ6OmNxbF9zZXJ2ZXI6OmNvbm5lY3Rpb246OnBy b2Nlc3MoKTo6e2xhbWJkYSgpIzF9Jj4odHJhbnNwb3J0OjpjcWxfc2VydmVyOjpjb25uZWN0aW9u Ojpwcm9jZXNzKCk6OntsYW1iZGEoKSMxfSYsIHRyYW5zcG9ydDo6Y3FsX3NlcnZlcjo6Y29ubmVj dGlvbjo6cHJvY2VzcygpOjp7bGFtYmRhKCkjMn0mJiwgcHJvbWlzZTw+KTo6e2xhbWJkYShmdXR1 cmU8PikjMX0sIHByb21pc2U8PiA+CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgZG9fdm9pZF9mdXR1cml6ZV9hcHBs eTx2b2lkIGRvX3VudGlsX2NvbnRpbnVlZDx0cmFuc3BvcnQ6OmNxbF9zZXJ2ZXI6OmNvbm5lY3Rp b246OnByb2Nlc3MoKTo6e2xhbWJkYSgpIzJ9LCB0cmFuc3BvcnQ6OmNxbF9zZXJ2ZXI6OmNvbm5l Y3Rpb246OnByb2Nlc3MoKTo6e2xhbWJkYSgpIzF9Jj4odHJhbnNwb3J0OjpjcWxfc2VydmVyOjpj b25uZWN0aW9uOjpwcm9jZXNzKCk6OntsYW1iZGEoKSMxfSYsIHRyYW5zcG9ydDo6Y3FsX3NlcnZl cjo6Y29ubmVjdGlvbjo6cHJvY2VzcygpOjp7bGFtYmRhKCkjMn0mJiwgcHJvbWlzZTw+KTo6e2xh bWJkYShmdXR1cmU8PikjMX0sIHByb21pc2U8PiA+CiAgICAgICAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgMHg2MDcwMDAwYzMw MDAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAg ICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8 LS0wLjc0JS0tIHJlYWN0b3I6OmRlbF90aW1lcgogICAgICAgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8LS04MC4wMCUt LSAweDYwYTAwMDBlMjA0MAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgLS0yMC4wMCUtLSAweDYwODAwMDBj M2RiMAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAg ICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAg IHwtLTAuNTklLS0gdW5pbXBsZW1lbnRlZDo6b3BlcmF0b3I8PAogICAgICAgICAgICAgICAgfCAg ICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAg ICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8 LS0yNS4wMCUtLSBfWk4xMmNvbnRpbnVhdGlvbklaTjZmdXR1cmVJSjEwc2hhcmVkX3B0cklOOXRy YW5zcG9ydDhtZXNzYWdlczE0cmVzdWx0X21lc3NhZ2VFRUVFNHRoZW5JWk40Y3FsMzE1cXVlcnlf cHJvY2Vzc29yMTdwcm9jZXNzX3N0YXRlbWVudEVTMV9JTlM4XzEzY3FsX3N0YXRlbWVudEVFUk43 c2VydmljZTExcXVlcnlfc3RhdGVFUktOUzhfMTNxdWVyeV9vcHRpb25zRUVVbFRfRV9TNl9FRVQw X09TSV9FVWxTTF9FX0pTNV9FRUQyRXYKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAweDYwMDEwMDAwMDAwOAogICAg ICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAg ICAgfCAgICAgICAgICB8LS0yNS4wMCUtLSBmbG9hdGluZ190eXBlX2ltcGw8ZmxvYXQ+Ojpmcm9t X3N0cmluZwogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgICAgICAgICAgICAgfCAgICAgICAgICB8LS0yNS4wMCUtLSAweDYwZTAwMDBlNGMxMAogICAg ICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAg ICAgfCAgICAgICAgICAgLS0yNS4wMCUtLSBfWk4xMmNvbnRpbnVhdGlvbklaTjZmdXR1cmVJSjEw c2hhcmVkX3B0cklOOXRyYW5zcG9ydDhtZXNzYWdlczE0cmVzdWx0X21lc3NhZ2VFRUVFNHRoZW5J Wk40Y3FsMzE1cXVlcnlfcHJvY2Vzc29yMTdwcm9jZXNzX3N0YXRlbWVudEVTMV9JTlM4XzEzY3Fs X3N0YXRlbWVudEVFUk43c2VydmljZTExcXVlcnlfc3RhdGVFUktOUzhfMTNxdWVyeV9vcHRpb25z RUVVbFRfRV9TNl9FRVQwX09TSV9FVWxTTF9FX0pTNV9FRUQyRXYKICAgICAgICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAweDYw MDEwMDAwMDAwOAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAg ICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAg ICAgICAgIHwtLTAuNTklLS0gc3RkOjpfSGFzaHRhYmxlPHVuc2lnbmVkIGxvbmcsIHN0ZDo6cGFp cjx1bnNpZ25lZCBsb25nIGNvbnN0LCBzZXJ2aWNlOjpzdG9yYWdlX3Byb3h5OjpyaF9lbnRyeT4s IHN0ZDo6YWxsb2NhdG9yPHN0ZDo6cGFpcjx1bnNpZ25lZCBsb25nIGNvbnN0LCBzZXJ2aWNlOjpz dG9yYWdlX3Byb3h5OjpyaF9lbnRyeT4gPiwgc3RkOjpfX2RldGFpbDo6X1NlbGVjdDFzdCwgc3Rk OjplcXVhbF90bzx1bnNpZ25lZCBsb25nPiwgc3RkOjpoYXNoPHVuc2lnbmVkIGxvbmc+LCBzdGQ6 Ol9fZGV0YWlsOjpfTW9kX3JhbmdlX2hhc2hpbmcsIHN0ZDo6X19kZXRhaWw6Ol9EZWZhdWx0X3Jh bmdlZF9oYXNoLCBzdGQ6Ol9fZGV0YWlsOjpfUHJpbWVfcmVoYXNoX3BvbGljeSwgc3RkOjpfX2Rl dGFpbDo6X0hhc2h0YWJsZV90cmFpdHM8ZmFsc2UsIGZhbHNlLCB0cnVlPiA+OjpfTV9pbnNlcnRf dW5pcXVlX25vZGUKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAg ICAgIHwgICAgICAgICAgc2VydmljZTo6c3RvcmFnZV9wcm94eTo6cmVnaXN0ZXJfcmVzcG9uc2Vf aGFuZGxlcgogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAg fCAgICAgICAgICBzZXJ2aWNlOjpzdG9yYWdlX3Byb3h5OjpjcmVhdGVfd3JpdGVfcmVzcG9uc2Vf aGFuZGxlcgogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAg fCAgICAgICAgICBzZXJ2aWNlOjpzdG9yYWdlX3Byb3h5OjpjcmVhdGVfd3JpdGVfcmVzcG9uc2Vf aGFuZGxlcgogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAg fCAgICAgICAgICBzZXJ2aWNlOjpzdG9yYWdlX3Byb3h5OjptdXRhdGVfcHJlcGFyZTxzdGQ6OnZl Y3RvcjxtdXRhdGlvbiwgc3RkOjphbGxvY2F0b3I8bXV0YXRpb24+ID4sIHNlcnZpY2U6OnN0b3Jh Z2VfcHJveHk6Om11dGF0ZV9wcmVwYXJlKHN0ZDo6dmVjdG9yPG11dGF0aW9uLCBzdGQ6OmFsbG9j YXRvcjxtdXRhdGlvbj4gPiYsIGRiOjpjb25zaXN0ZW5jeV9sZXZlbCwgZGI6OndyaXRlX3R5cGUp Ojp7bGFtYmRhKG11dGF0aW9uIGNvbnN0JiwgZGI6OmNvbnNpc3RlbmN5X2xldmVsLCBkYjo6d3Jp dGVfdHlwZSkjMX0+CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAg ICAgICB8ICAgICAgICAgIHNlcnZpY2U6OnN0b3JhZ2VfcHJveHk6Om11dGF0ZQogICAgICAgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICBzZXJ2aWNl OjpzdG9yYWdlX3Byb3h5OjptdXRhdGVfd2l0aF90cmlnZ2VycwogICAgICAgICAgICAgICAgfCAg ICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICBjcWwzOjpzdGF0ZW1lbnRz Ojptb2RpZmljYXRpb25fc3RhdGVtZW50OjpleGVjdXRlX3dpdGhvdXRfY29uZGl0aW9uCiAgICAg ICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIGNx bDM6OnN0YXRlbWVudHM6Om1vZGlmaWNhdGlvbl9zdGF0ZW1lbnQ6OmV4ZWN1dGUKICAgICAgICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgY3FsMzo6 cXVlcnlfcHJvY2Vzc29yOjpwcm9jZXNzX3N0YXRlbWVudAogICAgICAgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB0cmFuc3BvcnQ6OmNxbF9zZXJ2 ZXI6OmNvbm5lY3Rpb246OnByb2Nlc3NfZXhlY3V0ZQogICAgICAgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB0cmFuc3BvcnQ6OmNxbF9zZXJ2ZXI6 OmNvbm5lY3Rpb246OnByb2Nlc3NfcmVxdWVzdF9vbmUKICAgICAgICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgZnV0dXJpemU8ZnV0dXJlPHN0ZDo6 cGFpcjxmb3JlaWduX3B0cjxzaGFyZWRfcHRyPHRyYW5zcG9ydDo6Y3FsX3NlcnZlcjo6cmVzcG9u c2U+ID4sIHNlcnZpY2U6OmNsaWVudF9zdGF0ZT4gPiA+OjphcHBseTx0cmFuc3BvcnQ6OmNxbF9z ZXJ2ZXI6OmNvbm5lY3Rpb246OnByb2Nlc3NfcmVxdWVzdCgpOjp7bGFtYmRhKGZ1dHVyZTxzdGQ6 OmV4cGVyaW1lbnRhbDo6ZnVuZGFtZW50YWxzX3YxOjpvcHRpb25hbDx0cmFuc3BvcnQ6OmNxbF9i aW5hcnlfZnJhbWVfdjM+ID4mJikjMX06Om9wZXJhdG9yKCkoZnV0dXJlPHN0ZDo6ZXhwZXJpbWVu dGFsOjpmdW5kYW1lbnRhbHNfdjE6Om9wdGlvbmFsPHRyYW5zcG9ydDo6Y3FsX2JpbmFyeV9mcmFt ZV92Mz4gPiYmKSBjb25zdDo6e2xhbWJkYSh0ZW1wb3JhcnlfYnVmZmVyPGNoYXI+KSMxfTo6b3Bl cmF0b3IoKSh0ZW1wb3JhcnlfYnVmZmVyKSBjb25zdDo6e2xhbWJkYSgpIzF9OjpvcGVyYXRvcigp KCk6OntsYW1iZGEoKSMxfSY+CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg ICAgICAgICAgICB8ICAgICAgICAgIGZ1dHVyaXplPGZ1dHVyZTw+ID46OmFwcGx5PHRyYW5zcG9y dDo6Y3FsX3NlcnZlcjo6Y29ubmVjdGlvbjo6cHJvY2Vzc19yZXF1ZXN0KCk6OntsYW1iZGEoZnV0 dXJlPHN0ZDo6ZXhwZXJpbWVudGFsOjpmdW5kYW1lbnRhbHNfdjE6Om9wdGlvbmFsPHRyYW5zcG9y dDo6Y3FsX2JpbmFyeV9mcmFtZV92Mz4gPiYmKSMxfTo6b3BlcmF0b3IoKShmdXR1cmU8c3RkOjpl eHBlcmltZW50YWw6OmZ1bmRhbWVudGFsc192MTo6b3B0aW9uYWw8dHJhbnNwb3J0OjpjcWxfYmlu YXJ5X2ZyYW1lX3YzPiA+JiYpIGNvbnN0Ojp7bGFtYmRhKHRlbXBvcmFyeV9idWZmZXI8Y2hhcj4p IzF9LCB0ZW1wb3JhcnlfYnVmZmVyPgogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgICAgICAgICAgICAgfCAgICAgICAgICBmdXR1cml6ZTxmdXR1cmU8PiA+OjphcHBseTx0cmFu c3BvcnQ6OmNxbF9zZXJ2ZXI6OmNvbm5lY3Rpb246OnByb2Nlc3NfcmVxdWVzdCgpOjp7bGFtYmRh KGZ1dHVyZTxzdGQ6OmV4cGVyaW1lbnRhbDo6ZnVuZGFtZW50YWxzX3YxOjpvcHRpb25hbDx0cmFu c3BvcnQ6OmNxbF9iaW5hcnlfZnJhbWVfdjM+ID4mJikjMX0sIGZ1dHVyZTxzdGQ6OmV4cGVyaW1l bnRhbDo6ZnVuZGFtZW50YWxzX3YxOjpvcHRpb25hbDx0cmFuc3BvcnQ6OmNxbF9iaW5hcnlfZnJh bWVfdjM+ID4gPgogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAg ICAgfCAgICAgICAgICB0cmFuc3BvcnQ6OmNxbF9zZXJ2ZXI6OmNvbm5lY3Rpb246OnByb2Nlc3Nf cmVxdWVzdAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAg fCAgICAgICAgICBkb191bnRpbF9jb250aW51ZWQ8dHJhbnNwb3J0OjpjcWxfc2VydmVyOjpjb25u ZWN0aW9uOjpwcm9jZXNzKCk6OntsYW1iZGEoKSMyfSwgdHJhbnNwb3J0OjpjcWxfc2VydmVyOjpj b25uZWN0aW9uOjpwcm9jZXNzKCk6OntsYW1iZGEoKSMxfSY+CiAgICAgICAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIGRvX3ZvaWRfZnV0dXJpemVf YXBwbHk8dm9pZCBkb191bnRpbF9jb250aW51ZWQ8dHJhbnNwb3J0OjpjcWxfc2VydmVyOjpjb25u ZWN0aW9uOjpwcm9jZXNzKCk6OntsYW1iZGEoKSMyfSwgdHJhbnNwb3J0OjpjcWxfc2VydmVyOjpj b25uZWN0aW9uOjpwcm9jZXNzKCk6OntsYW1iZGEoKSMxfSY+KHRyYW5zcG9ydDo6Y3FsX3NlcnZl cjo6Y29ubmVjdGlvbjo6cHJvY2VzcygpOjp7bGFtYmRhKCkjMX0mLCB0cmFuc3BvcnQ6OmNxbF9z ZXJ2ZXI6OmNvbm5lY3Rpb246OnByb2Nlc3MoKTo6e2xhbWJkYSgpIzJ9JiYsIHByb21pc2U8Pik6 OntsYW1iZGEoZnV0dXJlPD4pIzF9LCBwcm9taXNlPD4gPgogICAgICAgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICBkb192b2lkX2Z1dHVyaXplX2Fw cGx5PHZvaWQgZG9fdW50aWxfY29udGludWVkPHRyYW5zcG9ydDo6Y3FsX3NlcnZlcjo6Y29ubmVj dGlvbjo6cHJvY2VzcygpOjp7bGFtYmRhKCkjMn0sIHRyYW5zcG9ydDo6Y3FsX3NlcnZlcjo6Y29u bmVjdGlvbjo6cHJvY2VzcygpOjp7bGFtYmRhKCkjMX0mPih0cmFuc3BvcnQ6OmNxbF9zZXJ2ZXI6 OmNvbm5lY3Rpb246OnByb2Nlc3MoKTo6e2xhbWJkYSgpIzF9JiwgdHJhbnNwb3J0OjpjcWxfc2Vy dmVyOjpjb25uZWN0aW9uOjpwcm9jZXNzKCk6OntsYW1iZGEoKSMyfSYmLCBwcm9taXNlPD4pOjp7 bGFtYmRhKGZ1dHVyZTw+KSMxfSwgcHJvbWlzZTw+ID4KICAgICAgICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgMHg2MGIwMDAwYzMwMDAKICAgICAg ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgCiAg ICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8LS0wLjU5JS0t IG11dGF0aW9uOjpzZXRfY2x1c3RlcmVkX2NlbGwKICAgICAgICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfC0tNzUuMDAl LS0gMHhhCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgICAgICAgICAgICB8ICAgICAgICAgICAtLTI1LjAwJS0tIGNxbDM6OmNvbnN0YW50czo6c2V0 dGVyOjpleGVjdXRlCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAg ICAgICB8ICAgICAgICAgICAgICAgICAgICAgY3FsMzo6c3RhdGVtZW50czo6dXBkYXRlX3N0YXRl bWVudDo6YWRkX3VwZGF0ZV9mb3Jfa2V5CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgX1pOOGZ1dHVyaXplSTZmdXR1 cmVJSlN0NnZlY3Rvckk4bXV0YXRpb25TYUlTMl9FRUVFRTVhcHBseUlaTjRjcWwzMTBzdGF0ZW1l bnRzMjJtb2RpZmljYXRpb25fc3RhdGVtZW50MTNnZXRfbXV0YXRpb25zRVJON3NlYXN0YXI3c2hh cmRlZElON3NlcnZpY2UxM3N0b3JhZ2VfcHJveHlFRUVSS05TOF8xM3F1ZXJ5X29wdGlvbnNFYmxF VWxUX0VfSlN0MTB1bmlxdWVfcHRySU5TOF8xN3VwZGF0ZV9wYXJhbWV0ZXJzRVN0MTRkZWZhdWx0 X2RlbGV0ZUlTTl9FRUVFRVM1X09TS19PU3Q1dHVwbGVJSkRwVDBfRUUKICAgICAgICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICBj cWwzOjpzdGF0ZW1lbnRzOjptb2RpZmljYXRpb25fc3RhdGVtZW50OjpnZXRfbXV0YXRpb25zCiAg ICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAg ICAgICAgICAgICAgY3FsMzo6c3RhdGVtZW50czo6bW9kaWZpY2F0aW9uX3N0YXRlbWVudDo6ZXhl Y3V0ZV93aXRob3V0X2NvbmRpdGlvbgogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIGNxbDM6OnF1ZXJ5X29wdGlvbnM6 OnF1ZXJ5X29wdGlvbnMKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAg ICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAweDdmNGFkODlmODBlMAogICAgICAgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwtLTAuNTklLS0gbWVtb3J5 OjpzbWFsbF9wb29sOjpzbWFsbF9wb29sCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwtLTI1LjAwJS0tIG1l bW9yeTo6c3RhdHMKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICBib29zdDo6cHJvZ3JhbV9vcHRpb25zOjp2YXJpYWJs ZXNfbWFwOjpnZXQKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfC0tMjUuMDAlLS0gbWVtb3J5OjpyZWNsYWlt ZXI6On5yZWNsYWltZXIKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAweDFlCiAgICAgICAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwtLTI1 LjAwJS0tIG1lbW9yeTo6YWxsb2NhdGVfYWxpZ25lZAogICAgICAgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgLS0yNS4w MCUtLSBtZW1vcnk6OnNtYWxsX3Bvb2w6OmFkZF9tb3JlX29iamVjdHMKICAgICAgICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICBt ZW1vcnk6OnNtYWxsX3Bvb2w6OmFkZF9tb3JlX29iamVjdHMKICAgICAgICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAweDYxMDAw MDBlMDMxMAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAg fCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAg ICAgIHwtLTAuNTklLS0gX19tZW1jcHlfc3NlMl91bmFsaWduZWQKICAgICAgICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAg ICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAg fC0tNTAuMDAlLS0gbXV0YXRpb25fcGFydGl0aW9uX2FwcGxpZXI6OmFjY2VwdF9yb3dfY2VsbAog ICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIG11dGF0aW9uX3BhcnRpdGlvbl92aWV3OjphY2NlcHQKICAgICAgICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICBib29zdDo6aW50cnVzaXZlOjpic3RyZWVfYWxnb3JpdGhtczxib29zdDo6aW50cnVzaXZlOjpy YnRyZWVfbm9kZV90cmFpdHM8dm9pZCosIGZhbHNlPiA+OjpwcmV2X25vZGUKICAgICAgICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICAweDEyZAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgICAgICAgICAgICAgfCAgICAgICAgICB8LS0yNS4wMCUtLSBzY2FubmluZ19yZWFkZXI6Om9w ZXJhdG9yKCkKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICBzc3RhYmxlczo6c3N0YWJsZTo6ZG9fd3JpdGVfY29tcG9u ZW50cwogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAg ICAgICAgICB8ICAgICAgICAgIHNzdGFibGVzOjpzc3RhYmxlOjpwcmVwYXJlX3dyaXRlX2NvbXBv bmVudHMKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICBzdGQ6Ol9GdW5jdGlvbl9oYW5kbGVyPHZvaWQgKCksIGZ1dHVy aXplPHN0ZDo6cmVzdWx0X29mPHN0ZDo6ZGVjYXk8c3N0YWJsZXM6OnNzdGFibGU6OndyaXRlX2Nv bXBvbmVudHMobXV0YXRpb25fcmVhZGVyLCB1bnNpZ25lZCBsb25nLCBsd19zaGFyZWRfcHRyPHNj aGVtYSBjb25zdD4sIHVuc2lnbmVkIGxvbmcpOjp7bGFtYmRhKCkjMX0+Ojp0eXBlICgpPjo6dHlw ZT46OnR5cGUgc2Vhc3Rhcjo6YXN5bmM8c3N0YWJsZXM6OnNzdGFibGU6OndyaXRlX2NvbXBvbmVu dHMobXV0YXRpb25fcmVhZGVyLCB1bnNpZ25lZCBsb25nLCBsd19zaGFyZWRfcHRyPHNjaGVtYSBj b25zdD4sIHVuc2lnbmVkIGxvbmcpOjp7bGFtYmRhKCkjMX0+KHN0ZDo6ZGVjYXkmJiwgKHN0ZDo6 ZGVjYXk8c3N0YWJsZXM6OnNzdGFibGU6OndyaXRlX2NvbXBvbmVudHMobXV0YXRpb25fcmVhZGVy LCB1bnNpZ25lZCBsb25nLCBsd19zaGFyZWRfcHRyPHNjaGVtYSBjb25zdD4sIHVuc2lnbmVkIGxv bmcpOjp7bGFtYmRhKCkjMX0+Ojp0eXBlJiYpLi4uKTo6e2xhbWJkYShmdXR1cml6ZTxzdGQ6OnJl c3VsdF9vZjxzdGQ6OmRlY2F5PHtsYW1iZGEoKSMxfT46OnR5cGUgKCk+Ojp0eXBlPiBzZWFzdGFy Ojphc3luYzx7bGFtYmRhKCkjMX0+KGZ1dHVyaXplPHN0ZDo6cmVzdWx0X29mPHN0ZDo6ZGVjYXk8 e2xhbWJkYSgpIzF9Pjo6dHlwZSAoKT46OnR5cGU+Ojp0eXBlLCBzdGQ6OmRlY2F5PHtsYW1iZGEo KSMxfT46OnR5cGUmJik6OndvcmsmKSMxfTo6b3BlcmF0b3IoKShmdXR1cml6ZTxzdGQ6OnJlc3Vs dF9vZjxzdGQ6OmRlY2F5PHtsYW1iZGEoKSMxfT46OnR5cGUgKCk+Ojp0eXBlPiBzZWFzdGFyOjph c3luYzx7bGFtYmRhKCkjMX0+KGZ1dHVyaXplPHN0ZDo6cmVzdWx0X29mPHN0ZDo6ZGVjYXk8e2xh bWJkYSgpIzF9Pjo6dHlwZSAoKT46OnR5cGU+Ojp0eXBlLCBzdGQ6OmRlY2F5PHtsYW1iZGEoKSMx fT46OnR5cGUmJik6OndvcmspOjp7bGFtYmRhKCkjMX0+OjpfTV9pbnZva2UKICAgICAgICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICBfR0xPQkFMX19zdWJfSV9fWk4xMmFwcF90ZW1wbGF0ZUMyRXYKICAgICAgICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAg ICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAg IC0tMjUuMDAlLS0gbWVtdGFibGU6OmZpbmRfb3JfY3JlYXRlX3BhcnRpdGlvbl9zbG93CiAgICAg ICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAg ICAgICAgICAgbWVtdGFibGU6OmFwcGx5CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgZGF0YWJhc2U6OmFwcGx5X2lu X21lbW9yeQogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAg fCAgICAgICAgICAgICAgICAgICAgIGRhdGFiYXNlOjpkb19hcHBseQogICAgICAgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIGRh dGFiYXNlOjphcHBseQogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAg ICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHNtcF9tZXNzYWdlX3F1ZXVlOjphc3luY193b3Jr X2l0ZW08ZnV0dXJlPD4gc2Vhc3Rhcjo6c2hhcmRlZDxkYXRhYmFzZT46Omludm9rZV9vbjxzZXJ2 aWNlOjpzdG9yYWdlX3Byb3h5OjptdXRhdGVfbG9jYWxseShtdXRhdGlvbiBjb25zdCYpOjp7bGFt YmRhKGRhdGFiYXNlJikjMX0sIGZ1dHVyZTw+ID4odW5zaWduZWQgaW50LCBzZXJ2aWNlOjpzdG9y YWdlX3Byb3h5OjptdXRhdGVfbG9jYWxseShtdXRhdGlvbiBjb25zdCYpOjp7bGFtYmRhKGRhdGFi YXNlJikjMX0mJik6OntsYW1iZGEoKSMxfT46OnByb2Nlc3MKICAgICAgICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICBzbXBfbWVz c2FnZV9xdWV1ZTo6cHJvY2Vzc19xdWV1ZTwydWwsIHNtcF9tZXNzYWdlX3F1ZXVlOjpwcm9jZXNz X2luY29taW5nKCk6OntsYW1iZGEoc21wX21lc3NhZ2VfcXVldWU6OndvcmtfaXRlbSopIzF9Pgog ICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAg ICAgICAgICAgICAgIGJvb3N0Ojpsb2NrZnJlZTo6ZGV0YWlsOjpyaW5nYnVmZmVyX2Jhc2U8c21w X21lc3NhZ2VfcXVldWU6OndvcmtfaXRlbSo+Ojpwb3AKICAgICAgICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICBib29zdDo6cHJv Z3JhbV9vcHRpb25zOjp2YXJpYWJsZXNfbWFwOjpnZXQKICAgICAgICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8LS0wLjU5JS0tIHNtcF9tZXNzYWdlX3F1ZXVl OjpmbHVzaF9yZXNwb25zZV9iYXRjaAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAg ICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8LS0yNS4wMCUtLSBib29z dDo6bG9ja2ZyZWU6OmRldGFpbDo6cmluZ2J1ZmZlcl9iYXNlPHNtcF9tZXNzYWdlX3F1ZXVlOjp3 b3JrX2l0ZW0qPjo6cG9wCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgYm9vc3Q6OnByb2dyYW1fb3B0aW9uczo6dmFy aWFibGVzX21hcDo6Z2V0CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwtLTI1LjAwJS0tIDB4MTMKICAgICAg ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAg IHwgICAgICAgICAgfC0tMjUuMDAlLS0gMHg3ZjRhZDVmZjhmNDAKICAgICAgICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAg ICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAg IC0tMjUuMDAlLS0gcmVhY3Rvcjo6cnVuCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgc21wOjpjb25maWd1cmUoYm9v c3Q6OnByb2dyYW1fb3B0aW9uczo6dmFyaWFibGVzX21hcCk6OntsYW1iZGEoKSMxfTo6b3BlcmF0 b3IoKQogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAg ICAgICAgICAgICAgICAgICAgIGNvbnRpbnVhdGlvbjxmdXR1cmU8dGVtcG9yYXJ5X2J1ZmZlcjxj aGFyPiA+IGZ1dHVyZTw+Ojp0aGVuPGZ1dHVyZTx0ZW1wb3JhcnlfYnVmZmVyPGNoYXI+ID4gZmls ZTo6ZG1hX3JlYWRfYnVsazxjaGFyPih1bnNpZ25lZCBsb25nLCB1bnNpZ25lZCBsb25nKTo6e2xh bWJkYSh1bnNpZ25lZCBsb25nKSMxfTo6b3BlcmF0b3IoKSh1bnNpZ25lZCBsb25nKTo6e2xhbWJk YSgpIzN9LCBmdXR1cmU8dGVtcG9yYXJ5X2J1ZmZlcjxjaGFyPiA+ID4oZnV0dXJlPHRlbXBvcmFy eV9idWZmZXI8Y2hhcj4gPiBmaWxlOjpkbWFfcmVhZF9idWxrPGNoYXI+KHVuc2lnbmVkIGxvbmcs IHVuc2lnbmVkIGxvbmcpOjp7bGFtYmRhKHVuc2lnbmVkIGxvbmcpIzF9OjpvcGVyYXRvcigpKHVu c2lnbmVkIGxvbmcpOjp7bGFtYmRhKCkjM30mJik6OntsYW1iZGEoZnV0dXJlPHRlbXBvcmFyeV9i dWZmZXI8Y2hhcj4gPikjMX0+OjpydW4KICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAweDYwMDAwMDA0M2QwMAogICAg ICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgIC0tNTQuMzglLS0g Wy4uLl0KICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAg ICAgIHwgICAgICAgICAgfC0tMTQuMjYlLS0gc2NoZWR1bGVfdGltZW91dAogICAgICAgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgfC0tMzguNTIlLS0gd2FpdF9mb3JfY29tcGxldGlvbgogICAgICAg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAg ICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwtLTkwLjA3JS0t IGZsdXNoX3dvcmsKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgeGxvZ19jaWxfZm9yY2VfbHNuCiAgICAgICAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwtLTk2 Ljg1JS0tIF94ZnNfbG9nX2ZvcmNlX2xzbgogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAg ICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgfC0tNzkuNjclLS0geGZzX2ZpbGVfZnN5bmMKICAgICAgICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIHZmc19mc3luY19yYW5nZQogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgZG9fZnN5bmMKICAg ICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgIHN5c19mZGF0YXN5bmMKICAgICAgICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIGVudHJ5X1NZU0NBTExfNjRfZmFzdHBhdGgKICAgICAgICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgLS0xMDAuMDAlLS0gMHg3ZjRhZGU0 MjEyYWQKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgc3lzY2FsbF93b3JrX3F1 ZXVlOjp3b3JrX2l0ZW1fcmV0dXJuaW5nPHN5c2NhbGxfcmVzdWx0PGludD4sIHBvc2l4X2ZpbGVf aW1wbDo6Zmx1c2goKTo6e2xhbWJkYSgpIzF9Pjo6cHJvY2VzcwogICAgICAgICAgICAgICAgfCAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgICAgICAgICAgICAweDYwMzAwMDBjM2VjMAogICAgICAgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgIC0tMjAuMzMlLS0geGZzX2Rpcl9mc3luYwogICAgICAgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAg ICAgICAgICAgdmZzX2ZzeW5jX3JhbmdlCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICBkb19mc3lu YwogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgICAgICAgICAgICAgc3lzX2ZkYXRhc3luYwogICAgICAgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAg ICAgICAgICAgZW50cnlfU1lTQ0FMTF82NF9mYXN0cGF0aAogICAgICAgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAg ICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAtLTEwMC4wMCUtLSAweDdm NGFkZTQyMTJhZAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeXNjYWxsX3dv cmtfcXVldWU6OndvcmtfaXRlbV9yZXR1cm5pbmc8c3lzY2FsbF9yZXN1bHQ8aW50PiwgcG9zaXhf ZmlsZV9pbXBsOjpmbHVzaCgpOjp7bGFtYmRhKCkjMX0+Ojpwcm9jZXNzCiAgICAgICAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgIDB4NjA0MDAwMGMzZWMwCiAgICAgICAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAg ICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAt LTMuMTUlLS0gX3hmc19sb2dfZm9yY2UKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB4ZnNfbG9nX2ZvcmNlCiAgICAg ICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAg ICAgICAgICAgeGZzX2J1Zl9sb2NrCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgX3hmc19idWZfZmluZAogICAgICAg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAg ICAgICAgIHhmc19idWZfZ2V0X21hcAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHhmc190cmFuc19nZXRfYnVmX21h cAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICAgICAgICAgICAgIHhmc19idHJlZV9nZXRfYnVmbAogICAgICAgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHhmc19ibWFw X2V4dGVudHNfdG9fYnRyZWUKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB4ZnNfYm1hcF9hZGRfZXh0ZW50X2hvbGVf cmVhbAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICAgICAgICAgICAgIHhmc19ibWFwaV93cml0ZQogICAgICAgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHhmc19pb21h cF93cml0ZV9kaXJlY3QKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgICAgICAgICAgICBfX3hmc19nZXRfYmxvY2tzCiAgICAgICAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAg ICAgeGZzX2dldF9ibG9ja3NfZGlyZWN0CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgZG9fYmxvY2tkZXZfZGlyZWN0 X0lPCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgICAgICAgICAgICAgX19ibG9ja2Rldl9kaXJlY3RfSU8KICAgICAgICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB4ZnNf dm1fZGlyZWN0X0lPCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgICAgICAgICAgICAgeGZzX2ZpbGVfZGlvX2Fpb193cml0ZQogICAgICAg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAg ICAgICAgIHhmc19maWxlX3dyaXRlX2l0ZXIKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICBhaW9fcnVuX2lvY2IKICAg ICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg ICAgICAgICAgICBkb19pb19zdWJtaXQKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICBzeXNfaW9fc3VibWl0CiAgICAg ICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAg ICAgICAgICAgZW50cnlfU1lTQ0FMTF82NF9mYXN0cGF0aAogICAgICAgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIGlvX3N1Ym1p dAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICAgICAgICAgICAgIDB4NDZkOThhCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgIC0tOS45MyUtLSBzdWJtaXRfYmlvX3dhaXQKICAgICAgICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgYmxrZGV2 X2lzc3VlX2ZsdXNoCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICAgICAgICAgICAgIHhmc19ibGtkZXZfaXNzdWVfZmx1c2gKICAgICAgICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgeGZzX2ZpbGVfZnN5bmMK ICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAg ICAgdmZzX2ZzeW5jX3JhbmdlCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICAgICAgICAgICAgIGRvX2ZzeW5jCiAgICAgICAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHN5c19mZGF0YXN5bmMKICAgICAgICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgZW50cnlf U1lTQ0FMTF82NF9mYXN0cGF0aAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgLS0xMDAuMDAlLS0gMHg3ZjRh ZGU0MjEyYWQKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICBzeXNjYWxsX3dvcmtfcXVldWU6OndvcmtfaXRlbV9yZXR1 cm5pbmc8c3lzY2FsbF9yZXN1bHQ8aW50PiwgcG9zaXhfZmlsZV9pbXBsOjpmbHVzaCgpOjp7bGFt YmRhKCkjMX0+Ojpwcm9jZXNzCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg2MDMwMDAwYzNlYzAKICAgICAgICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgIHwtLTMyLjc5JS0tIGlvX3NjaGVkdWxlX3RpbWVvdXQKICAg ICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIGJpdF93YWl0X2lv CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICBfX3dhaXRf b25fYml0CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgfC0tNTEuNjclLS0gd2FpdF9vbl9wYWdlX2JpdAogICAgICAgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8LS05NS4x NiUtLSBmaWxlbWFwX2ZkYXRhd2FpdF9yYW5nZQogICAgICAgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIGZpbGVtYXBfd3JpdGVf YW5kX3dhaXRfcmFuZ2UKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB4ZnNfZmlsZV9mc3luYwogICAgICAgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg IHZmc19mc3luY19yYW5nZQogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIGRvX2ZzeW5jCiAgICAgICAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgc3lz X2ZkYXRhc3luYwogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgIGVudHJ5X1NZU0NBTExfNjRfZmFzdHBhdGgKICAgICAg ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICAweDdmNGFkZTQyMTJhZAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHN5c2NhbGxfd29ya19xdWV1ZTo6 d29ya19pdGVtX3JldHVybmluZzxzeXNjYWxsX3Jlc3VsdDxpbnQ+LCBwb3NpeF9maWxlX2ltcGw6 OmZsdXNoKCk6OntsYW1iZGEoKSMxfT46OnByb2Nlc3MKICAgICAgICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAweDYwYjAwMDBj M2VjMAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICAgLS00Ljg0JS0tIF9fbWlncmF0aW9uX2VudHJ5X3dhaXQK ICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgICAgICAgICAgICBtaWdyYXRpb25fZW50cnlfd2FpdAogICAgICAgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIGhhbmRsZV9t bV9mYXVsdAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICAgICAgICAgICAgIF9fZG9fcGFnZV9mYXVsdAogICAgICAgICAgICAgICAgfCAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIGRvX3Bh Z2VfZmF1bHQKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgICAgICAgICAgICBwYWdlX2ZhdWx0CiAgICAgICAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgc3RkOjpfRnVu Y3Rpb25faGFuZGxlcjx2b2lkICgpLCBodHRwZDo6aHR0cF9zZXJ2ZXI6Ol9kYXRlX2Zvcm1hdF90 aW1lcjo6e2xhbWJkYSgpIzF9Pjo6X01faW52b2tlCiAgICAgICAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAK ICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgICAgICAgICAgICAgLS0xMDAuMDAlLS0gc2VydmljZTo6c3RvcmFnZV9wcm94eTo6bXV0YXRl X3ByZXBhcmU8c3RkOjp2ZWN0b3I8bXV0YXRpb24sIHN0ZDo6YWxsb2NhdG9yPG11dGF0aW9uPiA+ LCBzZXJ2aWNlOjpzdG9yYWdlX3Byb3h5OjptdXRhdGVfcHJlcGFyZShzdGQ6OnZlY3RvcjxtdXRh dGlvbiwgc3RkOjphbGxvY2F0b3I8bXV0YXRpb24+ID4mLCBkYjo6Y29uc2lzdGVuY3lfbGV2ZWws IGRiOjp3cml0ZV90eXBlKTo6e2xhbWJkYShtdXRhdGlvbiBjb25zdCYsIGRiOjpjb25zaXN0ZW5j eV9sZXZlbCwgZGI6OndyaXRlX3R5cGUpIzF9PgogICAgICAgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vy dmljZTo6c3RvcmFnZV9wcm94eTo6bXV0YXRlCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXJ2 aWNlOjpzdG9yYWdlX3Byb3h5OjptdXRhdGVfd2l0aF90cmlnZ2VycwogICAgICAgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgY3FsMzo6c3RhdGVtZW50czo6bW9kaWZpY2F0aW9uX3N0YXRlbWVudDo6ZXhlY3V0 ZV93aXRob3V0X2NvbmRpdGlvbgogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3FsMzo6c3RhdGVt ZW50czo6bW9kaWZpY2F0aW9uX3N0YXRlbWVudDo6ZXhlY3V0ZQogICAgICAgICAgICAgICAgfCAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgY3FsMzo6cXVlcnlfcHJvY2Vzc29yOjpwcm9jZXNzX3N0YXRlbWVudAogICAgICAgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgdHJhbnNwb3J0OjpjcWxfc2VydmVyOjpjb25uZWN0aW9uOjpwcm9jZXNz X2V4ZWN1dGUKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zcG9ydDo6Y3FsX3NlcnZlcjo6 Y29ubmVjdGlvbjo6cHJvY2Vzc19yZXF1ZXN0X29uZQogICAgICAgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ZnV0dXJpemU8ZnV0dXJlPHN0ZDo6cGFpcjxmb3JlaWduX3B0cjxzaGFyZWRfcHRyPHRyYW5zcG9y dDo6Y3FsX3NlcnZlcjo6cmVzcG9uc2U+ID4sIHNlcnZpY2U6OmNsaWVudF9zdGF0ZT4gPiA+Ojph cHBseTx0cmFuc3BvcnQ6OmNxbF9zZXJ2ZXI6OmNvbm5lY3Rpb246OnByb2Nlc3NfcmVxdWVzdCgp Ojp7bGFtYmRhKGZ1dHVyZTxzdGQ6OmV4cGVyaW1lbnRhbDo6ZnVuZGFtZW50YWxzX3YxOjpvcHRp b25hbDx0cmFuc3BvcnQ6OmNxbF9iaW5hcnlfZnJhbWVfdjM+ID4mJikjMX06Om9wZXJhdG9yKCko ZnV0dXJlPHN0ZDo6ZXhwZXJpbWVudGFsOjpmdW5kYW1lbnRhbHNfdjE6Om9wdGlvbmFsPHRyYW5z cG9ydDo6Y3FsX2JpbmFyeV9mcmFtZV92Mz4gPiYmKSBjb25zdDo6e2xhbWJkYSh0ZW1wb3Jhcnlf YnVmZmVyPGNoYXI+KSMxfTo6b3BlcmF0b3IoKSh0ZW1wb3JhcnlfYnVmZmVyKSBjb25zdDo6e2xh bWJkYSgpIzF9OjpvcGVyYXRvcigpKCk6OntsYW1iZGEoKSMxfSY+CiAgICAgICAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICBmdXR1cml6ZTxmdXR1cmU8PiA+OjphcHBseTx0cmFuc3BvcnQ6OmNxbF9zZXJ2ZXI6 OmNvbm5lY3Rpb246OnByb2Nlc3NfcmVxdWVzdCgpOjp7bGFtYmRhKGZ1dHVyZTxzdGQ6OmV4cGVy aW1lbnRhbDo6ZnVuZGFtZW50YWxzX3YxOjpvcHRpb25hbDx0cmFuc3BvcnQ6OmNxbF9iaW5hcnlf ZnJhbWVfdjM+ID4mJikjMX06Om9wZXJhdG9yKCkoZnV0dXJlPHN0ZDo6ZXhwZXJpbWVudGFsOjpm dW5kYW1lbnRhbHNfdjE6Om9wdGlvbmFsPHRyYW5zcG9ydDo6Y3FsX2JpbmFyeV9mcmFtZV92Mz4g PiYmKSBjb25zdDo6e2xhbWJkYSh0ZW1wb3JhcnlfYnVmZmVyPGNoYXI+KSMxfSwgdGVtcG9yYXJ5 X2J1ZmZlcj4KICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1dHVyaXplPGZ1dHVyZTw+ID46OmFw cGx5PHRyYW5zcG9ydDo6Y3FsX3NlcnZlcjo6Y29ubmVjdGlvbjo6cHJvY2Vzc19yZXF1ZXN0KCk6 OntsYW1iZGEoZnV0dXJlPHN0ZDo6ZXhwZXJpbWVudGFsOjpmdW5kYW1lbnRhbHNfdjE6Om9wdGlv bmFsPHRyYW5zcG9ydDo6Y3FsX2JpbmFyeV9mcmFtZV92Mz4gPiYmKSMxfSwgZnV0dXJlPHN0ZDo6 ZXhwZXJpbWVudGFsOjpmdW5kYW1lbnRhbHNfdjE6Om9wdGlvbmFsPHRyYW5zcG9ydDo6Y3FsX2Jp bmFyeV9mcmFtZV92Mz4gPiA+CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc3BvcnQ6OmNx bF9zZXJ2ZXI6OmNvbm5lY3Rpb246OnByb2Nlc3NfcmVxdWVzdAogICAgICAgICAgICAgICAgfCAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgZG9fdW50aWxfY29udGludWVkPHRyYW5zcG9ydDo6Y3FsX3NlcnZlcjo6Y29ubmVjdGlv bjo6cHJvY2VzcygpOjp7bGFtYmRhKCkjMn0sIHRyYW5zcG9ydDo6Y3FsX3NlcnZlcjo6Y29ubmVj dGlvbjo6cHJvY2VzcygpOjp7bGFtYmRhKCkjMX0mPgogICAgICAgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ZG9fdm9pZF9mdXR1cml6ZV9hcHBseTx2b2lkIGRvX3VudGlsX2NvbnRpbnVlZDx0cmFuc3BvcnQ6 OmNxbF9zZXJ2ZXI6OmNvbm5lY3Rpb246OnByb2Nlc3MoKTo6e2xhbWJkYSgpIzJ9LCB0cmFuc3Bv cnQ6OmNxbF9zZXJ2ZXI6OmNvbm5lY3Rpb246OnByb2Nlc3MoKTo6e2xhbWJkYSgpIzF9Jj4odHJh bnNwb3J0OjpjcWxfc2VydmVyOjpjb25uZWN0aW9uOjpwcm9jZXNzKCk6OntsYW1iZGEoKSMxfSYs IHRyYW5zcG9ydDo6Y3FsX3NlcnZlcjo6Y29ubmVjdGlvbjo6cHJvY2VzcygpOjp7bGFtYmRhKCkj Mn0mJiwgcHJvbWlzZTw+KTo6e2xhbWJkYShmdXR1cmU8PikjMX0sIHByb21pc2U8PiA+CiAgICAg ICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICBkb192b2lkX2Z1dHVyaXplX2FwcGx5PHZvaWQgZG9fdW50aWxf Y29udGludWVkPHRyYW5zcG9ydDo6Y3FsX3NlcnZlcjo6Y29ubmVjdGlvbjo6cHJvY2VzcygpOjp7 bGFtYmRhKCkjMn0sIHRyYW5zcG9ydDo6Y3FsX3NlcnZlcjo6Y29ubmVjdGlvbjo6cHJvY2Vzcygp Ojp7bGFtYmRhKCkjMX0mPih0cmFuc3BvcnQ6OmNxbF9zZXJ2ZXI6OmNvbm5lY3Rpb246OnByb2Nl c3MoKTo6e2xhbWJkYSgpIzF9JiwgdHJhbnNwb3J0OjpjcWxfc2VydmVyOjpjb25uZWN0aW9uOjpw cm9jZXNzKCk6OntsYW1iZGEoKSMyfSYmLCBwcm9taXNlPD4pOjp7bGFtYmRhKGZ1dHVyZTw+KSMx fSwgcHJvbWlzZTw+ID4KICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4NjE0MDAwMGMzMDAwCiAg ICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg IAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgIC0tNDgu MzMlLS0gb3V0X29mX2xpbmVfd2FpdF9vbl9iaXQKICAgICAgICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgYmxvY2tfdHJ1bmNhdGVfcGFnZQogICAg ICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB4 ZnNfc2V0YXR0cl9zaXplCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICAgICAgICAgICAgIHhmc192bl9zZXRhdHRyCiAgICAgICAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIG5vdGlmeV9jaGFuZ2UKICAgICAg ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgZG9f dHJ1bmNhdGUKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg ICAgICAgICAgICAgZG9fc3lzX2Z0cnVuY2F0ZS5jb25zdHByb3AuMTUKICAgICAgICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgc3lzX2Z0cnVuY2F0 ZQogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAg ICAgICBlbnRyeV9TWVNDQUxMXzY0X2Zhc3RwYXRoCiAgICAgICAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIF9fR0lfX19mdHJ1bmNhdGU2NAogICAg ICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICBz eXNjYWxsX3dvcmtfcXVldWU6OndvcmtfaXRlbV9yZXR1cm5pbmc8c3lzY2FsbF9yZXN1bHRfZXh0 cmE8c3RhdD4sIHBvc2l4X2ZpbGVfaW1wbDo6c3RhdCgpOjp7bGFtYmRhKCkjMX0+Ojpwcm9jZXNz CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAg ICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICAgICAgICAgICAgIHwtLTEzLjc5JS0tIDB4N2Y0YWQyOWZmNzAwCiAgICAgICAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAg ICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAg ICAgICAgIHwtLTEzLjc5JS0tIDB4N2Y0YWNkYmZmNzAwCiAgICAgICAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwtLTEy LjA3JS0tIDB4N2Y0YWQwNWZmNzAwCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwtLTEyLjA3JS0tIDB4N2Y0 YWNlZGZmNzAwCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICAgICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwtLTEwLjM0JS0tIDB4N2Y0YWQwYmZmNzAwCiAg ICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAg IHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICAgICAgICAgICAgIHwtLTYuOTAlLS0gMHg3ZjRhZDJmZmY3MDAKICAgICAgICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAK ICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAg ICAgfC0tNi45MCUtLSAweDdmNGFkMTFmZjcwMAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8LS02LjkwJS0t IDB4N2Y0YWNmOWZmNzAwCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwtLTYuOTAlLS0gMHg3ZjRhY2YzZmY3 MDAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAg ICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgICAgICAgICAgICAgfC0tNi45MCUtLSAweDdmNGFjZTdmZjcwMAogICAgICAgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAg ICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAg ICAgICAgICB8LS0xLjcyJS0tIDB4N2Y0YWQxN2ZmNzAwCiAgICAgICAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAtLTEu NzIlLS0gMHg3ZjRhY2E1ZmY3MDAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAtLTI4 LjY5JS0tIF9fZG93bgogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAg ICAgICAgZG93bgogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAg ICAgeGZzX2J1Zl9sb2NrCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAg ICAgICAgICBfeGZzX2J1Zl9maW5kCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgICAgICAgICAgICB4ZnNfYnVmX2dldF9tYXAKICAgICAgICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgICAgICAgICAgICB8LS05Ny4xNCUtLSB4ZnNfYnVmX3JlYWRfbWFwCiAg ICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAg IHhmc190cmFuc19yZWFkX2J1Zl9tYXAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfC0tOTguMDQlLS0geGZz X3JlYWRfYWdmCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgeGZzX2FsbG9jX3JlYWRfYWdmCiAgICAgICAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg eGZzX2FsbG9jX2ZpeF9mcmVlbGlzdAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgfC0tOTMuMDAlLS0geGZzX2ZyZWVfZXh0ZW50CiAgICAgICAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICB4ZnNfYm1hcF9maW5pc2gKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAg ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHhmc19pdHJ1bmNhdGVf ZXh0ZW50cwogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIHwtLTg3LjEwJS0tIHhmc19pbmFjdGl2ZV90cnVuY2F0ZQogICAgICAgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICB4ZnNfaW5hY3RpdmUKICAgICAgICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgeGZzX2ZzX2V2aWN0X2lub2RlCiAgICAgICAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgIGV2aWN0CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg IGlwdXQKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgX19kZW50cnlfa2lsbAog ICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICBkcHV0CiAgICAgICAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICB8ICAgICAgICAgIF9fZnB1dAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICBfX19fZnB1dAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB0YXNrX3dv cmtfcnVuCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIGRvX25vdGlmeV9yZXN1 bWUKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgaW50X3NpZ25hbAogICAgICAg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICBfX2xpYmNfY2xvc2UKICAgICAgICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgc3RkOjpleHBlcmltZW50YWw6OmZ1bmRhbWVudGFsc192MTo6 YmFkX29wdGlvbmFsX2FjY2Vzczo6fmJhZF9vcHRpb25hbF9hY2Nlc3MKICAgICAgICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgLS0xMi45MCUt LSB4ZnNfc2V0YXR0cl9zaXplCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg ICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHhm c192bl9zZXRhdHRyCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIG5vdGlmeV9j aGFuZ2UKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgZG9fdHJ1bmNhdGUKICAg ICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgZG9fc3lzX2Z0cnVuY2F0ZS5jb25zdHBy b3AuMTUKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgc3lzX2Z0cnVuY2F0ZQog ICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICBlbnRyeV9TWVNDQUxMXzY0X2Zhc3Rw YXRoCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgCiAgICAg ICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAtLTEwMC4wMCUtLSBfX0dJX19fZnRydW5j YXRlNjQKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzeXNj YWxsX3dvcmtfcXVldWU6OndvcmtfaXRlbV9yZXR1cm5pbmc8c3lzY2FsbF9yZXN1bHRfZXh0cmE8 c3RhdD4sIHBvc2l4X2ZpbGVfaW1wbDo6c3RhdCgpOjp7bGFtYmRhKCkjMX0+Ojpwcm9jZXNzCiAg ICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAK ICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8LS0yMC4wMCUt LSAweDdmNGFkMGJmZjcwMAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg ICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgfC0tMjAuMDAlLS0gMHg3ZjRhY2VkZmY3MDAKICAgICAgICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAg ICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwtLTEwLjAwJS0tIDB4N2Y0YWQyZmZmNzAwCiAg ICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAK ICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8LS0xMC4wMCUt LSAweDdmNGFkMTdmZjcwMAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg ICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgfC0tMTAuMDAlLS0gMHg3ZjRhZDExZmY3MDAKICAgICAgICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAg ICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwtLTEwLjAwJS0tIDB4N2Y0YWQwNWZmNzAwCiAg ICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAK ICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8LS0xMC4wMCUt LSAweDdmNGFjZjNmZjcwMAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg ICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgIC0tMTAuMDAlLS0gMHg3ZjRhY2RiZmY3MDAKICAgICAgICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAg ICAgICAgICB8ICAgICAgICAgICAtLTcuMDAlLS0geGZzX2FsbG9jX3ZleHRlbnQKICAgICAgICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICAgICAgICAgICAgIHhmc19ibWFwX2J0YWxsb2MKICAgICAgICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAg IHhmc19ibWFwX2FsbG9jCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB4ZnNfYm1hcGlfd3JpdGUK ICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICAgICAgICAgICAgIHhmc19pb21hcF93cml0ZV9kaXJlY3QKICAgICAgICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICAgICAgICAgICAgIF9feGZzX2dldF9ibG9ja3MKICAgICAgICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAg IHhmc19nZXRfYmxvY2tzX2RpcmVjdAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgZG9fYmxvY2tk ZXZfZGlyZWN0X0lPCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICBfX2Jsb2NrZGV2X2RpcmVjdF9J TwogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgICAgICAgICAgICAgeGZzX3ZtX2RpcmVjdF9JTwogICAgICAgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg ICAgICAgICAgICAgeGZzX2ZpbGVfZGlvX2Fpb193cml0ZQogICAgICAgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAg ICAgeGZzX2ZpbGVfd3JpdGVfaXRlcgogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgYWlvX3J1bl9p b2NiCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgICAgICAgICAgICBkb19pb19zdWJtaXQKICAgICAgICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAg ICAgICAgICAgIHN5c19pb19zdWJtaXQKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIGVudHJ5X1NZ U0NBTExfNjRfZmFzdHBhdGgKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAg ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIGlvX3N1Ym1pdAogICAg ICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgICAgICAgICAgICAgMHg0NmQ5OGEKICAgICAgICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgIC0tMS45NiUt LSB4ZnNfcmVhZF9hZ2kKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAg ICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB4ZnNfaXVubGlua19yZW1vdmUKICAgICAgICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAg ICAgICB4ZnNfaWZyZWUKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAg ICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB4ZnNfaW5hY3RpdmVfaWZyZWUKICAgICAgICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAg ICAgICB4ZnNfaW5hY3RpdmUKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAg ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB4ZnNfZnNfZXZpY3RfaW5vZGUKICAgICAg ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAg ICAgICAgICBldmljdAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAg ICAgICAgfCAgICAgICAgICAgICAgICAgICAgIGlwdXQKICAgICAgICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICBfX2RlbnRyeV9r aWxsCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAg ICAgICAgICAgICAgICAgICAgZHB1dAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIF9fZnB1dAogICAgICAgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAg IF9fX19mcHV0CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAg ICB8ICAgICAgICAgICAgICAgICAgICAgdGFza193b3JrX3J1bgogICAgICAgICAgICAgICAgfCAg ICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIGRvX25v dGlmeV9yZXN1bWUKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAg ICAgIHwgICAgICAgICAgICAgICAgICAgICBpbnRfc2lnbmFsCiAgICAgICAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgX19saWJj X2Nsb3NlCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8 ICAgICAgICAgICAgICAgICAgICAgc3RkOjpleHBlcmltZW50YWw6OmZ1bmRhbWVudGFsc192MTo6 YmFkX29wdGlvbmFsX2FjY2Vzczo6fmJhZF9vcHRpb25hbF9hY2Nlc3MKICAgICAgICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgLS0yLjg2JS0tIHhmc190cmFu c19nZXRfYnVmX21hcAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICB4ZnNfYnRyZWVfZ2V0X2J1ZmwKICAgICAgICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeGZzX2JtYXBfZXh0ZW50c190 b19idHJlZQogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICB4ZnNfYm1hcF9hZGRfZXh0ZW50X2hvbGVfcmVhbAogICAgICAgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ZnNfYm1hcGlfd3Jp dGUKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgeGZzX2lvbWFwX3dyaXRlX2RpcmVjdAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfX3hmc19nZXRfYmxvY2tzCiAgICAgICAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhmc19n ZXRfYmxvY2tzX2RpcmVjdAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICBkb19ibG9ja2Rldl9kaXJlY3RfSU8KICAgICAgICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX19ibG9ja2Rldl9k aXJlY3RfSU8KICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgeGZzX3ZtX2RpcmVjdF9JTwogICAgICAgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ZnNfZmlsZV9kaW9fYWlvX3dyaXRlCiAg ICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg IHhmc19maWxlX3dyaXRlX2l0ZXIKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgYWlvX3J1bl9pb2NiCiAgICAgICAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvX2lvX3N1Ym1pdAogICAg ICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBz eXNfaW9fc3VibWl0CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgIGVudHJ5X1NZU0NBTExfNjRfZmFzdHBhdGgKICAgICAgICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW9fc3VibWl0CiAg ICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg IDB4NDZkOThhCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAg ICAgICAgICB8ICAgICAgICAgIHwtLTEzLjQ4JS0tIGV2ZW50ZmRfY3R4X3JlYWQKICAgICAgICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICBldmVudGZkX3JlYWQKICAgICAgICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICBfX3Zmc19yZWFkCiAgICAgICAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgdmZzX3JlYWQKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICBzeXNfcmVhZAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIGVudHJ5 X1NZU0NBTExfNjRfZmFzdHBhdGgKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICAweDdmNGFkZTZmNzU0ZAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHNt cF9tZXNzYWdlX3F1ZXVlOjpyZXNwb25kCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgMHhmZmZmZmZmZmZmZmZmZmZmCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwtLTcuODMlLS0gbWRfZmx1c2hfcmVx dWVzdAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHJhaWQwX21ha2VfcmVx dWVzdAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIG1kX21ha2VfcmVxdWVz dAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIGdlbmVyaWNfbWFrZV9yZXF1 ZXN0CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgc3VibWl0X2JpbwogICAg ICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfC0tOTIuNTQlLS0gc3VibWl0X2Jpb193YWl0CiAg ICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICBibGtkZXZfaXNz dWVfZmx1c2gKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg IHhmc19ibGtkZXZfaXNzdWVfZmx1c2gKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgIHhmc19maWxlX2ZzeW5jCiAgICAgICAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICB2ZnNfZnN5bmNfcmFuZ2UKICAgICAgICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIGRvX2ZzeW5jCiAgICAgICAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICBzeXNfZmRhdGFzeW5jCiAgICAgICAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICBlbnRyeV9TWVNDQUxMXzY0X2Zh c3RwYXRoCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgIC0tMTAwLjAwJS0tIDB4N2Y0YWRlNDIxMmFkCiAgICAgICAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHN5c2NhbGxfd29ya19xdWV1ZTo6d29y a19pdGVtX3JldHVybmluZzxzeXNjYWxsX3Jlc3VsdDxpbnQ+LCBwb3NpeF9maWxlX2ltcGw6OmZs dXNoKCk6OntsYW1iZGEoKSMxfT46OnByb2Nlc3MKICAgICAgICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgMHg2MDEwMDAwYzNlYzAKICAgICAgICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgICAtLTcuNDYlLS0gX3hmc19idWZfaW9hcHBseQogICAgICAg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgeGZzX2J1Zl9zdWJtaXQK ICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHhsb2dfYmRz dHJhdAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgeGxv Z19zeW5jCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB4 bG9nX3N0YXRlX3JlbGVhc2VfaWNsb2cKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICAgICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgICAgICAgICAgICB8LS03My4zMyUtLSBfeGZzX2xvZ19mb3JjZV9sc24KICAgICAg ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgeGZz X2ZpbGVfZnN5bmMKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAg ICAgIHwgICAgICAgICAgdmZzX2ZzeW5jX3JhbmdlCiAgICAgICAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIGRvX2ZzeW5jCiAgICAgICAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHN5c19mZGF0YXN5 bmMKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAg ICAgICAgZW50cnlfU1lTQ0FMTF82NF9mYXN0cGF0aAogICAgICAgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgLS0xMDAu MDAlLS0gMHg3ZjRhZGU0MjEyYWQKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICBzeXNjYWxsX3dvcmtfcXVldWU6Ondv cmtfaXRlbV9yZXR1cm5pbmc8c3lzY2FsbF9yZXN1bHQ8aW50PiwgcG9zaXhfZmlsZV9pbXBsOjpm bHVzaCgpOjp7bGFtYmRhKCkjMX0+Ojpwcm9jZXNzCiAgICAgICAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgMHg2MDgwMDAwYzNl YzAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAg ICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAg LS0yNi42NyUtLSBfeGZzX2xvZ19mb3JjZQogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ZnNfbG9nX2ZvcmNlCiAgICAgICAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhmc19idWZfbG9j awogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICBfeGZzX2J1Zl9maW5kCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgIHhmc19idWZfZ2V0X21hcAogICAgICAgICAgICAgICAgfCAg ICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ZnNfdHJhbnNfZ2V0X2J1 Zl9tYXAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgeGZzX2J0cmVlX2dldF9idWZsCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhmc19ibWFwX2V4dGVudHNfdG9fYnRyZWUK ICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgeGZzX2JtYXBfYWRkX2V4dGVudF9ob2xlX3JlYWwKICAgICAgICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeGZzX2JtYXBpX3dyaXRlCiAgICAg ICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhm c19pb21hcF93cml0ZV9kaXJlY3QKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgX194ZnNfZ2V0X2Jsb2NrcwogICAgICAgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ZnNfZ2V0X2Jsb2Nr c19kaXJlY3QKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgZG9fYmxvY2tkZXZfZGlyZWN0X0lPCiAgICAgICAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9fYmxvY2tkZXZfZGlyZWN0X0lP CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgIHhmc192bV9kaXJlY3RfSU8KICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgeGZzX2ZpbGVfZGlvX2Fpb193cml0ZQogICAgICAgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ZnNfZmls ZV93cml0ZV9pdGVyCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgIGFpb19ydW5faW9jYgogICAgICAgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb19pb19zdWJtaXQKICAgICAgICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3lzX2lvX3N1 Ym1pdAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICBlbnRyeV9TWVNDQUxMXzY0X2Zhc3RwYXRoCiAgICAgICAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlvX3N1Ym1pdAogICAgICAgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDQ2ZDk4 YQogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAg fCAgICAgICAgICB8LS01LjUzJS0tIF94ZnNfbG9nX2ZvcmNlX2xzbgogICAgICAgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgfC0tODAuMjglLS0geGZzX2ZpbGVfZnN5bmMKICAgICAgICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHZmc19mc3luY19yYW5nZQogICAgICAg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgZG9fZnN5bmMKICAgICAg ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHN5c19mZGF0YXN5bmMK ICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIGVudHJ5X1NZ U0NBTExfNjRfZmFzdHBhdGgKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICAgLS0xMDAuMDAlLS0gMHg3ZjRhZGU0MjEyYWQKICAgICAgICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgc3lzY2FsbF93b3Jr X3F1ZXVlOjp3b3JrX2l0ZW1fcmV0dXJuaW5nPHN5c2NhbGxfcmVzdWx0PGludD4sIHBvc2l4X2Zp bGVfaW1wbDo6Zmx1c2goKTo6e2xhbWJkYSgpIzF9Pjo6cHJvY2VzcwogICAgICAgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIAog ICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAg ICB8LS05Ny45MiUtLSAweDYwZDAwMDBjM2VjMAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8LS0xLjA0JS0t IDB4NjAyMDAwMGMzZWMwCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAtLTEuMDQlLS0gMHg2MDAwMDA1NTdl YzAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAg ICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAtLTE5LjcyJS0tIHhmc19kaXJfZnN5 bmMKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHZmc19m c3luY19yYW5nZQogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAg ICAgZG9fZnN5bmMKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAg ICAgIHN5c19mZGF0YXN5bmMKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAg ICAgICAgICAgIGVudHJ5X1NZU0NBTExfNjRfZmFzdHBhdGgKICAgICAgICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgLS0xMDAuMDAlLS0gMHg3ZjRhZGU0MjEy YWQKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgc3lzY2FsbF93b3JrX3F1ZXVlOjp3b3JrX2l0ZW1fcmV0dXJuaW5nPHN5c2NhbGxfcmVz dWx0PGludD4sIHBvc2l4X2ZpbGVfaW1wbDo6Zmx1c2goKTo6e2xhbWJkYSgpIzF9Pjo6cHJvY2Vz cwogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAweDYwNDAwMDBjM2VjMAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg IAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8LS0xLjI1JS0tIHJ3c2VtX2Rvd25fcmVhZF9m YWlsZWQKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICBjYWxsX3J3c2VtX2Rv d25fcmVhZF9mYWlsZWQKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwtLTkwLjYyJS0t IHhmc19pbG9jawogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgIHwtLTg2LjIxJS0tIHhmc19pbG9ja19kYXRhX21hcF9zaGFyZWQKICAgICAgICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgX194ZnNfZ2V0 X2Jsb2NrcwogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICB4ZnNfZ2V0X2Jsb2Nrc19kaXJlY3QKICAgICAgICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgZG9fYmxvY2tkZXZfZGlyZWN0X0lP CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIF9fYmxvY2tkZXZfZGlyZWN0X0lPCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHhmc192bV9kaXJlY3RfSU8KICAgICAgICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgeGZzX2ZpbGVf ZGlvX2Fpb193cml0ZQogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICB4ZnNfZmlsZV93cml0ZV9pdGVyCiAgICAgICAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIGFpb19ydW5faW9jYgogICAg ICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICBk b19pb19zdWJtaXQKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgc3lzX2lvX3N1Ym1pdAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICBlbnRyeV9TWVNDQUxMXzY0X2Zhc3RwYXRo CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICB8ICAgICAgICAgICAtLTEwMC4wMCUtLSBpb19zdWJtaXQKICAgICAgICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAw eDQ2ZDk4YQogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIHwtLTYuOTAlLS0geGZzX2ZpbGVfZnN5bmMKICAgICAgICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgdmZzX2ZzeW5jX3JhbmdlCiAgICAgICAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIGRvX2Zz eW5jCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgIHN5c19mZGF0YXN5bmMKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgZW50cnlfU1lTQ0FMTF82NF9mYXN0cGF0aAogICAgICAg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAweDdm NGFkZTQyMTJhZAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICBzeXNjYWxsX3dvcmtfcXVldWU6OndvcmtfaXRlbV9yZXR1cm5pbmc8c3lz Y2FsbF9yZXN1bHQ8aW50PiwgcG9zaXhfZmlsZV9pbXBsOjpmbHVzaCgpOjp7bGFtYmRhKCkjMX0+ Ojpwcm9jZXNzCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIDB4NjA5MDAwMGMzZWMwCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgIC0tNi45MCUtLSB4ZnNfZGlyX2ZzeW5jCiAgICAgICAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHZmc19m c3luY19yYW5nZQogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgICAgICAgICAgICBkb19mc3luYwogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgICAgICAgICAgICBzeXNfZmRhdGFzeW5jCiAgICAgICAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIGVudHJ5X1NZU0NBTExf NjRfZmFzdHBhdGgKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgICAgICAgICAgICAgMHg3ZjRhZGU0MjEyYWQKICAgICAgICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgc3lzY2FsbF93b3JrX3F1ZXVlOjp3b3Jr X2l0ZW1fcmV0dXJuaW5nPHN5c2NhbGxfcmVzdWx0PGludD4sIHBvc2l4X2ZpbGVfaW1wbDo6Zmx1 c2goKTo6e2xhbWJkYSgpIzF9Pjo6cHJvY2VzcwogICAgICAgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAweDYwNzAwMDBjM2VjMAogICAgICAgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgIC0tOS4zOCUtLSB4ZnNfbG9nX2NvbW1pdF9jaWwKICAgICAg ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIF9feGZzX3RyYW5zX2Nv bW1pdAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgeGZz X3RyYW5zX2NvbW1pdAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAg ICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAg ICAgICAgICAgIHwtLTMzLjMzJS0tIHhmc19zZXRhdHRyX3NpemUKICAgICAgICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgeGZzX3ZuX3NldGF0dHIK ICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAg ICAgbm90aWZ5X2NoYW5nZQogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAg ICAgICAgICAgfCAgICAgICAgICBkb190cnVuY2F0ZQogICAgICAgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICBkb19zeXNfZnRydW5jYXRlLmNvbnN0 cHJvcC4xNQogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAg fCAgICAgICAgICBzeXNfZnRydW5jYXRlCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgICAgICAgICAgICB8ICAgICAgICAgIGVudHJ5X1NZU0NBTExfNjRfZmFzdHBhdGgKICAg ICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAg X19HSV9fX2Z0cnVuY2F0ZTY0CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg ICAgICAgICAgICB8ICAgICAgICAgIHN5c2NhbGxfd29ya19xdWV1ZTo6d29ya19pdGVtX3JldHVy bmluZzxzeXNjYWxsX3Jlc3VsdF9leHRyYTxzdGF0PiwgcG9zaXhfZmlsZV9pbXBsOjpzdGF0KCk6 OntsYW1iZGEoKSMxfT46OnByb2Nlc3MKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICAgICAgICAgICAgIHwgICAgICAgICAgMHg3ZjRhY2VkZmY3MDAKICAgICAgICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8LS0zMy4zMyUtLSB4ZnNfdm5f dXBkYXRlX3RpbWUKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAg ICAgIHwgICAgICAgICAgZmlsZV91cGRhdGVfdGltZQogICAgICAgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB4ZnNfZmlsZV9haW9fd3JpdGVfY2hl Y2tzCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAg ICAgICAgIHhmc19maWxlX2Rpb19haW9fd3JpdGUKICAgICAgICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgeGZzX2ZpbGVfd3JpdGVfaXRlcgogICAg ICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICBh aW9fcnVuX2lvY2IKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAg ICAgIHwgICAgICAgICAgZG9faW9fc3VibWl0CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHN5c19pb19zdWJtaXQKICAgICAgICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgZW50cnlfU1lT Q0FMTF82NF9mYXN0cGF0aAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAg ICAgICAgICAgfCAgICAgICAgICBpb19zdWJtaXQKICAgICAgICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgMHg0NmQ5OGEKICAgICAgICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgLS0zMy4zMyUtLSB4ZnNfYm1h cF9hZGRfYXR0cmZvcmsKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgeGZzX2F0dHJfc2V0CiAgICAgICAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhmc19pbml0eGF0dHJzCiAgICAgICAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlY3Vy aXR5X2lub2RlX2luaXRfc2VjdXJpdHkKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgeGZzX2luaXRfc2VjdXJpdHkKICAgICAgICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeGZzX2dlbmVy aWNfY3JlYXRlCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgIHhmc192bl9ta25vZAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ZnNfdm5fY3JlYXRlCiAgICAgICAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZmc19jcmVhdGUK ICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgcGF0aF9vcGVuYXQKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgZG9fZmlscF9vcGVuCiAgICAgICAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvX3N5c19vcGVuCiAgICAgICAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5c19vcGVu CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgIGVudHJ5X1NZU0NBTExfNjRfZmFzdHBhdGgKICAgICAgICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg3ZjRhZGU2ZjdjZGQKICAgICAgICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3lzY2Fs bF93b3JrX3F1ZXVlOjp3b3JrX2l0ZW1fcmV0dXJuaW5nPHN5c2NhbGxfcmVzdWx0PGludD4sIHJl YWN0b3I6Om9wZW5fZmlsZV9kbWEoYmFzaWNfc3N0cmluZzxjaGFyLCB1bnNpZ25lZCBpbnQsIDE1 dT4sIG9wZW5fZmxhZ3MsIGZpbGVfb3Blbl9vcHRpb25zKTo6e2xhbWJkYSgpIzF9Pjo6cHJvY2Vz cwogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAweGZmZmZmZmZmZmZmZmZmZmYKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICAKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfC0tMC45NyUtLSByd3NlbV9kb3duX3dy aXRlX2ZhaWxlZAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIGNhbGxfcndz ZW1fZG93bl93cml0ZV9mYWlsZWQKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICB4ZnNfaWxvY2sKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB4ZnNfdm5f dXBkYXRlX3RpbWUKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICBmaWxlX3Vw ZGF0ZV90aW1lCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgeGZzX2ZpbGVf YWlvX3dyaXRlX2NoZWNrcwogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHhm c19maWxlX2Rpb19haW9fd3JpdGUKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICB4ZnNfZmlsZV93cml0ZV9pdGVyCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgYWlvX3J1bl9pb2NiCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgZG9f aW9fc3VibWl0CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgc3lzX2lvX3N1 Ym1pdAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIGVudHJ5X1NZU0NBTExf NjRfZmFzdHBhdGgKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICBpb19zdWJt aXQKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAweDQ2ZDk4YQogICAgICAg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAg ICB8LS0wLjUxJS0tIHhsb2dfY2lsX2ZvcmNlX2xzbgogICAgICAgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgfC0tOTIuMzElLS0gX3hmc19sb2dfZm9yY2VfbHNuCiAgICAgICAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfC0tOTEuNjclLS0geGZzX2ZpbGVfZnN5 bmMKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgdmZzX2ZzeW5jX3JhbmdlCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgIGRvX2ZzeW5jCiAgICAgICAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHN5c19mZGF0YXN5bmMKICAgICAg ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgZW50 cnlfU1lTQ0FMTF82NF9mYXN0cGF0aAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICAweDdmNGFkZTQyMTJhZAogICAgICAgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICBzeXNjYWxsX3dvcmtf cXVldWU6OndvcmtfaXRlbV9yZXR1cm5pbmc8c3lzY2FsbF9yZXN1bHQ8aW50PiwgcG9zaXhfZmls ZV9pbXBsOjpmbHVzaCgpOjp7bGFtYmRhKCkjMX0+Ojpwcm9jZXNzCiAgICAgICAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIDB4NjBiMDAwMGMzZWMw CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgIC0t OC4zMyUtLSB4ZnNfZGlyX2ZzeW5jCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICAgICAgICAgICAgIHZmc19mc3luY19yYW5nZQogICAgICAgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICBkb19mc3luYwogICAg ICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICBz eXNfZmRhdGFzeW5jCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICAgICAgICAgICAgIGVudHJ5X1NZU0NBTExfNjRfZmFzdHBhdGgKICAgICAgICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgMHg3ZjRhZGU0MjEy YWQKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAg ICAgICAgc3lzY2FsbF93b3JrX3F1ZXVlOjp3b3JrX2l0ZW1fcmV0dXJuaW5nPHN5c2NhbGxfcmVz dWx0PGludD4sIHBvc2l4X2ZpbGVfaW1wbDo6Zmx1c2goKTo6e2xhbWJkYSgpIzF9Pjo6cHJvY2Vz cwogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAg ICAgICAweDYwZDAwMDBjM2VjMAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgIC0tNy42 OSUtLSBfeGZzX2xvZ19mb3JjZQogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg ICAgICAgICAgICAgeGZzX2xvZ19mb3JjZQogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgICAgICAgICAgICAgeGZzX2J1Zl9sb2NrCiAgICAgICAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgICAgICAgICAgICBfeGZzX2J1Zl9maW5kCiAgICAgICAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB4ZnNfYnVmX2dldF9tYXAKICAgICAgICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHhmc190cmFuc19nZXRfYnVmX21h cAogICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgeGZzX2J0 cmVlX2dldF9idWZsCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAg ICAgICB4ZnNfYm1hcF9leHRlbnRzX3RvX2J0cmVlCiAgICAgICAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgICAgICAgICAgICB4ZnNfYm1hcF9hZGRfZXh0ZW50X2hvbGVfcmVhbAogICAg ICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgeGZzX2JtYXBpX3dy aXRlCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB4ZnNf aW9tYXBfd3JpdGVfZGlyZWN0CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg ICAgICAgICAgICBfX3hmc19nZXRfYmxvY2tzCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgICAgICAgICAgICB4ZnNfZ2V0X2Jsb2Nrc19kaXJlY3QKICAgICAgICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIGRvX2Jsb2NrZGV2X2RpcmVjdF9JTwog ICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgX19ibG9ja2Rl dl9kaXJlY3RfSU8KICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAg ICAgIHhmc192bV9kaXJlY3RfSU8KICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICAgICAgICAgICAgIHhmc19maWxlX2Rpb19haW9fd3JpdGUKICAgICAgICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHhmc19maWxlX3dyaXRlX2l0ZXIKICAgICAgICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIGFpb19ydW5faW9jYgogICAg ICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgZG9faW9fc3VibWl0 CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICBzeXNfaW9f c3VibWl0CiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICBl bnRyeV9TWVNDQUxMXzY0X2Zhc3RwYXRoCiAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgICAgICAgICAgICBpb19zdWJtaXQKICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICAgICAgICAgICAgIDB4NDZkOThhCiAgICAgICAgICAgICAgICB8ICAgICAgICAgICAt LTAuMDQlLS0gWy4uLl0KICAgICAgICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAg ICAgLS0zLjgyJS0tIHByZWVtcHRfc2NoZWR1bGVfY29tbW9uCiAgICAgICAgICAgICAgICAgICAg ICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwtLTk5LjAyJS0t IF9jb25kX3Jlc2NoZWQKICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwtLTQxLjU4JS0t IHdhaXRfZm9yX2NvbXBsZXRpb24KICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICB8LS02Ni42NyUtLSBmbHVzaF93b3JrCiAgICAgICAgICAgICAgICAg ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHhsb2dfY2lsX2ZvcmNl X2xzbgogICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICB8LS05Ni40MyUtLSBfeGZzX2xvZ19mb3JjZV9sc24KICAg ICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwtLTc3Ljc4JS0tIHhmc19maWxl X2ZzeW5jCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB2ZnNfZnN5bmNfcmFuZ2UKICAgICAgICAg ICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgIGRvX2ZzeW5jCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICBzeXNfZmRh dGFzeW5jCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICBlbnRyeV9TWVNDQUxMXzY0X2Zhc3RwYXRo CiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICAweDdmNGFkZTQyMTJhZAogICAgICAgICAgICAgICAg ICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgc3lzY2FsbF93b3JrX3F1ZXVlOjp3b3JrX2l0ZW1fcmV0dXJuaW5nPHN5c2NhbGxf cmVzdWx0PGludD4sIHBvc2l4X2ZpbGVfaW1wbDo6Zmx1c2goKTo6e2xhbWJkYSgpIzF9Pjo6cHJv Y2VzcwogICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgMHg2MDMwMDAwYzNlYzAKICAgICAgICAgICAg ICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAtLTIyLjIyJS0tIHhmc19kaXJfZnN5bmMKICAg ICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICAgICAgICAgICAgIHZmc19mc3luY19yYW5nZQogICAgICAgICAgICAgICAgICAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAg ICAgICAgZG9fZnN5bmMKICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHN5c19mZGF0YXN5bmMKICAg ICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICAgICAgICAgICAgIGVudHJ5X1NZU0NBTExfNjRfZmFzdHBhdGgKICAgICAgICAg ICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICAgICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgLS0x MDAuMDAlLS0gMHg3ZjRhZGU0MjEyYWQKICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgc3lzY2FsbF93b3JrX3F1ZXVlOjp3b3JrX2l0ZW1fcmV0dXJuaW5nPHN5c2NhbGxfcmVzdWx0 PGludD4sIHBvc2l4X2ZpbGVfaW1wbDo6Zmx1c2goKTo6e2xhbWJkYSgpIzF9Pjo6cHJvY2Vzcwog ICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDYwMzAwMDBjM2VjMAogICAgICAg ICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICAgLS0zLjU3JS0tIF94ZnNfbG9nX2ZvcmNlCiAgICAgICAgICAgICAgICAgICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgeGZzX2xv Z19mb3JjZQogICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICAgICAgICAgICAgIHhmc19idWZfbG9jawogICAgICAgICAgICAgICAgICAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIF94ZnNfYnVm X2ZpbmQKICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgICAgICAgICAgICB4ZnNfYnVmX2dldF9tYXAKICAgICAgICAgICAgICAgICAgICAg ICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB4ZnNfdHJh bnNfZ2V0X2J1Zl9tYXAKICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB4ZnNfYnRyZWVfZ2V0X2J1ZmwKICAgICAgICAg ICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAg ICAgICB4ZnNfYm1hcF9leHRlbnRzX3RvX2J0cmVlCiAgICAgICAgICAgICAgICAgICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgeGZzX2JtYXBfYWRk X2V4dGVudF9ob2xlX3JlYWwKICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB4ZnNfYm1hcGlfd3JpdGUKICAgICAgICAg ICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAg ICAgICB4ZnNfaW9tYXBfd3JpdGVfZGlyZWN0CiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgX194ZnNfZ2V0X2Jsb2Nr cwogICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICAgICAgICAgICAgIHhmc19nZXRfYmxvY2tzX2RpcmVjdAogICAgICAgICAgICAgICAgICAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIGRvX2Js b2NrZGV2X2RpcmVjdF9JTwogICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIF9fYmxvY2tkZXZfZGlyZWN0X0lPCiAgICAg ICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAg ICAgICAgICAgeGZzX3ZtX2RpcmVjdF9JTwogICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHhmc19maWxlX2Rpb19haW9f d3JpdGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgICAgICAgICAgICB4ZnNfZmlsZV93cml0ZV9pdGVyCiAgICAgICAgICAgICAgICAg ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgYWlv X3J1bl9pb2NiCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgICAgICAgICAgICAgZG9faW9fc3VibWl0CiAgICAgICAgICAgICAgICAgICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgc3lzX2lv X3N1Ym1pdAogICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICAgICAgICAgICAgIGVudHJ5X1NZU0NBTExfNjRfZmFzdHBhdGgKICAgICAgICAg ICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAg ICAgICBpb19zdWJtaXQKICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAweDQ2ZDk4YQogICAgICAgICAgICAgICAgICAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAg ICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAtLTMzLjMzJS0tIHN1Ym1pdF9iaW9f d2FpdAogICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAg ICAgICAgICBibGtkZXZfaXNzdWVfZmx1c2gKICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAg ICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgeGZzX2Jsa2Rldl9pc3N1ZV9mbHVzaAogICAg ICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB4 ZnNfZmlsZV9mc3luYwogICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAg ICAgICAgICAgICAgICAgICB2ZnNfZnN5bmNfcmFuZ2UKICAgICAgICAgICAgICAgICAgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgZG9fZnN5bmMKICAgICAgICAgICAg ICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgc3lzX2ZkYXRh c3luYwogICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAg ICAgICAgICBlbnRyeV9TWVNDQUxMXzY0X2Zhc3RwYXRoCiAgICAgICAgICAgICAgICAgICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAg ICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAtLTEw MC4wMCUtLSAweDdmNGFkZTQyMTJhZAogICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5c2NhbGxfd29ya19xdWV1ZTo6 d29ya19pdGVtX3JldHVybmluZzxzeXNjYWxsX3Jlc3VsdDxpbnQ+LCBwb3NpeF9maWxlX2ltcGw6 OmZsdXNoKCk6OntsYW1iZGEoKSMxfT46OnByb2Nlc3MKICAgICAgICAgICAgICAgICAgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDYwMzAwMDBj M2VjMAogICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAg ICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfC0tMzMuNjYlLS0gZmx1c2hfd29y awogICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgeGxvZ19j aWxfZm9yY2VfbHNuCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgfC0tOTcuMDYlLS0gX3hmc19sb2dfZm9yY2VfbHNuCiAgICAgICAgICAgICAgICAg ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAg ICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg IHwtLTc4Ljc5JS0tIHhmc19maWxlX2ZzeW5jCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgdmZzX2ZzeW5jX3Jhbmdl CiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgZG9fZnN5bmMKICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICBzeXNfZmRhdGFzeW5jCiAgICAg ICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgZW50cnlfU1lTQ0FMTF82NF9mYXN0cGF0aAogICAgICAgICAgICAgICAgICAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIDB4N2Y0YWRl NDIxMmFkCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgc3lzY2FsbF93b3JrX3F1ZXVlOjp3b3JrX2l0ZW1fcmV0dXJu aW5nPHN5c2NhbGxfcmVzdWx0PGludD4sIHBvc2l4X2ZpbGVfaW1wbDo6Zmx1c2goKTo6e2xhbWJk YSgpIzF9Pjo6cHJvY2VzcwogICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIDB4NjAzMDAwMGMzZWMwCiAgICAgICAgICAg ICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgICAtLTIxLjIxJS0tIHhmc19kaXJfZnN5bmMKICAgICAgICAgICAgICAgICAgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB2ZnNfZnN5bmNf cmFuZ2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgICAgICAgICAgICBkb19mc3luYwogICAgICAgICAgICAgICAgICAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHN5c19mZGF0YXN5bmMK ICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgICAgICAgICAgICBlbnRyeV9TWVNDQUxMXzY0X2Zhc3RwYXRoCiAgICAgICAgICAgICAgICAg ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAg ICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgICAgICAgICAgICAgLS0xMDAuMDAlLS0gMHg3ZjRhZGU0MjEyYWQKICAgICAg ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgIHN5c2NhbGxfd29ya19xdWV1ZTo6d29ya19pdGVtX3JldHVybmlu ZzxzeXNjYWxsX3Jlc3VsdDxpbnQ+LCBwb3NpeF9maWxlX2ltcGw6OmZsdXNoKCk6OntsYW1iZGEo KSMxfT46OnByb2Nlc3MKICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4NjAzMDAwMGMzZWMwCiAg ICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg IAogICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgIC0tMi45 NCUtLSBfeGZzX2xvZ19mb3JjZQogICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgICAgICAgICAgICB4ZnNfbG9nX2ZvcmNlCiAgICAgICAgICAgICAgICAgICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHhmc19idWZfbG9jawogICAg ICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICBf eGZzX2J1Zl9maW5kCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICAgICAgICAgICAgIHhmc19idWZfZ2V0X21hcAogICAgICAgICAgICAgICAgICAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB4ZnNfdHJhbnNfZ2V0X2J1Zl9tYXAK ICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAg ICAgeGZzX2J0cmVlX2dldF9idWZsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICAgICAgICAgICAgIHhmc19ibWFwX2V4dGVudHNfdG9fYnRyZWUKICAgICAg ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgeGZz X2JtYXBfYWRkX2V4dGVudF9ob2xlX3JlYWwKICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAg ICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgeGZzX2JtYXBpX3dyaXRlCiAgICAgICAgICAg ICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHhmc19pb21h cF93cml0ZV9kaXJlY3QKICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgICAgICAgICAgICAgX194ZnNfZ2V0X2Jsb2NrcwogICAgICAgICAgICAgICAgICAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB4ZnNfZ2V0X2Jsb2Nrc19kaXJl Y3QKICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAg ICAgICAgZG9fYmxvY2tkZXZfZGlyZWN0X0lPCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIF9fYmxvY2tkZXZfZGlyZWN0X0lPCiAgICAg ICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHhm c192bV9kaXJlY3RfSU8KICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgICAgICAgICAgICAgeGZzX2ZpbGVfZGlvX2Fpb193cml0ZQogICAgICAgICAgICAgICAg ICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB4ZnNfZmlsZV93cml0 ZV9pdGVyCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAg ICAgICAgICAgIGFpb19ydW5faW9jYgogICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgICAgICAgICAgICBkb19pb19zdWJtaXQKICAgICAgICAgICAgICAgICAg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgc3lzX2lvX3N1Ym1pdAog ICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAg ICBlbnRyeV9TWVNDQUxMXzY0X2Zhc3RwYXRoCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIGlvX3N1Ym1pdAogICAgICAgICAgICAgICAg ICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAweDQ2ZDk4YQogICAg ICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAg ICAgICAgICAgICAgICAgIHwgICAgICAgICAgfC0tMTMuODYlLS0gbG9ja19zb2NrX25lc3RlZAog ICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwtLTc4 LjU3JS0tIHRjcF9zZW5kbXNnCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgIGluZXRfc2VuZG1zZwogICAgICAgICAgICAgICAgICAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICBzb2NrX3NlbmRtc2cKICAgICAg ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgU1lT Q19zZW5kdG8KICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgc3lzX3NlbmR0bwogICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICBlbnRyeV9TWVNDQUxMXzY0X2Zhc3RwYXRoCiAgICAg ICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIF9f bGliY19zZW5kCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIF9aTjEyY29udGludWF0aW9uSVpONmZ1dHVyZUlKbUVFNHRoZW5JWk43cmVh Y3RvcjE0d3JpdGVfYWxsX3BhcnRFUjE3cG9sbGFibGVfZmRfc3RhdGVQS3ZtbUVVbG1FX1MwX0lK RUVFRVQwX09UX0VVbFNDX0VfSm1FRTNydW5FdgogICAgICAgICAgICAgICAgICAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAg ICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8LS0zNi4zNiUt LSAweDdmNGFkNmJmOGRlMAogICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAg ICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8LS05LjA5JS0tIDB4NAogICAgICAg ICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICB8LS05LjA5JS0tIDB4N2Y0YWRhZGY4ZGUwCiAgICAgICAgICAgICAgICAgICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAg ICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwt LTkuMDklLS0gMHg3ZjRhZGExZjhkZTAKICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgICAg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfC0tOS4wOSUtLSAweDdm NGFkODlmOGRlMAogICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8LS05LjA5JS0tIDB4N2Y0YWQ4M2Y4ZGUwCiAg ICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgIHwtLTkuMDklLS0gMHg3ZjRhZDRkZjhkZTAKICAgICAgICAgICAgICAg ICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAK ICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgIC0tOS4wOSUtLSAweDdmNGFkMzVmOGRlMAogICAgICAgICAgICAgICAgICAgICAgICAgICB8 ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAg ICAgfCAgICAgICAgICB8ICAgICAgICAgICAtLTIxLjQzJS0tIHRjcF9yZWN2bXNnCiAgICAgICAg ICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIGluZXRf cmVjdm1zZwogICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg ICAgICAgICAgICBzb2NrX3JlY3Ztc2cKICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAg ICAgICB8ICAgICAgICAgICAgICAgICAgICAgc29ja19yZWFkX2l0ZXIKICAgICAgICAgICAgICAg ICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgX192ZnNfcmVhZAog ICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAg ICB2ZnNfcmVhZAogICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgICAgICAgICAgICBzeXNfcmVhZAogICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgICAgICAgICAgICBlbnRyeV9TWVNDQUxMXzY0X2Zhc3RwYXRoCiAgICAg ICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIDB4 N2Y0YWRlNmY3NTRkCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAg ICAgICAgICAgICAgICAgIHJlYWN0b3I6OnJlYWRfc29tZQogICAgICAgICAgICAgICAgICAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIAogICAgICAg ICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8LS02 Ni42NyUtLSBfWk4xMmNvbnRpbnVhdGlvbklaTjZmdXR1cmVJSkVFNHRoZW5JWlpON3NlcnZpY2Ux M3N0b3JhZ2VfcHJveHkyMnNlbmRfdG9fbGl2ZV9lbmRwb2ludHNFbUVOS1VsUlN0NHBhaXJJSzEz YmFzaWNfc3N0cmluZ0ljakxqMTVFRVN0NnZlY3RvcklOM2dtczEyaW5ldF9hZGRyZXNzRVNhSVNC X0VFRUVfY2xFU0ZfRVVsdkVfUzFfRUVUMF9PVF9FVWxTS19FX0pFRTNydW5FdgogICAgICAgICAg ICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAg ICAgIHJlYWN0b3I6OmRlbF90aW1lcgogICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIDB4NjE2MDAwMGUyMDQwCiAgICAg ICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHwg ICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICAgICAgICAgICAgICAtLTMzLjMzJS0tIGNvbnRpbnVhdGlvbjxmdXR1cmU8PiBmdXR1cmU8Pjo6 dGhlbl93cmFwcGVkPGZ1dHVyZTw+IGZ1dHVyZTw+OjpmaW5hbGx5PGF1dG8gc2Vhc3Rhcjo6d2l0 aF9nYXRlPHRyYW5zcG9ydDo6Y3FsX3NlcnZlcjo6Y29ubmVjdGlvbjo6cHJvY2VzcygpOjp7bGFt YmRhKCkjMn06Om9wZXJhdG9yKCkoKSBjb25zdDo6e2xhbWJkYSgpIzF9PihzZWFzdGFyOjpnYXRl JiwgdHJhbnNwb3J0OjpjcWxfc2VydmVyOjpjb25uZWN0aW9uOjpwcm9jZXNzKCk6OntsYW1iZGEo KSMyfTo6b3BlcmF0b3IoKSgpIGNvbnN0Ojp7bGFtYmRhKCkjMX0mJik6OntsYW1iZGEoKSMxfT4o c2Vhc3Rhcjo6Z2F0ZSYpOjp7bGFtYmRhKGZ1dHVyZTw+KSMxfTo6b3BlcmF0b3IoKShmdXR1cmU8 Pik6OntsYW1iZGEoc2Vhc3Rhcjo6Z2F0ZSkjMX0sIGZ1dHVyZTw+ID4oc2Vhc3Rhcjo6Z2F0ZSYp Ojp7bGFtYmRhKHNlYXN0YXI6OmdhdGUmKSMxfT46OnJ1bgogICAgICAgICAgICAgICAgICAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYWN0b3I6 OmRlbF90aW1lcgogICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgIDB4NjAzMDAwMGUyMDQwCiAgICAgICAgICAgICAgICAg ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAg ICAgfCAgICAgICAgICB8LS0zLjk2JS0tIGdlbmVyaWNfbWFrZV9yZXF1ZXN0X2NoZWNrcwogICAg ICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgZ2VuZXJpY19tYWtl X3JlcXVlc3QKICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg IHN1Ym1pdF9iaW8KICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAg ICAgIGRvX2Jsb2NrZGV2X2RpcmVjdF9JTwogICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgX19ibG9ja2Rldl9kaXJlY3RfSU8KICAgICAgICAgICAgICAgICAg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHhmc192bV9kaXJlY3RfSU8KICAgICAgICAg ICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHhmc19maWxlX2Rpb19haW9f d3JpdGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHhm c19maWxlX3dyaXRlX2l0ZXIKICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgIGFpb19ydW5faW9jYgogICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgZG9faW9fc3VibWl0CiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwg ICAgICAgICAgfCAgICAgICAgICBzeXNfaW9fc3VibWl0CiAgICAgICAgICAgICAgICAgICAgICAg ICAgIHwgICAgICAgICAgfCAgICAgICAgICBlbnRyeV9TWVNDQUxMXzY0X2Zhc3RwYXRoCiAgICAg ICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICBpb19zdWJtaXQKICAg ICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIDB4NDZkOThhCiAg ICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAg ICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8LS0zLjk2JS0tIGttZW1fY2FjaGVfYWxsb2Nf bm9kZQogICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgX19h bGxvY19za2IKICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAg IHNrX3N0cmVhbV9hbGxvY19za2IKICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIHRjcF9zZW5kbXNnCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICBpbmV0X3NlbmRtc2cKICAgICAgICAgICAgICAgICAgICAgICAgICAg fCAgICAgICAgICB8ICAgICAgICAgIHNvY2tfc2VuZG1zZwogICAgICAgICAgICAgICAgICAgICAg ICAgICB8ICAgICAgICAgIHwgICAgICAgICAgU1lTQ19zZW5kdG8KICAgICAgICAgICAgICAgICAg ICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHN5c19zZW5kdG8KICAgICAgICAgICAgICAg ICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIGVudHJ5X1NZU0NBTExfNjRfZmFzdHBh dGgKICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIF9fbGli Y19zZW5kCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICBf Wk4xMmNvbnRpbnVhdGlvbklaTjZmdXR1cmVJSm1FRTR0aGVuSVpON3JlYWN0b3IxNHdyaXRlX2Fs bF9wYXJ0RVIxN3BvbGxhYmxlX2ZkX3N0YXRlUEt2bW1FVWxtRV9TMF9JSkVFRUVUMF9PVF9FVWxT Q19FX0ptRUUzcnVuRXYKICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICB8LS0yNS4wMCUtLSAweDdmNGFkOWJmOGRlMAogICAgICAgICAgICAgICAgICAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAKICAgICAgICAgICAgICAg ICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIHwtLTI1LjAwJS0tIDB4N2Y0YWQ3ZGY4 ZGUwCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAg fC0tMjUuMDAlLS0gMHg3ZjRhZDc3ZjhkZTAKICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICAgLS0yNS4wMCUtLSAweDdmNGFkNTlmOGRlMAogICAgICAg ICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAg ICAgICAgICAgICAgIHwgICAgICAgICAgfC0tMC45OSUtLSB1bm1hcF91bmRlcmx5aW5nX21ldGFk YXRhCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICBkb19i bG9ja2Rldl9kaXJlY3RfSU8KICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8 ICAgICAgICAgIF9fYmxvY2tkZXZfZGlyZWN0X0lPCiAgICAgICAgICAgICAgICAgICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICB4ZnNfdm1fZGlyZWN0X0lPCiAgICAgICAgICAgICAgICAg ICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB4ZnNfZmlsZV9kaW9fYWlvX3dyaXRlCiAg ICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB4ZnNfZmlsZV93 cml0ZV9pdGVyCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAg ICBhaW9fcnVuX2lvY2IKICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAg ICAgICAgIGRvX2lvX3N1Ym1pdAogICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAg IHwgICAgICAgICAgc3lzX2lvX3N1Ym1pdAogICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAg ICAgICAgIHwgICAgICAgICAgZW50cnlfU1lTQ0FMTF82NF9mYXN0cGF0aAogICAgICAgICAgICAg ICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgaW9fc3VibWl0CiAgICAgICAgICAg ICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICAweDQ2ZDk4YQogICAgICAgICAg ICAgICAgICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICAg ICAgICAgICAgIHwgICAgICAgICAgfC0tMC45OSUtLSBfX2ttYWxsb2Nfbm9kZV90cmFja19jYWxs ZXIKICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIF9fa21h bGxvY19yZXNlcnZlLmlzcmEuMzIKICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAg ICB8ICAgICAgICAgIF9fYWxsb2Nfc2tiCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAg ICAgICAgfCAgICAgICAgICBza19zdHJlYW1fYWxsb2Nfc2tiCiAgICAgICAgICAgICAgICAgICAg ICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICB0Y3Bfc2VuZG1zZwogICAgICAgICAgICAgICAg ICAgICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgaW5ldF9zZW5kbXNnCiAgICAgICAgICAg ICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICBzb2NrX3NlbmRtc2cKICAgICAg ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICB8ICAgICAgICAgIFNZU0Nfc2VuZHRvCiAg ICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICBzeXNfc2VuZHRv CiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgfCAgICAgICAgICBlbnRyeV9T WVNDQUxMXzY0X2Zhc3RwYXRoCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAg fCAgICAgICAgICBfX2xpYmNfc2VuZAogICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAg ICAgIHwgICAgICAgICAgX1pOMTJjb250aW51YXRpb25JWk42ZnV0dXJlSUptRUU0dGhlbklaTjdy ZWFjdG9yMTR3cml0ZV9hbGxfcGFydEVSMTdwb2xsYWJsZV9mZF9zdGF0ZVBLdm1tRVVsbUVfUzBf SUpFRUVFVDBfT1RfRVVsU0NfRV9KbUVFM3J1bkV2CiAgICAgICAgICAgICAgICAgICAgICAgICAg IHwgICAgICAgICAgfCAgICAgICAgICAweDdmNGFkNmJmOGRlMAogICAgICAgICAgICAgICAgICAg ICAgICAgICB8ICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAg IHwgICAgICAgICAgIC0tMC45OSUtLSB0YXNrX3dvcmtfcnVuCiAgICAgICAgICAgICAgICAgICAg ICAgICAgIHwgICAgICAgICAgICAgICAgICAgICBkb19ub3RpZnlfcmVzdW1lCiAgICAgICAgICAg ICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICBpbnRfc2lnbmFsCiAgICAgICAg ICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICBfX2xpYmNfY2xvc2UKICAg ICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgIHN0ZDo6ZXhwZXJp bWVudGFsOjpmdW5kYW1lbnRhbHNfdjE6OmJhZF9vcHRpb25hbF9hY2Nlc3M6On5iYWRfb3B0aW9u YWxfYWNjZXNzCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgCiAgICAgICAg ICAgICAgICAgICAgICAgICAgICAtLTAuOTglLS0gX19jb25kX3Jlc2NoZWRfc29mdGlycQogICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbGVhc2Vfc29jawogICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRjcF9zZW5kbXNnCiAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgaW5ldF9zZW5kbXNnCiAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgc29ja19zZW5kbXNnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgU1lTQ19zZW5kdG8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICBzeXNfc2VuZHRvCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW50cnlf U1lTQ0FMTF82NF9mYXN0cGF0aAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg IF9fbGliY19zZW5kCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX1pOMTJj b250aW51YXRpb25JWk42ZnV0dXJlSUptRUU0dGhlbklaTjdyZWFjdG9yMTR3cml0ZV9hbGxfcGFy dEVSMTdwb2xsYWJsZV9mZF9zdGF0ZVBLdm1tRVVsbUVfUzBfSUpFRUVFVDBfT1RfRVVsU0NfRV9K bUVFM3J1bkV2CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg3ZjRhZGEx ZjhkZTAKCgoKIwojIChGb3IgYSBoaWdoZXIgbGV2ZWwgb3ZlcnZpZXcsIHRyeTogcGVyZiByZXBv cnQgLS1zb3J0IGNvbW0sZHNvKQojCg== --001a11c261ac279d57052590c74d Content-Type: text/plain; charset=US-ASCII; name="example-stale.txt" Content-Disposition: attachment; filename="example-stale.txt" Content-Transfer-Encoding: base64 X-Attachment-Id: f_ihigxxjp1 WzE2NDgxNC44MzU5MzNdIENQVTogMjIgUElEOiA0ODA0MiBDb21tOiBzY3lsbGEgVGFpbnRlZDog RyAgICAgICAgICAgIEUgICA0LjIuNi0yMDAuZmMyMi54ODZfNjQgIzEKWzE2NDgxNC44MzU5MzZd IEhhcmR3YXJlIG5hbWU6IFhlbiBIVk0gZG9tVSwgQklPUyA0LjIuYW1hem9uIDA1LzA2LzIwMTUK WzE2NDgxNC44MzU5MzddICAwMDAwMDAwMDAwMDAwMDAwIDAwMDAwMDAwYTg3MTNiN2EgZmZmZjg4 MDJmYjk3N2FiOCBmZmZmZmZmZjgxNzcyOWVhClsxNjQ4MTQuODM1OTQxXSAgMDAwMDAwMDAwMDAw MDAwMCBmZmZmODgwNzZhNjlmNzgwIGZmZmY4ODAyZmI5NzdhZDggZmZmZmZmZmZhMDMyMTdhNgpb MTY0ODE0LjgzNTk0Nl0gIGZmZmY4ODA3NzExOWJjYjAgMDAwMDAwMDAwMDAwMDAwMCBmZmZmODgw MmZiOTc3YjA4IGZmZmZmZmZmYTAzNGU3NDkKWzE2NDgxNC44MzU5NTFdIENhbGwgVHJhY2U6Clsx NjQ4MTQuODM1OTU0XSAgWzxmZmZmZmZmZjgxNzcyOWVhPl0gZHVtcF9zdGFjaysweDQ1LzB4NTcK WzE2NDgxNC44MzU5NzFdICBbPGZmZmZmZmZmYTAzMjE3YTY+XSB4ZnNfYnVmX3N0YWxlKzB4MjYv MHg4MCBbeGZzXQpbMTY0ODE0LjgzNTk4OV0gIFs8ZmZmZmZmZmZhMDM0ZTc0OT5dIHhmc190cmFu c19iaW52YWwrMHg3OS8weDEwMCBbeGZzXQpbMTY0ODE0LjgzNjAwMV0gIFs8ZmZmZmZmZmZhMDJm NDc5Yj5dIHhmc19ibWFwX2J0cmVlX3RvX2V4dGVudHMrMHgxMmIvMHgxYTAgW3hmc10KWzE2NDgx NC44MzYwMTJdICBbPGZmZmZmZmZmYTAyZjg5Nzc+XSB4ZnNfYnVubWFwaSsweDk2Ny8weDlmMCBb eGZzXQpbMTY0ODE0LjgzNjAyN10gIFs8ZmZmZmZmZmZhMDMzNGI5ZT5dIHhmc19pdHJ1bmNhdGVf ZXh0ZW50cysweDEwZS8weDIyMCBbeGZzXQpbMTY0ODE0LjgzNjA0NF0gIFs8ZmZmZmZmZmZhMDMz Zjc1YT5dID8ga21lbV96b25lX2FsbG9jKzB4NWEvMHhlMCBbeGZzXQpbMTY0ODE0LjgzNjA4NF0g IFs8ZmZmZmZmZmZhMDMzNGQ0OT5dIHhmc19pbmFjdGl2ZV90cnVuY2F0ZSsweDk5LzB4MTEwIFt4 ZnNdClsxNjQ4MTQuODM2MTIwXSAgWzxmZmZmZmZmZmEwMzM1YWEyPl0geGZzX2luYWN0aXZlKzB4 MTAyLzB4MTIwIFt4ZnNdClsxNjQ4MTQuODM2MTM1XSAgWzxmZmZmZmZmZmEwMzNhNmNmPl0geGZz X2ZzX2V2aWN0X2lub2RlKzB4NmYvMHhhMCBbeGZzXQpbMTY0ODE0LjgzNjEzOF0gIFs8ZmZmZmZm ZmY4MTIzOGQ3Nj5dIGV2aWN0KzB4YTYvMHgxNzAKWzE2NDgxNC44MzYxNDBdICBbPGZmZmZmZmZm ODEyMzkwMjY+XSBpcHV0KzB4MTk2LzB4MjIwClsxNjQ4MTQuODM2MTQ3XSAgWzxmZmZmZmZmZjgx MjM0ZmU0Pl0gX19kZW50cnlfa2lsbCsweDE3NC8weDFjMApbMTY0ODE0LjgzNjE1MF0gIFs8ZmZm ZmZmZmY4MTIzNTE0Yj5dIGRwdXQrMHgxMWIvMHgyMDAKWzE2NDgxNC44MzYxNTVdICBbPGZmZmZm ZmZmODEyMWZlMDI+XSBfX2ZwdXQrMHgxNzIvMHgxZTAKWzE2NDgxNC44MzYxNThdICBbPGZmZmZm ZmZmODEyMWZlYmU+XSBfX19fZnB1dCsweGUvMHgxMApbMTY0ODE0LjgzNjE2MV0gIFs8ZmZmZmZm ZmY4MTBiYWI3NT5dIHRhc2tfd29ya19ydW4rMHg4NS8weGIwClsxNjQ4MTQuODM2MTY0XSAgWzxm ZmZmZmZmZjgxMDE0YTRkPl0gZG9fbm90aWZ5X3Jlc3VtZSsweDhkLzB4OTAKWzE2NDgxNC44MzYx NjddICBbPGZmZmZmZmZmODE3Nzk1YmM+XSBpbnRfc2lnbmFsKzB4MTIvMHgxNwo= --001a11c261ac279d57052590c74d-- From wonga.loanszza@gmail.com Sat Nov 28 11:02:50 2015 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 387F57F37 for ; Sat, 28 Nov 2015 11:02:49 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id C6EE5AC002 for ; Sat, 28 Nov 2015 09:02:45 -0800 (PST) X-ASG-Debug-ID: 1448730157-04bdf07f0a297fe0001-NocioJ Received: from gogw0414.mail.goo.jp (gogw0414.mail.goo.jp [153.153.65.15]) by cuda.sgi.com with ESMTP id pjjAz7Vk0P8NFcjE for ; Sat, 28 Nov 2015 09:02:37 -0800 (PST) X-Barracuda-Envelope-From: wonga.loanszza@gmail.com X-Barracuda-Apparent-Source-IP: 153.153.65.15 Received: from ntt.pod01.gv-mta-ucb001 (gv-mta-ucb001.mail.goo.jp [180.8.112.200]) by gogw0414.mail.goo.jp (Postfix) with ESMTP id EA4E5800100; Sun, 29 Nov 2015 02:02:18 +0900 (JST) Received: from gzcstore012.mail.goo.jp ([180.8.112.235]) by ntt.pod01.gv-mta-ucb001 with id n52J1r00154mytg0152Jk6; Sat, 28 Nov 2015 17:02:18 +0000 Date: Sun, 29 Nov 2015 02:02:18 +0900 (JST) From: "3.5% WONGA LOANS BUSINESS AND PERSONAL LOANS OFFER" Reply-To: "3.5% WONGA LOANS BUSINESS AND PERSONAL LOANS OFFER" Message-ID: <135439375.6177420.1448730138084.JavaMail.root@goo.jp> In-Reply-To: <545366783.6164130.1448721178160.JavaMail.root@goo.jp> Subject: 3.5% WONGA LOANS BUSINESS AND PERSONAL LOANS OFFER MIME-Version: 1.0 X-ASG-Orig-Subj: 3.5% WONGA LOANS BUSINESS AND PERSONAL LOANS OFFER Content-Type: multipart/mixed; boundary="----=_Part_6177416_1671826187.1448730138062" X-Originating-IP: [41.150.108.21] X-Barracuda-Connect: gogw0414.mail.goo.jp[153.153.65.15] X-Barracuda-Start-Time: 1448730157 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Barracuda-BRTS-Status: 1 X-Virus-Scanned: by bsmtpd at sgi.com 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 To: undisclosed-recipients:; ------=_Part_6177416_1671826187.1448730138062 Content-Type: text/plain; charset=ISO-2022-JP Content-Transfer-Encoding: 7bit To Whom It May Concern, Wonga Loan is proud to introduce our loan service to South Africa citizens, be the first to partake of our initial 3.5% loan promotion. Views attached details on our loans offer and also fill the Loan application form and send it on this email Id:wongaza.loans@fastservice.com We await your reply Amanda Smith Marketing Supervisor Contact Number: +27(0)616437092 Email:wongaza.loans@fastservice.com ------=_Part_6177416_1671826187.1448730138062 Content-Type: application/pdf; name="3.5% WONGA LOANS OFFER-1.pdf" Content-Disposition: attachment; filename="3.5% WONGA LOANS OFFER-1.pdf" Content-Transfer-Encoding: base64 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 jr9sev5UniB/2iG41Jb501h1glFhOYOPZ7AqKk+QP2x9BW19NVYdbpNZ4xm90SYL2PKKWh2Q1FbY c+zy6nY0jjasrmFHEwmMPUazyVo8i3HqeOXlBINyGJQXKyqkRe0AT2or7DmyrtBg+nhjYaHhgS9R O8BjCFbVXamtsOfIAzx9dpLhjQdk+uykxhJ8Skjb0aQ24gnj1PG+qGDUXL0vqrEE2RMojT1BETiM U8ewB1RXNSyicV8raWBPUFUDOA/a4lJqIhzj1OHosQRpSO0a0KO0lD1Dk6ovKrVl9iiHpux1qsEC vqhv1KBpLAH2GM0sS22ZPY1Th9s9FvjKVqkgKTdJi4FFUFaI5ajAUnJWSJcU0vgFvMuv3JJ4h22Z d8Z5NpulWYPNLqWHFrFEchJ70sslSOm9jLANn4lROGWMzyX+mH8KfHJU0Acr063dU4ZFTwRREjvo 6Ft6EyNsi0BGYhAJaqadHbPn2gTJLJO06asY7T/ZBpfze59ss6JXBQLrkXcBGJpyukevMCpRKaS2 evpNR4aefoNdVk+/6ekEnrIaT3lkC6NDT78ZxlOe4sLpeCX8sXr6TUeHnn6T6IxPv+npeIXO6uk3 HR16+k0aj1Xvq8gUTqeGZySv9SmHQNpq/jvJkorMRCkLb5Sr/wfUmvVHZW5kc3RyZWFtCmVuZG9i ago2IDAgb2JqCjU5NzEwCmVuZG9iago0IDAgb2JqCjw8L1R5cGUvUGFnZS9NZWRpYUJveCBbMCAw IDYxMiA3OTJdCi9Sb3RhdGUgMC9QYXJlbnQgMyAwIFIKL1Jlc291cmNlczw8L1Byb2NTZXRbL1BE RiAvSW1hZ2VDIC9UZXh0XQovRXh0R1N0YXRlIDM1IDAgUgovWE9iamVjdCAzNiAwIFIKL0ZvbnQg MzcgMCBSCj4+Ci9Db250ZW50cyA1IDAgUgo+PgplbmRvYmoKMyAwIG9iago8PCAvVHlwZSAvUGFn ZXMgL0tpZHMgWwo0IDAgUgpdIC9Db3VudCAxCj4+CmVuZG9iagoxIDAgb2JqCjw8L1R5cGUgL0Nh dGFsb2cgL1BhZ2VzIDMgMCBSCj4+CmVuZG9iago3IDAgb2JqCjw8L1R5cGUvRXh0R1N0YXRlCi9P UE0gMT4+ZW5kb2JqCjM1IDAgb2JqCjw8L1I3CjcgMCBSPj4KZW5kb2JqCjM2IDAgb2JqCjw8L1Iy MgoyMiAwIFIvUjIxCjIxIDAgUi9SMjAKMjAgMCBSL1IxOQoxOSAwIFIvUjE4CjE4IDAgUi9SMTcK MTcgMCBSL1IxNgoxNiAwIFIvUjE1CjE1IDAgUi9SMTQKMTQgMCBSL1IxMwoxMyAwIFIvUjEyCjEy IDAgUi9SMTEKMTEgMCBSL1IxMAoxMCAwIFIvUjkKOSAwIFIvUjgKOCAwIFI+PgplbmRvYmoKMjIg MCBvYmoKPDwvU3VidHlwZS9JbWFnZQovQ29sb3JTcGFjZS9EZXZpY2VSR0IKL1dpZHRoIDEzNTgK L0hlaWdodCAxCi9CaXRzUGVyQ29tcG9uZW50IDgKL0ZpbHRlci9GbGF0ZURlY29kZQovRGVjb2Rl UGFybXM8PC9QcmVkaWN0b3IgMTUKL0NvbHVtbnMgMTM1OAovQ29sb3JzIDM+Pi9MZW5ndGggMzI+ PnN0cmVhbQp4nO3BAREAAAQEMGpo+d0E1MNt68kWAAAA8MUB87ABQQplbmRzdHJlYW0KZW5kb2Jq CjIxIDAgb2JqCjw8L1N1YnR5cGUvSW1hZ2UKL0NvbG9yU3BhY2UvRGV2aWNlUkdCCi9XaWR0aCAx MzU4Ci9IZWlnaHQgMQovQml0c1BlckNvbXBvbmVudCA4Ci9GaWx0ZXIvRmxhdGVEZWNvZGUKL0Rl Y29kZVBhcm1zPDwvUHJlZGljdG9yIDE1Ci9Db2x1bW5zIDEzNTgKL0NvbG9ycyAzPj4vTGVuZ3Ro IDMyPj5zdHJlYW0KeJztwQERAAAEBDBqiPnRJNTDbevJFgAAAPDFAePJAUAKZW5kc3RyZWFtCmVu ZG9iagoyMCAwIG9iago8PC9TdWJ0eXBlL0ltYWdlCi9Db2xvclNwYWNlL0RldmljZVJHQgovV2lk dGggMTM1OAovSGVpZ2h0IDEKL0JpdHNQZXJDb21wb25lbnQgOAovRmlsdGVyL0ZsYXRlRGVjb2Rl Ci9EZWNvZGVQYXJtczw8L1ByZWRpY3RvciAxNQovQ29sdW1ucyAxMzU4Ci9Db2xvcnMgMz4+L0xl bmd0aCA4ND4+c3RyZWFtCnic7dDBCQAgDEPRdA3HdDQXVPCu9iAaSC49Bfr4UWoDOhDri9Ogz81+ kJ9l3l1UPX5n1ReVI9CqHEFB5QgKKkegVTmCgsoRFFSOQKvijTAALPhxXgplbmRzdHJlYW0KZW5k b2JqCjE5IDAgb2JqCjw8L1N1YnR5cGUvSW1hZ2UKL0NvbG9yU3BhY2UvRGV2aWNlUkdCCi9XaWR0 aCAxMzU4Ci9IZWlnaHQgMQovQml0c1BlckNvbXBvbmVudCA4Ci9GaWx0ZXIvRmxhdGVEZWNvZGUK L0RlY29kZVBhcm1zPDwvUHJlZGljdG9yIDE1Ci9Db2x1bW5zIDEzNTgKL0NvbG9ycyAzPj4vTGVu Z3RoIDg0Pj5zdHJlYW0KeJzt0LEJACAQQ9HoEC7qck4ngr16hWggaa4K3OOnUhvQgby+OA363OwH 8Vnk3UXV43dWfVE5Aq3KERRUjqCgcgRalSMoqBxBQeUItCreCANUsXFhCmVuZHN0cmVhbQplbmRv YmoKMTggMCBvYmoKPDwvU3VidHlwZS9JbWFnZQovQ29sb3JTcGFjZS9EZXZpY2VSR0IKL1dpZHRo IDEzNTgKL0hlaWdodCAxCi9CaXRzUGVyQ29tcG9uZW50IDgKL0ZpbHRlci9GbGF0ZURlY29kZQov RGVjb2RlUGFybXM8PC9QcmVkaWN0b3IgMTUKL0NvbHVtbnMgMTM1OAovQ29sb3JzIDM+Pi9MZW5n dGggMzI+PnN0cmVhbQp4nO3BAREAAAQEMFII+t3k08Nt68kWAAAA8MUBA6MBQgplbmRzdHJlYW0K ZW5kb2JqCjE3IDAgb2JqCjw8L1N1YnR5cGUvSW1hZ2UKL0NvbG9yU3BhY2UvRGV2aWNlUkdCCi9X aWR0aCAxMzU4Ci9IZWlnaHQgMQovQml0c1BlckNvbXBvbmVudCA4Ci9GaWx0ZXIvRmxhdGVEZWNv ZGUKL0RlY29kZVBhcm1zPDwvUHJlZGljdG9yIDE1Ci9Db2x1bW5zIDEzNTgKL0NvbG9ycyAzPj4v TGVuZ3RoIDMyPj5zdHJlYW0KeJztwQERAAAEBDCCCPnJVNTDbevJFgAAAPDFAdPmAT8KZW5kc3Ry ZWFtCmVuZG9iagoxNiAwIG9iago8PC9TdWJ0eXBlL0ltYWdlCi9Db2xvclNwYWNlL0RldmljZVJH QgovV2lkdGggMTM1OAovSGVpZ2h0IDEKL0JpdHNQZXJDb21wb25lbnQgOAovRmlsdGVyL0ZsYXRl RGVjb2RlCi9EZWNvZGVQYXJtczw8L1ByZWRpY3RvciAxNQovQ29sdW1ucyAxMzU4Ci9Db2xvcnMg Mz4+L0xlbmd0aCA4Nj4+c3RyZWFtCnic7dDBDQAgCENRcA+HdDQXFFlAwsEoSXvh1ISXr31M06XW TldE4oFf38SD/Czz7qLq8TuqvqgYoayKERBUjICgYoSyKkZAUDECgooRyqoqR9gvHVGqCmVuZHN0 cmVhbQplbmRvYmoKMTUgMCBvYmoKPDwvU3VidHlwZS9JbWFnZQovQ29sb3JTcGFjZS9EZXZpY2VS R0IKL1dpZHRoIDEzNTgKL0hlaWdodCAxCi9CaXRzUGVyQ29tcG9uZW50IDgKL0ZpbHRlci9GbGF0 ZURlY29kZQovRGVjb2RlUGFybXM8PC9QcmVkaWN0b3IgMTUKL0NvbHVtbnMgMTM1OAovQ29sb3Jz IDM+Pi9MZW5ndGggODI+PnN0cmVhbQp4nO3QwQkAIAwEwaQJG7U6q9NUEH2IBm7J9yDDeutjenZm lg/iYrObnM5O3l1UPX6H6ouKCGVVRFBQEUFBRYSyKiIoqIigoCJCWVXlCAtmwVGtCmVuZHN0cmVh bQplbmRvYmoKMTQgMCBvYmoKPDwvU3VidHlwZS9JbWFnZQovQ29sb3JTcGFjZS9EZXZpY2VSR0IK L1dpZHRoIDEzNTgKL0hlaWdodCAxCi9CaXRzUGVyQ29tcG9uZW50IDgKL0ZpbHRlci9GbGF0ZURl Y29kZQovRGVjb2RlUGFybXM8PC9QcmVkaWN0b3IgMTUKL0NvbHVtbnMgMTM1OAovQ29sb3JzIDM+ Pi9MZW5ndGggODQ+PnN0cmVhbQp4nO3QMQoAIAxD0fQSXtTTeTrd3IodRAPJ0qWFPn60PiYQQDaR r/bE6aB+Vnl3UfX4nVVfVI5Aq3IEBZUjKKgcgVblCAoqR1BQOQKtijnCAkzccWIKZW5kc3RyZWFt CmVuZG9iagoxMyAwIG9iago8PC9TdWJ0eXBlL0ltYWdlCi9Db2xvclNwYWNlL0RldmljZVJHQgov V2lkdGggMTM1OAovSGVpZ2h0IDEKL0JpdHNQZXJDb21wb25lbnQgOAovRmlsdGVyL0ZsYXRlRGVj b2RlCi9EZWNvZGVQYXJtczw8L1ByZWRpY3RvciAxNQovQ29sdW1ucyAxMzU4Ci9Db2xvcnMgMz4+ L0xlbmd0aCA4ND4+c3RyZWFtCnic7dAxCgAgDEPR9B4e0qN5Q93cih1EA8nSpYU+frQ+JhBANpGv 9sTpoH5WeXdR9fidVV9UjkCrcgQFlSMoqByBVuUICipHUFA5Aq2KOcIC7WZxXAplbmRzdHJlYW0K ZW5kb2JqCjEyIDAgb2JqCjw8L1N1YnR5cGUvSW1hZ2UKL0NvbG9yU3BhY2UvRGV2aWNlUkdCCi9X aWR0aCAxMzU4Ci9IZWlnaHQgMQovQml0c1BlckNvbXBvbmVudCA4Ci9GaWx0ZXIvRmxhdGVEZWNv ZGUKL0RlY29kZVBhcm1zPDwvUHJlZGljdG9yIDE1Ci9Db2x1bW5zIDEzNTgKL0NvbG9ycyAzPj4v TGVuZ3RoIDMyPj5zdHJlYW0KeJztwQERAAAEBDCqiPjFVNTDbevJFgAAAPDFATNwAUUKZW5kc3Ry ZWFtCmVuZG9iagoxMSAwIG9iago8PC9TdWJ0eXBlL0ltYWdlCi9Db2xvclNwYWNlL0RldmljZVJH QgovV2lkdGggMTM1OAovSGVpZ2h0IDEKL0JpdHNQZXJDb21wb25lbnQgOAovRmlsdGVyL0ZsYXRl RGVjb2RlCi9EZWNvZGVQYXJtczw8L1ByZWRpY3RvciAxNQovQ29sdW1ucyAxMzU4Ci9Db2xvcnMg Mz4+L0xlbmd0aCAzMj4+c3RyZWFtCnic7cEBEQAABAQwmkj4yYTUw23ryRYAAADwxQGkMQE8CmVu ZHN0cmVhbQplbmRvYmoKMTAgMCBvYmoKPDwvU3VidHlwZS9JbWFnZQovQ29sb3JTcGFjZS9EZXZp Y2VSR0IKL1dpZHRoIDEzNTgKL0hlaWdodCAxCi9CaXRzUGVyQ29tcG9uZW50IDgKL0ZpbHRlci9G bGF0ZURlY29kZQovRGVjb2RlUGFybXM8PC9QcmVkaWN0b3IgMTUKL0NvbHVtbnMgMTM1OAovQ29s b3JzIDM+Pi9MZW5ndGggMzI+PnN0cmVhbQp4nO3BAREAAAQEMKKo+NUU1MNt68kWAAAA8MUBYyYB SAplbmRzdHJlYW0KZW5kb2JqCjkgMCBvYmoKPDwvU3VidHlwZS9JbWFnZQovQ29sb3JTcGFjZS9E ZXZpY2VSR0IKL1dpZHRoIDEzNTgKL0hlaWdodCAxCi9CaXRzUGVyQ29tcG9uZW50IDgKL0ZpbHRl ci9GbGF0ZURlY29kZQovRGVjb2RlUGFybXM8PC9QcmVkaWN0b3IgMTUKL0NvbHVtbnMgMTM1OAov Q29sb3JzIDM+Pi9MZW5ndGggMzI+PnN0cmVhbQp4nO3BAREAAAQEMELo+e3U08Nt68kWAAAA8MUB w+0BPgplbmRzdHJlYW0KZW5kb2JqCjggMCBvYmoKPDwvU3VidHlwZS9JbWFnZQovQ29sb3JTcGFj ZS9EZXZpY2VSR0IKL1dpZHRoIDEzNTgKL0hlaWdodCAxCi9CaXRzUGVyQ29tcG9uZW50IDgKL0Zp bHRlci9GbGF0ZURlY29kZQovRGVjb2RlUGFybXM8PC9QcmVkaWN0b3IgMTUKL0NvbHVtbnMgMTM1 OAovQ29sb3JzIDM+Pi9MZW5ndGggODE+PnN0cmVhbQp4nO3QMQ4AIAgEweP/b/UN2NkZKYyS3DY0 kDDZGJkphbSb2q/W1OmgflZ5d1H1+B2qLyoitFURwUFFBAcVEdqqiOCgIoKDightVZ0jTLjEcwsK ZW5kc3RyZWFtCmVuZG9iagozNyAwIG9iago8PC9SMzMKMzMgMCBSL1IyMwoyMyAwIFIvUjI1CjI1 IDAgUi9SMjcKMjcgMCBSL1IyOQoyOSAwIFIvUjMxCjMxIDAgUj4+CmVuZG9iagozMyAwIG9iago8 PC9CYXNlRm9udC9HTVRYU1UrQW5kYWx1cy9Gb250RGVzY3JpcHRvciAzNCAwIFIvVHlwZS9Gb250 Ci9GaXJzdENoYXIgMS9MYXN0Q2hhciAyNC9XaWR0aHNbIDMxMyAzMTMgNzI5IDU0MiAyNDQgNjE1 IDQ5MCA1NTIgMjkyIDQ2OSA0NDggNTUyIDM2NSA0NjIgNTUyCjU1MiAzMTkgNTUyIDMxOSA1NTIg NTUyIDU1MiA1NTIgNTUyXQovRW5jb2RpbmcgNDQgMCBSL1N1YnR5cGUvVHJ1ZVR5cGU+PgplbmRv YmoKNDQgMCBvYmoKPDwvVHlwZS9FbmNvZGluZy9CYXNlRW5jb2RpbmcvV2luQW5zaUVuY29kaW5n L0RpZmZlcmVuY2VzWwoxL2JyYWNrZXRsZWZ0L2JyYWNrZXRyaWdodC9PL1Ivc3BhY2UvQy9vL24v dC9hL2MvdS9zL3BsdXMvdHdvL3NldmVuCi9wYXJlbmxlZnQvemVyby9wYXJlbnJpZ2h0L3NpeC9v bmUvZWlnaHQvZm91ci9uaW5lXT4+CmVuZG9iagoyMyAwIG9iago8PC9CYXNlRm9udC9DQ0ZHTE8r VGltZXMtUm9tYW4vRm9udERlc2NyaXB0b3IgMjQgMCBSL1R5cGUvRm9udAovRmlyc3RDaGFyIDMy L0xhc3RDaGFyIDEyMi9XaWR0aHNbCjI1MCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMjUwIDAgMjUw IDAKNTAwIDUwMCA1MDAgNTAwIDUwMCA1MDAgNTAwIDUwMCA1MDAgNTAwIDAgMCAwIDAgMCA0NDQK OTIxIDcyMiA2NjcgNjY3IDcyMiAwIDAgMCA3MjIgMzMzIDAgMCA2MTEgMCAwIDcyMgowIDAgNjY3 IDAgNjExIDAgMCA5NDQgMCAwIDAgMCAwIDAgMCAwCjAgNDQ0IDUwMCA0NDQgNTAwIDQ0NCAzMzMg NTAwIDUwMCAyNzggMCA1MDAgMjc4IDc3OCA1MDAgNTAwCjUwMCAwIDMzMyAzODkgMjc4IDUwMCA1 MDAgNzIyIDAgNTAwIDQ0NF0KL0VuY29kaW5nL1dpbkFuc2lFbmNvZGluZy9TdWJ0eXBlL1R5cGUx Pj4KZW5kb2JqCjI1IDAgb2JqCjw8L0Jhc2VGb250L1BQTU1DTCtGcmVlc2lhVVBDL0ZvbnREZXNj cmlwdG9yIDI2IDAgUi9UeXBlL0ZvbnQKL0ZpcnN0Q2hhciAxL0xhc3RDaGFyIDQzL1dpZHRoc1sg MzE0IDE1NyAzNTQgMjg4IDE1NyAzNTQgMjAyIDIyMiAzNDEgMzU0IDM1NCAyMTAgMjEwIDUzOCAz NTQKMzU0IDMyOCAyODggMjc2IDM1NCAxOTcgMzE0IDUzOCA0MDcgMzY3IDMxOCAzNjcgMzE4IDQw NyAzNTQgNDMzCjE3MyA0NDAgNDQwIDQ0MCAzNTAgNDQwIDQ0MCA0NDAgNDQwIDM1NCA0MDcgNDQw XQovRW5jb2RpbmcgNDUgMCBSL1N1YnR5cGUvVHJ1ZVR5cGU+PgplbmRvYmoKNDUgMCBvYmoKPDwv VHlwZS9FbmNvZGluZy9CYXNlRW5jb2RpbmcvV2luQW5zaUVuY29kaW5nL0RpZmZlcmVuY2VzWwox L0YvbC9lL3gvaS9iL2NvbW1hL3NwYWNlL3MvaC9vL3IvdC9tL2EvbgovZy92L3kvdS9mL2MvVy9T L0EvcGFyZW5sZWZ0L1AvcGFyZW5yaWdodC9DL3AvTi9wZXJpb2QKL3R3by96ZXJvL29uZS9zbGFz aC9maXZlL3NpeC9uaW5lL3NldmVuL2QvUi90aHJlZV0+PgplbmRvYmoKMjcgMCBvYmoKPDwvQmFz ZUZvbnQvV0VBUVRaK1RpbWVzLUJvbGQvRm9udERlc2NyaXB0b3IgMjggMCBSL1R5cGUvRm9udAov Rmlyc3RDaGFyIDMyL0xhc3RDaGFyIDEyMS9XaWR0aHNbCjI1MCAwIDAgMCAwIDEwMDAgMCAwIDMz MyAzMzMgMCAwIDI1MCAwIDI1MCAwCjUwMCA1MDAgNTAwIDUwMCA1MDAgNTAwIDUwMCAwIDUwMCAw IDAgMCAwIDAgMCAwCjkzMCA3MjIgNjY3IDcyMiA3MjIgNjY3IDYxMSAwIDAgMCAwIDAgNjY3IDk0 NCA3MjIgNzc4CjYxMSAwIDcyMiA1NTYgNjY3IDcyMiA3MjIgMCAwIDAgMCAwIDAgMCAwIDAKMCA1 MDAgNTU2IDAgNTU2IDQ0NCAwIDAgNTU2IDI3OCAwIDAgMjc4IDgzMyA1NTYgNTAwCjU1NiAwIDQ0 NCAzODkgMzMzIDU1NiAwIDAgNTAwIDUwMF0KL0VuY29kaW5nL1dpbkFuc2lFbmNvZGluZy9TdWJ0 eXBlL1R5cGUxPj4KZW5kb2JqCjI5IDAgb2JqCjw8L0Jhc2VGb250L09BTktPUitUaW1lcy1Cb2xk SXRhbGljL0ZvbnREZXNjcmlwdG9yIDMwIDAgUi9UeXBlL0ZvbnQKL0ZpcnN0Q2hhciAzMi9MYXN0 Q2hhciAxNTAvV2lkdGhzWwoyNTAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCAwIDAg MCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMAowIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAw CjAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAKMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAg MCAwIDAgMAowIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwCjAgMCAwIDAgMCAwIDAgMCAw IDAgMCAwIDAgMCAwIDAKMCAwIDAgMCAwIDAgNTAwXQovRW5jb2RpbmcvV2luQW5zaUVuY29kaW5n L1N1YnR5cGUvVHlwZTE+PgplbmRvYmoKMzEgMCBvYmoKPDwvQmFzZUZvbnQvVkdCV0VWK0ZyYW5r bGluR290aGljTWVkaXVtL0ZvbnREZXNjcmlwdG9yIDMyIDAgUi9UeXBlL0ZvbnQKL0ZpcnN0Q2hh ciAxL0xhc3RDaGFyIDQyL1dpZHRoc1sgNTQzIDUyOSA1NDAgMzMyIDI1MCA1MDggMjQ1IDY1MCA1 NDEgODcwIDUyNCA1ODYgNTcxIDU0MiAyNjcKNjU1IDUzOSA1NzkgNTM3IDI0NSA2MDMgNTM5IDQ1 NCAzMjIgNDQyIDI0MSAyNDEgMzE2IDQ0MSA1ODYgNTg2CjU4NiAyOTMgNTg2IDI5MyA1ODYgNTg2 IDU4NiA1ODYgNTg2IDU4NiA0ODNdCi9FbmNvZGluZyA0NiAwIFIvU3VidHlwZS9UcnVlVHlwZT4+ CmVuZG9iago0NiAwIG9iago8PC9UeXBlL0VuY29kaW5nL0Jhc2VFbmNvZGluZy9XaW5BbnNpRW5j b2RpbmcvRGlmZmVyZW5jZXNbCjEvWS9vL3Uvci9zcGFjZS9GL2wvTi9hL20vZS9hc3Rlcmlzay9T L24vSS9ECi9iL0MvRS9pL0EvZC9zL3QveS9jb2xvbi9jb21tYS9mL3gvcGx1cy90d28vc2V2ZW4K L3BhcmVubGVmdC96ZXJvL3BhcmVucmlnaHQvZWlnaHQvc2l4L2ZpdmUvZm91ci9vbmUvbmluZS9U XT4+CmVuZG9iagozNCAwIG9iago8PC9UeXBlL0ZvbnREZXNjcmlwdG9yL0ZvbnROYW1lL0dNVFhT VStBbmRhbHVzL0ZvbnRCQm94WzAgLTI4MSA2OTIgNzUzXS9GbGFncyAxMzEwNzYKL0FzY2VudCA3 NTMKL0NhcEhlaWdodCA3MDEKL0Rlc2NlbnQgLTI4MQovSXRhbGljQW5nbGUgMAovU3RlbVYgMTAz Ci9NaXNzaW5nV2lkdGggNTAwCi9YSGVpZ2h0IDUyNAovRm9udEZpbGUyIDM4IDAgUj4+CmVuZG9i agozOCAwIG9iago8PC9GaWx0ZXIvRmxhdGVEZWNvZGUKL0xlbmd0aDEgODkxMi9MZW5ndGggNTYy Nz4+c3RyZWFtCnic7TlrVBvXmffemZEEktAIPRAI0IjhZWQQRjyMjWEMkozB4S0QBtkIhA0m2BAw fsc4sRMb7NhJ7MSOk8Zx3DycbCKSNMVp47gtdU9bu8kmTtp069SnzXG7SUncNulu0zDsN5Jw7Wya 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 uPmKS7IF8+GeieDzr6zWlHyKTGHjPfMgF3rzvOLje0Xx88cUryt+CmhUyD/g+i+6sfrmCmVuZHN0 cmVhbQplbmRvYmoKMjQgMCBvYmoKPDwvVHlwZS9Gb250RGVzY3JpcHRvci9Gb250TmFtZS9DQ0ZH TE8rVGltZXMtUm9tYW4vRm9udEJCb3hbMCAtMjE4IDkzMiA2ODhdL0ZsYWdzIDM0Ci9Bc2NlbnQg Njg4Ci9DYXBIZWlnaHQgNjc2Ci9EZXNjZW50IC0yMTgKL0l0YWxpY0FuZ2xlIDAKL1N0ZW1WIDEx MQovTWlzc2luZ1dpZHRoIDI1MAovWEhlaWdodCA0NjAKL0NoYXJTZXQoL0EvQi9DL0QvSC9JL0wv Ty9SL1QvVy9hL2F0L2IvYy9jb21tYS9kL2UvZWlnaHQvZi9maXZlL2ZvdXIvZy9oL2kvay9sL20v bi9uaW5lL28vb25lL3AvcGVyaW9kL3F1ZXN0aW9uL3Ivcy9zZXZlbi9zaXgvc3BhY2UvdC90aHJl ZS90d28vdS92L3cveS96L3plcm8pL0ZvbnRGaWxlMyAzOSAwIFI+PgplbmRvYmoKMzkgMCBvYmoK PDwvRmlsdGVyL0ZsYXRlRGVjb2RlCi9TdWJ0eXBlL1R5cGUxQy9MZW5ndGggNTM0NT4+c3RyZWFt CnicbVhpVFNXuz4xJOc4oSWmEmwTOreOaLVCrSPgiAPIjIgoASIkYSaEJCSBMG0IkBCGAGGSeZ4H wRHHWucB7YC29qu1o/2+233o5t51d+i69/6431qsLMjZ+z3v+DzPC4OwmUMwGIwF3iKxMH6Vl1Qc KrH+vZJexqDfmEO/yQRI8pfztBvrTcKjirkQLGCCBTY1b7w+aEcffg3+vgiOLyaYDEbP51+7SmNS 4kQRkQmOH/p4+X20YsXK//tmrYuLi+PxlP954ugmjBdFSBzfx78kCaOlMWKhJGGToys+HR0tOuEY EZ0SExnvGBoWJgyzXvMNjRZGOe4URYtiYqRJjh+6fuS4zslp7Sr8sW6T44FEsTBOutJRJAkXSUQJ KY6hkjDHg2JhRKijODRMaDXgJhYlxKU4rncSSf739gGR+HhivONsyI4HpC6OHo5ewojE6NC4//+E IIi12yU7pK4xbnHxCbsT9yQlhx73SDkhDxMeDI+I9BJ5R0WL/T5x3OjssnXbytVOa9d9vH4DQbxN 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 MyYthW9yVYXhXirtUcBD6Wz4GXR7/qL3EXjM++3TyXe8/RJPhPOjRIoouVtNpn3fL11ttwE1NeG1 cXPw6o3rBGgn8mSl0Q5Wq/TMFTt474nw3lLOObgKfsO9DOpy6rUUp+ZaYq/XToeNXnu3xyQb6sP5 4iq5waqeFcqkyMHEO5NPGvpHBaP9DZfATXAmdVTSmlwrKw2xUJxzt0dPdZ93+GrfxTUBIfKoCL44 RhGbeNCcZd9/f7j9OqBuDId4RCgi4uIEYrFUsSt+lqtq4Puf05urGXAEa+9omMp9j/YMYaObM56s fbADbZqEm16RaPfnXJTBhhnwJytm0F8+YcDpO0y4h/6SC/3ZFaAgX2/oeW6vNSiSNJlJODlCNmIg DdbIuSCHl1mQbWzry1D18yEZfm4/+JBacWDb5mS5oVbMj6pLMOEdSqJMixOOxj+cutd4ZlwwMlwz AR6Be7KRgPGQIa86NK+Gsk2upn2roXc1u2Xe0/ktxgULnlYtWEgQ/w262fe8CmVuZHN0cmVhbQpl bmRvYmoKMjYgMCBvYmoKPDwvVHlwZS9Gb250RGVzY3JpcHRvci9Gb250TmFtZS9QUE1NQ0wrRnJl ZXNpYVVQQy9Gb250QkJveFswIC0xNzcgNjI1IDYyNV0vRmxhZ3MgNAovQXNjZW50IDYyNQovQ2Fw SGVpZ2h0IDQ1NgovRGVzY2VudCAtMTc3Ci9JdGFsaWNBbmdsZSAwCi9TdGVtViA5MwovTWlzc2lu Z1dpZHRoIDc1MAovWEhlaWdodCAzODUKL0ZvbnRGaWxlMiA0MCAwIFI+PgplbmRvYmoKNDAgMCBv YmoKPDwvRmlsdGVyL0ZsYXRlRGVjb2RlCi9MZW5ndGgxIDg0OTIvTGVuZ3RoIDU5MDc+PnN0cmVh bQp4nO1ZeXxTVfa/574tL03TJM3SvUmTNE3bUGi6WNbQQgVkB2tBQVqgbJaCiFARWcpSQQQFFWWR QUTEogWRqQxLAasDwkh0qnQQZtSpDG6D/LTD0tz+znsp6DjLb/7+fSa39y03ue9+z/Y95/YRIIRE ksWEI8OHjcrKJuonWYOHkomVZbPC94n3EQLrJj78kH3vqtd+jQOf4n33illTKqnxeBkhNAbvz015 oLoi/Hsef29Nmzq5bNKH85Z3JcT+Aw7mTcWBSND6CeGu4L1rauVD8zvXm4DzH3qgamJZ+D5uGT7z 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 Qq50/N1A51s1nfr6LNy5NeTfdsEGJsFGWm91rgdQpdMm0iS8QBokLTkmaeEEdht2U2fHa3IZz55w V67/dRf+SBKVLtaQqltdEMmFf9fF78Id59UpHee0/Hy+0jWbSeJ/0oXdZD32XfjcsXiuwF7OeUis 0Ic48PoQrSHBn/UWnNOA40qfjj2odO4+cgzrmel41ijf8ZuJrrOb+eloGe7/sJ1iG4Gu3Vv/xsH7 o3r+SCIM6nBd79XfKudjE7dtu669UaDbpb+At7LqL/j5X7Sxa24KZW5kc3RyZWFtCmVuZG9iagoy OCAwIG9iago8PC9UeXBlL0ZvbnREZXNjcmlwdG9yL0ZvbnROYW1lL1dFQVFUWitUaW1lcy1Cb2xk L0ZvbnRCQm94WzAgLTIwNSA5MjEgNjk0XS9GbGFncyAzMgovQXNjZW50IDY5NAovQ2FwSGVpZ2h0 IDY5MgovRGVzY2VudCAtMjA1Ci9JdGFsaWNBbmdsZSAwCi9TdGVtViAxMzgKL01pc3NpbmdXaWR0 aCAyNTAKL1hIZWlnaHQgNDczCi9DaGFyU2V0KC9BL0IvQy9EL0UvRi9ML00vTi9PL1AvUi9TL1Qv VS9WL2EvYXQvYi9jb21tYS9kL2UvZWlnaHQvZml2ZS9mb3VyL2gvaS9sL20vbi9vL29uZS9wL3Bh cmVubGVmdC9wYXJlbnJpZ2h0L3BlcmNlbnQvcGVyaW9kL3Ivcy9zaXgvc3BhY2UvdC90aHJlZS90 d28vdS94L3kvemVybykvRm9udEZpbGUzIDQxIDAgUj4+CmVuZG9iago0MSAwIG9iago8PC9GaWx0 ZXIvRmxhdGVEZWNvZGUKL1N1YnR5cGUvVHlwZTFDL0xlbmd0aCA0OTY1Pj5zdHJlYW0KeJydV3lY U2e6PxHJOQqikp4B1Ca0I4jjbt2odV9aFxCRqqhhD2tCQsIStrAL+LGFfZMACaAxIJssKoJri7ZW 69aZbqPXUTvaaWfsnfdkPu5z73dweuc+9/53H54nBPKenPO+72/7BNTUKZRAILDzi1LINEu2KuVh /J+LubkCbt4U7m0bhIP/scS62/Ztau9J2xnI3gbZT22dx446cuxs6J8J2bMoG4FAqzduU6qS1VER kfGuHh/7Hlq4aNHif/1nhaenp2tI8q+fuG6XaaIiYl3dyZtEmVypUshi49e7biPVcnlUqGuEPFkV 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 5Oax2X++3+SAmmEm2HAryJAM4GbDLYcKltuxnvbZiN/C63ct27fYhahdEZ4PbjD/JtjQOOQ3WCYE GYzYkstzwINbAiIByeTDLJiFAyCyxQ+Fv8M//jm3P28w3eWpcswX7WIOBAYeiFfVnA4VB51R1MYR VMWpIw9ej3xKBG/aT/DO6z1fY4FZIquWl3qWMQ5JBi7YAIcMQst0cLWzWOztwbXVfgZF/ReUD4m0 CmVuZHN0cmVhbQplbmRvYmoKMzAgMCBvYmoKPDwvVHlwZS9Gb250RGVzY3JpcHRvci9Gb250TmFt ZS9PQU5LT1IrVGltZXMtQm9sZEl0YWxpYy9Gb250QkJveFstNDAgMCA0NjAgMjY5XS9GbGFncyA2 NTU2OAovQXNjZW50IDI2OQovQ2FwSGVpZ2h0IDI2OQovRGVzY2VudCAwCi9JdGFsaWNBbmdsZSAw Ci9TdGVtViA2OQovTWlzc2luZ1dpZHRoIDI1MAovQ2hhclNldCgvZW5kYXNoL3NwYWNlKS9Gb250 RmlsZTMgNDIgMCBSPj4KZW5kb2JqCjQyIDAgb2JqCjw8L0ZpbHRlci9GbGF0ZURlY29kZQovU3Vi dHlwZS9UeXBlMUMvTGVuZ3RoIDI3OD4+c3RyZWFtCnicY2RgYWJgZGQUDMnMTS3WdcrPSfEsSczJ TAYJav2QZvwhw/RDljm5+0fC94Wssgw+c7l5u3mYu3lY5n7fIfR9muD3ifzfewUYmBkZK2ascs4v qCzKTM8oUdAIDQrX1NbWQYgYWlpaKiRVwmQUXFKLM9PzFNSAjLLUnPyC3NS8EmsFZ6DqHKD1Cuk5 lQUZxQqJKSmpKSBtYYk5qdkKbpk5mQUF+WUKGs6aCkYGBoa6QMLILzM3qbRYISg/NzFPwS/fUsFH wTc1JbM0VwHiF0x5BgYGJoVpDAyMDPkgp7Owy3zv4wOiHx3f3Z4x/ij8vlD0TwdblQHrjw42vvL5 P0Lnf4+Zz7aM6zsP97KJPDwMDACepmamCmVuZHN0cmVhbQplbmRvYmoKMzIgMCBvYmoKPDwvVHlw ZS9Gb250RGVzY3JpcHRvci9Gb250TmFtZS9WR0JXRVYrRnJhbmtsaW5Hb3RoaWNNZWRpdW0vRm9u dEJCb3hbLTEyIC0xNzcgODc1IDc1MF0vRmxhZ3MgNAovQXNjZW50IDc1MAovQ2FwSGVpZ2h0IDY3 NgovRGVzY2VudCAtMTc3Ci9JdGFsaWNBbmdsZSAwCi9TdGVtViAxMzEKL01pc3NpbmdXaWR0aCAx MDAwCi9YSGVpZ2h0IDUwNwovRm9udEZpbGUyIDQzIDAgUj4+CmVuZG9iago0MyAwIG9iago8PC9G aWx0ZXIvRmxhdGVEZWNvZGUKL0xlbmd0aDEgMTMwNjAvTGVuZ3RoIDg1ODU+PnN0cmVhbQp4nO16 eXwUVdboPbe2ruqtqvekk3Q3TRJIAw1pEgLipAdIFDNqVAIJ0JAIgQQIJJig4hdBMIQERkCMGBmX ccRxe9qgQhicgVHcPj7UEcftG5fxi44LEURxg1TeudWJ4sy8mXn/vN/v/X5Tt8+tu1Xdc89+KiFA CLGStYQj5ZdeEc0nxjX2PaxmLmioaUz1oyMIgZsWrGoOxj4vHIUDf8L+nkWNixtqItVLCaFbCREn Ll527aLUevO9hGSV19XWLHy15LxZhOT/Fw4W1uGAbZ6phhAT6w+va2i+JrV+XBG+r3nZigU1qf7I LwkRxjfUXNPI/4WvxPUncTC4vKahdhC/HqxGNK64qjnVz3+YzTeurG18Zv/dpwiRVcTpFmEmcZEK o6406h9d3Bc4ch0hA8cH7v+hJkR/iNVCBWvhvZZYOG7gS3zeQocNfMnFiAXXfUkWkH/hMg3CP72e J73kKwR2/Y4cQ/jxtZFcSJSBawZ6Br4it5JLiDCwZGDPwBk4TYcxSgy8QUYPHPthOShYfTXY+Ryh d7D9HQNIO2dfQthz+8k2o73f6H/zr6D8o+sJlIgvyWGyTq8ma2AOeZzcRf5M3iKPknV4lgH4lKwg uyAbRpEyshMy8QzlpJ1swXXPk7vx6SfJNeQh0kZIfOKMsqIJhQXjY/njxkbHjB41ckRuTvbw8LBQ MJCVmeFPT/N5PW6X06GpdpvVYlZkkyQKPEeBjIKkb2plyZJk2tTqZGl4WlgNJksvOXlxNEkc/lBY i1WNTi1JCpEkcSbrVyVJdDeJFyXFyI/mL0ly2eqpED528dB4Mn1qZSjkT9Js/E3HefxdVBNcmFTL cRwnSHkl8qYoqRT5EVizqoq979wNF7MNkcIDh87d8hLoVHeXpk2dliSu3aT0/SRxszUni0iSTE6O iOCGKrbwXT58PAmuU0lwJsF9MeL3dw7EGn91npKFS8IlC+uRLgurf6DMyRRdhhbuNitTw1NrldGj yG7FjE0ztnBx424o/QkYDVpaMmk3JSYr0sPB8CphsCQZ31SNjfA0JATOOH+Y6Rk4tPncKYKPDbWc qRYkxalJydg3WJ+M1yTJpuDuUYc6N/eo5MrqiGVheGHN3MokV4M47iZcdkndDOzh+xGq64JJHl9u VH4cCZbUBTuxz5ZVYx2exlj398ZxWJ5a2R465E868F6S1CLJC3DFBat7/Vxnia8+yLqdne3B5N2X VZ47G2I18taHCHeWhPGF+LKSJVMYf6JD/OCz8Td9IaN6TTC59solKcGp2Twkm6FONVn6VQjJHwoZ bBok2cLqJQzLJTXsZCVLgp2bao3TbTawNghWUhcuqa/5Z6s6O0vY9jULp6TePjUZn2HcyIzZlQZJ kNjTqgaHBhfMZpizmeppVaEUe8our5zKEAvXTPOnUP1+pHpwBAdKhiaDDIPp+IJkcEEwSS6vDOPS IlbVFpHOBUXGgUNVgE+V//BUUshWw8HO0yQJ1eG+4z8eqRkcEbPV04Q1S8Ol1Z2dpeFgaWd1Z03P wNorw0E13Lm7rKyzsaQ6yFQRn+oZ+M0mf7J0c1VSra6DScgtJjOll1cW+0Na1VC3fKhLUAhRFFHo O1XcIxRikrepJ06uxE5y7WWVqX6QXOnfQ+LRCFKums0cGppxV7CZtUMz3z9eHUYyPk6Ym3UnTTnf /+yqx1lSNykJnn8wXZuaTzqnVnJ+WpVqUT/HWkoE1Xhy0hvBNs3uQYOBxqITqfZyOKlGksLUykP+ yVVBVUM1Z/S+Ilx22ezKIv/3Aqe+HH4BmC0hLjUJk42dgJkPQMqgjfMW4SR7+dQZlec+PSS0aAqm 7A7Dxst2x2HjFbMr96PTDW6cUbmHAp1aPaVq93Ccq9wfRKNujNLvR1kvyHqkjInTHmoypvz744Ss NWZ5Y8DoL+gBYoyZhsaALOihqTHVGGOm1nB7hEgV+lT0uQP6BXqb6aBB13OvBBuh3eQUmcy8KKFE JVkEfT3cOzCAMRDEB2akXeVZdbXHm7Hqaq9/1dVpDY3Ybmj0+hsa05atwPayFV7/shVpS5d7/EuX r1mZ3lJvDTQvQmhxuTOaW9z+5pa0xUuwvXiJ2794Sdqiemwvqnf7F9Wn1da5/LV1bU3pq6emha5F yH9p/7v7T+zn9nelBXq2nxd4dW9O4NUnng880VUeyL+1a3jgFzuzAzvnFga6EXYkCgNdCNvnNgS2 IRw74AvIr8DhNecF9iHsbSsIbN7kDWyaNTvQgdBeaQq0Va4IrEe4AftrEFoRFtSYAlci5CfmTAzM nZMWqJw5MTALoabCFIj/vBrr/DkV9sBMhDGgBfwT3L5Ct7vA7Rjvtsfclny3PM4tjnVzUTcZ4x41 2p4XsY0Yac/JtQ3Ptg8L24Ihe1bA5s/ItPrS0q1uj9fqcLqsdlWzWKw2i6yYLaJksnC8YCFALVEC dhLF+OAlwvvPMwXsk0wBbqIpQIpMgfIYJB1lpGzGlKQT8H7FlGQsUtYDWy9P5kfKknL5nMrdADdV 4WiSbkRBmZHkN6JszECrPntOZQ+ksek2w8jvJwBr237uH7xXVUUykwvLrqhMLsysSuazxtbMKhLB 66rmyD+69lTEK0o2TYOIsRgiqTtr/HA1Dw6eM/BXK869kr7kZDxbZLfMTjXu8illSdPlCOVzkunh KRFCmRhLRMSgFW9pcQt/gEgHQDjAYSPaF+0zqnFjQ1pIy8YKcOl3awVyht0JNlDqp+gP0RBGtRZy Xnz4DBPMsECaMFKoFzjwi0QUJQnpsgYXrlDWKFTp4aJ9iWgiFtVi0ViUFBdDIjFubALCRFMdE2Ii dbscNNSu3//hyvZ7/+MO/SG4Bk6ADV5Z8IHe1PsXpoRAJuCePtzTTKbFIzk8VNEqE51nBo+QIywU mgVe8pOhrUm10sj23coBF03g3n+9NUk4Y7g5lcKFjgJ1QjvM/rgJtxYq9A26U/9cH3NlL2z5AI7g vg/RbF4UFhAbWRCfUGsFqVC2FAqiLJo4jlIwm1EQJYW3gmC71AQmG0iS1UJlEwskzU9auScBrNG3 o31qv+adGMs/HxHxkeJowuGdGGU4GZUWi2mxcWMjCeCyvYJX4rjcCdkTBI7u80HhOP3wkTvvvOuO /9QPj4NCr7BAf3DV46Vn6sGhf1Z/pvTxVTAT8ZxPHuCvQBaakSc+nhfHyiDLZulpKgJwomjinzZz HFr2PZzVojkmFkVj/fn5jCwk1Upgc9xYcIe0sBYqCGkxjb9Cr/2dXgs7f8dpB/VZ8MBBeFCfyXix Wv8TXEUGUCImxj2cyeEp5DjxsAAgOHgeBPoi26lnr2wr5OCwEO2LRdQ+3BPpH4uqfbEoRMaNzXZz YWe4AK76ZeXVVw98oD8FwwfQnJKygU/5emEJ5pFpZGa8uNA9G2YLFVKFVShQbxOorXs6JhaUpLm7 S8V94kciJ0qOjoMKKH5lBfV2cMWas1Dl5nOUS+eW0Ug0EenDqo8UJ/rwx8QuIQxD3pNYvsfhdlEx N/8nUDCehoMaSuHMM/pJyDz5v060LD+5t27tmKa79U9WuaENRsE06Nyv79v6uX7kud+v/fDI/TCm X/9Y72X02EwI/0uhCWWkOl7cIUOODFa6E3xBfixPe/kvecqLv5Aks2Td9C6KJAdop9BZtFBRDYog ina4FOYDB3aoZRjHok1FeEOCMbxj0b78RFNxH+YwpCkRYrwRpYKf0AkxLcT/8synsPPo/Q/NvG/Y vbDuBW7eY1O/+umErvPPVDK8kFn8hUhLD9kQz69wwiZPr4dmuqHSDUudUKJWqHSSAs0SbOIhDxHz cJhQ+axWi0XpViUnSkt8mEUVyzyWDmvcBVKHc6sTnOCDOmrBIStHvZRhHEMco3hLqH34y48QxBal Guv8aFMidRmKl+0OFUAhZmQ54WFcbiHygCALgJ921gH3PL1hw9JPwn1+sL71PthO6tl//OMJ8Kx7 YUZtp/4/5+0FTh949lG9T/8S2V+CJ2tAiitIxo3xWRH+PJ7eZoGwEBPoBgG6eeg0g8IDaucfeMHF 8wJvMe2ksiwSh1kUN/AgWQUzRzfZUXIUXnbIVxMLH3e4CqP8fH4rz/Eav4ow6YlFogYjvPmxBDKj GDsxPFe7MCbCt6qHkSnG2ZoSpCnENAdQk91hDkLa+Anc3f3999B5/UePfqq3QpMIhY9z7Wd3vMJN 6r8Nrp08lvGoHOUdDQ/xk8/jF/jTwWaSzYUV2iLrKitXIcNF7ifSD6dz6YgR/4qfuPx+4uf99nQI pEN6utit+oI+2uBb7aM+H3F0W7idRFUZ4xxqub3aTu12i4+IXIDFKj0D78VH4ePpFEDm/WqHPd0f d6cV+v12d0e5XC03ymtlXpWDMpUzkSB29h5Vtc+3b7HfZX/ULtgz7MsYUZh0NvWhwYigOqOlQBPG 6qJoUwxNbAwluAgn1D5GuCbU96YESgijGBIMtFjKBkfQCIekEFdoCAEJDxueO8ETy08Jh5T7JneZ p//anOuefQbseu83z+hvjjpe8taGbVuvemT2n4SKY3rzHfrJA0/rH+49FP7DPVetvOMu9G0GNRtQ 4r0kTB6ON9/qhYCQdBxycC7vMG+plSsxwSQOTKYKBbK6SxjvPbNV8HVPV+tVqqYBqFDhWYMvIly3 R9oKcALNHLpMdT4joPXNEIRCpplW8HcctII127qCmDqccWZynPOd1DncadAnZXKYRTWg6GiiCVUi RRc0QinNRjU3RIdJECRAwlOjI/QiOXhGjqBho4IwSBDR7fLwxS9P2vvIJlj03VPA658c07/Vj0Hu N9Ci71i+Y8ua5ptu5rNGHNKP/ToUOvrVgWf103AVTIXzYfOZwraOxD23NzbdzCSuDnWnFCVOJkXx oEhB9FF5JxHb0HtRM60jwmZRpDIhsiLX4mnQOyG+eKKjCabXxQxfZ8hNKRdyQKiVe+HsLk3/Sxhe P/uFUPGIvl8P6mvpDvgU44tJyI1rkBtOjIvzYFj86Og82JwH2VmwPhOUPDfnljCmy8rmis2TnMXB 4rwS81RnhbnCWeGqVZrlZtd1eRukDm2nvCPrtSzfSCczrCMJjFTBDILslv3OiDM7a7wsoRUdzUOA kAAZQUmeS1FcipyRpRDiVLKUjjziylPkPKLkZbkU1IVAHidkdyt2sKeldQsCCJJLCZA8fFbJsmR4 Og7KJ1AF5BEdllGWFSSj4z3MQuiwDofBaMd8B3VEHIOMRqYiaYwbkmmiAagKg+4GnbzmxW67aUyk 3dR6GEy4YIP6+6E7OtymJhSOJqzRhDRBTsH44YYASAh8ODi8YHz2DwKAfhzrlI7AnJMgf/YmSF/A SP31s/pX+ud06W9vr63fcS+3cHX3XTd2r6H3LH/z/jefuvvp2jUfPfz+H+788/FLNs1ZOHtm1Tz9 2+FrLrzo+sXlJXXM505HPs0b1Jqb4tNWK6sy6W0O8PMlIVopz7JT0dcty3Y/bm/HvIwAunrgut1p Wd12V5UF/H6xY5LjWsdBB+fIdqwg0IG25lDc4xlRSEiow2LQzTLfQi3DLd/TLaUkGHigVKFcYZBW ZEhaTENpi6X8BSQmMJvgcIoi2oeC8cxhoFqEhuWcqxfXvnjpjp330Yt6FhzU+8H89ncQ09/QTz38 Lty+7Fc3tbZs7/j6vJsgC0jnpZ8/8ywI+q/1gyinV95NszffOKerq6H6TkaF61A5VnKPGnFxIK5x h6l0WHSAcJiKJlk87Isww4/IsugY3OECJwKs/Prrr7lHv/22v+y77/AdEurWM6hbEnqm++M18gi7 XSwrIfsIVdCAyyZmeSVZLJJAhn1EcmEoLvIy3yOILkEQcWYC5XaaFEXkCXCCQ5bQdMsQkO+SH5U5 WRbQEgVZjgMYezdSXkAL/bhgFhrQCRfFmFUuytcmpuGd+IpjsWJvLOWuIsz4trcebh/jY7eIpE4+ jDCZUZhEQiEuxIUh5OQ4/hn924b+L5a+As9A1PXcc1CiHxAqzj5Ba/rvYrbjEpSUFpSUNDzdzy7i pqvTffPUeb5O9xf0tPVUmtzphC0q3CfBQrIIltiW2leSlRhgrJZX21rta9PMw0g+uZdwo+1Mj7u9 cKsGvM9kKTT3DByPj8HI2ruNAO/UttnsZt6lYmRJWsHeCjaV2mwqSp0frqauVlO6icV2fUaw5C1C V4MxRyzWxyASYZJDmlIxB1ZeEZ1LDi1AucnnvRI17CzTIm5br0c/8c6Bj6+HEcAdAVu4t/j1zu57 25fdBm+lHdW/fhKmPAVF0P7dxz4o0Ae+/Kb/QeTxFuTxCeSxiWjkyviF6DdMQS4oreSapavMzXYT On9FgjwMhDmQtxOHth04noN263NWKgoeYYnwoPAbQbC2CvIaIjiFFZQ4yFI8TsRwmgnDWRSzULUp Aeg6tZDhC0K5huLTcHgLfA1euFy/V3/y6aO7Pnxh1yeYuLTo72BZ/cI3p58HN3LqVsTSauRLZfGx 4vb5MthRhg7KXLG8ghk3qmwHh7CdciY8SIAH3sqvoKKyBizAcEGZiTKvHTVwMRz5SkRpJGghTBEM 4K1nO7jl/RvhrM7TG4SKI/pNz+rrSGpv7rThYSbHh4nbZdLIkhE8prGfhPkUWQO8mb+aggJDJ89H yZ3IdmObaRNZChoe2gy293Pz+++E9/Qgc/2bjg7uAptxF4744yo4KAfCmuUm9ubUCVAkio2XxGDz V1+xP8KkqHIHNu0ov1fsU4BHR0FvVMArwCK6ilIz5ADdBA/Af8OXiKHFalWMPwiAaMVAvVDGYFgM aiGs9ylWdDNWK5gcomKTOciS7YVKz8D78XRsAMYI1m0oIMuJIkrbTKppKanWIMEIi5Tta8qPGBIb Q2gfg2k7aqVkQ42cPNm4McVsYqWJhMKQk5uTy9Iy8Hi1GH/Hif7vLH5L2rMYrLwjXvYUV+ca7Yqc xeT47J+UDm4fO6eEelqBepoNhfHWThVu5G9UT1Bugh/a5Tal3X5jWluGMIVWZS9VlloWZK22rMz6 xPKBvdf1nts82/KMQit4UFozMlSfTyyLZMDjGa9m9GZ8mcHLGZ0Zt2c8mMFnuEFuzcw0FszM3JX5 eObhzD9k9mZ+mSkVZJZmXp15YyaPqQY6gpfjaWzReyyCUkk5VMMWuAuZBBB2MzdhYbNut+q+2wUu NjAZI2CXS+O2hZ3ebRoPrcTd6hJbg+mttmIXvOR613XCxblsLlswN7iCBowPPhzJIQ20PJeRGH8T J0ZRYpk6sTIkwxEWgEU0NoeNRATdTSKRyk1R67CBOodXE9oN5wRPyHAxudljaMope6WUv/F6PR7m nIcNl05EILD+5/F6/cyGtReD+moS3DmfFD571bW/++jYVv0Pnx/RX4LpsSN1FxfN908LV90zd9/b t/980s7qi1qikwpean3hLw+mvipy7xg+oyQ+DhyixG3nORRjkwxrfHGxWtwinhB5URYbUXm4Bkrk sTIdK5fLSfllmUe8o8aR2SnzWXjGdLQAlYZepX+jd3Hv6F38umPHUCoGPkDpbzEs17Z4xgVCm0AF UeBF1czEukcyuSTJJPCCyLPAfwwb5fdx1MVx1IThHjgkTPN7hklQLq2XqCQp/L7RHGxgGa1M2CMW iyaWIeaygpgzDWTRr5EoYD2UPI0by5xRxIS5ADZ8qRbBxFaDEEAM6AH9jB6FPEy4C4/rpTTOufuP 0tjZTwcjFe5jXiIZJJvcFpcznOgsrs2iXkxtHkPvYWIpzhVub6EYxF4wE9oskLn/fyxgsbiHdU0X 6vHEnuEccTscms9sEcviGmRooNm7tK/c8Lob3KoFj5Pd5s/111FHm6YF1ptyTIsMg6iyQM+LEUAi EevDE0Uww0UFTvSlwvkmdDqoyOh0QuGcXIxXcgrUUL63YDzLZgoxrM+ibs3FBQcjOO7jNzPFOWd2 7KMLfCNfeznjKbX3jZZbFuW+o5dWzV7XNrfxz7s3wFz42R13ZF7/q9xEwzq9aAF0Hyuu2lWPdOhA /ZYMO5ZBZsRjG0xQipn5DqtHs4ObYo43PQ3SdkiqZ73is6mFGATXY04DdnuGyrVBpvGdAaVlIstt UX6Y7KC1L2bn6TMykhiaTY1hzb6RhIflOg2sJ6RCrpOLe3+6btZ9b73+wn82xlsSs1fzyxfOW41O yNl0of7hd+/rhw6A3H7DLW/c+dDNbYjthci15xBbG0kn1XFnmwemOWGTa52HrvCt81GqWpj0jAC3 laR5d1Deozp2WBR1hhvAbm2zZdjqqHt9s7QRhc4vMWYYMXd+PkvIMSNhUFxUxJQXNTcULkDio846 YvloLrkUyqpB8+f+WPnKb5598XdP/6y3tyVRu/LVGTf815+h8MPX4Cd74PjZges6ko/qj2xrGsQZ aUxcmJlvjAc/ccGl6fPTX6cfUv45FzRTNL6gElhrRztmAiPenYRxWxmqmM1+q9+vOLt4j69LUZdY V1sftP7GytdKLdIu6QmJJ+sB3OutmdZ66revlzKkRYMOF6NidP9D1sr4ZBZBQ7UyZZZYluhlgTAx AmGHWwq5PMgVZw47ocSZXxzx0aOvDBCgb79xHPrLcptnPTAabpg/73ozTMno2APpn38Ao/Q3Pkpf /B9z4ZWGzhtWofXxoFrVCcuIm0yN56EXFVxdTrulywxSULYVqqQNY33OYncFDKPrdS2hnIdbbPjs xFB0aWAcy09523BBrGA8Co7XjWjZwB1zh2Hjn269det/B8dF1BnTrO+9x/10d/4tj9PHuNHnz9uN tN6IornM8OQSGRn3QRBESgSHaBfktjoTBoRtgkkwRDbGNitGO4LcBtxJY959WS9efF3fdw9xp/BE P7wtE9XbweReYK9pQ5/DXtIfif4QGeCzqcgAnxIbkN+ZpH4/yRg49JhsLfQyrp6HliTPCqqJuPl0 y47pHvCoPpfD7jO1ybIGbZhz1lGn2qZlabVUDQQDYwPlgerA2sDJgJQY5CtLafJJylognWIxlvhF IojBeCac2g/3mJuRDsHjFhtOPFJ77alfLWj/9O1lH7w7dfXrN++hLYdv2d7/GW157u7O/s+4U68f P358bzvDvwO9yFHE30FK9hMNzeAIPECeCM9qQBS31WwXdhRhwqsiwi5E2IJhgFOppWNdMISkkbNi QMK+kTYZuOWci5THzR3tnfvTqg29Lzc80/ZbevXC2l/c0f8td+qTgfuPkUGN+QIxMKNMVcdLRwIU emCkY6KDfgzwmhlKPTM9GzzcRdpsbRfhSi0zLQ+InKWLeLQuUV0ir5ZpLdfCUdt62SfXU9d6zsst SgX5Q0phfDdC/9wETQLT8NT3Q5Kbrw2lgtT13nEQXjuCSd7nz3+4fOWqlde6YcrL70Ge/s5HJ/S3 n4RZOx/b373rkRTF6GZeJVbyk/1EQIpl+9IKLUF3WiE4GpW1ClWonZfVRxVQ7AqKPQqQbdBwRqLG t8DDTShGBhuRQobIIxLQ0PviqNsvMzsfaeJOff7zdXD6nTrczYbUWYnUCYA5nh9VipUyZY7SYd8Q 2BGQsq15GQXWSRkbvG1pt9q7vNvTHlbus+xKe9C/12O7T3rAQ5l92ZuRIZZJPhTKj+LpdnTO3vXy UhlekN+QP5S5kfIkDOttmVrPwBtxF1uqaaqmjmGtteotmKUwYZ5lRZ1WnSwQA4izubEABG1ZEMai enBdmR5nl00V0t3pe9M5bX2xCi+p76on1AGVV4X16aH0FqqY080U1hP3+v3ml8zUHDQ3Gyb5tT4m Sa+iqx9K6TE0YUk9C7wiRuRlxFlqbyQ/FklZayO9Z1FW7nBmNIJGjGWEWEaElWN7bdyvX50yukd/ 8alDEL/gSPDWvdvf7NfPPrbzs49GXtc6YrwcPu/khgOfjly58tKs0eM/+/WuVqT18IFPaEJQUA5n xMcJcVQEi8UKDuLu4pya3GW1KXarTWuzmE0mWVW34BM+0kJlr7yYlvuYPuBx8plrjLFPvUZmmc8+ fUWNP5FEst1ohMdAATN1zgnsc6/GvCNNLCqae+P5129yHzhypKTav2ePZ/qaG6l5N0ia/tFu3Tm/ hEkdysHzaKcc5KfxvEIbUNW6g7egjeGdmCqa7KC1LXKAw+Woo3KbyYnSaHKamNQNfi9hclcc6ctn appydTkF6KpTQQW6u+dfnflx5z0fV4+56Pbet0481E2f7l/eMK3tTfiADMaaG3F3M5ji/kVQL62C azEfo7LJQ9NMOXSkaT/dazKZmD9upKqZUyRCOUUEEy9LROBlESQQQbWi+MHe1AcMmVO4J3jZxfMy NYkcEI53S7LCiXazScDIkZeVIJM0Jag5sfZZbWLZTxT4FPUq7k4vVBRAFVxCJRGDt8dVJwtFBz7a x1aNw5yLSa3Xl14oilwvZqkWfjGNW8uta61brXwilaNG0JTGItH8fJQzbEZi2tBHOG/qE8jEcz5/ sLsdL8ICBvblNRTiuDBAyOmMAbdRP/vaJ4ehXH8bhPt+e1D/H2jUt1ITfKK/DiP1i5geY0h9ncG/ F+JegbppNi2gJbSCirQSPeVf0NxqjHrlFDBkJooiaxZNtSBLLY4nCCDBQNW0vehRLZrDYqeCYgJB szhNXUKG6iCc3Y4xK2fRgLM7iNqOO7qQOKrd+BhvkyS7076YXuCCxS4g8zF7QZks0tinn6J8h3fi fFQ9L8qqFsNjs8K+PAos1GZffmyYZJrUwyZWTyZ4/vkJmJ/AClhYkVvgzWd/m8mFmNPJXadfPbx1 5eiZDReWjHDru06cPsadOrNuSYv0BI1eo4hF3OP9i+jtTKBCf7fMITvIpxjRXzpYHoDT9Eosz3HL ecIXCLKwWXjk3CJmYblb/EIaJy00yvXfl1NDxfS8qX+oyPP+qryvTMSy3SyZpxul0SibzJ9aRllu NMoBa5P1oFVnxXaXfcS/y7/Lv8u/y//rQli0nPpvMhdmKeyfzdIRRGxMvryyght56bhp5RdaCy8b lVuSM+Jnwy+YOWtupn36HJs73ey0+NN8XlfGhP/rf6v+/+LiSbNR84w+J/MGBrAGVmOfx3oyuZxU EpbbjSSXknFkGiknF2L4UEguI6NILikhOWQE+RkZTi4gM8ksMhfzOTuZjt7IhhluOuYmTmLBjD4N Iz4vUj+DpAgJ6M8p+7MvEVlGXLqyZvnSZfXLgxesaK6rXxC8uHZhfUsDwwm2EuFf+zd88jf/rn+S nBz40QAMLYPvgaHwD6GKTEGYwO8mDyHMhz6y+lzAsTKEzQgzB6EEoXwQ6hAmIUzHtdf9n4A/RiQD 7iGXCOeTLXwZuRXzpO+BDvtbEGJ/C/zNROLeYV83fwx81cCH/xCuINP5S0nHIFzI55MLaTvxDAGc JhvPBfErspGvwLXn4dpBoL8mHdw9xEZvIcP5y3BuEDjM87kOlAbun/CO8UagW3YnH/3NfPvk08Sf YubDD8y1sPvvF9zcpV/Qv9l0ULoDu/IQL/83gw208gplbmRzdHJlYW0KZW5kb2JqCjIgMCBvYmoK PDwvUHJvZHVjZXIoR1BMIEdob3N0c2NyaXB0IDguNjQpCi9DcmVhdGlvbkRhdGUoRDoyMDE0MTIx ODExMTk0MiswMicwMCcpCi9Nb2REYXRlKEQ6MjAxNDEyMTgxMTE5NDIrMDInMDAnKQovVGl0bGUo TWljcm9zb2Z0IFdvcmQgLSBfNDE0MzExNDcyXyAzLjUlIFdPTkdBIExPQU5TIE9GRkVSKQovQ3Jl YXRvcihQU2NyaXB0NS5kbGwgVmVyc2lvbiA1LjIpCi9BdXRob3IodXNlcik+PmVuZG9iagp4cmVm CjAgNDcKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDYwMDU5IDAwMDAwIG4gCjAwMDAwOTk5NzAg MDAwMDAgbiAKMDAwMDA2MDAwMCAwMDAwMCBuIAowMDAwMDU5ODE2IDAwMDAwIG4gCjAwMDAwMDAw MTUgMDAwMDAgbiAKMDAwMDA1OTc5NSAwMDAwMCBuIAowMDAwMDYwMTA3IDAwMDAwIG4gCjAwMDAw NjM5MTkgMDAwMDAgbiAKMDAwMDA2MzY4OCAwMDAwMCBuIAowMDAwMDYzNDU2IDAwMDAwIG4gCjAw MDAwNjMyMjQgMDAwMDAgbiAKMDAwMDA2Mjk5MiAwMDAwMCBuIAowMDAwMDYyNzA4IDAwMDAwIG4g CjAwMDAwNjI0MjQgMDAwMDAgbiAKMDAwMDA2MjE0MiAwMDAwMCBuIAowMDAwMDYxODU2IDAwMDAw IG4gCjAwMDAwNjE2MjQgMDAwMDAgbiAKMDAwMDA2MTM5MiAwMDAwMCBuIAowMDAwMDYxMTA4IDAw MDAwIG4gCjAwMDAwNjA4MjQgMDAwMDAgbiAKMDAwMDA2MDU5MiAwMDAwMCBuIAowMDAwMDYwMzYw IDAwMDAwIG4gCjAwMDAwNjQ3MjQgMDAwMDAgbiAKMDAwMDA3MzAyOSAwMDAwMCBuIAowMDAwMDY1 MTYxIDAwMDAwIG4gCjAwMDAwNzg4MzcgMDAwMDAgbiAKMDAwMDA2NTcwNiAwMDAwMCBuIAowMDAw MDg1MDQzIDAwMDAwIG4gCjAwMDAwNjYxMzkgMDAwMDAgbiAKMDAwMDA5MDQ3NyAwMDAwMCBuIAow MDAwMDY2NTQzIDAwMDAwIG4gCjAwMDAwOTEwNzEgMDAwMDAgbiAKMDAwMDA2NDI4NiAwMDAwMCBu IAowMDAwMDY3MTAwIDAwMDAwIG4gCjAwMDAwNjAxNDggMDAwMDAgbiAKMDAwMDA2MDE3OCAwMDAw MCBuIAowMDAwMDY0MTk5IDAwMDAwIG4gCjAwMDAwNjczMTkgMDAwMDAgbiAKMDAwMDA3MzQwNyAw MDAwMCBuIAowMDAwMDc5MDUzIDAwMDAwIG4gCjAwMDAwODU0MjcgMDAwMDAgbiAKMDAwMDA5MDcw OSAwMDAwMCBuIAowMDAwMDkxMzAxIDAwMDAwIG4gCjAwMDAwNjQ1MjcgMDAwMDAgbiAKMDAwMDA2 NTQ4MSAwMDAwMCBuIAowMDAwMDY2ODY5IDAwMDAwIG4gCnRyYWlsZXIKPDwgL1NpemUgNDcgL1Jv b3QgMSAwIFIgL0luZm8gMiAwIFIKL0lEIFs8QTdCOTlCODJFRUJGNTJDNzczNjhDQzdGNzU1NEQ5 QTg+PEE3Qjk5QjgyRUVCRjUyQzc3MzY4Q0M3Rjc1NTREOUE4Pl0KPj4Kc3RhcnR4cmVmCjEwMDIw MgolJUVPRgo= ------=_Part_6177416_1671826187.1448730138062 Content-Type: application/pdf; name="WONGA LOANS APPLICATION FORM.pdf" Content-Disposition: attachment; filename="WONGA LOANS APPLICATION FORM.pdf" Content-Transfer-Encoding: base64 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 Ci9Sb3RhdGUgMC9QYXJlbnQgMyAwIFIKL1Jlc291cmNlczw8L1Byb2NTZXRbL1BERiAvSW1hZ2VD IC9UZXh0XQovRXh0R1N0YXRlIDE3IDAgUgovWE9iamVjdCAxOCAwIFIKL0ZvbnQgMTkgMCBSCj4+ Ci9Db250ZW50cyA1IDAgUgo+PgplbmRvYmoKMyAwIG9iago8PCAvVHlwZSAvUGFnZXMgL0tpZHMg Wwo0IDAgUgpdIC9Db3VudCAxCj4+CmVuZG9iagoxIDAgb2JqCjw8L1R5cGUgL0NhdGFsb2cgL1Bh Z2VzIDMgMCBSCj4+CmVuZG9iago3IDAgb2JqCjw8L1R5cGUvRXh0R1N0YXRlCi9PUE0gMT4+ZW5k b2JqCjE3IDAgb2JqCjw8L1I3CjcgMCBSPj4KZW5kb2JqCjE4IDAgb2JqCjw8L1I4CjggMCBSPj4K ZW5kb2JqCjggMCBvYmoKPDwvU3VidHlwZS9JbWFnZQovQ29sb3JTcGFjZS9EZXZpY2VSR0IKL1dp ZHRoIDE2NjMKL0hlaWdodCAxNTkxCi9CaXRzUGVyQ29tcG9uZW50IDgKL0ZpbHRlci9EQ1REZWNv ZGUvTGVuZ3RoIDM0NTA1Nz4+c3RyZWFtCv/Y/+4ADkFkb2JlAGQAAAAAAf/bAEMAAgICAgICAgIC AgMDAgMEBgQEAwMEBwUGBAYJCAkJCQgICAoLDgwKCg0KCAgMEAwNDg8PEA8JDBESEQ8SDg8PD//b AEMBAwMDBAMEBwQEBw8KCAoPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8P Dw8PDw8PDw8PD//AABEIBjcGfwMBEQACEQEDEQH/xAAfAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUG BwgJCgv/xAC1EAACAQMDAgQDBQUEBAAAAX0BAgMABBEFEiExQQYTUWEHInEUMoGRoQgjQrHBFVLR 8CQzYnKCCQoWFxgZGiUmJygpKjQ1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5 eoOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4eLj 5OXm5+jp6vHy8/T19vf4+fr/xAAfAQADAQEBAQEBAQEBAAAAAAAAAQIDBAUGBwgJCgv/xAC1EQAC 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 ABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUA FABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAU AFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQA UAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQ AUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAB QAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFNjRw1l/ycn8P/APsRPFH/AKcNArWl ujkxv8N+jPwhXpFX9HZW/wBxD0P5zx3+8VPU+l/2Pf8Ak4/4df8Ab9/6QXVfO8Wr/hLqesfzR7PC /wDvK+f5Hl3xm/5LB8U/+xm1b/0qejhmjGWFptoxzetJV52YvwX/AOSy/Cj/ALGbSP8A0qSjieio 4Wq0uheQ1m8XTuz9n9T/AOTkfiH/ANiN4X/9OGv1+Hy3Z++0fgR2NSWtwoAKACgAoAKACgAoAKAC gAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKA CgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAK ACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoA KACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAo AKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgA oAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACmxR3OGs/ +TkvAP8A2Inij/04aBWtLdHPjf4cvRn4RD/lj9a/o3LPgh6fofzljP8AeKnqfSf7Hf8Aycf8OP8A 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 P4hf+G68Sf8AyFQAf8L08E/9AP4hf+G68Sf/ACFQAf8AC9PBP/QD+IX/AIbrxJ/8hUAH/C9PBP8A 0A/iF/4brxJ/8hUAH/C9PBP/AEA/iF/4brxJ/wDIVAB/wvTwT/0A/iF/4brxJ/8AIVAB/wAL08E/ 9AP4hf8AhuvEn/yFQAf8L08E/wDQD+IX/huvEn/yFQAf8L08E/8AQD+IX/huvEn/AMhUAH/C9PBP /QD+IX/huvEn/wAhUAH/AAvTwT/0A/iF/wCG68Sf/IVAB/wvTwT/ANAP4hf+G68Sf/IVAB/wvTwT /wBAP4hf+G68Sf8AyFQAf8L08E/9AP4hf+G68Sf/ACFQAf8AC9PBP/QD+IX/AIbrxJ/8hUAH/C9P BP8A0A/iF/4brxJ/8hUAH/C9PBP/AEA/iF/4brxJ/wDIVAB/wvTwT/0A/iF/4brxJ/8AIVAB/wAL 08E/9AP4hf8AhuvEn/yFQAf8L08E/wDQD+IX/huvEn/yFQAf8L08E/8AQD+IX/huvEn/AMhUAH/C 9PBP/QD+IX/huvEn/wAhUAH/AAvTwT/0A/iF/wCG68Sf/IVAB/wvTwT/ANAP4hf+G68Sf/IVAB/w vTwT/wBAP4hf+G68Sf8AyFQAf8L08E/9AP4hf+G68Sf/ACFQAf8AC9PBP/QD+IX/AIbrxJ/8hUAH /C9PBP8A0A/iF/4brxJ/8hUAH/C9PBP/AEA/iF/4brxJ/wDIVAB/wvTwT/0A/iF/4brxJ/8AIVAB /wAL08E/9AP4hf8AhuvEn/yFQAf8L08E/wDQD+IX/huvEn/yFQAf8L08E/8AQD+IX/huvEn/AMhU AH/C9PBP/QD+IX/huvEn/wAhUAH/AAvTwT/0A/iF/wCG68Sf/IVAB/wvTwT/ANAP4hf+G68Sf/IV AB/wvTwT/wBAP4hf+G68Sf8AyFQAf8L08E/9AP4hf+G68Sf/ACFQAf8AC9PBP/QD+IX/AIbrxJ/8 hUAH/C9PBP8A0A/iF/4brxJ/8hUAH/C9PBP/AEA/iF/4brxJ/wDIVAB/wvTwT/0A/iF/4brxJ/8A IVAB/wAL08E/9AP4hf8AhuvEn/yFQAf8L08E/wDQD+IX/huvEn/yFQAf8L08E/8AQD+IX/huvEn/ AMhUAH/C9PBP/QD+IX/huvEn/wAhUAH/AAvTwT/0A/iF/wCG68Sf/IVAB/wvTwT/ANAP4hf+G68S f/IVAB/wvTwT/wBAP4hf+G68Sf8AyFQAf8L08E/9AP4hf+G68Sf/ACFQAf8AC9PBP/QD+IX/AIbr xJ/8hUAH/C9PBP8A0A/iF/4brxJ/8hUAH/C9PBP/AEA/iF/4brxJ/wDIVAB/wvTwT/0A/iF/4brx J/8AIVAB/wAL08E/9AP4hf8AhuvEn/yFQAf8L08E/wDQD+IX/huvEn/yFQAf8L08E/8AQD+IX/hu vEn/AMhUAH/C9PBP/QD+IX/huvEn/wAhUAH/AAvTwT/0A/iF/wCG68Sf/IVAB/wvTwT/ANAP4hf+ G68Sf/IVAB/wvTwT/wBAP4hf+G68Sf8AyFQAf8L08E/9AP4hf+G68Sf/ACFQAf8AC9PBP/QD+IX/ AIbrxJ/8hUAH/C9PBP8A0A/iF/4brxJ/8hUAH/C9PBP/AEA/iF/4brxJ/wDIVAB/wvTwT/0A/iF/ 4brxJ/8AIVAB/wAL08E/9AP4hf8AhuvEn/yFQAf8L08E/wDQD+IX/huvEn/yFQAf8L08E/8AQD+I X/huvEn/AMhUAH/C9PBP/QD+IX/huvEn/wAhUAH/AAvTwT/0A/iF/wCG68Sf/IVAB/wvTwT/ANAP 4hf+G68Sf/IVAB/wvTwT/wBAP4hf+G68Sf8AyFQAf8L08E/9AP4hf+G68Sf/ACFQAf8AC9PBP/QD +IX/AIbrxJ/8hUAH/C9PBP8A0A/iF/4brxJ/8hUAH/C9PBP/AEA/iF/4brxJ/wDIVAB/wvTwT/0A /iF/4brxJ/8AIVAB/wAL08E/9AP4hf8AhuvEn/yFQAf8L08E/wDQD+IX/huvEn/yFQAf8L08E/8A QD+IX/huvEn/AMhUAH/C9PBP/QD+IX/huvEn/wAhUAH/AAvTwT/0A/iF/wCG68Sf/IVAB/wvTwT/ ANAP4hf+G68Sf/IVAB/wvTwT/wBAP4hf+G68Sf8AyFQAf8L08E/9AP4hf+G68Sf/ACFQAf8AC9PB P/QD+IX/AIbrxJ/8hUAH/C9PBP8A0A/iF/4brxJ/8hUAH/C9PBP/AEA/iF/4brxJ/wDIVAB/wvTw T/0A/iF/4brxJ/8AIVAB/wAL08E/9AP4hf8AhuvEn/yFQAf8L08E/wDQD+IX/huvEn/yFQAf8L08 E/8AQD+IX/huvEn/AMhUAH/C9PBP/QD+IX/huvEn/wAhUAH/AAvTwT/0A/iF/wCG68Sf/IVAB/wv TwT/ANAP4hf+G68Sf/IVAB/wvTwT/wBAP4hf+G68Sf8AyFQAf8L08E/9AP4hf+G68Sf/ACFQAf8A C9PBP/QD+IX/AIbrxJ/8hUAH/C9PBP8A0A/iF/4brxJ/8hUAH/C9PBP/AEA/iF/4brxJ/wDIVAB/ wvTwT/0A/iF/4brxJ/8AIVAB/wAL08E/9AP4hf8AhuvEn/yFQAf8L08E/wDQD+IX/huvEn/yFQAf 8L08E/8AQD+IX/huvEn/AMhUAH/C9PBP/QD+IX/huvEn/wAhUAH/AAvTwT/0A/iF/wCG68Sf/IVA B/wvTwT/ANAP4hf+G68Sf/IVAB/wvTwT/wBAP4hf+G68Sf8AyFQAf8L08E/9AP4hf+G68Sf/ACFQ Af8AC9PBP/QD+IX/AIbrxJ/8hUAH/C9PBP8A0A/iF/4brxJ/8hUAH/C9PBP/AEA/iF/4brxJ/wDI VAB/wvTwT/0A/iF/4brxJ/8AIVAB/wAL08E/9AP4hf8AhuvEn/yFQAf8L08E/wDQD+IX/huvEn/y FQAf8L08E/8AQD+IX/huvEn/AMhUAH/C9PBP/QD+IX/huvEn/wAhUAH/AAvTwT/0A/iF/wCG68Sf /IVAB/wvTwT/ANAP4hf+G68Sf/IVAB/wvTwT/wBAP4hf+G68Sf8AyFQAf8L08E/9AP4hf+G68Sf/ ACFQAf8AC9PBP/QD+IX/AIbrxJ/8hUAH/C9PBP8A0A/iF/4brxJ/8hUAH/C9PBP/AEA/iF/4brxJ /wDIVAB/wvTwT/0A/iF/4brxJ/8AIVAB/wAL08E/9AP4hf8AhuvEn/yFQAf8L08E/wDQD+IX/huv En/yFQAf8L08E/8AQD+IX/huvEn/AMhUAH/C9PBP/QD+IX/huvEn/wAhUAH/AAvTwT/0A/iF/wCG 68Sf/IVAB/wvTwT/ANAP4hf+G68Sf/IVAB/wvTwT/wBAP4hf+G68Sf8AyFQAf8L08E/9AP4hf+G6 8Sf/ACFQAf8AC9PBP/QD+IX/AIbrxJ/8hUAH/C9PBP8A0A/iF/4brxJ/8hUAH/C9PBP/AEA/iF/4 brxJ/wDIVAFr4D6bqWj/AAP+DWlarZXNnqdl4V0i1ubS7hkjmt50soEdJI3+46UAeq0AFABQAUAF NijucNZf8nJeAP8AsRPFH/pw0CtaW6OfG/w5ejPwhX/ln9a/o7LNKcH5H8545P6xP1PpP9j35v2k vhzj1vv/AE33VfN8Xf8AIuqesfzR7PC6f1q3r+R5n8Zf+SwfFH/sZtW/9Knrp4V/3WmednH+8SD4 L/8AJZfhR/2M2kf+lSUuK/8AdKvob8O/73A/Z/Uv+Tk/iF/2Ivhf/wBOGv1+Ey3Z/QdD4EdjUlrc KACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAo AKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgA oAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACg AoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAC gAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKA CgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAK ACgAoAKACgAoCJxWm8/tI/DxR/0Ivij/ANOGgVUXZowrpyi0j8a/+FNfFzyPK/4VF4183/sA33/x Fft2H4owMcFGm5a2PxPFZDj3jZTUdD3/APZg+HPxF8O/HDwDrWu/DjxRYaPYreNdT32kXaL89nOi dUx9968jiTPcHi8uVOnLW6/M6+H8px+GzCU5R01/I+d/jJ/yWD4o/wDYzat/6VNX0HCv+60z5rOP 94kO+C//ACWX4Uf9jNpH/pUlLiv/AHSr6G/Dv+9wP2e1L/k5P4hf9iL4X/8AThr9fhMt2f0HQ+BH ZVJa3CgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAC gAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKA CgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAK ACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoA 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 AUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAB QAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFA BQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQBx2lfJ+0t8P PT/hBvFH/pw0CnuJtJXZ6N/wv34Jf9Fc8G/+Dy0/+KrsWW4t7Rf3HkyzjBp2bRNp/wAW/hb4iv7f SPDfxH8MahrN2WWC1sdUguHlKpvf5UbsiZrnq5fi4atP7jpo5jg6mzR7LUncFAHydq//ACcx8Q/+ xF8L/wDpw1+oA7GgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAK ACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoA KACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAo AKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgA oAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACg AoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAC gAoAKACgAoAKACgAoAKACgAoAKACmxR3OHsv+Tk/AH/YieKP/ThoFa0t0c+N0py9Gfg//cr+hctw 0HCGi2/Q/nnG4iaxFTXqfSv7HZ2/tJfDg/7Wof8Apvua+d4roQhl9RpdV+aPY4YxE5Ymzff8j+gL I9a/GT93uGRQB8n6v/ycx8Q/+xF8L/8Apw1+oA7GgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACg AoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAC gAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKA CgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAK ACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoA KACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAo AKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACmxR3OGsv+Tk/AH/AGInij/0 4aBWtLdHPjf4cvRn4Rr96Gv6NyqLdOHofzjjZL6xU9T6V/Y9/wCTj/h1/wBv3/pBdV87xdFrL6nr H80ezwvJfWvv/I+w/FX7ftz4R8WeJvC8nwt+2Po2o3Omm5/t3y/P8qZ49+z7L8n+rr4XLOC6uOw6 lGp+H/BPucZxtDC4iSdH8Q8Kft/XPi7xd4X8Lx/C37G+s6jbaYtz/bvmfZ/NmSPds+y/N9+jNOC6 uAw7lKpt5f8ABLwXGsMZiIxVHfzPovU/m/aV+Ibf9SN4X/8AThr9fEtW0Pv4PmVzsqRowoEFABQA UAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAHl XiH4x+FfCvi+88FarpXiubVLTTrbVHk0Tw3qesw+RPNcpH/x5W82x/8ARJPv7P8AY3/PsAKv/C9P BP8A0A/iF/4brxJ/8hUAH/C9PBP/AEA/iF/4brxJ/wDIVAB/wvTwT/0A/iF/4brxJ/8AIVAB/wAL 08E/9AP4hf8AhuvEn/yFQAf8L08E/wDQD+IX/huvEn/yFQAf8L08E/8AQD+IX/huvEn/AMhUAH/C 9PBP/QD+IX/huvEn/wAhUAH/AAvTwT/0A/iF/wCG68Sf/IVAB/wvTwT/ANAP4hf+G68Sf/IVAB/w vTwT/wBAP4hf+G68Sf8AyFQAf8L08E/9AP4hf+G68Sf/ACFQAf8AC9PBP/QD+IX/AIbrxJ/8hUAH /C9PBP8A0A/iF/4brxJ/8hUAH/C9PBP/AEA/iF/4brxJ/wDIVAB/wvTwT/0A/iF/4brxJ/8AIVAB /wAL08E/9AP4hf8AhuvEn/yFQAf8L08E/wDQD+IX/huvEn/yFQAf8L08E/8AQD+IX/huvEn/AMhU AH/C9PBP/QD+IX/huvEn/wAhUAH/AAvTwT/0A/iF/wCG68Sf/IVAB/wvTwT/ANAP4hf+G68Sf/IV AB/wvTwT/wBAP4hf+G68Sf8AyFQAf8L08E/9AP4hf+G68Sf/ACFQAf8AC9PBP/QD+IX/AIbrxJ/8 hUAH/C9PBP8A0A/iF/4brxJ/8hUAH/C9PBP/AEA/iF/4brxJ/wDIVAB/wvTwT/0A/iF/4brxJ/8A IVAB/wAL08E/9AP4hf8AhuvEn/yFQAf8L08E/wDQD+IX/huvEn/yFQAf8L08E/8AQD+IX/huvEn/ AMhUAH/C9PBP/QD+IX/huvEn/wAhUAH/AAvTwT/0A/iF/wCG68Sf/IVAB/wvTwT/ANAP4hf+G68S f/IVAB/wvTwT/wBAP4hf+G68Sf8AyFQAf8L08E/9AP4hf+G68Sf/ACFQAf8AC9PBP/QD+IX/AIbr xJ/8hUAH/C9PBP8A0A/iF/4brxJ/8hUAH/C9PBP/AEA/iF/4brxJ/wDIVAB/wvTwT/0A/iF/4brx J/8AIVAB/wAL08E/9AP4hf8AhuvEn/yFQAf8L08E/wDQD+IX/huvEn/yFQAf8L08E/8AQD+IX/hu vEn/AMhUAH/C9PBP/QD+IX/huvEn/wAhUAH/AAvTwT/0A/iF/wCG68Sf/IVAB/wvTwT/ANAP4hf+ G68Sf/IVAB/wvTwT/wBAP4hf+G68Sf8AyFQAf8L08E/9AP4hf+G68Sf/ACFQAf8AC9PBP/QD+IX/ AIbrxJ/8hUAH/C9PBP8A0A/iF/4brxJ/8hUAH/C9PBP/AEA/iF/4brxJ/wDIVAB/wvTwT/0A/iF/ 4brxJ/8AIVAB/wAL08E/9AP4hf8AhuvEn/yFQAf8L08E/wDQD+IX/huvEn/yFQAf8L08E/8AQD+I X/huvEn/AMhUAH/C9PBP/QD+IX/huvEn/wAhUAH/AAvTwT/0A/iF/wCG68Sf/IVAB/wvTwT/ANAP 4hf+G68Sf/IVAB/wvTwT/wBAP4hf+G68Sf8AyFQAf8L08E/9AP4hf+G68Sf/ACFQAf8AC9PBP/QD +IX/AIbrxJ/8hUAH/C9PBP8A0A/iF/4brxJ/8hUAH/C9PBP/AEA/iF/4brxJ/wDIVAB/wvTwT/0A /iF/4brxJ/8AIVAB/wAL08E/9AP4hf8AhuvEn/yFQAf8L08E/wDQD+IX/huvEn/yFQAf8L08E/8A QD+IX/huvEn/AMhUAH/C9PBP/QD+IX/huvEn/wAhUAH/AAvTwT/0A/iF/wCG68Sf/IVAB/wvTwT/ ANAP4hf+G68Sf/IVAB/wvTwT/wBAP4hf+G68Sf8AyFQAf8L08E/9AP4hf+G68Sf/ACFQAf8AC9PB P/QD+IX/AIbrxJ/8hUAH/C9PBP8A0A/iF/4brxJ/8hUAH/C9PBP/AEA/iF/4brxJ/wDIVAB/wvTw T/0A/iF/4brxJ/8AIVAB/wAL08E/9AP4hf8AhuvEn/yFQAf8L08E/wDQD+IX/huvEn/yFQAf8L08 E/8AQD+IX/huvEn/AMhUAH/C9PBP/QD+IX/huvEn/wAhUAH/AAvTwT/0A/iF/wCG68Sf/IVAB/wv TwT/ANAP4hf+G68Sf/IVAB/wvTwT/wBAP4hf+G68Sf8AyFQAf8L08E/9AP4hf+G68Sf/ACFQAf8A C9PBP/QD+IX/AIbrxJ/8hUAH/C9PBP8A0A/iF/4brxJ/8hUAH/C9PBP/AEA/iF/4brxJ/wDIVAB/ wvTwT/0A/iF/4brxJ/8AIVAB/wAL08E/9AP4hf8AhuvEn/yFQAf8L08E/wDQD+IX/huvEn/yFQAf 8L08E/8AQD+IX/huvEn/AMhUAH/C9PBP/QD+IX/huvEn/wAhUAH/AAvTwT/0A/iF/wCG68Sf/IVA B/wvTwT/ANAP4hf+G68Sf/IVAB/wvTwT/wBAP4hf+G68Sf8AyFQAf8L08E/9AP4hf+G68Sf/ACFQ Af8AC9PBP/QD+IX/AIbrxJ/8hUAH/C9PBP8A0A/iF/4brxJ/8hUAH/C9PBP/AEA/iF/4brxJ/wDI VAB/wvTwT/0A/iF/4brxJ/8AIVAB/wAL08E/9AP4hf8AhuvEn/yFQAf8L08E/wDQD+IX/huvEn/y FQAf8L08E/8AQD+IX/huvEn/AMhUAH/C9PBP/QD+IX/huvEn/wAhUAH/AAvTwT/0A/iF/wCG68Sf /IVAB/wvTwT/ANAP4hf+G68Sf/IVAB/wvTwT/wBAP4hf+G68Sf8AyFQAf8L08E/9AP4hf+G68Sf/ ACFQAf8AC9PBP/QD+IX/AIbrxJ/8hUAH/C9PBP8A0A/iF/4brxJ/8hUAH/C9PBP/AEA/iF/4brxJ /wDIVAB/wvTwT/0A/iF/4brxJ/8AIVAB/wAL08E/9AP4hf8AhuvEn/yFQAf8L08E/wDQD+IX/huv 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 gAoAKACgAoAKACgDyDRP+S/fEz/sT/C//pbr9AHr9ABQAUAFABQAUAFABQAUAFABQAUAFABQAUAF ABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUA FABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAU AFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQA UAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQ AUAFABQAUAFABQAUAFABQAUAFABQAUAeP/E7/kdP2eP+xwuf/Ue1igD2CgAoAKACgAoA47Rv+Tl/ h1/2Ivij/wBOGgUAfWGB6VYrIMCgdj+a74yf8li+KX/Yzav/AOlT1+3cM4ynTwtOLaPwDNsFUdeV kx3wY/5LJ8KP+xm0j/0qSlxPjKdTC1Emi8hwVSOLg2mftBqX/JyPxD/7Ebwv/wCnDX6/EZbs/eaO kUdhUlrcKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgA oAKACgAoAKACgDyDRP8Akv3xM/7E/wAL/wDpbr9AHr9ABQAUAFABQAUAFABQAUAFABQAUAFABQAU AFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQA UAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQ AUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAB QAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFA BQAUAFABQAUAFABQAUAFABQAUAFABQAUAeP/ABO/5HT9nj/scLn/ANR7WKAPYKACgAoAKACgDjtI /wCTmPh5/wBiL4o/9OGgUAfWNWAUAVTbxH7yJV+0l3OV4Wm94oT7NEOka/8AfNHtJdwWFgtoo+Wd Y/5OW+Iv/Yi+F/8A04a/WR1HY0gCgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKA CgAoAKACgAoAKACgAoAKACgAoAKACgAoA8g0T/kv3xM/7E/wv/6W6/QB6/QAUAFABQAUAFABQAUA FABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAU AFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQA UAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQ AUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAB QAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAHj/xO/5HT9nj/scLn/1HtYoA9goA KACgAoAKAOO0j/k5j4ef9iL4o/8AThoFAH1jVgFADdvvRZE6ht96LINT5Q1f/k5j4h/9iL4X/wDT hr9QUdjQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFA BQAUAFABQAUAFAHkGif8l++Jn/Yn+F//AEt1+gD1+gAoAKACgAoAKACgAoAKACgAoAKACgAoAKAC gAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKA CgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAK ACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoA KACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAo AKACgAoAKACgAoAKACgAoAKACgAoAKAPH/id/wAjp+zx/wBjhc/+o9rFAHsFABQAUAFABQBxuj/8 nL/Dv/sR/FH/AKcNAoA+sqsBMj1oFdC0DCgD5O1f/k5j4h/9iL4X/wDThr9QB2NABQAUAFABQAUA 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 gAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKA CgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAK ACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoA KACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAo AKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACmxR3OGs/8Ak5LwD/2Ifij/ANOGgVrS 3Rz43+HL0Z+EQ/5Y/Wv6Nyz4Kfp+h/OWM/3ip6n0n+x3/wAnH/Dj/t+/9ILuvnuL/wDkX1PVfmj2 eGf95+/8jzP4y/8AJYPij/2M2rf+lT1vwr/utM8/OP8AeJB8GP8Aksnwo/7GbSP/AEqSlxX/ALpV 9Dfh3/e4H7O6l/ycn8Qv+xF8L/8Apw1+vwmW7P6DofAjsqktbhQAUAFABQAUAFABQAUAFABQAUAF ABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUA FABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAU AFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQA UAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQ AUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAB QAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFNijucNZ/wDJyXgH /sQ/FH/pw0CtaW6OfG/w5ejPwiH/ACx+tf0blnwU/T9D+csZ/vFT1PpP9jv/AJOP+HH/AG/f+kF3 Xz3F/wDyL6nqvzR7PDP+8/f+R5l8Zf8AksHxR/7GbVv/AEqet+Ff91pnn5x/vEg+C/8AyWX4Uf8A YzaR/wClSUuK/wDdKvob8O/73A/Z/Uv+Tk/iF/2Ivhf/ANOGv1+Ey3Z/QdD4EdjUlrcKACgAoAKA CgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAK ACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoA KACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAo AKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgA oAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACg AoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAC gApsUdzhrP8A5OS8A/8AYh+KP/ThoFa0t0c+N/hy9GfhEP8Alj9a/o3LPgp+n6H85Yz/AHip6n0n +x3/AMnH/Dj/ALfv/SC7r57i/wD5F9T1X5o9nhn/AHn7/wAjzD4y/wDJYPih/wBjNq3/AKVPW/Cv +60zz85/3iQvwX/5LL8KP+xn0j/0qSlxX/ulX0Nci/3qB+0Gpf8AJyfxC/7EXwv/AOnDX6/CZbs/ oWh8COxqS1uFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFA BQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAF ABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUA FABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQB5VqXx4+B 2j3+o6Vqvxl8DWeqWUz2tzaXfiGxjmt50fY6yI7/ACOlAFP/AIaH/Z+/6Lr8Pv8Awp7H/wCPUAH/ AA0P+z9/0XX4ff8AhT2P/wAeoAP+Gh/2fv8Aouvw+/8ACnsf/j1AB/w0P+z9/wBF1+H3/hT2P/x6 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 JP8A5NoAP+FF+Cf+g58Qv/Di+JP/AJNoAP8AhRfgn/oOfEL/AMOL4k/+TaAD/hRfgn/oOfEL/wAO L4k/+TaAD/hRfgn/AKDnxC/8OL4k/wDk2gA/4UX4J/6DnxC/8OL4k/8Ak2gA/wCFF+Cf+g58Qv8A w4viT/5NoAP+FF+Cf+g58Qv/AA4viT/5NoAP+FF+Cf8AoOfEL/w4viT/AOTaAD/hRfgn/oOfEL/w 4viT/wCTaAD/AIUX4J/6DnxC/wDDi+JP/k2gA/4UX4J/6DnxC/8ADi+JP/k2gA/4UX4J/wCg58Qv /Di+JP8A5NoAP+FF+Cf+g58Qv/Di+JP/AJNoAP8AhRfgn/oOfEL/AMOL4k/+TaAD/hRfgn/oOfEL /wAOL4k/+TaAD/hRfgn/AKDnxC/8OL4k/wDk2gA/4UX4J/6DnxC/8OL4k/8Ak2gA/wCFF+Cf+g58 Qv8Aw4viT/5NoAP+FF+Cf+g58Qv/AA4viT/5NoAP+FF+Cf8AoOfEL/w4viT/AOTaAD/hRfgn/oOf EL/w4viT/wCTaAD/AIUX4J/6DnxC/wDDi+JP/k2gA/4UX4J/6DnxC/8ADi+JP/k2gA/4UX4J/wCg 58Qv/Di+JP8A5NoAP+FF+Cf+g58Qv/Di+JP/AJNoAP8AhRfgn/oOfEL/AMOL4k/+TaAD/hRfgn/o OfEL/wAOL4k/+TaAD/hRfgn/AKDnxC/8OL4k/wDk2gA/4UX4J/6DnxC/8OL4k/8Ak2gA/wCFF+Cf +g58Qv8Aw4viT/5NoAP+FF+Cf+g58Qv/AA4viT/5NoAP+FF+Cf8AoOfEL/w4viT/AOTaAD/hRfgn /oOfEL/w4viT/wCTaAD/AIUX4J/6DnxC/wDDi+JP/k2gA/4UX4J/6DnxC/8ADi+JP/k2gA/4UX4J /wCg58Qv/Di+JP8A5NoAP+FF+Cf+g58Qv/Di+JP/AJNoAP8AhRfgn/oOfEL/AMOL4k/+TaAD/hRf gn/oOfEL/wAOL4k/+TaAD/hRfgn/AKDnxC/8OL4k/wDk2gA/4UX4J/6DnxC/8OL4k/8Ak2gA/wCF F+Cf+g58Qv8Aw4viT/5NoAP+FF+Cf+g58Qv/AA4viT/5NoAP+FF+Cf8AoOfEL/w4viT/AOTaAD/h Rfgn/oOfEL/w4viT/wCTaAD/AIUX4J/6DnxC/wDDi+JP/k2gA/4UX4J/6DnxC/8ADi+JP/k2gA/4 UX4J/wCg58Qv/Di+JP8A5NoAP+FF+Cf+g58Qv/Di+JP/AJNoAP8AhRfgn/oOfEL/AMOL4k/+TaAD /hRfgn/oOfEL/wAOL4k/+TaAD/hRfgn/AKDnxC/8OL4k/wDk2gA/4UX4J/6DnxC/8OL4k/8Ak2gA /wCFF+Cf+g58Qv8Aw4viT/5NoAP+FF+Cf+g58Qv/AA4viT/5NoAP+FF+Cf8AoOfEL/w4viT/AOTa AD/hRfgn/oOfEL/w4viT/wCTaAD/AIUX4J/6DnxC/wDDi+JP/k2gA/4UX4J/6DnxC/8ADi+JP/k2 gDP1L9nv4caxYahpWq33jm80y/he1ubS78feJJIbiB02Mkkb3vzo9AHt9ABQAUAFABQBx2kc/tLf DzP/AEI3ij/04aBT2E1c+pvs8H/PJPyFa+0l3OZ4am/sr7gEMK/diUflQ6kn1BYeEdkj+bn4zf8A JYfih/2M2rf+lT1+58K/7rTPwHOP48hfgv8A8ll+FH/YzaR/6VJS4r/3Sr6F8P8A+9w9T9n9S/5O T+IX/Yi+F/8A04a/X4TLdn9BUfgR2NSWtwoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgA oAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACg AoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAC gAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKA CgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAK ACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoA KACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgDjtI/5OY+Hn/Yi+KP/AE4aBQB9XYHr WhNmGB60BZn5k+Kf+Cfz+LPFfifxa3xWWzl1nUZ9Q+ynQ932fzXd9nmfafn+/X2OV8aSy9WVO/zt +h8DjuCJYr/l4HhX9gCTwj4r8MeLV+Ky3jaLqMGofZBoez7R5To+zzPtPyf6ulmvGcsxi06dr+f/ AAB5fwTLBtS9psfRWqDH7SfxEX/qRfC//pw1+vjG7u599FcqSOvpDCgAoAKACgAoAKACgAoAKACg AoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAC gAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKA CgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAK ACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoA KACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAo AKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAOO0j/k5j4e f9iL4o/9OGgUAfWNWAUAVxGnYYqb+02MvZRhuBjQ9RRfk3BU4yPlfVf+TmfiF/2Ivhf/ANOGv0jU 7CgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoA KACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAo AKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgA oAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACg AoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAC gAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKA CgAoAKACgAoAKACgDjtI/wCTmPh5/wBiL4o/9OGgUAfWNWAUAFABQB8nav8A8nMfEP8A7EXwv/6c NfqAOxoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgA 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 ALpV9DXIv96gftBqX/JyfxC/7EXwv/6cNfr8Jluz+haHwI7GpLW4UAFABQAUAFABQAUAFABQAUAF ABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUA FABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAU AFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQA UAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQ AUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAB QAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABTYo7nDWf/ACcl 4B/7EPxR/wCnDQK1pbo58b/Dl6M/CIf8sfrX9G5Z8FP0/Q/nLGf7xU9T6T/Y7/5OP+HH/b9/6QXd fPcX/wDIvqeq/NHs8M/7z9/5HmHxl/5LB8UP+xm1b/0qet+Ff91pnn5z/vEhfgv/AMll+FH/AGM+ kf8ApUlLiv8A3Sr6GuRf71A/aDUv+Tk/iF/2Ivhf/wBOGv1+Ey3Z/QtD4EdjUlrcKACgAoAKACgA oAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACg AoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAC gAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKA CgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAK ACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoA KACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAp 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 xfEn/wAm0AH/AAovwT/0HPiF/wCHF8Sf/JtAB/wovwT/ANBz4hf+HF8Sf/JtAB/wovwT/wBBz4hf +HF8Sf8AybQAf8KL8E/9Bz4hf+HF8Sf/ACbQAf8ACi/BP/Qc+IX/AIcXxJ/8m0AH/Ci/BP8A0HPi F/4cXxJ/8m0AH/Ci/BP/AEHPiF/4cXxJ/wDJtAB/wovwT/0HPiF/4cXxJ/8AJtAB/wAKL8E/9Bz4 hf8AhxfEn/ybQAf8KL8E/wDQc+IX/hxfEn/ybQAf8KL8E/8AQc+IX/hxfEn/AMm0AH/Ci/BP/Qc+ IX/hxfEn/wAm0AH/AAovwT/0HPiF/wCHF8Sf/JtAB/wovwT/ANBz4hf+HF8Sf/JtAB/wovwT/wBB z4hf+HF8Sf8AybQAf8KL8E/9Bz4hf+HF8Sf/ACbQAf8ACi/BP/Qc+IX/AIcXxJ/8m0AH/Ci/BP8A 0HPiF/4cXxJ/8m0AH/Ci/BP/AEHPiF/4cXxJ/wDJtAB/wovwT/0HPiF/4cXxJ/8AJtAB/wAKL8E/ 9Bz4hf8AhxfEn/ybQAf8KL8E/wDQc+IX/hxfEn/ybQAf8KL8E/8AQc+IX/hxfEn/AMm0AH/Ci/BP /Qc+IX/hxfEn/wAm0AH/AAovwT/0HPiF/wCHF8Sf/JtAB/wovwT/ANBz4hf+HF8Sf/JtAB/wovwT /wBBz4hf+HF8Sf8AybQAf8KL8E/9Bz4hf+HF8Sf/ACbQAf8ACi/BP/Qc+IX/AIcXxJ/8m0AH/Ci/ BP8A0HPiF/4cXxJ/8m0AH/Ci/BP/AEHPiF/4cXxJ/wDJtAB/wovwT/0HPiF/4cXxJ/8AJtAB/wAK L8E/9Bz4hf8AhxfEn/ybQAf8KL8E/wDQc+IX/hxfEn/ybQAf8KL8E/8AQc+IX/hxfEn/AMm0AH/C i/BP/Qc+IX/hxfEn/wAm0AH/AAovwT/0HPiF/wCHF8Sf/JtAB/wovwT/ANBz4hf+HF8Sf/JtAB/w ovwT/wBBz4hf+HF8Sf8AybQAf8KL8E/9Bz4hf+HF8Sf/ACbQAf8ACi/BP/Qc+IX/AIcXxJ/8m0AH /Ci/BP8A0HPiF/4cXxJ/8m0AH/Ci/BP/AEHPiF/4cXxJ/wDJtAB/wovwT/0HPiF/4cXxJ/8AJtAB /wAKL8E/9Bz4hf8AhxfEn/ybQAf8KL8E/wDQc+IX/hxfEn/ybQAf8KL8E/8AQc+IX/hxfEn/AMm0 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 gAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKA CgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAK ACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoA KACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAo AKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKbFHc 4az/AOTkvAP/AGIfij/04aBWtLdHPjf4cvRn4RD/AJY/Wv6Nyz4Kfp+h/OWM/wB4qep9J/sd/wDJ x/w4/wC37/0gu6+e4v8A+RfU9V+aPZ4Z/wB5+/8AI8v+Mf8AyWL4of8AYzav/wClT1vwr/utM5M4 /jyH/Bf/AJLL8KP+xm0j/wBKkpcV/wC6VfQvh/8A3uHqfs/qX/JyfxC/7EXwv/6cNfr8Jluz+gqH wI7GpLW4UAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAB QAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFA BQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAF ABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUA FABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAU AFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQA UAFABQAUAFABQAUAFABTYo7nDWf/ACcl4B/7EPxR/wCnDQK1pbo58b/Dl6M/CIf8sfrX9G5Z8FP0 /Q/nLGf7xU9T6T/Y7/5OP+HH/b9/6QXdfPcX/wDIvqeq/NHs8M/7z9/5HmPxm/5LD8UP+xm1b/0q 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 WxWDxMWfsGgwqj2r4Dc/T4KysKOgoLFqACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAC gAoAKACgAoAKACgAoAKACgAoAKACgAqrAFFgCiwBRYAosAUWAKLAFFgCiwBRYAosAUWAKLAFFgCi wBRYAosAUWAKLAFFgCiwBRYAosAUWAKLAFFgCiwBRYAosAUWAKLAFFgCiwBRYAosAUWAKLAFFgCi wBRYAosAUWAKLAFFgCiwBRYAosAUWAKLAFFgCiwBRYAosAUWAKLAFFgCiwBRYAosAUWAKLAFFgCi wBRYAosAUWAKLAFFgCiwBRYAosAUWAKkAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAo AKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgA oAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACg AoAKACgAoAKACgAoAKACgAoAKACrAKACgAoAMD0qbMAoswCqAKACgAoAKACgAoAKACgAoAKACgAo AKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgA oAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACg AoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAC gAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKA CgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAK ACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgBmDQK4YNAX H0DCgD82PE2iS+I/jB8dBfeL/HNtb6X4isrOztNE8YaxpVtawf2LpU+1ILW6RP8AWTzv9z+OgCT/ AIQaD/ofPiX/AOHF8Sf/ACbQAf8ACDQf9D58S/8Aw4viT/5NoAP+EGg/6Hz4l/8AhxfEn/ybQAf8 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 HvAv/hP2P/xFAB/wor4Jf9Ee8C/+E/Y//EUAH/Civgl/0R7wL/4T9j/8RQAf8KK+CX/RHvAv/hP2 P/xFAB/wor4Jf9Ee8C/+E/Y//EUAH/Civgl/0R7wL/4T9j/8RQAf8KK+CX/RHvAv/hP2P/xFAB/w or4Jf9Ee8C/+E/Y//EUAH/Civgl/0R7wL/4T9j/8RQAf8KK+CX/RHvAv/hP2P/xFAB/wor4Jf9Ee 8C/+E/Y//EUAH/Civgl/0R7wL/4T9j/8RQAf8KK+CX/RHvAv/hP2P/xFAB/wor4Jf9Ee8C/+E/Y/ /EUAH/Civgl/0R7wL/4T9j/8RQAf8KK+CX/RHvAv/hP2P/xFAB/wor4Jf9Ee8C/+E/Y//EUAH/Ci vgl/0R7wL/4T9j/8RQAf8KK+CX/RHvAv/hP2P/xFAB/wor4Jf9Ee8C/+E/Y//EUAH/Civgl/0R7w L/4T9j/8RQAf8KK+CX/RHvAv/hP2P/xFAB/wor4Jf9Ee8C/+E/Y//EUAH/Civgl/0R7wL/4T9j/8 RQAf8KK+CX/RHvAv/hP2P/xFAB/wor4Jf9Ee8C/+E/Y//EUAH/Civgl/0R7wL/4T9j/8RQAf8KK+ CX/RHvAv/hP2P/xFAB/wor4Jf9Ee8C/+E/Y//EUAH/Civgl/0R7wL/4T9j/8RQAf8KK+CX/RHvAv /hP2P/xFAB/wor4Jf9Ee8C/+E/Y//EUAH/Civgl/0R7wL/4T9j/8RQAf8KK+CX/RHvAv/hP2P/xF AB/wor4Jf9Ee8C/+E/Y//EUAH/Civgl/0R7wL/4T9j/8RQAf8KK+CX/RHvAv/hP2P/xFAB/wor4J f9Ee8C/+E/Y//EUAH/Civgl/0R7wL/4T9j/8RQAf8KK+CX/RHvAv/hP2P/xFAB/wor4Jf9Ee8C/+ E/Y//EUAH/Civgl/0R7wL/4T9j/8RQAf8KK+CX/RHvAv/hP2P/xFAB/wor4Jf9Ee8C/+E/Y//EUA H/Civgl/0R7wL/4T9j/8RQAf8KK+CX/RHvAv/hP2P/xFAB/wor4Jf9Ee8C/+E/Y//EUAH/Civgl/ 0R7wL/4T9j/8RQAf8KK+CX/RHvAv/hP2P/xFAB/wor4Jf9Ee8C/+E/Y//EUAH/Civgl/0R7wL/4T 9j/8RQAf8KK+CX/RHvAv/hP2P/xFAB/wor4Jf9Ee8C/+E/Y//EUAH/Civgl/0R7wL/4T9j/8RQAf 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 94F/8J+x/wDiKAD/AIUV8Ev+iPeBf/Cfsf8A4igA/wCFFfBL/oj3gX/wn7H/AOIoAP8AhRXwS/6I 94F/8J+x/wDiKAD/AIUV8Ev+iPeBf/Cfsf8A4igA/wCFFfBL/oj3gX/wn7H/AOIoAP8AhRXwS/6I 94F/8J+x/wDiKAD/AIUV8Ev+iPeBf/Cfsf8A4igA/wCFFfBL/oj3gX/wn7H/AOIoAP8AhRXwS/6I 94F/8J+x/wDiKAD/AIUV8Ev+iPeBf/Cfsf8A4igA/wCFFfBL/oj3gX/wn7H/AOIoAP8AhRXwS/6I 94F/8J+x/wDiKAD/AIUV8Ev+iPeBf/Cfsf8A4igA/wCFFfBL/oj3gX/wn7H/AOIoAP8AhRXwS/6I 94F/8J+x/wDiKAD/AIUV8Ev+iPeBf/Cfsf8A4igA/wCFFfBL/oj3gX/wn7H/AOIoAP8AhRXwS/6I 94F/8J+x/wDiKAD/AIUV8Ev+iPeBf/Cfsf8A4igA/wCFFfBL/oj3gX/wn7H/AOIoAP8AhRXwS/6I 94F/8J+x/wDiKAD/AIUV8Ev+iPeBf/Cfsf8A4igA/wCFFfBL/oj3gX/wn7H/AOIoAP8AhRXwS/6I 94F/8J+x/wDiKAD/AIUV8Ev+iPeBf/Cfsf8A4igA/wCFFfBL/oj3gX/wn7H/AOIoAP8AhRXwS/6I 94F/8J+x/wDiKAD/AIUV8Ev+iPeBf/Cfsf8A4igA/wCFFfBL/oj3gX/wn7H/AOIoAP8AhRXwS/6I 94F/8J+x/wDiKAD/AIUV8Ev+iPeBf/Cfsf8A4igA/wCFFfBL/oj3gX/wn7H/AOIoAP8AhRXwS/6I 94F/8J+x/wDiKAD/AIUV8Ev+iPeBf/Cfsf8A4igA/wCFFfBL/oj3gX/wn7H/AOIoAP8AhRXwS/6I 94F/8J+x/wDiKAD/AIUV8Ev+iPeBf/Cfsf8A4igA/wCFFfBL/oj3gX/wn7H/AOIoAP8AhRXwS/6I 94F/8J+x/wDiKAD/AIUV8Ev+iPeBf/Cfsf8A4igA/wCFFfBL/oj3gX/wn7H/AOIoAP8AhRXwS/6I 94F/8J+x/wDiKAD/AIUV8Ev+iPeBf/Cfsf8A4igA/wCFFfBL/oj3gX/wn7H/AOIoAP8AhRXwS/6I 94F/8J+x/wDiKAD/AIUV8Ev+iPeBf/Cfsf8A4igA/wCFFfBL/oj3gX/wn7H/AOIoAP8AhRXwS/6I 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 ABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUA FABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAU AFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQA UAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABTYo7m78B/wDktHxq/wCxU8Mf+lmv1rS3Rz43 +HL0Z+Ha9Iq/o7LP4cPQ/nTHf7xU9T6X/Y9/5OP+HX/b9/6QXVfOcW/8i6p6x/NHrcMf719/5Hlv xl/5LB8UP+xm1b/0qeujhX/daZwZz/vEhfgv/wAll+FH/Yz6R/6VJS4r/wB0q+hrkX+9QP1Hn/5K 9+0T/wBjVZf+o9o9fhMt2f0LQ+BG1UlrcKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAK ACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoA KACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAo AKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgA oAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACg AoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAC gAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgApsUdzc+BH/JaPjV/2Knhj/0s1+taW6Of G/w5ejPw8XpFX9H5bZU6d+36H86Y5XxFT1Ppf9j3/k4/4df9v3/pBdV81xc/+E+p6x/NHrcMf719 /wCR5b8Zf+SwfFD/ALGbVv8A0qeunhX/AHWmcGc/7xIX4L/8ll+FH/Yz6R/6VJS4r/3Sr6GuRf71 A/Uef/kr37RP/Y1WX/qPaPX4TLdn9C0PgRtVJa3CgAoAKACgAoHYKAsFAgoAKACgAoAKACgAoAKA CgAoAKACgAoA8W1W/wDiTqXxT8SeHfCPirRNN0fTvD2kXvka3ocmpfv57rUUZo5Eurd0/d2iff3/ APAPn3gGt/Y/xt/6KJ4G/wDCOvv/AJaUAH9j/G3/AKKJ4G/8I6+/+WlAB/Y/xt/6KJ4G/wDCOvv/ AJaUAH9j/G3/AKKJ4G/8I6+/+WlAB/Y/xt/6KJ4G/wDCOvv/AJaUAH9j/G3/AKKJ4G/8I6+/+WlA B/Y/xt/6KJ4G/wDCOvv/AJaUAH9j/G3/AKKJ4G/8I6+/+WlAB/Y/xt/6KJ4G/wDCOvv/AJaUAH9j /G3/AKKJ4G/8I6+/+WlAB/Y/xt/6KJ4G/wDCOvv/AJaUAH9j/G3/AKKJ4G/8I6+/+WlAB/Y/xt/6 KJ4G/wDCOvv/AJaUAH9j/G3/AKKJ4G/8I6+/+WlAB/Y/xt/6KJ4G/wDCOvv/AJaUAH9j/G3/AKKJ 4G/8I6+/+WlAB/Y/xt/6KJ4G/wDCOvv/AJaUAH9j/G3/AKKJ4G/8I6+/+WlAB/Y/xt/6KJ4G/wDC Ovv/AJaUAH9j/G3/AKKJ4G/8I6+/+WlAB/Y/xt/6KJ4G/wDCOvv/AJaUAH9j/G3/AKKJ4G/8I6+/ +WlAB/Y/xt/6KJ4G/wDCOvv/AJaUAH9j/G3/AKKJ4G/8I6+/+WlAB/Y/xt/6KJ4G/wDCOvv/AJaU AH9j/G3/AKKJ4G/8I6+/+WlAB/Y/xt/6KJ4G/wDCOvv/AJaUAH9j/G3/AKKJ4G/8I6+/+WlAB/Y/ xt/6KJ4G/wDCOvv/AJaUAH9j/G3/AKKJ4G/8I6+/+WlAB/Y/xt/6KJ4G/wDCOvv/AJaUAH9j/G3/ AKKJ4G/8I6+/+WlAB/Y/xt/6KJ4G/wDCOvv/AJaUAH9j/G3/AKKJ4G/8I6+/+WlAB/Y/xt/6KJ4G /wDCOvv/AJaUAH9j/G3/AKKJ4G/8I6+/+WlAB/Y/xt/6KJ4G/wDCOvv/AJaUAH9j/G3/AKKJ4G/8 I6+/+WlAB/Y/xt/6KJ4G/wDCOvv/AJaUAH9j/G3/AKKJ4G/8I6+/+WlAB/Y/xt/6KJ4G/wDCOvv/ AJaUAH9j/G3/AKKJ4G/8I6+/+WlAB/Y/xt/6KJ4G/wDCOvv/AJaUAH9j/G3/AKKJ4G/8I6+/+WlA B/Y/xt/6KJ4G/wDCOvv/AJaUAH9j/G3/AKKJ4G/8I6+/+WlAB/Y/xt/6KJ4G/wDCOvv/AJaUAH9j /G3/AKKJ4G/8I6+/+WlAB/Y/xt/6KJ4G/wDCOvv/AJaUAH9j/G3/AKKJ4G/8I6+/+WlAB/Y/xt/6 KJ4G/wDCOvv/AJaUAH9j/G3/AKKJ4G/8I6+/+WlAB/Y/xt/6KJ4G/wDCOvv/AJaUAH9j/G3/AKKJ 4G/8I6+/+WlAB/Y/xt/6KJ4G/wDCOvv/AJaUAH9j/G3/AKKJ4G/8I6+/+WlAB/Y/xt/6KJ4G/wDC Ovv/AJaUAH9j/G3/AKKJ4G/8I6+/+WlAB/Y/xt/6KJ4G/wDCOvv/AJaUAH9j/G3/AKKJ4G/8I6+/ +WlAB/Y/xt/6KJ4G/wDCOvv/AJaUAH9j/G3/AKKJ4G/8I6+/+WlAB/Y/xt/6KJ4G/wDCOvv/AJaU AH9j/G3/AKKJ4G/8I6+/+WlAB/Y/xt/6KJ4G/wDCOvv/AJaUAH9j/G3/AKKJ4G/8I6+/+WlAB/Y/ xt/6KJ4G/wDCOvv/AJaUAH9j/G3/AKKJ4G/8I6+/+WlAB/Y/xt/6KJ4G/wDCOvv/AJaUAH9j/G3/ AKKJ4G/8I6+/+WlAB/Y/xt/6KJ4G/wDCOvv/AJaUAH9j/G3/AKKJ4G/8I6+/+WlAB/Y/xt/6KJ4G /wDCOvv/AJaUAH9j/G3/AKKJ4G/8I6+/+WlAB/Y/xt/6KJ4G/wDCOvv/AJaUAH9j/G3/AKKJ4G/8 I6+/+WlAB/Y/xt/6KJ4G/wDCOvv/AJaUAH9j/G3/AKKJ4G/8I6+/+WlAB/Y/xt/6KJ4G/wDCOvv/ AJaUAH9j/G3/AKKJ4G/8I6+/+WlAGn8KNb1XxJ8Lfhl4i1y7+06xqnh7Tr29n2Rx+bO9qjs/lp8n +segD0CgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKA CgAoAKACgAoAKAPmv4UfDfR/Enws+GXiPXfEHjq51jVPD2nXl7P/AMJtrsfmTvao7v5aXWz78lAH oH/CnPCX/QY8c/8Ahca//wDJtAB/wpzwl/0GPHP/AIXGv/8AybQAf8Kc8Jf9Bjxz/wCFxr//AMm0 AH/CnPCX/QY8c/8Ahca//wDJtAB/wpzwl/0GPHP/AIXGv/8AybQAf8Kc8Jf9Bjxz/wCFxr//AMm0 AH/CnPCX/QY8c/8Ahca//wDJtAB/wpzwl/0GPHP/AIXGv/8AybQAf8Kc8Jf9Bjxz/wCFxr//AMm0 AH/CnPCX/QY8c/8Ahca//wDJtAB/wpzwl/0GPHP/AIXGv/8AybQAf8Kc8Jf9Bjxz/wCFxr//AMm0 AH/CnPCX/QY8c/8Ahca//wDJtAB/wpzwl/0GPHP/AIXGv/8AybQAf8Kc8Jf9Bjxz/wCFxr//AMm0 AH/CnPCX/QY8c/8Ahca//wDJtAB/wpzwl/0GPHP/AIXGv/8AybQAf8Kc8Jf9Bjxz/wCFxr//AMm0 AH/CnPCX/QY8c/8Ahca//wDJtAB/wpzwl/0GPHP/AIXGv/8AybQAf8Kc8Jf9Bjxz/wCFxr//AMm0 AH/CnPCX/QY8c/8Ahca//wDJtAB/wpzwl/0GPHP/AIXGv/8AybQAf8Kc8Jf9Bjxz/wCFxr//AMm0 AH/CnPCX/QY8c/8Ahca//wDJtAB/wpzwl/0GPHP/AIXGv/8AybQAf8Kc8Jf9Bjxz/wCFxr//AMm0 AH/CnPCX/QY8c/8Ahca//wDJtAB/wpzwl/0GPHP/AIXGv/8AybQAf8Kc8Jf9Bjxz/wCFxr//AMm0 AH/CnPCX/QY8c/8Ahca//wDJtAB/wpzwl/0GPHP/AIXGv/8AybQAf8Kc8Jf9Bjxz/wCFxr//AMm0 AH/CnPCX/QY8c/8Ahca//wDJtAB/wpzwl/0GPHP/AIXGv/8AybQAf8Kc8Jf9Bjxz/wCFxr//AMm0 AH/CnPCX/QY8c/8Ahca//wDJtAB/wpzwl/0GPHP/AIXGv/8AybQAf8Kc8Jf9Bjxz/wCFxr//AMm0 AH/CnPCX/QY8c/8Ahca//wDJtAB/wpzwl/0GPHP/AIXGv/8AybQAf8Kc8Jf9Bjxz/wCFxr//AMm0 AH/CnPCX/QY8c/8Ahca//wDJtAB/wpzwl/0GPHP/AIXGv/8AybQAf8Kc8Jf9Bjxz/wCFxr//AMm0 AH/CnPCX/QY8c/8Ahca//wDJtAB/wpzwl/0GPHP/AIXGv/8AybQAf8Kc8Jf9Bjxz/wCFxr//AMm0 AH/CnPCX/QY8c/8Ahca//wDJtAB/wpzwl/0GPHP/AIXGv/8AybQAf8Kc8Jf9Bjxz/wCFxr//AMm0 AH/CnPCX/QY8c/8Ahca//wDJtAB/wpzwl/0GPHP/AIXGv/8AybQAf8Kc8Jf9Bjxz/wCFxr//AMm0 AH/CnPCX/QY8c/8Ahca//wDJtAB/wpzwl/0GPHP/AIXGv/8AybQBxfjzwHpXg/S9D1/w/wCIPGEO op4k8PW/+l+L9au45Un1e2gmR4J7p0dHSR0+dP46APoigAoAKACgAoYQ3Nr4E/8AJafjX/2Kvhj/ ANLNfrWl8SOXH605ejPxDPlPJD61/RGFUatODXY/nbGKtSrVF5n0r+yII2/aR+GggHOdQ5/7h9zX g8YuMcukl3X5o9HhWnWeLu/P8jyr4y/8lg+KH/Yzat/6VPXVwr/utM5M5/3iQvwX/wCSy/Cj/sZ9 I/8ASpKXFf8AulX0Nci/3qB+o8//ACV79on/ALGqy/8AUe0evwmW7P6FofAjaqS1uFABQAUAFAH4 z+M/2kP2s7z4v/FDwV8Ntd1XUrfRNc1G3ttM0jw9aX0lvbQXTov/AC6u+xPkTe9BrYpw/tRftkfD TVNC8T/FHRdbm8HrepbzWHiHw2mkw3+9H/cpOlqjo/l73T/c+46fJQFj9UPg/wDGDwj8b/CH/CZe Dft6WCXj2U1pqcPkTQTpsfZJs3p/q3jf5Hf79BkeqUAFABQB8r+Kv2qPDHhj9oTw38CJ9K87+0fI hvdf86SP7Bezq7ww+R9n+ff5lp8+/Z+//wBh6ALniT9rH4ceFfjJb/A/UtG8SP4snv7LT1u7e2g+ yb7tYHX959o37P36b/koA7z43/GPw/8AA3wHeeNfEFpPeS+d9isNOg+/f3bq7xpv/gT5JHd/7ifx vsjcA6D4V/ELSvip8PPCXj/Rk8mz1ez+0PB+8k8idPkmt/MdE37HSRN+z5/LoA9AoAKACgAoAKAC gDyzR/8Akt3xE/7FTw9/6W63QB6nQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFA BQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAF ABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAeWfAr/AJIj8G/+ xU0f/wBIkoA9ToAKACgAoA/MP4nftXeO/hd+1veeFdd8Sb/g/YXllDeab9jg/cQT2cG6belu877J J/P2fx7NlAH6eUAfF/7bHxs8T/BzwR4P/wCEE8Tf2P401fVfk/0KO7+0WUED+f8A65HRPne0/wBv /wAfoA9U/Zd8beJ/iL8CvA/jHxlqX2/xJqH237Td+THB5my8nRfkRET7kaUAe+UAFABQAUAeQW3x 1+Gs3xT1H4LSazPbfEOCbYmmT2Unl3SfY0ud0c6Js2eXJ/G6PvR/9jeAeHftsfEX4m/CjwR4P8Zf Djxr/Y+/Vf7LvbT+zLS7+1+fC7xv5k6Ps2eQ/wDv+f8A7FAH0h8KNb1XxJ8Lfhl4i1y7+06xqnh7 Tr29n2Rx+bO9qjs/lp8n+segDg/2ovG3if4dfArxx4x8G6l9g8Saf9i+zXfkxz+XvvIEb5HR0+5I 9AHn37FvxS8d/Fr4Wa/4j+Ieu/2rrFt4gnsYZ/s0EHlQJa2z7PLhRE/1kklAH17QAUAVL9L17K8T TbiC21B4X+zT3cPnpE//ACzaSPem9P8AY3p/v0AfB/7Dfxs+Jvxj/wCFn/8ACx/E/wDbH9kf2d9i /wBDtLT7P5/2vd/qETf/AKtKAPvugAoAKACgAoAKACgAoAKACgAoAKACgAoAKAPLPgV/yRH4N/8A YqaP/wCkSUAep0AFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQA UAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAHlnxk/wCR R0f/ALGrwv8A+nqwoA9ToAKACgAoAKGSnqbvwEXd8a/jSv8A1Kvhf/0s1+rg7O5liY88Wj4jT/gn 18cPMZf7c8I8f9P95/8AGa/SsNxnRoUoq2x+XYrhHFV8TJ9z1L4F/sh/FD4V/Fnw1418Sar4an0b TDc+fJp99eNLh7aWBNqNbquN8nPzV5+ZcVUsxwsoNdvzOnAcL4rA100fBXxl/wCSwfFD/sZtW/8A Sp6+84W/3WmfA5z/ALxIX4L/APJZfhR/2M+kf+lSUuKv90qehrkP+9w9T9R5/wDkr37RP/Y1WX/q PaPX4TLdn9C0PgRtVJa3CgAoAKACgD8rv2Wv+T3f2i/+47/6doKCj7p/aN0TSvEPwH+LllrVp51m nh+9vUj3yR/v7RPPhb5P7jwRvQB8L/8ABM3r8av+4R/7f0DOg8f/ALfOq/2tJqHwc+Hk+t/DzQpk /wCEg13V7OeOOVHuNi+XIn/Hqj+X8jz/ALx3f7nyfOAfWnwN/aN+Hvx40uP/AIR+++x+MILRLrUf DV3/AK60+bZ+7k+5Mm/+NP7679jvsoJseJ/Dr9rHxF8YPj7b+Dfhz4O+0/Bu03wX/iWewnkm3+TO 6zeZu2WqPJHGiI6b3/2HfYgFiD4nfHXwron7TfhP4beJv2fNJ1XXXv8ASLPSvG+pPH50STunlzQb 7V32QTvP9x/vo/3KCkfmr4/+N9l4q/aU/wCF6ab4flTTrTXNO1C20i6m8t50svIRfMf+B38j/b2b /wCOg1P0R1L9rqx8Yfs8ax8Uda+BkWt6AniRNCv/AA9d3/2u1iTyEnW6nke12bPPeBPnT77p89Bk e6fC74zfD22/Z40P4v32gWHgPwGnn79O06Hz4bD/AE17b93HDbp99/n+RP46APkTWP29vipYapH4 1g+Df/Fjrm9e106/v7a7tJr/AOV0/wCP754N+9HfYiP9x0/g30Afc2lfHjwN4h+Eeo/Gbwql/rHh vTrN7q8sLDyPttp5Sb5keN3REdI/n2b/AJ0+5v3pvAPANB/bt8C+IfB+mXGi+ENb1X4s6j56L4A8 PW099NE6ee675/s6I6bER32I7pv+4+x6AO0/Zv8A2sfD/wC0Df67oH/COzeHvFenQ/bksJLn7XHc WnyJuSfYnzpI8fybP+WibN/z7AD60oICgDyzR/8Akt3xE/7FTw9/6W63QB6nQAUAFABQAUAFABQA UAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQ AUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAB QAUAFABQAUAFABQAUAeWfAr/AJIj8G/+xU0f/wBIkoA9ToAKACgAoA/Aj9tj/k5v4m/9w7/032lB dM/S79h74o3HxC+CenaPqVxE+ueEJv7FeOOaPzJLZFj+ys8aJ8ieX+4/2/szPv8Av0BM/Pj9vD4h f8Jn8cbzw/ZXfnaP4Qs00tfIvfPhkuX/AH8z+X9xH8ySOB/+vT/gCBR+gH7Lvjbwz8Ov2PPA/jLx lqP2Dw3p3237Td+TJP5e/VJ0X92iO/8ArHjoA8T/AOHlmh/235H/AAqO/wD+Eb+27ft39sR/afs2 77/keTs3+X/B5/8AwP8AjoJPse2/aE8B6l8G9R+NnhyDVdb8L2UO+8sNIto5NQtH3p5ySQb/AJHg 8ze/z+Xs+f502PQB886r/wAFBfhrbeCNQ8VaP4cv7nWH1X+z9N8NXdzHBdXECW8DvdT7N6QpvnkR Pv79n+/sANP4OftvaF8Tv+Fgf214Av8ARP8AhF/D934kf7Jfx3/2q0tv9cvzpDsf95Hs/v8Az/On 8YB8RP8AtV+FdE/ad8afHvRfAE+t6dqlhBY2Fhq80djc2D/Z7SCSbeiTbH/cTp8n8E//AACgD3b9 q74l/wDC4/2RPhh8R/7C/sf+1/FX/Hh9p+1+R5S6jB/rNib/ALm/7lAHTa9+238Pfgnongf4ZeA7 L/hYX/CPaVBpd5rcFz/ZtrvtlSD5Pkffv8uR/k+T502O/wDAAd18Y/iRY/Hv9ijxr418K6dP9onh tvtukQN9rm0t4LyB5lfZ/AkaefvfZ+42vsSgDyr9j/4qeFfgz+y7448b+LpJ30+Dxg8KWlp5f2m7 d7WwTbBG7pvf/WP/ALiPQXI/STwl4ksvGHhfw34t01J4dO1uwg1C2ju4/LeJJ0R18z/b+egyR4v8 EP2nPhx8e7/xBpvhK31Ww1HSIUnktNZWCCSdH3pugjSZ96J8m/8A30/v0GjPoigg/Hv9hLxzY/Df wV+0Z441HStV1LTtIh0Sa5tNEtvPu9m67Rn2b0+RPvv/AHER6C2fTn/DfPwh/wCEI8QeL4rW/TU4 L17XR/DM7x/bdU2QQPufZvS1TfO6b3d/kgd03v8AJQZsufAH9tXw/wDGzxp/wgmo+DpfDeu3MLtp vl3v26O6dEd2WR/JTY/lx7/7j+W/3Pk3hR0H7T/7V2lfAH+z/DmlaH/bHjzVLKS6hgnaSC2sIPnR ZpJP4/nj/wBQn9x/nT5N4Afs3/tUf8Lp1STwV4k8EX/h7x5Y6Umrzf8APld2m202zJv+dN/2qN0T 5/k2/O9AHj/j/wD4KL+CtB8QS6f4E8FS+KtCSFP+J3Pfyaakr/xLHA8LvsT+++z59/yfxuAfSnwE /aW8B/H6yvE0OOfSvFenQpJf6FfvHviT5NzQP/y2g3ybN/yP9zeib0oA83tv28/gen/CUweILXxX 4e1jSN6/2VrOleXd3U6b91vHGjuiP5kez9+6ff8A9/YAcR4A/wCChHgPxb48i8MeI/Cs/hjwtczP DZ+Jb+/jkj37v3P2uPZ+5R/7+90R/wDY3ugAfFH/AIKEeA/B/iGfw/4H8Ky+MI7KZ7e51eO/jsbW V/k/49H2P5yf6z59iJ8nyb0ffQB9geGPi14L8VfC+D4vWF9LD4L+wT6hNNd20m+1SLf529E/jTZI nyb/ALnyb6CbHwtqX7fPip7/AFjxl4R+B+q6r8GNOhS1fV7vzLR4735P9fdok0CJ88aeR9/50ff8 +ygLH3h8Mfid4Q+LvhCw8a+CtS+06Zc/K8EnyTWs/wDFbzp/A6f/AGab0dHoEegUAFABQB5Z8Cv+ SI/Bv/sVNH/9IkoA9ToAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoA KACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAPLPj J/yKOj/9jV4X/wDT1YUAep0AFABQAUAFAHRfs/f8lv8AjP8A9ir4X/8ASzX6APs6nZgJgUWA/mt+ Mf8AyWH4o/8AYzat/wClUlfu/C7SwtO5/OecJvESHfBj/ksvwp/7GfSP/SpKXFLTwlS3Y1yJNYqH qfqPP/yV79on/sarL/1HtHr8Kluz+hKHwI2qktbhQAUAFABQB+F2j/HL/hQP7Uvx48Zf8Iz/AG99 t1XW9M+yfbPsnlb9Q37t+x/+eH/j9BpZHqnjn9vnXPiX4P8AEnw48OfB3ydY8UWb6LDJ/asl9J/p P7hlSBIUd32SOifP9/Z9/wC5QOyINB+F3xJ/Z+/ZG+NHi/WreWw13x5Dp1lJp3kx+ZpNl5zwM11v f788d3ImxEd03r9z5/ICT78/Zs8AeFfD37PHw+0CDSornTtf0SDUNSju4Y5Pt73sKPN5/wAnzp+8 2fP/AMs0VKAPgv4e+Hrr4aft9eKfh74V1j+zdL1v+0bdpNMsoI/sttd2T6isECOjonkSeRs+T/lh 9zY/l0Fcps/sr/GDxb8B/GGj/s4fFTwJ/Y9vreqv9i1Oe28iaKefzIF+4j/bUedERJ9/yf33RE2A cp638TrCx1L/AIKCfAe31GxguYE8NvMsc6eYm9P7VeNv99HjjdP9tKBI+Y/jH/ykJ0f/ALGvwv8A +i7Cg0Pv39tn/k2P4mf9w3/04WlBkz41+Myaz8Ov2D/gn4S0+4nudO8SzW1zf38cMEabJ/P1FbWT e+/fveP50/59n37N+xwD9PfCvgDwr4S8B6Z8NdP0qKbwnZWH9nvaXcMci3abNjeemzY7v87v8nzu 7UAfkf8ACv8A4pLxv+3T8ONA/wBD8FweFfFG2x/1n/HlcPBa/O/z/Ik86ff/AI/noA+h/wDgm54b srb4d/EHxbFLP/aOqa4mnzRyN8kSW0KOvl/7f+lP/wCO0AcBZWFlpv8AwUxlt9PsYraB5nmeOCPy 4976E7s/++8kkjv/ALb0Afq5QQFAHlmj/wDJbviJ/wBip4e/9LdboA9ToAKACgAoAKACgAoAKACg AoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAC gAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKA CgAoAKACgAoAKAPLPgV/yRH4N/8AYqaP/wCkSUAep0AFABQAUAfk3r2iaV4k/wCCjWseHddtPtOj 6pZT2V7Bukj82B/Dexl3p8/+reguman7Emm678Lv2gfjj8Fr5N9naWTzNc3dtJBPcfYrpEhuI03/ ACRzpfO/8f8AB8/98CZ8IeM7C+8eWXxM+Oz2M+m6dqHjH7PDaSL5kcr3v2+7ZEn+Te8HkR/wf8t0 +5QUfVHjPxPfaP8A8E+fg/oFjcTpFrut3Nve+XbeYktpBeXs+ySfZsR/Pjgf76O+xv4EegD9I/Df 7P3gPQfgnL8DvsMD6Fe2H2XUbuC2jje6u3X5rz59/wC/3xo6ff2bF2fcSgk+AvgDo994P+Hf7e/w 4k1qW/0/w1YXtlD5n7uOR0h1GBrhIN/yO/kJ/wB8L/coA9B/4J3fDrwVeeDdd+Jt14egm8eWWuXe l22rzvJI9vafZbR9qR/cR/3j/Ps8zy3dPuUAWPgX4M0LwB+3X8b/AAx4bg8nR08PPdQwbY447f7S 2nXLJGiIiJGjzuiJ/c2UAdb8Pf8AlIT8df8AsVYP/QNKoAP+CjX/ACRDwr/2Ndp/6R3tAHsHwT+E vgR/2cfD/h3TtCg0qLxr4Qtk1u/0xY47q7e5tfmZ53373/fz7N+9E3/3PkoA+Hfgb4n/AOES/YN+ P+q/YftPn6re6X5e/wAv/j9tbK03f8A8/f8A8AoA848K+G7HW/2CPiRqV5LOlx4e8cpqFtHBJ+7l d4bC0/ef7Gy7f/ge2guR+nn7Knj/AMP+P/gZ4DfQHl83QLC08P38c8PlyQXdtAiN/vp/q3T/AGH/ AL+9KDJHwH/wTc8N31z8RPiD4tjkg/s/S9DTT5o5G+eV7mZHXy/9j/RX/wDHKDRn7CUEH4t/sh/8 kR/bO/7FSP8A9IdRoLZ7R/wTr+GPhK58OeJPizfab9p8aW2qz6RZTz/vI7CDyYHZ4E/gd/PkR3/u fJ8m994Zs8Y+Jf8AxT3/AAUJ07+wP+Jb5/ivQt/2D9x5n2tLT7V9z/nv58+/+/vff9+go9T/AGdU g+KP7ZXxw8XeKrGw1WLTvtP2D+2bOCC7tHivIEsnjtJkSdHSCDZv2b0/j+d/nAP0J+Mfie+8GfCf 4keKtKuJ4dY0vQ7uazmgtvtb2935L+S/l7H+RJPL37/kRPnf5N9AHyt+wH8LvD/h74RwfEryIrnx Z4rmu1a/kh/eWlpBcPB9ljk3/c3wSP8Awb967/uJQB5B8Uf+LOft5/DvVfBf+jf8Jz/Z39sWn+rh n+23T2U3yJs3/wCrSf59/wC/+egDivgn8OvBXxI/bN+OeneOPD8Gsadpd/reqW1pdySeX9rTV0RW kT+NP3knyPvR6AOg/wCClmiaVDrnwj8RwWmzWL201GyuZ98n7yCB4HhXZ9z5JLuf/vugD7Q+N/wx 8I2f7L/xD8AaFp/9leFtI8PT3llaWH7vyntv9LX7+/fvkg+d/vvvf59/z0AfAfjPW9V0r/gnV8J7 Gyu/Js9X8QT2V5H5ccn2iBL3UZ9v+x+8ggf5P7lBXKHg/wDbe+HfgPwhP4D8K/s02Fn4PufP+06Z J4h89Lvzfvef59q7zb4/k+ff8nyfcoDlPaf+Cengbxx4J/4W3/wmXg3W9B+2/wBl/Zv7b02e0+0b Pte7y96fP/rI/wDv5QZH6T0AFABQB5Z8Cv8AkiPwb/7FTR//AEiSgD1OgAoAKACgAoAKACgAoAKA CgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAK ACgAoAKACgAoAKACgAoAKACgAoAKACgAoA8s+Mn/ACKOj/8AY1eF/wD09WFAHqdABQAUAFABQB0n 7P3/ACXD4z/9ir4X/wDS3X6APsyrAKAPk/Vf2Sf2f9d1a+1rWPAPnaxqVxJeXEv9q30fmyO+9n2J Ns++9exhs8zGirKpb7j5jEcOZbP/AJdi6V+yT+z/AKDq+n63o/gHydY024jvLeb+1b6TyZEfer7H m2ffSjE55mNZWlUuvkPDcO5dTd1TPJrnj4wftFr/ANTVYf8AqPaPXivzPpUklZGxSGFABQAUAFAH 5Hfs5eJLDRP27fjBpt2k7z+Ib/xDp9tJAn7uJ0vftfz/AOxstX/4HtoA/XGgDz/4qfD3Svip8PPF vgDWX8mz1ez+zpP+8k8idPnhuPLR037HSN9m/wCfy6APyQ+G/wC2N8UfgJ4f1/4SeKvDMGvax4em n0zTZL+//eaK8W9PJk2b/tUCSJ8iI6fJ8m/Zs2AHqf7B/gDxp4n+Iniv9oXxlpUU2nalDepbarfw xxyXeoz3CPNNaR7PkT/Xo7ps++6J/HsDXmPLPFvxX8dftw+NfCnwy03wBpWlaPBfpeLqMEMl9e6N abdl0zzu6J5H7zfs2JvdIU+/s3gcx9afEL/lIT8Cv+xVn/8AQNVoDmPmr9sPRNV+Ev7UHg/403Fp /aWj6peadrVtBujg82fT/ISa13/O/wByOB9+z/lv/HsoDmPYPiF8b734/fsZfHHxrd+H4NEgtNcs tPtrCCbz5IkSfTn/AHknyb33zv8AwJ8m3/foJPQfiX8Or74kfsN+A9N0Lw/PrHijS/Degapp1paP +83pDAjPGn8b+Q8/yfPv/g+fZQB8veCf+Chfi7wr8O9M8K614N/4SHxhZWb26+JdR1X/AF7/AD+S 88CQ732J5aP8+99n3970FXPTPgP8K77Qf2Xfjx8X/F8Utz408c+G9XuFu7/95d/Yvss77pJHTfvn k3zv87o6eS9AXPSf+Ccv/JEPFX/Y13f/AKR2VAXPK/8AnJv+H/uv0Bc/U+gyCgDyzR/+S3fET/sV PD3/AKW63QB6nQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAB QAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFA BQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAeWfAr/kiPwb/7FTR//SJKAPU6ACgA oAKAPyw/5yb/AIf+6/Qa3OR/4KI+GP8AhGPiL4I+ImhX/wBg1HxLpV3pl5HYJ5EkvkfIzu6ff3wX Xkf7kGygLlz9ofwBY/Df9ib4MaBBpUthqN3rdlqGox3cPkXP22eyu3n8/wCRPnT7nz/OiIqfwUBz HXaP8Or34kf8E7PDem6FoEuseKNLmu9U020tH+femqTozpH/ABv5Ek/yfPv/AIPn2UBzHlXhv/go d8RtB8B2fhy68G6TqviuyhgtbbxDf3k8iSoiIm+6g+/PO/lyfP56fO/3P74Fz2j4J+BvEGm/su/t IfFvxlcSv4r+JOh6vqk0ci+R+4S1u/Lm8vYmx3knnf5P3ex7fZQFztf+Ccv/ACRDxV/2Nd3/AOkd lQSHw9/5SE/HX/sVYP8A0DSqAPn34l/HL/hQP7aXxg8Y/wDCMf299t0qy0v7J9t+yeXvtdOfdv2P /wA8P/H6CrnRftS/E6++Mf7JPw/+I114cg0S31Txgn2awgv/ALdJsgt7+DfI/wBnTY/mRv8AJ8/y bPn/AIEAufoR8Cv+SI/Bv/sVNH/9IkoJPyu+Hv8Ayj2+Ov8A2NcH/oelUAfQ/wCwf4V8P+Nv2cPi D4V8VaVFqWgap4ku4bm0n+5In2Ww/wC+H/jR0/eI9AHxx4k8Q/FT9ku8+MHwB32Gq+G/FFnt+139 tdxxy2ktu6farVN6IjvHJsf7/wA8Gz59lAH60fszfCL/AIUz8I/D/hW7t9niS7/4mesfP/y+zom5 fvunyIkcHyfu38jf/HQQe+UAfi3+yH/yRH9s7/sVI/8A0h1Gg15j6p/4Jy/8kQ8Vf9jXd/8ApHZU Bc+VvjH/AMpCdH/7Gvwv/wCi7CgLnoHxs1LXf2P/ANpS4+LfhLQrDUvDfj+znaa0v3k+/wDaIHvU jffvR/Mjjfe6bE+17Nj7KAue+fBD9qLSv2pdc8V/CvXfhl/ZWj3fh67uLyT+3JJ/PgdkgaD5IUdN 8c/399BJ8XfCX9p/4lfsqf258IPGngT+0rPS72dv7Mv72S0urCd9n3H+dPI/1j/Inz+fv3/PQB77 +z9c65+1X8eLj4/eNPDFhYeG/A1kmn6PaQJJJHLd753h3yOjpM8CTu7umzY/2V9lBVzK/Za/5Pd/ aL/7jv8A6doKAuXv+Ckd5cabf/AnULeOJ7i2m1SZY7uGOdN6fYPvo/yOn+w/yUGR9t/tG63pXh74 D/Fy91q78mzfw/e2SSbJJP392nkQr8n99540oA+GNN+FGufFr/gn74D07w3P/wATjQr3UddhsPJk nfVPKutRRrePZ8+90nk2f33RU/j3oGvMcl4J/b/8W/D3wvpngfx58Ob/AF7xhom+zvNT1HWPsl3K 6M/yzx/ZXfeieWj7/nfZvf56A5j7h/Zp+NPjz462Xizxl4g8BxeG/AfnQW/h6SOaSd7p03/avMd9 m9Efy/nRET76fO6PQZH03QAUAFAHlnwK/wCSI/Bv/sVNH/8ASJKAPU6ACgAoAKACgAoAKACgAoAK ACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoA KACgAoAKACgAoAKACgAoAKACgAoAKACgDyz4yf8AIo6P/wBjV4X/APT1YUAep0AFABQAUAFAHSfs /f8AJcPjP/2Kvhf/ANLdfoA+zKsAoArbc1lyXITcg24ocLA24n5+3f8AyWP9o7/sarL/ANR/R6os 26ACgAoAKACgAoAKACgAoAKB3CgLhQFwoC4UFBQAUE3CgLhQFwoC4UCCgDyzR/8Akt3xE/7FTw9/ 6W63QB6nQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAF ABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUA FABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAeWfAr/AJIj8G/+xU0f/wBIkoA9ToAKACgA oAKB3CgLhQFwoC4UBcKAuFBQUAFBNwoC4UFBQB5/8UdS+IWleBdcvvhXoVhrHjxPI+waZqbeXDcf vk3eZ86fwb3+/QB+fnwr/Z1+OPjP9pSL4zftB+GYNNt7ab+10+yXNpIlxcwbEtYUjguN6InyPvff v8jY+/fQB+odBAUAFA7hQFwoC4UBcKCgoAKCbhQFwoEFABQO4UBcKBBQAUAFAHlnwK/5Ij8G/wDs VNH/APSJKAPU6ACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAK ACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgDyz4yf8ijo /wD2NXhf/wBPVhQB6nQAUAFABQAUAdH+z9/yW/40f9ir4X/9LNfoA+zasBMigBaACgD8+Lz/AJLH +0f/ANjXYf8AqPaPUAa9ABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAeWaP/wAl u+In/YqeHv8A0t1ugD1OgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAC gAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKA CgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoA8s+BX/ACRH4N/9ipo//pEl AHqdABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAB QAUAFABQAUAeWfAr/kiPwb/7FTR//SJKAPU6ACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAo AKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgA oAKACgAoAKACgDyz4yf8ijo//Y1eF/8A09WFAHqdABQAUAFABTkKe50XwEO343fGck/KvhXwv/6W a/RFX0M6slFXZpn9s39m7OR8RSr/AN/+yNR/+M170OHMwdPSk9fQ+YnxRgVPkdTY1fDH7UPwU8c6 1pvhfwj41N54juw5t4JNIvohIUR3c7mhVeER658RkePw2HvKnb5rud9DiLAYj3FU1PqXIryz3QyK APz1u/8Aksf7R3/Y1WX/AKj+j1AG3QAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAF AHi2qzeKvDfxT8SeI7L4e634h0fVPD+kWST6Jc6ZH5U9tdai7LJHdXUL/wCru4PuUAa3/CwvFv8A 0Qzx1/4G6B/8saAD/hYXi3/ohnjr/wADdA/+WNAB/wALC8W/9EM8df8AgboH/wAsaAD/AIWF4t/6 IZ46/wDA3QP/AJY0AH/CwvFv/RDPHX/gboH/AMsaAD/hYXi3/ohnjr/wN0D/AOWNAB/wsLxb/wBE M8df+Bugf/LGgA/4WF4t/wCiGeOv/A3QP/ljQAf8LC8W/wDRDPHX/gboH/yxoAP+FheLf+iGeOv/ AAN0D/5Y0AH/AAsLxb/0Qzx1/wCBugf/ACxoAP8AhYXi3/ohnjr/AMDdA/8AljQAf8LC8W/9EM8d f+Bugf8AyxoAP+FheLf+iGeOv/A3QP8A5Y0AH/CwvFv/AEQzx1/4G6B/8saAD/hYXi3/AKIZ46/8 DdA/+WNAB/wsLxb/ANEM8df+Bugf/LGgA/4WF4t/6IZ46/8AA3QP/ljQAf8ACwvFv/RDPHX/AIG6 B/8ALGgA/wCFheLf+iGeOv8AwN0D/wCWNAB/wsLxb/0Qzx1/4G6B/wDLGgA/4WF4t/6IZ46/8DdA /wDljQAf8LC8W/8ARDPHX/gboH/yxoAP+FheLf8Aohnjr/wN0D/5Y0AH/CwvFv8A0Qzx1/4G6B/8 saAD/hYXi3/ohnjr/wADdA/+WNAB/wALC8W/9EM8df8AgboH/wAsaAD/AIWF4t/6IZ46/wDA3QP/ AJY0AH/CwvFv/RDPHX/gboH/AMsaAD/hYXi3/ohnjr/wN0D/AOWNAB/wsLxb/wBEM8df+Bugf/LG gA/4WF4t/wCiGeOv/A3QP/ljQAf8LC8W/wDRDPHX/gboH/yxoAP+FheLf+iGeOv/AAN0D/5Y0AH/ AAsLxb/0Qzx1/wCBugf/ACxoAP8AhYXi3/ohnjr/AMDdA/8AljQAf8LC8W/9EM8df+Bugf8AyxoA P+FheLf+iGeOv/A3QP8A5Y0AH/CwvFv/AEQzx1/4G6B/8saAD/hYXi3/AKIZ46/8DdA/+WNAB/ws Lxb/ANEM8df+Bugf/LGgA/4WF4t/6IZ46/8AA3QP/ljQAf8ACwvFv/RDPHX/AIG6B/8ALGgA/wCF heLf+iGeOv8AwN0D/wCWNAB/wsLxb/0Qzx1/4G6B/wDLGgA/4WF4t/6IZ46/8DdA/wDljQAf8LC8 W/8ARDPHX/gboH/yxoAP+FheLf8Aohnjr/wN0D/5Y0AH/CwvFv8A0Qzx1/4G6B/8saAD/hYXi3/o hnjr/wADdA/+WNAB/wALC8W/9EM8df8AgboH/wAsaAD/AIWF4t/6IZ46/wDA3QP/AJY0AH/CwvFv /RDPHX/gboH/AMsaAD/hYXi3/ohnjr/wN0D/AOWNAB/wsLxb/wBEM8df+Bugf/LGgA/4WF4t/wCi GeOv/A3QP/ljQAf8LC8W/wDRDPHX/gboH/yxoAP+FheLf+iGeOv/AAN0D/5Y0AH/AAsLxb/0Qzx1 /wCBugf/ACxoAP8AhYXi3/ohnjr/AMDdA/8AljQAf8LC8W/9EM8df+Bugf8AyxoAP+FheLf+iGeO v/A3QP8A5Y0AH/CwvFv/AEQzx1/4G6B/8saAD/hYXi3/AKIZ46/8DdA/+WNAB/wsLxb/ANEM8df+ Bugf/LGgA/4WF4t/6IZ46/8AA3QP/ljQAf8ACwvFv/RDPHX/AIG6B/8ALGgA/wCFheLf+iGeOv8A wN0D/wCWNAB/wsLxb/0Qzx1/4G6B/wDLGgA/4WF4t/6IZ46/8DdA/wDljQAf8LC8W/8ARDPHX/gb oH/yxoAP+FheLf8Aohnjr/wN0D/5Y0AH/CwvFv8A0Qzx1/4G6B/8saAD/hYXi3/ohnjr/wADdA/+ WNAB/wALC8W/9EM8df8AgboH/wAsaAD/AIWF4t/6IZ46/wDA3QP/AJY0AH/CwvFv/RDPHX/gboH/ AMsaAD/hYXi3/ohnjr/wN0D/AOWNAB/wsLxb/wBEM8df+Bugf/LGgA/4WF4t/wCiGeOv/A3QP/lj QBp/CjRNV8N/C34ZeHdctPs2saX4e06yvYN8cnlTpaojJ5ifJ/rEoA9AoAKACgAoAKACgAoAKACg AoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgDwPwNYfG7wT4I 8H+Df+EL8DXn9haVbaX9r/4S2+j+0eVbom/y/wCy/k/1dAHU/wBsfG3/AKJ34G/8LG+/+VdAB/bH xt/6J34G/wDCxvv/AJV0AH9sfG3/AKJ34G/8LG+/+VdAB/bHxt/6J34G/wDCxvv/AJV0AH9sfG3/ AKJ34G/8LG+/+VdAB/bHxt/6J34G/wDCxvv/AJV0AH9sfG3/AKJ34G/8LG+/+VdAB/bHxt/6J34G /wDCxvv/AJV0AH9sfG3/AKJ34G/8LG+/+VdAB/bHxt/6J34G/wDCxvv/AJV0AH9sfG3/AKJ34G/8 LG+/+VdAB/bHxt/6J34G/wDCxvv/AJV0AH9sfG3/AKJ34G/8LG+/+VdAB/bHxt/6J34G/wDCxvv/ AJV0AH9sfG3/AKJ34G/8LG+/+VdAB/bHxt/6J34G/wDCxvv/AJV0AH9sfG3/AKJ34G/8LG+/+VdA B/bHxt/6J34G/wDCxvv/AJV0AH9sfG3/AKJ34G/8LG+/+VdAB/bHxt/6J34G/wDCxvv/AJV0AH9s fG3/AKJ34G/8LG+/+VdAB/bHxt/6J34G/wDCxvv/AJV0AH9sfG3/AKJ34G/8LG+/+VdAB/bHxt/6 J34G/wDCxvv/AJV0AH9sfG3/AKJ34G/8LG+/+VdAB/bHxt/6J34G/wDCxvv/AJV0AH9sfG3/AKJ3 4G/8LG+/+VdAB/bHxt/6J34G/wDCxvv/AJV0AH9sfG3/AKJ34G/8LG+/+VdAB/bHxt/6J34G/wDC xvv/AJV0AH9sfG3/AKJ34G/8LG+/+VdAB/bHxt/6J34G/wDCxvv/AJV0AH9sfG3/AKJ34G/8LG+/ +VdAB/bHxt/6J34G/wDCxvv/AJV0AH9sfG3/AKJ34G/8LG+/+VdAB/bHxt/6J34G/wDCxvv/AJV0 AH9sfG3/AKJ34G/8LG+/+VdAB/bHxt/6J34G/wDCxvv/AJV0AH9sfG3/AKJ34G/8LG+/+VdAB/bH xt/6J34G/wDCxvv/AJV0AH9sfG3/AKJ34G/8LG+/+VdAB/bHxt/6J34G/wDCxvv/AJV0AH9sfG3/ AKJ34G/8LG+/+VdAB/bHxt/6J34G/wDCxvv/AJV0AH9sfG3/AKJ34G/8LG+/+VdAB/bHxt/6J34G /wDCxvv/AJV0AH9sfG3/AKJ34G/8LG+/+VdAB/bHxt/6J34G/wDCxvv/AJV0AH9sfG3/AKJ34G/8 LG+/+VdAB/bHxt/6J34G/wDCxvv/AJV0AH9sfG3/AKJ34G/8LG+/+VdAB/bHxt/6J34G/wDCxvv/ AJV0AH9sfG3/AKJ34G/8LG+/+VdAB/bHxt/6J34G/wDCxvv/AJV0AH9sfG3/AKJ34G/8LG+/+VdA B/bHxt/6J34G/wDCxvv/AJV0AZOsaV8VPGaaXo/iPw74U0fR4NV07U5r/TPEF3qU0f2K9gu1SOB7 KFH3vAiff+Tfv+fZscA9poAKACgAoAKTE9WbvwH/AOS0/Gz/ALFTwv8A+lmv1tSWqOXFu1OXofh2 P9VIfev6IwseanFW6I/nbGNRx0lfqz6e/Y/hA/aI+GEh6SNfn/yn3VeBxlT9ll2i6r80erwxVVXM XB7Wf5H71BcIOfmUYr8UhUjPY/eG3To8jeoYyNy/eIonOMNyot1KPKmfAd3/AMlj/aO/7Gqy/wDU f0eo3NTboAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAC gAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKA CgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAK ACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoA KACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAo AKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgA oAKACgAoAKACgAoAKACgApsUdzd+A/8AyWj41f8AYqeGP/SzX61pbo58b/Dl6M/DtekVf0hlmtOn 6fofzpjv94qep9Kfsff8nI/Dv633/pvua+Z4u/5F9T1j+Z6vDC/2r7/yO6+Iv7Vvx/0P4hePdE0n x/JbaXpet3tnbQDTLFxHEl06Ku94d/3ErwMi4cwOMinKn+LPbzTiXHUq/Iqgvw3/AGrfj9rvxD8A 6JrHj9rnTNW1uysrm3OmWKCSJ7qNHXekO/7j0s+4bwWCi3Cn+LLyfiTHVsSqbqaH1/cf8lf/AGi/ +xqsf/Ue0evzB7n6/B3imbNIoKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKA CgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAK ACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoA KACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAo AKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgA oAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACg AoAKACgAoAKACgAoAKACgAoAKACgAoAKACgApsUdzd+A/wDyWj41f9ip4Y/9LNfrWlujnxv8OXoz 8O16RV/R2Wfw4eh/OmO/3ip6n0v+x7/ycf8ADr/t+/8ASC6r5zi3/kXVPWP5o9bhj/evv/I8u+Mf /JYvij/2M2rf+lT10cK/7rTODOP94kO+C3/JZfhR/wBjPpP/AKVJS4r/AN0q+hvw7/vcD9Ytd+FX xwh+I/xU8TeEtC8D6l4e8UarbapbSa34kvtNuYNmmWVk0bxx6fOn37F3+/8Ax1+Fy3Z/QND4EP8A +FbftJ/9CV8Nf/C21H/5S0jWO4f8K1/aT/6Er4af+FtqP/ymoAP+FbftKf8AQlfDX/wttR/+UlAB /wAK2/aU/wChK+Gv/hbaj/8AKSgA/wCFbftKf9CV8Nf/AAttR/8AlJQAf8K2/aU/6Er4a/8Ahbaj /wDKSgA/4Vt+0p/0JXw1/wDC21H/AOUlAB/wrb9pT/oSvhr/AOFtqP8A8pKAD/hW37Sn/QlfDX/w ttR/+UlAB/wrb9pT/oSvhr/4W2o//KSgA/4Vt+0p/wBCV8Nf/C21H/5SUAH/AArb9pT/AKEr4a/+ FtqP/wApKAD/AIVt+0p/0JXw1/8AC21H/wCUlAB/wrb9pT/oSvhr/wCFtqP/AMpKAD/hW37Sn/Ql fDX/AMLbUf8A5SUAH/Ctv2lP+hK+Gv8A4W2o/wDykoAP+FbftKf9CV8Nf/C21H/5SUAH/Ctv2lP+ hK+Gv/hbaj/8pKAD/hW37Sn/AEJXw1/8LbUf/lJQAf8ACtv2lP8AoSvhr/4W2o//ACkoAP8AhW37 Sn/QlfDX/wALbUf/AJSUAH/Ctv2lP+hK+Gv/AIW2o/8AykoAP+FbftKf9CV8Nf8AwttR/wDlJQAf 8K2/aU/6Er4a/wDhbaj/APKSgA/4Vt+0p/0JXw1/8LbUf/lJQAf8K2/aU/6Er4a/+FtqP/ykoAP+ FbftKf8AQlfDX/wttR/+UlAB/wAK2/aU/wChK+Gv/hbaj/8AKSgA/wCFbftKf9CV8Nf/AAttR/8A lJQAf8K2/aU/6Er4a/8Ahbaj/wDKSgA/4Vt+0p/0JXw1/wDC21H/AOUlAB/wrb9pT/oSvhr/AOFt qP8A8pKAD/hW37Sn/QlfDX/wttR/+UlAHiesfEDXfDPiDxB4V8S+KvgJoXifRpktr/TvEHxPutNm jd4IJ4/km0hN6eXPH88fyfwffR6AIf8AhaLf9FT/AGZv/Dx//eygA/4Wi3/RU/2Zv/Dx/wD3soAP +Fot/wBFT/Zm/wDDx/8A3soAP+Fot/0VP9mb/wAPH/8AeygA/wCFot/0VP8AZm/8PH/97KAD/haL f9FT/Zm/8PH/APeygA/4Wi3/AEVP9mb/AMPH/wDeygA/4Wi3/RU/2Zv/AA8f/wB7KAD/AIWi3/RU /wBmb/w8f/3soAP+Fot/0VP9mb/w8f8A97KAD/haLf8ARU/2Zv8Aw8f/AN7KAD/haLf9FT/Zm/8A Dx//AHsoAP8AhaLf9FT/AGZv/Dx//eygA/4Wi3/RU/2Zv/Dx/wD3soAP+Fot/wBFT/Zm/wDDx/8A 3soAP+Fot/0VP9mb/wAPH/8AeygA/wCFot/0VP8AZm/8PH/97KAD/haLf9FT/Zm/8PH/APeygA/4 Wi3/AEVP9mb/AMPH/wDeygA/4Wi3/RU/2Zv/AA8f/wB7KAD/AIWi3/RU/wBmb/w8f/3soAP+Fot/ 0VP9mb/w8f8A97KAD/haLf8ARU/2Zv8Aw8f/AN7KAD/haLf9FT/Zm/8ADx//AHsoAP8AhaLf9FT/ AGZv/Dx//eygA/4Wi3/RU/2Zv/Dx/wD3soAP+Fot/wBFT/Zm/wDDx/8A3soAP+Fot/0VP9mb/wAP H/8AeygA/wCFot/0VP8AZm/8PH/97KAD/haLf9FT/Zm/8PH/APeygA/4Wi3/AEVP9mb/AMPH/wDe ygA/4Wi3/RU/2Zv/AA8f/wB7KAD/AIWi3/RU/wBmb/w8f/3soAP+Fot/0VP9mb/w8f8A97KAD/ha Lf8ARU/2Zv8Aw8f/AN7KAD/haLf9FT/Zm/8ADx//AHsoAP8AhaLf9FT/AGZv/Dx//eygA/4Wi3/R U/2Zv/Dx/wD3soAP+Fot/wBFT/Zm/wDDx/8A3soAP+Fot/0VP9mb/wAPH/8AeygA/wCFot/0VP8A Zm/8PH/97KAD/haLf9FT/Zm/8PH/APeygA/4Wi3/AEVP9mb/AMPH/wDeygA/4Wi3/RU/2Zv/AA8f /wB7KAD/AIWi3/RU/wBmb/w8f/3soAP+Fot/0VP9mb/w8f8A97KAD/haLf8ARU/2Zv8Aw8f/AN7K AD/haLf9FT/Zm/8ADx//AHsoAP8AhaLf9FT/AGZv/Dx//eygA/4Wi3/RU/2Zv/Dx/wD3soAP+Fot /wBFT/Zm/wDDx/8A3soAP+Fot/0VP9mb/wAPH/8AeygA/wCFot/0VP8AZm/8PH/97KAD/haLf9FT /Zm/8PH/APeygA/4Wi3/AEVP9mb/AMPH/wDeygA/4Wi3/RU/2Zv/AA8f/wB7KAD/AIWi3/RU/wBm b/w8f/3soAP+Fot/0VP9mb/w8f8A97KAD/haLf8ARU/2Zv8Aw8f/AN7KAD/haLf9FT/Zm/8ADx// AHsoAP8AhaLf9FT/AGZv/Dx//eygA/4Wi3/RU/2Zv/Dx/wD3soAP+Fot/wBFT/Zm/wDDx/8A3soA P+Fot/0VP9mb/wAPH/8AeygA/wCFot/0VP8AZm/8PH/97KAD/haLf9FT/Zm/8PH/APeygA/4Wi3/ AEVP9mb/AMPH/wDeygDd8DeIfiF8TNS1PSvhzN8GvE15pENtdX8nh/x/fX0NvHcvOkP79NI2b/8A RZ/k3+Yn8f303gHqv/Ctv2lP+hK+Gv8A4W2o/wDykoAP+FbftKf9CV8Nf/C21H/5SUAH/Ctv2lP+ hK+Gv/hbaj/8pKAD/hW37Sn/AEJXw1/8LbUf/lJQAf8ACtv2lP8AoSvhr/4W2o//ACkoAP8AhW37 Sn/QlfDX/wALbUf/AJSUAH/Ctv2lP+hK+Gv/AIW2o/8AykoAP+FbftKf9CV8Nf8AwttR/wDlJQAf 8K2/aU/6Er4a/wDhbaj/APKSgA/4Vt+0p/0JXw1/8LbUf/lJQAf8K2/aU/6Er4a/+FtqP/ykoAP+ FbftKf8AQlfDX/wttR/+UlAB/wAK2/aU/wChK+Gv/hbaj/8AKSgA/wCFbftKf9CV8Nf/AAttR/8A lJQAf8K2/aU/6Er4a/8Ahbaj/wDKSgA/4Vt+0p/0JXw1/wDC21H/AOUlAB/wrb9pT/oSvhr/AOFt qP8A8pKAD/hW37Sn/QlfDX/wttR/+UlAB/wrb9pT/oSvhr/4W2o//KSgA/4Vt+0p/wBCV8Nf/C21 H/5SUAH/AArb9pT/AKEr4a/+FtqP/wApKAD/AIVt+0p/0JXw1/8AC21H/wCUlAB/wrb9pT/oSvhr /wCFtqP/AMpKAD/hW37Sn/QlfDX/AMLbUf8A5SUAH/Ctv2lP+hK+Gv8A4W2o/wDykoAP+FbftKf9 CV8Nf/C21H/5SUAH/Ctv2lP+hK+Gv/hbaj/8pKAD/hW37Sn/AEJXw1/8LbUf/lJQAf8ACtv2lP8A oSvhr/4W2o//ACkoAP8AhW37Sn/QlfDX/wALbUf/AJSUAH/Ctv2lP+hK+Gv/AIW2o/8AykoAP+Fb ftKf9CV8Nf8AwttR/wDlJQAf8K2/aU/6Er4a/wDhbaj/APKSgA/4Vt+0p/0JXw1/8LbUf/lJQAf8 K2/aU/6Er4a/+FtqP/ykoAP+FbftKf8AQlfDX/wttR/+UlAB/wAK2/aU/wChK+Gv/hbaj/8AKSgA /wCFbftKf9CV8Nf/AAttR/8AlJQAf8K2/aU/6Er4a/8Ahbaj/wDKSgA/4Vt+0p/0JXw1/wDC21H/ AOUlAB/wrb9pT/oSvhr/AOFtqP8A8pKAD/hW37Sn/QlfDX/wttR/+UlAB/wrb9pT/oSvhr/4W2o/ /KSgA/4Vt+0p/wBCV8Nf/C21H/5SUAH/AArb9pT/AKEr4a/+FtqP/wApKAD/AIVt+0p/0JXw1/8A C21H/wCUlAB/wrb9pT/oSvhr/wCFtqP/AMpKAD/hW37Sn/QlfDX/AMLbUf8A5SUAH/Ctv2lP+hK+ Gv8A4W2o/wDykoAP+FbftKf9CV8Nf/C21H/5SUAH/Ctv2lP+hK+Gv/hbaj/8pKAD/hW37Sn/AEJX w1/8LbUf/lJQAf8ACtv2lP8AoSvhr/4W2o//ACkoAP8AhW37Sn/QlfDX/wALbUf/AJSUAH/Ctv2l P+hK+Gv/AIW2o/8AykoAP+FbftKf9CV8Nf8AwttR/wDlJQAf8K2/aU/6Er4a/wDhbaj/APKSgA/4 Vt+0p/0JXw1/8LbUf/lJQAf8K2/aU/6Er4a/+FtqP/ykoAP+FbftKf8AQlfDX/wttR/+UlAB/wAK 2/aU/wChK+Gv/hbaj/8AKSgA/wCFbftKf9CV8Nf/AAttR/8AlJQAf8K2/aU/6Er4a/8Ahbaj/wDK SgA/4Vt+0p/0JXw1/wDC21H/AOUlAB/wrb9pT/oSvhr/AOFtqP8A8pKAD/hW37Sn/QlfDX/wttR/ +UlAB/wrb9pT/oSvhr/4W2o//KSgA/4Vt+0p/wBCV8Nf/C21H/5SUAH/AArb9pT/AKEr4a/+FtqP /wApKAD/AIVt+0p/0JXw1/8AC21H/wCUlAB/wrb9pT/oSvhr/wCFtqP/AMpKAD/hW37Sn/QlfDX/ AMLbUf8A5SUAH/Ctv2lP+hK+Gv8A4W2o/wDykoAP+FbftKf9CV8Nf/C21H/5SUAH/Ctv2lP+hK+G v/hbaj/8pKAD/hW37Sn/AEJXw1/8LbUf/lJQAf8ACtv2lP8AoSvhr/4W2o//ACkoAP8AhW37Sn/Q lfDX/wALbUf/AJSUAH/Ctv2lP+hK+Gv/AIW2o/8AykoAP+FbftKf9CV8Nf8AwttR/wDlJQAf8K2/ aU/6Er4a/wDhbaj/APKSgA/4Vt+0p/0JXw1/8LbUf/lJQAf8K2/aU/6Er4a/+FtqP/ykoAP+Fbft Kf8AQlfDX/wttR/+UlAB/wAK2/aU/wChK+Gv/hbaj/8AKSgA/wCFbftKf9CV8Nf/AAttR/8AlJQA f8K2/aU/6Er4a/8Ahbaj/wDKSgA/4Vt+0p/0JXw1/wDC21H/AOUlAB/wrb9pT/oSvhr/AOFtqP8A 8pKAD/hW37Sn/QlfDX/wttR/+UlAB/wrb9pT/oSvhr/4W2o//KSgA/4Vt+0p/wBCV8Nf/C21H/5S UAH/AArb9pT/AKEr4a/+FtqP/wApKAD/AIVt+0p/0JXw1/8AC21H/wCUlAB/wrb9pT/oSvhr/wCF tqP/AMpKAD/hW37Sn/QlfDX/AMLbUf8A5SUAH/Ctv2lP+hK+Gv8A4W2o/wDykoAP+FbftKf9CV8N f/C21H/5SUAH/Ctv2lP+hK+Gv/hbaj/8pKAD/hW37Sf/AEJXw1/8LbUf/lLUtEo6/wCDfw8+JPhL xl8RfGPxAsPDdpHrOk6Rplvb+HtYudS/48ptRkd3ea1ttn/H9H/f+49b0viSOfG/w5ejPwkH/LH6 1/ReWfDD0/Q/nPGf7xU9T6T/AGPP+Tj/AIcf9v3/AKQXdfPcX/8AIvqeq/NHs8M/7z9/5HmXxl/5 LB8Uf+xm1b/0qet+Ff8AdaZ5+cf7xIPgv/yWX4Uf9jNpH/pUlLiv/dKvob8O/wC9wP6S4vuLX4ZL c/oCj8CHHqak2juOHQUALQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFA BQAUAFABQAUAFABQB4R8Kf8Akf8A9pv/ALHq0/8AUb0CgD3egAoAKACgAoAKACgAoAKACgAoAKAC gAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKA CgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgDwnw//wAnLfFn/sR/Cf8A6cPE dAHu1ABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFA BQB89/HHxz468A+ENO1jwFpGharrV94k0TSDF4gvp7OGOC91CCy374YXffvnVP8AY3+Z8+zyJAC9 /wAJB+0t/wBEl+Gn/hxNT/8AlFQAf8JB+0t/0SX4af8AhxNT/wDlFQAf8JB+0t/0SX4af+HE1P8A +UVAB/wkH7S3/RJfhp/4cTU//lFQAf8ACQftLf8ARJfhp/4cTU//AJRUAH/CQftLf9El+Gn/AIcT U/8A5RUAH/CQftLf9El+Gn/hxNT/APlFQAf8JB+0t/0SX4af+HE1P/5RUAH/AAkH7S3/AESX4af+ HE1P/wCUVAB/wkH7S3/RJfhp/wCHE1P/AOUVAB/wkH7S3/RJfhp/4cTU/wD5RUAH/CQftLf9El+G n/hxNT/+UVAB/wAJB+0t/wBEl+Gn/hxNT/8AlFQAf8JB+0t/0SX4af8AhxNT/wDlFQAf8JB+0t/0 SX4af+HE1P8A+UVAB/wkH7S3/RJfhp/4cTU//lFQAf8ACQftLf8ARJfhp/4cTU//AJRUAH/CQftL f9El+Gn/AIcTU/8A5RUAH/CQftLf9El+Gn/hxNT/APlFQAf8JB+0t/0SX4af+HE1P/5RUAH/AAkH 7S3/AESX4af+HE1P/wCUVAB/wkH7S3/RJfhp/wCHE1P/AOUVAB/wkH7S3/RJfhp/4cTU/wD5RUAH /CQftLf9El+Gn/hxNT/+UVAB/wAJB+0t/wBEl+Gn/hxNT/8AlFQAf8JB+0t/0SX4af8AhxNT/wDl FQAf8JB+0t/0SX4af+HE1P8A+UVAB/wkH7S3/RJfhp/4cTU//lFQAf8ACQftLf8ARJfhp/4cTU// AJRUAH/CQftLf9El+Gn/AIcTU/8A5RUAH/CQftLf9El+Gn/hxNT/APlFQAf8JB+0t/0SX4af+HE1 P/5RUAH/AAkH7S3/AESX4af+HE1P/wCUVAB/wkH7S3/RJfhp/wCHE1P/AOUVAB/wkH7S3/RJfhp/ 4cTU/wD5RUAH/CQftLf9El+Gn/hxNT/+UVAB/wAJB+0t/wBEl+Gn/hxNT/8AlFQAf8JB+0t/0SX4 af8AhxNT/wDlFQAf8JB+0t/0SX4af+HE1P8A+UVAB/wkH7S3/RJfhp/4cTU//lFQAf8ACQftLf8A RJfhp/4cTU//AJRUAH/CQftLf9El+Gn/AIcTU/8A5RUAH/CQftLf9El+Gn/hxNT/APlFQAf8JB+0 t/0SX4af+HE1P/5RUAH/AAkH7S3/AESX4af+HE1P/wCUVAB/wkH7S3/RJfhp/wCHE1P/AOUVAB/w kH7S3/RJfhp/4cTU/wD5RUAH/CQftLf9El+Gn/hxNT/+UVAB/wAJB+0t/wBEl+Gn/hxNT/8AlFQA f8JB+0t/0SX4af8AhxNT/wDlFQAf8JB+0t/0SX4af+HE1P8A+UVAB/wkH7S3/RJfhp/4cTU//lFQ Af8ACQftLf8ARJfhp/4cTU//AJRUAH/CQftLf9El+Gn/AIcTU/8A5RUAH/CQftLf9El+Gn/hxNT/ APlFQAf8JB+0t/0SX4af+HE1P/5RUAH/AAkH7S3/AESX4af+HE1P/wCUVAB/wkH7S3/RJfhp/wCH E1P/AOUVAB/wkH7S3/RJfhp/4cTU/wD5RUAH/CQftLf9El+Gn/hxNT/+UVAB/wAJB+0t/wBEl+Gn /hxNT/8AlFQB5h8S/iX+0n4E+HHjzxx/wq74aRjw9oV7qwk/4TjUbvyzBBJP/qP7Ih8//V/c8+Pf /fT79AH2LQAUAFACDoKAEPQUMlFW6/1L/wC6aun8SOfGfw5ejP5dR/yx+tf0blnwQ9P0P5zxn+8V PU+k/wBjv/k4/wCHH/b9/wCkF3Xz3F//ACL6nqvzR7PDP+8/f+R5h8Zf+SwfFD/sZtW/9KnrfhX/ AHWmefnP+8SF+C//ACWX4Uf9jPpH/pUlLiv/AHSr6GuQ/wC9w9T+kuH/AFa/QV+Fy3P6CofAh56m kbR3HDoKAFoAKAPlL9pf9ozQP2XvCPhLxv4t8P6jqvh3UNaj0af+xvLNzb77W5nR40fYj/PapHs3 p/rN/wDBscA+Uv8Ah75+zV/0JPxK/wDBbp3/AMm1A+Q6f4P/APBRz4dfGz4z/Dz4S+BfAniVZPEX 9ofbNW8QtBafYPItZLlfLgiebz9/kSJ99Nny/foDkP0zqxBQAUAFABQAUAFABQAUAIehoA/Lf4xf 8FJfhv8ACL43W/wgs/Dlzqthp2qxab4n8Tm+SOy0ZH8jzGgSFJnuZIPMnSSD9w6PBs+f+AKP1IHQ UCZ+f/gL9uX4beO/2j/EH7ONv4Q8TWnjCy13VNDttSkWCSyn+xQvJcO/77en7yC6RE2P8nlv8m90 QEfoDQAUAFABQAUAFABQAUAFABQAUAFABQB4R8Kf+R//AGm/+x6tP/Ub0CgD3egAoAKACgAoAKAC gAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKA CgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgDwnw/8A8nLf Fn/sR/Cf/pw8R0Ae7UAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAF ABQAUAFABQAUAFAHhP7QX/Ig+H/+x58Ff+pJpdAHu1ABQAUAFABQAUAFABQAUAFABQAUAFABQAUA FABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAU AFABQAUAFABQAUAFABQAUAFABQAUAFAHhX7T3/JtP7RP/Yj69/6b56APdaACgAoAQdBQA002Qtyt df6l/wDdNXT+I58Z8EvRn8uo/wCWP1r+jMs+Cn6fofzpjP8AeKnqfSf7Hf8Aycf8OP8At+/9ILuv nuL/APkX1PVfmj2eGf8Aefv/ACPMPjL/AMlg+KH/AGM2rf8ApU9b8K/7rTPPzn/eJC/Bf/ksvwo/ 7GfSP/SpKXFf+6VfQ1yH/e4ep/SXD/q1+gr8Lluf0FQ+BDz1NI2juOHQUALQAUAeJfF/4J/DP4++ GrPwl8VvDKa74esb9NQhsPtl1aeXdojoknmQOj/cnk/77oA/Cv8A4KVfs4fBr9n5PgnL8IvBf9g/ 27/a/wDaX/Ezu7v7R5H2Lyf9fM+z/Xyfc/v1A+c/WzwV+yB+y38C/E1t8XfC/gS38Max4ahuJxrt 9r2pyw2UHkuk0kgmuXi2eQ8nzv8AcoDnPorwd8Q/A/xG0ubW/AHjLRvEejW832Wa90K/gvoUn2I+ zzImdN+yRPk/26sRLc+O/Blh40tPAl/400W28d6hD9os/Dk+pQR391B8/wC8jtd+90/cz/Ps/wCW b/3KAPHfAH7W/wAA/iX4Z+IvjLwP4+GpeGvAdh/aHiC7/sq+t/sFtsnk37J4Ud/ktZ/ub/uUAbHw k/aW+B/x3nvIfhZ8QNN17U7SRy+m7ZLW9jjTyw8/2WdEn8j9/Gnm7Nm99m+gD0L4ieOvC/w38IeI PGfjjXYtG8KaRD513ql3kLAnb1d3d9iIifO7uiJ89AHzR8Pf28f2XviL4vg8AeGviKYdfvb9NP0p r3Tbqxh1Z3hjkj8iR02J87+QiT7HeRNiI++PeAfctABQB8Vah+3L+y5o3jrUfh7q/wAX7bT/ABTp +qvo15ZX+kajbw2l2k3kNHJdPD5CIr/8tN+z+PfsoA779p3xO3hT9n74z+I08QSaBf2XhbVPsGqx 3f2R7a9e2dLXZJ/BP57xomz597rsoA/Ib/gkx4n+HXhjxT8XovFWv+HdK8Yav/Ymn6F/at5BBe3/ AJslz51ra7/nffIlpvRP4/J/6Z0FH9B46CgTPwN8LeG9J8K/8FiZ9I0SxFvp81/f6m8YeR/9Ju/D kl3cv8/9+ed3/wCB0CP3zoA5HWdZ03w/pWoazrGo29hpWnxPc3N/dypBBZwIN7SSO/yIiJ1egD5S 8G/t1fstfELxhpHgzwj8W7e48T65OLWxtLvS9TsUml/hUSzW6Jvc/Iib/nfaifO9AH23QB8dv+2j +zBbeONW+G+o/GDTtO8ZaZf3em3sGtWt1YW1pc22/wA9HupoUgz+7k/5afP/AAffoA9+tvHfgy/8 aXfgSw8aaLc+O9Ph+0XnhyDUoJL+1g+T95Ja796J++g+fZ/y0T+/QBxfh746/CDxT/wmEnhb4neH NY03wraRanrWr6dqUFxZabbSeeUknukPlJ/x6zu/z/Iib32b0oA4/wCEn7W37PHxu1p/Dfw2+K2n aj4kjHyaTdxT6dc3Xyu/7iO6RHn2JBI7+Xv2fx4oA+qqACgAoAKACgDwj4U/8j/+03/2PVp/6jeg UAe70AFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUA FABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAU AFABQAUAeE+H/wDk5b4s/wDYj+E//Th4joA92oA8p8Z/E/4b/Ds6Z/wsDx/4b8Lf2hv+yHxDqsGm i7KbA2zznXfs3p/32tAGx4O8V6P4v8NeHvFOg3z3Oh6/YQanYXZjeP7RbTojxybH+dPkdPv0Ad9Q AUAFABQAUAFABQAUAFABQAUAFABQB5p4x+IPgf4c6ZDrfj/xlo3hzR7ib7LDe67fwWMLz7HfZ5kr Im/ZG/yf7FAHpdAHmnjH4g+B/hzpkOt+P/GWjeHNHuJvssN7rt/BYwvPsd9nmSsib9kb/J/sUAbu jazpviDStP1nR9Rt7/StQiS5tr+0lSeC8gcb1kjdPkdHTo9AHXUAFABQAUAFAHl//CyPh9/wmv8A wrb/AIWN4a/4WJ5n/Isf2tB/af8AqfP/AOPXfv8A9R8/3PufPQB6hQAUAFAHDeKvE/hzwPo134m8 Wa/p+i+H7LYLnVdVuUtbaDe/lx75H+RPndE/4HQAeGPFHhzxvo1n4l8Ja7Ya34evfM+zarpNyl1b 3Gxtj7JE+R/nR0/4BQB3NAHhP7QX/Ig+H/8AsefBX/qSaXQB7tQAUAFABQAUAFABQAUAFABQAUAF ABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUA FABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQB4V+09/ybT+0T/wBiPr3/AKb56APdaACgAoAQ dBQA002Qtytdf6l/901dP4jnxnwS9Gfy6j/lj9a/ozLPgp+n6H86Yz/eKnqfSf7Hf/Jx/wAOP+37 /wBILuvnuL/+RfU9V+aPZ4Z/3n7/AMjzD4y/8lg+KH/Yzat/6VPW/Cv+60zz85/3iQvwX/5LL8KP +xn0j/0qSlxX/ulX0Nch/wB7h6n9JcP+rX6CvwuW5/QVD4EPPU0jaO44dBQAtABQAUAfht/wWa+7 +zh9fEP/ALjqgD9VP2nv+Taf2if+xH17/wBN89AH58f8EhtVsZvgV8Q9HS8tn1S28YS3M1lHMnnQ wT2VkivJH99Ed4J9j/x+Q/8AcoKOh+LX/KWj9l7/ALEe7/8ARGv0Afnn8PPhd4m+On7d/wAdvhLB rOp23wwv/G2r61410q0vpILbVNOstTd1jnjSZN++d44EdN8kHn70+5QB7D+2r+zJ4U/Y7/4QL9oz 9nLxFr3hHxCPEiWEOlC4+1QWbvbTvvgkm+fZ/os++CfzUk+07PkT924A39u39qfxv49+HPwJ+E12 NG8PaP8AEnwb4f8AF/inXZIbh4W+0yb1hSNEmnhtYZ7fzX2b53/dp/C6TgHNftHX/wDwTy8WfAbT /Dfwe8ZWFn8UPB1hAuj6knhvU9Nm8Q7EjSZNSkTTkSeeeNN+99n7/b88aPLvAP06/YL/AGg/F37Q vwP/AOEv8eLbjxVoerz+H72/tMRpqzxQwTfaTH9yJ3jnTeifJvjd02I+xLFM5n/gpD8VvEvwp/Zt vLnwZf6vpviLxNr1jottrOk6jJY3Omf6y7d43T5/nSzeDZvT/X/8AcCB5x8Kf+CZvwJh+C3hjR/i 14JuZ/i3d6a7axrlhq91BNY3M+99kaJcPbO9rvSPfseN/I37Pn2VAz5O+EvxE8Va38D/ANsr9ir4 z3S+JLn4Z+FtZudEvYXk8u3/ALIk2eT5+9XaCO6jsXgjdPub0f5PLgoA4b/gmT+z34F+NXivxh4y 8W/2nD4g+HWu+G9d0O70258v50e9d4J0dHR4XeCDf/H8nyOnz75RUz+kk9DWiMz8M1/5TR/5/wCh VqSz9zaCD8cP+CiHiX4n/Fz4n/Cn9ij4ZWVvE/i6KDxJd6jPfyQR3aI91+5n/g+ywJayXb/fd3SD y03p84Uc/wDtB/8ABOfwR8Nvgbb+PvhDrF3oPxU+GWkf27qXiGO5u408RPZwpLPNHH5zvZXW+B54 PI+RH+T/AJ5yQAHK+Ov21PH/AIv/AOCd1r4zTVtRsPind+KYPA994j0O6/sd4LmCP+0ftUHkv/y0 tYI45ETyvnnm2JsREcA9N8A/8EuPhQ3wCttE8dpqcPx01ewS5udcS6d/+EevXRH+zR2qTeRNBB9x /vu+ZHR03psAPnz/AIJvaL4q8M/tlfGPwZ4t17+0fEnhfwrqPh65u45pJ1/0LUNOtI0jd/n8hI4E RPufJGv3KAPIP+Cc3wF1v46+LfiHZ3nxG13QfhLpcNkvinw3oWq3VjL4tSf7SkNnP5Lon2XZHdb/ AOPY+xPv+YgM6T4xfs+eCP2cP2+v2a/B/wAMzqJ0LV9e8Pa79k1K58/7BJPrUkfkQPs3+RGkCbN+ 9/77vQN7H9JJ6GgzFqwCgAoAKAPCPhT/AMj/APtN/wDY9Wn/AKjegUAe70AFABQAUAFABQAUAFAB QAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFA BQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAeE+H/8Ak5b4s/8A Yj+E/wD04eI6APdqAP51P+CtnxF/t74w+APh1Dd6dcWnhnQXvZ1tG33dve3s3z28/wA3yfuLS0dE 2I/7/f8AxpUFn3F/wS0+IGm+Lf2arHwfDPHDrHgrV72zmgjvEkmuILm4kvYbqSD78KO9xPAn9/7I /wA/8CAj9SMirFYMigLBkUBYMigLHD+KvE/hzwPo134m8Wa/p+i+H7LYLnVdVuUtbaDe/lx75H+R PndE/wCB1AWDwx4o8OeN9Gs/EvhLXbDW/D175n2bVdJuUure42NsfZInyP8AOjp/wCgLHcZFWFgy KAsGBUCDAoAWgD8gv+CX/wAd/jD8Z7b4r6R8S/G9z4h07wnDo1tpT3sNv51ukiXqSGSdE3zO/kQ/ PM7v8n+29A7H69DoasR+QX/BXnSrKb4G/DzWXsrZ9TtPF0VrFfyQp51vBPZXrzJHJ99Y3eCDfH/H 5Cf3KC4nn3/BNb9qDxFHrd7+yj8YrvUk8RaXvt/CtvqUEn2qzNss/wBp0y6f76eTHBvgR0+Ty5o9 /wAkCVAj2v8A4K+/8m1+B/8AsebP/wBN+o0CR9w/sw/8m0/s7f8AYj6D/wCm+CgR3Nj4n8O6xr2v +G9N8S6fda/oTwLqelwXccl1pnnp5kPnxp88XmR/Om/79AHd5FWKxxsWtabPrl7oq6lbyaraQwXM 1jHMnnQwTvIkLSR/fRHeCbY/8fkSf3KAsdlkUBY4j/hKPDP/AAlP/CH/APCQ6d/wl/2D+0/7H+2R /bfsXmeX9p8jO/yfM+TzPub6Asfjf/zmj/z/ANCrUF9D9mtZ1nTfD+lahrOsajb2GlafE9zc393K kEFnAg3tJI7/ACIiJ1egDrcirIscjrWs6boGlahrWsalb2GlafE9zc395MkEFnEg3tJI7/IiInV6 AsfIn/BST/kzH4xfXSP/AE72NQVAP+Cbf/JmPwd+ur/+ne+oCZ91VYjwn9oL/kQfD/8A2PPgr/1J NLoA92oAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgA oAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoA8K/a e/5Np/aJ/wCxH17/ANN89AHutABQAUAIOgoAaabIW5Wuv9S/+6aun8Rz4z4JejP5dR/yx+tf0Zln wU/T9D+dMZ/vFT1PpP8AY7/5OP8Ahx/2/f8ApBd189xf/wAi+p6r80ezwz/vP3/keYfGX/ksHxQ/ 7GbVv/Sp634V/wB1pnn5z/vEhfgv/wAll+FH/Yz6R/6VJS4r/wB0q+hrkP8AvcPU/pLh/wBWv0Ff hctz+gqHwIeeppG0dxw6CgBaACgAoA/Bb/gsZq1lNq/wE0VL22fV7OHWbmaySaPzoUlayjhkdPvo jvBPsf8Aj8iT+5UAft3rOjab4g0rUNG1jTre/wBK1CJ7a5sLuJJ4LyBxsaORH+R0dOqUAfgV4Zvb r/gmD+1P4stPFuneMNb+BfivSnh0q6s2SN9RRNk8c2zekE91avvtn3vA+yd59iJMiOFkn7DmlfGn 9pH9sS5/as8T6dH/AGBpFxdf2tqsUTWlt576e9lBZ2qfxukbwf7kab5H3um8EYfwU/aM8Ofs6/t8 /tHX3xA1W5sPhv4k8TeJNP1GeNp3htJ01Gee2upLWFHeZ96SQJ8nyfaXff8Af3gHpH/BRn9rD9n7 47/BLwv4P+E3j9de8QWXiu21S4tBpV9abLZLO9jZ981uiffnj/77oGeN/tbfD7UPB+q/sP8Aj74r /D7XX+E2m+A/CmgeIoFieCbz7aR5b3T3/eI8N15D/JveP/lpsf5H2AH13/wr7/gkB/whP/Cf/bfD H9jZ/wCPT/hI9d/tP/X+R/yDfP8Atv3/APph9z5/ufPQI+8/2QfE/gPxl+zr8LfEnw48Fr4T8GTW ElvbeH8+Z9geC4eKZN//AC2/fxzv57/O+/e/zu9WKZ8o/wDBWDwLf+IP2dNM8VWOh21zN4U8SWl1 c6nJ5fn2FlOskD7Hf5/Le6ew3on9xH/5Z/IBA9D8Mf8ABSj9k/VPDvh7U/EfxFOg+JLywguL/R/7 H1W7/s27dEeS38+O12TbH3pvT7+yoGfmx8A9P1X4j6l/wUa/aT0fTLuz+G+seEfGNrbyanC6TPPq DyXsafJvi3wQQfv03/J59v8Af30DPb/+CMnT9oz/ALl7/wByNShzP3LPQ1ojM/ny+JPxI8HfCL/g rPrXxE8dax/ZXg/R/I+23/2ae48jzfDCQL+7hR3++6fwVJR+lP8Aw8i/Yu/6LN/5b2sf/ItAmfDH 7S/xeuPAn7TX7Jn7bT+BNe1D4L3vg20jS4j8tJopL2G9eSB/ndEuo7XUEnSN32TeW6I/yPIgM9q/ aB/4KD/sveKPgX8YvCvhL4g3OteKde8OahpNhp1roepQO8t3A8CvvmhREjTzN7/P9yNtm9/koA/P LxB8CfFmi/8ABNbw5461Tw1bfbn8ff8ACVRXU8Oy90zRbm1j0/8A5boj7J7qCxfZBv3o8D/7gB+r Xhb/AIKUfsoap4f8O6n4j+IraD4kvLCCe/0f+x9Vu/7NuXRHkt/PS12TbH3pvT7+ygD4W/4J4eMN O8dft3ftC+PtCiuV0fxLpWv6vaQXsccc0cFzrVlOqSbHdN+x/wC/QB2v/BGX7v7R/wBfD3/uRoBj f22/+Ukv7If/AHKn/p+u6C2fuUehoMhasAoAKACgDwj4U/8AI/8A7Tf/AGPVp/6jegUAe70AFABQ AUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAB QAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAeE +H/+Tlviz/2I/hP/ANOHiOgD3agD8E/2G9PuP2lP21fi9+1Hd6pP/Y/heea40qGdY7a52XqT2Wnw zxojpsh06CdJPn3+YkHzv+8qCzf/AGX4dO/Zk/4KGfGf9m7Qr+5fwX4rg3adaRW6eXaTpa/2papI 8zvPsgtZ76LzN773dHdP7gBu/wDBWPx5438I2/7P9t4Z8Ya/olnfz6xdXMGk6jPaR3E1tJp09q8m x/neF/njf+B/nSrA8I+K37K/7YXxN8NXn7Y/xJ8Xad4e8caZYXfiRvDc0t5YXnhnT7JPtNqllsR/ In/17+Q7o6Ptd38959gI6v4Fw/te/t0/BjR/BV38XH8LfDPw3f3ui634rN7JPqfixHso/JtZ4E2P P5EcmyV5J0SdLtHdJ5YXdwZv/sGN4w/Zk/an+Jn7InxC17TLmXVLCPULZNOa6ntpNUjtYLkfZd6o ib7KSfz3eNN/2a3Tf8ibwDlv2k/+Fu/t1/tR+Ov2dPhv400a18C/DOKS6trTVnu7G2nuYPItr159 kMjz3SXV1JBG+zy/LR9n33eeCrGN4Pvvjt/wS18YeDLf4k6xoXif4SfEGa5a/wDDfhu7nna3e08h GvIPPhhRLrZPH/sTpHsfZsgdALHpH7Zfib+3P2+v2KBpWv8A9p+E5R4X1PTfsl59ps5PtOtSbrmD HyfPHBB+8T76In9xKsk+6v8AgoZq2r6P+x78aLvS9QubS5eHTrWS4tJnjZ4JdQtoJkOz+B45HR0/ jR3SgD8wfBmj+PbD/glP488SXnibxNo+nweK3u9DTTNY8uG/0uea20u5tZ0R/wDj1eefUneD5N8i b/4/ngehFpfwC/bb/bM+D3wo07VZfD3hb4SeEdB0618MWmtXM9imtIkMkEeoPAiTO8/kRp88+xNk u+BNkz7wLI4f9iLxh+0V8UPBnxc/Zc+GfxG/sSN9BTxB4fv7u/urGTQbmDV7D7QkF1Dvkhhngnn3 x7H+c/wb5d4Ox8/fs0/sj/En9qs+Nl+HuueGdN/4Rf7F9s/4SG5ng837X5+3Z5EL/wDPB/8Ax2gL H9QXwX8N6t4A+EPwt8A65JbS6z4Y0DT9Hu5bF3kile0tY4HePciPsLx/3O9WZs+Df+CvX/Jtngf/ ALHiz/8ATfqNBUT5k/b6+D+j+Gv+FYft0fs825s4tUv7LWtRvrKyk8n7XL5dzp+rfZZIdkO+T5Jz Ps3ySQfJ5jyb4Edp/wAFA/inonxu/YV+CHxQ0CAw6b4h8V2U72hkkk+y3KWWopND5jom/wAudJI9 +z59m+gZ7X8UvjVffBH/AIJx/DPXtE10ab4r1vwN4e0DQ5k8/wAw3Vzp6eZJG8P+pmjtUup433/6 yFP9xwg+CPiD/wAE8vjz4B+FF3+0df8AxK+0fF/RzJ4p17RFmkjvdN2b7ma6TVfO/fXUHyTv9z59 /lyO6R+eAfZP/DdfiL/h3z/wuT/hJtM/4Xp9u/4RH7R/ZUnk/wBr79+/Zs8rz/7N/wBJ/wCeHmfJ s/5YVZpZHxhafsD/ABef4G6p+1vffGu2h8ZppX/CwbKG3+1yXVxF5Caj58mo70dL3/Wv9yT94ifv vn8xALI+uf2XP23fEFz+xx8Y/Gfj7xNbap8SPhdbm1trjU7O6ne+SeEJpP250/10kl15kTujo+yP fJ/z3kAsfE3wj/Ym/al/aM8O+Ev2jtF+KuhHWNZne5tNb8Sa9qv9sRz2Uz20ckk6WrvvR7X5H8z7 iLQFjc/Zk1HxzqH/AAUq8H2vxF1K21Dx7oNxqPhnUtTtZ550v5dM0K507zvMm+d3f7Lvd3++7u+x PuVAj2f9oC2+JH7eP7Xni39nLwd8QtM0v4W/Dr9+0c8M6J50UkNpqEzwbP8ASbpJ7qeJN+yPZH8j pvkkcEeZfDzRvjt+wX+158L/AIJwfEK21XwZ411Wy87SoGn/ALPurLUNQ+xefJaP8kF7stUfejvs 2Im903o9lWR7d+3XrfxC/aM/aW+H37G3ww8aW2m2n9lNNrFnd3F9Y2VxevDJqBhvtm9JkS1tLV4N iPsed/n/ALgFj5S+Nf7Nv7SX7IPwQ8UWXjLx14b1L4WeO7+00G50PRtV1GdIL3fHerepA8MMCT/8 SqODz/nfY+z/AKaJBMT9sv2IfCE3gb9lH4D6P/aUF9Dc6CmtST+V5Hl/2hI+oBPvv9z7Vs3/AMez f8n3KBTPsmrEeE/tBf8AIg+H/wDsefBX/qSaXQB7tQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAB QAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFA BQAUAFABQAUAFABQAUAFABQAUAFABQB4V+09/wAm0/tE/wDYj69/6b56APdaACgAoAQdBQA002Qt ytdf6l/901dP4jnxnwS9Gfy6j/lj9a/ozLPgp+n6H86Yz/eKnqfSf7Hf/Jx/w4/7fv8A0gu6+e4v /wCRfU9V+aPZ4Z/3n7/yPMPjL/yWD4of9jNq3/pU9b8K/wC60zz85/3iQvwX/wCSy/Cj/sZ9I/8A SpKXFf8AulX0Nch/3uHqf0lw/wCrX6CvwuW5/QVD4EPPU0jaO44dBQAtABQAUAfB/wC0N+wf8KP2 m/G9h4/8f+I/GFjqun6VHpMNv4eu7SCHyEmlm3nzrWR/M8yeT+OgD6m+IXjix+H3gfxh491W0uZt N8M6dc6te29oiec8EELzyJHvdE3+Wn9+gD+f79rr9qS1/bp1j4T/AAb+A3wl1G81VL957a61m2gT VpLl1dGgg2TOkFr5f72d3f8A5Zo77Eh3uAfuz8DPhhovwV+FHgP4Y+HrjzrDQLEQNdGOSP7Xcv8A PNN5bu+zzJ3kk2b/AJN+ygD8sv2c/gl4G+PvxU/4KR+APiFpxvNIvfHKNDNb4jm027S91vZdWsn8 E6b/AP0JH3o7o4Vc+ovgt/wTg+AHwU8f6N8QtOl8SeI9c0s77CDxRc2s9taXP/LO5jjht4/3yfwF 9+z7/wB9EdALn2f8RPAvhf4keEPEHgzxxoUWs+FNXh8m70u7yVnTt6Ojo+x0dPnR0R0+egk/Oux/ 4JMfs16ZqOnX11r3xD1OztLqOabTLnVbSOG8RJP9S/lWyPsf7nyOj4/jSgD9M9H0bTfD+ladouj6 fBYaVp8SW1tYWsSQQWcSLsWONE+REROiUAVfFXhjw5440a78M+LNA0/WvD97sNzpWq2yXVtPsfzI 98b/ACP86I//AACgD88P+HT37MX/AAkn9uf2j45/sv7f9q/4R7+1IPsXkb9/2Xf9n8/yP+Wf+v8A M2fx7/noA+1JPgt4BHwg1H4GeHbA+HPAF9oV34eS00WQJLb2tzC6SPG77/3/AO8kfzH373+d99AH mf7NP7Ifw9/ZVfxm3w91vxLqMfij7F9sHiG4gn8r7N5/l+X5MMf/AD3k/wDHaAPsCgD86/jR/wAE 4vgx8dvib4n+KXi3xV42s/EGvC2Nzb6NfWMdsnkQxwR7Ee1d/uQJ/HQVc87/AOHQn7Nf/Q6fEr/w Z6d/8hUBc+yNQ/Zx+FPiX4PeFPgP448OyeKPAehWOn2dmmrzPHcj7FCkEM3nwCN0m8tMPImw/O6f cfZQSfJfgf8A4Jb/ALMng3xnofia4vPGHiOHS7n7UNC8RXlpPYXj/wAPnxpao7x+Z8+zfsfZ8+9N 6UAfoX4q8MeHPHGjXfhnxZoGn614fvdhudK1W2S6tp9j+ZHvjf5H+dEf/gFAH596Z/wSo/ZgtPE7 +ILtfGGoaO9xPN/wi93rGyySN/M2w+YiJc7I/M+T9/v/AHa73f594B9A/D39kv4VfCv40eK/jZ4D trnQ9Z8QaX/ZE/hvTo7S00a1g/0b5oLWKFHSR3tEf/WffeSgCP8AZp/ZD+Hv7Kr+M2+Hut+JdRj8 UfYvtg8Q3EE/lfZvP8vy/Jhj/wCe8n/jtAEfxX/ZK+G3xa+N3w3+P3iLXfE9t4w8EHTvsFtplzbx 2Vx9jvHu4/PR4Xf/AFkjh9jp8lAH2JQAUAFABQAUAeEfCn/kf/2m/wDserT/ANRvQKAPd6ACgAoA KACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAo AKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAPCf D/8Ayct8Wf8AsR/Cf/pw8R0Aef8A7YnxB1n4VfszfF/xhocdwNUh0o6fbXFhdyWc1rPeTJZR3Mc6 fOjwvc+b/wBs/vp9+gD8J/2SfA37emieE9b8d/suaFc2fhPxJMltc6nP/YsaX8ltv2+X/aHzuiPP Om9Pk370++nyZ2NbnmHxf0X9pz4D/HTwp8YPj1oFz/ws251WDxVaXuszwX1tqU9pNG/l77R9mxNk aeQjpsj2fcTZSswufcv/AAVi8TaP4z8LfsoeK9BuTd6DrNhq+qWF0YXj+02kqaW6ybH+dPkdPv1q ZH7B/tPf8m0/tE/9iPr3/pvnoA+Hv+CQX/Jtfjj/ALHm8/8ATfp1QNnnnhP/AIQr/h8H8T/+Em/5 Dn9gwf8ACN/6/wD5CP8AYtl5n3fk/wCPH7d9/wCT/geygYfsK38/hH9r39tf4X6/LrcvjDVNVfWY tT1GzjglvLa21C7/AH0+xETfPHqtrOmyDy3R2dNieXQM47/gs1939nD6+If/AHHUCR4f8ddNm+GH 7Uv/AAT50rxu9lol54U8IeA7bW3v7mPyNMe21CdJvMn37NibJPn37PkoGfov/wAFNPGvhrw9+yx4 48J614htrXxH4rmsrXRNJkH7/UXgvbSefYn/ADzRE+d/ufOiffdN4I+Wv+cLn+f+hqqyT9Uv2Yf+ Taf2dv8AsR9B/wDTfBQB+K3/AATF0Gz8I/ti/Gfwzo/ie213R9E8N6vp9prtls8jU4INXso1uY9j umx0Tf8Aff7/AN+oLPV/+CMvT9o7/uXv/cjQJn7kVZJ+VP8AwV9/5Nr8D/8AY82f/pv1GgD6Q+GX w78M/Fn9jL4UfDjxbaPP4b8Q/DvRLGfYsckkBfTYNs0e9HRJo32SI+z5HRHqC0z+cD4sx/Ff4KaZ 4z/ZI8eNpw0zSPFMHiR47TZPsvfsTxLNBN/zwntZ4H2SfvPkT5I38xHDRM/TX9ra81DSv2Gv2G9X g8S3eiaTZS+FZpb7TbJ5NSs500aSSG6tJPOhTfCiT/u/k3u8f76DZ84Znp1v/wAE+/iL8S9H0y38 Y/t7+OvG3wv1iS2vLmwj8+e21iy3xzx7He/mi+f928cmx0+6+x6BHzx+2F8E/hl8Cv2LNH8K/Crx Rr+t+GLv4tTzXN34gKPKl7BZajp11D8kMPyI9i6fc/4G6bKAPZfh3+x38SvjZ4C8H+M/+G+fiR4h +Fni+wSW+0eQXMj3VnP8lzZyP/ac0CTY8yCRHSeNJN29JNlAw/aE/Yq8M/s4fsjftBWvwb1XxPrJ 13+xLzWrbXYU1GX7Fp95v/0f7KkPk7PPM8jukqeXA/yJ/rEAPvv9kPxf4a8d/s3/AAY1/wAIWup2 PhuLQYNMtrTV5o57m3+xf6EwkkRER/3lrJ8/lpv+/sT7iAj8ifhX4hsfFH/BW/U9S0bw5b6JaQeI /EOnvaWnl7XnttLvbaa6+SNPnnkged/+mk7/ADv9+gDhvhH4A8Z/Ej9rn9pL4Y6V+0vr/wANfHt5 4k1e+e88Jwz2tr4knttQn85EgXUUkR03vOkH7/5PO+f5PnAP0R8Cf8E7dOsviJ4P+Jfxi+PfxE+I PxD8KaraahpWp388aQJFbTJPDayJc/ap3QT+Y/yTp/rPuJ99wDgfAmtf8IR/wVR+LOn+NNJ1ObxJ 4+0JLXw7q+nwfZbL7CllBc/vIH3vN8mn+T58cmzz4Jv3Pz/uADv/APgqjrdho/7Lj6df+G7bUr3X fEmn6faahPs36TOnn3P2mP5Pv+XbTwf8s/kuX+f+B7JPtH9mH/k2n9nb/sR9B/8ATfBQB7rQB4T+ 0F/yIPh//sefBX/qSaXQB7tQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUA FABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAU AFABQAUAFABQB4V+09/ybT+0T/2I+vf+m+egD3WgAoAKAEHQUANNNkLcrXX+pf8A3TV0/iOfGfBL 0Z/LqP8Alj9a/ozLPgp+n6H86Yz/AHip6n0n+x3/AMnH/Dj/ALfv/SC7r57i/wD5F9T1X5o9nhn/ AHn7/wAjzD4y/wDJYPih/wBjNq3/AKVPW/Cv+60zz85/3iQvwX/5LL8KP+xn0j/0qSlxX/ulX0Nc h/3uHqf0lw/6tfoK/C5bn9BUPgQ89TSNo7jh0FAC0AFABQAUAFAHlPgz4X/DX4dvqf8AwgHgDw34 WOobPta+HtKg037UU37d/kom/Zvf/vtqAPUqAH5FBNwyKAuLQUFABQAUAFABQAUAFACZFBNwyKAu LQUFABQAUAFABQAUAFABQAUAFABQB4R8Kf8Akf8A9pv/ALHq0/8AUb0CgD3egAoAKACgAoAKACgA oAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACg AoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgDwnw//wAnLfFn /sR/Cf8A6cPEdAHkH7Xv7L+rftT+EfDHgSPx7aeFtJ0vVf7XmuX0STUpp5khkghjj/0qFETZPPv+ R9/yfc2fOAe/fDP4d+GvhT4C8H/DjwdD9l8N+H7RLG38xI0ecp96aTYiI80j75HfZ87yM9Kw7niP 7XH7M5/ar+GWh/D3/hM/+EZOn65BrP286d/aRk2QTxeWY/Oj/wCe/wB/f/BRYLnzP8Q/+Ccut/Ez 4Q/AT4V658erqOf4Yxapax67d6C92+pQXc8Dwx+W97+5SCOCOJE3v8iL9z7lMR+g/wAU/BkvxE+G njz4f2+pfYD4o0W90X7eYfP+x/aYZIPM8vcu/Z5h+TfQB4h+yP8Aszn9lT4Za58Pf+Ez/wCEmOoa 5PrP28ad/Zpj3wQReWI/Ok/54ff3/wAdQUcf/wAMZTf8Nnf8Nef8LF7/APIp/wBj/wDUK/s7/j7+ 0f8AbT/Uf7H+3QB4Z+2h/wAE89Q/aE8bW/xU+FfiLStH8faj5dvr1p4huZ/sd+kcHlwzRvGjukyI iR7Nmx02v8jo/mgzL/Y9/wCCb6fBPxi/xJ+MmpaF4k8ZaXMreHtN0lZZ9P0yT/n9czojvdb/ALn7 vZDs3/O+zyAR7f8AtcfsLeGP2rtS8LeKpPGF14S8d6Xb/wBntqyWX9pQ3dlud44Xg85NjpJJI6SI /wDG+/f8mwA+aPDP/BI/w7onhfx/pWrfGA6j4l12wtrPStVfwxGiaH5d7BczTJA907vPIkHlb0kj 2JPN9/fQM918L/sDjwr+yh8Uf2Xk+LH2mTxbrUGtf8JIdB8sWmxrJ9n2X7V8/wDx4/f8xPv/AOxV kH2z8LPBkvw7+GngP4f3Gpfbz4X0Wy0X7eIfI+2fZoY4PM8vc2zf5Y+TfQB8U/sj/sCN+yr8StW+ IUXxX/4Sn+0dFfRGsDoP9m+Tvmgn8zf9qk/54fc2fx1BR8U+KP8AgkD48PjaCLwL8VNEf4dzzbp7 zxFbzx6naxPM/wAvkQJ5Vy6QbPn8yDe/8EVAz9rPhZ4Ml+Hfw08B/D+41L7efC+i2Wi/bxD5H2z7 NDHB5nl7m2b/ACx8m+rIPl79sv8AYzn/AGupfh5/xcr/AIRL/hFf7R/5g/8AaX2sXP2b/ptDs2fZ f9v79AH0/wDCzwbL8Ofhp4B+HtzqX9ot4X0Wy0X7eIfI+1/ZoY4PMEe59m/Yvyb6gSZ8vftf/sS+ HP2qYvBmq3Pi4+FfGGhGe3/tlNKS++32Uh3+TOm9H/dyfPH+82J5k3yfvPkDRM9M179nDQvF/wCz PoX7NnjPW9Rm8O2Wi6RotzrOiLHaXU66f5DxyIj+cib3tY/k+f79Aj8edU/4JCfH6LUb9dF8e/D6 50dJnjtLq9ub60mmg3/u5JIEtXRH2fwb32f33oGfqloH7Ffw30r9l0/srX+q30nhvU/KuNW8RaVD BYXupXqXUd2033HT78Ecab97pBGib32b6BH5W6p/wSE+P0Wo366L49+H1zo6TPHaXV7c31pNNBv/ AHckkCWroj7P4N77P770DP1P/Zz/AGNvAPwL+EPjb4SalNH4qt/GTXKeJNVksv7OfUraWHyPsqbH 3rAkDv8A8tn/AHks7ps37EBH5ial/wAEgfi9F4qitdL+KfhC58D+dBHJq93Ddwah5X7vzn+wpG6b 0+fYn2r5/LT503/IDPtz4Q/8E4vC/wAF/wBoTwl8bfBXj24TwxoELww+FL3TPPmuHfTHspppL7zv vu7yT/u4ET59iIiUCOP/AGyP+CdGo/Hrx5efFv4X+NYbDx5q80Caxp3iiaSPT/IhtY4Ee1eG3d0f 9wnmI+/fu+/Hs2OAeV/s4/8ABLjxv4D+KfhL4gfE34j6EbXwpqtlrFjpvhPz7qW+mgk81FnnnRPI TzI4PuI++PenyffoA+jv24v2Jbr9qS90Dxp4J8QWeifEXRrF9LdNZjn+yazaeejqjyJv8jyPMun+ SB/M8/Y/3PkAPl34d/8ABI3UP+ER8XW/xU+IunQ+P73yodCu/D0M99Z6SiTQPNNJG/2V55pI45IN n3ER3f532bLJP1S/Zu+DM/7P3wc8HfCEeJP7eGhfa/8Aia/Y/snn+fdT3P8AqN77P9fs+/8AwUAf RNAHhP7QX/Ig+H/+x58Ff+pJpdAHu1ABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQA UAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQ AUAFABQAUAFABQAUAFAHhX7T3/JtP7RP/Yj69/6b56APdaACgAoAQdBQA002Qtytdf6l/wDdNXT+ I58Z8EvRn8uo/wCWP1r+jMs+CHp+h/OmM/3ip6n0n+x5/wAnH/Dj/t+/9ILuvnuL/wDkX1PVfmj2 eGf95+/8jzD4y/8AJYPih/2M2rf+lT1vwr/utM8/Of8AeJC/Bf8A5LL8KP8AsZ9I/wDSpKXFf+6V fQ1yH/e4ep/SXD/q1+gr8Lluf0FQ+BDz1NI2juOHQUALQAUAFABQAUAFABQAUAFABQAUAFABQAUA FABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQB8+ax8B/A2seIfEXiqS68YWGs67Ml1fS+HfGu uaNDdSpbwWyP9ntb2ODf5EECb9n/ACzoAu/8M8+A/wDoYPiZ/wCHN8V//LGgA/4Z58B/9DB8TP8A w5viv/5Y0AH/AAzz4D/6GD4mf+HN8V//ACxoAP8AhnnwH/0MHxM/8Ob4r/8AljQAf8M8+A/+hg+J n/hzfFf/AMsaAD/hnnwH/wBDB8TP/Dm+K/8A5Y0AH/DPPgP/AKGD4mf+HN8V/wDyxoAP+GefAf8A 0MHxM/8ADm+K/wD5Y0AH/DPPgP8A6GD4mf8AhzfFf/yxoAP+GefAf/QwfEz/AMOb4r/+WNAB/wAM 8+A/+hg+Jn/hzfFf/wAsaAD/AIZ58B/9DB8TP/Dm+K//AJY0AH/DPPgP/oYPiZ/4c3xX/wDLGgA/ 4Z58B/8AQwfEz/w5viv/AOWNAB/wzz4D/wChg+Jn/hzfFf8A8saAD/hnnwH/ANDB8TP/AA5viv8A +WNAB/wzz4D/AOhg+Jn/AIc3xX/8saAD/hnnwH/0MHxM/wDDm+K//ljQAf8ADPPgP/oYPiZ/4c3x X/8ALGgA/wCGefAf/QwfEz/w5viv/wCWNAB/wzz4D/6GD4mf+HN8V/8AyxoAP+GefAf/AEMHxM/8 Ob4r/wDljQAf8M8+A/8AoYPiZ/4c3xX/APLGgA/4Z58B/wDQwfEz/wAOb4r/APljQAf8M8+A/wDo YPiZ/wCHN8V//LGgA/4Z58B/9DB8TP8Aw5viv/5Y0AH/AAzz4D/6GD4mf+HN8V//ACxoAP8Ahnnw H/0MHxM/8Ob4r/8AljQAf8M8+A/+hg+Jn/hzfFf/AMsaAD/hnnwH/wBDB8TP/Dm+K/8A5Y0AH/DP PgP/AKGD4mf+HN8V/wDyxoAP+GefAf8A0MHxM/8ADm+K/wD5Y0AH/DPPgP8A6GD4mf8AhzfFf/yx oAP+GefAf/QwfEz/AMOb4r/+WNAB/wAM8+A/+hg+Jn/hzfFf/wAsaAD/AIZ58B/9DB8TP/Dm+K// AJY0AH/DPPgP/oYPiZ/4c3xX/wDLGgA/4Z58B/8AQwfEz/w5viv/AOWNAB/wzz4D/wChg+Jn/hzf Ff8A8saAD/hnnwH/ANDB8TP/AA5viv8A+WNAB/wzz4D/AOhg+Jn/AIc3xX/8saAD/hnnwH/0MHxM /wDDm+K//ljQAf8ADPPgP/oYPiZ/4c3xX/8ALGgA/wCGefAf/QwfEz/w5viv/wCWNAB/wzz4D/6G D4mf+HN8V/8AyxoAP+GefAf/AEMHxM/8Ob4r/wDljQAf8M8+A/8AoYPiZ/4c3xX/APLGgA/4Z58B /wDQwfEz/wAOb4r/APljQAf8M8+A/wDoYPiZ/wCHN8V//LGgA/4Z58B/9DB8TP8Aw5viv/5Y0AH/ AAzz4D/6GD4mf+HN8V//ACxoAP8AhnnwH/0MHxM/8Ob4r/8AljQAf8M8+A/+hg+Jn/hzfFf/AMsa AD/hnnwH/wBDB8TP/Dm+K/8A5Y0AH/DPPgP/AKGD4mf+HN8V/wDyxoAP+GefAf8A0MHxM/8ADm+K /wD5Y0AH/DPPgP8A6GD4mf8AhzfFf/yxoAP+GefAf/QwfEz/AMOb4r/+WNAB/wAM8+A/+hg+Jn/h zfFf/wAsaAD/AIZ58B/9DB8TP/Dm+K//AJY0AH/DPPgP/oYPiZ/4c3xX/wDLGgA/4Z58B/8AQwfE z/w5viv/AOWNAB/wzz4D/wChg+Jn/hzfFf8A8saAD/hnnwH/ANDB8TP/AA5viv8A+WNAB/wzz4D/ AOhg+Jn/AIc3xX/8saAD/hnnwH/0MHxM/wDDm+K//ljQAf8ADPPgP/oYPiZ/4c3xX/8ALGgDW8Hf DLw74FbVDoJ1RtQ1IwC41bXdYvtZvZ449/lw/ar2aabyE3yOkPmeWjzTPs/ePvAPYKACgAoAKACg AoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgD5h/aQvrm38Da CBo2v6nL/wAJd4XujH4d0e+1WZILTWrK9ncw2qO+xILWZ9//AAD77ojgHUf8NDeA/wDoX/iZ/wCG y8V//K6gA/4aG8B/9C/8TP8Aw2Xiv/5XUAH/AA0N4D/6F/4mf+Gy8V//ACuoAP8AhobwH/0L/wAT P/DZeK//AJXUAH/DQ3gP/oX/AImf+Gy8V/8AyuoAP+GhvAf/AEL/AMTP/DZeK/8A5XUAH/DQ3gP/ AKF/4mf+Gy8V/wDyuoAP+GhvAf8A0L/xM/8ADZeK/wD5XUAH/DQ3gP8A6F/4mf8AhsvFf/yuoAP+ GhvAf/Qv/Ez/AMNl4r/+V1AB/wANDeA/+hf+Jn/hsvFf/wArqAD/AIaG8B/9C/8AEz/w2Xiv/wCV 1AB/w0N4D/6F/wCJn/hsvFf/AMrqAD/hobwH/wBC/wDEz/w2Xiv/AOV1AB/w0N4D/wChf+Jn/hsv Ff8A8rqAD/hobwH/ANC/8TP/AA2Xiv8A+V1AB/w0N4D/AOhf+Jn/AIbLxX/8rqAD/hobwH/0L/xM /wDDZeK//ldQAf8ADQ3gP/oX/iZ/4bLxX/8AK6gA/wCGhvAf/Qv/ABM/8Nl4r/8AldQAf8NDeA/+ hf8AiZ/4bLxX/wDK6gA/4aG8B/8AQv8AxM/8Nl4r/wDldQAf8NDeA/8AoX/iZ/4bLxX/APK6gA/4 aG8B/wDQv/Ez/wANl4r/APldQAf8NDeA/wDoX/iZ/wCGy8V//K6gA/4aG8B/9C/8TP8Aw2Xiv/5X UAH/AA0N4D/6F/4mf+Gy8V//ACuoAP8AhobwH/0L/wATP/DZeK//AJXUAH/DQ3gP/oX/AImf+Gy8 V/8AyuoAP+GhvAf/AEL/AMTP/DZeK/8A5XUAH/DQ3gP/AKF/4mf+Gy8V/wDyuoAP+GhvAf8A0L/x M/8ADZeK/wD5XUAH/DQ3gP8A6F/4mf8AhsvFf/yuoAP+GhvAf/Qv/Ez/AMNl4r/+V1AB/wANDeA/ +hf+Jn/hsvFf/wArqAD/AIaG8B/9C/8AEz/w2Xiv/wCV1AB/w0N4D/6F/wCJn/hsvFf/AMrqAD/h obwH/wBC/wDEz/w2Xiv/AOV1AB/w0N4D/wChf+Jn/hsvFf8A8rqAD/hobwH/ANC/8TP/AA2Xiv8A +V1AB/w0N4D/AOhf+Jn/AIbLxX/8rqAD/hobwH/0L/xM/wDDZeK//ldQAf8ADQ3gP/oX/iZ/4bLx X/8AK6gA/wCGhvAf/Qv/ABM/8Nl4r/8AldQAf8NDeA/+hf8AiZ/4bLxX/wDK6gA/4aG8B/8AQv8A xM/8Nl4r/wDldQAf8NDeA/8AoX/iZ/4bLxX/APK6gA/4aG8B/wDQv/Ez/wANl4r/APldQAf8NDeA /wDoX/iZ/wCGy8V//K6gA/4aG8B/9C/8TP8Aw2Xiv/5XUAH/AA0N4D/6F/4mf+Gy8V//ACuoAP8A hobwH/0L/wATP/DZeK//AJXUAH/DQ3gP/oX/AImf+Gy8V/8AyuoAP+GhvAf/AEL/AMTP/DZeK/8A 5XUAH/DQ3gP/AKF/4mf+Gy8V/wDyuoAP+GhvAf8A0L/xM/8ADZeK/wD5XUAH/DQ3gP8A6F/4mf8A hsvFf/yuoAP+GhvAf/Qv/Ez/AMNl4r/+V1AB/wANDeA/+hf+Jn/hsvFf/wArqAD/AIaG8B/9C/8A Ez/w2Xiv/wCV1AB/w0N4D/6F/wCJn/hsvFf/AMrqAPFfj38Y9B8Z/BT4veC/C/hb4k3niPXfCur6 dYWn/CtPE6faLmezlRE3vYbE+d0+/QB9wUAFABQAg6CgBppshblW4/1T/wC6aun8Rz4z4JejP5dV 6RV/RuWfw4eh/O2O/wB4qep9L/se/wDJx/w6/wC37/0guq+c4t/5F1T1j+aPW4Y/3r7/AMjy34y/ 8lg+KH/Yzat/6VPXRwr/ALrTODOf94kL8F/+Sy/Cj/sZ9I/9KkpcV/7pV9DXIf8Ae4ep/SXD/q1+ gr8Lluf0FQ+BDz1NI2juOHQUALQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQ AUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAB QAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFA BQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAF ABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUA FABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAU AFABQAUAFABQAUAFABQAUAFABQAUAFABQAw02Qtyvc/6p/8AdNVT+JHPi/4cvRn8ua/8s/rX9G5Y 0qcPQ/nbHJ/WKnqfSv7H2D+0f8Oj733/AKQXdfOcWtPL6lu8fzR63DKtibvz/I8x+Mv/ACWD4o/9 jNq3/pU9dPCv+60zgzj/AHiQfBf/AJLL8KP+xm0j/wBKkpcV/wC6VfQ34d/3uB/SXF9xa/DJbn9A UfgQ49TUm0dxw6CgBaACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAC gAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKA CgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAK ACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoA 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 xw8Hf+pJptfO7n1kVZWLVIthQIKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAK ACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoA KACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAo AKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgA oAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACg AoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAC gAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgDx/9of8A5N/+On/Yn63/AOkU9AH2/kVYC0AJtHpQ TYMD0oCx89ftN/8AJMbT/scfB3/qR6ZUFE1ABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUA FABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAU AFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQA UAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQ AUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAB QAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFA BQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAHj/AO0P/wAm/wDx0/7E/W//AEin oA+0z/sNWU1WZMXSiNzn/WEUQdaISq0i/XQUFAHz1+03/wAkxtP+xx8Hf+pHplQBLQAUAFABQAUA FABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAHges al8WNV+L/ivwr4K8ZeHtK0PS/Deiah9k13w/Jq37+7utVRnR4Lq1dPktI/v7/ufJs+feAbv9iftA /wDRTfh9/wCENff/AC5oAP7E/aB/6Kb8Pv8Awhr7/wCXNAB/Yn7QP/RTfh9/4Q19/wDLmgA/sT9o H/opvw+/8Ia+/wDlzQAf2J+0D/0U34ff+ENff/LmgA/sT9oH/opvw+/8Ia+/+XNAB/Yn7QP/AEU3 4ff+ENff/LmgA/sT9oH/AKKb8Pv/AAhr7/5c0AH9iftA/wDRTfh9/wCENff/AC5oAP7E/aB/6Kb8 Pv8Awhr7/wCXNAB/Yn7QP/RTfh9/4Q19/wDLmgA/sT9oH/opvw+/8Ia+/wDlzQAf2J+0D/0U34ff +ENff/LmgA/sT9oH/opvw+/8Ia+/+XNAB/Yn7QP/AEU34ff+ENff/LmgA/sT9oH/AKKb8Pv/AAhr 7/5c0AH9iftA/wDRTfh9/wCENff/AC5oAP7E/aB/6Kb8Pv8Awhr7/wCXNAB/Yn7QP/RTfh9/4Q19 /wDLmgA/sT9oH/opvw+/8Ia+/wDlzQAf2J+0D/0U34ff+ENff/LmgA/sT9oH/opvw+/8Ia+/+XNA B/Yn7QP/AEU34ff+ENff/LmgA/sT9oH/AKKb8Pv/AAhr7/5c0AH9iftA/wDRTfh9/wCENff/AC5o AP7E/aB/6Kb8Pv8Awhr7/wCXNAB/Yn7QP/RTfh9/4Q19/wDLmgA/sT9oH/opvw+/8Ia+/wDlzQAf 2J+0D/0U34ff+ENff/LmgA/sT9oH/opvw+/8Ia+/+XNAB/Yn7QP/AEU34ff+ENff/LmgA/sT9oH/ AKKb8Pv/AAhr7/5c0AH9iftA/wDRTfh9/wCENff/AC5oAP7E/aB/6Kb8Pv8Awhr7/wCXNAB/Yn7Q P/RTfh9/4Q19/wDLmgA/sT9oH/opvw+/8Ia+/wDlzQAf2J+0D/0U34ff+ENff/LmgA/sT9oH/opv w+/8Ia+/+XNAB/Yn7QP/AEU34ff+ENff/LmgA/sT9oH/AKKb8Pv/AAhr7/5c0AH9iftA/wDRTfh9 /wCENff/AC5oAP7E/aB/6Kb8Pv8Awhr7/wCXNAB/Yn7QP/RTfh9/4Q19/wDLmgA/sT9oH/opvw+/ 8Ia+/wDlzQAf2J+0D/0U34ff+ENff/LmgA/sT9oH/opvw+/8Ia+/+XNAB/Yn7QP/AEU34ff+ENff /LmgA/sT9oH/AKKb8Pv/AAhr7/5c0AH9iftA/wDRTfh9/wCENff/AC5oAP7E/aB/6Kb8Pv8Awhr7 /wCXNAB/Yn7QP/RTfh9/4Q19/wDLmgA/sT9oH/opvw+/8Ia+/wDlzQAf2J+0D/0U34ff+ENff/Lm gA/sT9oH/opvw+/8Ia+/+XNAB/Yn7QP/AEU34ff+ENff/LmgA/sT9oH/AKKb8Pv/AAhr7/5c0AH9 iftA/wDRTfh9/wCENff/AC5oAP7E/aB/6Kb8Pv8Awhr7/wCXNAB/Yn7QP/RTfh9/4Q19/wDLmgA/ sT9oH/opvw+/8Ia+/wDlzQAf2J+0D/0U34ff+ENff/LmgA/sT9oH/opvw+/8Ia+/+XNAB/Yn7QP/ AEU34ff+ENff/LmgA/sT9oH/AKKb8Pv/AAhr7/5c0AH9iftA/wDRTfh9/wCENff/AC5oAP7E/aB/ 6Kb8Pv8Awhr7/wCXNAB/Yn7QP/RTfh9/4Q19/wDLmgA/sT9oH/opvw+/8Ia+/wDlzQAf2J+0D/0U 34ff+ENff/LmgA/sT9oH/opvw+/8Ia+/+XNAB/Yn7QP/AEU34ff+ENff/LmgA/sT9oH/AKKb8Pv/ AAhr7/5c0AH9iftA/wDRTfh9/wCENff/AC5oAP7E/aB/6Kb8Pv8Awhr7/wCXNAB/Yn7QP/RTfh9/ 4Q19/wDLmgA/sT9oH/opvw+/8Ia+/wDlzQAf2J+0D/0U34ff+ENff/LmgA/sT9oH/opvw+/8Ia+/ +XNAB/Yn7QP/AEU34ff+ENff/LmgA/sT9oH/AKKb8Pv/AAhr7/5c0AH9iftA/wDRTfh9/wCENff/ AC5oAP7E/aB/6Kb8Pv8Awhr7/wCXNAB/Yn7QP/RTfh9/4Q19/wDLmgA/sT9oH/opvw+/8Ia+/wDl zQAf2J+0D/0U34ff+ENff/LmgA/sT9oH/opvw+/8Ia+/+XNAB/Yn7QP/AEU34ff+ENff/LmgA/sT 9oH/AKKb8Pv/AAhr7/5c0AH9iftA/wDRTfh9/wCENff/AC5oAP7E/aB/6Kb8Pv8Awhr7/wCXNAB/ Yn7QP/RTfh9/4Q19/wDLmgA/sT9oH/opvw+/8Ia+/wDlzQAf2J+0D/0U34ff+ENff/LmgA/sT9oH /opvw+/8Ia+/+XNAB/Yn7QP/AEU34ff+ENff/LmgA/sT9oH/AKKb8Pv/AAhr7/5c0AH9iftA/wDR Tfh9/wCENff/AC5oAP7E/aB/6Kb8Pv8Awhr7/wCXNAB/Yn7QP/RTfh9/4Q19/wDLmgA/sT9oH/op vw+/8Ia+/wDlzQAf2J+0D/0U34ff+ENff/LmgA/sT9oH/opvw+/8Ia+/+XNAB/Yn7QP/AEU34ff+ ENff/LmgA/sT9oH/AKKb8Pv/AAhr7/5c0AH9iftA/wDRTfh9/wCENff/AC5oAP7E/aB/6Kb8Pv8A whr7/wCXNAB/Yn7QP/RTfh9/4Q19/wDLmgA/sT9oH/opvw+/8Ia+/wDlzQAf2J+0D/0U34ff+ENf f/LmgA/sT9oH/opvw+/8Ia+/+XNAB/Yn7QP/AEU34ff+ENff/LmgA/sT9oH/AKKb8Pv/AAhr7/5c 0AH9iftA/wDRTfh9/wCENff/AC5oAP7E/aB/6Kb8Pv8Awhr7/wCXNAB/Yn7QP/RTfh9/4Q19/wDL mgA/sT9oH/opvw+/8Ia+/wDlzQAf2J+0D/0U34ff+ENff/LmgA/sT9oH/opvw+/8Ia+/+XNAB/Yn 7QP/AEU34ff+ENff/LmgA/sT9oH/AKKb8Pv/AAhr7/5c0AH9iftA/wDRTfh9/wCENff/AC5oAP7E /aB/6Kb8Pv8Awhr7/wCXNAB/Yn7QP/RTfh9/4Q19/wDLmgA/sT9oH/opvw+/8Ia+/wDlzQAf2J+0 D/0U34ff+ENff/LmgA/sT9oH/opvw+/8Ia+/+XNAB/Yn7QP/AEU34ff+ENff/LmgA/sT9oH/AKKb 8Pv/AAhr7/5c0AH9iftA/wDRTfh9/wCENff/AC5oAP7E/aB/6Kb8Pv8Awhr7/wCXNAB/Yn7QP/RT fh9/4Q19/wDLmgA/sT9oH/opvw+/8Ia+/wDlzQAf2J+0D/0U34ff+ENff/LmgA/sT9oH/opvw+/8 Ia+/+XNAB/Yn7QP/AEU34ff+ENff/LmgA/sT9oH/AKKb8Pv/AAhr7/5c0AH9iftA/wDRTfh9/wCE Nff/AC5oAP7E/aB/6Kb8Pv8Awhr7/wCXNAB/Yn7QP/RTfh9/4Q19/wDLmgA/sT9oH/opvw+/8Ia+ /wDlzQAf2J+0D/0U34ff+ENff/LmgA/sT9oH/opvw+/8Ia+/+XNAB/Yn7QP/AEU34ff+ENff/Lmg A/sT9oH/AKKb8Pv/AAhr7/5c0AH9iftA/wDRTfh9/wCENff/AC5oAP7E/aB/6Kb8Pv8Awhr7/wCX NAB/Yn7QP/RTfh9/4Q19/wDLmgA/sT9oH/opvw+/8Ia+/wDlzQAf2J+0D/0U34ff+ENff/LmgA/s T9oH/opvw+/8Ia+/+XNAB/Yn7QP/AEU34ff+ENff/LmgA/sT9oH/AKKb8Pv/AAhr7/5c0AH9iftA /wDRTfh9/wCENff/AC5oAP7E/aB/6Kb8Pv8Awhr7/wCXNAB/Yn7QP/RTfh9/4Q19/wDLmgA/sT9o H/opvw+/8Ia+/wDlzQAf2J+0D/0U34ff+ENff/LmgA/sT9oH/opvw+/8Ia+/+XNAB/Yn7QP/AEU3 4ff+ENff/LmgDz/4qXP7Qvg/4X/EjxbafE7wN9o0TQdR1BPsngm7jm3xWrv+7kfVHRH/AHf8aOn+ w9AH0/QAUAFABQAUAeP/ALQ//Jv/AMdP+xP1v/0inppN6ITaSuz3X/hfvwS/6K54N/8AB5af/FV2 LLcW9ov7jyZZxg07Nom0/wCLfwt8RX9vpHhv4j+GNQ1m7LLBa2OqQXDylU3v8qN2RM1z1cvxcNWn 9x00cxwdTZo9lqTuCgD56/ab/wCSY2n/AGOPg7/1I9MqAJaACgAoAKACgAoGj5H/AGrv2rvDX7N/ hqO3t47bVfifqkO/R9Akk/dxp9z7Vd7PuQJ/327psT+N0DRH5z6D/wAFUPi9batZz+Kvh74Pv9CT f51ppCXdjNL8vybJ3uJkT95s/gf/ANnoJP1g+BX7QPw4/aH8NXniPwBfXSS2U3k3+iaiscd7YP8A w+YiO/yP5e9HR3T738aOiAGR8Cv2mfhx+0Pf+PLL4d2+sfZ/Ck0CzX+o20cEN+krz7Wg+ffs/cSf fRH+dfkoIPoegAoAKACgAoA/I/8Aac/b2+L/AMFvjj44+GfhXw54PudC0j7F5M+r2V3JNJ5tnBO3 mOl0if6yR/4KCzwL/h6P+0D/ANCb8Pv/AAAvv/k2gD9cv2Y/ijr/AMafgf4H+Jniq0sLbW9X+2+d BpCyRwxeVezwLsR3d/8AVon8dBB73QAUFn5l/s6/tmfFD4u/C/8AaY8beIvD/hS21P4eaD/aelR6 ZbXccNxP9lv3/f77h96f6In3Nn8dAHvv7Gfx78ZftFfC/XfGnjXTdHs9Tsten0xY9Ghnjh8hLW0f +N3+f9/JQNn1vQZM/C/Qf+Ck37UPi3V7PQPCvwx8H6xrtzv8nTNK0TU7ua42Jvby0S63v+7SR6DQ 9I+Gn/BTXxVYeN5fCv7QPgCw0qw+2/Y7m/0K2u7SbQXTek3n2k7u7/vPL3omx02N8jv8lAH696bq Wm6xYafqulXtteaXfwpdW13aTRyQ3EDpvVo5E++j0E2LtAWCgLHj/wAPfjx8Mvid4r8aeA/DXiD/ AIrjwneXdnqug3cPkTR+RdPbPPH/AATp5iffTfs3pv2O+ygLHsFBNgoCxzfjPxVpvgbwh4r8a6rb 3M2meHtOu9UuY7RY5JpYIrd3fZv/AI/3dBofJHi39sPStY/ZX8b/ALQ3wbsvOvNAvYNP/s3xRZSR /Z53urZGSeOB/n/cXcbpsf8AjT/bSgD2D9mP4o6/8afgf4H+Jniq0sLbW9X+2+dBpCyRwxeVezwL sR3d/wDVon8dBB73QAUAeQaJ/wAl++Jn/Yn+F/8A0t1+gD1+gAoAKACgAoAKACgAoAKACgAoAKAC gAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKA CgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAK ACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoA KACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAo AKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAPH/wBof/k3/wCOn/Yn63/6RT0AewUAFABQAUAF DFHc8f8A2h/+Tf8A46f9ifrf/pFPXbl6vUV+6OTHO1OXofiP/cr9+wOGg4w0Wx/PmNxE1iKmvU+l f2Ozt/aS+HB/2tQ/9N9zXz3FlCEMvqNLqvzR7HDGInLE2b7/AJH9AeR61+LXZ+7hRdgfPX7Tf/JM bT/scfB3/qR6ZSAloAKACgAoAKACgaPwv8FXmlfth/t/3HiO70T/AISH4V6X59wtlqNzJJDFp1lb +RazeQ+x9k93JBP9m2f8vL70f56DRH7ca94e8PeLdJvPD3irQrDWNCudnnadqttHdwz7H3r5kb/I /wC8SN6CT5r/AGVP2WtK/Zj8PeK9Pg8Rf8JDruv3qXFzq/2OSx/cRL+5t/I850+R3nff/wBN/wDY SgDyz9mn42fsxP4P/aA8a/BL4Xax4Y0zw1D/AMJJ4kjksoI5r/8Ac3bqkH+lP8ieRPsg+RE3/Js3 vQQfSHwE+Pfg79orwhqPjXwXpusWelWWpPpjx6zDBHN56W8D/wADv8n7+OgDmv8AhqXwB/w0P/wz P/Y3iH/hPP8An/8As0H9n/8AHl9t+/52/wD1f+x9+gDzj9oT9tvwl8GfFtn8MvCvhK/8c/FR7yC1 ufD1h59p9k89UeH5/s7+c7+fBsSBH/j37PkRwC5+zl+2f4a+OXibxB8PfEfhW58B/E/TpnRfDWo3 Pnvdon+uSOR0T9+nlvvgdN+xN/z7H2AH2fQB+A/7Qmpabo//AAUks9V1W9trPS7LxV4Uurm7vJo4 4YIEt9Odnkd/uIlBZ+xOpftLfs9aVYahqV38cPAz29pC9w8dpr1pdzSoib/3cCO7u/8AsIm96AOa 8Z/tY/Bnwf8ABvR/jp/at/rHgPV73+z9Nk0qwk86/n3OjKkc2zZs8id/n2fc/wBzeEHuHgzxVpvj nwh4U8a6Vb3MOmeIdOtNUto7tY45ooJbdHTfs/j/AHlAHjnwK/aZ+HH7Q9/48svh3b6x9n8KTQLN f6jbRwQ36SvPtaD59+z9xJ99Ef51+Sgs/Nr/AIJoeFdN8c+D/wBqjwVqtxcw6Z4h07TtMuZLR445 o4J4dRRvL3/x/vKAPon/AIJb/wDJAPGH/Y33X/pHZUDZ+kdBkz8d/wDgk7/zXv8A7gn/ALkaDQ/Q D9pb9n7wz+0P8OdT8N6lZWyeK7KGefw9rMj+W9he7fl3ybH/AHD+XGjpsf5P9tEdAD4v/wCCWvxO /tXwR48+Emo32+80C9TV9Njnv/Mk+zXPyTJBB/AiTpvd0+Tfe/wfxhVjpNe/4KOwXl/4of4O/AXx T488F+HoftGq+JY3ktIbRN0/+kPGkM2yB44N6PPsf73yJsoCx9KfCv8Aau+HHxR+DPin4vadFcwy +FNNn1DxB4ajeOS90t4IXnZY/ub0fZJsf5Ef/YdHjQCx+Yf7Ov7Znwv+EXxQ/aY8beIvD/iu50z4 h69/aelR6ZbWkk1vB9qv3/f77hNj/wClp9zf/HQFj9VPiF+0n4A+HvwP0P446r9ph0vxDpsF1omm 3ayRzX9zPZSXdraySQpN5Lv5ezf9xKBWPjv4b/8ABUfwB4k8SxaV8RvAFz4M0B4Xf+3YNSk1aOKf +BZIEtUfY/7z503/AD7Pk2fOgFj6V0H9rT4M/Ff4c/GjxHoGh6x4k8LeCoXXXtEnsII5L/TnR91x HHM6I8DpHO+x3R9iP8nzojgj5S+Ivjn4M+PP+CffxgvvgZ4DufCvgrS9T07THsLuyggmuLtLrSv3 0mx3899jwfO7732fPQB6x+y78WvA/wAE/wBhT4d+P/H+q/Y9HtP7UWGCP95Nfz/2hf7YII/43f8A +Ld9iI70EHvH7NP7SGlftJ+HvGHiLRfCt/olnpGsPp8Md/5kn2qDajrNv2eQj/vPngR32fL8/wA6 UAfSlAHkGif8l++Jn/Yn+F//AEt1+gD1+gAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACg AoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAC gAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKA CgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAK ACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoA KACgAoAKACgAoAKACgAoAKAPH/2h/wDk3/46f9ifrf8A6RT0AewUAFABQAUAFDFHc8f/AGh/+Tf/ AI6f9ifrf/pFPXdl/wDEj6o5Mf8Aw5ejPxKX70Nf0NlsW4w9D+dMbJfWKnqfSv7Hv/Jx/wAOv+37 /wBILqvnOL4tZfU9Y/mezwvJfWvv/I928d/tyfF/wn438ZeFNP0nwo9npGr3un20l3aXckkqQTOi 7/333/3dfIZXwpRxmHjJPc+qx/FeLwuIkS+BP24/i94s8ceCfCuoaV4YSz1jWLLT7mS1tLqN4klm RG2fvvv/ALyjNeFKOCw8pX2Ky7inFYzExR99ftL8/DGy/wCxw8Gf+pJp1fnzVnY/T4O8Uy3SNGFA goAKACgAoGj8I/8AgnRcwfDf9p7xr8OPGmm21n41u9OvdFh8x5J5o720uEea1jkhfyNnlwTu7v8A 8+i7H+f5w0R+7lBnY/FP9lT9qv8AaY8c/tMeCvhd8UPGlzNpk82o2uq6Nd6JY2M0U8FncvsfZCjo 6SRp/wB8UBY5v9gPQdV8W/CD9tPwr4ftftOuav4btNPsrTdHH5889rqqKm9/kT55P46Cj6E/4JZe MPDL/C/xv4ATWrb/AITWDXp9XbSZP3c32J7W0gWaP++m9JEfZ9z5d/303gB4w8Vab4h/4KlfCvSr C3uUufDWgz6ZeSTpH5ck76fqN78n+xsu4/8Age+gD5v8E/tM/C74e/taftAfGH4t6N4p1vxA+o3e l+G/sGj2kclhaI7wfv4LryXgnS0ggg/v+W9wj/O9AGF4t+LXg39pD9t/4BeNPhX4Q1i2i/tHRF1K O7sII7m7ntr2R5rqTyXfeiWmz53+4kH9xKC5H780GSP57v2pfCun+Of+Cgmo+CtVuLmHTPEOveGt LuZLSSOOaOCe1sEby9/8f7yg0kfd3/Drf9n7/ocviD/4H2P/AMhUGbPJv27fhvo/wT/ZL+Enwo8K prF54W0vxVvh1XU5oJJIndL2fa+zZ87+fJs2Js2QPvf7m8KP1v03TdN0ew0/StKsraz0uwhS1trS 0hjjht4ETYqxxp9xEoA/IT/gk7/zXv8A7gn/ALkaC5B/wSd/5r3/ANwT/wByNBkj2X/glv8A8kA8 Yf8AY33X/pHZUGjP0joIZ+O//BJ3/mvf/cE/9yNA2j9iKDNo/nL/AGJ9e1/wNdftF/EbQoL+GXQf hpqn2bV7TTpL6O11F7iD7L5nyOn30d/n+TZA7v8AIj0Gh7J+yF+17+z9+zl8MZPD+teEvGF5481e 9e91jU9MsLGSOX+CGFJHuEfYkfz7H/jnuP79AGx/wTlh0rUv2oPjJ4j8CeH7+z+G/wDY+opYRzrJ J9ggn1CB7WGeTe/z+RHJ/G+/yG+/soA9g/Y8+HXgDxD8X/23fCHiDwN4e1LwvpfjCD7Ho1/pkE9r a7LrWEXZA6bE2R/J8n/LOgDg/wBtvwqnjz9qj9mj4A/aLbTfh3/ZtlDbWFg9ppsdhBPePBN5Ej/J v8i0gRE+f50RETe+xwD9JfiR8BPAHxF+DEnwRn0q2ttAttOSy0R50ku30aeCDZa3Efz73dP9/wCd NyP8jvQB+Z37HOg6VbfsPftc+KoLTZruo2Wt6fc3e+T95BbaTvhTy/ufI91P/wB9/wC5QUc34P8A CupeHv8Aglr8VNVvp7Z7bxLr0Gp2ccDSeZFAmoadZfP/ALe+0f8A4BsoA2Lz4XeP/ip/wTa+Celf D3w5c63qml69e6tc2lo0fnfZkm1hGZI3f53/AHifIm933/IlBJ9P/sQ/tb+Eviv4e0f4Qa1pth4Y 8eaBZJa6VpNo0/2bU9OgT5fsnnu774I4/nR3d9ib/n+fYAfobQQeQaJ/yX74mf8AYn+F/wD0t1+g D1+gAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAo AKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgA oAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACg AoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAC gAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAPH/ANof /k3/AOOn/Yn63/6RT0AewUAFABQAUAFDFHc8f/aH/wCTf/jp/wBifrf/AKRT13Zf/Ej6o5Mf/Dl6 M/Ekf8sfrX9EZd8MPQ/nXGf7xU9T6T/Y8/5OP+HH/b9/6QXdfN8X/wDIvqeq/NHs8M/7z9/5Hmnx jdP+FxfFKSXr/wAJNq3/AKVPW/C0YxwkL9jjz2VWeIkHwadP+FyfC2SL/oZ9J/8ASpKXFUYywk7d jbh11YYqFz9wv2lv+SYWf/Y3+DP/AFJNOr8Jluz9/p/Ci5UmrCgQUAFABQAUDR+R/wC2r8N/HHwN +LWj/trfDLUPtN4l7bWuq6df2Xnx2j/Zfsit8n/LrPBH5D73SRHddj/OmwNInH69/wAFXNfudJvI PCvwWsLDXX2eTd6vrkl9DH8/zeZAlvC7/u9/8af+yUBY8b/ZRtvH+pftqfDP4m+O/B1/on/CeXuv 67bTz2E9pa3/AJ+n3M7PaST/AH0/fx/xv8jrQFj3z/gk7/zXv/uCf+5Ggk5v9pbwH4//AGJ/irqf x++BP9j6V4I8Ywz6L9gjto5I9Ju54d7LHA/8HmQfa02fIjp5Dps+ScA+lP2GPg5qOq2F5+1R8X4r nWPjB41mnurDUdX3+ZYadt2K8cDqnkvP+82bPk+y/Z0TYjujgHzv4n+Luv8A7En7WPxbu38EX9/8 J/iFrEGqXt/f20kc11+58+b+zZ/kgfyJ9Rf5Pn+4qb0f56APVLD9vbxP8Y/jP8I/BXwB8Aaw/hN9 RgbxVPq+nefc/YnnSBm2QO/kQQeek/n7/v7PuIjpOFyP1MoMkfgn8cv+Um2h/wDY4+EP/ROnUGkj 97KDNnxh+358N7j4i/s2eLXsUuZtU8KTJ4ktoIZo40lSDek3mb/4EtZ7t9ifPvRf9xwo+Ovhd/wU g+L/AItsPDfw20r4LW3i34wXsL2dtq8Go+RDf3Ox9s09qkPyIn35/wB+ifIz/uE+4AXP+CTv/Ne/ +4J/7kaC5B/wSd/5r3/3BP8A3I0GSPZf+CW//JAPGH/Y33X/AKR2VBoz9I6CD+bP9k79rH/hl3/h YP8AxQH/AAk//CS/Yv8AmK/Yfsn2Tz/+mL79/n/+OUGrR7h8V/29vi9+0Jo0fwr+Evw2udEn1+G7 tdRtNMf/AISC91e0eF0a3jj+ypsTy/Pd3RN/yL86bH3hm0fev7MH7Ium/DT4BeK/BXjRLm28b/Ef TZ7XxVJYXkc/2SB1nSGGD5NiOiTyfP8AP87t87psoA+Fv2Wv2w/+GV/D+sfBn42eAPGCfYb2fULb /n70vzVgdLX7DdbNif6+ffv+/P8Ac+ffQB9o/sr/ALXXif8AaN+M/wAVNKg8I3Nn8L9O02CfR7iR f3lg6T7P9LdE/wBfdeZv2b9iJbbE3/PJQB8JeFf2sf8Ahl39oD9rD/igP+En/wCEl8X3v/MV+w/Z fsl7f/8ATu+/f5//AI5QB6x+29o/ifXvDP7O37bXgqC603U4NO0u4ubSP/To9Gd/9Nsrj/j32bEn ndHd/kd3t02fO9AGPf8A/BSP4j/FHwzF8K/B3wotbD4oeK4YNCstdsNekjSK9udkG6BNieQ/7z93 vn+R9ru77PnAOk/Y/wD+Uf8A+1H/ANzJ/wCmWCgo838Da9qusf8ABLz4y6dqF351noHiSDT7CPbH H9nge80q72f7f7+7nf5/79AH1Z8Afi1/wo3/AIJ3eE/ij/wj/wDbf9ifaf8AiWfafsn2jzddng/1 mx9n+v3/AHP4KCT53/ZU03xP+0D+2Nqn7T3h34eW3hX4d6dNO9/H53mQ/bZ9Pe0ZIJERPOnd5PtL /J8m/wCd97pvAP2soIPINE/5L98TP+xP8L/+luv0Aev0AFABQAUAFABQAUAFABQAUAFABQAUAFAB QAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFA BQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAF ABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUA FABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAU AFABQAUAFABQAUAFABQAUAFABQAUAFABQB4/+0P/AMm//HT/ALE/W/8A0inoA9goAKACgAoAKGKO 54/+0P8A8m//AB0/7E/W/wD0inruy/8AiR9UcmP/AIcvRn4kj/lj9a/ojLvhh6H864z/AHip6n0n +x3/AMnH/Dj/ALfv/SC7r5vi/wD5F9T1X5o9nhn/AHn7/wAjzD4y/wDJYPih/wBjNq3/AKVPW/Cv +60zgzf+PIX4L/8AJZfhR/2M+kf+lSUuK/8AdKvoXkD/ANrh6n7i/tLf8kvs/wDsb/Bn/qSadX4T Ldn9DUPgXoXKktbhQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUA FABQAUAFABQAUAFABQAUAeQaJ/yX74mf9if4X/8AS3X6APX6ACgAoAKACgAoAKACgAoAKACgAoAK ACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoA KACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAo AKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgA oAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACg AoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoA8f/aH/AOTf/jp/2J+t/wDpFPQB7BQAUAFABQAU MUdzx/8AaH/5N/8Ajp/2J+t/+kU9d2X/AMSPqjkx/wDDl6M/Ekf8sfrX9EZd8MPQ/nXGf7xU9T6T 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 ACgAoAKAChijueP/ALQ//Jv/AMdP+xP1v/0inruy/wDiR9UcmP8A4cvRn4kj/lj9a/ojLvhh6H86 4z/eKnqfSf7Hf/Jx/wAOP+37/wBILuvm+L/+RfU9V+aPZ4Z/3n7/AMjzD4y/8lg+KH/Yzat/6VPW /Cv+60zz85/3iQvwX/5LL8KP+xn0j/0qSlxX/ulX0Nci/wB6gfuL+0t/yS+z/wCxv8Gf+pJp1fhM t2f0LQ+BehcqS1uFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQA UAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQ AUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAB QAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFA BQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAF ABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUA FABQAUAFABQAUAFABQAUAFABQAUMUdzx/wDaH/5N/wDjp/2J+t/+kU9d2X/xI+qOTH/w5ejPxJH/ ACx+tf0Rl3ww9D+dcZ/vFT1PpP8AY7/5OP8Ahx/2/f8ApBd183xf/wAi+p6r80ezwz/vP3/keYfG X/ksHxQ/7GbVv/Sp634V/wB1pnn5z/vEhfgv/wAll+FH/Yz6R/6VJS4r/wB0q+hrkX+9QP3F/aW/ 5JfZ/wDY3+DP/Uk06vwmW7P6FofAvQuVJa3CgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAK ACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoA KACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAo AKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgA 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 u7L/AOJH1RyY/wDhy9GfiSP+WP1r+iMu+GHofzrjP94qep9J/sd/8nH/AA4/7fv/AEgu6+b4v/5F 9T1X5o9nhn/efv8AyPMPjL/yWD4of9jNq3/pU9b8K/7rTPPzn/eJC/Bf/ksvwo/7GfSP/SpKXFf+ 6VfQ1yL/AHqB+4v7S3/JL7P/ALG/wZ/6kmnV+Ey3Z/QtD4F6FypLW4UAFABQAUAFABQAUAFABQAU AFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQA UAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQ AUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAB QAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFA BQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAF ABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQxR3PH/ANof /k3/AOOn/Yn63/6RT13Zf/Ej6o5Mf/Dl6M/Ekf8ALH61/RGXfDD0P51xn+8VPU+k/wBjz/k4/wCH H/b9/wCkF3XzfF//ACL6nqvzR7PDP+8/f+R5h8Zf+SwfFD/sZtW/9KnrfhX/AHWmefnP+8SF+C// ACWX4Uf9jPpH/pUlLiv/AHSr6GuRf71A/cX9pb/kl9n/ANjf4M/9STTq/CZbs/oWh8C9C5UlrcKA CgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAK ACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoA KACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAo AKACgAoAKACgAoAKACgAoAKACgAoAKACgAoA+AP+CkHjPxl4G+B3hfVfBXirWPD2qT+KrS1e70S/ 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 P+G/fE//AERPSv8Awr3/APldR/qTje4f66YMP+G/fE//AERPSv8Awr3/APldR/qTje4f66YMP+G/ fE//AERPSv8Awr3/APldR/qTje4f66YMP+G/fE//AERPSv8Awr3/APldR/qTje4f66YMP+G/fE// AERPSv8Awr3/APldR/qTje4f66YMP+G/fE//AERPSv8Awr3/APldR/qTje4f66YMP+G/fE//AERP Sv8Awr3/APldR/qTje4f66YMP+G/fE//AERPSv8Awr3/APldR/qTje4f66YMP+G/fE//AERPSv8A wr3/APldR/qTje4f664NHd/Dz9rvx78S/G2j+BfDnwe0C21bVPP8mfU/Gc8cJ2QvK2/Zpjv9xP7l eZmXDNTLY87O/LuKKeZS5UfXX9k/tK/9E5+Gf/hean/8pq+Z5knZn0+tk0S/2R+0t/0Tn4Z/+F5q f/ympGgf2R+0t/0Tn4Z/+F5qf/ymoewEP9lftJ/9E4+Gv/heaj/8pKKC5INmdT95USPNPiP48+N/ wv8AB2seO/Efwu8B3Oj6d5HnQad45vpJpN8yRJs36Qifff8Av125Xhfrtbk6s4s4xv8AZ9LmPlb/ AIb98T/9ET0r/wAK9/8A5XV9euDcU9T5b/XTCLRh/wAN++J/+iJ6V/4V7/8Ayup/6mYsP9dMGH/D fvif/oielf8AhXv/APK6o/1JxvcP9dMGH/Dfvif/AKInpX/hXv8A/K6j/UnG9w/10wYf8N++J/8A oielf+Fe/wD8rqP9Scb3D/XTBh/w374n/wCiJ6V/4V7/APyuo/1JxvcP9dMGH/Dfvif/AKInpX/h Xv8A/K6j/UnG9w/10wYf8N++J/8Aoielf+Fe/wD8rqP9Scb3D/XTBh/w374n/wCiJ6V/4V7/APyu o/1JxvcP9dMGH/Dfvif/AKInpX/hXv8A/K6j/UnG9w/10wYf8N++J/8Aoielf+Fe/wD8rqP9Scb3 K/15wIf8N++J/wDoielf+Fe//wArqP8AUnG9xf684EX/AIb98R/9EW03/wAK1/8A5ArGfBFWK5mR Hjyi5csT6o+GXj743fFbwXo/jrw58LvAdto+oef5MGo+Ob5Jo9kzxSb9mkOn30/v18tjsH/Z03Ds fW5bmMcyjzHqH9k/tLf9E5+Gf/hean/8pq5D0boX+yP2lv8AonPwz/8AC81P/wCU1AXD+yP2lv8A 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 BQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAF ABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUA FABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAU AFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQA UAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQ AUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAB QAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFA BQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAF ABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUA FABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAU AFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQA UAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQ AUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAB QAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFA BQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAF ABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUA FABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAU AFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQA UAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQ AUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAB QAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFA BQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAF ABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUA FABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAU AFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQA UAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABRcAoAKAC gAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKA CgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAK ACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoA KACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAo AKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAouAUAFA BQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAF 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 80efmLioH88+yv7xpxo1UlY+aumyPj3ro9ku4WQce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4W Qce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4W Qce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4W Qce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4W Qce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4W Qce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4W Qce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4W Qce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4W Qce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4W Qce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4W Qce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4W Qce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4W Qce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4W Qce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4W Qce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4W Qce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4W Qce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4W Qce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4W Qce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4W Qce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4WQce9Hsl3CyDj3o9ku4W Qce9Hsl3CyDj3o9ku4WQce9Hs13CyH7686NCj7SdW2wWaZ/Ud/wTfGz9jj4Tu/8Af1f/ANOl7X8B +KV5cWY2UHZXX/pKPpsvTcUfe1fBHeFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQ AUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFAH5O/8ABXf/AJN+8Bf9jpbf +m++r9Z8GdeJqfo/0POx+zP52X6rX920vhgfOS3CuwzCgAoAKACgAoAKACgAoAKACgAoAKACgAoA KACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAo AKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgA oAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACg AoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAC gAoAKACgAoAKACgAoAKACgAoAKACgAoAKlgFc01+7mVH4j+pX/gnB/yZ18Kf97VP/Tre1/nn4m/8 lPjP8S/9JR9ZgvgR9518IdQUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFA BQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAfk3/wV2/5N/8AAf8A2O9r/wCm+9r9 Z8Gf+Snp+j/Q8/H7M/nbfqtf3dS+GB83LcK7DMKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAC gAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKA CgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAK ACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoA KACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAo AKACgAoAKACgAoAKACgAoAKACgAqGAdqxqfw5FR+I/qV/wCCbv8AyZx8Jv8Arpqn/p2va/zw8Tf+ Snxv+Jf+kxPrMF8CPvMdBXwh1BQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQ AUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQB+Tf/BXb/k3/wAB/wDY72v/AKb7 2v1nwZ/5Ken6P9Dz8fsz+dt+q1/d1L4YHzctwrsMwoAKACgAoAKACgAoAKACgAoAKACgAoAKACgA oAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACg AoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAC gAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKA CgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAK ACgAoAKACgAoAKACgAoAKACgAoAKACoYBWNT+HIpfEj+pX/gm7/yZx8Jv+umqf8Ap2va/wA8fE3/ AJKfG/4l/wCkxPq8H8CPvOvgzrCgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAC gAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgD8m/8Agrt/yb/4D/7He1/9N97X 6z4M/wDJT0/R/oefj9mfztv1Wv7upfDA+bluFdhmFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAF ABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUA FABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAU AFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQA UAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQ AUAFABQAUAFABQAUAFABQAUAFABQAVDAKxqfw5FL4kf1K/8ABN3/AJM4+E3/AF01T/07Xtf54+Jv /JT43/Ev/SYn1eD+BH3nXwZ1hQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQA UAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQAUAFABQB+Tf/BXb/k3/AMB/9jva/wDpvva/ WfBn/kp6fo/0PPx+zP5236rX93UvhgfNy3CuwzCgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgA oAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACg AoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKAC gAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKA CgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAK ACgAoAKACgAoAKACgAoAKACgAoAKhgFY1P4cil8SP6lf+Cbv/JnHwm/66ap/6dr2v88fE3/kp8b/ AIl/6TE+rwfwI+86+DOsKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoAKACgAoA KAP/2QplbmRzdHJlYW0KZW5kb2JqCjE5IDAgb2JqCjw8L1I5CjkgMCBSL1IxMQoxMSAwIFIvUjEz CjEzIDAgUi9SMTUKMTUgMCBSPj4KZW5kb2JqCjkgMCBvYmoKPDwvQmFzZUZvbnQvU1NQT1dOK1Rp bWVzLVJvbWFuL0ZvbnREZXNjcmlwdG9yIDEwIDAgUi9UeXBlL0ZvbnQKL0ZpcnN0Q2hhciAzMi9M YXN0Q2hhciA4OS9XaWR0aHNbCjI1MCAwIDAgMCAwIDAgMCAwIDMzMyAzMzMgMCAwIDAgMCAwIDAK MCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMAowIDcyMiA2NjcgNjY3IDcyMiA2MTEgNTU2 IDAgMCAzMzMgMCA3MjIgNjExIDg4OSA3MjIgNzIyCjU1NiAwIDY2NyA1NTYgNjExIDcyMiAwIDAg MCA3MjJdCi9FbmNvZGluZy9XaW5BbnNpRW5jb2RpbmcvU3VidHlwZS9UeXBlMT4+CmVuZG9iagox MSAwIG9iago8PC9CYXNlRm9udC9JS0ZaUkorVGltZXMtQm9sZC9Gb250RGVzY3JpcHRvciAxMiAw IFIvVHlwZS9Gb250Ci9GaXJzdENoYXIgMzIvTGFzdENoYXIgMTIyL1dpZHRoc1sKMjUwIDAgMCAw IDAgMCAwIDAgMCAwIDAgNTcwIDI1MCAwIDI1MCAwCjUwMCA1MDAgNTAwIDUwMCA1MDAgNTAwIDUw MCA1MDAgNTAwIDUwMCAzMzMgMCAwIDAgMCAwCjkzMCA3MjIgMCAwIDAgMCA2MTEgNzc4IDAgMCAw IDAgMCA5NDQgMCAwCjAgMCAwIDU1NiA2NjcgMCAwIDAgMCAwIDAgMCAwIDAgMCAwCjAgNTAwIDAg NDQ0IDU1NiA0NDQgMzMzIDUwMCA1NTYgMjc4IDAgMCAyNzggODMzIDU1NiA1MDAKMCAwIDQ0NCAz ODkgMzMzIDU1NiA1MDAgNzIyIDUwMCAwIDQ0NF0KL0VuY29kaW5nL1dpbkFuc2lFbmNvZGluZy9T dWJ0eXBlL1R5cGUxPj4KZW5kb2JqCjEzIDAgb2JqCjw8L0Jhc2VGb250L1JYTlFPTCtBcmlhbEJs YWNrL0ZvbnREZXNjcmlwdG9yIDE0IDAgUi9UeXBlL0ZvbnQKL0ZpcnN0Q2hhciAxL0xhc3RDaGFy IDE2L1dpZHRoc1sgMTAwMCA4MzMgODMzIDgzMyA3NzggMzMzIDcyMiA3MjIgNzc4IDcyMiA2Njcg Mzg5IDc3OCA3MjIgNjY3Cjk0NF0KL0VuY29kaW5nIDI0IDAgUi9TdWJ0eXBlL1RydWVUeXBlPj4K ZW5kb2JqCjI0IDAgb2JqCjw8L1R5cGUvRW5jb2RpbmcvQmFzZUVuY29kaW5nL1dpbkFuc2lFbmNv ZGluZy9EaWZmZXJlbmNlc1sKMS9XL08vTi9HL0Evc3BhY2UvUC9FL1IvUy9ML0kvQy9UL0YvTV0+ PgplbmRvYmoKMTUgMCBvYmoKPDwvQmFzZUZvbnQvQ1VVUUFGK0FuZGFsdXMvRm9udERlc2NyaXB0 b3IgMTYgMCBSL1R5cGUvRm9udAovRmlyc3RDaGFyIDEvTGFzdENoYXIgMzYvV2lkdGhzWyA5Njkg NDkwIDU1MiA1MDAgNDY5IDI0NCA0MjcgMjcxIDQ0OCA0MzggNDQ4IDYwNCAzMTkgNDc5IDI5Mgo0 NjkgMzE5IDYxNSA4MDIgNTMxIDY3NyAyMDMgNTUyIDU1MiA1NTIgMjc4IDU1MiA1NTIgNTUyIDU1 MiA1NDIKMzY1IDM5NiA1MjEgNDc5IDU1Ml0KL0VuY29kaW5nIDI1IDAgUi9TdWJ0eXBlL1RydWVU eXBlPj4KZW5kb2JqCjI1IDAgb2JqCjw8L1R5cGUvRW5jb2RpbmcvQmFzZUVuY29kaW5nL1dpbkFu c2lFbmNvZGluZy9EaWZmZXJlbmNlc1sKMS9XL28vbi9nL2Evc3BhY2UvRi9pL2MvZS9TL0EvcGFy ZW5sZWZ0L1AvdC95Ci9wYXJlbnJpZ2h0L0MvbS9wL04vcGVyaW9kL3R3by96ZXJvL29uZS9zbGFz aC9maXZlL3NpeC9uaW5lL3NldmVuL1Ivcwovci9kL3YvdGhyZWVdPj4KZW5kb2JqCjEwIDAgb2Jq Cjw8L1R5cGUvRm9udERlc2NyaXB0b3IvRm9udE5hbWUvU1NQT1dOK1RpbWVzLVJvbWFuL0ZvbnRC Qm94WzAgLTE3NyA4NjMgNjc2XS9GbGFncyA2NTU2OAovQXNjZW50IDY3NgovQ2FwSGVpZ2h0IDY3 NgovRGVzY2VudCAtMTc3Ci9JdGFsaWNBbmdsZSAwCi9TdGVtViAxMjkKL01pc3NpbmdXaWR0aCAy NTAKL0NoYXJTZXQoL0EvQi9DL0QvRS9GL0kvSy9ML00vTi9PL1AvUi9TL1QvVS9ZL3BhcmVubGVm dC9wYXJlbnJpZ2h0L3NwYWNlKS9Gb250RmlsZTMgMjAgMCBSPj4KZW5kb2JqCjIwIDAgb2JqCjw8 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 sG3G3Jh4zOQa9perA8aTn/vJO9PlQkbvzOPuWQ6xtCLXkvk+TkYH/D63dVqPtne1OQbgBBwzOrMO s6Kv+6UhbUFTRcfxYS19rchifqzfAtNqL7qdBN0qo83rrXjmo3JUiEeEaAntSeTuiEVfd9TV9KFn z+0MitckpWkDtmell8wr8yJgbNZ0cxua0bz+KaN3kOGBr+gkt5lQoKH3qM3mPCiAvMq8mlR7ak0G 7IR38t7NTJfrkmArrBjcjAQxl6Wnk9+T1hqrNJDDivRvxG8PXxR9FvnEB6hp0clOnC5sofc7rPZ6 IIm1x1Hcq+8r6iNcMndv/HQr9iL2Gw188VzSIJxhzw70Xjg+oE3rDjiSYc9qiCFZMm4n7i8DPFRN gqHaTYk9exlYajaHeFV/nGRDpcHmhbrmDINoaNEdwhPYVroErRR6RugSvFLYSrci3iEHEoA3Ksjf itvBe+hCvwzyOcRZxeCyNtyyEC3rvZHQsBtmsZjo/PViab5ClbhevhoiIaFVdULXVeyET1l0hYHL dXXfVJOKHi1zo6TOTByFLzI47GYoWol417ovfRDQOlA7BF+TVKsgwTZ8h4+GCZxhiYqs1O2Ri9Nn AZ4IWOSc8/3M/sS23aczrA1+Kz5Vdquu5Xxu/gruw8+2W+0XOi509lw+501GlHiH34ujxFeHO9uc Q6Pfdd8HNBHQb1PHXnElD2e1bO0y5ft9E92e3rG69Y26VTALphtDVBuV0Yq0iLdYn9wmLq4JxTbR nZNuP9VZM3ny7YOTn6aofwITHu33CmVuZHN0cmVhbQplbmRvYmoKMTIgMCBvYmoKPDwvVHlwZS9G b250RGVzY3JpcHRvci9Gb250TmFtZS9JS0ZaUkorVGltZXMtQm9sZC9Gb250QkJveFswIC0yMDYg OTIxIDY5Ml0vRmxhZ3MgMzIKL0FzY2VudCA2OTIKL0NhcEhlaWdodCA2OTIKL0Rlc2NlbnQgLTIw NgovSXRhbGljQW5nbGUgMAovU3RlbVYgMTM4Ci9NaXNzaW5nV2lkdGggMjUwCi9YSGVpZ2h0IDQ3 MwovQ2hhclNldCgvQS9GL0cvTS9TL1QvYS9hdC9jL2NvbG9uL2NvbW1hL2QvZS9laWdodC9mL2Zp dmUvZm91ci9nL2gvaS9sL20vbi9uaW5lL28vb25lL3BlcmlvZC9wbHVzL3Ivcy9zZXZlbi9zaXgv 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 3OPpq9Yd7zCWVpVWSv4Mdc5b6a0x3KniBk1xZHFwul9KeHKoQq1AbHSSfeTKiQ+6eiU2e1eztZhw 8S5qAf+nREqeOhE5ucThyOUQieVPQQ6RT3EkyJfThELX8U4O2LuX/oyesPfDh/cGxcUFyU7HD1Qa UalRXF5ahsoQazbl6OSxYRsDJeQN4s3+DwgdDLONimwCCywjxF7mBOWE/ruQb0j4lviA5EVoFYvD vydoiMg5CuaDDI6+AwswJ743FsUh/9x1OSpDYkZWEmKDtDfBUwJpDCxounHhYvMePE/8ymeNehAF 8gNPJ/jY0VmVWOB8jKkuN5WXl7XXWKvqEGs1Jx+VjHEM8klN9yxhNbyLhfEqS29Aj1n+LuNYBET8 HqAFMALTnXg1RHMaOnGLPn8OGccLaHgXFn/+qPsu+kz0+/rPMBV0JDU6RhwZmRqr3Mja6I5bPbYr aBDZtSeja1NMSmJ/Q7QB8YcPrYsJI4Pci03ivR1JssDTHc7A3I1ATxGO3OCbud4P7a2XEXu7L2K3 b0zMQoUknfkq0Z5+JpYVtnQkngg+MnWLXLZXozV3xokj+xSNpKBylSb2/Q+jn8EaMn1pmDuUOZDY LUmxpNdGnGCFI3f6mk7dnPrE74M5nhuDZge8AqgFJoITv5SA1AxzHI7PxPHb1jD+6/FbeI3vkr0L RUR5SsmZZg7MJociBoe/jeU0ocMlctguygVPfhEIBTCfH+Kggx4AoTN+RL+D//FD3tn8wSzRt8qR /ciXPRASciBJVXs6Qhzaqag7Rqh3TB1z8EbMt0RT3vwZZv763hdY0CGRmxMqfCpZt9RmPqwZAptp +3iQutjtrq4gbXWdQFH/DWycq5UKZW5kc3RyZWFtCmVuZG9iagoxNCAwIG9iago8PC9UeXBlL0Zv bnREZXNjcmlwdG9yL0ZvbnROYW1lL1JYTlFPTCtBcmlhbEJsYWNrL0ZvbnRCQm94WzAgLTEyIDEw MDAgNzI4XS9GbGFncyA2NTU0MAovQXNjZW50IDcyOAovQ2FwSGVpZ2h0IDcyOAovRGVzY2VudCAt MTIKL0l0YWxpY0FuZ2xlIDAKL1N0ZW1WIDE1MAovTWlzc2luZ1dpZHRoIDc1MAovRm9udEZpbGUy IDIyIDAgUj4+CmVuZG9iagoyMiAwIG9iago8PC9GaWx0ZXIvRmxhdGVEZWNvZGUKL0xlbmd0aDEg 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 mTZ2E9PBsnPJjVwTaeHYCTLB0fsRlwKHkc35OYUoHMPRtZp2lHOBAIfM8gcFnQ0OY5bj7hElm8jx osSAC9JLNj3BegkcJ1yFkMGGkEEaz7wi15istYSTGIPAswyGE1zUGyw6XhChBxOcqYxewgbwrFWo lV5QhD7poESk6SuTZvxg73AdyRI5J0sfutZ0H+gGTKeHdOBquWsISGkJdb4B8DRb4ToV15wwQ12w i96qRIjw3zz0W/zUvz2En1T/Vm1SQa9qE7i9nzNhCnB9D13OfSi0/T+FPRAm0ST24VthS0zg39AA ettKxhiJaYIwxrazAzRwNd+Eb8I34ZvwpxE0P0pyX65s8NZAP2wVAXggFoSqZ5cx4Vk1tcEK/7wb qv7gf0b+RB4WyVrMUv1cNNET/qJ2zkOe/ue1AIVQNZoNN0wGhdEsVINq4SZRgfxoHroBZdWFkSX7 tQPx8E6N/mxbd7LHs7AnuX5TthTB2cz9QX8j0ee6ehfRxcw1jNwXSP4qkCf++ODrEMkhScGdQ4e4 Vego/2N0CwVTgo5PA/iHhf1oBPjHAHGo+yAFtHsY0kWA4DQ0dTBfozOqE864dlQ5cepWY/3nyJVV 4mPLJj6j6ZkHp4bU/ql9eSkdSAprlNPhfwEybhreCmVuZHN0cmVhbQplbmRvYmoKMTYgMCBvYmoK PDwvVHlwZS9Gb250RGVzY3JpcHRvci9Gb250TmFtZS9DVVVRQUYrQW5kYWx1cy9Gb250QkJveFst MTYgLTI4MSA5NjggNzUxXS9GbGFncyA0Ci9Bc2NlbnQgNzUxCi9DYXBIZWlnaHQgNzEzCi9EZXNj ZW50IC0yODEKL0l0YWxpY0FuZ2xlIDAKL1N0ZW1WIDE0NQovTWlzc2luZ1dpZHRoIDUwMAovWEhl aWdodCA1MjQKL0ZvbnRGaWxlMiAyMyAwIFI+PgplbmRvYmoKMjMgMCBvYmoKPDwvRmlsdGVyL0Zs YXRlRGVjb2RlCi9MZW5ndGgxIDEyMjEyL0xlbmd0aCA4MTQ1Pj5zdHJlYW0KeJztemtUFFe66N67 qvrddDX0C7obqqluEBpsoGkQQWihaRBUGhuwERoBQVBEQfCtEY1GgyZqoomJMeZ18k5sJ5PEzCPJ zOE6Z87oTCYx88pzzczJZM6ESc5MkjsPKe5X1UDUlTvr3Lvun7vW1Oarvfe3d+3a32N/j6IRRghp 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 bIf6YHOv8DvfdGA9rsxQvX1LxQn8DPUfmk+n1pE3vofz8pwG29STuOTs6i2Qr+DpPwnfpd4AOpzo AX8b7TQ4iYLnIBlZx+5gidnmpHUsq7fbbakcQ9OrOK2B47Q2u72V1QOxep7jWJNez2q1ikIWs7Se s9F2lB7lZYyWtdNqC2Q4MnVEKYcg6crkHHl68YNR9LLXo4dUT4RDc58zoWITJhRQEuLfM6MQVEnE ArkyeWaxZBiKi69P9CTSeSD9DX96Tq7wVMM7jxQ1dK0r0hewwqcuW/4SHMiQ/aW78hh+mPoP2uXZ eu22K0mvubsH+L1Z5Imoyw9sISaVbupezMRGh6WfkRm/tixGg3PlKHoWW3Aj/iEJQ/khtZS6m7qb TripnIHyV7EwjTeVj5mPZbVQrspH4kWR8TXlWSjTym3Kd5Xvqp6DMhUv6sc0Rs12zZeaL7V12h8n pEC5RSw61T/LP8s/y//LIv22h8z82seAKLHCKQAyaCxc0VgXoLKWBmuLnGrvynZNRiicrzcmGRIt ybYUX0tzTavp/+InsP/fXDTql+60yJ/PnNPTcMfiHfo03BdCJNOI6iDDolAWWoqCqBYVgbdRQyS2 ErUjDcpAIRRG+UgP9jUJ+JuILCgZ2VAK8qEW1IxqUCuKsxDDGIGCkEz8pc7ijT1dG7aMxEcQPo4Y pPhv7vqmeZ+hz6ZvQOBZ4tDYLODPAf0PgNyBjgH03gz4HNpCSlA+PYCW0wOYg7ob4NEZuASwB+DV GRj+h/A2UkrwB7R0FqgBtOgfATOA0kWg3kalItDNaAF1CnVeD/LX0YL/DlCvo4USnEK5tBvlUGNx oNH0ByIQNyq9HmQDqBD2XUj9AWXTfuQUgXIjL/kDWkGakV0E2JN2Dl6f/nP8fP2DS5QN84eDF2Ln v7VaV/YFssSF+cy9nPTkJcWnJwTh2sOKnyh+Dl2lpC9w/S+XUQIDCmVuZHN0cmVhbQplbmRvYmoK MiAwIG9iago8PC9Qcm9kdWNlcihHUEwgR2hvc3RzY3JpcHQgOC42NCkKL0NyZWF0aW9uRGF0ZShE OjIwMTUxMTExMTA1MTAyKzAyJzAwJykKL01vZERhdGUoRDoyMDE1MTExMTEwNTEwMiswMicwMCcp Ci9UaXRsZShNaWNyb3NvZnQgV29yZCAtIF82ODEzNzM5MDBfIFdPTkdBIExPQU5TIEFQUExJQ0FU SU9OIEZPUk0pCi9DcmVhdG9yKFBTY3JpcHQ1LmRsbCBWZXJzaW9uIDUuMikKL0F1dGhvcih1c2Vy KT4+ZW5kb2JqCnhyZWYKMCAyNgowMDAwMDAwMDAwIDY1NTM1IGYgCjAwMDAwMzMwMzIgMDAwMDAg biAKMDAwMDQwMDE5NyAwMDAwMCBuIAowMDAwMDMyOTczIDAwMDAwIG4gCjAwMDAwMzI3ODkgMDAw MDAgbiAKMDAwMDAwMDAxNSAwMDAwMCBuIAowMDAwMDMyNzY4IDAwMDAwIG4gCjAwMDAwMzMwODAg MDAwMDAgbiAKMDAwMDAzMzE4MSAwMDAwMCBuIAowMDAwMzc4NDUxIDAwMDAwIG4gCjAwMDAzODAw MTEgMDAwMDAgbiAKMDAwMDM3ODc2NCAwMDAwMCBuIAowMDAwMzgyNzM3IDAwMDAwIG4gCjAwMDAz NzkxODYgMDAwMDAgbiAKMDAwMDM4NzM1MyAwMDAwMCBuIAowMDAwMzc5NTE1IDAwMDAwIG4gCjAw MDAzOTE3NTIgMDAwMDAgbiAKMDAwMDAzMzEyMSAwMDAwMCBuIAowMDAwMDMzMTUxIDAwMDAwIG4g CjAwMDAzNzgzODggMDAwMDAgbiAKMDAwMDM4MDI5MyAwMDAwMCBuIAowMDAwMzgzMTAwIDAwMDAw IG4gCjAwMDAzODc1NjAgMDAwMDAgbiAKMDAwMDM5MTk2OCAwMDAwMCBuIAowMDAwMzc5Mzk5IDAw MDAwIG4gCjAwMDAzNzk4MDQgMDAwMDAgbiAKdHJhaWxlcgo8PCAvU2l6ZSAyNiAvUm9vdCAxIDAg UiAvSW5mbyAyIDAgUgovSUQgWzxBNjY3RjJGMTRCMkVBQTc5OTY1QTYyODBCOTg0QTRCNj48QTY2 N0YyRjE0QjJFQUE3OTk2NUE2MjgwQjk4NEE0QjY+XQo+PgpzdGFydHhyZWYKNDAwNDM1CiUlRU9G Cg== ------=_Part_6177416_1671826187.1448730138062 Content-Type: application/pdf; name="WONGA BUSINESS LOAN APPLICATION FORM.pdf" Content-Disposition: attachment; filename="WONGA BUSINESS LOAN APPLICATION FORM.pdf" Content-Transfer-Encoding: base64 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 i7p//B3zQ8bFObkvw7eVKhHVoWzS6HEtfp3s/039GdVOTUpXY8TVbpOG1WI2BPbIlnHwoYtxvQ6t 31Hh7yZffB59PeTzehd6lL0w99P9X67qUGDYyHTL+v3eb9INoXPzpAKrG265kvGrn+d0r9jj7olD HX4d1a/hp+c2PZi6q0z3jp0fPd4c9zpg58p5Tz2Owvd5QLVWU0WP/ixVssbQ9LelwLxtd0041LN0 3f33PurUOTrjobpnL0Y8SBf9etqBr8pEHbmY8ihzYrrEfIVzsTUmTsp+8Hmzyqn5p391Lax02Itb ORNyRpQKS4raf+LLjCvSB+Wq/Ne80Lgl84bnf5Hef+jkMl1nZPq6SXSuX45UlSKqFO+Tacx3+bM/ Ole3bVz6YaOT5dr7vjoVW+HvCq2a9G3Yc8uSYk3P1W/SIeKLxn9XTkpmhq5omI7dc3nhSr5xxj4H 3afyfb237tEH13J9veLIyvwnuh7f1G1oaO48fO2TCyqerny1Rp6UCUVWLf7+yMo23zyaOP7w4HRN hu1pXT6+RlauZ/1sm6vF9xzX6PnZCa9mjTnTdHB4a/8dI8WLFaIGfTtoXZdXZU4kdhWyh/VbvXXW hmofn3lV63TJLfEVSvy1d09B/z/ODZtcd9yh89FXdklnyzdPYqYdGdv0g1FTbg8u/vuC8/O2dh+/ sOK9Ht+d7rnl4fpmP4kftepbNybX+YFN2j47zwwe8suAsuvvvbp0Jnhfgesvc6bkv0RNi4j/ZViG zucvfnh+QtdptXr3+efS8g13zt/pe3hB4SJD/NmtYQst1+byAuNBHyzX5t59dM+jPr3PQ63/p0// e/qUlmuYCX0SSH2yXed5e0Ewb/fBqaVNzqp32YyfP4Me8/HzgBHcpOyXF78otr3dH3v3uFbUuXzx 0Jy+hbp+nSTcufr4ec5yTy5eeXSxRb/Xv70uWipzaOKUaU++fXDDL/TGvU3XilSNeXy9aElmZ8gj OmKd/+lh+f0XZiwT+WjbZ9/3+aZO54i92dYGh/ywcMEJOezQjqMzM33yYcd1LX6dN61afT+/Rwci j/1S6dTvzI3sw2rc6ezfofmgLPevPT0zp/jcP6veuVkw27VOAd/Uq3qlaLuC2Xo1m1qpzL2UmItx n3Ze9lfvzdcv9DzQp+601r22FK0+o32exCR3+eSrxfL3mNm17Pd7F5YdXiLot/V8s1Xbpx6qxf+6 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 VnRpXR9XbxFAHCkUbUcvtapcR5tiWvATbgf4PkcHp8gACSgCg+tJdYMGIgk64ka88ktoJF76ySxB yxtuh8KmRmHRqHgbpcFlkPSEG8PdRC8a8Dlw6RG3Y7jYaIYH2yrejtQAM0x6w40Bxwq4Qp8DOJ6h jRtCS502dKQpmsrPuF3WVHh/DcUWK7aeVCWZ0NZd+RU3kiSUSH70k2mSZJfjUJiJJdcD7kgNcJQ1 LGUngLNMKPrJNMD0kNsx3kzgfFPVnjRn8Ok0z+XBh4M7KDjwxarl2tHmoOPDPJfh7ahfmc7tVCu6 o02BJ2d5LsPDYzuABSZEM9cbbQo8OcpzHR4cv8GRbIOraC2w4THAtspJHposWKQ5wj+bNV3kJM/h fMGLTgPsjtbBrqs7vuAmsHEEdnnMbSLs9Ww7wkfYAF+nCB2pQ5xcRZz2ijjtFXGaueXLe24noLO3 K5OizVFfftDtuvoGWYiaTaJoTarBJZFq8LLWY5GlSj+bJlV+0e1Qqvygm8BBe3uVB90EDriVE+H4 Mwnzi26oht1s6mlzBpnzOtcHGc6/04C6hk8R5QGfP/VVxxQfaNA5jjf98e3379/SoywC68m9xD9/ D7lwe5UUjDGLMsRqh2ARevidGKg48SLgAncaO/BXovWRrZPYHCtFm5sS5JTbdc2BABJCaig7ks64 8QA0y9U105V/NWs2SsbteDYmtl5S6lE32tSE23WZQm4NHei9wetpU/NtN+Dxltq5/Io2Nd12AO9D kmmrZNtYm6DI2gQMvTa9lG27ERfBxJo1Snva1GTb9THcExmgnYZ1JJ1rE0HnOm2hKIJOM01SybUd T9udA0uh36UUsT2Ktmzid65rtaWxSGiRQQH/E+9sYfcP0i0XaWP7z0fX9P+xu1rfLtEfbny/gSM6 y+6cvk4/7ocwhapUQEDJVQEl2RFZVnZHvLURbr5OZnf01B2vbc3C7Ek6/ceQA8dBOP3HY0q/mqWM kv47VEZM2Rn/SNF09k9gR19hR19hT43YSfbveNW6UvVZ8m9drmb+oM8XMn/Abm4HqxokXqtvB2uW bbEEqlfdDtYcHKrSt4MVS2JHoqVjkq1FAl76ArBmycSiE5eKBRKXWItOXCqenWOpNnGpmDBxCRST uNRMXgSqE5eGiU04cwHYMCXScH0B2PAM/ccLwJopiAT0BWDD5JMe1K9TqaYC7qW5HayZNlYDeztY c0Xulcm3aiYxg3W+1fBE4jH5Vs2UGVPLt35ltQ1DlXmoTHZVM0F2FdXnOQnvwzjubtA/yrPZs/xA 0alXw8MLg029Ki5MvVKndOpVcwU7sZ84y29ryGYyfJ2YVTVQIq/f9L7IZa3JpoaiM5QUbJ1p5MmW AouPpsBSoym4sBiSHxDhomFJcR9IAwSc/5aEkRpFgqlpSHGsK40g8vjDPOIC7bekERdoryUNY4k6 Z0lDh75WGc3/wUnfzClhMs+wFLKkhMNdk22BSItJCcNB7zsf9QIUmP9dRNtH2kfNFP/4KbjAvcES 9YZ/M6k3FL8/7hCmeANlhZdmYxjSR80e/6h5Wc63Ikz5yRzAkig+QcythgZ4oHxUlD9qXpbTrUEj n4OXMsUneLlV2E4E8Ej6qDh/cII4S6o4aOxzEMdTuJFmUuoUYiR91ARygZuTwIUSwY0z5yPnlo8B Y+o3UPJ1kd1gIH3UrPKPnyTgxQlkhCk/mQSYE8gniFk4PeKR9FHTyj/q1sUZZEI8V8SUQT4BnKkp 3/T1gPRR88o/fsqL6ASWCHCeCxhTzseAMYccOIe8yGY/0j5qtrlA9rtAhhICld9Mgsx56GPMO+si JpYXMUdG2kdNQf/4ac+yUmAJke5Vp2dgluT0MWbKNgcK7C3VYBpoHy0v/aMUs0iaioGKcaasJWt9 ghvzyYHiFYL7gPbREtY/JB+da2qacMvPJuHm1PQZbtk5etwj7aNlrH9IQjrX3DTjnrqjYG76DHSi NavTkZH00TLWPyQjnWtymiGnmWaGJKfPUEMmWq9wR7SPlrOGfOuyCW4sMm7+2STcnNE+wR1knWvm 0BHtoyWzf0iuOte0NeEOU5c/SVsf4/6QtHSWvLXgCaHi8VPlyHnrMzkGWkdzN9UOaB8tnQ2401Jx p6XiDjOXZEl2n+DG5HXg5LUAPyJ+tER3Qb7FVZBjkZDL7yYhj5/YcZTjDZTjFdwHtI+WDYaUajU0 qEiw41RTg1PEp3orad8fLZcqGd6Qa4Z3HhzO8J6IUdpNnd4e0D4aWMBdDQkqBtOFObg/Xbcwzxso zyu4D2gfLSP8A2IZFXeuvlL92STcnC8+w82bUuffH9E+WqoYcO++4t59xT11f5NE8qneUqo4Sy6Z 8WCR8CDDPDycVD6R4+5GU/KA9tGyyYC7Gu1UZNxT9y3JNZ/hZvukU9uR9NGyzD8ki5xrQplRp5mG pCSUz1BziAnvaVbcB8SPlmj+8dO61GgVFRn51HhV+NR5xvubNLfaYnZI/GAyIXdOZE7FQJ3YZwaC 5CLoCfLAy1Izwg5IHy0F/ENSvLlmewl1mLq+Sbb3DDW7Op17cUT7aEngH5LjzTXdy7inht0k3XsS qb1S91m+9/qjV3owiRJM7kMTAhK6pO8T2RDVyKeYiL1rkEK1QWWQvWEJ9BtvCV1KmStZngQd3SXQ 0Zn2MNYVugT1V5dK7Eh8/pZ1MKOSAo1Kn+P6tL1r/Uu2f4n711LnXz9vdaW9bNvL1J5/cvwwUfZ8 e8TetQdJfeyff1KgmId7vkFi7xrc48IdfFJjKM33fIvM3zWJ5w0wXZqfbNJfm8rM3zfpZTI/KVZK U15pEvlVk+jLXGky7teaZDHqkxVAeVqu12YH86sWL84PyuJeaDLYGYKnPlCu/RmPxTL5cGndrcGT p3HxwqfPiaDwn5U+pqovNEn8fZMbL8fdqZMn7mlfaTMOIx55xOOT2zDl2i80mYaZlHgm9SdirFak jbQiPTvb8kXp50H6maV/6XzNpSaHCZ55gj9rA9F5hQtNEn/fJJzuwcX62RYvTvB9mOC7u7g94HGL K00muz3srObPjuQ+GLBftGitWTyqRAvUkysUHmS60Cbzd23iwSfSniclS0dULrQZ7CTBY1SK8sQx qkst2nV4lXW47bt0TMb4k9YqGSnXnC77QYE9P2J3uNZhaOT////gf/+57JuP2P4PHSYHeU84SE6F 5w6N49neCJ9OoDczQ1wXZHn41UN0utJ291iLt8Zf5P7j2/8ETyhuxW9Lb7/BxxrXze9vv33fSyE6 B+fLIXia1+zgkUbh/fP3NT5SgE+3wR2rsiVt69v/DKfKwc4rv8+lhZR9/5tGxDPpVPzX/w4fgXPJ w7uN22Nxi9vf/kP7+1+8fwuPuJd1HY+qp8fqS6N/+b6U1v3i09t/LFB99mF/+yv41lsK8IAks/3N e3ws2xJC37f/BM94lukW3Nv/8i7YFExfpLWX/vwV/KiD9bfv/lFUT9X2n0sTew7b9va/1u79b7X0 vxfG9bEn1xP/DrqUUhnFY86/r8RW5X9pf/6Hzyv6fS0RtLT2Mmyd+UOpsVQY/AZjgC9m5vWRi3Ly i5ll5Nf1sa5Fom1g/xGqKs6JW4vg8yPv/BU+GcP/472OViP+n6BDPFwNQBucsx/BsfS89nrV2mz1 /GVhhAGLrquoG6H/2nSlVdRDOoRvR72sOB3iTnhIDJtTSvn3R+P+37rSthXRhghi/wZy34uj/g0B x7L0oPx/nZm/zsxfZ+YvPjPh663LrzPy1xn564z8NzEjfXEDIP/w61b568T8dWL+W5mYlOtDp/S1 hzA2+EpAaB6qSlH+D+G/27xlbmRzdHJlYW0KZW5kb2JqCjYgMCBvYmoKOTY3MzUKZW5kb2JqCjQg MCBvYmoKPDwvVHlwZS9QYWdlL01lZGlhQm94IFswIDAgNjEyIDc5Ml0KL1JvdGF0ZSAwL1BhcmVu dCAzIDAgUgovUmVzb3VyY2VzPDwvUHJvY1NldFsvUERGIC9JbWFnZUMgL1RleHRdCi9FeHRHU3Rh dGUgMjAgMCBSCi9Gb250IDIxIDAgUgo+PgovQ29udGVudHMgNSAwIFIKPj4KZW5kb2JqCjMgMCBv YmoKPDwgL1R5cGUgL1BhZ2VzIC9LaWRzIFsKNCAwIFIKXSAvQ291bnQgMQo+PgplbmRvYmoKMSAw IG9iago8PC9UeXBlIC9DYXRhbG9nIC9QYWdlcyAzIDAgUgo+PgplbmRvYmoKNyAwIG9iago8PC9U eXBlL0V4dEdTdGF0ZQovT1BNIDE+PmVuZG9iagoyMCAwIG9iago8PC9SNwo3IDAgUj4+CmVuZG9i agoyMSAwIG9iago8PC9SMTgKMTggMCBSL1IxMgoxMiAwIFIvUjE0CjE0IDAgUi9SMTYKMTYgMCBS L1I4CjggMCBSL1IxMAoxMCAwIFI+PgplbmRvYmoKMTggMCBvYmoKPDwvQmFzZUZvbnQvQ1VVUUFG K0FuZGFsdXMvRm9udERlc2NyaXB0b3IgMTkgMCBSL1R5cGUvRm9udAovRmlyc3RDaGFyIDEvTGFz dENoYXIgMzYvV2lkdGhzWyA5NjkgNDkwIDU1MiA1MDAgNDY5IDI0NCA0MjcgMjcxIDQ0OCA0Mzgg NDQ4IDYwNCAzMTkgNDc5IDI5Mgo0NjkgMzE5IDYxNSA4MDIgNTMxIDY3NyAyMDMgNTUyIDU1MiA1 NTIgMjc4IDU1MiA1NTIgNTUyIDU1MiA1NDIKMzY1IDM5NiA1MjEgNDc5IDU1Ml0KL0VuY29kaW5n IDI4IDAgUi9TdWJ0eXBlL1RydWVUeXBlPj4KZW5kb2JqCjI4IDAgb2JqCjw8L1R5cGUvRW5jb2Rp bmcvQmFzZUVuY29kaW5nL1dpbkFuc2lFbmNvZGluZy9EaWZmZXJlbmNlc1sKMS9XL28vbi9nL2Ev c3BhY2UvRi9pL2MvZS9TL0EvcGFyZW5sZWZ0L1AvdC95Ci9wYXJlbnJpZ2h0L0MvbS9wL04vcGVy aW9kL3R3by96ZXJvL29uZS9zbGFzaC9maXZlL3NpeC9uaW5lL3NldmVuL1Ivcwovci9kL3YvdGhy ZWVdPj4KZW5kb2JqCjEyIDAgb2JqCjw8L0Jhc2VGb250L0VFSFFJQitUaW1lcy1Cb2xkL0ZvbnRE ZXNjcmlwdG9yIDEzIDAgUi9UeXBlL0ZvbnQKL0ZpcnN0Q2hhciAzMi9MYXN0Q2hhciA4Ny9XaWR0 aHNbCjI1MCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMAowIDAgMCAwIDAgMCAwIDAgMCAw IDAgMCAwIDAgMCAwCjAgNzIyIDY2NyA3MjIgMCA2NjcgNjExIDc3OCAwIDM4OSAwIDAgNjY3IDk0 NCA3MjIgNzc4CjYxMSAwIDcyMiA1NTYgNjY3IDcyMiAwIDEwMDBdCi9FbmNvZGluZy9XaW5BbnNp RW5jb2RpbmcvU3VidHlwZS9UeXBlMT4+CmVuZG9iagoxNCAwIG9iago8PC9CYXNlRm9udC9MV1dI S0MrQm9kb25pTVQvRm9udERlc2NyaXB0b3IgMTUgMCBSL1R5cGUvRm9udAovRmlyc3RDaGFyIDEv TGFzdENoYXIgMjEvV2lkdGhzWyAzMjMgNjQ2IDcwOCAyNDUgNjk4IDY5OCA1OTQgODQzIDY1NiA2 NDYgNzYwIDcwOCA3NjAgNjQ2IDc2MAo3NjAgNDI3IDc2MCA3OTIgNTQyIDMyM10KL0VuY29kaW5n IDI5IDAgUi9TdWJ0eXBlL1RydWVUeXBlPj4KZW5kb2JqCjI5IDAgb2JqCjw8L1R5cGUvRW5jb2Rp bmcvQmFzZUVuY29kaW5nL1dpbkFuc2lFbmNvZGluZy9EaWZmZXJlbmNlc1sKMS9wYXJlbmxlZnQv VC9PL3NwYWNlL0IvRS9DL00vUC9ML0QvQS9SL0YvVS9ZCi9JL04vSy9TL3BhcmVucmlnaHRdPj4K ZW5kb2JqCjE2IDAgb2JqCjw8L0Jhc2VGb250L0xSTVNFUitCZXJsaW5TYW5zRkIvRm9udERlc2Ny aXB0b3IgMTcgMCBSL1R5cGUvRm9udAovRmlyc3RDaGFyIDEvTGFzdENoYXIgNDkvV2lkdGhzWyA2 MTEgNTUyIDI5OSAyMjAgNTIzIDQ4MiAyNTAgNzE4IDU1NCA4MzkgNjU5IDU1NiAzMzMgNTEzIDQ3 Ngo1NjQgNTExIDI5NCA1OTMgNTk2IDU1NCA0NjcgNTk0IDcyNSA0MDIgNTE3IDIyMCA2MjQgNTIw IDY4MCAzNDIKNTIwIDUzOCA0MzQgNzI5IDc5MCAyMzcgMjgwIDUzMyA0ODUgMzUxIDM1MSA4OTIg NTg3IDM5OCA2NzUgNTA2CjU0NyAyMTVdCi9FbmNvZGluZyAzMCAwIFIvU3VidHlwZS9UcnVlVHlw ZT4+CmVuZG9iagozMCAwIG9iago8PC9UeXBlL0VuY29kaW5nL0Jhc2VFbmNvZGluZy9XaW5BbnNp RW5jb2RpbmcvRGlmZmVyZW5jZXNbCjEvQi91L3MvaS9uL2Uvc3BhY2UvTi9hL20vQS9kL3IvVC95 L3AKL28vZi9DL0svYi9TL1IvTy9jL0wvbC9QL2gvRC90L2cKL0UveC93L00vSS9vbmUvRi90d28v cGFyZW5sZWZ0L3BhcmVucmlnaHQvVy9ZL3F1ZXN0aW9uL0cvdi9rCi9wZXJpb2RdPj4KZW5kb2Jq CjggMCBvYmoKPDwvQmFzZUZvbnQvU0lSQU1GK1RpbWVzLVJvbWFuL0ZvbnREZXNjcmlwdG9yIDkg MCBSL1R5cGUvRm9udAovRmlyc3RDaGFyIDMyL0xhc3RDaGFyIDEyMi9XaWR0aHNbCjI1MCAwIDAg MCAwIDAgMCAwIDAgMCAwIDAgMCAwIDI1MCAwCjAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAw IDAKOTIxIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwCjAgMCAwIDAgMCAwIDAgMCAwIDAg MCAwIDAgMCAwIDAKMCA0NDQgMCA0NDQgMCA0NDQgMzMzIDUwMCAwIDI3OCAwIDAgMjc4IDc3OCA1 MDAgNTAwCjAgMCAzMzMgMzg5IDI3OCAwIDUwMCA3MjIgMCAwIDQ0NF0KL0VuY29kaW5nL1dpbkFu c2lFbmNvZGluZy9TdWJ0eXBlL1R5cGUxPj4KZW5kb2JqCjEwIDAgb2JqCjw8L0Jhc2VGb250L0dJ WVJOWStCb2RvbmlNVCxCb2xkL0ZvbnREZXNjcmlwdG9yIDExIDAgUi9UeXBlL0ZvbnQKL0ZpcnN0 Q2hhciAxL0xhc3RDaGFyIDM3L1dpZHRoc1sgODEzIDQ5MCAzNzUgNTQyIDI3MSA0OTAgMzc1IDQ5 MCA0MjcgMjcxIDI0NSA0OTAgNDkwIDMyMyA0OTAKNDkwIDY0NiA1NDIgNTQyIDY5OCAzMjMgNDI3 IDI3MSA1OTQgMjcxIDI3MSA2NjcgNDkwIDQ5MCA0OTAgNDkwCjQ5MCA1OTQgNDkwIDQ5MCA0OTAg NDkwXQovRW5jb2RpbmcgMzEgMCBSL1N1YnR5cGUvVHJ1ZVR5cGU+PgplbmRvYmoKMzEgMCBvYmoK PDwvVHlwZS9FbmNvZGluZy9CYXNlRW5jb2RpbmcvV2luQW5zaUVuY29kaW5nL0RpZmZlcmVuY2Vz WwoxL00vby9yL24vaS9nL3MvZC9lL2NvbW1hL3NwYWNlL1MvYS90L3R3by9laWdodAovRy91L2gv QS9mL2MvcGVyaW9kL1QvbC9jb2xvbi9wbHVzL3NldmVuL3NpeC9vbmUvdGhyZWUvemVybwovRi94 L2ZpdmUvZm91ci9uaW5lXT4+CmVuZG9iagoxOSAwIG9iago8PC9UeXBlL0ZvbnREZXNjcmlwdG9y L0ZvbnROYW1lL0NVVVFBRitBbmRhbHVzL0ZvbnRCQm94Wy0xNiAtMjgxIDk2OCA3NTFdL0ZsYWdz IDQKL0FzY2VudCA3NTEKL0NhcEhlaWdodCA3MTMKL0Rlc2NlbnQgLTI4MQovSXRhbGljQW5nbGUg MAovU3RlbVYgMTQ1Ci9NaXNzaW5nV2lkdGggNTAwCi9YSGVpZ2h0IDUyNAovRm9udEZpbGUyIDIy IDAgUj4+CmVuZG9iagoyMiAwIG9iago8PC9GaWx0ZXIvRmxhdGVEZWNvZGUKL0xlbmd0aDEgMTIy MTIvTGVuZ3RoIDgxNDU+PnN0cmVhbQp4nO16a1QUV7ro3ruq+t10NfQLuhuqqW4QGmygaRBBaKFp EFQaG7ARGgFBUERB8K0RjUaDJmqiiYkx5nXyTmwnk8TMI8nM4TpnzuhMJjHzynPNzMlkzoRJzkyS Ow8p7lfVQNSVO+vcu+6fu9bU5qu997d37drfY3+PohFGCGnRGKJQqCHsKUDSlXscbi1rBruG4n33 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 9R+aT6fWkTe+h/PynAbb1JO45OzqLZCv4Ok/Cd+l3gA6nOgBfxvtNDiJgucgGVnH7mCJ2eakdSyr t9ttqRxD06s4rYHjtDa7vZXVA7F6nuNYk17ParWKQhaztJ6z0XaUHuVljJa102oLZDgydUQphyDp yuQceXrxg1H0stejh1RPhENznzOhYhMmFFAS4t8zoxBUScQCuTJ5ZrFkGIqLr0/0JNJ5IP0Nf3pO rvBUwzuPFDV0rSvSF7DCpy5b/hIcyJD9pbvyGH6Y+g/a5dl67bYrSa+5uwf4vVnkiajLD2whJpVu 6l7MxEaHpZ+RGb+2LEaDc+UoehZbcCP+IQlD+SG1lLqbuptOuKmcgfJXsTCNN5WPmY9ltVCuykfi RZHxNeVZKNPKbcp3le+qnoMyFS/qxzRGzXbNl5ovtXXaHyekQLlFLDrVP8s/yz/L/8si/baHzPza x4AoscIpADJoLFzRWBegspYGa4ucau/Kdk1GKJyvNyYZEi3JthRfS3NNq+n/4iew/99cNOqX7rTI n8+c09Nwx+Id+jTcF0Ik04jqIMOiUBZaioKoFhWBt1FDJLYStSMNykAhFEb5SA/2NQn4m4gsKBnZ UAryoRbUjGpQK4qzEMMYgYKQTPylzuKNPV0btozERxA+jhik+G/u+qZ5n6HPpm9A4Fni0Ngs4M8B /Q+A3IGOAfTeDPgc2kJKUD49gJbTA5iDuhvg0Rm4BLAH4NUZGP6H8DZSSvAHtHQWqAG06B8BM4DS RaDeRqUi0M1oAXUKdV4P8tfRgv8OUK+jhRKcQrm0G+VQY3Gg0fQHIhA3Kr0eZAOoEPZdSP0BZdN+ 5BSBciMv+QNaQZqRXQTYk3YOXp/+c/x8/YNLlA3zh4MXYue/tVpX9gWyxIX5zL2c9OQlxacnBOHa w4qfKH4OXaWkL3D9L5dRAgMKZW5kc3RyZWFtCmVuZG9iagoxMyAwIG9iago8PC9UeXBlL0ZvbnRE ZXNjcmlwdG9yL0ZvbnROYW1lL0VFSFFJQitUaW1lcy1Cb2xkL0ZvbnRCQm94WzAgLTE5IDk4MSA2 OTJdL0ZsYWdzIDY1NTY4Ci9Bc2NlbnQgNjkyCi9DYXBIZWlnaHQgNjkyCi9EZXNjZW50IC0xOQov SXRhbGljQW5nbGUgMAovU3RlbVYgMTQ3Ci9NaXNzaW5nV2lkdGggMjUwCi9DaGFyU2V0KC9BL0Iv Qy9FL0YvRy9JL0wvTS9OL08vUC9SL1MvVC9VL1cvc3BhY2UpL0ZvbnRGaWxlMyAyMyAwIFI+Pgpl bmRvYmoKMjMgMCBvYmoKPDwvRmlsdGVyL0ZsYXRlRGVjb2RlCi9TdWJ0eXBlL1R5cGUxQy9MZW5n dGggMjAzOT4+c3RyZWFtCnicZVYLUFTXGb7LsvdeBTHlzg5QddmxCWB8R0PFFElEjAmPWNTgCxHY hV1YdpdFYBd3ecnTY4Ad3guyPK6K8sgqCMRHSKJ1rCSNRsF0ajvRtqYdbazG9r/r2c70XEyaSTN3 5sy59zy+//++/zvnSihvL0oikfhs1+ao85ZvNOhU4utSYYFEWOglLJIi8zOte4tsERV3VDYP+UqR r3fvQvaxP5z7GTTPh7IXKKlEYrb3RRuMFpM2U3NAGbYjMWnJ0qXLfviyOiIiQplm+X5EuUmdp83U K0NIp0CtMxhz1PoDrymjyWydTpuuzNRZjJo8ZapKpVaJy95N1amzlZu1Oq3RaChQhkUvUb6yatXq 5aR5JUGbk5afp0w05KTqlQmGCGWcMl6t0ubn/HSAoij/NzZGx2x+8624+IR3tiZu274jSUlRi6lf UC9SIVQoFUa9TC2nVlArqVXUamoNtZZ6lQqn1lESiiMkUd6UTUJLDnl5eRm8/iNdJ0VSwTvJe1i2 XDZJ76H7mQCmi+mBOj93BuJNJyDyjLDZ6c+53DG8vJpWoYPdu2AuzhN6Aw00Nnkm1CtKrHvKgzij CVIYzsUzW+sPtKBjqK2R7/7YcSYQ8umhyNZMlM9yRlRQXKapZTlXFSo+bCMdo4ksgS9pTw2Uyv8O 1f/E1TI/90oCPABTJ+HYSRPv/y2shVUQgRXwegA33OFeJzcx16u7DqKdrMfMoJ3Wko2HWLJPPszQ EAneMyCbMI9qTgVrTmodMQ6WKwB2aGz09s+frLiMX1Mk4LvykzSnfnJxB/Z6OW3X+pSizvFg4Yg3 V/C+o+3MjYH9yxdnGfD8GgVhwHzePWfwgNP/AsQEcNfdL8Ey+db47LzdZn1JVqUBvYXihvWT+o9s N9EjFtKnwAt8z41Z1GOKMVVv1nAUy9MkvWIjY9OUlppRObLW5zez3PW+rXta9izAe/ASvALvx2kQ ikMg/Ysrna5Pggd6epwTF9nnLJyCD4fAuxtChmaJCA/gxoS/EgY80yb6Bw64MZRkK31jloUi4Y/0 CKhkBlq3pdCQqU/O2H4wCrGx5raxYKhiQIJGVa2YZY/B/VzaimlVJqaOsGBlTrc1TcIvL2hxEK/g aT8BEA+X/w/8ofAHEXxqFtyKkmYF+A4aPDyzst7Sij5hwcY8rnVltBMYHu6baAumNZpQJKJwT11t zR9+faVIc0rRY2oxtsexfbSfu8s8CEd4gRG5dkEMTMIqguauhhE5fmCi71Y5StEOdjGzU5+/JS61 ayxLkXKp4C4CXxbU10AK8z4grI8rxtS92ues3/kp6w9/xHoaYT0EvwgZT0DSd3oqGDgG3WxpnWlk /YQgxLtpXgIyCJeC7IEc7bLYXq8gKT7hmagGczuaZAWS+GR3x3Qdy+MnJuZmVbeVaPGdaG6K938q 8mV0+0OhXE9nRRbqNNlpGdssGxCbIEoh6Bg00952r56sf2xiPq8++r2WLrSzuHRjuailUZih/Z5t eh7N07PCCVgpda8X/iX32Bm0zVYyG9NXPBPZXNaCvmCFBJKCw3GrgezZwOC9Hh3eK+hk2G6ib1V2 FItyGRj0TnFJpChXMc9E2M1daJoVshho8NyXHSdCZFi6a0Q4/2/HhejxAG4CiojiONNEO1Gn9Xwi 69EznBklWm1iiFDIMxuaLF0ieAjDTQjbPKOyE8JdGl1ua/u0mcSRbWKmK7oK0CYW/4aZ1dkdOCgZ JhL/G2KkwiL3m3KsJoKEYRVOJzYIhXTyhEIYaffjJbAUJwcfzpKD1xSeR6akxmMvzGAmnjhtH+iu AQtzgmdr1dQPx4fh0jAp1UcQDutnDwtwwCU5LDgyVDd+9M6p8avoS5YLB3bZZ+Qc4IbxjIm+Udl+ EMWwngSGy0DxxYV7K1luuAaV1ZbWkvTu8cyvmsub0C1WsHlz4b2drYN/GkzBVFyJOveAIq8wq2IT YmcPShgdgIuiT4Am6LEQFcDdcafwcgsqtpe14WQ4HXili287wfcf7xhBE6QagQm7hmMV3B0xjOmq diuKFsNAG8vKIkVq7/9PV9h5nIF0/JkMUmlPrPBQjuz1jjo72aPZ3tHAL/jatX9xrFWVXRCcW6St iDpMKvgj86CQ2g3rTpmd/uMggUrwIQEJZsEgh5wcpiL30KEiYozSuvxGsk3H3my7egFeuG4D9l8z GQc+icG/y/5zal8uSgravHvfhl/v4i+oFUaXbbDoBqvHqJ+2841NHagRtdT0VFwsclWMEXOHPfoK /GeSZ2IHgnHorfUj+Tw6H/Tbs6c/nzhrznhfMaTp0Dvffm4R4d1uWOuUgF00mB3myNEbpaWvitXs 5pm19tJmdJsV+hiYXz2Z3Il92H66FpJlnod0DU6W9dOd4DP5AbxQL1JvvuCW8JJ/wBqYGZe6pcI1 ObrS3jEl1h65XH5f6SxEG8Xaw2HbNmOfl/ZdgYUKuMegEXuPo721uaP+/Htk6n0Tc6OitZhIgMnY ku7dV1POa6Yst9A0utEz5po4few2+hvr98xq7XYH8RLyL0FM8baJ/rjGUYZ0qLjWWmXD3vhBIKbg L2UD1Q7UFIT6HE3jde+hBmQ/QiA+NTGjtc7ylrzhpYF4Lr6KfQWqqqO2UZzZ39o0KZ4E50zM2crm 8s7doPF8E3iChgQhF6I8ucSasFf4pm2kt3uwLsiPXM6FTiHVCUlOenAuKH0GB319QdnrO4+i/guc uEZwCmVuZHN0cmVhbQplbmRvYmoKMTUgMCBvYmoKPDwvVHlwZS9Gb250RGVzY3JpcHRvci9Gb250 TmFtZS9MV1dIS0MrQm9kb25pTVQvRm9udEJCb3hbMCAtMjQ3IDg3NSA3NTBdL0ZsYWdzIDY1NTQw Ci9Bc2NlbnQgNzUwCi9DYXBIZWlnaHQgNjY5Ci9EZXNjZW50IC0yNDcKL0l0YWxpY0FuZ2xlIDAK L1N0ZW1WIDEzMQovTWlzc2luZ1dpZHRoIDEwMDAKL0ZvbnRGaWxlMiAyNCAwIFI+PgplbmRvYmoK MjQgMCBvYmoKPDwvRmlsdGVyL0ZsYXRlRGVjb2RlCi9MZW5ndGgxIDk5NDQvTGVuZ3RoIDY1MjQ+ PnN0cmVhbQp4nO06bXhUVXrnnHvvzJ3P+zEzmZlMkpnJJYE4wJAMCQkEc0sSCmTVAIFN0IEJBgzh I+FDFDUmSCM6YEGn0BXX3cDq1rUoN+u6RrcrcYuKu6bgIlCrFHFhu2uNUlv3seDM9D13JiFad7f9 0afP06f35ny95z3nnvf7PTAII4RsqBcxqPGmxeEypD9F1VAtvXV9a1dmrPwNQrjt1q1bAtdtLvMD 4D0Yv7m667b1xndL4wiRpxAyvnTbum2rM/j2RoQcW9pXtbb9Qt05E6HifgBWtAPAvp/7CCFzG4wn tK/fcmf2e38B1UfrOm9tzYyDx2D/z9e33tnFPMp2A/4DAAxsaF2/KosfgMrX1bl5S2Zc3Evnuzat 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 MDEKL0Rlc2NlbnQgLTE2NAovSXRhbGljQW5nbGUgMAovU3RlbVYgMTQ4Ci9NaXNzaW5nV2lkdGgg NTAwCi9YSGVpZ2h0IDQ4OAovRm9udEZpbGUyIDI1IDAgUj4+CmVuZG9iagoyNSAwIG9iago8PC9G aWx0ZXIvRmxhdGVEZWNvZGUKL0xlbmd0aDEgMTcyMjAvTGVuZ3RoIDEyMTMwPj5zdHJlYW0KeJzt e3l8G9W97zlnFo32kTTabMvaLMm2bMuWvEjepNjyItuxLceLbEeJnQ1n35zESUhitiwmrAkhAVoI ISS0BRTKEnZanBR6CXugUKDtrRPoLebRvtL29sXyOyPJTgK0n/ve5/3x/rgzOqM5Z87MnN/+/Z0j AQgAkIJRQID2tnkuN0hsc0z40L149eC6ZN2/BAB43+LNw6Z2TcUgbvgE19csW3fN6nd3Hv8RAKgF AGrTNau2Lkv2F70BQNErQ0sHl7z++KkMAGoluLF0CDfIFwjuBEAwjutZQ6uHR1Lvw99weNXaxYPJ euV+/MxfrR4cWUcM0y/h/l/gRtOawdVLU/35g2nd2o3DyXrNl4n6hqXrTuad2AsAw+D7f05tB9W4 OMhTII14DtgAmL4wU+K/mP4L9TQA8Rju6Z/+M7UVpMGx6S/JF4EcfGcj/gLM3239L2wvga/Au7h8 BP4M4uA8eA18Cd4Ck+AiUAMaKMHvcJ/3wARufxUXfr8I0nCbAWrAX8F2cAGcxr3/Ac7gJ30JXgB3 gz6gBU48mn+Ae3Hbw2AX7v0wuA+MgCX4mZj10Az+CD4EF6Ab/AjsByfwWz+Gevzkd7DUngLvoOsI ErwIleg52IQeAU+Q9WAl2AweRtfC5Xg8G/Fz/wFyk2IEVjyG+aAK7MBlLchHa8AtYCHUwWPwPHwe /hxF4ONwAYjAYV4jAuXh9rbWuS3NTaHGhvq6YG3NnIC/uqqyotznLSstcRXk52XbbVlWi1HHKVi5 VCwSMgKaIgkEQV6dtX7AFLMPxEi7tbExn69bB3HD4BUNAzETbqq/uk/MNJDoZrq6ZwD3XPatnoFk z8BsT8iaKkFlfp6pzmqKnQtaTadhXziCz28JWntNscnE+dzEOWlPVKS4YjbjO0x1uqGgKQYHTHWx +s1DY3UDQfy8U2JRrbV2qSg/D5wSifGpGJ/Fsq3rTsHsapg4Qdl15acQYKT8a2OErW5wSaw9HKkL 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 HCASf9hLw4XGJ7ZId0u4kSgKtmc1dJXNn9cRshfUlZa4611tnmZHT1N2f19hHpejFkvKKy25va2K /6t/of//u5Hg+sSR5PnzddH0ND5C/ojrJD7aQAR0A/5XZo2Yc0UgCNpBFmgAXaAMzAfzMNoJATso AHWgFGB4grMAF2gDHtAMHKAHNIFs0A/6QCHOkjiQA9RADCSgHFQCC8gFvaAVKEByPhzhHQAayACo Wbph1fI1pnmDazaa6msS/5u8HVCA+S9S9K1+X4Ovp69qgDOEg9GZwr/6X5a3wFr01vR/frvA0yA4 U1AV0BC/A5L/4+ICBr5Q9UBI/h4MkS8BH7UerCJbwRIyCJZSy3AdF3gBDPGFPIOLFQzRHWCIegmX c6CKjOO+fPkZWIIR6FoyHUhnisAKqvhCPgGs/7KsBU5cmogy4CA3ghyc2TpQH1CSObieA+rhq6Cb L+QAWIK/F9FPgzrSBfykFl+/ATTxBf0IVKElIB+9ABhyBRggJaCGOg88xFbgIN4C1qTt/YsNJsup 2OPPLZRXfgPSksKM3fTnMv771L8Nz58+HB9gDgv4fxsKE8LB2/8GEyNb8gplbmRzdHJlYW0KZW5k b2JqCjkgMCBvYmoKPDwvVHlwZS9Gb250RGVzY3JpcHRvci9Gb250TmFtZS9TSVJBTUYrVGltZXMt Um9tYW4vRm9udEJCb3hbMCAtMjE4IDgwOSA2ODNdL0ZsYWdzIDMyCi9Bc2NlbnQgNjgzCi9DYXBI ZWlnaHQgNjgzCi9EZXNjZW50IC0yMTgKL0l0YWxpY0FuZ2xlIDAKL1N0ZW1WIDEyMQovTWlzc2lu Z1dpZHRoIDI1MAovWEhlaWdodCA0NjAKL0NoYXJTZXQoL2EvYXQvYy9lL2YvZy9pL2wvbS9uL28v cGVyaW9kL3Ivcy9zcGFjZS90L3Yvdy96KS9Gb250RmlsZTMgMjYgMCBSPj4KZW5kb2JqCjI2IDAg b2JqCjw8L0ZpbHRlci9GbGF0ZURlY29kZQovU3VidHlwZS9UeXBlMUMvTGVuZ3RoIDIzMDA+PnN0 cmVhbQp4nGVVa1RTVxa+MZB7pwVswSjRmpu201bHFzqdVpZtrYKPjvGFPCJoASWEYJ6QBBJCSCAB w4GQJwmBAAmQ8EZARS0MU4tU+7CjdRytbbGrqx2103amM7POZU5/zI1rzcyPWeuuu+65Z59vf3uf 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 Kyowfe6qPBI5ohj6I400Rpkfz27Wt4IJAo7ioNnlcTp7Q+c7RgExFSzZRSIpDo4YjRlR3io/ntGk 7wDXCGjHB84PBy4CYi6g2EoiES1YdXWHzbSR3I8rm6XNhgCY4MATOHyi6P03DguUh7O42jlxOAvk A3n1Vj5xm9YmQSWtTXpOAi2I/9pQPQGfPE+9PciAxAKMv0nFTzIX02+xXy8RGPbS/fEGSoBPwZ0P xh7OzZPT09fDt+je2AyXo6Vo7Uv8X72lNPgHnU32Jgf5EXTG7maZhOqz+tYSwCkAJVVicXa2ZDvY SfAncqenLoUvjHAd+Wdk7wDih/uQCdkwFT0Pl6H9KB+9gjahHJQJX0Zr4MkbM76pv5DodSqVHbH6 y61F1jzdIeWxSpFMrQBEsWp49t3AzMg4GRka7eqx0g1kg0//yJaWKSWy3rL+wb7e/kFln5RMqOii srtgZhdr4In7Tw644uLuB+LiMezfU4l5vAplbmRzdHJlYW0KZW5kb2JqCjExIDAgb2JqCjw8L1R5 cGUvRm9udERlc2NyaXB0b3IvRm9udE5hbWUvR0lZUk5ZK0JvZG9uaU1ULEJvbGQvRm9udEJCb3hb MCAtMjU2IDg3NSA3NTBdL0ZsYWdzIDQKL0FzY2VudCA3NTAKL0NhcEhlaWdodCA2NjYKL0Rlc2Nl bnQgLTI1NgovSXRhbGljQW5nbGUgMAovU3RlbVYgMTMxCi9NaXNzaW5nV2lkdGggMTAwMAovWEhl aWdodCA0MTcKL0ZvbnRGaWxlMiAyNyAwIFI+PgplbmRvYmoKMjcgMCBvYmoKPDwvRmlsdGVyL0Zs YXRlRGVjb2RlCi9MZW5ndGgxIDEyNzg4L0xlbmd0aCA4ODIwPj5zdHJlYW0KeJztent4VNXZ71r7 MveZfZnZc8kkmZlMJiFMwiSZJJuQSWaTkHAVIkJIkJEEwkXKLQjeMSBEJIhABSJaK0L0sdSa4aIC Yo1FaltE7GOr7elFPw+inpLKQxH9lNk579qTIFpPv37P+es8z9l73nXfa6/1rt96L2sPwgghK1qH aNQ47aZIKdKuyO8gaJq/rG1lOj+qGCG8cf7tq/35cTkTCv4M+fsWrly07HcPfu1AiJqDEOtetPSu hen25u0I+Z9dvKCt/TdvPngAoZITUFixGApsAfZ2hPSrIZ+7eNnqO9Ptiwuhv5VLV8xvS+cLR0P+ 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 YLlgXWY9RG6bx/Z7LpfrJDc/4//f/zc3+YfK0L/VHOBTkH8CZwDpIFE8feaNUyY1jZ/A0RXjZkne kc2Tcyc2CPK0LFuGx+G0F9zsdmX+O3+G/n/0YtASLWQIfy6GBgchxCSEPANhMZqOZqIb0RQ0CTWh 8eCDccDBCjQOzUIS8qKRqBlNRrloImpAApLRNLBSbGApeYDTTmRHBehmsLdd2v+vMRJhHShI6aAN ql3RvmL5rf4bZhTWrljaTt6PtyP23/vrOfqnv6hfRBcHv1WAh5vha4SvoH+b2Ca0gQqjpiFaSIi+ gIqA5gBVAsWBsoBKhvIlQ/WR4fbfR+xu5PsuMa+hMBtG8e8j3Xrk+z6C90yC54r+uwTPyRot0eIo xFFqN8qHdJhpQi4YY/Q6KicE5eR9VdcIwbwRisNzXqi7RlDnS++vf3GRdaE8jx1M9h2fy8U+R970 Qh749eE5JD5u6liunkhdMlj0TdDWOLyO/xsItbI6CmVuZHN0cmVhbQplbmRvYmoKMiAwIG9iago8 PC9Qcm9kdWNlcihHUEwgR2hvc3RzY3JpcHQgOC42NCkKL0NyZWF0aW9uRGF0ZShEOjIwMTUxMTEx MTA1NzIwKzAyJzAwJykKL01vZERhdGUoRDoyMDE1MTExMTEwNTcyMCswMicwMCcpCi9UaXRsZShN aWNyb3NvZnQgV29yZCAtIFdPTkdBIEJVU0lORVNTIExPQU4gQVBQTElDQVRJT04gRk9STSkKL0Ny ZWF0b3IoUFNjcmlwdDUuZGxsIFZlcnNpb24gNS4yKQovQXV0aG9yKHVzZXIpPj5lbmRvYmoKeHJl ZgowIDMyCjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDA5NzA2OCAwMDAwMCBuIAowMDAwMTQxNzUw IDAwMDAwIG4gCjAwMDAwOTcwMDkgMDAwMDAgbiAKMDAwMDA5Njg0MSAwMDAwMCBuIAowMDAwMDAw MDE1IDAwMDAwIG4gCjAwMDAwOTY4MjAgMDAwMDAgbiAKMDAwMDA5NzExNiAwMDAwMCBuIAowMDAw MDk5MDEwIDAwMDAwIG4gCjAwMDAxMjk5NjQgMDAwMDAgbiAKMDAwMDA5OTM4NSAwMDAwMCBuIAow MDAwMTMyNjI1IDAwMDAwIG4gCjAwMDAwOTc3NjggMDAwMDAgbiAKMDAwMDEwODMzNSAwMDAwMCBu IAowMDAwMDk4MDcyIDAwMDAwIG4gCjAwMDAxMTA3MTUgMDAwMDAgbiAKMDAwMDA5ODQ0NiAwMDAw MCBuIAowMDAwMTE3NTI5IDAwMDAwIG4gCjAwMDAwOTcyNzIgMDAwMDAgbiAKMDAwMDA5OTg5MCAw MDAwMCBuIAowMDAwMDk3MTU3IDAwMDAwIG4gCjAwMDAwOTcxODcgMDAwMDAgbiAKMDAwMDEwMDEw NiAwMDAwMCBuIAowMDAwMTA4NTkxIDAwMDAwIG4gCjAwMDAxMTA5MjIgMDAwMDAgbiAKMDAwMDEx Nzc0OSAwMDAwMCBuIAowMDAwMTMwMjQwIDAwMDAwIG4gCjAwMDAxMzI4NDYgMDAwMDAgbiAKMDAw MDA5NzU2MSAwMDAwMCBuIAowMDAwMDk4MzAyIDAwMDAwIG4gCjAwMDAwOTg3OTIgMDAwMDAgbiAK MDAwMDA5OTY4NCAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDMyIC9Sb290IDEgMCBSIC9JbmZv IDIgMCBSCi9JRCBbPDQxREVFRENBQzMyRTkwQUVDOTQwNDhFOEFDQUEzMDZGPjw0MURFRURDQUMz MkU5MEFFQzk0MDQ4RThBQ0FBMzA2Rj5dCj4+CnN0YXJ0eHJlZgoxNDE5ODQKJSVFT0YK ------=_Part_6177416_1671826187.1448730138062-- From genbear-xfs=oss.sgi.com@moteninvest.com Sat Nov 28 15:20:17 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 5E8047F37 for ; Sat, 28 Nov 2015 15:20:17 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 3391E8F8035 for ; Sat, 28 Nov 2015 13:20:14 -0800 (PST) X-ASG-Debug-ID: 1448745579-04bdf07f0829c060001-NocioJ Received: from control.moteninvest.com ([104.233.64.190]) by cuda.sgi.com with ESMTP id 1xZf4ttJ47LNGyzB for ; Sat, 28 Nov 2015 13:20:10 -0800 (PST) X-Barracuda-Envelope-From: genbear-xfs=oss.sgi.com@moteninvest.com X-Barracuda-Apparent-Source-IP: 104.233.64.190 Received: by control.moteninvest.com id hb8d8k0001gi for ; Sat, 28 Nov 2015 16:08:49 -0500 (envelope-from ) MIME-Version: 1.0 From: "Gen Bear" To: xfs@oss.sgi.com Subject: Protect yourself from Radicals! Date: Sat, 28 Nov 2015 16:08:49 -0500 X-ASG-Orig-Subj: Protect yourself from Radicals! Content-Type: text/plain; List-unsubscribe: http://moteninvest.com/5pFXWBmsEh0ce80MKJ63 Message-ID: <0.0.0.B.1D12A20FA6B5676.9C5ED5@control.moteninvest.com> X-Barracuda-Connect: UNKNOWN[104.233.64.190] X-Barracuda-Start-Time: 1448745610 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 2.10 X-Barracuda-Spam-Status: No, SCORE=2.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MV0702, BSF_SC5_MJ1963, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24803 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 1.50 BSF_SC0_MV0702 Custom rule MV0702 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 . The NRA knows that the best deterent to violence is an armed populace. . And they are right! But make sure you have ALL the tools you need. . Police and military have the advantage from the general public with their equipment. . Make sure you do to! . The will give you the advantage over any aggressors. . Keep a watchful eye with 700 lumens that can not only help you see but actually BLIND an attacker. . Hurry and get 75% off. . We want you to be prepared. We are doing our part with this special offer. . http://moteninvest.com/27Qgc2DgFkG3lfW6pGuK/Tactical/Light . . . . . I don't want to get this offer anymore: http://moteninvest.com/5pFXWBmsEh0ce80MKJ63 . . . 2317 Patton Lane Raleigh, NC 27609 From genbear-xfs=oss.sgi.com@moteninvest.com Sat Nov 28 15:20:24 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 4A99C29DF9 for ; Sat, 28 Nov 2015 15:20:24 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 1D2398F8035 for ; Sat, 28 Nov 2015 13:20:24 -0800 (PST) X-ASG-Debug-ID: 1448745579-04bdf07f0829c060002-NocioJ Received: from control.moteninvest.com ([104.233.64.190]) by cuda.sgi.com with ESMTP id Cv0nn8fvUy0sQywc for ; Sat, 28 Nov 2015 13:20:13 -0800 (PST) X-Barracuda-Envelope-From: genbear-xfs=oss.sgi.com@moteninvest.com X-Barracuda-Apparent-Source-IP: 104.233.64.190 Received: by control.moteninvest.com id hb8d9e0001g9 for ; Sat, 28 Nov 2015 16:12:05 -0500 (envelope-from ) MIME-Version: 1.0 From: "Gen Bear" To: xfs@oss.sgi.com Subject: Protect yourself from Radicals! Date: Sat, 28 Nov 2015 16:12:05 -0500 X-ASG-Orig-Subj: Protect yourself from Radicals! Content-Type: text/plain; List-unsubscribe: http://moteninvest.com/5pFXWBmsEh0ce80MKJ63 Message-ID: <0.0.0.43.1D12A216F004C3A.17E65CB@control.moteninvest.com> X-Barracuda-Connect: UNKNOWN[104.233.64.190] X-Barracuda-Start-Time: 1448745611 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 2.10 X-Barracuda-Spam-Status: No, SCORE=2.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MV0702, BSF_SC5_MJ1963, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.24803 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 1.50 BSF_SC0_MV0702 Custom rule MV0702 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 . The NRA knows that the best deterent to violence is an armed populace. . And they are right! But make sure you have ALL the tools you need. . Police and military have the advantage from the general public with their equipment. . Make sure you do to! . The will give you the advantage over any aggressors. . Keep a watchful eye with 700 lumens that can not only help you see but actually BLIND an attacker. . Hurry and get 75% off. . We want you to be prepared. We are doing our part with this special offer. . http://moteninvest.com/27Qgc2DgFkG3lfW6pGuK/Tactical/Light . . . . . I don't want to get this offer anymore: http://moteninvest.com/5pFXWBmsEh0ce80MKJ63 . . . 2317 Patton Lane Raleigh, NC 27609 From lvml@5t9.de Sun Nov 29 15:40:45 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 AA8777F37 for ; Sun, 29 Nov 2015 15:40:45 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 8F8328F8033 for ; Sun, 29 Nov 2015 13:40:44 -0800 (PST) X-ASG-Debug-ID: 1448833240-04cbb0605b2ade50001-NocioJ Received: from app1a.xlhost.de (mailout173.xlhost.de [84.200.252.173]) by cuda.sgi.com with ESMTP id JRXC4pFiJEzDzMNU for ; Sun, 29 Nov 2015 13:40:41 -0800 (PST) X-Barracuda-Envelope-From: lvml@5t9.de X-Barracuda-Apparent-Source-IP: 84.200.252.173 Received: from [10.223.0.1] (55d41b70.access.ecotel.net [85.212.27.112]) (Authenticated sender: lkv@5t9.de) by app1a.xlhost.de (Postfix) with ESMTPSA id 5DB29101535B; Sun, 29 Nov 2015 22:40:38 +0100 (CET) Message-ID: <565B70F9.8060707@5t9.de> Date: Sun, 29 Nov 2015 22:41:13 +0100 From: Lutz Vieweg User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.2.0 MIME-Version: 1.0 To: Dave Chinner CC: xfs@oss.sgi.com Subject: Re: Does XFS support cgroup writeback limiting? References: <5652F311.7000406@5t9.de> <20151123202619.GE26718@dastard> <56538E6A.6030203@5t9.de> <20151123232052.GI26718@dastard> <5655FDDA.9050502@5t9.de> <20151125213500.GK26718@dastard> X-ASG-Orig-Subj: Re: Does XFS support cgroup writeback limiting? In-Reply-To: <20151125213500.GK26718@dastard> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 8bit X-Virus-Scanned: clamav-milter 0.98.1 at app1a.xlhost.de X-Virus-Status: Clean X-Barracuda-Connect: mailout173.xlhost.de[84.200.252.173] X-Barracuda-Start-Time: 1448833241 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24827 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 11/25/2015 10:35 PM, Dave Chinner wrote: >> 2) Create 3 different XFS filesystem instances on the block >> device, one for access by only the "good" processes, >> on for access by only the "evil" processes, one for >> shared access by at least two "good" and two "evil" >> processes. > > Why do you need multiple filesystems? The writeback throttling is > designed to work within a single filesystem... Hmm. Previously, I thought that the limiting of buffered writes was realized by keeping track of the owners of dirty pages, and that filesystem support was just required to make sure that writing via a filesystem did not "anonymize" the dirty data. From what I had read in blkio-controller.txt it seemed evident that limitations would be accounted for "per block device", not "per filesystem", and options like > echo ": " > /cgrp/blkio.throttle.read_bps_device document how to configure limits per block device. Now after reading through the new Writeback section of blkio-controller.txt again I am somewhat confused - the text states > writeback operates on inode basis and if that means inodes as in "file system inodes", this would indeed mean limits would be enforced "per filesystem" - and yet there are no options documented to specify limits for any specific filesystem. Does this mean some process writing to a block device (not via filesystem) without "O_DIRECT" will dirty buffer pages, but those will not be limited (as they are neither synchronous nor via-filesystem writes)? That would mean VMs sharing some (physical or abstract) block device could not really be isolated regarding their asynchronous write I/O... > Metadata IO not throttled - it is owned by the filesystem and hence > root cgroup. Ouch. That kind of defeats the purpose of limiting evil processes' ability to DOS other processes. Wouldn't it be possible to assign some arbitrary cost to meta-data operations - like "account one page write for each meta-data change to the originating process of that change"? While certainly not allowing for limiting to byte-precise limits of write bandwidth, this would regain the ability to defend against DOS situations, and for well-behaved processes, the "cost" accounted for their not-so-frequent meta-data operations would probably not really hurt their writing speed. >> The test is successful if all "good processes" terminate successfully >> after a time not longer than it would take to write 10 times X MB to the >> rate-limited block device. > > if we are rate limiting to 1MB/s, then a 10s test is not long enough > to reach steady state. Indeed, it's going to take at least 30s worth > of IO to guarantee that we getting writeback occurring for low > bandwidth streams.... Sure, the "X/100 MB per second" throttle to the scratch device was meant to result in a minimal test time of > 100s. > i.e. the test needs to run for a period of time and then measure > the throughput of each stream, comparing it against the expected > throughput for the stream, rather than trying to write a fixed > bandwidth.... The reason why I thought it to be a good idea to have the "good" processes use only a limited write rate was to make sure that the actual write activity of those processes is spread out over enough time to make sure that they could, after all, feel some "pressure back" from the operating system that is applied only after the "bad" processes have filled up all RAM dedicated to dirty buffer cache. Assume the test instance has lots of memory and would be willing to spend many Gigabytes of RAM for dirty buffer caches. Chances are that in such a situation the "good" processes might be done writing their limited amount of data almost instantaneously, because the data just went to RAM. (I understand that if one used the absolute "blkio.throttle.write*" options pressure back could apply before the dirty buffer cache was maxed out, but in real-world scenarios people will almost always use the relative "blkio.weight" based limiting, after all, you usually don't want to throttle processes if there is plenty of bandwidth left no other process wants at the same time.) Regards, Lutz Vieweg From aluno3@poczta.onet.pl Mon Nov 30 02:38:05 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 0314D7F37 for ; Mon, 30 Nov 2015 02:38:05 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id D896830404E for ; Mon, 30 Nov 2015 00:38:01 -0800 (PST) X-ASG-Debug-ID: 1448872674-04cb6c535458a00001-NocioJ Received: from smtpo65.poczta.onet.pl (smtpo33.poczta.onet.pl [213.180.142.164]) by cuda.sgi.com with ESMTP id gAZ0lT2OcpKPTqP5 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 30 Nov 2015 00:37:55 -0800 (PST) X-Barracuda-Envelope-From: aluno3@poczta.onet.pl X-Barracuda-Apparent-Source-IP: 213.180.142.164 Received: from [192.168.176.22] (host8514118246.static.open-e.3s.pl [85.14.118.246]) (Authenticated sender: aluno3@poczta.onet.pl) by smtp.poczta.onet.pl (Onet) with ESMTPA id 3p8Kgy35V9zT2Rmvs; Mon, 30 Nov 2015 09:37:49 +0100 (CET) Subject: Re: Which xfsprogs version to which kernel version To: Brian Foster X-ASG-Orig-Subj: Re: Which xfsprogs version to which kernel version References: <5656DD39.8060403@poczta.onet.pl> <20151126132638.53ed9fc7@harpe.intellique.com> <565706BB.3030006@poczta.onet.pl> <20151126135053.GB39911@bfoster.bfoster> <5657190A.1050103@poczta.onet.pl> <20151127152250.GA64860@bfoster.bfoster> Cc: xfs@oss.sgi.com From: "aluno3@poczta.onet.pl" X-Enigmail-Draft-Status: N1110 Message-ID: <565C0ADA.908@poczta.onet.pl> Date: Mon, 30 Nov 2015 09:37:46 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.2.0 MIME-Version: 1.0 In-Reply-To: <20151127152250.GA64860@bfoster.bfoster> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 8bit X-Barracuda-Connect: smtpo33.poczta.onet.pl[213.180.142.164] X-Barracuda-Start-Time: 1448872675 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24843 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 11/27/15 16:22, Brian Foster wrote: > On Thu, Nov 26, 2015 at 03:36:58PM +0100, aluno3@poczta.onet.pl wrote: >> dmesg when mounting volume which was formated xfsprogs 4.3.0: >> >> * >> root@192.168.176.24:~$ mkfs.xfs -V >> mkfs.xfs version 4.3.0 >> >> root@192.168.176.24:~$ mkfs.xfs -f -m crc=0,finobt=0 /dev/sdc4 >> meta-data=/dev/sdc4 isize=256 agcount=4, agsize=474552 blks >> = sectsz=512 attr=2, projid32bit=1 >> = crc=0 finobt=0, sparse=0 >> data = bsize=4096 blocks=1898208, imaxpct=25 >> = sunit=0 swidth=0 blks >> naming =version 2 bsize=4096 ascii-ci=0 ftype=1 >> log =internal log bsize=4096 blocks=2560, version=2 >> = sectsz=512 sunit=0 blks, lazy-count=1 >> realtime =none extsz=4096 blocks=0, rtextents=0 >> >> root@192.168.176.24:~$ mount /dev/sdc4 /mnt/sdc4 >> mount: wrong fs type, bad option, bad superblock on /dev/sdc4, >> missing codepage or helper program, or other error >> >> In some cases useful info is found in syslog - try >> dmesg | tail or so. >> >> root@192.168.176.24:~$ dmesg >> [ 212.984534] XFS (sdc4): bad version >> [ 212.984547] ffff88005cccb000: 58 46 53 42 00 00 10 00 00 00 00 00 00 >> 1c f6 e0 XFSB............ >> [ 212.984550] ffff88005cccb010: 00 00 00 00 00 00 00 00 00 00 00 00 00 >> 00 00 00 ................ >> [ 212.984551] ffff88005cccb020: 55 9d 20 d9 1c e9 4e a9 a3 ee 8d fd ba >> 68 b3 70 U. ...N......h.p >> [ 212.984553] ffff88005cccb030: 00 00 00 00 00 10 00 04 00 00 00 00 00 >> 00 00 80 ................ >> [ 212.984556] XFS (sdc4): Internal error xfs_sb_read_verify at line 730 >> of file fs/xfs/xfs_mount.c. Caller 0xffffffff81256c7d >> > > Interesting... have you tried to format without ftype support? It looks > like that wasn't introduced until v3.13. E.g., > > mkfs.xfs -f -m crc=0 -n ftype=0 > With ftype=0 and crc=0 options, mounting the volume is possible. root:~$ mkfs.xfs -f -m crc=0 -n ftype=0 /dev/sdc meta-data=/dev/sdc isize=256 agcount=4, agsize=30524162 blks = sectsz=512 attr=2, projid32bit=1 = crc=0 finobt=0, sparse=0 data = bsize=4096 blocks=122096646, imaxpct=25 = sunit=0 swidth=0 blks naming =version 2 bsize=4096 ascii-ci=0 ftype=0 log =internal log bsize=4096 blocks=59617, version=2 = sectsz=512 sunit=0 blks, lazy-count=1 realtime =none extsz=4096 blocks=0, rtextents=0 root:~$ mount /dev/sdc /mnt/sdc root:~$ dmesg [ 1761.805159] sdc: unknown partition table [ 1768.928019] XFS (sdc): Mounting Filesystem [ 1768.987660] XFS (sdc): Ending clean mount so is it safe to use xfsprogs 4.3.0 with crc=0 and ftype=0 with kernel 3.10? > Brian > >> [ 212.984560] CPU: 0 PID: 440 Comm: kworker/0:1H Tainted: P O >> 3.10.92-oe64-ge331686 #15 >> [ 212.984562] Hardware name: System manufacturer System Product >> Name/P5WDG2 WS Pro, BIOS 0905 03/06/2008 >> [ 212.984567] Workqueue: xfslogd xfs_buf_iodone_work >> [ 212.984570] ffffffff81692f75 ffffffff81258c5d ffffffff81256c7d >> ffffffff818a39e3 >> [ 212.984573] ffff88007aa9ef00 0000000000000016 ffff88007aa8b000 >> 0000000000000000 >> [ 212.984576] ffff88007ea17800 ffffffff812a32ac ffffffff81256c7d >> ffff88007ea11a40 >> [ 212.984579] Call Trace: >> [ 212.984584] [] ? dump_stack+0xc/0x15 >> [ 212.984587] [] ? xfs_corruption_error+0x8d/0x90 >> [ 212.984590] [] ? xfs_buf_iodone_work+0x6d/0x90 >> [ 212.984595] [] ? xfs_sb_read_verify+0xfc/0x120 >> [ 212.984598] [] ? xfs_buf_iodone_work+0x6d/0x90 >> [ 212.984600] [] ? xfs_buf_iodone_work+0x6d/0x90 >> [ 212.984604] [] ? process_one_work+0x13d/0x3b0 >> [ 212.984607] [] ? worker_thread+0x121/0x3d0 >> [ 212.984609] [] ? manage_workers.isra.26+0x280/0x280 >> [ 212.984613] [] ? kthread+0xc2/0xd0 >> [ 212.984616] [] ? sched_clock_cpu+0x30/0x100 >> [ 212.984619] [] ? kthread_create_on_node+0x110/0x110 >> [ 212.984623] [] ? ret_from_fork+0x58/0x90 >> [ 212.984626] [] ? kthread_create_on_node+0x110/0x110 >> [ 212.984628] XFS (sdc4): Corruption detected. Unmount and run xfs_repair >> [ 212.984634] XFS (sdc4): SB validate failed with error 22. >> * >> >> On 11/26/15 14:50, Brian Foster wrote: >>> On Thu, Nov 26, 2015 at 02:18:51PM +0100, aluno3@poczta.onet.pl wrote: >>>> Yes I used -f option with 4.X version of xfsprogs but mounting the >>>> volume was not possible - before mkfs.xfs finished successfully >>>> (mkfs.xfs -f -m crc=0,finobt=0). >>>> >>> >>> You posted the output associated with the crc=1 fs mount failure, what >>> happens when you try to mount after formatting with crc=0? >>> >>> Brian >>> >>>> Should I stay in 3.1.X family of xfsprogs or is it recommended to use at >>>> least 3.2.x version with kernel 3.10? >>>> >>>> The most I care about xfs_repair. >>>> >>>> On 11/26/15 13:26, Emmanuel Florac wrote: >>>>> Le Thu, 26 Nov 2015 11:21:45 +0100 >>>>> "aluno3@poczta.onet.pl" écrivait: >>>>> >>>>>> mkfs.xfs -m crc=0,finobt=0 >>>>>> >>>>>> but it does not work with 4.X version of xfsprogs. Call trace also >>>>>> occurred so I tried to use 3.2.4 family with crc=0,finobt=0 and volume >>>>>> mounted successfully. >>>>>> >>>>> >>>>> Did you use -f? else mkfs.xfs won't do anything as it'll detect an >>>>> existing filesystem. >>>>> >>>> >>>> _______________________________________________ >>>> 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 cmaiolino@redhat.com Mon Nov 30 03:51:14 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 7EEF07F37 for ; Mon, 30 Nov 2015 03:51:14 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 53113304048 for ; Mon, 30 Nov 2015 01:51:11 -0800 (PST) X-ASG-Debug-ID: 1448877069-04bdf07f092c86d0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id ijd8R69Ef03HWPx2 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 30 Nov 2015 01:51:09 -0800 (PST) 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 (Postfix) with ESMTPS id 36BF2C0D222C; Mon, 30 Nov 2015 09:51:09 +0000 (UTC) Received: from redhat.com (vpn-62-148.rdu2.redhat.com [10.10.62.148]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAU9p4j6024208 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Mon, 30 Nov 2015 04:51:07 -0500 Date: Mon, 30 Nov 2015 10:51:04 +0100 From: Carlos Maiolino To: "aluno3@poczta.onet.pl" Cc: Brian Foster , xfs@oss.sgi.com Subject: Re: Which xfsprogs version to which kernel version Message-ID: <20151130095104.GA25920@redhat.com> X-ASG-Orig-Subj: Re: Which xfsprogs version to which kernel version Mail-Followup-To: "aluno3@poczta.onet.pl" , Brian Foster , xfs@oss.sgi.com References: <5656DD39.8060403@poczta.onet.pl> <20151126132638.53ed9fc7@harpe.intellique.com> <565706BB.3030006@poczta.onet.pl> <20151126135053.GB39911@bfoster.bfoster> <5657190A.1050103@poczta.onet.pl> <20151127152250.GA64860@bfoster.bfoster> <565C0ADA.908@poczta.onet.pl> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <565C0ADA.908@poczta.onet.pl> User-Agent: Mutt/1.5.24 (2015-08-30) 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: 1448877069 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Mon, Nov 30, 2015 at 09:37:46AM +0100, aluno3@poczta.onet.pl wrote: > On 11/27/15 16:22, Brian Foster wrote: > > On Thu, Nov 26, 2015 at 03:36:58PM +0100, aluno3@poczta.onet.pl wrote: > >> dmesg when mounting volume which was formated xfsprogs 4.3.0: > >> > >> * > >> root@192.168.176.24:~$ mkfs.xfs -V > >> mkfs.xfs version 4.3.0 > >> > >> root@192.168.176.24:~$ mkfs.xfs -f -m crc=0,finobt=0 /dev/sdc4 > >> meta-data=/dev/sdc4 isize=256 agcount=4, agsize=474552 blks > >> = sectsz=512 attr=2, projid32bit=1 > >> = crc=0 finobt=0, sparse=0 > >> data = bsize=4096 blocks=1898208, imaxpct=25 > >> = sunit=0 swidth=0 blks > >> naming =version 2 bsize=4096 ascii-ci=0 ftype=1 > >> log =internal log bsize=4096 blocks=2560, version=2 > >> = sectsz=512 sunit=0 blks, lazy-count=1 > >> realtime =none extsz=4096 blocks=0, rtextents=0 > >> > >> root@192.168.176.24:~$ mount /dev/sdc4 /mnt/sdc4 > >> mount: wrong fs type, bad option, bad superblock on /dev/sdc4, > >> missing codepage or helper program, or other error > >> > >> In some cases useful info is found in syslog - try > >> dmesg | tail or so. > >> > >> root@192.168.176.24:~$ dmesg > >> [ 212.984534] XFS (sdc4): bad version > >> [ 212.984547] ffff88005cccb000: 58 46 53 42 00 00 10 00 00 00 00 00 00 > >> 1c f6 e0 XFSB............ > >> [ 212.984550] ffff88005cccb010: 00 00 00 00 00 00 00 00 00 00 00 00 00 > >> 00 00 00 ................ > >> [ 212.984551] ffff88005cccb020: 55 9d 20 d9 1c e9 4e a9 a3 ee 8d fd ba > >> 68 b3 70 U. ...N......h.p > >> [ 212.984553] ffff88005cccb030: 00 00 00 00 00 10 00 04 00 00 00 00 00 > >> 00 00 80 ................ > >> [ 212.984556] XFS (sdc4): Internal error xfs_sb_read_verify at line 730 > >> of file fs/xfs/xfs_mount.c. Caller 0xffffffff81256c7d > >> > > > > Interesting... have you tried to format without ftype support? It looks > > like that wasn't introduced until v3.13. E.g., > > > > mkfs.xfs -f -m crc=0 -n ftype=0 > > > > With ftype=0 and crc=0 options, mounting the volume is possible. > > > root:~$ mkfs.xfs -f -m crc=0 -n ftype=0 /dev/sdc > meta-data=/dev/sdc isize=256 agcount=4, agsize=30524162 > blks > = sectsz=512 attr=2, projid32bit=1 > = crc=0 finobt=0, sparse=0 > data = bsize=4096 blocks=122096646, imaxpct=25 > = sunit=0 swidth=0 blks > naming =version 2 bsize=4096 ascii-ci=0 ftype=0 > log =internal log bsize=4096 blocks=59617, version=2 > = sectsz=512 sunit=0 blks, lazy-count=1 > realtime =none extsz=4096 blocks=0, rtextents=0 > root:~$ mount /dev/sdc /mnt/sdc > root:~$ dmesg > [ 1761.805159] sdc: unknown partition table > [ 1768.928019] XFS (sdc): Mounting Filesystem > [ 1768.987660] XFS (sdc): Ending clean mount > > so is it safe to use xfsprogs 4.3.0 with crc=0 and ftype=0 with kernel > 3.10? > Hi, it's safe once you're disabling the unsupported filesystem formats for the kernel you're using. > > Brian > > > >> [ 212.984560] CPU: 0 PID: 440 Comm: kworker/0:1H Tainted: P O > >> 3.10.92-oe64-ge331686 #15 > >> [ 212.984562] Hardware name: System manufacturer System Product > >> Name/P5WDG2 WS Pro, BIOS 0905 03/06/2008 > >> [ 212.984567] Workqueue: xfslogd xfs_buf_iodone_work > >> [ 212.984570] ffffffff81692f75 ffffffff81258c5d ffffffff81256c7d > >> ffffffff818a39e3 > >> [ 212.984573] ffff88007aa9ef00 0000000000000016 ffff88007aa8b000 > >> 0000000000000000 > >> [ 212.984576] ffff88007ea17800 ffffffff812a32ac ffffffff81256c7d > >> ffff88007ea11a40 > >> [ 212.984579] Call Trace: > >> [ 212.984584] [] ? dump_stack+0xc/0x15 > >> [ 212.984587] [] ? xfs_corruption_error+0x8d/0x90 > >> [ 212.984590] [] ? xfs_buf_iodone_work+0x6d/0x90 > >> [ 212.984595] [] ? xfs_sb_read_verify+0xfc/0x120 > >> [ 212.984598] [] ? xfs_buf_iodone_work+0x6d/0x90 > >> [ 212.984600] [] ? xfs_buf_iodone_work+0x6d/0x90 > >> [ 212.984604] [] ? process_one_work+0x13d/0x3b0 > >> [ 212.984607] [] ? worker_thread+0x121/0x3d0 > >> [ 212.984609] [] ? manage_workers.isra.26+0x280/0x280 > >> [ 212.984613] [] ? kthread+0xc2/0xd0 > >> [ 212.984616] [] ? sched_clock_cpu+0x30/0x100 > >> [ 212.984619] [] ? kthread_create_on_node+0x110/0x110 > >> [ 212.984623] [] ? ret_from_fork+0x58/0x90 > >> [ 212.984626] [] ? kthread_create_on_node+0x110/0x110 > >> [ 212.984628] XFS (sdc4): Corruption detected. Unmount and run xfs_repair > >> [ 212.984634] XFS (sdc4): SB validate failed with error 22. > >> * > >> > >> On 11/26/15 14:50, Brian Foster wrote: > >>> On Thu, Nov 26, 2015 at 02:18:51PM +0100, aluno3@poczta.onet.pl wrote: > >>>> Yes I used -f option with 4.X version of xfsprogs but mounting the > >>>> volume was not possible - before mkfs.xfs finished successfully > >>>> (mkfs.xfs -f -m crc=0,finobt=0). > >>>> > >>> > >>> You posted the output associated with the crc=1 fs mount failure, what > >>> happens when you try to mount after formatting with crc=0? > >>> > >>> Brian > >>> > >>>> Should I stay in 3.1.X family of xfsprogs or is it recommended to use at > >>>> least 3.2.x version with kernel 3.10? > >>>> > >>>> The most I care about xfs_repair. > >>>> > >>>> On 11/26/15 13:26, Emmanuel Florac wrote: > >>>>> Le Thu, 26 Nov 2015 11:21:45 +0100 > >>>>> "aluno3@poczta.onet.pl" écrivait: > >>>>> > >>>>>> mkfs.xfs -m crc=0,finobt=0 > >>>>>> > >>>>>> but it does not work with 4.X version of xfsprogs. Call trace also > >>>>>> occurred so I tried to use 3.2.4 family with crc=0,finobt=0 and volume > >>>>>> mounted successfully. > >>>>>> > >>>>> > >>>>> Did you use -f? else mkfs.xfs won't do anything as it'll detect an > >>>>> existing filesystem. > >>>>> > >>>> > >>>> _______________________________________________ > >>>> 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 > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs -- Carlos From bfoster@redhat.com Mon Nov 30 07:22:23 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 979AD7F37 for ; Mon, 30 Nov 2015 07:22:23 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 256A9AC003 for ; Mon, 30 Nov 2015 05:22:22 -0800 (PST) X-ASG-Debug-ID: 1448889740-04cbb0605b2c5e00001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 1u9AtvVhu7Z3Bzdp (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 30 Nov 2015 05:22:21 -0800 (PST) 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 (Postfix) with ESMTPS id 7186B42E5B7 for ; Mon, 30 Nov 2015 13:22:20 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-132.bos.redhat.com [10.18.41.132]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAUDMK0M018624; Mon, 30 Nov 2015 08:22:20 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id A61CE12013B; Mon, 30 Nov 2015 08:22:19 -0500 (EST) Date: Mon, 30 Nov 2015 08:22:19 -0500 From: Brian Foster To: Carlos Maiolino Cc: xfs@oss.sgi.com Subject: Re: [PATCH] xfs_io: implement 'inode' command V5 Message-ID: <20151130132217.GA24765@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH] xfs_io: implement 'inode' command V5 References: <1448552795-8794-1-git-send-email-cmaiolino@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1448552795-8794-1-git-send-email-cmaiolino@redhat.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: 1448889741 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Thu, Nov 26, 2015 at 04:46:35PM +0100, Carlos Maiolino wrote: > Implements a new xfs_io command, named 'inode', which is supposed to be > used to query information about inode's existence and its physical size > in the filesystem. > > Supported options: > > Default: -- Return true(1) or false(0) if any inode greater than > 32bits has been found in the filesystem > -v -- verbose mode > Display the number and the physical size (in bits) > of the largest inode in the filesystem > [num] -- Return true(1) or false(0) if the inode [num] is in use > -n [num] -- Return the next valid inode after [num] > > No manpage sent because there were changes in the supported options and its > descriptions. > I'll send the manpage after the options and descriptions are reviewed. > > - Changelog > > V3: > - Merge all 3 patches from the V2 together in a single patch > - Rework of '-n [num]' and 'num' only arguments algorithm > - Argument -n now relies on bulkreq.count to check for next inodes, not > on bstat.bs_ino anymore. > - for loop in ret_lsize or ret_largest case, now relies on count being 0 > to break the loop > > V4: > - Refactor inode_f function to reduce its size and easier logic > - Implement error handlers for invalid command combination (hopefully > all invalid combinations). > - use a single xfs_inogrp array for keep track of inodes > - Fix missing newline in inode_help() > - Rewrite help message in inode_help() > - Fix indentation > > V5: > - Reduce the amount of options > - remove igrp_rec variable, and use igroup[lastgrp] directly to get > information from the last inode groups returned by ioctl > > Signed-off-by: Carlos Maiolino > --- > io/open.c | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 143 insertions(+) > > diff --git a/io/open.c b/io/open.c > index ac5a5e0..1e38ea8 100644 > --- a/io/open.c > +++ b/io/open.c > @@ -20,6 +20,7 @@ > #include "input.h" > #include "init.h" > #include "io.h" > +#include "libxfs.h" > > #ifndef __O_TMPFILE > #if defined __alpha__ > @@ -44,6 +45,7 @@ static cmdinfo_t statfs_cmd; > static cmdinfo_t chproj_cmd; > static cmdinfo_t lsproj_cmd; > static cmdinfo_t extsize_cmd; > +static cmdinfo_t inode_cmd; > static prid_t prid; > static long extsize; > > @@ -750,6 +752,136 @@ statfs_f( > return 0; > } > > +static void > +inode_help(void) > +{ > + printf(_( > +"\n" > +"Query physical information about the inode" > +"\n" > +" Default: -- Return true(1) or false(0) if any inode greater than\n" > +" 32bits has been found in the filesystem\n" > +" -v -- verbose mode\n" > +" Display the number and the physical size (in bits)\n" > +" of the largest inode in the filesystem\n" > +"[num] -- Return true(1) or false(0) if the inode [num] is in use\n" > +" -n [num] -- Return the next valid inode after [num]\n" > +"\n")); > +} > + > +static int > +inode_f( > + int argc, > + char **argv) > +{ > + __s32 count = 0; > + __s32 lastgrp = 0; > + __u64 last = 0; > + __u64 lastino = 0; > + __u64 userino = 0; > + char *p; > + int c; > + int verbose = 0; > + int ret_next = 0; > + int cmd = 0; > + struct xfs_inogrp igroup[1024]; > + struct xfs_fsop_bulkreq bulkreq; > + struct xfs_bstat bstat; > + > + while ((c = getopt(argc, argv, "nv")) != EOF) { I think we want "n:v" here since -n expects an argument, even if we don't process the arg here. > + switch (c) { > + case 'v': > + verbose = 1; > + break; > + case 'n': > + ret_next = 1; > + break; > + default: > + return command_usage(&inode_cmd); > + } > + } > + > + if (ret_next && verbose) > + return command_usage(&inode_cmd); > + Why is this not supported? Hmm, I see that -n returns an inode number and otherwise we print 0/1 or : with -v. Perhaps this would be easier if the command semantics/output were more consistent. E.g., "inode": print 0/1 based on largest inode size "inode -v": print : of largest inode "inode ": print if inode exists "inode -v ": print : if inode exists "inode -n ": print if next inode exists "inode -nv ": print : if next inode exists In other words, the default behavior is to identify the 32-bit/64-bit state of the fs. If an inode is provided, we print the inode number if the inode exists. The -n flags alters this behavior to find the next inode. The -v flag alters the previous two situations to also print the inode size. > + if (optind < argc) { A comment above this check to explain what it means (i.e., user passed an inode number) would be nice. > + if (verbose) > + return command_usage(&inode_cmd); Also, why is this not supported (see above)? > + > + if (ret_next) { > + cmd = XFS_IOC_FSBULKSTAT; > + } else { > + if (argc > 2) > + return command_usage(&inode_cmd); > + else > + cmd = XFS_IOC_FSBULKSTAT_SINGLE; > + } > + > + userino = strtoull(argv[optind], &p, 10); > + if ((*p != '\0')) { > + printf(_("[num] must be a numeric value\n")); > + exitcode = 1; > + return 0; > + } > + > + bulkreq.lastip = &userino; > + bulkreq.icount = 1; > + bulkreq.ubuffer = &bstat; > + bulkreq.ocount = &count; > + > + if (xfsctl(file->name, file->fd, cmd, &bulkreq)) { > + if (errno == EINVAL) { > + if (!ret_next) > + printf("0\n"); > + } else { > + perror("xfsctl"); > + } > + exitcode = 1; > + return 0; > + } > + > + if (ret_next) { > + printf("%llu\n", bstat.bs_ino); > + return 0; > + } else { > + /* Inode number used*/ > + printf("1\n"); > + return 0; > + } The return 0 can go after the if/else. > + } > + /* * The user has not provided an inode number. Therefore, find * the largest inode in the fs. */ Brian > + bulkreq.lastip = &last; > + bulkreq.icount = 1024; /* User-defined maybe!? */ > + bulkreq.ubuffer = &igroup; > + bulkreq.ocount = &count; > + > + for (;;) { > + if (xfsctl(file->name, file->fd, XFS_IOC_FSINUMBERS, > + &bulkreq)) { > + perror("XFS_IOC_FSINUMBERS"); > + exitcode = 1; > + return 0; > + } > + > + if (count == 0) > + break; > + > + lastgrp = count; > + } > + > + lastgrp--; > + lastino = igroup[lastgrp].xi_startino + > + xfs_highbit64(igroup[lastgrp].xi_allocmask); > + > + if (verbose) > + printf("%llu:%d\n", lastino, > + lastino > XFS_MAXINUMBER_32 ? 64 : 32); > + else > + printf("%d\n", lastino > XFS_MAXINUMBER_32 ? 1 : 0); > + > + return 0; > +} > + > void > open_init(void) > { > @@ -815,6 +947,16 @@ open_init(void) > _("get/set preferred extent size (in bytes) for the open file"); > extsize_cmd.help = extsize_help; > > + inode_cmd.name = "inode"; > + inode_cmd.cfunc = inode_f; > + inode_cmd.args = _("[-n | -v] [num]"); > + inode_cmd.argmin = 0; > + inode_cmd.argmax = 2; > + inode_cmd.flags = CMD_NOMAP_OK; > + inode_cmd.oneline = > + _("Query inode number usage in the filesystem"); > + inode_cmd.help = inode_help; > + > add_command(&open_cmd); > add_command(&stat_cmd); > add_command(&close_cmd); > @@ -822,4 +964,5 @@ open_init(void) > add_command(&chproj_cmd); > add_command(&lsproj_cmd); > add_command(&extsize_cmd); > + add_command(&inode_cmd); > } > -- > 2.4.3 > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From bfoster@redhat.com Mon Nov 30 07:22:26 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 762EC7F50 for ; Mon, 30 Nov 2015 07:22:26 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 23655AC003 for ; Mon, 30 Nov 2015 05:22:26 -0800 (PST) X-ASG-Debug-ID: 1448889745-04bdf07f092cee80001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id Oo7YzPUWnwIu44wA (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 30 Nov 2015 05:22:25 -0800 (PST) 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 (Postfix) with ESMTPS id 01A19A81; Mon, 30 Nov 2015 13:22:24 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-132.bos.redhat.com [10.18.41.132]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAUDMOBI031551; Mon, 30 Nov 2015 08:22:24 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id 3F04A12013B; Mon, 30 Nov 2015 08:22:24 -0500 (EST) Date: Mon, 30 Nov 2015 08:22:24 -0500 From: Brian Foster To: Alexander Kuleshov Cc: Dave Chinner , linux-kernel@vger.kernel.org, xfs@oss.sgi.com Subject: Re: [PATCH] xfs/xfs_buf: make xfs_buf_ioend_async() static Message-ID: <20151130132223.GB24765@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH] xfs/xfs_buf: make xfs_buf_ioend_async() static References: <1448646749-18978-1-git-send-email-kuleshovmail@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1448646749-18978-1-git-send-email-kuleshovmail@gmail.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: 1448889745 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Fri, Nov 27, 2015 at 11:52:29PM +0600, Alexander Kuleshov wrote: > There are no callers of the xfs_buf_ioend_async() function outside > of the fs/xfs/xfs_buf.c. So, let's make it static. > > Signed-off-by: Alexander Kuleshov > --- Reviewed-by: Brian Foster > fs/xfs/xfs_buf.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c > index 3243cdf..45a8ea7 100644 > --- a/fs/xfs/xfs_buf.c > +++ b/fs/xfs/xfs_buf.c > @@ -1045,7 +1045,7 @@ xfs_buf_ioend_work( > xfs_buf_ioend(bp); > } > > -void > +static void > xfs_buf_ioend_async( > struct xfs_buf *bp) > { > -- > 2.5.0 > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From Vincent.Riera@imgtec.com Mon Nov 30 07:25:43 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 592C97F37 for ; Mon, 30 Nov 2015 07:25:43 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 48E908F8035 for ; Mon, 30 Nov 2015 05:25:40 -0800 (PST) X-ASG-Debug-ID: 1448889937-04cb6c535560480001-NocioJ Received: from mailapp01.imgtec.com (mailapp01.imgtec.com [195.59.15.196]) by cuda.sgi.com with ESMTP id ZzJkRj2sxlx7FkjA for ; Mon, 30 Nov 2015 05:25:37 -0800 (PST) X-Barracuda-Envelope-From: Vincent.Riera@imgtec.com X-Barracuda-Apparent-Source-IP: 195.59.15.196 Received: from HHMAIL01.hh.imgtec.org (unknown [10.100.10.19]) by Websense Email Security Gateway with ESMTPS id 7F1904579DFE0 for ; Mon, 30 Nov 2015 13:25:34 +0000 (GMT) Received: from LEMAIL01.le.imgtec.org (192.168.152.62) by HHMAIL01.hh.imgtec.org (10.100.10.19) with Microsoft SMTP Server (TLS) id 14.3.235.1; Mon, 30 Nov 2015 13:25:36 +0000 Received: from [192.168.154.114] (192.168.154.114) by LEMAIL01.le.imgtec.org (192.168.152.62) with Microsoft SMTP Server (TLS) id 14.3.210.2; Mon, 30 Nov 2015 13:25:35 +0000 Subject: Re: [PATCH xfsprogs] mdrestore: do not do dynamic linking of libtool libraries To: X-ASG-Orig-Subj: Re: [PATCH xfsprogs] mdrestore: do not do dynamic linking of libtool libraries References: <1448449838-47261-1-git-send-email-Vincent.Riera@imgtec.com> From: Vicente Olivert Riera Message-ID: <565C4E4F.4060303@imgtec.com> Date: Mon, 30 Nov 2015 13:25:35 +0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <1448449838-47261-1-git-send-email-Vincent.Riera@imgtec.com> Content-Type: text/plain; charset="windows-1252" Content-Transfer-Encoding: 7bit X-Originating-IP: [192.168.154.114] X-Barracuda-Connect: mailapp01.imgtec.com[195.59.15.196] X-Barracuda-Start-Time: 1448889937 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24848 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- ping On 25/11/15 11:10, Vicente Olivert Riera wrote: > As explained in commit ece49daeff1a3cad765e106d678c608925c9d768, use > -static-libtool-libs instead of -static to allow fallback to the dynamic > linking for libuuid only. Otherwise the build will fail like this: > > ld: attempted static link of dynamic object `/usr/lib/libuuid.so' > > Signed-off-by: Vicente Olivert Riera > --- > mdrestore/Makefile | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/mdrestore/Makefile b/mdrestore/Makefile > index 5171306..1b34a0e 100644 > --- a/mdrestore/Makefile > +++ b/mdrestore/Makefile > @@ -10,7 +10,7 @@ CFILES = xfs_mdrestore.c > > LLDLIBS = $(LIBXFS) $(LIBRT) $(LIBPTHREAD) $(LIBUUID) > LTDEPENDENCIES = $(LIBXFS) > -LLDFLAGS = -static > +LLDFLAGS = -static-libtool-libs > > default: depend $(LTCOMMAND) > > From fxurdcbbsygrm@qualitynet.net Mon Nov 30 07:53:30 2015 Return-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.2 required=5.0 tests=HK_RANDOM_ENVFROM, HK_RANDOM_FROM,HTML_MESSAGE,SUBJ_ALL_CAPS 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 D15397F37 for ; Mon, 30 Nov 2015 07:53:30 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id C07EE304051 for ; Mon, 30 Nov 2015 05:53:27 -0800 (PST) X-ASG-Debug-ID: 1448891601-04cbb0605e2c8480001-NocioJ Received: from smtp2.qualitynet.net (dbncl-asg-40g-s02.onyx.net [213.131.112.183]) by cuda.sgi.com with ESMTP id fFJwDVaYWw24imX0 for ; Mon, 30 Nov 2015 05:53:22 -0800 (PST) X-Barracuda-Envelope-From: fxurdcbbsygrm@qualitynet.net X-Barracuda-Apparent-Source-IP: 213.131.112.183 MIME-Version: 1.0 Date: Mon, 30 Nov 2015 16:53:24 +0300 Message-ID: <557719897.20151130165324@WVUIIWQIMZD> Subject: =?utf-8?B?0J7RhtC10L3QutCwINGA0LDQsdC+0YLRiyDQutC+0LzQv9Cw0L3QuNC4INC4INGB0L7RgtGA0YPQtNC90LjQutC+0LIg0L/QviDQnNCS0J4sIEtQSSDQuCBCU0M=?= From: "=?utf-8?B?0J7RgtC00LXQuyDRgNCw0LfQstC40YLQuNGPINC/0LXRgNGB0L7QvdCw0LvQsA==?=" X-ASG-Orig-Subj: =?utf-8?B?0J7RhtC10L3QutCwINGA0LDQsdC+0YLRiyDQutC+0LzQv9Cw0L3QuNC4INC4INGB0L7RgtGA0YPQtNC90LjQutC+0LIg0L/QviDQnNCS0J4sIEtQSSDQuCBCU0M=?= To: xfs@oss.sgi.com Content-Type: multipart/alternative; boundary=----------716D51D3798C78C9 X-Barracuda-Connect: dbncl-asg-40g-s02.onyx.net[213.131.112.183] X-Barracuda-Start-Time: 1448891601 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24849 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 HTML_MESSAGE BODY: HTML included in message ------------716D51D3798C78C9 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: base64 0KPRh9C10LHQvdGL0Lkg0YbQtdC90YLRgCDQv9GA0LjQs9C70LDRiNCw0LXRgiDQvdCwINC+0LHR g9GH0LXQvdC40LUgKCrQv9GA0L7QvNC+0LrQvtC0OjI2MiopINC/0L4g0YLQtdC80LU6DQoNCirQ oNCw0LfRgNCw0LHQvtGC0LrQsCDQuCDQstC90LXQtNGA0LXQvdC40LUg0L/QvtC60LDQt9Cw0YLQ tdC70LXQuSBLUEksINCc0JLQniDQuCBCU0MuICoNCg0KKtCU0LvRjzoqINGA0YPQutC+0LLQvtC0 0LjRgtC10LvQtdC5INC4INGB0L/QtdGG0LjQsNC70LjRgdGC0L7Qsiwg0L7RgtCy0LXRh9Cw0Y7R idC40YUg0LfQsCDQvtGA0LPQsNC90LjQt9Cw0YbQuNC+0L3QvdC+0LUg0YDQsNC30LLQuNGC0LjQ tSwNCtGA0YPQutC+0LLQvtC00LjRgtC10LvQtdC5INC4INGB0L/QtdGG0LjQsNC70LjRgdGC0L7Q siDQsiDQvtCx0LvQsNGB0YLQuCDRg9C/0YDQsNCy0LvQtdC90LjRjyDQv9C10YDRgdC+0L3QsNC7 0L7QvCwg0YDRg9C60L7QstC+0LTQuNGC0LXQu9C10LkNCtC60L7QvNC/0LDQvdC40Lkg0Lgg0YHQ vtCx0YHRgtCy0LXQvdC90LjQutC+0LIg0LHQuNC30L3QtdGB0LAuDQoNCg0KDQoNCg0KKjE3IH4g MTgg0LTQtdC60LDQsdGA0Y8g0LPQvtGA0L7QtCDQnNC+0YHQutCy0LAqDQrQl9Cw0L3Rj9GC0LjR jyDQv9GA0L7QstC+0LTRj9GC0YHRjyDRgSAxMDowMCDQtNC+IDE3OjMwDQoNCtCc0LXRgNC+0L/R gNC40Y/RgtC40LUg0YHQvtGB0YLQvtC40YLRgdGPOiDQvC4g0JHQsNGD0LzQsNC90YHQutCw0Y8s INGD0LsuINCR0LDRg9C80LDQvdGB0LrQsNGPLCDQtC42LCDQkS7Qpi4gItCS0LjQutGC0L7RgNC4 0Y8NCtCf0LvQsNC30LAiLg0KDQrQo9C30L3QsNGC0Ywg0LLRgdGOINC/0L7QtNGA0L7QsdC90YPR jiDQuNC90YTQvtGA0LzQsNGG0LjRjiDQuCDQv9C+0LTQsNGC0Ywg0LfQsNGP0LLQutGDINC90LAg 0YPRh9Cw0YHRgtC40LUg0LIg0L7QsdGD0YfQtdC90LjQuCDQvNC+0LbQvdC+DQrQv9C+INGC0LXQ uy46DQoNCjggINC60L7QtCDQs9C+0YDQvtC00LAgICggNCA5IDUgKSAg0L3QvtC80LXRgCAgNyAy IDUgIC0gIDAgNCAgLSAgNCA4ICAo0LzQvdC+0LPQvtC60LDQvdCw0LvRjNC90YvQuSkNCg0KDQoq 0JTQsNC90L3QvtC1INC+0LHRg9GH0LXQvdC40LUg0L/QvtC30LLQvtC70Y/QtdGCOiAqDQogKiDQ v9C+0LvRg9GH0LjRgtGMINCz0L7RgtC+0LLRi9C1INC90LDRgNCw0LHQvtGC0LrQuCDQuCDRgNC1 0YjQtdC90LjRjyDQuNC3INC/0YDQsNC60YLQuNC60Lgg0YDQvtGB0YHQuNC50YHQutC40YUg0Lgg 0LfQsNC/0LDQtNC90YvRhQ0K0LrQvtC80L/QsNC90LjQuSwNCiAqINGD0LfQvdCw0YLRjCDQsNC7 0LPQvtGA0LjRgtC8INGA0LDQt9GA0LDQsdC+0YLQutC4INGB0LHQsNC70LDQvdGB0LjRgNC+0LLQ sNC90L3QvtC5INGB0LjRgdGC0LXQvNGLINC/0L7QutCw0LfQsNGC0LXQu9C10LkgKNCh0KHQnyks DQogKiDQvtGC0YDQsNCx0L7RgtCw0YLRjCDQvdCw0LLRi9C6INC40L3RgtC10LPRgNCw0YbQuNC4 INGB0YLRgNCw0YLQtdCz0LjRh9C10YHQutC40YUg0YbQtdC70LXQuSDQuCDQv9C+0LrQsNC30LDR gtC10LvQtdC5DQrRgNC10LfRg9C70YzRgtCw0YLQuNCy0L3QvtGB0YLQuCwNCiAqINC/0L7Qu9GD 0YfQuNGC0Ywg0L/RgNCw0LrRgtC40YfQtdGB0LrQuNC1INC40L3RgdGC0YDRg9C80LXQvdGC0Ysg 0LTQtdC60L7QvNC/0L7Qt9C40YbQuNC4INGG0LXQu9C10Lkg0Lgg0L/QvtC60LDQt9Cw0YLQtdC7 0LXQuSwNCiAqINC+0YHQstC+0LjRgtGMINC80LXRhdCw0L3QuNC30Lwg0L/RgNC40LLRj9C30LrQ uCDQv9GA0LXQvNC40Lgg0Log0LLRi9C/0L7Qu9C90LXQvdC40Y4g0YbQtdC70LXQuSwNCiAqINGD 0LfQvdCw0YLRjCDQv9GA0LDQutGC0LjRh9C10YHQutC40LUg0L/QvtC00YXQvtC00Ysg0Log0LLQ vdC10LTRgNC10L3QuNGOINGB0LjRgdGC0LXQvNGLINGD0L/RgNCw0LLQu9C10L3QuNGPINC/0L4N CtGA0LXQt9GD0LvRjNGC0LDRgtCw0Lwg0L3QsCDQvtGB0L3QvtCy0LUNCiAgINCh0KHQny4NCg0K ICAgICAgICAq0J7Qv9C40YHQsNC90LjQtSDQv9GA0L7Qs9GA0LDQvNC80Ys6Kg0KKjEuINCg0LDQ t9GA0LDQsdC+0YLQutCwINGB0LHQsNC70LDQvdGB0LjRgNC+0LLQsNC90L3QvtC5INGB0LjRgdGC 0LXQvNGLINC/0L7QutCw0LfQsNGC0LXQu9C10LkgKEJTQyk6Kg0KLdCY0YHRgtC+0YDQuNGPINC4 INC/0YDQuNC90YbQuNC/0Ysg0YDQsNCx0L7RgtGLIEJTQy4NCi3QodGG0LXQvdCw0YDQuNC5INGB 0YLRgNCw0YLQtdCz0LjRh9C10YHQutC+0Lkg0YHQtdGB0YHQuNC4INC/0L4g0YDQsNC30YDQsNCx 0L7RgtC60LUgQlNDLg0KLdCQ0LvQs9C+0YDQuNGC0Lwg0YHQvtC30LTQsNC90LjRjyDRgdGC0YDQ sNGC0LXQs9C40YfQtdGB0LrQvtC5INC60LDRgNGC0YsuDQot0J/RgNC40LzQtdGA0YsgQlNDINC0 0LvRjyDRgNCw0LfQu9C40YfQvdGL0YUg0L7RgtGA0LDRgdC70LXQuSDQuCDRhNGD0L3QutGG0LjQ vtC90LDQu9GM0L3Ri9GFINC/0L7QtNGA0LDQt9C00LXQu9C10L3QuNC5Lg0KKjIuINCU0LXQutC+ 0LzQv9C+0LfQuNGG0LjRjyDRgdGC0YDQsNGC0LXQs9C40YfQtdGB0LrQuNGFINGG0LXQu9C10Lkg 0L7RgNCz0LDQvdC40LfQsNGG0LjQuDoqDQot0J7RgdC90L7QstGLINGG0LXQu9C10LLQvtCz0L4g 0YPQv9GA0LDQstC70LXQvdC40Y8gKE1CTykuDQot0JTQtdGA0LXQstC+INGG0LXQu9C10Lkg0LrQ vtC80L/QsNC90LjQuC4NCi3Ql9Cw0LrRgNC10L/Qu9C10L3QuNC1INGG0LXQu9C10Lkg0LfQsCDR hNGD0L3QutGG0LjRj9C80Lgg0Lgg0LjRgdC/0L7Qu9C90LjRgtC10LvRj9C80LgsINC80LDRgtGA 0LjRhtCwINGG0LXQu9C10LkuDQot0J/RgNC40L3RhtC40L/RiyDQtNC10LrQvtC80L/QvtC30LjR htC40Lgg0YbQtdC70LXQuS4NCi3QoNCw0LfRgNCw0LHQvtGC0LrQsCDQvNC10YDQvtC/0YDQuNGP 0YLQuNC5INC/0L4g0LTQvtGB0YLQuNC20LXQvdC40Y4g0YbQtdC70LXQuSDQuCDQv9C70LDQvdCw INC00LXQudGB0YLQstC40LkuDQoqMy4g0J/QvtGB0YLQsNC90L7QstC60LAg0LrQu9GO0YfQtdCy 0YvRhSDQv9C+0LrQsNC30LDRgtC10LvQtdC5INGN0YTRhNC10LrRgtC40LLQvdC+0YHRgtC4IChL UEkpOioNCi3QotC10YXQvdC+0LvQvtCz0LjRjyDQstGL0LHQvtGA0LAg0L/QvtC60LDQt9Cw0YLQ tdC70LXQuSDQuCDRg9GB0YLQsNC90L7QstC70LXQvdC40LUg0LLQtdGB0L7QsiBLUEkuDQot0KDQ sNC30YDQsNCx0L7RgtC60LAg0LrQsNGA0YLRiyBLUEkuDQot0KPRgNC+0LLQvdC4INC00L7RgdGC 0LjQttC10L3QuNGPIEtQSS4NCi3Qn9GA0LjQvNC10YDRiyDQutCw0YDRgiDQv9C+0LrQsNC30LDR gtC10LvQtdC5INC00LvRjyDRgNCw0LfQu9C40YfQvdGL0YUg0L/QvtC00YDQsNC30LTQtdC70LXQ vdC40Lkg0Lgg0LTQvtC70LbQvdC+0YHRgtC10LkuDQot0J/RgNC40LHQvtGA0L3Ri9C1INC/0LDQ vdC10LvQuCDQtNC70Y8g0LzQvtC90LjRgtC+0YDQuNC90LPQsCDQv9C+0LrQsNC30LDRgtC10LvQ tdC5IChkYXNoYm9hcmRzKS4NCio0LiDQn9GA0LXQvNC40YDQvtCy0LDQvdC40LUg0L3QsCDQvtGB 0L3QvtCy0LUgS1BJOioNCi3QktGL0LHQvtGAINC/0LXRgNC40L7QtNC40YfQvdC+0YHRgtC4INC/ 0YDQtdC80LjRgNC+0LLQsNC90LjRjy4NCi3Qn9GA0LjQvNC10YDRiyDQv9GA0LXQvNC40LDQu9GM 0L3Ri9GFINC/0LvQsNC90L7QsiDQvdCwINC+0YHQvdC+0LLQtSBLUEkuDQot0KDQsNGB0YfQtdGC INC4INC/0LvQsNC90LjRgNC+0LLQsNC90LjQtSDRhNC+0L3QtNCwINC/0YDQtdC80LjRgNC+0LLQ sNC90LjRjy4NCi3Qn9GA0LjQstGP0LfQutCwINC/0YDQtdC80LjQuCDQuiBLUEk6INGD0YDQvtCy 0L3QuCDQuCDRgNC10LrQvtC80LXQvdC00YPQtdC80YvQuSDQv9GA0L7RhtC10L3RgiDQv9GA0LXQ vNC40LgsINGF0LDRgNCw0LrRgtC10YANCtC30LDQstC40YHQuNC80L7RgdGC0LgNCiAg0L/RgNC1 0LzQuNC4INC+0YIg0L/QvtC60LDQt9Cw0YLQtdC70Y8uDQoqNS4g0KDQtdC60L7QvNC10L3QtNCw 0YbQuNC4INC/0L4g0LLQvdC10LTRgNC10L3QuNGOLioNCi3Qn9C+0LTQstC+0LTQvdGL0LUg0LrQ sNC80L3QuCDQv9GA0Lgg0LLQvdC10LTRgNC10L3QuNC4INGB0LjRgdGC0LXQvNGLINGD0L/RgNCw 0LLQu9C10L3QuNGPINGN0YTRhNC10LrRgtC40LLQvdC+0YHRgtGM0Y4uDQot0JvRg9GH0YjQuNC1 INC/0YDQsNC60YLQuNC60Lgg0LLQvdC10LTRgNC10L3QuNGPLg0KLdCS0L3Rg9GC0YDQtdC90L3Q uNC1INC60L7QvNC80YPQvdC40LrQsNGG0LjQuCDRgSDRgdC+0YLRgNGD0LTQvdC40LrQsNC80Lgu DQoNCg0K0KPRh9Cw0YHRgtC40LU6IDIyIDjQvtC+INGA0YPQsdC70LXQuS4NCtCh0Lp10LTQunUg KNC+0YIgMi3RhSDRh9C10LvQvtCy0LXQuiDigJMgMTAlLCDQvtGCIDMt0YUg0Lgg0LHQvtC70LXQ tSDigJMgMTUlKS4NCtCS0YXQvtC00LjRgiDQvNC10YLQvtC00LjRh9C10YHQutC40Lkg0LzQsNGC 0LXRgNC40LDQuywg0L7QsdC10LTRiywg0LrQvtGE0LUt0L/QsNGD0LfRiy4NCtCf0L4g0L7QutC+ 0L3Rh9Cw0L3QuNGOINC30LDQvdGP0YLQuNC5INCS0LDQvCDQv9GA0LXQtNC+0YHRgtCw0LLQu9GP 0LXRgtGB0Y8g0YHQtdGA0YLQuNGE0LjQutCw0YIuDQo= ------------716D51D3798C78C9 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: base64 PGRpdiBkaXI9Imx0ciI+PGRpdiBhbGlnbj0iY2VudGVyIj48dGFibGUgYmdjb2xvcj0iI2Y0ZTNk YiIgYm9yZGVyPSIwIiBjZWxsc3BhY2luZz0iMCI+PHRib2R5Pjx0cj48dGQgYmdjb2xvcj0iIzY2 MDA2NiI+wqA8L3RkPjx0ZCBiZ2NvbG9yPSIjNjYwMDY2Ij7CoDwvdGQ+PHRkIGJnY29sb3I9IiM2 NjAwNjYiPsKgPC90ZD48dGQgYmdjb2xvcj0iIzY2MDA2NiI+wqA8L3RkPjx0ZCBiZ2NvbG9yPSIj NjYwMDY2Ij7CoDwvdGQ+PC90cj48dHI+PHRkIGJnY29sb3I9IiM2NjAwNjYiPsKgPC90ZD48dGQg Ymdjb2xvcj0iI2ZkZjlmNyI+wqA8L3RkPjx0ZCBiZ2NvbG9yPSIjZmRmOWY3Ij48cCBhbGlnbj0i Y2VudGVyIj7Qo9GH0LXQsdC90YvQuSDRhtC10L3RgtGAINC/0YDQuNCz0LvQsNGI0LDQtdGCINC9 0LAg0L7QsdGD0YfQtdC90LjQtSAoPGI+0L/RgNC+0LzQvtC60L7QtDoyNjI8L2I+KSAJCQkg0L/Q viDRgtC10LzQtTo8YnI+PGJyPjxmb250IGNvbG9yPSIjMDAwMGZmIj48Yj48Zm9udCBzaXplPSI1 Ij7QoNCw0LfRgNCw0LHQvtGC0LrQsCDQuCDQstC90LXQtNGA0LXQvdC40LUgCQkJ0L/QvtC60LDQ t9Cw0YLQtdC70LXQuSBLUEksINCc0JLQniDQuCBCU0MuIDwvZm9udD48L2I+PGJyPjwvZm9udD48 YnI+PGZvbnQgY29sb3I9IiNjYzAwNjYiPjxiPtCU0LvRjzo8L2I+PC9mb250PiDRgNGD0LrQvtCy 0L7QtNC40YLQtdC70LXQuSDQuCAJCQnRgdC/0LXRhtC40LDQu9C40YHRgtC+0LIsINC+0YLQstC1 0YfQsNGO0YnQuNGFINC30LAg0L7RgNCz0LDQvdC40LfQsNGG0LjQvtC90L3QvtC1INGA0LDQt9Cy 0LjRgtC40LUsPGJyPtGA0YPQutC+0LLQvtC00LjRgtC10LvQtdC5INC4INGB0L/QtdGG0LjQsNC7 0LjRgdGC0L7QsiDQsiDQvtCx0LvQsNGB0YLQuCDRg9C/0YDQsNCy0LvQtdC90LjRjyDQv9C10YDR gdC+0L3QsNC70L7QvCwgCQkJINGA0YPQutC+0LLQvtC00LjRgtC10LvQtdC5PGJyPgkJCdC60L7Q vNC/0LDQvdC40Lkg0Lgg0YHQvtCx0YHRgtCy0LXQvdC90LjQutC+0LIg0LHQuNC30L3QtdGB0LAu PGJyPiDCoDwvcD48cCBhbGlnbj0iY2VudGVyIj48YnI+PGI+PGZvbnQgY29sb3I9IiNjYzAwNjYi IHNpemU9IjQiPjE3IDxzcGFuIGxhbmc9ImVuLXVzIj5+PC9zcGFuPiAxOCAJCQkg0LTQtdC60LDQ sdGA0Y8gPGJyPjwvZm9udD7Qs9C+0YDQvtC0INCc0L7RgdC60LLQsDxicj48L2I+PGJyPgkJCdCX 0LDQvdGP0YLQuNGPINC/0YDQvtCy0L7QtNGP0YLRgdGPINGBIDEwPHNwYW4gbGFuZz0iZW4tdXMi Pjo8L3NwYW4+MDAg0LTQviAxNzxzcGFuIGxhbmc9ImVuLXVzIj46PC9zcGFuPjMwPGJyPjxicj7Q nNC10YDQvtC/0YDQuNGP0YLQuNC1INGB0L7RgdGC0L7QuNGC0YHRjzog0LwuINCR0LDRg9C80LDQ vdGB0LrQsNGPLCDRg9C7LiDQkdCw0YPQvNCw0L3RgdC60LDRjywg0LQuNiwg0JEu0KYuIAkJCSZx dW90O9CS0LjQutGC0L7RgNC40Y8g0J/Qu9Cw0LfQsCZxdW90Oy48YnI+PGJyPtCj0LfQvdCw0YLR jCDQstGB0Y4g0L/QvtC00YDQvtCx0L3Rg9GOINC40L3RhNC+0YDQvNCw0YbQuNGOINC4INC/0L7Q tNCw0YLRjCDQt9Cw0Y/QstC60YMg0L3QsCDRg9GH0LDRgdGC0LjQtSDQsiAJCQnQvtCx0YPRh9C1 0L3QuNC4INC80L7QttC90L4g0L/QviDRgtC10LsuOjxicj48YnI+PGZvbnQgc2l6ZT0iNCI+ODwv Zm9udD4gwqA8Zm9udCBzaXplPSIyIj7QutC+0LQg0LPQvtGA0L7QtNCwPC9mb250PsKgIAkJCTxm b250IHNpemU9IjQiPiggNCA5IDUgKTwvZm9udD7CoCA8Zm9udCBzaXplPSIyIj7QvdC+0LzQtdGA PC9mb250PsKgIDxmb250IHNpemU9IjQiPjcgMiA1wqAgLcKgIAkJCTAgNMKgIC3CoCA0IDg8L2Zv bnQ+wqAgPGZvbnQgc2l6ZT0iMiI+KNC80L3QvtCz0L7QutCw0L3QsNC70YzQvdGL0LkpPC9mb250 Pjxicj4gwqA8L3A+PC90ZD48dGQgYmdjb2xvcj0iI2ZkZjlmNyI+wqA8L3RkPjx0ZCBiZ2NvbG9y PSIjNjYwMDY2Ij7CoDwvdGQ+PC90cj48dHI+PHRkIGJnY29sb3I9IiM2NjAwNjYiPsKgPC90ZD48 dGQgYmdjb2xvcj0iI2Y4ZjdmNSI+wqA8L3RkPjx0ZCBiZ2NvbG9yPSIjZjhmN2Y1Ij48YnI+PGZv bnQgY29sb3I9IiMwMDAwY2MiPjxiPtCU0LDQvdC90L7QtSDQvtCx0YPRh9C10L3QuNC1INC/0L7Q t9Cy0L7Qu9GP0LXRgjogPC9iPjwvZm9udD48YnI+PHNwYW4gbGFuZz0iZW4tdXMiPsKgKiA8L3Nw YW4+0L/QvtC70YPRh9C40YLRjCDQs9C+0YLQvtCy0YvQtSDQvdCw0YDQsNCx0L7RgtC60Lgg0Lgg CQkJ0YDQtdGI0LXQvdC40Y8g0LjQtyDQv9GA0LDQutGC0LjQutC4INGA0L7RgdGB0LjQudGB0LrQ uNGFINC4INC30LDQv9Cw0LTQvdGL0YUg0LrQvtC80L/QsNC90LjQuSwgPGJyPjxzcGFuIGxhbmc9 ImVuLXVzIj7CoCogPC9zcGFuPtGD0LfQvdCw0YLRjCDQsNC70LPQvtGA0LjRgtC8INGA0LDQt9GA 0LDQsdC+0YLQutC4IAkJCdGB0LHQsNC70LDQvdGB0LjRgNC+0LLQsNC90L3QvtC5INGB0LjRgdGC 0LXQvNGLINC/0L7QutCw0LfQsNGC0LXQu9C10LkgKNCh0KHQnyksPGJyPjxzcGFuIGxhbmc9ImVu LXVzIj7CoCogPC9zcGFuPtC+0YLRgNCw0LHQvtGC0LDRgtGMINC90LDQstGL0Log0LjQvdGC0LXQ s9GA0LDRhtC40LggCQkJ0YHRgtGA0LDRgtC10LPQuNGH0LXRgdC60LjRhSDRhtC10LvQtdC5INC4 INC/0L7QutCw0LfQsNGC0LXQu9C10Lkg0YDQtdC30YPQu9GM0YLQsNGC0LjQstC90L7RgdGC0Lgs PGJyPjxzcGFuIGxhbmc9ImVuLXVzIj7CoCogPC9zcGFuPtC/0L7Qu9GD0YfQuNGC0Ywg0L/RgNCw 0LrRgtC40YfQtdGB0LrQuNC1INC40L3RgdGC0YDRg9C80LXQvdGC0YsgCQkJ0LTQtdC60L7QvNC/ 0L7Qt9C40YbQuNC4INGG0LXQu9C10Lkg0Lgg0L/QvtC60LDQt9Cw0YLQtdC70LXQuSw8YnI+PHNw YW4gbGFuZz0iZW4tdXMiPsKgKiA8L3NwYW4+0L7RgdCy0L7QuNGC0Ywg0LzQtdGF0LDQvdC40LfQ vCDQv9GA0LjQstGP0LfQutC4INC/0YDQtdC80LjQuCDQuiAJCQnQstGL0L/QvtC70L3QtdC90LjR jiDRhtC10LvQtdC5LDxicj48c3BhbiBsYW5nPSJlbi11cyI+wqAqIDwvc3Bhbj7Rg9C30L3QsNGC 0Ywg0L/RgNCw0LrRgtC40YfQtdGB0LrQuNC1INC/0L7QtNGF0L7QtNGLINC6IAkJCdCy0L3QtdC0 0YDQtdC90LjRjiDRgdC40YHRgtC10LzRiyDRg9C/0YDQsNCy0LvQtdC90LjRjyDQv9C+INGA0LXQ t9GD0LvRjNGC0LDRgtCw0Lwg0L3QsCDQvtGB0L3QvtCy0LU8YnI+PHNwYW4gbGFuZz0iZW4tdXMi PsKgwqAgPC9zcGFuPtCh0KHQny48YnI+PGJyPjxzcGFuIGxhbmc9ImVuLXVzIj7CoMKgwqDCoMKg wqAJCQkgPGZvbnQgY29sb3I9IiMwMDAwY2MiPsKgPC9mb250Pjwvc3Bhbj48Zm9udCBjb2xvcj0i IzAwMDBjYyI+PGI+PGZvbnQgc2l6ZT0iNCI+0J7Qv9C40YHQsNC90LjQtSAJCQnQv9GA0L7Qs9GA 0LDQvNC80Ys6PC9mb250PjwvYj48L2ZvbnQ+PGJyPjxiPjxmb250IHNpemU9IjUiPjEuIDwvZm9u dD7QoNCw0LfRgNCw0LHQvtGC0LrQsCDRgdCx0LDQu9Cw0L3RgdC40YDQvtCy0LDQvdC90L7QuSDR gdC40YHRgtC10LzRiyAJCQnQv9C+0LrQsNC30LDRgtC10LvQtdC5IChCU0MpOjwvYj48YnI+LdCY 0YHRgtC+0YDQuNGPINC4INC/0YDQuNC90YbQuNC/0Ysg0YDQsNCx0L7RgtGLIEJTQy48YnI+LdCh 0YbQtdC90LDRgNC40Lkg0YHRgtGA0LDRgtC10LPQuNGH0LXRgdC60L7QuSDRgdC10YHRgdC40Lgg 0L/QviDRgNCw0LfRgNCw0LHQvtGC0LrQtSBCU0MuPGJyPi3QkNC70LPQvtGA0LjRgtC8INGB0L7Q t9C00LDQvdC40Y8g0YHRgtGA0LDRgtC10LPQuNGH0LXRgdC60L7QuSDQutCw0YDRgtGLLjxicj4t 0J/RgNC40LzQtdGA0YsgQlNDINC00LvRjyDRgNCw0LfQu9C40YfQvdGL0YUg0L7RgtGA0LDRgdC7 0LXQuSDQuCDRhNGD0L3QutGG0LjQvtC90LDQu9GM0L3Ri9GFINC/0L7QtNGA0LDQt9C00LXQu9C1 0L3QuNC5Ljxicj48Yj48Zm9udCBzaXplPSI1Ij4yLiA8L2ZvbnQ+0JTQtdC60L7QvNC/0L7Qt9C4 0YbQuNGPINGB0YLRgNCw0YLQtdCz0LjRh9C10YHQutC40YUg0YbQtdC70LXQuSAJCQnQvtGA0LPQ sNC90LjQt9Cw0YbQuNC4OjwvYj48YnI+LdCe0YHQvdC+0LLRiyDRhtC10LvQtdCy0L7Qs9C+INGD 0L/RgNCw0LLQu9C10L3QuNGPIChNQk8pLjxicj4t0JTQtdGA0LXQstC+INGG0LXQu9C10Lkg0LrQ vtC80L/QsNC90LjQuC48YnI+LdCX0LDQutGA0LXQv9C70LXQvdC40LUg0YbQtdC70LXQuSDQt9Cw INGE0YPQvdC60YbQuNGP0LzQuCDQuCDQuNGB0L/QvtC70L3QuNGC0LXQu9GP0LzQuCwg0LzQsNGC 0YDQuNGG0LAg0YbQtdC70LXQuS48YnI+LdCf0YDQuNC90YbQuNC/0Ysg0LTQtdC60L7QvNC/0L7Q t9C40YbQuNC4INGG0LXQu9C10LkuPGJyPi3QoNCw0LfRgNCw0LHQvtGC0LrQsCDQvNC10YDQvtC/ 0YDQuNGP0YLQuNC5INC/0L4g0LTQvtGB0YLQuNC20LXQvdC40Y4g0YbQtdC70LXQuSDQuCDQv9C7 0LDQvdCwINC00LXQudGB0YLQstC40LkuPGJyPjxiPjxmb250IHNpemU9IjUiPjMuIDwvZm9udD7Q n9C+0YHRgtCw0L3QvtCy0LrQsCDQutC70Y7Rh9C10LLRi9GFINC/0L7QutCw0LfQsNGC0LXQu9C1 0LkgCQkJ0Y3RhNGE0LXQutGC0LjQstC90L7RgdGC0LggKEtQSSk6PC9iPjxicj4t0KLQtdGF0L3Q vtC70L7Qs9C40Y8g0LLRi9Cx0L7RgNCwINC/0L7QutCw0LfQsNGC0LXQu9C10Lkg0Lgg0YPRgdGC 0LDQvdC+0LLQu9C10L3QuNC1INCy0LXRgdC+0LIgS1BJLjxicj4t0KDQsNC30YDQsNCx0L7RgtC6 0LAg0LrQsNGA0YLRiyBLUEkuPGJyPi3Qo9GA0L7QstC90Lgg0LTQvtGB0YLQuNC20LXQvdC40Y8g S1BJLjxicj4t0J/RgNC40LzQtdGA0Ysg0LrQsNGA0YIg0L/QvtC60LDQt9Cw0YLQtdC70LXQuSDQ tNC70Y8g0YDQsNC30LvQuNGH0L3Ri9GFINC/0L7QtNGA0LDQt9C00LXQu9C10L3QuNC5INC4INC0 0L7Qu9C20L3QvtGB0YLQtdC5Ljxicj4t0J/RgNC40LHQvtGA0L3Ri9C1INC/0LDQvdC10LvQuCDQ tNC70Y8g0LzQvtC90LjRgtC+0YDQuNC90LPQsCDQv9C+0LrQsNC30LDRgtC10LvQtdC5IChkYXNo Ym9hcmRzKS48YnI+PGI+PGZvbnQgc2l6ZT0iNSI+NC4gPC9mb250PtCf0YDQtdC80LjRgNC+0LLQ sNC90LjQtSDQvdCwINC+0YHQvdC+0LLQtSBLUEk6PC9iPjxicj4t0JLRi9Cx0L7RgCDQv9C10YDQ uNC+0LTQuNGH0L3QvtGB0YLQuCDQv9GA0LXQvNC40YDQvtCy0LDQvdC40Y8uPGJyPi3Qn9GA0LjQ vNC10YDRiyDQv9GA0LXQvNC40LDQu9GM0L3Ri9GFINC/0LvQsNC90L7QsiDQvdCwINC+0YHQvdC+ 0LLQtSBLUEkuPGJyPi3QoNCw0YHRh9C10YIg0Lgg0L/Qu9Cw0L3QuNGA0L7QstCw0L3QuNC1INGE 0L7QvdC00LAg0L/RgNC10LzQuNGA0L7QstCw0L3QuNGPLjxicj4t0J/RgNC40LLRj9C30LrQsCDQ v9GA0LXQvNC40Lgg0LogS1BJOiDRg9GA0L7QstC90Lgg0Lgg0YDQtdC60L7QvNC10L3QtNGD0LXQ vNGL0Lkg0L/RgNC+0YbQtdC90YIg0L/RgNC10LzQuNC4LCAJCQkg0YXQsNGA0LDQutGC0LXRgCDQ t9Cw0LLQuNGB0LjQvNC+0YHRgtC4PGJyPjxzcGFuIGxhbmc9ImVuLXVzIj7CoCA8L3NwYW4+0L/R gNC10LzQuNC4INC+0YIg0L/QvtC60LDQt9Cw0YLQtdC70Y8uPGJyPjxiPjxmb250IHNpemU9IjUi PjUuIDwvZm9udD7QoNC10LrQvtC80LXQvdC00LDRhtC40Lgg0L/QviDQstC90LXQtNGA0LXQvdC4 0Y4uPC9iPjxicj4t0J/QvtC00LLQvtC00L3Ri9C1INC60LDQvNC90Lgg0L/RgNC4INCy0L3QtdC0 0YDQtdC90LjQuCDRgdC40YHRgtC10LzRiyDRg9C/0YDQsNCy0LvQtdC90LjRjyDRjdGE0YTQtdC6 0YLQuNCy0L3QvtGB0YLRjNGOLjxicj4t0JvRg9GH0YjQuNC1INC/0YDQsNC60YLQuNC60Lgg0LLQ vdC10LTRgNC10L3QuNGPLjxicj4t0JLQvdGD0YLRgNC10L3QvdC40LUg0LrQvtC80LzRg9C90LjQ utCw0YbQuNC4INGBINGB0L7RgtGA0YPQtNC90LjQutCw0LzQuC48YnI+PGJyPjxicj48Zm9udCBm YWNlPSJ2ZXJkYW5hLCBzYW5zLXNlcmlmIj7Qo9GH0LDRgdGC0LjQtTogMjIgONC+0L4g0YDRg9Cx 0LvQtdC5Ljxicj7QodC6PHNwYW4gbGFuZz0iZW4tdXMiPnU8L3NwYW4+0LTQujxzcGFuIGxhbmc9 ImVuLXVzIj51PC9zcGFuPiAo0L7RgiAyPHNwYW4gbGFuZz0iZW4tdXMiPi08L3NwYW4+0YUgCQkJ 0YfQtdC70L7QstC10Log4oCTIDEwJSwg0L7RgiAzLdGFINC4INCx0L7Qu9C10LUg4oCTIDE1JSku PGJyPtCS0YXQvtC00LjRgiDQvNC10YLQvtC00LjRh9C10YHQutC40Lkg0LzQsNGC0LXRgNC40LDQ uywg0L7QsdC10LTRiywg0LrQvtGE0LUt0L/QsNGD0LfRiy48YnI+0J/QviDQvtC60L7QvdGH0LDQ vdC40Y4g0LfQsNC90Y/RgtC40Lkg0JLQsNC8INC/0YDQtdC00L7RgdGC0LDQstC70Y/QtdGC0YHR jyDRgdC10YDRgtC40YTQuNC60LDRgi48L2ZvbnQ+PGJyPiDCoDwvdGQ+PHRkIGJnY29sb3I9IiNm OGY3ZjUiPsKgPC90ZD48dGQgYmdjb2xvcj0iIzY2MDA2NiI+wqA8L3RkPjwvdHI+PHRyPjx0ZCBi Z2NvbG9yPSIjNjYwMDY2Ij7CoDwvdGQ+PHRkIGJnY29sb3I9IiM2NjAwNjYiPsKgPC90ZD48dGQg Ymdjb2xvcj0iIzY2MDA2NiI+wqA8L3RkPjx0ZCBiZ2NvbG9yPSIjNjYwMDY2Ij7CoDwvdGQ+PHRk IGJnY29sb3I9IiM2NjAwNjYiPsKgPC90ZD48L3RyPjwvdGJvZHk+PC90YWJsZT48L2Rpdj48L2Rp dj4NCg== ------------716D51D3798C78C9-- From bfoster@redhat.com Mon Nov 30 08:10:13 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 8CED57F37 for ; Mon, 30 Nov 2015 08:10:13 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 6CE03304051 for ; Mon, 30 Nov 2015 06:10:10 -0800 (PST) X-ASG-Debug-ID: 1448892602-04cb6c535362810001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id Gcchz8tHNC5lDCwO (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 30 Nov 2015 06:10:03 -0800 (PST) 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 (Postfix) with ESMTPS id CBC2A8F27E; Mon, 30 Nov 2015 14:10:02 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-132.bos.redhat.com [10.18.41.132]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAUEA1Yv005127; Mon, 30 Nov 2015 09:10:01 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id 1FCC512013B; Mon, 30 Nov 2015 09:10:01 -0500 (EST) Date: Mon, 30 Nov 2015 09:10:01 -0500 From: Brian Foster To: Glauber Costa Cc: xfs@oss.sgi.com, Avi Kivity , david@fromorbit.com Subject: Re: sleeps and waits during io_submit Message-ID: <20151130141000.GC24765@bfoster.bfoster> X-ASG-Orig-Subj: Re: sleeps and waits during io_submit References: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable In-Reply-To: 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: 1448892603 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Fri, Nov 27, 2015 at 09:43:50PM -0500, Glauber Costa wrote: > Hello my dear XFSers, >=20 > For those of you who don't know, we at ScyllaDB produce a modern NoSQL > data store that, at the moment, runs on top of XFS only. We deal > exclusively with asynchronous and direct IO, due to our > thread-per-core architecture. Due to that, we avoid issuing any > operation that will sleep. >=20 > While debugging an extreme case of bad performance (most likely > related to a not-so-great disk), I have found a variety of cases in > which XFS blocks. To find those, I have used perf record -e > sched:sched_switch -p , and I am attaching the perf report > as xfs-sched_switch.log. Please note that this doesn't tell me for how > long we block, but as mentioned before, blocking operations outside > our control are detrimental to us regardless of the elapsed time. >=20 > For those who are not acquainted to our internals, please ignore > everything in that file but the xfs functions. For the xfs symbols, > there are two kinds of events: the ones that are a children of > io_submit, where we don't tolerate blocking, and the ones that are > children of our helper IO thread, to where we push big operations that > we know will block until we can get rid of them all. We care about the > former and ignore the latter. >=20 > Please allow me to ask you a couple of questions about those findings. > If we are doing anything wrong, advise on best practices is truly > welcome. >=20 > 1) xfs_buf_lock -> xfs_log_force. >=20 > I've started wondering what would make xfs_log_force sleep. But then I > have noticed that xfs_log_force will only be called when a buffer is > marked stale. Most of the times a buffer is marked stale seems to be > due to errors. Although that is not my case (more on that), it got me > thinking that maybe the right thing to do would be to avoid hitting > this case altogether? >=20 I'm not following where you get the "only if marked stale" part..? It certainly looks like that's one potential purpose for the call, but this is called in a variety of other places as well. E.g., forcing the log via pushing on the ail when it has pinned items is another case. The ail push itself can originate from transaction reservation, etc., when log space is needed. In other words, I'm not sure this is something that's easily controlled from userspace, if at all. Rather, it's a significant part of the wider state machine the fs uses to manage logging. > The file example-stale.txt contains a backtrace of the case where we > are being marked as stale. It seems to be happening when we convert > the the inode's extents from unwritten to real. Can this case be > avoided? I won't pretend I know the intricacies of this, but couldn't > we be keeping extents from the very beginning to avoid creating stale > buffers? >=20 This is down in xfs_fs_evict_inode()->xfs_inactive(), which is generally when an inode is evicted from cache. In this case, it looks like the inode is unlinked (permanently removed), the extents are being removed and a bmap btree block is being invalidated as part of that overall process. I don't think this has anything to do with unwritten extents. > 2) xfs_buf_lock -> down > This is one I truly don't understand. What can be causing contention > in this lock? We never have two different cores writing to the same > buffer, nor should we have the same core doingCAP_FOWNER so. >=20 This is not one single lock. An XFS buffer is the data structure used to modify/log/read-write metadata on-disk and each buffer has its own lock to prevent corruption. Buffer lock contention is possible because the filesystem has bits of "global" metadata that has to be updated via buffers. For example, usually one has multiple allocation groups to maximize parallelism, but we still have per-ag metadata that has to be tracked globally with respect to each AG (e.g., free space trees, inode allocation trees, etc.). Any operation that affects this metadata (e.g., block/inode allocation) has to lock the agi/agf buffers along with any buffers associated with the modified btree leaf/node blocks, etc. One example in your attached perf traces has several threads looking to acquire the AGF, which is a per-AG data structure for tracking free space in the AG. One thread looks like the inode eviction case noted above (freeing blocks), another looks like a file truncate (also freeing blocks), and yet another is a block allocation due to a direct I/O write. Were any of these operations directed to an inode in a separate AG, they would be able to proceed in parallel (but I believe they would still hit the same codepaths as far as perf can tell). > 3) xfs_file_aio_write_checks -> file_update_time -> xfs_vn_update_time >=20 > You guys seem to have an interface to avoid that, by setting the > FMODE_NOCMTIME flag. This is done by issuing the open by handle ioctl, > which will set this flag for all regular files. That's great, but that > ioctl required CAP_SYS_ADMIN, which is a big no for us, since we run > our server as an unprivileged user. I don't understand, however, why > such an strict check is needed. If we have full rights on the > filesystem, why can't we issue this operation? In my view, CAP_FOWNER > should already be enough.I do understand the handles have to be stable > and a file can have its ownership changed, in which case the previous > owner would keep the handle valid. Is that the reason you went with > the most restrictive capability ? I'm not familiar enough with the open-by-handle stuff to comment on the permission constraints. Perhaps Dave or others can comment further on this bit... Brian > # To display the perf.data header info, please use --header/--header-only= options. > # > # > # Total Lost Samples: 0 > # > # Samples: 2K of event 'sched:sched_switch' > # Event count (approx.): 2669 > # > # Overhead Command Shared Object Symbol =20 > # ........ ....... ................. .............. > # > 100.00% scylla [kernel.kallsyms] [k] __schedule > | > ---__schedule > | =20 > |--96.18%-- schedule > | | =20 > | |--56.14%-- schedule_user > | | | =20 > | | |--53.30%-- int_careful > | | | | =20 > | | | |--45.05%-- 0x7f4ade6f74= ed > | | | | reactor_backe= nd_epoll::make_reactor_notifier > | | | | | =20 > | | | | |--67.63%-- s= yscall_work_queue::submit_item > | | | | | | = =20 > | | | | | |-= -32.05%-- posix_file_impl::truncate > | | | | | | = | =20 > | | | | | | = |--65.33%-- _ZN12continuationIZN6futureIJEE4thenIZN19file_data_sin= k_impl5flushEvEUlvE_S1_EET0_OT_EUlS7_E_JEE3runEv > | | | | | | = | reactor::del_timer > | | | | | | = | 0x60b0000e2040 > | | | | | | = | =20 > | | | | | | = |--20.00%-- db::commitlog::segment::flush(unsigned long)::{lambda(= )#1}::operator() > | | | | | | = | | =20 > | | | | | | = | |--73.33%-- future<>::then > > > | | | | | | = | | _ZN12continuationIZN6futureIJ13lw_shared_ptr= IN2db9commitlog7segmentEEEE4thenIZNS4_4syncEvEUlT_E_S6_EET0_OS8_EUlSB_E_JS5= _EE3runEv > | | | | | | = | | reactor::del_timer > | | | | | | = | | 0x60e0000e2040 > | | | | | | = | | =20 > | | | | | | = | --26.67%-- _ZN12continuationIZN6futureIJEE4thenIZN2db9= commitlog7segment5flushEmEUlvE_S0_IJ13lw_shared_ptrIS5_EEEEET0_OT_EUlSC_E_J= EE3runEv > | | | | | | = | reactor::del_timer > | | | | | | = | 0x6090000e2040 > | | | | | | = | =20 > | | | | | | = |--10.67%-- sstables::sstable::seal_sstable > | | | | | | = | std::_Function_handler, unsigned long)::{lambda()#1}>::type ()>::= type>::type seastar::async, unsigned long)::{lambda()#= 1}>(std::decay&&, (std::decay, unsigned long)::{lambda= ()#1}>::type&&)...)::{lambda(futurize::type ()>::type> seastar::async<{lambda()#1}>(futurize::type ()>::type>::type, std::decay<{lambda()#1}>::ty= pe&&)::work&)#1}::operator()(futurize::type ()>::type> seastar::async<{lambda()#1}>(futurize::type ()>::type>::type, std::decay<{lambda()#1}>::ty= pe&&)::work)::{lambda()#1}>::_M_invoke > | | | | | | = | _GLOBAL__sub_I__ZN12app_templateC2Ev > | | | | | | = | =20 > | | | | | | = --4.00%-- sstables::sstable::write_toc > | | | | | | = sstables::sstable::prepare_write_components > | | | | | | = | =20 > | | | | | | = |--50.00%-- 0x4d3a4f6ec4e8cd75 > | | | | | | = | =20 > | | | | | | = --50.00%-- 0x3ebf3dd80e3b174d > | | | | | | = =20 > | | | | | |-= -23.93%-- posix_file_impl::discard > | | | | | | = | =20 > | | | | | | = |--82.14%-- _ZN12continuationIZN6futureIImEE4thenIZN19file_data_si= nk_impl6do_putEm16temporary_bufferIcEEUlmE_S0_IIEEEET0_OT_EUlSA_E_ImEE3runEv > | | | | | | = | reactor::del_timer > | | | | | | = | 0x6080000e2040 > | | | | | | = | =20 > | | | | | | = --17.86%-- futurize = > >::apply > | | | | | | = _ZN12continuationIZN6futureIJ4fileEE4thenIZN2db9commitl= og15segment_manager16allocate_segmentEbEUlS1_E_S0_IJ13lw_shared_ptrINS5_7se= gmentEEEEEET0_OT_EUlSE_E_JS1_EE3runEv > | | | | | | = =20 > | | | | | |-= -20.94%-- reactor::open_file_dma > | | | | | | = | =20 > | | | | | | = |--20.41%-- db::commitlog::segment_manager::allocate_segment > | | | | | | = | db::commitlog::segment_manager::on_timer()::{lambda()#1= }::operator() > | | | | | | = | 0xb8c264 > | | | | | | = | =20 > | | | | | | = |--14.29%-- sstables::sstable::write_simple<(sstables::sstable::co= mponent_type)8, sstables::statistics> > | | | | | | = | std::_Function_handler, unsigned long)::{lambda()#1}>::type ()>::= type>::type seastar::async, unsigned long)::{lambda()#= 1}>(std::decay&&, (std::decay, unsigned long)::{lambda= ()#1}>::type&&)...)::{lambda(futurize::type ()>::type> seastar::async<{lambda()#1}>(futurize::type ()>::type>::type, std::decay<{lambda()#1}>::ty= pe&&)::work&)#1}::operator()(futurize::type ()>::type> seastar::async<{lambda()#1}>(futurize::type ()>::type>::type, std::decay<{lambda()#1}>::ty= pe&&)::work)::{lambda()#1}>::_M_invoke > | | | | | | = | _GLOBAL__sub_I__ZN12app_templateC2Ev > | | | | | | = | =20 > | | | | | | = |--12.24%-- sstables::write_crc > | | | | | | = | | =20 > | | | | | | = | |--16.67%-- 0x313532343536002f > | | | | | | = | | =20 > | | | | | | = | |--16.67%-- 0x373633323533002f > | | | | | | = | | =20 > | | | | | | = | |--16.67%-- 0x363139333232002f > | | | | | | = | | =20 > | | | | | | = | |--16.67%-- 0x353933303330002f > | | | | | | = | | =20 > | | | | | | = | |--16.67%-- 0x383930383133002f > | | | | | | = | | =20 > | | | | | | = | --16.67%-- 0x323338303037002f > | | | | | | = | =20 > | | | | | | = |--12.24%-- sstables::write_digest > | | | | | | = | =20 > | | | | | | = |--10.20%-- sstables::sstable::write_simple<(sstables::sstable::co= mponent_type)7, sstables::filter> > | | | | | | = | sstables::sstable::write_filter > | | | | | | = | std::_Function_handler, unsigned long)::{lambda()#1}>::type ()>::= type>::type seastar::async, unsigned long)::{lambda()#= 1}>(std::decay&&, (std::decay, unsigned long)::{lambda= ()#1}>::type&&)...)::{lambda(futurize::type ()>::type> seastar::async<{lambda()#1}>(futurize::type ()>::type>::type, std::decay<{lambda()#1}>::ty= pe&&)::work&)#1}::operator()(futurize::type ()>::type> seastar::async<{lambda()#1}>(futurize::type ()>::type>::type, std::decay<{lambda()#1}>::ty= pe&&)::work)::{lambda()#1}>::_M_invoke > | | | | | | = | _GLOBAL__sub_I__ZN12app_templateC2Ev > | | | | | | = | =20 > | | | | | | = |--10.20%-- sstables::sstable::write_simple<(sstables::sstable::co= mponent_type)4, sstables::summary_ka> > | | | | | | = | std::_Function_handler, unsigned long)::{lambda()#1}>::type ()>::= type>::type seastar::async, unsigned long)::{lambda()#= 1}>(std::decay&&, (std::decay, unsigned long)::{lambda= ()#1}>::type&&)...)::{lambda(futurize::type ()>::type> seastar::async<{lambda()#1}>(futurize::type ()>::type>::type, std::decay<{lambda()#1}>::ty= pe&&)::work&)#1}::operator()(futurize::type ()>::type> seastar::async<{lambda()#1}>(futurize::type ()>::type>::type, std::decay<{lambda()#1}>::ty= pe&&)::work)::{lambda()#1}>::_M_invoke > | | | | | | = | _GLOBAL__sub_I__ZN12app_templateC2Ev > | | | | | | = | =20 > | | | | | | = |--10.20%-- 0x78d93b > | | | | | | = | =20 > | | | | | | = |--6.12%-- sstables::sstable::open_data > | | | | | | = | | =20 > | | | | | | = | --100.00%-- 0x8000000004000000 > | | | | | | = | =20 > | | | | | | = --4.08%-- sstables::sstable::write_toc > | | | | | | = sstables::sstable::prepare_write_components > | | | | | | = | =20 > | | | | | | = --100.00%-- 0x6100206690ef > | | | | | | = =20 > | | | | | |-= -18.38%-- syscall_work_queue::submit_item > | | | | | | = | =20 > | | | | | | = |--10.00%-- 0x7f4ad89f8fe0 > | | | | | | = | =20 > | | | | | | = |--7.50%-- 0x7f4ad83f8fe0 > | | | | | | = | =20 > | | | | | | = |--7.50%-- 0x7f4ad6bf8fe0 > | | | | | | = | =20 > | | | | | | = |--7.50%-- 0x7f4ad65f8fe0 > | | | | | | = | =20 > | | | | | | = |--5.00%-- 0x60b015e8cd90 > | | | | | | = | =20 > | | | | | | = |--5.00%-- 0x60100acaed90 > | | | | | | = | =20 > | | | | | | = |--5.00%-- 0x607006f04d90 > | | | | | | = | =20 > | | | | | | = |--5.00%-- 0xffffffffffffa5d0 > | | | | | | = | =20 > | | | | | | = |--2.50%-- 0x60e01acbed90 > | | | | | | = | =20 > | | | | | | = |--2.50%-- 0x60e01acbec60 > | | | | | | = | =20 > | | | | | | = |--2.50%-- 0x60a018d7ad90 > | | | | | | = | =20 > | | | | | | = |--2.50%-- 0x60a018d7ac60 > | | | | | | = | =20 > | | | | | | = |--2.50%-- 0x60b015e8cc60 > | | | | | | = | =20 > | | | | | | = |--2.50%-- 0x60900bb8ad60 > | | | | | | = | =20 > | | | | | | = |--2.50%-- 0x60100acaec60 > | | | | | | = | =20 > | | | | | | = |--2.50%-- 0x60800951dd90 > | | | | | | = | =20 > | | | | | | = |--2.50%-- 0x60800951dc60 > | | | | | | = | =20 > | | | | | | = |--2.50%-- 0x60d009089d90 > | | | | | | = | =20 > | | | | | | = |--2.50%-- 0x60d009089c60 > | | | | | | = | =20 > | | | | | | = |--2.50%-- 0x607006f04c60 > | | | | | | = | =20 > | | | | | | = |--2.50%-- 0x60f005984d60 > | | | | | | = | =20 > | | | | | | = |--2.50%-- 0x7f4ad77f8fe0 > | | | | | | = | =20 > | | | | | | = |--2.50%-- 0x7f4adb9f8fe0 > | | | | | | = | =20 > | | | | | | = |--2.50%-- 0x7f4ad9bf8fe0 > | | | | | | = | =20 > | | | | | | = |--2.50%-- 0x7f4ad7df8fe0 > | | | | | | = | =20 > | | | | | | = |--2.50%-- 0x7f4ad77f8fe0 > | | | | | | = | =20 > | | | | | | = --2.50%-- 0x7f4ad5ff8fe0 > | | | | | | = =20 > | | | | | |-= -2.99%-- reactor::open_directory > | | | | | | = | =20 > | | | | | | = |--57.14%-- sstables::sstable::filename > | | | | | | = | =20 > | | | | | | = --42.86%-- sstables::sstable::write_toc > | | | | | | = sstables::sstable::prepare_write_components > | | | | | | = | =20 > | | | | | | = |--50.00%-- 0x4d3a4f6ec4e8cd75 > | | | | | | = | =20 > | | | | | | = --50.00%-- 0x3ebf3dd80e3b174d > | | | | | | = =20 > | | | | | -= -1.71%-- reactor::rename_file > | | | | | = sstables::sstable::seal_sstable > | | | | | = std::_Function_handler, unsigned long)::{lambda()#1}>::type ()>::type>::type= seastar::async, unsigned long)::{lambda()#1}>(std::de= cay&&, (std::decay, unsigned long)::{lambda()#1}>::typ= e&&)...)::{lambda(futurize::type ()= >::type> seastar::async<{lambda()#1}>(futurize::type ()>::type>::type, std::decay<{lambda()#1}>::type&&)::work= &)#1}::operator()(futurize::type ()= >::type> seastar::async<{lambda()#1}>(futurize::type ()>::type>::type, std::decay<{lambda()#1}>::type&&)::work= )::{lambda()#1}>::_M_invoke > | | | | | = _GLOBAL__sub_I__ZN12app_templateC2Ev > | | | | | =20 > | | | | --32.37%-- _= ZN12continuationIZN6futureIJEE4thenIZN18syscall_work_queue11submit_itemEPNS= 3_9work_itemEEUlvE_S1_EET0_OT_EUlS9_E_JEE3runEv > | | | | re= actor::del_timer > | | | | 0x= 60d0000e2040 > | | | | =20 > | | | |--29.04%-- __vdso_clock= _gettime > | | | | =20 > | | | |--19.66%-- 0x7f4ade42b1= 93 > | | | | reactor_backe= nd_epoll::complete_epoll_event > | | | | | =20 > | | | | |--41.61%-- s= mp_message_queue::async_work_item seastar::sharded::invo= ke_on >(unsigned int, service::storage_proxy::mutate_l= ocally(frozen_mutation const&)::{lambda(database&)#1}&&)::{lambda()#1}>::pr= ocess > | | | | | | = =20 > | | | | | |-= -79.03%-- smp_message_queue::process_queue<2ul, smp_message_queue::process_= incoming()::{lambda(smp_message_queue::work_item*)#1}> > | | | | | | = | =20 > | | | | | | = |--95.92%-- 0x6070000c3000 > | | | | | | = | =20 > | | | | | | = |--2.04%-- 0x61d0000c1000 > | | | | | | = | =20 > | | | | | | = --2.04%-- 0x61d0000c1000 > | | | | | | = =20 > | | | | | |-= -3.23%-- 0x14dd51 > | | | | | | = =20 > | | | | | |-= -1.61%-- 0x162a54 > | | | | | | = =20 > | | | | | |-= -1.61%-- 0x161dca > | | | | | | = =20 > | | | | | |-= -1.61%-- 0x159c8b > | | | | | | = =20 > | | | | | |-= -1.61%-- 0x1598b5 > | | | | | | = =20 > | | | | | |-= -1.61%-- 0x14dd3e > | | | | | | = =20 > | | | | | |-= -1.61%-- 0x14bad8 > | | | | | | = =20 > | | | | | |-= -1.61%-- 0x14a880 > | | | | | | = =20 > | | | | | |-= -1.61%-- 0x127105 > | | | | | | = =20 > | | | | | |-= -1.61%-- 0x6070000e2040 > | | | | | | = =20 > | | | | | |-= -1.61%-- smp_message_queue::process_queue<2ul, smp_message_queue::process_i= ncoming()::{lambda(smp_message_queue::work_item*)#1}> > | | | | | | = 0x60d0000c3000 > | | | | | | = =20 > | | | | | -= -1.61%-- __vdso_clock_gettime > | | | | | = 0x7f4ad77f9160 > | | | | | =20 > | | | | |--30.20%-- _= _restore_rt > | | | | | | = =20 > | | | | | |-= -57.14%-- __vdso_clock_gettime > | | | | | | = 0x1d > | | | | | | = =20 > | | | | | |-= -9.52%-- smp_message_queue::smp_message_queue > | | | | | | = 0x6070000c3000 > | | | | | | = =20 > | | | | | |-= -4.76%-- 0x600000357240 > | | | | | | = =20 > | | | | | |-= -4.76%-- 0x60000031a640 > | | | | | | = =20 > | | | | | |-= -2.38%-- posix_file_impl::list_directory > | | | | | | = 0x609000044730 > | | | | | | = =20 > | | | | | |-= -2.38%-- 0x46efbf > | | | | | | = =20 > | | | | | |-= -2.38%-- 0x600000442e40 > | | | | | | = =20 > | | | | | |-= -2.38%-- 0x600000376440 > | | | | | | = =20 > | | | | | |-= -2.38%-- 0x6000002bac40 > | | | | | | = =20 > | | | | | |-= -2.38%-- 0x600000295640 > | | | | | | = =20 > | | | | | |-= -2.38%-- 0x600000289e40 > | | | | | | = =20 > | | | | | |-= -2.38%-- 0x60000031a640 > | | | | | | = =20 > | | | | | |-= -2.38%-- 0x7f4ade6f74ed > | | | | | | = __libc_siglongjmp > | | | | | | = 0x60000047be40 > | | | | | | = =20 > | | | | | -= -2.38%-- 0x7f4adb3f7fd0 > | | | | | =20 > | | | | |--14.09%-- 0= x33 > | | | | | =20 > | | | | |--12.08%-- p= romise >::promise > | | | | | _Z= N6futureIJ16temporary_bufferIcEEE4thenIZN12input_streamIcE12read_exactlyEmE= UlT_E_S2_EET0_OS6_ > | | | | | | = =20 > | | | | | |-= -44.44%-- input_stream::read_exactly > | | | | | | = 0x8 > | | | | | | = =20 > | | | | | |-= -11.11%-- 0x7f4adb3f8ea0 > | | | | | | = =20 > | | | | | |-= -11.11%-- 0x7f4ad9bf8ea0 > | | | | | | = =20 > | | | | | |-= -11.11%-- 0x7f4ad89f8ea0 > | | | | | | = =20 > | | | | | |-= -11.11%-- 0x7f4ad83f8ea0 > | | | | | | = =20 > | | | | | |-= -5.56%-- 0x7f4ad77f8ea0 > | | | | | | = =20 > | | | | | -= -5.56%-- 0x7f4ad7df8ea0 > | | | | | =20 > | | | | |--1.34%-- 0x= 7f4ad6bf8d80 > | | | | | =20 > | | | | --0.67%-- 0x= 7f4adadf8d80 > | | | | =20 > | | | |--4.43%-- __libc_send > | | | | _ZN12continua= tionIZN6futureIJmEE4thenIZN7reactor14write_all_partER17pollable_fd_statePKv= mmEUlmE_S0_IJEEEET0_OT_EUlSC_E_JmEE3runEv > | | | | | =20 > | | | | |--14.71%-- 0= x4 > | | | | | =20 > | | | | |--11.76%-- 0= x7f4ad89f8de0 > | | | | | =20 > | | | | |--8.82%-- 0x= 7f4adb3f8de0 > | | | | | =20 > | | | | |--8.82%-- 0x= 7f4ad9bf8de0 > | | | | | =20 > | | | | |--8.82%-- 0x= 7f4ad77f8de0 > | | | | | =20 > | | | | |--8.82%-- 0x= 7f4ad6bf8de0 > | | | | | =20 > | | | | |--5.88%-- 0x= 7f4ad83f8de0 > | | | | | =20 > | | | | |--5.88%-- 0x= 7f4ad7df8de0 > | | | | | =20 > | | | | |--5.88%-- 0x= 7f4ad53f8de0 > | | | | | =20 > | | | | |--2.94%-- 0x= 7f4acc9f8de0 > | | | | | =20 > | | | | |--2.94%-- co= ntinuation::wait()::{lambda(future_state&&)#1}, file>::~= continuation > | | | | | 0x= 611003c8e9b8 > | | | | | =20 > | | | | |--2.94%-- 0x= 7f4adb9f8de0 > | | | | | =20 > | | | | |--2.94%-- 0x= 7f4ad71f8de0 > | | | | | =20 > | | | | |--2.94%-- 0x= 7f4ad65f8de0 > | | | | | =20 > | | | | |--2.94%-- 0x= 7f4ad59f8de0 > | | | | | =20 > | | | | --2.94%-- 0x= 7f4ad35f8de0 > | | | | =20 > | | | |--1.56%-- 0x7f4ade6f754d > | | | | reactor::read= _some > | | | | | =20 > | | | | |--66.67%-- _= ZN12continuationIZN6futureIJEE4thenIZZN7service13storage_proxy22send_to_liv= e_endpointsEmENKUlRSt4pairIK13basic_sstringIcjLj15EESt6vectorIN3gms12inet_a= ddressESaISB_EEEE_clESF_EUlvE_S1_EET0_OT_EUlSK_E_JEE3runEv > | | | | | re= actor::del_timer > | | | | | 0x= 6070000e2040 > | | | | | =20 > | | | | |--8.33%-- _Z= N12continuationIZN6futureIIEE4thenIZ5sleepINSt6chrono3_V212system_clockEmSt= 5ratioILl1ELl1000000EEES1_NS4_8durationIT0_T1_EEEUlvE_S1_EESA_OT_EUlSF_E_IE= E3runEv > | | | | | re= actor::del_timer > | | | | | 0x= 6080000e2040 > | | | | | =20 > | | | | |--8.33%-- 0x= 600000483640 > | | | | | =20 > | | | | |--8.33%-- 0x= 600000480440 > | | | | | =20 > | | | | --8.33%-- 0x= 36 > | | | --0.26%-- [...] > | | | =20 > | | --46.70%-- retint_careful > | | | =20 > | | |--6.24%-- posix_file_im= pl::list_directory > | | | | =20 > | | | |--80.00%-- 0= x60f0000e2020 > | | | | =20 > | | | |--5.00%-- 0x= 601000044730 > | | | | =20 > | | | |--5.00%-- 0x= 60e000044720 > | | | | =20 > | | | |--2.50%-- 0x= 60f000135500 > | | | | =20 > | | | |--2.50%-- 0x= 6190000e2098 > | | | | =20 > | | | |--2.50%-- 0x= 60d0000c3000 > | | | | =20 > | | | --2.50%-- 0x1 > | | | =20 > | | |--3.42%-- boost::lockfr= ee::detail::ringbuffer_base::pop > | | | | =20 > | | | |--95.65%-- b= oost::program_options::variables_map::get > | | | | =20 > | | | --4.35%-- 0x= 618000044680 > | | | =20 > | | |--3.12%-- memory::small= _pool::add_more_objects > | | | | =20 > | | | |--10.53%-- m= anaged_vector::clear_and_relea= se > | | | | mu= tation_partition::clustered_row > | | | | mu= tation::set_clustered_cell > | | | | cq= l3::constants::setter::execute > | | | | cq= l3::statements::update_statement::add_update_for_key > | | | | _Z= N8futurizeI6futureIJSt6vectorI8mutationSaIS2_EEEEE5applyIZN4cql310statement= s22modification_statement13get_mutationsERN7seastar7shardedIN7service13stor= age_proxyEEERKNS8_13query_optionsEblEUlT_E_JSt10unique_ptrINS8_17update_par= ametersESt14default_deleteISN_EEEEES5_OSK_OSt5tupleIJDpT0_EE > | | | | cq= l3::statements::modification_statement::get_mutations > | | | | cq= l3::statements::modification_statement::execute_without_condition > | | | | cq= l3::query_options::query_options > | | | | | = =20 > | | | | |-= -50.00%-- 0x7f4ad77f80e0 > | | | | | = =20 > | | | | -= -50.00%-- 0x7f4ad6bf80e0 > | | | | =20 > | | | |--10.53%-- m= emory::small_pool::add_more_objects > | | | | | = =20 > | | | | |-= -50.00%-- 0x60e00015d000 > | | | | | = =20 > | | | | -= -50.00%-- 0x60b00af6c758 > | | | | =20 > | | | |--5.26%-- 0x= 60a018ee3867 > | | | | =20 > | | | |--5.26%-- 0x= 60d00d41f680 > | | | | =20 > | | | |--5.26%-- 0x= 61400c6bb4d0 > | | | | =20 > | | | |--5.26%-- 0x= 60e007c918d6 > | | | | =20 > | | | |--5.26%-- 0x= 60e0078294ce > | | | | =20 > | | | |--5.26%-- 0x= 607006ee4da0 > | | | | =20 > | | | |--5.26%-- _Z= N12continuationIZN6futureIJEE12then_wrappedIZNS1_16handle_exceptionIZN7serv= ice13storage_proxy22send_to_live_endpointsEmEUlNSt15__exception_ptr13except= ion_ptrEE0_EES1_OT_EUlSA_E_S1_EET0_SA_EUlSA_E_JEE3runEv > | | | | re= actor::del_timer > | | | | 0x= 6030000e2040 > | | | | =20 > | | | |--5.26%-- se= rvice::storage_proxy::mutate_locally > | | | | se= rvice::storage_proxy::send_to_live_endpoints > | | | | pa= rallel_for_each<__gnu_cxx::__normal_iterator > >, service::storage_proxy::mut= ate_begin(std::vector >, db::c= onsistency_level)::{lambda(unsigned long)#1}> > | | | | 0x= 601000136d00 > | | | | =20 > | | | |--5.26%-- 0x= 60a0001900e0 > | | | | =20 > | | | |--5.26%-- 0x= 60e00015d040 > | | | | =20 > | | | |--5.26%-- 0x= 61300015d000 > | | | | =20 > | | | |--5.26%-- 0x= 60e00013bde0 > | | | | =20 > | | | |--5.26%-- 0x= 60b00010f308 > | | | | =20 > | | | |--5.26%-- 0x= 6010000e4808 > | | | | =20 > | | | --5.26%-- 0x= 7f4ad65f7f50 > | | | =20 > | | |--2.82%-- std::unique_p= tr > reactor::make_po= llfn(reactor::run()::{lambda()#3}&&)::the_pol= lfn::poll_and_check_more_work > | | | | =20 > | | | |--25.00%-- b= oost::lockfree::detail::ringbuffer_base::pop > | | | | bo= ost::program_options::variables_map::get > | | | | =20 > | | | |--25.00%-- 0= x1 > | | | | =20 > | | | |--12.50%-- 0= x53 > | | | | =20 > | | | |--12.50%-- 0= x3e > | | | | =20 > | | | |--12.50%-- 0= x24 > | | | | =20 > | | | --12.50%-- 0= xb958000000000000 > | | | =20 > | | |--2.67%-- std::_Functio= n_handler, std::less, std::allocator > > > >)::{lambda(partition_key con= st&)#1}>::_M_invoke > | | | | =20 > | | | |--66.67%-- 0= x1b5c280 > | | | | =20 > | | | |--27.78%-- m= anaged_vector::resize > | | | | ro= w::apply > | | | | mu= tation_partition_applier::accept_row_cell > | | | | mu= tation_partition_view::accept > | | | | =20 > | | | --5.56%-- 0x= 2a4399 > | | | =20 > | | |--2.08%-- smp_message_q= ueue::smp_message_queue > | | | | =20 > | | | |--60.00%-- 0= x60f0000c3000 > | | | | =20 > | | | |--10.00%-- 0= x6000002d7240 > | | | | =20 > | | | |--10.00%-- 0= x19 > | | | | =20 > | | | |--10.00%-- 0= xb > | | | | =20 > | | | --10.00%-- 0= x7 > | | | =20 > | | |--1.93%-- smp_message_q= ueue::process_queue<4ul, smp_message_queue::process_completions()::{lambda(= smp_message_queue::work_item*)#1}> > | | | =20 > | | |--1.63%-- __vdso_clock_= gettime > | | | | =20 > | | | --100.00%-- = __clock_gettime > | | | st= d::chrono::_V2::system_clock::now > | | | 0x= a63209 > | | | =20 > | | |--1.49%-- memory::small= _pool::deallocate > | | | | =20 > | | | |--40.00%-- m= anaged_vector::emplace_back > | | | | =20 > | | | |--20.00%-- s= td::_Hashtable, std::allocator >, std::__detail::_Select1st, std::equal_to, std::hash, std::__detail::_Mod_range_hashing, std= ::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std:= :__detail::_Hashtable_traits >::_M_erase > | | | | se= rvice::storage_proxy::got_response > | | | | _Z= N12continuationIZN6futureIJEE4thenIZZN7service13storage_proxy22send_to_live= _endpointsEmENKUlRSt4pairIK13basic_sstringIcjLj15EESt6vectorIN3gms12inet_ad= dressESaISB_EEEE_clESF_EUlvE_S1_EET0_OT_EUlSK_E_JEE3runEv > | | | | re= actor::del_timer > | | | | 0x= 6100000e2040 > | | | | =20 > | | | |--10.00%-- c= ql3::statements::modification_statement::get_mutations > | | | | =20 > | | | |--10.00%-- c= ql3::statements::modification_statement::build_partition_keys > | | | | cq= l3::statements::modification_statement::create_exploded_clustering_prefix > | | | | 0x= 60c014be0b00 > | | | | =20 > | | | |--10.00%-- m= utation_partition::~mutation_partition > | | | | st= d::vector >::~vector > | | | | se= rvice::storage_proxy::mutate_with_triggers > | | | | cq= l3::statements::modification_statement::execute_without_condition > | | | | cq= l3::statements::modification_statement::execute > | | | | cq= l3::query_processor::process_statement > | | | | tr= ansport::cql_server::connection::process_execute > | | | | tr= ansport::cql_server::connection::process_request_one > | | | | fu= turize >, service::client_state> > >::apply >&&)#1}::operator()(future >&&) con= st::{lambda(temporary_buffer)#1}::operator()(temporary_buffer) const:= :{lambda()#1}::operator()()::{lambda()#1}&> > | | | | fu= turize >::apply >&&)#1}::operator()(future >&&) const::{lambda(tempo= rary_buffer)#1}, temporary_buffer> > | | | | fu= turize >::apply >&&)#1}, future > > > | | | | 0x= 8961de > | | | | =20 > | | | --10.00%-- o= bject_deleter_impl::~object_deleter_impl > | | | _Z= N12continuationIZN6futureIJEE12then_wrappedIZZNS1_7finallyIZ7do_withI11fore= ign_ptrI10shared_ptrIN9transport10cql_server8responseEEEZZNS8_10connection1= 4write_responseEOSB_ENUlvE_clEvEUlRT_E_EDaOSF_OT0_EUlvE_EES1_SI_ENUlS1_E_cl= ES1_EUlSF_E_S1_EESJ_SI_EUlSI_E_JEED0Ev > | | | 0x= 61a0000c3db0 > | | | =20 > | | |--1.34%-- dht::decorate= d_key::equal > | | | | =20 > | | | |--83.33%-- 0= x607000138f00 > | | | | =20 > | | | --16.67%-- 0= x60a0000e0f40 > | | | =20 > | | |--1.34%-- service::stor= age_proxy::send_to_live_endpoints > | | | =20 > | | |--1.19%-- transport::cq= l_server::connection::process_execute > | | | transport::cq= l_server::connection::process_request_one > | | | futurize >, ser= vice::client_state> > >::apply >&&)#1}::operator()(future >&&) const::{lambda= (temporary_buffer)#1}::operator()(temporary_buffer) const::{lambda()#= 1}::operator()()::{lambda()#1}&> > | | | futurize >::apply >&&)#1}::operator()(future >&&) const::{lambda(temporary_buffer= )#1}, temporary_buffer> > | | | futurize >::apply >&&)#1}, future > > > | | | | =20 > | | | |--87.50%-- t= ransport::cql_server::connection::process_request > | | | | do= _until_continued > | | | | do= _void_futurize_apply(transport::cql_server::connection::process()::{lambda()#1}&= , transport::cql_server::connection::process()::{lambda()#2}&&, promise<>):= :{lambda(future<>)#1}, promise<> > > | | | | do= _void_futurize_apply(transport::cql_server::connection::process()::{lambda()#1}&= , transport::cql_server::connection::process()::{lambda()#2}&&, promise<>):= :{lambda(future<>)#1}, promise<> > > | | | | 0x= 60e0000c3000 > | | | | =20 > | | | --12.50%-- 0= x8961de > | | | =20 > | | |--1.19%-- reactor::run > | | | | =20 > | | | |--87.50%-- s= mp::configure(boost::program_options::variables_map)::{lambda()#1}::operato= r() > | | | | co= ntinuation > future<>::then > file::dma_read_bulk(unsigned long, unsigned long)::{la= mbda(unsigned long)#1}::operator()(unsigned long)::{lambda()#3}, future > >(future > file::dma_read_bulk= (unsigned long, unsigned long)::{lambda(unsigned long)#1}::operator()= (unsigned long)::{lambda()#3}&&)::{lambda(future >)#= 1}>::run > | | | | 0x= 600000043d00 > | | | | =20 > | | | --12.50%-- a= pp_template::run_deprecated > | | | ma= in > | | | __= libc_start_main > | | | _G= LOBAL__sub_I__ZN3org6apache9cassandra21g_cassandra_constantsE > | | | 0x= 7f4ae20c9fa0 > | | | =20 > | | |--1.04%-- __clock_getti= me > | | | std::chrono::= _V2::system_clock::now > | | | | =20 > | | | |--42.86%-- r= eactor::run > | | | | sm= p::configure(boost::program_options::variables_map)::{lambda()#1}::operator= () > | | | | co= ntinuation > future<>::then > file::dma_read_bulk(unsigned long, unsigned long)::{la= mbda(unsigned long)#1}::operator()(unsigned long)::{lambda()#3}, future > >(future > file::dma_read_bulk= (unsigned long, unsigned long)::{lambda(unsigned long)#1}::operator()= (unsigned long)::{lambda()#3}&&)::{lambda(future >)#= 1}>::run > | | | | 0x= 600000043d00 > | | | | =20 > | | | |--14.29%-- 0= xa63209 > | | | | =20 > | | | |--14.29%-- c= ontinuation future<>::finally >, shared_ptr= , service::storage_proxy::init_messaging_service()::{lambda(std::vector >)#1}::operator()(std::vector= >) const::{lambda(std::ve= ctor > const&, shared_ptr<= service::storage_proxy>&)#1}>(std::vector >&&, shared_ptr&&, service::storage= _proxy::init_messaging_service()::{lambda(std::vector >)#1}::operator()(std::vector >) const::{lambda(std::vector > const&, shared_ptr&)#1}&&)::{lambda()#1}>(service::storage_proxy::init_messaging_service= ()::{lambda(std::vector | | | | 0x= 2b7434 > | | | | =20 > | | | |--14.29%-- _= ZN8futurizeI6futureIJSt10unique_ptrIN4cql317update_parametersESt14default_d= eleteIS3_EEEEE5applyIZNS2_10statements22modification_statement22make_update= _parametersERN7seastar7shardedIN7service13storage_proxyEEE13lw_shared_ptrIS= t6vectorI13partition_keySaISK_EEESI_I26exploded_clustering_prefixERKNS2_13q= uery_optionsEblEUlT_E_JNSt12experimental15fundamentals_v18optionalINS3_13pr= efetch_dataEEEEEES7_OST_OSt5tupleIJDpT0_EE > | | | | cq= l3::statements::modification_statement::make_update_parameters > | | | | cq= l3::statements::modification_statement::get_mutations > | | | | cq= l3::statements::modification_statement::execute_without_condition > | | | | cq= l3::query_options::query_options > | | | | 0x= 7f4ad6bf80e0 > | | | | =20 > | | | --14.29%-- d= atabase::apply_in_memory > | | | da= tabase::do_apply > | | | _Z= N12continuationIZN6futureIJEE4thenIZN8database5applyERK15frozen_mutationEUl= vE_S1_EET0_OT_EUlSA_E_JEE3runEv > | | | re= actor::del_timer > | | | 0x= 6090000e2040 > | | | =20 > | | |--1.04%-- memory::small= _pool::allocate > | | | | =20 > | | | |--14.29%-- 0= x5257c379469d9 > | | | | =20 > | | | |--14.29%-- 0= x609002b9fe98 > | | | | =20 > | | | |--14.29%-- 0= x13c8b90 > | | | | =20 > | | | |--14.29%-- 0= x60f000190710 > | | | | =20 > | | | |--14.29%-- 0= x25 > | | | | =20 > | | | |--14.29%-- 0= x7f4ad6bf84c0 > | | | | =20 > | | | --14.29%-- 0= x7f4ad53f81f0 > | | | =20 > | | |--0.89%-- db::serialize= r::serializer > | | | mutation_part= ition_serializer::write_without_framing > | | | frozen_mutati= on::frozen_mutation > | | | frozen_mutati= on::frozen_mutation > | | | =20 > | | |--0.89%-- do_until_cont= inued > | | | do_void_futur= ize_apply(transport::cql_server::connection::process()::{lambda()#1}&, transport= ::cql_server::connection::process()::{lambda()#2}&&, promise<>)::{lambda(fu= ture<>)#1}, promise<> > > | | | do_void_futur= ize_apply(transport::cql_server::connection::process()::{lambda()#1}&, transport= ::cql_server::connection::process()::{lambda()#2}&&, promise<>)::{lambda(fu= ture<>)#1}, promise<> > > | | | 0x60f0000c3000 > | | | =20 > | | |--0.89%-- futurize >::apply >&&)#1}::operator()(future >&&) const::{lambda(temporary_buffer= )#1}, temporary_buffer> > | | | futurize >::apply >&&)#1}, future > > > | | | transport::cq= l_server::connection::process_request > | | | do_until_cont= inued > | | | do_void_futur= ize_apply(transport::cql_server::connection::process()::{lambda()#1}&, transport= ::cql_server::connection::process()::{lambda()#2}&&, promise<>)::{lambda(fu= ture<>)#1}, promise<> > > | | | do_void_futur= ize_apply(transport::cql_server::connection::process()::{lambda()#1}&, transport= ::cql_server::connection::process()::{lambda()#2}&&, promise<>)::{lambda(fu= ture<>)#1}, promise<> > > | | | | =20 > | | | |--83.33%-- 0= x6090000c3000 > | | | | =20 > | | | --16.67%-- 0= x600000044400 > | | | =20 > | | |--0.89%-- std::_Functio= n_handler::_M_invoke > | | | | =20 > | | | |--50.00%-- r= eactor::run > | | | | sm= p::configure(boost::program_options::variables_map)::{lambda()#1}::operator= () > | | | | co= ntinuation > future<>::then > file::dma_read_bulk(unsigned long, unsigned long)::{la= mbda(unsigned long)#1}::operator()(unsigned long)::{lambda()#3}, future > >(future > file::dma_read_bulk= (unsigned long, unsigned long)::{lambda(unsigned long)#1}::operator()= (unsigned long)::{lambda()#3}&&)::{lambda(future >)#= 1}>::run > | | | | 0x= 600000043d00 > | | | | =20 > | | | --50.00%-- r= eactor::signals::signal_handler::signal_handler > | | | 0x= 3e8 > | | | =20 > | | |--0.74%-- db::commitlog= ::segment::allocate > | | | | =20 > | | | --100.00%-- = db::commitlog::add > | | | da= tabase::do_apply > | | | | = =20 > | | | |-= -75.00%-- database::apply > | | | | = smp_message_queue::async_work_item seastar::sharded::invoke_on >(unsigned int, service::storage_proxy::mutat= e_locally(mutation const&)::{lambda(database&)#1}&&)::{lambda()#1}>::process > | | | | = smp_message_queue::process_queue<2ul, smp_message_queue::process_i= ncoming()::{lambda(smp_message_queue::work_item*)#1}> > | | | | = boost::lockfree::detail::ringbuffer_base::pop > | | | | = boost::program_options::variables_map::get > | | | | = =20 > | | | -= -25.00%-- _ZN12continuationIZN6futureIJEE4thenIZN8database5applyERK15frozen= _mutationEUlvE_S1_EET0_OT_EUlSA_E_JEE3runEv > | | | = reactor::del_timer > | | | = 0x60b0000e2040 > | | | =20 > | | |--0.74%-- service::stor= age_proxy::create_write_response_handler > | | | =20 > | | |--0.74%-- transport::cq= l_server::connection::process_request_one > | | | futurize >, ser= vice::client_state> > >::apply >&&)#1}::operator()(future >&&) const::{lambda= (temporary_buffer)#1}::operator()(temporary_buffer) const::{lambda()#= 1}::operator()()::{lambda()#1}&> > | | | futurize >::apply >&&)#1}::operator()(future >&&) const::{lambda(temporary_buffer= )#1}, temporary_buffer> > | | | futurize >::apply >&&)#1}, future > > > | | | | =20 > | | | |--80.00%-- t= ransport::cql_server::connection::process_request > | | | | do= _until_continued > | | | | do= _void_futurize_apply(transport::cql_server::connection::process()::{lambda()#1}&= , transport::cql_server::connection::process()::{lambda()#2}&&, promise<>):= :{lambda(future<>)#1}, promise<> > > | | | | do= _void_futurize_apply(transport::cql_server::connection::process()::{lambda()#1}&= , transport::cql_server::connection::process()::{lambda()#2}&&, promise<>):= :{lambda(future<>)#1}, promise<> > > | | | | 0x= 60a0000c3000 > | | | | =20 > | | | --20.00%-- 0= x8961de > | | | =20 > | | |--0.74%-- compound_type= <(allow_prefixes)0>::compare > | | | | =20 > | | | |--20.00%-- 0= x6030056c0f20 > | | | | =20 > | | | |--20.00%-- b= oost::intrusive::bstbase2, &rows_entry::_link>, rows_= entry::compare, (boost::intrusive::algo_types)5, boost::intrusive::detail::= default_header_holder > = >::find > | | | | mu= tation_partition::clustered_row > | | | | mu= tation::set_clustered_cell > | | | | cq= l3::constants::setter::execute > | | | | cq= l3::statements::update_statement::add_update_for_key > | | | | _Z= N8futurizeI6futureIJSt6vectorI8mutationSaIS2_EEEEE5applyIZN4cql310statement= s22modification_statement13get_mutationsERN7seastar7shardedIN7service13stor= age_proxyEEERKNS8_13query_optionsEblEUlT_E_JSt10unique_ptrINS8_17update_par= ametersESt14default_deleteISN_EEEEES5_OSK_OSt5tupleIJDpT0_EE > | | | | cq= l3::statements::modification_statement::get_mutations > | | | | cq= l3::statements::modification_statement::execute_without_condition > | | | | cq= l3::query_options::query_options > | | | | 0x= 7f4adb3f80e0 > | | | | =20 > | | | |--20.00%-- c= ompound_type<(allow_prefixes)0>::compare > | | | | =20 > | | | |--20.00%-- m= utation_partition::clustered_row > | | | | bo= ost::intrusive::bstree_impl, &rows_entry::_link>, row= s_entry::compare, unsigned long, true, (boost::intrusive::algo_types)5, boo= st::intrusive::detail::default_header_holder > >::insert_unique > | | | | bo= ost::intrusive::bstree_algorithms >::prev_node > | | | | 0x= 12d > | | | | =20 > | | | --20.00%-- 0= x60f00052daf0 > | | | =20 > | | |--0.74%-- __memmove_sss= e3_back > | | | | =20 > | | | |--40.00%-- o= utput_stream::write > | | | | | = =20 > | | | | |-= -50.00%-- transport::cql_server::response::output > | | | | | = futurize >::apply >&&)::{l= ambda()#1}> > | | | | | = =20 > | | | | -= -50.00%-- 0x7c7fb2 > | | | | = 0x5257c37847fa0 > | | | | =20 > | | | |--20.00%-- t= ransport::cql_server::connection::read_short_bytes > | | | | tr= ansport::cql_server::connection::process_query > | | | | 0x= 7f4ada7f86f0 > | | | | =20 > | | | |--20.00%-- t= ransport::cql_server::response::output > | | | | fu= turize >::apply >&&)::{lambda()#1}> > | | | | 0x2 > | | | | =20 > | | | --20.00%-- s= mp_message_queue::flush_response_batch > | | | bo= ost::lockfree::detail::ringbuffer_base::pop > | | | bo= ost::program_options::variables_map::get > | | | =20 > | | |--0.74%-- syscall_work_= queue::work_item_returning, reactor::file_size(b= asic_sstring)::{lambda()#1}>::~work_item_returning > | | | | =20 > | | | |--60.00%-- 0= x6130000c3000 > | | | | =20 > | | | |--20.00%-- 0= x608001fe59a0 > | | | | =20 > | | | --20.00%-- 0= x16 > | | | =20 > | | |--0.74%-- __memset_sse2 > | | | | =20 > | | | |--40.00%-- s= td::_Hashtable, std::pair const, std::u= nordered_set, std::equal_to= , std::allocator > >, std::allocator<= std::pair const, std::unordered_set, std::equal_to, std::allocato= r > > >, std::__detail::_Select1st, std::equal_to >, std::hash >, std::__detail::_Mod_range_has= hing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_pol= icy, std::__detail::_Hashtable_traits >::~_Hashtable > | | | | lo= cator::token_metadata::pending_endpoints_for > | | | | se= rvice::storage_proxy::create_write_response_handler > | | | | se= rvice::storage_proxy::mutate_prepare >, service::storage_proxy::mutate_prepare(std::vector >&, db::consistency_level, db::write_type)::{lambda(= mutation const&, db::consistency_level, db::write_type)#1}> > | | | | se= rvice::storage_proxy::mutate > | | | | se= rvice::storage_proxy::mutate_with_triggers > | | | | cq= l3::statements::modification_statement::execute_without_condition > | | | | cq= l3::statements::modification_statement::execute > | | | | cq= l3::query_processor::process_statement > | | | | tr= ansport::cql_server::connection::process_execute > | | | | tr= ansport::cql_server::connection::process_request_one > | | | | fu= turize >, service::client_state> > >::apply >&&)#1}::operator()(future >&&) con= st::{lambda(temporary_buffer)#1}::operator()(temporary_buffer) const:= :{lambda()#1}::operator()()::{lambda()#1}&> > | | | | fu= turize >::apply >&&)#1}::operator()(future >&&) const::{lambda(tempo= rary_buffer)#1}, temporary_buffer> > | | | | fu= turize >::apply >&&)#1}, future > > > | | | | tr= ansport::cql_server::connection::process_request > | | | | do= _until_continued > | | | | do= _void_futurize_apply(transport::cql_server::connection::process()::{lambda()#1}&= , transport::cql_server::connection::process()::{lambda()#2}&&, promise<>):= :{lambda(future<>)#1}, promise<> > > | | | | do= _void_futurize_apply(transport::cql_server::connection::process()::{lambda()#1}&= , transport::cql_server::connection::process()::{lambda()#2}&&, promise<>):= :{lambda(future<>)#1}, promise<> > > | | | | 0x= 6020000c3000 > | | | | =20 > | | | |--40.00%-- s= ervice::digest_read_resolver::~digest_read_resolver > | | | | | = =20 > | | | | -= -100.00%-- 0x610002612b50 > | | | | =20 > | | | --20.00%-- s= td::_Hashtable, std::pair const, std::vector > >, std::allocator const, std::vector > > >, std::__detail::_Select1st, std::equal_to >, std::hash >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_= hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits= >::~_Hashtable > | | | se= rvice::storage_proxy::send_to_live_endpoints > | | | pa= rallel_for_each<__gnu_cxx::__normal_iterator > >, service::storage_proxy::mut= ate_begin(std::vector >, db::c= onsistency_level)::{lambda(unsigned long)#1}> > | | | se= rvice::storage_proxy::mutate > | | | se= rvice::storage_proxy::mutate_with_triggers > | | | cq= l3::statements::modification_statement::execute_without_condition > | | | cq= l3::statements::modification_statement::execute > | | | cq= l3::query_processor::process_statement > | | | tr= ansport::cql_server::connection::process_execute > | | | tr= ansport::cql_server::connection::process_request_one > | | | fu= turize >, service::client_state> > >::apply >&&)#1}::operator()(future >&&) con= st::{lambda(temporary_buffer)#1}::operator()(temporary_buffer) const:= :{lambda()#1}::operator()()::{lambda()#1}&> > | | | fu= turize >::apply >&&)#1}::operator()(future >&&) const::{lambda(tempo= rary_buffer)#1}, temporary_buffer> > | | | fu= turize >::apply >&&)#1}, future > > > | | | tr= ansport::cql_server::connection::process_request > | | | do= _until_continued > | | | do= _void_futurize_apply(transport::cql_server::connection::process()::{lambda()#1}&= , transport::cql_server::connection::process()::{lambda()#2}&&, promise<>):= :{lambda(future<>)#1}, promise<> > > | | | do= _void_futurize_apply(transport::cql_server::connection::process()::{lambda()#1}&= , transport::cql_server::connection::process()::{lambda()#2}&&, promise<>):= :{lambda(future<>)#1}, promise<> > > | | | 0x= 6070000c3000 > | | | =20 > | | |--0.74%-- reactor::del_= timer > | | | | =20 > | | | |--80.00%-- 0= x60a0000e2040 > | | | | =20 > | | | --20.00%-- 0= x6080000c3db0 > | | | =20 > | | |--0.59%-- unimplemented= ::operator<< > | | | | =20 > | | | |--25.00%-- _= ZN12continuationIZN6futureIJ10shared_ptrIN9transport8messages14result_messa= geEEEE4thenIZN4cql315query_processor17process_statementES1_INS8_13cql_state= mentEERN7service11query_stateERKNS8_13query_optionsEEUlT_E_S6_EET0_OSI_EUlS= L_E_JS5_EED2Ev > | | | | 0x= 600100000008 > | | | | =20 > | | | |--25.00%-- f= loating_type_impl::from_string > | | | | =20 > | | | |--25.00%-- 0= x60e0000e4c10 > | | | | =20 > | | | --25.00%-- _= ZN12continuationIZN6futureIJ10shared_ptrIN9transport8messages14result_messa= geEEEE4thenIZN4cql315query_processor17process_statementES1_INS8_13cql_state= mentEERN7service11query_stateERKNS8_13query_optionsEEUlT_E_S6_EET0_OSI_EUlS= L_E_JS5_EED2Ev > | | | 0x= 600100000008 > | | | =20 > | | |--0.59%-- std::_Hashtab= le, std::allocator >, std::__detail::_Select1st, std::equal_to, s= td::hash, std::__detail::_Mod_range_hashing, std::__detail::= _Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_= Hashtable_traits >::_M_insert_unique_node > | | | service::stor= age_proxy::register_response_handler > | | | service::stor= age_proxy::create_write_response_handler > | | | service::stor= age_proxy::create_write_response_handler > | | | service::stor= age_proxy::mutate_prepare >,= service::storage_proxy::mutate_prepare(std::vector >&, db::consistency_level, db::write_type)::{lambda(mutation co= nst&, db::consistency_level, db::write_type)#1}> > | | | service::stor= age_proxy::mutate > | | | service::stor= age_proxy::mutate_with_triggers > | | | cql3::stateme= nts::modification_statement::execute_without_condition > | | | cql3::stateme= nts::modification_statement::execute > | | | cql3::query_p= rocessor::process_statement > | | | transport::cq= l_server::connection::process_execute > | | | transport::cq= l_server::connection::process_request_one > | | | futurize >, ser= vice::client_state> > >::apply >&&)#1}::operator()(future >&&) const::{lambda= (temporary_buffer)#1}::operator()(temporary_buffer) const::{lambda()#= 1}::operator()()::{lambda()#1}&> > | | | futurize >::apply >&&)#1}::operator()(future >&&) const::{lambda(temporary_buffer= )#1}, temporary_buffer> > | | | futurize >::apply >&&)#1}, future > > > | | | transport::cq= l_server::connection::process_request > | | | do_until_cont= inued > | | | do_void_futur= ize_apply(transport::cql_server::connection::process()::{lambda()#1}&, transport= ::cql_server::connection::process()::{lambda()#2}&&, promise<>)::{lambda(fu= ture<>)#1}, promise<> > > | | | do_void_futur= ize_apply(transport::cql_server::connection::process()::{lambda()#1}&, transport= ::cql_server::connection::process()::{lambda()#2}&&, promise<>)::{lambda(fu= ture<>)#1}, promise<> > > | | | 0x60b0000c3000 > | | | =20 > | | |--0.59%-- mutation::set= _clustered_cell > | | | | =20 > | | | |--75.00%-- 0= xa > | | | | =20 > | | | --25.00%-- c= ql3::constants::setter::execute > | | | cq= l3::statements::update_statement::add_update_for_key > | | | _Z= N8futurizeI6futureIJSt6vectorI8mutationSaIS2_EEEEE5applyIZN4cql310statement= s22modification_statement13get_mutationsERN7seastar7shardedIN7service13stor= age_proxyEEERKNS8_13query_optionsEblEUlT_E_JSt10unique_ptrINS8_17update_par= ametersESt14default_deleteISN_EEEEES5_OSK_OSt5tupleIJDpT0_EE > | | | cq= l3::statements::modification_statement::get_mutations > | | | cq= l3::statements::modification_statement::execute_without_condition > | | | cq= l3::query_options::query_options > | | | 0x= 7f4ad89f80e0 > | | | =20 > | | |--0.59%-- memory::small= _pool::small_pool > | | | | =20 > | | | |--25.00%-- m= emory::stats > | | | | bo= ost::program_options::variables_map::get > | | | | =20 > | | | |--25.00%-- m= emory::reclaimer::~reclaimer > | | | | 0x= 1e > | | | | =20 > | | | |--25.00%-- m= emory::allocate_aligned > | | | | =20 > | | | --25.00%-- m= emory::small_pool::add_more_objects > | | | me= mory::small_pool::add_more_objects > | | | 0x= 6100000e0310 > | | | =20 > | | |--0.59%-- __memcpy_sse2= _unaligned > | | | | =20 > | | | |--50.00%-- m= utation_partition_applier::accept_row_cell > | | | | mu= tation_partition_view::accept > | | | | bo= ost::intrusive::bstree_algorithms >::prev_node > | | | | 0x= 12d > | | | | =20 > | | | |--25.00%-- s= canning_reader::operator() > | | | | ss= tables::sstable::do_write_components > | | | | ss= tables::sstable::prepare_write_components > | | | | st= d::_Function_handler, unsigned long)::{lambda()#1}>::type ()>::type>::type seastar::a= sync, unsigned long)::{lambda()#1}>(std::decay&&, (std= ::decay, unsigned long)::{lambda()#1}>::type&&)...)::{= lambda(futurize::type ()>::type> se= astar::async<{lambda()#1}>(futurize= ::type ()>::type>::type, std::decay<{lambda()#1}>::type&&)::work&)#1}::oper= ator()(futurize::type ()>::type> se= astar::async<{lambda()#1}>(futurize= ::type ()>::type>::type, std::decay<{lambda()#1}>::type&&)::work)::{lambda(= )#1}>::_M_invoke > | | | | _G= LOBAL__sub_I__ZN12app_templateC2Ev > | | | | =20 > | | | --25.00%-- m= emtable::find_or_create_partition_slow > | | | me= mtable::apply > | | | da= tabase::apply_in_memory > | | | da= tabase::do_apply > | | | da= tabase::apply > | | | sm= p_message_queue::async_work_item seastar::sharded::invok= e_on >(unsigned int, service::storage_proxy::mutate_locally(m= utation const&)::{lambda(database&)#1}&&)::{lambda()#1}>::process > | | | sm= p_message_queue::process_queue<2ul, smp_message_queue::process_incoming()::= {lambda(smp_message_queue::work_item*)#1}> > | | | bo= ost::lockfree::detail::ringbuffer_base::pop > | | | bo= ost::program_options::variables_map::get > | | | =20 > | | |--0.59%-- smp_message_q= ueue::flush_response_batch > | | | | =20 > | | | |--25.00%-- b= oost::lockfree::detail::ringbuffer_base::pop > | | | | bo= ost::program_options::variables_map::get > | | | | =20 > | | | |--25.00%-- 0= x13 > | | | | =20 > | | | |--25.00%-- 0= x7f4ad5ff8f40 > | | | | =20 > | | | --25.00%-- r= eactor::run > | | | sm= p::configure(boost::program_options::variables_map)::{lambda()#1}::operator= () > | | | co= ntinuation > future<>::then > file::dma_read_bulk(unsigned long, unsigned long)::{la= mbda(unsigned long)#1}::operator()(unsigned long)::{lambda()#3}, future > >(future > file::dma_read_bulk= (unsigned long, unsigned long)::{lambda(unsigned long)#1}::operator()= (unsigned long)::{lambda()#3}&&)::{lambda(future >)#= 1}>::run > | | | 0x= 600000043d00 > | | --54.38%-- [...] > | | =20 > | |--14.26%-- schedule_timeout > | | | =20 > | | |--38.52%-- wait_for_completion > | | | | =20 > | | | |--90.07%-- flush_work > | | | | xlog_cil_forc= e_lsn > | | | | | =20 > | | | | |--96.85%-- _= xfs_log_force_lsn > | | | | | | = =20 > | | | | | |-= -79.67%-- xfs_file_fsync > | | | | | | = vfs_fsync_range > | | | | | | = do_fsync > | | | | | | = sys_fdatasync > | | | | | | = entry_SYSCALL_64_fastpath > | | | | | | = | =20 > | | | | | | = --100.00%-- 0x7f4ade4212ad > | | | | | | = syscall_work_queue::work_item_returning, posix_file_impl::flush()::{lambda()#1}>::process > | | | | | | = 0x6030000c3ec0 > | | | | | | = =20 > | | | | | -= -20.33%-- xfs_dir_fsync > | | | | | = vfs_fsync_range > | | | | | = do_fsync > | | | | | = sys_fdatasync > | | | | | = entry_SYSCALL_64_fastpath > | | | | | = | =20 > | | | | | = --100.00%-- 0x7f4ade4212ad > | | | | | = syscall_work_queue::work_item_returning, posix_file_impl::flush()::{lambda()#1}>::process > | | | | | = 0x6040000c3ec0 > | | | | | =20 > | | | | --3.15%-- _x= fs_log_force > | | | | xf= s_log_force > | | | | xf= s_buf_lock > | | | | _x= fs_buf_find > | | | | xf= s_buf_get_map > | | | | xf= s_trans_get_buf_map > | | | | xf= s_btree_get_bufl > | | | | xf= s_bmap_extents_to_btree > | | | | xf= s_bmap_add_extent_hole_real > | | | | xf= s_bmapi_write > | | | | xf= s_iomap_write_direct > | | | | __= xfs_get_blocks > | | | | xf= s_get_blocks_direct > | | | | do= _blockdev_direct_IO > | | | | __= blockdev_direct_IO > | | | | xf= s_vm_direct_IO > | | | | xf= s_file_dio_aio_write > | | | | xf= s_file_write_iter > | | | | ai= o_run_iocb > | | | | do= _io_submit > | | | | sy= s_io_submit > | | | | en= try_SYSCALL_64_fastpath > | | | | io= _submit > | | | | 0x= 46d98a > | | | | =20 > | | | --9.93%-- submit_bio_wa= it > | | | blkdev_issue_= flush > | | | xfs_blkdev_is= sue_flush > | | | xfs_file_fsync > | | | vfs_fsync_ran= ge > | | | do_fsync > | | | sys_fdatasync > | | | entry_SYSCALL= _64_fastpath > | | | | =20 > | | | --100.00%-- = 0x7f4ade4212ad > | | | sy= scall_work_queue::work_item_returning, posix_file_impl:= :flush()::{lambda()#1}>::process > | | | 0x= 6030000c3ec0 > | | | =20 > | | |--32.79%-- io_schedule_timeout > | | | bit_wait_io > | | | __wait_on_bit > | | | | =20 > | | | |--51.67%-- wait_on_page= _bit > | | | | | =20 > | | | | |--95.16%-- f= ilemap_fdatawait_range > | | | | | fi= lemap_write_and_wait_range > | | | | | xf= s_file_fsync > | | | | | vf= s_fsync_range > | | | | | do= _fsync > | | | | | sy= s_fdatasync > | | | | | en= try_SYSCALL_64_fastpath > | | | | | 0x= 7f4ade4212ad > | | | | | sy= scall_work_queue::work_item_returning, posix_file_impl:= :flush()::{lambda()#1}>::process > | | | | | 0x= 60b0000c3ec0 > | | | | | =20 > | | | | --4.84%-- __= migration_entry_wait > | | | | mi= gration_entry_wait > | | | | ha= ndle_mm_fault > | | | | __= do_page_fault > | | | | do= _page_fault > | | | | pa= ge_fault > | | | | st= d::_Function_handler::_M_invoke > | | | | | = =20 > | | | | -= -100.00%-- service::storage_proxy::mutate_prepare >, service::storage_proxy::mutate_prepare(std::vector= >&, db::consistency_level, db::write_ty= pe)::{lambda(mutation const&, db::consistency_level, db::write_type)#1}> > | | | | = service::storage_proxy::mutate > | | | | = service::storage_proxy::mutate_with_triggers > | | | | = cql3::statements::modification_statement::execute_without_condition > | | | | = cql3::statements::modification_statement::execute > | | | | = cql3::query_processor::process_statement > | | | | = transport::cql_server::connection::process_execute > | | | | = transport::cql_server::connection::process_request_one > | | | | = futurize >, service::client_state> > >::apply >&&)#1}::operator()(future= >&&) const::{lambda(temporary_buffer)#1}::operator()(temporary_buf= fer) const::{lambda()#1}::operator()()::{lambda()#1}&> > | | | | = futurize >::apply >&&)#1}::operator()(future >&&) const::{l= ambda(temporary_buffer)#1}, temporary_buffer> > | | | | = futurize >::apply >&&)#1}, future > > > | | | | = transport::cql_server::connection::process_request > | | | | = do_until_continued > | | | | = do_void_futurize_apply(transport::cql_server::connection::process()::{l= ambda()#1}&, transport::cql_server::connection::process()::{lambda()#2}&&, = promise<>)::{lambda(future<>)#1}, promise<> > > | | | | = do_void_futurize_apply(transport::cql_server::connection::process()::{l= ambda()#1}&, transport::cql_server::connection::process()::{lambda()#2}&&, = promise<>)::{lambda(future<>)#1}, promise<> > > | | | | = 0x6140000c3000 > | | | | =20 > | | | --48.33%-- out_of_line_= wait_on_bit > | | | block_truncat= e_page > | | | xfs_setattr_s= ize > | | | xfs_vn_setattr > | | | notify_change > | | | do_truncate > | | | do_sys_ftrunc= ate.constprop.15 > | | | sys_ftruncate > | | | entry_SYSCALL= _64_fastpath > | | | __GI___ftrunc= ate64 > | | | syscall_work_= queue::work_item_returning, posix_file_impl::sta= t()::{lambda()#1}>::process > | | | | =20 > | | | |--13.79%-- 0= x7f4ad29ff700 > | | | | =20 > | | | |--13.79%-- 0= x7f4acdbff700 > | | | | =20 > | | | |--12.07%-- 0= x7f4ad05ff700 > | | | | =20 > | | | |--12.07%-- 0= x7f4acedff700 > | | | | =20 > | | | |--10.34%-- 0= x7f4ad0bff700 > | | | | =20 > | | | |--6.90%-- 0x= 7f4ad2fff700 > | | | | =20 > | | | |--6.90%-- 0x= 7f4ad11ff700 > | | | | =20 > | | | |--6.90%-- 0x= 7f4acf9ff700 > | | | | =20 > | | | |--6.90%-- 0x= 7f4acf3ff700 > | | | | =20 > | | | |--6.90%-- 0x= 7f4ace7ff700 > | | | | =20 > | | | |--1.72%-- 0x= 7f4ad17ff700 > | | | | =20 > | | | --1.72%-- 0x= 7f4aca5ff700 > | | | =20 > | | --28.69%-- __down > | | down > | | xfs_buf_lock > | | _xfs_buf_find > | | xfs_buf_get_map > | | | =20 > | | |--97.14%-- xfs_buf_read= _map > | | | xfs_trans_rea= d_buf_map > | | | | =20 > | | | |--98.04%-- x= fs_read_agf > | | | | xf= s_alloc_read_agf > | | | | xf= s_alloc_fix_freelist > | | | | | = =20 > | | | | |-= -93.00%-- xfs_free_extent > | | | | | = xfs_bmap_finish > | | | | | = xfs_itruncate_extents > | | | | | = | =20 > | | | | | = |--87.10%-- xfs_inactive_truncate > | | | | | = | xfs_inactive > | | | | | = | xfs_fs_evict_inode > | | | | | = | evict > | | | | | = | iput > | | | | | = | __dentry_kill > | | | | | = | dput > | | | | | = | __fput > | | | | | = | ____fput > | | | | | = | task_work_run > | | | | | = | do_notify_resume > | | | | | = | int_signal > | | | | | = | __libc_close > | | | | | = | std::experimental::fundamentals_v1::bad_optional_access= ::~bad_optional_access > | | | | | = | =20 > | | | | | = --12.90%-- xfs_setattr_size > | | | | | = xfs_vn_setattr > | | | | | = notify_change > | | | | | = do_truncate > | | | | | = do_sys_ftruncate.constprop.15 > | | | | | = sys_ftruncate > | | | | | = entry_SYSCALL_64_fastpath > | | | | | = | =20 > | | | | | = --100.00%-- __GI___ftruncate64 > | | | | | = syscall_work_queue::work_item_returning, posix_file_impl::stat()::{lambda()#1}>::process > | | | | | = | =20 > | | | | | = |--20.00%-- 0x7f4ad0bff700 > | | | | | = | =20 > | | | | | = |--20.00%-- 0x7f4acedff700 > | | | | | = | =20 > | | | | | = |--10.00%-- 0x7f4ad2fff700 > | | | | | = | =20 > | | | | | = |--10.00%-- 0x7f4ad17ff700 > | | | | | = | =20 > | | | | | = |--10.00%-- 0x7f4ad11ff700 > | | | | | = | =20 > | | | | | = |--10.00%-- 0x7f4ad05ff700 > | | | | | = | =20 > | | | | | = |--10.00%-- 0x7f4acf3ff700 > | | | | | = | =20 > | | | | | = --10.00%-- 0x7f4acdbff700 > | | | | | = =20 > | | | | -= -7.00%-- xfs_alloc_vextent > | | | | = xfs_bmap_btalloc > | | | | = xfs_bmap_alloc > | | | | = xfs_bmapi_write > | | | | = xfs_iomap_write_direct > | | | | = __xfs_get_blocks > | | | | = xfs_get_blocks_direct > | | | | = do_blockdev_direct_IO > | | | | = __blockdev_direct_IO > | | | | = xfs_vm_direct_IO > | | | | = xfs_file_dio_aio_write > | | | | = xfs_file_write_iter > | | | | = aio_run_iocb > | | | | = do_io_submit > | | | | = sys_io_submit > | | | | = entry_SYSCALL_64_fastpath > | | | | = io_submit > | | | | = 0x46d98a > | | | | =20 > | | | --1.96%-- xf= s_read_agi > | | | xf= s_iunlink_remove > | | | xf= s_ifree > | | | xf= s_inactive_ifree > | | | xf= s_inactive > | | | xf= s_fs_evict_inode > | | | ev= ict > | | | ip= ut > | | | __= dentry_kill > | | | dp= ut > | | | __= fput > | | | __= __fput > | | | ta= sk_work_run > | | | do= _notify_resume > | | | in= t_signal > | | | __= libc_close > | | | st= d::experimental::fundamentals_v1::bad_optional_access::~bad_optional_access > | | | =20 > | | --2.86%-- xfs_trans_get= _buf_map > | | xfs_btree_get= _bufl > | | xfs_bmap_exte= nts_to_btree > | | xfs_bmap_add_= extent_hole_real > | | xfs_bmapi_wri= te > | | xfs_iomap_wri= te_direct > | | __xfs_get_blo= cks > | | xfs_get_block= s_direct > | | do_blockdev_d= irect_IO > | | __blockdev_di= rect_IO > | | xfs_vm_direct= _IO > | | xfs_file_dio_= aio_write > | | xfs_file_writ= e_iter > | | aio_run_iocb > | | do_io_submit > | | sys_io_submit > | | entry_SYSCALL= _64_fastpath > | | io_submit > | | 0x46d98a > | | =20 > | |--13.48%-- eventfd_ctx_read > | | eventfd_read > | | __vfs_read > | | vfs_read > | | sys_read > | | entry_SYSCALL_64_fastpath > | | 0x7f4ade6f754d > | | smp_message_queue::respond > | | 0xffffffffffffffff > | | =20 > | |--7.83%-- md_flush_request > | | raid0_make_request > | | md_make_request > | | generic_make_request > | | submit_bio > | | | =20 > | | |--92.54%-- submit_bio_wait > | | | blkdev_issue_flush > | | | xfs_blkdev_issue_flush > | | | xfs_file_fsync > | | | vfs_fsync_range > | | | do_fsync > | | | sys_fdatasync > | | | entry_SYSCALL_64_fastpath > | | | | =20 > | | | --100.00%-- 0x7f4ade421= 2ad > | | | syscall_work_= queue::work_item_returning, posix_file_impl::flush()::{= lambda()#1}>::process > | | | 0x6010000c3ec0 > | | | =20 > | | --7.46%-- _xfs_buf_ioapply > | | xfs_buf_submit > | | xlog_bdstrat > | | xlog_sync > | | xlog_state_release_iclog > | | | =20 > | | |--73.33%-- _xfs_log_for= ce_lsn > | | | xfs_file_fsync > | | | vfs_fsync_ran= ge > | | | do_fsync > | | | sys_fdatasync > | | | entry_SYSCALL= _64_fastpath > | | | | =20 > | | | --100.00%-- = 0x7f4ade4212ad > | | | sy= scall_work_queue::work_item_returning, posix_file_impl:= :flush()::{lambda()#1}>::process > | | | 0x= 6080000c3ec0 > | | | =20 > | | --26.67%-- _xfs_log_for= ce > | | xfs_log_force > | | xfs_buf_lock > | | _xfs_buf_find > | | xfs_buf_get_m= ap > | | xfs_trans_get= _buf_map > | | xfs_btree_get= _bufl > | | xfs_bmap_exte= nts_to_btree > | | xfs_bmap_add_= extent_hole_real > | | xfs_bmapi_wri= te > | | xfs_iomap_wri= te_direct > | | __xfs_get_blo= cks > | | xfs_get_block= s_direct > | | do_blockdev_d= irect_IO > | | __blockdev_di= rect_IO > | | xfs_vm_direct= _IO > | | xfs_file_dio_= aio_write > | | xfs_file_writ= e_iter > | | aio_run_iocb > | | do_io_submit > | | sys_io_submit > | | entry_SYSCALL= _64_fastpath > | | io_submit > | | 0x46d98a > | | =20 > | |--5.53%-- _xfs_log_force_lsn > | | | =20 > | | |--80.28%-- xfs_file_fsync > | | | vfs_fsync_range > | | | do_fsync > | | | sys_fdatasync > | | | entry_SYSCALL_64_fastpath > | | | | =20 > | | | --100.00%-- 0x7f4ade421= 2ad > | | | syscall_work_= queue::work_item_returning, posix_file_impl::flush()::{= lambda()#1}>::process > | | | | =20 > | | | |--97.92%-- 0= x60d0000c3ec0 > | | | | =20 > | | | |--1.04%-- 0x= 6020000c3ec0 > | | | | =20 > | | | --1.04%-- 0x= 600000557ec0 > | | | =20 > | | --19.72%-- xfs_dir_fsync > | | vfs_fsync_range > | | do_fsync > | | sys_fdatasync > | | entry_SYSCALL_64_fastpath > | | | =20 > | | --100.00%-- 0x7f4ade421= 2ad > | | syscall_work_= queue::work_item_returning, posix_file_impl::flush()::{= lambda()#1}>::process > | | 0x6040000c3ec0 > | | =20 > | |--1.25%-- rwsem_down_read_failed > | | call_rwsem_down_read_failed > | | | =20 > | | |--90.62%-- xfs_ilock > | | | | =20 > | | | |--86.21%-- xfs_ilock_da= ta_map_shared > | | | | __xfs_get_blo= cks > | | | | xfs_get_block= s_direct > | | | | do_blockdev_d= irect_IO > | | | | __blockdev_di= rect_IO > | | | | xfs_vm_direct= _IO > | | | | xfs_file_dio_= aio_write > | | | | xfs_file_writ= e_iter > | | | | aio_run_iocb > | | | | do_io_submit > | | | | sys_io_submit > | | | | entry_SYSCALL= _64_fastpath > | | | | | =20 > | | | | --100.00%-- = io_submit > | | | | 0x= 46d98a > | | | | =20 > | | | |--6.90%-- xfs_file_fsync > | | | | vfs_fsync_ran= ge > | | | | do_fsync > | | | | sys_fdatasync > | | | | entry_SYSCALL= _64_fastpath > | | | | 0x7f4ade4212ad > | | | | syscall_work_= queue::work_item_returning, posix_file_impl::flush()::{= lambda()#1}>::process > | | | | 0x6090000c3ec0 > | | | | =20 > | | | --6.90%-- xfs_dir_fsync > | | | vfs_fsync_ran= ge > | | | do_fsync > | | | sys_fdatasync > | | | entry_SYSCALL= _64_fastpath > | | | 0x7f4ade4212ad > | | | syscall_work_= queue::work_item_returning, posix_file_impl::flush()::{= lambda()#1}>::process > | | | 0x6070000c3ec0 > | | | =20 > | | --9.38%-- xfs_log_commit_cil > | | __xfs_trans_commit > | | xfs_trans_commit > | | | =20 > | | |--33.33%-- xfs_setattr_= size > | | | xfs_vn_setattr > | | | notify_change > | | | do_truncate > | | | do_sys_ftrunc= ate.constprop.15 > | | | sys_ftruncate > | | | entry_SYSCALL= _64_fastpath > | | | __GI___ftrunc= ate64 > | | | syscall_work_= queue::work_item_returning, posix_file_impl::sta= t()::{lambda()#1}>::process > | | | 0x7f4acedff700 > | | | =20 > | | |--33.33%-- xfs_vn_updat= e_time > | | | file_update_t= ime > | | | xfs_file_aio_= write_checks > | | | xfs_file_dio_= aio_write > | | | xfs_file_writ= e_iter > | | | aio_run_iocb > | | | do_io_submit > | | | sys_io_submit > | | | entry_SYSCALL= _64_fastpath > | | | io_submit > | | | 0x46d98a > | | | =20 > | | --33.33%-- xfs_bmap_add= _attrfork > | | xfs_attr_set > | | xfs_initxattrs > | | security_inod= e_init_security > | | xfs_init_secu= rity > | | xfs_generic_c= reate > | | xfs_vn_mknod > | | xfs_vn_create > | | vfs_create > | | path_openat > | | do_filp_open > | | do_sys_open > | | sys_open > | | entry_SYSCALL= _64_fastpath > | | 0x7f4ade6f7cdd > | | syscall_work_= queue::work_item_returning, reactor::open_file_dma(basi= c_sstring, open_flags, file_open_options)::{lambda= ()#1}>::process > | | 0xfffffffffff= fffff > | | =20 > | |--0.97%-- rwsem_down_write_failed > | | call_rwsem_down_write_failed > | | xfs_ilock > | | xfs_vn_update_time > | | file_update_time > | | xfs_file_aio_write_checks > | | xfs_file_dio_aio_write > | | xfs_file_write_iter > | | aio_run_iocb > | | do_io_submit > | | sys_io_submit > | | entry_SYSCALL_64_fastpath > | | io_submit > | | 0x46d98a > | | =20 > | |--0.51%-- xlog_cil_force_lsn > | | | =20 > | | |--92.31%-- _xfs_log_force_lsn > | | | | =20 > | | | |--91.67%-- xfs_file_fsy= nc > | | | | vfs_fsync_ran= ge > | | | | do_fsync > | | | | sys_fdatasync > | | | | entry_SYSCALL= _64_fastpath > | | | | 0x7f4ade4212ad > | | | | syscall_work_= queue::work_item_returning, posix_file_impl::flush()::{= lambda()#1}>::process > | | | | 0x60b0000c3ec0 > | | | | =20 > | | | --8.33%-- xfs_dir_fsync > | | | vfs_fsync_ran= ge > | | | do_fsync > | | | sys_fdatasync > | | | entry_SYSCALL= _64_fastpath > | | | 0x7f4ade4212ad > | | | syscall_work_= queue::work_item_returning, posix_file_impl::flush()::{= lambda()#1}>::process > | | | 0x60d0000c3ec0 > | | | =20 > | | --7.69%-- _xfs_log_force > | | xfs_log_force > | | xfs_buf_lock > | | _xfs_buf_find > | | xfs_buf_get_map > | | xfs_trans_get_buf_map > | | xfs_btree_get_bufl > | | xfs_bmap_extents_to_btree > | | xfs_bmap_add_extent_hole= _real > | | xfs_bmapi_write > | | xfs_iomap_write_direct > | | __xfs_get_blocks > | | xfs_get_blocks_direct > | | do_blockdev_direct_IO > | | __blockdev_direct_IO > | | xfs_vm_direct_IO > | | xfs_file_dio_aio_write > | | xfs_file_write_iter > | | aio_run_iocb > | | do_io_submit > | | sys_io_submit > | | entry_SYSCALL_64_fastpath > | | io_submit > | | 0x46d98a > | --0.04%-- [...] > | =20 > --3.82%-- preempt_schedule_common > | =20 > |--99.02%-- _cond_resched > | | =20 > | |--41.58%-- wait_for_completion > | | | =20 > | | |--66.67%-- flush_work > | | | xlog_cil_forc= e_lsn > | | | | =20 > | | | |--96.43%-- _= xfs_log_force_lsn > | | | | | = =20 > | | | | |-= -77.78%-- xfs_file_fsync > | | | | | = vfs_fsync_range > | | | | | = do_fsync > | | | | | = sys_fdatasync > | | | | | = entry_SYSCALL_64_fastpath > | | | | | = 0x7f4ade4212ad > | | | | | = syscall_work_queue::work_item_returning, posix= _file_impl::flush()::{lambda()#1}>::process > | | | | | = 0x6030000c3ec0 > | | | | | = =20 > | | | | -= -22.22%-- xfs_dir_fsync > | | | | = vfs_fsync_range > | | | | = do_fsync > | | | | = sys_fdatasync > | | | | = entry_SYSCALL_64_fastpath > | | | | = | =20 > | | | | = --100.00%-- 0x7f4ade4212ad > | | | | = syscall_work_queue::work_item_returning, posix_file_impl::flush()::{lambda()#1}>::process > | | | | = 0x6030000c3ec0 > | | | | =20 > | | | --3.57%-- _x= fs_log_force > | | | xf= s_log_force > | | | xf= s_buf_lock > | | | _x= fs_buf_find > | | | xf= s_buf_get_map > | | | xf= s_trans_get_buf_map > | | | xf= s_btree_get_bufl > | | | xf= s_bmap_extents_to_btree > | | | xf= s_bmap_add_extent_hole_real > | | | xf= s_bmapi_write > | | | xf= s_iomap_write_direct > | | | __= xfs_get_blocks > | | | xf= s_get_blocks_direct > | | | do= _blockdev_direct_IO > | | | __= blockdev_direct_IO > | | | xf= s_vm_direct_IO > | | | xf= s_file_dio_aio_write > | | | xf= s_file_write_iter > | | | ai= o_run_iocb > | | | do= _io_submit > | | | sy= s_io_submit > | | | en= try_SYSCALL_64_fastpath > | | | io= _submit > | | | 0x= 46d98a > | | | =20 > | | --33.33%-- submit_bio_w= ait > | | blkdev_issue_= flush > | | xfs_blkdev_is= sue_flush > | | xfs_file_fsync > | | vfs_fsync_ran= ge > | | do_fsync > | | sys_fdatasync > | | entry_SYSCALL= _64_fastpath > | | | =20 > | | --100.00%-- = 0x7f4ade4212ad > | | sy= scall_work_queue::work_item_returning, posix_file_impl:= :flush()::{lambda()#1}>::process > | | 0x= 6030000c3ec0 > | | =20 > | |--33.66%-- flush_work > | | xlog_cil_force_lsn > | | | =20 > | | |--97.06%-- _xfs_log_for= ce_lsn > | | | | =20 > | | | |--78.79%-- x= fs_file_fsync > | | | | vf= s_fsync_range > | | | | do= _fsync > | | | | sy= s_fdatasync > | | | | en= try_SYSCALL_64_fastpath > | | | | 0x= 7f4ade4212ad > | | | | sy= scall_work_queue::work_item_returning, posix_file_impl:= :flush()::{lambda()#1}>::process > | | | | 0x= 6030000c3ec0 > | | | | =20 > | | | --21.21%-- x= fs_dir_fsync > | | | vf= s_fsync_range > | | | do= _fsync > | | | sy= s_fdatasync > | | | en= try_SYSCALL_64_fastpath > | | | | = =20 > | | | -= -100.00%-- 0x7f4ade4212ad > | | | = syscall_work_queue::work_item_returning, posix= _file_impl::flush()::{lambda()#1}>::process > | | | = 0x6030000c3ec0 > | | | =20 > | | --2.94%-- _xfs_log_force > | | xfs_log_force > | | xfs_buf_lock > | | _xfs_buf_find > | | xfs_buf_get_m= ap > | | xfs_trans_get= _buf_map > | | xfs_btree_get= _bufl > | | xfs_bmap_exte= nts_to_btree > | | xfs_bmap_add_= extent_hole_real > | | xfs_bmapi_wri= te > | | xfs_iomap_wri= te_direct > | | __xfs_get_blo= cks > | | xfs_get_block= s_direct > | | do_blockdev_d= irect_IO > | | __blockdev_di= rect_IO > | | xfs_vm_direct= _IO > | | xfs_file_dio_= aio_write > | | xfs_file_writ= e_iter > | | aio_run_iocb > | | do_io_submit > | | sys_io_submit > | | entry_SYSCALL= _64_fastpath > | | io_submit > | | 0x46d98a > | | =20 > | |--13.86%-- lock_sock_nested > | | | =20 > | | |--78.57%-- tcp_sendmsg > | | | inet_sendmsg > | | | sock_sendmsg > | | | SYSC_sendto > | | | sys_sendto > | | | entry_SYSCALL= _64_fastpath > | | | __libc_send > | | | _ZN12continua= tionIZN6futureIJmEE4thenIZN7reactor14write_all_partER17pollable_fd_statePKv= mmEUlmE_S0_IJEEEET0_OT_EUlSC_E_JmEE3runEv > | | | | =20 > | | | |--36.36%-- 0= x7f4ad6bf8de0 > | | | | =20 > | | | |--9.09%-- 0x4 > | | | | =20 > | | | |--9.09%-- 0x= 7f4adadf8de0 > | | | | =20 > | | | |--9.09%-- 0x= 7f4ada1f8de0 > | | | | =20 > | | | |--9.09%-- 0x= 7f4ad89f8de0 > | | | | =20 > | | | |--9.09%-- 0x= 7f4ad83f8de0 > | | | | =20 > | | | |--9.09%-- 0x= 7f4ad4df8de0 > | | | | =20 > | | | --9.09%-- 0x= 7f4ad35f8de0 > | | | =20 > | | --21.43%-- tcp_recvmsg > | | inet_recvmsg > | | sock_recvmsg > | | sock_read_iter > | | __vfs_read > | | vfs_read > | | sys_read > | | entry_SYSCALL= _64_fastpath > | | 0x7f4ade6f754d > | | reactor::read= _some > | | | =20 > | | |--66.67%-- _= ZN12continuationIZN6futureIJEE4thenIZZN7service13storage_proxy22send_to_liv= e_endpointsEmENKUlRSt4pairIK13basic_sstringIcjLj15EESt6vectorIN3gms12inet_a= ddressESaISB_EEEE_clESF_EUlvE_S1_EET0_OT_EUlSK_E_JEE3runEv > | | | re= actor::del_timer > | | | 0x= 6160000e2040 > | | | =20 > | | --33.33%-- c= ontinuation future<>::then_wrapped future<>::finally(seastar::gate&, transport::cql_serve= r::connection::process()::{lambda()#2}::operator()() const::{lambda()#1}&&)= ::{lambda()#1}>(seastar::gate&)::{lambda(future<>)#1}::operator()(future<>)= ::{lambda(seastar::gate)#1}, future<> >(seastar::gate&)::{lambda(seastar::g= ate&)#1}>::run > | | re= actor::del_timer > | | 0x= 6030000e2040 > | | =20 > | |--3.96%-- generic_make_request_che= cks > | | generic_make_request > | | submit_bio > | | do_blockdev_direct_IO > | | __blockdev_direct_IO > | | xfs_vm_direct_IO > | | xfs_file_dio_aio_write > | | xfs_file_write_iter > | | aio_run_iocb > | | do_io_submit > | | sys_io_submit > | | entry_SYSCALL_64_fastpath > | | io_submit > | | 0x46d98a > | | =20 > | |--3.96%-- kmem_cache_alloc_node > | | __alloc_skb > | | sk_stream_alloc_skb > | | tcp_sendmsg > | | inet_sendmsg > | | sock_sendmsg > | | SYSC_sendto > | | sys_sendto > | | entry_SYSCALL_64_fastpath > | | __libc_send > | | _ZN12continuationIZN6fut= ureIJmEE4thenIZN7reactor14write_all_partER17pollable_fd_statePKvmmEUlmE_S0_= IJEEEET0_OT_EUlSC_E_JmEE3runEv > | | | =20 > | | |--25.00%-- 0x7f4ad9bf8d= e0 > | | | =20 > | | |--25.00%-- 0x7f4ad7df8d= e0 > | | | =20 > | | |--25.00%-- 0x7f4ad77f8d= e0 > | | | =20 > | | --25.00%-- 0x7f4ad59f8d= e0 > | | =20 > | |--0.99%-- unmap_underlying_metadata > | | do_blockdev_direct_IO > | | __blockdev_direct_IO > | | xfs_vm_direct_IO > | | xfs_file_dio_aio_write > | | xfs_file_write_iter > | | aio_run_iocb > | | do_io_submit > | | sys_io_submit > | | entry_SYSCALL_64_fastpath > | | io_submit > | | 0x46d98a > | | =20 > | |--0.99%-- __kmalloc_node_track_cal= ler > | | __kmalloc_reserve.isra.32 > | | __alloc_skb > | | sk_stream_alloc_skb > | | tcp_sendmsg > | | inet_sendmsg > | | sock_sendmsg > | | SYSC_sendto > | | sys_sendto > | | entry_SYSCALL_64_fastpath > | | __libc_send > | | _ZN12continuationIZN6fut= ureIJmEE4thenIZN7reactor14write_all_partER17pollable_fd_statePKvmmEUlmE_S0_= IJEEEET0_OT_EUlSC_E_JmEE3runEv > | | 0x7f4ad6bf8de0 > | | =20 > | --0.99%-- task_work_run > | do_notify_resume > | int_signal > | __libc_close > | std::experimental::funda= mentals_v1::bad_optional_access::~bad_optional_access > | =20 > --0.98%-- __cond_resched_softirq > release_sock > tcp_sendmsg > inet_sendmsg > sock_sendmsg > SYSC_sendto > sys_sendto > entry_SYSCALL_64_fastpath > __libc_send > _ZN12continuationIZN6futureIJmEE4th= enIZN7reactor14write_all_partER17pollable_fd_statePKvmmEUlmE_S0_IJEEEET0_OT= _EUlSC_E_JmEE3runEv > 0x7f4ada1f8de0 >=20 >=20 >=20 > # > # (For a higher level overview, try: perf report --sort comm,dso) > # > [164814.835933] CPU: 22 PID: 48042 Comm: scylla Tainted: G E = 4.2.6-200.fc22.x86_64 #1 > [164814.835936] Hardware name: Xen HVM domU, BIOS 4.2.amazon 05/06/2015 > [164814.835937] 0000000000000000 00000000a8713b7a ffff8802fb977ab8 fffff= fff817729ea > [164814.835941] 0000000000000000 ffff88076a69f780 ffff8802fb977ad8 fffff= fffa03217a6 > [164814.835946] ffff88077119bcb0 0000000000000000 ffff8802fb977b08 fffff= fffa034e749 > [164814.835951] Call Trace: > [164814.835954] [] dump_stack+0x45/0x57 > [164814.835971] [] xfs_buf_stale+0x26/0x80 [xfs] > [164814.835989] [] xfs_trans_binval+0x79/0x100 [xfs] > [164814.836001] [] xfs_bmap_btree_to_extents+0x12b/0x1= a0 [xfs] > [164814.836012] [] xfs_bunmapi+0x967/0x9f0 [xfs] > [164814.836027] [] xfs_itruncate_extents+0x10e/0x220 [= xfs] > [164814.836044] [] ? kmem_zone_alloc+0x5a/0xe0 [xfs] > [164814.836084] [] xfs_inactive_truncate+0x99/0x110 [x= fs] > [164814.836120] [] xfs_inactive+0x102/0x120 [xfs] > [164814.836135] [] xfs_fs_evict_inode+0x6f/0xa0 [xfs] > [164814.836138] [] evict+0xa6/0x170 > [164814.836140] [] iput+0x196/0x220 > [164814.836147] [] __dentry_kill+0x174/0x1c0 > [164814.836150] [] dput+0x11b/0x200 > [164814.836155] [] __fput+0x172/0x1e0 > [164814.836158] [] ____fput+0xe/0x10 > [164814.836161] [] task_work_run+0x85/0xb0 > [164814.836164] [] do_notify_resume+0x8d/0x90 > [164814.836167] [] int_signal+0x12/0x17 > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From cmaiolino@redhat.com Mon Nov 30 08:26:28 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 B959F7F37 for ; Mon, 30 Nov 2015 08:26:28 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id A57CA304039 for ; Mon, 30 Nov 2015 06:26:28 -0800 (PST) X-ASG-Debug-ID: 1448893587-04cbb0605b2c92d0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id gsRZPf6QLQp2VuYN (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 30 Nov 2015 06:26:27 -0800 (PST) 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 (Postfix) with ESMTPS id EC0A2C0B7AC8 for ; Mon, 30 Nov 2015 14:26:26 +0000 (UTC) Received: from redhat.com (vpn-62-205.rdu2.redhat.com [10.10.62.205]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAUEQMhH020223 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Mon, 30 Nov 2015 09:26:25 -0500 Date: Mon, 30 Nov 2015 15:26:22 +0100 From: Carlos Maiolino To: Brian Foster Cc: xfs@oss.sgi.com Subject: Re: [PATCH] xfs_io: implement 'inode' command V5 Message-ID: <20151130142622.GA27492@redhat.com> X-ASG-Orig-Subj: Re: [PATCH] xfs_io: implement 'inode' command V5 Mail-Followup-To: Brian Foster , xfs@oss.sgi.com References: <1448552795-8794-1-git-send-email-cmaiolino@redhat.com> <20151130132217.GA24765@bfoster.bfoster> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151130132217.GA24765@bfoster.bfoster> User-Agent: Mutt/1.5.24 (2015-08-30) 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: 1448893587 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 > > I think we want "n:v" here since -n expects an argument, even if we > don't process the arg here. Using getopt() to handle the -n argument, will make the inode command having 2 different entry points for the same argument, i.e. the inode number. One as an argument for -n, and another as an argument for the command itself, like: inode -n inode We need to handle [num] as a stand-alone argument anyway, so, I just don't think we need to handle the same argument in different ways, which I achieved by not using [num] as a getopt() argument, but instead, handling [num] 'manually' according to the options used in getopt(). Not sure if I could be clear or get things more confused :) > > + if (ret_next && verbose) > > + return command_usage(&inode_cmd); > > + > > Why is this not supported? Hmm, I see that -n returns an inode number > and otherwise we print 0/1 or : with -v. Perhaps this would > be easier if the command semantics/output were more consistent. E.g., > > "inode": print 0/1 based on largest inode size > "inode -v": print : of largest inode > "inode ": print if inode exists > "inode -v ": print : if inode exists I thought about this, but I decided to not do it because the command looks a bit redundant for me when 'inode "inode -n ": print if next inode exists > "inode -nv ": print : if next inode exists Just FYI, if the 'next inode' doesn't exist (i.e. using the last fs inode as argument), the ioctl will return 0 in bstat.bs_ino, which, I choose to leave it as-is, and adding this observation to the man page, instead of returning a messag like "no more inodes in the fs". I decided to leave it as-is, because for usage would be easier to parse a '0' return value from -n argument, than parsing an error message which has the same meaning of a zeroed return. Anyway, I'm going add -v to the another options, just please take a look at my replies regarding the 'inode -n' return value and the reason I didn't use getopt() to handle -n argument and if you agree or not, so I'll rewrite the patch to v6 based on this. Cheers o> -- Carlos From avi@cloudius-systems.com Mon Nov 30 08:29:19 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 8B1637F3F for ; Mon, 30 Nov 2015 08:29:19 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 5A66C304048 for ; Mon, 30 Nov 2015 06:29:19 -0800 (PST) X-ASG-Debug-ID: 1448893756-04cbb0605d2c93c0001-NocioJ Received: from mail-wm0-f50.google.com (mail-wm0-f50.google.com [74.125.82.50]) by cuda.sgi.com with ESMTP id 2irutrQEP35xt47r (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Mon, 30 Nov 2015 06:29:16 -0800 (PST) X-Barracuda-Envelope-From: avi@cloudius-systems.com X-Barracuda-Apparent-Source-IP: 74.125.82.50 Received: by wmuu63 with SMTP id u63so131862700wmu.0 for ; Mon, 30 Nov 2015 06:29:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=scylladb-com.20150623.gappssmtp.com; s=20150623; h=subject:to:references:cc:from:message-id:date:user-agent :mime-version:in-reply-to:content-type:content-transfer-encoding; bh=HIWiENc7LBxY8Xvrb3IS2p9nNCXEBP5N3IktuYkt01U=; b=U/hrY6SEMgzW59SLYSf3ZwnvZEVw8/9ieB2YWLvvkKn68hr6QpZmT9D9CqLPw83nXN At6hb66KzkX+Us4BGmX+GgiQ3X9LYhXqXTdMqPo5Coe1ZpC1KhW2gfxrzBNc4X/RCL7c z5I30I//Jwr53V2Or/R/L86H3QXPL6i7QtXGh4xMIMoSp8Aldf+cRUSVi9xJcR4ygkdy nyEY5IfvGeGu5dZfudD+tQLRNpAyQ9KcMK9UnTb7cRgQKIiCV7qux+ddVlSmk/mVlMKc RdpG2dqDyIn9MU+pUfZGjnJ9iLoD2SSxGSF0ezZ31twRAYrCDT8TXUHjzF22rnHN2D0j vEEQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:subject:to:references:cc:from:message-id:date :user-agent:mime-version:in-reply-to:content-type :content-transfer-encoding; bh=HIWiENc7LBxY8Xvrb3IS2p9nNCXEBP5N3IktuYkt01U=; b=muITSD4FbJA4YPR6SGWQasfwx1aNuOdNvS7xbPJHV+xL9O9Z+Xl8bCB0llV9/j8crx XLSPjbsU+6FBoNitwDqRrKyVmBCRjX4C293SP/d3qphwpF9Lv3B53gpf3bhGtEj57gYL qdIvXP+O7Vamdwfmwm7rd1zGua7UDQWBt2Qi7vl1OSwtnc2t3C4wc5BujZCXMj/Wqnia uGH/e5CBMjfAvBntv/uc4AOexPEING3DW5d8HmQ5Mactux/DcLlbcdfewSanPgmxTko/ 6BWR5rb523I8C/gDKVzO+syvaBscfvIU1DZ2OVGYcR9c/iosIT2XnKab46tCJtWSCiAq UQbA== X-Gm-Message-State: ALoCoQl+6LKTBDMDq3rUqYoPgEGbIjIoWULnAj8N5MTf480Zh8VDZUUwwGfROC8Dw0h0bESUSkIT X-Received: by 10.28.101.195 with SMTP id z186mr30330339wmb.52.1448893755861; Mon, 30 Nov 2015 06:29:15 -0800 (PST) Received: from avi.cloudius-systems.com ([37.142.229.250]) by smtp.googlemail.com with ESMTPSA id u205sm21575008wmb.12.2015.11.30.06.29.14 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 30 Nov 2015 06:29:14 -0800 (PST) Subject: Re: sleeps and waits during io_submit To: Brian Foster , Glauber Costa X-ASG-Orig-Subj: Re: sleeps and waits during io_submit References: <20151130141000.GC24765@bfoster.bfoster> Cc: xfs@oss.sgi.com, david@fromorbit.com From: Avi Kivity Message-ID: <565C5D39.8080300@scylladb.com> Date: Mon, 30 Nov 2015 16:29:13 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <20151130141000.GC24765@bfoster.bfoster> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mail-wm0-f50.google.com[74.125.82.50] X-Barracuda-Start-Time: 1448893756 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24849 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 11/30/2015 04:10 PM, Brian Foster wrote: >> 2) xfs_buf_lock -> down >> This is one I truly don't understand. What can be causing contention >> in this lock? We never have two different cores writing to the same >> buffer, nor should we have the same core doingCAP_FOWNER so. >> > This is not one single lock. An XFS buffer is the data structure used to > modify/log/read-write metadata on-disk and each buffer has its own lock > to prevent corruption. Buffer lock contention is possible because the > filesystem has bits of "global" metadata that has to be updated via > buffers. > > For example, usually one has multiple allocation groups to maximize > parallelism, but we still have per-ag metadata that has to be tracked > globally with respect to each AG (e.g., free space trees, inode > allocation trees, etc.). Any operation that affects this metadata (e.g., > block/inode allocation) has to lock the agi/agf buffers along with any > buffers associated with the modified btree leaf/node blocks, etc. > > One example in your attached perf traces has several threads looking to > acquire the AGF, which is a per-AG data structure for tracking free > space in the AG. One thread looks like the inode eviction case noted > above (freeing blocks), another looks like a file truncate (also freeing > blocks), and yet another is a block allocation due to a direct I/O > write. Were any of these operations directed to an inode in a separate > AG, they would be able to proceed in parallel (but I believe they would > still hit the same codepaths as far as perf can tell). I guess we can mitigate (but not eliminate) this by creating more allocation groups. What is the default value for agsize? Are there any downsides to decreasing it, besides consuming more memory? Are those locks held around I/O, or just CPU operations, or a mix? From glommer@cloudius-systems.com Mon Nov 30 09:49:34 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 E1BCD7F3F for ; Mon, 30 Nov 2015 09:49:34 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id D21AE304067 for ; Mon, 30 Nov 2015 07:49:34 -0800 (PST) X-ASG-Debug-ID: 1448898567-04cb6c535366df0001-NocioJ Received: from mail-lf0-f54.google.com (mail-lf0-f54.google.com [209.85.215.54]) by cuda.sgi.com with ESMTP id Bm6QCkmtmBrpu7eo (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Mon, 30 Nov 2015 07:49:28 -0800 (PST) X-Barracuda-Envelope-From: glommer@cloudius-systems.com X-Barracuda-Apparent-Source-IP: 209.85.215.54 Received: by lfdl133 with SMTP id l133so201519125lfd.2 for ; Mon, 30 Nov 2015 07:49:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=scylladb-com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=6SWCJ9wogdH2xzk6B0OlF0OZkj5t8SbPSM9rJ7nlxWo=; b=a+T8lWyhzBnk91dqL5l8cLEDF6jbq7c8D5SqEx79Xs9JdcUYhRbOVhOxrpPSZR/bnE Ebtn50WZLhHHEQa+q15MPCHgmvjenkhttGBWLOW97CrzYumWv5H7mTvsoUbNu07RW6bn hLvUtliC2Cb5XA49lpMrcEaaBf/69yp3AmXZXEgToEH7yJ2mZSEm33Ik8QWHQ0CEApRj xOy3W6LKZanWHSqX4u5Ki2xktnPQmvrCinTpEicVnRmDbMuJKP6wiYlTIKPE6TT7jIx1 3+xWQnIomG6CJ/LIbZNFq7Wez6SdkYx3JX6deRnRFZgj5uk4dRplr6PSJ557ZnBbIJMn mn1g== 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=6SWCJ9wogdH2xzk6B0OlF0OZkj5t8SbPSM9rJ7nlxWo=; b=ElAvjHVBBP2crrABOsSKkHUNn175eQhmwPFECqUEOTbkSWWBRShSSKgfpYHGCeigN3 sC2mgoVJjZyFYEokBL3fc9T4quBs2Z4OwH3LizOrUE4jA8nH6GQaXnhMvFP1Ajdd7xn0 LzFee5ykryu/6VDQBYmMI5673sThIFaWlYs65xsTYBQmresK+X+iRe8m1juhT0/pL9UF O1R+BK9Bkocg5qSqPRSjR8IDDRULZAg7MOepz9/xq9QPnwPivfTCiJU4kw+66wPFjWv6 1ciC/CDM6UJwjVt9MOIqSCmVYlGbVXtr5unN6MsuUrcPqDjVvEXtNexuaMPP7U4cz7hu yTAw== X-Gm-Message-State: ALoCoQkg8CVnBKW+QMRjg7dOBorWRwZi9XhKkPDRTHe7sPpDJrY73RcjFl3fBTjzBFIiJjpeTXS0 MIME-Version: 1.0 X-Received: by 10.25.146.201 with SMTP id u192mr12247296lfd.14.1448898567434; Mon, 30 Nov 2015 07:49:27 -0800 (PST) Received: by 10.25.205.133 with HTTP; Mon, 30 Nov 2015 07:49:27 -0800 (PST) In-Reply-To: <20151130141000.GC24765@bfoster.bfoster> References: <20151130141000.GC24765@bfoster.bfoster> Date: Mon, 30 Nov 2015 10:49:27 -0500 Message-ID: Subject: Re: sleeps and waits during io_submit From: Glauber Costa X-ASG-Orig-Subj: Re: sleeps and waits during io_submit To: Brian Foster Cc: xfs@oss.sgi.com, Avi Kivity , david@fromorbit.com Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-lf0-f54.google.com[209.85.215.54] X-Barracuda-Start-Time: 1448898568 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24851 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 Brian >> 1) xfs_buf_lock -> xfs_log_force. >> >> I've started wondering what would make xfs_log_force sleep. But then I >> have noticed that xfs_log_force will only be called when a buffer is >> marked stale. Most of the times a buffer is marked stale seems to be >> due to errors. Although that is not my case (more on that), it got me >> thinking that maybe the right thing to do would be to avoid hitting >> this case altogether? >> > > I'm not following where you get the "only if marked stale" part..? It > certainly looks like that's one potential purpose for the call, but this > is called in a variety of other places as well. E.g., forcing the log > via pushing on the ail when it has pinned items is another case. The ail > push itself can originate from transaction reservation, etc., when log > space is needed. In other words, I'm not sure this is something that's > easily controlled from userspace, if at all. Rather, it's a significant > part of the wider state machine the fs uses to manage logging. I understand that in general xfs_log_force can be called from many places. But in our traces the ones we see sleeping are coming from xfs_buf_lock. The code for xfs_buf_lock reads: if (atomic_read(&bp->b_pin_count) && (bp->b_flags & XBF_STALE)) xfs_log_force(bp->b_target->bt_mount, 0); which if I read correctly, will be called only for stale buffers. True thing they happen to be pinned as well, but somehow the stale part caught my attention. It seemed to me from briefly looking that the stale condition was a more "avoidable" one. (keep in mind I am not an awesome XFSer, may be missing something) > >> The file example-stale.txt contains a backtrace of the case where we >> are being marked as stale. It seems to be happening when we convert >> the the inode's extents from unwritten to real. Can this case be >> avoided? I won't pretend I know the intricacies of this, but couldn't >> we be keeping extents from the very beginning to avoid creating stale >> buffers? >> > > This is down in xfs_fs_evict_inode()->xfs_inactive(), which is generally > when an inode is evicted from cache. In this case, it looks like the > inode is unlinked (permanently removed), the extents are being removed > and a bmap btree block is being invalidated as part of that overall > process. I don't think this has anything to do with unwritten extents. > Cool. If the inode is indeed unliked, could that sill be triggering that condition in xfs_buf_lock? I am not even close to fully understanding how XFS manages and/or recycles buffers, but it seems to me that if an inode is going away, there isn't really any reason to contend for its buffers. >> 2) xfs_buf_lock -> down >> This is one I truly don't understand. What can be causing contention >> in this lock? We never have two different cores writing to the same >> buffer, nor should we have the same core doingCAP_FOWNER so. >> > > This is not one single lock. An XFS buffer is the data structure used to > modify/log/read-write metadata on-disk and each buffer has its own lock > to prevent corruption. Buffer lock contention is possible because the > filesystem has bits of "global" metadata that has to be updated via > buffers. I see. Since I hate guessing, is there any way you would recommend for us to probe the system to determine if this contention scenario is indeed the one we are seeing? We usually open a file, write to it from a single core only, sequentially, direct IO only, as well behavedly as we can, with all the effort in the world to be good kids to the extent Santa will bring us presents without us even asking. So we were very puzzled to see contention. Contention for global metadata updates is the best explanation we've had so far, and would be great if we could verify it is indeed the case. > > For example, usually one has multiple allocation groups to maximize > parallelism, but we still have per-ag metadata that has to be tracked > globally with respect to each AG (e.g., free space trees, inode > allocation trees, etc.). Any operation that affects this metadata (e.g., > block/inode allocation) has to lock the agi/agf buffers along with any > buffers associated with the modified btree leaf/node blocks, etc. > > One example in your attached perf traces has several threads looking to > acquire the AGF, which is a per-AG data structure for tracking free > space in the AG. One thread looks like the inode eviction case noted > above (freeing blocks), another looks like a file truncate (also freeing > blocks), and yet another is a block allocation due to a direct I/O > write. Were any of these operations directed to an inode in a separate > AG, they would be able to proceed in parallel (but I believe they would > still hit the same codepaths as far as perf can tell). This is great, great, awesome info Brian. Thanks. We are so far allocating inodes and truncating them when we need a new one, but maybe there is some allocation pattern that is friendlier to the AG? I understand that with such a data structure it may very well be impossible to get rid of all waiting, but we will certainly do all we can to mitigate it. > >> 3) xfs_file_aio_write_checks -> file_update_time -> xfs_vn_update_time >> >> You guys seem to have an interface to avoid that, by setting the >> FMODE_NOCMTIME flag. This is done by issuing the open by handle ioctl, >> which will set this flag for all regular files. That's great, but that >> ioctl required CAP_SYS_ADMIN, which is a big no for us, since we run >> our server as an unprivileged user. I don't understand, however, why >> such an strict check is needed. If we have full rights on the >> filesystem, why can't we issue this operation? In my view, CAP_FOWNER >> should already be enough.I do understand the handles have to be stable >> and a file can have its ownership changed, in which case the previous >> owner would keep the handle valid. Is that the reason you went with >> the most restrictive capability ? > > I'm not familiar enough with the open-by-handle stuff to comment on the > permission constraints. Perhaps Dave or others can comment further on > this bit... > > Brian Thanks again Brian. The pointer to the AG stuff was really helpful. From bfoster@redhat.com Mon Nov 30 10:14:45 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 CEAD77F37 for ; Mon, 30 Nov 2015 10:14:44 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 6CBB6AC004 for ; Mon, 30 Nov 2015 08:14:41 -0800 (PST) X-ASG-Debug-ID: 1448900079-04bdf07f082d5f30001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id U9ZYeuhUCuuXsmnB (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 30 Nov 2015 08:14:40 -0800 (PST) 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 (Postfix) with ESMTPS id 62FD28F28B; Mon, 30 Nov 2015 16:14:39 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-132.bos.redhat.com [10.18.41.132]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAUGEcXM026342; Mon, 30 Nov 2015 11:14:39 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id 6FF3712013B; Mon, 30 Nov 2015 11:14:38 -0500 (EST) Date: Mon, 30 Nov 2015 11:14:38 -0500 From: Brian Foster To: Avi Kivity Cc: Glauber Costa , xfs@oss.sgi.com, david@fromorbit.com Subject: Re: sleeps and waits during io_submit Message-ID: <20151130161438.GD24765@bfoster.bfoster> X-ASG-Orig-Subj: Re: sleeps and waits during io_submit References: <20151130141000.GC24765@bfoster.bfoster> <565C5D39.8080300@scylladb.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <565C5D39.8080300@scylladb.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: 1448900080 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Mon, Nov 30, 2015 at 04:29:13PM +0200, Avi Kivity wrote: > > > On 11/30/2015 04:10 PM, Brian Foster wrote: > >>2) xfs_buf_lock -> down > >>This is one I truly don't understand. What can be causing contention > >>in this lock? We never have two different cores writing to the same > >>buffer, nor should we have the same core doingCAP_FOWNER so. > >> > >This is not one single lock. An XFS buffer is the data structure used to > >modify/log/read-write metadata on-disk and each buffer has its own lock > >to prevent corruption. Buffer lock contention is possible because the > >filesystem has bits of "global" metadata that has to be updated via > >buffers. > > > >For example, usually one has multiple allocation groups to maximize > >parallelism, but we still have per-ag metadata that has to be tracked > >globally with respect to each AG (e.g., free space trees, inode > >allocation trees, etc.). Any operation that affects this metadata (e.g., > >block/inode allocation) has to lock the agi/agf buffers along with any > >buffers associated with the modified btree leaf/node blocks, etc. > > > >One example in your attached perf traces has several threads looking to > >acquire the AGF, which is a per-AG data structure for tracking free > >space in the AG. One thread looks like the inode eviction case noted > >above (freeing blocks), another looks like a file truncate (also freeing > >blocks), and yet another is a block allocation due to a direct I/O > >write. Were any of these operations directed to an inode in a separate > >AG, they would be able to proceed in parallel (but I believe they would > >still hit the same codepaths as far as perf can tell). > > I guess we can mitigate (but not eliminate) this by creating more allocation > groups. What is the default value for agsize? Are there any downsides to > decreasing it, besides consuming more memory? > I suppose so, but I would be careful to check that you actually see contention and test that increasing agcount actually helps. As mentioned, I'm not sure off hand if the perf trace alone would look any different if you have multiple metadata operations in progress on separate AGs. My understanding is that there are diminishing returns to high AG counts and usually 32-64 is sufficient for most storage. Dave might be able to elaborate more on that... (I think this would make a good FAQ entry, actually). The agsize/agcount mkfs-time heuristics change depending on the type of storage. A single AG can be up to 1TB and if the fs is not considered "multidisk" (e.g., no stripe unit/width is defined), 4 AGs is the default up to 4TB. If a stripe unit is set, the agsize/agcount is adjusted depending on the size of the overall volume (see xfsprogs-dev/mkfs/xfs_mkfs.c:calc_default_ag_geometry() for details). > Are those locks held around I/O, or just CPU operations, or a mix? I believe it's a mix of modifications and I/O, though it looks like some of the I/O cases don't necessarily wait on the lock. E.g., the AIL pushing case will trylock and defer to the next list iteration if the buffer is busy. Brian From bfoster@redhat.com Mon Nov 30 10:16:44 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 4E0E87F37 for ; Mon, 30 Nov 2015 10:16:44 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 31E3B304066 for ; Mon, 30 Nov 2015 08:16:44 -0800 (PST) X-ASG-Debug-ID: 1448900202-04cb6c5354686c0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 4S34piFnVR2mf4tA (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 30 Nov 2015 08:16:43 -0800 (PST) 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 (Postfix) with ESMTPS id AA5EF688 for ; Mon, 30 Nov 2015 16:16:42 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-132.bos.redhat.com [10.18.41.132]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAUGGgdq015138 for ; Mon, 30 Nov 2015 11:16:42 -0500 Received: by bfoster.bfoster (Postfix, from userid 1000) id DD3D112013B; Mon, 30 Nov 2015 11:16:41 -0500 (EST) Date: Mon, 30 Nov 2015 11:16:41 -0500 From: Brian Foster To: xfs@oss.sgi.com Subject: Re: [PATCH] xfs_io: implement 'inode' command V5 Message-ID: <20151130161641.GE24765@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH] xfs_io: implement 'inode' command V5 References: <1448552795-8794-1-git-send-email-cmaiolino@redhat.com> <20151130132217.GA24765@bfoster.bfoster> <20151130142622.GA27492@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151130142622.GA27492@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: 1448900203 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Mon, Nov 30, 2015 at 03:26:22PM +0100, Carlos Maiolino wrote: > > > > I think we want "n:v" here since -n expects an argument, even if we > > don't process the arg here. > > Using getopt() to handle the -n argument, will make the inode command having 2 > different entry points for the same argument, i.e. the inode number. One as an > argument for -n, and another as an argument for the command itself, like: > > inode -n > inode > > We need to handle [num] as a stand-alone argument anyway, so, I just don't think > we need to handle the same argument in different ways, which I achieved by not > using [num] as a getopt() argument, but instead, handling [num] 'manually' > according to the options used in getopt(). > > Not sure if I could be clear or get things more confused :) > Sure, but I'm just referring to the error case when the user passes -n without an argument. This should return an error but it doesn't at the moment. I'm assuming that using "n:" would ensure the error message is printed without disrupting the other code (e.g., continue to process [num] manually even though "n:" is passed to getopt()). Is that the case? If not, the error could be detected/handled manually as well. Either way, a comment would also be useful here to document the special handling as you note above. > > > > + if (ret_next && verbose) > > > + return command_usage(&inode_cmd); > > > + > > > > Why is this not supported? Hmm, I see that -n returns an inode number > > and otherwise we print 0/1 or : with -v. Perhaps this would > > be easier if the command semantics/output were more consistent. E.g., > > > > "inode": print 0/1 based on largest inode size > > "inode -v": print : of largest inode > > "inode ": print if inode exists > > "inode -v ": print : if inode exists > > I thought about this, but I decided to not do it because the command looks a bit > redundant for me when 'inode number itself, if it exists, makes more sense to have a -v option here too. > Not sure I follow... AFAICT the command semantics change depending on whether an inode number is passed or not (irrespective of -n and -v). If not, we're looking to see if the largest inode is 32-bit or 64-bit. If an inode number is passed, we're checking to see if an inode exists. Brian > > "inode -n ": print if next inode exists > > "inode -nv ": print : if next inode exists > > Just FYI, if the 'next inode' doesn't exist (i.e. using the last fs inode as > argument), the ioctl will return 0 in bstat.bs_ino, which, I choose to leave it > as-is, and adding this observation to the man page, instead of returning a > messag like "no more inodes in the fs". > > I decided to leave it as-is, because for usage would be easier to parse a '0' > return value from -n argument, than parsing an error message which has the same > meaning of a zeroed return. > > > Anyway, I'm going add -v to the another options, just please take a look at my > replies regarding the 'inode -n' return value and the reason I didn't use > getopt() to handle -n argument and if you agree or not, so I'll rewrite the > patch to v6 based on this. > > Cheers o> > > -- > Carlos From spatel@omnifone.com Mon Nov 30 10:52:03 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 98BE17F37 for ; Mon, 30 Nov 2015 10:52:03 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 8355E304067 for ; Mon, 30 Nov 2015 08:52:03 -0800 (PST) X-ASG-Debug-ID: 1448902319-04cb6c5352693b0001-NocioJ Received: from mail1.bemta14.messagelabs.com (mail1.bemta14.messagelabs.com [193.109.254.107]) by cuda.sgi.com with ESMTP id ogtnXQmoFHGx6XE5 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 30 Nov 2015 08:52:00 -0800 (PST) X-Barracuda-Envelope-From: spatel@omnifone.com X-Barracuda-Apparent-Source-IP: 193.109.254.107 Received: from [193.109.255.147] by server-3.bemta-14.messagelabs.com id 45/73-25435-FAE7C565; Mon, 30 Nov 2015 16:51:59 +0000 X-Env-Sender: spatel@omnifone.com X-Msg-Ref: server-15.tower-72.messagelabs.com!1448902318!6297943!1 X-Originating-IP: [195.54.58.132] X-StarScan-Received: X-StarScan-Version: 7.19.2; banners=omnifone.com,-,- X-VirusChecked: Checked Received: (qmail 11268 invoked from network); 30 Nov 2015 16:51:58 -0000 Received: from brookgreen.ribob01.net (HELO EXFE1IS02.omnifone.com) (195.54.58.132) by server-15.tower-72.messagelabs.com with AES128-SHA encrypted SMTP; 30 Nov 2015 16:51:58 -0000 Received: from EXBE1IS02.omnifone.com ([::1]) by EXFE1IS02.omnifone.com ([::1]) with mapi id 14.01.0438.000; Mon, 30 Nov 2015 16:51:58 +0000 From: Sandeep Patel To: "xfs@oss.sgi.com" Subject: XFS corruptions Thread-Topic: XFS corruptions X-ASG-Orig-Subj: XFS corruptions Thread-Index: AdErjxENXmHY5tPxRXq2ndhekRd0vA== Date: Mon, 30 Nov 2015 16:51:57 +0000 Deferred-Delivery: Mon, 30 Nov 2015 16:51:00 +0000 Message-ID: <558408F298C8CE4C89D93BD56AB474E8018617B2B3@EXBE1IS02.omnifone.com> Accept-Language: en-GB, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.0.0.156] Content-Type: multipart/alternative; boundary="_000_558408F298C8CE4C89D93BD56AB474E8018617B2B3EXBE1IS02omni_" MIME-Version: 1.0 X-Barracuda-Connect: mail1.bemta14.messagelabs.com[193.109.254.107] X-Barracuda-Start-Time: 1448902319 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/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.24853 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_558408F298C8CE4C89D93BD56AB474E8018617B2B3EXBE1IS02omni_ Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Hi, We have multiple 22 disk raid 6 arrays using LSI 9280-24i4e raid cards, al= l using enterprise grade drives. The array is setup with physical drive ca= che disabled and mounted using inode64 with nobarriers option in Oracle Li= nux Server release 6.6, kernel version 3.8.13-55.1.5.el6uek.x86_64. We are= suffering from corruptions with xfs_repair unable to permanently fix the = the issues. Output of dmesg from the latest corruption. Pid: 5319, comm: glusterfsd Not tainted 3.8.13-55.1.5.el6uek.x86_64 #2 Call Trace: [] xfs_error_report+0x3f/0x50 [xfs] [] ? xfs_iread_extents+0x86/0x110 [xfs] [] xfs_corruption_error+0x5e/0x90 [xfs] [] xfs_bmap_read_extents+0x3f8/0x450 [xfs] [] ? xfs_iread_extents+0x86/0x110 [xfs] [] ? xfs_iext_realloc_direct+0xae/0x160 [xfs] [] xfs_iread_extents+0x86/0x110 [xfs] [] ? xfs_trans_free_item_desc+0x3c/0x50 [xfs] [] xfs_bmap_last_extent+0x95/0xb0 [xfs] [] xfs_bmap_last_offset+0x66/0xc0 [xfs] [] ? xfs_dir_lookup+0xc3/0x170 [xfs] [] xfs_dir2_isblock+0x26/0x60 [xfs] [] xfs_dir_lookup+0xc3/0x170 [xfs] [] xfs_lookup+0x87/0x110 [xfs] [] ? __d_alloc+0x14d/0x180 [] xfs_vn_lookup+0x54/0xa0 [xfs] [] ? lookup_dcache+0xa3/0xd0 [] lookup_real+0x1d/0x60 [] __lookup_hash+0x38/0x50 [] lookup_slow+0x4e/0xc0 [] path_lookupat+0x201/0x780 [] filename_lookup+0x34/0xc0 [] user_path_at_empty+0x59/0xa0 [] ? user_path_at+0x11/0x20 [] ? vfs_fstatat+0x50/0xb0 [] user_path_at+0x11/0x20 [] sys_linkat+0x78/0x250 [] ? __audit_syscall_exit+0x216/0x2c0 [] system_call_fastpath+0x16/0x1b XFS (sdb): Corruption detected. Unmount and run xfs_repair XFS (sdb): corrupt dinode 6442451040, (btree extents). ffff88042615d000: 42 4d 41 50 00 00 00 fe ff ff ff ff ff ff ff ff BMAP....= ........ XFS (sdb): Internal error xfs_bmap_read_extents(1) at line 1610 of file fs= /xfs/xfs_bmap.c. Caller 0xffffffffa02ed416 What could be causing these issues? Thanks for your help in advanced. ______________________________________________________________________ This email has been scanned by the Symantec Email Security.cloud service. For more information please visit http://www.symanteccloud.com ______________________________________________________________________ --_000_558408F298C8CE4C89D93BD56AB474E8018617B2B3EXBE1IS02omni_ Content-Type: text/html; charset="us-ascii" Content-Transfer-Encoding: quoted-printable

Hi,

&n= bsp;

We have= multiple 22 disk raid 6 arrays using LSI 9280-24i4e raid cards, all using= enterprise grade drives. The array is setup with physical drive cache disabled and mounted using inode64 with nobarriers option in = Oracle Linux Server release 6.6, kernel version 3.8.13-55.1.5.el6uek.x86_6= 4. We are suffering from corruptions with xfs_repair unable to permanently= fix the the issues. Output of dmesg from the latest corruption.

Pid: 5319, comm: glusterfsd Not tainted= 3.8.13-55.1.5.el6uek.x86_64 #2
Call Trace:
[<ffffffffa02a3a9f>] xfs_error_re= port+0x3f/0x50 [xfs]
[<ffffffffa02ed416>] ? xfs_iread_= extents+0x86/0x110 [xfs]
[<ffffffffa02a3b0e>] xfs_corrupti= on_error+0x5e/0x90 [xfs]
[<ffffffffa02c7ac8>] xfs_bmap_rea= d_extents+0x3f8/0x450 [xfs]
[<ffffffffa02ed416>] ? xfs_iread_= extents+0x86/0x110 [xfs]
[<ffffffffa02eb94e>] ? xfs_iext_r= ealloc_direct+0xae/0x160 [xfs]
[<ffffffffa02ed416>] xfs_iread_ex= tents+0x86/0x110 [xfs]
[<ffffffffa02fb0cc>] ? xfs_trans_= free_item_desc+0x3c/0x50 [xfs]
[<ffffffffa02c5df5>] xfs_bmap_las= t_extent+0x95/0xb0 [xfs]
[<ffffffffa02c5ef6>] xfs_bmap_las= t_offset+0x66/0xc0 [xfs]
[<ffffffffa02dc123>] ? xfs_dir_lo= okup+0xc3/0x170 [xfs]
[<ffffffffa02dbc96>] xfs_dir2_isb= lock+0x26/0x60 [xfs]
[<ffffffffa02dc123>] xfs_dir_look= up+0xc3/0x170 [xfs]
[<ffffffffa02b6497>] xfs_lookup&#= 43;0x87/0x110 [xfs]
[<ffffffff811a92ed>] ? __d_alloc&= #43;0x14d/0x180
[<ffffffffa02aea84>] xfs_vn_looku= p+0x54/0xa0 [xfs]
[<ffffffff8119db43>] ? lookup_dca= che+0xa3/0xd0
[<ffffffff8119d3ad>] lookup_real&= #43;0x1d/0x60
[<ffffffff8119dba8>] __lookup_has= h+0x38/0x50
[<ffffffff8119dc0e>] lookup_slow&= #43;0x4e/0xc0
[<ffffffff811a1d41>] path_lookupa= t+0x201/0x780
[<ffffffff811a22f4>] filename_loo= kup+0x34/0xc0
[<ffffffff811a35b9>] user_path_at= _empty+0x59/0xa0
[<ffffffff811a3611>] ? user_path_= at+0x11/0x20
[<ffffffff811986c0>] ? vfs_fstata= t+0x50/0xb0
[<ffffffff811a3611>] user_path_at= +0x11/0x20
[<ffffffff811a3698>] sys_linkat&#= 43;0x78/0x250
[<ffffffff810e37e6>] ? __audit_sy= scall_exit+0x216/0x2c0
[<ffffffff815a25d9>] system_call_= fastpath+0x16/0x1b
XFS (sdb): Corruption detected. Unmount= and run xfs_repair
XFS (sdb): corrupt dinode 6442451040, (= btree extents).
ffff88042615d000: 42 4d 41 50 00 00 00 = fe ff ff ff ff ff=20ff ff ff BMAP............
XFS (sdb): Internal error xfs_bmap_read= _extents(1) at line 1610 of file fs/xfs/xfs_bmap.c. Caller 0xffffffffa02ed= 416

What could be causing these issues?

Thanks for your help in advanced.<= /o:p>


______________________________________________________________________
= This email has been scanned by the Symantec Email Security.cloud service.<= BR> For more information please visit http://www.symanteccloud.com
______________________________________________________________________
= --_000_558408F298C8CE4C89D93BD56AB474E8018617B2B3EXBE1IS02omni_-- From eflorac@intellique.com Mon Nov 30 11:40:51 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 4E6F37F37 for ; Mon, 30 Nov 2015 11:40:51 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 2E2E58F8039 for ; Mon, 30 Nov 2015 09:40:50 -0800 (PST) X-ASG-Debug-ID: 1448905244-04cbb0605c2d1bf0001-NocioJ Received: from mail1.g1.pair.com (mail1.g1.pair.com [66.39.3.162]) by cuda.sgi.com with ESMTP id jbhQtI7LAW0vmHlU (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 30 Nov 2015 09:40:44 -0800 (PST) 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 027512CF89; Mon, 30 Nov 2015 12:40:44 -0500 (EST) Received: from harpe.intellique.com (labo.djinux.com [82.225.196.72]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail1.g1.pair.com (Postfix) with ESMTPSA id 231FA2CFA6; Mon, 30 Nov 2015 12:40:43 -0500 (EST) Date: Mon, 30 Nov 2015 18:40:48 +0100 From: Emmanuel Florac To: Sandeep Patel Cc: "xfs@oss.sgi.com" Subject: Re: XFS corruptions Message-ID: <20151130184048.3fa123e0@harpe.intellique.com> X-ASG-Orig-Subj: Re: XFS corruptions In-Reply-To: <558408F298C8CE4C89D93BD56AB474E8018617B2B3@EXBE1IS02.omnifone.com> References: <558408F298C8CE4C89D93BD56AB474E8018617B2B3@EXBE1IS02.omnifone.com> Organization: Intellique X-Mailer: Claws Mail 3.12.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: 1448905244 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24854 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Le Mon, 30 Nov 2015 16:51:57 +0000 Sandeep Patel =C3=A9crivait: >=20 > What could be causing these issues? >=20 > Thanks for your help in advanced. Hard to say, what does xfs_info /mountpoint says? Are the corruption occuring on all machines or do they target some systems more? Did you try repairing using the latest (4.2 or 4.3) version of xfs_repair? The Oracle Linux version is probably seriously out of date. --=20 ------------------------------------------------------------------------ Emmanuel Florac | Direction technique | Intellique | | +33 1 78 94 84 02 ------------------------------------------------------------------------ From spatel@omnifone.com Mon Nov 30 12:07:04 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 19DF329DF5 for ; Mon, 30 Nov 2015 12:07:04 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 09BF0304062 for ; Mon, 30 Nov 2015 10:07:00 -0800 (PST) X-ASG-Debug-ID: 1448906817-04cb6c53556b540001-NocioJ Received: from mail1.bemta5.messagelabs.com (mail1.bemta5.messagelabs.com [195.245.231.143]) by cuda.sgi.com with ESMTP id nL3uBXGXBUiLnmur (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 30 Nov 2015 10:06:58 -0800 (PST) X-Barracuda-Envelope-From: spatel@omnifone.com X-Barracuda-Apparent-Source-IP: 195.245.231.143 Received: from [85.158.136.51] by server-7.bemta-5.messagelabs.com id 0F/FB-13905-1409C565; Mon, 30 Nov 2015 18:06:57 +0000 X-Env-Sender: spatel@omnifone.com X-Msg-Ref: server-4.tower-49.messagelabs.com!1448906817!3555432!1 X-Originating-IP: [195.54.58.132] X-StarScan-Received: X-StarScan-Version: 7.19.2; banners=omnifone.com,-,- X-VirusChecked: Checked Received: (qmail 10463 invoked from network); 30 Nov 2015 18:06:57 -0000 Received: from brookgreen.ribob01.net (HELO EXFE1IS02.omnifone.com) (195.54.58.132) by server-4.tower-49.messagelabs.com with AES128-SHA encrypted SMTP; 30 Nov 2015 18:06:57 -0000 Received: from EXBE1IS02.omnifone.com ([::1]) by EXFE1IS02.omnifone.com ([::1]) with mapi id 14.01.0438.000; Mon, 30 Nov 2015 18:06:56 +0000 From: Sandeep Patel To: Emmanuel Florac CC: "xfs@oss.sgi.com" Subject: RE: XFS corruptions Thread-Topic: XFS corruptions X-ASG-Orig-Subj: RE: XFS corruptions Thread-Index: AdErjxENXmHY5tPxRXq2ndhekRd0vAABy5kAAAAX3HA= Date: Mon, 30 Nov 2015 18:06:55 +0000 Deferred-Delivery: Mon, 30 Nov 2015 18:06:00 +0000 Message-ID: <558408F298C8CE4C89D93BD56AB474E8018617B3A6@EXBE1IS02.omnifone.com> References: <558408F298C8CE4C89D93BD56AB474E8018617B2B3@EXBE1IS02.omnifone.com> <20151130184048.3fa123e0@harpe.intellique.com> In-Reply-To: <20151130184048.3fa123e0@harpe.intellique.com> Accept-Language: en-GB, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.0.0.156] Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 MIME-Version: 1.0 X-Barracuda-Connect: mail1.bemta5.messagelabs.com[195.245.231.143] X-Barracuda-Start-Time: 1448906818 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/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.24855 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.01 THREAD_INDEX thread-index: AcO7Y8iR61tzADqsRmmc5wNiFHEOig== 0.01 THREAD_TOPIC Thread-Topic: ...(Japanese Subject)... SGkgRW1tYW51ZWwsCgpUaGFua3MgZm9yIHRoZSByZXNwb25zZS4KCiBbcm9vdEBnYzAwM2Igfl0j IHhmc19pbmZvIC9kZXYvc2RiCm1ldGEtZGF0YT0vZGV2L3NkYiAgICAgICAgICAgICAgIGlzaXpl PTUxMiAgICBhZ2NvdW50PTUyLCBhZ3NpemU9MjY4NDM1NDU1IGJsa3MKICAgICAgICAgPSAgICAg ICAgICAgICAgICAgICAgICAgc2VjdHN6PTQwOTYgIGF0dHI9MiwgcHJvamlkMzJiaXQ9MQogICAg ICAgICA9ICAgICAgICAgICAgICAgICAgICAgICBjcmM9MApkYXRhICAgICA9ICAgICAgICAgICAg ICAgICAgICAgICBic2l6ZT00MDk2ICAgYmxvY2tzPTEzOTE2MTc2Mzg0LCBpbWF4cGN0PTEKICAg ICAgICAgPSAgICAgICAgICAgICAgICAgICAgICAgc3VuaXQ9MCAgICAgIHN3aWR0aD0wIGJsa3MK bmFtaW5nICAgPXZlcnNpb24gMiAgICAgICAgICAgICAgYnNpemU9NDA5NiAgIGFzY2lpLWNpPTAK bG9nICAgICAgPWludGVybmFsICAgICAgICAgICAgICAgYnNpemU9NDA5NiAgIGJsb2Nrcz01MjE3 MjgsIHZlcnNpb249MgogICAgICAgICA9ICAgICAgICAgICAgICAgICAgICAgICBzZWN0c3o9NDA5 NiAgc3VuaXQ9MSBibGtzLCBsYXp5LWNvdW50PTEKcmVhbHRpbWUgPW5vbmUgICAgICAgICAgICAg ICAgICAgZXh0c3o9NDA5NiAgIGJsb2Nrcz0wLCBydGV4dGVudHM9MAoKV2UgaGF2ZSAxOCBub2Rl cyBlYWNoIHdpdGggMiBvZiB0aGVzZSBhcnJheXMgYW5kIHdlIGFyZSBzZWVpbmcgdGhpcyBhY3Jv c3MgdGhlIGJvYXJkLgoKSSBoYXZlIHVwZGF0ZWQgdGhlIHhmc3Byb2dzIHRvIDMuMS4xMS0xLjAu Ni5lbDYueDg2XzY0IHdoaWNoIGlzIHRoZSBsYXRlc3QgdmVyc2lvbiBhdmFpbGFibGUgb24gb3Vy IHl1bSByZXBvLgoKVGhpcyBpcyBhIHByb2R1Y3Rpb24gc3lzdGVtIHNvIHVwZ3JhZGluZyB0byB0 aGUgbGF0ZXN0IHZlcnNpb24gaXMgbm90IHZlcnkgZWFzeS4gCgpUaGFua3MKU2FuZGVlcAoKLS0t LS1PcmlnaW5hbCBNZXNzYWdlLS0tLS0KRnJvbTogRW1tYW51ZWwgRmxvcmFjIFttYWlsdG86ZWZs b3JhY0BpbnRlbGxpcXVlLmNvbV0gClNlbnQ6IDMwIE5vdmVtYmVyIDIwMTUgMTc6NDEKVG86IFNh bmRlZXAgUGF0ZWwKQ2M6IHhmc0Bvc3Muc2dpLmNvbQpTdWJqZWN0OiBSZTogWEZTIGNvcnJ1cHRp b25zCgpMZSBNb24sIDMwIE5vdiAyMDE1IDE2OjUxOjU3ICswMDAwClNhbmRlZXAgUGF0ZWwgPHNw YXRlbEBvbW5pZm9uZS5jb20+IMOpY3JpdmFpdDoKCj4gCj4gV2hhdCBjb3VsZCBiZSBjYXVzaW5n IHRoZXNlIGlzc3Vlcz8KPiAKPiBUaGFua3MgZm9yIHlvdXIgaGVscCBpbiBhZHZhbmNlZC4KCkhh cmQgdG8gc2F5LCB3aGF0IGRvZXMgeGZzX2luZm8gL21vdW50cG9pbnQgc2F5cz8KCkFyZSB0aGUg Y29ycnVwdGlvbiBvY2N1cmluZyBvbiBhbGwgbWFjaGluZXMgb3IgZG8gdGhleSB0YXJnZXQgc29t ZSBzeXN0ZW1zIG1vcmU/CgpEaWQgeW91IHRyeSByZXBhaXJpbmcgdXNpbmcgdGhlIGxhdGVzdCAo NC4yIG9yIDQuMykgdmVyc2lvbiBvZiB4ZnNfcmVwYWlyPyBUaGUgT3JhY2xlIExpbnV4IHZlcnNp b24gaXMgcHJvYmFibHkgc2VyaW91c2x5IG91dCBvZiBkYXRlLgoKCi0tCi0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LQpFbW1hbnVlbCBGbG9yYWMgICAgIHwgICBEaXJlY3Rpb24gdGVjaG5pcXVlCiAgICAgICAgICAg ICAgICAgICAgfCAgIEludGVsbGlxdWUKICAgICAgICAgICAgICAgICAgICB8CTxlZmxvcmFjQGlu dGVsbGlxdWUuY29tPgogICAgICAgICAgICAgICAgICAgIHwgICArMzMgMSA3OCA5NCA4NCAwMgot LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0KCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX18KVGhpcyBlbWFpbCBoYXMgYmVlbiBzY2FubmVk IGJ5IHRoZSBTeW1hbnRlYyBFbWFpbCBTZWN1cml0eS5jbG91ZCBzZXJ2aWNlLgpGb3IgbW9yZSBp bmZvcm1hdGlvbiBwbGVhc2UgdmlzaXQgaHR0cDovL3d3dy5zeW1hbnRlY2Nsb3VkLmNvbSBfX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fCgpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fClRoaXMgZW1haWwgaGFzIGJlZW4gc2Nhbm5lZCBieSB0 aGUgU3ltYW50ZWMgRW1haWwgU2VjdXJpdHkuY2xvdWQgc2VydmljZS4KRm9yIG1vcmUgaW5mb3Jt YXRpb24gcGxlYXNlIHZpc2l0IGh0dHA6Ly93d3cuc3ltYW50ZWNjbG91ZC5jb20KX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fXwo= From eflorac@intellique.com Mon Nov 30 12:45:56 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 5065A29DF5 for ; Mon, 30 Nov 2015 12:45:56 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 17DA28F8039 for ; Mon, 30 Nov 2015 10:45:52 -0800 (PST) X-ASG-Debug-ID: 1448909149-04bdf07f0a2da4c0001-NocioJ Received: from mail1.g1.pair.com (mail1.g1.pair.com [66.39.3.162]) by cuda.sgi.com with ESMTP id 89mHmLXIpYHVGIyr (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 30 Nov 2015 10:45:50 -0800 (PST) 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 9AF9A2D123; Mon, 30 Nov 2015 13:45:49 -0500 (EST) Received: from harpe.intellique.com (labo.djinux.com [82.225.196.72]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail1.g1.pair.com (Postfix) with ESMTPSA id D71C32D11A; Mon, 30 Nov 2015 13:45:48 -0500 (EST) Date: Mon, 30 Nov 2015 19:45:54 +0100 From: Emmanuel Florac To: Sandeep Patel Cc: "xfs@oss.sgi.com" Subject: Re: XFS corruptions Message-ID: <20151130194554.6140bf30@harpe.intellique.com> X-ASG-Orig-Subj: Re: XFS corruptions In-Reply-To: <558408F298C8CE4C89D93BD56AB474E8018617B3A6@EXBE1IS02.omnifone.com> References: <558408F298C8CE4C89D93BD56AB474E8018617B2B3@EXBE1IS02.omnifone.com> <20151130184048.3fa123e0@harpe.intellique.com> <558408F298C8CE4C89D93BD56AB474E8018617B3A6@EXBE1IS02.omnifone.com> Organization: Intellique X-Mailer: Claws Mail 3.12.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: 1448909150 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24856 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Le Mon, 30 Nov 2015 18:06:55 +0000 Sandeep Patel =C3=A9crivait: > Hi Emmanuel, >=20 > Thanks for the response. >=20 > [root@gc003b ~]# xfs_info /dev/sdb > meta-data=3D/dev/sdb isize=3D512 agcount=3D52, > agsize=3D268435455 blks =3D sectsz=3D4096 attr=3D2, > projid32bit=3D1 =3D crc=3D0 > data =3D bsize=3D4096 blocks=3D13916176384, > imaxpct=3D1 =3D sunit=3D0 swidth=3D0 blks > naming =3Dversion 2 bsize=3D4096 ascii-ci=3D0 > log =3Dinternal bsize=3D4096 blocks=3D521728, versio= n=3D2 > =3D sectsz=3D4096 sunit=3D1 blks, > lazy-count=3D1 realtime =3Dnone extsz=3D4096 blocks= =3D0, > rtextents=3D0 Looks plain defaults... you didn't apply any customization, did you? >=20 > We have 18 nodes each with 2 of these arrays and we are seeing this > across the board. Hum, strange, are you running the latest RAID firmware on the controllers? Does this happen more often when the array is rebuilding, or verifying, or when the system is under heavy IO? Or does it happen just completely at random? =20 > I have updated the xfsprogs to 3.1.11-1.0.6.el6.x86_64 which is the > latest version available on our yum repo. If you're not afraid of running binaries from unknown source, here's a 4.2.0 version I've built recently: http://update.intellique.com/pub/xfs_repair-4.2.0.gz =20 --=20 ------------------------------------------------------------------------ Emmanuel Florac | Direction technique | Intellique | | +33 1 78 94 84 02 ------------------------------------------------------------------------ From amirsoroka@gmail.com Mon Nov 30 14:48:51 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 3237829DF5 for ; Mon, 30 Nov 2015 14:48:51 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 0BB6C30405F for ; Mon, 30 Nov 2015 12:48:50 -0800 (PST) X-ASG-Debug-ID: 1448916526-04cbb0605d2d7140001-NocioJ Received: from mail-lf0-f45.google.com (mail-lf0-f45.google.com [209.85.215.45]) by cuda.sgi.com with ESMTP id 2qwpr90bQgj0i2Op (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Mon, 30 Nov 2015 12:48:46 -0800 (PST) X-Barracuda-Envelope-From: amirsoroka@gmail.com X-Barracuda-Apparent-Source-IP: 209.85.215.45 Received: by lfaz4 with SMTP id z4so213882381lfa.0 for ; Mon, 30 Nov 2015 12:48:45 -0800 (PST) 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=KwgQChdnWdDazvaBGu/c9u/4L4a5yUB7vNVyE61vb8g=; b=HsfLbKcjOZBG605FrsGUfbe/49R+y6SVJwvWXrBWAoGkD7xj5zzTgqOWGqWsYBOWDz Ro2Hwut9X3PGUeHeRKWg0adp4pjel5HIAr1Q/3paekHXjOxhEnCdVdOUFPseImmuVanl nayfQbR5YwVQNm/mDrISZuvb0Ys77XOTr3NcPf/fFJVLZbQYVZ5AFmZKCGRBj4WP2a+7 vyn6eKBcxoXdl6gla5pa+Xe0vHqODola/ZNde/dKbtDGQ7WD7G1kmqGmnO0iXInFoZLF pSPpdZMpoH8qtjvfv1gJNNL3GPTdpMHstjsETFaru+dYSSDhtvHW5h6/3EwCrc4Al3zR 0rAA== MIME-Version: 1.0 X-Received: by 10.112.171.74 with SMTP id as10mr25449753lbc.137.1448916525310; Mon, 30 Nov 2015 12:48:45 -0800 (PST) Received: by 10.25.214.147 with HTTP; Mon, 30 Nov 2015 12:48:45 -0800 (PST) Date: Mon, 30 Nov 2015 22:48:45 +0200 Message-ID: Subject: XFS corruption - Ubuntu 14.04 VM with RDM From: Amir Soroka X-ASG-Orig-Subj: XFS corruption - Ubuntu 14.04 VM with RDM To: xfs@oss.sgi.com Content-Type: multipart/alternative; boundary=001a11c37fbaccec750525c82a2b X-Barracuda-Connect: mail-lf0-f45.google.com[209.85.215.45] X-Barracuda-Start-Time: 1448916526 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24858 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 --001a11c37fbaccec750525c82a2b Content-Type: text/plain; charset=UTF-8 Hello, We have a corruption issue. Would be happy to get a solution. Configuration is Ubuntu 14.04 (generic) as a VM over ESXi 5.5, with 1.6 TB RDM - storage has a Cache battery, Raid 6, SSD disks. During some heavy indexing activity we get a corruption as you can see below. Some more information: * Mount options: defaults,noatime,nodiratime,nobarrier,inode64,logbufs=8 0 0 * XFS was created like this: mkfs.xfs -f -d su=131072,sw=8 -i size=1024 /dev/sdb1 * Parted command was: /sbin/parted -s $i mklabel gpt mkpart /dev/sdb1 xfs 2048s 100% [ 10.395575] XFS (sdb1): Mounting V4 Filesystem [ 10.430107] XFS (sdb1): Ending clean mount [ 675.504000] XFS (sdb1): Metadata corruption detected at xfs_agf_read_verify+0x61/0x100 [xfs], block 0x1 [ 675.504043] XFS (sdb1): Unmount and run xfs_repair [ 675.504062] XFS (sdb1): First 64 bytes of corrupted metadata buffer: [ 675.504218] XFS (sdb1): metadata I/O error: block 0x1 ("xfs_trans_read_buf_map") error 117 numblks 1 [ 675.504257] XFS (sdb1): page discard on page ffffea003fbdc280, inode 0x86, offset 0. [ 677.186009] XFS (sdb1): Metadata corruption detected at xfs_agf_read_verify+0x61/0x100 [xfs], block 0x1 [ 677.186052] XFS (sdb1): Unmount and run xfs_repair [ 677.186070] XFS (sdb1): First 64 bytes of corrupted metadata buffer: [ 677.186239] XFS (sdb1): metadata I/O error: block 0x1 ("xfs_trans_read_buf_map") error 117 numblks 1 [ 677.186283] XFS (sdb1): page discard on page ffffea0000d8d480, inode 0x87, offset 0. [ 4203.145905] XFS (sdb1): Metadata corruption detected at xfs_agf_read_verify+0x61/0x100 [xfs], block 0x1 [ 4203.145957] XFS (sdb1): Unmount and run xfs_repair [ 4203.145976] XFS (sdb1): First 64 bytes of corrupted metadata buffer: [ 4203.146132] XFS (sdb1): metadata I/O error: block 0x1 ("xfs_trans_read_buf_map") error 117 numblks 1 [ 4203.146171] XFS (sdb1): page discard on page ffffea002c1399c0, inode 0x60003c0c, offset 0. [84997.832171] XFS (sdb1): Metadata corruption detected at xfs_inode_buf_verify+0x7d/0xe0 [xfs], block 0x110 [84997.835828] XFS (sdb1): Unmount and run xfs_repair [84997.836502] XFS (sdb1): First 64 bytes of corrupted metadata buffer: [84997.839848] XFS (sdb1): Metadata corruption detected at xfs_inode_buf_verify+0x7d/0xe0 [xfs], block 0x110 [84997.841188] XFS (sdb1): Unmount and run xfs_repair [84997.841872] XFS (sdb1): First 64 bytes of corrupted metadata buffer: [84997.845252] XFS (sdb1): Metadata corruption detected at xfs_inode_buf_verify+0x7d/0xe0 [xfs], block 0x110 [84997.846523] XFS (sdb1): Unmount and run xfs_repair [84997.847154] XFS (sdb1): First 64 bytes of corrupted metadata buffer: [84997.850467] XFS (sdb1): Metadata corruption detected at xfs_inode_buf_verify+0x7d/0xe0 [xfs], block 0x110 [84997.851714] XFS (sdb1): Unmount and run xfs_repair [84997.852319] XFS (sdb1): First 64 bytes of corrupted metadata buffer: [84997.855469] XFS (sdb1): Metadata corruption detected at xfs_inode_buf_verify+0x7d/0xe0 [xfs], block 0x110 [84997.856718] XFS (sdb1): Unmount and run xfs_repair [84997.857340] XFS (sdb1): First 64 bytes of corrupted metadata buffer: [84997.860366] XFS (sdb1): Metadata corruption detected at xfs_inode_buf_verify+0x7d/0xe0 [xfs], block 0x110 [84997.861521] XFS (sdb1): Unmount and run xfs_repair [84997.862117] XFS (sdb1): First 64 bytes of corrupted metadata buffer: [84997.865178] XFS (sdb1): Metadata corruption detected at xfs_inode_buf_verify+0x7d/0xe0 [xfs], block 0x110 [84997.866356] XFS (sdb1): Unmount and run xfs_repair [84997.866962] XFS (sdb1): First 64 bytes of corrupted metadata buffer: [84997.869987] XFS (sdb1): Metadata corruption detected at xfs_inode_buf_verify+0x7d/0xe0 [xfs], block 0x110 [84997.871163] XFS (sdb1): Unmount and run xfs_repair [84997.871760] XFS (sdb1): First 64 bytes of corrupted metadata buffer: [84997.874798] XFS (sdb1): metadata I/O error: block 0x110 ("xfs_trans_read_buf_map") error 117 numblks 16 [84997.875947] XFS (sdb1): xfs_do_force_shutdown(0x1) called from line 315 of file /build/linux-lts-vivid-6tG2ln/linux-lts-vivid-3.19.0/fs/xfs/xfs_trans_buf.c. Return address = 0xffffffffc02596ab [84997.888409] XFS (sdb1): I/O Error Detected. Shutting down filesystem [84997.889017] XFS (sdb1): Please umount the filesystem and rectify the problem(s) [84997.889643] XFS (sdb1): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [85011.531433] XFS (sdb1): xfs_log_force: error -5 returned. [85041.596418] XFS (sdb1): xfs_log_force: error -5 returned. [85071.661447] XFS (sdb1): xfs_log_force: error -5 returned. [85101.726398] XFS (sdb1): xfs_log_force: error -5 returned. [85131.791376] XFS (sdb1): xfs_log_force: error -5 returned. [85161.856372] XFS (sdb1): xfs_log_force: error -5 returned. [85191.921373] XFS (sdb1): xfs_log_force: error -5 returned. [85221.986341] XFS (sdb1): xfs_log_force: error -5 returned. [85252.051322] XFS (sdb1): xfs_log_force: error -5 returned. [85282.117357] XFS (sdb1): xfs_log_force: error -5 returned. [85312.181319] XFS (sdb1): xfs_log_force: error -5 returned. [85342.246276] XFS (sdb1): xfs_log_force: error -5 returned. [85372.311273] XFS (sdb1): xfs_log_force: error -5 returned. [85402.376250] XFS (sdb1): xfs_log_force: error -5 returned. [85432.441269] XFS (sdb1): xfs_log_force: error -5 returned. [85462.506208] XFS (sdb1): xfs_log_force: error -5 returned. [85492.571203] XFS (sdb1): xfs_log_force: error -5 returned. [85522.636192] XFS (sdb1): xfs_log_force: error -5 returned. [85552.701213] XFS (sdb1): xfs_log_force: error -5 returned. [85582.766164] XFS (sdb1): xfs_log_force: error -5 returned. [85612.831140] XFS (sdb1): xfs_log_force: error -5 returned. [85642.896133] XFS (sdb1): xfs_log_force: error -5 returned. [85672.961128] XFS (sdb1): xfs_log_force: error -5 returned. [85703.026104] XFS (sdb1): xfs_log_force: error -5 returned. [85733.091083] XFS (sdb1): xfs_log_force: error -5 returned. [85763.156070] XFS (sdb1): xfs_log_force: error -5 returned. [85793.221079] XFS (sdb1): xfs_log_force: error -5 returned. [85823.286041] XFS (sdb1): xfs_log_force: error -5 returned. [85853.351019] XFS (sdb1): xfs_log_force: error -5 returned. [85883.416016] XFS (sdb1): xfs_log_force: error -5 returned. [85913.481014] XFS (sdb1): xfs_log_force: error -5 returned. [85923.032422] XFS (sdb1): xfs_log_force: error -5 returned. [85923.033429] XFS (sdb1): xfs_log_force: error -5 returned. [85923.033601] XFS (sdb1): xfs_log_force: error -5 returned. [86173.742817] XFS (sdb1): Mounting V4 Filesystem [86173.780730] XFS (sdb1): Starting recovery (logdev: internal) [86173.787173] XFS (sdb1): Metadata corruption detected at xfs_agf_read_verify+0x61/0x100 [xfs], block 0x1 [86173.788445] XFS (sdb1): Unmount and run xfs_repair [86173.789072] XFS (sdb1): First 64 bytes of corrupted metadata buffer: [86173.792242] XFS (sdb1): metadata I/O error: block 0x1 ("xfs_trans_read_buf_map") error 117 numblks 1 [86187.845410] XFS (sdb1): Mounting V4 Filesystem [86187.881669] XFS (sdb1): Ending clean mount Thanks, Amir --001a11c37fbaccec750525c82a2b Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
Hello,
We have a corruption issue. Would be= happy to get a solution.

Configuration is Ubuntu = 14.04 (generic) as a VM over ESXi 5.5, with 1.6 TB RDM - storage has a Cach= e battery, Raid 6, SSD disks.
During some heavy indexing activity= we get a corruption as you can see below.
Some more information:=
* Mount options: defaults,noatime,nodiratime,nobarrier,inode64,l= ogbufs=3D8 0 0
* XFS was created like this: mkfs.xfs -f -d su=3D1= 31072,sw=3D8 -i size=3D1024 /dev/sdb1
* Parted command was: /sbin= /parted -s $i mklabel gpt mkpart /dev/sdb1 xfs 2048s 100%


[ =C2=A0 10.395575] XFS (sdb1): Mounting V4 Filesyst= em
[ =C2=A0 10.430107] XFS (sdb1): Ending clean mount
[= =C2=A0675.504000] XFS (sdb1): Metadata corruption detected at xfs_agf_read= _verify+0x61/0x100 [xfs], block 0x1
[ =C2=A0675.504043] XFS (sdb1= ): Unmount and run xfs_repair
[ =C2=A0675.504062] XFS (sdb1): Fir= st 64 bytes of corrupted metadata buffer:
[ =C2=A0675.504218] XFS= (sdb1): metadata I/O error: block 0x1 ("xfs_trans_read_buf_map")= error 117 numblks 1
[ =C2=A0675.504257] XFS (sdb1): page discard= on page ffffea003fbdc280, inode 0x86, offset 0.
[ =C2=A0677.1860= 09] XFS (sdb1): Metadata corruption detected at xfs_agf_read_verify+0x61/0x= 100 [xfs], block 0x1
[ =C2=A0677.186052] XFS (sdb1): Unmount and = run xfs_repair
[ =C2=A0677.186070] XFS (sdb1): First 64 bytes of = corrupted metadata buffer:
[ =C2=A0677.186239] XFS (sdb1): metada= ta I/O error: block 0x1 ("xfs_trans_read_buf_map") error 117 numb= lks 1
[ =C2=A0677.186283] XFS (sdb1): page discard on page ffffea= 0000d8d480, inode 0x87, offset 0.
[ 4203.145905] XFS (sdb1): Meta= data corruption detected at xfs_agf_read_verify+0x61/0x100 [xfs], block 0x1=
[ 4203.145957] XFS (sdb1): Unmount and run xfs_repair
= [ 4203.145976] XFS (sdb1): First 64 bytes of corrupted metadata buffer:
[ 4203.146132] XFS (sdb1): metadata I/O error: block 0x1 ("xfs_= trans_read_buf_map") error 117 numblks 1
[ 4203.146171] XFS = (sdb1): page discard on page ffffea002c1399c0, inode 0x60003c0c, offset 0.<= /div>
[84997.832171] XFS (sdb1): Metadata corruption detected at xfs_in= ode_buf_verify+0x7d/0xe0 [xfs], block 0x110
[84997.835828] XFS (s= db1): Unmount and run xfs_repair
[84997.836502] XFS (sdb1): First= 64 bytes of corrupted metadata buffer:
[84997.839848] XFS (sdb1)= : Metadata corruption detected at xfs_inode_buf_verify+0x7d/0xe0 [xfs], blo= ck 0x110
[84997.841188] XFS (sdb1): Unmount and run xfs_repair
[84997.841872] XFS (sdb1): First 64 bytes of corrupted metadata buf= fer:
[84997.845252] XFS (sdb1): Metadata corruption detected at x= fs_inode_buf_verify+0x7d/0xe0 [xfs], block 0x110
[84997.846523] X= FS (sdb1): Unmount and run xfs_repair
[84997.847154] XFS (sdb1): = First 64 bytes of corrupted metadata buffer:
[84997.850467] XFS (= sdb1): Metadata corruption detected at xfs_inode_buf_verify+0x7d/0xe0 [xfs]= , block 0x110
[84997.851714] XFS (sdb1): Unmount and run xfs_repa= ir
[84997.852319] XFS (sdb1): First 64 bytes of corrupted metadat= a buffer:
[84997.855469] XFS (sdb1): Metadata corruption detected= at xfs_inode_buf_verify+0x7d/0xe0 [xfs], block 0x110
[84997.8567= 18] XFS (sdb1): Unmount and run xfs_repair
[84997.857340] XFS (sd= b1): First 64 bytes of corrupted metadata buffer:
[84997.860366] = XFS (sdb1): Metadata corruption detected at xfs_inode_buf_verify+0x7d/0xe0 = [xfs], block 0x110
[84997.861521] XFS (sdb1): Unmount and run xfs= _repair
[84997.862117] XFS (sdb1): First 64 bytes of corrupted me= tadata buffer:
[84997.865178] XFS (sdb1): Metadata corruption det= ected at xfs_inode_buf_verify+0x7d/0xe0 [xfs], block 0x110
[84997= .866356] XFS (sdb1): Unmount and run xfs_repair
[84997.866962] XF= S (sdb1): First 64 bytes of corrupted metadata buffer:
[84997.869= 987] XFS (sdb1): Metadata corruption detected at xfs_inode_buf_verify+0x7d/= 0xe0 [xfs], block 0x110
[84997.871163] XFS (sdb1): Unmount and ru= n xfs_repair
[84997.871760] XFS (sdb1): First 64 bytes of corrupt= ed metadata buffer:
[84997.874798] XFS (sdb1): metadata I/O error= : block 0x110 ("xfs_trans_read_buf_map") error 117 numblks 16
[84997.875947] XFS (sdb1): xfs_do_force_shutdown(0x1) called from li= ne 315 of file /build/linux-lts-vivid-6tG2ln/linux-lts-vivid-3.19.0/fs/xfs/= xfs_trans_buf.c.=C2=A0 Return address =3D 0xffffffffc02596ab
[849= 97.888409] XFS (sdb1): I/O Error Detected. Shutting down filesystem
[84997.889017] XFS (sdb1): Please umount the filesystem and rectify the = problem(s)
[84997.889643] XFS (sdb1): xfs_imap_to_bp: xfs_trans_r= ead_buf() returned error -117.
[85011.531433] XFS (sdb1): xfs_log= _force: error -5 returned.
[85041.596418] XFS (sdb1): xfs_log_for= ce: error -5 returned.
[85071.661447] XFS (sdb1): xfs_log_force: = error -5 returned.
[85101.726398] XFS (sdb1): xfs_log_force: erro= r -5 returned.
[85131.791376] XFS (sdb1): xfs_log_force: error -5= returned.
[85161.856372] XFS (sdb1): xfs_log_force: error -5 ret= urned.
[85191.921373] XFS (sdb1): xfs_log_force: error -5 returne= d.
[85221.986341] XFS (sdb1): xfs_log_force: error -5 returned.
[85252.051322] XFS (sdb1): xfs_log_force: error -5 returned.
=
[85282.117357] XFS (sdb1): xfs_log_force: error -5 returned.
[85312.181319] XFS (sdb1): xfs_log_force: error -5 returned.
[85= 342.246276] XFS (sdb1): xfs_log_force: error -5 returned.
[85372.= 311273] XFS (sdb1): xfs_log_force: error -5 returned.
[85402.3762= 50] XFS (sdb1): xfs_log_force: error -5 returned.
[85432.441269] = XFS (sdb1): xfs_log_force: error -5 returned.
[85462.506208] XFS = (sdb1): xfs_log_force: error -5 returned.
[85492.571203] XFS (sdb= 1): xfs_log_force: error -5 returned.
[85522.636192] XFS (sdb1): = xfs_log_force: error -5 returned.
[85552.701213] XFS (sdb1): xfs_= log_force: error -5 returned.
[85582.766164] XFS (sdb1): xfs_log_= force: error -5 returned.
[85612.831140] XFS (sdb1): xfs_log_forc= e: error -5 returned.
[85642.896133] XFS (sdb1): xfs_log_force: e= rror -5 returned.
[85672.961128] XFS (sdb1): xfs_log_force: error= -5 returned.
[85703.026104] XFS (sdb1): xfs_log_force: error -5 = returned.
[85733.091083] XFS (sdb1): xfs_log_force: error -5 retu= rned.
[85763.156070] XFS (sdb1): xfs_log_force: error -5 returned= .
[85793.221079] XFS (sdb1): xfs_log_force: error -5 returned.
[85823.286041] XFS (sdb1): xfs_log_force: error -5 returned.
<= div>[85853.351019] XFS (sdb1): xfs_log_force: error -5 returned.
= [85883.416016] XFS (sdb1): xfs_log_force: error -5 returned.
[859= 13.481014] XFS (sdb1): xfs_log_force: error -5 returned.
[85923.0= 32422] XFS (sdb1): xfs_log_force: error -5 returned.
[85923.03342= 9] XFS (sdb1): xfs_log_force: error -5 returned.
[85923.033601] X= FS (sdb1): xfs_log_force: error -5 returned.
[86173.742817] XFS (= sdb1): Mounting V4 Filesystem
[86173.780730] XFS (sdb1): Starting= recovery (logdev: internal)
[86173.787173] XFS (sdb1): Metadata = corruption detected at xfs_agf_read_verify+0x61/0x100 [xfs], block 0x1
[86173.788445] XFS (sdb1): Unmount and run xfs_repair
[8617= 3.789072] XFS (sdb1): First 64 bytes of corrupted metadata buffer:
[86173.792242] XFS (sdb1): metadata I/O error: block 0x1 ("xfs_trans= _read_buf_map") error 117 numblks 1
[86187.845410] XFS (sdb1= ): Mounting V4 Filesystem
[86187.881669] XFS (sdb1): Ending clean= mount

Thanks,
Amir
--001a11c37fbaccec750525c82a2b-- From david@fromorbit.com Mon Nov 30 15:41:55 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 119F429DF5 for ; Mon, 30 Nov 2015 15:41:55 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id E712B304062 for ; Mon, 30 Nov 2015 13:41:51 -0800 (PST) X-ASG-Debug-ID: 1448919708-04bdf07f072e12f0001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id 8qDjlQZQnNl9cF2g for ; Mon, 30 Nov 2015 13:41:49 -0800 (PST) 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: A2ANCQAQwlxW/1bELHlegzuBQoJhqEAGiz+JPoYJAgIBAQKBOU0BAQEBAQGBAAuENQEBBDocIxAIAxgJJQ8FJQMhExuHfgMRtxMYhEwBAQgCASAZhXSFRYk5BZZXjS+BZJIthGeDcmOEGCo0hXEBAQE Received: from ppp121-44-196-86.lns20.syd7.internode.on.net (HELO dastard) ([121.44.196.86]) by ipmail07.adl2.internode.on.net with ESMTP; 01 Dec 2015 08:11:17 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1a3WC1-0006d1-08; Tue, 01 Dec 2015 08:41:05 +1100 Date: Tue, 1 Dec 2015 08:41:04 +1100 From: Dave Chinner To: "aluno3@poczta.onet.pl" Cc: xfs@oss.sgi.com Subject: Re: Which xfsprogs version to which kernel version Message-ID: <20151130214104.GL26718@dastard> X-ASG-Orig-Subj: Re: Which xfsprogs version to which kernel version References: <5656DD39.8060403@poczta.onet.pl> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <5656DD39.8060403@poczta.onet.pl> 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: 1448919708 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24859 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header On Thu, Nov 26, 2015 at 11:21:45AM +0100, aluno3@poczta.onet.pl wrote: > Hello, > > I am using kernel 3.10 and would like to update xfsprogs (currently I > have 3.1.5). > > When I tried to use the newest version of xfsprogs 4.3.0 I get the call > trace about detected version 5 of superblock when mounting volume which > was formatted using mkfs.xfs from 4.3.0. More recent xfsprogs versions enable features that are only supported by recent kernels. We tend to wait at least a year before enabling new features by default in xfsprogs so that kernel support is usually picke dup by distros before they update xfsprogs.... If you have an old kernel, then you need to turn off the newer features that your kernel does not support. This has always been the case - if you update the xfsprogs yourself, then you need to use the correct options for your kernel. In general, this: # mkfs.xfs -f -m crc=0 -n ftype=0 will make a filesystem that can be mounted on old kernels. If distros are shipping old kernels with new xfsprogs and are not changing the default behaviour to suit their kernel, then that is a distro problem. As it is, in future the version of xfsprogs will tell you what kernel has the same feature support. i.e. xfsprogs 4.2.0 has exactly the same code/feature support as kernel 4.2.0. Similarly for xfsprogs/kernel 4.3.0. However, this won't prevent the fact that xfsprogs 4.8.0 might enable features that kernel 4.3.0 does not know about - the only way to prevent that sort of problem is to never enable new features in mkfs.xfs, and that's not a viable solution. Cheers, Dave. -- Dave Chinner david@fromorbit.com From agruenba@redhat.com Mon Nov 30 15:44:23 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 6CDB629DF5 for ; Mon, 30 Nov 2015 15:44:23 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 4EE36304059 for ; Mon, 30 Nov 2015 13:44:23 -0800 (PST) X-ASG-Debug-ID: 1448919861-04cbb0605c2d8ed0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id pePFsJTFlzwpTxmS (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 30 Nov 2015 13:44:21 -0800 (PST) X-Barracuda-Envelope-From: agruenba@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 (Postfix) with ESMTPS id 2B9A6C0D2241; Mon, 30 Nov 2015 21:44:21 +0000 (UTC) Received: from nux.redhat.com (vpn1-6-54.ams2.redhat.com [10.36.6.54]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAULhiRQ010792; Mon, 30 Nov 2015 16:44:17 -0500 From: Andreas Gruenbacher To: Alexander Viro , Christoph Hellwig , linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org Cc: Andreas Gruenbacher , Dave Chinner , xfs@oss.sgi.com Subject: [PATCH 08/10] xfs: Change how listxattr generates synthetic attributes Date: Mon, 30 Nov 2015 22:43:41 +0100 X-ASG-Orig-Subj: [PATCH 08/10] xfs: Change how listxattr generates synthetic attributes Message-Id: <1448919823-27103-9-git-send-email-agruenba@redhat.com> In-Reply-To: <1448919823-27103-1-git-send-email-agruenba@redhat.com> References: <1448919823-27103-1-git-send-email-agruenba@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: 1448919861 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Instead of adding the synthesized POSIX ACL attribute names after listing all non-synthesized attributes, generate them immediately when listing the non-synthesized attributes. In addition, merge xfs_xattr_put_listent and xfs_xattr_put_listent_sizes to ensure that the list size is computed correctly; the split version was overestimating the list size for non-root users. Signed-off-by: Andreas Gruenbacher Cc: Dave Chinner Cc: xfs@oss.sgi.com --- fs/xfs/xfs_acl.c | 23 --------- fs/xfs/xfs_acl.h | 4 -- fs/xfs/xfs_xattr.c | 137 +++++++++++++++++++++++------------------------------ 3 files changed, 59 insertions(+), 105 deletions(-) diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c index 6bb470f..2d5df1f 100644 --- a/fs/xfs/xfs_acl.c +++ b/fs/xfs/xfs_acl.c @@ -252,29 +252,6 @@ xfs_set_mode(struct inode *inode, umode_t mode) return error; } -static int -xfs_acl_exists(struct inode *inode, unsigned char *name) -{ - int len = XFS_ACL_MAX_SIZE(XFS_M(inode->i_sb)); - - return (xfs_attr_get(XFS_I(inode), name, NULL, &len, - ATTR_ROOT|ATTR_KERNOVAL) == 0); -} - -int -posix_acl_access_exists(struct inode *inode) -{ - return xfs_acl_exists(inode, SGI_ACL_FILE); -} - -int -posix_acl_default_exists(struct inode *inode) -{ - if (!S_ISDIR(inode->i_mode)) - return 0; - return xfs_acl_exists(inode, SGI_ACL_DEFAULT); -} - int xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type) { diff --git a/fs/xfs/xfs_acl.h b/fs/xfs/xfs_acl.h index 52f8255..286fa89 100644 --- a/fs/xfs/xfs_acl.h +++ b/fs/xfs/xfs_acl.h @@ -24,16 +24,12 @@ struct posix_acl; #ifdef CONFIG_XFS_POSIX_ACL extern struct posix_acl *xfs_get_acl(struct inode *inode, int type); extern int xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type); -extern int posix_acl_access_exists(struct inode *inode); -extern int posix_acl_default_exists(struct inode *inode); #else static inline struct posix_acl *xfs_get_acl(struct inode *inode, int type) { return NULL; } # define xfs_set_acl NULL -# define posix_acl_access_exists(inode) 0 -# define posix_acl_default_exists(inode) 0 #endif /* CONFIG_XFS_POSIX_ACL */ extern void xfs_forget_acl(struct inode *inode, const char *name, int xflags); diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c index 36a4385..110f1d7 100644 --- a/fs/xfs/xfs_xattr.c +++ b/fs/xfs/xfs_xattr.c @@ -129,47 +129,19 @@ const struct xattr_handler *xfs_xattr_handlers[] = { NULL }; -static unsigned int xfs_xattr_prefix_len(int flags) -{ - if (flags & XFS_ATTR_SECURE) - return sizeof("security"); - else if (flags & XFS_ATTR_ROOT) - return sizeof("trusted"); - else - return sizeof("user"); -} - -static const char *xfs_xattr_prefix(int flags) -{ - if (flags & XFS_ATTR_SECURE) - return xfs_xattr_security_handler.prefix; - else if (flags & XFS_ATTR_ROOT) - return xfs_xattr_trusted_handler.prefix; - else - return xfs_xattr_user_handler.prefix; -} - static int -xfs_xattr_put_listent( +__xfs_xattr_put_listent( struct xfs_attr_list_context *context, - int flags, - unsigned char *name, - int namelen, - int valuelen, - unsigned char *value) + char *prefix, + int prefix_len, + unsigned char *name, + int namelen) { - unsigned int prefix_len = xfs_xattr_prefix_len(flags); char *offset; int arraytop; - ASSERT(context->count >= 0); - - /* - * Only show root namespace entries if we are actually allowed to - * see them. - */ - if ((flags & XFS_ATTR_ROOT) && !capable(CAP_SYS_ADMIN)) - return 0; + if (!context->alist) + goto compute_size; arraytop = context->count + prefix_len + namelen + 1; if (arraytop > context->firstu) { @@ -177,17 +149,19 @@ xfs_xattr_put_listent( return 1; } offset = (char *)context->alist + context->count; - strncpy(offset, xfs_xattr_prefix(flags), prefix_len); + strncpy(offset, prefix, prefix_len); offset += prefix_len; strncpy(offset, (char *)name, namelen); /* real name */ offset += namelen; *offset = '\0'; + +compute_size: context->count += prefix_len + namelen + 1; return 0; } static int -xfs_xattr_put_listent_sizes( +xfs_xattr_put_listent( struct xfs_attr_list_context *context, int flags, unsigned char *name, @@ -195,24 +169,55 @@ xfs_xattr_put_listent_sizes( int valuelen, unsigned char *value) { - context->count += xfs_xattr_prefix_len(flags) + namelen + 1; - return 0; -} + char *prefix; + int prefix_len; -static int -list_one_attr(const char *name, const size_t len, void *data, - size_t size, ssize_t *result) -{ - char *p = data + *result; + ASSERT(context->count >= 0); - *result += len; - if (!size) - return 0; - if (*result > size) - return -ERANGE; + if (flags & XFS_ATTR_ROOT) { +#ifdef CONFIG_XFS_POSIX_ACL + if (namelen == SGI_ACL_FILE_SIZE && + strncmp(name, SGI_ACL_FILE, + SGI_ACL_FILE_SIZE) == 0) { + int ret = __xfs_xattr_put_listent( + context, XATTR_SYSTEM_PREFIX, + XATTR_SYSTEM_PREFIX_LEN, + XATTR_POSIX_ACL_ACCESS, + strlen(XATTR_POSIX_ACL_ACCESS)); + if (ret) + return ret; + } else if (namelen == SGI_ACL_DEFAULT_SIZE && + strncmp(name, SGI_ACL_DEFAULT, + SGI_ACL_DEFAULT_SIZE) == 0) { + int ret = __xfs_xattr_put_listent( + context, XATTR_SYSTEM_PREFIX, + XATTR_SYSTEM_PREFIX_LEN, + XATTR_POSIX_ACL_DEFAULT, + strlen(XATTR_POSIX_ACL_DEFAULT)); + if (ret) + return ret; + } +#endif - strcpy(p, name); - return 0; + /* + * Only show root namespace entries if we are actually allowed to + * see them. + */ + if (!capable(CAP_SYS_ADMIN)) + return 0; + + prefix = XATTR_TRUSTED_PREFIX; + prefix_len = XATTR_TRUSTED_PREFIX_LEN; + } else if (flags & XFS_ATTR_SECURE) { + prefix = XATTR_SECURITY_PREFIX; + prefix_len = XATTR_SECURITY_PREFIX_LEN; + } else { + prefix = XATTR_USER_PREFIX; + prefix_len = XATTR_USER_PREFIX_LEN; + } + + return __xfs_xattr_put_listent(context, prefix, prefix_len, name, + namelen); } ssize_t @@ -221,7 +226,6 @@ xfs_vn_listxattr(struct dentry *dentry, char *data, size_t size) struct xfs_attr_list_context context; struct attrlist_cursor_kern cursor = { 0 }; struct inode *inode = d_inode(dentry); - int error; /* * First read the regular on-disk attributes. @@ -230,37 +234,14 @@ xfs_vn_listxattr(struct dentry *dentry, char *data, size_t size) context.dp = XFS_I(inode); context.cursor = &cursor; context.resynch = 1; - context.alist = data; + context.alist = size ? data : NULL; context.bufsize = size; context.firstu = context.bufsize; - - if (size) - context.put_listent = xfs_xattr_put_listent; - else - context.put_listent = xfs_xattr_put_listent_sizes; + context.put_listent = xfs_xattr_put_listent; xfs_attr_list_int(&context); if (context.count < 0) return -ERANGE; - /* - * Then add the two synthetic ACL attributes. - */ - if (posix_acl_access_exists(inode)) { - error = list_one_attr(XATTR_NAME_POSIX_ACL_ACCESS, - strlen(XATTR_NAME_POSIX_ACL_ACCESS) + 1, - data, size, &context.count); - if (error) - return error; - } - - if (posix_acl_default_exists(inode)) { - error = list_one_attr(XATTR_NAME_POSIX_ACL_DEFAULT, - strlen(XATTR_NAME_POSIX_ACL_DEFAULT) + 1, - data, size, &context.count); - if (error) - return error; - } - return context.count; } -- 2.5.0 From david@fromorbit.com Mon Nov 30 15:51:32 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 BA66C29DF5 for ; Mon, 30 Nov 2015 15:51:32 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 9C5FB8F8033 for ; Mon, 30 Nov 2015 13:51:29 -0800 (PST) X-ASG-Debug-ID: 1448920285-04cbb0605c2d9120001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id Tjfxos907ygwGRlY for ; Mon, 30 Nov 2015 13:51:26 -0800 (PST) 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: A2CxCAApxFxW/1bELHlegzuBQoJhqEAGiz+JPoYJBAICgTlNAQEBAQEBgQuENQEBBDocIxAIAw4KCSUPBSUDIROILbt9AQEIAiEZhXSFRYRChHcFlleNL4FklxSDcmOCER2Baio0hXEBAQE Received: from ppp121-44-196-86.lns20.syd7.internode.on.net (HELO dastard) ([121.44.196.86]) by ipmail07.adl2.internode.on.net with ESMTP; 01 Dec 2015 08:21:25 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1a3WLo-0006f0-9r; Tue, 01 Dec 2015 08:51:12 +1100 Date: Tue, 1 Dec 2015 08:51:12 +1100 From: Dave Chinner To: Sandeep Patel Cc: "xfs@oss.sgi.com" Subject: Re: XFS corruptions Message-ID: <20151130215112.GM26718@dastard> X-ASG-Orig-Subj: Re: XFS corruptions References: <558408F298C8CE4C89D93BD56AB474E8018617B2B3@EXBE1IS02.omnifone.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <558408F298C8CE4C89D93BD56AB474E8018617B2B3@EXBE1IS02.omnifone.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: 1448920285 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24860 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Mon, Nov 30, 2015 at 04:51:57PM +0000, Sandeep Patel wrote: > Hi, > > We have multiple 22 disk raid 6 arrays using LSI 9280-24i4e raid > cards, all using enterprise grade drives. The array is setup with > physical drive cache disabled and mounted using inode64 with > nobarriers option in Oracle Linux Server release 6.6, kernel > version 3.8.13-55.1.5.el6uek.x86_64. We are suffering from > corruptions with xfs_repair unable to permanently fix the the > issues. Output of dmesg from the latest corruption. > > Pid: 5319, comm: glusterfsd Not tainted 3.8.13-55.1.5.el6uek.x86_64 #2 FYI, we cannot really support vendor enterprise on the upstream lists because the code base is so different from vanilla/upstream kernels. I same exactly the same thing for bugs reported on RHEL/CentOS kernels, and for SLES kernels - only the vendor can properly support their own franken-kernels... Hence I'd suggest that you report the problem to your Oracle support contact so they can walk you through the process of finding the problem.... [ Darrick is really going to thank me for saying this. ] Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Mon Nov 30 16:01:29 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 8A54029DF5 for ; Mon, 30 Nov 2015 16:01:29 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 2B48AAC003 for ; Mon, 30 Nov 2015 14:01:26 -0800 (PST) X-ASG-Debug-ID: 1448920882-04bdf07f072e1ba0001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id gIheOmz2eTFNgLy7 for ; Mon, 30 Nov 2015 14:01:22 -0800 (PST) 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: A2DUCADwxlxW/1bELHlEGoM7U2+CYYo4nggGiz+JPiOFZgQCAoE5TQEBAQEBAYELhDQBAQEDATocIwULCAMYCSUPBSUDIRMbiAsHDju7OgEBCAIhGYV0hUWEJCCEdQWWV4UqiAWBZIRClkRjgg4DHYFqKjQBhCeBSQEBAQ Received: from ppp121-44-196-86.lns20.syd7.internode.on.net (HELO dastard) ([121.44.196.86]) by ipmail07.adl2.internode.on.net with ESMTP; 01 Dec 2015 08:30:52 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1a3WUx-0006h1-WD; Tue, 01 Dec 2015 09:00:40 +1100 Date: Tue, 1 Dec 2015 09:00:39 +1100 From: Dave Chinner To: Amir Soroka Cc: xfs@oss.sgi.com Subject: Re: XFS corruption - Ubuntu 14.04 VM with RDM Message-ID: <20151130220039.GN26718@dastard> X-ASG-Orig-Subj: Re: XFS corruption - Ubuntu 14.04 VM with RDM 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: 1448920882 X-Barracuda-URL: https://192.48.157.11:443/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.24860 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 BSF_SC0_SA085 Custom Rule SA085 On Mon, Nov 30, 2015 at 10:48:45PM +0200, Amir Soroka wrote: > Hello, > We have a corruption issue. Would be happy to get a solution. > > Configuration is Ubuntu 14.04 (generic) as a VM over ESXi 5.5, with 1.6 TB > RDM - storage has a Cache battery, Raid 6, SSD disks. Please reproduce on bare metal, and with a recent kernel. > During some heavy indexing activity we get a corruption as you can see > below. Doesn't tell me anything about the workload. Please include: http://xfs.org/index.php/XFS_FAQ#Q:_What_information_should_I_include_when_reporting_a_problem.3F > Some more information: > * Mount options: defaults,noatime,nodiratime,nobarrier,inode64,logbufs=8 0 0 > * XFS was created like this: mkfs.xfs -f -d su=131072,sw=8 -i size=1024 > /dev/sdb1 > * Parted command was: /sbin/parted -s $i mklabel gpt mkpart /dev/sdb1 xfs > 2048s 100% > > > [ 10.395575] XFS (sdb1): Mounting V4 Filesystem > [ 10.430107] XFS (sdb1): Ending clean mount > [ 675.504000] XFS (sdb1): Metadata corruption detected at > xfs_agf_read_verify+0x61/0x100 [xfs], block 0x1 There should be lots more error logging than that. Where are the stack traces, the hex dumps, etc that go along with normal corruption reports? > [84997.869987] XFS (sdb1): Metadata corruption detected at > xfs_inode_buf_verify+0x7d/0xe0 [xfs], block 0x110 There's more than one type of corruption - I'd suggest that you have a vmware/esx level problem.... > [84997.871163] XFS (sdb1): Unmount and run xfs_repair > [84997.871760] XFS (sdb1): First 64 bytes of corrupted metadata buffer: > [84997.874798] XFS (sdb1): metadata I/O error: block 0x110 Yup, you've removed all the detailed corruption information in the output. i.e. all the bits that might tell us what went wrong. Please post the logs *in full*. Cheers, Dave. -- Dave Chinner david@fromorbit.com From darrick.wong@oracle.com Mon Nov 30 16:04:33 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id DC48F29DF5 for ; Mon, 30 Nov 2015 16:04:32 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 7CD75AC007 for ; Mon, 30 Nov 2015 14:04:32 -0800 (PST) X-ASG-Debug-ID: 1448921070-04bdf07f082e1cd0001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id hYNjU5wATMsQrbir (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 30 Nov 2015 14:04:30 -0800 (PST) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id tAUM4PMu031326 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Mon, 30 Nov 2015 22:04:26 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id tAUM4PLl017967 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Mon, 30 Nov 2015 22:04:25 GMT Received: from abhmp0009.oracle.com (abhmp0009.oracle.com [141.146.116.15]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id tAUM4OLY010838; Mon, 30 Nov 2015 22:04:25 GMT Received: from localhost (/10.145.178.207) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Mon, 30 Nov 2015 14:04:24 -0800 Date: Mon, 30 Nov 2015 14:04:23 -0800 From: "Darrick J. Wong" To: Dave Chinner Cc: Sandeep Patel , "xfs@oss.sgi.com" Subject: Re: XFS corruptions Message-ID: <20151130220423.GA16277@birch.djwong.org> X-ASG-Orig-Subj: Re: XFS corruptions References: <558408F298C8CE4C89D93BD56AB474E8018617B2B3@EXBE1IS02.omnifone.com> <20151130215112.GM26718@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151130215112.GM26718@dastard> User-Agent: Mutt/1.5.21 (2010-09-15) X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1448921070 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24860 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines On Tue, Dec 01, 2015 at 08:51:12AM +1100, Dave Chinner wrote: > On Mon, Nov 30, 2015 at 04:51:57PM +0000, Sandeep Patel wrote: > > Hi, > > > > We have multiple 22 disk raid 6 arrays using LSI 9280-24i4e raid > > cards, all using enterprise grade drives. The array is setup with > > physical drive cache disabled and mounted using inode64 with > > nobarriers option in Oracle Linux Server release 6.6, kernel > > version 3.8.13-55.1.5.el6uek.x86_64. We are suffering from > > corruptions with xfs_repair unable to permanently fix the the > > issues. Output of dmesg from the latest corruption. > > > > Pid: 5319, comm: glusterfsd Not tainted 3.8.13-55.1.5.el6uek.x86_64 #2 > > FYI, we cannot really support vendor enterprise on the upstream lists > because the code base is so different from vanilla/upstream kernels. > I same exactly the same thing for bugs reported on RHEL/CentOS > kernels, and for SLES kernels - only the vendor can properly support > their own franken-kernels... > > Hence I'd suggest that you report the problem to your Oracle support > contact so they can walk you through the process of finding the > problem.... > > [ Darrick is really going to thank me for saying this. ] Probably what I'd have written anyway. :) Oracle support might just tell you to upgrade the kernel whatever the latest is. 3.8.13-55 is pretty far back AFAIK. (Is not a support engineer, nor do I play one on TV.) --D > > Cheers, > > Dave. > -- > Dave Chinner > david@fromorbit.com > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From david@fromorbit.com Mon Nov 30 17:12:47 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 647CC29DF5 for ; Mon, 30 Nov 2015 17:12:47 -0600 (CST) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 024FEAC005 for ; Mon, 30 Nov 2015 15:12:46 -0800 (PST) X-ASG-Debug-ID: 1448925158-04bdf07f092e3640001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id AciB4m71McPXacaE for ; Mon, 30 Nov 2015 15:12:38 -0800 (PST) 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: A2AwCQBX11xW/1bELHlWCIM7U2+CYYo4nggGiz+JPiGFaAICAQECgTdNAQEBAQEBgQuENAEBAQMBJxMcIwULCAMSBgklDwUlAw0UEwmIHQcOvA4BAQEBBgIhGYV0hD+BBoJxgUWFAwWSWYN+hSqIBYFkhEKDJniEdoRXiFljghEdgWoqNIVxAQEB Received: from ppp121-44-196-86.lns20.syd7.internode.on.net (HELO dastard) ([121.44.196.86]) by ipmail07.adl2.internode.on.net with ESMTP; 01 Dec 2015 09:40:40 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1a3XaV-0006r0-SD; Tue, 01 Dec 2015 10:10:27 +1100 Date: Tue, 1 Dec 2015 10:10:27 +1100 From: Dave Chinner To: Glauber Costa Cc: xfs@oss.sgi.com, Avi Kivity Subject: Re: sleeps and waits during io_submit Message-ID: <20151130231027.GO26718@dastard> X-ASG-Orig-Subj: Re: sleeps and waits during io_submit 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: 1448925158 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-BRTS-Evidence: kernelhub.org X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24861 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri, Nov 27, 2015 at 09:43:50PM -0500, Glauber Costa wrote: > Hello my dear XFSers, > > For those of you who don't know, we at ScyllaDB produce a modern NoSQL > data store that, at the moment, runs on top of XFS only. We deal > exclusively with asynchronous and direct IO, due to our > thread-per-core architecture. Due to that, we avoid issuing any > operation that will sleep. > > While debugging an extreme case of bad performance (most likely > related to a not-so-great disk), I have found a variety of cases in > which XFS blocks. To find those, I have used perf record -e > sched:sched_switch -p , and I am attaching the perf report > as xfs-sched_switch.log. Please note that this doesn't tell me for how > long we block, but as mentioned before, blocking operations outside > our control are detrimental to us regardless of the elapsed time. > > For those who are not acquainted to our internals, please ignore > everything in that file but the xfs functions. For the xfs symbols, > there are two kinds of events: the ones that are a children of > io_submit, where we don't tolerate blocking, and the ones that are > children of our helper IO thread, to where we push big operations that > we know will block until we can get rid of them all. We care about the > former and ignore the latter. > > Please allow me to ask you a couple of questions about those findings. > If we are doing anything wrong, advise on best practices is truly > welcome. > > 1) xfs_buf_lock -> xfs_log_force. > > I've started wondering what would make xfs_log_force sleep. But then I > have noticed that xfs_log_force will only be called when a buffer is > marked stale. Most of the times a buffer is marked stale seems to be > due to errors. Although that is not my case (more on that), it got me > thinking that maybe the right thing to do would be to avoid hitting > this case altogether? The buffer is stale because it has recently been freed, and we cannot re-use it until the transaction that freed it has been committed to the journal. e.g. this trace: --3.15%-- _xfs_log_force xfs_log_force xfs_buf_lock _xfs_buf_find xfs_buf_get_map xfs_trans_get_buf_map xfs_btree_get_bufl xfs_bmap_extents_to_btree xfs_bmap_add_extent_hole_real xfs_bmapi_write xfs_iomap_write_direct __xfs_get_blocks xfs_get_blocks_direct do_blockdev_direct_IO __blockdev_direct_IO xfs_vm_direct_IO xfs_file_dio_aio_write xfs_file_write_iter aio_run_iocb do_io_submit sys_io_submit entry_SYSCALL_64_fastpath io_submit 0x46d98a implies something like this has happened: truncate free extent extent list now fits inline in inode btree-to-extent format change free last bmbt block X mark block contents stale add block to busy extent list place block on AGFL AIO write allocate extent inline extents full extent-to-btree conversion allocate bmbt block grab block X from free list get locked buffer for block X xfs_buf_lock buffer stale log force to commit previous free transaction to disk ..... log force completes buffer removed from busy extent list buffer no longer stale add bmbt record to new block update btree indexes .... And, looking at the trace you attached, we see this: dump_stack xfs_buf_stale xfs_trans_binval xfs_bmap_btree_to_extents <<<<<<<<< xfs_bunmapi xfs_itruncate_extents So I'd say this is a pretty clear indication that we're immediately recycling freed blocks from the free list here.... > The file example-stale.txt contains a backtrace of the case where we > are being marked as stale. It seems to be happening when we convert > the the inode's extents from unwritten to real. Can this case be > avoided? I won't pretend I know the intricacies of this, but couldn't > we be keeping extents from the very beginning to avoid creating stale > buffers? > > 2) xfs_buf_lock -> down > This is one I truly don't understand. What can be causing contention > in this lock? We never have two different cores writing to the same > buffer, nor should we have the same core doingCAP_FOWNER so. As Brian pointed out, this is probably AGF or AGI contention - attempting to allocate/free extents or inodes in the same AG at the same time will show this sort of pattern. This trace shows AGF contention: down xfs_buf_lock _xfs_buf_find xfs_buf_get_map xfs_buf_read_map xfs_trans_read_buf_map xfs_read_agf ..... This trace shows AGI contention: down xfs_buf_lock _xfs_buf_find xfs_buf_get_map xfs_buf_read_map xfs_trans_read_buf_map xfs_read_agi .... > 3) xfs_file_aio_write_checks -> file_update_time -> xfs_vn_update_time This trace?: rwsem_down_write_failed call_rwsem_down_write_failed xfs_ilock xfs_vn_update_time file_update_time xfs_file_aio_write_checks xfs_file_dio_aio_write xfs_file_write_iter aio_run_iocb do_io_submit sys_io_submit entry_SYSCALL_64_fastpath io_submit 0x46d98a Which is an mtime timestamp update racing with another operation that takes the internal metadata lock (e.g. block mapping/allocation for that inode). > You guys seem to have an interface to avoid that, by setting the > FMODE_NOCMTIME flag. We've talked about exposing this through open() for Ceph. http://www.kernelhub.org/?p=2&msg=744325 https://lkml.org/lkml/2015/5/15/671 Read the first thread for why it's problematic to expose this to userspace - I won't repeat it all here. As it is, there was some code recently hacked into ext4 to reduce mtime overhead - the MS_LAZYTIME superblock option. What it does it prevent the inode from being marked dirty when timestamps are updated and hence the timestamps are never journalled or written until something else marks the inode metadata dirty (e.g. block allocation). ext4 gets away with this because it doesn't actually journal timestamp changes - they get captured in the journal by other modifications that are journalled, but still rely on the inod being marked dirty for fsync, writeback and inode cache eviction doing the right thing. The ext4 implementation looks like the timestamp updates can be thrown away, as the inodes are not marked dirty and so on memory pressure they will simply be reclaimed without writing back the updated timestamps that are held in memory. I suspect fsync will also have problems on ext4 as the inode is not metadata dirty or journalled, and hence the timestamp changes will never get written back. And, IMO, the worst part of the ext4 implementation is that the inode buffer writeback code in ext4 now checks to see if any of the other inodes in the buffer being written back need to have their inode timestamps updated. IOWs, ext4 now does writeback of /unjournalled metadata/ to inodes that are purely timestamp dirty. We /used/ to do shit like this in XFS. We got rid of it in preference of journalling everything because the corner cases in log recovery meant that after a crash the inodes were in inconsistent states, and that meant we had unexpected, unpredictable recovery behaviour where files weren't the expected size and/or didn't contain the expected data. Hence going back to the bad old days of hacking around the journal "for speed" doesn't exactly fill me with joy. Let me have a think about how we can implement lazytime in a sane way, such that fsync() works correctly, we don't throw away timstamp changes in memory reclaim and we don't write unlogged changes to the on-disk locations.... Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Mon Nov 30 17:44:46 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none 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 533F729DF5 for ; Mon, 30 Nov 2015 17:44:46 -0600 (CST) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 36A788F8033 for ; Mon, 30 Nov 2015 15:44:43 -0800 (PST) X-ASG-Debug-ID: 1448927079-04cbb0605b2dc9e0001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id 2Y1He44WXHTGyfSS for ; Mon, 30 Nov 2015 15:44:40 -0800 (PST) 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: A2AMCQBh3lxW/1bELHlegzuBQoJhqEAGiz+JPoYJAgIBAQKBN00BAQEBAQGBC4Q0AQEBAwE6HCMFCwgDDgoJDBkPBSUDIROIJge8GAEBAQcCASAZhXSFRYQ0ZoQfBZZXjS+BZIdokx5jghEdgWoqNIQngUoBAQE Received: from ppp121-44-196-86.lns20.syd7.internode.on.net (HELO dastard) ([121.44.196.86]) by ipmail07.adl2.internode.on.net with ESMTP; 01 Dec 2015 10:14:39 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1a3Y7O-0006ty-B0; Tue, 01 Dec 2015 10:44:26 +1100 Date: Tue, 1 Dec 2015 10:44:26 +1100 From: Dave Chinner To: Lutz Vieweg Cc: xfs@oss.sgi.com Subject: Re: Does XFS support cgroup writeback limiting? Message-ID: <20151130234426.GP26718@dastard> X-ASG-Orig-Subj: Re: Does XFS support cgroup writeback limiting? References: <5652F311.7000406@5t9.de> <20151123202619.GE26718@dastard> <56538E6A.6030203@5t9.de> <20151123232052.GI26718@dastard> <5655FDDA.9050502@5t9.de> <20151125213500.GK26718@dastard> <565B70F9.8060707@5t9.de> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <565B70F9.8060707@5t9.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: 1448927079 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24861 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Sun, Nov 29, 2015 at 10:41:13PM +0100, Lutz Vieweg wrote: > On 11/25/2015 10:35 PM, Dave Chinner wrote: > >>2) Create 3 different XFS filesystem instances on the block > >> device, one for access by only the "good" processes, > >> on for access by only the "evil" processes, one for > >> shared access by at least two "good" and two "evil" > >> processes. > > > >Why do you need multiple filesystems? The writeback throttling is > >designed to work within a single filesystem... > > Hmm. Previously, I thought that the limiting of buffered writes > was realized by keeping track of the owners of dirty pages, and > that filesystem support was just required to make sure that writing > via a filesystem did not "anonymize" the dirty data. From what > I had read in blkio-controller.txt it seemed evident that limitations > would be accounted for "per block device", not "per filesystem", and > options like > >echo ": " > /cgrp/blkio.throttle.read_bps_device > document how to configure limits per block device. > > Now after reading through the new Writeback section of blkio-controller.txt > again I am somewhat confused - the text states > >writeback operates on inode basis > and if that means inodes as in "file system inodes", this would > indeed mean limits would be enforced "per filesystem" - and yet > there are no options documented to specify limits for any specific > filesystem. > > Does this mean some process writing to a block device (not via filesystem) > without "O_DIRECT" will dirty buffer pages, but those will not be limited > (as they are neither synchronous nor via-filesystem writes)? > That would mean VMs sharing some (physical or abstract) block device could > not really be isolated regarding their asynchronous write I/O... You are asking the wrong person - I don't know how this is all supposed to work, how it's supposed to be configured, how different cgroup controllers are supposed to interact, etc. Hence my request for regression tests before we say "XFS supports ...." because without them I have no idea if something is desired/correct behaviour or not... > >Metadata IO not throttled - it is owned by the filesystem and hence > >root cgroup. > > Ouch. That kind of defeats the purpose of limiting evil processes' > ability to DOS other processes. > Wouldn't it be possible to assign some arbitrary cost to meta-data > operations - like "account one page write for each meta-data change No. Think of a file with millions of extents. Just reading a byte of data will require pulling the entire extent map into memory, and so doing hundreds of megabytes of IO and using that much memory. > to the originating process of that change"? While certainly not > allowing for limiting to byte-precise limits of write bandwidth, > this would regain the ability to defend against DOS situations, No, that won't help at all. In fact, it might even introduce new DOS situations where we block a global metadata operation because it doesn't have reservation space and so *everything* stops until that metadata IO is dispatched and completed... > Assume the test instance has lots of memory and would be willing to > spend many Gigabytes of RAM for dirty buffer caches. Most people will be running the tests on machines with limited RAM and disk space, and so the tests really cannot depend on having many multiple gigabytes of RAM available for correct operation.... Indeed, limiting dirty memory thresholds will be part of setting up a predictable, reliable test scenario (e.g. via /proc/sys/vm/dirty_bytes and friends). > (I understand that if one used the absolute "blkio.throttle.write*" options > pressure back could apply before the dirty buffer cache was maxed out, > but in real-world scenarios people will almost always use the relative > "blkio.weight" based limiting, after all, you usually don't want to throttle > processes if there is plenty of bandwidth left no other process wants > at the same time.) Again, I have no idea how the throttling works or is configured, so we need regression tests to cover both (all?) of these sorts of common configuration scenarios. Cheers, Dave. -- Dave Chinner david@fromorbit.com From glommer@cloudius-systems.com Mon Nov 30 17:51:58 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 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 6FB0A29DF5 for ; Mon, 30 Nov 2015 17:51:58 -0600 (CST) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id D6AB3AC004 for ; Mon, 30 Nov 2015 15:51:57 -0800 (PST) X-ASG-Debug-ID: 1448927511-04cb6c535477480001-NocioJ Received: from mail-lf0-f54.google.com (mail-lf0-f54.google.com [209.85.215.54]) by cuda.sgi.com with ESMTP id KuWY9kSL6Rv9f4mJ (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Mon, 30 Nov 2015 15:51:52 -0800 (PST) X-Barracuda-Envelope-From: glommer@cloudius-systems.com X-Barracuda-Apparent-Source-IP: 209.85.215.54 Received: by lffu14 with SMTP id u14so219214240lff.1 for ; Mon, 30 Nov 2015 15:51:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=scylladb-com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=M9CgbefNjajh1Q8nfOLYMIKBeyd47IvxpPsZ7WbCh2c=; b=klxeozfxT8ro19QxIwih1uhH8p96Zw20yDWDR0A0purXqcOQ0aCzllrs7Ul6V2eksO r8cNg8ECQETwDqm6E9lHR+340iqR2n/evOdIEnVy5WcLX2KOM1HhlJlaObS1a+7HLqjw 1fonbYdbB2D9O8fhmC4N8Ee8cTfh5E3HPTzFVIy02Vl2g4cXTawpPVFfksj/827Qf4sV K42h19lxtN8RD8wsibRyovMbnOnfVar6Dr+NP0aUyN7s/snhIY2AWv3jPDwDkfl1XBlc /mLX4K8nK9+d/GL9aOImJD1z+xlKhTQuct4aFfL5dPtTYjAdQRZkpxbeVn8iYZwiY7+U oRHw== 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=M9CgbefNjajh1Q8nfOLYMIKBeyd47IvxpPsZ7WbCh2c=; b=mRLdq88t5wk0IpF6SPWNFyCKcolNrXD/LNpWodlAUx0fUmjEt15eq/jXpnTEbUKjHD xFzCt5VKSkA7/3P/gU2S6yKAgHP8ENIiDsK8/9Bw+uI+GS3mO6e9XW41QEwP4YjGDVpq /Q867PHnzhvjNdQCK5LnbNj9SSBxW99vhFHMfMG6gAgItBfdG8JCzSd3zYmobVhLIakY 0GhgJXWiz/1GDYS96HyVKZh8PajDUujAbo6BMNiExaY+32lcpIouwooKYOLVfnFrVgpf MJ3YOrqPG+hWNZUu81ntrHK6IOgj4+/guIdP+WpeWiw+kDjb+J9+73Tze8Fh0JDKZOZ6 FE2A== X-Gm-Message-State: ALoCoQnBkg6W/X2xNSgetFrZizorwLudQ32F0gZR+K73Byy45NJmWP9hWnE6Kr1kXsysZfZyQdrU MIME-Version: 1.0 X-Received: by 10.112.36.130 with SMTP id q2mr27083280lbj.24.1448927511270; Mon, 30 Nov 2015 15:51:51 -0800 (PST) Received: by 10.25.205.133 with HTTP; Mon, 30 Nov 2015 15:51:51 -0800 (PST) In-Reply-To: <20151130231027.GO26718@dastard> References: <20151130231027.GO26718@dastard> Date: Mon, 30 Nov 2015 18:51:51 -0500 Message-ID: Subject: Re: sleeps and waits during io_submit From: Glauber Costa X-ASG-Orig-Subj: Re: sleeps and waits during io_submit To: Dave Chinner Cc: xfs@oss.sgi.com, Avi Kivity Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-lf0-f54.google.com[209.85.215.54] X-Barracuda-Start-Time: 1448927512 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-BRTS-Evidence: kernelhub.org X-Barracuda-Spam-Score: 0.00 X-Barracuda-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.24862 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 Dave On Mon, Nov 30, 2015 at 6:10 PM, Dave Chinner wrote: > On Fri, Nov 27, 2015 at 09:43:50PM -0500, Glauber Costa wrote: >> Hello my dear XFSers, >> >> For those of you who don't know, we at ScyllaDB produce a modern NoSQL >> data store that, at the moment, runs on top of XFS only. We deal >> exclusively with asynchronous and direct IO, due to our >> thread-per-core architecture. Due to that, we avoid issuing any >> operation that will sleep. >> >> While debugging an extreme case of bad performance (most likely >> related to a not-so-great disk), I have found a variety of cases in >> which XFS blocks. To find those, I have used perf record -e >> sched:sched_switch -p , and I am attaching the perf report >> as xfs-sched_switch.log. Please note that this doesn't tell me for how >> long we block, but as mentioned before, blocking operations outside >> our control are detrimental to us regardless of the elapsed time. >> >> For those who are not acquainted to our internals, please ignore >> everything in that file but the xfs functions. For the xfs symbols, >> there are two kinds of events: the ones that are a children of >> io_submit, where we don't tolerate blocking, and the ones that are >> children of our helper IO thread, to where we push big operations that >> we know will block until we can get rid of them all. We care about the >> former and ignore the latter. >> >> Please allow me to ask you a couple of questions about those findings. >> If we are doing anything wrong, advise on best practices is truly >> welcome. >> >> 1) xfs_buf_lock -> xfs_log_force. >> >> I've started wondering what would make xfs_log_force sleep. But then I >> have noticed that xfs_log_force will only be called when a buffer is >> marked stale. Most of the times a buffer is marked stale seems to be >> due to errors. Although that is not my case (more on that), it got me >> thinking that maybe the right thing to do would be to avoid hitting >> this case altogether? > > The buffer is stale because it has recently been freed, and we > cannot re-use it until the transaction that freed it has been > committed to the journal. e.g. this trace: > > --3.15%-- _xfs_log_force > xfs_log_force > xfs_buf_lock > _xfs_buf_find > xfs_buf_get_map > xfs_trans_get_buf_map > xfs_btree_get_bufl > xfs_bmap_extents_to_btree > xfs_bmap_add_extent_hole_real > xfs_bmapi_write > xfs_iomap_write_direct > __xfs_get_blocks > xfs_get_blocks_direct > do_blockdev_direct_IO > __blockdev_direct_IO > xfs_vm_direct_IO > xfs_file_dio_aio_write > xfs_file_write_iter > aio_run_iocb > do_io_submit > sys_io_submit > entry_SYSCALL_64_fastpath > io_submit > 0x46d98a > > implies something like this has happened: > > truncate > free extent > extent list now fits inline in inode > btree-to-extent format change > free last bmbt block X > mark block contents stale > add block to busy extent list > place block on AGFL > > AIO write > allocate extent > inline extents full > extent-to-btree conversion > allocate bmbt block > grab block X from free list > get locked buffer for block X > xfs_buf_lock > buffer stale > log force to commit previous free transaction to disk > ..... > log force completes > buffer removed from busy extent list > buffer no longer stale > add bmbt record to new block > update btree indexes > .... > > > And, looking at the trace you attached, we see this: > > dump_stack > xfs_buf_stale > xfs_trans_binval > xfs_bmap_btree_to_extents <<<<<<<<< > xfs_bunmapi > xfs_itruncate_extents > > So I'd say this is a pretty clear indication that we're immediately > recycling freed blocks from the free list here.... > >> The file example-stale.txt contains a backtrace of the case where we >> are being marked as stale. It seems to be happening when we convert >> the the inode's extents from unwritten to real. Can this case be >> avoided? I won't pretend I know the intricacies of this, but couldn't >> we be keeping extents from the very beginning to avoid creating stale >> buffers? >> >> 2) xfs_buf_lock -> down >> This is one I truly don't understand. What can be causing contention >> in this lock? We never have two different cores writing to the same >> buffer, nor should we have the same core doingCAP_FOWNER so. > > As Brian pointed out, this is probably AGF or AGI contention - > attempting to allocate/free extents or inodes in the same AG at the > same time will show this sort of pattern. This trace shows AGF > contention: > > down > xfs_buf_lock > _xfs_buf_find > xfs_buf_get_map > xfs_buf_read_map > xfs_trans_read_buf_map > xfs_read_agf > ..... > > This trace shows AGI contention: > > down > xfs_buf_lock > _xfs_buf_find > xfs_buf_get_map > xfs_buf_read_map > xfs_trans_read_buf_map > xfs_read_agi > .... > Great. I will take a look at how can we mitigate those on our side. I will need some time to understand all of that better, so for now I'd just leave you guys with a big thank you. >> 3) xfs_file_aio_write_checks -> file_update_time -> xfs_vn_update_time > > This trace?: > > rwsem_down_write_failed > call_rwsem_down_write_failed > xfs_ilock > xfs_vn_update_time > file_update_time > xfs_file_aio_write_checks > xfs_file_dio_aio_write > xfs_file_write_iter > aio_run_iocb > do_io_submit > sys_io_submit > entry_SYSCALL_64_fastpath > io_submit > 0x46d98a > > Which is an mtime timestamp update racing with another operation > that takes the internal metadata lock (e.g. block mapping/allocation > for that inode). > >> You guys seem to have an interface to avoid that, by setting the >> FMODE_NOCMTIME flag. > > We've talked about exposing this through open() for Ceph. > > http://www.kernelhub.org/?p=2&msg=744325 > https://lkml.org/lkml/2015/5/15/671 > > Read the first thread for why it's problematic to expose this to > userspace - I won't repeat it all here. > > As it is, there was some code recently hacked into ext4 to reduce > mtime overhead - the MS_LAZYTIME superblock option. What it does it > prevent the inode from being marked dirty when timestamps are > updated and hence the timestamps are never journalled or written > until something else marks the inode metadata dirty (e.g. block > allocation). ext4 gets away with this because it doesn't actually > journal timestamp changes - they get captured in the journal by > other modifications that are journalled, but still rely on the inod > being marked dirty for fsync, writeback and inode cache eviction > doing the right thing. > > The ext4 implementation looks like the timestamp updates can be > thrown away, as the inodes are not marked dirty and so on memory > pressure they will simply be reclaimed without writing back the > updated timestamps that are held in memory. I suspect fsync will > also have problems on ext4 as the inode is not metadata dirty or > journalled, and hence the timestamp changes will never get written > back. > > And, IMO, the worst part of the ext4 implementation is that the > inode buffer writeback code in ext4 now checks to see if any of the > other inodes in the buffer being written back need to have their > inode timestamps updated. IOWs, ext4 now does writeback of > /unjournalled metadata/ to inodes that are purely timestamp dirty. > > We /used/ to do shit like this in XFS. We got rid of it in > preference of journalling everything because the corner cases in log > recovery meant that after a crash the inodes were in inconsistent > states, and that meant we had unexpected, unpredictable recovery > behaviour where files weren't the expected size and/or didn't > contain the expected data. Hence going back to the bad old days of > hacking around the journal "for speed" doesn't exactly fill me with > joy. > > Let me have a think about how we can implement lazytime in a sane > way, such that fsync() works correctly, we don't throw away > timstamp changes in memory reclaim and we don't write unlogged > changes to the on-disk locations.... I trust you fully for matters related to speed. Keep in mind, though, that at least for us the fact that it blocks is a lot worse than the fact that it is slow. We can work around slow, but blocking basically means that we won't have any more work to push - since we don't do threading. The processor that stales just sits idle until the lock is released. So any non-blocking solution to this would already be a win for us. > > Cheers, > > Dave. > -- > Dave Chinner > david@fromorbit.com