From BATV+1dd5f1c206cd6a728cfd+2868+infradead.org+hch@bombadil.srs.infradead.org Fri Jul 1 03:52:05 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p618q4fw053368 for ; Fri, 1 Jul 2011 03:52:05 -0500 X-ASG-Debug-ID: 1309510294-63c402e60000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from bombadil.infradead.org (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id DDE2645D33 for ; Fri, 1 Jul 2011 01:51:34 -0700 (PDT) Received: from bombadil.infradead.org (173-166-109-252-newengland.hfc.comcastbusiness.net [173.166.109.252]) by cuda.sgi.com with ESMTP id 9JIUVOE5omitMPiD for ; Fri, 01 Jul 2011 01:51:34 -0700 (PDT) Received: from hch by bombadil.infradead.org with local (Exim 4.76 #1 (Red Hat Linux)) id 1QcZRm-0000Wy-3Z; Fri, 01 Jul 2011 08:51:34 +0000 Date: Fri, 1 Jul 2011 04:51:34 -0400 From: Christoph Hellwig To: Dave Chinner Cc: Christoph Hellwig , xfs@oss.sgi.com X-ASG-Orig-Subj: Re: [PATCH 03/27] xfs: use write_cache_pages for writeback clustering Subject: Re: [PATCH 03/27] xfs: use write_cache_pages for writeback clustering Message-ID: <20110701085134.GA30819@infradead.org> References: <20110629140109.003209430@bombadil.infradead.org> <20110629140336.950805096@bombadil.infradead.org> <20110701022248.GM561@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20110701022248.GM561@dastard> User-Agent: Mutt/1.5.21 (2010-09-15) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: 173-166-109-252-newengland.hfc.comcastbusiness.net[173.166.109.252] X-Barracuda-Start-Time: 1309510294 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0003 1.0000 -2.0189 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -1.92 X-Barracuda-Spam-Status: No, SCORE=-1.92 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=RDNS_DYNAMIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67643 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_DYNAMIC Delivered to trusted network by host with dynamic-looking rDNS X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean > > This piece of logic checks is the type of buffer has changed from the > previous buffer. This used to work just fine, but now "type" is > local to the __xfs_vm_writepage() function, while the imap life > span?? multiple calls to the __xfs_vm_writepage() function. Hence > type is reinitialised to IO_OVERWRITE on every page that written, > and so for delalloc we are invalidating the imap and looking it up > again on every page. Traces show this sort of behaviour: Ah crap. I actually had it that way initially, but it got lost during a rebase due to a minimal context change screwing most hunks of the patch. Thanks for tracking this down! From BATV+1dd5f1c206cd6a728cfd+2868+infradead.org+hch@bombadil.srs.infradead.org Fri Jul 1 04:00:00 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p618xxcf053681 for ; Fri, 1 Jul 2011 04:00:00 -0500 X-ASG-Debug-ID: 1309510798-613a00020000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from bombadil.infradead.org (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 40EB9B29A4B for ; Fri, 1 Jul 2011 01:59:58 -0700 (PDT) Received: from bombadil.infradead.org (173-166-109-252-newengland.hfc.comcastbusiness.net [173.166.109.252]) by cuda.sgi.com with ESMTP id Lw1Nzqtatncanr5Y for ; Fri, 01 Jul 2011 01:59:58 -0700 (PDT) Received: from hch by bombadil.infradead.org with local (Exim 4.76 #1 (Red Hat Linux)) id 1QcZZu-0001pg-D0; Fri, 01 Jul 2011 08:59:58 +0000 Date: Fri, 1 Jul 2011 04:59:58 -0400 From: Christoph Hellwig To: Dave Chinner Cc: Christoph Hellwig , xfs@oss.sgi.com X-ASG-Orig-Subj: Re: [PATCH 03/27] xfs: use write_cache_pages for writeback clustering Subject: Re: [PATCH 03/27] xfs: use write_cache_pages for writeback clustering Message-ID: <20110701085958.GB30819@infradead.org> References: <20110629140109.003209430@bombadil.infradead.org> <20110629140336.950805096@bombadil.infradead.org> <20110701022248.GM561@dastard> <20110701041851.GN561@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20110701041851.GN561@dastard> User-Agent: Mutt/1.5.21 (2010-09-15) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: 173-166-109-252-newengland.hfc.comcastbusiness.net[173.166.109.252] X-Barracuda-Start-Time: 1309510799 X-Barracuda-Bayes: INNOCENT GLOBAL 0.2601 1.0000 -0.5273 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -0.43 X-Barracuda-Spam-Status: No, SCORE=-0.43 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=RDNS_DYNAMIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67643 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_DYNAMIC Delivered to trusted network by host with dynamic-looking rDNS X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean > xfs: writepage context needs to handle discontiguous page ranges > > From: Dave Chinner > > If the pages sent down by write_cache_pages to the writepage > callback are discontiguous, we need to detect this and put each > discontiguous page range into individual ioends. This is needed to > ensure that the ioend accurately represents the range of the file > that it covers so that file size updates during IO completion set > the size correctly. Failure to take into account the discontiguous > ranges results in files being too small when writeback patterns are > non-sequential. Looks good. I still wonder why I haven't been able to hit this. Haven't seen any 180 failure for a long time, with both 4k and 512 byte filesystems and since yesterday 1k as well. I'll merge this, and to avoid bisect regressions it'll have to go into the main writepages patch. That probaby means folding the add_to_ioend cleanup into it as well to not make the calling convention too ugly. From david@fromorbit.com Fri Jul 1 04:03:40 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p6193exr054576 for ; Fri, 1 Jul 2011 04:03:40 -0500 X-ASG-Debug-ID: 1309511017-614800370000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from ipmail04.adl6.internode.on.net (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 1459BB29A9A for ; Fri, 1 Jul 2011 02:03:38 -0700 (PDT) Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id XN7mHnGrNNqw01kZ for ; Fri, 01 Jul 2011 02:03:38 -0700 (PDT) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Av0EANWJDU55LCkB/2dsb2JhbABSp194iHnAbg6GJASidQ Received: from ppp121-44-41-1.lns20.syd6.internode.on.net (HELO dastard) ([121.44.41.1]) by ipmail04.adl6.internode.on.net with ESMTP; 01 Jul 2011 18:33:34 +0930 Received: from dave by dastard with local (Exim 4.72) (envelope-from ) id 1QcZdM-0005eK-8t; Fri, 01 Jul 2011 19:03:32 +1000 Date: Fri, 1 Jul 2011 19:03:32 +1000 From: Dave Chinner To: Amit Sahrawat Cc: xfs@oss.sgi.com X-ASG-Orig-Subj: Re: XFS and USB Hang on 2.6.35.13 Subject: Re: XFS and USB Hang on 2.6.35.13 Message-ID: <20110701090332.GO561@dastard> References: <20110630121918.GK561@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.20 (2009-06-14) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1309511019 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0009 1.0000 -2.0149 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -1.51 X-Barracuda-Spam-Status: No, SCORE=-1.51 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=BSF_RULE_7582B X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67643 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.50 BSF_RULE_7582B Custom Rule 7582B X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean On Fri, Jul 01, 2011 at 10:00:54AM +0530, Amit Sahrawat wrote: > On Thu, Jun 30, 2011 at 5:49 PM, Dave Chinner wrote: > > On Thu, Jun 30, 2011 at 04:57:42PM +0530, Amit Sahrawat wrote: > > > Hi All, > > > I encountered a hang on XFS during unplug. > > > *Test Case:* > > > #!/bin/sh > > > index=0 > > > while [ "$?" == 0 ] > > > do > > >         index=$(($index+1)) > > >         sync > > >         cp /mnt/1KB.txt /tmp/"$index".test > > > done > > > Where /mnt - mount point for vfat and /tmp mount point for XFS, both can be > > > XFS also. > > > > > > During this operation, unplug the USB. I am getting HANG almost everytime I > > > unplug. > > > > Well, that's no surprise. The unplug appears to be losing IOs in > > progress. > > > > > *Kernel Version:* 2.6.35.13 (extremely sorry, I know next question will be > > > why am I not using TOT kernel - I tried but my PC does not boot up with the > > > latest one) ..... > > > *INFO: task khubd:*33 blocked for more than 120 seconds. > > > "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. > > > khubd         D c06c261c     0    33      2 0x00000000 > > > Backtrace: > > > [] (schedule+0x0/0x500) from [] > > > (_xfs_log_force+0x230/0x284) > > > > You need to turn off line wrapping for stuff you paste into email. > > The cleaned up (i.e. relevant part) trace is: > > > > [] (schedule+0x0/0x500) > > [] (_xfs_log_force+0x0/0x284) > > [] (xfs_log_force+0x0/0x38) > > [] (xfs_sync_data+0x0/0x58) > > [] (xfs_quiesce_data+0x0/0x80) > > [] (xfs_fs_sync_fs+0x0/0xe0) > > [] (__sync_filesystem+0x0/0xa0) > > [] (sync_filesystem+0x0/0x60) > > [] (fsync_bdev+0x0/0x44) > > [] (invalidate_partition+0x0/0x3c) > > [] (del_gendisk+0x0/0x140) > > [] (sd_remove+0x0/0x84) > > [] (__device_release_driver+0x0/0xac) > > [] (device_release_driver+0x0/0x30) > > [] (bus_remove_device+0x0/0x8c) > > [] (device_del+0x0/0x170) > > [] (__scsi_remove_device+0x0/0x90) > > [] (scsi_forget_host+0x0/0x6c) > > [] (scsi_remove_host+0x0/0x104) > > [] (quiesce_and_remove_host+0x0/0x9c) > > [] (usb_stor_disconnect+0x0/0x28) > > [] (usb_unbind_interface+0x0/0xdc) > > [] (__device_release_driver+0x0/0xac) > > [] (device_release_driver+0x0/0x30) > > [] (bus_remove_device+0x0/0x8c) > > [] (device_del+0x0/0x170) > > [] (usb_disable_device+0x0/0xf8) > > [] (usb_disconnect+0x0/0xf4) > > [] (hub_thread+0x0/0xd78) > > [] (kthread+0x0/0x8c) > > > > Well, that just looks utterly braindamaged to me. > > > > We just had the device containing the filesystem removed from the > > system, so the error handling routine ends up trying to sync the > > filesystem to the device that doesn't exist anymore. WTF? > > > > >>> This is what I think, why is syncing taking place when the Amit, you don't need to quote your own reply. That just confuses mail readers that understand the ">" quoting convention and highlight appropriately, and made me wonder if you'd even replied.... > This is what I think, why is syncing taking place when the > device doesn't exist anymore. What is the gain in doing so? I doubt the person who wrote the error handling even realised that it ended up in such a mess. > I > will try and propose this feature. Not sure what you mean by this.... .... > > AFAICT, this problem doesn't exist in TOT - the conversion of the > > Again I have a problem which seems fixed in TOT :) > > > xfslogd workqueue to CMWQ allows processing of other xfslogd > > workqueue events to continue even though this one has gone to sleep. > > > > You probably need to change the shutdown type to > > SHUTDOWN_LOG_IO_ERROR to prevent a log flush from occurring in this > > shutdown context. > > This will fix the error for this kernel version, I will give this a try. > Is this the patchwork for CMWQ: > http://patchwork.xfs.org/patch/2037/ (xfs: improve sync behaviour > in face of aggressive dirtying) ? Please let me know. No. 2.6.35 doesn't have the CMWQ infrastructure, it was introduced in 2.6.38 IIRC. IOWs, there isn't a fix you can just backport - you're going to need to write and test your own fix, and my suggestion for doing that is above. Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Fri Jul 1 04:20:29 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p619KShY055038 for ; Fri, 1 Jul 2011 04:20:29 -0500 X-ASG-Debug-ID: 1309512025-652200a90000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from ipmail04.adl6.internode.on.net (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id D4DEA176761C for ; Fri, 1 Jul 2011 02:20:26 -0700 (PDT) Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id BDDvUY6Q6NBKM3nu for ; Fri, 01 Jul 2011 02:20:26 -0700 (PDT) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Av0EALmQDU55LCkB/2dsb2JhbAA0HqdeeIh5sy6NPA6DJIMABJpEiDE Received: from ppp121-44-41-1.lns20.syd6.internode.on.net (HELO dastard) ([121.44.41.1]) by ipmail04.adl6.internode.on.net with ESMTP; 01 Jul 2011 18:50:24 +0930 Received: from dave by dastard with local (Exim 4.72) (envelope-from ) id 1QcZtd-0005fq-JJ; Fri, 01 Jul 2011 19:20:21 +1000 Date: Fri, 1 Jul 2011 19:20:21 +1000 From: Dave Chinner To: Christoph Hellwig Cc: xfs@oss.sgi.com X-ASG-Orig-Subj: Re: [PATCH 03/27] xfs: use write_cache_pages for writeback clustering Subject: Re: [PATCH 03/27] xfs: use write_cache_pages for writeback clustering Message-ID: <20110701092021.GP561@dastard> References: <20110629140109.003209430@bombadil.infradead.org> <20110629140336.950805096@bombadil.infradead.org> <20110701022248.GM561@dastard> <20110701041851.GN561@dastard> <20110701085958.GB30819@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20110701085958.GB30819@infradead.org> User-Agent: Mutt/1.5.20 (2009-06-14) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1309512027 X-Barracuda-Bayes: INNOCENT GLOBAL 0.4045 1.0000 0.0000 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67645 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean On Fri, Jul 01, 2011 at 04:59:58AM -0400, Christoph Hellwig wrote: > > xfs: writepage context needs to handle discontiguous page ranges > > > > From: Dave Chinner > > > > If the pages sent down by write_cache_pages to the writepage > > callback are discontiguous, we need to detect this and put each > > discontiguous page range into individual ioends. This is needed to > > ensure that the ioend accurately represents the range of the file > > that it covers so that file size updates during IO completion set > > the size correctly. Failure to take into account the discontiguous > > ranges results in files being too small when writeback patterns are > > non-sequential. > > Looks good. I still wonder why I haven't been able to hit this. > Haven't seen any 180 failure for a long time, with both 4k and 512 byte > filesystems and since yesterday 1k as well. It requires the test to run the VM out of RAM and then force enough memory pressure for kswapd to start writeback from the LRU. The reproducer I have is a 1p, 1GB RAM VM with it's disk image on a 100MB/s HW RAID1 w/ 512MB BBWC disk subsystem. When kswapd starts doing writeback from the LRU, the iops rate goes through the roof (from ~300iops @~320k/io to ~7000iops @4k/io) and throughput drops from 100MB/s to ~30MB/s. BBWC is the only reason the IOPS stays as high as it does - maybe that is why I saw this and you haven't. As it is, the kswapd writeback behaviour is utterly atrocious and, ultimately, quite easy to provoke. I wish the MM folk would fix that goddamn problem already - we've only been complaining about it for the last 6 or 7 years. As such, I'm wondering if it's a bad idea to even consider removing the .writepage clustering... > I'll merge this, and to avoid bisect regressions it'll have to go into > the main writepages patch. That probaby means folding the add_to_ioend > cleanup into it as well to not make the calling convention too ugly. Yup, I figured you'd want to do that. Cheers, Dave. -- Dave Chinner david@fromorbit.com From BATV+1dd5f1c206cd6a728cfd+2868+infradead.org+hch@bombadil.srs.infradead.org Fri Jul 1 04:33:12 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p619XBEZ055590 for ; Fri, 1 Jul 2011 04:33:12 -0500 X-ASG-Debug-ID: 1309512790-6d2300640000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from bombadil.infradead.org (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id EB43E1D1E2AA for ; Fri, 1 Jul 2011 02:33:10 -0700 (PDT) Received: from bombadil.infradead.org (173-166-109-252-newengland.hfc.comcastbusiness.net [173.166.109.252]) by cuda.sgi.com with ESMTP id no5pCib0bXNxE1Qi for ; Fri, 01 Jul 2011 02:33:10 -0700 (PDT) Received: from hch by bombadil.infradead.org with local (Exim 4.76 #1 (Red Hat Linux)) id 1Qca5x-0007SB-C4; Fri, 01 Jul 2011 09:33:05 +0000 Date: Fri, 1 Jul 2011 05:33:05 -0400 From: Christoph Hellwig To: Mel Gorman , Johannes Weiner , Wu Fengguang Cc: Dave Chinner , xfs@oss.sgi.com, linux-mm@kvack.org X-ASG-Orig-Subj: Re: [PATCH 03/27] xfs: use write_cache_pages for writeback clustering Subject: Re: [PATCH 03/27] xfs: use write_cache_pages for writeback clustering Message-ID: <20110701093305.GA28531@infradead.org> References: <20110629140109.003209430@bombadil.infradead.org> <20110629140336.950805096@bombadil.infradead.org> <20110701022248.GM561@dastard> <20110701041851.GN561@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20110701041851.GN561@dastard> User-Agent: Mutt/1.5.21 (2010-09-15) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: 173-166-109-252-newengland.hfc.comcastbusiness.net[173.166.109.252] X-Barracuda-Start-Time: 1309512790 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -1.92 X-Barracuda-Spam-Status: No, SCORE=-1.92 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=RDNS_DYNAMIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67645 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_DYNAMIC Delivered to trusted network by host with dynamic-looking rDNS X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean Johannes, Mel, Wu, Dave has been stressing some XFS patches of mine that remove the XFS internal writeback clustering in favour of using write_cache_pages. As part of investigating the behaviour he found out that we're still doing lots of I/O from the end of the LRU in kswapd. Not only is that pretty bad behaviour in general, but it also means we really can't just remove the writeback clustering in writepage given how much I/O is still done through that. Any chance we could the writeback vs kswap behaviour sorted out a bit better finally? Some excerpts from the previous discussion: On Fri, Jul 01, 2011 at 02:18:51PM +1000, Dave Chinner wrote: > I'm now only running test 180 on 100 files rather than the 1000 the > test normally runs on, because it's faster and still shows the > problem. That means the test is only using 1GB of disk space, and > I'm running on a VM with 1GB RAM. It appears to be related to the VM > triggering random page writeback from the LRU - 100x10MB files more > than fills memory, hence it being the smallest test case i could > reproduce the problem on. > > My triage notes are as follows, and the patch that fixes the bug is > attached below. > > --- 180.out 2010-04-28 15:00:22.000000000 +1000 > +++ 180.out.bad 2011-07-01 12:44:12.000000000 +1000 > @@ -1 +1,9 @@ > QA output created by 180 > +file /mnt/scratch/81 has incorrect size 10473472 - sync failed > +file /mnt/scratch/86 has incorrect size 10371072 - sync failed > +file /mnt/scratch/87 has incorrect size 10104832 - sync failed > +file /mnt/scratch/88 has incorrect size 10125312 - sync failed > +file /mnt/scratch/89 has incorrect size 10469376 - sync failed > +file /mnt/scratch/90 has incorrect size 10240000 - sync failed > +file /mnt/scratch/91 has incorrect size 10362880 - sync failed > +file /mnt/scratch/92 has incorrect size 10366976 - sync failed > > $ ls -li /mnt/scratch/ | awk '/rw/ { printf("0x%x %d %d\n", $1, $6, $10); }' > 0x244093 10473472 81 > 0x244098 10371072 86 > 0x244099 10104832 87 > 0x24409a 10125312 88 > 0x24409b 10469376 89 > 0x24409c 10240000 90 > 0x24409d 10362880 91 > 0x24409e 10366976 92 > > So looking at inode 0x244099 (/mnt/scratch/87), the last setfilesize > call in the trace (got a separate patch for that) is: > > <...>-393 [000] 696245.229559: xfs_ilock_nowait: dev 253:16 ino 0x244099 flags ILOCK_EXCL caller xfs_setfilesize > <...>-393 [000] 696245.229560: xfs_setfilesize: dev 253:16 ino 0x244099 isize 0xa00000 disize 0x94e000 new_size 0x0 offset 0x600000 count 3813376 > <...>-393 [000] 696245.229561: xfs_iunlock: dev 253:16 ino 0x244099 flags ILOCK_EXCL caller xfs_setfilesize > > For an IO that was from offset 0x600000 for just under 4MB. The end > of that IO is at byte 10104832, which is _exactly_ what the inode > size says it is. > > It is very clear that from the IO completions that we are getting a > *lot* of kswapd driven writeback directly through .writepage: > > $ grep "xfs_setfilesize:" t.t |grep "4096$" | wc -l > 801 > $ grep "xfs_setfilesize:" t.t |grep -v "4096$" | wc -l > 78 > > So there's ~900 IO completions that change the file size, and 90% of > them are single page updates. > > $ ps -ef |grep [k]swap > root 514 2 0 12:43 ? 00:00:00 [kswapd0] > $ grep "writepage:" t.t | grep "514 " |wc -l > 799 > > Oh, now that is too close to just be a co-incidence. We're getting > significant amounts of random page writeback from the the ends of > the LRUs done by the VM. > > On Fri, Jul 01, 2011 at 07:20:21PM +1000, Dave Chinner wrote: > > Looks good. I still wonder why I haven't been able to hit this. > > Haven't seen any 180 failure for a long time, with both 4k and 512 byte > > filesystems and since yesterday 1k as well. > > It requires the test to run the VM out of RAM and then force enough > memory pressure for kswapd to start writeback from the LRU. The > reproducer I have is a 1p, 1GB RAM VM with it's disk image on a > 100MB/s HW RAID1 w/ 512MB BBWC disk subsystem. > > When kswapd starts doing writeback from the LRU, the iops rate goes > through the roof (from ~300iops @~320k/io to ~7000iops @4k/io) and > throughput drops from 100MB/s to ~30MB/s. BBWC is the only reason > the IOPS stays as high as it does - maybe that is why I saw this and > you haven't. > > As it is, the kswapd writeback behaviour is utterly atrocious and, > ultimately, quite easy to provoke. I wish the MM folk would fix that > goddamn problem already - we've only been complaining about it for > the last 6 or 7 years. As such, I'm wondering if it's a bad idea to > even consider removing the .writepage clustering... From BATV+1dd5f1c206cd6a728cfd+2868+infradead.org+hch@bombadil.srs.infradead.org Fri Jul 1 04:37:08 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.8 required=5.0 tests=BAYES_00,J_CHICKENPOX_15 autolearn=no version=3.4.0-r929098 Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p619b8uE055694 for ; Fri, 1 Jul 2011 04:37:08 -0500 X-ASG-Debug-ID: 1309513026-798b01df0000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from bombadil.infradead.org (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id D0EC714FC7FD for ; Fri, 1 Jul 2011 02:37:06 -0700 (PDT) Received: from bombadil.infradead.org (173-166-109-252-newengland.hfc.comcastbusiness.net [173.166.109.252]) by cuda.sgi.com with ESMTP id kG9C2DM0u1FGJKkk for ; Fri, 01 Jul 2011 02:37:06 -0700 (PDT) Received: from hch by bombadil.infradead.org with local (Exim 4.76 #1 (Red Hat Linux)) id 1Qca9m-0008Lq-9U; Fri, 01 Jul 2011 09:37:02 +0000 Date: Fri, 1 Jul 2011 05:37:02 -0400 From: Christoph Hellwig To: P?draig Brady Cc: Christoph Hellwig , linux-kernel@vger.kernel.org, Josef Bacik , xfs@oss.sgi.com, viro@ZenIV.linux.org.uk, linux-fsdevel@vger.kernel.org, linux-btrfs@vger.kernel.org X-ASG-Orig-Subj: Re: [PATCH] xfstests 255: add a seek_data/seek_hole tester Subject: Re: [PATCH] xfstests 255: add a seek_data/seek_hole tester Message-ID: <20110701093702.GA28684@infradead.org> References: <1309275199-10801-1-git-send-email-josef@redhat.com> <1309275199-10801-5-git-send-email-josef@redhat.com> <20110629065306.GC1026@dastard> <20110629074021.GA26086@infradead.org> <4E0B019E.8080800@draigBrady.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <4E0B019E.8080800@draigBrady.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: 173-166-109-252-newengland.hfc.comcastbusiness.net[173.166.109.252] X-Barracuda-Start-Time: 1309513027 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -1.92 X-Barracuda-Spam-Status: No, SCORE=-1.92 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=RDNS_DYNAMIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67646 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_DYNAMIC Delivered to trusted network by host with dynamic-looking rDNS X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean On Wed, Jun 29, 2011 at 11:42:38AM +0100, P?draig Brady wrote: > There is the argument, that if this interface can distinguish > these dirty unwritten extents, then why can't the fiemap interface too? > The advantage of the fiemap interface is that it can distinguish > empty extents vs holes. Empty extents will become increasingly common > I think, given the fragmentation and space guarantee benefits they give. > It would be cool for cp for example to be able to efficiently copy > empty extents from source to dest. That brings us back to square one. FIEMAP is supposed to tell you about the physical layout on disk. Unwritten extents physically always are there, but whether they might have to be copied depends entirely on in-core state. Finding that incore state in addition is not all that easy compared to simply walking the extents. People might decide it's worth for an interface like SEEK_HOLE specificly asking for that, but grafting it into FIEMAP through the backdoor is a horrible idea. From BATV+1dd5f1c206cd6a728cfd+2868+infradead.org+hch@bombadil.srs.infradead.org Fri Jul 1 04:46:04 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p619k3N5055976 for ; Fri, 1 Jul 2011 04:46:04 -0500 X-ASG-Debug-ID: 1309513562-6d1900b30000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from bombadil.infradead.org (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 353631E56724 for ; Fri, 1 Jul 2011 02:46:02 -0700 (PDT) Received: from bombadil.infradead.org (173-166-109-252-newengland.hfc.comcastbusiness.net [173.166.109.252]) by cuda.sgi.com with ESMTP id 3IgRdUdiHgi9Chpj for ; Fri, 01 Jul 2011 02:46:02 -0700 (PDT) Received: from hch by bombadil.infradead.org with local (Exim 4.76 #1 (Red Hat Linux)) id 1QcaIU-0001qN-GE for xfs@oss.sgi.com; Fri, 01 Jul 2011 09:46:02 +0000 Message-Id: <20110701094602.465074143@bombadil.infradead.org> User-Agent: quilt/0.48-1 Date: Fri, 01 Jul 2011 05:43:23 -0400 From: Christoph Hellwig To: xfs@oss.sgi.com X-ASG-Orig-Subj: [PATCH 02/27] xfs: re-enable non-blocking behaviour in xfs_map_blocks Subject: [PATCH 02/27] xfs: re-enable non-blocking behaviour in xfs_map_blocks References: <20110701094321.936534538@bombadil.infradead.org> Content-Disposition: inline; filename=xfs-writepage-repair-nolock-support X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: 173-166-109-252-newengland.hfc.comcastbusiness.net[173.166.109.252] X-Barracuda-Start-Time: 1309513563 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -1.42 X-Barracuda-Spam-Status: No, SCORE=-1.42 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=BSF_SC5_MJ1963, RDNS_DYNAMIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67645 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_DYNAMIC Delivered to trusted network by host with dynamic-looking rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean The non-blockig behaviour in xfs_map_blocks currently is conditional on having both the WB_SYNC_NONE sync_mode and the nonblocking flag set. The latter used to be used by both pdflush, kswapd and a few other places in older kernels, but has been fading out starting with the introduction of the per-bdi flusher threads. Enable the non-blocking behaviour for all WB_SYNC_NONE calls to get back the behaviour we want. Signed-off-by: Christoph Hellwig Index: xfs/fs/xfs/linux-2.6/xfs_aops.c =================================================================== --- xfs.orig/fs/xfs/linux-2.6/xfs_aops.c 2011-06-30 20:10:06.959596789 +0200 +++ xfs/fs/xfs/linux-2.6/xfs_aops.c 2011-06-30 20:10:19.749596630 +0200 @@ -959,7 +959,7 @@ xfs_vm_writepage( offset = page_offset(page); type = IO_OVERWRITE; - if (wbc->sync_mode == WB_SYNC_NONE && wbc->nonblocking) + if (wbc->sync_mode == WB_SYNC_NONE) nonblocking = 1; do { From BATV+1dd5f1c206cd6a728cfd+2868+infradead.org+hch@bombadil.srs.infradead.org Fri Jul 1 04:46:04 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p619k3b2055975 for ; Fri, 1 Jul 2011 04:46:04 -0500 X-ASG-Debug-ID: 1309513562-2b47001f0000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from bombadil.infradead.org (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 1C58216748B7 for ; Fri, 1 Jul 2011 02:46:02 -0700 (PDT) Received: from bombadil.infradead.org (173-166-109-252-newengland.hfc.comcastbusiness.net [173.166.109.252]) by cuda.sgi.com with ESMTP id dDe4apfgKn4GPDWQ for ; Fri, 01 Jul 2011 02:46:02 -0700 (PDT) Received: from hch by bombadil.infradead.org with local (Exim 4.76 #1 (Red Hat Linux)) id 1QcaIU-0001pH-4I for xfs@oss.sgi.com; Fri, 01 Jul 2011 09:46:02 +0000 Message-Id: <20110701094321.936534538@bombadil.infradead.org> User-Agent: quilt/0.48-1 Date: Fri, 01 Jul 2011 05:43:21 -0400 From: Christoph Hellwig To: xfs@oss.sgi.com X-ASG-Orig-Subj: [PATCH 00/27] patch queue for Linux 3.1, V2 Subject: [PATCH 00/27] patch queue for Linux 3.1, V2 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: 173-166-109-252-newengland.hfc.comcastbusiness.net[173.166.109.252] X-Barracuda-Start-Time: 1309513563 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0206 1.0000 -1.8872 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -1.29 X-Barracuda-Spam-Status: No, SCORE=-1.29 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=BSF_SC5_MJ1963, RDNS_DYNAMIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67646 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_DYNAMIC Delivered to trusted network by host with dynamic-looking rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean This is my current patch queue for Linux 3.1. Compared to the last posting all review comments were incorporated and two additional trivial patches were added. The ->writepages implementation was dropped for now, given the bad situation of kswap-originating writeback, but I'll repost the fixed version separately to get feedback on the updated version. From BATV+1dd5f1c206cd6a728cfd+2868+infradead.org+hch@bombadil.srs.infradead.org Fri Jul 1 04:46:04 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p619k3sd055977 for ; Fri, 1 Jul 2011 04:46:04 -0500 X-ASG-Debug-ID: 1309513562-6d2400a90000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from bombadil.infradead.org (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 2C3F1178BD62 for ; Fri, 1 Jul 2011 02:46:03 -0700 (PDT) Received: from bombadil.infradead.org (173-166-109-252-newengland.hfc.comcastbusiness.net [173.166.109.252]) by cuda.sgi.com with ESMTP id 3SG9XsiG8E7Hi5qh for ; Fri, 01 Jul 2011 02:46:03 -0700 (PDT) Received: from hch by bombadil.infradead.org with local (Exim 4.76 #1 (Red Hat Linux)) id 1QcaIU-0001qt-M6 for xfs@oss.sgi.com; Fri, 01 Jul 2011 09:46:02 +0000 Message-Id: <20110701094602.647499467@bombadil.infradead.org> User-Agent: quilt/0.48-1 Date: Fri, 01 Jul 2011 05:43:24 -0400 From: Christoph Hellwig To: xfs@oss.sgi.com X-ASG-Orig-Subj: [PATCH 03/27] xfs: work around bogus gcc warning in xfs_allocbt_init_cursor Subject: [PATCH 03/27] xfs: work around bogus gcc warning in xfs_allocbt_init_cursor References: <20110701094321.936534538@bombadil.infradead.org> Content-Disposition: inline; filename=xfs-fix-xfs_allocbt_init_cursor-warning X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: 173-166-109-252-newengland.hfc.comcastbusiness.net[173.166.109.252] X-Barracuda-Start-Time: 1309513563 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -1.42 X-Barracuda-Spam-Status: No, SCORE=-1.42 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=BSF_SC5_MJ1963, RDNS_DYNAMIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67645 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_DYNAMIC Delivered to trusted network by host with dynamic-looking rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean GCC 4.6 complains about an array subscript is above array bounds when using the btree index to index into the agf_levels array. The only two indices passed in are 0 and 1, and we have an assert insuring that. Replace the trick of using the array index directly with using constants in the already existing branch for assigning the XFS_BTREE_LASTREC_UPDATE flag. Signed-off-by: Christoph Hellwig Reviewed-by: Alex Elder Reviewed-by: Dave Chinner Index: xfs/fs/xfs/xfs_alloc_btree.c =================================================================== --- xfs.orig/fs/xfs/xfs_alloc_btree.c 2011-06-17 14:16:27.929065669 +0200 +++ xfs/fs/xfs/xfs_alloc_btree.c 2011-06-17 14:17:22.145729599 +0200 @@ -427,13 +427,16 @@ xfs_allocbt_init_cursor( cur->bc_tp = tp; cur->bc_mp = mp; - cur->bc_nlevels = be32_to_cpu(agf->agf_levels[btnum]); cur->bc_btnum = btnum; cur->bc_blocklog = mp->m_sb.sb_blocklog; - cur->bc_ops = &xfs_allocbt_ops; - if (btnum == XFS_BTNUM_CNT) + + if (btnum == XFS_BTNUM_CNT) { + cur->bc_nlevels = be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]); cur->bc_flags = XFS_BTREE_LASTREC_UPDATE; + } else { + cur->bc_nlevels = be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]); + } cur->bc_private.a.agbp = agbp; cur->bc_private.a.agno = agno; From BATV+1dd5f1c206cd6a728cfd+2868+infradead.org+hch@bombadil.srs.infradead.org Fri Jul 1 04:46:05 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.8 required=5.0 tests=BAYES_00,J_CHICKENPOX_64 autolearn=no version=3.4.0-r929098 Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p619k5GB056022 for ; Fri, 1 Jul 2011 04:46:05 -0500 X-ASG-Debug-ID: 1309513563-63a803bb0000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from bombadil.infradead.org (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id BD6104669F for ; Fri, 1 Jul 2011 02:46:03 -0700 (PDT) Received: from bombadil.infradead.org (173-166-109-252-newengland.hfc.comcastbusiness.net [173.166.109.252]) by cuda.sgi.com with ESMTP id UAoshp3eIdyTmDvf for ; Fri, 01 Jul 2011 02:46:03 -0700 (PDT) Received: from hch by bombadil.infradead.org with local (Exim 4.76 #1 (Red Hat Linux)) id 1QcaIU-0001rP-S7 for xfs@oss.sgi.com; Fri, 01 Jul 2011 09:46:02 +0000 Message-Id: <20110701094602.835186772@bombadil.infradead.org> User-Agent: quilt/0.48-1 Date: Fri, 01 Jul 2011 05:43:25 -0400 From: Christoph Hellwig To: xfs@oss.sgi.com X-ASG-Orig-Subj: [PATCH 04/27] xfs: split xfs_setattr Subject: [PATCH 04/27] xfs: split xfs_setattr References: <20110701094321.936534538@bombadil.infradead.org> Content-Disposition: inline; filename=xfs-split-setattr X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: 173-166-109-252-newengland.hfc.comcastbusiness.net[173.166.109.252] X-Barracuda-Start-Time: 1309513563 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -1.42 X-Barracuda-Spam-Status: No, SCORE=-1.42 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=BSF_SC5_MJ1963, RDNS_DYNAMIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67645 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_DYNAMIC Delivered to trusted network by host with dynamic-looking rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean Split up xfs_setattr into two functions, one for the complex truncate handling, and one for the trivial attribute updates. Also move both new routines to xfs_iops.c as they are fairly Linux-specific. Signed-off-by: Christoph Hellwig Reviewed-by: Alex Elder Reviewed-by: Dave Chinner Index: xfs/fs/xfs/linux-2.6/xfs_iops.c =================================================================== --- xfs.orig/fs/xfs/linux-2.6/xfs_iops.c 2011-06-29 11:29:02.684972774 +0200 +++ xfs/fs/xfs/linux-2.6/xfs_iops.c 2011-06-29 11:29:07.154948558 +0200 @@ -39,6 +39,7 @@ #include "xfs_buf_item.h" #include "xfs_utils.h" #include "xfs_vnodeops.h" +#include "xfs_inode_item.h" #include "xfs_trace.h" #include @@ -497,12 +498,449 @@ xfs_vn_getattr( return 0; } +int +xfs_setattr_nonsize( + struct xfs_inode *ip, + struct iattr *iattr, + int flags) +{ + xfs_mount_t *mp = ip->i_mount; + struct inode *inode = VFS_I(ip); + int mask = iattr->ia_valid; + xfs_trans_t *tp; + int error; + uid_t uid = 0, iuid = 0; + gid_t gid = 0, igid = 0; + struct xfs_dquot *udqp = NULL, *gdqp = NULL; + struct xfs_dquot *olddquot1 = NULL, *olddquot2 = NULL; + + trace_xfs_setattr(ip); + + if (mp->m_flags & XFS_MOUNT_RDONLY) + return XFS_ERROR(EROFS); + + if (XFS_FORCED_SHUTDOWN(mp)) + return XFS_ERROR(EIO); + + error = -inode_change_ok(inode, iattr); + if (error) + return XFS_ERROR(error); + + ASSERT((mask & ATTR_SIZE) == 0); + + /* + * If disk quotas is on, we make sure that the dquots do exist on disk, + * before we start any other transactions. Trying to do this later + * is messy. We don't care to take a readlock to look at the ids + * in inode here, because we can't hold it across the trans_reserve. + * If the IDs do change before we take the ilock, we're covered + * because the i_*dquot fields will get updated anyway. + */ + if (XFS_IS_QUOTA_ON(mp) && (mask & (ATTR_UID|ATTR_GID))) { + uint qflags = 0; + + if ((mask & ATTR_UID) && XFS_IS_UQUOTA_ON(mp)) { + uid = iattr->ia_uid; + qflags |= XFS_QMOPT_UQUOTA; + } else { + uid = ip->i_d.di_uid; + } + if ((mask & ATTR_GID) && XFS_IS_GQUOTA_ON(mp)) { + gid = iattr->ia_gid; + qflags |= XFS_QMOPT_GQUOTA; + } else { + gid = ip->i_d.di_gid; + } + + /* + * We take a reference when we initialize udqp and gdqp, + * so it is important that we never blindly double trip on + * the same variable. See xfs_create() for an example. + */ + ASSERT(udqp == NULL); + ASSERT(gdqp == NULL); + error = xfs_qm_vop_dqalloc(ip, uid, gid, xfs_get_projid(ip), + qflags, &udqp, &gdqp); + if (error) + return error; + } + + tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_NOT_SIZE); + error = xfs_trans_reserve(tp, 0, XFS_ICHANGE_LOG_RES(mp), 0, 0, 0); + if (error) + goto out_dqrele; + + xfs_ilock(ip, XFS_ILOCK_EXCL); + + /* + * Change file ownership. Must be the owner or privileged. + */ + if (mask & (ATTR_UID|ATTR_GID)) { + /* + * These IDs could have changed since we last looked at them. + * But, we're assured that if the ownership did change + * while we didn't have the inode locked, inode's dquot(s) + * would have changed also. + */ + iuid = ip->i_d.di_uid; + igid = ip->i_d.di_gid; + gid = (mask & ATTR_GID) ? iattr->ia_gid : igid; + uid = (mask & ATTR_UID) ? iattr->ia_uid : iuid; + + /* + * Do a quota reservation only if uid/gid is actually + * going to change. + */ + if (XFS_IS_QUOTA_RUNNING(mp) && + ((XFS_IS_UQUOTA_ON(mp) && iuid != uid) || + (XFS_IS_GQUOTA_ON(mp) && igid != gid))) { + ASSERT(tp); + error = xfs_qm_vop_chown_reserve(tp, ip, udqp, gdqp, + capable(CAP_FOWNER) ? + XFS_QMOPT_FORCE_RES : 0); + if (error) /* out of quota */ + goto out_trans_cancel; + } + } + + xfs_trans_ijoin(tp, ip); + + /* + * Change file ownership. Must be the owner or privileged. + */ + if (mask & (ATTR_UID|ATTR_GID)) { + /* + * CAP_FSETID overrides the following restrictions: + * + * The set-user-ID and set-group-ID bits of a file will be + * cleared upon successful return from chown() + */ + if ((ip->i_d.di_mode & (S_ISUID|S_ISGID)) && + !capable(CAP_FSETID)) + ip->i_d.di_mode &= ~(S_ISUID|S_ISGID); + + /* + * Change the ownerships and register quota modifications + * in the transaction. + */ + if (iuid != uid) { + if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_UQUOTA_ON(mp)) { + ASSERT(mask & ATTR_UID); + ASSERT(udqp); + olddquot1 = xfs_qm_vop_chown(tp, ip, + &ip->i_udquot, udqp); + } + ip->i_d.di_uid = uid; + inode->i_uid = uid; + } + if (igid != gid) { + if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_GQUOTA_ON(mp)) { + ASSERT(!XFS_IS_PQUOTA_ON(mp)); + ASSERT(mask & ATTR_GID); + ASSERT(gdqp); + olddquot2 = xfs_qm_vop_chown(tp, ip, + &ip->i_gdquot, gdqp); + } + ip->i_d.di_gid = gid; + inode->i_gid = gid; + } + } + + /* + * Change file access modes. + */ + if (mask & ATTR_MODE) { + umode_t mode = iattr->ia_mode; + + if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID)) + mode &= ~S_ISGID; + + ip->i_d.di_mode &= S_IFMT; + ip->i_d.di_mode |= mode & ~S_IFMT; + + inode->i_mode &= S_IFMT; + inode->i_mode |= mode & ~S_IFMT; + } + + /* + * Change file access or modified times. + */ + if (mask & ATTR_ATIME) { + inode->i_atime = iattr->ia_atime; + ip->i_d.di_atime.t_sec = iattr->ia_atime.tv_sec; + ip->i_d.di_atime.t_nsec = iattr->ia_atime.tv_nsec; + ip->i_update_core = 1; + } + if (mask & ATTR_CTIME) { + inode->i_ctime = iattr->ia_ctime; + ip->i_d.di_ctime.t_sec = iattr->ia_ctime.tv_sec; + ip->i_d.di_ctime.t_nsec = iattr->ia_ctime.tv_nsec; + ip->i_update_core = 1; + } + if (mask & ATTR_MTIME) { + inode->i_mtime = iattr->ia_mtime; + ip->i_d.di_mtime.t_sec = iattr->ia_mtime.tv_sec; + ip->i_d.di_mtime.t_nsec = iattr->ia_mtime.tv_nsec; + ip->i_update_core = 1; + } + + xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); + + XFS_STATS_INC(xs_ig_attrchg); + + if (mp->m_flags & XFS_MOUNT_WSYNC) + xfs_trans_set_sync(tp); + error = xfs_trans_commit(tp, 0); + + xfs_iunlock(ip, XFS_ILOCK_EXCL); + + /* + * Release any dquot(s) the inode had kept before chown. + */ + xfs_qm_dqrele(olddquot1); + xfs_qm_dqrele(olddquot2); + xfs_qm_dqrele(udqp); + xfs_qm_dqrele(gdqp); + + if (error) + return XFS_ERROR(error); + + /* + * XXX(hch): Updating the ACL entries is not atomic vs the i_mode + * update. We could avoid this with linked transactions + * and passing down the transaction pointer all the way + * to attr_set. No previous user of the generic + * Posix ACL code seems to care about this issue either. + */ + if ((mask & ATTR_MODE) && !(flags & XFS_ATTR_NOACL)) { + error = -xfs_acl_chmod(inode); + if (error) + return XFS_ERROR(error); + } + + return 0; + +out_trans_cancel: + xfs_trans_cancel(tp, 0); + xfs_iunlock(ip, XFS_ILOCK_EXCL); +out_dqrele: + xfs_qm_dqrele(udqp); + xfs_qm_dqrele(gdqp); + return error; +} + +/* + * Truncate file. Must have write permission and not be a directory. + */ +int +xfs_setattr_size( + struct xfs_inode *ip, + struct iattr *iattr, + int flags) +{ + struct xfs_mount *mp = ip->i_mount; + struct inode *inode = VFS_I(ip); + int mask = iattr->ia_valid; + struct xfs_trans *tp; + int error; + uint lock_flags; + uint commit_flags = 0; + + trace_xfs_setattr(ip); + + if (mp->m_flags & XFS_MOUNT_RDONLY) + return XFS_ERROR(EROFS); + + if (XFS_FORCED_SHUTDOWN(mp)) + return XFS_ERROR(EIO); + + error = -inode_change_ok(inode, iattr); + if (error) + return XFS_ERROR(error); + + ASSERT(S_ISREG(ip->i_d.di_mode)); + ASSERT((mask & (ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_ATIME|ATTR_ATIME_SET| + ATTR_MTIME_SET|ATTR_KILL_SUID|ATTR_KILL_SGID| + ATTR_KILL_PRIV|ATTR_TIMES_SET)) == 0); + + lock_flags = XFS_ILOCK_EXCL; + if (!(flags & XFS_ATTR_NOLOCK)) + lock_flags |= XFS_IOLOCK_EXCL; + xfs_ilock(ip, lock_flags); + + /* + * Short circuit the truncate case for zero length files. + */ + if (iattr->ia_size == 0 && + ip->i_size == 0 && ip->i_d.di_nextents == 0) { + xfs_iunlock(ip, XFS_ILOCK_EXCL); + lock_flags &= ~XFS_ILOCK_EXCL; + if (mask & ATTR_CTIME) { + inode->i_mtime = inode->i_ctime = + current_fs_time(inode->i_sb); + xfs_mark_inode_dirty_sync(ip); + } + goto out_unlock; + } + + /* + * Make sure that the dquots are attached to the inode. + */ + error = xfs_qm_dqattach_locked(ip, 0); + if (error) + goto out_unlock; + + /* + * Now we can make the changes. Before we join the inode to the + * transaction, take care of the part of the truncation that must be + * done without the inode lock. This needs to be done before joining + * the inode to the transaction, because the inode cannot be unlocked + * once it is a part of the transaction. + */ + if (iattr->ia_size > ip->i_size) { + /* + * Do the first part of growing a file: zero any data in the + * last block that is beyond the old EOF. We need to do this + * before the inode is joined to the transaction to modify + * i_size. + */ + error = xfs_zero_eof(ip, iattr->ia_size, ip->i_size); + if (error) + goto out_unlock; + } + xfs_iunlock(ip, XFS_ILOCK_EXCL); + lock_flags &= ~XFS_ILOCK_EXCL; + + /* + * We are going to log the inode size change in this transaction so + * any previous writes that are beyond the on disk EOF and the new + * EOF that have not been written out need to be written here. If we + * do not write the data out, we expose ourselves to the null files + * problem. + * + * Only flush from the on disk size to the smaller of the in memory + * file size or the new size as that's the range we really care about + * here and prevents waiting for other data not within the range we + * care about here. + */ + if (ip->i_size != ip->i_d.di_size && iattr->ia_size > ip->i_d.di_size) { + error = xfs_flush_pages(ip, ip->i_d.di_size, iattr->ia_size, + XBF_ASYNC, FI_NONE); + if (error) + goto out_unlock; + } + + /* + * Wait for all I/O to complete. + */ + xfs_ioend_wait(ip); + + error = -block_truncate_page(inode->i_mapping, iattr->ia_size, + xfs_get_blocks); + if (error) + goto out_unlock; + + tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_SIZE); + error = xfs_trans_reserve(tp, 0, XFS_ITRUNCATE_LOG_RES(mp), 0, + XFS_TRANS_PERM_LOG_RES, + XFS_ITRUNCATE_LOG_COUNT); + if (error) + goto out_trans_cancel; + + truncate_setsize(inode, iattr->ia_size); + + commit_flags = XFS_TRANS_RELEASE_LOG_RES; + lock_flags |= XFS_ILOCK_EXCL; + + xfs_ilock(ip, XFS_ILOCK_EXCL); + + xfs_trans_ijoin(tp, ip); + + /* + * Only change the c/mtime if we are changing the size or we are + * explicitly asked to change it. This handles the semantic difference + * between truncate() and ftruncate() as implemented in the VFS. + * + * The regular truncate() case without ATTR_CTIME and ATTR_MTIME is a + * special case where we need to update the times despite not having + * these flags set. For all other operations the VFS set these flags + * explicitly if it wants a timestamp update. + */ + if (iattr->ia_size != ip->i_size && + (!(mask & (ATTR_CTIME | ATTR_MTIME)))) { + iattr->ia_ctime = iattr->ia_mtime = + current_fs_time(inode->i_sb); + mask |= ATTR_CTIME | ATTR_MTIME; + } + + if (iattr->ia_size > ip->i_size) { + ip->i_d.di_size = iattr->ia_size; + ip->i_size = iattr->ia_size; + } else if (iattr->ia_size <= ip->i_size || + (iattr->ia_size == 0 && ip->i_d.di_nextents)) { + /* + * Signal a sync transaction unless we are truncating an + * already unlinked file on a wsync filesystem. + */ + error = xfs_itruncate_finish(&tp, ip, iattr->ia_size, + XFS_DATA_FORK, + ((ip->i_d.di_nlink != 0 || + !(mp->m_flags & XFS_MOUNT_WSYNC)) + ? 1 : 0)); + if (error) + goto out_trans_abort; + + /* + * Truncated "down", so we're removing references to old data + * here - if we delay flushing for a long time, we expose + * ourselves unduly to the notorious NULL files problem. So, + * we mark this inode and flush it when the file is closed, + * and do not wait the usual (long) time for writeout. + */ + xfs_iflags_set(ip, XFS_ITRUNCATED); + } + + if (mask & ATTR_CTIME) { + inode->i_ctime = iattr->ia_ctime; + ip->i_d.di_ctime.t_sec = iattr->ia_ctime.tv_sec; + ip->i_d.di_ctime.t_nsec = iattr->ia_ctime.tv_nsec; + ip->i_update_core = 1; + } + if (mask & ATTR_MTIME) { + inode->i_mtime = iattr->ia_mtime; + ip->i_d.di_mtime.t_sec = iattr->ia_mtime.tv_sec; + ip->i_d.di_mtime.t_nsec = iattr->ia_mtime.tv_nsec; + ip->i_update_core = 1; + } + + xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); + + XFS_STATS_INC(xs_ig_attrchg); + + if (mp->m_flags & XFS_MOUNT_WSYNC) + xfs_trans_set_sync(tp); + + error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); +out_unlock: + if (lock_flags) + xfs_iunlock(ip, lock_flags); + return error; + +out_trans_abort: + commit_flags |= XFS_TRANS_ABORT; +out_trans_cancel: + xfs_trans_cancel(tp, commit_flags); + goto out_unlock; +} + STATIC int xfs_vn_setattr( struct dentry *dentry, struct iattr *iattr) { - return -xfs_setattr(XFS_I(dentry->d_inode), iattr, 0); + if (iattr->ia_valid & ATTR_SIZE) + return -xfs_setattr_size(XFS_I(dentry->d_inode), iattr, 0); + return -xfs_setattr_nonsize(XFS_I(dentry->d_inode), iattr, 0); } #define XFS_FIEMAP_FLAGS (FIEMAP_FLAG_SYNC|FIEMAP_FLAG_XATTR) Index: xfs/fs/xfs/linux-2.6/xfs_acl.c =================================================================== --- xfs.orig/fs/xfs/linux-2.6/xfs_acl.c 2011-06-29 11:29:02.698306035 +0200 +++ xfs/fs/xfs/linux-2.6/xfs_acl.c 2011-06-29 11:29:07.154948558 +0200 @@ -264,7 +264,7 @@ xfs_set_mode(struct inode *inode, mode_t iattr.ia_mode = mode; iattr.ia_ctime = current_fs_time(inode->i_sb); - error = -xfs_setattr(XFS_I(inode), &iattr, XFS_ATTR_NOACL); + error = -xfs_setattr_nonsize(XFS_I(inode), &iattr, XFS_ATTR_NOACL); } return error; Index: xfs/fs/xfs/linux-2.6/xfs_file.c =================================================================== --- xfs.orig/fs/xfs/linux-2.6/xfs_file.c 2011-06-29 11:29:02.711639297 +0200 +++ xfs/fs/xfs/linux-2.6/xfs_file.c 2011-06-29 11:29:07.158281874 +0200 @@ -944,7 +944,7 @@ xfs_file_fallocate( iattr.ia_valid = ATTR_SIZE; iattr.ia_size = new_size; - error = -xfs_setattr(ip, &iattr, XFS_ATTR_NOLOCK); + error = -xfs_setattr_size(ip, &iattr, XFS_ATTR_NOLOCK); } out_unlock: Index: xfs/fs/xfs/xfs_vnodeops.c =================================================================== --- xfs.orig/fs/xfs/xfs_vnodeops.c 2011-06-29 11:29:02.721639242 +0200 +++ xfs/fs/xfs/xfs_vnodeops.c 2011-06-29 11:29:07.158281874 +0200 @@ -50,430 +50,6 @@ #include "xfs_vnodeops.h" #include "xfs_trace.h" -int -xfs_setattr( - struct xfs_inode *ip, - struct iattr *iattr, - int flags) -{ - xfs_mount_t *mp = ip->i_mount; - struct inode *inode = VFS_I(ip); - int mask = iattr->ia_valid; - xfs_trans_t *tp; - int code; - uint lock_flags; - uint commit_flags=0; - uid_t uid=0, iuid=0; - gid_t gid=0, igid=0; - struct xfs_dquot *udqp, *gdqp, *olddquot1, *olddquot2; - int need_iolock = 1; - - trace_xfs_setattr(ip); - - if (mp->m_flags & XFS_MOUNT_RDONLY) - return XFS_ERROR(EROFS); - - if (XFS_FORCED_SHUTDOWN(mp)) - return XFS_ERROR(EIO); - - code = -inode_change_ok(inode, iattr); - if (code) - return code; - - olddquot1 = olddquot2 = NULL; - udqp = gdqp = NULL; - - /* - * If disk quotas is on, we make sure that the dquots do exist on disk, - * before we start any other transactions. Trying to do this later - * is messy. We don't care to take a readlock to look at the ids - * in inode here, because we can't hold it across the trans_reserve. - * If the IDs do change before we take the ilock, we're covered - * because the i_*dquot fields will get updated anyway. - */ - if (XFS_IS_QUOTA_ON(mp) && (mask & (ATTR_UID|ATTR_GID))) { - uint qflags = 0; - - if ((mask & ATTR_UID) && XFS_IS_UQUOTA_ON(mp)) { - uid = iattr->ia_uid; - qflags |= XFS_QMOPT_UQUOTA; - } else { - uid = ip->i_d.di_uid; - } - if ((mask & ATTR_GID) && XFS_IS_GQUOTA_ON(mp)) { - gid = iattr->ia_gid; - qflags |= XFS_QMOPT_GQUOTA; - } else { - gid = ip->i_d.di_gid; - } - - /* - * We take a reference when we initialize udqp and gdqp, - * so it is important that we never blindly double trip on - * the same variable. See xfs_create() for an example. - */ - ASSERT(udqp == NULL); - ASSERT(gdqp == NULL); - code = xfs_qm_vop_dqalloc(ip, uid, gid, xfs_get_projid(ip), - qflags, &udqp, &gdqp); - if (code) - return code; - } - - /* - * For the other attributes, we acquire the inode lock and - * first do an error checking pass. - */ - tp = NULL; - lock_flags = XFS_ILOCK_EXCL; - if (flags & XFS_ATTR_NOLOCK) - need_iolock = 0; - if (!(mask & ATTR_SIZE)) { - tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_NOT_SIZE); - commit_flags = 0; - code = xfs_trans_reserve(tp, 0, XFS_ICHANGE_LOG_RES(mp), - 0, 0, 0); - if (code) { - lock_flags = 0; - goto error_return; - } - } else { - if (need_iolock) - lock_flags |= XFS_IOLOCK_EXCL; - } - - xfs_ilock(ip, lock_flags); - - /* - * Change file ownership. Must be the owner or privileged. - */ - if (mask & (ATTR_UID|ATTR_GID)) { - /* - * These IDs could have changed since we last looked at them. - * But, we're assured that if the ownership did change - * while we didn't have the inode locked, inode's dquot(s) - * would have changed also. - */ - iuid = ip->i_d.di_uid; - igid = ip->i_d.di_gid; - gid = (mask & ATTR_GID) ? iattr->ia_gid : igid; - uid = (mask & ATTR_UID) ? iattr->ia_uid : iuid; - - /* - * Do a quota reservation only if uid/gid is actually - * going to change. - */ - if (XFS_IS_QUOTA_RUNNING(mp) && - ((XFS_IS_UQUOTA_ON(mp) && iuid != uid) || - (XFS_IS_GQUOTA_ON(mp) && igid != gid))) { - ASSERT(tp); - code = xfs_qm_vop_chown_reserve(tp, ip, udqp, gdqp, - capable(CAP_FOWNER) ? - XFS_QMOPT_FORCE_RES : 0); - if (code) /* out of quota */ - goto error_return; - } - } - - /* - * Truncate file. Must have write permission and not be a directory. - */ - if (mask & ATTR_SIZE) { - /* Short circuit the truncate case for zero length files */ - if (iattr->ia_size == 0 && - ip->i_size == 0 && ip->i_d.di_nextents == 0) { - xfs_iunlock(ip, XFS_ILOCK_EXCL); - lock_flags &= ~XFS_ILOCK_EXCL; - if (mask & ATTR_CTIME) { - inode->i_mtime = inode->i_ctime = - current_fs_time(inode->i_sb); - xfs_mark_inode_dirty_sync(ip); - } - code = 0; - goto error_return; - } - - if (S_ISDIR(ip->i_d.di_mode)) { - code = XFS_ERROR(EISDIR); - goto error_return; - } else if (!S_ISREG(ip->i_d.di_mode)) { - code = XFS_ERROR(EINVAL); - goto error_return; - } - - /* - * Make sure that the dquots are attached to the inode. - */ - code = xfs_qm_dqattach_locked(ip, 0); - if (code) - goto error_return; - - /* - * Now we can make the changes. Before we join the inode - * to the transaction, if ATTR_SIZE is set then take care of - * the part of the truncation that must be done without the - * inode lock. This needs to be done before joining the inode - * to the transaction, because the inode cannot be unlocked - * once it is a part of the transaction. - */ - if (iattr->ia_size > ip->i_size) { - /* - * Do the first part of growing a file: zero any data - * in the last block that is beyond the old EOF. We - * need to do this before the inode is joined to the - * transaction to modify the i_size. - */ - code = xfs_zero_eof(ip, iattr->ia_size, ip->i_size); - if (code) - goto error_return; - } - xfs_iunlock(ip, XFS_ILOCK_EXCL); - lock_flags &= ~XFS_ILOCK_EXCL; - - /* - * We are going to log the inode size change in this - * transaction so any previous writes that are beyond the on - * disk EOF and the new EOF that have not been written out need - * to be written here. If we do not write the data out, we - * expose ourselves to the null files problem. - * - * Only flush from the on disk size to the smaller of the in - * memory file size or the new size as that's the range we - * really care about here and prevents waiting for other data - * not within the range we care about here. - */ - if (ip->i_size != ip->i_d.di_size && - iattr->ia_size > ip->i_d.di_size) { - code = xfs_flush_pages(ip, - ip->i_d.di_size, iattr->ia_size, - XBF_ASYNC, FI_NONE); - if (code) - goto error_return; - } - - /* wait for all I/O to complete */ - xfs_ioend_wait(ip); - - code = -block_truncate_page(inode->i_mapping, iattr->ia_size, - xfs_get_blocks); - if (code) - goto error_return; - - tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_SIZE); - code = xfs_trans_reserve(tp, 0, XFS_ITRUNCATE_LOG_RES(mp), 0, - XFS_TRANS_PERM_LOG_RES, - XFS_ITRUNCATE_LOG_COUNT); - if (code) - goto error_return; - - truncate_setsize(inode, iattr->ia_size); - - commit_flags = XFS_TRANS_RELEASE_LOG_RES; - lock_flags |= XFS_ILOCK_EXCL; - - xfs_ilock(ip, XFS_ILOCK_EXCL); - - xfs_trans_ijoin(tp, ip); - - /* - * Only change the c/mtime if we are changing the size - * or we are explicitly asked to change it. This handles - * the semantic difference between truncate() and ftruncate() - * as implemented in the VFS. - * - * The regular truncate() case without ATTR_CTIME and ATTR_MTIME - * is a special case where we need to update the times despite - * not having these flags set. For all other operations the - * VFS set these flags explicitly if it wants a timestamp - * update. - */ - if (iattr->ia_size != ip->i_size && - (!(mask & (ATTR_CTIME | ATTR_MTIME)))) { - iattr->ia_ctime = iattr->ia_mtime = - current_fs_time(inode->i_sb); - mask |= ATTR_CTIME | ATTR_MTIME; - } - - if (iattr->ia_size > ip->i_size) { - ip->i_d.di_size = iattr->ia_size; - ip->i_size = iattr->ia_size; - xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); - } else if (iattr->ia_size <= ip->i_size || - (iattr->ia_size == 0 && ip->i_d.di_nextents)) { - /* - * signal a sync transaction unless - * we're truncating an already unlinked - * file on a wsync filesystem - */ - code = xfs_itruncate_finish(&tp, ip, iattr->ia_size, - XFS_DATA_FORK, - ((ip->i_d.di_nlink != 0 || - !(mp->m_flags & XFS_MOUNT_WSYNC)) - ? 1 : 0)); - if (code) - goto abort_return; - /* - * Truncated "down", so we're removing references - * to old data here - if we now delay flushing for - * a long time, we expose ourselves unduly to the - * notorious NULL files problem. So, we mark this - * vnode and flush it when the file is closed, and - * do not wait the usual (long) time for writeout. - */ - xfs_iflags_set(ip, XFS_ITRUNCATED); - } - } else if (tp) { - xfs_trans_ijoin(tp, ip); - } - - /* - * Change file ownership. Must be the owner or privileged. - */ - if (mask & (ATTR_UID|ATTR_GID)) { - /* - * CAP_FSETID overrides the following restrictions: - * - * The set-user-ID and set-group-ID bits of a file will be - * cleared upon successful return from chown() - */ - if ((ip->i_d.di_mode & (S_ISUID|S_ISGID)) && - !capable(CAP_FSETID)) { - ip->i_d.di_mode &= ~(S_ISUID|S_ISGID); - } - - /* - * Change the ownerships and register quota modifications - * in the transaction. - */ - if (iuid != uid) { - if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_UQUOTA_ON(mp)) { - ASSERT(mask & ATTR_UID); - ASSERT(udqp); - olddquot1 = xfs_qm_vop_chown(tp, ip, - &ip->i_udquot, udqp); - } - ip->i_d.di_uid = uid; - inode->i_uid = uid; - } - if (igid != gid) { - if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_GQUOTA_ON(mp)) { - ASSERT(!XFS_IS_PQUOTA_ON(mp)); - ASSERT(mask & ATTR_GID); - ASSERT(gdqp); - olddquot2 = xfs_qm_vop_chown(tp, ip, - &ip->i_gdquot, gdqp); - } - ip->i_d.di_gid = gid; - inode->i_gid = gid; - } - } - - /* - * Change file access modes. - */ - if (mask & ATTR_MODE) { - umode_t mode = iattr->ia_mode; - - if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID)) - mode &= ~S_ISGID; - - ip->i_d.di_mode &= S_IFMT; - ip->i_d.di_mode |= mode & ~S_IFMT; - - inode->i_mode &= S_IFMT; - inode->i_mode |= mode & ~S_IFMT; - } - - /* - * Change file access or modified times. - */ - if (mask & ATTR_ATIME) { - inode->i_atime = iattr->ia_atime; - ip->i_d.di_atime.t_sec = iattr->ia_atime.tv_sec; - ip->i_d.di_atime.t_nsec = iattr->ia_atime.tv_nsec; - ip->i_update_core = 1; - } - if (mask & ATTR_CTIME) { - inode->i_ctime = iattr->ia_ctime; - ip->i_d.di_ctime.t_sec = iattr->ia_ctime.tv_sec; - ip->i_d.di_ctime.t_nsec = iattr->ia_ctime.tv_nsec; - ip->i_update_core = 1; - } - if (mask & ATTR_MTIME) { - inode->i_mtime = iattr->ia_mtime; - ip->i_d.di_mtime.t_sec = iattr->ia_mtime.tv_sec; - ip->i_d.di_mtime.t_nsec = iattr->ia_mtime.tv_nsec; - ip->i_update_core = 1; - } - - /* - * And finally, log the inode core if any attribute in it - * has been changed. - */ - if (mask & (ATTR_UID|ATTR_GID|ATTR_MODE| - ATTR_ATIME|ATTR_CTIME|ATTR_MTIME)) - xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); - - XFS_STATS_INC(xs_ig_attrchg); - - /* - * If this is a synchronous mount, make sure that the - * transaction goes to disk before returning to the user. - * This is slightly sub-optimal in that truncates require - * two sync transactions instead of one for wsync filesystems. - * One for the truncate and one for the timestamps since we - * don't want to change the timestamps unless we're sure the - * truncate worked. Truncates are less than 1% of the laddis - * mix so this probably isn't worth the trouble to optimize. - */ - code = 0; - if (mp->m_flags & XFS_MOUNT_WSYNC) - xfs_trans_set_sync(tp); - - code = xfs_trans_commit(tp, commit_flags); - - xfs_iunlock(ip, lock_flags); - - /* - * Release any dquot(s) the inode had kept before chown. - */ - xfs_qm_dqrele(olddquot1); - xfs_qm_dqrele(olddquot2); - xfs_qm_dqrele(udqp); - xfs_qm_dqrele(gdqp); - - if (code) - return code; - - /* - * XXX(hch): Updating the ACL entries is not atomic vs the i_mode - * update. We could avoid this with linked transactions - * and passing down the transaction pointer all the way - * to attr_set. No previous user of the generic - * Posix ACL code seems to care about this issue either. - */ - if ((mask & ATTR_MODE) && !(flags & XFS_ATTR_NOACL)) { - code = -xfs_acl_chmod(inode); - if (code) - return XFS_ERROR(code); - } - - return 0; - - abort_return: - commit_flags |= XFS_TRANS_ABORT; - error_return: - xfs_qm_dqrele(udqp); - xfs_qm_dqrele(gdqp); - if (tp) { - xfs_trans_cancel(tp, commit_flags); - } - if (lock_flags != 0) { - xfs_iunlock(ip, lock_flags); - } - return code; -} - /* * The maximum pathlen is 1024 bytes. Since the minimum file system * blocksize is 512 bytes, we can get a max of 2 extents back from @@ -2784,7 +2360,7 @@ xfs_change_file_space( iattr.ia_valid = ATTR_SIZE; iattr.ia_size = startoffset; - error = xfs_setattr(ip, &iattr, attr_flags); + error = xfs_setattr_size(ip, &iattr, attr_flags); if (error) return error; Index: xfs/fs/xfs/xfs_vnodeops.h =================================================================== --- xfs.orig/fs/xfs/xfs_vnodeops.h 2011-06-29 11:29:02.734972504 +0200 +++ xfs/fs/xfs/xfs_vnodeops.h 2011-06-29 11:29:07.161615190 +0200 @@ -13,7 +13,8 @@ struct xfs_inode; struct xfs_iomap; -int xfs_setattr(struct xfs_inode *ip, struct iattr *vap, int flags); +int xfs_setattr_nonsize(struct xfs_inode *ip, struct iattr *vap, int flags); +int xfs_setattr_size(struct xfs_inode *ip, struct iattr *vap, int flags); #define XFS_ATTR_DMI 0x01 /* invocation from a DMI function */ #define XFS_ATTR_NONBLOCK 0x02 /* return EAGAIN if operation would block */ #define XFS_ATTR_NOLOCK 0x04 /* Don't grab any conflicting locks */ From BATV+1dd5f1c206cd6a728cfd+2868+infradead.org+hch@bombadil.srs.infradead.org Fri Jul 1 04:46:05 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p619k57f056004 for ; Fri, 1 Jul 2011 04:46:05 -0500 X-ASG-Debug-ID: 1309513563-63a603ba0000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from bombadil.infradead.org (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id F30E9466A1 for ; Fri, 1 Jul 2011 02:46:03 -0700 (PDT) Received: from bombadil.infradead.org (173-166-109-252-newengland.hfc.comcastbusiness.net [173.166.109.252]) by cuda.sgi.com with ESMTP id IgSUEFhJzv4h2R6L for ; Fri, 01 Jul 2011 02:46:03 -0700 (PDT) Received: from hch by bombadil.infradead.org with local (Exim 4.76 #1 (Red Hat Linux)) id 1QcaIV-0001sZ-9p for xfs@oss.sgi.com; Fri, 01 Jul 2011 09:46:03 +0000 Message-Id: <20110701094603.254731796@bombadil.infradead.org> User-Agent: quilt/0.48-1 Date: Fri, 01 Jul 2011 05:43:27 -0400 From: Christoph Hellwig To: xfs@oss.sgi.com X-ASG-Orig-Subj: [PATCH 06/27] xfs: kill xfs_itruncate_start Subject: [PATCH 06/27] xfs: kill xfs_itruncate_start References: <20110701094321.936534538@bombadil.infradead.org> Content-Disposition: inline; filename=xfs-kill-xfs_itruncate_start X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: 173-166-109-252-newengland.hfc.comcastbusiness.net[173.166.109.252] X-Barracuda-Start-Time: 1309513563 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -1.42 X-Barracuda-Spam-Status: No, SCORE=-1.42 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=BSF_SC5_MJ1963, RDNS_DYNAMIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67645 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_DYNAMIC Delivered to trusted network by host with dynamic-looking rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean xfs_itruncate_start is a rather length wrapper that evaluates to a call to xfs_ioend_wait and xfs_tosspages, and only has two callers. Instead of using the complicated checks left over from IRIX where we can to truncate the pagecache just call xfs_tosspages (aka truncate_inode_pages) directly as we want to get rid of all data after i_size, and truncate_inode_pages handles incorrect alignments and too large offsets just fine. Signed-off-by: Christoph Hellwig Reviewed-by: Alex Elder Reviewed-by: Dave Chinner Index: xfs/fs/xfs/xfs_inode.c =================================================================== --- xfs.orig/fs/xfs/xfs_inode.c 2011-06-29 11:29:02.494973804 +0200 +++ xfs/fs/xfs/xfs_inode.c 2011-06-29 11:29:11.888256249 +0200 @@ -1217,165 +1217,8 @@ xfs_isize_check( #endif /* DEBUG */ /* - * Calculate the last possible buffered byte in a file. This must - * include data that was buffered beyond the EOF by the write code. - * This also needs to deal with overflowing the xfs_fsize_t type - * which can happen for sizes near the limit. - * - * We also need to take into account any blocks beyond the EOF. It - * may be the case that they were buffered by a write which failed. - * In that case the pages will still be in memory, but the inode size - * will never have been updated. - */ -STATIC xfs_fsize_t -xfs_file_last_byte( - xfs_inode_t *ip) -{ - xfs_mount_t *mp; - xfs_fsize_t last_byte; - xfs_fileoff_t last_block; - xfs_fileoff_t size_last_block; - int error; - - ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL|XFS_IOLOCK_SHARED)); - - mp = ip->i_mount; - /* - * Only check for blocks beyond the EOF if the extents have - * been read in. This eliminates the need for the inode lock, - * and it also saves us from looking when it really isn't - * necessary. - */ - if (ip->i_df.if_flags & XFS_IFEXTENTS) { - xfs_ilock(ip, XFS_ILOCK_SHARED); - error = xfs_bmap_last_offset(NULL, ip, &last_block, - XFS_DATA_FORK); - xfs_iunlock(ip, XFS_ILOCK_SHARED); - if (error) { - last_block = 0; - } - } else { - last_block = 0; - } - size_last_block = XFS_B_TO_FSB(mp, (xfs_ufsize_t)ip->i_size); - last_block = XFS_FILEOFF_MAX(last_block, size_last_block); - - last_byte = XFS_FSB_TO_B(mp, last_block); - if (last_byte < 0) { - return XFS_MAXIOFFSET(mp); - } - last_byte += (1 << mp->m_writeio_log); - if (last_byte < 0) { - return XFS_MAXIOFFSET(mp); - } - return last_byte; -} - -/* - * Start the truncation of the file to new_size. The new size - * must be smaller than the current size. This routine will - * clear the buffer and page caches of file data in the removed - * range, and xfs_itruncate_finish() will remove the underlying - * disk blocks. - * - * The inode must have its I/O lock locked EXCLUSIVELY, and it - * must NOT have the inode lock held at all. This is because we're - * calling into the buffer/page cache code and we can't hold the - * inode lock when we do so. - * - * We need to wait for any direct I/Os in flight to complete before we - * proceed with the truncate. This is needed to prevent the extents - * being read or written by the direct I/Os from being removed while the - * I/O is in flight as there is no other method of synchronising - * direct I/O with the truncate operation. Also, because we hold - * the IOLOCK in exclusive mode, we prevent new direct I/Os from being - * started until the truncate completes and drops the lock. Essentially, - * the xfs_ioend_wait() call forms an I/O barrier that provides strict - * ordering between direct I/Os and the truncate operation. - * - * The flags parameter can have either the value XFS_ITRUNC_DEFINITE - * or XFS_ITRUNC_MAYBE. The XFS_ITRUNC_MAYBE value should be used - * in the case that the caller is locking things out of order and - * may not be able to call xfs_itruncate_finish() with the inode lock - * held without dropping the I/O lock. If the caller must drop the - * I/O lock before calling xfs_itruncate_finish(), then xfs_itruncate_start() - * must be called again with all the same restrictions as the initial - * call. - */ -int -xfs_itruncate_start( - xfs_inode_t *ip, - uint flags, - xfs_fsize_t new_size) -{ - xfs_fsize_t last_byte; - xfs_off_t toss_start; - xfs_mount_t *mp; - int error = 0; - - ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL)); - ASSERT((new_size == 0) || (new_size <= ip->i_size)); - ASSERT((flags == XFS_ITRUNC_DEFINITE) || - (flags == XFS_ITRUNC_MAYBE)); - - mp = ip->i_mount; - - /* wait for the completion of any pending DIOs */ - if (new_size == 0 || new_size < ip->i_size) - xfs_ioend_wait(ip); - - /* - * Call toss_pages or flushinval_pages to get rid of pages - * overlapping the region being removed. We have to use - * the less efficient flushinval_pages in the case that the - * caller may not be able to finish the truncate without - * dropping the inode's I/O lock. Make sure - * to catch any pages brought in by buffers overlapping - * the EOF by searching out beyond the isize by our - * block size. We round new_size up to a block boundary - * so that we don't toss things on the same block as - * new_size but before it. - * - * Before calling toss_page or flushinval_pages, make sure to - * call remapf() over the same region if the file is mapped. - * This frees up mapped file references to the pages in the - * given range and for the flushinval_pages case it ensures - * that we get the latest mapped changes flushed out. - */ - toss_start = XFS_B_TO_FSB(mp, (xfs_ufsize_t)new_size); - toss_start = XFS_FSB_TO_B(mp, toss_start); - if (toss_start < 0) { - /* - * The place to start tossing is beyond our maximum - * file size, so there is no way that the data extended - * out there. - */ - return 0; - } - last_byte = xfs_file_last_byte(ip); - trace_xfs_itruncate_start(ip, new_size, flags, toss_start, last_byte); - if (last_byte > toss_start) { - if (flags & XFS_ITRUNC_DEFINITE) { - xfs_tosspages(ip, toss_start, - -1, FI_REMAPF_LOCKED); - } else { - error = xfs_flushinval_pages(ip, toss_start, - -1, FI_REMAPF_LOCKED); - } - } - -#ifdef DEBUG - if (new_size == 0) { - ASSERT(VN_CACHED(VFS_I(ip)) == 0); - } -#endif - return error; -} - -/* - * Shrink the file to the given new_size. The new size must be smaller than - * the current size. This will free up the underlying blocks in the removed - * range after a call to xfs_itruncate_start() or xfs_atruncate_start(). + * Free up the underlying blocks past new_size. The new size must be + * smaller than the current size. * * The transaction passed to this routine must have made a permanent log * reservation of at least XFS_ITRUNCATE_LOG_RES. This routine may commit the @@ -1387,7 +1230,7 @@ xfs_itruncate_start( * will be "held" within the returned transaction. This routine does NOT * require any disk space to be reserved for it within the transaction. * - * The fork parameter must be either xfs_attr_fork or xfs_data_fork, and it + * The fork parameter must be either XFS_ATTR_FORK or XFS_DATA_FORK, and it * indicates the fork which is to be truncated. For the attribute fork we only * support truncation to size 0. * Index: xfs/fs/xfs/xfs_vnodeops.c =================================================================== --- xfs.orig/fs/xfs/xfs_vnodeops.c 2011-06-29 11:29:07.158281874 +0200 +++ xfs/fs/xfs/xfs_vnodeops.c 2011-06-29 11:29:11.888256249 +0200 @@ -197,13 +197,6 @@ xfs_free_eofblocks( */ tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE); - /* - * Do the xfs_itruncate_start() call before - * reserving any log space because - * itruncate_start will call into the buffer - * cache and we can't - * do that within a transaction. - */ if (flags & XFS_FREE_EOF_TRYLOCK) { if (!xfs_ilock_nowait(ip, XFS_IOLOCK_EXCL)) { xfs_trans_cancel(tp, 0); @@ -212,13 +205,6 @@ xfs_free_eofblocks( } else { xfs_ilock(ip, XFS_IOLOCK_EXCL); } - error = xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE, - ip->i_size); - if (error) { - xfs_trans_cancel(tp, 0); - xfs_iunlock(ip, XFS_IOLOCK_EXCL); - return error; - } error = xfs_trans_reserve(tp, 0, XFS_ITRUNCATE_LOG_RES(mp), @@ -660,20 +646,9 @@ xfs_inactive( tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE); if (truncate) { - /* - * Do the xfs_itruncate_start() call before - * reserving any log space because itruncate_start - * will call into the buffer cache and we can't - * do that within a transaction. - */ xfs_ilock(ip, XFS_IOLOCK_EXCL); - error = xfs_itruncate_start(ip, XFS_ITRUNC_DEFINITE, 0); - if (error) { - xfs_trans_cancel(tp, 0); - xfs_iunlock(ip, XFS_IOLOCK_EXCL); - return VN_INACTIVE_CACHE; - } + xfs_ioend_wait(ip); error = xfs_trans_reserve(tp, 0, XFS_ITRUNCATE_LOG_RES(mp), Index: xfs/fs/xfs/linux-2.6/xfs_trace.h =================================================================== --- xfs.orig/fs/xfs/linux-2.6/xfs_trace.h 2011-06-29 11:29:02.518307010 +0200 +++ xfs/fs/xfs/linux-2.6/xfs_trace.h 2011-06-29 11:29:11.891589564 +0200 @@ -1029,40 +1029,6 @@ DEFINE_SIMPLE_IO_EVENT(xfs_delalloc_enos DEFINE_SIMPLE_IO_EVENT(xfs_unwritten_convert); DEFINE_SIMPLE_IO_EVENT(xfs_get_blocks_notfound); - -TRACE_EVENT(xfs_itruncate_start, - TP_PROTO(struct xfs_inode *ip, xfs_fsize_t new_size, int flag, - xfs_off_t toss_start, xfs_off_t toss_finish), - TP_ARGS(ip, new_size, flag, toss_start, toss_finish), - TP_STRUCT__entry( - __field(dev_t, dev) - __field(xfs_ino_t, ino) - __field(xfs_fsize_t, size) - __field(xfs_fsize_t, new_size) - __field(xfs_off_t, toss_start) - __field(xfs_off_t, toss_finish) - __field(int, flag) - ), - TP_fast_assign( - __entry->dev = VFS_I(ip)->i_sb->s_dev; - __entry->ino = ip->i_ino; - __entry->size = ip->i_d.di_size; - __entry->new_size = new_size; - __entry->toss_start = toss_start; - __entry->toss_finish = toss_finish; - __entry->flag = flag; - ), - TP_printk("dev %d:%d ino 0x%llx %s size 0x%llx new_size 0x%llx " - "toss start 0x%llx toss finish 0x%llx", - MAJOR(__entry->dev), MINOR(__entry->dev), - __entry->ino, - __print_flags(__entry->flag, "|", XFS_ITRUNC_FLAGS), - __entry->size, - __entry->new_size, - __entry->toss_start, - __entry->toss_finish) -); - DECLARE_EVENT_CLASS(xfs_itrunc_class, TP_PROTO(struct xfs_inode *ip, xfs_fsize_t new_size), TP_ARGS(ip, new_size), Index: xfs/fs/xfs/xfs_inode.h =================================================================== --- xfs.orig/fs/xfs/xfs_inode.h 2011-06-29 11:29:02.531640272 +0200 +++ xfs/fs/xfs/xfs_inode.h 2011-06-29 11:29:11.891589564 +0200 @@ -458,16 +458,6 @@ static inline void xfs_ifunlock(xfs_inod extern struct lock_class_key xfs_iolock_reclaimable; /* - * Flags for xfs_itruncate_start(). - */ -#define XFS_ITRUNC_DEFINITE 0x1 -#define XFS_ITRUNC_MAYBE 0x2 - -#define XFS_ITRUNC_FLAGS \ - { XFS_ITRUNC_DEFINITE, "DEFINITE" }, \ - { XFS_ITRUNC_MAYBE, "MAYBE" } - -/* * For multiple groups support: if S_ISGID bit is set in the parent * directory, group of new file is set to that of the parent, and * new subdirectory gets S_ISGID bit from parent. @@ -501,7 +491,6 @@ uint xfs_ip2xflags(struct xfs_inode *); uint xfs_dic2xflags(struct xfs_dinode *); int xfs_ifree(struct xfs_trans *, xfs_inode_t *, struct xfs_bmap_free *); -int xfs_itruncate_start(xfs_inode_t *, uint, xfs_fsize_t); int xfs_itruncate_finish(struct xfs_trans **, xfs_inode_t *, xfs_fsize_t, int, int); int xfs_iunlink(struct xfs_trans *, xfs_inode_t *); From BATV+1dd5f1c206cd6a728cfd+2868+infradead.org+hch@bombadil.srs.infradead.org Fri Jul 1 04:46:04 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p619k3rV055978 for ; Fri, 1 Jul 2011 04:46:04 -0500 X-ASG-Debug-ID: 1309513562-2b4c001b0000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from bombadil.infradead.org (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 1E8B016748BA for ; Fri, 1 Jul 2011 02:46:02 -0700 (PDT) Received: from bombadil.infradead.org (173-166-109-252-newengland.hfc.comcastbusiness.net [173.166.109.252]) by cuda.sgi.com with ESMTP id QgEY7CYDxDVxrXc7 for ; Fri, 01 Jul 2011 02:46:02 -0700 (PDT) Received: from hch by bombadil.infradead.org with local (Exim 4.76 #1 (Red Hat Linux)) id 1QcaIU-0001pr-AD for xfs@oss.sgi.com; Fri, 01 Jul 2011 09:46:02 +0000 Message-Id: <20110701094602.285184989@bombadil.infradead.org> User-Agent: quilt/0.48-1 Date: Fri, 01 Jul 2011 05:43:22 -0400 From: Christoph Hellwig To: xfs@oss.sgi.com X-ASG-Orig-Subj: [PATCH 01/27] xfs: PF_FSTRANS should never be set in ->writepage Subject: [PATCH 01/27] xfs: PF_FSTRANS should never be set in ->writepage References: <20110701094321.936534538@bombadil.infradead.org> Content-Disposition: inline; filename=xfs-writepage-simplify-fstrans-check X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: 173-166-109-252-newengland.hfc.comcastbusiness.net[173.166.109.252] X-Barracuda-Start-Time: 1309513563 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -1.42 X-Barracuda-Spam-Status: No, SCORE=-1.42 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=BSF_SC5_MJ1963, RDNS_DYNAMIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67646 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_DYNAMIC Delivered to trusted network by host with dynamic-looking rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean Now that we reject direct reclaim in addition to always using GFP_NOFS allocation there's no chance we'll ever end up in ->writepage with PF_FSTRANS set. Add a WARN_ON if we hit this case, and stop checking if we'd actually need to start a transaction. Signed-off-by: Christoph Hellwig Reviewed-by: Alex Elder Reviewed-by: Dave Chinner Index: xfs/fs/xfs/linux-2.6/xfs_aops.c =================================================================== --- xfs.orig/fs/xfs/linux-2.6/xfs_aops.c 2011-06-30 14:50:35.206501640 +0200 +++ xfs/fs/xfs/linux-2.6/xfs_aops.c 2011-06-30 15:34:59.156468543 +0200 @@ -894,11 +894,6 @@ out_invalidate: * For unwritten space on the page we need to start the conversion to * regular allocated space. * For any other dirty buffer heads on the page we should flush them. - * - * If we detect that a transaction would be required to flush the page, we - * have to check the process flags first, if we are already in a transaction - * or disk I/O during allocations is off, we need to fail the writepage and - * redirty the page. */ STATIC int xfs_vm_writepage( @@ -906,7 +901,6 @@ xfs_vm_writepage( struct writeback_control *wbc) { struct inode *inode = page->mapping->host; - int delalloc, unwritten; struct buffer_head *bh, *head; struct xfs_bmbt_irec imap; xfs_ioend_t *ioend = NULL, *iohead = NULL; @@ -938,15 +932,10 @@ xfs_vm_writepage( goto redirty; /* - * We need a transaction if there are delalloc or unwritten buffers - * on the page. - * - * If we need a transaction and the process flags say we are already - * in a transaction, or no IO is allowed then mark the page dirty - * again and leave the page as is. + * Given that we do not allow direct reclaim to call us, we should + * never be called while in a filesystem transaction. */ - xfs_count_page_state(page, &delalloc, &unwritten); - if ((current->flags & PF_FSTRANS) && (delalloc || unwritten)) + if (WARN_ON(current->flags & PF_FSTRANS)) goto redirty; /* Is this page beyond the end of the file? */ From BATV+1dd5f1c206cd6a728cfd+2868+infradead.org+hch@bombadil.srs.infradead.org Fri Jul 1 04:46:06 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p619k5Ia056028 for ; Fri, 1 Jul 2011 04:46:05 -0500 X-ASG-Debug-ID: 1309513564-63c103c70000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from bombadil.infradead.org (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 3F189466A2 for ; Fri, 1 Jul 2011 02:46:05 -0700 (PDT) Received: from bombadil.infradead.org (173-166-109-252-newengland.hfc.comcastbusiness.net [173.166.109.252]) by cuda.sgi.com with ESMTP id RF6A8BiNq6UIIOFq for ; Fri, 01 Jul 2011 02:46:05 -0700 (PDT) Received: from hch by bombadil.infradead.org with local (Exim 4.76 #1 (Red Hat Linux)) id 1QcaIW-0001vB-Kp for xfs@oss.sgi.com; Fri, 01 Jul 2011 09:46:04 +0000 Message-Id: <20110701094604.608829837@bombadil.infradead.org> User-Agent: quilt/0.48-1 Date: Fri, 01 Jul 2011 05:43:32 -0400 From: Christoph Hellwig To: xfs@oss.sgi.com X-ASG-Orig-Subj: [PATCH 11/27] xfs: kill the unused struct xfs_sync_work Subject: [PATCH 11/27] xfs: kill the unused struct xfs_sync_work References: <20110701094321.936534538@bombadil.infradead.org> Content-Disposition: inline; filename=xfs-kill-xfs_sync_work X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: 173-166-109-252-newengland.hfc.comcastbusiness.net[173.166.109.252] X-Barracuda-Start-Time: 1309513565 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -1.42 X-Barracuda-Spam-Status: No, SCORE=-1.42 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=BSF_SC5_MJ1963, RDNS_DYNAMIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67645 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_DYNAMIC Delivered to trusted network by host with dynamic-looking rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean Signed-off-by: Christoph Hellwig Index: xfs/fs/xfs/linux-2.6/xfs_sync.h =================================================================== --- xfs.orig/fs/xfs/linux-2.6/xfs_sync.h 2011-06-30 15:47:30.203125879 +0200 +++ xfs/fs/xfs/linux-2.6/xfs_sync.h 2011-06-30 15:47:39.093125768 +0200 @@ -21,14 +21,6 @@ struct xfs_mount; struct xfs_perag; -typedef struct xfs_sync_work { - struct list_head w_list; - struct xfs_mount *w_mount; - void *w_data; /* syncer routine argument */ - void (*w_syncer)(struct xfs_mount *, void *); - struct completion *w_completion; -} xfs_sync_work_t; - #define SYNC_WAIT 0x0001 /* wait for i/o to complete */ #define SYNC_TRYLOCK 0x0002 /* only try to lock inodes */ From BATV+1dd5f1c206cd6a728cfd+2868+infradead.org+hch@bombadil.srs.infradead.org Fri Jul 1 04:46:05 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p619k4Vh055996 for ; Fri, 1 Jul 2011 04:46:05 -0500 X-ASG-Debug-ID: 1309513563-2b44001f0000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from bombadil.infradead.org (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id E1E1616748BA for ; Fri, 1 Jul 2011 02:46:03 -0700 (PDT) Received: from bombadil.infradead.org (173-166-109-252-newengland.hfc.comcastbusiness.net [173.166.109.252]) by cuda.sgi.com with ESMTP id DIsDFvSKbD3iDPzw for ; Fri, 01 Jul 2011 02:46:03 -0700 (PDT) Received: from hch by bombadil.infradead.org with local (Exim 4.76 #1 (Red Hat Linux)) id 1QcaIV-0001rw-2K for xfs@oss.sgi.com; Fri, 01 Jul 2011 09:46:03 +0000 Message-Id: <20110701094603.034828069@bombadil.infradead.org> User-Agent: quilt/0.48-1 Date: Fri, 01 Jul 2011 05:43:26 -0400 From: Christoph Hellwig To: xfs@oss.sgi.com X-ASG-Orig-Subj: [PATCH 05/27] xfs: always log timestamp updates in xfs_setattr_size Subject: [PATCH 05/27] xfs: always log timestamp updates in xfs_setattr_size References: <20110701094321.936534538@bombadil.infradead.org> Content-Disposition: inline; filename=xfs-simplify-setattr X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: 173-166-109-252-newengland.hfc.comcastbusiness.net[173.166.109.252] X-Barracuda-Start-Time: 1309513563 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -1.42 X-Barracuda-Spam-Status: No, SCORE=-1.42 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=BSF_SC5_MJ1963, RDNS_DYNAMIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67646 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_DYNAMIC Delivered to trusted network by host with dynamic-looking rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean Get rid of the special case where we use unlogged timestamp updates for a truncate to the current inode size, and just call xfs_setattr_nonsize for it to treat it like a utimes calls. Signed-off-by: Christoph Hellwig Reviewed-by: Alex Elder Reviewed-by: Dave Chinner Index: xfs/fs/xfs/linux-2.6/xfs_iops.c =================================================================== --- xfs.orig/fs/xfs/linux-2.6/xfs_iops.c 2011-06-30 00:11:54.876715732 +0200 +++ xfs/fs/xfs/linux-2.6/xfs_iops.c 2011-06-30 09:02:46.606760906 +0200 @@ -773,14 +773,15 @@ xfs_setattr_size( */ if (iattr->ia_size == 0 && ip->i_size == 0 && ip->i_d.di_nextents == 0) { - xfs_iunlock(ip, XFS_ILOCK_EXCL); - lock_flags &= ~XFS_ILOCK_EXCL; - if (mask & ATTR_CTIME) { - inode->i_mtime = inode->i_ctime = - current_fs_time(inode->i_sb); - xfs_mark_inode_dirty_sync(ip); - } - goto out_unlock; + if (!(mask & (ATTR_CTIME|ATTR_MTIME))) + goto out_unlock; + + /* + * Use the regular setattr path to update the timestamps. + */ + xfs_iunlock(ip, lock_flags); + iattr->ia_valid &= ~ATTR_SIZE; + return xfs_setattr_nonsize(ip, iattr, 0); } /* From BATV+1dd5f1c206cd6a728cfd+2868+infradead.org+hch@bombadil.srs.infradead.org Fri Jul 1 04:46:06 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.4 required=5.0 tests=BAYES_00,J_CHICKENPOX_35, J_CHICKENPOX_38,J_CHICKENPOX_39,J_CHICKENPOX_65,J_CHICKENPOX_73 autolearn=no version=3.4.0-r929098 Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p619k6bO056051 for ; Fri, 1 Jul 2011 04:46:06 -0500 X-ASG-Debug-ID: 1309513565-63a403d70000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from bombadil.infradead.org (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 75B414669F for ; Fri, 1 Jul 2011 02:46:05 -0700 (PDT) Received: from bombadil.infradead.org (173-166-109-252-newengland.hfc.comcastbusiness.net [173.166.109.252]) by cuda.sgi.com with ESMTP id d92S0RQuvgg2kpT1 for ; Fri, 01 Jul 2011 02:46:05 -0700 (PDT) Received: from hch by bombadil.infradead.org with local (Exim 4.76 #1 (Red Hat Linux)) id 1QcaIW-0001vh-Qt for xfs@oss.sgi.com; Fri, 01 Jul 2011 09:46:04 +0000 Message-Id: <20110701094604.795668656@bombadil.infradead.org> User-Agent: quilt/0.48-1 Date: Fri, 01 Jul 2011 05:43:33 -0400 From: Christoph Hellwig To: xfs@oss.sgi.com X-ASG-Orig-Subj: [PATCH 12/27] xfs: factor out xfs_dir2_leaf_find_entry Subject: [PATCH 12/27] xfs: factor out xfs_dir2_leaf_find_entry References: <20110701094321.936534538@bombadil.infradead.org> Content-Disposition: inline; filename=xfs-factor-dir2-leaf-code X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: 173-166-109-252-newengland.hfc.comcastbusiness.net[173.166.109.252] X-Barracuda-Start-Time: 1309513565 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -1.42 X-Barracuda-Spam-Status: No, SCORE=-1.42 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=BSF_SC5_MJ1963, RDNS_DYNAMIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67645 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_DYNAMIC Delivered to trusted network by host with dynamic-looking rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean Add a new xfs_dir2_leaf_find_entry helper to factor out some duplicate code from xfs_dir2_leaf_addname xfs_dir2_leafn_add. Found by Eric Sandeen using an automated code duplication checker. Signed-off-by: Christoph Hellwig Reviewed-by: Dave Chinner Index: xfs/fs/xfs/xfs_dir2_leaf.c =================================================================== --- xfs.orig/fs/xfs/xfs_dir2_leaf.c 2011-06-29 19:45:24.846962285 +0200 +++ xfs/fs/xfs/xfs_dir2_leaf.c 2011-06-30 09:29:24.446740960 +0200 @@ -152,6 +152,123 @@ xfs_dir2_block_to_leaf( return 0; } +struct xfs_dir2_leaf_entry * +xfs_dir2_leaf_find_entry( + xfs_dir2_leaf_t *leaf, /* leaf structure */ + int index, /* leaf table position */ + int compact, /* need to compact leaves */ + int lowstale, /* index of prev stale leaf */ + int highstale, /* index of next stale leaf */ + int *lfloglow, /* low leaf logging index */ + int *lfloghigh) /* high leaf logging index */ +{ + if (!leaf->hdr.stale) { + xfs_dir2_leaf_entry_t *lep; /* leaf entry table pointer */ + + /* + * Now we need to make room to insert the leaf entry. + * + * If there are no stale entries, just insert a hole at index. + */ + lep = &leaf->ents[index]; + if (index < be16_to_cpu(leaf->hdr.count)) + memmove(lep + 1, lep, + (be16_to_cpu(leaf->hdr.count) - index) * + sizeof(*lep)); + + /* + * Record low and high logging indices for the leaf. + */ + *lfloglow = index; + *lfloghigh = be16_to_cpu(leaf->hdr.count); + be16_add_cpu(&leaf->hdr.count, 1); + return lep; + } + + /* + * There are stale entries. + * + * We will use one of them for the new entry. It's probably not at + * the right location, so we'll have to shift some up or down first. + * + * If we didn't compact before, we need to find the nearest stale + * entries before and after our insertion point. + */ + if (compact == 0) { + /* + * Find the first stale entry before the insertion point, + * if any. + */ + for (lowstale = index - 1; + lowstale >= 0 && + be32_to_cpu(leaf->ents[lowstale].address) != + XFS_DIR2_NULL_DATAPTR; + lowstale--) + continue; + + /* + * Find the next stale entry at or after the insertion point, + * if any. Stop if we go so far that the lowstale entry + * would be better. + */ + for (highstale = index; + highstale < be16_to_cpu(leaf->hdr.count) && + be32_to_cpu(leaf->ents[highstale].address) != + XFS_DIR2_NULL_DATAPTR && + (lowstale < 0 || + index - lowstale - 1 >= highstale - index); + highstale++) + continue; + } + + /* + * If the low one is better, use it. + */ + if (lowstale >= 0 && + (highstale == be16_to_cpu(leaf->hdr.count) || + index - lowstale - 1 < highstale - index)) { + ASSERT(index - lowstale - 1 >= 0); + ASSERT(be32_to_cpu(leaf->ents[lowstale].address) == + XFS_DIR2_NULL_DATAPTR); + + /* + * Copy entries up to cover the stale entry and make room + * for the new entry. + */ + if (index - lowstale - 1 > 0) { + memmove(&leaf->ents[lowstale], + &leaf->ents[lowstale + 1], + (index - lowstale - 1) * + sizeof(xfs_dir2_leaf_entry_t)); + } + *lfloglow = MIN(lowstale, *lfloglow); + *lfloghigh = MAX(index - 1, *lfloghigh); + be16_add_cpu(&leaf->hdr.stale, -1); + return &leaf->ents[index - 1]; + } + + /* + * The high one is better, so use that one. + */ + ASSERT(highstale - index >= 0); + ASSERT(be32_to_cpu(leaf->ents[highstale].address) == + XFS_DIR2_NULL_DATAPTR); + + /* + * Copy entries down to cover the stale entry and make room for the + * new entry. + */ + if (highstale - index > 0) { + memmove(&leaf->ents[index + 1], + &leaf->ents[index], + (highstale - index) * sizeof(xfs_dir2_leaf_entry_t)); + } + *lfloglow = MIN(index, *lfloglow); + *lfloghigh = MAX(highstale, *lfloghigh); + be16_add_cpu(&leaf->hdr.stale, -1); + return &leaf->ents[index]; +} + /* * Add an entry to a leaf form directory. */ @@ -430,102 +547,10 @@ xfs_dir2_leaf_addname( if (!grown) xfs_dir2_leaf_log_bests(tp, lbp, use_block, use_block); } - /* - * Now we need to make room to insert the leaf entry. - * If there are no stale entries, we just insert a hole at index. - */ - if (!leaf->hdr.stale) { - /* - * lep is still good as the index leaf entry. - */ - if (index < be16_to_cpu(leaf->hdr.count)) - memmove(lep + 1, lep, - (be16_to_cpu(leaf->hdr.count) - index) * sizeof(*lep)); - /* - * Record low and high logging indices for the leaf. - */ - lfloglow = index; - lfloghigh = be16_to_cpu(leaf->hdr.count); - be16_add_cpu(&leaf->hdr.count, 1); - } - /* - * There are stale entries. - * We will use one of them for the new entry. - * It's probably not at the right location, so we'll have to - * shift some up or down first. - */ - else { - /* - * If we didn't compact before, we need to find the nearest - * stale entries before and after our insertion point. - */ - if (compact == 0) { - /* - * Find the first stale entry before the insertion - * point, if any. - */ - for (lowstale = index - 1; - lowstale >= 0 && - be32_to_cpu(leaf->ents[lowstale].address) != - XFS_DIR2_NULL_DATAPTR; - lowstale--) - continue; - /* - * Find the next stale entry at or after the insertion - * point, if any. Stop if we go so far that the - * lowstale entry would be better. - */ - for (highstale = index; - highstale < be16_to_cpu(leaf->hdr.count) && - be32_to_cpu(leaf->ents[highstale].address) != - XFS_DIR2_NULL_DATAPTR && - (lowstale < 0 || - index - lowstale - 1 >= highstale - index); - highstale++) - continue; - } - /* - * If the low one is better, use it. - */ - if (lowstale >= 0 && - (highstale == be16_to_cpu(leaf->hdr.count) || - index - lowstale - 1 < highstale - index)) { - ASSERT(index - lowstale - 1 >= 0); - ASSERT(be32_to_cpu(leaf->ents[lowstale].address) == - XFS_DIR2_NULL_DATAPTR); - /* - * Copy entries up to cover the stale entry - * and make room for the new entry. - */ - if (index - lowstale - 1 > 0) - memmove(&leaf->ents[lowstale], - &leaf->ents[lowstale + 1], - (index - lowstale - 1) * sizeof(*lep)); - lep = &leaf->ents[index - 1]; - lfloglow = MIN(lowstale, lfloglow); - lfloghigh = MAX(index - 1, lfloghigh); - } - /* - * The high one is better, so use that one. - */ - else { - ASSERT(highstale - index >= 0); - ASSERT(be32_to_cpu(leaf->ents[highstale].address) == - XFS_DIR2_NULL_DATAPTR); - /* - * Copy entries down to cover the stale entry - * and make room for the new entry. - */ - if (highstale - index > 0) - memmove(&leaf->ents[index + 1], - &leaf->ents[index], - (highstale - index) * sizeof(*lep)); - lep = &leaf->ents[index]; - lfloglow = MIN(index, lfloglow); - lfloghigh = MAX(highstale, lfloghigh); - } - be16_add_cpu(&leaf->hdr.stale, -1); - } + + lep = xfs_dir2_leaf_find_entry(leaf, index, compact, lowstale, + highstale, &lfloglow, &lfloghigh); + /* * Fill in the new leaf entry. */ Index: xfs/fs/xfs/xfs_dir2_leaf.h =================================================================== --- xfs.orig/fs/xfs/xfs_dir2_leaf.h 2011-06-29 19:45:24.856962230 +0200 +++ xfs/fs/xfs/xfs_dir2_leaf.h 2011-06-30 09:18:07.263416117 +0200 @@ -248,6 +248,9 @@ extern int xfs_dir2_leaf_search_hash(str struct xfs_dabuf *lbp); extern int xfs_dir2_leaf_trim_data(struct xfs_da_args *args, struct xfs_dabuf *lbp, xfs_dir2_db_t db); +extern xfs_dir2_leaf_entry_t *xfs_dir2_leaf_find_entry(xfs_dir2_leaf_t *, int, + int, int, int, + int *, int *); extern int xfs_dir2_node_to_leaf(struct xfs_da_state *state); #endif /* __XFS_DIR2_LEAF_H__ */ Index: xfs/fs/xfs/xfs_dir2_node.c =================================================================== --- xfs.orig/fs/xfs/xfs_dir2_node.c 2011-06-29 19:45:24.870295493 +0200 +++ xfs/fs/xfs/xfs_dir2_node.c 2011-06-30 09:27:19.103409194 +0200 @@ -244,89 +244,13 @@ xfs_dir2_leafn_add( lfloglow = be16_to_cpu(leaf->hdr.count); lfloghigh = -1; } - /* - * No stale entries, just insert a space for the new entry. - */ - if (!leaf->hdr.stale) { - lep = &leaf->ents[index]; - if (index < be16_to_cpu(leaf->hdr.count)) - memmove(lep + 1, lep, - (be16_to_cpu(leaf->hdr.count) - index) * sizeof(*lep)); - lfloglow = index; - lfloghigh = be16_to_cpu(leaf->hdr.count); - be16_add_cpu(&leaf->hdr.count, 1); - } - /* - * There are stale entries. We'll use one for the new entry. - */ - else { - /* - * If we didn't do a compact then we need to figure out - * which stale entry will be used. - */ - if (compact == 0) { - /* - * Find first stale entry before our insertion point. - */ - for (lowstale = index - 1; - lowstale >= 0 && - be32_to_cpu(leaf->ents[lowstale].address) != - XFS_DIR2_NULL_DATAPTR; - lowstale--) - continue; - /* - * Find next stale entry after insertion point. - * Stop looking if the answer would be worse than - * lowstale already found. - */ - for (highstale = index; - highstale < be16_to_cpu(leaf->hdr.count) && - be32_to_cpu(leaf->ents[highstale].address) != - XFS_DIR2_NULL_DATAPTR && - (lowstale < 0 || - index - lowstale - 1 >= highstale - index); - highstale++) - continue; - } - /* - * Using the low stale entry. - * Shift entries up toward the stale slot. - */ - if (lowstale >= 0 && - (highstale == be16_to_cpu(leaf->hdr.count) || - index - lowstale - 1 < highstale - index)) { - ASSERT(be32_to_cpu(leaf->ents[lowstale].address) == - XFS_DIR2_NULL_DATAPTR); - ASSERT(index - lowstale - 1 >= 0); - if (index - lowstale - 1 > 0) - memmove(&leaf->ents[lowstale], - &leaf->ents[lowstale + 1], - (index - lowstale - 1) * sizeof(*lep)); - lep = &leaf->ents[index - 1]; - lfloglow = MIN(lowstale, lfloglow); - lfloghigh = MAX(index - 1, lfloghigh); - } - /* - * Using the high stale entry. - * Shift entries down toward the stale slot. - */ - else { - ASSERT(be32_to_cpu(leaf->ents[highstale].address) == - XFS_DIR2_NULL_DATAPTR); - ASSERT(highstale - index >= 0); - if (highstale - index > 0) - memmove(&leaf->ents[index + 1], - &leaf->ents[index], - (highstale - index) * sizeof(*lep)); - lep = &leaf->ents[index]; - lfloglow = MIN(index, lfloglow); - lfloghigh = MAX(highstale, lfloghigh); - } - be16_add_cpu(&leaf->hdr.stale, -1); - } + /* * Insert the new entry, log everything. */ + lep = xfs_dir2_leaf_find_entry(leaf, index, compact, lowstale, + highstale, &lfloglow, &lfloghigh); + lep->hashval = cpu_to_be32(args->hashval); lep->address = cpu_to_be32(xfs_dir2_db_off_to_dataptr(mp, args->blkno, args->index)); From BATV+1dd5f1c206cd6a728cfd+2868+infradead.org+hch@bombadil.srs.infradead.org Fri Jul 1 04:46:06 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p619k5BB056031 for ; Fri, 1 Jul 2011 04:46:05 -0500 X-ASG-Debug-ID: 1309513564-6d2300af0000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from bombadil.infradead.org (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id EB2B01EE3234 for ; Fri, 1 Jul 2011 02:46:04 -0700 (PDT) Received: from bombadil.infradead.org (173-166-109-252-newengland.hfc.comcastbusiness.net [173.166.109.252]) by cuda.sgi.com with ESMTP id cOPMbGSwYPLdQSmC for ; Fri, 01 Jul 2011 02:46:04 -0700 (PDT) Received: from hch by bombadil.infradead.org with local (Exim 4.76 #1 (Red Hat Linux)) id 1QcaIW-0001u9-86 for xfs@oss.sgi.com; Fri, 01 Jul 2011 09:46:04 +0000 Message-Id: <20110701094604.200765470@bombadil.infradead.org> User-Agent: quilt/0.48-1 Date: Fri, 01 Jul 2011 05:43:30 -0400 From: Christoph Hellwig To: xfs@oss.sgi.com X-ASG-Orig-Subj: [PATCH 09/27] xfs: fix filesystsem freeze race in xfs_trans_alloc Subject: [PATCH 09/27] xfs: fix filesystsem freeze race in xfs_trans_alloc References: <20110701094321.936534538@bombadil.infradead.org> Content-Disposition: inline; filename=xfs-fix-freeze-race X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: 173-166-109-252-newengland.hfc.comcastbusiness.net[173.166.109.252] X-Barracuda-Start-Time: 1309513564 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -1.42 X-Barracuda-Spam-Status: No, SCORE=-1.42 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=BSF_SC5_MJ1963, RDNS_DYNAMIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67645 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_DYNAMIC Delivered to trusted network by host with dynamic-looking rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean As pointed out by Jan xfs_trans_alloc can race with a concurrent filesystem freeze when it sleeps during the memory allocation. Fix this by moving the wait_for_freeze call after the memory allocation. This means moving the freeze into the low-level _xfs_trans_alloc helper, which thus grows a new argument. Also fix up some comments in that area while at it. Signed-off-by: Christoph Hellwig Reviewed-by: Dave Chinner Index: xfs/fs/xfs/xfs_fsops.c =================================================================== --- xfs.orig/fs/xfs/xfs_fsops.c 2011-06-18 17:50:43.477373715 +0200 +++ xfs/fs/xfs/xfs_fsops.c 2011-06-20 09:17:00.933518761 +0200 @@ -626,7 +626,7 @@ xfs_fs_log_dummy( xfs_trans_t *tp; int error; - tp = _xfs_trans_alloc(mp, XFS_TRANS_DUMMY1, KM_SLEEP); + tp = _xfs_trans_alloc(mp, XFS_TRANS_DUMMY1, KM_SLEEP, false); error = xfs_trans_reserve(tp, 0, mp->m_sb.sb_sectsize + 128, 0, 0, XFS_DEFAULT_LOG_COUNT); if (error) { Index: xfs/fs/xfs/xfs_iomap.c =================================================================== --- xfs.orig/fs/xfs/xfs_iomap.c 2011-06-18 17:50:43.487373714 +0200 +++ xfs/fs/xfs/xfs_iomap.c 2011-06-20 09:17:00.933518761 +0200 @@ -688,8 +688,7 @@ xfs_iomap_write_unwritten( * the same inode that we complete here and might deadlock * on the iolock. */ - xfs_wait_for_freeze(mp, SB_FREEZE_TRANS); - tp = _xfs_trans_alloc(mp, XFS_TRANS_STRAT_WRITE, KM_NOFS); + tp = _xfs_trans_alloc(mp, XFS_TRANS_STRAT_WRITE, KM_NOFS, true); tp->t_flags |= XFS_TRANS_RESERVE; error = xfs_trans_reserve(tp, resblks, XFS_WRITE_LOG_RES(mp), 0, Index: xfs/fs/xfs/xfs_trans.h =================================================================== --- xfs.orig/fs/xfs/xfs_trans.h 2011-06-18 17:50:43.497373713 +0200 +++ xfs/fs/xfs/xfs_trans.h 2011-06-21 10:57:04.908840421 +0200 @@ -447,8 +447,14 @@ typedef struct xfs_trans { /* * XFS transaction mechanism exported interfaces. */ -xfs_trans_t *xfs_trans_alloc(struct xfs_mount *, uint); -xfs_trans_t *_xfs_trans_alloc(struct xfs_mount *, uint, uint); +xfs_trans_t *_xfs_trans_alloc(struct xfs_mount *, uint, uint, bool); + +static inline struct xfs_trans * +xfs_trans_alloc(struct xfs_mount *mp, uint type) +{ + return _xfs_trans_alloc(mp, type, KM_SLEEP, true); +} + xfs_trans_t *xfs_trans_dup(xfs_trans_t *); int xfs_trans_reserve(xfs_trans_t *, uint, uint, uint, uint, uint); Index: xfs/fs/xfs/xfs_mount.c =================================================================== --- xfs.orig/fs/xfs/xfs_mount.c 2011-06-18 17:50:43.510707047 +0200 +++ xfs/fs/xfs/xfs_mount.c 2011-06-20 09:17:00.936852094 +0200 @@ -1566,15 +1566,9 @@ xfs_fs_writable(xfs_mount_t *mp) } /* - * xfs_log_sbcount - * * Called either periodically to keep the on disk superblock values * roughly up to date or from unmount to make sure the values are * correct on a clean unmount. - * - * Note this code can be called during the process of freezing, so - * we may need to use the transaction allocator which does not not - * block when the transaction subsystem is in its frozen state. */ int xfs_log_sbcount( @@ -1596,7 +1590,13 @@ xfs_log_sbcount( if (!xfs_sb_version_haslazysbcount(&mp->m_sb)) return 0; - tp = _xfs_trans_alloc(mp, XFS_TRANS_SB_COUNT, KM_SLEEP); + /* + * We can be called during the process of freezing, so make sure + * we go ahead even if the frozen for new transactions. We will + * always use a sync transaction in the freeze path to make sure + * the transaction has completed by the time we return. + */ + tp = _xfs_trans_alloc(mp, XFS_TRANS_SB_COUNT, KM_SLEEP, false); error = xfs_trans_reserve(tp, 0, mp->m_sb.sb_sectsize + 128, 0, 0, XFS_DEFAULT_LOG_COUNT); if (error) { Index: xfs/fs/xfs/xfs_trans.c =================================================================== --- xfs.orig/fs/xfs/xfs_trans.c 2011-06-18 17:50:43.524040379 +0200 +++ xfs/fs/xfs/xfs_trans.c 2011-06-21 10:56:25.305509042 +0200 @@ -566,31 +566,24 @@ xfs_trans_init( /* * This routine is called to allocate a transaction structure. + * * The type parameter indicates the type of the transaction. These * are enumerated in xfs_trans.h. - * - * Dynamically allocate the transaction structure from the transaction - * zone, initialize it, and return it to the caller. */ -xfs_trans_t * -xfs_trans_alloc( - xfs_mount_t *mp, - uint type) -{ - xfs_wait_for_freeze(mp, SB_FREEZE_TRANS); - return _xfs_trans_alloc(mp, type, KM_SLEEP); -} - -xfs_trans_t * +struct xfs_trans * _xfs_trans_alloc( - xfs_mount_t *mp, - uint type, - uint memflags) + struct xfs_mount *mp, + uint type, + uint memflags, + bool wait_for_freeze) { - xfs_trans_t *tp; + struct xfs_trans *tp; atomic_inc(&mp->m_active_trans); + if (wait_for_freeze) + xfs_wait_for_freeze(mp, SB_FREEZE_TRANS); + tp = kmem_zone_zalloc(xfs_trans_zone, memflags); tp->t_magic = XFS_TRANS_MAGIC; tp->t_type = type; From BATV+1dd5f1c206cd6a728cfd+2868+infradead.org+hch@bombadil.srs.infradead.org Fri Jul 1 04:46:06 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.8 required=5.0 tests=BAYES_00,J_CHICKENPOX_64 autolearn=no version=3.4.0-r929098 Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p619k6uc056042 for ; Fri, 1 Jul 2011 04:46:06 -0500 X-ASG-Debug-ID: 1309513563-64f001440000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from bombadil.infradead.org (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 3D5DA1E56724 for ; Fri, 1 Jul 2011 02:46:03 -0700 (PDT) Received: from bombadil.infradead.org (173-166-109-252-newengland.hfc.comcastbusiness.net [173.166.109.252]) by cuda.sgi.com with ESMTP id 0vAHfFJVbzQOz6n1 for ; Fri, 01 Jul 2011 02:46:03 -0700 (PDT) Received: from hch by bombadil.infradead.org with local (Exim 4.76 #1 (Red Hat Linux)) id 1QcaIV-0001t5-KA for xfs@oss.sgi.com; Fri, 01 Jul 2011 09:46:03 +0000 Message-Id: <20110701094603.580931463@bombadil.infradead.org> User-Agent: quilt/0.48-1 Date: Fri, 01 Jul 2011 05:43:28 -0400 From: Christoph Hellwig To: xfs@oss.sgi.com X-ASG-Orig-Subj: [PATCH 07/27] xfs: split xfs_itruncate_finish Subject: [PATCH 07/27] xfs: split xfs_itruncate_finish References: <20110701094321.936534538@bombadil.infradead.org> Content-Disposition: inline; filename=xfs-split-xfs_itruncate_finish X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: 173-166-109-252-newengland.hfc.comcastbusiness.net[173.166.109.252] X-Barracuda-Start-Time: 1309513564 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -1.42 X-Barracuda-Spam-Status: No, SCORE=-1.42 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=BSF_SC5_MJ1963, RDNS_DYNAMIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67645 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_DYNAMIC Delivered to trusted network by host with dynamic-looking rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean Split the guts of xfs_itruncate_finish that loop over the existing extents and calls xfs_bunmapi on them into a new helper, xfs_itruncate_externs. Make xfs_attr_inactive call it directly instead of xfs_itruncate_finish, which allows to simplify the latter a lot, by only letting it deal with the data fork. As a result xfs_itruncate_finish is renamed to xfs_itruncate_data to make its use case more obvious. Also remove the sync parameter from xfs_itruncate_data, which has been unessecary since the introduction of the busy extent list in 2002, and completely dead code since 2003 when the XFS_BMAPI_ASYNC parameter was made a no-op. I can't actually see why the xfs_attr_inactive needs to set the transaction sync, but let's keep this patch simple and without changes in behaviour. Signed-off-by: Christoph Hellwig Reviewed-by: Dave Chinner Index: xfs/fs/xfs/linux-2.6/xfs_iops.c =================================================================== --- xfs.orig/fs/xfs/linux-2.6/xfs_iops.c 2011-06-30 09:02:46.606760906 +0200 +++ xfs/fs/xfs/linux-2.6/xfs_iops.c 2011-06-30 09:05:30.870092231 +0200 @@ -879,15 +879,7 @@ xfs_setattr_size( ip->i_size = iattr->ia_size; } else if (iattr->ia_size <= ip->i_size || (iattr->ia_size == 0 && ip->i_d.di_nextents)) { - /* - * Signal a sync transaction unless we are truncating an - * already unlinked file on a wsync filesystem. - */ - error = xfs_itruncate_finish(&tp, ip, iattr->ia_size, - XFS_DATA_FORK, - ((ip->i_d.di_nlink != 0 || - !(mp->m_flags & XFS_MOUNT_WSYNC)) - ? 1 : 0)); + error = xfs_itruncate_data(&tp, ip, iattr->ia_size); if (error) goto out_trans_abort; Index: xfs/fs/xfs/quota/xfs_qm_syscalls.c =================================================================== --- xfs.orig/fs/xfs/quota/xfs_qm_syscalls.c 2011-06-29 19:45:25.346959576 +0200 +++ xfs/fs/xfs/quota/xfs_qm_syscalls.c 2011-06-30 09:05:30.870092231 +0200 @@ -263,7 +263,7 @@ xfs_qm_scall_trunc_qfile( xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip); - error = xfs_itruncate_finish(&tp, ip, 0, XFS_DATA_FORK, 1); + error = xfs_itruncate_data(&tp, ip, 0); if (error) { xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT); Index: xfs/fs/xfs/xfs_attr.c =================================================================== --- xfs.orig/fs/xfs/xfs_attr.c 2011-06-29 19:45:25.360292838 +0200 +++ xfs/fs/xfs/xfs_attr.c 2011-06-30 09:05:30.873425550 +0200 @@ -822,17 +822,21 @@ xfs_attr_inactive(xfs_inode_t *dp) error = xfs_attr_root_inactive(&trans, dp); if (error) goto out; + /* - * signal synchronous inactive transactions unless this - * is a synchronous mount filesystem in which case we - * know that we're here because we've been called out of - * xfs_inactive which means that the last reference is gone - * and the unlink transaction has already hit the disk so - * async inactive transactions are safe. + * Signal synchronous inactive transactions unless this is a + * synchronous mount filesystem in which case we know that we're here + * because we've been called out of xfs_inactive which means that the + * last reference is gone and the unlink transaction has already hit + * the disk so async inactive transactions are safe. */ - if ((error = xfs_itruncate_finish(&trans, dp, 0LL, XFS_ATTR_FORK, - (!(mp->m_flags & XFS_MOUNT_WSYNC) - ? 1 : 0)))) + if (!(mp->m_flags & XFS_MOUNT_WSYNC)) { + if (dp->i_d.di_anextents > 0) + xfs_trans_set_sync(trans); + } + + error = xfs_itruncate_extents(&trans, dp, XFS_ATTR_FORK, 0); + if (error) goto out; /* Index: xfs/fs/xfs/xfs_inode.c =================================================================== --- xfs.orig/fs/xfs/xfs_inode.c 2011-06-30 09:02:59.840094075 +0200 +++ xfs/fs/xfs/xfs_inode.c 2011-06-30 09:15:11.956751640 +0200 @@ -52,7 +52,7 @@ kmem_zone_t *xfs_ifork_zone; kmem_zone_t *xfs_inode_zone; /* - * Used in xfs_itruncate(). This is the maximum number of extents + * Used in xfs_itruncate_extents(). This is the maximum number of extents * freed from a file in a single transaction. */ #define XFS_ITRUNC_MAX_EXTENTS 2 @@ -1218,7 +1218,9 @@ xfs_isize_check( /* * Free up the underlying blocks past new_size. The new size must be - * smaller than the current size. + * smaller than the current size. This routine can be used both for + * the attribute and data fork, and does not modify the inode size, + * which is left to the caller. * * The transaction passed to this routine must have made a permanent log * reservation of at least XFS_ITRUNCATE_LOG_RES. This routine may commit the @@ -1230,31 +1232,6 @@ xfs_isize_check( * will be "held" within the returned transaction. This routine does NOT * require any disk space to be reserved for it within the transaction. * - * The fork parameter must be either XFS_ATTR_FORK or XFS_DATA_FORK, and it - * indicates the fork which is to be truncated. For the attribute fork we only - * support truncation to size 0. - * - * We use the sync parameter to indicate whether or not the first transaction - * we perform might have to be synchronous. For the attr fork, it needs to be - * so if the unlink of the inode is not yet known to be permanent in the log. - * This keeps us from freeing and reusing the blocks of the attribute fork - * before the unlink of the inode becomes permanent. - * - * For the data fork, we normally have to run synchronously if we're being - * called out of the inactive path or we're being called out of the create path - * where we're truncating an existing file. Either way, the truncate needs to - * be sync so blocks don't reappear in the file with altered data in case of a - * crash. wsync filesystems can run the first case async because anything that - * shrinks the inode has to run sync so by the time we're called here from - * inactive, the inode size is permanently set to 0. - * - * Calls from the truncate path always need to be sync unless we're in a wsync - * filesystem and the file has already been unlinked. - * - * The caller is responsible for correctly setting the sync parameter. It gets - * too hard for us to guess here which path we're being called out of just - * based on inode state. - * * If we get an error, we must return with the inode locked and linked into the * current transaction. This keeps things simple for the higher level code, * because it always knows that the inode is locked and held in the transaction @@ -1262,124 +1239,31 @@ xfs_isize_check( * dirty on error so that transactions can be easily aborted if possible. */ int -xfs_itruncate_finish( - xfs_trans_t **tp, - xfs_inode_t *ip, - xfs_fsize_t new_size, - int fork, - int sync) +xfs_itruncate_extents( + struct xfs_trans **tpp, + struct xfs_inode *ip, + int whichfork, + xfs_fsize_t new_size) { - xfs_fsblock_t first_block; - xfs_fileoff_t first_unmap_block; - xfs_fileoff_t last_block; - xfs_filblks_t unmap_len=0; - xfs_mount_t *mp; - xfs_trans_t *ntp; - int done; - int committed; - xfs_bmap_free_t free_list; - int error; + struct xfs_mount *mp = ip->i_mount; + struct xfs_trans *tp = *tpp; + struct xfs_trans *ntp; + xfs_bmap_free_t free_list; + xfs_fsblock_t first_block; + xfs_fileoff_t first_unmap_block; + xfs_fileoff_t last_block; + xfs_filblks_t unmap_len; + int committed; + int error = 0; + int done = 0; ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_IOLOCK_EXCL)); - ASSERT((new_size == 0) || (new_size <= ip->i_size)); - ASSERT(*tp != NULL); - ASSERT((*tp)->t_flags & XFS_TRANS_PERM_LOG_RES); - ASSERT(ip->i_transp == *tp); + ASSERT(new_size <= ip->i_size); + ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES); + ASSERT(ip->i_transp == tp); ASSERT(ip->i_itemp != NULL); ASSERT(ip->i_itemp->ili_lock_flags == 0); - - - ntp = *tp; - mp = (ntp)->t_mountp; - ASSERT(! XFS_NOT_DQATTACHED(mp, ip)); - - /* - * We only support truncating the entire attribute fork. - */ - if (fork == XFS_ATTR_FORK) { - new_size = 0LL; - } - first_unmap_block = XFS_B_TO_FSB(mp, (xfs_ufsize_t)new_size); - trace_xfs_itruncate_finish_start(ip, new_size); - - /* - * The first thing we do is set the size to new_size permanently - * on disk. This way we don't have to worry about anyone ever - * being able to look at the data being freed even in the face - * of a crash. What we're getting around here is the case where - * we free a block, it is allocated to another file, it is written - * to, and then we crash. If the new data gets written to the - * file but the log buffers containing the free and reallocation - * don't, then we'd end up with garbage in the blocks being freed. - * As long as we make the new_size permanent before actually - * freeing any blocks it doesn't matter if they get written to. - * - * The callers must signal into us whether or not the size - * setting here must be synchronous. There are a few cases - * where it doesn't have to be synchronous. Those cases - * occur if the file is unlinked and we know the unlink is - * permanent or if the blocks being truncated are guaranteed - * to be beyond the inode eof (regardless of the link count) - * and the eof value is permanent. Both of these cases occur - * only on wsync-mounted filesystems. In those cases, we're - * guaranteed that no user will ever see the data in the blocks - * that are being truncated so the truncate can run async. - * In the free beyond eof case, the file may wind up with - * more blocks allocated to it than it needs if we crash - * and that won't get fixed until the next time the file - * is re-opened and closed but that's ok as that shouldn't - * be too many blocks. - * - * However, we can't just make all wsync xactions run async - * because there's one call out of the create path that needs - * to run sync where it's truncating an existing file to size - * 0 whose size is > 0. - * - * It's probably possible to come up with a test in this - * routine that would correctly distinguish all the above - * cases from the values of the function parameters and the - * inode state but for sanity's sake, I've decided to let the - * layers above just tell us. It's simpler to correctly figure - * out in the layer above exactly under what conditions we - * can run async and I think it's easier for others read and - * follow the logic in case something has to be changed. - * cscope is your friend -- rcc. - * - * The attribute fork is much simpler. - * - * For the attribute fork we allow the caller to tell us whether - * the unlink of the inode that led to this call is yet permanent - * in the on disk log. If it is not and we will be freeing extents - * in this inode then we make the first transaction synchronous - * to make sure that the unlink is permanent by the time we free - * the blocks. - */ - if (fork == XFS_DATA_FORK) { - if (ip->i_d.di_nextents > 0) { - /* - * If we are not changing the file size then do - * not update the on-disk file size - we may be - * called from xfs_inactive_free_eofblocks(). If we - * update the on-disk file size and then the system - * crashes before the contents of the file are - * flushed to disk then the files may be full of - * holes (ie NULL files bug). - */ - if (ip->i_size != new_size) { - ip->i_d.di_size = new_size; - ip->i_size = new_size; - xfs_trans_log_inode(ntp, ip, XFS_ILOG_CORE); - } - } - } else if (sync) { - ASSERT(!(mp->m_flags & XFS_MOUNT_WSYNC)); - if (ip->i_d.di_anextents > 0) - xfs_trans_set_sync(ntp); - } - ASSERT(fork == XFS_DATA_FORK || - (fork == XFS_ATTR_FORK && - ((sync && !(mp->m_flags & XFS_MOUNT_WSYNC)) || - (sync == 0 && (mp->m_flags & XFS_MOUNT_WSYNC))))); + ASSERT(!XFS_NOT_DQATTACHED(mp, ip)); /* * Since it is possible for space to become allocated beyond @@ -1390,128 +1274,143 @@ xfs_itruncate_finish( * beyond the maximum file size (ie it is the same as last_block), * then there is nothing to do. */ + first_unmap_block = XFS_B_TO_FSB(mp, (xfs_ufsize_t)new_size); last_block = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_MAXIOFFSET(mp)); - ASSERT(first_unmap_block <= last_block); - done = 0; - if (last_block == first_unmap_block) { - done = 1; - } else { - unmap_len = last_block - first_unmap_block + 1; - } + if (first_unmap_block == last_block) + return 0; + + ASSERT(first_unmap_block < last_block); + unmap_len = last_block - first_unmap_block + 1; while (!done) { - /* - * Free up up to XFS_ITRUNC_MAX_EXTENTS. xfs_bunmapi() - * will tell us whether it freed the entire range or - * not. If this is a synchronous mount (wsync), - * then we can tell bunmapi to keep all the - * transactions asynchronous since the unlink - * transaction that made this inode inactive has - * already hit the disk. There's no danger of - * the freed blocks being reused, there being a - * crash, and the reused blocks suddenly reappearing - * in this file with garbage in them once recovery - * runs. - */ xfs_bmap_init(&free_list, &first_block); - error = xfs_bunmapi(ntp, ip, + error = xfs_bunmapi(tp, ip, first_unmap_block, unmap_len, - xfs_bmapi_aflag(fork), + xfs_bmapi_aflag(whichfork), XFS_ITRUNC_MAX_EXTENTS, &first_block, &free_list, &done); - if (error) { - /* - * If the bunmapi call encounters an error, - * return to the caller where the transaction - * can be properly aborted. We just need to - * make sure we're not holding any resources - * that we were not when we came in. - */ - xfs_bmap_cancel(&free_list); - return error; - } + if (error) + goto out_bmap_cancel; /* * Duplicate the transaction that has the permanent * reservation and commit the old transaction. */ - error = xfs_bmap_finish(tp, &free_list, &committed); - ntp = *tp; + error = xfs_bmap_finish(&tp, &free_list, &committed); if (committed) - xfs_trans_ijoin(ntp, ip); - - if (error) { - /* - * If the bmap finish call encounters an error, return - * to the caller where the transaction can be properly - * aborted. We just need to make sure we're not - * holding any resources that we were not when we came - * in. - * - * Aborting from this point might lose some blocks in - * the file system, but oh well. - */ - xfs_bmap_cancel(&free_list); - return error; - } + xfs_trans_ijoin(tp, ip); + if (error) + goto out_bmap_cancel; if (committed) { /* * Mark the inode dirty so it will be logged and * moved forward in the log as part of every commit. */ - xfs_trans_log_inode(ntp, ip, XFS_ILOG_CORE); + xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); } - ntp = xfs_trans_dup(ntp); - error = xfs_trans_commit(*tp, 0); - *tp = ntp; + ntp = xfs_trans_dup(tp); + error = xfs_trans_commit(tp, 0); + tp = ntp; - xfs_trans_ijoin(ntp, ip); + xfs_trans_ijoin(tp, ip); if (error) - return error; + goto out; + /* - * transaction commit worked ok so we can drop the extra ticket + * Transaction commit worked ok so we can drop the extra ticket * reference that we gained in xfs_trans_dup() */ - xfs_log_ticket_put(ntp->t_ticket); - error = xfs_trans_reserve(ntp, 0, + xfs_log_ticket_put(tp->t_ticket); + error = xfs_trans_reserve(tp, 0, XFS_ITRUNCATE_LOG_RES(mp), 0, XFS_TRANS_PERM_LOG_RES, XFS_ITRUNCATE_LOG_COUNT); if (error) - return error; + goto out; } + +out: + *tpp = tp; + return error; +out_bmap_cancel: + /* + * If the bunmapi call encounters an error, return to the caller where + * the transaction can be properly aborted. We just need to make sure + * we're not holding any resources that we were not when we came in. + */ + xfs_bmap_cancel(&free_list); + goto out; +} + +int +xfs_itruncate_data( + struct xfs_trans **tpp, + struct xfs_inode *ip, + xfs_fsize_t new_size) +{ + struct xfs_mount *mp = ip->i_mount; + int error; + + trace_xfs_itruncate_data_start(ip, new_size); + /* - * Only update the size in the case of the data fork, but - * always re-log the inode so that our permanent transaction - * can keep on rolling it forward in the log. + * The first thing we do is set the size to new_size permanently on + * disk. This way we don't have to worry about anyone ever being able + * to look at the data being freed even in the face of a crash. + * What we're getting around here is the case where we free a block, it + * is allocated to another file, it is written to, and then we crash. + * If the new data gets written to the file but the log buffers + * containing the free and reallocation don't, then we'd end up with + * garbage in the blocks being freed. As long as we make the new_size + * permanent before actually freeing any blocks it doesn't matter if + * they get written to. */ - if (fork == XFS_DATA_FORK) { - xfs_isize_check(mp, ip, new_size); + if (ip->i_d.di_nextents > 0) { /* - * If we are not changing the file size then do - * not update the on-disk file size - we may be - * called from xfs_inactive_free_eofblocks(). If we - * update the on-disk file size and then the system - * crashes before the contents of the file are - * flushed to disk then the files may be full of - * holes (ie NULL files bug). + * If we are not changing the file size then do not update + * the on-disk file size - we may be called from + * xfs_inactive_free_eofblocks(). If we update the on-disk + * file size and then the system crashes before the contents + * of the file are flushed to disk then the files may be + * full of holes (ie NULL files bug). */ if (ip->i_size != new_size) { ip->i_d.di_size = new_size; ip->i_size = new_size; + xfs_trans_log_inode(*tpp, ip, XFS_ILOG_CORE); } } - xfs_trans_log_inode(ntp, ip, XFS_ILOG_CORE); - ASSERT((new_size != 0) || - (fork == XFS_ATTR_FORK) || - (ip->i_delayed_blks == 0)); - ASSERT((new_size != 0) || - (fork == XFS_ATTR_FORK) || - (ip->i_d.di_nextents == 0)); - trace_xfs_itruncate_finish_end(ip, new_size); + + error = xfs_itruncate_extents(tpp, ip, XFS_DATA_FORK, new_size); + if (error) + return error; + + /* + * If we are not changing the file size then do not update the on-disk + * file size - we may be called from xfs_inactive_free_eofblocks(). + * If we update the on-disk file size and then the system crashes + * before the contents of the file are flushed to disk then the files + * may be full of holes (ie NULL files bug). + */ + xfs_isize_check(mp, ip, new_size); + if (ip->i_size != new_size) { + ip->i_d.di_size = new_size; + ip->i_size = new_size; + } + + ASSERT(new_size != 0 || ip->i_delayed_blks == 0); + ASSERT(new_size != 0 || ip->i_d.di_nextents == 0); + + /* + * Always re-log the inode so that our permanent transaction can keep + * on rolling it forward in the log. + */ + xfs_trans_log_inode(*tpp, ip, XFS_ILOG_CORE); + + trace_xfs_itruncate_data_end(ip, new_size); return 0; } Index: xfs/fs/xfs/xfs_inode.h =================================================================== --- xfs.orig/fs/xfs/xfs_inode.h 2011-06-30 09:02:59.846760741 +0200 +++ xfs/fs/xfs/xfs_inode.h 2011-06-30 09:05:30.876758871 +0200 @@ -491,8 +491,10 @@ uint xfs_ip2xflags(struct xfs_inode *); uint xfs_dic2xflags(struct xfs_dinode *); int xfs_ifree(struct xfs_trans *, xfs_inode_t *, struct xfs_bmap_free *); -int xfs_itruncate_finish(struct xfs_trans **, xfs_inode_t *, - xfs_fsize_t, int, int); +int xfs_itruncate_extents(struct xfs_trans **, struct xfs_inode *, + int, xfs_fsize_t); +int xfs_itruncate_data(struct xfs_trans **, struct xfs_inode *, + xfs_fsize_t); int xfs_iunlink(struct xfs_trans *, xfs_inode_t *); void xfs_iext_realloc(xfs_inode_t *, int, int); Index: xfs/fs/xfs/xfs_vnodeops.c =================================================================== --- xfs.orig/fs/xfs/xfs_vnodeops.c 2011-06-30 09:02:59.843427408 +0200 +++ xfs/fs/xfs/xfs_vnodeops.c 2011-06-30 09:05:30.876758871 +0200 @@ -220,15 +220,12 @@ xfs_free_eofblocks( xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip); - error = xfs_itruncate_finish(&tp, ip, - ip->i_size, - XFS_DATA_FORK, - 0); - /* - * If we get an error at this point we - * simply don't bother truncating the file. - */ + error = xfs_itruncate_data(&tp, ip, ip->i_size); if (error) { + /* + * If we get an error at this point we simply don't + * bother truncating the file. + */ xfs_trans_cancel(tp, (XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT)); @@ -665,16 +662,7 @@ xfs_inactive( xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip); - /* - * normally, we have to run xfs_itruncate_finish sync. - * But if filesystem is wsync and we're in the inactive - * path, then we know that nlink == 0, and that the - * xaction that made nlink == 0 is permanently committed - * since xfs_remove runs as a synchronous transaction. - */ - error = xfs_itruncate_finish(&tp, ip, 0, XFS_DATA_FORK, - (!(mp->m_flags & XFS_MOUNT_WSYNC) ? 1 : 0)); - + error = xfs_itruncate_data(&tp, ip, 0); if (error) { xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT); Index: xfs/fs/xfs/linux-2.6/xfs_trace.h =================================================================== --- xfs.orig/fs/xfs/linux-2.6/xfs_trace.h 2011-06-30 09:02:59.846760741 +0200 +++ xfs/fs/xfs/linux-2.6/xfs_trace.h 2011-06-30 09:05:30.880092189 +0200 @@ -1055,8 +1055,8 @@ DECLARE_EVENT_CLASS(xfs_itrunc_class, DEFINE_EVENT(xfs_itrunc_class, name, \ TP_PROTO(struct xfs_inode *ip, xfs_fsize_t new_size), \ TP_ARGS(ip, new_size)) -DEFINE_ITRUNC_EVENT(xfs_itruncate_finish_start); -DEFINE_ITRUNC_EVENT(xfs_itruncate_finish_end); +DEFINE_ITRUNC_EVENT(xfs_itruncate_data_start); +DEFINE_ITRUNC_EVENT(xfs_itruncate_data_end); TRACE_EVENT(xfs_pagecache_inval, TP_PROTO(struct xfs_inode *ip, xfs_off_t start, xfs_off_t finish), From BATV+1dd5f1c206cd6a728cfd+2868+infradead.org+hch@bombadil.srs.infradead.org Fri Jul 1 04:46:07 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p619k6KL056071 for ; Fri, 1 Jul 2011 04:46:07 -0500 X-ASG-Debug-ID: 1309513565-2b4c001c0000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from bombadil.infradead.org (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 456DF16748C3 for ; Fri, 1 Jul 2011 02:46:06 -0700 (PDT) Received: from bombadil.infradead.org (173-166-109-252-newengland.hfc.comcastbusiness.net [173.166.109.252]) by cuda.sgi.com with ESMTP id 6bYGowgrj17BNOAq for ; Fri, 01 Jul 2011 02:46:06 -0700 (PDT) Received: from hch by bombadil.infradead.org with local (Exim 4.76 #1 (Red Hat Linux)) id 1QcaIX-0001xG-Eo for xfs@oss.sgi.com; Fri, 01 Jul 2011 09:46:05 +0000 Message-Id: <20110701094605.415405585@bombadil.infradead.org> User-Agent: quilt/0.48-1 Date: Fri, 01 Jul 2011 05:43:36 -0400 From: Christoph Hellwig To: xfs@oss.sgi.com X-ASG-Orig-Subj: [PATCH 15/27] xfs: cleanup the defintion of struct xfs_dir2_sf_entry Subject: [PATCH 15/27] xfs: cleanup the defintion of struct xfs_dir2_sf_entry References: <20110701094321.936534538@bombadil.infradead.org> Content-Disposition: inline; filename=xfs-cleanup-xfs_dir2_sf_entry X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: 173-166-109-252-newengland.hfc.comcastbusiness.net[173.166.109.252] X-Barracuda-Start-Time: 1309513566 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -1.42 X-Barracuda-Spam-Status: No, SCORE=-1.42 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=BSF_SC5_MJ1963, RDNS_DYNAMIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67646 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_DYNAMIC Delivered to trusted network by host with dynamic-looking rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean Remove the inumber member which is at a variable offset after the actual name, and make name a real variable sized C99 array instead of the incorrect one-sized array which confuses (not only) gcc. Based on this clean up the helpers to calculate the entry size. Signed-off-by: Christoph Hellwig Index: xfs/fs/xfs/xfs_dir2_sf.c =================================================================== --- xfs.orig/fs/xfs/xfs_dir2_sf.c 2011-06-30 09:37:41.120068219 +0200 +++ xfs/fs/xfs/xfs_dir2_sf.c 2011-06-30 09:38:34.303400889 +0200 @@ -371,7 +371,7 @@ xfs_dir2_sf_addname( /* * Compute entry (and change in) size. */ - add_entsize = xfs_dir2_sf_entsize_byname(sfp, args->namelen); + add_entsize = xfs_dir2_sf_entsize(sfp, args->namelen); incr_isize = add_entsize; objchange = 0; #if XFS_BIG_INUMS @@ -465,7 +465,7 @@ xfs_dir2_sf_addname_easy( /* * Grow the in-inode space. */ - xfs_idata_realloc(dp, xfs_dir2_sf_entsize_byname(sfp, args->namelen), + xfs_idata_realloc(dp, xfs_dir2_sf_entsize(sfp, args->namelen), XFS_DATA_FORK); /* * Need to set up again due to realloc of the inode data. @@ -1001,7 +1001,7 @@ xfs_dir2_sf_removename( * Calculate sizes. */ byteoff = (int)((char *)sfep - (char *)sfp); - entsize = xfs_dir2_sf_entsize_byname(sfp, args->namelen); + entsize = xfs_dir2_sf_entsize(sfp, args->namelen); newsize = oldsize - entsize; /* * Copy the part if any after the removed entry, sliding it down. Index: xfs/fs/xfs/xfs_dir2_sf.h =================================================================== --- xfs.orig/fs/xfs/xfs_dir2_sf.h 2011-06-30 09:35:55.813402859 +0200 +++ xfs/fs/xfs/xfs_dir2_sf.h 2011-06-30 09:38:34.303400889 +0200 @@ -76,10 +76,13 @@ typedef struct xfs_dir2_sf_hdr { } __arch_pack xfs_dir2_sf_hdr_t; typedef struct xfs_dir2_sf_entry { - __uint8_t namelen; /* actual name length */ + __u8 namelen; /* actual name length */ xfs_dir2_sf_off_t offset; /* saved offset */ - __uint8_t name[1]; /* name, variable size */ - xfs_dir2_inou_t inumber; /* inode number, var. offset */ + __u8 name[]; /* name, variable size */ + /* + * A xfs_dir2_ino8_t or xfs_dir2_ino4_t follows here, at a + * variable offset after the name. + */ } __arch_pack xfs_dir2_sf_entry_t; static inline int xfs_dir2_sf_hdr_size(int i8count) @@ -101,32 +104,27 @@ xfs_dir2_sf_put_offset(xfs_dir2_sf_entry INT_SET_UNALIGNED_16_BE(&(sfep)->offset.i, off); } -static inline int xfs_dir2_sf_entsize_byname(xfs_dir2_sf_hdr_t *sfp, int len) -{ - return ((uint)sizeof(xfs_dir2_sf_entry_t) - 1 + (len) - \ - ((sfp)->i8count == 0) * \ - ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t))); -} - static inline int -xfs_dir2_sf_entsize_byentry(xfs_dir2_sf_hdr_t *sfp, xfs_dir2_sf_entry_t *sfep) +xfs_dir2_sf_entsize(xfs_dir2_sf_hdr_t *sfp, int len) { - return ((uint)sizeof(xfs_dir2_sf_entry_t) - 1 + (sfep)->namelen - \ - ((sfp)->i8count == 0) * \ - ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t))); + return sizeof(xfs_dir2_sf_entry_t) + /* namelen + offset */ + len + /* name */ + (sfp->i8count ? /* ino */ + sizeof(xfs_dir2_ino8_t) : + sizeof(xfs_dir2_ino4_t)); } static inline xfs_dir2_sf_entry_t *xfs_dir2_sf_firstentry(xfs_dir2_sf_hdr_t *sfp) { - return ((xfs_dir2_sf_entry_t *) \ - ((char *)(sfp) + xfs_dir2_sf_hdr_size(sfp->i8count))); + return (xfs_dir2_sf_entry_t *) + ((char *)sfp + xfs_dir2_sf_hdr_size(sfp->i8count)); } static inline xfs_dir2_sf_entry_t * xfs_dir2_sf_nextentry(xfs_dir2_sf_hdr_t *sfp, xfs_dir2_sf_entry_t *sfep) { - return ((xfs_dir2_sf_entry_t *) \ - ((char *)(sfep) + xfs_dir2_sf_entsize_byentry(sfp,sfep))); + return (xfs_dir2_sf_entry_t *) + ((char *)sfep + xfs_dir2_sf_entsize(sfp, sfep->namelen)); } /* From BATV+1dd5f1c206cd6a728cfd+2868+infradead.org+hch@bombadil.srs.infradead.org Fri Jul 1 04:46:06 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-4.8 required=5.0 tests=BAYES_00,J_CHICKENPOX_63, LOCAL_GNU_PATCH autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p619k5Nh056038 for ; Fri, 1 Jul 2011 04:46:06 -0500 X-ASG-Debug-ID: 1309513564-63a503d90000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from bombadil.infradead.org (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 0E897466A1 for ; Fri, 1 Jul 2011 02:46:04 -0700 (PDT) Received: from bombadil.infradead.org (173-166-109-252-newengland.hfc.comcastbusiness.net [173.166.109.252]) by cuda.sgi.com with ESMTP id wh5RbfXRhvoVS5jR for ; Fri, 01 Jul 2011 02:46:04 -0700 (PDT) Received: from hch by bombadil.infradead.org with local (Exim 4.76 #1 (Red Hat Linux)) id 1QcaIW-0001uf-Eg for xfs@oss.sgi.com; Fri, 01 Jul 2011 09:46:04 +0000 Message-Id: <20110701094604.425053359@bombadil.infradead.org> User-Agent: quilt/0.48-1 Date: Fri, 01 Jul 2011 05:43:31 -0400 From: Christoph Hellwig To: xfs@oss.sgi.com X-ASG-Orig-Subj: [PATCH 10/27] xfs: remove i_transp Subject: [PATCH 10/27] xfs: remove i_transp References: <20110701094321.936534538@bombadil.infradead.org> Content-Disposition: inline; filename=xfs-kill-i_transp X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: 173-166-109-252-newengland.hfc.comcastbusiness.net[173.166.109.252] X-Barracuda-Start-Time: 1309513565 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -1.42 X-Barracuda-Spam-Status: No, SCORE=-1.42 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=BSF_SC5_MJ1963, RDNS_DYNAMIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67645 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_DYNAMIC Delivered to trusted network by host with dynamic-looking rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean Remove the transaction pointer in the inode. It's only used to avoid passing down an argument in the bmap code, and for a few asserts in the transaction code right now. Signed-off-by: Christoph Hellwig Reviewed-by: Dave Chinner Index: xfs/fs/xfs/quota/xfs_trans_dquot.c =================================================================== --- xfs.orig/fs/xfs/quota/xfs_trans_dquot.c 2011-06-29 19:45:24.000000000 +0200 +++ xfs/fs/xfs/quota/xfs_trans_dquot.c 2011-06-30 09:16:44.710083825 +0200 @@ -59,7 +59,7 @@ xfs_trans_dqjoin( xfs_trans_add_item(tp, &dqp->q_logitem.qli_item); /* - * Initialize i_transp so we can later determine if this dquot is + * Initialize d_transp so we can later determine if this dquot is * associated with this transaction. */ dqp->q_transp = tp; Index: xfs/fs/xfs/xfs_bmap.c =================================================================== --- xfs.orig/fs/xfs/xfs_bmap.c 2011-06-29 19:45:24.000000000 +0200 +++ xfs/fs/xfs/xfs_bmap.c 2011-06-30 09:16:44.713417161 +0200 @@ -94,6 +94,7 @@ xfs_bmap_add_attrfork_local( */ STATIC int /* error */ xfs_bmap_add_extent_delay_real( + struct xfs_trans *tp, /* transaction pointer */ xfs_inode_t *ip, /* incore inode pointer */ xfs_extnum_t *idx, /* extent number to update/insert */ xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ @@ -439,6 +440,7 @@ xfs_bmap_add_attrfork_local( */ STATIC int /* error */ xfs_bmap_add_extent( + struct xfs_trans *tp, /* transaction pointer */ xfs_inode_t *ip, /* incore inode pointer */ xfs_extnum_t *idx, /* extent number to update/insert */ xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ @@ -524,7 +526,7 @@ xfs_bmap_add_extent( if (cur) ASSERT(cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL); - error = xfs_bmap_add_extent_delay_real(ip, + error = xfs_bmap_add_extent_delay_real(tp, ip, idx, &cur, new, &da_new, first, flist, &logflags); } else { @@ -561,7 +563,7 @@ xfs_bmap_add_extent( int tmp_logflags; /* partial log flag return val */ ASSERT(cur == NULL); - error = xfs_bmap_extents_to_btree(ip->i_transp, ip, first, + error = xfs_bmap_extents_to_btree(tp, ip, first, flist, &cur, da_old > 0, &tmp_logflags, whichfork); logflags |= tmp_logflags; if (error) @@ -604,6 +606,7 @@ done: */ STATIC int /* error */ xfs_bmap_add_extent_delay_real( + struct xfs_trans *tp, /* transaction pointer */ xfs_inode_t *ip, /* incore inode pointer */ xfs_extnum_t *idx, /* extent number to update/insert */ xfs_btree_cur_t **curp, /* if *curp is null, not a btree */ @@ -901,7 +904,7 @@ xfs_bmap_add_extent_delay_real( } if (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS && ip->i_d.di_nextents > ip->i_df.if_ext_max) { - error = xfs_bmap_extents_to_btree(ip->i_transp, ip, + error = xfs_bmap_extents_to_btree(tp, ip, first, flist, &cur, 1, &tmp_rval, XFS_DATA_FORK); rval |= tmp_rval; @@ -984,7 +987,7 @@ xfs_bmap_add_extent_delay_real( } if (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS && ip->i_d.di_nextents > ip->i_df.if_ext_max) { - error = xfs_bmap_extents_to_btree(ip->i_transp, ip, + error = xfs_bmap_extents_to_btree(tp, ip, first, flist, &cur, 1, &tmp_rval, XFS_DATA_FORK); rval |= tmp_rval; @@ -1052,7 +1055,7 @@ xfs_bmap_add_extent_delay_real( } if (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS && ip->i_d.di_nextents > ip->i_df.if_ext_max) { - error = xfs_bmap_extents_to_btree(ip->i_transp, ip, + error = xfs_bmap_extents_to_btree(tp, ip, first, flist, &cur, 1, &tmp_rval, XFS_DATA_FORK); rval |= tmp_rval; @@ -2871,8 +2874,8 @@ xfs_bmap_del_extent( len = del->br_blockcount; do_div(bno, mp->m_sb.sb_rextsize); do_div(len, mp->m_sb.sb_rextsize); - if ((error = xfs_rtfree_extent(ip->i_transp, bno, - (xfs_extlen_t)len))) + error = xfs_rtfree_extent(tp, bno, (xfs_extlen_t)len); + if (error) goto done; do_fx = 0; nblks = len * mp->m_sb.sb_rextsize; @@ -4662,7 +4665,7 @@ xfs_bmapi( if (!wasdelay && (flags & XFS_BMAPI_PREALLOC)) got.br_state = XFS_EXT_UNWRITTEN; } - error = xfs_bmap_add_extent(ip, &lastx, &cur, &got, + error = xfs_bmap_add_extent(tp, ip, &lastx, &cur, &got, firstblock, flist, &tmp_logflags, whichfork); logflags |= tmp_logflags; @@ -4763,7 +4766,7 @@ xfs_bmapi( mval->br_state = (mval->br_state == XFS_EXT_UNWRITTEN) ? XFS_EXT_NORM : XFS_EXT_UNWRITTEN; - error = xfs_bmap_add_extent(ip, &lastx, &cur, mval, + error = xfs_bmap_add_extent(tp, ip, &lastx, &cur, mval, firstblock, flist, &tmp_logflags, whichfork); logflags |= tmp_logflags; @@ -5117,7 +5120,7 @@ xfs_bunmapi( del.br_blockcount = mod; } del.br_state = XFS_EXT_UNWRITTEN; - error = xfs_bmap_add_extent(ip, &lastx, &cur, &del, + error = xfs_bmap_add_extent(tp, ip, &lastx, &cur, &del, firstblock, flist, &logflags, XFS_DATA_FORK); if (error) @@ -5175,18 +5178,18 @@ xfs_bunmapi( } prev.br_state = XFS_EXT_UNWRITTEN; lastx--; - error = xfs_bmap_add_extent(ip, &lastx, &cur, - &prev, firstblock, flist, &logflags, - XFS_DATA_FORK); + error = xfs_bmap_add_extent(tp, ip, &lastx, + &cur, &prev, firstblock, flist, + &logflags, XFS_DATA_FORK); if (error) goto error0; goto nodelete; } else { ASSERT(del.br_state == XFS_EXT_NORM); del.br_state = XFS_EXT_UNWRITTEN; - error = xfs_bmap_add_extent(ip, &lastx, &cur, - &del, firstblock, flist, &logflags, - XFS_DATA_FORK); + error = xfs_bmap_add_extent(tp, ip, &lastx, + &cur, &del, firstblock, flist, + &logflags, XFS_DATA_FORK); if (error) goto error0; goto nodelete; Index: xfs/fs/xfs/xfs_inode.c =================================================================== --- xfs.orig/fs/xfs/xfs_inode.c 2011-06-30 09:15:11.000000000 +0200 +++ xfs/fs/xfs/xfs_inode.c 2011-06-30 09:16:57.120083690 +0200 @@ -1260,7 +1260,6 @@ xfs_itruncate_extents( ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_IOLOCK_EXCL)); ASSERT(new_size <= ip->i_size); ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES); - ASSERT(ip->i_transp == tp); ASSERT(ip->i_itemp != NULL); ASSERT(ip->i_itemp->ili_lock_flags == 0); ASSERT(!XFS_NOT_DQATTACHED(mp, ip)); @@ -1436,7 +1435,6 @@ xfs_iunlink( ASSERT(ip->i_d.di_nlink == 0); ASSERT(ip->i_d.di_mode != 0); - ASSERT(ip->i_transp == tp); mp = tp->t_mountp; @@ -1828,7 +1826,6 @@ xfs_ifree( xfs_buf_t *ibp; ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); - ASSERT(ip->i_transp == tp); ASSERT(ip->i_d.di_nlink == 0); ASSERT(ip->i_d.di_nextents == 0); ASSERT(ip->i_d.di_anextents == 0); Index: xfs/fs/xfs/xfs_inode.h =================================================================== --- xfs.orig/fs/xfs/xfs_inode.h 2011-06-30 09:05:30.000000000 +0200 +++ xfs/fs/xfs/xfs_inode.h 2011-06-30 09:16:44.720083829 +0200 @@ -241,7 +241,6 @@ typedef struct xfs_inode { xfs_ifork_t i_df; /* data fork */ /* Transaction and locking information. */ - struct xfs_trans *i_transp; /* ptr to owning transaction*/ struct xfs_inode_log_item *i_itemp; /* logging information */ mrlock_t i_lock; /* inode lock */ mrlock_t i_iolock; /* inode IO lock */ Index: xfs/fs/xfs/xfs_inode_item.c =================================================================== --- xfs.orig/fs/xfs/xfs_inode_item.c 2011-06-29 19:45:24.960295005 +0200 +++ xfs/fs/xfs/xfs_inode_item.c 2011-06-30 09:16:44.723417161 +0200 @@ -636,11 +636,6 @@ xfs_inode_item_unlock( ASSERT(xfs_isilocked(iip->ili_inode, XFS_ILOCK_EXCL)); /* - * Clear the transaction pointer in the inode. - */ - ip->i_transp = NULL; - - /* * If the inode needed a separate buffer with which to log * its extents, then free it now. */ Index: xfs/fs/xfs/xfs_trans_inode.c =================================================================== --- xfs.orig/fs/xfs/xfs_trans_inode.c 2011-06-29 19:45:24.973628266 +0200 +++ xfs/fs/xfs/xfs_trans_inode.c 2011-06-30 09:16:44.723417161 +0200 @@ -55,7 +55,6 @@ xfs_trans_ijoin( { xfs_inode_log_item_t *iip; - ASSERT(ip->i_transp == NULL); ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); if (ip->i_itemp == NULL) xfs_inode_item_init(ip, ip->i_mount); @@ -68,12 +67,6 @@ xfs_trans_ijoin( xfs_trans_add_item(tp, &iip->ili_item); xfs_trans_inode_broot_debug(ip); - - /* - * Initialize i_transp so we can find it with xfs_inode_incore() - * in xfs_trans_iget() above. - */ - ip->i_transp = tp; } /* @@ -111,7 +104,6 @@ xfs_trans_ichgtime( ASSERT(tp); ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); - ASSERT(ip->i_transp == tp); tv = current_fs_time(inode->i_sb); @@ -140,7 +132,6 @@ xfs_trans_log_inode( xfs_inode_t *ip, uint flags) { - ASSERT(ip->i_transp == tp); ASSERT(ip->i_itemp != NULL); ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); From BATV+1dd5f1c206cd6a728cfd+2868+infradead.org+hch@bombadil.srs.infradead.org Fri Jul 1 04:46:08 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.7 required=5.0 tests=BAYES_00,J_CHICKENPOX_63, J_CHICKENPOX_65 autolearn=no version=3.4.0-r929098 Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p619k7LI056086 for ; Fri, 1 Jul 2011 04:46:07 -0500 X-ASG-Debug-ID: 1309513566-63c503bd0000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from bombadil.infradead.org (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 77FD74669F for ; Fri, 1 Jul 2011 02:46:06 -0700 (PDT) Received: from bombadil.infradead.org (173-166-109-252-newengland.hfc.comcastbusiness.net [173.166.109.252]) by cuda.sgi.com with ESMTP id APNiWPNBHQb2Azzo for ; Fri, 01 Jul 2011 02:46:06 -0700 (PDT) Received: from hch by bombadil.infradead.org with local (Exim 4.76 #1 (Red Hat Linux)) id 1QcaIX-0001yI-Rs for xfs@oss.sgi.com; Fri, 01 Jul 2011 09:46:05 +0000 Message-Id: <20110701094605.827598983@bombadil.infradead.org> User-Agent: quilt/0.48-1 Date: Fri, 01 Jul 2011 05:43:38 -0400 From: Christoph Hellwig To: xfs@oss.sgi.com X-ASG-Orig-Subj: [PATCH 17/27] xfs: kill struct xfs_dir2_block Subject: [PATCH 17/27] xfs: kill struct xfs_dir2_block References: <20110701094321.936534538@bombadil.infradead.org> Content-Disposition: inline; filename=xfs-kill-xfs_dir2_block_t X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: 173-166-109-252-newengland.hfc.comcastbusiness.net[173.166.109.252] X-Barracuda-Start-Time: 1309513566 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -1.42 X-Barracuda-Spam-Status: No, SCORE=-1.42 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=BSF_SC5_MJ1963, RDNS_DYNAMIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67645 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_DYNAMIC Delivered to trusted network by host with dynamic-looking rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean Remove the confusing xfs_dir2_block structure. It is supposed to describe an XFS dir2 block format btree block, but due to the variable sized nature of almost all elements in it it can't actuall do anything close to that job. In addition to accessing the fixed offset header structure it was only used to get a pointer to the first dir or unused entry after it, which can be trivially replaced by pointer arithmetics on the header pointer. For most users that is actually more natural anyway, as they don't use a typed pointer but rather a character pointer for further arithmetics. Signed-off-by: Christoph Hellwig Index: xfs/fs/xfs/xfs_dir2_block.h =================================================================== --- xfs.orig/fs/xfs/xfs_dir2_block.h 2011-06-30 09:38:36.596734195 +0200 +++ xfs/fs/xfs/xfs_dir2_block.h 2011-06-30 09:38:38.116734176 +0200 @@ -19,10 +19,30 @@ #define __XFS_DIR2_BLOCK_H__ /* - * xfs_dir2_block.h - * Directory version 2, single block format structures + * Directory version 2, single block format structures. + * + * The single block format looks like the following drawing on disk: + * + * +-------------------------------------------------+ + * | xfs_dir2_data_hdr_t | + * +-------------------------------------------------+ + * | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t | + * | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t | + * | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t | + * | ... | + * +-------------------------------------------------+ + * | unused space | + * +-------------------------------------------------+ + * | ... | + * | xfs_dir2_leaf_entry_t | + * | xfs_dir2_leaf_entry_t | + * +-------------------------------------------------+ + * | xfs_dir2_block_tail_t | + * +-------------------------------------------------+ + * + * As all the entries are variable sized structures the accessors in this + * file and xfs_dir2_data.h need to be used to iterate over them. */ - struct uio; struct xfs_dabuf; struct xfs_da_args; @@ -32,14 +52,6 @@ struct xfs_inode; struct xfs_mount; struct xfs_trans; -/* - * The single block format is as follows: - * xfs_dir2_data_hdr_t structure - * xfs_dir2_data_entry_t and xfs_dir2_data_unused_t structures - * xfs_dir2_leaf_entry_t structures - * xfs_dir2_block_tail_t structure - */ - #define XFS_DIR2_BLOCK_MAGIC 0x58443242 /* XD2B: for one block dirs */ typedef struct xfs_dir2_block_tail { @@ -48,16 +60,6 @@ typedef struct xfs_dir2_block_tail { } xfs_dir2_block_tail_t; /* - * Generic single-block structure, for xfs_db. - */ -typedef struct xfs_dir2_block { - xfs_dir2_data_hdr_t hdr; /* magic XFS_DIR2_BLOCK_MAGIC */ - xfs_dir2_data_union_t u[1]; - xfs_dir2_leaf_entry_t leaf[1]; - xfs_dir2_block_tail_t tail; -} xfs_dir2_block_t; - -/* * Pointer to the leaf header embedded in a data block (1-block format) */ static inline xfs_dir2_block_tail_t * Index: xfs/fs/xfs/xfs_dir2_block.c =================================================================== --- xfs.orig/fs/xfs/xfs_dir2_block.c 2011-06-30 09:38:36.586734196 +0200 +++ xfs/fs/xfs/xfs_dir2_block.c 2011-06-30 09:38:38.120067509 +0200 @@ -437,7 +437,6 @@ xfs_dir2_block_getdents( xfs_off_t *offset, filldir_t filldir) { - xfs_dir2_block_t *block; /* directory block structure */ xfs_dir2_data_hdr_t *hdr; /* block header */ xfs_dabuf_t *bp; /* buffer for block */ xfs_dir2_block_tail_t *btp; /* block tail */ @@ -471,14 +470,13 @@ xfs_dir2_block_getdents( * We'll skip entries before this. */ wantoff = xfs_dir2_dataptr_to_off(mp, *offset); - block = bp->data; - hdr = &block->hdr; + hdr = bp->data; xfs_dir2_data_check(dp, bp); /* * Set up values for the loop. */ btp = xfs_dir2_block_tail_p(mp, hdr); - ptr = (char *)block->u; + ptr = (char *)(hdr + 1); endptr = (char *)xfs_dir2_block_leaf_p(btp); /* @@ -1020,7 +1018,6 @@ xfs_dir2_sf_to_block( xfs_da_args_t *args) /* operation arguments */ { xfs_dir2_db_t blkno; /* dir-relative block # (0) */ - xfs_dir2_block_t *block; /* block structure */ xfs_dir2_data_hdr_t *hdr; /* block header */ xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ xfs_dabuf_t *bp; /* block buffer */ @@ -1091,8 +1088,7 @@ xfs_dir2_sf_to_block( kmem_free(sfp); return error; } - block = bp->data; - hdr = &block->hdr; + hdr = bp->data; hdr->magic = cpu_to_be32(XFS_DIR2_BLOCK_MAGIC); /* * Compute size of block "tail" area. @@ -1103,7 +1099,7 @@ xfs_dir2_sf_to_block( * The whole thing is initialized to free by the init routine. * Say we're using the leaf and tail area. */ - dup = (xfs_dir2_data_unused_t *)block->u; + dup = (xfs_dir2_data_unused_t *)(hdr + 1); needlog = needscan = 0; xfs_dir2_data_use_free(tp, bp, dup, mp->m_dirblksize - i, i, &needlog, &needscan); Index: xfs/fs/xfs/xfs_dir2_sf.c =================================================================== --- xfs.orig/fs/xfs/xfs_dir2_sf.c 2011-06-30 09:38:36.590067529 +0200 +++ xfs/fs/xfs/xfs_dir2_sf.c 2011-06-30 09:38:38.123400842 +0200 @@ -226,7 +226,7 @@ xfs_dir2_block_to_sf( int size, /* shortform directory size */ xfs_dir2_sf_hdr_t *sfhp) /* shortform directory hdr */ { - xfs_dir2_block_t *block; /* block structure */ + xfs_dir2_data_hdr_t *hdr; /* block header */ xfs_dir2_block_tail_t *btp; /* block tail pointer */ xfs_dir2_data_entry_t *dep; /* data entry pointer */ xfs_inode_t *dp; /* incore directory inode */ @@ -248,8 +248,8 @@ xfs_dir2_block_to_sf( * Make a copy of the block data, so we can shrink the inode * and add local data. */ - block = kmem_alloc(mp->m_dirblksize, KM_SLEEP); - memcpy(block, bp->data, mp->m_dirblksize); + hdr = kmem_alloc(mp->m_dirblksize, KM_SLEEP); + memcpy(hdr, bp->data, mp->m_dirblksize); logflags = XFS_ILOG_CORE; if ((error = xfs_dir2_shrink_inode(args, mp->m_dirdatablk, bp))) { ASSERT(error != ENOSPC); @@ -277,8 +277,8 @@ xfs_dir2_block_to_sf( /* * Set up to loop over the block's entries. */ - btp = xfs_dir2_block_tail_p(mp, &block->hdr); - ptr = (char *)block->u; + btp = xfs_dir2_block_tail_p(mp, hdr); + ptr = (char *)(hdr + 1); endptr = (char *)xfs_dir2_block_leaf_p(btp); sfep = xfs_dir2_sf_firstentry(sfp); /* @@ -314,7 +314,7 @@ xfs_dir2_block_to_sf( sfep->namelen = dep->namelen; xfs_dir2_sf_put_offset(sfep, (xfs_dir2_data_aoff_t) - ((char *)dep - (char *)block)); + ((char *)dep - (char *)hdr)); memcpy(sfep->name, dep->name, dep->namelen); xfs_dir2_sfe_put_ino(sfp, sfep, be64_to_cpu(dep->inumber)); @@ -327,7 +327,7 @@ xfs_dir2_block_to_sf( xfs_dir2_sf_check(args); out: xfs_trans_log_inode(args->trans, dp, logflags); - kmem_free(block); + kmem_free(hdr); return error; } From BATV+1dd5f1c206cd6a728cfd+2868+infradead.org+hch@bombadil.srs.infradead.org Fri Jul 1 04:46:06 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.7 required=5.0 tests=BAYES_00,J_CHICKENPOX_43, J_CHICKENPOX_45 autolearn=no version=3.4.0-r929098 Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p619k5C3056039 for ; Fri, 1 Jul 2011 04:46:06 -0500 X-ASG-Debug-ID: 1309513564-798a02010000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from bombadil.infradead.org (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 0ADBD16748BB for ; Fri, 1 Jul 2011 02:46:04 -0700 (PDT) Received: from bombadil.infradead.org (173-166-109-252-newengland.hfc.comcastbusiness.net [173.166.109.252]) by cuda.sgi.com with ESMTP id uqnslvBCHybFN30d for ; Fri, 01 Jul 2011 02:46:04 -0700 (PDT) Received: from hch by bombadil.infradead.org with local (Exim 4.76 #1 (Red Hat Linux)) id 1QcaIV-0001tb-Qv for xfs@oss.sgi.com; Fri, 01 Jul 2011 09:46:04 +0000 Message-Id: <20110701094603.789209280@bombadil.infradead.org> User-Agent: quilt/0.48-1 Date: Fri, 01 Jul 2011 05:43:29 -0400 From: Christoph Hellwig To: xfs@oss.sgi.com X-ASG-Orig-Subj: [PATCH 08/27] xfs: improve sync behaviour in the fact of aggressive dirtying Subject: [PATCH 08/27] xfs: improve sync behaviour in the fact of aggressive dirtying References: <20110701094321.936534538@bombadil.infradead.org> Content-Disposition: inline; filename=xfs-simplify-sync X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: 173-166-109-252-newengland.hfc.comcastbusiness.net[173.166.109.252] X-Barracuda-Start-Time: 1309513565 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -1.42 X-Barracuda-Spam-Status: No, SCORE=-1.42 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=BSF_SC5_MJ1963, RDNS_DYNAMIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67646 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_DYNAMIC Delivered to trusted network by host with dynamic-looking rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean The following script from Wu Fengguang shows very bad behaviour in XFS when aggressively dirtying data during a sync on XFS, with sync times up to almost 10 times as long as ext4. A large part of the issue is that XFS writes data out itself two times in the ->sync_fs method, overriding the lifelock protection in the core writeback code, and another issue is the lock-less xfs_ioend_wait call, which doesn't prevent new ioend from beeing queue up while waiting for the count to reach zero. This patch removes the XFS-internal sync calls and relies on the VFS to do it's work just like all other filesystems do. Note that the i_iocount wait which is rather suboptimal is simply removed here. We already do it in ->write_inode, which keeps the current supoptimal behaviour. We'll eventually need to remove that as well, but that's material for a separate commit. ------------------------------ snip ------------------------------ #!/bin/sh umount /dev/sda7 mkfs.xfs -f /dev/sda7 # mkfs.ext4 /dev/sda7 # mkfs.btrfs /dev/sda7 mount /dev/sda7 /fs echo $((50<<20)) > /proc/sys/vm/dirty_bytes pid= for i in `seq 10` do dd if=/dev/zero of=/fs/zero-$i bs=1M count=1000 & pid="$pid $!" done sleep 1 tic=$(date +'%s') sync tac=$(date +'%s') echo echo sync time: $((tac-tic)) egrep '(Dirty|Writeback|NFS_Unstable)' /proc/meminfo pidof dd > /dev/null && { kill -9 $pid; echo sync NOT livelocked; } ------------------------------ snip ------------------------------ Signed-off-by: Christoph Hellwig Reported-by: Wu Fengguang Reviewed-by: Dave Chinner Index: xfs/fs/xfs/linux-2.6/xfs_sync.c =================================================================== --- xfs.orig/fs/xfs/linux-2.6/xfs_sync.c 2011-06-29 11:26:14.109219361 +0200 +++ xfs/fs/xfs/linux-2.6/xfs_sync.c 2011-06-29 11:37:20.642275110 +0200 @@ -359,14 +359,12 @@ xfs_quiesce_data( { int error, error2 = 0; - /* push non-blocking */ - xfs_sync_data(mp, 0); xfs_qm_sync(mp, SYNC_TRYLOCK); - - /* push and block till complete */ - xfs_sync_data(mp, SYNC_WAIT); xfs_qm_sync(mp, SYNC_WAIT); + /* force out the newly dirtied log buffers */ + xfs_log_force(mp, XFS_LOG_SYNC); + /* write superblock and hoover up shutdown errors */ error = xfs_sync_fsdata(mp); From BATV+1dd5f1c206cd6a728cfd+2868+infradead.org+hch@bombadil.srs.infradead.org Fri Jul 1 04:46:08 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p619k7q5056076 for ; Fri, 1 Jul 2011 04:46:07 -0500 X-ASG-Debug-ID: 1309513565-14fa00e80000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from bombadil.infradead.org (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id EE92C16748BB for ; Fri, 1 Jul 2011 02:46:05 -0700 (PDT) Received: from bombadil.infradead.org (173-166-109-252-newengland.hfc.comcastbusiness.net [173.166.109.252]) by cuda.sgi.com with ESMTP id OE10Qoiygve6uQXW for ; Fri, 01 Jul 2011 02:46:05 -0700 (PDT) Received: from hch by bombadil.infradead.org with local (Exim 4.76 #1 (Red Hat Linux)) id 1QcaIX-0001wD-0T for xfs@oss.sgi.com; Fri, 01 Jul 2011 09:46:05 +0000 Message-Id: <20110701094604.976400061@bombadil.infradead.org> User-Agent: quilt/0.48-1 Date: Fri, 01 Jul 2011 05:43:34 -0400 From: Christoph Hellwig To: xfs@oss.sgi.com X-ASG-Orig-Subj: [PATCH 13/27] xfs: cleanup shortform directory inode number handling Subject: [PATCH 13/27] xfs: cleanup shortform directory inode number handling References: <20110701094321.936534538@bombadil.infradead.org> Content-Disposition: inline; filename=xfs-dir2_sf-cleanup-inum-handling X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: 173-166-109-252-newengland.hfc.comcastbusiness.net[173.166.109.252] X-Barracuda-Start-Time: 1309513565 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -1.42 X-Barracuda-Spam-Status: No, SCORE=-1.42 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=BSF_SC5_MJ1963, RDNS_DYNAMIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67646 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_DYNAMIC Delivered to trusted network by host with dynamic-looking rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean Refactor the shortform directory helpers that deal with the 32-bit vs 64-bit wide inode numbers into more sensible helpers, and kill the xfs_intino_t typedef that is now superflous. Signed-off-by: Christoph Hellwig Reviewed-by: Dave Chinner Index: xfs/fs/xfs/xfs_dir2_sf.c =================================================================== --- xfs.orig/fs/xfs/xfs_dir2_sf.c 2011-06-30 09:31:15.330073010 +0200 +++ xfs/fs/xfs/xfs_dir2_sf.c 2011-06-30 09:34:46.640070544 +0200 @@ -59,6 +59,79 @@ static void xfs_dir2_sf_toino4(xfs_da_ar static void xfs_dir2_sf_toino8(xfs_da_args_t *args); #endif /* XFS_BIG_INUMS */ + +/* + * Inode numbers in short-form directories can come in two versions, + * either 4 bytes or 8 bytes wide. These helpers deal with the + * two forms transparently by looking at the headers i8count field. + */ +static xfs_ino_t +xfs_dir2_sf_get_ino( + struct xfs_dir2_sf *sfp, + xfs_dir2_inou_t *from) +{ + if (sfp->hdr.i8count) + return XFS_GET_DIR_INO8(from->i8); + else + return XFS_GET_DIR_INO4(from->i4); +} + +static void +xfs_dir2_sf_put_ino( + struct xfs_dir2_sf *sfp, + xfs_dir2_inou_t *to, + xfs_ino_t ino) +{ + if (sfp->hdr.i8count) + XFS_PUT_DIR_INO8(ino, to->i8); + else + XFS_PUT_DIR_INO4(ino, to->i4); +} + +xfs_ino_t +xfs_dir2_sf_get_parent_ino( + struct xfs_dir2_sf *sfp) +{ + return xfs_dir2_sf_get_ino(sfp, &sfp->hdr.parent); +} + +static void +xfs_dir2_sf_put_parent_ino( + struct xfs_dir2_sf *sfp, + xfs_ino_t ino) +{ + xfs_dir2_sf_put_ino(sfp, &sfp->hdr.parent, ino); +} + +/* + * In short-form directory entries the inode numbers are stored at variable + * offset behind the entry name. The inode numbers may only be accessed + * through the helpers below. + */ +static xfs_dir2_inou_t * +xfs_dir2_sfe_inop( + struct xfs_dir2_sf_entry *sfep) +{ + return (xfs_dir2_inou_t *)&sfep->name[sfep->namelen]; +} + +xfs_ino_t +xfs_dir2_sfe_get_ino( + struct xfs_dir2_sf *sfp, + struct xfs_dir2_sf_entry *sfep) +{ + return xfs_dir2_sf_get_ino(sfp, xfs_dir2_sfe_inop(sfep)); +} + +static void +xfs_dir2_sfe_put_ino( + struct xfs_dir2_sf *sfp, + struct xfs_dir2_sf_entry *sfep, + xfs_ino_t ino) +{ + xfs_dir2_sf_put_ino(sfp, xfs_dir2_sfe_inop(sfep), ino); +} + /* * Given a block directory (dp/block), calculate its size as a shortform (sf) * directory and a header for the sf directory, if it will fit it the @@ -138,7 +211,7 @@ xfs_dir2_block_sfsize( */ sfhp->count = count; sfhp->i8count = i8count; - xfs_dir2_sf_put_inumber((xfs_dir2_sf_t *)sfhp, &parent, &sfhp->parent); + xfs_dir2_sf_put_parent_ino((xfs_dir2_sf_t *)sfhp, parent); return size; } @@ -165,7 +238,6 @@ xfs_dir2_block_to_sf( char *ptr; /* current data pointer */ xfs_dir2_sf_entry_t *sfep; /* shortform entry */ xfs_dir2_sf_t *sfp; /* shortform structure */ - xfs_ino_t temp; trace_xfs_dir2_block_to_sf(args); @@ -233,7 +305,7 @@ xfs_dir2_block_to_sf( else if (dep->namelen == 2 && dep->name[0] == '.' && dep->name[1] == '.') ASSERT(be64_to_cpu(dep->inumber) == - xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent)); + xfs_dir2_sf_get_parent_ino(sfp)); /* * Normal entry, copy it into shortform. */ @@ -243,9 +315,9 @@ xfs_dir2_block_to_sf( (xfs_dir2_data_aoff_t) ((char *)dep - (char *)block)); memcpy(sfep->name, dep->name, dep->namelen); - temp = be64_to_cpu(dep->inumber); - xfs_dir2_sf_put_inumber(sfp, &temp, - xfs_dir2_sf_inumberp(sfep)); + xfs_dir2_sfe_put_ino(sfp, sfep, + be64_to_cpu(dep->inumber)); + sfep = xfs_dir2_sf_nextentry(sfp, sfep); } ptr += xfs_dir2_data_entsize(dep->namelen); @@ -406,8 +478,7 @@ xfs_dir2_sf_addname_easy( sfep->namelen = args->namelen; xfs_dir2_sf_put_offset(sfep, offset); memcpy(sfep->name, args->name, sfep->namelen); - xfs_dir2_sf_put_inumber(sfp, &args->inumber, - xfs_dir2_sf_inumberp(sfep)); + xfs_dir2_sfe_put_ino(sfp, sfep, args->inumber); /* * Update the header and inode. */ @@ -498,8 +569,7 @@ xfs_dir2_sf_addname_hard( sfep->namelen = args->namelen; xfs_dir2_sf_put_offset(sfep, offset); memcpy(sfep->name, args->name, sfep->namelen); - xfs_dir2_sf_put_inumber(sfp, &args->inumber, - xfs_dir2_sf_inumberp(sfep)); + xfs_dir2_sfe_put_ino(sfp, sfep, args->inumber); sfp->hdr.count++; #if XFS_BIG_INUMS if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && !objchange) @@ -618,14 +688,14 @@ xfs_dir2_sf_check( sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; offset = XFS_DIR2_DATA_FIRST_OFFSET; - ino = xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent); + ino = xfs_dir2_sf_get_parent_ino(sfp); i8count = ino > XFS_DIR2_MAX_SHORT_INUM; for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->hdr.count; i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep)) { ASSERT(xfs_dir2_sf_get_offset(sfep) >= offset); - ino = xfs_dir2_sf_get_inumber(sfp, xfs_dir2_sf_inumberp(sfep)); + ino = xfs_dir2_sfe_get_ino(sfp, sfep); i8count += ino > XFS_DIR2_MAX_SHORT_INUM; offset = xfs_dir2_sf_get_offset(sfep) + @@ -686,7 +756,7 @@ xfs_dir2_sf_create( /* * Now can put in the inode number, since i8count is set. */ - xfs_dir2_sf_put_inumber(sfp, &pino, &sfp->hdr.parent); + xfs_dir2_sf_put_parent_ino(sfp, pino); sfp->hdr.count = 0; dp->i_d.di_size = size; xfs_dir2_sf_check(args); @@ -759,7 +829,7 @@ xfs_dir2_sf_getdents( * Put .. entry unless we're starting past it. */ if (*offset <= dotdot_offset) { - ino = xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent); + ino = xfs_dir2_sf_get_parent_ino(sfp); if (filldir(dirent, "..", 2, dotdot_offset & 0x7fffffff, ino, DT_DIR)) { *offset = dotdot_offset & 0x7fffffff; return 0; @@ -779,7 +849,7 @@ xfs_dir2_sf_getdents( continue; } - ino = xfs_dir2_sf_get_inumber(sfp, xfs_dir2_sf_inumberp(sfep)); + ino = xfs_dir2_sfe_get_ino(sfp, sfep); if (filldir(dirent, (char *)sfep->name, sfep->namelen, off & 0x7fffffff, ino, DT_UNKNOWN)) { *offset = off & 0x7fffffff; @@ -839,7 +909,7 @@ xfs_dir2_sf_lookup( */ if (args->namelen == 2 && args->name[0] == '.' && args->name[1] == '.') { - args->inumber = xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent); + args->inumber = xfs_dir2_sf_get_parent_ino(sfp); args->cmpresult = XFS_CMP_EXACT; return XFS_ERROR(EEXIST); } @@ -858,8 +928,7 @@ xfs_dir2_sf_lookup( sfep->namelen); if (cmp != XFS_CMP_DIFFERENT && cmp != args->cmpresult) { args->cmpresult = cmp; - args->inumber = xfs_dir2_sf_get_inumber(sfp, - xfs_dir2_sf_inumberp(sfep)); + args->inumber = xfs_dir2_sfe_get_ino(sfp, sfep); if (cmp == XFS_CMP_EXACT) return XFS_ERROR(EEXIST); ci_sfep = sfep; @@ -918,9 +987,8 @@ xfs_dir2_sf_removename( i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep)) { if (xfs_da_compname(args, sfep->name, sfep->namelen) == XFS_CMP_EXACT) { - ASSERT(xfs_dir2_sf_get_inumber(sfp, - xfs_dir2_sf_inumberp(sfep)) == - args->inumber); + ASSERT(xfs_dir2_sfe_get_ino(sfp, sfep) == + args->inumber); break; } } @@ -1040,10 +1108,10 @@ xfs_dir2_sf_replace( if (args->namelen == 2 && args->name[0] == '.' && args->name[1] == '.') { #if XFS_BIG_INUMS || defined(DEBUG) - ino = xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent); + ino = xfs_dir2_sf_get_parent_ino(sfp); ASSERT(args->inumber != ino); #endif - xfs_dir2_sf_put_inumber(sfp, &args->inumber, &sfp->hdr.parent); + xfs_dir2_sf_put_parent_ino(sfp, args->inumber); } /* * Normal entry, look for the name. @@ -1055,12 +1123,10 @@ xfs_dir2_sf_replace( if (xfs_da_compname(args, sfep->name, sfep->namelen) == XFS_CMP_EXACT) { #if XFS_BIG_INUMS || defined(DEBUG) - ino = xfs_dir2_sf_get_inumber(sfp, - xfs_dir2_sf_inumberp(sfep)); + ino = xfs_dir2_sfe_get_ino(sfp, sfep); ASSERT(args->inumber != ino); #endif - xfs_dir2_sf_put_inumber(sfp, &args->inumber, - xfs_dir2_sf_inumberp(sfep)); + xfs_dir2_sfe_put_ino(sfp, sfep, args->inumber); break; } } @@ -1121,7 +1187,6 @@ xfs_dir2_sf_toino4( char *buf; /* old dir's buffer */ xfs_inode_t *dp; /* incore directory inode */ int i; /* entry index */ - xfs_ino_t ino; /* entry inode number */ int newsize; /* new inode size */ xfs_dir2_sf_entry_t *oldsfep; /* old sf entry */ xfs_dir2_sf_t *oldsfp; /* old sf directory */ @@ -1162,8 +1227,7 @@ xfs_dir2_sf_toino4( */ sfp->hdr.count = oldsfp->hdr.count; sfp->hdr.i8count = 0; - ino = xfs_dir2_sf_get_inumber(oldsfp, &oldsfp->hdr.parent); - xfs_dir2_sf_put_inumber(sfp, &ino, &sfp->hdr.parent); + xfs_dir2_sf_put_parent_ino(sfp, xfs_dir2_sf_get_parent_ino(oldsfp)); /* * Copy the entries field by field. */ @@ -1175,9 +1239,8 @@ xfs_dir2_sf_toino4( sfep->namelen = oldsfep->namelen; sfep->offset = oldsfep->offset; memcpy(sfep->name, oldsfep->name, sfep->namelen); - ino = xfs_dir2_sf_get_inumber(oldsfp, - xfs_dir2_sf_inumberp(oldsfep)); - xfs_dir2_sf_put_inumber(sfp, &ino, xfs_dir2_sf_inumberp(sfep)); + xfs_dir2_sfe_put_ino(sfp, sfep, + xfs_dir2_sfe_get_ino(oldsfp, oldsfep)); } /* * Clean up the inode. @@ -1199,7 +1262,6 @@ xfs_dir2_sf_toino8( char *buf; /* old dir's buffer */ xfs_inode_t *dp; /* incore directory inode */ int i; /* entry index */ - xfs_ino_t ino; /* entry inode number */ int newsize; /* new inode size */ xfs_dir2_sf_entry_t *oldsfep; /* old sf entry */ xfs_dir2_sf_t *oldsfp; /* old sf directory */ @@ -1240,8 +1302,7 @@ xfs_dir2_sf_toino8( */ sfp->hdr.count = oldsfp->hdr.count; sfp->hdr.i8count = 1; - ino = xfs_dir2_sf_get_inumber(oldsfp, &oldsfp->hdr.parent); - xfs_dir2_sf_put_inumber(sfp, &ino, &sfp->hdr.parent); + xfs_dir2_sf_put_parent_ino(sfp, xfs_dir2_sf_get_parent_ino(oldsfp)); /* * Copy the entries field by field. */ @@ -1253,9 +1314,8 @@ xfs_dir2_sf_toino8( sfep->namelen = oldsfep->namelen; sfep->offset = oldsfep->offset; memcpy(sfep->name, oldsfep->name, sfep->namelen); - ino = xfs_dir2_sf_get_inumber(oldsfp, - xfs_dir2_sf_inumberp(oldsfep)); - xfs_dir2_sf_put_inumber(sfp, &ino, xfs_dir2_sf_inumberp(sfep)); + xfs_dir2_sfe_put_ino(sfp, sfep, + xfs_dir2_sfe_get_ino(oldsfp, oldsfep)); } /* * Clean up the inode. Index: xfs/fs/xfs/xfs_dir2_sf.h =================================================================== --- xfs.orig/fs/xfs/xfs_dir2_sf.h 2011-06-30 09:31:15.343406344 +0200 +++ xfs/fs/xfs/xfs_dir2_sf.h 2011-06-30 09:32:00.390072451 +0200 @@ -90,28 +90,6 @@ static inline int xfs_dir2_sf_hdr_size(i ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t))); } -static inline xfs_dir2_inou_t *xfs_dir2_sf_inumberp(xfs_dir2_sf_entry_t *sfep) -{ - return (xfs_dir2_inou_t *)&(sfep)->name[(sfep)->namelen]; -} - -static inline xfs_intino_t -xfs_dir2_sf_get_inumber(xfs_dir2_sf_t *sfp, xfs_dir2_inou_t *from) -{ - return ((sfp)->hdr.i8count == 0 ? \ - (xfs_intino_t)XFS_GET_DIR_INO4((from)->i4) : \ - (xfs_intino_t)XFS_GET_DIR_INO8((from)->i8)); -} - -static inline void xfs_dir2_sf_put_inumber(xfs_dir2_sf_t *sfp, xfs_ino_t *from, - xfs_dir2_inou_t *to) -{ - if ((sfp)->hdr.i8count == 0) - XFS_PUT_DIR_INO4(*(from), (to)->i4); - else - XFS_PUT_DIR_INO8(*(from), (to)->i8); -} - static inline xfs_dir2_data_aoff_t xfs_dir2_sf_get_offset(xfs_dir2_sf_entry_t *sfep) { @@ -155,6 +133,9 @@ xfs_dir2_sf_nextentry(xfs_dir2_sf_t *sfp /* * Functions. */ +extern xfs_ino_t xfs_dir2_sf_get_parent_ino(struct xfs_dir2_sf *sfp); +extern xfs_ino_t xfs_dir2_sfe_get_ino(struct xfs_dir2_sf *sfp, + struct xfs_dir2_sf_entry *sfep); extern int xfs_dir2_block_sfsize(struct xfs_inode *dp, struct xfs_dir2_block *block, xfs_dir2_sf_hdr_t *sfhp); Index: xfs/fs/xfs/xfs_inum.h =================================================================== --- xfs.orig/fs/xfs/xfs_inum.h 2011-06-30 09:31:15.353406344 +0200 +++ xfs/fs/xfs/xfs_inum.h 2011-06-30 09:32:00.390072451 +0200 @@ -28,17 +28,6 @@ typedef __uint32_t xfs_agino_t; /* within allocation grp inode number */ -/* - * Useful inode bits for this kernel. - * Used in some places where having 64-bits in the 32-bit kernels - * costs too much. - */ -#if XFS_BIG_INUMS -typedef xfs_ino_t xfs_intino_t; -#else -typedef __uint32_t xfs_intino_t; -#endif - #define NULLFSINO ((xfs_ino_t)-1) #define NULLAGINO ((xfs_agino_t)-1) Index: xfs/fs/xfs/xfs_dir2_block.c =================================================================== --- xfs.orig/fs/xfs/xfs_dir2_block.c 2011-06-30 09:31:15.000000000 +0200 +++ xfs/fs/xfs/xfs_dir2_block.c 2011-06-30 09:32:00.393405784 +0200 @@ -1146,7 +1146,7 @@ xfs_dir2_sf_to_block( */ dep = (xfs_dir2_data_entry_t *) ((char *)block + XFS_DIR2_DATA_DOTDOT_OFFSET); - dep->inumber = cpu_to_be64(xfs_dir2_sf_get_inumber(sfp, &sfp->hdr.parent)); + dep->inumber = cpu_to_be64(xfs_dir2_sf_get_parent_ino(sfp)); dep->namelen = 2; dep->name[0] = dep->name[1] = '.'; tagp = xfs_dir2_data_entry_tag_p(dep); @@ -1195,8 +1195,7 @@ xfs_dir2_sf_to_block( * Copy a real entry. */ dep = (xfs_dir2_data_entry_t *)((char *)block + newoffset); - dep->inumber = cpu_to_be64(xfs_dir2_sf_get_inumber(sfp, - xfs_dir2_sf_inumberp(sfep))); + dep->inumber = cpu_to_be64(xfs_dir2_sfe_get_ino(sfp, sfep)); dep->namelen = sfep->namelen; memcpy(dep->name, sfep->name, dep->namelen); tagp = xfs_dir2_data_entry_tag_p(dep); From BATV+1dd5f1c206cd6a728cfd+2868+infradead.org+hch@bombadil.srs.infradead.org Fri Jul 1 04:46:08 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-4.9 required=5.0 tests=BAYES_00,LOCAL_GNU_PATCH autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p619k7C6056102 for ; Fri, 1 Jul 2011 04:46:08 -0500 X-ASG-Debug-ID: 1309513566-14c800f00000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from bombadil.infradead.org (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 24C3616748BB for ; Fri, 1 Jul 2011 02:46:06 -0700 (PDT) Received: from bombadil.infradead.org (173-166-109-252-newengland.hfc.comcastbusiness.net [173.166.109.252]) by cuda.sgi.com with ESMTP id TPL1GILr005EzEeD for ; Fri, 01 Jul 2011 02:46:06 -0700 (PDT) Received: from hch by bombadil.infradead.org with local (Exim 4.76 #1 (Red Hat Linux)) id 1QcaIY-0001zK-7n for xfs@oss.sgi.com; Fri, 01 Jul 2011 09:46:06 +0000 Message-Id: <20110701094606.199361663@bombadil.infradead.org> User-Agent: quilt/0.48-1 Date: Fri, 01 Jul 2011 05:43:40 -0400 From: Christoph Hellwig To: xfs@oss.sgi.com X-ASG-Orig-Subj: [PATCH 19/27] xfs: kill struct xfs_dir2_data Subject: [PATCH 19/27] xfs: kill struct xfs_dir2_data References: <20110701094321.936534538@bombadil.infradead.org> Content-Disposition: inline; filename=xfs-kill-xfs_dir2_data_t X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: 173-166-109-252-newengland.hfc.comcastbusiness.net[173.166.109.252] X-Barracuda-Start-Time: 1309513567 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -1.42 X-Barracuda-Spam-Status: No, SCORE=-1.42 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=BSF_SC5_MJ1963, RDNS_DYNAMIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67646 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_DYNAMIC Delivered to trusted network by host with dynamic-looking rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean Remove the confusing xfs_dir2_data structure. It is supposed to describe an XFS dir2 data btree block, but due to the variable sized nature of almost all elements in it it can't actuall do anything close to that job. In addition to accessing the fixed offset header structure it was only used to get a pointer to the first dir or unused entry after it, which can be trivially replaced by pointer arithmetics on the header pointer. For most users that is actually more natural anyway, as they don't use a typed pointer but rather a character pointer for further arithmetics. Signed-off-by: Christoph Hellwig Index: xfs/fs/xfs/xfs_dir2_data.c =================================================================== --- xfs.orig/fs/xfs/xfs_dir2_data.c 2011-06-30 09:38:40.133400821 +0200 +++ xfs/fs/xfs/xfs_dir2_data.c 2011-06-30 09:38:41.643400800 +0200 @@ -53,7 +53,6 @@ xfs_dir2_data_check( xfs_dir2_data_free_t *bf; /* bestfree table */ xfs_dir2_block_tail_t *btp=NULL; /* block tail */ int count; /* count of entries found */ - xfs_dir2_data_t *d; /* data block pointer */ xfs_dir2_data_hdr_t *hdr; /* data block header */ xfs_dir2_data_entry_t *dep; /* data entry */ xfs_dir2_data_free_t *dfp; /* bestfree entry */ @@ -70,10 +69,9 @@ xfs_dir2_data_check( struct xfs_name name; mp = dp->i_mount; - d = bp->data; - hdr = &d->hdr; + hdr = bp->data; bf = hdr->bestfree; - p = (char *)d->u; + p = (char *)(hdr + 1); if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC)) { btp = xfs_dir2_block_tail_p(mp, hdr); @@ -336,7 +334,6 @@ xfs_dir2_data_freescan( xfs_dir2_data_hdr_t *hdr, /* data block header */ int *loghead) /* out: log data header */ { - xfs_dir2_data_t *d = (xfs_dir2_data_t *)hdr; xfs_dir2_block_tail_t *btp; /* block tail */ xfs_dir2_data_entry_t *dep; /* active data entry */ xfs_dir2_data_unused_t *dup; /* unused data entry */ @@ -355,7 +352,7 @@ xfs_dir2_data_freescan( /* * Set up pointers. */ - p = (char *)d->u; + p = (char *)(hdr + 1); if (be32_to_cpu(hdr->magic) == XFS_DIR2_BLOCK_MAGIC) { btp = xfs_dir2_block_tail_p(mp, hdr); endp = (char *)xfs_dir2_block_leaf_p(btp); @@ -398,7 +395,6 @@ xfs_dir2_data_init( xfs_dabuf_t **bpp) /* output block buffer */ { xfs_dabuf_t *bp; /* block buffer */ - xfs_dir2_data_t *d; /* pointer to block */ xfs_dir2_data_hdr_t *hdr; /* data block header */ xfs_inode_t *dp; /* incore directory inode */ xfs_dir2_data_unused_t *dup; /* unused entry pointer */ @@ -424,8 +420,7 @@ xfs_dir2_data_init( /* * Initialize the header. */ - d = bp->data; - hdr = &d->hdr; + hdr = bp->data; hdr->magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC); hdr->bestfree[0].offset = cpu_to_be16(sizeof(*hdr)); for (i = 1; i < XFS_DIR2_DATA_FD_COUNT; i++) { @@ -436,7 +431,7 @@ xfs_dir2_data_init( /* * Set up an unused entry for the block's body. */ - dup = &d->u[0].unused; + dup = (xfs_dir2_data_unused_t *)(hdr + 1); dup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); t = mp->m_dirblksize - (uint)sizeof(*hdr); Index: xfs/fs/xfs/xfs_dir2_data.h =================================================================== --- xfs.orig/fs/xfs/xfs_dir2_data.h 2011-06-30 09:38:40.136734154 +0200 +++ xfs/fs/xfs/xfs_dir2_data.h 2011-06-30 09:38:41.646734133 +0200 @@ -20,6 +20,22 @@ /* * Directory format 2, data block structures. + * + * A pure data block looks like the following drawing on disk: + * + * +-------------------------------------------------+ + * | xfs_dir2_data_hdr_t | + * +-------------------------------------------------+ + * | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t | + * | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t | + * | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t | + * | ... | + * +-------------------------------------------------+ + * | unused space | + * +-------------------------------------------------+ + * + * As all the entries are variable sized structures the accessors in this + * file need to be used to iterate over them. */ struct xfs_dabuf; @@ -103,23 +119,6 @@ typedef struct xfs_dir2_data_unused { __be16 tag; /* starting offset of us */ } xfs_dir2_data_unused_t; -typedef union { - xfs_dir2_data_entry_t entry; - xfs_dir2_data_unused_t unused; -} xfs_dir2_data_union_t; - -/* - * Generic data block structure, for xfs_db. - */ -typedef struct xfs_dir2_data { - xfs_dir2_data_hdr_t hdr; /* magic XFS_DIR2_DATA_MAGIC */ - xfs_dir2_data_union_t u[1]; -} xfs_dir2_data_t; - -/* - * Macros. - */ - /* * Size of a data entry. */ Index: xfs/fs/xfs/xfs_dir2_leaf.c =================================================================== --- xfs.orig/fs/xfs/xfs_dir2_leaf.c 2011-06-30 09:38:40.140067486 +0200 +++ xfs/fs/xfs/xfs_dir2_leaf.c 2011-06-30 09:38:41.646734133 +0200 @@ -785,7 +785,6 @@ xfs_dir2_leaf_getdents( int byteoff; /* offset in current block */ xfs_dir2_db_t curdb; /* db for current block */ xfs_dir2_off_t curoff; /* current overall offset */ - xfs_dir2_data_t *data; /* data block structure */ xfs_dir2_data_hdr_t *hdr; /* data block header */ xfs_dir2_data_entry_t *dep; /* data entry */ xfs_dir2_data_unused_t *dup; /* unused entry */ @@ -1044,13 +1043,12 @@ xfs_dir2_leaf_getdents( else if (curoff > newoff) ASSERT(xfs_dir2_byte_to_db(mp, curoff) == curdb); - data = bp->data; - hdr = &data->hdr; + hdr = bp->data; xfs_dir2_data_check(dp, bp); /* * Find our position in the block. */ - ptr = (char *)&data->u; + ptr = (char *)(hdr + 1); byteoff = xfs_dir2_byte_to_off(mp, curoff); /* * Skip past the header. From BATV+1dd5f1c206cd6a728cfd+2868+infradead.org+hch@bombadil.srs.infradead.org Fri Jul 1 04:46:08 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p619k85F056113 for ; Fri, 1 Jul 2011 04:46:08 -0500 X-ASG-Debug-ID: 1309513566-63af03b40000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from bombadil.infradead.org (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 2E476466AD for ; Fri, 1 Jul 2011 02:46:06 -0700 (PDT) Received: from bombadil.infradead.org (173-166-109-252-newengland.hfc.comcastbusiness.net [173.166.109.252]) by cuda.sgi.com with ESMTP id VtmdswGvcGhv0E86 for ; Fri, 01 Jul 2011 02:46:06 -0700 (PDT) Received: from hch by bombadil.infradead.org with local (Exim 4.76 #1 (Red Hat Linux)) id 1QcaIY-00020M-Jr for xfs@oss.sgi.com; Fri, 01 Jul 2011 09:46:06 +0000 Message-Id: <20110701094606.567693269@bombadil.infradead.org> User-Agent: quilt/0.48-1 Date: Fri, 01 Jul 2011 05:43:42 -0400 From: Christoph Hellwig To: xfs@oss.sgi.com X-ASG-Orig-Subj: [PATCH 21/27] xfs: cleanup struct xfs_dir2_leaf Subject: [PATCH 21/27] xfs: cleanup struct xfs_dir2_leaf References: <20110701094321.936534538@bombadil.infradead.org> Content-Disposition: inline; filename=xfs-cleanup-xfs_dir2_leaf_t X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: 173-166-109-252-newengland.hfc.comcastbusiness.net[173.166.109.252] X-Barracuda-Start-Time: 1309513567 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -1.42 X-Barracuda-Spam-Status: No, SCORE=-1.42 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=BSF_SC5_MJ1963, RDNS_DYNAMIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67645 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_DYNAMIC Delivered to trusted network by host with dynamic-looking rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean Simplify the confusing xfs_dir2_leaf structure. It is supposed to describe an XFS dir2 leaf format btree block, but due to the variable sized nature of almost all elements in it it can't actuall do anything close to that job. Remove the members that are after the first variable sized array, given that they could only be used for sizeof expressions that can as well just use the underlying types directly, and make the ents array a real C99 variable sized array. Also factor out the xfs_dir2_leaf_size, to make the sizing of a leaf entry which already was convoluted somewhat readable after using the longer type names in the sizeof expressions. Signed-off-by: Christoph Hellwig Index: xfs/fs/xfs/xfs_dir2_leaf.c =================================================================== --- xfs.orig/fs/xfs/xfs_dir2_leaf.c 2011-06-30 09:38:41.646734133 +0200 +++ xfs/fs/xfs/xfs_dir2_leaf.c 2011-06-30 09:38:44.723400763 +0200 @@ -367,9 +367,12 @@ xfs_dir2_leaf_addname( /* * How many bytes do we need in the leaf block? */ - needbytes = - (leaf->hdr.stale ? 0 : (uint)sizeof(leaf->ents[0])) + - (use_block != -1 ? 0 : (uint)sizeof(leaf->bests[0])); + needbytes = 0; + if (!leaf->hdr.stale) + needbytes += sizeof(xfs_dir2_leaf_entry_t); + if (use_block == -1) + needbytes += sizeof(xfs_dir2_data_off_t); + /* * Now kill use_block if it refers to a missing block, so we * can use it as an indication of allocation needed. @@ -1763,6 +1766,20 @@ xfs_dir2_leaf_trim_data( return 0; } +static inline size_t +xfs_dir2_leaf_size( + struct xfs_dir2_leaf_hdr *hdr, + int counts) +{ + int entries; + + entries = be16_to_cpu(hdr->count) - be16_to_cpu(hdr->stale); + return sizeof(xfs_dir2_leaf_hdr_t) + + entries * sizeof(xfs_dir2_leaf_entry_t) + + counts * sizeof(xfs_dir2_data_off_t) + + sizeof(xfs_dir2_leaf_tail_t); +} + /* * Convert node form directory to leaf form directory. * The root of the node form dir needs to already be a LEAFN block. @@ -1844,18 +1861,17 @@ xfs_dir2_node_to_leaf( free = fbp->data; ASSERT(be32_to_cpu(free->hdr.magic) == XFS_DIR2_FREE_MAGIC); ASSERT(!free->hdr.firstdb); + /* * Now see if the leafn and free data will fit in a leaf1. * If not, release the buffer and give up. */ - if ((uint)sizeof(leaf->hdr) + - (be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale)) * (uint)sizeof(leaf->ents[0]) + - be32_to_cpu(free->hdr.nvalid) * (uint)sizeof(leaf->bests[0]) + - (uint)sizeof(leaf->tail) > - mp->m_dirblksize) { + if (xfs_dir2_leaf_size(&leaf->hdr, be32_to_cpu(free->hdr.nvalid)) > + mp->m_dirblksize) { xfs_da_brelse(tp, fbp); return 0; } + /* * If the leaf has any stale entries in it, compress them out. * The compact routine will log the header. @@ -1874,7 +1890,7 @@ xfs_dir2_node_to_leaf( * Set up the leaf bests table. */ memcpy(xfs_dir2_leaf_bests_p(ltp), free->bests, - be32_to_cpu(ltp->bestcount) * sizeof(leaf->bests[0])); + be32_to_cpu(ltp->bestcount) * sizeof(xfs_dir2_data_off_t)); xfs_dir2_leaf_log_bests(tp, lbp, 0, be32_to_cpu(ltp->bestcount) - 1); xfs_dir2_leaf_log_tail(tp, lbp); xfs_dir2_leaf_check(dp, lbp); Index: xfs/fs/xfs/xfs_dir2_leaf.h =================================================================== --- xfs.orig/fs/xfs/xfs_dir2_leaf.h 2011-06-30 09:18:07.263416117 +0200 +++ xfs/fs/xfs/xfs_dir2_leaf.h 2011-06-30 09:38:44.723400763 +0200 @@ -72,10 +72,7 @@ typedef struct xfs_dir2_leaf_tail { */ typedef struct xfs_dir2_leaf { xfs_dir2_leaf_hdr_t hdr; /* leaf header */ - xfs_dir2_leaf_entry_t ents[1]; /* entries */ - /* ... */ - xfs_dir2_data_off_t bests[1]; /* best free counts */ - xfs_dir2_leaf_tail_t tail; /* leaf tail */ + xfs_dir2_leaf_entry_t ents[]; /* entries */ } xfs_dir2_leaf_t; /* From BATV+1dd5f1c206cd6a728cfd+2868+infradead.org+hch@bombadil.srs.infradead.org Fri Jul 1 04:46:08 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p619k7Kn056095 for ; Fri, 1 Jul 2011 04:46:07 -0500 X-ASG-Debug-ID: 1309513566-648d01380000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from bombadil.infradead.org (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 038AD1EE3239 for ; Fri, 1 Jul 2011 02:46:06 -0700 (PDT) Received: from bombadil.infradead.org (173-166-109-252-newengland.hfc.comcastbusiness.net [173.166.109.252]) by cuda.sgi.com with ESMTP id McSQU1jaGyuCo3WT for ; Fri, 01 Jul 2011 02:46:06 -0700 (PDT) Received: from hch by bombadil.infradead.org with local (Exim 4.76 #1 (Red Hat Linux)) id 1QcaIY-0001zq-Db for xfs@oss.sgi.com; Fri, 01 Jul 2011 09:46:06 +0000 Message-Id: <20110701094606.386730624@bombadil.infradead.org> User-Agent: quilt/0.48-1 Date: Fri, 01 Jul 2011 05:43:41 -0400 From: Christoph Hellwig To: xfs@oss.sgi.com X-ASG-Orig-Subj: [PATCH 20/27] xfs: cleanup the defintion of struct xfs_dir2_data_entry Subject: [PATCH 20/27] xfs: cleanup the defintion of struct xfs_dir2_data_entry References: <20110701094321.936534538@bombadil.infradead.org> Content-Disposition: inline; filename=xfs-cleanup-xfs_dir2_data_entry X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: 173-166-109-252-newengland.hfc.comcastbusiness.net[173.166.109.252] X-Barracuda-Start-Time: 1309513567 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0047 1.0000 -1.9903 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -1.39 X-Barracuda-Spam-Status: No, SCORE=-1.39 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=BSF_SC5_MJ1963, RDNS_DYNAMIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67645 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_DYNAMIC Delivered to trusted network by host with dynamic-looking rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean Remove the tag member which is at a variable offset after the actual name, and make name a real variable sized C99 array instead of the incorrect one-sized array which confuses (not only) gcc. Signed-off-by: Christoph Hellwig Index: xfs/fs/xfs/xfs_dir2_data.h =================================================================== --- xfs.orig/fs/xfs/xfs_dir2_data.h 2011-06-29 13:42:35.521563513 +0200 +++ xfs/fs/xfs/xfs_dir2_data.h 2011-06-29 13:43:03.284746440 +0200 @@ -98,14 +98,14 @@ typedef struct xfs_dir2_data_hdr { /* * Active entry in a data block. Aligned to 8 bytes. - * Tag appears as the last 2 bytes. + * + * After the variable length name field there is a 2 byte tag field, which + * can be accessed using xfs_dir2_data_entry_tag_p. */ typedef struct xfs_dir2_data_entry { __be64 inumber; /* inode number */ __u8 namelen; /* name length */ - __u8 name[1]; /* name bytes, no null */ - /* variable offset */ - __be16 tag; /* starting offset of us */ + __u8 name[]; /* name bytes, no null */ } xfs_dir2_data_entry_t; /* From BATV+1dd5f1c206cd6a728cfd+2868+infradead.org+hch@bombadil.srs.infradead.org Fri Jul 1 04:46:09 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p619k8VR056145 for ; Fri, 1 Jul 2011 04:46:09 -0500 X-ASG-Debug-ID: 1309513567-798c02190000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from bombadil.infradead.org (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 31D8716748CB for ; Fri, 1 Jul 2011 02:46:07 -0700 (PDT) Received: from bombadil.infradead.org (173-166-109-252-newengland.hfc.comcastbusiness.net [173.166.109.252]) by cuda.sgi.com with ESMTP id u6qdGFbdCSXLWPR6 for ; Fri, 01 Jul 2011 02:46:07 -0700 (PDT) Received: from hch by bombadil.infradead.org with local (Exim 4.76 #1 (Red Hat Linux)) id 1QcaIZ-00022S-Cg for xfs@oss.sgi.com; Fri, 01 Jul 2011 09:46:07 +0000 Message-Id: <20110701094607.356791525@bombadil.infradead.org> User-Agent: quilt/0.48-1 Date: Fri, 01 Jul 2011 05:43:46 -0400 From: Christoph Hellwig To: xfs@oss.sgi.com X-ASG-Orig-Subj: [PATCH 25/27] xfs: return the buffer locked from xfs_buf_get_uncached Subject: [PATCH 25/27] xfs: return the buffer locked from xfs_buf_get_uncached References: <20110701094321.936534538@bombadil.infradead.org> Content-Disposition: inline; filename=xfs-buf_get_uncached-locked-buffer X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: 173-166-109-252-newengland.hfc.comcastbusiness.net[173.166.109.252] X-Barracuda-Start-Time: 1309513568 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -1.42 X-Barracuda-Spam-Status: No, SCORE=-1.42 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=BSF_SC5_MJ1963, RDNS_DYNAMIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67646 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_DYNAMIC Delivered to trusted network by host with dynamic-looking rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean All other xfs_buf_get/read-like helpers return the buffer locked, make sure xfs_buf_get_uncached isn't different for no reason. Half of the callers already lock it directly after, and the others probably should also keep it locked if only for consistency and beeing able to use xfs_buf_rele, but I'll leave that for later. Signed-off-by: Christoph Hellwig Index: xfs/fs/xfs/linux-2.6/xfs_buf.c =================================================================== --- xfs.orig/fs/xfs/linux-2.6/xfs_buf.c 2011-06-29 13:57:15.596795734 +0200 +++ xfs/fs/xfs/linux-2.6/xfs_buf.c 2011-06-29 13:57:32.243372220 +0200 @@ -679,7 +679,6 @@ xfs_buf_read_uncached( return NULL; /* set up the buffer for a read IO */ - xfs_buf_lock(bp); XFS_BUF_SET_ADDR(bp, daddr); XFS_BUF_READ(bp); XFS_BUF_BUSY(bp); @@ -814,8 +813,6 @@ xfs_buf_get_uncached( goto fail_free_mem; } - xfs_buf_unlock(bp); - trace_xfs_buf_get_uncached(bp, _RET_IP_); return bp; Index: xfs/fs/xfs/xfs_log.c =================================================================== --- xfs.orig/fs/xfs/xfs_log.c 2011-06-29 13:53:33.954663139 +0200 +++ xfs/fs/xfs/xfs_log.c 2011-06-29 13:57:32.243372220 +0200 @@ -1090,8 +1090,7 @@ xlog_alloc_log(xfs_mount_t *mp, log->l_iclog_size, 0); if (!bp) goto out_free_iclog; - if (!xfs_buf_trylock(bp)) - ASSERT(0); + XFS_BUF_SET_IODONE_FUNC(bp, xlog_iodone); XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)1); iclog->ic_bp = bp; Index: xfs/fs/xfs/xfs_log_recover.c =================================================================== --- xfs.orig/fs/xfs/xfs_log_recover.c 2011-06-29 13:51:20.425386530 +0200 +++ xfs/fs/xfs/xfs_log_recover.c 2011-06-29 13:57:32.246705535 +0200 @@ -91,6 +91,8 @@ xlog_get_bp( xlog_t *log, int nbblks) { + struct xfs_buf *bp; + if (!xlog_buf_bbcount_valid(log, nbblks)) { xfs_warn(log->l_mp, "Invalid block length (0x%x) for buffer", nbblks); @@ -118,8 +120,10 @@ xlog_get_bp( nbblks += log->l_sectBBsize; nbblks = round_up(nbblks, log->l_sectBBsize); - return xfs_buf_get_uncached(log->l_mp->m_logdev_targp, - BBTOB(nbblks), 0); + bp = xfs_buf_get_uncached(log->l_mp->m_logdev_targp, BBTOB(nbblks), 0); + if (bp) + xfs_buf_unlock(bp); + return bp; } STATIC void Index: xfs/fs/xfs/xfs_vnodeops.c =================================================================== --- xfs.orig/fs/xfs/xfs_vnodeops.c 2011-06-29 11:35:45.789455635 +0200 +++ xfs/fs/xfs/xfs_vnodeops.c 2011-06-29 13:57:32.250038850 +0200 @@ -1969,6 +1969,8 @@ xfs_zero_remaining_bytes( if (!bp) return XFS_ERROR(ENOMEM); + xfs_buf_unlock(bp); + for (offset = startoff; offset <= endoff; offset = lastoffset + 1) { offset_fsb = XFS_B_TO_FSBT(mp, offset); nimap = 1; From BATV+1dd5f1c206cd6a728cfd+2868+infradead.org+hch@bombadil.srs.infradead.org Fri Jul 1 04:46:09 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-4.9 required=5.0 tests=BAYES_00,LOCAL_GNU_PATCH autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p619k8LK056132 for ; Fri, 1 Jul 2011 04:46:08 -0500 X-ASG-Debug-ID: 1309513567-6d2200a90000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from bombadil.infradead.org (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 7EB9D1EE323B for ; Fri, 1 Jul 2011 02:46:07 -0700 (PDT) Received: from bombadil.infradead.org (173-166-109-252-newengland.hfc.comcastbusiness.net [173.166.109.252]) by cuda.sgi.com with ESMTP id HZlNzx5tNwDPjDqJ for ; Fri, 01 Jul 2011 02:46:07 -0700 (PDT) Received: from hch by bombadil.infradead.org with local (Exim 4.76 #1 (Red Hat Linux)) id 1QcaIY-00020s-Pt for xfs@oss.sgi.com; Fri, 01 Jul 2011 09:46:06 +0000 Message-Id: <20110701094606.763430916@bombadil.infradead.org> User-Agent: quilt/0.48-1 Date: Fri, 01 Jul 2011 05:43:43 -0400 From: Christoph Hellwig To: xfs@oss.sgi.com X-ASG-Orig-Subj: [PATCH 22/27] xfs: use generic get_unaligned_beXX helpers Subject: [PATCH 22/27] xfs: use generic get_unaligned_beXX helpers References: <20110701094321.936534538@bombadil.infradead.org> Content-Disposition: inline; filename=xfs-dir2-use-generic-unaligned-byteswap-macros X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: 173-166-109-252-newengland.hfc.comcastbusiness.net[173.166.109.252] X-Barracuda-Start-Time: 1309513567 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -0.82 X-Barracuda-Spam-Status: No, SCORE=-0.82 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=BSF_SC5_MJ1963, MARKETING_SUBJECT, RDNS_DYNAMIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67645 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.60 MARKETING_SUBJECT Subject contains popular marketing words 0.10 RDNS_DYNAMIC Delivered to trusted network by host with dynamic-looking rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean Switch the shortform directory code over to use the generic get_unaligned_beXX helpers instead of reinventing them. As a result kill off xfs_arch.h and move the setting of XFS_NATIVE_HOST into xfs_linux.h. Signed-off-by: Christoph Hellwig Index: xfs/fs/xfs/linux-2.6/xfs_linux.h =================================================================== --- xfs.orig/fs/xfs/linux-2.6/xfs_linux.h 2011-06-30 20:22:44.849587371 +0200 +++ xfs/fs/xfs/linux-2.6/xfs_linux.h 2011-06-30 20:40:52.116240531 +0200 @@ -33,7 +33,6 @@ #endif #include -#include #include #include @@ -88,6 +87,12 @@ #include #include +#ifdef __BIG_ENDIAN +#define XFS_NATIVE_HOST 1 +#else +#undef XFS_NATIVE_HOST +#endif + /* * Feature macros (disable/enable) */ Index: xfs/fs/xfs/xfs_arch.h =================================================================== --- xfs.orig/fs/xfs/xfs_arch.h 2011-06-30 20:21:42.116254819 +0200 +++ /dev/null 1970-01-01 00:00:00.000000000 +0000 @@ -1,136 +0,0 @@ -/* - * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ -#ifndef __XFS_ARCH_H__ -#define __XFS_ARCH_H__ - -#ifndef XFS_BIG_INUMS -# error XFS_BIG_INUMS must be defined true or false -#endif - -#ifdef __KERNEL__ - -#include - -#ifdef __BIG_ENDIAN -#define XFS_NATIVE_HOST 1 -#else -#undef XFS_NATIVE_HOST -#endif - -#else /* __KERNEL__ */ - -#if __BYTE_ORDER == __BIG_ENDIAN -#define XFS_NATIVE_HOST 1 -#else -#undef XFS_NATIVE_HOST -#endif - -#ifdef XFS_NATIVE_HOST -#define cpu_to_be16(val) ((__force __be16)(__u16)(val)) -#define cpu_to_be32(val) ((__force __be32)(__u32)(val)) -#define cpu_to_be64(val) ((__force __be64)(__u64)(val)) -#define be16_to_cpu(val) ((__force __u16)(__be16)(val)) -#define be32_to_cpu(val) ((__force __u32)(__be32)(val)) -#define be64_to_cpu(val) ((__force __u64)(__be64)(val)) -#else -#define cpu_to_be16(val) ((__force __be16)__swab16((__u16)(val))) -#define cpu_to_be32(val) ((__force __be32)__swab32((__u32)(val))) -#define cpu_to_be64(val) ((__force __be64)__swab64((__u64)(val))) -#define be16_to_cpu(val) (__swab16((__force __u16)(__be16)(val))) -#define be32_to_cpu(val) (__swab32((__force __u32)(__be32)(val))) -#define be64_to_cpu(val) (__swab64((__force __u64)(__be64)(val))) -#endif - -static inline void be16_add_cpu(__be16 *a, __s16 b) -{ - *a = cpu_to_be16(be16_to_cpu(*a) + b); -} - -static inline void be32_add_cpu(__be32 *a, __s32 b) -{ - *a = cpu_to_be32(be32_to_cpu(*a) + b); -} - -static inline void be64_add_cpu(__be64 *a, __s64 b) -{ - *a = cpu_to_be64(be64_to_cpu(*a) + b); -} - -#endif /* __KERNEL__ */ - -/* - * get and set integers from potentially unaligned locations - */ - -#define INT_GET_UNALIGNED_16_BE(pointer) \ - ((__u16)((((__u8*)(pointer))[0] << 8) | (((__u8*)(pointer))[1]))) -#define INT_SET_UNALIGNED_16_BE(pointer,value) \ - { \ - ((__u8*)(pointer))[0] = (((value) >> 8) & 0xff); \ - ((__u8*)(pointer))[1] = (((value) ) & 0xff); \ - } - -/* - * In directories inode numbers are stored as unaligned arrays of unsigned - * 8bit integers on disk. - * - * For v1 directories or v2 directories that contain inode numbers that - * do not fit into 32bit the array has eight members, but the first member - * is always zero: - * - * |unused|48-55|40-47|32-39|24-31|16-23| 8-15| 0- 7| - * - * For v2 directories that only contain entries with inode numbers that fit - * into 32bits a four-member array is used: - * - * |24-31|16-23| 8-15| 0- 7| - */ - -#define XFS_GET_DIR_INO4(di) \ - (((__u32)(di).i[0] << 24) | ((di).i[1] << 16) | ((di).i[2] << 8) | ((di).i[3])) - -#define XFS_PUT_DIR_INO4(from, di) \ -do { \ - (di).i[0] = (((from) & 0xff000000ULL) >> 24); \ - (di).i[1] = (((from) & 0x00ff0000ULL) >> 16); \ - (di).i[2] = (((from) & 0x0000ff00ULL) >> 8); \ - (di).i[3] = ((from) & 0x000000ffULL); \ -} while (0) - -#define XFS_DI_HI(di) \ - (((__u32)(di).i[1] << 16) | ((di).i[2] << 8) | ((di).i[3])) -#define XFS_DI_LO(di) \ - (((__u32)(di).i[4] << 24) | ((di).i[5] << 16) | ((di).i[6] << 8) | ((di).i[7])) - -#define XFS_GET_DIR_INO8(di) \ - (((xfs_ino_t)XFS_DI_LO(di) & 0xffffffffULL) | \ - ((xfs_ino_t)XFS_DI_HI(di) << 32)) - -#define XFS_PUT_DIR_INO8(from, di) \ -do { \ - (di).i[0] = 0; \ - (di).i[1] = (((from) & 0x00ff000000000000ULL) >> 48); \ - (di).i[2] = (((from) & 0x0000ff0000000000ULL) >> 40); \ - (di).i[3] = (((from) & 0x000000ff00000000ULL) >> 32); \ - (di).i[4] = (((from) & 0x00000000ff000000ULL) >> 24); \ - (di).i[5] = (((from) & 0x0000000000ff0000ULL) >> 16); \ - (di).i[6] = (((from) & 0x000000000000ff00ULL) >> 8); \ - (di).i[7] = ((from) & 0x00000000000000ffULL); \ -} while (0) - -#endif /* __XFS_ARCH_H__ */ Index: xfs/fs/xfs/xfs_dir2_sf.c =================================================================== --- xfs.orig/fs/xfs/xfs_dir2_sf.c 2011-06-30 20:24:26.516252776 +0200 +++ xfs/fs/xfs/xfs_dir2_sf.c 2011-06-30 20:46:45.366236141 +0200 @@ -59,11 +59,12 @@ static void xfs_dir2_sf_toino4(xfs_da_ar static void xfs_dir2_sf_toino8(xfs_da_args_t *args); #endif /* XFS_BIG_INUMS */ - /* * Inode numbers in short-form directories can come in two versions, * either 4 bytes or 8 bytes wide. These helpers deal with the * two forms transparently by looking at the headers i8count field. + * + * For 64-bit inode number the most significant byte must be zero. */ static xfs_ino_t xfs_dir2_sf_get_ino( @@ -71,9 +72,9 @@ xfs_dir2_sf_get_ino( xfs_dir2_inou_t *from) { if (hdr->i8count) - return XFS_GET_DIR_INO8(from->i8); + return get_unaligned_be64(&from->i8.i) & 0x00ffffffffffffffULL; else - return XFS_GET_DIR_INO4(from->i4); + return get_unaligned_be32(&from->i4.i); } static void @@ -82,10 +83,12 @@ xfs_dir2_sf_put_ino( xfs_dir2_inou_t *to, xfs_ino_t ino) { + ASSERT((ino & 0xff00000000000000ULL) == 0); + if (hdr->i8count) - XFS_PUT_DIR_INO8(ino, to->i8); + put_unaligned_be64(ino, &to->i8.i); else - XFS_PUT_DIR_INO4(ino, to->i4); + put_unaligned_be32(ino, &to->i4.i); } xfs_ino_t Index: xfs/fs/xfs/xfs_dir2_sf.h =================================================================== --- xfs.orig/fs/xfs/xfs_dir2_sf.h 2011-06-30 20:24:08.732919663 +0200 +++ xfs/fs/xfs/xfs_dir2_sf.h 2011-06-30 20:38:37.019575543 +0200 @@ -95,13 +95,13 @@ static inline int xfs_dir2_sf_hdr_size(i static inline xfs_dir2_data_aoff_t xfs_dir2_sf_get_offset(xfs_dir2_sf_entry_t *sfep) { - return INT_GET_UNALIGNED_16_BE(&(sfep)->offset.i); + return get_unaligned_be16(&sfep->offset.i); } static inline void xfs_dir2_sf_put_offset(xfs_dir2_sf_entry_t *sfep, xfs_dir2_data_aoff_t off) { - INT_SET_UNALIGNED_16_BE(&(sfep)->offset.i, off); + put_unaligned_be16(off, &sfep->offset.i); } static inline int From BATV+1dd5f1c206cd6a728cfd+2868+infradead.org+hch@bombadil.srs.infradead.org Fri Jul 1 04:46:08 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=unavailable version=3.4.0-r929098 Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p619k8bk056116 for ; Fri, 1 Jul 2011 04:46:08 -0500 X-ASG-Debug-ID: 1309513567-63c403ae0000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from bombadil.infradead.org (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 7F52B4669F for ; Fri, 1 Jul 2011 02:46:07 -0700 (PDT) Received: from bombadil.infradead.org (173-166-109-252-newengland.hfc.comcastbusiness.net [173.166.109.252]) by cuda.sgi.com with ESMTP id HM09kqnQxcgxdNRo for ; Fri, 01 Jul 2011 02:46:07 -0700 (PDT) Received: from hch by bombadil.infradead.org with local (Exim 4.76 #1 (Red Hat Linux)) id 1QcaIY-00021Q-Vy for xfs@oss.sgi.com; Fri, 01 Jul 2011 09:46:07 +0000 Message-Id: <20110701094606.955329993@bombadil.infradead.org> User-Agent: quilt/0.48-1 Date: Fri, 01 Jul 2011 05:43:44 -0400 From: Christoph Hellwig To: xfs@oss.sgi.com X-ASG-Orig-Subj: [PATCH 23/27] xfs: remove the unused xfs_bufhash structure Subject: [PATCH 23/27] xfs: remove the unused xfs_bufhash structure References: <20110701094321.936534538@bombadil.infradead.org> Content-Disposition: inline; filename=xfs-remove-bufhash X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: 173-166-109-252-newengland.hfc.comcastbusiness.net[173.166.109.252] X-Barracuda-Start-Time: 1309513567 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -1.42 X-Barracuda-Spam-Status: No, SCORE=-1.42 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=BSF_SC5_MJ1963, RDNS_DYNAMIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67645 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_DYNAMIC Delivered to trusted network by host with dynamic-looking rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean Signed-off-by: Christoph Hellwig Index: xfs/fs/xfs/linux-2.6/xfs_buf.h =================================================================== --- xfs.orig/fs/xfs/linux-2.6/xfs_buf.h 2011-06-29 11:26:14.542550346 +0200 +++ xfs/fs/xfs/linux-2.6/xfs_buf.h 2011-06-29 13:50:40.648935352 +0200 @@ -91,11 +91,6 @@ typedef enum { XBT_FORCE_FLUSH = 1, } xfs_buftarg_flags_t; -typedef struct xfs_bufhash { - struct list_head bh_list; - spinlock_t bh_lock; -} xfs_bufhash_t; - typedef struct xfs_buftarg { dev_t bt_dev; struct block_device *bt_bdev; From BATV+1dd5f1c206cd6a728cfd+2868+infradead.org+hch@bombadil.srs.infradead.org Fri Jul 1 04:46:09 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p619k8Y0056143 for ; Fri, 1 Jul 2011 04:46:09 -0500 X-ASG-Debug-ID: 1309513568-63b303c70000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from bombadil.infradead.org (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 51B79466AD for ; Fri, 1 Jul 2011 02:46:08 -0700 (PDT) Received: from bombadil.infradead.org (173-166-109-252-newengland.hfc.comcastbusiness.net [173.166.109.252]) by cuda.sgi.com with ESMTP id qCMKJq5kqGlN4NqD for ; Fri, 01 Jul 2011 02:46:08 -0700 (PDT) Received: from hch by bombadil.infradead.org with local (Exim 4.76 #1 (Red Hat Linux)) id 1QcaIZ-00023Z-Qp for xfs@oss.sgi.com; Fri, 01 Jul 2011 09:46:07 +0000 Message-Id: <20110701094607.799498339@bombadil.infradead.org> User-Agent: quilt/0.48-1 Date: Fri, 01 Jul 2011 05:43:48 -0400 From: Christoph Hellwig To: xfs@oss.sgi.com X-ASG-Orig-Subj: [PATCH 27/27] xfs: avoid a few disk cache flushes Subject: [PATCH 27/27] xfs: avoid a few disk cache flushes References: <20110701094321.936534538@bombadil.infradead.org> Content-Disposition: inline; filename=xfs-avoid-cache-flushes X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: 173-166-109-252-newengland.hfc.comcastbusiness.net[173.166.109.252] X-Barracuda-Start-Time: 1309513568 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -1.42 X-Barracuda-Spam-Status: No, SCORE=-1.42 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=BSF_SC5_MJ1963, RDNS_DYNAMIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67645 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_DYNAMIC Delivered to trusted network by host with dynamic-looking rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean There is no need for a pre-flush when doing writing the second part of a split log buffer, and if we are using an external log there is no need to do a full cache flush of the log device at all given that all writes to it use the FUA flag. Signed-off-by: Christoph Hellwig Index: xfs/fs/xfs/xfs_log.c =================================================================== --- xfs.orig/fs/xfs/xfs_log.c 2011-07-01 11:35:50.874088428 +0200 +++ xfs/fs/xfs/xfs_log.c 2011-07-01 11:35:51.287421756 +0200 @@ -1371,15 +1371,21 @@ xlog_sync(xlog_t *log, bp->b_flags |= XBF_SYNCIO; if (log->l_mp->m_flags & XFS_MOUNT_BARRIER) { + bp->b_flags |= XBF_FUA; + /* - * If we have an external log device, flush the data device - * before flushing the log to make sure all meta data - * written back from the AIL actually made it to disk - * before writing out the new log tail LSN in the log buffer. + * Flush the data device before flushing the log to make + * sure all meta data written back from the AIL actually made + * it to disk before stamping the new log tail LSN into the + * log buffer. For an external log we need to issue the + * flush explicitly, and unfortunately synchronously here; + * for an internal log we can simply use the block layer + * state machine for preflushes. */ if (log->l_mp->m_logdev_targp != log->l_mp->m_ddev_targp) xfs_blkdev_issue_flush(log->l_mp->m_ddev_targp); - bp->b_flags |= XBF_FUA | XBF_FLUSH; + else + bp->b_flags |= XBF_FLUSH; } ASSERT(XFS_BUF_ADDR(bp) <= log->l_logBBsize-1); @@ -1414,7 +1420,7 @@ xlog_sync(xlog_t *log, XFS_BUF_ASYNC(bp); bp->b_flags |= XBF_SYNCIO; if (log->l_mp->m_flags & XFS_MOUNT_BARRIER) - bp->b_flags |= XBF_FUA | XBF_FLUSH; + bp->b_flags |= XBF_FUA; dptr = XFS_BUF_PTR(bp); /* * Bump the cycle numbers at the start of each block From BATV+1dd5f1c206cd6a728cfd+2868+infradead.org+hch@bombadil.srs.infradead.org Fri Jul 1 04:46:08 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-4.6 required=5.0 tests=BAYES_00,J_CHICKENPOX_33, J_CHICKENPOX_63,J_CHICKENPOX_66,LOCAL_GNU_PATCH autolearn=unavailable version=3.4.0-r929098 Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p619k74M056103 for ; Fri, 1 Jul 2011 04:46:08 -0500 X-ASG-Debug-ID: 1309513565-63c003b30000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from bombadil.infradead.org (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 13455466A1 for ; Fri, 1 Jul 2011 02:46:05 -0700 (PDT) Received: from bombadil.infradead.org (173-166-109-252-newengland.hfc.comcastbusiness.net [173.166.109.252]) by cuda.sgi.com with ESMTP id SncYendvCIOdR0FF for ; Fri, 01 Jul 2011 02:46:05 -0700 (PDT) Received: from hch by bombadil.infradead.org with local (Exim 4.76 #1 (Red Hat Linux)) id 1QcaIX-0001wj-7o for xfs@oss.sgi.com; Fri, 01 Jul 2011 09:46:05 +0000 Message-Id: <20110701094605.197942925@bombadil.infradead.org> User-Agent: quilt/0.48-1 Date: Fri, 01 Jul 2011 05:43:35 -0400 From: Christoph Hellwig To: xfs@oss.sgi.com X-ASG-Orig-Subj: [PATCH 14/27] xfs: kill struct xfs_dir2_sf Subject: [PATCH 14/27] xfs: kill struct xfs_dir2_sf References: <20110701094321.936534538@bombadil.infradead.org> Content-Disposition: inline; filename=xfs-kill-xfs_dir2_sf_t X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: 173-166-109-252-newengland.hfc.comcastbusiness.net[173.166.109.252] X-Barracuda-Start-Time: 1309513566 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -1.42 X-Barracuda-Spam-Status: No, SCORE=-1.42 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=BSF_SC5_MJ1963, RDNS_DYNAMIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67645 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_DYNAMIC Delivered to trusted network by host with dynamic-looking rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean The list field of it is never cactually used, so all uses can simply be replaced with the xfs_dir2_sf_hdr_t type that it has as first member. Signed-off-by: Christoph Hellwig Index: xfs/fs/xfs/xfs_dir2.c =================================================================== --- xfs.orig/fs/xfs/xfs_dir2.c 2011-06-29 19:45:24.000000000 +0200 +++ xfs/fs/xfs/xfs_dir2.c 2011-06-30 09:35:55.806736193 +0200 @@ -122,15 +122,15 @@ int xfs_dir_isempty( xfs_inode_t *dp) { - xfs_dir2_sf_t *sfp; + xfs_dir2_sf_hdr_t *sfp; ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); if (dp->i_d.di_size == 0) /* might happen during shutdown. */ return 1; if (dp->i_d.di_size > XFS_IFORK_DSIZE(dp)) return 0; - sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; - return !sfp->hdr.count; + sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; + return !sfp->count; } /* Index: xfs/fs/xfs/xfs_dir2_block.c =================================================================== --- xfs.orig/fs/xfs/xfs_dir2_block.c 2011-06-30 09:32:00.000000000 +0200 +++ xfs/fs/xfs/xfs_dir2_block.c 2011-06-30 09:35:55.810069526 +0200 @@ -1028,8 +1028,6 @@ xfs_dir2_sf_to_block( xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ xfs_dabuf_t *bp; /* block buffer */ xfs_dir2_block_tail_t *btp; /* block tail pointer */ - char *buf; /* sf buffer */ - int buf_len; xfs_dir2_data_entry_t *dep; /* data entry pointer */ xfs_inode_t *dp; /* incore directory inode */ int dummy; /* trash */ @@ -1043,7 +1041,8 @@ xfs_dir2_sf_to_block( int newoffset; /* offset from current entry */ int offset; /* target block offset */ xfs_dir2_sf_entry_t *sfep; /* sf entry pointer */ - xfs_dir2_sf_t *sfp; /* shortform structure */ + xfs_dir2_sf_hdr_t *oldsfp; /* old shortform header */ + xfs_dir2_sf_hdr_t *sfp; /* shortform header */ __be16 *tagp; /* end of data entry */ xfs_trans_t *tp; /* transaction pointer */ struct xfs_name name; @@ -1061,32 +1060,30 @@ xfs_dir2_sf_to_block( ASSERT(XFS_FORCED_SHUTDOWN(mp)); return XFS_ERROR(EIO); } + + oldsfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; + ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); ASSERT(dp->i_df.if_u1.if_data != NULL); - sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; - ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(sfp->hdr.i8count)); + ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(oldsfp->i8count)); + /* - * Copy the directory into the stack buffer. + * Copy the directory into a temporary buffer. * Then pitch the incore inode data so we can make extents. */ + sfp = kmem_alloc(dp->i_df.if_bytes, KM_SLEEP); + memcpy(sfp, oldsfp, dp->i_df.if_bytes); - buf_len = dp->i_df.if_bytes; - buf = kmem_alloc(buf_len, KM_SLEEP); - - memcpy(buf, sfp, buf_len); - xfs_idata_realloc(dp, -buf_len, XFS_DATA_FORK); + xfs_idata_realloc(dp, -dp->i_df.if_bytes, XFS_DATA_FORK); dp->i_d.di_size = 0; xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE); - /* - * Reset pointer - old sfp is gone. - */ - sfp = (xfs_dir2_sf_t *)buf; + /* * Add block 0 to the inode. */ error = xfs_dir2_grow_inode(args, XFS_DIR2_DATA_SPACE, &blkno); if (error) { - kmem_free(buf); + kmem_free(sfp); return error; } /* @@ -1094,7 +1091,7 @@ xfs_dir2_sf_to_block( */ error = xfs_dir2_data_init(args, blkno, &bp); if (error) { - kmem_free(buf); + kmem_free(sfp); return error; } block = bp->data; @@ -1103,7 +1100,7 @@ xfs_dir2_sf_to_block( * Compute size of block "tail" area. */ i = (uint)sizeof(*btp) + - (sfp->hdr.count + 2) * (uint)sizeof(xfs_dir2_leaf_entry_t); + (sfp->count + 2) * (uint)sizeof(xfs_dir2_leaf_entry_t); /* * The whole thing is initialized to free by the init routine. * Say we're using the leaf and tail area. @@ -1117,7 +1114,7 @@ xfs_dir2_sf_to_block( * Fill in the tail. */ btp = xfs_dir2_block_tail_p(mp, block); - btp->count = cpu_to_be32(sfp->hdr.count + 2); /* ., .. */ + btp->count = cpu_to_be32(sfp->count + 2); /* ., .. */ btp->stale = 0; blp = xfs_dir2_block_leaf_p(btp); endoffset = (uint)((char *)blp - (char *)block); @@ -1159,7 +1156,8 @@ xfs_dir2_sf_to_block( /* * Loop over existing entries, stuff them in. */ - if ((i = 0) == sfp->hdr.count) + i = 0; + if (!sfp->count) sfep = NULL; else sfep = xfs_dir2_sf_firstentry(sfp); @@ -1208,13 +1206,13 @@ xfs_dir2_sf_to_block( blp[2 + i].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp, (char *)dep - (char *)block)); offset = (int)((char *)(tagp + 1) - (char *)block); - if (++i == sfp->hdr.count) + if (++i == sfp->count) sfep = NULL; else sfep = xfs_dir2_sf_nextentry(sfp, sfep); } /* Done with the temporary buffer */ - kmem_free(buf); + kmem_free(sfp); /* * Sort the leaf entries by hash value. */ Index: xfs/fs/xfs/xfs_dir2_sf.c =================================================================== --- xfs.orig/fs/xfs/xfs_dir2_sf.c 2011-06-30 09:34:46.000000000 +0200 +++ xfs/fs/xfs/xfs_dir2_sf.c 2011-06-30 09:37:41.120068219 +0200 @@ -67,10 +67,10 @@ static void xfs_dir2_sf_toino8(xfs_da_ar */ static xfs_ino_t xfs_dir2_sf_get_ino( - struct xfs_dir2_sf *sfp, + struct xfs_dir2_sf_hdr *hdr, xfs_dir2_inou_t *from) { - if (sfp->hdr.i8count) + if (hdr->i8count) return XFS_GET_DIR_INO8(from->i8); else return XFS_GET_DIR_INO4(from->i4); @@ -78,11 +78,11 @@ xfs_dir2_sf_get_ino( static void xfs_dir2_sf_put_ino( - struct xfs_dir2_sf *sfp, + struct xfs_dir2_sf_hdr *hdr, xfs_dir2_inou_t *to, xfs_ino_t ino) { - if (sfp->hdr.i8count) + if (hdr->i8count) XFS_PUT_DIR_INO8(ino, to->i8); else XFS_PUT_DIR_INO4(ino, to->i4); @@ -90,17 +90,17 @@ xfs_dir2_sf_put_ino( xfs_ino_t xfs_dir2_sf_get_parent_ino( - struct xfs_dir2_sf *sfp) + struct xfs_dir2_sf_hdr *hdr) { - return xfs_dir2_sf_get_ino(sfp, &sfp->hdr.parent); + return xfs_dir2_sf_get_ino(hdr, &hdr->parent); } static void xfs_dir2_sf_put_parent_ino( - struct xfs_dir2_sf *sfp, + struct xfs_dir2_sf_hdr *hdr, xfs_ino_t ino) { - xfs_dir2_sf_put_ino(sfp, &sfp->hdr.parent, ino); + xfs_dir2_sf_put_ino(hdr, &hdr->parent, ino); } /* @@ -117,19 +117,19 @@ xfs_dir2_sfe_inop( xfs_ino_t xfs_dir2_sfe_get_ino( - struct xfs_dir2_sf *sfp, + struct xfs_dir2_sf_hdr *hdr, struct xfs_dir2_sf_entry *sfep) { - return xfs_dir2_sf_get_ino(sfp, xfs_dir2_sfe_inop(sfep)); + return xfs_dir2_sf_get_ino(hdr, xfs_dir2_sfe_inop(sfep)); } static void xfs_dir2_sfe_put_ino( - struct xfs_dir2_sf *sfp, + struct xfs_dir2_sf_hdr *hdr, struct xfs_dir2_sf_entry *sfep, xfs_ino_t ino) { - xfs_dir2_sf_put_ino(sfp, xfs_dir2_sfe_inop(sfep), ino); + xfs_dir2_sf_put_ino(hdr, xfs_dir2_sfe_inop(sfep), ino); } /* @@ -211,7 +211,7 @@ xfs_dir2_block_sfsize( */ sfhp->count = count; sfhp->i8count = i8count; - xfs_dir2_sf_put_parent_ino((xfs_dir2_sf_t *)sfhp, parent); + xfs_dir2_sf_put_parent_ino(sfhp, parent); return size; } @@ -237,7 +237,7 @@ xfs_dir2_block_to_sf( xfs_mount_t *mp; /* filesystem mount point */ char *ptr; /* current data pointer */ xfs_dir2_sf_entry_t *sfep; /* shortform entry */ - xfs_dir2_sf_t *sfp; /* shortform structure */ + xfs_dir2_sf_hdr_t *sfp; /* shortform structure */ trace_xfs_dir2_block_to_sf(args); @@ -270,7 +270,7 @@ xfs_dir2_block_to_sf( /* * Copy the header into the newly allocate local space. */ - sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; + sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; memcpy(sfp, sfhp, xfs_dir2_sf_hdr_size(sfhp->i8count)); dp->i_d.di_size = size; /* @@ -349,7 +349,7 @@ xfs_dir2_sf_addname( xfs_dir2_data_aoff_t offset = 0; /* offset for new entry */ int old_isize; /* di_size before adding name */ int pick; /* which algorithm to use */ - xfs_dir2_sf_t *sfp; /* shortform structure */ + xfs_dir2_sf_hdr_t *sfp; /* shortform structure */ xfs_dir2_sf_entry_t *sfep = NULL; /* shortform entry */ trace_xfs_dir2_sf_addname(args); @@ -366,8 +366,8 @@ xfs_dir2_sf_addname( } ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); ASSERT(dp->i_df.if_u1.if_data != NULL); - sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; - ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(sfp->hdr.i8count)); + sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; + ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(sfp->i8count)); /* * Compute entry (and change in) size. */ @@ -378,7 +378,7 @@ xfs_dir2_sf_addname( /* * Do we have to change to 8 byte inodes? */ - if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && sfp->hdr.i8count == 0) { + if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && sfp->i8count == 0) { /* * Yes, adjust the entry size and the total size. */ @@ -386,7 +386,7 @@ xfs_dir2_sf_addname( (uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t); incr_isize += - (sfp->hdr.count + 2) * + (sfp->count + 2) * ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t)); objchange = 1; @@ -456,11 +456,11 @@ xfs_dir2_sf_addname_easy( { int byteoff; /* byte offset in sf dir */ xfs_inode_t *dp; /* incore directory inode */ - xfs_dir2_sf_t *sfp; /* shortform structure */ + xfs_dir2_sf_hdr_t *sfp; /* shortform structure */ dp = args->dp; - sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; + sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; byteoff = (int)((char *)sfep - (char *)sfp); /* * Grow the in-inode space. @@ -470,7 +470,7 @@ xfs_dir2_sf_addname_easy( /* * Need to set up again due to realloc of the inode data. */ - sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; + sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; sfep = (xfs_dir2_sf_entry_t *)((char *)sfp + byteoff); /* * Fill in the new entry. @@ -482,10 +482,10 @@ xfs_dir2_sf_addname_easy( /* * Update the header and inode. */ - sfp->hdr.count++; + sfp->count++; #if XFS_BIG_INUMS if (args->inumber > XFS_DIR2_MAX_SHORT_INUM) - sfp->hdr.i8count++; + sfp->i8count++; #endif dp->i_d.di_size = new_isize; xfs_dir2_sf_check(args); @@ -515,19 +515,19 @@ xfs_dir2_sf_addname_hard( xfs_dir2_data_aoff_t offset; /* current offset value */ int old_isize; /* previous di_size */ xfs_dir2_sf_entry_t *oldsfep; /* entry in original dir */ - xfs_dir2_sf_t *oldsfp; /* original shortform dir */ + xfs_dir2_sf_hdr_t *oldsfp; /* original shortform dir */ xfs_dir2_sf_entry_t *sfep; /* entry in new dir */ - xfs_dir2_sf_t *sfp; /* new shortform dir */ + xfs_dir2_sf_hdr_t *sfp; /* new shortform dir */ /* * Copy the old directory to the stack buffer. */ dp = args->dp; - sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; + sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; old_isize = (int)dp->i_d.di_size; buf = kmem_alloc(old_isize, KM_SLEEP); - oldsfp = (xfs_dir2_sf_t *)buf; + oldsfp = (xfs_dir2_sf_hdr_t *)buf; memcpy(oldsfp, sfp, old_isize); /* * Loop over the old directory finding the place we're going @@ -556,7 +556,7 @@ xfs_dir2_sf_addname_hard( /* * Reset the pointer since the buffer was reallocated. */ - sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; + sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; /* * Copy the first part of the directory, including the header. */ @@ -570,10 +570,10 @@ xfs_dir2_sf_addname_hard( xfs_dir2_sf_put_offset(sfep, offset); memcpy(sfep->name, args->name, sfep->namelen); xfs_dir2_sfe_put_ino(sfp, sfep, args->inumber); - sfp->hdr.count++; + sfp->count++; #if XFS_BIG_INUMS if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && !objchange) - sfp->hdr.i8count++; + sfp->i8count++; #endif /* * If there's more left to copy, do that. @@ -607,14 +607,14 @@ xfs_dir2_sf_addname_pick( xfs_mount_t *mp; /* filesystem mount point */ xfs_dir2_data_aoff_t offset; /* data block offset */ xfs_dir2_sf_entry_t *sfep; /* shortform entry */ - xfs_dir2_sf_t *sfp; /* shortform structure */ + xfs_dir2_sf_hdr_t *sfp; /* shortform structure */ int size; /* entry's data size */ int used; /* data bytes used */ dp = args->dp; mp = dp->i_mount; - sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; + sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; size = xfs_dir2_data_entsize(args->namelen); offset = XFS_DIR2_DATA_FIRST_OFFSET; sfep = xfs_dir2_sf_firstentry(sfp); @@ -624,7 +624,7 @@ xfs_dir2_sf_addname_pick( * Keep track of data offset and whether we've seen a place * to insert the new entry. */ - for (i = 0; i < sfp->hdr.count; i++) { + for (i = 0; i < sfp->count; i++) { if (!holefit) holefit = offset + size <= xfs_dir2_sf_get_offset(sfep); offset = xfs_dir2_sf_get_offset(sfep) + @@ -636,7 +636,7 @@ xfs_dir2_sf_addname_pick( * was a data block (block form directory). */ used = offset + - (sfp->hdr.count + 3) * (uint)sizeof(xfs_dir2_leaf_entry_t) + + (sfp->count + 3) * (uint)sizeof(xfs_dir2_leaf_entry_t) + (uint)sizeof(xfs_dir2_block_tail_t); /* * If it won't fit in a block form then we can't insert it, @@ -682,17 +682,17 @@ xfs_dir2_sf_check( xfs_ino_t ino; /* entry inode number */ int offset; /* data offset */ xfs_dir2_sf_entry_t *sfep; /* shortform dir entry */ - xfs_dir2_sf_t *sfp; /* shortform structure */ + xfs_dir2_sf_hdr_t *sfp; /* shortform structure */ dp = args->dp; - sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; + sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; offset = XFS_DIR2_DATA_FIRST_OFFSET; ino = xfs_dir2_sf_get_parent_ino(sfp); i8count = ino > XFS_DIR2_MAX_SHORT_INUM; for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); - i < sfp->hdr.count; + i < sfp->count; i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep)) { ASSERT(xfs_dir2_sf_get_offset(sfep) >= offset); ino = xfs_dir2_sfe_get_ino(sfp, sfep); @@ -701,11 +701,11 @@ xfs_dir2_sf_check( xfs_dir2_sf_get_offset(sfep) + xfs_dir2_data_entsize(sfep->namelen); } - ASSERT(i8count == sfp->hdr.i8count); + ASSERT(i8count == sfp->i8count); ASSERT(XFS_BIG_INUMS || i8count == 0); ASSERT((char *)sfep - (char *)sfp == dp->i_d.di_size); ASSERT(offset + - (sfp->hdr.count + 2) * (uint)sizeof(xfs_dir2_leaf_entry_t) + + (sfp->count + 2) * (uint)sizeof(xfs_dir2_leaf_entry_t) + (uint)sizeof(xfs_dir2_block_tail_t) <= dp->i_mount->m_dirblksize); } @@ -721,7 +721,7 @@ xfs_dir2_sf_create( { xfs_inode_t *dp; /* incore directory inode */ int i8count; /* parent inode is an 8-byte number */ - xfs_dir2_sf_t *sfp; /* shortform structure */ + xfs_dir2_sf_hdr_t *sfp; /* shortform structure */ int size; /* directory size */ trace_xfs_dir2_sf_create(args); @@ -751,13 +751,13 @@ xfs_dir2_sf_create( /* * Fill in the header, */ - sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; - sfp->hdr.i8count = i8count; + sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; + sfp->i8count = i8count; /* * Now can put in the inode number, since i8count is set. */ xfs_dir2_sf_put_parent_ino(sfp, pino); - sfp->hdr.count = 0; + sfp->count = 0; dp->i_d.di_size = size; xfs_dir2_sf_check(args); xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE | XFS_ILOG_DDATA); @@ -775,7 +775,7 @@ xfs_dir2_sf_getdents( xfs_mount_t *mp; /* filesystem mount point */ xfs_dir2_dataptr_t off; /* current entry's offset */ xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */ - xfs_dir2_sf_t *sfp; /* shortform structure */ + xfs_dir2_sf_hdr_t *sfp; /* shortform structure */ xfs_dir2_dataptr_t dot_offset; xfs_dir2_dataptr_t dotdot_offset; xfs_ino_t ino; @@ -794,9 +794,9 @@ xfs_dir2_sf_getdents( ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); ASSERT(dp->i_df.if_u1.if_data != NULL); - sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; + sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; - ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(sfp->hdr.i8count)); + ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(sfp->i8count)); /* * If the block number in the offset is out of range, we're done. @@ -840,7 +840,7 @@ xfs_dir2_sf_getdents( * Loop while there are more entries and put'ing works. */ sfep = xfs_dir2_sf_firstentry(sfp); - for (i = 0; i < sfp->hdr.count; i++) { + for (i = 0; i < sfp->count; i++) { off = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, xfs_dir2_sf_get_offset(sfep)); @@ -875,7 +875,7 @@ xfs_dir2_sf_lookup( int i; /* entry index */ int error; xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */ - xfs_dir2_sf_t *sfp; /* shortform structure */ + xfs_dir2_sf_hdr_t *sfp; /* shortform structure */ enum xfs_dacmp cmp; /* comparison result */ xfs_dir2_sf_entry_t *ci_sfep; /* case-insens. entry */ @@ -894,8 +894,8 @@ xfs_dir2_sf_lookup( } ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); ASSERT(dp->i_df.if_u1.if_data != NULL); - sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; - ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(sfp->hdr.i8count)); + sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; + ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(sfp->i8count)); /* * Special case for . */ @@ -917,7 +917,7 @@ xfs_dir2_sf_lookup( * Loop over all the entries trying to match ours. */ ci_sfep = NULL; - for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->hdr.count; + for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->count; i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep)) { /* * Compare name and if it's an exact match, return the inode @@ -960,7 +960,7 @@ xfs_dir2_sf_removename( int newsize; /* new inode size */ int oldsize; /* old inode size */ xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */ - xfs_dir2_sf_t *sfp; /* shortform structure */ + xfs_dir2_sf_hdr_t *sfp; /* shortform structure */ trace_xfs_dir2_sf_removename(args); @@ -977,13 +977,13 @@ xfs_dir2_sf_removename( } ASSERT(dp->i_df.if_bytes == oldsize); ASSERT(dp->i_df.if_u1.if_data != NULL); - sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; - ASSERT(oldsize >= xfs_dir2_sf_hdr_size(sfp->hdr.i8count)); + sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; + ASSERT(oldsize >= xfs_dir2_sf_hdr_size(sfp->i8count)); /* * Loop over the old directory entries. * Find the one we're deleting. */ - for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->hdr.count; + for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); i < sfp->count; i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep)) { if (xfs_da_compname(args, sfep->name, sfep->namelen) == XFS_CMP_EXACT) { @@ -995,7 +995,7 @@ xfs_dir2_sf_removename( /* * Didn't find it. */ - if (i == sfp->hdr.count) + if (i == sfp->count) return XFS_ERROR(ENOENT); /* * Calculate sizes. @@ -1012,22 +1012,22 @@ xfs_dir2_sf_removename( /* * Fix up the header and file size. */ - sfp->hdr.count--; + sfp->count--; dp->i_d.di_size = newsize; /* * Reallocate, making it smaller. */ xfs_idata_realloc(dp, newsize - oldsize, XFS_DATA_FORK); - sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; + sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; #if XFS_BIG_INUMS /* * Are we changing inode number size? */ if (args->inumber > XFS_DIR2_MAX_SHORT_INUM) { - if (sfp->hdr.i8count == 1) + if (sfp->i8count == 1) xfs_dir2_sf_toino4(args); else - sfp->hdr.i8count--; + sfp->i8count--; } #endif xfs_dir2_sf_check(args); @@ -1051,7 +1051,7 @@ xfs_dir2_sf_replace( int i8elevated; /* sf_toino8 set i8count=1 */ #endif xfs_dir2_sf_entry_t *sfep; /* shortform directory entry */ - xfs_dir2_sf_t *sfp; /* shortform structure */ + xfs_dir2_sf_hdr_t *sfp; /* shortform structure */ trace_xfs_dir2_sf_replace(args); @@ -1067,19 +1067,19 @@ xfs_dir2_sf_replace( } ASSERT(dp->i_df.if_bytes == dp->i_d.di_size); ASSERT(dp->i_df.if_u1.if_data != NULL); - sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; - ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(sfp->hdr.i8count)); + sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; + ASSERT(dp->i_d.di_size >= xfs_dir2_sf_hdr_size(sfp->i8count)); #if XFS_BIG_INUMS /* * New inode number is large, and need to convert to 8-byte inodes. */ - if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && sfp->hdr.i8count == 0) { + if (args->inumber > XFS_DIR2_MAX_SHORT_INUM && sfp->i8count == 0) { int error; /* error return value */ int newsize; /* new inode size */ newsize = dp->i_df.if_bytes + - (sfp->hdr.count + 1) * + (sfp->count + 1) * ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t)); /* @@ -1097,7 +1097,7 @@ xfs_dir2_sf_replace( */ xfs_dir2_sf_toino8(args); i8elevated = 1; - sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; + sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; } else i8elevated = 0; #endif @@ -1118,7 +1118,7 @@ xfs_dir2_sf_replace( */ else { for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp); - i < sfp->hdr.count; + i < sfp->count; i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep)) { if (xfs_da_compname(args, sfep->name, sfep->namelen) == XFS_CMP_EXACT) { @@ -1133,7 +1133,7 @@ xfs_dir2_sf_replace( /* * Didn't find it. */ - if (i == sfp->hdr.count) { + if (i == sfp->count) { ASSERT(args->op_flags & XFS_DA_OP_OKNOENT); #if XFS_BIG_INUMS if (i8elevated) @@ -1151,10 +1151,10 @@ xfs_dir2_sf_replace( /* * And the old count was one, so need to convert to small. */ - if (sfp->hdr.i8count == 1) + if (sfp->i8count == 1) xfs_dir2_sf_toino4(args); else - sfp->hdr.i8count--; + sfp->i8count--; } /* * See if the old number was small, the new number is large. @@ -1165,9 +1165,9 @@ xfs_dir2_sf_replace( * add to the i8count unless we just converted to 8-byte * inodes (which does an implied i8count = 1) */ - ASSERT(sfp->hdr.i8count != 0); + ASSERT(sfp->i8count != 0); if (!i8elevated) - sfp->hdr.i8count++; + sfp->i8count++; } #endif xfs_dir2_sf_check(args); @@ -1189,10 +1189,10 @@ xfs_dir2_sf_toino4( int i; /* entry index */ int newsize; /* new inode size */ xfs_dir2_sf_entry_t *oldsfep; /* old sf entry */ - xfs_dir2_sf_t *oldsfp; /* old sf directory */ + xfs_dir2_sf_hdr_t *oldsfp; /* old sf directory */ int oldsize; /* old inode size */ xfs_dir2_sf_entry_t *sfep; /* new sf entry */ - xfs_dir2_sf_t *sfp; /* new sf directory */ + xfs_dir2_sf_hdr_t *sfp; /* new sf directory */ trace_xfs_dir2_sf_toino4(args); @@ -1205,35 +1205,35 @@ xfs_dir2_sf_toino4( */ oldsize = dp->i_df.if_bytes; buf = kmem_alloc(oldsize, KM_SLEEP); - oldsfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; - ASSERT(oldsfp->hdr.i8count == 1); + oldsfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; + ASSERT(oldsfp->i8count == 1); memcpy(buf, oldsfp, oldsize); /* * Compute the new inode size. */ newsize = oldsize - - (oldsfp->hdr.count + 1) * + (oldsfp->count + 1) * ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t)); xfs_idata_realloc(dp, -oldsize, XFS_DATA_FORK); xfs_idata_realloc(dp, newsize, XFS_DATA_FORK); /* * Reset our pointers, the data has moved. */ - oldsfp = (xfs_dir2_sf_t *)buf; - sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; + oldsfp = (xfs_dir2_sf_hdr_t *)buf; + sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; /* * Fill in the new header. */ - sfp->hdr.count = oldsfp->hdr.count; - sfp->hdr.i8count = 0; + sfp->count = oldsfp->count; + sfp->i8count = 0; xfs_dir2_sf_put_parent_ino(sfp, xfs_dir2_sf_get_parent_ino(oldsfp)); /* * Copy the entries field by field. */ for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp), oldsfep = xfs_dir2_sf_firstentry(oldsfp); - i < sfp->hdr.count; + i < sfp->count; i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep), oldsfep = xfs_dir2_sf_nextentry(oldsfp, oldsfep)) { sfep->namelen = oldsfep->namelen; @@ -1264,10 +1264,10 @@ xfs_dir2_sf_toino8( int i; /* entry index */ int newsize; /* new inode size */ xfs_dir2_sf_entry_t *oldsfep; /* old sf entry */ - xfs_dir2_sf_t *oldsfp; /* old sf directory */ + xfs_dir2_sf_hdr_t *oldsfp; /* old sf directory */ int oldsize; /* old inode size */ xfs_dir2_sf_entry_t *sfep; /* new sf entry */ - xfs_dir2_sf_t *sfp; /* new sf directory */ + xfs_dir2_sf_hdr_t *sfp; /* new sf directory */ trace_xfs_dir2_sf_toino8(args); @@ -1280,35 +1280,35 @@ xfs_dir2_sf_toino8( */ oldsize = dp->i_df.if_bytes; buf = kmem_alloc(oldsize, KM_SLEEP); - oldsfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; - ASSERT(oldsfp->hdr.i8count == 0); + oldsfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; + ASSERT(oldsfp->i8count == 0); memcpy(buf, oldsfp, oldsize); /* * Compute the new inode size. */ newsize = oldsize + - (oldsfp->hdr.count + 1) * + (oldsfp->count + 1) * ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t)); xfs_idata_realloc(dp, -oldsize, XFS_DATA_FORK); xfs_idata_realloc(dp, newsize, XFS_DATA_FORK); /* * Reset our pointers, the data has moved. */ - oldsfp = (xfs_dir2_sf_t *)buf; - sfp = (xfs_dir2_sf_t *)dp->i_df.if_u1.if_data; + oldsfp = (xfs_dir2_sf_hdr_t *)buf; + sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; /* * Fill in the new header. */ - sfp->hdr.count = oldsfp->hdr.count; - sfp->hdr.i8count = 1; + sfp->count = oldsfp->count; + sfp->i8count = 1; xfs_dir2_sf_put_parent_ino(sfp, xfs_dir2_sf_get_parent_ino(oldsfp)); /* * Copy the entries field by field. */ for (i = 0, sfep = xfs_dir2_sf_firstentry(sfp), oldsfep = xfs_dir2_sf_firstentry(oldsfp); - i < sfp->hdr.count; + i < sfp->count; i++, sfep = xfs_dir2_sf_nextentry(sfp, sfep), oldsfep = xfs_dir2_sf_nextentry(oldsfp, oldsfep)) { sfep->namelen = oldsfep->namelen; Index: xfs/fs/xfs/xfs_dir2_sf.h =================================================================== --- xfs.orig/fs/xfs/xfs_dir2_sf.h 2011-06-30 09:32:00.390072451 +0200 +++ xfs/fs/xfs/xfs_dir2_sf.h 2011-06-30 09:35:55.813402859 +0200 @@ -21,8 +21,12 @@ /* * Directory layout when stored internal to an inode. * - * Small directories are packed as tightly as possible so as to - * fit into the literal area of the inode. + * Small directories are packed as tightly as possible so as to fit into the + * literal area of the inode. They consist of a single xfs_dir2_sf_hdr header + * followed by zero or more xfs_dir2_sf_entry structures. Due the different + * inode number storage sized and the variable length name filed in + * the xfs_dir2_sf_entry all these structure are variable length, and the + * accessors in this file need to be used to iterate over them. */ struct uio; @@ -61,9 +65,9 @@ typedef struct { __uint8_t i[2]; } __arc * The parent directory has a dedicated field, and the self-pointer must * be calculated on the fly. * - * Entries are packed toward the top as tightly as possible. The header - * and the elements must be memcpy'd out into a work area to get correct - * alignment for the inode number fields. + * Entries are packed toward the top as tightly as possible, and thus may + * be misaligned. Care needs to be taken to access them through special + * helpers or copy them into aligned variables first. */ typedef struct xfs_dir2_sf_hdr { __uint8_t count; /* count of entries */ @@ -78,11 +82,6 @@ typedef struct xfs_dir2_sf_entry { xfs_dir2_inou_t inumber; /* inode number, var. offset */ } __arch_pack xfs_dir2_sf_entry_t; -typedef struct xfs_dir2_sf { - xfs_dir2_sf_hdr_t hdr; /* shortform header */ - xfs_dir2_sf_entry_t list[1]; /* shortform entries */ -} xfs_dir2_sf_t; - static inline int xfs_dir2_sf_hdr_size(int i8count) { return ((uint)sizeof(xfs_dir2_sf_hdr_t) - \ @@ -102,29 +101,29 @@ xfs_dir2_sf_put_offset(xfs_dir2_sf_entry INT_SET_UNALIGNED_16_BE(&(sfep)->offset.i, off); } -static inline int xfs_dir2_sf_entsize_byname(xfs_dir2_sf_t *sfp, int len) +static inline int xfs_dir2_sf_entsize_byname(xfs_dir2_sf_hdr_t *sfp, int len) { return ((uint)sizeof(xfs_dir2_sf_entry_t) - 1 + (len) - \ - ((sfp)->hdr.i8count == 0) * \ + ((sfp)->i8count == 0) * \ ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t))); } static inline int -xfs_dir2_sf_entsize_byentry(xfs_dir2_sf_t *sfp, xfs_dir2_sf_entry_t *sfep) +xfs_dir2_sf_entsize_byentry(xfs_dir2_sf_hdr_t *sfp, xfs_dir2_sf_entry_t *sfep) { return ((uint)sizeof(xfs_dir2_sf_entry_t) - 1 + (sfep)->namelen - \ - ((sfp)->hdr.i8count == 0) * \ + ((sfp)->i8count == 0) * \ ((uint)sizeof(xfs_dir2_ino8_t) - (uint)sizeof(xfs_dir2_ino4_t))); } -static inline xfs_dir2_sf_entry_t *xfs_dir2_sf_firstentry(xfs_dir2_sf_t *sfp) +static inline xfs_dir2_sf_entry_t *xfs_dir2_sf_firstentry(xfs_dir2_sf_hdr_t *sfp) { return ((xfs_dir2_sf_entry_t *) \ - ((char *)(sfp) + xfs_dir2_sf_hdr_size(sfp->hdr.i8count))); + ((char *)(sfp) + xfs_dir2_sf_hdr_size(sfp->i8count))); } static inline xfs_dir2_sf_entry_t * -xfs_dir2_sf_nextentry(xfs_dir2_sf_t *sfp, xfs_dir2_sf_entry_t *sfep) +xfs_dir2_sf_nextentry(xfs_dir2_sf_hdr_t *sfp, xfs_dir2_sf_entry_t *sfep) { return ((xfs_dir2_sf_entry_t *) \ ((char *)(sfep) + xfs_dir2_sf_entsize_byentry(sfp,sfep))); @@ -133,8 +132,8 @@ xfs_dir2_sf_nextentry(xfs_dir2_sf_t *sfp /* * Functions. */ -extern xfs_ino_t xfs_dir2_sf_get_parent_ino(struct xfs_dir2_sf *sfp); -extern xfs_ino_t xfs_dir2_sfe_get_ino(struct xfs_dir2_sf *sfp, +extern xfs_ino_t xfs_dir2_sf_get_parent_ino(struct xfs_dir2_sf_hdr *sfp); +extern xfs_ino_t xfs_dir2_sfe_get_ino(struct xfs_dir2_sf_hdr *sfp, struct xfs_dir2_sf_entry *sfep); extern int xfs_dir2_block_sfsize(struct xfs_inode *dp, struct xfs_dir2_block *block, From BATV+1dd5f1c206cd6a728cfd+2868+infradead.org+hch@bombadil.srs.infradead.org Fri Jul 1 04:46:11 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-4.9 required=5.0 tests=BAYES_00,LOCAL_GNU_PATCH autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p619k9t0056154 for ; Fri, 1 Jul 2011 04:46:09 -0500 X-ASG-Debug-ID: 1309513567-6d1800c10000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from bombadil.infradead.org (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id CAF3F1EE3239 for ; Fri, 1 Jul 2011 02:46:07 -0700 (PDT) Received: from bombadil.infradead.org (173-166-109-252-newengland.hfc.comcastbusiness.net [173.166.109.252]) by cuda.sgi.com with ESMTP id oFIQyawyde3wJ21C for ; Fri, 01 Jul 2011 02:46:07 -0700 (PDT) Received: from hch by bombadil.infradead.org with local (Exim 4.76 #1 (Red Hat Linux)) id 1QcaIZ-00021w-6F for xfs@oss.sgi.com; Fri, 01 Jul 2011 09:46:07 +0000 Message-Id: <20110701094607.155544131@bombadil.infradead.org> User-Agent: quilt/0.48-1 Date: Fri, 01 Jul 2011 05:43:45 -0400 From: Christoph Hellwig To: xfs@oss.sgi.com X-ASG-Orig-Subj: [PATCH 24/27] xfs: clean up buffer locking helpers Subject: [PATCH 24/27] xfs: clean up buffer locking helpers References: <20110701094321.936534538@bombadil.infradead.org> Content-Disposition: inline; filename=xfs-cleanup-buffer-locking X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: 173-166-109-252-newengland.hfc.comcastbusiness.net[173.166.109.252] X-Barracuda-Start-Time: 1309513567 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -1.42 X-Barracuda-Spam-Status: No, SCORE=-1.42 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=BSF_SC5_MJ1963, RDNS_DYNAMIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67645 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_DYNAMIC Delivered to trusted network by host with dynamic-looking rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean Rename xfs_buf_cond_lock and reverse it's return value to fit most other trylock operations in the Kernel and XFS (with the exception of down_trylock, after which xfs_buf_cond_lock was modelled), and replace xfs_buf_lock_val with an xfs_buf_islocked for use in asserts, or and opencoded variant in tracing. remove the XFS_BUF_* wrappers for all the locking helpers. Signed-off-by: Christoph Hellwig Index: xfs/fs/xfs/linux-2.6/xfs_buf.c =================================================================== --- xfs.orig/fs/xfs/linux-2.6/xfs_buf.c 2011-06-29 11:26:14.000000000 +0200 +++ xfs/fs/xfs/linux-2.6/xfs_buf.c 2011-06-29 13:57:15.596795734 +0200 @@ -499,16 +499,14 @@ found: spin_unlock(&pag->pag_buf_lock); xfs_perag_put(pag); - if (xfs_buf_cond_lock(bp)) { - /* failed, so wait for the lock if requested. */ - if (!(flags & XBF_TRYLOCK)) { - xfs_buf_lock(bp); - XFS_STATS_INC(xb_get_locked_waited); - } else { + if (!xfs_buf_trylock(bp)) { + if (flags & XBF_TRYLOCK) { xfs_buf_rele(bp); XFS_STATS_INC(xb_busy_locked); return NULL; } + xfs_buf_lock(bp); + XFS_STATS_INC(xb_get_locked_waited); } /* @@ -896,8 +894,8 @@ xfs_buf_rele( * to push on stale inode buffers. */ int -xfs_buf_cond_lock( - xfs_buf_t *bp) +xfs_buf_trylock( + struct xfs_buf *bp) { int locked; @@ -907,15 +905,8 @@ xfs_buf_cond_lock( else if (atomic_read(&bp->b_pin_count) && (bp->b_flags & XBF_STALE)) xfs_log_force(bp->b_target->bt_mount, 0); - trace_xfs_buf_cond_lock(bp, _RET_IP_); - return locked ? 0 : -EBUSY; -} - -int -xfs_buf_lock_value( - xfs_buf_t *bp) -{ - return bp->b_sema.count; + trace_xfs_buf_trylock(bp, _RET_IP_); + return locked; } /* @@ -929,7 +920,7 @@ xfs_buf_lock_value( */ void xfs_buf_lock( - xfs_buf_t *bp) + struct xfs_buf *bp) { trace_xfs_buf_lock(bp, _RET_IP_); @@ -950,7 +941,7 @@ xfs_buf_lock( */ void xfs_buf_unlock( - xfs_buf_t *bp) + struct xfs_buf *bp) { if ((bp->b_flags & (XBF_DELWRI|_XBF_DELWRI_Q)) == XBF_DELWRI) { atomic_inc(&bp->b_hold); @@ -1694,7 +1685,7 @@ xfs_buf_delwri_split( list_for_each_entry_safe(bp, n, dwq, b_list) { ASSERT(bp->b_flags & XBF_DELWRI); - if (!XFS_BUF_ISPINNED(bp) && !xfs_buf_cond_lock(bp)) { + if (!XFS_BUF_ISPINNED(bp) && xfs_buf_trylock(bp)) { if (!force && time_before(jiffies, bp->b_queuetime + age)) { xfs_buf_unlock(bp); Index: xfs/fs/xfs/linux-2.6/xfs_buf.h =================================================================== --- xfs.orig/fs/xfs/linux-2.6/xfs_buf.h 2011-06-29 13:50:40.000000000 +0200 +++ xfs/fs/xfs/linux-2.6/xfs_buf.h 2011-06-29 13:54:35.250997736 +0200 @@ -187,10 +187,11 @@ extern void xfs_buf_free(xfs_buf_t *); extern void xfs_buf_rele(xfs_buf_t *); /* Locking and Unlocking Buffers */ -extern int xfs_buf_cond_lock(xfs_buf_t *); -extern int xfs_buf_lock_value(xfs_buf_t *); +extern int xfs_buf_trylock(xfs_buf_t *); extern void xfs_buf_lock(xfs_buf_t *); extern void xfs_buf_unlock(xfs_buf_t *); +#define xfs_buf_islocked(bp) \ + ((bp)->b_sema.count <= 0) /* Buffer Read and Write Routines */ extern int xfs_bwrite(struct xfs_mount *mp, struct xfs_buf *bp); @@ -308,10 +309,6 @@ xfs_buf_set_ref( #define XFS_BUF_ISPINNED(bp) atomic_read(&((bp)->b_pin_count)) -#define XFS_BUF_VALUSEMA(bp) xfs_buf_lock_value(bp) -#define XFS_BUF_CPSEMA(bp) (xfs_buf_cond_lock(bp) == 0) -#define XFS_BUF_VSEMA(bp) xfs_buf_unlock(bp) -#define XFS_BUF_PSEMA(bp,x) xfs_buf_lock(bp) #define XFS_BUF_FINISH_IOWAIT(bp) complete(&bp->b_iowait); #define XFS_BUF_SET_TARGET(bp, target) ((bp)->b_target = (target)) Index: xfs/fs/xfs/linux-2.6/xfs_trace.h =================================================================== --- xfs.orig/fs/xfs/linux-2.6/xfs_trace.h 2011-06-29 11:35:45.000000000 +0200 +++ xfs/fs/xfs/linux-2.6/xfs_trace.h 2011-06-29 13:54:32.974343403 +0200 @@ -293,7 +293,7 @@ DECLARE_EVENT_CLASS(xfs_buf_class, __entry->buffer_length = bp->b_buffer_length; __entry->hold = atomic_read(&bp->b_hold); __entry->pincount = atomic_read(&bp->b_pin_count); - __entry->lockval = xfs_buf_lock_value(bp); + __entry->lockval = bp->b_sema.count; __entry->flags = bp->b_flags; __entry->caller_ip = caller_ip; ), @@ -323,7 +323,7 @@ DEFINE_BUF_EVENT(xfs_buf_bawrite); DEFINE_BUF_EVENT(xfs_buf_bdwrite); DEFINE_BUF_EVENT(xfs_buf_lock); DEFINE_BUF_EVENT(xfs_buf_lock_done); -DEFINE_BUF_EVENT(xfs_buf_cond_lock); +DEFINE_BUF_EVENT(xfs_buf_trylock); DEFINE_BUF_EVENT(xfs_buf_unlock); DEFINE_BUF_EVENT(xfs_buf_iowait); DEFINE_BUF_EVENT(xfs_buf_iowait_done); @@ -366,7 +366,7 @@ DECLARE_EVENT_CLASS(xfs_buf_flags_class, __entry->flags = flags; __entry->hold = atomic_read(&bp->b_hold); __entry->pincount = atomic_read(&bp->b_pin_count); - __entry->lockval = xfs_buf_lock_value(bp); + __entry->lockval = bp->b_sema.count; __entry->caller_ip = caller_ip; ), TP_printk("dev %d:%d bno 0x%llx len 0x%zx hold %d pincount %d " @@ -409,7 +409,7 @@ TRACE_EVENT(xfs_buf_ioerror, __entry->buffer_length = bp->b_buffer_length; __entry->hold = atomic_read(&bp->b_hold); __entry->pincount = atomic_read(&bp->b_pin_count); - __entry->lockval = xfs_buf_lock_value(bp); + __entry->lockval = bp->b_sema.count; __entry->error = error; __entry->flags = bp->b_flags; __entry->caller_ip = caller_ip; @@ -454,7 +454,7 @@ DECLARE_EVENT_CLASS(xfs_buf_item_class, __entry->buf_flags = bip->bli_buf->b_flags; __entry->buf_hold = atomic_read(&bip->bli_buf->b_hold); __entry->buf_pincount = atomic_read(&bip->bli_buf->b_pin_count); - __entry->buf_lockval = xfs_buf_lock_value(bip->bli_buf); + __entry->buf_lockval = bip->bli_buf->b_sema.count; __entry->li_desc = bip->bli_item.li_desc; __entry->li_flags = bip->bli_item.li_flags; ), Index: xfs/fs/xfs/quota/xfs_dquot.c =================================================================== --- xfs.orig/fs/xfs/quota/xfs_dquot.c 2011-05-11 08:41:56.000000000 +0200 +++ xfs/fs/xfs/quota/xfs_dquot.c 2011-06-29 13:53:07.801471491 +0200 @@ -318,7 +318,7 @@ xfs_qm_init_dquot_blk( ASSERT(tp); ASSERT(XFS_BUF_ISBUSY(bp)); - ASSERT(XFS_BUF_VALUSEMA(bp) <= 0); + ASSERT(xfs_buf_islocked(bp)); d = (xfs_dqblk_t *)XFS_BUF_PTR(bp); @@ -534,7 +534,7 @@ xfs_qm_dqtobp( } ASSERT(XFS_BUF_ISBUSY(bp)); - ASSERT(XFS_BUF_VALUSEMA(bp) <= 0); + ASSERT(xfs_buf_islocked(bp)); /* * calculate the location of the dquot inside the buffer. @@ -622,7 +622,7 @@ xfs_qm_dqread( * brelse it because we have the changes incore. */ ASSERT(XFS_BUF_ISBUSY(bp)); - ASSERT(XFS_BUF_VALUSEMA(bp) <= 0); + ASSERT(xfs_buf_islocked(bp)); xfs_trans_brelse(tp, bp); return (error); Index: xfs/fs/xfs/xfs_buf_item.c =================================================================== --- xfs.orig/fs/xfs/xfs_buf_item.c 2011-04-22 06:21:45.000000000 +0200 +++ xfs/fs/xfs/xfs_buf_item.c 2011-06-29 13:53:20.938066990 +0200 @@ -420,7 +420,7 @@ xfs_buf_item_unpin( if (freed && stale) { ASSERT(bip->bli_flags & XFS_BLI_STALE); - ASSERT(XFS_BUF_VALUSEMA(bp) <= 0); + ASSERT(xfs_buf_islocked(bp)); ASSERT(!(XFS_BUF_ISDELAYWRITE(bp))); ASSERT(XFS_BUF_ISSTALE(bp)); ASSERT(bip->bli_format.blf_flags & XFS_BLF_CANCEL); @@ -483,7 +483,7 @@ xfs_buf_item_trylock( if (XFS_BUF_ISPINNED(bp)) return XFS_ITEM_PINNED; - if (!XFS_BUF_CPSEMA(bp)) + if (!xfs_buf_trylock(bp)) return XFS_ITEM_LOCKED; /* take a reference to the buffer. */ @@ -905,7 +905,7 @@ xfs_buf_attach_iodone( xfs_log_item_t *head_lip; ASSERT(XFS_BUF_ISBUSY(bp)); - ASSERT(XFS_BUF_VALUSEMA(bp) <= 0); + ASSERT(xfs_buf_islocked(bp)); lip->li_cb = cb; if (XFS_BUF_FSPRIVATE(bp, void *) != NULL) { Index: xfs/fs/xfs/xfs_log.c =================================================================== --- xfs.orig/fs/xfs/xfs_log.c 2011-06-17 14:07:57.000000000 +0200 +++ xfs/fs/xfs/xfs_log.c 2011-06-29 13:53:33.954663139 +0200 @@ -1059,7 +1059,7 @@ xlog_alloc_log(xfs_mount_t *mp, XFS_BUF_SET_IODONE_FUNC(bp, xlog_iodone); XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)1); ASSERT(XFS_BUF_ISBUSY(bp)); - ASSERT(XFS_BUF_VALUSEMA(bp) <= 0); + ASSERT(xfs_buf_islocked(bp)); log->l_xbuf = bp; spin_lock_init(&log->l_icloglock); @@ -1090,7 +1090,7 @@ xlog_alloc_log(xfs_mount_t *mp, log->l_iclog_size, 0); if (!bp) goto out_free_iclog; - if (!XFS_BUF_CPSEMA(bp)) + if (!xfs_buf_trylock(bp)) ASSERT(0); XFS_BUF_SET_IODONE_FUNC(bp, xlog_iodone); XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)1); @@ -1118,7 +1118,7 @@ xlog_alloc_log(xfs_mount_t *mp, iclog->ic_datap = (char *)iclog->ic_data + log->l_iclog_hsize; ASSERT(XFS_BUF_ISBUSY(iclog->ic_bp)); - ASSERT(XFS_BUF_VALUSEMA(iclog->ic_bp) <= 0); + ASSERT(xfs_buf_islocked(iclog->ic_bp)); init_waitqueue_head(&iclog->ic_force_wait); init_waitqueue_head(&iclog->ic_write_wait); Index: xfs/fs/xfs/xfs_log_recover.c =================================================================== --- xfs.orig/fs/xfs/xfs_log_recover.c 2011-05-20 15:25:52.000000000 +0200 +++ xfs/fs/xfs/xfs_log_recover.c 2011-06-29 13:51:20.425386530 +0200 @@ -264,7 +264,7 @@ xlog_bwrite( XFS_BUF_ZEROFLAGS(bp); XFS_BUF_BUSY(bp); XFS_BUF_HOLD(bp); - XFS_BUF_PSEMA(bp, PRIBIO); + xfs_buf_lock(bp); XFS_BUF_SET_COUNT(bp, BBTOB(nbblks)); XFS_BUF_SET_TARGET(bp, log->l_mp->m_logdev_targp); Index: xfs/fs/xfs/xfs_mount.c =================================================================== --- xfs.orig/fs/xfs/xfs_mount.c 2011-06-29 11:38:53.000000000 +0200 +++ xfs/fs/xfs/xfs_mount.c 2011-06-29 13:51:20.425386530 +0200 @@ -1941,22 +1941,19 @@ unwind: * the superblock buffer if it can be locked without sleeping. * If it can't then we'll return NULL. */ -xfs_buf_t * +struct xfs_buf * xfs_getsb( - xfs_mount_t *mp, - int flags) + struct xfs_mount *mp, + int flags) { - xfs_buf_t *bp; + struct xfs_buf *bp = mp->m_sb_bp; - ASSERT(mp->m_sb_bp != NULL); - bp = mp->m_sb_bp; - if (flags & XBF_TRYLOCK) { - if (!XFS_BUF_CPSEMA(bp)) { + if (!xfs_buf_trylock(bp)) { + if (flags & XBF_TRYLOCK) return NULL; - } - } else { - XFS_BUF_PSEMA(bp, PRIBIO); + xfs_buf_lock(bp); } + XFS_BUF_HOLD(bp); ASSERT(XFS_BUF_ISDONE(bp)); return bp; Index: xfs/fs/xfs/xfs_trans_buf.c =================================================================== --- xfs.orig/fs/xfs/xfs_trans_buf.c 2011-03-27 23:52:57.000000000 +0200 +++ xfs/fs/xfs/xfs_trans_buf.c 2011-06-29 13:53:47.084592005 +0200 @@ -160,7 +160,7 @@ xfs_trans_get_buf(xfs_trans_t *tp, */ bp = xfs_trans_buf_item_match(tp, target_dev, blkno, len); if (bp != NULL) { - ASSERT(XFS_BUF_VALUSEMA(bp) <= 0); + ASSERT(xfs_buf_islocked(bp)); if (XFS_FORCED_SHUTDOWN(tp->t_mountp)) XFS_BUF_SUPER_STALE(bp); @@ -327,7 +327,7 @@ xfs_trans_read_buf( */ bp = xfs_trans_buf_item_match(tp, target, blkno, len); if (bp != NULL) { - ASSERT(XFS_BUF_VALUSEMA(bp) <= 0); + ASSERT(xfs_buf_islocked(bp)); ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp); ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL); ASSERT((XFS_BUF_ISERROR(bp)) == 0); From BATV+1dd5f1c206cd6a728cfd+2868+infradead.org+hch@bombadil.srs.infradead.org Fri Jul 1 04:46:11 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p619k9VA056155 for ; Fri, 1 Jul 2011 04:46:11 -0500 X-ASG-Debug-ID: 1309513567-63bd03ab0000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from bombadil.infradead.org (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 47DAA4669F for ; Fri, 1 Jul 2011 02:46:08 -0700 (PDT) Received: from bombadil.infradead.org (173-166-109-252-newengland.hfc.comcastbusiness.net [173.166.109.252]) by cuda.sgi.com with ESMTP id PGPrGktyynwMepfw for ; Fri, 01 Jul 2011 02:46:08 -0700 (PDT) Received: from hch by bombadil.infradead.org with local (Exim 4.76 #1 (Red Hat Linux)) id 1QcaIZ-00022z-Ie for xfs@oss.sgi.com; Fri, 01 Jul 2011 09:46:07 +0000 Message-Id: <20110701094607.536262104@bombadil.infradead.org> User-Agent: quilt/0.48-1 Date: Fri, 01 Jul 2011 05:43:47 -0400 From: Christoph Hellwig To: xfs@oss.sgi.com X-ASG-Orig-Subj: [PATCH 26/27] xfs: cleanup I/O-related buffer flags Subject: [PATCH 26/27] xfs: cleanup I/O-related buffer flags References: <20110701094321.936534538@bombadil.infradead.org> Content-Disposition: inline; filename=xfs-buf-cleanup-flags X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: 173-166-109-252-newengland.hfc.comcastbusiness.net[173.166.109.252] X-Barracuda-Start-Time: 1309513568 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -1.42 X-Barracuda-Spam-Status: No, SCORE=-1.42 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=BSF_SC5_MJ1963, RDNS_DYNAMIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67645 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_DYNAMIC Delivered to trusted network by host with dynamic-looking rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean Remove the unused and misnamed _XBF_RUN_QUEUES flag, rename XBF_LOG_BUFFER to the more fitting XBF_SYNCIO, and split XBF_ORDERED into XBF_FUA and XBF_FLUSH to allow more fine grained control over the bio flags. Also cleanup processing of the flags in _xfs_buf_ioapply to make more sense, and renumber the sparse flag number space to group flags by purpose. Signed-off-by: Christoph Hellwig Index: xfs/fs/xfs/linux-2.6/xfs_buf.c =================================================================== --- xfs.orig/fs/xfs/linux-2.6/xfs_buf.c 2011-06-29 14:04:28.084452749 +0200 +++ xfs/fs/xfs/linux-2.6/xfs_buf.c 2011-06-29 14:27:00.987123445 +0200 @@ -592,10 +592,8 @@ _xfs_buf_read( ASSERT(!(flags & (XBF_DELWRI|XBF_WRITE))); ASSERT(bp->b_bn != XFS_BUF_DADDR_NULL); - bp->b_flags &= ~(XBF_WRITE | XBF_ASYNC | XBF_DELWRI | \ - XBF_READ_AHEAD | _XBF_RUN_QUEUES); - bp->b_flags |= flags & (XBF_READ | XBF_ASYNC | \ - XBF_READ_AHEAD | _XBF_RUN_QUEUES); + bp->b_flags &= ~(XBF_WRITE | XBF_ASYNC | XBF_DELWRI | XBF_READ_AHEAD); + bp->b_flags |= flags & (XBF_READ | XBF_ASYNC | XBF_READ_AHEAD); status = xfs_buf_iorequest(bp); if (status || XFS_BUF_ISERROR(bp) || (flags & XBF_ASYNC)) @@ -1211,23 +1209,21 @@ _xfs_buf_ioapply( total_nr_pages = bp->b_page_count; map_i = 0; - if (bp->b_flags & XBF_ORDERED) { - ASSERT(!(bp->b_flags & XBF_READ)); - rw = WRITE_FLUSH_FUA; - } else if (bp->b_flags & XBF_LOG_BUFFER) { - ASSERT(!(bp->b_flags & XBF_READ_AHEAD)); - bp->b_flags &= ~_XBF_RUN_QUEUES; - rw = (bp->b_flags & XBF_WRITE) ? WRITE_SYNC : READ_SYNC; - } else if (bp->b_flags & _XBF_RUN_QUEUES) { - ASSERT(!(bp->b_flags & XBF_READ_AHEAD)); - bp->b_flags &= ~_XBF_RUN_QUEUES; - rw = (bp->b_flags & XBF_WRITE) ? WRITE_META : READ_META; + if (bp->b_flags & XBF_WRITE) { + if (bp->b_flags & XBF_SYNCIO) + rw = WRITE_SYNC; + else + rw = WRITE; + if (bp->b_flags & XBF_FUA) + rw |= REQ_FUA; + if (bp->b_flags & XBF_FLUSH) + rw |= REQ_FLUSH; + } else if (bp->b_flags & XBF_READ_AHEAD) { + rw = READA; } else { - rw = (bp->b_flags & XBF_WRITE) ? WRITE : - (bp->b_flags & XBF_READ_AHEAD) ? READA : READ; + rw = READ; } - next_chunk: atomic_inc(&bp->b_io_remaining); nr_pages = BIO_MAX_SECTORS >> (PAGE_SHIFT - BBSHIFT); @@ -1689,8 +1685,7 @@ xfs_buf_delwri_split( break; } - bp->b_flags &= ~(XBF_DELWRI|_XBF_DELWRI_Q| - _XBF_RUN_QUEUES); + bp->b_flags &= ~(XBF_DELWRI | _XBF_DELWRI_Q); bp->b_flags |= XBF_WRITE; list_move_tail(&bp->b_list, list); trace_xfs_buf_delwri_split(bp, _RET_IP_); Index: xfs/fs/xfs/linux-2.6/xfs_buf.h =================================================================== --- xfs.orig/fs/xfs/linux-2.6/xfs_buf.h 2011-06-29 14:03:57.994615760 +0200 +++ xfs/fs/xfs/linux-2.6/xfs_buf.h 2011-06-29 14:18:16.806629842 +0200 @@ -46,43 +46,46 @@ typedef enum { #define XBF_READ (1 << 0) /* buffer intended for reading from device */ #define XBF_WRITE (1 << 1) /* buffer intended for writing to device */ -#define XBF_MAPPED (1 << 2) /* buffer mapped (b_addr valid) */ +#define XBF_READ_AHEAD (1 << 2) /* asynchronous read-ahead */ +#define XBF_MAPPED (1 << 3) /* buffer mapped (b_addr valid) */ #define XBF_ASYNC (1 << 4) /* initiator will not wait for completion */ #define XBF_DONE (1 << 5) /* all pages in the buffer uptodate */ #define XBF_DELWRI (1 << 6) /* buffer has dirty pages */ #define XBF_STALE (1 << 7) /* buffer has been staled, do not find it */ -#define XBF_ORDERED (1 << 11)/* use ordered writes */ -#define XBF_READ_AHEAD (1 << 12)/* asynchronous read-ahead */ -#define XBF_LOG_BUFFER (1 << 13)/* this is a buffer used for the log */ + +/* I/O hints for the BIO layer */ +#define XBF_SYNCIO (1 << 10)/* treat this buffer as synchronous I/O */ +#define XBF_FUA (1 << 11)/* force cache write through mode */ +#define XBF_FLUSH (1 << 12)/* flush the disk cache before a write */ /* flags used only as arguments to access routines */ -#define XBF_LOCK (1 << 14)/* lock requested */ -#define XBF_TRYLOCK (1 << 15)/* lock requested, but do not wait */ -#define XBF_DONT_BLOCK (1 << 16)/* do not block in current thread */ +#define XBF_LOCK (1 << 15)/* lock requested */ +#define XBF_TRYLOCK (1 << 16)/* lock requested, but do not wait */ +#define XBF_DONT_BLOCK (1 << 17)/* do not block in current thread */ /* flags used only internally */ -#define _XBF_PAGES (1 << 18)/* backed by refcounted pages */ -#define _XBF_RUN_QUEUES (1 << 19)/* run block device task queue */ -#define _XBF_KMEM (1 << 20)/* backed by heap memory */ -#define _XBF_DELWRI_Q (1 << 21)/* buffer on delwri queue */ +#define _XBF_PAGES (1 << 20)/* backed by refcounted pages */ +#define _XBF_KMEM (1 << 21)/* backed by heap memory */ +#define _XBF_DELWRI_Q (1 << 22)/* buffer on delwri queue */ typedef unsigned int xfs_buf_flags_t; #define XFS_BUF_FLAGS \ { XBF_READ, "READ" }, \ { XBF_WRITE, "WRITE" }, \ + { XBF_READ_AHEAD, "READ_AHEAD" }, \ { XBF_MAPPED, "MAPPED" }, \ { XBF_ASYNC, "ASYNC" }, \ { XBF_DONE, "DONE" }, \ { XBF_DELWRI, "DELWRI" }, \ { XBF_STALE, "STALE" }, \ - { XBF_ORDERED, "ORDERED" }, \ - { XBF_READ_AHEAD, "READ_AHEAD" }, \ + { XBF_SYNCIO, "SYNCIO" }, \ + { XBF_FUA, "FUA" }, \ + { XBF_FLUSH, "FLUSH" }, \ { XBF_LOCK, "LOCK" }, /* should never be set */\ { XBF_TRYLOCK, "TRYLOCK" }, /* ditto */\ { XBF_DONT_BLOCK, "DONT_BLOCK" }, /* ditto */\ { _XBF_PAGES, "PAGES" }, \ - { _XBF_RUN_QUEUES, "RUN_QUEUES" }, \ { _XBF_KMEM, "KMEM" }, \ { _XBF_DELWRI_Q, "DELWRI_Q" } @@ -230,8 +233,9 @@ extern void xfs_buf_terminate(void); #define XFS_BUF_BFLAGS(bp) ((bp)->b_flags) -#define XFS_BUF_ZEROFLAGS(bp) ((bp)->b_flags &= \ - ~(XBF_READ|XBF_WRITE|XBF_ASYNC|XBF_DELWRI|XBF_ORDERED)) +#define XFS_BUF_ZEROFLAGS(bp) \ + ((bp)->b_flags &= ~(XBF_READ|XBF_WRITE|XBF_ASYNC|XBF_DELWRI| \ + XBF_SYNCIO|XBF_FUA|XBF_FLUSH)) void xfs_buf_stale(struct xfs_buf *bp); #define XFS_BUF_STALE(bp) xfs_buf_stale(bp); @@ -263,10 +267,6 @@ void xfs_buf_stale(struct xfs_buf *bp); #define XFS_BUF_UNASYNC(bp) ((bp)->b_flags &= ~XBF_ASYNC) #define XFS_BUF_ISASYNC(bp) ((bp)->b_flags & XBF_ASYNC) -#define XFS_BUF_ORDERED(bp) ((bp)->b_flags |= XBF_ORDERED) -#define XFS_BUF_UNORDERED(bp) ((bp)->b_flags &= ~XBF_ORDERED) -#define XFS_BUF_ISORDERED(bp) ((bp)->b_flags & XBF_ORDERED) - #define XFS_BUF_HOLD(bp) xfs_buf_hold(bp) #define XFS_BUF_READ(bp) ((bp)->b_flags |= XBF_READ) #define XFS_BUF_UNREAD(bp) ((bp)->b_flags &= ~XBF_READ) Index: xfs/fs/xfs/xfs_log.c =================================================================== --- xfs.orig/fs/xfs/xfs_log.c 2011-06-29 14:04:18.587837528 +0200 +++ xfs/fs/xfs/xfs_log.c 2011-06-29 19:45:20.176987585 +0200 @@ -1268,7 +1268,6 @@ xlog_bdstrat( return 0; } - bp->b_flags |= _XBF_RUN_QUEUES; xfs_buf_iorequest(bp); return 0; } @@ -1369,7 +1368,7 @@ xlog_sync(xlog_t *log, XFS_BUF_ZEROFLAGS(bp); XFS_BUF_BUSY(bp); XFS_BUF_ASYNC(bp); - bp->b_flags |= XBF_LOG_BUFFER; + bp->b_flags |= XBF_SYNCIO; if (log->l_mp->m_flags & XFS_MOUNT_BARRIER) { /* @@ -1380,7 +1379,7 @@ xlog_sync(xlog_t *log, */ if (log->l_mp->m_logdev_targp != log->l_mp->m_ddev_targp) xfs_blkdev_issue_flush(log->l_mp->m_ddev_targp); - XFS_BUF_ORDERED(bp); + bp->b_flags |= XBF_FUA | XBF_FLUSH; } ASSERT(XFS_BUF_ADDR(bp) <= log->l_logBBsize-1); @@ -1413,9 +1412,9 @@ xlog_sync(xlog_t *log, XFS_BUF_ZEROFLAGS(bp); XFS_BUF_BUSY(bp); XFS_BUF_ASYNC(bp); - bp->b_flags |= XBF_LOG_BUFFER; + bp->b_flags |= XBF_SYNCIO; if (log->l_mp->m_flags & XFS_MOUNT_BARRIER) - XFS_BUF_ORDERED(bp); + bp->b_flags |= XBF_FUA | XBF_FLUSH; dptr = XFS_BUF_PTR(bp); /* * Bump the cycle numbers at the start of each block From BATV+1dd5f1c206cd6a728cfd+2868+infradead.org+hch@bombadil.srs.infradead.org Fri Jul 1 04:46:12 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-4.5 required=5.0 tests=BAYES_00,J_CHICKENPOX_43, J_CHICKENPOX_62,J_CHICKENPOX_63,J_CHICKENPOX_65,LOCAL_GNU_PATCH autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p619k8lK056125 for ; Fri, 1 Jul 2011 04:46:08 -0500 X-ASG-Debug-ID: 1309513565-6d2200a80000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from bombadil.infradead.org (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 754C81EE3236 for ; Fri, 1 Jul 2011 02:46:06 -0700 (PDT) Received: from bombadil.infradead.org (173-166-109-252-newengland.hfc.comcastbusiness.net [173.166.109.252]) by cuda.sgi.com with ESMTP id h4qYdTLkaT1FboFB for ; Fri, 01 Jul 2011 02:46:06 -0700 (PDT) Received: from hch by bombadil.infradead.org with local (Exim 4.76 #1 (Red Hat Linux)) id 1QcaIX-0001xm-LL for xfs@oss.sgi.com; Fri, 01 Jul 2011 09:46:05 +0000 Message-Id: <20110701094605.621819832@bombadil.infradead.org> User-Agent: quilt/0.48-1 Date: Fri, 01 Jul 2011 05:43:37 -0400 From: Christoph Hellwig To: xfs@oss.sgi.com X-ASG-Orig-Subj: [PATCH 16/27] xfs: avoid usage of struct xfs_dir2_block Subject: [PATCH 16/27] xfs: avoid usage of struct xfs_dir2_block References: <20110701094321.936534538@bombadil.infradead.org> Content-Disposition: inline; filename=xfs-avoid-xfs_dir2_block_t X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: 173-166-109-252-newengland.hfc.comcastbusiness.net[173.166.109.252] X-Barracuda-Start-Time: 1309513566 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -1.42 X-Barracuda-Spam-Status: No, SCORE=-1.42 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=BSF_SC5_MJ1963, RDNS_DYNAMIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67645 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_DYNAMIC Delivered to trusted network by host with dynamic-looking rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean In most places we can simply pass around and use the struct xfs_dir2_data_hdr, which is the first and most important member of struct xfs_dir2_block instead of the full structure. Signed-off-by: Christoph Hellwig Index: xfs/fs/xfs/xfs_dir2_block.c =================================================================== --- xfs.orig/fs/xfs/xfs_dir2_block.c 2011-06-30 09:35:55.810069526 +0200 +++ xfs/fs/xfs/xfs_dir2_block.c 2011-06-30 09:38:36.586734196 +0200 @@ -67,7 +67,7 @@ xfs_dir2_block_addname( xfs_da_args_t *args) /* directory op arguments */ { xfs_dir2_data_free_t *bf; /* bestfree table in block */ - xfs_dir2_block_t *block; /* directory block structure */ + xfs_dir2_data_hdr_t *hdr; /* block header */ xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ xfs_dabuf_t *bp; /* buffer for block */ xfs_dir2_block_tail_t *btp; /* block tail */ @@ -105,13 +105,13 @@ xfs_dir2_block_addname( return error; } ASSERT(bp != NULL); - block = bp->data; + hdr = bp->data; /* * Check the magic number, corrupted if wrong. */ - if (unlikely(be32_to_cpu(block->hdr.magic) != XFS_DIR2_BLOCK_MAGIC)) { + if (unlikely(hdr->magic != cpu_to_be32(XFS_DIR2_BLOCK_MAGIC))) { XFS_CORRUPTION_ERROR("xfs_dir2_block_addname", - XFS_ERRLEVEL_LOW, mp, block); + XFS_ERRLEVEL_LOW, mp, hdr); xfs_da_brelse(tp, bp); return XFS_ERROR(EFSCORRUPTED); } @@ -119,8 +119,8 @@ xfs_dir2_block_addname( /* * Set up pointers to parts of the block. */ - bf = block->hdr.bestfree; - btp = xfs_dir2_block_tail_p(mp, block); + bf = hdr->bestfree; + btp = xfs_dir2_block_tail_p(mp, hdr); blp = xfs_dir2_block_leaf_p(btp); /* * No stale entries? Need space for entry and new leaf. @@ -133,7 +133,7 @@ xfs_dir2_block_addname( /* * Data object just before the first leaf entry. */ - enddup = (xfs_dir2_data_unused_t *)((char *)block + be16_to_cpu(*tagp)); + enddup = (xfs_dir2_data_unused_t *)((char *)hdr + be16_to_cpu(*tagp)); /* * If it's not free then can't do this add without cleaning up: * the space before the first leaf entry needs to be free so it @@ -146,7 +146,7 @@ xfs_dir2_block_addname( */ else { dup = (xfs_dir2_data_unused_t *) - ((char *)block + be16_to_cpu(bf[0].offset)); + ((char *)hdr + be16_to_cpu(bf[0].offset)); if (dup == enddup) { /* * It is the biggest freespace, is it too small @@ -159,7 +159,7 @@ xfs_dir2_block_addname( */ if (be16_to_cpu(bf[1].length) >= len) dup = (xfs_dir2_data_unused_t *) - ((char *)block + + ((char *)hdr + be16_to_cpu(bf[1].offset)); else dup = NULL; @@ -182,7 +182,7 @@ xfs_dir2_block_addname( */ else if (be16_to_cpu(bf[0].length) >= len) { dup = (xfs_dir2_data_unused_t *) - ((char *)block + be16_to_cpu(bf[0].offset)); + ((char *)hdr + be16_to_cpu(bf[0].offset)); compact = 0; } /* @@ -196,7 +196,7 @@ xfs_dir2_block_addname( /* * Data object just before the first leaf entry. */ - dup = (xfs_dir2_data_unused_t *)((char *)block + be16_to_cpu(*tagp)); + dup = (xfs_dir2_data_unused_t *)((char *)hdr + be16_to_cpu(*tagp)); /* * If it's not free then the data will go where the * leaf data starts now, if it works at all. @@ -272,7 +272,7 @@ xfs_dir2_block_addname( lfloghigh -= be32_to_cpu(btp->stale) - 1; be32_add_cpu(&btp->count, -(be32_to_cpu(btp->stale) - 1)); xfs_dir2_data_make_free(tp, bp, - (xfs_dir2_data_aoff_t)((char *)blp - (char *)block), + (xfs_dir2_data_aoff_t)((char *)blp - (char *)hdr), (xfs_dir2_data_aoff_t)((be32_to_cpu(btp->stale) - 1) * sizeof(*blp)), &needlog, &needscan); blp += be32_to_cpu(btp->stale) - 1; @@ -282,7 +282,7 @@ xfs_dir2_block_addname( * This needs to happen before the next call to use_free. */ if (needscan) { - xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog); + xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)hdr, &needlog); needscan = 0; } } @@ -318,7 +318,7 @@ xfs_dir2_block_addname( */ xfs_dir2_data_use_free(tp, bp, enddup, (xfs_dir2_data_aoff_t) - ((char *)enddup - (char *)block + be16_to_cpu(enddup->length) - + ((char *)enddup - (char *)hdr + be16_to_cpu(enddup->length) - sizeof(*blp)), (xfs_dir2_data_aoff_t)sizeof(*blp), &needlog, &needscan); @@ -331,7 +331,7 @@ xfs_dir2_block_addname( * This needs to happen before the next call to use_free. */ if (needscan) { - xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, + xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)hdr, &needlog); needscan = 0; } @@ -397,13 +397,13 @@ xfs_dir2_block_addname( */ blp[mid].hashval = cpu_to_be32(args->hashval); blp[mid].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp, - (char *)dep - (char *)block)); + (char *)dep - (char *)hdr)); xfs_dir2_block_log_leaf(tp, bp, lfloglow, lfloghigh); /* * Mark space for the data entry used. */ xfs_dir2_data_use_free(tp, bp, dup, - (xfs_dir2_data_aoff_t)((char *)dup - (char *)block), + (xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr), (xfs_dir2_data_aoff_t)len, &needlog, &needscan); /* * Create the new data entry. @@ -412,12 +412,12 @@ xfs_dir2_block_addname( dep->namelen = args->namelen; memcpy(dep->name, args->name, args->namelen); tagp = xfs_dir2_data_entry_tag_p(dep); - *tagp = cpu_to_be16((char *)dep - (char *)block); + *tagp = cpu_to_be16((char *)dep - (char *)hdr); /* * Clean up the bestfree array and log the header, tail, and entry. */ if (needscan) - xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog); + xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)hdr, &needlog); if (needlog) xfs_dir2_data_log_header(tp, bp); xfs_dir2_block_log_tail(tp, bp); @@ -438,6 +438,7 @@ xfs_dir2_block_getdents( filldir_t filldir) { xfs_dir2_block_t *block; /* directory block structure */ + xfs_dir2_data_hdr_t *hdr; /* block header */ xfs_dabuf_t *bp; /* buffer for block */ xfs_dir2_block_tail_t *btp; /* block tail */ xfs_dir2_data_entry_t *dep; /* block data entry */ @@ -471,11 +472,12 @@ xfs_dir2_block_getdents( */ wantoff = xfs_dir2_dataptr_to_off(mp, *offset); block = bp->data; + hdr = &block->hdr; xfs_dir2_data_check(dp, bp); /* * Set up values for the loop. */ - btp = xfs_dir2_block_tail_p(mp, block); + btp = xfs_dir2_block_tail_p(mp, hdr); ptr = (char *)block->u; endptr = (char *)xfs_dir2_block_leaf_p(btp); @@ -502,11 +504,11 @@ xfs_dir2_block_getdents( /* * The entry is before the desired starting point, skip it. */ - if ((char *)dep - (char *)block < wantoff) + if ((char *)dep - (char *)hdr < wantoff) continue; cook = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, - (char *)dep - (char *)block); + (char *)dep - (char *)hdr); /* * If it didn't fit, set the final offset to here & return. @@ -540,17 +542,14 @@ xfs_dir2_block_log_leaf( int first, /* index of first logged leaf */ int last) /* index of last logged leaf */ { - xfs_dir2_block_t *block; /* directory block structure */ - xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ - xfs_dir2_block_tail_t *btp; /* block tail */ - xfs_mount_t *mp; /* filesystem mount point */ + xfs_dir2_data_hdr_t *hdr = bp->data; + xfs_dir2_leaf_entry_t *blp; + xfs_dir2_block_tail_t *btp; - mp = tp->t_mountp; - block = bp->data; - btp = xfs_dir2_block_tail_p(mp, block); + btp = xfs_dir2_block_tail_p(tp->t_mountp, hdr); blp = xfs_dir2_block_leaf_p(btp); - xfs_da_log_buf(tp, bp, (uint)((char *)&blp[first] - (char *)block), - (uint)((char *)&blp[last + 1] - (char *)block - 1)); + xfs_da_log_buf(tp, bp, (uint)((char *)&blp[first] - (char *)hdr), + (uint)((char *)&blp[last + 1] - (char *)hdr - 1)); } /* @@ -561,15 +560,12 @@ xfs_dir2_block_log_tail( xfs_trans_t *tp, /* transaction structure */ xfs_dabuf_t *bp) /* block buffer */ { - xfs_dir2_block_t *block; /* directory block structure */ - xfs_dir2_block_tail_t *btp; /* block tail */ - xfs_mount_t *mp; /* filesystem mount point */ + xfs_dir2_data_hdr_t *hdr = bp->data; + xfs_dir2_block_tail_t *btp; - mp = tp->t_mountp; - block = bp->data; - btp = xfs_dir2_block_tail_p(mp, block); - xfs_da_log_buf(tp, bp, (uint)((char *)btp - (char *)block), - (uint)((char *)(btp + 1) - (char *)block - 1)); + btp = xfs_dir2_block_tail_p(tp->t_mountp, hdr); + xfs_da_log_buf(tp, bp, (uint)((char *)btp - (char *)hdr), + (uint)((char *)(btp + 1) - (char *)hdr - 1)); } /* @@ -580,7 +576,7 @@ int /* error */ xfs_dir2_block_lookup( xfs_da_args_t *args) /* dir lookup arguments */ { - xfs_dir2_block_t *block; /* block structure */ + xfs_dir2_data_hdr_t *hdr; /* block header */ xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ xfs_dabuf_t *bp; /* block buffer */ xfs_dir2_block_tail_t *btp; /* block tail */ @@ -600,14 +596,14 @@ xfs_dir2_block_lookup( return error; dp = args->dp; mp = dp->i_mount; - block = bp->data; + hdr = bp->data; xfs_dir2_data_check(dp, bp); - btp = xfs_dir2_block_tail_p(mp, block); + btp = xfs_dir2_block_tail_p(mp, hdr); blp = xfs_dir2_block_leaf_p(btp); /* * Get the offset from the leaf entry, to point to the data. */ - dep = (xfs_dir2_data_entry_t *)((char *)block + + dep = (xfs_dir2_data_entry_t *)((char *)hdr + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(blp[ent].address))); /* * Fill in inode number, CI name if appropriate, release the block. @@ -628,7 +624,7 @@ xfs_dir2_block_lookup_int( int *entno) /* returned entry number */ { xfs_dir2_dataptr_t addr; /* data entry address */ - xfs_dir2_block_t *block; /* block structure */ + xfs_dir2_data_hdr_t *hdr; /* block header */ xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ xfs_dabuf_t *bp; /* block buffer */ xfs_dir2_block_tail_t *btp; /* block tail */ @@ -654,9 +650,9 @@ xfs_dir2_block_lookup_int( return error; } ASSERT(bp != NULL); - block = bp->data; + hdr = bp->data; xfs_dir2_data_check(dp, bp); - btp = xfs_dir2_block_tail_p(mp, block); + btp = xfs_dir2_block_tail_p(mp, hdr); blp = xfs_dir2_block_leaf_p(btp); /* * Loop doing a binary search for our hash value. @@ -694,7 +690,7 @@ xfs_dir2_block_lookup_int( * Get pointer to the entry from the leaf. */ dep = (xfs_dir2_data_entry_t *) - ((char *)block + xfs_dir2_dataptr_to_off(mp, addr)); + ((char *)hdr + xfs_dir2_dataptr_to_off(mp, addr)); /* * Compare name and if it's an exact match, return the index * and buffer. If it's the first case-insensitive match, store @@ -733,7 +729,7 @@ int /* error */ xfs_dir2_block_removename( xfs_da_args_t *args) /* directory operation args */ { - xfs_dir2_block_t *block; /* block structure */ + xfs_dir2_data_hdr_t *hdr; /* block header */ xfs_dir2_leaf_entry_t *blp; /* block leaf pointer */ xfs_dabuf_t *bp; /* block buffer */ xfs_dir2_block_tail_t *btp; /* block tail */ @@ -760,20 +756,20 @@ xfs_dir2_block_removename( dp = args->dp; tp = args->trans; mp = dp->i_mount; - block = bp->data; - btp = xfs_dir2_block_tail_p(mp, block); + hdr = bp->data; + btp = xfs_dir2_block_tail_p(mp, hdr); blp = xfs_dir2_block_leaf_p(btp); /* * Point to the data entry using the leaf entry. */ dep = (xfs_dir2_data_entry_t *) - ((char *)block + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(blp[ent].address))); + ((char *)hdr + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(blp[ent].address))); /* * Mark the data entry's space free. */ needlog = needscan = 0; xfs_dir2_data_make_free(tp, bp, - (xfs_dir2_data_aoff_t)((char *)dep - (char *)block), + (xfs_dir2_data_aoff_t)((char *)dep - (char *)hdr), xfs_dir2_data_entsize(dep->namelen), &needlog, &needscan); /* * Fix up the block tail. @@ -789,15 +785,15 @@ xfs_dir2_block_removename( * Fix up bestfree, log the header if necessary. */ if (needscan) - xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog); + xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)hdr, &needlog); if (needlog) xfs_dir2_data_log_header(tp, bp); xfs_dir2_data_check(dp, bp); /* * See if the size as a shortform is good enough. */ - if ((size = xfs_dir2_block_sfsize(dp, block, &sfh)) > - XFS_IFORK_DSIZE(dp)) { + size = xfs_dir2_block_sfsize(dp, hdr, &sfh); + if (size > XFS_IFORK_DSIZE(dp)) { xfs_da_buf_done(bp); return 0; } @@ -815,7 +811,7 @@ int /* error */ xfs_dir2_block_replace( xfs_da_args_t *args) /* directory operation args */ { - xfs_dir2_block_t *block; /* block structure */ + xfs_dir2_data_hdr_t *hdr; /* block header */ xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ xfs_dabuf_t *bp; /* block buffer */ xfs_dir2_block_tail_t *btp; /* block tail */ @@ -836,14 +832,14 @@ xfs_dir2_block_replace( } dp = args->dp; mp = dp->i_mount; - block = bp->data; - btp = xfs_dir2_block_tail_p(mp, block); + hdr = bp->data; + btp = xfs_dir2_block_tail_p(mp, hdr); blp = xfs_dir2_block_leaf_p(btp); /* * Point to the data entry we need to change. */ dep = (xfs_dir2_data_entry_t *) - ((char *)block + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(blp[ent].address))); + ((char *)hdr + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(blp[ent].address))); ASSERT(be64_to_cpu(dep->inumber) != args->inumber); /* * Change the inode number to the new value. @@ -882,7 +878,7 @@ xfs_dir2_leaf_to_block( xfs_dabuf_t *dbp) /* data buffer */ { __be16 *bestsp; /* leaf bests table */ - xfs_dir2_block_t *block; /* block structure */ + xfs_dir2_data_hdr_t *hdr; /* block header */ xfs_dir2_block_tail_t *btp; /* block tail */ xfs_inode_t *dp; /* incore directory inode */ xfs_dir2_data_unused_t *dup; /* unused data entry */ @@ -917,7 +913,7 @@ xfs_dir2_leaf_to_block( while (dp->i_d.di_size > mp->m_dirblksize) { bestsp = xfs_dir2_leaf_bests_p(ltp); if (be16_to_cpu(bestsp[be32_to_cpu(ltp->bestcount) - 1]) == - mp->m_dirblksize - (uint)sizeof(block->hdr)) { + mp->m_dirblksize - (uint)sizeof(*hdr)) { if ((error = xfs_dir2_leaf_trim_data(args, lbp, (xfs_dir2_db_t)(be32_to_cpu(ltp->bestcount) - 1)))) @@ -935,18 +931,18 @@ xfs_dir2_leaf_to_block( XFS_DATA_FORK))) { goto out; } - block = dbp->data; - ASSERT(be32_to_cpu(block->hdr.magic) == XFS_DIR2_DATA_MAGIC); + hdr = dbp->data; + ASSERT(be32_to_cpu(hdr->magic) == XFS_DIR2_DATA_MAGIC); /* * Size of the "leaf" area in the block. */ - size = (uint)sizeof(block->tail) + + size = (uint)sizeof(xfs_dir2_block_tail_t) + (uint)sizeof(*lep) * (be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale)); /* * Look at the last data entry. */ - tagp = (__be16 *)((char *)block + mp->m_dirblksize) - 1; - dup = (xfs_dir2_data_unused_t *)((char *)block + be16_to_cpu(*tagp)); + tagp = (__be16 *)((char *)hdr + mp->m_dirblksize) - 1; + dup = (xfs_dir2_data_unused_t *)((char *)hdr + be16_to_cpu(*tagp)); /* * If it's not free or is too short we can't do it. */ @@ -958,7 +954,7 @@ xfs_dir2_leaf_to_block( /* * Start converting it to block form. */ - block->hdr.magic = cpu_to_be32(XFS_DIR2_BLOCK_MAGIC); + hdr->magic = cpu_to_be32(XFS_DIR2_BLOCK_MAGIC); needlog = 1; needscan = 0; /* @@ -969,7 +965,7 @@ xfs_dir2_leaf_to_block( /* * Initialize the block tail. */ - btp = xfs_dir2_block_tail_p(mp, block); + btp = xfs_dir2_block_tail_p(mp, hdr); btp->count = cpu_to_be32(be16_to_cpu(leaf->hdr.count) - be16_to_cpu(leaf->hdr.stale)); btp->stale = 0; xfs_dir2_block_log_tail(tp, dbp); @@ -988,7 +984,7 @@ xfs_dir2_leaf_to_block( * Scan the bestfree if we need it and log the data block header. */ if (needscan) - xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog); + xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)hdr, &needlog); if (needlog) xfs_dir2_data_log_header(tp, dbp); /* @@ -1002,8 +998,8 @@ xfs_dir2_leaf_to_block( /* * Now see if the resulting block can be shrunken to shortform. */ - if ((size = xfs_dir2_block_sfsize(dp, block, &sfh)) > - XFS_IFORK_DSIZE(dp)) { + size = xfs_dir2_block_sfsize(dp, hdr, &sfh); + if (size > XFS_IFORK_DSIZE(dp)) { error = 0; goto out; } @@ -1025,6 +1021,7 @@ xfs_dir2_sf_to_block( { xfs_dir2_db_t blkno; /* dir-relative block # (0) */ xfs_dir2_block_t *block; /* block structure */ + xfs_dir2_data_hdr_t *hdr; /* block header */ xfs_dir2_leaf_entry_t *blp; /* block leaf entries */ xfs_dabuf_t *bp; /* block buffer */ xfs_dir2_block_tail_t *btp; /* block tail pointer */ @@ -1095,7 +1092,8 @@ xfs_dir2_sf_to_block( return error; } block = bp->data; - block->hdr.magic = cpu_to_be32(XFS_DIR2_BLOCK_MAGIC); + hdr = &block->hdr; + hdr->magic = cpu_to_be32(XFS_DIR2_BLOCK_MAGIC); /* * Compute size of block "tail" area. */ @@ -1113,45 +1111,45 @@ xfs_dir2_sf_to_block( /* * Fill in the tail. */ - btp = xfs_dir2_block_tail_p(mp, block); + btp = xfs_dir2_block_tail_p(mp, hdr); btp->count = cpu_to_be32(sfp->count + 2); /* ., .. */ btp->stale = 0; blp = xfs_dir2_block_leaf_p(btp); - endoffset = (uint)((char *)blp - (char *)block); + endoffset = (uint)((char *)blp - (char *)hdr); /* * Remove the freespace, we'll manage it. */ xfs_dir2_data_use_free(tp, bp, dup, - (xfs_dir2_data_aoff_t)((char *)dup - (char *)block), + (xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr), be16_to_cpu(dup->length), &needlog, &needscan); /* * Create entry for . */ dep = (xfs_dir2_data_entry_t *) - ((char *)block + XFS_DIR2_DATA_DOT_OFFSET); + ((char *)hdr + XFS_DIR2_DATA_DOT_OFFSET); dep->inumber = cpu_to_be64(dp->i_ino); dep->namelen = 1; dep->name[0] = '.'; tagp = xfs_dir2_data_entry_tag_p(dep); - *tagp = cpu_to_be16((char *)dep - (char *)block); + *tagp = cpu_to_be16((char *)dep - (char *)hdr); xfs_dir2_data_log_entry(tp, bp, dep); blp[0].hashval = cpu_to_be32(xfs_dir_hash_dot); blp[0].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp, - (char *)dep - (char *)block)); + (char *)dep - (char *)hdr)); /* * Create entry for .. */ dep = (xfs_dir2_data_entry_t *) - ((char *)block + XFS_DIR2_DATA_DOTDOT_OFFSET); + ((char *)hdr + XFS_DIR2_DATA_DOTDOT_OFFSET); dep->inumber = cpu_to_be64(xfs_dir2_sf_get_parent_ino(sfp)); dep->namelen = 2; dep->name[0] = dep->name[1] = '.'; tagp = xfs_dir2_data_entry_tag_p(dep); - *tagp = cpu_to_be16((char *)dep - (char *)block); + *tagp = cpu_to_be16((char *)dep - (char *)hdr); xfs_dir2_data_log_entry(tp, bp, dep); blp[1].hashval = cpu_to_be32(xfs_dir_hash_dotdot); blp[1].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp, - (char *)dep - (char *)block)); + (char *)dep - (char *)hdr)); offset = XFS_DIR2_DATA_FIRST_OFFSET; /* * Loop over existing entries, stuff them in. @@ -1177,14 +1175,13 @@ xfs_dir2_sf_to_block( * There should be a hole here, make one. */ if (offset < newoffset) { - dup = (xfs_dir2_data_unused_t *) - ((char *)block + offset); + dup = (xfs_dir2_data_unused_t *)((char *)hdr + offset); dup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); dup->length = cpu_to_be16(newoffset - offset); *xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16( - ((char *)dup - (char *)block)); + ((char *)dup - (char *)hdr)); xfs_dir2_data_log_unused(tp, bp, dup); - (void)xfs_dir2_data_freeinsert((xfs_dir2_data_t *)block, + (void)xfs_dir2_data_freeinsert((xfs_dir2_data_t *)hdr, dup, &dummy); offset += be16_to_cpu(dup->length); continue; @@ -1192,20 +1189,20 @@ xfs_dir2_sf_to_block( /* * Copy a real entry. */ - dep = (xfs_dir2_data_entry_t *)((char *)block + newoffset); + dep = (xfs_dir2_data_entry_t *)((char *)hdr + newoffset); dep->inumber = cpu_to_be64(xfs_dir2_sfe_get_ino(sfp, sfep)); dep->namelen = sfep->namelen; memcpy(dep->name, sfep->name, dep->namelen); tagp = xfs_dir2_data_entry_tag_p(dep); - *tagp = cpu_to_be16((char *)dep - (char *)block); + *tagp = cpu_to_be16((char *)dep - (char *)hdr); xfs_dir2_data_log_entry(tp, bp, dep); name.name = sfep->name; name.len = sfep->namelen; blp[2 + i].hashval = cpu_to_be32(mp->m_dirnameops-> hashname(&name)); blp[2 + i].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp, - (char *)dep - (char *)block)); - offset = (int)((char *)(tagp + 1) - (char *)block); + (char *)dep - (char *)hdr)); + offset = (int)((char *)(tagp + 1) - (char *)hdr); if (++i == sfp->count) sfep = NULL; else Index: xfs/fs/xfs/xfs_dir2_data.c =================================================================== --- xfs.orig/fs/xfs/xfs_dir2_data.c 2011-06-29 19:45:24.326965102 +0200 +++ xfs/fs/xfs/xfs_dir2_data.c 2011-06-30 09:38:36.586734196 +0200 @@ -72,7 +72,7 @@ xfs_dir2_data_check( bf = d->hdr.bestfree; p = (char *)d->u; if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) { - btp = xfs_dir2_block_tail_p(mp, (xfs_dir2_block_t *)d); + btp = xfs_dir2_block_tail_p(mp, &d->hdr); lep = xfs_dir2_block_leaf_p(btp); endp = (char *)lep; } else @@ -348,7 +348,7 @@ xfs_dir2_data_freescan( */ p = (char *)d->u; if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) { - btp = xfs_dir2_block_tail_p(mp, (xfs_dir2_block_t *)d); + btp = xfs_dir2_block_tail_p(mp, &d->hdr); endp = (char *)xfs_dir2_block_leaf_p(btp); } else endp = (char *)d + mp->m_dirblksize; @@ -537,7 +537,7 @@ xfs_dir2_data_make_free( xfs_dir2_block_tail_t *btp; /* block tail */ ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); - btp = xfs_dir2_block_tail_p(mp, (xfs_dir2_block_t *)d); + btp = xfs_dir2_block_tail_p(mp, &d->hdr); endptr = (char *)xfs_dir2_block_leaf_p(btp); } /* Index: xfs/fs/xfs/xfs_dir2_leaf.c =================================================================== --- xfs.orig/fs/xfs/xfs_dir2_leaf.c 2011-06-30 09:29:24.446740960 +0200 +++ xfs/fs/xfs/xfs_dir2_leaf.c 2011-06-30 09:38:36.590067529 +0200 @@ -64,7 +64,7 @@ xfs_dir2_block_to_leaf( { __be16 *bestsp; /* leaf's bestsp entries */ xfs_dablk_t blkno; /* leaf block's bno */ - xfs_dir2_block_t *block; /* block structure */ + xfs_dir2_data_hdr_t *hdr; /* block header */ xfs_dir2_leaf_entry_t *blp; /* block's leaf entries */ xfs_dir2_block_tail_t *btp; /* block's tail */ xfs_inode_t *dp; /* incore directory inode */ @@ -101,9 +101,9 @@ xfs_dir2_block_to_leaf( } ASSERT(lbp != NULL); leaf = lbp->data; - block = dbp->data; + hdr = dbp->data; xfs_dir2_data_check(dp, dbp); - btp = xfs_dir2_block_tail_p(mp, block); + btp = xfs_dir2_block_tail_p(mp, hdr); blp = xfs_dir2_block_leaf_p(btp); /* * Set the counts in the leaf header. @@ -123,23 +123,23 @@ xfs_dir2_block_to_leaf( * tail be free. */ xfs_dir2_data_make_free(tp, dbp, - (xfs_dir2_data_aoff_t)((char *)blp - (char *)block), - (xfs_dir2_data_aoff_t)((char *)block + mp->m_dirblksize - + (xfs_dir2_data_aoff_t)((char *)blp - (char *)hdr), + (xfs_dir2_data_aoff_t)((char *)hdr + mp->m_dirblksize - (char *)blp), &needlog, &needscan); /* * Fix up the block header, make it a data block. */ - block->hdr.magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC); + hdr->magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC); if (needscan) - xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)block, &needlog); + xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)hdr, &needlog); /* * Set up leaf tail and bests table. */ ltp = xfs_dir2_leaf_tail_p(mp, leaf); ltp->bestcount = cpu_to_be32(1); bestsp = xfs_dir2_leaf_bests_p(ltp); - bestsp[0] = block->hdr.bestfree[0].length; + bestsp[0] = hdr->bestfree[0].length; /* * Log the data header and leaf bests table. */ Index: xfs/fs/xfs/xfs_dir2_sf.c =================================================================== --- xfs.orig/fs/xfs/xfs_dir2_sf.c 2011-06-30 09:38:34.303400889 +0200 +++ xfs/fs/xfs/xfs_dir2_sf.c 2011-06-30 09:38:36.590067529 +0200 @@ -141,7 +141,7 @@ xfs_dir2_sfe_put_ino( int /* size for sf form */ xfs_dir2_block_sfsize( xfs_inode_t *dp, /* incore inode pointer */ - xfs_dir2_block_t *block, /* block directory data */ + xfs_dir2_data_hdr_t *hdr, /* block directory data */ xfs_dir2_sf_hdr_t *sfhp) /* output: header for sf form */ { xfs_dir2_dataptr_t addr; /* data entry address */ @@ -161,7 +161,7 @@ xfs_dir2_block_sfsize( mp = dp->i_mount; count = i8count = namelen = 0; - btp = xfs_dir2_block_tail_p(mp, block); + btp = xfs_dir2_block_tail_p(mp, hdr); blp = xfs_dir2_block_leaf_p(btp); /* @@ -174,7 +174,7 @@ xfs_dir2_block_sfsize( * Calculate the pointer to the entry at hand. */ dep = (xfs_dir2_data_entry_t *) - ((char *)block + xfs_dir2_dataptr_to_off(mp, addr)); + ((char *)hdr + xfs_dir2_dataptr_to_off(mp, addr)); /* * Detect . and .., so we can special-case them. * . is not included in sf directories. @@ -255,6 +255,7 @@ xfs_dir2_block_to_sf( ASSERT(error != ENOSPC); goto out; } + /* * The buffer is now unconditionally gone, whether * xfs_dir2_shrink_inode worked or not. @@ -276,7 +277,7 @@ xfs_dir2_block_to_sf( /* * Set up to loop over the block's entries. */ - btp = xfs_dir2_block_tail_p(mp, block); + btp = xfs_dir2_block_tail_p(mp, &block->hdr); ptr = (char *)block->u; endptr = (char *)xfs_dir2_block_leaf_p(btp); sfep = xfs_dir2_sf_firstentry(sfp); Index: xfs/fs/xfs/xfs_dir2_sf.h =================================================================== --- xfs.orig/fs/xfs/xfs_dir2_sf.h 2011-06-30 09:38:34.303400889 +0200 +++ xfs/fs/xfs/xfs_dir2_sf.h 2011-06-30 09:38:36.593400862 +0200 @@ -32,7 +32,7 @@ struct uio; struct xfs_dabuf; struct xfs_da_args; -struct xfs_dir2_block; +struct xfs_dir2_data_hdr; struct xfs_inode; struct xfs_mount; struct xfs_trans; @@ -134,7 +134,7 @@ extern xfs_ino_t xfs_dir2_sf_get_parent_ extern xfs_ino_t xfs_dir2_sfe_get_ino(struct xfs_dir2_sf_hdr *sfp, struct xfs_dir2_sf_entry *sfep); extern int xfs_dir2_block_sfsize(struct xfs_inode *dp, - struct xfs_dir2_block *block, + struct xfs_dir2_data_hdr *block, xfs_dir2_sf_hdr_t *sfhp); extern int xfs_dir2_block_to_sf(struct xfs_da_args *args, struct xfs_dabuf *bp, int size, xfs_dir2_sf_hdr_t *sfhp); Index: xfs/fs/xfs/xfs_dir2_block.h =================================================================== --- xfs.orig/fs/xfs/xfs_dir2_block.h 2011-06-29 19:45:24.376964832 +0200 +++ xfs/fs/xfs/xfs_dir2_block.h 2011-06-30 09:38:36.596734195 +0200 @@ -61,10 +61,9 @@ typedef struct xfs_dir2_block { * Pointer to the leaf header embedded in a data block (1-block format) */ static inline xfs_dir2_block_tail_t * -xfs_dir2_block_tail_p(struct xfs_mount *mp, xfs_dir2_block_t *block) +xfs_dir2_block_tail_p(struct xfs_mount *mp, xfs_dir2_data_hdr_t *hdr) { - return (((xfs_dir2_block_tail_t *) - ((char *)(block) + (mp)->m_dirblksize)) - 1); + return ((xfs_dir2_block_tail_t *)((char *)hdr + mp->m_dirblksize)) - 1; } /* From BATV+1dd5f1c206cd6a728cfd+2868+infradead.org+hch@bombadil.srs.infradead.org Fri Jul 1 04:46:11 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-4.3 required=5.0 tests=BAYES_00,J_CHICKENPOX_36, J_CHICKENPOX_43,J_CHICKENPOX_62,J_CHICKENPOX_63,J_CHICKENPOX_64, J_CHICKENPOX_66,LOCAL_GNU_PATCH autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p619k9OU056163 for ; Fri, 1 Jul 2011 04:46:11 -0500 X-ASG-Debug-ID: 1309513566-63ae03bc0000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from bombadil.infradead.org (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id BB661466AC for ; Fri, 1 Jul 2011 02:46:06 -0700 (PDT) Received: from bombadil.infradead.org (173-166-109-252-newengland.hfc.comcastbusiness.net [173.166.109.252]) by cuda.sgi.com with ESMTP id 4ybVjPdfBcRe3XZH for ; Fri, 01 Jul 2011 02:46:06 -0700 (PDT) Received: from hch by bombadil.infradead.org with local (Exim 4.76 #1 (Red Hat Linux)) id 1QcaIY-0001yo-1U for xfs@oss.sgi.com; Fri, 01 Jul 2011 09:46:06 +0000 Message-Id: <20110701094606.003170984@bombadil.infradead.org> User-Agent: quilt/0.48-1 Date: Fri, 01 Jul 2011 05:43:39 -0400 From: Christoph Hellwig To: xfs@oss.sgi.com X-ASG-Orig-Subj: [PATCH 18/27] xfs: avoid usage of struct xfs_dir2_data Subject: [PATCH 18/27] xfs: avoid usage of struct xfs_dir2_data References: <20110701094321.936534538@bombadil.infradead.org> Content-Disposition: inline; filename=xfs-avoid-xfs_dir2_data_t X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: 173-166-109-252-newengland.hfc.comcastbusiness.net[173.166.109.252] X-Barracuda-Start-Time: 1309513566 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -1.42 X-Barracuda-Spam-Status: No, SCORE=-1.42 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=BSF_SC5_MJ1963, RDNS_DYNAMIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67645 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_DYNAMIC Delivered to trusted network by host with dynamic-looking rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean In most places we can simply pass around and use the struct xfs_dir2_data_hdr, which is the first and most important member of struct xfs_dir2_data instead of the full structure. Signed-off-by: Christoph Hellwig Index: xfs/fs/xfs/xfs_da_btree.c =================================================================== --- xfs.orig/fs/xfs/xfs_da_btree.c 2011-06-29 19:45:24.010300152 +0200 +++ xfs/fs/xfs/xfs_da_btree.c 2011-06-30 09:38:40.126734150 +0200 @@ -2079,16 +2079,13 @@ xfs_da_do_buf( * For read_buf, check the magic number. */ if (caller == 1) { - xfs_dir2_data_t *data; - xfs_dir2_free_t *free; - xfs_da_blkinfo_t *info; + xfs_dir2_data_hdr_t *hdr = rbp->data; + xfs_dir2_free_t *free = rbp->data; + xfs_da_blkinfo_t *info = rbp->data; uint magic, magic1; - info = rbp->data; - data = rbp->data; - free = rbp->data; magic = be16_to_cpu(info->magic); - magic1 = be32_to_cpu(data->hdr.magic); + magic1 = be32_to_cpu(hdr->magic); if (unlikely( XFS_TEST_ERROR((magic != XFS_DA_NODE_MAGIC) && (magic != XFS_ATTR_LEAF_MAGIC) && Index: xfs/fs/xfs/xfs_dir2_block.c =================================================================== --- xfs.orig/fs/xfs/xfs_dir2_block.c 2011-06-30 09:38:38.120067509 +0200 +++ xfs/fs/xfs/xfs_dir2_block.c 2011-06-30 09:38:40.130067486 +0200 @@ -282,7 +282,7 @@ xfs_dir2_block_addname( * This needs to happen before the next call to use_free. */ if (needscan) { - xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)hdr, &needlog); + xfs_dir2_data_freescan(mp, hdr, &needlog); needscan = 0; } } @@ -331,8 +331,7 @@ xfs_dir2_block_addname( * This needs to happen before the next call to use_free. */ if (needscan) { - xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)hdr, - &needlog); + xfs_dir2_data_freescan(mp, hdr, &needlog); needscan = 0; } /* @@ -417,7 +416,7 @@ xfs_dir2_block_addname( * Clean up the bestfree array and log the header, tail, and entry. */ if (needscan) - xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)hdr, &needlog); + xfs_dir2_data_freescan(mp, hdr, &needlog); if (needlog) xfs_dir2_data_log_header(tp, bp); xfs_dir2_block_log_tail(tp, bp); @@ -783,7 +782,7 @@ xfs_dir2_block_removename( * Fix up bestfree, log the header if necessary. */ if (needscan) - xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)hdr, &needlog); + xfs_dir2_data_freescan(mp, hdr, &needlog); if (needlog) xfs_dir2_data_log_header(tp, bp); xfs_dir2_data_check(dp, bp); @@ -982,7 +981,7 @@ xfs_dir2_leaf_to_block( * Scan the bestfree if we need it and log the data block header. */ if (needscan) - xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)hdr, &needlog); + xfs_dir2_data_freescan(mp, hdr, &needlog); if (needlog) xfs_dir2_data_log_header(tp, dbp); /* @@ -1177,8 +1176,7 @@ xfs_dir2_sf_to_block( *xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16( ((char *)dup - (char *)hdr)); xfs_dir2_data_log_unused(tp, bp, dup); - (void)xfs_dir2_data_freeinsert((xfs_dir2_data_t *)hdr, - dup, &dummy); + (void)xfs_dir2_data_freeinsert(hdr, dup, &dummy); offset += be16_to_cpu(dup->length); continue; } Index: xfs/fs/xfs/xfs_dir2_data.c =================================================================== --- xfs.orig/fs/xfs/xfs_dir2_data.c 2011-06-30 09:38:36.586734196 +0200 +++ xfs/fs/xfs/xfs_dir2_data.c 2011-06-30 09:38:40.133400821 +0200 @@ -35,6 +35,9 @@ #include "xfs_dir2_block.h" #include "xfs_error.h" +STATIC xfs_dir2_data_free_t * +xfs_dir2_data_freefind(xfs_dir2_data_hdr_t *hdr, xfs_dir2_data_unused_t *dup); + #ifdef DEBUG /* * Check the consistency of the data block. @@ -51,6 +54,7 @@ xfs_dir2_data_check( xfs_dir2_block_tail_t *btp=NULL; /* block tail */ int count; /* count of entries found */ xfs_dir2_data_t *d; /* data block pointer */ + xfs_dir2_data_hdr_t *hdr; /* data block header */ xfs_dir2_data_entry_t *dep; /* data entry */ xfs_dir2_data_free_t *dfp; /* bestfree entry */ xfs_dir2_data_unused_t *dup; /* unused entry */ @@ -67,16 +71,19 @@ xfs_dir2_data_check( mp = dp->i_mount; d = bp->data; - ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC || - be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); - bf = d->hdr.bestfree; + hdr = &d->hdr; + bf = hdr->bestfree; p = (char *)d->u; - if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) { - btp = xfs_dir2_block_tail_p(mp, &d->hdr); + + if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC)) { + btp = xfs_dir2_block_tail_p(mp, hdr); lep = xfs_dir2_block_leaf_p(btp); endp = (char *)lep; - } else - endp = (char *)d + mp->m_dirblksize; + } else { + ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC)); + endp = (char *)hdr + mp->m_dirblksize; + } + count = lastfree = freeseen = 0; /* * Account for zero bestfree entries. @@ -108,8 +115,8 @@ xfs_dir2_data_check( if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { ASSERT(lastfree == 0); ASSERT(be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup)) == - (char *)dup - (char *)d); - dfp = xfs_dir2_data_freefind(d, dup); + (char *)dup - (char *)hdr); + dfp = xfs_dir2_data_freefind(hdr, dup); if (dfp) { i = (int)(dfp - bf); ASSERT((freeseen & (1 << i)) == 0); @@ -132,13 +139,13 @@ xfs_dir2_data_check( ASSERT(dep->namelen != 0); ASSERT(xfs_dir_ino_validate(mp, be64_to_cpu(dep->inumber)) == 0); ASSERT(be16_to_cpu(*xfs_dir2_data_entry_tag_p(dep)) == - (char *)dep - (char *)d); + (char *)dep - (char *)hdr); count++; lastfree = 0; - if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) { + if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC)) { addr = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, (xfs_dir2_data_aoff_t) - ((char *)dep - (char *)d)); + ((char *)dep - (char *)hdr)); name.name = dep->name; name.len = dep->namelen; hash = mp->m_dirnameops->hashname(&name); @@ -155,7 +162,7 @@ xfs_dir2_data_check( * Need to have seen all the entries and all the bestfree slots. */ ASSERT(freeseen == 7); - if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) { + if (hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC)) { for (i = stale = 0; i < be32_to_cpu(btp->count); i++) { if (be32_to_cpu(lep[i].address) == XFS_DIR2_NULL_DATAPTR) stale++; @@ -172,9 +179,9 @@ xfs_dir2_data_check( * Given a data block and an unused entry from that block, * return the bestfree entry if any that corresponds to it. */ -xfs_dir2_data_free_t * +STATIC xfs_dir2_data_free_t * xfs_dir2_data_freefind( - xfs_dir2_data_t *d, /* data block */ + xfs_dir2_data_hdr_t *hdr, /* data block */ xfs_dir2_data_unused_t *dup) /* data unused entry */ { xfs_dir2_data_free_t *dfp; /* bestfree entry */ @@ -184,17 +191,17 @@ xfs_dir2_data_freefind( int seenzero; /* saw a 0 bestfree entry */ #endif - off = (xfs_dir2_data_aoff_t)((char *)dup - (char *)d); + off = (xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr); #if defined(DEBUG) && defined(__KERNEL__) /* * Validate some consistency in the bestfree table. * Check order, non-overlapping entries, and if we find the * one we're looking for it has to be exact. */ - ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC || - be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); - for (dfp = &d->hdr.bestfree[0], seenzero = matched = 0; - dfp < &d->hdr.bestfree[XFS_DIR2_DATA_FD_COUNT]; + ASSERT(be32_to_cpu(hdr->magic) == XFS_DIR2_DATA_MAGIC || + be32_to_cpu(hdr->magic) == XFS_DIR2_BLOCK_MAGIC); + for (dfp = &hdr->bestfree[0], seenzero = matched = 0; + dfp < &hdr->bestfree[XFS_DIR2_DATA_FD_COUNT]; dfp++) { if (!dfp->offset) { ASSERT(!dfp->length); @@ -210,7 +217,7 @@ xfs_dir2_data_freefind( else ASSERT(be16_to_cpu(dfp->offset) + be16_to_cpu(dfp->length) <= off); ASSERT(matched || be16_to_cpu(dfp->length) >= be16_to_cpu(dup->length)); - if (dfp > &d->hdr.bestfree[0]) + if (dfp > &hdr->bestfree[0]) ASSERT(be16_to_cpu(dfp[-1].length) >= be16_to_cpu(dfp[0].length)); } #endif @@ -219,13 +226,13 @@ xfs_dir2_data_freefind( * it can't be there since they're sorted. */ if (be16_to_cpu(dup->length) < - be16_to_cpu(d->hdr.bestfree[XFS_DIR2_DATA_FD_COUNT - 1].length)) + be16_to_cpu(hdr->bestfree[XFS_DIR2_DATA_FD_COUNT - 1].length)) return NULL; /* * Look at the three bestfree entries for our guy. */ - for (dfp = &d->hdr.bestfree[0]; - dfp < &d->hdr.bestfree[XFS_DIR2_DATA_FD_COUNT]; + for (dfp = &hdr->bestfree[0]; + dfp < &hdr->bestfree[XFS_DIR2_DATA_FD_COUNT]; dfp++) { if (!dfp->offset) return NULL; @@ -243,7 +250,7 @@ xfs_dir2_data_freefind( */ xfs_dir2_data_free_t * /* entry inserted */ xfs_dir2_data_freeinsert( - xfs_dir2_data_t *d, /* data block pointer */ + xfs_dir2_data_hdr_t *hdr, /* data block pointer */ xfs_dir2_data_unused_t *dup, /* unused space */ int *loghead) /* log the data header (out) */ { @@ -251,12 +258,13 @@ xfs_dir2_data_freeinsert( xfs_dir2_data_free_t new; /* new bestfree entry */ #ifdef __KERNEL__ - ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC || - be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); + ASSERT(be32_to_cpu(hdr->magic) == XFS_DIR2_DATA_MAGIC || + be32_to_cpu(hdr->magic) == XFS_DIR2_BLOCK_MAGIC); #endif - dfp = d->hdr.bestfree; + dfp = hdr->bestfree; new.length = dup->length; - new.offset = cpu_to_be16((char *)dup - (char *)d); + new.offset = cpu_to_be16((char *)dup - (char *)hdr); + /* * Insert at position 0, 1, or 2; or not at all. */ @@ -286,36 +294,36 @@ xfs_dir2_data_freeinsert( */ STATIC void xfs_dir2_data_freeremove( - xfs_dir2_data_t *d, /* data block pointer */ + xfs_dir2_data_hdr_t *hdr, /* data block header */ xfs_dir2_data_free_t *dfp, /* bestfree entry pointer */ int *loghead) /* out: log data header */ { #ifdef __KERNEL__ - ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC || - be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); + ASSERT(be32_to_cpu(hdr->magic) == XFS_DIR2_DATA_MAGIC || + be32_to_cpu(hdr->magic) == XFS_DIR2_BLOCK_MAGIC); #endif /* * It's the first entry, slide the next 2 up. */ - if (dfp == &d->hdr.bestfree[0]) { - d->hdr.bestfree[0] = d->hdr.bestfree[1]; - d->hdr.bestfree[1] = d->hdr.bestfree[2]; + if (dfp == &hdr->bestfree[0]) { + hdr->bestfree[0] = hdr->bestfree[1]; + hdr->bestfree[1] = hdr->bestfree[2]; } /* * It's the second entry, slide the 3rd entry up. */ - else if (dfp == &d->hdr.bestfree[1]) - d->hdr.bestfree[1] = d->hdr.bestfree[2]; + else if (dfp == &hdr->bestfree[1]) + hdr->bestfree[1] = hdr->bestfree[2]; /* * Must be the last entry. */ else - ASSERT(dfp == &d->hdr.bestfree[2]); + ASSERT(dfp == &hdr->bestfree[2]); /* * Clear the 3rd entry, must be zero now. */ - d->hdr.bestfree[2].length = 0; - d->hdr.bestfree[2].offset = 0; + hdr->bestfree[2].length = 0; + hdr->bestfree[2].offset = 0; *loghead = 1; } @@ -325,9 +333,10 @@ xfs_dir2_data_freeremove( void xfs_dir2_data_freescan( xfs_mount_t *mp, /* filesystem mount point */ - xfs_dir2_data_t *d, /* data block pointer */ + xfs_dir2_data_hdr_t *hdr, /* data block header */ int *loghead) /* out: log data header */ { + xfs_dir2_data_t *d = (xfs_dir2_data_t *)hdr; xfs_dir2_block_tail_t *btp; /* block tail */ xfs_dir2_data_entry_t *dep; /* active data entry */ xfs_dir2_data_unused_t *dup; /* unused data entry */ @@ -335,23 +344,23 @@ xfs_dir2_data_freescan( char *p; /* current entry pointer */ #ifdef __KERNEL__ - ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC || - be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); + ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || + hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC)); #endif /* * Start by clearing the table. */ - memset(d->hdr.bestfree, 0, sizeof(d->hdr.bestfree)); + memset(hdr->bestfree, 0, sizeof(hdr->bestfree)); *loghead = 1; /* * Set up pointers. */ p = (char *)d->u; - if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC) { - btp = xfs_dir2_block_tail_p(mp, &d->hdr); + if (be32_to_cpu(hdr->magic) == XFS_DIR2_BLOCK_MAGIC) { + btp = xfs_dir2_block_tail_p(mp, hdr); endp = (char *)xfs_dir2_block_leaf_p(btp); } else - endp = (char *)d + mp->m_dirblksize; + endp = (char *)hdr + mp->m_dirblksize; /* * Loop over the block's entries. */ @@ -361,9 +370,9 @@ xfs_dir2_data_freescan( * If it's a free entry, insert it. */ if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) { - ASSERT((char *)dup - (char *)d == + ASSERT((char *)dup - (char *)hdr == be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup))); - xfs_dir2_data_freeinsert(d, dup, loghead); + xfs_dir2_data_freeinsert(hdr, dup, loghead); p += be16_to_cpu(dup->length); } /* @@ -371,7 +380,7 @@ xfs_dir2_data_freescan( */ else { dep = (xfs_dir2_data_entry_t *)p; - ASSERT((char *)dep - (char *)d == + ASSERT((char *)dep - (char *)hdr == be16_to_cpu(*xfs_dir2_data_entry_tag_p(dep))); p += xfs_dir2_data_entsize(dep->namelen); } @@ -390,6 +399,7 @@ xfs_dir2_data_init( { xfs_dabuf_t *bp; /* block buffer */ xfs_dir2_data_t *d; /* pointer to block */ + xfs_dir2_data_hdr_t *hdr; /* data block header */ xfs_inode_t *dp; /* incore directory inode */ xfs_dir2_data_unused_t *dup; /* unused entry pointer */ int error; /* error return value */ @@ -410,26 +420,29 @@ xfs_dir2_data_init( return error; } ASSERT(bp != NULL); + /* * Initialize the header. */ d = bp->data; - d->hdr.magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC); - d->hdr.bestfree[0].offset = cpu_to_be16(sizeof(d->hdr)); + hdr = &d->hdr; + hdr->magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC); + hdr->bestfree[0].offset = cpu_to_be16(sizeof(*hdr)); for (i = 1; i < XFS_DIR2_DATA_FD_COUNT; i++) { - d->hdr.bestfree[i].length = 0; - d->hdr.bestfree[i].offset = 0; + hdr->bestfree[i].length = 0; + hdr->bestfree[i].offset = 0; } + /* * Set up an unused entry for the block's body. */ dup = &d->u[0].unused; dup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); - t=mp->m_dirblksize - (uint)sizeof(d->hdr); - d->hdr.bestfree[0].length = cpu_to_be16(t); + t = mp->m_dirblksize - (uint)sizeof(*hdr); + hdr->bestfree[0].length = cpu_to_be16(t); dup->length = cpu_to_be16(t); - *xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16((char *)dup - (char *)d); + *xfs_dir2_data_unused_tag_p(dup) = cpu_to_be16((char *)dup - (char *)hdr); /* * Log it and return it. */ @@ -448,14 +461,14 @@ xfs_dir2_data_log_entry( xfs_dabuf_t *bp, /* block buffer */ xfs_dir2_data_entry_t *dep) /* data entry pointer */ { - xfs_dir2_data_t *d; /* data block pointer */ + xfs_dir2_data_hdr_t *hdr = bp->data; - d = bp->data; - ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC || - be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); - xfs_da_log_buf(tp, bp, (uint)((char *)dep - (char *)d), + ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || + hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC)); + + xfs_da_log_buf(tp, bp, (uint)((char *)dep - (char *)hdr), (uint)((char *)(xfs_dir2_data_entry_tag_p(dep) + 1) - - (char *)d - 1)); + (char *)hdr - 1)); } /* @@ -466,13 +479,12 @@ xfs_dir2_data_log_header( xfs_trans_t *tp, /* transaction pointer */ xfs_dabuf_t *bp) /* block buffer */ { - xfs_dir2_data_t *d; /* data block pointer */ + xfs_dir2_data_hdr_t *hdr = bp->data; - d = bp->data; - ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC || - be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); - xfs_da_log_buf(tp, bp, (uint)((char *)&d->hdr - (char *)d), - (uint)(sizeof(d->hdr) - 1)); + ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || + hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC)); + + xfs_da_log_buf(tp, bp, 0, sizeof(*hdr) - 1); } /* @@ -484,23 +496,23 @@ xfs_dir2_data_log_unused( xfs_dabuf_t *bp, /* block buffer */ xfs_dir2_data_unused_t *dup) /* data unused pointer */ { - xfs_dir2_data_t *d; /* data block pointer */ + xfs_dir2_data_hdr_t *hdr = bp->data; + + ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC) || + hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC)); - d = bp->data; - ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC || - be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); /* * Log the first part of the unused entry. */ - xfs_da_log_buf(tp, bp, (uint)((char *)dup - (char *)d), + xfs_da_log_buf(tp, bp, (uint)((char *)dup - (char *)hdr), (uint)((char *)&dup->length + sizeof(dup->length) - - 1 - (char *)d)); + 1 - (char *)hdr)); /* * Log the end (tag) of the unused entry. */ xfs_da_log_buf(tp, bp, - (uint)((char *)xfs_dir2_data_unused_tag_p(dup) - (char *)d), - (uint)((char *)xfs_dir2_data_unused_tag_p(dup) - (char *)d + + (uint)((char *)xfs_dir2_data_unused_tag_p(dup) - (char *)hdr), + (uint)((char *)xfs_dir2_data_unused_tag_p(dup) - (char *)hdr + sizeof(xfs_dir2_data_off_t) - 1)); } @@ -517,7 +529,7 @@ xfs_dir2_data_make_free( int *needlogp, /* out: log header */ int *needscanp) /* out: regen bestfree */ { - xfs_dir2_data_t *d; /* data block pointer */ + xfs_dir2_data_hdr_t *hdr; /* data block pointer */ xfs_dir2_data_free_t *dfp; /* bestfree pointer */ char *endptr; /* end of data area */ xfs_mount_t *mp; /* filesystem mount point */ @@ -527,28 +539,29 @@ xfs_dir2_data_make_free( xfs_dir2_data_unused_t *prevdup; /* unused entry before us */ mp = tp->t_mountp; - d = bp->data; + hdr = bp->data; + /* * Figure out where the end of the data area is. */ - if (be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC) - endptr = (char *)d + mp->m_dirblksize; + if (hdr->magic == cpu_to_be32(XFS_DIR2_DATA_MAGIC)) + endptr = (char *)hdr + mp->m_dirblksize; else { xfs_dir2_block_tail_t *btp; /* block tail */ - ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); - btp = xfs_dir2_block_tail_p(mp, &d->hdr); + ASSERT(hdr->magic == cpu_to_be32(XFS_DIR2_BLOCK_MAGIC)); + btp = xfs_dir2_block_tail_p(mp, hdr); endptr = (char *)xfs_dir2_block_leaf_p(btp); } /* * If this isn't the start of the block, then back up to * the previous entry and see if it's free. */ - if (offset > sizeof(d->hdr)) { + if (offset > sizeof(*hdr)) { __be16 *tagp; /* tag just before us */ - tagp = (__be16 *)((char *)d + offset) - 1; - prevdup = (xfs_dir2_data_unused_t *)((char *)d + be16_to_cpu(*tagp)); + tagp = (__be16 *)((char *)hdr + offset) - 1; + prevdup = (xfs_dir2_data_unused_t *)((char *)hdr + be16_to_cpu(*tagp)); if (be16_to_cpu(prevdup->freetag) != XFS_DIR2_DATA_FREE_TAG) prevdup = NULL; } else @@ -557,9 +570,9 @@ xfs_dir2_data_make_free( * If this isn't the end of the block, see if the entry after * us is free. */ - if ((char *)d + offset + len < endptr) { + if ((char *)hdr + offset + len < endptr) { postdup = - (xfs_dir2_data_unused_t *)((char *)d + offset + len); + (xfs_dir2_data_unused_t *)((char *)hdr + offset + len); if (be16_to_cpu(postdup->freetag) != XFS_DIR2_DATA_FREE_TAG) postdup = NULL; } else @@ -576,21 +589,21 @@ xfs_dir2_data_make_free( /* * See if prevdup and/or postdup are in bestfree table. */ - dfp = xfs_dir2_data_freefind(d, prevdup); - dfp2 = xfs_dir2_data_freefind(d, postdup); + dfp = xfs_dir2_data_freefind(hdr, prevdup); + dfp2 = xfs_dir2_data_freefind(hdr, postdup); /* * We need a rescan unless there are exactly 2 free entries * namely our two. Then we know what's happening, otherwise * since the third bestfree is there, there might be more * entries. */ - needscan = (d->hdr.bestfree[2].length != 0); + needscan = (hdr->bestfree[2].length != 0); /* * Fix up the new big freespace. */ be16_add_cpu(&prevdup->length, len + be16_to_cpu(postdup->length)); *xfs_dir2_data_unused_tag_p(prevdup) = - cpu_to_be16((char *)prevdup - (char *)d); + cpu_to_be16((char *)prevdup - (char *)hdr); xfs_dir2_data_log_unused(tp, bp, prevdup); if (!needscan) { /* @@ -600,18 +613,18 @@ xfs_dir2_data_make_free( * Remove entry 1 first then entry 0. */ ASSERT(dfp && dfp2); - if (dfp == &d->hdr.bestfree[1]) { - dfp = &d->hdr.bestfree[0]; + if (dfp == &hdr->bestfree[1]) { + dfp = &hdr->bestfree[0]; ASSERT(dfp2 == dfp); - dfp2 = &d->hdr.bestfree[1]; + dfp2 = &hdr->bestfree[1]; } - xfs_dir2_data_freeremove(d, dfp2, needlogp); - xfs_dir2_data_freeremove(d, dfp, needlogp); + xfs_dir2_data_freeremove(hdr, dfp2, needlogp); + xfs_dir2_data_freeremove(hdr, dfp, needlogp); /* * Now insert the new entry. */ - dfp = xfs_dir2_data_freeinsert(d, prevdup, needlogp); - ASSERT(dfp == &d->hdr.bestfree[0]); + dfp = xfs_dir2_data_freeinsert(hdr, prevdup, needlogp); + ASSERT(dfp == &hdr->bestfree[0]); ASSERT(dfp->length == prevdup->length); ASSERT(!dfp[1].length); ASSERT(!dfp[2].length); @@ -621,10 +634,10 @@ xfs_dir2_data_make_free( * The entry before us is free, merge with it. */ else if (prevdup) { - dfp = xfs_dir2_data_freefind(d, prevdup); + dfp = xfs_dir2_data_freefind(hdr, prevdup); be16_add_cpu(&prevdup->length, len); *xfs_dir2_data_unused_tag_p(prevdup) = - cpu_to_be16((char *)prevdup - (char *)d); + cpu_to_be16((char *)prevdup - (char *)hdr); xfs_dir2_data_log_unused(tp, bp, prevdup); /* * If the previous entry was in the table, the new entry @@ -632,27 +645,27 @@ xfs_dir2_data_make_free( * the old one and add the new one. */ if (dfp) { - xfs_dir2_data_freeremove(d, dfp, needlogp); - (void)xfs_dir2_data_freeinsert(d, prevdup, needlogp); + xfs_dir2_data_freeremove(hdr, dfp, needlogp); + (void)xfs_dir2_data_freeinsert(hdr, prevdup, needlogp); } /* * Otherwise we need a scan if the new entry is big enough. */ else { needscan = be16_to_cpu(prevdup->length) > - be16_to_cpu(d->hdr.bestfree[2].length); + be16_to_cpu(hdr->bestfree[2].length); } } /* * The following entry is free, merge with it. */ else if (postdup) { - dfp = xfs_dir2_data_freefind(d, postdup); - newdup = (xfs_dir2_data_unused_t *)((char *)d + offset); + dfp = xfs_dir2_data_freefind(hdr, postdup); + newdup = (xfs_dir2_data_unused_t *)((char *)hdr + offset); newdup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); newdup->length = cpu_to_be16(len + be16_to_cpu(postdup->length)); *xfs_dir2_data_unused_tag_p(newdup) = - cpu_to_be16((char *)newdup - (char *)d); + cpu_to_be16((char *)newdup - (char *)hdr); xfs_dir2_data_log_unused(tp, bp, newdup); /* * If the following entry was in the table, the new entry @@ -660,28 +673,28 @@ xfs_dir2_data_make_free( * the old one and add the new one. */ if (dfp) { - xfs_dir2_data_freeremove(d, dfp, needlogp); - (void)xfs_dir2_data_freeinsert(d, newdup, needlogp); + xfs_dir2_data_freeremove(hdr, dfp, needlogp); + (void)xfs_dir2_data_freeinsert(hdr, newdup, needlogp); } /* * Otherwise we need a scan if the new entry is big enough. */ else { needscan = be16_to_cpu(newdup->length) > - be16_to_cpu(d->hdr.bestfree[2].length); + be16_to_cpu(hdr->bestfree[2].length); } } /* * Neither neighbor is free. Make a new entry. */ else { - newdup = (xfs_dir2_data_unused_t *)((char *)d + offset); + newdup = (xfs_dir2_data_unused_t *)((char *)hdr + offset); newdup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); newdup->length = cpu_to_be16(len); *xfs_dir2_data_unused_tag_p(newdup) = - cpu_to_be16((char *)newdup - (char *)d); + cpu_to_be16((char *)newdup - (char *)hdr); xfs_dir2_data_log_unused(tp, bp, newdup); - (void)xfs_dir2_data_freeinsert(d, newdup, needlogp); + (void)xfs_dir2_data_freeinsert(hdr, newdup, needlogp); } *needscanp = needscan; } @@ -699,7 +712,7 @@ xfs_dir2_data_use_free( int *needlogp, /* out: need to log header */ int *needscanp) /* out: need regen bestfree */ { - xfs_dir2_data_t *d; /* data block */ + xfs_dir2_data_hdr_t *hdr; /* data block header */ xfs_dir2_data_free_t *dfp; /* bestfree pointer */ int matchback; /* matches end of freespace */ int matchfront; /* matches start of freespace */ @@ -708,24 +721,24 @@ xfs_dir2_data_use_free( xfs_dir2_data_unused_t *newdup2; /* another new unused entry */ int oldlen; /* old unused entry's length */ - d = bp->data; - ASSERT(be32_to_cpu(d->hdr.magic) == XFS_DIR2_DATA_MAGIC || - be32_to_cpu(d->hdr.magic) == XFS_DIR2_BLOCK_MAGIC); + hdr = bp->data; + ASSERT(be32_to_cpu(hdr->magic) == XFS_DIR2_DATA_MAGIC || + be32_to_cpu(hdr->magic) == XFS_DIR2_BLOCK_MAGIC); ASSERT(be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG); - ASSERT(offset >= (char *)dup - (char *)d); - ASSERT(offset + len <= (char *)dup + be16_to_cpu(dup->length) - (char *)d); - ASSERT((char *)dup - (char *)d == be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup))); + ASSERT(offset >= (char *)dup - (char *)hdr); + ASSERT(offset + len <= (char *)dup + be16_to_cpu(dup->length) - (char *)hdr); + ASSERT((char *)dup - (char *)hdr == be16_to_cpu(*xfs_dir2_data_unused_tag_p(dup))); /* * Look up the entry in the bestfree table. */ - dfp = xfs_dir2_data_freefind(d, dup); + dfp = xfs_dir2_data_freefind(hdr, dup); oldlen = be16_to_cpu(dup->length); - ASSERT(dfp || oldlen <= be16_to_cpu(d->hdr.bestfree[2].length)); + ASSERT(dfp || oldlen <= be16_to_cpu(hdr->bestfree[2].length)); /* * Check for alignment with front and back of the entry. */ - matchfront = (char *)dup - (char *)d == offset; - matchback = (char *)dup + oldlen - (char *)d == offset + len; + matchfront = (char *)dup - (char *)hdr == offset; + matchback = (char *)dup + oldlen - (char *)hdr == offset + len; ASSERT(*needscanp == 0); needscan = 0; /* @@ -734,9 +747,9 @@ xfs_dir2_data_use_free( */ if (matchfront && matchback) { if (dfp) { - needscan = (d->hdr.bestfree[2].offset != 0); + needscan = (hdr->bestfree[2].offset != 0); if (!needscan) - xfs_dir2_data_freeremove(d, dfp, needlogp); + xfs_dir2_data_freeremove(hdr, dfp, needlogp); } } /* @@ -744,27 +757,27 @@ xfs_dir2_data_use_free( * Make a new entry with the remaining freespace. */ else if (matchfront) { - newdup = (xfs_dir2_data_unused_t *)((char *)d + offset + len); + newdup = (xfs_dir2_data_unused_t *)((char *)hdr + offset + len); newdup->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); newdup->length = cpu_to_be16(oldlen - len); *xfs_dir2_data_unused_tag_p(newdup) = - cpu_to_be16((char *)newdup - (char *)d); + cpu_to_be16((char *)newdup - (char *)hdr); xfs_dir2_data_log_unused(tp, bp, newdup); /* * If it was in the table, remove it and add the new one. */ if (dfp) { - xfs_dir2_data_freeremove(d, dfp, needlogp); - dfp = xfs_dir2_data_freeinsert(d, newdup, needlogp); + xfs_dir2_data_freeremove(hdr, dfp, needlogp); + dfp = xfs_dir2_data_freeinsert(hdr, newdup, needlogp); ASSERT(dfp != NULL); ASSERT(dfp->length == newdup->length); - ASSERT(be16_to_cpu(dfp->offset) == (char *)newdup - (char *)d); + ASSERT(be16_to_cpu(dfp->offset) == (char *)newdup - (char *)hdr); /* * If we got inserted at the last slot, * that means we don't know if there was a better * choice for the last slot, or not. Rescan. */ - needscan = dfp == &d->hdr.bestfree[2]; + needscan = dfp == &hdr->bestfree[2]; } } /* @@ -773,25 +786,25 @@ xfs_dir2_data_use_free( */ else if (matchback) { newdup = dup; - newdup->length = cpu_to_be16(((char *)d + offset) - (char *)newdup); + newdup->length = cpu_to_be16(((char *)hdr + offset) - (char *)newdup); *xfs_dir2_data_unused_tag_p(newdup) = - cpu_to_be16((char *)newdup - (char *)d); + cpu_to_be16((char *)newdup - (char *)hdr); xfs_dir2_data_log_unused(tp, bp, newdup); /* * If it was in the table, remove it and add the new one. */ if (dfp) { - xfs_dir2_data_freeremove(d, dfp, needlogp); - dfp = xfs_dir2_data_freeinsert(d, newdup, needlogp); + xfs_dir2_data_freeremove(hdr, dfp, needlogp); + dfp = xfs_dir2_data_freeinsert(hdr, newdup, needlogp); ASSERT(dfp != NULL); ASSERT(dfp->length == newdup->length); - ASSERT(be16_to_cpu(dfp->offset) == (char *)newdup - (char *)d); + ASSERT(be16_to_cpu(dfp->offset) == (char *)newdup - (char *)hdr); /* * If we got inserted at the last slot, * that means we don't know if there was a better * choice for the last slot, or not. Rescan. */ - needscan = dfp == &d->hdr.bestfree[2]; + needscan = dfp == &hdr->bestfree[2]; } } /* @@ -800,15 +813,15 @@ xfs_dir2_data_use_free( */ else { newdup = dup; - newdup->length = cpu_to_be16(((char *)d + offset) - (char *)newdup); + newdup->length = cpu_to_be16(((char *)hdr + offset) - (char *)newdup); *xfs_dir2_data_unused_tag_p(newdup) = - cpu_to_be16((char *)newdup - (char *)d); + cpu_to_be16((char *)newdup - (char *)hdr); xfs_dir2_data_log_unused(tp, bp, newdup); - newdup2 = (xfs_dir2_data_unused_t *)((char *)d + offset + len); + newdup2 = (xfs_dir2_data_unused_t *)((char *)hdr + offset + len); newdup2->freetag = cpu_to_be16(XFS_DIR2_DATA_FREE_TAG); newdup2->length = cpu_to_be16(oldlen - len - be16_to_cpu(newdup->length)); *xfs_dir2_data_unused_tag_p(newdup2) = - cpu_to_be16((char *)newdup2 - (char *)d); + cpu_to_be16((char *)newdup2 - (char *)hdr); xfs_dir2_data_log_unused(tp, bp, newdup2); /* * If the old entry was in the table, we need to scan @@ -819,12 +832,12 @@ xfs_dir2_data_use_free( * the 2 new will work. */ if (dfp) { - needscan = (d->hdr.bestfree[2].length != 0); + needscan = (hdr->bestfree[2].length != 0); if (!needscan) { - xfs_dir2_data_freeremove(d, dfp, needlogp); - (void)xfs_dir2_data_freeinsert(d, newdup, + xfs_dir2_data_freeremove(hdr, dfp, needlogp); + (void)xfs_dir2_data_freeinsert(hdr, newdup, needlogp); - (void)xfs_dir2_data_freeinsert(d, newdup2, + (void)xfs_dir2_data_freeinsert(hdr, newdup2, needlogp); } } Index: xfs/fs/xfs/xfs_dir2_data.h =================================================================== --- xfs.orig/fs/xfs/xfs_dir2_data.h 2011-06-29 19:45:24.043633305 +0200 +++ xfs/fs/xfs/xfs_dir2_data.h 2011-06-30 09:38:40.136734154 +0200 @@ -157,12 +157,10 @@ extern void xfs_dir2_data_check(struct x #else #define xfs_dir2_data_check(dp,bp) #endif -extern xfs_dir2_data_free_t *xfs_dir2_data_freefind(xfs_dir2_data_t *d, - xfs_dir2_data_unused_t *dup); -extern xfs_dir2_data_free_t *xfs_dir2_data_freeinsert(xfs_dir2_data_t *d, +extern xfs_dir2_data_free_t *xfs_dir2_data_freeinsert(xfs_dir2_data_hdr_t *hdr, xfs_dir2_data_unused_t *dup, int *loghead); -extern void xfs_dir2_data_freescan(struct xfs_mount *mp, xfs_dir2_data_t *d, - int *loghead); +extern void xfs_dir2_data_freescan(struct xfs_mount *mp, + xfs_dir2_data_hdr_t *hdr, int *loghead); extern int xfs_dir2_data_init(struct xfs_da_args *args, xfs_dir2_db_t blkno, struct xfs_dabuf **bpp); extern void xfs_dir2_data_log_entry(struct xfs_trans *tp, struct xfs_dabuf *bp, Index: xfs/fs/xfs/xfs_dir2_leaf.c =================================================================== --- xfs.orig/fs/xfs/xfs_dir2_leaf.c 2011-06-30 09:38:36.590067529 +0200 +++ xfs/fs/xfs/xfs_dir2_leaf.c 2011-06-30 09:38:40.140067486 +0200 @@ -132,7 +132,7 @@ xfs_dir2_block_to_leaf( */ hdr->magic = cpu_to_be32(XFS_DIR2_DATA_MAGIC); if (needscan) - xfs_dir2_data_freescan(mp, (xfs_dir2_data_t *)hdr, &needlog); + xfs_dir2_data_freescan(mp, hdr, &needlog); /* * Set up leaf tail and bests table. */ @@ -278,7 +278,7 @@ xfs_dir2_leaf_addname( { __be16 *bestsp; /* freespace table in leaf */ int compact; /* need to compact leaves */ - xfs_dir2_data_t *data; /* data block structure */ + xfs_dir2_data_hdr_t *hdr; /* data block header */ xfs_dabuf_t *dbp; /* data block buffer */ xfs_dir2_data_entry_t *dep; /* data block entry */ xfs_inode_t *dp; /* incore directory inode */ @@ -486,8 +486,8 @@ xfs_dir2_leaf_addname( */ else xfs_dir2_leaf_log_bests(tp, lbp, use_block, use_block); - data = dbp->data; - bestsp[use_block] = data->hdr.bestfree[0].length; + hdr = dbp->data; + bestsp[use_block] = hdr->bestfree[0].length; grown = 1; } /* @@ -501,7 +501,7 @@ xfs_dir2_leaf_addname( xfs_da_brelse(tp, lbp); return error; } - data = dbp->data; + hdr = dbp->data; grown = 0; } xfs_dir2_data_check(dp, dbp); @@ -509,14 +509,14 @@ xfs_dir2_leaf_addname( * Point to the biggest freespace in our data block. */ dup = (xfs_dir2_data_unused_t *) - ((char *)data + be16_to_cpu(data->hdr.bestfree[0].offset)); + ((char *)hdr + be16_to_cpu(hdr->bestfree[0].offset)); ASSERT(be16_to_cpu(dup->length) >= length); needscan = needlog = 0; /* * Mark the initial part of our freespace in use for the new entry. */ xfs_dir2_data_use_free(tp, dbp, dup, - (xfs_dir2_data_aoff_t)((char *)dup - (char *)data), length, + (xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr), length, &needlog, &needscan); /* * Initialize our new entry (at last). @@ -526,12 +526,12 @@ xfs_dir2_leaf_addname( dep->namelen = args->namelen; memcpy(dep->name, args->name, dep->namelen); tagp = xfs_dir2_data_entry_tag_p(dep); - *tagp = cpu_to_be16((char *)dep - (char *)data); + *tagp = cpu_to_be16((char *)dep - (char *)hdr); /* * Need to scan fix up the bestfree table. */ if (needscan) - xfs_dir2_data_freescan(mp, data, &needlog); + xfs_dir2_data_freescan(mp, hdr, &needlog); /* * Need to log the data block's header. */ @@ -542,8 +542,8 @@ xfs_dir2_leaf_addname( * If the bests table needs to be changed, do it. * Log the change unless we've already done that. */ - if (be16_to_cpu(bestsp[use_block]) != be16_to_cpu(data->hdr.bestfree[0].length)) { - bestsp[use_block] = data->hdr.bestfree[0].length; + if (be16_to_cpu(bestsp[use_block]) != be16_to_cpu(hdr->bestfree[0].length)) { + bestsp[use_block] = hdr->bestfree[0].length; if (!grown) xfs_dir2_leaf_log_bests(tp, lbp, use_block, use_block); } @@ -786,6 +786,7 @@ xfs_dir2_leaf_getdents( xfs_dir2_db_t curdb; /* db for current block */ xfs_dir2_off_t curoff; /* current overall offset */ xfs_dir2_data_t *data; /* data block structure */ + xfs_dir2_data_hdr_t *hdr; /* data block header */ xfs_dir2_data_entry_t *dep; /* data entry */ xfs_dir2_data_unused_t *dup; /* unused entry */ int error = 0; /* error return value */ @@ -1044,6 +1045,7 @@ xfs_dir2_leaf_getdents( ASSERT(xfs_dir2_byte_to_db(mp, curoff) == curdb); data = bp->data; + hdr = &data->hdr; xfs_dir2_data_check(dp, bp); /* * Find our position in the block. @@ -1054,12 +1056,12 @@ xfs_dir2_leaf_getdents( * Skip past the header. */ if (byteoff == 0) - curoff += (uint)sizeof(data->hdr); + curoff += (uint)sizeof(*hdr); /* * Skip past entries until we reach our offset. */ else { - while ((char *)ptr - (char *)data < byteoff) { + while ((char *)ptr - (char *)hdr < byteoff) { dup = (xfs_dir2_data_unused_t *)ptr; if (be16_to_cpu(dup->freetag) @@ -1080,8 +1082,8 @@ xfs_dir2_leaf_getdents( curoff = xfs_dir2_db_off_to_byte(mp, xfs_dir2_byte_to_db(mp, curoff), - (char *)ptr - (char *)data); - if (ptr >= (char *)data + mp->m_dirblksize) { + (char *)ptr - (char *)hdr); + if (ptr >= (char *)hdr + mp->m_dirblksize) { continue; } } @@ -1462,7 +1464,7 @@ xfs_dir2_leaf_removename( xfs_da_args_t *args) /* operation arguments */ { __be16 *bestsp; /* leaf block best freespace */ - xfs_dir2_data_t *data; /* data block structure */ + xfs_dir2_data_hdr_t *hdr; /* data block header */ xfs_dir2_db_t db; /* data block number */ xfs_dabuf_t *dbp; /* data block buffer */ xfs_dir2_data_entry_t *dep; /* data entry structure */ @@ -1492,7 +1494,7 @@ xfs_dir2_leaf_removename( tp = args->trans; mp = dp->i_mount; leaf = lbp->data; - data = dbp->data; + hdr = dbp->data; xfs_dir2_data_check(dp, dbp); /* * Point to the leaf entry, use that to point to the data entry. @@ -1500,9 +1502,9 @@ xfs_dir2_leaf_removename( lep = &leaf->ents[index]; db = xfs_dir2_dataptr_to_db(mp, be32_to_cpu(lep->address)); dep = (xfs_dir2_data_entry_t *) - ((char *)data + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address))); + ((char *)hdr + xfs_dir2_dataptr_to_off(mp, be32_to_cpu(lep->address))); needscan = needlog = 0; - oldbest = be16_to_cpu(data->hdr.bestfree[0].length); + oldbest = be16_to_cpu(hdr->bestfree[0].length); ltp = xfs_dir2_leaf_tail_p(mp, leaf); bestsp = xfs_dir2_leaf_bests_p(ltp); ASSERT(be16_to_cpu(bestsp[db]) == oldbest); @@ -1510,7 +1512,7 @@ xfs_dir2_leaf_removename( * Mark the former data entry unused. */ xfs_dir2_data_make_free(tp, dbp, - (xfs_dir2_data_aoff_t)((char *)dep - (char *)data), + (xfs_dir2_data_aoff_t)((char *)dep - (char *)hdr), xfs_dir2_data_entsize(dep->namelen), &needlog, &needscan); /* * We just mark the leaf entry stale by putting a null in it. @@ -1524,23 +1526,23 @@ xfs_dir2_leaf_removename( * log the data block header if necessary. */ if (needscan) - xfs_dir2_data_freescan(mp, data, &needlog); + xfs_dir2_data_freescan(mp, hdr, &needlog); if (needlog) xfs_dir2_data_log_header(tp, dbp); /* * If the longest freespace in the data block has changed, * put the new value in the bests table and log that. */ - if (be16_to_cpu(data->hdr.bestfree[0].length) != oldbest) { - bestsp[db] = data->hdr.bestfree[0].length; + if (be16_to_cpu(hdr->bestfree[0].length) != oldbest) { + bestsp[db] = hdr->bestfree[0].length; xfs_dir2_leaf_log_bests(tp, lbp, db, db); } xfs_dir2_data_check(dp, dbp); /* * If the data block is now empty then get rid of the data block. */ - if (be16_to_cpu(data->hdr.bestfree[0].length) == - mp->m_dirblksize - (uint)sizeof(data->hdr)) { + if (be16_to_cpu(hdr->bestfree[0].length) == + mp->m_dirblksize - (uint)sizeof(*hdr)) { ASSERT(db != mp->m_dirdatablk); if ((error = xfs_dir2_shrink_inode(args, db, dbp))) { /* @@ -1711,9 +1713,6 @@ xfs_dir2_leaf_trim_data( xfs_dir2_db_t db) /* data block number */ { __be16 *bestsp; /* leaf bests table */ -#ifdef DEBUG - xfs_dir2_data_t *data; /* data block structure */ -#endif xfs_dabuf_t *dbp; /* data block buffer */ xfs_inode_t *dp; /* incore directory inode */ int error; /* error return value */ @@ -1732,20 +1731,21 @@ xfs_dir2_leaf_trim_data( XFS_DATA_FORK))) { return error; } -#ifdef DEBUG - data = dbp->data; - ASSERT(be32_to_cpu(data->hdr.magic) == XFS_DIR2_DATA_MAGIC); -#endif - /* this seems to be an error - * data is only valid if DEBUG is defined? - * RMC 09/08/1999 - */ leaf = lbp->data; ltp = xfs_dir2_leaf_tail_p(mp, leaf); - ASSERT(be16_to_cpu(data->hdr.bestfree[0].length) == - mp->m_dirblksize - (uint)sizeof(data->hdr)); + +#ifdef DEBUG +{ + struct xfs_dir2_data_hdr *hdr = dbp->data; + + ASSERT(be32_to_cpu(hdr->magic) == XFS_DIR2_DATA_MAGIC); + ASSERT(be16_to_cpu(hdr->bestfree[0].length) == + mp->m_dirblksize - (uint)sizeof(*hdr)); ASSERT(db == be32_to_cpu(ltp->bestcount) - 1); +} +#endif + /* * Get rid of the data block. */ Index: xfs/fs/xfs/xfs_dir2_node.c =================================================================== --- xfs.orig/fs/xfs/xfs_dir2_node.c 2011-06-30 09:27:19.103409194 +0200 +++ xfs/fs/xfs/xfs_dir2_node.c 2011-06-30 09:38:40.143400818 +0200 @@ -842,7 +842,7 @@ xfs_dir2_leafn_remove( xfs_da_state_blk_t *dblk, /* data block */ int *rval) /* resulting block needs join */ { - xfs_dir2_data_t *data; /* data block structure */ + xfs_dir2_data_hdr_t *hdr; /* data block header */ xfs_dir2_db_t db; /* data block number */ xfs_dabuf_t *dbp; /* data block buffer */ xfs_dir2_data_entry_t *dep; /* data block entry */ @@ -887,9 +887,9 @@ xfs_dir2_leafn_remove( * in the data block in case it changes. */ dbp = dblk->bp; - data = dbp->data; - dep = (xfs_dir2_data_entry_t *)((char *)data + off); - longest = be16_to_cpu(data->hdr.bestfree[0].length); + hdr = dbp->data; + dep = (xfs_dir2_data_entry_t *)((char *)hdr + off); + longest = be16_to_cpu(hdr->bestfree[0].length); needlog = needscan = 0; xfs_dir2_data_make_free(tp, dbp, off, xfs_dir2_data_entsize(dep->namelen), &needlog, &needscan); @@ -898,7 +898,7 @@ xfs_dir2_leafn_remove( * Log the data block header if needed. */ if (needscan) - xfs_dir2_data_freescan(mp, data, &needlog); + xfs_dir2_data_freescan(mp, hdr, &needlog); if (needlog) xfs_dir2_data_log_header(tp, dbp); xfs_dir2_data_check(dp, dbp); @@ -906,7 +906,7 @@ xfs_dir2_leafn_remove( * If the longest data block freespace changes, need to update * the corresponding freeblock entry. */ - if (longest < be16_to_cpu(data->hdr.bestfree[0].length)) { + if (longest < be16_to_cpu(hdr->bestfree[0].length)) { int error; /* error return value */ xfs_dabuf_t *fbp; /* freeblock buffer */ xfs_dir2_db_t fdb; /* freeblock block number */ @@ -932,19 +932,19 @@ xfs_dir2_leafn_remove( * Calculate which entry we need to fix. */ findex = xfs_dir2_db_to_fdindex(mp, db); - longest = be16_to_cpu(data->hdr.bestfree[0].length); + longest = be16_to_cpu(hdr->bestfree[0].length); /* * If the data block is now empty we can get rid of it * (usually). */ - if (longest == mp->m_dirblksize - (uint)sizeof(data->hdr)) { + if (longest == mp->m_dirblksize - (uint)sizeof(*hdr)) { /* * Try to punch out the data block. */ error = xfs_dir2_shrink_inode(args, db, dbp); if (error == 0) { dblk->bp = NULL; - data = NULL; + hdr = NULL; } /* * We can get ENOSPC if there's no space reservation. @@ -960,7 +960,7 @@ xfs_dir2_leafn_remove( * If we got rid of the data block, we can eliminate that entry * in the free block. */ - if (data == NULL) { + if (hdr == NULL) { /* * One less used entry in the free table. */ @@ -1356,7 +1356,7 @@ xfs_dir2_node_addname_int( xfs_da_args_t *args, /* operation arguments */ xfs_da_state_blk_t *fblk) /* optional freespace block */ { - xfs_dir2_data_t *data; /* data block structure */ + xfs_dir2_data_hdr_t *hdr; /* data block header */ xfs_dir2_db_t dbno; /* data block number */ xfs_dabuf_t *dbp; /* data block buffer */ xfs_dir2_data_entry_t *dep; /* data entry pointer */ @@ -1641,8 +1641,8 @@ xfs_dir2_node_addname_int( * We haven't allocated the data entry yet so this will * change again. */ - data = dbp->data; - free->bests[findex] = data->hdr.bestfree[0].length; + hdr = dbp->data; + free->bests[findex] = hdr->bestfree[0].length; logfree = 1; } /* @@ -1667,21 +1667,21 @@ xfs_dir2_node_addname_int( xfs_da_buf_done(fbp); return error; } - data = dbp->data; + hdr = dbp->data; logfree = 0; } - ASSERT(be16_to_cpu(data->hdr.bestfree[0].length) >= length); + ASSERT(be16_to_cpu(hdr->bestfree[0].length) >= length); /* * Point to the existing unused space. */ dup = (xfs_dir2_data_unused_t *) - ((char *)data + be16_to_cpu(data->hdr.bestfree[0].offset)); + ((char *)hdr + be16_to_cpu(hdr->bestfree[0].offset)); needscan = needlog = 0; /* * Mark the first part of the unused space, inuse for us. */ xfs_dir2_data_use_free(tp, dbp, dup, - (xfs_dir2_data_aoff_t)((char *)dup - (char *)data), length, + (xfs_dir2_data_aoff_t)((char *)dup - (char *)hdr), length, &needlog, &needscan); /* * Fill in the new entry and log it. @@ -1691,13 +1691,13 @@ xfs_dir2_node_addname_int( dep->namelen = args->namelen; memcpy(dep->name, args->name, dep->namelen); tagp = xfs_dir2_data_entry_tag_p(dep); - *tagp = cpu_to_be16((char *)dep - (char *)data); + *tagp = cpu_to_be16((char *)dep - (char *)hdr); xfs_dir2_data_log_entry(tp, dbp, dep); /* * Rescan the block for bestfree if needed. */ if (needscan) - xfs_dir2_data_freescan(mp, data, &needlog); + xfs_dir2_data_freescan(mp, hdr, &needlog); /* * Log the data block header if needed. */ @@ -1706,8 +1706,8 @@ xfs_dir2_node_addname_int( /* * If the freespace entry is now wrong, update it. */ - if (be16_to_cpu(free->bests[findex]) != be16_to_cpu(data->hdr.bestfree[0].length)) { - free->bests[findex] = data->hdr.bestfree[0].length; + if (be16_to_cpu(free->bests[findex]) != be16_to_cpu(hdr->bestfree[0].length)) { + free->bests[findex] = hdr->bestfree[0].length; logfree = 1; } /* @@ -1857,7 +1857,7 @@ xfs_dir2_node_replace( xfs_da_args_t *args) /* operation arguments */ { xfs_da_state_blk_t *blk; /* leaf block */ - xfs_dir2_data_t *data; /* data block structure */ + xfs_dir2_data_hdr_t *hdr; /* data block header */ xfs_dir2_data_entry_t *dep; /* data entry changed */ int error; /* error return value */ int i; /* btree level */ @@ -1901,10 +1901,10 @@ xfs_dir2_node_replace( /* * Point to the data entry. */ - data = state->extrablk.bp->data; - ASSERT(be32_to_cpu(data->hdr.magic) == XFS_DIR2_DATA_MAGIC); + hdr = state->extrablk.bp->data; + ASSERT(be32_to_cpu(hdr->magic) == XFS_DIR2_DATA_MAGIC); dep = (xfs_dir2_data_entry_t *) - ((char *)data + + ((char *)hdr + xfs_dir2_dataptr_to_off(state->mp, be32_to_cpu(lep->address))); ASSERT(inum != be64_to_cpu(dep->inumber)); /* From amit.sahrawat83@gmail.com Fri Jul 1 05:37:55 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM, T_DKIM_INVALID autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p61AbttB060858 for ; Fri, 1 Jul 2011 05:37:55 -0500 X-ASG-Debug-ID: 1309516672-3d64012c0000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from mail-ey0-f181.google.com (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id E26CA46271 for ; Fri, 1 Jul 2011 03:37:52 -0700 (PDT) Received: from mail-ey0-f181.google.com (mail-ey0-f181.google.com [209.85.215.181]) by cuda.sgi.com with ESMTP id WDa1amEX8OeP2Lcl for ; Fri, 01 Jul 2011 03:37:52 -0700 (PDT) Received: by eyh5 with SMTP id 5so1106919eyh.26 for ; Fri, 01 Jul 2011 03:37:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type:content-transfer-encoding; bh=AffjASdlcpo/Bz1DJ3nm/6vcn3kWw1hPMK4x+RBFNV4=; b=TyGEnt9SzGcaPMGEdI4FUJsm5VK32KPRwA8UMi1kP0Go1jyU9rdm6PJJT8seOfULH0 VwZ4ta65pyEIp+vLVV3oNVfeWW8cPup1IMREdFWSmUE0o2/4MuTLovRGz+4L5vl5ywSD 8ad+S/yIjYCJnHitIRvAeIcbEvqGpd9RlE1pw= MIME-Version: 1.0 Received: by 10.14.42.76 with SMTP id i52mr31321eeb.174.1309516669430; Fri, 01 Jul 2011 03:37:49 -0700 (PDT) Received: by 10.14.37.15 with HTTP; Fri, 1 Jul 2011 03:37:49 -0700 (PDT) In-Reply-To: <20110701090332.GO561@dastard> References: <20110630121918.GK561@dastard> <20110701090332.GO561@dastard> Date: Fri, 1 Jul 2011 16:07:49 +0530 Message-ID: X-ASG-Orig-Subj: Re: XFS and USB Hang on 2.6.35.13 Subject: Re: XFS and USB Hang on 2.6.35.13 From: Amit Sahrawat To: Dave Chinner Cc: xfs@oss.sgi.com Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable X-Barracuda-Connect: mail-ey0-f181.google.com[209.85.215.181] X-Barracuda-Start-Time: 1309516673 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0208 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -1.52 X-Barracuda-Spam-Status: No, SCORE=-1.52 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=BSF_RULE_7582B, DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67649 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.50 BSF_RULE_7582B Custom Rule 7582B X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean On Fri, Jul 1, 2011 at 2:33 PM, Dave Chinner wrote: > On Fri, Jul 01, 2011 at 10:00:54AM +0530, Amit Sahrawat wrote: >> On Thu, Jun 30, 2011 at 5:49 PM, Dave Chinner wrot= e: >> > On Thu, Jun 30, 2011 at 04:57:42PM +0530, Amit Sahrawat wrote: >> > > Hi All, >> > > I encountered a hang on XFS during unplug. >> > > *Test Case:* >> > > #!/bin/sh >> > > index=3D0 >> > > while [ "$?" =3D=3D 0 ] >> > > do >> > > =A0 =A0 =A0 =A0 index=3D$(($index+1)) >> > > =A0 =A0 =A0 =A0 sync >> > > =A0 =A0 =A0 =A0 cp /mnt/1KB.txt /tmp/"$index".test >> > > done >> > > Where /mnt - mount point for vfat and /tmp mount point for XFS, both= can be >> > > XFS also. >> > > >> > > During this operation, unplug the USB. I am getting HANG almost ever= ytime I >> > > unplug. >> > >> > Well, that's no surprise. The unplug appears to be losing IOs in >> > progress. >> > >> > > *Kernel Version:* 2.6.35.13 (extremely sorry, I know next question w= ill be >> > > why am I not using TOT kernel - I tried but my PC does not boot up w= ith the >> > > latest one) > ..... >> > > *INFO: task khubd:*33 blocked for more than 120 seconds. >> > > "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this mes= sage. >> > > khubd =A0 =A0 =A0 =A0 D c06c261c =A0 =A0 0 =A0 =A033 =A0 =A0 =A02 0x= 00000000 >> > > Backtrace: >> > > [] (schedule+0x0/0x500) from [] >> > > (_xfs_log_force+0x230/0x284) >> > >> > You need to turn off line wrapping for stuff you paste into email. >> > The cleaned up (i.e. relevant part) trace is: >> > >> > [] (schedule+0x0/0x500) >> > [] (_xfs_log_force+0x0/0x284) >> > [] (xfs_log_force+0x0/0x38) >> > [] (xfs_sync_data+0x0/0x58) >> > [] (xfs_quiesce_data+0x0/0x80) >> > [] (xfs_fs_sync_fs+0x0/0xe0) >> > [] (__sync_filesystem+0x0/0xa0) >> > [] (sync_filesystem+0x0/0x60) >> > [] (fsync_bdev+0x0/0x44) >> > [] (invalidate_partition+0x0/0x3c) >> > [] (del_gendisk+0x0/0x140) >> > [] (sd_remove+0x0/0x84) >> > [] (__device_release_driver+0x0/0xac) >> > [] (device_release_driver+0x0/0x30) >> > [] (bus_remove_device+0x0/0x8c) >> > [] (device_del+0x0/0x170) >> > [] (__scsi_remove_device+0x0/0x90) >> > [] (scsi_forget_host+0x0/0x6c) >> > [] (scsi_remove_host+0x0/0x104) >> > [] (quiesce_and_remove_host+0x0/0x9c) >> > [] (usb_stor_disconnect+0x0/0x28) >> > [] (usb_unbind_interface+0x0/0xdc) >> > [] (__device_release_driver+0x0/0xac) >> > [] (device_release_driver+0x0/0x30) >> > [] (bus_remove_device+0x0/0x8c) >> > [] (device_del+0x0/0x170) >> > [] (usb_disable_device+0x0/0xf8) >> > [] (usb_disconnect+0x0/0xf4) >> > [] (hub_thread+0x0/0xd78) >> > [] (kthread+0x0/0x8c) >> > >> > Well, that just looks utterly braindamaged to me. >> > >> > We just had the device containing the filesystem removed from the >> > system, so the error handling routine ends up trying to sync the >> > filesystem to the device that doesn't exist anymore. WTF? >> > >> >> >>> This is what I think, why is syncing taking place when the > > Amit, you don't need to quote your own reply. That just confuses > mail readers that understand the ">" quoting convention and > highlight appropriately, and made me wonder if you'd even > replied.... Ok will take care of this in future. > >> This is what I think, why is syncing taking place when the >> device doesn't exist anymore. What is the gain in doing so? > > I doubt the person who wrote the error handling even realised that > it ended up in such a mess. That means there is no review going on for that path. > >> I >> will try and propose this feature. > > Not sure what you mean by this.... I wanted to revise this error leg where-in sync is taking place. I can only propose the suggestion for these error condition at the moment. > > .... >> > AFAICT, this problem doesn't exist in TOT - the conversion of the >> >> Again I have a problem which seems fixed in TOT :) >> >> > xfslogd workqueue to CMWQ allows processing of other xfslogd >> > workqueue events to continue even though this one has gone to sleep. >> > >> > You probably need to change the shutdown type to >> > SHUTDOWN_LOG_IO_ERROR to prevent a log flush from occurring in this >> > shutdown context. >> >> This will fix the error for this kernel version, I will give this a try. >> Is this the patchwork for CMWQ: >> http://patchwork.xfs.org/patch/2037/ (xfs: improve sync behaviour >> in face of aggressive dirtying) ? Please let me know. > > No. 2.6.35 doesn't have the CMWQ infrastructure, it was introduced > in 2.6.38 IIRC. > > IOWs, there isn't a fix you can just backport - you're going to need > to write and test your own fix, and my suggestion for doing that is > above. Yes, I went through the lwn.net and the kernel patches survey, CMWQ is new infrastructure and cannot be adopted to 2.6.35. At first I thought changes might be related only to XFS, but it is not like that. Regarding your fix - I tried out the change by setting the flag(SHUTDOWN_LOG_IO_ERROR) in this condition and it is working fine. There is a comment also in the function : xfs_do_force_shutdown() which appropriately mentions the very same thing. But since in our case it was returning due to flag not set, we ended up putting xfslogd to infinite sleep. Thanks for your help. > > Cheers, > > Dave. > -- > Dave Chinner > david@fromorbit.com > Regards, Amit Sahrawat From david@fromorbit.com Fri Jul 1 05:46:31 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p61AkVCj061259 for ; Fri, 1 Jul 2011 05:46:31 -0500 X-ASG-Debug-ID: 1309517188-09de01360000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from ipmail04.adl6.internode.on.net (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 53E821D7ED74 for ; Fri, 1 Jul 2011 03:46:28 -0700 (PDT) Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id PUEutiEjENmDRqpo for ; Fri, 01 Jul 2011 03:46:28 -0700 (PDT) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AgMIADKiDU55LCkB/2dsb2JhbABSmG2OcXjJQw6GJASaRIgx Received: from ppp121-44-41-1.lns20.syd6.internode.on.net (HELO dastard) ([121.44.41.1]) by ipmail04.adl6.internode.on.net with ESMTP; 01 Jul 2011 20:16:27 +0930 Received: from dave by dastard with local (Exim 4.72) (envelope-from ) id 1QcbEu-0005qL-Rn; Fri, 01 Jul 2011 20:46:24 +1000 Date: Fri, 1 Jul 2011 20:46:24 +1000 From: Dave Chinner To: kkeller@sonic.net Cc: xfs@oss.sgi.com X-ASG-Orig-Subj: Re: xfs_growfs doesn't resize Subject: Re: xfs_growfs doesn't resize Message-ID: <20110701104624.GS561@dastard> References: <55283.1309476620@sonic.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <55283.1309476620@sonic.net> User-Agent: Mutt/1.5.20 (2009-06-14) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1309517190 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0001 1.0000 -2.0204 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -2.02 X-Barracuda-Spam-Status: No, SCORE=-2.02 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67649 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean On Thu, Jun 30, 2011 at 04:30:20PM -0700, kkeller@sonic.net wrote: > Hello again all, > > I apologize for following up my own post, but I found some new information. > > On Thu 30/06/11 2:42 PM , kkeller@sonic.net wrote: > > > http://oss.sgi.com/archives/xfs/2008-01/msg00085.html > > I found a newer thread in the archives which might be more relevant to my issue: > > http://oss.sgi.com/archives/xfs/2009-09/msg00206.html > > But I haven't yet done a umount, and don't really wish to. So, my followup questions are: > > ==Is there a simple way to figure out what xfs_growfs did, and whether it caused any problems? Apart from looking at what is on disk with xfs_db in the manner that is done in the first thread you quoted, no. > ==Will I be able to fix these problems, if any, without needing a umount? If you need to modify anything with xfs_db, then you have to unmount the filesystem first. And realistically, you need to unmount the filesystem to make sure what xfs-db is reporting is not being modified by the active filesystem. So either way, you will have to unmount the filesystem. > ==Assuming my filesystem is healthy, will a simple kernel update > (and reboot of course!) allow me to resize the filesystem in one > step, instead of 2TB increments? I'd upgrade both kernel and userspace. Cheers, Dave. -- Dave Chinner david@fromorbit.com From achender@linux.vnet.ibm.com Fri Jul 1 09:30:36 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p61EUaoJ070191 for ; Fri, 1 Jul 2011 09:30:36 -0500 X-ASG-Debug-ID: 1309530634-1900007e0000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from e35.co.us.ibm.com (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id A9D6616759A6 for ; Fri, 1 Jul 2011 07:30:34 -0700 (PDT) Received: from e35.co.us.ibm.com (e35.co.us.ibm.com [32.97.110.153]) by cuda.sgi.com with ESMTP id SuzeDQ580EmXKtBd for ; Fri, 01 Jul 2011 07:30:34 -0700 (PDT) X-ASG-Whitelist: Barracuda Reputation Received: from d03relay03.boulder.ibm.com (d03relay03.boulder.ibm.com [9.17.195.228]) by e35.co.us.ibm.com (8.14.4/8.13.1) with ESMTP id p61EC5PE007828 for ; Fri, 1 Jul 2011 08:12:05 -0600 Received: from d03av03.boulder.ibm.com (d03av03.boulder.ibm.com [9.17.195.169]) by d03relay03.boulder.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id p61EUKvB136742 for ; Fri, 1 Jul 2011 08:30:23 -0600 Received: from d03av03.boulder.ibm.com (loopback [127.0.0.1]) by d03av03.boulder.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id p618UJ4c017207 for ; Fri, 1 Jul 2011 02:30:19 -0600 Received: from lc4eb0185863151.ibm.com (sig-9-65-52-4.mts.ibm.com [9.65.52.4]) by d03av03.boulder.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id p618UIe3017152; Fri, 1 Jul 2011 02:30:18 -0600 Message-ID: <4E0DD9FB.8090307@linux.vnet.ibm.com> Date: Fri, 01 Jul 2011 07:30:19 -0700 From: Allison Henderson User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.17) Gecko/20110414 Thunderbird/3.1.10 MIME-Version: 1.0 To: Allison Henderson CC: xfs@oss.sgi.com, linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org, Eric Sandeen X-ASG-Orig-Subj: Re: [PATCH 0/2v v7] XFS TESTS: ENOSPC Punch Hole Test Subject: Re: [PATCH 0/2v v7] XFS TESTS: ENOSPC Punch Hole Test References: <1309272301-5742-1-git-send-email-achender@linux.vnet.ibm.com> In-Reply-To: <1309272301-5742-1-git-send-email-achender@linux.vnet.ibm.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: e35.co.us.ibm.com[32.97.110.153] X-Barracuda-Start-Time: 1309530635 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean On 06/28/2011 07:44 AM, Allison Henderson wrote: > Hi All, > > This is another set I sent out a while ago, but I didnt see it show up on the lists, > so I am resending this one too. The work in this patch is a continuation from a > previous patch set that has been partially accepted, so I thought I > should retain the v6. > > This patch set adds the ENOSPC test that was used for ext4 punch hole testing. > This test will verify that a hole can be punched even when the disk is full. > Reserved blocks should be used to complete the operation when there is not blocks > to further fragment the file. > > Because punching a hole does not always require extra blocks, there needs to > be serveal iterations of punching holes, and then filling the file system to 100% > usage before it is forced to grow the tree in order to handle the fragmentation. > The growing of the tree is what would cause ENOSPC if not for the use of reserved blocks. > > I could use some opinions on this patch set becuase I am not sure if other filesystems > handle their punch holes in the same way. Although xfs appears to pass the test, > should this test be an ext4 only test? Thx! > Hi All, I just wanted to poke this thread before too much time goes by. This patch was initially part of an earlier set that's already been picked up, and it seemed like people were generally interested in it, so I resubmitted it as it's own patch. Is there still an interest in this patch set? I have another set that now also needs to add a new test 255 (the fix 252 failure patch set). I am thinking that if people still want this test, I could put this patch in with the other set so that they stack properly. Thx! Allison Henderson From mgorman@suse.de Fri Jul 1 09:59:41 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p61Exfgo071088 for ; Fri, 1 Jul 2011 09:59:41 -0500 X-ASG-Debug-ID: 1309532379-34e600370000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from mx2.suse.de (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 0DC74521D1A for ; Fri, 1 Jul 2011 07:59:39 -0700 (PDT) Received: from mx2.suse.de (cantor2.suse.de [195.135.220.15]) by cuda.sgi.com with ESMTP id 1fkCOCditKJpnZgT for ; Fri, 01 Jul 2011 07:59:39 -0700 (PDT) Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.221.2]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx2.suse.de (Postfix) with ESMTP id 9253E8F3B5; Fri, 1 Jul 2011 16:59:38 +0200 (CEST) Date: Fri, 1 Jul 2011 15:59:35 +0100 From: Mel Gorman To: Christoph Hellwig Cc: Johannes Weiner , Wu Fengguang , Dave Chinner , xfs@oss.sgi.com, jack@suse.cz, linux-mm@kvack.org X-ASG-Orig-Subj: Re: [PATCH 03/27] xfs: use write_cache_pages for writeback clustering Subject: Re: [PATCH 03/27] xfs: use write_cache_pages for writeback clustering Message-ID: <20110701145935.GB29530@suse.de> References: <20110629140109.003209430@bombadil.infradead.org> <20110629140336.950805096@bombadil.infradead.org> <20110701022248.GM561@dastard> <20110701041851.GN561@dastard> <20110701093305.GA28531@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-15 Content-Disposition: inline In-Reply-To: <20110701093305.GA28531@infradead.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: cantor2.suse.de[195.135.220.15] X-Barracuda-Start-Time: 1309532380 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0001 1.0000 -2.0207 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -2.02 X-Barracuda-Spam-Status: No, SCORE=-2.02 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67667 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean On Fri, Jul 01, 2011 at 05:33:05AM -0400, Christoph Hellwig wrote: > Johannes, Mel, Wu, Am adding Jan Kara as he has been working on writeback efficiency recently as well. > Dave has been stressing some XFS patches of mine that remove the XFS > internal writeback clustering in favour of using write_cache_pages. > Against what kernel? 2.6.38 was a disaster for reclaim I've been finding out this week. I don't know about 2.6.38.8. 2.6.39 was better. > As part of investigating the behaviour he found out that we're still > doing lots of I/O from the end of the LRU in kswapd. Not only is that > pretty bad behaviour in general, but it also means we really can't > just remove the writeback clustering in writepage given how much > I/O is still done through that. > > Any chance we could the writeback vs kswap behaviour sorted out a bit > better finally? > > Some excerpts from the previous discussion: > > On Fri, Jul 01, 2011 at 02:18:51PM +1000, Dave Chinner wrote: > > I'm now only running test 180 on 100 files rather than the 1000 the > > test normally runs on, because it's faster and still shows the > > problem. I had stopped looking at writeback problems while Wu and Jan were working on various writeback patchsets like io-less throttling. I don't know where they currently stand and while I submitted a number of reclaim patches since I last looked at this problem around 2.6.37, they were related to migration, kswapd reclaiming too much memory and kswapd using too much CPU - not writeback. At the time I stopped, the tests I was looking at were writing very few pages off the end of the LRU. Unfortunately I no longer have the results to see but for unrelated reasons, I've been other regression tests. Here is an example fsmark report over a number of kernels. The machine used is old but unfortunately it's the only one I have a full range of results at the moment. FS-Mark fsmark-2.6.32.42-mainline-fsmarkfsmark-2.6.34.10-mainline-fsmarkfsmark-2.6.37.6-mainline-fsmarkfsmark-2.6.38-mainline-fsmarkfsmark-2.6.39-mainline-fsmark 2.6.32.42-mainline2.6.34.10-mainline 2.6.37.6-mainline 2.6.38-mainline 2.6.39-mainline Files/s min 162.80 ( 0.00%) 156.20 (-4.23%) 155.60 (-4.63%) 157.80 (-3.17%) 151.10 (-7.74%) Files/s mean 173.77 ( 0.00%) 176.27 ( 1.42%) 168.19 (-3.32%) 172.98 (-0.45%) 172.05 (-1.00%) Files/s stddev 7.64 ( 0.00%) 12.54 (39.05%) 8.55 (10.57%) 8.39 ( 8.90%) 10.30 (25.77%) Files/s max 190.30 ( 0.00%) 206.80 ( 7.98%) 185.20 (-2.75%) 198.90 ( 4.32%) 201.00 ( 5.32%) Overhead min 1742851.00 ( 0.00%) 1612311.00 ( 8.10%) 1251552.00 (39.26%) 1239859.00 (40.57%) 1393047.00 (25.11%) Overhead mean 2443021.87 ( 0.00%) 2486525.60 (-1.75%) 2024365.53 (20.68%) 1849402.47 (32.10%) 1886692.53 (29.49%) Overhead stddev 744034.70 ( 0.00%) 359446.19 (106.99%) 335986.49 (121.45%) 375627.48 (98.08%) 320901.34 (131.86%) Overhead max 4744130.00 ( 0.00%) 3082235.00 (53.92%) 2561054.00 (85.24%) 2626346.00 (80.64%) 2559170.00 (85.38%) MMTests Statistics: duration User/Sys Time Running Test (seconds) 624.12 647.61 658.8 670.78 653.98 Total Elapsed Time (seconds) 5767.71 5742.30 5974.45 5852.32 5760.49 MMTests Statistics: vmstat Page Ins 3143712 3367600 3108596 3371952 3102548 Page Outs 104939296 105255268 105126820 105130540 105226620 Swap Ins 0 0 0 0 0 Swap Outs 0 0 0 0 0 Direct pages scanned 3521 131 7035 0 0 Kswapd pages scanned 23596104 23662641 23588211 23695015 23638226 Kswapd pages reclaimed 23594758 23661359 23587478 23693447 23637005 Direct pages reclaimed 3521 131 7031 0 0 Kswapd efficiency 99% 99% 99% 99% 99% Kswapd velocity 4091.070 4120.760 3948.181 4048.824 4103.510 Direct efficiency 100% 100% 99% 100% 100% Direct velocity 0.610 0.023 1.178 0.000 0.000 Percentage direct scans 0% 0% 0% 0% 0% Page writes by reclaim 75 32 37 252 44 Slabs scanned 1843200 1927168 2714112 2801280 2738816 Direct inode steals 0 0 0 0 0 Kswapd inode steals 1827970 1822770 1669879 1819583 1681155 Compaction stalls 0 0 0 0 0 Compaction success 0 0 0 0 0 Compaction failures 0 0 0 0 0 Compaction pages moved 0 0 0 228180 0 Compaction move failure 0 0 0 637776 0 The number of pages written from reclaim is exceptionally low (2.6.38 was a total disaster but that release was bad for a number of reasons, haven't tested 2.6.38.8 yet) but reduced by 2.6.37 as expected. Direct reclaim usage was reduced and efficiency (ratio of pages scanned to pages reclaimed) was high. As I look through the results I have at the moment, the number of pages written back was simply really low which is why the problem fell off my radar. > > That means the test is only using 1GB of disk space, and > > I'm running on a VM with 1GB RAM. It appears to be related to the VM > > triggering random page writeback from the LRU - 100x10MB files more > > than fills memory, hence it being the smallest test case i could > > reproduce the problem on. > > My tests were on a machine with 8G and ext3. I'm running some of the tests against ext4 and xfs to see if that makes a difference but it's possible the tests are simply not agressive enough so I want to reproduce Dave's test if possible. I'm assuming "test 180" is from xfstests which was not one of the tests I used previously. To run with 1000 files instead of 100, was the file "180" simply editted to make it look like this loop instead? # create files and sync them i=1; while [ $i -lt 100 ] do file=$SCRATCH_MNT/$i xfs_io -f -c "pwrite -b 64k -S 0xff 0 10m" $file > /dev/null if [ $? -ne 0 ] then echo error creating/writing file $file exit fi let i=$i+1 done > > My triage notes are as follows, and the patch that fixes the bug is > > attached below. > > > > > > > > <...>-393 [000] 696245.229559: xfs_ilock_nowait: dev 253:16 ino 0x244099 flags ILOCK_EXCL caller xfs_setfilesize > > <...>-393 [000] 696245.229560: xfs_setfilesize: dev 253:16 ino 0x244099 isize 0xa00000 disize 0x94e000 new_size 0x0 offset 0x600000 count 3813376 > > <...>-393 [000] 696245.229561: xfs_iunlock: dev 253:16 ino 0x244099 flags ILOCK_EXCL caller xfs_setfilesize > > > > For an IO that was from offset 0x600000 for just under 4MB. The end > > of that IO is at byte 10104832, which is _exactly_ what the inode > > size says it is. > > > > It is very clear that from the IO completions that we are getting a > > *lot* of kswapd driven writeback directly through .writepage: > > > > $ grep "xfs_setfilesize:" t.t |grep "4096$" | wc -l > > 801 > > $ grep "xfs_setfilesize:" t.t |grep -v "4096$" | wc -l > > 78 > > > > So there's ~900 IO completions that change the file size, and 90% of > > them are single page updates. > > > > $ ps -ef |grep [k]swap > > root 514 2 0 12:43 ? 00:00:00 [kswapd0] > > $ grep "writepage:" t.t | grep "514 " |wc -l > > 799 > > > > Oh, now that is too close to just be a co-incidence. We're getting > > significant amounts of random page writeback from the the ends of > > the LRUs done by the VM. > > > > Does the value for nr_vmscan_write in /proc/vmstat correlate? It must but lets me sure because I'm using that figure rather than ftrace to count writebacks at the moment. A more relevant question is this - how many pages were reclaimed by kswapd and what percentage is 799 pages of that? What do you consider an acceptable percentage? > On Fri, Jul 01, 2011 at 07:20:21PM +1000, Dave Chinner wrote: > > > Looks good. I still wonder why I haven't been able to hit this. > > > Haven't seen any 180 failure for a long time, with both 4k and 512 byte > > > filesystems and since yesterday 1k as well. > > > > It requires the test to run the VM out of RAM and then force enough > > memory pressure for kswapd to start writeback from the LRU. The > > reproducer I have is a 1p, 1GB RAM VM with it's disk image on a > > 100MB/s HW RAID1 w/ 512MB BBWC disk subsystem. > > You say it's a 1G VM but you don't say what architecure. What is the size of the highest zone? If this is 32-bit x86 for example, the highest zone is HighMem and it would be really small. Unfortunately it would always be the first choice for allocating and reclaiming from which would drastically increase the number of pages written back from reclaim. -- Mel Gorman SUSE Labs From BATV+1dd5f1c206cd6a728cfd+2868+infradead.org+hch@bombadil.srs.infradead.org Fri Jul 1 10:15:15 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p61FFFo2071770 for ; Fri, 1 Jul 2011 10:15:15 -0500 X-ASG-Debug-ID: 1309533314-036c00ea0000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from bombadil.infradead.org (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id DFCFE1EE45BE for ; Fri, 1 Jul 2011 08:15:14 -0700 (PDT) Received: from bombadil.infradead.org (173-166-109-252-newengland.hfc.comcastbusiness.net [173.166.109.252]) by cuda.sgi.com with ESMTP id qDphks0vTcD947zq for ; Fri, 01 Jul 2011 08:15:14 -0700 (PDT) Received: from hch by bombadil.infradead.org with local (Exim 4.76 #1 (Red Hat Linux)) id 1QcfQz-0001eY-DF; Fri, 01 Jul 2011 15:15:09 +0000 Date: Fri, 1 Jul 2011 11:15:09 -0400 From: Christoph Hellwig To: Mel Gorman Cc: Christoph Hellwig , Johannes Weiner , Wu Fengguang , Dave Chinner , xfs@oss.sgi.com, jack@suse.cz, linux-mm@kvack.org X-ASG-Orig-Subj: Re: [PATCH 03/27] xfs: use write_cache_pages for writeback clustering Subject: Re: [PATCH 03/27] xfs: use write_cache_pages for writeback clustering Message-ID: <20110701151509.GA30620@infradead.org> References: <20110629140109.003209430@bombadil.infradead.org> <20110629140336.950805096@bombadil.infradead.org> <20110701022248.GM561@dastard> <20110701041851.GN561@dastard> <20110701093305.GA28531@infradead.org> <20110701145935.GB29530@suse.de> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20110701145935.GB29530@suse.de> User-Agent: Mutt/1.5.21 (2010-09-15) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: 173-166-109-252-newengland.hfc.comcastbusiness.net[173.166.109.252] X-Barracuda-Start-Time: 1309533314 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0078 1.0000 -1.9703 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -1.87 X-Barracuda-Spam-Status: No, SCORE=-1.87 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=RDNS_DYNAMIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67667 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_DYNAMIC Delivered to trusted network by host with dynamic-looking rDNS X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean On Fri, Jul 01, 2011 at 03:59:35PM +0100, Mel Gorman wrote: > On Fri, Jul 01, 2011 at 05:33:05AM -0400, Christoph Hellwig wrote: > > Johannes, Mel, Wu, > > Am adding Jan Kara as he has been working on writeback efficiency > recently as well. > > > Dave has been stressing some XFS patches of mine that remove the XFS > > internal writeback clustering in favour of using write_cache_pages. > > > > Against what kernel? 2.6.38 was a disaster for reclaim I've been > finding out this week. I don't know about 2.6.38.8. 2.6.39 was better. The patch series is against current 3.0-rc, I assume that's what Dave tested as well. > I'm assuming "test 180" is from xfstests which was not one of the tests > I used previously. To run with 1000 files instead of 100, was the file > "180" simply editted to make it look like this loop instead? Yes. to both questions. From fengguang.wu@intel.com Fri Jul 1 10:41:42 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p61FfghL072839 for ; Fri, 1 Jul 2011 10:41:42 -0500 X-ASG-Debug-ID: 1309534899-033101450000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from mga03.intel.com (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id A11BA1EE4890 for ; Fri, 1 Jul 2011 08:41:40 -0700 (PDT) Received: from mga03.intel.com (mga03.intel.com [143.182.124.21]) by cuda.sgi.com with ESMTP id mjhsNZQQsptc3kfb for ; Fri, 01 Jul 2011 08:41:40 -0700 (PDT) X-ASG-Whitelist: Barracuda Reputation Received: from azsmga001.ch.intel.com ([10.2.17.19]) by azsmga101.ch.intel.com with ESMTP; 01 Jul 2011 08:41:39 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.65,458,1304319600"; d="scan'208";a="21551370" Received: from gsingh1-mobl1.gar.corp.intel.com (HELO localhost.localdomain) ([10.255.20.217]) by azsmga001.ch.intel.com with ESMTP; 01 Jul 2011 08:41:38 -0700 Received: from wfg by localhost.localdomain with local (Exim 4.69) (envelope-from ) id 1Qcfqa-0004ez-S7; Fri, 01 Jul 2011 23:41:36 +0800 Date: Fri, 1 Jul 2011 23:41:36 +0800 From: Wu Fengguang To: Christoph Hellwig Cc: Mel Gorman , Johannes Weiner , Dave Chinner , "xfs@oss.sgi.com" , "linux-mm@kvack.org" X-ASG-Orig-Subj: Re: [PATCH 03/27] xfs: use write_cache_pages for writeback clustering Subject: Re: [PATCH 03/27] xfs: use write_cache_pages for writeback clustering Message-ID: <20110701154136.GA17881@localhost> References: <20110629140109.003209430@bombadil.infradead.org> <20110629140336.950805096@bombadil.infradead.org> <20110701022248.GM561@dastard> <20110701041851.GN561@dastard> <20110701093305.GA28531@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20110701093305.GA28531@infradead.org> User-Agent: Mutt/1.5.20 (2009-06-14) X-Barracuda-Connect: mga03.intel.com[143.182.124.21] X-Barracuda-Start-Time: 1309534901 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean Christoph, On Fri, Jul 01, 2011 at 05:33:05PM +0800, Christoph Hellwig wrote: > Johannes, Mel, Wu, > > Dave has been stressing some XFS patches of mine that remove the XFS > internal writeback clustering in favour of using write_cache_pages. > > As part of investigating the behaviour he found out that we're still > doing lots of I/O from the end of the LRU in kswapd. Not only is that > pretty bad behaviour in general, but it also means we really can't > just remove the writeback clustering in writepage given how much > I/O is still done through that. > > Any chance we could the writeback vs kswap behaviour sorted out a bit > better finally? I once tried this approach: http://www.spinics.net/lists/linux-mm/msg09202.html It used a list structure that is not linearly scalable, however that part should be independently improvable when necessary. The real problem was, it seem to not very effective in my test runs. I found many ->nr_pages works queued before the ->inode works, which effectively makes the flusher working on more dispersed pages rather than focusing on the dirty pages encountered in LRU reclaim. So for the patch to work efficiently, we'll need to first merge the ->nr_pages works and make them lower priority than the ->inode works. Thanks, Fengguang > Some excerpts from the previous discussion: > > On Fri, Jul 01, 2011 at 02:18:51PM +1000, Dave Chinner wrote: > > I'm now only running test 180 on 100 files rather than the 1000 the > > test normally runs on, because it's faster and still shows the > > problem. That means the test is only using 1GB of disk space, and > > I'm running on a VM with 1GB RAM. It appears to be related to the VM > > triggering random page writeback from the LRU - 100x10MB files more > > than fills memory, hence it being the smallest test case i could > > reproduce the problem on. > > > > My triage notes are as follows, and the patch that fixes the bug is > > attached below. > > > > --- 180.out 2010-04-28 15:00:22.000000000 +1000 > > +++ 180.out.bad 2011-07-01 12:44:12.000000000 +1000 > > @@ -1 +1,9 @@ > > QA output created by 180 > > +file /mnt/scratch/81 has incorrect size 10473472 - sync failed > > +file /mnt/scratch/86 has incorrect size 10371072 - sync failed > > +file /mnt/scratch/87 has incorrect size 10104832 - sync failed > > +file /mnt/scratch/88 has incorrect size 10125312 - sync failed > > +file /mnt/scratch/89 has incorrect size 10469376 - sync failed > > +file /mnt/scratch/90 has incorrect size 10240000 - sync failed > > +file /mnt/scratch/91 has incorrect size 10362880 - sync failed > > +file /mnt/scratch/92 has incorrect size 10366976 - sync failed > > > > $ ls -li /mnt/scratch/ | awk '/rw/ { printf("0x%x %d %d\n", $1, $6, $10); }' > > 0x244093 10473472 81 > > 0x244098 10371072 86 > > 0x244099 10104832 87 > > 0x24409a 10125312 88 > > 0x24409b 10469376 89 > > 0x24409c 10240000 90 > > 0x24409d 10362880 91 > > 0x24409e 10366976 92 > > > > So looking at inode 0x244099 (/mnt/scratch/87), the last setfilesize > > call in the trace (got a separate patch for that) is: > > > > <...>-393 [000] 696245.229559: xfs_ilock_nowait: dev 253:16 ino 0x244099 flags ILOCK_EXCL caller xfs_setfilesize > > <...>-393 [000] 696245.229560: xfs_setfilesize: dev 253:16 ino 0x244099 isize 0xa00000 disize 0x94e000 new_size 0x0 offset 0x600000 count 3813376 > > <...>-393 [000] 696245.229561: xfs_iunlock: dev 253:16 ino 0x244099 flags ILOCK_EXCL caller xfs_setfilesize > > > > For an IO that was from offset 0x600000 for just under 4MB. The end > > of that IO is at byte 10104832, which is _exactly_ what the inode > > size says it is. > > > > It is very clear that from the IO completions that we are getting a > > *lot* of kswapd driven writeback directly through .writepage: > > > > $ grep "xfs_setfilesize:" t.t |grep "4096$" | wc -l > > 801 > > $ grep "xfs_setfilesize:" t.t |grep -v "4096$" | wc -l > > 78 > > > > So there's ~900 IO completions that change the file size, and 90% of > > them are single page updates. > > > > $ ps -ef |grep [k]swap > > root 514 2 0 12:43 ? 00:00:00 [kswapd0] > > $ grep "writepage:" t.t | grep "514 " |wc -l > > 799 > > > > Oh, now that is too close to just be a co-incidence. We're getting > > significant amounts of random page writeback from the the ends of > > the LRUs done by the VM. > > > > > > > On Fri, Jul 01, 2011 at 07:20:21PM +1000, Dave Chinner wrote: > > > Looks good. I still wonder why I haven't been able to hit this. > > > Haven't seen any 180 failure for a long time, with both 4k and 512 byte > > > filesystems and since yesterday 1k as well. > > > > It requires the test to run the VM out of RAM and then force enough > > memory pressure for kswapd to start writeback from the LRU. The > > reproducer I have is a 1p, 1GB RAM VM with it's disk image on a > > 100MB/s HW RAID1 w/ 512MB BBWC disk subsystem. > > > > When kswapd starts doing writeback from the LRU, the iops rate goes > > through the roof (from ~300iops @~320k/io to ~7000iops @4k/io) and > > throughput drops from 100MB/s to ~30MB/s. BBWC is the only reason > > the IOPS stays as high as it does - maybe that is why I saw this and > > you haven't. > > > > As it is, the kswapd writeback behaviour is utterly atrocious and, > > ultimately, quite easy to provoke. I wish the MM folk would fix that > > goddamn problem already - we've only been complaining about it for > > the last 6 or 7 years. As such, I'm wondering if it's a bad idea to > > even consider removing the .writepage clustering... From kkeller@sonic.net Fri Jul 1 11:44:46 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p61Gik6u081287 for ; Fri, 1 Jul 2011 11:44:46 -0500 X-ASG-Debug-ID: 1309538681-693602940000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from a.mail.sonic.net (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 70EC81675FC5 for ; Fri, 1 Jul 2011 09:44:41 -0700 (PDT) Received: from a.mail.sonic.net (a.mail.sonic.net [64.142.16.245]) by cuda.sgi.com with ESMTP id paKyhxtQSaRO6Zy0 for ; Fri, 01 Jul 2011 09:44:41 -0700 (PDT) Received: from webmail.sonic.net (b.webmail.sonic.net [69.12.208.80]) by a.mail.sonic.net (8.13.8.Beta0-Sonic/8.13.7) with ESMTP id p61GifeR000730 for ; Fri, 1 Jul 2011 09:44:41 -0700 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Priority: Normal X-Mailer: AtMail PHP 5.62 Message-ID: <51043.1309538681@sonic.net> To: Reply-To: kkeller@sonic.net X-Origin: 75.101.60.64 X-Atmail-Account: kkeller@sonic.net Date: Fri, 01 Jul 2011 09:44:41 -0700 X-ASG-Orig-Subj: Re: xfs_growfs doesn't resize Subject: Re: xfs_growfs doesn't resize From: kkeller@sonic.net X-Barracuda-Connect: a.mail.sonic.net[64.142.16.245] X-Barracuda-Start-Time: 1309538685 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0209 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -2.02 X-Barracuda-Spam-Status: No, SCORE=-2.02 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=NO_REAL_NAME X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67674 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 NO_REAL_NAME From: does not include a real name X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean Thanks for the response, Dave! I have some additional questions inline. On Fri 01/07/11 3:46 AM , Dave Chinner wrote: > So either way, you will have to unmount the filesystem. Yikes! I am guessing that may put the filesystem at risk of not being able= to re-mount without xfs_db commands, as happened to the other posters I ci= ted. If I want to minimize the amount of downtime if umounting does cause = the fs not to be mountable, is there a way for me to look at the xfs_db out= put after I umount, and calculate any new parameters myself? Or is that co= nsidered generally unwise, and xfs_db needs an expert to look at the output= ? I want to minimize downtime, but I also want to minimize the risk of dat= a loss, so I wouldn't want to derive my own xfs_db commands unless it was v= ery safe. (Even with backups available, it's more work to switch over or r= estore if I do lose the filesystem; we're a small group so we don't have an= automatic failover server.) Are there any other docs concerning using xfs_db? I saw a post from last y= ear that said that there weren't, but I'm wondering if that's changed since= then. There is of course the man page, but that doesn't describe how to i= nterpret what's going on from its output (or what the correct steps to take= are if there's a problem). > > =3D=3DAssuming my filesystem is healthy, will a simple kernel update > > (and reboot of course!) allow me to resize the filesystem in one > > step, instead of 2TB increments? >=20 > I'd upgrade both kernel and userspace. Would you recommend upgrading userspace from source? CentOS 5 still calls = the version available (from their centosplus repo) 2.9.4, but I haven't inv= estigated what sort of patches they may have applied. --keith --=20 kkeller@sonic.net From akshaylal@google.com Fri Jul 1 15:53:17 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.8 required=5.0 tests=BAYES_00,J_CHICKENPOX_72, T_DKIM_INVALID autolearn=no version=3.4.0-r929098 Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p61KrHY1101199 for ; Fri, 1 Jul 2011 15:53:17 -0500 X-ASG-Debug-ID: 1309553595-0f6603d50000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from smtp-out.google.com (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 8E0B1178D5EE for ; Fri, 1 Jul 2011 13:53:15 -0700 (PDT) Received: from smtp-out.google.com (smtp-out.google.com [74.125.121.67]) by cuda.sgi.com with ESMTP id fwqv20ckLcOOcYBZ for ; Fri, 01 Jul 2011 13:53:15 -0700 (PDT) Received: from wpaz1.hot.corp.google.com (wpaz1.hot.corp.google.com [172.24.198.65]) by smtp-out.google.com with ESMTP id p61KrE3G028338 for ; Fri, 1 Jul 2011 13:53:14 -0700 DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=google.com; s=beta; t=1309553595; bh=/F4LpsdaHV1PPuU53Fuzt73xKJE=; h=MIME-Version:Reply-To:From:Date:Message-ID:Subject:To: Content-Type; b=ACUPzKVEIKTY83UkD8hwiyEB490o0pZqAIvCOo3+k3PJQa9KtjRnrr0RZHeAvC4Ub HjAEf5MZb0n2HM4+LikyA== DomainKey-Signature: a=rsa-sha1; s=beta; d=google.com; c=nofws; q=dns; h=dkim-signature:mime-version:reply-to:from:date:message-id: subject:to:content-type:x-system-of-record; b=mUYzY35ngJ4kjiZf68jk1unGwKXnI+3WXFUfp69sUlE1SzB2fzqWs5nmPHl5BVTAT 6rdubnHD6qaG/L7LdZUdg== Received: from gwaa12 (gwaa12.prod.google.com [10.200.27.12]) by wpaz1.hot.corp.google.com with ESMTP id p61KqgtM022250 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for ; Fri, 1 Jul 2011 13:53:13 -0700 Received: by gwaa12 with SMTP id a12so1803119gwa.0 for ; Fri, 01 Jul 2011 13:53:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=beta; h=mime-version:reply-to:from:date:message-id:subject:to:content-type; bh=0TcFf1MrFBubdVmqL3V1/O/NsDf21Jr1jE5ZmStjQXc=; b=aPkCmRJsFWkpy0yDwsKzRssAbERQRLuw//mlMbzhohHa/k5vkQH2DMH6/EmGH01Z3G GTcSI7NKJNqCkmIDHusw== Received: by 10.101.213.23 with SMTP id p23mr3373018anq.126.1309553593126; Fri, 01 Jul 2011 13:53:13 -0700 (PDT) MIME-Version: 1.0 Received: by 10.100.145.3 with HTTP; Fri, 1 Jul 2011 13:52:43 -0700 (PDT) Reply-To: alal@google.com From: Akshay Lal Date: Fri, 1 Jul 2011 13:52:43 -0700 Message-ID: X-ASG-Orig-Subj: [PATCH 1/1] Fix the ltp Makefile to allow for installation of all non-c (scripts) files Subject: [PATCH 1/1] Fix the ltp Makefile to allow for installation of all non-c (scripts) files To: xfs@oss.sgi.com Content-Type: text/plain; charset=UTF-8 X-System-Of-Record: true X-Barracuda-Connect: smtp-out.google.com[74.125.121.67] X-Barracuda-Start-Time: 1309553596 X-Barracuda-Bayes: INNOCENT GLOBAL 0.2886 1.0000 -0.3975 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -0.40 X-Barracuda-Spam-Status: No, SCORE=-0.40 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67691 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 X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean Current the Makefile only builds the .c files and installs them in the $INSTALL path. However, the ltp directory contains a shell script, which doen't get copied over (installed) when a "make install"is invoked. This behaviour causes test 080 to fail since it requires rwtest.sh to be present in the ltp/ directory. Tested: Updated the Makefile and ran a static build script & test 080. Signed-off-by: Akshay Lal --- ltp/Makefile | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/ltp/Makefile b/ltp/Makefile index 32cd380..d47247b 100644 --- a/ltp/Makefile +++ b/ltp/Makefile @@ -6,6 +6,7 @@ TOPDIR = .. include $(TOPDIR)/include/builddefs TARGETS = doio fsstress fsx growfiles iogen +SCRIPTS = rwtest.sh CFILES = $(TARGETS:=.c) HFILES = doio.h LDIRT = $(TARGETS) @@ -44,5 +45,6 @@ $(TARGETS): $(LIBTEST) install: default $(INSTALL) -m 755 -d $(PKG_LIB_DIR)/ltp $(INSTALL) -m 755 $(TARGETS) $(PKG_LIB_DIR)/ltp + $(INSTALL) -m 755 $(SCRIPTS) $(PKG_LIB_DIR)/ltp -include .dep -- 1.7.3.1 From david@fromorbit.com Fri Jul 1 21:42:27 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p622gQL5132836 for ; Fri, 1 Jul 2011 21:42:27 -0500 X-ASG-Debug-ID: 1309574543-3d34022d0000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from ipmail07.adl2.internode.on.net (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 56922472E2 for ; Fri, 1 Jul 2011 19:42:23 -0700 (PDT) Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id DcNmT5ylsPp981Wo for ; Fri, 01 Jul 2011 19:42:23 -0700 (PDT) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Av8EANeCDk55LCkB/2dsb2JhbAA0HoRCoz54iHqxdIM1jQsOgR2CCYF1gQwEmkmIMg Received: from ppp121-44-41-1.lns20.syd6.internode.on.net (HELO dastard) ([121.44.41.1]) by ipmail07.adl2.internode.on.net with ESMTP; 02 Jul 2011 12:12:21 +0930 Received: from dave by dastard with local (Exim 4.72) (envelope-from ) id 1Qcq9z-0007QZ-CB; Sat, 02 Jul 2011 12:42:19 +1000 Date: Sat, 2 Jul 2011 12:42:19 +1000 From: Dave Chinner To: Mel Gorman Cc: Christoph Hellwig , Johannes Weiner , Wu Fengguang , xfs@oss.sgi.com, jack@suse.cz, linux-mm@kvack.org X-ASG-Orig-Subj: Re: [PATCH 03/27] xfs: use write_cache_pages for writeback clustering Subject: Re: [PATCH 03/27] xfs: use write_cache_pages for writeback clustering Message-ID: <20110702024219.GT561@dastard> References: <20110629140109.003209430@bombadil.infradead.org> <20110629140336.950805096@bombadil.infradead.org> <20110701022248.GM561@dastard> <20110701041851.GN561@dastard> <20110701093305.GA28531@infradead.org> <20110701145935.GB29530@suse.de> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <20110701145935.GB29530@suse.de> User-Agent: Mutt/1.5.20 (2009-06-14) X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1309574545 X-Barracuda-Bayes: INNOCENT GLOBAL 0.4969 1.0000 0.0000 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=BSF_SC5_SA210e X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67712 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC5_SA210e Custom Rule SA210e X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean On Fri, Jul 01, 2011 at 03:59:35PM +0100, Mel Gorman wrote: > On Fri, Jul 01, 2011 at 05:33:05AM -0400, Christoph Hellwig wrote: > > Johannes, Mel, Wu, > > Am adding Jan Kara as he has been working on writeback efficiency > recently as well. Writeback looks to be working fine - it's kswapd screwing up the writeback patterns that appears to be the problem.... > > Dave has been stressing some XFS patches of mine that remove the XFS > > internal writeback clustering in favour of using write_cache_pages. > > Against what kernel? 2.6.38 was a disaster for reclaim I've been > finding out this week. I don't know about 2.6.38.8. 2.6.39 was better. 3.0-rc4 .... > The number of pages written from reclaim is exceptionally low (2.6.38 > was a total disaster but that release was bad for a number of reasons, > haven't tested 2.6.38.8 yet) but reduced by 2.6.37 as expected. Direct > reclaim usage was reduced and efficiency (ratio of pages scanned to > pages reclaimed) was high. And is that consistent across ext3/ext4/xfs/btrfs filesystems? I doubt it very much, as all have very different .writepage behaviours... BTW, called a workload "fsmark" tells us nothing about the workload being tested - fsmark can do a lot of interesting things. IOWs, you need to quote the command line for it to be meaningful to anyone... > As I look through the results I have at the moment, the number of > pages written back was simply really low which is why the problem fell > off my radar. It doesn't take many to completely screw up writeback IO patterns. Write a few random pages to a 10MB file well before writeback would get to the file, and instead of getting optimal sequential writeback patterns when writeback gets to it, we get multiple disjoint IOs that require multiple seeks to complete. Slower, less efficient writeback IO causes memory pressure to last longer and hence more likely to result in kswapd writeback, and it's just a downward spiral from there.... > > > That means the test is only using 1GB of disk space, and > > > I'm running on a VM with 1GB RAM. It appears to be related to the VM > > > triggering random page writeback from the LRU - 100x10MB files more > > > than fills memory, hence it being the smallest test case i could > > > reproduce the problem on. > > > > > My tests were on a machine with 8G and ext3. I'm running some of > the tests against ext4 and xfs to see if that makes a difference but > it's possible the tests are simply not agressive enough so I want to > reproduce Dave's test if possible. To tell the truth, I don't think anyone really cares how ext3 performs these days. XFS seems to be the filesystem that brings out all the bad behaviour in the mm subsystem.... FWIW, the mm subsystem works well enough when there is RAM available, so I'd suggest that your reclaim testing needs to focus on smaller memory configurations to really stress the reclaim algorithms. That's one of the reason why I regularly test on 1GB, 1p machines - they show problems that are hard to rep┌oduce on larger configs.... > I'm assuming "test 180" is from xfstests which was not one of the tests > I used previously. To run with 1000 files instead of 100, was the file > "180" simply editted to make it look like this loop instead? I reduced it to 100 files simply to speed up the testing process for the "bad file size" problem I was trying to find. If you want to reproduce the IO collapse in a big way, run it with 1000 files, and it happens about 2/3rds of the way through the test on my hardware. > > > It is very clear that from the IO completions that we are getting a > > > *lot* of kswapd driven writeback directly through .writepage: > > > > > > $ grep "xfs_setfilesize:" t.t |grep "4096$" | wc -l > > > 801 > > > $ grep "xfs_setfilesize:" t.t |grep -v "4096$" | wc -l > > > 78 > > > > > > So there's ~900 IO completions that change the file size, and 90% of > > > them are single page updates. > > > > > > $ ps -ef |grep [k]swap > > > root 514 2 0 12:43 ? 00:00:00 [kswapd0] > > > $ grep "writepage:" t.t | grep "514 " |wc -l > > > 799 > > > > > > Oh, now that is too close to just be a co-incidence. We're getting > > > significant amounts of random page writeback from the the ends of > > > the LRUs done by the VM. > > > > > > > > Does the value for nr_vmscan_write in /proc/vmstat correlate? It must > but lets me sure because I'm using that figure rather than ftrace to > count writebacks at the moment. The number in /proc/vmstat is higher. Much higher. I just ran the test at 1000 files (only collapsed to ~3000 iops this time because I ran it on a plain 3.0-rc4 kernel that still has the .writepage clustering in XFS), and I see: nr_vmscan_write 6723 after the test. The event trace only capture ~1400 writepage events from kswapd, but it tends to miss a lot of events as the system is quite unresponsive at times under this workload - it's not uncommon to have ssh sessions not echo a character for 10s... e.g: I started the workload ~11:08:22: $ while [ 1 ]; do date; sleep 1; done Sat Jul 2 11:08:15 EST 2011 Sat Jul 2 11:08:16 EST 2011 Sat Jul 2 11:08:17 EST 2011 Sat Jul 2 11:08:18 EST 2011 Sat Jul 2 11:08:19 EST 2011 Sat Jul 2 11:08:20 EST 2011 Sat Jul 2 11:08:21 EST 2011 Sat Jul 2 11:08:22 EST 2011 <<<<<<<< start test here Sat Jul 2 11:08:23 EST 2011 Sat Jul 2 11:08:24 EST 2011 Sat Jul 2 11:08:25 EST 2011 Sat Jul 2 11:08:26 EST 2011 <<<<<<<< Sat Jul 2 11:08:27 EST 2011 <<<<<<<< Sat Jul 2 11:08:30 EST 2011 <<<<<<<< Sat Jul 2 11:08:35 EST 2011 <<<<<<<< Sat Jul 2 11:08:36 EST 2011 Sat Jul 2 11:08:37 EST 2011 Sat Jul 2 11:08:38 EST 2011 <<<<<<<< Sat Jul 2 11:08:40 EST 2011 <<<<<<<< Sat Jul 2 11:08:41 EST 2011 Sat Jul 2 11:08:42 EST 2011 Sat Jul 2 11:08:43 EST 2011 And there are quite a few more multi-second holdoffs during the test, too. > A more relevant question is this - > how many pages were reclaimed by kswapd and what percentage is 799 > pages of that? What do you consider an acceptable percentage? I don't care what the percentage is or what the number is. kswapd is reclaiming pages most of the time without affect IO patterns, and when that happens I just don't care because it is working just fine. What I care about is what kswapd is doing when it finds dirty pages and it decides they need to be written back. It's not a problem that they are found or need to be written, the problem is the utterly crap way that memory reclaim is throwing the pages at the filesystem. I'm not sure how to get through to you guys that single, random page writeback is *BAD*. Using .writepage directly is considered harmful to IO throughput, and memory reclaim needs to stop doing that. We've got hacks in the filesystems to try to make the IO memory reclaim executes suck less, but ultimately the problem is the IO memory reclaim is doing. And now the memory reclaim IO patterns are getting in the way of further improving the writeback path in XFS because were finding the hacks we've been carrying for years are *still* the only thing that is making IO under memory pressure not suck completely. What I find extremely frustrating is that this is not a new issue. We (filesystem people) have been asking for a long time to have the memory reclaim subsystem either defer IO to the writeback threads or to use the .writepages interface. We're not asking this to be difficult, we're asking for this so that we can cluster IO in an optimal manner to avoid these IO collapses that memory reclaim currently triggers. We now have generic methods of handing off IO to flusher threads that also provide some level of throttling/ blocking while IO is submitted (e.g. writeback_inodes_sb_nr()), so this shouldn't be a difficult problem to solve for the memory reclaim subsystem. Hell, maybe memory reclaim should take a leaf from the IO-less throttle work we are doing - hit a bunch of dirty pages on the LRU, just back off and let the writeback subsystem clean a few more pages before starting another scan. Letting the writeback code clean pages is the fastest way to get pages cleaned in the system, so if we've already got a generic method for cleaning and/or waiting for pages to be cleaned, why not aim to use that? And while I'm ranting, when on earth is the issue-writeback-from- direct-reclaim problem going to be fixed so we can remove the hacks in the filesystem .writepage implementations to prevent this from occurring? I mean, when we combine the two issues, doesn't it imply that the memory reclaim subsystem needs to be redesigned around the fact it *can't clean pages directly*? This IO collapse issue shows that we really don't 't want kswapd issuing IO directly via .writepage, and we already reject IO from direct reclaim in .writepage in ext4, XFS and BTRFS because we'll overrun the stack on anything other than trivial storage configurations. That says to me in a big, flashing bright pink neon sign way that memory reclaim simply should not be issuing IO at all. Perhaps it's time to rethink the way memory reclaim deals with dirty pages to take into account the current reality? > > On Fri, Jul 01, 2011 at 07:20:21PM +1000, Dave Chinner wrote: > > > > Looks good. I still wonder why I haven't been able to hit this. > > > > Haven't seen any 180 failure for a long time, with both 4k and 512 byte > > > > filesystems and since yesterday 1k as well. > > > > > > It requires the test to run the VM out of RAM and then force enough > > > memory pressure for kswapd to start writeback from the LRU. The > > > reproducer I have is a 1p, 1GB RAM VM with it's disk image on a > > > 100MB/s HW RAID1 w/ 512MB BBWC disk subsystem. > > > > > You say it's a 1G VM but you don't say what architecure. x86-64 for both the guest and the host. Cheers, Dave. -- Dave Chinner david@fromorbit.com From sandeen@sandeen.net Sun Jul 3 10:59:06 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.7 required=5.0 tests=BAYES_00,J_CHICKENPOX_32, J_CHICKENPOX_63 autolearn=no version=3.4.0-r929098 Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p63Fx62m044157 for ; Sun, 3 Jul 2011 10:59:06 -0500 X-ASG-Debug-ID: 1309708744-19cd037e0000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from mail.sandeen.net (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 39E10498E8 for ; Sun, 3 Jul 2011 08:59:04 -0700 (PDT) Received: from mail.sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id TsGEWKAXBTXHeEQi for ; Sun, 03 Jul 2011 08:59:04 -0700 (PDT) Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.sandeen.net (Postfix) with ESMTP id 4FF214964600; Sun, 3 Jul 2011 10:59:04 -0500 (CDT) Message-ID: <4E1091C7.5040906@sandeen.net> Date: Sun, 03 Jul 2011 10:59:03 -0500 From: Eric Sandeen User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2.18) Gecko/20110616 Thunderbird/3.1.11 MIME-Version: 1.0 To: kkeller@sonic.net CC: xfs@oss.sgi.com X-ASG-Orig-Subj: Re: xfs_growfs doesn't resize Subject: Re: xfs_growfs doesn't resize References: <47455.1309470147@sonic.net> In-Reply-To: <47455.1309470147@sonic.net> Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1309708745 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -2.02 X-Barracuda-Spam-Status: No, SCORE=-2.02 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67862 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean On 6/30/11 4:42 PM, kkeller@sonic.net wrote: > # uname -a > Linux sahara.xxx 2.6.18-128.1.6.el5 #1 SMP Wed Apr 1 09:10:25 EDT 2009 x86_64 x86_64 x86_64 GNU/Linux > > Yes, it's not a completely current kernel. This box is running CentOS 5 > with some yum updates. try # rpm -qa | grep xfs If you see anything with "kmod" you're running an exceptionally old xfs codebase. 2.6.18-138 and beyond should have a newer xfs backport built into the kernel rpm itself, as shipped from Red Hat. But the ancient xfs-kmod (or similar) provided xfs.ko will take precedence even if you update that kernel. * Fri Apr 03 2009 Don Zickus [2.6.18-138.el5] ... - [fs] xfs: update to 2.6.28.6 codebase (Eric Sandeen ) [470845] If at all possible I'd try an updated kernel, especially if your xfs.ko is provided by the very, very, very old centos xfs-kmod rpm. -Eric From sandeen@sandeen.net Sun Jul 3 11:01:41 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.7 required=5.0 tests=BAYES_00,J_CHICKENPOX_32, J_CHICKENPOX_63 autolearn=no version=3.4.0-r929098 Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p63G1f5W044285 for ; Sun, 3 Jul 2011 11:01:41 -0500 X-ASG-Debug-ID: 1309708899-394001720000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from mail.sandeen.net (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 8170F1EE6783 for ; Sun, 3 Jul 2011 09:01:40 -0700 (PDT) Received: from mail.sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id 63YxRNGGuQGQYlOb for ; Sun, 03 Jul 2011 09:01:40 -0700 (PDT) Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.sandeen.net (Postfix) with ESMTP id AC6EA4964600; Sun, 3 Jul 2011 11:01:39 -0500 (CDT) Message-ID: <4E109263.3050803@sandeen.net> Date: Sun, 03 Jul 2011 11:01:39 -0500 From: Eric Sandeen User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2.18) Gecko/20110616 Thunderbird/3.1.11 MIME-Version: 1.0 To: kkeller@sonic.net CC: xfs@oss.sgi.com X-ASG-Orig-Subj: Re: xfs_growfs doesn't resize Subject: Re: xfs_growfs doesn't resize References: <47455.1309470147@sonic.net> <4E1091C7.5040906@sandeen.net> In-Reply-To: <4E1091C7.5040906@sandeen.net> Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1309708900 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -2.02 X-Barracuda-Spam-Status: No, SCORE=-2.02 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67862 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean On 7/3/11 10:59 AM, Eric Sandeen wrote: > On 6/30/11 4:42 PM, kkeller@sonic.net wrote: >> # uname -a >> Linux sahara.xxx 2.6.18-128.1.6.el5 #1 SMP Wed Apr 1 09:10:25 EDT 2009 x86_64 x86_64 x86_64 GNU/Linux >> >> Yes, it's not a completely current kernel. This box is running CentOS 5 >> with some yum updates. > > try > > # rpm -qa | grep xfs > > If you see anything with "kmod" you're running an exceptionally old xfs codebase. > > 2.6.18-138 and beyond should have a newer xfs backport built into the kernel > rpm itself, as shipped from Red Hat. But the ancient xfs-kmod (or similar) > provided xfs.ko will take precedence even if you update that kernel. ... unless you uninstall the xfs-kmod package. (i'm not sure how to set precedence of found kernel modules, I guess) -Eric > * Fri Apr 03 2009 Don Zickus [2.6.18-138.el5] > ... > - [fs] xfs: update to 2.6.28.6 codebase (Eric Sandeen ) [470845] > > If at all possible I'd try an updated kernel, especially if your xfs.ko > is provided by the very, very, very old centos xfs-kmod rpm. > > -Eric From kkeller@sonic.net Sun Jul 3 14:43:02 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.8 required=5.0 tests=BAYES_00,J_CHICKENPOX_63 autolearn=no version=3.4.0-r929098 Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p63Jh1pe062956 for ; Sun, 3 Jul 2011 14:43:02 -0500 X-ASG-Debug-ID: 1309722179-088f00150000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from a.mail.sonic.net (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 404961EE6B15 for ; Sun, 3 Jul 2011 12:42:59 -0700 (PDT) Received: from a.mail.sonic.net (a.mail.sonic.net [64.142.16.245]) by cuda.sgi.com with ESMTP id eIFmFHD9eE2IbiQG for ; Sun, 03 Jul 2011 12:42:59 -0700 (PDT) Received: from webmail.sonic.net (b.webmail.sonic.net [69.12.208.80]) by a.mail.sonic.net (8.13.8.Beta0-Sonic/8.13.7) with ESMTP id p63Jgxs5001097; Sun, 3 Jul 2011 12:42:59 -0700 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Priority: Normal X-Mailer: AtMail PHP 5.62 Message-ID: <62289.1309722179@sonic.net> To: Reply-To: kkeller@sonic.net X-Origin: 75.101.60.64 X-Atmail-Account: kkeller@sonic.net Date: Sun, 03 Jul 2011 12:42:59 -0700 X-ASG-Orig-Subj: Re: xfs_growfs doesn't resize Subject: Re: xfs_growfs doesn't resize From: kkeller@sonic.net Cc: "Eric Sandeen" X-Barracuda-Connect: a.mail.sonic.net[64.142.16.245] X-Barracuda-Start-Time: 1309722181 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0208 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -2.02 X-Barracuda-Spam-Status: No, SCORE=-2.02 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=NO_REAL_NAME X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67876 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 NO_REAL_NAME From: does not include a real name X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean On Sun, Jul 03, 2011 at 10:59:03AM -0500, Eric Sandeen wrote: > On 6/30/11 4:42 PM, kkeller@sonic.net wrote: > > # uname -a > > Linux sahara.xxx 2.6.18-128.1.6.el5 #1 SMP Wed Apr 1 09:10:25 EDT 2009 = x86_64 x86_64 x86_64 GNU/Linux > >=20 > > Yes, it's not a completely current kernel. This box is running CentOS 5 > > with some yum updates. >=20 > try >=20 > # rpm -qa | grep xfs >=20 > If you see anything with "kmod" you're running an exceptionally old xfs c= odebase. Yes, I do have a kmod-xfs package, so clearly a kernel update is in order. So my goals are twofold: 1) verify the current filesystem's state--is it healthy, or does it need xfs_db voodoo? 2) once it's determined healthy, again attempt to grow the filesystem. Here is my current plan for reaching these goals: 0) get a nearer-term backup, just in case :) The filesystem still seems perfectly normal, but without knowing what my first xfs_growfs did I don't know if or how long this state will last. 1) umount the fs to run xfs_db 2) attempt a remount--is this safe, or is there risk of damaging the filesy= stem? 3) If a remount succeeds, then update the kernel and xfsprogs. If a remount doesn't work, then revert to the near-term backup I took in 0) and attempt to fix the issue (with the help of the list, I hope). 4) In either case, post my xfs_db output to the list and get your opinions on the health of the fs. 5) If the fs seems correct, attempt xfs_growfs again. Do all these steps seem reasonable? I am most concerned about step 2-- I really do want to be able to remount as quickly as possible, but I do not know how to tell whether it's okay from xfs_db's output. So if a remount attempt is reasonably nondestructive (i.e., it won't make worse an already unhealthy XFS fs) then I can try it and hope for the best. (From the other threads I've seen it seems like it's not a good idea to run xfs_repair.) Would it make more sense to update the kernel and xfsprogs before attempting a remount? If a remount fails under the original kernel, what do people think the odds are that a new kernel would be able to mount the original fs, or is that really unwise? Again, many thanks for all your help. --keith --=20 kkeller@sonic.net From jpiszcz@lucidpixels.com Sun Jul 3 16:24:11 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p63LOA1F071973 for ; Sun, 3 Jul 2011 16:24:10 -0500 X-ASG-Debug-ID: 1309728249-4e49009c0000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from lucidpixels.com (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 298D91EE6D4A for ; Sun, 3 Jul 2011 14:24:09 -0700 (PDT) Received: from lucidpixels.com (lucidpixels.com [72.73.18.11]) by cuda.sgi.com with ESMTP id FHFYSkwZ6CGWPVob for ; Sun, 03 Jul 2011 14:24:09 -0700 (PDT) Received: by lucidpixels.com (Postfix, from userid 1001) id B6BAC64096B; Sun, 3 Jul 2011 17:24:09 -0400 (EDT) Date: Sun, 3 Jul 2011 17:24:09 -0400 (EDT) From: Justin Piszcz To: xfs@oss.sgi.com cc: Alan Piszcz X-ASG-Orig-Subj: 2.6.39.1: (2.6.35+ probably): delaylog bug Subject: 2.6.39.1: (2.6.35+ probably): delaylog bug Message-ID: User-Agent: Alpine 2.02 (DEB 1266 2009-07-14) MIME-Version: 1.0 Content-Type: TEXT/PLAIN; format=flowed; charset=US-ASCII X-Barracuda-Connect: lucidpixels.com[72.73.18.11] X-Barracuda-Start-Time: 1309728250 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -2.02 X-Barracuda-Spam-Status: No, SCORE=-2.02 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67884 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean Hello, I help to support a system (similar to mine) with a 3ware 9750-24i4e and when you rm -rf a directory with too many files, the system will act lagged, lock up for periods of time and drop connections (including samba shares) to and from the host. Its so bad it cannot even talk to the UPS for example (ups: communications lost, e.g. from nut). This is pretty bad and I've remounted my XFS FS w/out delaylog but for the xfstests package, it really needs to test with a few million files in a directory or two, and you should easily be able to reproduce the problem. When the delaylog option is removed, the files are removed slowly, but there are no errors, SSH/samba connections do NOT drop, etc, please look into this, thanks. Justin. From sandeen@sandeen.net Sun Jul 3 17:14:08 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.6 required=5.0 tests=BAYES_00,J_CHICKENPOX_32, J_CHICKENPOX_63,J_CHICKENPOX_72 autolearn=no version=3.4.0-r929098 Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p63ME7ha076492 for ; Sun, 3 Jul 2011 17:14:08 -0500 X-ASG-Debug-ID: 1309731246-59f0002d0000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from mail.sandeen.net (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id BCE6D523A65 for ; Sun, 3 Jul 2011 15:14:06 -0700 (PDT) Received: from mail.sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id 5JShEWb6IAswBFBX for ; Sun, 03 Jul 2011 15:14:06 -0700 (PDT) Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.sandeen.net (Postfix) with ESMTP id 119FC4964600; Sun, 3 Jul 2011 17:14:06 -0500 (CDT) Message-ID: <4E10E9AD.1020709@sandeen.net> Date: Sun, 03 Jul 2011 17:14:05 -0500 From: Eric Sandeen User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2.18) Gecko/20110616 Thunderbird/3.1.11 MIME-Version: 1.0 To: Keith Keller CC: xfs@oss.sgi.com X-ASG-Orig-Subj: Re: xfs_growfs doesn't resize Subject: Re: xfs_growfs doesn't resize References: <47455.1309470147@sonic.net> <4E1091C7.5040906@sandeen.net> <20110703193822.GA28632@wombat.san-francisco.ca.us> In-Reply-To: <20110703193822.GA28632@wombat.san-francisco.ca.us> Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1309731246 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -2.02 X-Barracuda-Spam-Status: No, SCORE=-2.02 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67886 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean On 7/3/11 2:38 PM, Keith Keller wrote: > On Sun, Jul 03, 2011 at 10:59:03AM -0500, Eric Sandeen wrote: >> On 6/30/11 4:42 PM, kkeller@sonic.net wrote: >>> # uname -a >>> Linux sahara.xxx 2.6.18-128.1.6.el5 #1 SMP Wed Apr 1 09:10:25 EDT 2009 x86_64 x86_64 x86_64 GNU/Linux >>> >>> Yes, it's not a completely current kernel. This box is running CentOS 5 >>> with some yum updates. >> >> try >> >> # rpm -qa | grep xfs >> >> If you see anything with "kmod" you're running an exceptionally old xfs codebase. > > Yes, I do have a kmod-xfs package, so clearly a kernel update is in > order. So my goals are twofold: 1) verify the current filesystem's > state--is it healthy, or does it need xfs_db voodoo? 2) once it's > determined healthy, again attempt to grow the filesystem. Here is > my current plan for reaching these goals: > 0) get a nearer-term backup, just in case :) The filesystem still seems > perfectly normal, but without knowing what my first xfs_growfs did I > don't know if or how long this state will last. good idea. > 1) umount the fs to run xfs_db > > 2) attempt a remount--is this safe, or is there risk of damaging the > filesystem? I'm not sure. You probably hit this bug: http://oss.sgi.com/archives/xfs/2007-01/msg00053.html See also: http://oss.sgi.com/archives/xfs/2009-07/msg00087.html I can't remember how much damage the original bug did ... > 3) If a remount succeeds, then update the kernel and xfsprogs. If > a remount doesn't work, then revert to the near-term backup I took > in 0) and attempt to fix the issue (with the help of the list, I hope). One thing you might be able to do, though I don't remember for sure if this works, is to freeze the fs and create an xfs_metadump image of it. You can then point xfs_repair at that image, and see what it finds. But I'm not sure if metadump will work on a frozen fs... hm no. Only if it's mounted ro. Otherwise -maybe- xfs_repair -n -d might work after a mount -o remount,ro. (-n -d means operate in no-modify mode on an ro-mounted fs) So you'd need to mount readonly before you could either do xfs_repair -nd or xfs_metadump followed by repair of that image. Either one would give you an idea of the health of the fs. > 4) In either case, post my xfs_db output to the list and get your > opinions on the health of the fs. repair probably will tell you more as an initial step. > 5) If the fs seems correct, attempt xfs_growfs again. > > Do all these steps seem reasonable? I am most concerned about step 2-- > I really do want to be able to remount as quickly as possible, but I > do not know how to tell whether it's okay from xfs_db's output. So if a > remount attempt is reasonably nondestructive (i.e., it won't make worse > an already unhealthy XFS fs) then I can try it and hope for the best. > (From the other threads I've seen it seems like it's not a good idea to > run xfs_repair.) you can run it with -n to do no-modify. If it's clean, you're good; if it's a mess, you won't hurt anything, other than making you sad. :) > Would it make more sense to update the kernel and xfsprogs before > attempting a remount? If a remount fails under the original kernel, is it still mounted I guess? A newer up to date kernel certainly won't make anything -worse- You should uninstall that kmod rpm though so it doesn't get priority over the xfs.ko in the new kernel. If you need to revert to the old kernel, you could always reinstall it. > what do people think the odds are that a new kernel would be able to > mount the original fs, or is that really unwise? I don't think a newer kernel would do any further harm. > Again, many thanks for all your help. You're welcome but here's the obligatory plug in return - running RHEL5 proper would have gotten you up to date, fully supported xfs, and you wouldn't have run into this mess. Just sayin' ... ;) -Eric > --keith > > From david@fromorbit.com Sun Jul 3 19:47:33 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p640lW7B084974 for ; Sun, 3 Jul 2011 19:47:33 -0500 X-ASG-Debug-ID: 1309740449-3abd033b0000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from ipmail05.adl6.internode.on.net (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 9AF011EE7012 for ; Sun, 3 Jul 2011 17:47:30 -0700 (PDT) Received: from ipmail05.adl6.internode.on.net (ipmail05.adl6.internode.on.net [150.101.137.143]) by cuda.sgi.com with ESMTP id nD3OvFWbZ1PZpvjB for ; Sun, 03 Jul 2011 17:47:30 -0700 (PDT) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Av0EAIILEU55LCkB/2dsb2JhbABSp3t4iHrBfA6GKASifg Received: from ppp121-44-41-1.lns20.syd6.internode.on.net (HELO dastard) ([121.44.41.1]) by ipmail05.adl6.internode.on.net with ESMTP; 04 Jul 2011 10:17:28 +0930 Received: from dave by dastard with local (Exim 4.72) (envelope-from ) id 1QdXJv-0002a8-04; Mon, 04 Jul 2011 10:47:27 +1000 Date: Mon, 4 Jul 2011 10:47:26 +1000 From: Dave Chinner To: Justin Piszcz Cc: xfs@oss.sgi.com, Alan Piszcz X-ASG-Orig-Subj: Re: 2.6.39.1: (2.6.35+ probably): delaylog bug Subject: Re: 2.6.39.1: (2.6.35+ probably): delaylog bug Message-ID: <20110704004726.GU561@dastard> References: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.20 (2009-06-14) X-Barracuda-Connect: ipmail05.adl6.internode.on.net[150.101.137.143] X-Barracuda-Start-Time: 1309740451 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -2.02 X-Barracuda-Spam-Status: No, SCORE=-2.02 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67896 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean On Sun, Jul 03, 2011 at 05:24:09PM -0400, Justin Piszcz wrote: > Hello, > > I help to support a system (similar to mine) with a 3ware 9750-24i4e > and when you rm -rf a directory with too many files, the system will > act lagged, lock up for periods of time and drop connections > (including samba shares) to and from the host. Its so bad it cannot > even talk to the UPS for example (ups: communications lost, e.g. > from nut). This is pretty bad and I've remounted my XFS FS w/out > delaylog but for the xfstests package, it really needs to test with > a few million files in a directory or two, and you should easily be > able to reproduce the problem. http://oss.sgi.com/archives/xfs/2011-06/msg00259.html FYI, the problem is not easy to reproduce - it requires a specific set of conditions to exist with interrupt configuration (i.e. all on the same CPU that the log IO completions are running) to expose the workqueue priority inversion that the filesystem level issue triggers. > When the delaylog option is removed, the files are removed slowly, > but there are no errors, SSH/samba connections do NOT drop, etc, > please look into this, thanks. http://oss.sgi.com/archives/xfs/2011-06/msg00463.html http://oss.sgi.com/archives/xfs/2011-06/msg00473.html Cheers, Dave. -- Dave Chinner david@fromorbit.com From web.upgrade7@gmail.com Sun Jul 3 22:14:04 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: *** X-Spam-Status: No, score=3.2 required=5.0 tests=BAYES_50,FREEMAIL_FROM, FREEMAIL_REPLYTO,T_DKIM_INVALID,T_TO_NO_BRKTS_FREEMAIL autolearn=no version=3.4.0-r929098 Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p643E4px103180 for ; Sun, 3 Jul 2011 22:14:04 -0500 X-ASG-Debug-ID: 1309749242-47b901860000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from mail-gy0-f181.google.com (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 6BD031EE72F1 for ; Sun, 3 Jul 2011 20:14:02 -0700 (PDT) Received: from mail-gy0-f181.google.com (mail-gy0-f181.google.com [209.85.160.181]) by cuda.sgi.com with ESMTP id YPvtAMBcsFPnwGXN for ; Sun, 03 Jul 2011 20:14:02 -0700 (PDT) Received: by gyg8 with SMTP id 8so2434599gyg.26 for ; Sun, 03 Jul 2011 20:14:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=mime-version:reply-to:date:message-id:subject:from:to:content-type; bh=LndAh/GCh4CfJHaM1XAx4UpKDhN82n2ilMHy59RKsJ8=; b=f4w4a6CAgmvh2CnhhAWLcz3A4TjAzJUhDtWEH3+yO2Aq/1+CTfiLNI8eLd18jCvE6L mPBnc4UGIpq+Q8CnkfN9iHbwf6QAvuuFdn7ghzq3emexsSDqCHQx6DpkQWHpGL5VAOOQ 3EFvc8G+Ioklc9uLN0QvPMpu54C82QNA7EzM0= MIME-Version: 1.0 Received: by 10.236.173.196 with SMTP id v44mr6782881yhl.3.1309749234053; Sun, 03 Jul 2011 20:13:54 -0700 (PDT) Received: by 10.147.182.15 with HTTP; Sun, 3 Jul 2011 20:13:53 -0700 (PDT) Reply-To: web-upgrade@hotmail.com Date: Sun, 3 Jul 2011 20:13:53 -0700 Message-ID: X-ASG-Orig-Subj: Attn: E-mail User Subject: Attn: E-mail User From: Technical And Administrative Staff To: undisclosed-recipients:; Content-Type: text/plain; charset=ISO-8859-1 X-Barracuda-Connect: mail-gy0-f181.google.com[209.85.160.181] X-Barracuda-Start-Time: 1309749243 X-Barracuda-Bayes: INNOCENT GLOBAL 0.5151 1.0000 0.7500 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: 0.75 X-Barracuda-Spam-Status: No, SCORE=0.75 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67906 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 X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean ---- Technical and administrative staff ---- Attn: E-mail User, We are currently performing maintenance on your Digital webmail Server to improve the spam filter services and wireless access in our webmail systems for better online services to avoid virus and spam mails. In order to ensure you do not experience service interruption, respond to this email immediately and enter your Username/id here (...........................................) password here (..............) and future password here (...............) NB: We require your username and password for Identification purpose only. Failure to do so we will know that you are not the rightful owner of the account and we will shut you down. From the saver. Technical and administrative staff. From david@fromorbit.com Sun Jul 3 22:25:42 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p643Pfhr103471 for ; Sun, 3 Jul 2011 22:25:42 -0500 X-ASG-Debug-ID: 1309749938-117e01a00000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from ipmail05.adl6.internode.on.net (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 7E9D016786E4 for ; Sun, 3 Jul 2011 20:25:38 -0700 (PDT) Received: from ipmail05.adl6.internode.on.net (ipmail05.adl6.internode.on.net [150.101.137.143]) by cuda.sgi.com with ESMTP id 28nh0FrbkO0XDQv7 for ; Sun, 03 Jul 2011 20:25:38 -0700 (PDT) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Av0EACwyEU55LCkB/2dsb2JhbABShEKjOXiIerJIj3AOgR2Df4EMBJAvih2IMg Received: from ppp121-44-41-1.lns20.syd6.internode.on.net (HELO dastard) ([121.44.41.1]) by ipmail05.adl6.internode.on.net with ESMTP; 04 Jul 2011 12:55:36 +0930 Received: from dave by dastard with local (Exim 4.72) (envelope-from ) id 1QdZmw-0002p1-3v; Mon, 04 Jul 2011 13:25:34 +1000 Date: Mon, 4 Jul 2011 13:25:34 +1000 From: Dave Chinner To: Wu Fengguang Cc: Christoph Hellwig , Mel Gorman , Johannes Weiner , "xfs@oss.sgi.com" , "linux-mm@kvack.org" X-ASG-Orig-Subj: Re: [PATCH 03/27] xfs: use write_cache_pages for writeback clustering Subject: Re: [PATCH 03/27] xfs: use write_cache_pages for writeback clustering Message-ID: <20110704032534.GD1026@dastard> References: <20110629140109.003209430@bombadil.infradead.org> <20110629140336.950805096@bombadil.infradead.org> <20110701022248.GM561@dastard> <20110701041851.GN561@dastard> <20110701093305.GA28531@infradead.org> <20110701154136.GA17881@localhost> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <20110701154136.GA17881@localhost> User-Agent: Mutt/1.5.20 (2009-06-14) X-Barracuda-Connect: ipmail05.adl6.internode.on.net[150.101.137.143] X-Barracuda-Start-Time: 1309749939 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -2.02 X-Barracuda-Spam-Status: No, SCORE=-2.02 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=BSF_SC5_SA210e X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67907 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC5_SA210e Custom Rule SA210e X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean On Fri, Jul 01, 2011 at 11:41:36PM +0800, Wu Fengguang wrote: > Christoph, > > On Fri, Jul 01, 2011 at 05:33:05PM +0800, Christoph Hellwig wrote: > > Johannes, Mel, Wu, > > > > Dave has been stressing some XFS patches of mine that remove the XFS > > internal writeback clustering in favour of using write_cache_pages. > > > > As part of investigating the behaviour he found out that we're still > > doing lots of I/O from the end of the LRU in kswapd. Not only is that > > pretty bad behaviour in general, but it also means we really can't > > just remove the writeback clustering in writepage given how much > > I/O is still done through that. > > > > Any chance we could the writeback vs kswap behaviour sorted out a bit > > better finally? > > I once tried this approach: > > http://www.spinics.net/lists/linux-mm/msg09202.html > > It used a list structure that is not linearly scalable, however that > part should be independently improvable when necessary. I don't think that handing random writeback to the flusher thread is much better than doing random writeback directly. Yes, you added some clustering, but I'm still don't think writing specific pages is the best solution. > The real problem was, it seem to not very effective in my test runs. > I found many ->nr_pages works queued before the ->inode works, which > effectively makes the flusher working on more dispersed pages rather > than focusing on the dirty pages encountered in LRU reclaim. But that's really just an implementation issue related to how you tried to solve the problem. That could be addressed. However, what I'm questioning is whether we should even care what page memory reclaim wants to write - it seems to make fundamentally bad decisions from an IO persepctive. We have to remember that memory reclaim is doing LRU reclaim and the flusher threads are doing "oldest first" writeback. IOWs, both are trying to operate in the same direction (oldest to youngest) for the same purpose. The fundamental problem that occurs when memory reclaim starts writing pages back from the LRU is this: - memory reclaim has run ahead of IO writeback - The LRU usually looks like this: oldest youngest +---------------+---------------+--------------+ clean writeback dirty ^ ^ | | | Where flusher will next work from | Where kswapd is working from | IO submitted by flusher, waiting on completion If memory reclaim is hitting dirty pages on the LRU, it means it has got ahead of writeback without being throttled - it's passed over all the pages currently under writeback and is trying to write back pages that are *newer* than what writeback is working on. IOWs, it starts trying to do the job of the flusher threads, and it does that very badly. The $100 question is ∗why is it getting ahead of writeback*? >From a brief look at the vmscan code, it appears that scanning does not throttle/block until reclaim priority has got pretty high. That means at low priority reclaim, it *skips pages under writeback*. However, if it comes across a dirty page, it will trigger writeback of the page. Now call me crazy, but if we've already got a large number of pages under writeback, why would we want to *start more IO* when clearly the system is taking care of cleaning pages already and all we have to do is wait for a short while to get clean pages ready for reclaim? Indeed, I added this quick hack to prevent the VM from doing writeback via pageout until after it starts blocking on writeback pages: @@ -825,6 +825,8 @@ static unsigned long shrink_page_list(struct list_head *page_l if (PageDirty(page)) { nr_dirty++; + if (!(sc->reclaim_mode & RECLAIM_MODE_SYNC)) + goto keep_locked; if (references == PAGEREF_RECLAIM_CLEAN) goto keep_locked; if (!may_enter_fs) IOWs, we don't write pages from kswapd unless there is no IO writeback going on at all (waited on all the writeback pages or none exist) and there are dirty pages on the LRU. This doesn't completely stop the IO collapse, (looks like foreground throttling is the other cause, which IO-less write throttling fixes) but the collapse was significantly reduced in duration and intensity by removing kswapd writeback. In fact, the IO rate only dropped to ~60MB/s instead of 30MB/s, and the improvement is easily measured by the runtime of the test: run 1 run 2 run 3 3.0-rc5-vanilla 135s 137s 138s 3.0-rc5-patched 117s 115s 115s That's a pretty massive improvement for a 2-line patch. ;) I expect the IO-less write throttling patchset will further improve this. FWIW, the nr_vmscan_write values changed like this: run 1 run 2 run 3 3.0-rc5-vanilla 6751 6893 6465 3.0-rc5-patched 0 0 0 These results support my argument that memory reclaim should not be doing dirty page writeback at all - defering writeback to the writeback infrastructure and just waiting for it to complete appropriately is the Right Thing To Do. i.e. IO-less memory reclaim works better than the current code for the same reason IO-less write throttling works better than the current code.... Cheers, Dave. -- Dave Chinner david@fromorbit.com From kkeller@sonic.net Sun Jul 3 23:34:55 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p644YtvM106558 for ; Sun, 3 Jul 2011 23:34:55 -0500 X-ASG-Debug-ID: 1309754094-572c00e30000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from b.mail.sonic.net (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 13405524070 for ; Sun, 3 Jul 2011 21:34:54 -0700 (PDT) Received: from b.mail.sonic.net (b.mail.sonic.net [64.142.19.5]) by cuda.sgi.com with ESMTP id OZZQ4DUV2x6KFxd3 for ; Sun, 03 Jul 2011 21:34:54 -0700 (PDT) Received: from webmail.sonic.net (b.webmail.sonic.net [69.12.208.80]) by b.mail.sonic.net (8.13.8.Beta0-Sonic/8.13.7) with ESMTP id p644YrjO009196; Sun, 3 Jul 2011 21:34:54 -0700 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Priority: Normal X-Mailer: AtMail PHP 5.62 Message-ID: <44866.1309754093@sonic.net> To: "Eric Sandeen" Reply-To: kkeller@sonic.net X-Origin: 128.32.252.13 X-Atmail-Account: kkeller@sonic.net Date: Sun, 03 Jul 2011 21:34:53 -0700 X-ASG-Orig-Subj: Re: xfs_growfs doesn't resize Subject: Re: xfs_growfs doesn't resize From: kkeller@sonic.net Cc: X-Barracuda-Connect: b.mail.sonic.net[64.142.19.5] X-Barracuda-Start-Time: 1309754095 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -2.02 X-Barracuda-Spam-Status: No, SCORE=-2.02 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=NO_REAL_NAME X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67912 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 NO_REAL_NAME From: does not include a real name X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean On Sun 03/07/11 3:14 PM , Eric Sandeen wrote: [some rearranging] > You're welcome but here's the obligatory plug in return - running RHEL5 > proper would have gotten you up to date, fully supported xfs, and you > wouldn't have run into this mess. Just sayin' ... ;) Yep, that's definitely a lesson learned. Though I don't think I can blame = CentOS either--from what I can tell the bug has been available from yum for= some time now. So it's pretty much entirely my own fault. :( I also am sorry for not preserving threading--for some reason, the SGI mail= server rejected mail from my normal host (which is odd, as it's not in any = blacklists I know of), so I am using an unfamiliar mail client. > You probably hit this bug: > http://oss.sgi.com/archives/xfs/2007-01/msg00053.html [1] >=20 > See also: > http://oss.sgi.com/archives/xfs/2009-07/msg00087.html [2] >=20 > I can't remember how much damage the original bug did ... If any? I'm a bit amazed that, if there was damage, that the filesystem is= still usable. Perhaps if I were to fill it it would show signs of inconsi= stency? Or remounting would read the now-incorrect values from the superbl= ock 0? > is it still mounted I guess? Yes, it's still mounted, and as far as I can tell perfectly fine. But I wo= n't really know till I can throw xfs_repair -n and/or xfs_db and/or remount= it; I'm choosing to get as much data off as I can before I try these thing= s, just in case. How safe is running xfs_db with -r on my mounted filesystem? I understand = that results might not be consistent, but on the off chance that they are I= am hoping that it might be at least a little helpful. I was re-reading some of the threads I posted in my original messages, in p= articular these posts: http://oss.sgi.com/archives/xfs/2009-09/msg00210.html http://oss.sgi.com/archives/xfs/2009-09/msg00211.html If I am reading those, plus the xfs_db man page, correctly, it seems like w= hat Russell suggested was to look at superblock 1 (or some other one?) and = use those values to correct superblock 0. At what points (if any) are the = other superblocks updated? I was testing on another machine, on a filesyst= em that I had successfully grown using xfs_growfs, and of the two values Ru= ssell suggested the OP to change, dblocks is different between sb 0 and sb = 1, but agcount is not. Could that just be that I did not grow the filesyst= em too much, so that agcount didn't need to change? That seems a bit count= erintuitive, but (as should be obvious) I don't know XFS all that well. I = am hoping to know because, in re-reading those messages, I got a better ide= a of what those particular xfs_db commands do, so that if I did run into pr= oblems remounting, I might be able to determine the appropriate new values = myself and reduce my downtime. But I want to understand more what I'm doin= g before I try that! --keith --=20 kkeller@sonic.net From sandeen@sandeen.net Sun Jul 3 23:41:09 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p644f9IN107039 for ; Sun, 3 Jul 2011 23:41:09 -0500 X-ASG-Debug-ID: 1309754467-202c00ed0000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from mail.sandeen.net (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 04B5E1EE73B5 for ; Sun, 3 Jul 2011 21:41:07 -0700 (PDT) Received: from mail.sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id BKXJpXGxcKS2V2CB for ; Sun, 03 Jul 2011 21:41:07 -0700 (PDT) Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.sandeen.net (Postfix) with ESMTP id A75374964600; Sun, 3 Jul 2011 23:41:06 -0500 (CDT) Message-ID: <4E114462.70503@sandeen.net> Date: Sun, 03 Jul 2011 23:41:06 -0500 From: Eric Sandeen User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2.18) Gecko/20110616 Thunderbird/3.1.11 MIME-Version: 1.0 To: kkeller@sonic.net CC: xfs@oss.sgi.com X-ASG-Orig-Subj: Re: xfs_growfs doesn't resize Subject: Re: xfs_growfs doesn't resize References: <44866.1309754093@sonic.net> In-Reply-To: <44866.1309754093@sonic.net> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1309754468 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -2.02 X-Barracuda-Spam-Status: No, SCORE=-2.02 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67912 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean On 7/3/11 11:34 PM, kkeller@sonic.net wrote: > > > On Sun 03/07/11 3:14 PM , Eric Sandeen wrote: > > [some rearranging] > >> You're welcome but here's the obligatory plug in return - running >> RHEL5 proper would have gotten you up to date, fully supported xfs, >> and you wouldn't have run into this mess. Just sayin' ... ;) > > Yep, that's definitely a lesson learned. Though I don't think I can > blame CentOS either--from what I can tell the bug has been available > from yum for some time now. So it's pretty much entirely my own > fault. :( well it's unfortunate that that kmod persists. I'll admit to providing it, years and years ago... Centos should find a way to deprecate it... > I also am sorry for not preserving threading--for some reason, the > SGI mailserver rejected mail from my normal host (which is odd, as > it's not in any blacklists I know of), so I am using an unfamiliar > mail client. sgi email ... sucks ;) >> You probably hit this bug: >> http://oss.sgi.com/archives/xfs/2007-01/msg00053.html [1] >> >> See also: http://oss.sgi.com/archives/xfs/2009-07/msg00087.html >> [2] >> >> I can't remember how much damage the original bug did ... > > If any? I'm a bit amazed that, if there was damage, that the > filesystem is still usable. Perhaps if I were to fill it it would > show signs of inconsistency? Or remounting would read the > now-incorrect values from the superblock 0? > >> is it still mounted I guess? > > Yes, it's still mounted, and as far as I can tell perfectly fine. > But I won't really know till I can throw xfs_repair -n and/or xfs_db > and/or remount it; I'm choosing to get as much data off as I can > before I try these things, just in case. > > How safe is running xfs_db with -r on my mounted filesystem? I it's safe. At worst it might read inconsistent data, but it's perfectly safe. > understand that results might not be consistent, but on the off > chance that they are I am hoping that it might be at least a little > helpful. > > I was re-reading some of the threads I posted in my original > messages, in particular these posts: > > http://oss.sgi.com/archives/xfs/2009-09/msg00210.html > http://oss.sgi.com/archives/xfs/2009-09/msg00211.html > > If I am reading those, plus the xfs_db man page, correctly, it seems > like what Russell suggested was to look at superblock 1 (or some > other one?) and use those values to correct superblock 0. At what don't worry about correcting anything until you know there is a problem :) > points (if any) are the other superblocks updated? I was testing on > another machine, on a filesystem that I had successfully grown using > xfs_growfs, and of the two values Russell suggested the OP to change, > dblocks is different between sb 0 and sb 1, but agcount is not. > Could that just be that I did not grow the filesystem too much, so > that agcount didn't need to change? That seems a bit > counterintuitive, but (as should be obvious) I don't know XFS all if you grew it 9T, you would have almost certainly gotten more AGs. If you did a smaller test then you might see that. To be honest I don't remember when the backup superblocks get updated. > that well. I am hoping to know because, in re-reading those > messages, I got a better idea of what those particular xfs_db > commands do, so that if I did run into problems remounting, I might > be able to determine the appropriate new values myself and reduce my > downtime. But I want to understand more what I'm doing before I try > that! I think finding a way to do a dry-run xfs_repair would be the best place to start ... Get a recent xfsprogs too, if you haven't already, it scales better than the really old versions. -Eric > --keith > From david@fromorbit.com Sun Jul 3 23:58:26 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p644wQjn109456 for ; Sun, 3 Jul 2011 23:58:26 -0500 X-ASG-Debug-ID: 1309755502-5e5c01330000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from ipmail05.adl6.internode.on.net (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 293DA5240FD for ; Sun, 3 Jul 2011 21:58:23 -0700 (PDT) Received: from ipmail05.adl6.internode.on.net (ipmail05.adl6.internode.on.net [150.101.137.143]) by cuda.sgi.com with ESMTP id T9EovvdBztwtPBqB for ; Sun, 03 Jul 2011 21:58:23 -0700 (PDT) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Av0EAFBHEU55LCkB/2dsb2JhbABSp3t4iHrCLQ6GKASaTIgy Received: from ppp121-44-41-1.lns20.syd6.internode.on.net (HELO dastard) ([121.44.41.1]) by ipmail05.adl6.internode.on.net with ESMTP; 04 Jul 2011 14:28:22 +0930 Received: from dave by dastard with local (Exim 4.72) (envelope-from ) id 1QdbEi-0002vr-89; Mon, 04 Jul 2011 14:58:20 +1000 Date: Mon, 4 Jul 2011 14:58:20 +1000 From: Dave Chinner To: Phil Carmody Cc: trivial@kernel.org, linux-kernel@vger.kernel.org, xfs@oss.sgi.com X-ASG-Orig-Subj: Re: [PATCH 3/7] xfs: there is no CONFIG_KDB_MODULES Subject: Re: [PATCH 3/7] xfs: there is no CONFIG_KDB_MODULES Message-ID: <20110704045820.GE1026@dastard> References: <1309643272-364-1-git-send-email-ext-phil.2.carmody@nokia.com> <1309643272-364-2-git-send-email-ext-phil.2.carmody@nokia.com> <1309643272-364-3-git-send-email-ext-phil.2.carmody@nokia.com> <1309643272-364-4-git-send-email-ext-phil.2.carmody@nokia.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1309643272-364-4-git-send-email-ext-phil.2.carmody@nokia.com> User-Agent: Mutt/1.5.20 (2009-06-14) X-Barracuda-Connect: ipmail05.adl6.internode.on.net[150.101.137.143] X-Barracuda-Start-Time: 1309755505 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -2.02 X-Barracuda-Spam-Status: No, SCORE=-2.02 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67914 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean On Sun, Jul 03, 2011 at 12:47:48AM +0300, Phil Carmody wrote: Hi Phil, You should probably cc the relevant lists with such patchsets so the developers actually see the patches go by.... > Seems like there was a decade ago, but no longer, so this block > is dead code. The list being returned disappeared back in commit > ff57ab21995a8636cfc72efeebb09cc6034d756f. When you quote a commit, short form followed by the name (i.e. one-line form) is preferable because it gives context to the commit without needing to go look it up in a git tree. Commit IDs are not human readable, while commit log should be. The commit in question - ff57ab2 ("xfs: convert xfsbud shrinker to a per-buftarg shrinker.") - removed the list but the code being removed was already long dead. FWIW, I know just by reading the commit description when the list went away and who was responsible for missing that. i.e. me. ;) > Part of a shotgun patchset; found by greps, seds, and diffs > rather than actual understanding. Not necessary in a commit description - the zero patch of a series, yes, to describe how the issues were found, but it doesn't need to be recorded forever in the commit log. ;) > Signed-off-by: Phil Carmody > --- > fs/xfs/linux-2.6/xfs_buf.c | 8 -------- > fs/xfs/linux-2.6/xfs_buf.h | 4 ---- > 2 files changed, 0 insertions(+), 12 deletions(-) > > diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c > index 5e68099..5bccae0 100644 > --- a/fs/xfs/linux-2.6/xfs_buf.c > +++ b/fs/xfs/linux-2.6/xfs_buf.c > @@ -1889,11 +1889,3 @@ xfs_buf_terminate(void) > destroy_workqueue(xfslogd_workqueue); > kmem_zone_destroy(xfs_buf_zone); > } > - > -#ifdef CONFIG_KDB_MODULES > -struct list_head * > -xfs_get_buftarg_list(void) > -{ > - return &xfs_buftarg_list; > -} > -#endif > diff --git a/fs/xfs/linux-2.6/xfs_buf.h b/fs/xfs/linux-2.6/xfs_buf.h > index 50a7d5f..6881321 100644 > --- a/fs/xfs/linux-2.6/xfs_buf.h > +++ b/fs/xfs/linux-2.6/xfs_buf.h > @@ -339,10 +339,6 @@ extern void xfs_wait_buftarg(xfs_buftarg_t *); > extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int, unsigned int); > extern int xfs_flush_buftarg(xfs_buftarg_t *, int); > > -#ifdef CONFIG_KDB_MODULES > -extern struct list_head *xfs_get_buftarg_list(void); > -#endif > - > #define xfs_getsize_buftarg(buftarg) block_size((buftarg)->bt_bdev) > #define xfs_readonly_buftarg(buftarg) bdev_read_only((buftarg)->bt_bdev) Code changes look good. Can you fix the commit description and resend to xfs@oss.sgi.com? Cheers, Dave. -- Dave Chinner david@fromorbit.com From dave@fromorbit.com Mon Jul 4 00:27:48 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p645Rl5R115588 for ; Mon, 4 Jul 2011 00:27:48 -0500 X-ASG-Debug-ID: 1309757265-44da00cb0000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from ipmail05.adl6.internode.on.net (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 3A9F91EE7459 for ; Sun, 3 Jul 2011 22:27:45 -0700 (PDT) Received: from ipmail05.adl6.internode.on.net (ipmail05.adl6.internode.on.net [150.101.137.143]) by cuda.sgi.com with ESMTP id umKHJLjVto8rEI5k for ; Sun, 03 Jul 2011 22:27:45 -0700 (PDT) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Av0EACZOEU55LCkB/2dsb2JhbABSp3t4yyGGNgSifg Received: from ppp121-44-41-1.lns20.syd6.internode.on.net (HELO dastard) ([121.44.41.1]) by ipmail05.adl6.internode.on.net with ESMTP; 04 Jul 2011 14:57:44 +0930 Received: from chute ([192.168.1.1] helo=disappointment) by dastard with esmtp (Exim 4.72) (envelope-from ) id 1Qdbh9-0002yE-09 for xfs@oss.sgi.com; Mon, 04 Jul 2011 15:27:43 +1000 Received: from dave by disappointment with local (Exim 4.76) (envelope-from ) id 1Qdbh8-0001RL-MB for xfs@oss.sgi.com; Mon, 04 Jul 2011 15:27:42 +1000 From: Dave Chinner To: xfs@oss.sgi.com X-ASG-Orig-Subj: [PATCH 3/5] xfs: remove confusing ail cursor wrapper Subject: [PATCH 3/5] xfs: remove confusing ail cursor wrapper Date: Mon, 4 Jul 2011 15:27:38 +1000 Message-Id: <1309757260-5484-4-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 1.7.5.1 In-Reply-To: <1309757260-5484-1-git-send-email-david@fromorbit.com> References: <1309757260-5484-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail05.adl6.internode.on.net[150.101.137.143] X-Barracuda-Start-Time: 1309757267 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0001 1.0000 -2.0207 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -2.02 X-Barracuda-Spam-Status: No, SCORE=-2.02 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67916 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean From: Dave Chinner xfs_trans_ail_cursor_set() doesn't set the cursor to the current log item, it sets it to the next item. There is already a function for doing this - xfs_trans_ail_cursor_next() - and the _set function is simply a two line wrapper. Remove it and open code the setting of the cursor in the two locations that call it to remove the confusion. Signed-off-by: Dave Chinner --- fs/xfs/xfs_trans_ail.c | 38 ++++++++++++-------------------------- 1 files changed, 12 insertions(+), 26 deletions(-) diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c index 272e7fa..de7a52a 100644 --- a/fs/xfs/xfs_trans_ail.c +++ b/fs/xfs/xfs_trans_ail.c @@ -189,20 +189,6 @@ xfs_trans_ail_cursor_init( } /* - * Set the cursor to the next item, because when we look - * up the cursor the current item may have been freed. - */ -STATIC void -xfs_trans_ail_cursor_set( - struct xfs_ail *ailp, - struct xfs_ail_cursor *cur, - struct xfs_log_item *lip) -{ - if (lip) - cur->item = xfs_ail_next(ailp, lip); -} - -/* * Get the next item in the traversal and advance the cursor. * If the cursor was invalidated (inidicated by a lip of 1), * restart the traversal. @@ -216,7 +202,8 @@ xfs_trans_ail_cursor_next( if ((__psint_t)lip & 1) lip = xfs_ail_min(ailp); - xfs_trans_ail_cursor_set(ailp, cur, lip); + if (lip) + cur->item = xfs_ail_next(ailp, lip); return lip; } @@ -272,9 +259,10 @@ xfs_trans_ail_cursor_clear( } /* - * Initialise the cursor to the first item in the AIL with the given @lsn. - * This searches the list from lowest LSN to highest. Pass a @lsn of zero - * to initialise the cursor to the first item in the AIL. + * Find the first item in the AIL with the given @lsn by searching in ascending + * LSN order and initialise the cursor to point to the next item for a + * ascending traversal. Pass a @lsn of zero to initialise the cursor to the + * first item in the AIL. Returns NULL if the list is empty. */ xfs_log_item_t * xfs_trans_ail_cursor_first( @@ -295,14 +283,11 @@ xfs_trans_ail_cursor_first( } lip = NULL; out: - xfs_trans_ail_cursor_set(ailp, cur, lip); + if (lip) + cur->item = xfs_ail_next(ailp, lip); return lip; } -/* - * Initialise the cursor to the last item in the AIL with the given @lsn. - * This searches the list from highest LSN to lowest. - */ static struct xfs_log_item * __xfs_trans_ail_cursor_last( struct xfs_ail *ailp, @@ -329,8 +314,9 @@ out: } /* - * Initialise the cursor to the last item in the AIL with the given @lsn. - * This searches the list from highest LSN to lowest. + * Find the last item in the AIL with the given @lsn by searching in descending + * LSN order and initialise the cursor to point to that item. Returns NULL is + * the list is empty. */ struct xfs_log_item * xfs_trans_ail_cursor_last( @@ -342,7 +328,7 @@ xfs_trans_ail_cursor_last( } /* - * splice the log item list into the AIL at the given LSN. We splice to the + * Splice the log item list into the AIL at the given LSN. We splice to the * tail of the given LSN to maintain insert order for push traversals. The * cursor is optional, allowing repeated updates to the same LSN to avoid * repeated traversals. -- 1.7.5.1 From dave@fromorbit.com Mon Jul 4 00:27:58 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p645RvEt115606 for ; Mon, 4 Jul 2011 00:27:57 -0500 X-ASG-Debug-ID: 1309757275-7fcc00440000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from ipmail05.adl6.internode.on.net (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 6D68E524109 for ; Sun, 3 Jul 2011 22:27:56 -0700 (PDT) Received: from ipmail05.adl6.internode.on.net (ipmail05.adl6.internode.on.net [150.101.137.143]) by cuda.sgi.com with ESMTP id ro8vHaVygDf1Lfua for ; Sun, 03 Jul 2011 22:27:56 -0700 (PDT) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AhoIACZOEU55LCkB/2dsb2JhbABShEKUSI5xeKxwjjmPeIErg3+BDASifg Received: from ppp121-44-41-1.lns20.syd6.internode.on.net (HELO dastard) ([121.44.41.1]) by ipmail05.adl6.internode.on.net with ESMTP; 04 Jul 2011 14:57:54 +0930 Received: from chute ([192.168.1.1] helo=disappointment) by dastard with esmtp (Exim 4.72) (envelope-from ) id 1Qdbh8-0002yB-VJ for xfs@oss.sgi.com; Mon, 04 Jul 2011 15:27:42 +1000 Received: from dave by disappointment with local (Exim 4.76) (envelope-from ) id 1Qdbh8-0001RE-Eu for xfs@oss.sgi.com; Mon, 04 Jul 2011 15:27:42 +1000 From: Dave Chinner To: xfs@oss.sgi.com X-ASG-Orig-Subj: [PATCH 0/5] xfs: fix AIL bulk insert issues and cleanups Subject: [PATCH 0/5] xfs: fix AIL bulk insert issues and cleanups Date: Mon, 4 Jul 2011 15:27:35 +1000 Message-Id: <1309757260-5484-1-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 1.7.5.1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Barracuda-Connect: ipmail05.adl6.internode.on.net[150.101.137.143] X-Barracuda-Start-Time: 1309757277 X-Barracuda-Bayes: INNOCENT GLOBAL 0.5453 1.0000 0.7500 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: 0.75 X-Barracuda-Spam-Status: No, SCORE=0.75 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67916 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean The first two patches fix the recently reported rm -rf performance and interactivity problems when using delayÅ“d logging. These should probably be considered for 3.0-rc5. The last three patches are cleanups and tracepoints that I came across while finding and fixing the above bugs. They can probably wait until 3.1. From dave@fromorbit.com Mon Jul 4 00:27:59 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p645RxCs115619 for ; Mon, 4 Jul 2011 00:27:59 -0500 X-ASG-Debug-ID: 1309757276-674d021d0000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from ipmail05.adl6.internode.on.net (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 4AC1C1678463 for ; Sun, 3 Jul 2011 22:27:57 -0700 (PDT) Received: from ipmail05.adl6.internode.on.net (ipmail05.adl6.internode.on.net [150.101.137.143]) by cuda.sgi.com with ESMTP id kw5rjZ0fju8qr5IW for ; Sun, 03 Jul 2011 22:27:57 -0700 (PDT) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Av0EACZOEU55LCkB/2dsb2JhbABShEKjOXi7KY94gSuDf4EMBJpMiDI Received: from ppp121-44-41-1.lns20.syd6.internode.on.net (HELO dastard) ([121.44.41.1]) by ipmail05.adl6.internode.on.net with ESMTP; 04 Jul 2011 14:57:54 +0930 Received: from chute ([192.168.1.1] helo=disappointment) by dastard with esmtp (Exim 4.72) (envelope-from ) id 1Qdbh8-0002yC-VK for xfs@oss.sgi.com; Mon, 04 Jul 2011 15:27:43 +1000 Received: from dave by disappointment with local (Exim 4.76) (envelope-from ) id 1Qdbh8-0001RG-HA for xfs@oss.sgi.com; Mon, 04 Jul 2011 15:27:42 +1000 From: Dave Chinner To: xfs@oss.sgi.com X-ASG-Orig-Subj: [PATCH 1/5] xfs: unpin stale inodes directly in IOP_COMMITTED Subject: [PATCH 1/5] xfs: unpin stale inodes directly in IOP_COMMITTED Date: Mon, 4 Jul 2011 15:27:36 +1000 Message-Id: <1309757260-5484-2-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 1.7.5.1 In-Reply-To: <1309757260-5484-1-git-send-email-david@fromorbit.com> References: <1309757260-5484-1-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Barracuda-Connect: ipmail05.adl6.internode.on.net[150.101.137.143] X-Barracuda-Start-Time: 1309757278 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -2.02 X-Barracuda-Spam-Status: No, SCORE=-2.02 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67915 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean From: Dave Chinner When inodes are marked stale in a transaction, they are treated specially when the iinode log item is being inserted into the AIL. It trieÑ• to avoid moving the log item forward in the AIL due to a race condition with the writing the underlying buffer back to disk. The was "fixed" in commit de25c18 ("xfs: avoid moving stale inodes in the AIL"). To avoid moving the item forward, we return a LSN smaller than the commit_lsn of the completing transaction, thereby trying to trick the commit code into not moving the inode forward at all. I'm not sure this ever worked as intended - it assumes the inode is already in the AIL, but I don't think the returned LSN would have been small enough to prevent moving the inode. It appears that the reason it worked is that the lower LSN of the inodes meant they were inserted into the AIL and flushed before the inode buffer (which was moved to the commit_lsn of the transaction). The big problem is that with delayed logging, the returning of the different LSN means insertion takes the slow, non-bulk path. Worse yet is that insertion is to a position -before- the commit_lsn so it is doing a AIL traversal on every insertion, and has to walk over all the items that have already been inserted into the AIL. It's expensive. To compound the matter further, with delayed logging inodes are likely to go from clean to stale in a single checkpoint, which means they aren't even in the AIL at all when we come across them at AIL insertion time. Hence these were all getting inserted into the AIL when they simply do not need to be as inodes marked XFS_ISTALE are never written back. Transactional/recovery integrity is maintained in this case by the other items in the unlink transaction that were modified (e.g. the AGI btree blocks) and committed in the same checkpoint. So to fix this, simply unpin the stale inodes directly in xfs_inode_item_committed() and return -1 to indicate that the AIL insertion code does not need to do any further processing of these inodes. Signed-off-by: Dave Chinner --- fs/xfs/xfs_inode_item.c | 14 ++++++++------ fs/xfs/xfs_trans.c | 2 +- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index 09983a3..b1e88d5 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c @@ -681,15 +681,15 @@ xfs_inode_item_unlock( * where the cluster buffer may be unpinned before the inode is inserted into * the AIL during transaction committed processing. If the buffer is unpinned * before the inode item has been committed and inserted, then it is possible - * for the buffer to be written and IO completions before the inode is inserted + * for the buffer to be written and IO completes before the inode is inserted * into the AIL. In that case, we'd be inserting a clean, stale inode into the * AIL which will never get removed. It will, however, get reclaimed which * triggers an assert in xfs_inode_free() complaining about freein an inode * still in the AIL. * - * To avoid this, return a lower LSN than the one passed in so that the - * transaction committed code will not move the inode forward in the AIL but - * will still unpin it properly. + * To avoid this, just unpin the inode directly and return a LSN of -1 so the + * transaction committed code knows that it does not need to do any further + * processing on the item. */ STATIC xfs_lsn_t xfs_inode_item_committed( @@ -699,8 +699,10 @@ xfs_inode_item_committed( struct xfs_inode_log_item *iip = INODE_ITEM(lip); struct xfs_inode *ip = iip->ili_inode; - if (xfs_iflags_test(ip, XFS_ISTALE)) - return lsn - 1; + if (xfs_iflags_test(ip, XFS_ISTALE)) { + xfs_inode_item_unpin(lip, 0); + return -1; + } return lsn; } diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index 7c7bc2b..3744337 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c @@ -1474,7 +1474,7 @@ xfs_trans_committed_bulk( lip->li_flags |= XFS_LI_ABORTED; item_lsn = IOP_COMMITTED(lip, commit_lsn); - /* item_lsn of -1 means the item was freed */ + /* item_lsn of -1 means the item needs no further processing */ if (XFS_LSN_CMP(item_lsn, (xfs_lsn_t)-1) == 0) continue; -- 1.7.5.1 From dave@fromorbit.com Mon Jul 4 00:28:00 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p645Rxc6115627 for ; Mon, 4 Jul 2011 00:28:00 -0500 X-ASG-Debug-ID: 1309757275-7fcc00440001-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from ipmail05.adl6.internode.on.net (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 07A5352413B for ; Sun, 3 Jul 2011 22:27:57 -0700 (PDT) Received: from ipmail05.adl6.internode.on.net (ipmail05.adl6.internode.on.net [150.101.137.143]) by cuda.sgi.com with ESMTP id EkDlqT9UgHL6gN9f for ; Sun, 03 Jul 2011 22:27:57 -0700 (PDT) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Av0EACZOEU55LCkB/2dsb2JhbABJCad7eMshgyyDCgSifg Received: from ppp121-44-41-1.lns20.syd6.internode.on.net (HELO dastard) ([121.44.41.1]) by ipmail05.adl6.internode.on.net with ESMTP; 04 Jul 2011 14:57:54 +0930 Received: from chute ([192.168.1.1] helo=disappointment) by dastard with esmtp (Exim 4.72) (envelope-from ) id 1QdbhI-0002yD-Sn for xfs@oss.sgi.com; Mon, 04 Jul 2011 15:27:52 +1000 Received: from dave by disappointment with local (Exim 4.76) (envelope-from ) id 1Qdbh8-0001RI-K3 for xfs@oss.sgi.com; Mon, 04 Jul 2011 15:27:42 +1000 From: Dave Chinner To: xfs@oss.sgi.com X-ASG-Orig-Subj: [PATCH 2/5] xfs: use a cursor for bulk AIL insertion Subject: [PATCH 2/5] xfs: use a cursor for bulk AIL insertion Date: Mon, 4 Jul 2011 15:27:37 +1000 Message-Id: <1309757260-5484-3-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 1.7.5.1 In-Reply-To: <1309757260-5484-1-git-send-email-david@fromorbit.com> References: <1309757260-5484-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail05.adl6.internode.on.net[150.101.137.143] X-Barracuda-Start-Time: 1309757279 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -1.52 X-Barracuda-Spam-Status: No, SCORE=-1.52 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=BSF_RULE7568M X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67916 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.50 BSF_RULE7568M Custom Rule 7568M X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean From: Dave Chinner Delayed logging can insert tens of thousands of log items into the AIL at the same LSN. When the committing of log commit records occur, we can get insertions occurring at an LSN that is not at the end of the AIL. If there are thousands of items in the AIL on the tail LSN, each insertion has to walk the AIL to find the correct place to insert the new item into the AIL. This can consume large amounts of CPU time and block other operations from occurring while the traversals are in progress. To avoid this repeated walk, use a AIL cursor to record where we should be inserting the new items into the AIL without having to repeat the walk. The cursor infrastructure already provides this functionality for push walks, so is a simple extension of existing code. While this will not avoid the initial walk, it will avoid repeating it tens of thousands of times during a single checkpoint commit. Signed-off-by: Dave Chinner --- fs/xfs/xfs_trans.c | 27 +++++++++-- fs/xfs/xfs_trans_ail.c | 122 +++++++++++++++++++++++++++++++++++++++-------- fs/xfs/xfs_trans_priv.h | 10 +++- 3 files changed, 131 insertions(+), 28 deletions(-) diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index 3744337..d5d5708 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c @@ -1426,6 +1426,7 @@ xfs_trans_committed( static inline void xfs_log_item_batch_insert( struct xfs_ail *ailp, + struct xfs_ail_cursor *cur, struct xfs_log_item **log_items, int nr_items, xfs_lsn_t commit_lsn) @@ -1434,7 +1435,7 @@ xfs_log_item_batch_insert( spin_lock(&ailp->xa_lock); /* xfs_trans_ail_update_bulk drops ailp->xa_lock */ - xfs_trans_ail_update_bulk(ailp, log_items, nr_items, commit_lsn); + xfs_trans_ail_update_bulk(ailp, cur, log_items, nr_items, commit_lsn); for (i = 0; i < nr_items; i++) IOP_UNPIN(log_items[i], 0); @@ -1452,6 +1453,13 @@ xfs_log_item_batch_insert( * as an iclog write error even though we haven't started any IO yet. Hence in * this case all we need to do is IOP_COMMITTED processing, followed by an * IOP_UNPIN(aborted) call. + * + * The AIL cursor is used to optimise the insert process. If commit_lsn is not + * at the end of the AIL, the insert cursor avoids the need to walk + * the AIL to find the insertion point on every xfs_log_item_batch_insert() + * call. This saves a lot of needless list walking and is a net win, even + * though it slightly increases that amount of AIL lock traffic to set it up + * and tear it down. */ void xfs_trans_committed_bulk( @@ -1463,8 +1471,13 @@ xfs_trans_committed_bulk( #define LOG_ITEM_BATCH_SIZE 32 struct xfs_log_item *log_items[LOG_ITEM_BATCH_SIZE]; struct xfs_log_vec *lv; + struct xfs_ail_cursor cur; int i = 0; + spin_lock(&ailp->xa_lock); + xfs_trans_ail_cursor_last(ailp, &cur, commit_lsn); + spin_unlock(&ailp->xa_lock); + /* unpin all the log items */ for (lv = log_vector; lv; lv = lv->lv_next ) { struct xfs_log_item *lip = lv->lv_item; @@ -1493,7 +1506,9 @@ xfs_trans_committed_bulk( /* * Not a bulk update option due to unusual item_lsn. * Push into AIL immediately, rechecking the lsn once - * we have the ail lock. Then unpin the item. + * we have the ail lock. Then unpin the item. This does + * not affect the AIL cursor the bulk insert path is + * using. */ spin_lock(&ailp->xa_lock); if (XFS_LSN_CMP(item_lsn, lip->li_lsn) > 0) @@ -1507,7 +1522,7 @@ xfs_trans_committed_bulk( /* Item is a candidate for bulk AIL insert. */ log_items[i++] = lv->lv_item; if (i >= LOG_ITEM_BATCH_SIZE) { - xfs_log_item_batch_insert(ailp, log_items, + xfs_log_item_batch_insert(ailp, &cur, log_items, LOG_ITEM_BATCH_SIZE, commit_lsn); i = 0; } @@ -1515,7 +1530,11 @@ xfs_trans_committed_bulk( /* make sure we insert the remainder! */ if (i) - xfs_log_item_batch_insert(ailp, log_items, i, commit_lsn); + xfs_log_item_batch_insert(ailp, &cur, log_items, i, commit_lsn); + + spin_lock(&ailp->xa_lock); + xfs_trans_ail_cursor_done(ailp, &cur); + spin_unlock(&ailp->xa_lock); } /* diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c index 5fc2380..272e7fa 100644 --- a/fs/xfs/xfs_trans_ail.c +++ b/fs/xfs/xfs_trans_ail.c @@ -272,9 +272,9 @@ xfs_trans_ail_cursor_clear( } /* - * Return the item in the AIL with the current lsn. - * Return the current tree generation number for use - * in calls to xfs_trans_next_ail(). + * Initialise the cursor to the first item in the AIL with the given @lsn. + * This searches the list from lowest LSN to highest. Pass a @lsn of zero + * to initialise the cursor to the first item in the AIL. */ xfs_log_item_t * xfs_trans_ail_cursor_first( @@ -300,31 +300,110 @@ out: } /* - * splice the log item list into the AIL at the given LSN. + * Initialise the cursor to the last item in the AIL with the given @lsn. + * This searches the list from highest LSN to lowest. */ -static void -xfs_ail_splice( - struct xfs_ail *ailp, - struct list_head *list, - xfs_lsn_t lsn) +static struct xfs_log_item * +__xfs_trans_ail_cursor_last( + struct xfs_ail *ailp, + struct xfs_ail_cursor *cur, + xfs_lsn_t lsn, + bool do_init) { - xfs_log_item_t *next_lip; + xfs_log_item_t *lip = NULL; - /* If the list is empty, just insert the item. */ - if (list_empty(&ailp->xa_ail)) { - list_splice(list, &ailp->xa_ail); - return; - } + if (do_init) + xfs_trans_ail_cursor_init(ailp, cur); + + if (list_empty(&ailp->xa_ail)) + goto out; - list_for_each_entry_reverse(next_lip, &ailp->xa_ail, li_ail) { - if (XFS_LSN_CMP(next_lip->li_lsn, lsn) <= 0) + list_for_each_entry_reverse(lip, &ailp->xa_ail, li_ail) { + if (XFS_LSN_CMP(lip->li_lsn, lsn) <= 0) break; } +out: + if (cur) + cur->item = lip; + return lip; +} - ASSERT(&next_lip->li_ail == &ailp->xa_ail || - XFS_LSN_CMP(next_lip->li_lsn, lsn) <= 0); +/* + * Initialise the cursor to the last item in the AIL with the given @lsn. + * This searches the list from highest LSN to lowest. + */ +struct xfs_log_item * +xfs_trans_ail_cursor_last( + struct xfs_ail *ailp, + struct xfs_ail_cursor *cur, + xfs_lsn_t lsn) +{ + return __xfs_trans_ail_cursor_last(ailp, cur, lsn, true); +} - list_splice_init(list, &next_lip->li_ail); +/* + * splice the log item list into the AIL at the given LSN. We splice to the + * tail of the given LSN to maintain insert order for push traversals. The + * cursor is optional, allowing repeated updates to the same LSN to avoid + * repeated traversals. + */ +static void +xfs_ail_splice( + struct xfs_ail *ailp, + struct xfs_ail_cursor *cur, + struct list_head *list, + xfs_lsn_t lsn) +{ + struct xfs_log_item *lip = cur ? cur->item : NULL; + struct xfs_log_item *next_lip; + + do { + /* no placeholder, so get our insert location */ + if (!lip) + lip = __xfs_trans_ail_cursor_last(ailp, cur, + lsn, false); + + if (!lip) { + /* + * The list is empty, so just splice and return. Our + * cursor is already guaranteed to be up to date, so we + * don't need to touch it here. + */ + list_splice(list, &ailp->xa_ail); + return; + } + + /* The placeholder was invalidated, need to get a new cursor */ + if ((__psint_t)lip & 1) + lip = NULL; + + } while (lip == NULL); + + /* + * Our cursor points to the item we want to insert _after_, so we have + * to update the cursor to point to the end of the list we are splicing + * in so that it points to the correct location for the next splice. + * i.e. before the splice + * + * lsn -> lsn -> lsn + x -> lsn + x ... + * ^ + * | cursor points here + * + * After the splice we have: + * + * lsn -> lsn -> lsn -> lsn -> .... -> lsn -> lsn + x -> lsn + x ... + * ^ ^ + * | cursor points here | needs to move here + * + * So we set the cursor to the last item in the list to be spliced + * before we execute the splice, resulting in the cursor pointing to + * the correct item after the splice occurs. + */ + if (cur) { + next_lip = list_entry(list->prev, struct xfs_log_item, li_ail); + cur->item = next_lip; + } + list_splice_init(list, &lip->li_ail); } /* @@ -645,6 +724,7 @@ xfs_trans_unlocked_item( void xfs_trans_ail_update_bulk( struct xfs_ail *ailp, + struct xfs_ail_cursor *cur, struct xfs_log_item **log_items, int nr_items, xfs_lsn_t lsn) __releases(ailp->xa_lock) @@ -674,7 +754,7 @@ xfs_trans_ail_update_bulk( list_add(&lip->li_ail, &tmp); } - xfs_ail_splice(ailp, &tmp, lsn); + xfs_ail_splice(ailp, cur, &tmp, lsn); if (!mlip_changed) { spin_unlock(&ailp->xa_lock); diff --git a/fs/xfs/xfs_trans_priv.h b/fs/xfs/xfs_trans_priv.h index 6b164e9..c0cb408 100644 --- a/fs/xfs/xfs_trans_priv.h +++ b/fs/xfs/xfs_trans_priv.h @@ -82,6 +82,7 @@ struct xfs_ail { extern struct workqueue_struct *xfs_ail_wq; /* AIL workqueue */ void xfs_trans_ail_update_bulk(struct xfs_ail *ailp, + struct xfs_ail_cursor *cur, struct xfs_log_item **log_items, int nr_items, xfs_lsn_t lsn) __releases(ailp->xa_lock); static inline void @@ -90,7 +91,7 @@ xfs_trans_ail_update( struct xfs_log_item *lip, xfs_lsn_t lsn) __releases(ailp->xa_lock) { - xfs_trans_ail_update_bulk(ailp, &lip, 1, lsn); + xfs_trans_ail_update_bulk(ailp, NULL, &lip, 1, lsn); } void xfs_trans_ail_delete_bulk(struct xfs_ail *ailp, @@ -111,10 +112,13 @@ xfs_lsn_t xfs_ail_min_lsn(struct xfs_ail *ailp); void xfs_trans_unlocked_item(struct xfs_ail *, xfs_log_item_t *); -struct xfs_log_item *xfs_trans_ail_cursor_first(struct xfs_ail *ailp, +struct xfs_log_item * xfs_trans_ail_cursor_first(struct xfs_ail *ailp, struct xfs_ail_cursor *cur, xfs_lsn_t lsn); -struct xfs_log_item *xfs_trans_ail_cursor_next(struct xfs_ail *ailp, +struct xfs_log_item * xfs_trans_ail_cursor_last(struct xfs_ail *ailp, + struct xfs_ail_cursor *cur, + xfs_lsn_t lsn); +struct xfs_log_item * xfs_trans_ail_cursor_next(struct xfs_ail *ailp, struct xfs_ail_cursor *cur); void xfs_trans_ail_cursor_done(struct xfs_ail *ailp, struct xfs_ail_cursor *cur); -- 1.7.5.1 From dave@fromorbit.com Mon Jul 4 00:28:00 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p645S0V7115638 for ; Mon, 4 Jul 2011 00:28:00 -0500 X-ASG-Debug-ID: 1309757277-1cda02d70000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from ipmail05.adl6.internode.on.net (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id AAC2F1EE745B for ; Sun, 3 Jul 2011 22:27:58 -0700 (PDT) Received: from ipmail05.adl6.internode.on.net (ipmail05.adl6.internode.on.net [150.101.137.143]) by cuda.sgi.com with ESMTP id HFRbfD6UFQjDBN3Z for ; Sun, 03 Jul 2011 22:27:58 -0700 (PDT) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Av0EACZOEU55LCkB/2dsb2JhbABShEKjOXi7KY94gSuDf4EMBJpMiDI Received: from ppp121-44-41-1.lns20.syd6.internode.on.net (HELO dastard) ([121.44.41.1]) by ipmail05.adl6.internode.on.net with ESMTP; 04 Jul 2011 14:57:54 +0930 Received: from chute ([192.168.1.1] helo=disappointment) by dastard with esmtp (Exim 4.72) (envelope-from ) id 1Qdbh9-0002yF-26 for xfs@oss.sgi.com; Mon, 04 Jul 2011 15:27:43 +1000 Received: from dave by disappointment with local (Exim 4.76) (envelope-from ) id 1Qdbh8-0001RO-OI for xfs@oss.sgi.com; Mon, 04 Jul 2011 15:27:42 +1000 From: Dave Chinner To: xfs@oss.sgi.com X-ASG-Orig-Subj: =?UTF-8?q?=5BPATCH=204/5=5D=20xfs=3A=20convert=20AIL=20cursors=20to=20use=20struct=20list=5Fhead?= Subject: =?UTF-8?q?=5BPATCH=204/5=5D=20xfs=3A=20convert=20AIL=20cursors=20to=20use=20struct=20list=5Fhead?= Date: Mon, 4 Jul 2011 15:27:39 +1000 Message-Id: <1309757260-5484-5-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 1.7.5.1 In-Reply-To: <1309757260-5484-1-git-send-email-david@fromorbit.com> References: <1309757260-5484-1-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Barracuda-Connect: ipmail05.adl6.internode.on.net[150.101.137.143] X-Barracuda-Start-Time: 1309757279 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -1.52 X-Barracuda-Spam-Status: No, SCORE=-1.52 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=BSF_RULE7568M X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67916 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.50 BSF_RULE7568M Custom Rule 7568M X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean From: Dave Chinner The list of active AIL cursors uses a roll-your-own linked list with special casing for the AIL push cursor. Simplify this code by replacing the list with standard struct list_head lists, and use a separate list_head to track the active cursors so that the code can just treat the AIL push cursor (which is still embedded into the struct xfs_ail) as a generic cursor. Further, fix the duplicate push cursor initialisation that the special case handling was hiding, and clean up all the comments around the active cursor list handling. Signed-off-by: Dave Chinner --- fs/xfs/xfs_trans_ail.c | 68 +++++++++++++++------------------------------- fs/xfs/xfs_trans_priv.h | 5 ++- 2 files changed, 25 insertions(+), 48 deletions(-) diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c index de7a52a..3b5b5e4 100644 --- a/fs/xfs/xfs_trans_ail.c +++ b/fs/xfs/xfs_trans_ail.c @@ -165,15 +165,11 @@ xfs_ail_max_lsn( /* * AIL traversal cursor initialisation. * - * The cursor keeps track of where our current traversal is up - * to by tracking the next Æ£tem in the list for us. However, for - * this to be safe, removing an object from the AIL needs to invalidate - * any cursor that points to it. hence the traversal cursor needs to - * be linked to the struct xfs_ail so that deletion can search all the - * active cursors for invalidation. - * - * We don't link the push cursor because it is embedded in the struct - * xfs_ail and hence easily findable. + * The cursor keeps track of where our current traversal is up to by tracking + * the next Æ£tem in the list for us. However, for this to be safe, removing an + * object from the AIL needs to invalidate any cursor that points to it. hence + * the traversal cursor needs to be linked to the struct xfs_ail so that + * deletion can search all the active cursors for invalidation. */ STATIC void xfs_trans_ail_cursor_init( @@ -181,17 +177,13 @@ xfs_trans_ail_cursor_init( struct xfs_ail_cursor *cur) { cur->item = NULL; - if (cur == &ailp->xa_cursors) - return; - - cur->next = ailp->xa_cursors.next; - ailp->xa_cursors.next = cur; + INIT_LIST_HEAD(&cur->list); + list_add_tail(&cur->list, &ailp->xa_cursors); } /* - * Get the next item in the traversal and advance the cursor. - * If the cursor was invalidated (inidicated by a lip of 1), - * restart the traversal. + * Get the next item in the traversal and advance the cursor. If the cursor + * was invalidated (inidicated by a lip of 1), restart the traversal. */ struct xfs_log_item * xfs_trans_ail_cursor_next( @@ -208,39 +200,24 @@ xfs_trans_ail_cursor_next( } /* - * Now that the traversal is complete, we need to remove the cursor - * from the list of traversing cursors. Avoid removing the embedded - * push cursor, but use the fact it is always present to make the - * list deletion simple. + * When the traversal is complete, we need to remove the cursor from the list + * of traversing cursors. */ void xfs_trans_ail_cursor_done( struct xfs_ail *ailp, - struct xfs_ail_cursor *done) + struct xfs_ail_cursor *cur) { - struct xfs_ail_cursor *prev = NULL; - struct xfs_ail_cursor *cur; - - done->item = NULL; - if (done == &ailp->xa_cursors) - return; - prev = &ailp->xa_cursors; - for (cur = prev->next; cur; prev = cur, cur = prev->next) { - if (cur == done) { - prev->next = cur->next; - break; - } - } - ASSERT(cur); + cur->item = NULL; + list_del_init(&cur->list); } /* - * Invalidate any cursor that is pointing to this item. This is - * called when an item is removed from the AIL. Any cursor pointing - * to this object is now invalid and the traversal needs to be - * terminated so it doesn't reference a freed object. We set the - * cursor item to a value of 1 so we can distinguish between an - * invalidation and the end of the list when getting the next item + * Invalidate any cursor that is pointing to this item. This is called when an + * item is removed from the AIL. Any cursor pointing to this object is now + * invalid and the traversal needs to be terminated so it doesn't reference a + * freed object. We set the cursor item to a value of 1 so we can distinguish + * between an invalidation and the end of the list when getting the next item * from the cursor. */ STATIC void @@ -250,8 +227,7 @@ xfs_trans_ail_cursor_clear( { struct xfs_ail_cursor *cur; - /* need to search all cursors */ - for (cur = &ailp->xa_cursors; cur; cur = cur->next) { + list_for_each_entry(cur, &ailp->xa_cursors, list) { if (cur->item == lip) cur->item = (struct xfs_log_item *) ((__psint_t)cur->item | 1); @@ -416,7 +392,7 @@ xfs_ail_worker( struct xfs_ail *ailp = container_of(to_delayed_work(work), struct xfs_ail, xa_work); xfs_mount_t *mp = ailp->xa_mount; - struct xfs_ail_cursor *cur = &ailp->xa_cursors; + struct xfs_ail_cursor *cur = &ailp->xa_push_cursor; xfs_log_item_t *lip; xfs_lsn_t lsn; xfs_lsn_t target; @@ -428,7 +404,6 @@ xfs_ail_worker( spin_lock(&ailp->xa_lock); target = ailp->xa_target; - xfs_trans_ail_cursor_init(ailp, cur); lip = xfs_trans_ail_cursor_first(ailp, cur, ailp->xa_last_pushed_lsn); if (!lip || XFS_FORCED_SHUTDOWN(mp)) { /* @@ -859,6 +834,7 @@ xfs_trans_ail_init( ailp->xa_mount = mp; INIT_LIST_HEAD(&ailp->xa_ail); + INIT_LIST_HEAD(&ailp->xa_cursors); spin_lock_init(&ailp->xa_lock); INIT_DELAYED_WORK(&ailp->xa_work, xfs_ail_worker); mp->m_ail = ailp; diff --git a/fs/xfs/xfs_trans_priv.h b/fs/xfs/xfs_trans_priv.h index c0cb408..a394e2c 100644 --- a/fs/xfs/xfs_trans_priv.h +++ b/fs/xfs/xfs_trans_priv.h @@ -53,7 +53,7 @@ void xfs_trans_committed_bulk(struct xfs_ail *ailp, struct xfs_log_vec *lv, * of the list to trigger traversal restarts. */ struct xfs_ail_cursor { - struct xfs_ail_cursor *next; + struct list_head list; struct xfs_log_item *item; }; @@ -66,7 +66,8 @@ struct xfs_ail { struct xfs_mount *xa_mount; struct list_head xa_ail; xfs_lsn_t xa_target; - struct xfs_ail_cursor xa_cursors; + struct list_head xa_cursors; + struct xfs_ail_cursor xa_push_cursor; spinlock_t xa_lock; struct delayed_work xa_work; xfs_lsn_t xa_last_pushed_lsn; -- 1.7.5.1 From dave@fromorbit.com Mon Jul 4 00:28:05 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p645S4sE115659 for ; Mon, 4 Jul 2011 00:28:04 -0500 X-ASG-Debug-ID: 1309757277-1cda02d70001-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from ipmail05.adl6.internode.on.net (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 056D71EE7461 for ; Sun, 3 Jul 2011 22:28:03 -0700 (PDT) Received: from ipmail05.adl6.internode.on.net (ipmail05.adl6.internode.on.net [150.101.137.143]) by cuda.sgi.com with ESMTP id EqJPI2S94T2DrvZt for ; Sun, 03 Jul 2011 22:28:03 -0700 (PDT) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AhgIACZOEU55LCkB/2dsb2JhbABSmQqOcXjLIYY2BKJ+ Received: from ppp121-44-41-1.lns20.syd6.internode.on.net (HELO dastard) ([121.44.41.1]) by ipmail05.adl6.internode.on.net with ESMTP; 04 Jul 2011 14:58:02 +0930 Received: from chute ([192.168.1.1] helo=disappointment) by dastard with esmtp (Exim 4.72) (envelope-from ) id 1QdbhJ-0002yU-JZ for xfs@oss.sgi.com; Mon, 04 Jul 2011 15:27:53 +1000 Received: from dave by disappointment with local (Exim 4.76) (envelope-from ) id 1QdbhI-0001RR-P2 for xfs@oss.sgi.com; Mon, 04 Jul 2011 15:27:52 +1000 From: Dave Chinner To: xfs@oss.sgi.com X-ASG-Orig-Subj: [PATCH 5/5] xfs: add size update tracepoint to IO completion Subject: [PATCH 5/5] xfs: add size update tracepoint to IO completion Date: Mon, 4 Jul 2011 15:27:40 +1000 Message-Id: <1309757260-5484-6-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 1.7.5.1 In-Reply-To: <1309757260-5484-1-git-send-email-david@fromorbit.com> References: <1309757260-5484-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail05.adl6.internode.on.net[150.101.137.143] X-Barracuda-Start-Time: 1309757284 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -2.02 X-Barracuda-Spam-Status: No, SCORE=-2.02 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67916 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean From: Dave Chinner For improving insight into IO completion behaviour. Signed-off-by: Dave Chinner --- fs/xfs/linux-2.6/xfs_aops.c | 1 + fs/xfs/linux-2.6/xfs_trace.h | 12 ++++++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index 79ce38b..211abe7 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c @@ -181,6 +181,7 @@ xfs_setfilesize( isize = xfs_ioend_new_eof(ioend); if (isize) { + trace_xfs_setfilesize(ip, ioend->io_offset, ioend->io_size); ip->i_d.di_size = isize; xfs_mark_inode_dirty(ip); } diff --git a/fs/xfs/linux-2.6/xfs_trace.h b/fs/xfs/linux-2.6/xfs_trace.h index d48b7a5..97dad27 100644 --- a/fs/xfs/linux-2.6/xfs_trace.h +++ b/fs/xfs/linux-2.6/xfs_trace.h @@ -998,7 +998,8 @@ DECLARE_EVENT_CLASS(xfs_simple_io_class, TP_STRUCT__entry( __field(dev_t, dev) __field(xfs_ino_t, ino) - __field(loff_t, size) + __field(loff_t, isize) + __field(loff_t, disize) __field(loff_t, new_size) __field(loff_t, offset) __field(size_t, count) @@ -1006,16 +1007,18 @@ DECLARE_EVENT_CLASS(xfs_simple_io_class, TP_fast_assign( __entry->dev = VFS_I(ip)->i_sb->s_dev; __entry->ino = ip->i_ino; - __entry->size = ip->i_d.di_size; + __entry->isize = ip->i_size; + __entry->disize = ip->i_d.di_size; __entry->new_size = ip->i_new_size; __entry->offset = offset; __entry->count = count; ), - TP_printk("dev %d:%d ino 0x%llx size 0x%llx new_size 0x%llx " + TP_printk("dev %d:%d ino 0x%llx isize 0x%llx disize 0x%llx new_size 0x%llx " "offset 0x%llx count %zd", MAJOR(__entry->dev), MINOR(__entry->dev), __entry->ino, - __entry->size, + __entry->isize, + __entry->disize, __entry->new_size, __entry->offset, __entry->count) @@ -1028,6 +1031,7 @@ DEFINE_EVENT(xfs_simple_io_class, name, \ DEFINE_SIMPLE_IO_EVENT(xfs_delalloc_enospc); DEFINE_SIMPLE_IO_EVENT(xfs_unwritten_convert); DEFINE_SIMPLE_IO_EVENT(xfs_get_blocks_notfound); +DEFINE_SIMPLE_IO_EVENT(xfs_setfilesize); TRACE_EVENT(xfs_itruncate_start, -- 1.7.5.1 From BATV+e83e9d2711330749e835+2871+infradead.org+hch@bombadil.srs.infradead.org Mon Jul 4 03:13:55 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p648Dqgt124637 for ; Mon, 4 Jul 2011 03:13:55 -0500 X-ASG-Debug-ID: 1309767229-18bd02300000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from bombadil.infradead.org (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 34DBB1EE78DB for ; Mon, 4 Jul 2011 01:13:49 -0700 (PDT) Received: from bombadil.infradead.org (173-166-109-252-newengland.hfc.comcastbusiness.net [173.166.109.252]) by cuda.sgi.com with ESMTP id drUm43u0c7nUy99A for ; Mon, 04 Jul 2011 01:13:49 -0700 (PDT) Received: from hch by bombadil.infradead.org with local (Exim 4.76 #1 (Red Hat Linux)) id 1QdeHt-0005su-ER; Mon, 04 Jul 2011 08:13:49 +0000 Date: Mon, 4 Jul 2011 04:13:49 -0400 From: Christoph Hellwig To: Dave Chinner Cc: xfs@oss.sgi.com X-ASG-Orig-Subj: Re: [PATCH 1/5] xfs: unpin stale inodes directly in IOP_COMMITTED Subject: Re: [PATCH 1/5] xfs: unpin stale inodes directly in IOP_COMMITTED Message-ID: <20110704081349.GB22496@infradead.org> References: <1309757260-5484-1-git-send-email-david@fromorbit.com> <1309757260-5484-2-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1309757260-5484-2-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: 173-166-109-252-newengland.hfc.comcastbusiness.net[173.166.109.252] X-Barracuda-Start-Time: 1309767230 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0301 1.0000 -1.8264 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -1.73 X-Barracuda-Spam-Status: No, SCORE=-1.73 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=RDNS_DYNAMIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67926 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_DYNAMIC Delivered to trusted network by host with dynamic-looking rDNS X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean On Mon, Jul 04, 2011 at 03:27:36PM +1000, Dave Chinner wrote: > From: Dave Chinner > > When inodes are marked stale in a transaction, they are treated > specially when the iinode log item is being inserted into the AIL. s/iinode/inode/ > It trie?? to avoid moving the log item forward in the AIL due to a Weird character. Otherwise looks good good. From BATV+e83e9d2711330749e835+2871+infradead.org+hch@bombadil.srs.infradead.org Mon Jul 4 03:14:05 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p648E5J6124659 for ; Mon, 4 Jul 2011 03:14:05 -0500 X-ASG-Debug-ID: 1309767194-7a1a002d0000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from bombadil.infradead.org (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 0E2F95245BC for ; Mon, 4 Jul 2011 01:13:14 -0700 (PDT) Received: from bombadil.infradead.org (173-166-109-252-newengland.hfc.comcastbusiness.net [173.166.109.252]) by cuda.sgi.com with ESMTP id snlmvM27PokKNTbW for ; Mon, 04 Jul 2011 01:13:14 -0700 (PDT) Received: from hch by bombadil.infradead.org with local (Exim 4.76 #1 (Red Hat Linux)) id 1QdeHI-0005se-3z; Mon, 04 Jul 2011 08:13:12 +0000 Date: Mon, 4 Jul 2011 04:13:12 -0400 From: Christoph Hellwig To: Dave Chinner Cc: xfs@oss.sgi.com X-ASG-Orig-Subj: Re: [PATCH 0/5] xfs: fix AIL bulk insert issues and cleanups Subject: Re: [PATCH 0/5] xfs: fix AIL bulk insert issues and cleanups Message-ID: <20110704081312.GA22496@infradead.org> References: <1309757260-5484-1-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1309757260-5484-1-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: 173-166-109-252-newengland.hfc.comcastbusiness.net[173.166.109.252] X-Barracuda-Start-Time: 1309767195 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0003 1.0000 -2.0192 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -1.92 X-Barracuda-Spam-Status: No, SCORE=-1.92 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=RDNS_DYNAMIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67926 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_DYNAMIC Delivered to trusted network by host with dynamic-looking rDNS X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean On Mon, Jul 04, 2011 at 03:27:35PM +1000, Dave Chinner wrote: > The first two patches fix the recently reported rm -rf performance > and interactivity problems when using delay??d logging. These should > probably be considered for 3.0-rc5. I think it's a bit late for patch 2. Patch 1 is triviall, and helps with a regression introduced in 2.6.39 by switching to the delaylog mode, but patch 2 is a bit too large for this in the merge window unless absolutely nessecary. From BATV+e83e9d2711330749e835+2871+infradead.org+hch@bombadil.srs.infradead.org Mon Jul 4 03:16:05 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p648G4ie124762 for ; Mon, 4 Jul 2011 03:16:05 -0500 X-ASG-Debug-ID: 1309767363-18b902390000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from bombadil.infradead.org (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id DE94D1EE788B for ; Mon, 4 Jul 2011 01:16:03 -0700 (PDT) Received: from bombadil.infradead.org (173-166-109-252-newengland.hfc.comcastbusiness.net [173.166.109.252]) by cuda.sgi.com with ESMTP id TSLseR7EuygtI3Pm for ; Mon, 04 Jul 2011 01:16:03 -0700 (PDT) Received: from hch by bombadil.infradead.org with local (Exim 4.76 #1 (Red Hat Linux)) id 1QdeK3-0006ci-9h; Mon, 04 Jul 2011 08:16:03 +0000 Date: Mon, 4 Jul 2011 04:16:03 -0400 From: Christoph Hellwig To: Dave Chinner Cc: xfs@oss.sgi.com X-ASG-Orig-Subj: Re: [PATCH 3/5] xfs: remove confusing ail cursor wrapper Subject: Re: [PATCH 3/5] xfs: remove confusing ail cursor wrapper Message-ID: <20110704081603.GC22496@infradead.org> References: <1309757260-5484-1-git-send-email-david@fromorbit.com> <1309757260-5484-4-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1309757260-5484-4-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: 173-166-109-252-newengland.hfc.comcastbusiness.net[173.166.109.252] X-Barracuda-Start-Time: 1309767363 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0497 1.0000 -1.7016 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -1.60 X-Barracuda-Spam-Status: No, SCORE=-1.60 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=RDNS_DYNAMIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67926 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_DYNAMIC Delivered to trusted network by host with dynamic-looking rDNS X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean On Mon, Jul 04, 2011 at 03:27:38PM +1000, Dave Chinner wrote: > From: Dave Chinner > > xfs_trans_ail_cursor_set() doesn't set the cursor to the current log > item, it sets it to the next item. There is already a function for > doing this - xfs_trans_ail_cursor_next() - and the _set function is > simply a two line wrapper. Remove it and open code the setting of > the cursor in the two locations that call it to remove the > confusion. > > Signed-off-by: Dave Chinner > --- > fs/xfs/xfs_trans_ail.c | 38 ++++++++++++-------------------------- > 1 files changed, 12 insertions(+), 26 deletions(-) > @@ -295,14 +283,11 @@ xfs_trans_ail_cursor_first( > } > lip = NULL; > out: > - xfs_trans_ail_cursor_set(ailp, cur, lip); > + if (lip) > + cur->item = xfs_ail_next(ailp, lip); > return lip; The lip = NULL above could nbe turned into a direct return NULL; Otherwise looks good, Reviewed-by: Christoph Hellwig From BATV+e83e9d2711330749e835+2871+infradead.org+hch@bombadil.srs.infradead.org Mon Jul 4 03:16:41 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p648GeCM124784 for ; Mon, 4 Jul 2011 03:16:41 -0500 X-ASG-Debug-ID: 1309767400-3a2a02500000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from bombadil.infradead.org (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 6C6BB52459D for ; Mon, 4 Jul 2011 01:16:40 -0700 (PDT) Received: from bombadil.infradead.org (173-166-109-252-newengland.hfc.comcastbusiness.net [173.166.109.252]) by cuda.sgi.com with ESMTP id YIfD4UBm46ntHtY0 for ; Mon, 04 Jul 2011 01:16:40 -0700 (PDT) Received: from hch by bombadil.infradead.org with local (Exim 4.76 #1 (Red Hat Linux)) id 1QdeKd-0006cr-V3; Mon, 04 Jul 2011 08:16:40 +0000 Date: Mon, 4 Jul 2011 04:16:39 -0400 From: Christoph Hellwig To: Dave Chinner Cc: xfs@oss.sgi.com X-ASG-Orig-Subj: Re: [PATCH 5/5] xfs: add size update tracepoint to IO completion Subject: Re: [PATCH 5/5] xfs: add size update tracepoint to IO completion Message-ID: <20110704081639.GD22496@infradead.org> References: <1309757260-5484-1-git-send-email-david@fromorbit.com> <1309757260-5484-6-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1309757260-5484-6-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: 173-166-109-252-newengland.hfc.comcastbusiness.net[173.166.109.252] X-Barracuda-Start-Time: 1309767400 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0001 1.0000 -2.0204 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -1.92 X-Barracuda-Spam-Status: No, SCORE=-1.92 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=RDNS_DYNAMIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67926 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_DYNAMIC Delivered to trusted network by host with dynamic-looking rDNS X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean On Mon, Jul 04, 2011 at 03:27:40PM +1000, Dave Chinner wrote: > From: Dave Chinner > > For improving insight into IO completion behaviour. Looks fine, Reviewed-by: Christoph Hellwig From BATV+e83e9d2711330749e835+2871+infradead.org+hch@bombadil.srs.infradead.org Mon Jul 4 03:32:08 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p648W7aC125883 for ; Mon, 4 Jul 2011 03:32:08 -0500 X-ASG-Debug-ID: 1309768326-5748022d0000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from bombadil.infradead.org (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 35DB71678D19 for ; Mon, 4 Jul 2011 01:32:06 -0700 (PDT) Received: from bombadil.infradead.org (173-166-109-252-newengland.hfc.comcastbusiness.net [173.166.109.252]) by cuda.sgi.com with ESMTP id DAjcWAuoAH6UxbV9 for ; Mon, 04 Jul 2011 01:32:06 -0700 (PDT) Received: from hch by bombadil.infradead.org with local (Exim 4.76 #1 (Red Hat Linux)) id 1QdeZa-0000mu-4h; Mon, 04 Jul 2011 08:32:06 +0000 Date: Mon, 4 Jul 2011 04:32:06 -0400 From: Christoph Hellwig To: Dave Chinner Cc: xfs@oss.sgi.com X-ASG-Orig-Subj: Re: [PATCH 2/5] xfs: use a cursor for bulk AIL insertion Subject: Re: [PATCH 2/5] xfs: use a cursor for bulk AIL insertion Message-ID: <20110704083206.GA28858@infradead.org> References: <1309757260-5484-1-git-send-email-david@fromorbit.com> <1309757260-5484-3-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1309757260-5484-3-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: 173-166-109-252-newengland.hfc.comcastbusiness.net[173.166.109.252] X-Barracuda-Start-Time: 1309768327 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -1.92 X-Barracuda-Spam-Status: No, SCORE=-1.92 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=RDNS_DYNAMIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67927 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_DYNAMIC Delivered to trusted network by host with dynamic-looking rDNS X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean > /* > + * Initialise the cursor to the last item in the AIL with the given @lsn. > + * This searches the list from highest LSN to lowest. > */ > +static struct xfs_log_item * > +__xfs_trans_ail_cursor_last( > + struct xfs_ail *ailp, > + struct xfs_ail_cursor *cur, > + xfs_lsn_t lsn, > + bool do_init) > { > + xfs_log_item_t *lip = NULL; > > + if (do_init) > + xfs_trans_ail_cursor_init(ailp, cur); > + > + if (list_empty(&ailp->xa_ail)) > + goto out; > > + list_for_each_entry_reverse(lip, &ailp->xa_ail, li_ail) { > + if (XFS_LSN_CMP(lip->li_lsn, lsn) <= 0) > break; > } > +out: > + if (cur) > + cur->item = lip; > + return lip; > +} Please just move the xfs_trans_ail_cursor_init call to xfs_trans_ail_cursor_init instead of adding the do_init parameter. Also the list_empty check is not needed due to the list_for_each* macros handling that case just fine. I haven't looked at the details of the new xfs_ail_splice code yet, so more updates later. From BATV+e83e9d2711330749e835+2871+infradead.org+hch@bombadil.srs.infradead.org Mon Jul 4 03:43:18 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p648hHSs127615 for ; Mon, 4 Jul 2011 03:43:18 -0500 X-ASG-Debug-ID: 1309768996-3a2703160000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from bombadil.infradead.org (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 102895246A3 for ; Mon, 4 Jul 2011 01:43:16 -0700 (PDT) Received: from bombadil.infradead.org (173-166-109-252-newengland.hfc.comcastbusiness.net [173.166.109.252]) by cuda.sgi.com with ESMTP id MNwos1iawA6UlidQ for ; Mon, 04 Jul 2011 01:43:16 -0700 (PDT) Received: from hch by bombadil.infradead.org with local (Exim 4.76 #1 (Red Hat Linux)) id 1QdekO-0002QM-DT; Mon, 04 Jul 2011 08:43:16 +0000 Date: Mon, 4 Jul 2011 04:43:16 -0400 From: Christoph Hellwig To: Dave Chinner Cc: xfs@oss.sgi.com X-ASG-Orig-Subj: Re: [PATCH 4/5] xfs: convert AIL cursors to use struct list_head Subject: Re: [PATCH 4/5] xfs: convert AIL cursors to use struct list_head Message-ID: <20110704084316.GA5907@infradead.org> References: <1309757260-5484-1-git-send-email-david@fromorbit.com> <1309757260-5484-5-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1309757260-5484-5-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: 173-166-109-252-newengland.hfc.comcastbusiness.net[173.166.109.252] X-Barracuda-Start-Time: 1309768997 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -1.92 X-Barracuda-Spam-Status: No, SCORE=-1.92 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=RDNS_DYNAMIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67928 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_DYNAMIC Delivered to trusted network by host with dynamic-looking rDNS X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean On Mon, Jul 04, 2011 at 03:27:39PM +1000, Dave Chinner wrote: > /* > * AIL traversal cursor initialisation. > * > + * The cursor keeps track of where our current traversal is up to by tracking > + * the next ??tem in the list for us. However, for this to be safe, removing an ^^ Non-ASCSI character. > + * object from the AIL needs to invalidate any cursor that points to it. hence > + * the traversal cursor needs to be linked to the struct xfs_ail so that > + * deletion can search all the active cursors for invalidation. > */ > STATIC void > xfs_trans_ail_cursor_init( > @@ -181,17 +177,13 @@ xfs_trans_ail_cursor_init( > struct xfs_ail_cursor *cur) > { > cur->item = NULL; > - if (cur == &ailp->xa_cursors) > - return; > - > - cur->next = ailp->xa_cursors.next; > - ailp->xa_cursors.next = cur; > + INIT_LIST_HEAD(&cur->list); > + list_add_tail(&cur->list, &ailp->xa_cursors); > } There is no need to initialize a list_head before adding it to a list. Otherwise looks good, Reviewed-by: Christoph Hellwig From ext-phil.2.carmody@nokia.com Mon Jul 4 03:55:51 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.7 required=5.0 tests=BAYES_00,J_CHICKENPOX_23, J_CHICKENPOX_25 autolearn=no version=3.4.0-r929098 Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p648tpBp129155 for ; Mon, 4 Jul 2011 03:55:51 -0500 X-ASG-Debug-ID: 1309769748-39fd03650000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from mgw-sa01.nokia.com (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 87EF0524570 for ; Mon, 4 Jul 2011 01:55:48 -0700 (PDT) Received: from mgw-sa01.nokia.com (smtp.nokia.com [147.243.1.47]) by cuda.sgi.com with ESMTP id 0EDQWLIHdielxdUv for ; Mon, 04 Jul 2011 01:55:48 -0700 (PDT) Received: from localhost (essapo-nirac25252.europe.nokia.com [10.162.252.52]) by mgw-sa01.nokia.com (Switch-3.4.4/Switch-3.4.3) with ESMTP id p648q2cf014070; Mon, 4 Jul 2011 11:52:03 +0300 Date: Mon, 4 Jul 2011 11:51:26 +0300 From: Phil Carmody To: ext Dave Chinner Cc: trivial@kernel.org, linux-kernel@vger.kernel.org, xfs@oss.sgi.com X-ASG-Orig-Subj: Re: [PATCH 3/7] xfs: there is no CONFIG_KDB_MODULES Subject: Re: [PATCH 3/7] xfs: there is no CONFIG_KDB_MODULES Message-ID: <20110704085126.GI19426@pcarmody2.research.nokia.com> References: <1309643272-364-1-git-send-email-ext-phil.2.carmody@nokia.com> <1309643272-364-2-git-send-email-ext-phil.2.carmody@nokia.com> <1309643272-364-3-git-send-email-ext-phil.2.carmody@nokia.com> <1309643272-364-4-git-send-email-ext-phil.2.carmody@nokia.com> <20110704045820.GE1026@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20110704045820.GE1026@dastard> User-Agent: Mutt/1.5.20 (2009-06-14) X-Nokia-AV: Clean X-Barracuda-Connect: smtp.nokia.com[147.243.1.47] X-Barracuda-Start-Time: 1309769750 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -2.02 X-Barracuda-Spam-Status: No, SCORE=-2.02 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67930 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean On 04/07/11 14:58 +1000, ext Dave Chinner wrote: > On Sun, Jul 03, 2011 at 12:47:48AM +0300, Phil Carmody wrote: > > Hi Phil, > > You should probably cc the relevant lists with such patchsets so the > developers actually see the patches go by.... Yeah, I was wondering how to do that. The idea of cc:ing about 30 people for the whole set seemed a bit too spammy, and wasn't sure if individually-selected cc:lists for eack of the patches made sense. The alternative was to make it 7 (or more...) independent patchsets, but that turned the task into too much of a game of chess. I chickened out of thinking more, and cowardly went for the 'trivial' route. I realised after sending that a truly trivial patch still hadn't been done - there are a whole bunch of comments or printk strings that refer to the wrong options that I forgot to fix. So there will be a v2. > > Seems like there was a decade ago, but no longer, so this block > > is dead code. The list being returned disappeared back in commit > > ff57ab21995a8636cfc72efeebb09cc6034d756f. > > When you quote a commit, short form followed by the name (i.e. > one-line form) is preferable because it gives context to the commit > without needing to go look it up in a git tree. Commit IDs are not > human readable, while commit log should be. Yup, good point, I can clean that up. > The commit in question - ff57ab2 ("xfs: convert xfsbud shrinker to a > per-buftarg shrinker.") - removed the list but the code being > removed was already long dead. FWIW, I know just by reading the > commit description when the list went away and who was responsible > for missing that. i.e. me. ;) > > > Part of a shotgun patchset; found by greps, seds, and diffs > > rather than actual understanding. > > Not necessary in a commit description - the zero patch of a series, > yes, to describe how the issues were found, but it doesn't need to > be recorded forever in the commit log. ;) Sure. Thanks for the feedback, and look forward to v2! Phil > > Signed-off-by: Phil Carmody > > --- > > fs/xfs/linux-2.6/xfs_buf.c | 8 -------- > > fs/xfs/linux-2.6/xfs_buf.h | 4 ---- > > 2 files changed, 0 insertions(+), 12 deletions(-) > > > > diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c > > index 5e68099..5bccae0 100644 > > --- a/fs/xfs/linux-2.6/xfs_buf.c > > +++ b/fs/xfs/linux-2.6/xfs_buf.c > > @@ -1889,11 +1889,3 @@ xfs_buf_terminate(void) > > destroy_workqueue(xfslogd_workqueue); > > kmem_zone_destroy(xfs_buf_zone); > > } > > - > > -#ifdef CONFIG_KDB_MODULES > > -struct list_head * > > -xfs_get_buftarg_list(void) > > -{ > > - return &xfs_buftarg_list; > > -} > > -#endif > > diff --git a/fs/xfs/linux-2.6/xfs_buf.h b/fs/xfs/linux-2.6/xfs_buf.h > > index 50a7d5f..6881321 100644 > > --- a/fs/xfs/linux-2.6/xfs_buf.h > > +++ b/fs/xfs/linux-2.6/xfs_buf.h > > @@ -339,10 +339,6 @@ extern void xfs_wait_buftarg(xfs_buftarg_t *); > > extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int, unsigned int); > > extern int xfs_flush_buftarg(xfs_buftarg_t *, int); > > > > -#ifdef CONFIG_KDB_MODULES > > -extern struct list_head *xfs_get_buftarg_list(void); > > -#endif > > - > > #define xfs_getsize_buftarg(buftarg) block_size((buftarg)->bt_bdev) > > #define xfs_readonly_buftarg(buftarg) bdev_read_only((buftarg)->bt_bdev) > > Code changes look good. Can you fix the commit description and > resend to xfs@oss.sgi.com? > > Cheers, > > Dave. > -- > Dave Chinner > david@fromorbit.com From korczyk.l@gmail.com Mon Jul 4 04:41:50 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: **** X-Spam-Status: No, score=4.1 required=5.0 tests=BAYES_50,FREEMAIL_FROM, HTML_MESSAGE,MIME_8BIT_HEADER,T_DKIM_INVALID,T_TO_NO_BRKTS_FREEMAIL autolearn=no version=3.4.0-r929098 Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p649foPC135590 for ; Mon, 4 Jul 2011 04:41:50 -0500 X-ASG-Debug-ID: 1309772509-2ed600c00000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from mail-qw0-f53.google.com (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id EB63A52459A for ; Mon, 4 Jul 2011 02:41:49 -0700 (PDT) Received: from mail-qw0-f53.google.com (mail-qw0-f53.google.com [209.85.216.53]) by cuda.sgi.com with ESMTP id MSFLIpHl9Reb0w9x for ; Mon, 04 Jul 2011 02:41:49 -0700 (PDT) Received: by qwb7 with SMTP id 7so3144305qwb.26 for ; Mon, 04 Jul 2011 02:41:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=mime-version:date:message-id:subject:from:to:content-type; bh=RxU3sST8fcrC6Vl+C7fyvmichPB/mgpVQefn9LXdOcQ=; b=hNNAl3YjlJ95qeRJVT7G+seq/kggHYFgKw5WAwJr4udUTF2WNNQLUifD9yo4u/D1b2 yJ2GoZypstU0+mfj5Pk+1GfE6Y3fxsdNelcqoXFSXbnaM2+l50KBkJb3J4+x6vprm/5u I5l0t1AXswIQUPsRFTcs+laUW364sQ9NGr6NM= MIME-Version: 1.0 Received: by 10.229.249.132 with SMTP id mk4mr4531904qcb.159.1309772509410; Mon, 04 Jul 2011 02:41:49 -0700 (PDT) Received: by 10.229.68.155 with HTTP; Mon, 4 Jul 2011 02:41:49 -0700 (PDT) Date: Mon, 4 Jul 2011 11:41:49 +0200 Message-ID: X-ASG-Orig-Subj: question about xfs_repair Subject: question about xfs_repair From: =?ISO-8859-2?Q?=A3ukasz_Korczyk?= To: xfs@oss.sgi.com Content-Type: multipart/alternative; boundary=00163630fc2528f6cb04a73b2dd8 X-Barracuda-Connect: mail-qw0-f53.google.com[209.85.216.53] X-Barracuda-Start-Time: 1309772509 X-Barracuda-Bayes: INNOCENT GLOBAL 0.4117 1.0000 0.0000 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=DKIM_SIGNED, DKIM_VERIFIED, HTML_MESSAGE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67932 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 X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean --00163630fc2528f6cb04a73b2dd8 Content-Type: text/plain; charset=ISO-8859-2 Content-Transfer-Encoding: quoted-printable Helo I have a question I wasn't able to find answer for. Which factors influence memory usage of xfs_repair? Does any formula exist to count possible memory usage? Best Regards =A3ukasz Korczyk --00163630fc2528f6cb04a73b2dd8 Content-Type: text/html; charset=ISO-8859-2 Content-Transfer-Encoding: quoted-printable
Helo

I have a question I wasn't able to find answer for.
=
Which factors influence memory usage of xfs_repair?
Does any formula= exist to count possible memory usage?

Best Regards
=A3ukasz Korc= zyk
--00163630fc2528f6cb04a73b2dd8-- From volkan.yazici@gmail.com Mon Jul 4 05:23:58 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM, T_DKIM_INVALID,T_TO_NO_BRKTS_FREEMAIL autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p64ANv3L139682 for ; Mon, 4 Jul 2011 05:23:57 -0500 X-ASG-Debug-ID: 1309775035-2ef202120000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from mail-fx0-f47.google.com (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 5B0974C3605 for ; Mon, 4 Jul 2011 03:23:56 -0700 (PDT) Received: from mail-fx0-f47.google.com (mail-fx0-f47.google.com [209.85.161.47]) by cuda.sgi.com with ESMTP id sZu7EqjfwUoRiotT for ; Mon, 04 Jul 2011 03:23:56 -0700 (PDT) Received: by fxg11 with SMTP id 11so5242794fxg.6 for ; Mon, 04 Jul 2011 03:23:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=mime-version:date:message-id:subject:from:to:content-type; bh=nOZzOZyU1YrY1+J14mL5h4fOFZv22KEV1Tj6bUm8oUg=; b=tme/CJF2ZEorugDtwTUX3NtGxl38e3/frtc9M56GJFGu/D9Q5DUeobq3tK3yLY/m5X NigpULrzs4eWreKtfI+QUGZqO9enK/OLyWjT3CZv1MBBBIccJ/tFpBKxVVUiTL38S5ka 4mHwrQkeEfw4JtLr299QC6uwc3ewHKJZFs3sg= MIME-Version: 1.0 Received: by 10.223.97.131 with SMTP id l3mr9372049fan.43.1309775035500; Mon, 04 Jul 2011 03:23:55 -0700 (PDT) Received: by 10.223.118.20 with HTTP; Mon, 4 Jul 2011 03:23:55 -0700 (PDT) Date: Mon, 4 Jul 2011 10:23:55 +0000 Message-ID: X-ASG-Orig-Subj: Recovering XFS Partition of Type FAT16 Subject: Recovering XFS Partition of Type FAT16 From: Volkan YAZICI To: xfs@oss.sgi.com Content-Type: text/plain; charset=ISO-8859-1 X-Barracuda-Connect: mail-fx0-f47.google.com[209.85.161.47] X-Barracuda-Start-Time: 1309775037 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -1.61 X-Barracuda-Spam-Status: No, SCORE=-1.61 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=DKIM_SIGNED, DKIM_VERIFIED, SUBJECT_FUZZY_TION X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67936 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.41 SUBJECT_FUZZY_TION Attempt to obfuscate words in Subject: -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean Hi, I have an XFS partition, which is 1) Mistakenly quick formatted as FAT16. 2) At first, I couldn't see in "fdisk -l" that it is set to FAT16, instead of Linux. Hence, tried to fix it with xfs_recover. xfs_recover returned 0, and mount operation succeeded; but mounted fs size appeared as 20GB (despite it is 350GB) and almost every file was missing. 3) Later, I set the type of /dev/sda1 (the only partition in /dev/sda) to Linux, re-run xfs_recover, but nothing changed: Same fs size (20GB) and same missing files. I open the system with Knoppix, and below are the partition diagnostics. I need urgent help to recover the files. I will be really, really appreciated for any help! (If you need further information, just drop me a mail.) Best. # fdisk -l Disk /dev/sda: 320.1 GB, 320072933376 bytes 255 heads, 63 sectors/track, 38913 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x447c435f Device Boot Start End Blocks Id System /dev/sda1 * 1 38913 312568641 83 Linux # mount | grep /dev/sda1 /dev/sda1 on /media/sda1 type xfs (rw,relatime,attr2,noquota) # df -h | grep /dev/sda1 /dev/sda1 19G 4,2G 15G 23% /media/sda1 # xfs_info /mnt/sda1 meta-data=/dev/sda1 isize=256 agcount=4, agsize=1226963 blks = sectsz=512 attr=2 data = bsize=4096 blocks=4907849, imaxpct=25 = sunit=0 swidth=0 blks naming =version 2 bsize=4096 ascii-ci=0 log =internal bsize=4096 blocks=2560, version=2 = sectsz=512 sunit=0 blks, lazy-count=1 realtime =none extsz=4096 blocks=0, rtextents=0 From BATV+e83e9d2711330749e835+2871+infradead.org+hch@bombadil.srs.infradead.org Mon Jul 4 06:16:10 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p64BG9j7141432 for ; Mon, 4 Jul 2011 06:16:10 -0500 X-ASG-Debug-ID: 1309778167-2bcd039e0000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from bombadil.infradead.org (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id D55C8E714BA for ; Mon, 4 Jul 2011 04:16:07 -0700 (PDT) Received: from bombadil.infradead.org (173-166-109-252-newengland.hfc.comcastbusiness.net [173.166.109.252]) by cuda.sgi.com with ESMTP id zi4n5F8u5l0XJBny for ; Mon, 04 Jul 2011 04:16:07 -0700 (PDT) Received: from hch by bombadil.infradead.org with local (Exim 4.76 #1 (Red Hat Linux)) id 1Qdh8H-000563-Qp; Mon, 04 Jul 2011 11:16:05 +0000 Date: Mon, 4 Jul 2011 07:16:05 -0400 From: Christoph Hellwig To: Dave Chinner Cc: xfs@oss.sgi.com X-ASG-Orig-Subj: Re: [PATCH 2/5] xfs: use a cursor for bulk AIL insertion Subject: Re: [PATCH 2/5] xfs: use a cursor for bulk AIL insertion Message-ID: <20110704111605.GA5513@infradead.org> References: <1309757260-5484-1-git-send-email-david@fromorbit.com> <1309757260-5484-3-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1309757260-5484-3-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: 173-166-109-252-newengland.hfc.comcastbusiness.net[173.166.109.252] X-Barracuda-Start-Time: 1309778168 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -1.92 X-Barracuda-Spam-Status: No, SCORE=-1.92 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=RDNS_DYNAMIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67939 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_DYNAMIC Delivered to trusted network by host with dynamic-looking rDNS X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean > + do { > + /* no placeholder, so get our insert location */ > + if (!lip) > + lip = __xfs_trans_ail_cursor_last(ailp, cur, > + lsn, false); > + > + if (!lip) { > + /* > + * The list is empty, so just splice and return. Our > + * cursor is already guaranteed to be up to date, so we > + * don't need to touch it here. > + */ > + list_splice(list, &ailp->xa_ail); > + return; > + } > + > + /* The placeholder was invalidated, need to get a new cursor */ > + if ((__psint_t)lip & 1) > + lip = NULL; > + > + } while (lip == NULL); Why do we even need a loop here? Given that we're under xa_lock no new cursor will get invalidated. Isn't the simple code below equivalent? /* no valid placeholder, get us a useful one */ if (!lip || (__psint_t)lip & 1)) lip = __xfs_trans_ail_cursor_last(ailp, cur, lsn, false); if (!lip) { /* * The list is empty, so just splice and return. Our * cursor is already guaranteed to be up to date, so we * don't need to touch it here. */ list_splice(list, &ailp->xa_ail); return; } From david@fromorbit.com Mon Jul 4 06:26:07 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p64BQ7SY142012 for ; Mon, 4 Jul 2011 06:26:07 -0500 X-ASG-Debug-ID: 1309778764-03a7006f0000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from ipmail07.adl2.internode.on.net (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 287C7496A9 for ; Mon, 4 Jul 2011 04:26:05 -0700 (PDT) Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id 6o6Z57nGheC7OCn5 for ; Mon, 04 Jul 2011 04:26:05 -0700 (PDT) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Av0EANegEU55LCkB/2dsb2JhbABSp3x4ylcOhigEon4 Received: from ppp121-44-41-1.lns20.syd6.internode.on.net (HELO dastard) ([121.44.41.1]) by ipmail07.adl2.internode.on.net with ESMTP; 04 Jul 2011 20:56:03 +0930 Received: from dave by dastard with local (Exim 4.72) (envelope-from ) id 1QdhHu-0003Wy-0h; Mon, 04 Jul 2011 21:26:02 +1000 Date: Mon, 4 Jul 2011 21:26:01 +1000 From: Dave Chinner To: Christoph Hellwig Cc: xfs@oss.sgi.com X-ASG-Orig-Subj: Re: [PATCH 0/5] xfs: fix AIL bulk insert issues and cleanups Subject: Re: [PATCH 0/5] xfs: fix AIL bulk insert issues and cleanups Message-ID: <20110704112601.GV561@dastard> References: <1309757260-5484-1-git-send-email-david@fromorbit.com> <20110704081312.GA22496@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20110704081312.GA22496@infradead.org> User-Agent: Mutt/1.5.20 (2009-06-14) X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1309778766 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0515 1.0000 -1.6905 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -1.69 X-Barracuda-Spam-Status: No, SCORE=-1.69 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67940 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean On Mon, Jul 04, 2011 at 04:13:12AM -0400, Christoph Hellwig wrote: > On Mon, Jul 04, 2011 at 03:27:35PM +1000, Dave Chinner wrote: > > The first two patches fix the recently reported rm -rf performance > > and interactivity problems when using delay??d logging. These should > > probably be considered for 3.0-rc5. > > I think it's a bit late for patch 2. Patch 1 is triviall, and helps > with a regression introduced in 2.6.39 by switching to the delaylog > mode, but patch 2 is a bit too large for this in the merge window > unless absolutely nessecary. Yeah, that's fair enough. The first patch should prevent the majority of the problematic occurrences of out-of-order AIL insertion, so we can live without the second one for the moment. Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Mon Jul 4 07:13:12 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.6 required=5.0 tests=BAYES_00,MIME_8BIT_HEADER autolearn=no version=3.4.0-r929098 Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p64CDCh2143540 for ; Mon, 4 Jul 2011 07:13:12 -0500 X-ASG-Debug-ID: 1309781589-6c76025b0000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from ipmail07.adl2.internode.on.net (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 6285C1EE814A for ; Mon, 4 Jul 2011 05:13:10 -0700 (PDT) Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id LnolnAaA6Xq3413H for ; Mon, 04 Jul 2011 05:13:10 -0700 (PDT) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Av0EAGOrEU55LCkB/2dsb2JhbABShEKjOni5d5AlDoEdg3+BDASaTIgy Received: from ppp121-44-41-1.lns20.syd6.internode.on.net (HELO dastard) ([121.44.41.1]) by ipmail07.adl2.internode.on.net with ESMTP; 04 Jul 2011 21:43:09 +0930 Received: from dave by dastard with local (Exim 4.72) (envelope-from ) id 1Qdi1U-0003bD-0K; Mon, 04 Jul 2011 22:13:08 +1000 Date: Mon, 4 Jul 2011 22:13:07 +1000 From: Dave Chinner To: =?utf-8?Q?=C5=81ukasz?= Korczyk Cc: xfs@oss.sgi.com X-ASG-Orig-Subj: Re: question about xfs_repair Subject: Re: question about xfs_repair Message-ID: <20110704121307.GX561@dastard> References: MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: User-Agent: Mutt/1.5.20 (2009-06-14) X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1309781591 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0013 1.0000 -2.0126 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -2.01 X-Barracuda-Spam-Status: No, SCORE=-2.01 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67942 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean On Mon, Jul 04, 2011 at 11:41:49AM +0200, Åukasz Korczyk wrote: > Helo > > I have a question I wasn't able to find answer for. > > Which factors influence memory usage of xfs_repair? > Does any formula exist to count possible memory usage? # xfs_repair -n -vv -m 1 /dev/vda Phase 1 - find and verify superblock... - max_mem = 1024, icount = 64, imem = 0, dblock = 4294967296, dmem = 2097152 Required memory for repair is greater that the maximum specified with the -m option. Please increase it to at least 2096. So it's telling me I need at least 2096MB of RAM to repair my 16TB filesystem, of which 2097152KB is needed for tracking free space... I just added 50 million inodes to the filesystem (it now has 50M + 10 inodes in it), and the result is: # xfs_repair -vv -m 1 /dev/vda Phase 1 - find and verify superblock... - max_mem = 1024, icount = 50401792, imem = 196882, dblock = 4294967296, dmem = 2097152 Required memory for repair is greater that the maximum specified with the -m option. Please increase it to at least 2289. That is now needs at least another 200MB of RAM to run. It is worth noting that these numbers are the absolute minimum required and repair may require more RAM than this to complete successfully. If you only give it this much RAM, it will be slow; for best repair performance, the more RAM you can give it the better. Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Mon Jul 4 07:49:11 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p64CnBVM146898 for ; Mon, 4 Jul 2011 07:49:11 -0500 X-ASG-Debug-ID: 1309783749-21e902070000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from ipmail07.adl2.internode.on.net (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 619CD1678A95 for ; Mon, 4 Jul 2011 05:49:09 -0700 (PDT) Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id bxvROI2PhaEIi0ZN for ; Mon, 04 Jul 2011 05:49:09 -0700 (PDT) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Av0EAPS1EU55LCkB/2dsb2JhbABSp3x4iHrBHw6GKASifg Received: from ppp121-44-41-1.lns20.syd6.internode.on.net (HELO dastard) ([121.44.41.1]) by ipmail07.adl2.internode.on.net with ESMTP; 04 Jul 2011 22:19:08 +0930 Received: from dave by dastard with local (Exim 4.72) (envelope-from ) id 1QdiaI-0003eB-Ud; Mon, 04 Jul 2011 22:49:06 +1000 Date: Mon, 4 Jul 2011 22:49:06 +1000 From: Dave Chinner To: Volkan YAZICI Cc: xfs@oss.sgi.com X-ASG-Orig-Subj: Re: Recovering XFS Partition of Type FAT16 Subject: Re: Recovering XFS Partition of Type FAT16 Message-ID: <20110704124906.GY561@dastard> References: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.20 (2009-06-14) X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1309783750 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -1.61 X-Barracuda-Spam-Status: No, SCORE=-1.61 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=SUBJECT_FUZZY_TION X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67945 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.41 SUBJECT_FUZZY_TION Attempt to obfuscate words in Subject: X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean On Mon, Jul 04, 2011 at 10:23:55AM +0000, Volkan YAZICI wrote: > Hi, > > I have an XFS partition, which is > > 1) Mistakenly quick formatted as FAT16. > 2) At first, I couldn't see in "fdisk -l" that it is set to FAT16, > instead of Linux. Hence, tried to fix it with xfs_recover. xfs_recover > returned 0, and mount operation succeeded; but mounted fs size > appeared as 20GB (despite it is 350GB) and almost every file was > missing. > 3) Later, I set the type of /dev/sda1 (the only partition in /dev/sda) > to Linux, re-run xfs_recover, but nothing changed: Same fs size (20GB) > and same missing files. What is this xfs_recover tool you speak of? I've never heard of it, I can't find any direct links to it in google (only forum posts from years ago about how great it is) so I have no idea what you've done to your filesystem... > I open the system with Knoppix, and below are the partition > diagnostics. I need urgent help to recover the files. I will be > really, really appreciated for any help! (If you need further > information, just drop me a mail.) > > > Best. > > > # fdisk -l > > Disk /dev/sda: 320.1 GB, 320072933376 bytes > 255 heads, 63 sectors/track, 38913 cylinders > Units = cylinders of 16065 * 512 = 8225280 bytes > Sector size (logical/physical): 512 bytes / 512 bytes > I/O size (minimum/optimal): 512 bytes / 512 bytes > Disk identifier: 0x447c435f > > Device Boot Start End Blocks Id System > /dev/sda1 * 1 38913 312568641 83 Linux > > > # mount | grep /dev/sda1 > /dev/sda1 on /media/sda1 type xfs (rw,relatime,attr2,noquota) > > > # df -h | grep /dev/sda1 > /dev/sda1 19G 4,2G 15G 23% /media/sda1 > > # xfs_info /mnt/sda1 > meta-data=/dev/sda1 isize=256 agcount=4, agsize=1226963 blks > = sectsz=512 attr=2 > data = bsize=4096 blocks=4907849, imaxpct=25 > = sunit=0 swidth=0 blks > naming =version 2 bsize=4096 ascii-ci=0 > log =internal bsize=4096 blocks=2560, version=2 > = sectsz=512 sunit=0 blks, lazy-count=1 > realtime =none extsz=4096 blocks=0, rtextents=0 That looks like a newly made 20GB XFS filesystem, not the result of repairing a 350GB filesystem... If I were you, I'd be restoring from backups. You do have backups, right? Cheers, Dave. -- Dave Chinner david@fromorbit.com From BATV+e83e9d2711330749e835+2871+infradead.org+hch@bombadil.srs.infradead.org Mon Jul 4 10:34:52 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p64FYpQN162449 for ; Mon, 4 Jul 2011 10:34:52 -0500 X-ASG-Debug-ID: 1309793684-20b3034a0000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from bombadil.infradead.org (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id 5623C1EE87E4 for ; Mon, 4 Jul 2011 08:34:44 -0700 (PDT) Received: from bombadil.infradead.org (173-166-109-252-newengland.hfc.comcastbusiness.net [173.166.109.252]) by cuda.sgi.com with ESMTP id oo6AeMUdGO55OGkd for ; Mon, 04 Jul 2011 08:34:44 -0700 (PDT) Received: from hch by bombadil.infradead.org with local (Exim 4.76 #1 (Red Hat Linux)) id 1QdlAZ-0005o8-N7 for xfs@oss.sgi.com; Mon, 04 Jul 2011 15:34:43 +0000 Date: Mon, 4 Jul 2011 11:34:43 -0400 From: Christoph Hellwig To: xfs@oss.sgi.com X-ASG-Orig-Subj: [RFC] remove filestreams support? Subject: [RFC] remove filestreams support? Message-ID: <20110704153443.GA21501@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: 173-166-109-252-newengland.hfc.comcastbusiness.net[173.166.109.252] X-Barracuda-Start-Time: 1309793684 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0674 1.0000 -1.5911 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -0.99 X-Barracuda-Spam-Status: No, SCORE=-0.99 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=BSF_SC5_MJ1963, RDNS_DYNAMIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67956 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_DYNAMIC Delivered to trusted network by host with dynamic-looking rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean I'd like to know if there are any people actively using the filestreams support in XFS (-o filestreams). It's pretty much a fringe feature, and I've not seen any user reports for it, while it never passes all its XFSQA tests reliably. It was added specificly for CXFS media streaming operations on one particular array model that hasn't been sold for a long time. The feature purely is an in-memory one so unlike for example the realtime device there are no issue about beeing able to read old filesystems. The filestreams specific files are around 1500 lines of code, not even counting the hooks in the core XFS codebase. If no serious users reply to this mail I'd like to add a deprecation warning to the mount option in the Linux 3.0 release cycle, with a goal to drop it 4 releases later. From BATV+e83e9d2711330749e835+2871+infradead.org+hch@bombadil.srs.infradead.org Mon Jul 4 16:21:03 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p64LL1nE189650 for ; Mon, 4 Jul 2011 16:21:03 -0500 X-ASG-Debug-ID: 1309814458-445800df0000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from bombadil.infradead.org (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id BD91A4A1C6 for ; Mon, 4 Jul 2011 14:20:58 -0700 (PDT) Received: from bombadil.infradead.org (173-166-109-252-newengland.hfc.comcastbusiness.net [173.166.109.252]) by cuda.sgi.com with ESMTP id 01i5GnhtCZtHBQ3s for ; Mon, 04 Jul 2011 14:20:58 -0700 (PDT) Received: from hch by bombadil.infradead.org with local (Exim 4.76 #1 (Red Hat Linux)) id 1QdqZc-00073n-1Z; Mon, 04 Jul 2011 21:20:56 +0000 Date: Mon, 4 Jul 2011 17:20:56 -0400 From: Christoph Hellwig To: Dave Chinner Cc: xfs@oss.sgi.com X-ASG-Orig-Subj: Re: [PATCH 2/5] xfs: use a cursor for bulk AIL insertion Subject: Re: [PATCH 2/5] xfs: use a cursor for bulk AIL insertion Message-ID: <20110704212055.GA24500@infradead.org> References: <1309757260-5484-1-git-send-email-david@fromorbit.com> <1309757260-5484-3-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1309757260-5484-3-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: 173-166-109-252-newengland.hfc.comcastbusiness.net[173.166.109.252] X-Barracuda-Start-Time: 1309814458 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -1.92 X-Barracuda-Spam-Status: No, SCORE=-1.92 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests=RDNS_DYNAMIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67980 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_DYNAMIC Delivered to trusted network by host with dynamic-looking rDNS X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean FYI: the following patch implementing my suggested cleanups survived a few rounds of xfsqa: Index: xfs/fs/xfs/xfs_trans_ail.c =================================================================== --- xfs.orig/fs/xfs/xfs_trans_ail.c 2011-07-04 16:04:08.932174424 +0200 +++ xfs/fs/xfs/xfs_trans_ail.c 2011-07-04 16:12:51.402677292 +0200 @@ -267,26 +267,14 @@ out: static struct xfs_log_item * __xfs_trans_ail_cursor_last( struct xfs_ail *ailp, - struct xfs_ail_cursor *cur, - xfs_lsn_t lsn, - bool do_init) + xfs_lsn_t lsn) { - xfs_log_item_t *lip = NULL; - - if (do_init) - xfs_trans_ail_cursor_init(ailp, cur); + struct xfs_log_item *lip; - if (list_empty(&ailp->xa_ail)) - goto out; - - list_for_each_entry_reverse(lip, &ailp->xa_ail, li_ail) { + list_for_each_entry_reverse(lip, &ailp->xa_ail, li_ail) if (XFS_LSN_CMP(lip->li_lsn, lsn) <= 0) - break; - } -out: - if (cur) - cur->item = lip; - return lip; + return lip; + return NULL; } /* @@ -300,7 +288,9 @@ xfs_trans_ail_cursor_last( struct xfs_ail_cursor *cur, xfs_lsn_t lsn) { - return __xfs_trans_ail_cursor_last(ailp, cur, lsn, true); + xfs_trans_ail_cursor_init(ailp, cur); + cur->item = __xfs_trans_ail_cursor_last(ailp, lsn); + return cur->item; } /* @@ -319,27 +309,22 @@ xfs_ail_splice( struct xfs_log_item *lip = cur ? cur->item : NULL; struct xfs_log_item *next_lip; - do { - /* no placeholder, so get our insert location */ - if (!lip) - lip = __xfs_trans_ail_cursor_last(ailp, cur, - lsn, false); - + /* + * Get a new cursor if we do not have a placeholder or an + * invalidated one. + */ + if (!lip || (__psint_t)lip & 1) { + lip = __xfs_trans_ail_cursor_last(ailp, lsn); if (!lip) { /* - * The list is empty, so just splice and return. Our - * cursor is already guaranteed to be up to date, so we - * don't need to touch it here. + * The list is empty, so just splice and return. */ + if (cur) + cur->item = NULL; list_splice(list, &ailp->xa_ail); return; } - - /* The placeholder was invalidated, need to get a new cursor */ - if ((__psint_t)lip & 1) - lip = NULL; - - } while (lip == NULL); + } /* * Our cursor points to the item we want to insert _after_, so we have From stewart@flamingspork.com Mon Jul 4 20:17:41 2011 X-Spam-Checker-Version: SpamAssassin 3.4.0-r929098 (2010-03-30) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.4.0-r929098 Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p651Hfba206627 for ; Mon, 4 Jul 2011 20:17:41 -0500 X-ASG-Debug-ID: 1309828660-217a03280000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from kaylee.flamingspork.com (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with ESMTP id CD4A923D5D for ; Mon, 4 Jul 2011 18:17:40 -0700 (PDT) Received: from kaylee.flamingspork.com (kaylee.flamingspork.com [74.207.245.61]) by cuda.sgi.com with ESMTP id dnKnaib0FIlITlNR for ; Mon, 04 Jul 2011 18:17:40 -0700 (PDT) Received: from willster (localhost [127.0.0.1]) by kaylee.flamingspork.com (Postfix) with ESMTPS id 1D88C60B2; Tue, 5 Jul 2011 01:16:01 +0000 (UTC) Received: by willster (Postfix, from userid 1000) id EFBDF3077FDF; Tue, 5 Jul 2011 11:17:46 +1000 (EST) From: Stewart Smith To: Christoph Hellwig , xfs@oss.sgi.com X-ASG-Orig-Subj: Re: [RFC] remove filestreams support? Subject: Re: [RFC] remove filestreams support? In-Reply-To: <20110704153443.GA21501@infradead.org> References: <20110704153443.GA21501@infradead.org> User-Agent: Notmuch/0.5-215-g5143e5e (http://notmuchmail.org) Emacs/23.2.1 (x86_64-pc-linux-gnu) Date: Tue, 05 Jul 2011 11:17:46 +1000 Message-ID: <87sjqlbk5h.fsf@flamingspork.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Barracuda-Connect: kaylee.flamingspork.com[74.207.245.61] X-Barracuda-Start-Time: 1309828660 X-Barracuda-Bayes: INNOCENT GLOBAL 0.0000 1.0000 -2.0210 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -2.02 X-Barracuda-Spam-Status: No, SCORE=-2.02 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.67994 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean On Mon, 4 Jul 2011 11:34:43 -0400, Christoph Hellwig wrote: > I'd like to know if there are any people actively using the filestreams > support in XFS (-o filestreams). It's pretty much a fringe feature, and > I've not seen any user reports for it, while it never passes all its > XFSQA tests reliably. It was added specificly for CXFS media streaming > operations on one particular array model that hasn't been sold for a > long time. The feature purely is an in-memory one so unlike for example > the realtime device there are no issue about beeing able to read old > filesystems. The filestreams specific files are around 1500 lines of > code, not even counting the hooks in the core XFS codebase. I used it a bit on MythTV box to help circumvent the stupid behaviour of it fsync()ing every second[1] leading to poor file layout on disk. I found that filestreams worked a bit better than just setting allocsize mount option... but I wouldn't be screaming too much if it went away.... [1] which was to work around ext3 taking locks for so long that you'd then miss part of your TV program -- Stewart Smith From gxwct@qq.com Mon Jul 4 20:50:12 2011 Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by oss.sgi.com (8.14.3/8.14.3/SuSE Linux 0.8) with ESMTP id p651oAHK211133 for ; Mon, 4 Jul 2011 20:50:11 -0500 X-ASG-Debug-ID: 1309830304-46e502640000-NocioJ X-Barracuda-URL: http://cuda.sgi.com:80/cgi-bin/mark.cgi Received: from smtpbg52.qq.com (localhost [127.0.0.1]) by cuda.sgi.com (Spam Firewall) with SMTP id 8F9414AFF6 for ; Mon, 4 Jul 2011 18:45:05 -0700 (PDT) Received: from smtpbg52.qq.com (smtpbg52.qq.com [64.71.138.43]) by cuda.sgi.com with SMTP id a77R3wA71g1gfP9D for ; Mon, 04 Jul 2011 18:45:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qq.com; s=s0907; t=1309830293; bh=Cej6YwArcbuY6TeiHKEQxWNKLdBJgzOeYWRAayJq8hw=; h=X-QQ-SSF:X-QQ-BUSINESS-ORIGIN:X-Originating-IP:X-QQ-STYLE: X-QQ-mid:From:To:Subject:Mime-Version:Content-Type: Content-Transfer-Encoding:Date:X-Priority:Message-ID:X-QQ-MIME: X-Mailer:X-QQ-Mailer; b=DjrTYKto9wbbCe/4NOxJQPEI4CvjU11QaNigHujqK58HUOZrN/XaDjFi6dwqU5tAU Gl8x18bwmxfjuFIUY2BL84VXU+jew7ki6hMmHIG2gL/qH5x+szG+uGhM/M5PcyU X-QQ-SSF:00000000000000F0 X-QQ-BUSINESS-ORIGIN:2 X-Originating-IP: 112.94.22.132 X-QQ-STYLE: X-QQ-mid:webmail54t1309830288t1082205 From: "=?gbk?B?eHdnYW8=?=" To: "=?gbk?B?eGZz?=" X-ASG-Orig-Subj: About XFS write disk error Subject: About XFS write disk error Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_4E126C90_DECC7AC0_2512BD9E" Content-Transfer-Encoding: 8Bit Date: Tue, 5 Jul 2011 09:44:48 +0800 X-Priority: 3 Message-ID: X-QQ-MIME: TCMime 1.0 by Tencent X-Mailer: QQMail 2.x X-QQ-Mailer: QQMail 2.x X-Barracuda-Connect: smtpbg52.qq.com[64.71.138.43] X-Barracuda-Start-Time: 1309830307 X-Barracuda-Virus-Scanned: by cuda.sgi.com at sgi.com X-Barracuda-Spam-Score: -1001.00 X-Barracuda-Spam-Status: No, SCORE=-1001.00 using per-user scores of TAG_LEVEL=2.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.1 X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on oss.sgi.com X-Virus-Status: Clean This is a multi-part message in MIME format. ------=_NextPart_4E126C90_DECC7AC0_2512BD9E Content-Type: multipart/alternative; boundary="----=_NextPart_4E126C90_DECC7AC0_1BB50841"; ------=_NextPart_4E126C90_DECC7AC0_1BB50841 Content-Type: text/plain; charset="gbk" Content-Transfer-Encoding: base64 QXR0YWNoZWQgaXMgc3luY2hyb25pemVkIHdpdGggcnN5bmMgY29tbWFuZCB0byB3cml0ZSBk YXRhIHRvIHRoZSBjb3JyZXNwb25kaW5nIFhGUyBmaWxlIHN5c3RlbSBkaXNrIGVycm9yIG1l c3NhZ2UgcmVwb3J0ZWQgYnkgdGhl ------=_NextPart_4E126C90_DECC7AC0_1BB50841 Content-Type: text/html; charset="gbk" Content-Transfer-Encoding: base64 PGRpdj48aW5jbHVkZXRhaWw+PGRpdiBzdHlsZT0iZm9udDpWZXJkYW5hIG5vcm1hbCAxNHB4 O2NvbG9yOiMwMDA7Ij48c3BhbiBpZD0icmVzdWx0X2JveCIgY2xhc3M9IiIgbGFuZz0iZW4i PjxzcGFuIHRpdGxlPSK147v3v8nP1Mq+xuTL+7et0usiIGNsYXNzPSJocHMiPkF0dGFjaGVk IGlzPC9zcGFuPiA8c3BhbiB0aXRsZT0iteO797/Jz9TKvsbky/u3rdLrIiBjbGFzcz0iaHBz Ij5zeW5jaHJvbml6ZWQ8L3NwYW4+IDxzcGFuIHRpdGxlPSK147v3v8nP1Mq+xuTL+7et0usi IGNsYXNzPSJocHMiPndpdGggcnN5bmM8L3NwYW4+IDxzcGFuIHRpdGxlPSK147v3v8nP1Mq+ xuTL+7et0usiIGNsYXNzPSJocHMiPmNvbW1hbmQ8L3NwYW4+IDxzcGFuIHRpdGxlPSK147v3 v8nP1Mq+xuTL+7et0usiIGNsYXNzPSJocHMiPnRvIHdyaXRlIGRhdGE8L3NwYW4+IDxzcGFu IHRpdGxlPSK147v3v8nP1Mq+xuTL+7et0usiIGNsYXNzPSJocHMiPnRvIHRoZSBjb3JyZXNw b25kaW5nPC9zcGFuPiA8c3BhbiB0aXRsZT0iteO797/Jz9TKvsbky/u3rdLrIiBjbGFzcz0i aHBzIj5YRlMgZmlsZTwvc3Bhbj4gPHNwYW4gdGl0bGU9IrXju/e/yc/Uyr7G5Mv7t63S6yIg Y2xhc3M9ImhwcyI+c3lzdGVtPC9zcGFuPiA8c3BhbiB0aXRsZT0iteO797/Jz9TKvsbky/u3 rdLrIiBjbGFzcz0iaHBzIj5kaXNrPC9zcGFuPiA8c3BhbiB0aXRsZT0iteO797/Jz9TKvsbk y/u3rdLrIiBjbGFzcz0iaHBzIj5lcnJvciBtZXNzYWdlPC9zcGFuPiA8c3BhbiB0aXRsZT0i teO797/Jz9TKvsbky/u3rdLrIiBjbGFzcz0iaHBzIj5yZXBvcnRlZDwvc3Bhbj4gPHNwYW4g dGl0bGU9IrXju/e/yc/Uyr7G5Mv7t63S6yIgY2xhc3M9ImhwcyI+YnkgdGhlPC9zcGFuPjwv c3Bhbj48L2Rpdj48L2luY2x1ZGV0YWlsPjwvZGl2Pg== ------=_NextPart_4E126C90_DECC7AC0_1BB50841-- ------=_NextPart_4E126C90_DECC7AC0_2512BD9E Content-Type: application/octet-stream; charset="gbk"; name="=?gbk?B?NtTCMTbI1bGotO3M4cq+LmpwZWc=?=" Content-Disposition: attachment; filename="=?gbk?B?NtTCMTbI1bGotO3M4cq+LmpwZWc=?=" Content-Transfer-Encoding: base64 /9j/4AAQSkZJRgABAQAAAQABAAD/4gxYSUNDX1BST0ZJTEUAAQEAAAxITGlubwIQAABtbnRy UkdCIFhZWiAHzgACAAkABgAxAABhY3NwTVNGVAAAAABJRUMgc1JHQgAAAAAAAAAAAAAAAAAA 9tYAAQAAAADTLUhQICAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAABFjcHJ0AAABUAAAADNkZXNjAAABhAAAAGx3dHB0AAAB8AAAABRia3B0AAACBAAA ABRyWFlaAAACGAAAABRnWFlaAAACLAAAABRiWFlaAAACQAAAABRkbW5kAAACVAAAAHBkbWRk AAACxAAAAIh2dWVkAAADTAAAAIZ2aWV3AAAD1AAAACRsdW1pAAAD+AAAABRtZWFzAAAEDAAA ACR0ZWNoAAAEMAAAAAxyVFJDAAAEPAAACAxnVFJDAAAEPAAACAxiVFJDAAAEPAAACAx0ZXh0 AAAAAENvcHlyaWdodCAoYykgMTk5OCBIZXdsZXR0LVBhY2thcmQgQ29tcGFueQAAZGVzYwAA AAAAAAASc1JHQiBJRUM2MTk2Ni0yLjEAAAAAAAAAAAAAABJzUkdCIElFQzYxOTY2LTIuMQAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWFlaIAAA AAAAAPNRAAEAAAABFsxYWVogAAAAAAAAAAAAAAAAAAAAAFhZWiAAAAAAAABvogAAOPUAAAOQ WFlaIAAAAAAAAGKZAAC3hQAAGNpYWVogAAAAAAAAJKAAAA+EAAC2z2Rlc2MAAAAAAAAAFklF QyBodHRwOi8vd3d3LmllYy5jaAAAAAAAAAAAAAAAFklFQyBodHRwOi8vd3d3LmllYy5jaAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABkZXNjAAAAAAAA AC5JRUMgNjE5NjYtMi4xIERlZmF1bHQgUkdCIGNvbG91ciBzcGFjZSAtIHNSR0IAAAAAAAAA AAAAAC5JRUMgNjE5NjYtMi4xIERlZmF1bHQgUkdCIGNvbG91ciBzcGFjZSAtIHNSR0IAAAAA AAAAAAAAAAAAAAAAAAAAAAAAZGVzYwAAAAAAAAAsUmVmZXJlbmNlIFZpZXdpbmcgQ29uZGl0 aW9uIGluIElFQzYxOTY2LTIuMQAAAAAAAAAAAAAALFJlZmVyZW5jZSBWaWV3aW5nIENvbmRp dGlvbiBpbiBJRUM2MTk2Ni0yLjEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHZpZXcAAAAA ABOk/gAUXy4AEM8UAAPtzAAEEwsAA1yeAAAAAVhZWiAAAAAAAEwJVgBQAAAAVx/nbWVhcwAA AAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAo8AAAACc2lnIAAAAABDUlQgY3VydgAAAAAAAAQA AAAABQAKAA8AFAAZAB4AIwAoAC0AMgA3ADsAQABFAEoATwBUAFkAXgBjAGgAbQByAHcAfACB AIYAiwCQAJUAmgCfAKQAqQCuALIAtwC8AMEAxgDLANAA1QDbAOAA5QDrAPAA9gD7AQEBBwEN ARMBGQEfASUBKwEyATgBPgFFAUwBUgFZAWABZwFuAXUBfAGDAYsBkgGaAaEBqQGxAbkBwQHJ AdEB2QHhAekB8gH6AgMCDAIUAh0CJgIvAjgCQQJLAlQCXQJnAnECegKEAo4CmAKiAqwCtgLB AssC1QLgAusC9QMAAwsDFgMhAy0DOANDA08DWgNmA3IDfgOKA5YDogOuA7oDxwPTA+AD7AP5 BAYEEwQgBC0EOwRIBFUEYwRxBH4EjASaBKgEtgTEBNME4QTwBP4FDQUcBSsFOgVJBVgFZwV3 BYYFlgWmBbUFxQXVBeUF9gYGBhYGJwY3BkgGWQZqBnsGjAadBq8GwAbRBuMG9QcHBxkHKwc9 B08HYQd0B4YHmQesB78H0gflB/gICwgfCDIIRghaCG4IggiWCKoIvgjSCOcI+wkQCSUJOglP CWQJeQmPCaQJugnPCeUJ+woRCicKPQpUCmoKgQqYCq4KxQrcCvMLCwsiCzkLUQtpC4ALmAuw C8gL4Qv5DBIMKgxDDFwMdQyODKcMwAzZDPMNDQ0mDUANWg10DY4NqQ3DDd4N+A4TDi4OSQ5k Dn8Omw62DtIO7g8JDyUPQQ9eD3oPlg+zD88P7BAJECYQQxBhEH4QmxC5ENcQ9RETETERTxFt EYwRqhHJEegSBxImEkUSZBKEEqMSwxLjEwMTIxNDE2MTgxOkE8UT5RQGFCcUSRRqFIsUrRTO FPAVEhU0FVYVeBWbFb0V4BYDFiYWSRZsFo8WshbWFvoXHRdBF2UXiReuF9IX9xgbGEAYZRiK GK8Y1Rj6GSAZRRlrGZEZtxndGgQaKhpRGncanhrFGuwbFBs7G2MbihuyG9ocAhwqHFIcexyj HMwc9R0eHUcdcB2ZHcMd7B4WHkAeah6UHr4e6R8THz4faR+UH78f6iAVIEEgbCCYIMQg8CEc IUghdSGhIc4h+yInIlUigiKvIt0jCiM4I2YjlCPCI/AkHyRNJHwkqyTaJQklOCVoJZclxyX3 JicmVyaHJrcm6CcYJ0kneierJ9woDSg/KHEooijUKQYpOClrKZ0p0CoCKjUqaCqbKs8rAis2 K2krnSvRLAUsOSxuLKIs1y0MLUEtdi2rLeEuFi5MLoIuty7uLyQvWi+RL8cv/jA1MGwwpDDb MRIxSjGCMbox8jIqMmMymzLUMw0zRjN/M7gz8TQrNGU0njTYNRM1TTWHNcI1/TY3NnI2rjbp NyQ3YDecN9c4FDhQOIw4yDkFOUI5fzm8Ofk6Njp0OrI67zstO2s7qjvoPCc8ZTykPOM9Ij1h PaE94D4gPmA+oD7gPyE/YT+iP+JAI0BkQKZA50EpQWpBrEHuQjBCckK1QvdDOkN9Q8BEA0RH RIpEzkUSRVVFmkXeRiJGZ0arRvBHNUd7R8BIBUhLSJFI10kdSWNJqUnwSjdKfUrESwxLU0ua S+JMKkxyTLpNAk1KTZNN3E4lTm5Ot08AT0lPk0/dUCdQcVC7UQZRUFGbUeZSMVJ8UsdTE1Nf U6pT9lRCVI9U21UoVXVVwlYPVlxWqVb3V0RXklfgWC9YfVjLWRpZaVm4WgdaVlqmWvVbRVuV W+VcNVyGXNZdJ114XcleGl5sXr1fD19hX7NgBWBXYKpg/GFPYaJh9WJJYpxi8GNDY5dj62RA ZJRk6WU9ZZJl52Y9ZpJm6Gc9Z5Nn6Wg/aJZo7GlDaZpp8WpIap9q92tPa6dr/2xXbK9tCG1g bbluEm5rbsRvHm94b9FwK3CGcOBxOnGVcfByS3KmcwFzXXO4dBR0cHTMdSh1hXXhdj52m3b4 d1Z3s3gReG54zHkqeYl553pGeqV7BHtje8J8IXyBfOF9QX2hfgF+Yn7CfyN/hH/lgEeAqIEK gWuBzYIwgpKC9INXg7qEHYSAhOOFR4Wrhg6GcobXhzuHn4gEiGmIzokziZmJ/opkisqLMIuW i/yMY4zKjTGNmI3/jmaOzo82j56QBpBukNaRP5GokhGSepLjk02TtpQglIqU9JVflcmWNJaf lwqXdZfgmEyYuJkkmZCZ/JpomtWbQpuvnByciZz3nWSd0p5Anq6fHZ+Ln/qgaaDYoUehtqIm opajBqN2o+akVqTHpTilqaYapoum/adup+CoUqjEqTepqaocqo+rAqt1q+msXKzQrUStuK4t rqGvFq+LsACwdbDqsWCx1rJLssKzOLOutCW0nLUTtYq2AbZ5tvC3aLfguFm40blKucK6O7q1 uy67p7whvJu9Fb2Pvgq+hL7/v3q/9cBwwOzBZ8Hjwl/C28NYw9TEUcTOxUvFyMZGxsPHQce/ yD3IvMk6ybnKOMq3yzbLtsw1zLXNNc21zjbOts83z7jQOdC60TzRvtI/0sHTRNPG1EnUy9VO 1dHWVdbY11zX4Nhk2OjZbNnx2nba+9uA3AXcit0Q3ZbeHN6i3ynfr+A24L3hROHM4lPi2+Nj 4+vkc+T85YTmDeaW5x/nqegy6LzpRunQ6lvq5etw6/vshu0R7ZzuKO6070DvzPBY8OXxcvH/ 8ozzGfOn9DT0wvVQ9d72bfb794r4Gfio+Tj5x/pX+uf7d/wH/Jj9Kf26/kv+3P9t////2wBD AAICAgICAQICAgICAgIDAwYEAwMDAwcFBQQGCAcICAgHCAgJCg0LCQkMCggICw8LDA0ODg4O CQsQEQ8OEQ0ODg7/2wBDAQICAgMDAwYEBAYOCQgJDg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4O Dg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg7/wAARCAHgAoADASIAAhEBAxEB/8QAHwAAAQUB AQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIh MUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdI SUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKz tLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEB AQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSEx BhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZH 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 m4uoLBDs1JXl2BZsk52N84wetebal8b9U1P9p/SviIdM00W2mWUGmWuizxCWCOxjTZ9myR82 QXwx5G6naz8WNIb4E+IfA/gvwdB4QsfEF7BLrkq3jXBnjgYvHEAyjaA20574rnjiKUasXduy 17bW79/I0nh8UqKgoWV01r/eV9PT1Ox+HPxPGr/GD4Q2Hifw7pWvapp2oWOmWWq3M0i3EUAn Xy1ADBSU4xxnA717ba22hWP7Rv7YXi29mNreaFqBEGoQWq3Mtms1yVkKRt8pY/KPoTXy78Pv iV4b8CWMGo2vgpL3x1ZrM1hrFzeb44JHUhJfJ24LJnIGevNU/A/xPHhz/hOLPxHY3PirQfFt h9m1yE3Gye4cP5kcok67g5yfUVGFqQjZye8tv19PLS1h4nL6ln7OFrR+9uSbt8k+256B418W eAPH8/wt0mzk1rWfE1vrYs9Z1G5sEtvtlpLMuxNqcbl3ON3YVufF34gXPhj9qX4qeBZ9I0jV fBVnd3WkWWmtbpEYI1G2JlkUbsoQD789M1454k8faLPY+ELLwR4Zg8K2mgXTahHcSN9ouri5 Mm8NJJxlBtUBMYGK9A1r4zeBdd8eeJvHU3gG4uPH2s20rTTXd0slil1LGFkmEOB0wSo7Guyv XbdRc1npdrr5Le/zt5nnYag7QjOnKUbytFvVN2s9LW0va2zPKPhvq3ibQ/jR4cu/CSi7117p YoLRRlbzf8rROOhVgSDwcde1bvxt0bw14e/aK8Q6f4YniNgNktzbRSCRLO5dN0lujjhlQkDI 45x2qLwD47s/h7pniTWLHThP40vLFbfQ9SdwE0zcSJZAOvmlThT2ryiabzLySSVpTkFixzuY k85z1z1z615TqU4xavfm/Cz39f0Pp6UZyxjk4WUVbrrfb7vzbPprUSq/8EhfDkke5gvxOukd kP3c2qnn256V8xowdMGYiEsTtBxk1714p+JXgq+/ZB0f4ZeEdG8RWa2fiNtYmvdSnjbzGeDy 2UBSeM8j04rwQum/ID++Ohp1q0JRpx3aWu/d9/0KyinL95OorKUm1fsfQ/wt0bSdR/Y7/aN1 G502yvNQ03SdMl024lXL2xe6IcqexIXB+uKk+NOi+H9Dn+DBtdMht7W78Aabe6glmAkty7yz CRsnI3MF6nPOK5j4U/EHQvDPhv4geDvFdpfSeFPFunxW97dacAbmBoZRJGVzxgknIqf4h/EX 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 ------=_NextPart_4E126C90_DECC7AC0_2512BD9E Content-Type: application/octet-stream; charset="gbk"; name="=?gbk?B?NtTCMTfI1bnK1c/M4cq+XzEuanBlZw==?=" Content-Disposition: attachment; filename="=?gbk?B?NtTCMTfI1bnK1c/M4cq+XzEuanBlZw==?=" Content-Transfer-Encoding: base64 /9j/4AAQSkZJRgABAQAAAQABAAD/4gxYSUNDX1BST0ZJTEUAAQEAAAxITGlubwIQAABtbnRy UkdCIFhZWiAHzgACAAkABgAxAABhY3NwTVNGVAAAAABJRUMgc1JHQgAAAAAAAAAAAAAAAAAA 9tYAAQAAAADTLUhQICAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAABFjcHJ0AAABUAAAADNkZXNjAAABhAAAAGx3dHB0AAAB8AAAABRia3B0AAACBAAA ABRyWFlaAAACGAAAABRnWFlaAAACLAAAABRiWFlaAAACQAAAABRkbW5kAAACVAAAAHBkbWRk AAACxAAAAIh2dWVkAAADTAAAAIZ2aWV3AAAD1AAAACRsdW1pAAAD+AAAABRtZWFzAAAEDAAA ACR0ZWNoAAAEMAAAAAxyVFJDAAAEPAAACAxnVFJDAAAEPAAACAxiVFJDAAAEPAAACAx0ZXh0 AAAAAENvcHlyaWdodCAoYykgMTk5OCBIZXdsZXR0LVBhY2thcmQgQ29tcGFueQAAZGVzYwAA AAAAAAASc1JHQiBJRUM2MTk2Ni0yLjEAAAAAAAAAAAAAABJzUkdCIElFQzYxOTY2LTIuMQAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWFlaIAAA AAAAAPNRAAEAAAABFsxYWVogAAAAAAAAAAAAAAAAAAAAAFhZWiAAAAAAAABvogAAOPUAAAOQ WFlaIAAAAAAAAGKZAAC3hQAAGNpYWVogAAAAAAAAJKAAAA+EAAC2z2Rlc2MAAAAAAAAAFklF QyBodHRwOi8vd3d3LmllYy5jaAAAAAAAAAAAAAAAFklFQyBodHRwOi8vd3d3LmllYy5jaAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABkZXNjAAAAAAAA AC5JRUMgNjE5NjYtMi4xIERlZmF1bHQgUkdCIGNvbG91ciBzcGFjZSAtIHNSR0IAAAAAAAAA AAAAAC5JRUMgNjE5NjYtMi4xIERlZmF1bHQgUkdCIGNvbG91ciBzcGFjZSAtIHNSR0IAAAAA AAAAAAAAAAAAAAAAAAAAAAAAZGVzYwAAAAAAAAAsUmVmZXJlbmNlIFZpZXdpbmcgQ29uZGl0 aW9uIGluIElFQzYxOTY2LTIuMQAAAAAAAAAAAAAALFJlZmVyZW5jZSBWaWV3aW5nIENvbmRp dGlvbiBpbiBJRUM2MTk2Ni0yLjEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHZpZXcAAAAA ABOk/gAUXy4AEM8UAAPtzAAEEwsAA1yeAAAAAVhZWiAAAAAAAEwJVgBQAAAAVx/nbWVhcwAA AAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAo8AAAACc2lnIAAAAABDUlQgY3VydgAAAAAAAAQA AAAABQAKAA8AFAAZAB4AIwAoAC0AMgA3ADsAQABFAEoATwBUAFkAXgBjAGgAbQByAHcAfACB AIYAiwCQAJUAmgCfAKQAqQCuALIAtwC8AMEAxgDLANAA1QDbAOAA5QDrAPAA9gD7AQEBBwEN ARMBGQEfASUBKwEyATgBPgFFAUwBUgFZAWABZwFuAXUBfAGDAYsBkgGaAaEBqQGxAbkBwQHJ AdEB2QHhAekB8gH6AgMCDAIUAh0CJgIvAjgCQQJLAlQCXQJnAnECegKEAo4CmAKiAqwCtgLB AssC1QLgAusC9QMAAwsDFgMhAy0DOANDA08DWgNmA3IDfgOKA5YDogOuA7oDxwPTA+AD7AP5 BAYEEwQgBC0EOwRIBFUEYwRxBH4EjASaBKgEtgTEBNME4QTwBP4FDQUcBSsFOgVJBVgFZwV3 BYYFlgWmBbUFxQXVBeUF9gYGBhYGJwY3BkgGWQZqBnsGjAadBq8GwAbRBuMG9QcHBxkHKwc9 B08HYQd0B4YHmQesB78H0gflB/gICwgfCDIIRghaCG4IggiWCKoIvgjSCOcI+wkQCSUJOglP CWQJeQmPCaQJugnPCeUJ+woRCicKPQpUCmoKgQqYCq4KxQrcCvMLCwsiCzkLUQtpC4ALmAuw C8gL4Qv5DBIMKgxDDFwMdQyODKcMwAzZDPMNDQ0mDUANWg10DY4NqQ3DDd4N+A4TDi4OSQ5k Dn8Omw62DtIO7g8JDyUPQQ9eD3oPlg+zD88P7BAJECYQQxBhEH4QmxC5ENcQ9RETETERTxFt EYwRqhHJEegSBxImEkUSZBKEEqMSwxLjEwMTIxNDE2MTgxOkE8UT5RQGFCcUSRRqFIsUrRTO FPAVEhU0FVYVeBWbFb0V4BYDFiYWSRZsFo8WshbWFvoXHRdBF2UXiReuF9IX9xgbGEAYZRiK GK8Y1Rj6GSAZRRlrGZEZtxndGgQaKhpRGncanhrFGuwbFBs7G2MbihuyG9ocAhwqHFIcexyj HMwc9R0eHUcdcB2ZHcMd7B4WHkAeah6UHr4e6R8THz4faR+UH78f6iAVIEEgbCCYIMQg8CEc IUghdSGhIc4h+yInIlUigiKvIt0jCiM4I2YjlCPCI/AkHyRNJHwkqyTaJQklOCVoJZclxyX3 JicmVyaHJrcm6CcYJ0kneierJ9woDSg/KHEooijUKQYpOClrKZ0p0CoCKjUqaCqbKs8rAis2 K2krnSvRLAUsOSxuLKIs1y0MLUEtdi2rLeEuFi5MLoIuty7uLyQvWi+RL8cv/jA1MGwwpDDb MRIxSjGCMbox8jIqMmMymzLUMw0zRjN/M7gz8TQrNGU0njTYNRM1TTWHNcI1/TY3NnI2rjbp NyQ3YDecN9c4FDhQOIw4yDkFOUI5fzm8Ofk6Njp0OrI67zstO2s7qjvoPCc8ZTykPOM9Ij1h PaE94D4gPmA+oD7gPyE/YT+iP+JAI0BkQKZA50EpQWpBrEHuQjBCckK1QvdDOkN9Q8BEA0RH RIpEzkUSRVVFmkXeRiJGZ0arRvBHNUd7R8BIBUhLSJFI10kdSWNJqUnwSjdKfUrESwxLU0ua S+JMKkxyTLpNAk1KTZNN3E4lTm5Ot08AT0lPk0/dUCdQcVC7UQZRUFGbUeZSMVJ8UsdTE1Nf U6pT9lRCVI9U21UoVXVVwlYPVlxWqVb3V0RXklfgWC9YfVjLWRpZaVm4WgdaVlqmWvVbRVuV W+VcNVyGXNZdJ114XcleGl5sXr1fD19hX7NgBWBXYKpg/GFPYaJh9WJJYpxi8GNDY5dj62RA ZJRk6WU9ZZJl52Y9ZpJm6Gc9Z5Nn6Wg/aJZo7GlDaZpp8WpIap9q92tPa6dr/2xXbK9tCG1g bbluEm5rbsRvHm94b9FwK3CGcOBxOnGVcfByS3KmcwFzXXO4dBR0cHTMdSh1hXXhdj52m3b4 d1Z3s3gReG54zHkqeYl553pGeqV7BHtje8J8IXyBfOF9QX2hfgF+Yn7CfyN/hH/lgEeAqIEK gWuBzYIwgpKC9INXg7qEHYSAhOOFR4Wrhg6GcobXhzuHn4gEiGmIzokziZmJ/opkisqLMIuW i/yMY4zKjTGNmI3/jmaOzo82j56QBpBukNaRP5GokhGSepLjk02TtpQglIqU9JVflcmWNJaf lwqXdZfgmEyYuJkkmZCZ/JpomtWbQpuvnByciZz3nWSd0p5Anq6fHZ+Ln/qgaaDYoUehtqIm opajBqN2o+akVqTHpTilqaYapoum/adup+CoUqjEqTepqaocqo+rAqt1q+msXKzQrUStuK4t rqGvFq+LsACwdbDqsWCx1rJLssKzOLOutCW0nLUTtYq2AbZ5tvC3aLfguFm40blKucK6O7q1 uy67p7whvJu9Fb2Pvgq+hL7/v3q/9cBwwOzBZ8Hjwl/C28NYw9TEUcTOxUvFyMZGxsPHQce/ yD3IvMk6ybnKOMq3yzbLtsw1zLXNNc21zjbOts83z7jQOdC60TzRvtI/0sHTRNPG1EnUy9VO 1dHWVdbY11zX4Nhk2OjZbNnx2nba+9uA3AXcit0Q3ZbeHN6i3ynfr+A24L3hROHM4lPi2+Nj 4+vkc+T85YTmDeaW5x/nqegy6LzpRunQ6lvq5etw6/vshu0R7ZzuKO6070DvzPBY8OXxcvH/ 8ozzGfOn9DT0wvVQ9d72bfb794r4Gfio+Tj5x/pX+uf7d/wH/Jj9Kf26/kv+3P9t////2wBD AAICAgICAQICAgICAgIDAwYEAwMDAwcFBQQGCAcICAgHCAgJCg0LCQkMCggICw8LDA0ODg4O CQsQEQ8OEQ0ODg7/2wBDAQICAgMDAwYEBAYOCQgJDg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4O Dg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg7/wAARCAFpAoADASIAAhEBAxEB/8QAHwAAAQUB AQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIh MUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdI SUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKz tLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEB AQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSEx BhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZH 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 ------=_NextPart_4E126C90_DECC7AC0_2512BD9E Content-Type: application/octet-stream; charset="gbk"; name="=?gbk?B?NtTCMTfI1bnK1c/M4cq+XzIuanBlZw==?=" Content-Disposition: attachment; filename="=?gbk?B?NtTCMTfI1bnK1c/M4cq+XzIuanBlZw==?=" Content-Transfer-Encoding: base64 /9j/4AAQSkZJRgABAQAAAQABAAD/4gxYSUNDX1BST0ZJTEUAAQEAAAxITGlubwIQAABtbnRy UkdCIFhZWiAHzgACAAkABgAxAABhY3NwTVNGVAAAAABJRUMgc1JHQgAAAAAAAAAAAAAAAAAA 9tYAAQAAAADTLUhQICAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAABFjcHJ0AAABUAAAADNkZXNjAAABhAAAAGx3dHB0AAAB8AAAABRia3B0AAACBAAA ABRyWFlaAAACGAAAABRnWFlaAAACLAAAABRiWFlaAAACQAAAABRkbW5kAAACVAAAAHBkbWRk AAACxAAAAIh2dWVkAAADTAAAAIZ2aWV3AAAD1AAAACRsdW1pAAAD+AAAABRtZWFzAAAEDAAA ACR0ZWNoAAAEMAAAAAxyVFJDAAAEPAAACAxnVFJDAAAEPAAACAxiVFJDAAAEPAAACAx0ZXh0 AAAAAENvcHlyaWdodCAoYykgMTk5OCBIZXdsZXR0LVBhY2thcmQgQ29tcGFueQAAZGVzYwAA AAAAAAASc1JHQiBJRUM2MTk2Ni0yLjEAAAAAAAAAAAAAABJzUkdCIElFQzYxOTY2LTIuMQAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWFlaIAAA AAAAAPNRAAEAAAABFsxYWVogAAAAAAAAAAAAAAAAAAAAAFhZWiAAAAAAAABvogAAOPUAAAOQ WFlaIAAAAAAAAGKZAAC3hQAAGNpYWVogAAAAAAAAJKAAAA+EAAC2z2Rlc2MAAAAAAAAAFklF QyBodHRwOi8vd3d3LmllYy5jaAAAAAAAAAAAAAAAFklFQyBodHRwOi8vd3d3LmllYy5jaAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABkZXNjAAAAAAAA AC5JRUMgNjE5NjYtMi4xIERlZmF1bHQgUkdCIGNvbG91ciBzcGFjZSAtIHNSR0IAAAAAAAAA AAAAAC5JRUMgNjE5NjYtMi4xIERlZmF1bHQgUkdCIGNvbG91ciBzcGFjZSAtIHNSR0IAAAAA AAAAAAAAAAAAAAAAAAAAAAAAZGVzYwAAAAAAAAAsUmVmZXJlbmNlIFZpZXdpbmcgQ29uZGl0 aW9uIGluIElFQzYxOTY2LTIuMQAAAAAAAAAAAAAALFJlZmVyZW5jZSBWaWV3aW5nIENvbmRp dGlvbiBpbiBJRUM2MTk2Ni0yLjEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHZpZXcAAAAA ABOk/gAUXy4AEM8UAAPtzAAEEwsAA1yeAAAAAVhZWiAAAAAAAEwJVgBQAAAAVx/nbWVhcwAA AAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAo8AAAACc2lnIAAAAABDUlQgY3VydgAAAAAAAAQA AAAABQAKAA8AFAAZAB4AIwAoAC0AMgA3ADsAQABFAEoATwBUAFkAXgBjAGgAbQByAHcAfACB AIYAiwCQAJUAmgCfAKQAqQCuALIAtwC8AMEAxgDLANAA1QDbAOAA5QDrAPAA9gD7AQEBBwEN ARMBGQEfASUBKwEyATgBPgFFAUwBUgFZAWABZwFuAXUBfAGDAYsBkgGaAaEBqQGxAbkBwQHJ AdEB2QHhAekB8gH6AgMCDAIUAh0CJgIvAjgCQQJLAlQCXQJnAnECegKEAo4CmAKiAqwCtgLB AssC1QLgAusC9QMAAwsDFgMhAy0DOANDA08DWgNmA3IDfgOKA5YDogOuA7oDxwPTA+AD7AP5 BAYEEwQgBC0EOwRIBFUEYwRxBH4EjASaBKgEtgTEBNME4QTwBP4FDQUcBSsFOgVJBVgFZwV3 BYYFlgWmBbUFxQXVBeUF9gYGBhYGJwY3BkgGWQZqBnsGjAadBq8GwAbRBuMG9QcHBxkHKwc9 B08HYQd0B4YHmQesB78H0gflB/gICwgfCDIIRghaCG4IggiWCKoIvgjSCOcI+wkQCSUJOglP CWQJeQmPCaQJugnPCeUJ+woRCicKPQpUCmoKgQqYCq4KxQrcCvMLCwsiCzkLUQtpC4ALmAuw C8gL4Qv5DBIMKgxDDFwMdQyODKcMwAzZDPMNDQ0mDUANWg10DY4NqQ3DDd4N+A4TDi4OSQ5k Dn8Omw62DtIO7g8JDyUPQQ9eD3oPlg+zD88P7BAJECYQQxBhEH4QmxC5ENcQ9RETETERTxFt EYwRqhHJEegSBxImEkUSZBKEEqMSwxLjEwMTIxNDE2MTgxOkE8UT5RQGFCcUSRRqFIsUrRTO FPAVEhU0FVYVeBWbFb0V4BYDFiYWSRZsFo8WshbWFvoXHRdBF2UXiReuF9IX9xgbGEAYZRiK GK8Y1Rj6GSAZRRlrGZEZtxndGgQaKhpRGncanhrFGuwbFBs7G2MbihuyG9ocAhwqHFIcexyj HMwc9R0eHUcdcB2ZHcMd7B4WHkAeah6UHr4e6R8THz4faR+UH78f6iAVIEEgbCCYIMQg8CEc IUghdSGhIc4h+yInIlUigiKvIt0jCiM4I2YjlCPCI/AkHyRNJHwkqyTaJQklOCVoJZclxyX3 JicmVyaHJrcm6CcYJ0kneierJ9woDSg/KHEooijUKQYpOClrKZ0p0CoCKjUqaCqbKs8rAis2 K2krnSvRLAUsOSxuLKIs1y0MLUEtdi2rLeEuFi5MLoIuty7uLyQvWi+RL8cv/jA1MGwwpDDb MRIxSjGCMbox8jIqMmMymzLUMw0zRjN/M7gz8TQrNGU0njTYNRM1TTWHNcI1/TY3NnI2rjbp NyQ3YDecN9c4FDhQOIw4yDkFOUI5fzm8Ofk6Njp0OrI67zstO2s7qjvoPCc8ZTykPOM9Ij1h PaE94D4gPmA+oD7gPyE/YT+iP+JAI0BkQKZA50EpQWpBrEHuQjBCckK1QvdDOkN9Q8BEA0RH RIpEzkUSRVVFmkXeRiJGZ0arRvBHNUd7R8BIBUhLSJFI10kdSWNJqUnwSjdKfUrESwxLU0ua S+JMKkxyTLpNAk1KTZNN3E4lTm5Ot08AT0lPk0/dUCdQcVC7UQZRUFGbUeZSMVJ8UsdTE1Nf U6pT9lRCVI9U21UoVXVVwlYPVlxWqVb3V0RXklfgWC9YfVjLWRpZaVm4WgdaVlqmWvVbRVuV W+VcNVyGXNZdJ114XcleGl5sXr1fD19hX7NgBWBXYKpg/GFPYaJh9WJJYpxi8GNDY5dj62RA ZJRk6WU9ZZJl52Y9ZpJm6Gc9Z5Nn6Wg/aJZo7GlDaZpp8WpIap9q92tPa6dr/2xXbK9tCG1g bbluEm5rbsRvHm94b9FwK3CGcOBxOnGVcfByS3KmcwFzXXO4dBR0cHTMdSh1hXXhdj52m3b4 d1Z3s3gReG54zHkqeYl553pGeqV7BHtje8J8IXyBfOF9QX2hfgF+Yn7CfyN/hH/lgEeAqIEK gWuBzYIwgpKC9INXg7qEHYSAhOOFR4Wrhg6GcobXhzuHn4gEiGmIzokziZmJ/opkisqLMIuW i/yMY4zKjTGNmI3/jmaOzo82j56QBpBukNaRP5GokhGSepLjk02TtpQglIqU9JVflcmWNJaf lwqXdZfgmEyYuJkkmZCZ/JpomtWbQpuvnByciZz3nWSd0p5Anq6fHZ+Ln/qgaaDYoUehtqIm opajBqN2o+akVqTHpTilqaYapoum/adup+CoUqjEqTepqaocqo+rAqt1q+msXKzQrUStuK4t rqGvFq+LsACwdbDqsWCx1rJLssKzOLOutCW0nLUTtYq2AbZ5tvC3aLfguFm40blKucK6O7q1 uy67p7whvJu9Fb2Pvgq+hL7/v3q/9cBwwOzBZ8Hjwl/C28NYw9TEUcTOxUvFyMZGxsPHQce/ yD3IvMk6ybnKOMq3yzbLtsw1zLXNNc21zjbOts83z7jQOdC60TzRvtI/0sHTRNPG1EnUy9VO 1dHWVdbY11zX4Nhk2OjZbNnx2nba+9uA3AXcit0Q3ZbeHN6i3ynfr+A24L3hROHM4lPi2+Nj 4+vkc+T85YTmDeaW5x/nqegy6LzpRunQ6lvq5etw6/vshu0R7ZzuKO6070DvzPBY8OXxcvH/ 8ozzGfOn9DT0wvVQ9d72bfb794r4Gfio+Tj5x/pX+uf7d/wH/Jj9Kf26/kv+3P9t////2wBD AAICAgICAQICAgICAgIDAwYEAwMDAwcFBQQGCAcICAgHCAgJCg0LCQkMCggICw8LDA0ODg4O CQsQEQ8OEQ0ODg7/2wBDAQICAgMDAwYEBAYOCQgJDg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4O Dg4ODg4ODg4ODg4ODg4ODg4ODg4ODg4ODg7/wAARCAGSAoADASIAAhEBAxEB/8QAHwAAAQUB AQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIh MUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdI SUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKz tLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEB AQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSEx BhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZH 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 rPz3KNbmASGWTLudhOCzEc4xgkVo3ib+6lb/AIP+RbeJv7qVv+D/AJHmFxr2sz+Ixq0mpXaa kiIiXMUhjdFRAihSuMAKAOOwqL+29Xz/AMhXUujj/j6fo5y/f+I8n1PWqDK7yNtUsTzhRUkN hfXMNxJb2V3cR26b52jhZhEvq2BwPc122j2O7lj2Nc+KvEpvRcHxHr32gR+WJP7Ql3bM5253 ZxnnFVZNd1ifSfsE+r6nPY7932aS6dot2Sd20nGcknOOprHooUUugKKXQUnLE0lFFMoKKKKA CiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAoo ooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA6/wAc/wDJbfGX/Ycu/wD0 e9ei6lf6Tp3x707U/EVuL7SZdFtBYz4FxHbuLSJFmMWcSqjg5jJGSD1xg+deOj/xe/xl/wBh 27/9HvXbv4S0fVfjXY+HLUQaNaR6VbzusDM9zfSNbRyskYkbaZnZyFGVX2JwDz1rddrM5sQ4 397s/wBCo/jOyi+CNnoEVvpN1qEfiG4u7gtZMFmhKQ7HPIBLFXBGOFxwK6zUfihpM3xR+Jer W9tpzWup6XJbaQ7WThmYzRMARnK5UPnoPlX8eaGieEbb4DQavcC+TV7zX5rBnns2drRI0iba oEyKWAkJJZeTxhcZPYah4T+H1l8VviBp6wT/AGLwzpDyQwm0lYSyLLFGWkP2kFiPM/hKAk9B tweOXsNbp9fzX6nDL6vd3T6/mv1/Aw7H4iaTBL8JYprPTBBotyJdXH2Fzt/0tn3AZ+c+WQ3H 8Q/CqLfEG0fwL8Q7ZrXTRqOr6lbyWZFo+XiUy78tu4xlCAe5P4a9l4V8EXNt8KrSR7pZvEt9 m+uFtH3qn2tofLTM+1V+ULkqTyWz/DUB0jwMfC3xE1qO3O7S7yCysLf7HMI08wyjef8ASSxY mPGSxUYztOcBr2F9nf8A+2/z/ApfV+bZ/wBS/wA/wNC3+JuixfFrwpqT2mlppmn+GVtJStg/ 7u4+xshCru6CQgBh2J+tbPhb4m+DbH4RaZp3iCGO6mW9W4u7SG3k35F+kxVQQYmi8oE5YmTc AoOzis618H+AJPib4M0BmvJLWfw6uqXkhtHEl05tGnCsftGFQ4JwoBAAG453DQ8OfDLwZ4m+ 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 Yqy5mk7dPl/wTKMcW0uZr+rW/X8DqB8M7mXwloW