<div class="gmail_quote">Am 21.11.2012 02:38 schrieb  &lt;<a href="mailto:xfs-request@oss.sgi.com">xfs-request@oss.sgi.com</a>&gt;:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Send xfs mailing list submissions to<br>
        <a href="mailto:xfs@oss.sgi.com">xfs@oss.sgi.com</a><br>
<br>
To subscribe or unsubscribe via the World Wide Web, visit<br>
        <a href="http://oss.sgi.com/mailman/listinfo/xfs" target="_blank">http://oss.sgi.com/mailman/listinfo/xfs</a><br>
or, via email, send a message with subject or body &#39;help&#39; to<br>
        <a href="mailto:xfs-request@oss.sgi.com">xfs-request@oss.sgi.com</a><br>
<br>
You can reach the person managing the list at<br>
        <a href="mailto:xfs-owner@oss.sgi.com">xfs-owner@oss.sgi.com</a><br>
<br>
When replying, please edit your Subject line so it is more specific<br>
than &quot;Re: Contents of xfs digest...&quot;<br>
<br>Today&#39;s Topics:<br>
<br>
   1. [PATCH 0/2] discontiguous buffer patches (Mark Tinguely)<br>
   2. Re: [PATCH 0/2] xfsprogs: fixes for release candidate.<br>
      (Mark Tinguely)<br>
   3. Re: [PATCH] xfs: Don&#39;t flush inodes when project quota<br>
      exceeded (Jan Kara)<br>
   4. Re: [PATCH 2/9] ext4: honor the O_SYNC flag for aysnchronous<br>
      direct I/O requests (Jan Kara)<br>
   5. [PATCH] ext4: Reduce i_mutex usage in ext4_file_sync() (Jan Kara)<br>
   6. Re: [PATCH 9/9] blkdev: Fix up AIO+DIO+O_SYNC to do the sync<br>
      part      correctly (Jan Kara)<br>
   7. Re: [PATCH] xfs: Don&#39;t flush inodes when project quota<br>
      exceeded (Dave Chinner)<br>
<br><br>---------- Weitergeleitete Nachricht ----------<br>From: Mark Tinguely &lt;<a href="mailto:tinguely@sgi.com">tinguely@sgi.com</a>&gt;<br>To: <a href="mailto:xfs@oss.sgi.com">xfs@oss.sgi.com</a><br>Cc: <br>Date: Tue, 20 Nov 2012 16:41:20 -0600<br>
Subject: [PATCH 0/2] discontiguous buffer patches<br>Eric Sundeen&#39;s &quot;userspace vs. fragmented multiblock dir2&quot;, xfstest 291<br>
commit 2a4ed, causes a xfs_buf lock hang:<br>
<br>
[&lt;ffffffff81065d87&gt;] down+0x47/0x50<br>
[&lt;ffffffffa03a25c6&gt;] xfs_buf_lock+0x66/0xe0 [xfs]<br>
[&lt;ffffffffa03a33c9&gt;] _xfs_buf_find+0x1f9/0x320 [xfs]<br>
[&lt;ffffffffa03a393f&gt;] xfs_buf_get_map+0x2f/0x170 [xfs]<br>
[&lt;ffffffffa03a3f7a&gt;] xfs_buf_read_map+0x2a/0x100 [xfs]<br>
[&lt;ffffffffa0411630&gt;] xfs_trans_read_buf_map+0x3b0/0x590 [xfs]<br>
[&lt;ffffffffa03e1c5e&gt;] xfs_da_read_buf+0xbe/0x230 [xfs]<br>
[&lt;ffffffffa03e78dc&gt;] xfs_dir2_block_addname+0x7c/0x980 [xfs]<br>
[&lt;ffffffffa03f1468&gt;] xfs_dir2_sf_addname+0x3e8/0x450 [xfs]<br>
[&lt;ffffffffa03e634c&gt;] xfs_dir_createname+0x17c/0x1e0 [xfs]<br>
[&lt;ffffffffa03b9fe2&gt;] xfs_create+0x4c2/0x5f0 [xfs]<br>
[&lt;ffffffffa03b0c8a&gt;] xfs_vn_mknod+0x8a/0x1a0 [xfs]<br>
[&lt;ffffffffa03b0dce&gt;] xfs_vn_create+0xe/0x10 [xfs]<br>
[&lt;ffffffff8115695c&gt;] vfs_create+0xac/0xd0<br>
[&lt;ffffffff811587de&gt;] do_last+0x8be/0x960<br>
[&lt;ffffffff8115940c&gt;] path_openat+0xdc/0x410<br>
[&lt;ffffffff81159853&gt;] do_filp_open+0x43/0xa0<br>
[&lt;ffffffff8114a502&gt;] do_sys_open+0x152/0x1e0<br>
[&lt;ffffffff8114a5cc&gt;] sys_open+0x1c/0x20<br>
[&lt;ffffffff81423df9&gt;] system_call_fastpath+0x16/0x1b<br>
[&lt;ffffffffffffffff&gt;] 0xffffffffffffffff<br>
<br>
That bisect a problem to:<br>
<br>
    commit 3605431fb9739a30ccd0c6380ae8e3c6f8e670a5<br>
    Author: Dave Chinner &lt;<a href="mailto:dchinner@redhat.com">dchinner@redhat.com</a>&gt;<br>
    Date:   Fri Jun 22 18:50:13 2012 +1000<br>
    xfs: use discontiguous xfs_buf support in dabuf wrappers<br>
<br>
xfs_trans_buf_item_match() is looking for the block number of the<br>
buffer in the single segment map area.<br>
<br>
Futhermore, there are a couple issue with multi-segment buffer log<br>
format.<br>
<br>
Patch 1 cleans up the buffer map so that XFS always uses b_maps[].<br>
<br>
Patch 2 fixes the buffer log format issues.<br>
<br>
--Mark.<br>
<br>
<br>
<br>
<br><br>---------- Weitergeleitete Nachricht ----------<br>From: Mark Tinguely &lt;<a href="mailto:tinguely@sgi.com">tinguely@sgi.com</a>&gt;<br>To: Dave Chinner &lt;<a href="mailto:david@fromorbit.com">david@fromorbit.com</a>&gt;<br>
Cc: <a href="mailto:xfs@oss.sgi.com">xfs@oss.sgi.com</a><br>Date: Tue, 20 Nov 2012 17:17:36 -0600<br>Subject: Re: [PATCH 0/2] xfsprogs: fixes for release candidate.<br>On 11/09/12 01:02, Dave Chinner wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Hi Ben,<br>
<br>
These are two fixes for bugs that have shown up during the -rc<br>
phase of the release. Please consider them for inclusion.<br>
<br>
Cheers,<br>
<br>
Dave.<br>
<br>
______________________________<u></u>_________________<br>
xfs mailing list<br>
<a href="mailto:xfs@oss.sgi.com" target="_blank">xfs@oss.sgi.com</a><br>
<a href="http://oss.sgi.com/mailman/listinfo/xfs" target="_blank">http://oss.sgi.com/mailman/<u></u>listinfo/xfs</a><br>
</blockquote>
<br>
This series has been committed to git://<a href="http://oss.sgi.com/xfs/cmds/xfsprogs" target="_blank">oss.sgi.com/xfs/cmds/<u></u>xfsprogs</a> master branch, commit 1adfff, 19473a and 36298.<br>
<br>
--Mark.<br>
<br>
<br>
<br><br>---------- Weitergeleitete Nachricht ----------<br>From: Jan Kara &lt;<a href="mailto:jack@suse.cz">jack@suse.cz</a>&gt;<br>To: Dave Chinner &lt;<a href="mailto:david@fromorbit.com">david@fromorbit.com</a>&gt;<br>
Cc: Jan Kara &lt;<a href="mailto:jack@suse.cz">jack@suse.cz</a>&gt;, <a href="mailto:xfs@oss.sgi.com">xfs@oss.sgi.com</a><br>Date: Wed, 21 Nov 2012 01:24:59 +0100<br>Subject: Re: [PATCH] xfs: Don&#39;t flush inodes when project quota exceeded<br>
On Tue 20-11-12 11:04:28, Dave Chinner wrote:<br>
&gt; On Mon, Nov 19, 2012 at 10:39:13PM +0100, Jan Kara wrote:<br>
&gt; &gt; On Tue 13-11-12 01:36:13, Jan Kara wrote:<br>
&gt; &gt; &gt; When project quota gets exceeded xfs_iomap_write_delay() ends up flushing<br>
&gt; &gt; &gt; inodes because ENOSPC gets returned from xfs_bmapi_delay() instead of EDQUOT.<br>
&gt; &gt; &gt; This makes handling of writes over project quota rather slow as a simple test<br>
&gt; &gt; &gt; program shows:<br>
&gt; &gt; &gt;   fd = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC, 0644);<br>
&gt; &gt; &gt;   for (i = 0; i &lt; 50000; i++)<br>
&gt; &gt; &gt;           pwrite(fd, buf, 4096, i*4096);<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; Writing 200 MB like this into a directory with 100 MB project quota takes<br>
&gt; &gt; &gt; around 6 minutes while it takes about 2 seconds with this patch applied. This<br>
&gt; &gt; &gt; actually happens in a real world load when nfs pushes data into a directory<br>
&gt; &gt; &gt; which is over project quota.<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; Fix the problem by replacing XFS_QMOPT_ENOSPC flag with XFS_QMOPT_EPDQUOT.<br>
&gt; &gt; &gt; That makes xfs_trans_reserve_quota_bydquots() return new error EPDQUOT when<br>
&gt; &gt; &gt; project quota is exceeded. xfs_bmapi_delay() then uses this flag so that<br>
&gt; &gt; &gt; xfs_iomap_write_delay() can distinguish real ENOSPC (requiring flushing)<br>
&gt; &gt; &gt; from exceeded project quota (not requiring flushing).<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; As a side effect this patch fixes inconsistency where e.g. xfs_create()<br>
&gt; &gt; &gt; returned EDQUOT even when project quota was exceeded.<br>
&gt; &gt;   Ping? Any opinions?<br>
&gt;<br>
&gt; FWIW, it doesn&#39;t look like it&#39;ll apply to a current XFs tree:<br>
&gt;<br>
&gt; &gt; &gt; @@ -441,8 +442,11 @@ retry:<br>
&gt; &gt; &gt;    */<br>
&gt; &gt; &gt;   if (nimaps == 0) {<br>
&gt; &gt; &gt;           trace_xfs_delalloc_enospc(ip, offset, count);<br>
&gt; &gt; &gt; -         if (flushed)<br>
&gt; &gt; &gt; -                 return XFS_ERROR(error ? error : ENOSPC);<br>
&gt; &gt; &gt; +         if (flushed) {<br>
&gt; &gt; &gt; +                 if (error == 0 || error == EPDQUOT)<br>
&gt; &gt; &gt; +                         error = ENOSPC;<br>
&gt; &gt; &gt; +                 return XFS_ERROR(error);<br>
&gt; &gt; &gt; +         }<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt;           if (error == ENOSPC) {<br>
&gt; &gt; &gt;                   xfs_iunlock(ip, XFS_ILOCK_EXCL);<br>
&gt;<br>
&gt; This xfs_iomap_write_delay() looks like this now:<br>
&gt;<br>
&gt;         /*<br>
&gt;          * If bmapi returned us nothing, we got either ENOSPC or EDQUOT. Retry<br>
&gt;          * without EOF preallocation.<br>
&gt;          */<br>
&gt;         if (nimaps == 0) {<br>
&gt;                 trace_xfs_delalloc_enospc(ip, offset, count);<br>
&gt;                 if (prealloc) {<br>
&gt;                         prealloc = 0;<br>
&gt;                         error = 0;<br>
&gt;                         goto retry;<br>
&gt;                 }<br>
&gt;                 return XFS_ERROR(error ? error : ENOSPC);<br>
&gt;         }<br>
&gt;<br>
&gt; The flushing is now way up in xfs_file_buffered_aio_write(), and the<br>
&gt; implementation of xfs_flush_inodes() has changed as well. Hence it<br>
&gt; may or may not behave differently not....<br>
  OK, so I tested latest XFS tree and changes by commit 9aa05000 (changing<br>
xfs_flush_inodes()) indeed improve the performace from those ~6 minutes to<br>
~6 seconds which is good enough I believe. Thanks for the pointer! I was<br>
thinking for a while why sync_inodes_sb() is so much faster than the<br>
original XFS implementation and I believe it&#39;s because we don&#39;t force the<br>
log on each sync now.<br>
<br>
                                                                Honza<br>
--<br>
Jan Kara &lt;<a href="mailto:jack@suse.cz">jack@suse.cz</a>&gt;<br>
SUSE Labs, CR<br>
<br>
<br>
<br><br>---------- Weitergeleitete Nachricht ----------<br>From: Jan Kara &lt;<a href="mailto:jack@suse.cz">jack@suse.cz</a>&gt;<br>To: Jeff Moyer &lt;<a href="mailto:jmoyer@redhat.com">jmoyer@redhat.com</a>&gt;<br>Cc: <a href="mailto:axboe@kernel.dk">axboe@kernel.dk</a>, <a href="mailto:tytso@mit.edu">tytso@mit.edu</a>, &quot;Darrick J. Wong&quot; &lt;<a href="mailto:darrick.wong@oracle.com">darrick.wong@oracle.com</a>&gt;, <a href="mailto:linux-kernel@vger.kernel.org">linux-kernel@vger.kernel.org</a>, <a href="mailto:xfs@oss.sgi.com">xfs@oss.sgi.com</a>, <a href="mailto:hch@infradead.org">hch@infradead.org</a>, <a href="mailto:bpm@sgi.com">bpm@sgi.com</a>, <a href="mailto:viro@zeniv.linux.org.uk">viro@zeniv.linux.org.uk</a>, <a href="mailto:linux-fsdevel@vger.kernel.org">linux-fsdevel@vger.kernel.org</a>, Jan Kara &lt;<a href="mailto:jack@suse.cz">jack@suse.cz</a>&gt;, <a href="mailto:linux-ext4@vger.kernel.org">linux-ext4@vger.kernel.org</a><br>
Date: Wed, 21 Nov 2012 01:56:26 +0100<br>Subject: Re: [PATCH 2/9] ext4: honor the O_SYNC flag for aysnchronous direct I/O requests<br>On Tue 20-11-12 15:02:15, Jeff Moyer wrote:<br>
&gt; Jan Kara &lt;<a href="mailto:jack@suse.cz">jack@suse.cz</a>&gt; writes:<br>
&gt;<br>
&gt; &gt;&gt; @@ -1279,6 +1280,9 @@ struct ext4_sb_info {<br>
&gt; &gt;&gt;    /* workqueue for dio unwritten */<br>
&gt; &gt;&gt;    struct workqueue_struct *dio_unwritten_wq;<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; +  /* workqueue for aio+dio+o_sync disk cache flushing */<br>
&gt; &gt;&gt; +  struct workqueue_struct *aio_dio_flush_wq;<br>
&gt; &gt;&gt; +<br>
&gt; &gt;   Umm, I&#39;m not completely decided whether we really need a separate<br>
&gt; &gt; workqueue. But it doesn&#39;t cost too much so I guess it makes some sense -<br>
&gt; &gt; fsync() is rather heavy so syncing won&#39;t starve extent conversion...<br>
&gt;<br>
&gt; I&#39;m assuming you&#39;d like me to convert the names from flush to fsync,<br>
&gt; yes?<br>
  Would be nicer, yes.<br>
<br>
&gt; &gt;&gt; +<br>
&gt; &gt;&gt; +  /*<br>
&gt; &gt;&gt; +   * If we are running in nojournal mode, just flush the disk<br>
&gt; &gt;&gt; +   * cache and return.<br>
&gt; &gt;&gt; +   */<br>
&gt; &gt;&gt; +  if (!journal)<br>
&gt; &gt;&gt; +          return blkdev_issue_flush(inode-&gt;i_sb-&gt;s_bdev, GFP_NOIO, NULL);<br>
&gt; &gt;   And this is wrong as well - you need to do work similar to what<br>
&gt; &gt; ext4_sync_file() does. Actually it would be *much* better if these two<br>
&gt; &gt; sites used the same helper function. Which also poses an interesting<br>
&gt; &gt; question about locking - do we need i_mutex or not? Forcing a transaction<br>
&gt; &gt; commit is definitely OK without it, similarly as grabbing transaction ids<br>
&gt; &gt; from inode or ext4_should_journal_data() test. __sync_inode() call seems<br>
&gt; &gt; to be OK without i_mutex as well so I believe we can just get rid of it<br>
&gt; &gt; (getting i_mutex from the workqueue is a locking nightmare we don&#39;t want to<br>
&gt; &gt; return to).<br>
&gt;<br>
&gt; Just to be clear, are you saying you would like me to remove the<br>
&gt; mutex_lock/unlock pair from ext4_sync_file?  (I had already factored out<br>
&gt; the common code between this new code path and the fsync path in my tree.)<br>
  Yes, after some thinking I came to that conclusion. We actually need to<br>
keep i_mutex around ext4_flush_unwritten_io() to avoid livelocks but the<br>
rest doesn&#39;t need it. The change should be definitely a separate patch just<br>
in case there&#39;s something subtle I missed and we need to bisect in<br>
future... I&#39;ve attached a patch for that so that blame for bugs goes my way<br>
;) Compile tested only so far. I&#39;ll give it some more testing overnight.<br>
<br>
                                                                Honza<br>
--<br>
Jan Kara &lt;<a href="mailto:jack@suse.cz">jack@suse.cz</a>&gt;<br>
SUSE Labs, CR<br>
<br><br>---------- Weitergeleitete Nachricht ----------<br>From: Jan Kara &lt;<a href="mailto:jack@suse.cz">jack@suse.cz</a>&gt;<br>To: <br>Cc: <br>Date: Wed, 21 Nov 2012 01:46:51 +0100<br>Subject: [PATCH] ext4: Reduce i_mutex usage in ext4_file_sync()<br>
ext4_file_sync() needs i_mutex only to avoid livelocks of<br>
ext4_flush_unwritten_io() all other code doesn&#39;t need it. In particular<br>
syncing of inode &amp; metadata in non-journal case is safe (writeback doesn&#39;t<br>
hold i_mutex either) and forcing of transaction commits doesn&#39;t need i_mutex<br>
either (there&#39;s nothing inode specific in that code apart from grabbing<br>
transaction ids from the inode). So shorten the span where i_mutex is held.<br>
<br>
Signed-off-by: Jan Kara &lt;<a href="mailto:jack@suse.cz">jack@suse.cz</a>&gt;<br>
---<br>
 fs/ext4/fsync.c |    6 ++----<br>
 1 files changed, 2 insertions(+), 4 deletions(-)<br>
<br>
diff --git a/fs/ext4/fsync.c b/fs/ext4/fsync.c<br>
index be1d89f..2268114 100644<br>
--- a/fs/ext4/fsync.c<br>
+++ b/fs/ext4/fsync.c<br>
@@ -113,8 +113,6 @@ static int __sync_inode(struct inode *inode, int datasync)<br>
  *<br>
  * What we do is just kick off a commit and wait on it.  This will snapshot the<br>
  * inode to disk.<br>
- *<br>
- * i_mutex lock is held when entering and exiting this function<br>
  */<br>
<br>
 int ext4_sync_file(struct file *file, loff_t start, loff_t end, int datasync)<br>
@@ -133,12 +131,13 @@ int ext4_sync_file(struct file *file, loff_t start, loff_t end, int datasync)<br>
        ret = filemap_write_and_wait_range(inode-&gt;i_mapping, start, end);<br>
        if (ret)<br>
                return ret;<br>
-       mutex_lock(&amp;inode-&gt;i_mutex);<br>
<br>
        if (inode-&gt;i_sb-&gt;s_flags &amp; MS_RDONLY)<br>
                goto out;<br>
<br>
+       mutex_lock(&amp;inode-&gt;i_mutex);<br>
        ret = ext4_flush_unwritten_io(inode);<br>
+       mutex_unlock(&amp;inode-&gt;i_mutex);<br>
        if (ret &lt; 0)<br>
                goto out;<br>
<br>
@@ -180,7 +179,6 @@ int ext4_sync_file(struct file *file, loff_t start, loff_t end, int datasync)<br>
                        ret = err;<br>
        }<br>
  out:<br>
-       mutex_unlock(&amp;inode-&gt;i_mutex);<br>
        trace_ext4_sync_file_exit(inode, ret);<br>
        return ret;<br>
 }<br>
--<br>
1.7.1<br>
<br>
<br>
--k+w/mQv8wyuph6w0--<br>
<br>
<br>
<br><br>---------- Weitergeleitete Nachricht ----------<br>From: Jan Kara &lt;<a href="mailto:jack@suse.cz">jack@suse.cz</a>&gt;<br>To: Jeff Moyer &lt;<a href="mailto:jmoyer@redhat.com">jmoyer@redhat.com</a>&gt;<br>Cc: <a href="mailto:axboe@kernel.dk">axboe@kernel.dk</a>, <a href="mailto:tytso@mit.edu">tytso@mit.edu</a>, &quot;Darrick J. Wong&quot; &lt;<a href="mailto:darrick.wong@oracle.com">darrick.wong@oracle.com</a>&gt;, <a href="mailto:linux-kernel@vger.kernel.org">linux-kernel@vger.kernel.org</a>, <a href="mailto:xfs@oss.sgi.com">xfs@oss.sgi.com</a>, <a href="mailto:hch@infradead.org">hch@infradead.org</a>, <a href="mailto:bpm@sgi.com">bpm@sgi.com</a>, <a href="mailto:viro@zeniv.linux.org.uk">viro@zeniv.linux.org.uk</a>, <a href="mailto:linux-fsdevel@vger.kernel.org">linux-fsdevel@vger.kernel.org</a>, Jan Kara &lt;<a href="mailto:jack@suse.cz">jack@suse.cz</a>&gt;, <a href="mailto:linux-ext4@vger.kernel.org">linux-ext4@vger.kernel.org</a><br>
Date: Wed, 21 Nov 2012 01:57:39 +0100<br>Subject: Re: [PATCH 9/9] blkdev: Fix up AIO+DIO+O_SYNC to do the sync part correctly<br>On Tue 20-11-12 15:47:54, Jeff Moyer wrote:<br>
&gt; Jan Kara &lt;<a href="mailto:jack@suse.cz">jack@suse.cz</a>&gt; writes:<br>
&gt;<br>
&gt; &gt; On Mon 19-11-12 23:51:15, Darrick J. Wong wrote:<br>
&gt; &gt;&gt; When performing O_SYNC+AIO+DIO writes to block devices, use the DIO_SYNC_WRITES<br>
&gt; &gt;&gt; flag so that flushes are issued /after/ the write completes, not before.<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; Note, however, that for block devices, the DIO setup code ensures that a flush<br>
&gt; &gt;&gt; wq is attached to the superblock of the bdevfs filesystem, not the filesystem<br>
&gt; &gt;&gt; that the device node happens to reside in.  This means that unlike regular<br>
&gt; &gt;&gt; files, iocb-&gt;ki_filp-&gt;f_mapping-&gt;host-&gt;i_sb != inode-&gt;i_sb.  Therefore, adjust<br>
&gt; &gt;&gt; Jeff&#39;s earlier patch to keep the pointer use consistent and avoid a NULL deref.<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; Signed-off-by: Darrick J. Wong &lt;<a href="mailto:darrick.wong@oracle.com">darrick.wong@oracle.com</a>&gt;<br>
&gt; &gt;&gt; ---<br>
&gt; &gt;&gt;  fs/block_dev.c |    5 +++--<br>
&gt; &gt;&gt;  fs/direct-io.c |    3 ++-<br>
&gt; &gt;&gt;  2 files changed, 5 insertions(+), 3 deletions(-)<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt; diff --git a/fs/block_dev.c b/fs/block_dev.c<br>
&gt; &gt;&gt; index 1a1e5e3..05ff33a 100644<br>
&gt; &gt;&gt; --- a/fs/block_dev.c<br>
&gt; &gt;&gt; +++ b/fs/block_dev.c<br>
&gt; &gt;&gt; @@ -235,7 +235,8 @@ blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,<br>
&gt; &gt;&gt;    struct inode *inode = file-&gt;f_mapping-&gt;host;<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt;    return __blockdev_direct_IO(rw, iocb, inode, I_BDEV(inode), iov, offset,<br>
&gt; &gt;&gt; -                              nr_segs, blkdev_get_blocks, NULL, NULL, 0);<br>
&gt; &gt;&gt; +                              nr_segs, blkdev_get_blocks, NULL, NULL,<br>
&gt; &gt;&gt; +                              DIO_SYNC_WRITES);<br>
&gt; &gt;&gt;  }<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt;  int __sync_blockdev(struct block_device *bdev, int wait)<br>
&gt; &gt;&gt; @@ -1631,7 +1632,7 @@ ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov,<br>
&gt; &gt;&gt;    percpu_down_read(&amp;bdev-&gt;bd_block_size_semaphore);<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt;    ret = __generic_file_aio_write(iocb, iov, nr_segs, &amp;iocb-&gt;ki_pos);<br>
&gt; &gt;&gt; -  if (ret &gt; 0 || ret == -EIOCBQUEUED) {<br>
&gt; &gt;&gt; +  if (ret &gt; 0) {<br>
&gt; &gt;&gt;            ssize_t err;<br>
&gt; &gt;&gt;<br>
&gt; &gt;&gt;            err = generic_write_sync(file, pos, ret);<br>
&gt; &gt;&gt; diff --git a/fs/direct-io.c b/fs/direct-io.c<br>
&gt; &gt;&gt; index b7391d4..c626c43 100644<br>
&gt; &gt;&gt; --- a/fs/direct-io.c<br>
&gt; &gt;&gt; +++ b/fs/direct-io.c<br>
&gt; &gt;&gt; @@ -258,7 +258,8 @@ void generic_dio_end_io(struct kiocb *iocb, loff_t offset, ssize_t bytes,<br>
&gt; &gt;&gt;            work-&gt;ret = ret;<br>
&gt; &gt;&gt;            work-&gt;offset = offset;<br>
&gt; &gt;&gt;            work-&gt;len = bytes;<br>
&gt; &gt;&gt; -          queue_work(inode-&gt;i_sb-&gt;s_dio_flush_wq, &amp;work-&gt;work);<br>
&gt; &gt;&gt; +          queue_work(iocb-&gt;ki_filp-&gt;f_mapping-&gt;host-&gt;i_sb-&gt;s_dio_flush_wq,<br>
&gt; &gt;&gt; +                     &amp;work-&gt;work);<br>
&gt; &gt;   This should be folded into the original patch introducing the<br>
&gt; &gt; s_dio_flush_wq. And please add a comment before this line saying that block<br>
&gt; &gt; devices need a dereference exactly like this... Otherwise the patch looks<br>
&gt; &gt; good so you can add:<br>
&gt; &gt;   Reviewed-by: Jan Kara &lt;<a href="mailto:jack@suse.cz">jack@suse.cz</a>&gt;<br>
&gt;<br>
&gt; When you say, &quot;This,&quot; do you mean that one change, or the whole patch?<br>
  I meant the whole patch after that hung is folded ;)<br>
<br>
                                                                Honza<br>
--<br>
Jan Kara &lt;<a href="mailto:jack@suse.cz">jack@suse.cz</a>&gt;<br>
SUSE Labs, CR<br>
<br>
<br>
<br><br>---------- Weitergeleitete Nachricht ----------<br>From: Dave Chinner &lt;<a href="mailto:david@fromorbit.com">david@fromorbit.com</a>&gt;<br>To: Jan Kara &lt;<a href="mailto:jack@suse.cz">jack@suse.cz</a>&gt;<br>
Cc: <a href="mailto:xfs@oss.sgi.com">xfs@oss.sgi.com</a><br>Date: Wed, 21 Nov 2012 12:38:21 +1100<br>Subject: Re: [PATCH] xfs: Don&#39;t flush inodes when project quota exceeded<br>On Wed, Nov 21, 2012 at 01:24:59AM +0100, Jan Kara wrote:<br>

&gt; On Tue 20-11-12 11:04:28, Dave Chinner wrote:<br>
&gt; &gt; On Mon, Nov 19, 2012 at 10:39:13PM +0100, Jan Kara wrote:<br>
&gt; &gt; &gt; On Tue 13-11-12 01:36:13, Jan Kara wrote:<br>
&gt; &gt; &gt; &gt; When project quota gets exceeded xfs_iomap_write_delay() ends up flushing<br>
&gt; &gt; &gt; &gt; inodes because ENOSPC gets returned from xfs_bmapi_delay() instead of EDQUOT.<br>
&gt; &gt; &gt; &gt; This makes handling of writes over project quota rather slow as a simple test<br>
&gt; &gt; &gt; &gt; program shows:<br>
&gt; &gt; &gt; &gt;         fd = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC, 0644);<br>
&gt; &gt; &gt; &gt;         for (i = 0; i &lt; 50000; i++)<br>
&gt; &gt; &gt; &gt;                 pwrite(fd, buf, 4096, i*4096);<br>
&gt; &gt; &gt; &gt;<br>
&gt; &gt; &gt; &gt; Writing 200 MB like this into a directory with 100 MB project quota takes<br>
&gt; &gt; &gt; &gt; around 6 minutes while it takes about 2 seconds with this patch applied. This<br>
&gt; &gt; &gt; &gt; actually happens in a real world load when nfs pushes data into a directory<br>
&gt; &gt; &gt; &gt; which is over project quota.<br>
&gt; &gt; &gt; &gt;<br>
&gt; &gt; &gt; &gt; Fix the problem by replacing XFS_QMOPT_ENOSPC flag with XFS_QMOPT_EPDQUOT.<br>
&gt; &gt; &gt; &gt; That makes xfs_trans_reserve_quota_bydquots() return new error EPDQUOT when<br>
&gt; &gt; &gt; &gt; project quota is exceeded. xfs_bmapi_delay() then uses this flag so that<br>
&gt; &gt; &gt; &gt; xfs_iomap_write_delay() can distinguish real ENOSPC (requiring flushing)<br>
&gt; &gt; &gt; &gt; from exceeded project quota (not requiring flushing).<br>
&gt; &gt; &gt; &gt;<br>
&gt; &gt; &gt; &gt; As a side effect this patch fixes inconsistency where e.g. xfs_create()<br>
&gt; &gt; &gt; &gt; returned EDQUOT even when project quota was exceeded.<br>
&gt; &gt; &gt;   Ping? Any opinions?<br>
&gt; &gt;<br>
&gt; &gt; FWIW, it doesn&#39;t look like it&#39;ll apply to a current XFs tree:<br>
&gt; &gt;<br>
&gt; &gt; &gt; &gt; @@ -441,8 +442,11 @@ retry:<br>
&gt; &gt; &gt; &gt;          */<br>
&gt; &gt; &gt; &gt;         if (nimaps == 0) {<br>
&gt; &gt; &gt; &gt;                 trace_xfs_delalloc_enospc(ip, offset, count);<br>
&gt; &gt; &gt; &gt; -               if (flushed)<br>
&gt; &gt; &gt; &gt; -                       return XFS_ERROR(error ? error : ENOSPC);<br>
&gt; &gt; &gt; &gt; +               if (flushed) {<br>
&gt; &gt; &gt; &gt; +                       if (error == 0 || error == EPDQUOT)<br>
&gt; &gt; &gt; &gt; +                               error = ENOSPC;<br>
&gt; &gt; &gt; &gt; +                       return XFS_ERROR(error);<br>
&gt; &gt; &gt; &gt; +               }<br>
&gt; &gt; &gt; &gt;<br>
&gt; &gt; &gt; &gt;                 if (error == ENOSPC) {<br>
&gt; &gt; &gt; &gt;                         xfs_iunlock(ip, XFS_ILOCK_EXCL);<br>
&gt; &gt;<br>
&gt; &gt; This xfs_iomap_write_delay() looks like this now:<br>
&gt; &gt;<br>
&gt; &gt;         /*<br>
&gt; &gt;          * If bmapi returned us nothing, we got either ENOSPC or EDQUOT. Retry<br>
&gt; &gt;          * without EOF preallocation.<br>
&gt; &gt;          */<br>
&gt; &gt;         if (nimaps == 0) {<br>
&gt; &gt;                 trace_xfs_delalloc_enospc(ip, offset, count);<br>
&gt; &gt;                 if (prealloc) {<br>
&gt; &gt;                         prealloc = 0;<br>
&gt; &gt;                         error = 0;<br>
&gt; &gt;                         goto retry;<br>
&gt; &gt;                 }<br>
&gt; &gt;                 return XFS_ERROR(error ? error : ENOSPC);<br>
&gt; &gt;         }<br>
&gt; &gt;<br>
&gt; &gt; The flushing is now way up in xfs_file_buffered_aio_write(), and the<br>
&gt; &gt; implementation of xfs_flush_inodes() has changed as well. Hence it<br>
&gt; &gt; may or may not behave differently not....<br>
&gt;   OK, so I tested latest XFS tree and changes by commit 9aa05000 (changing<br>
&gt; xfs_flush_inodes()) indeed improve the performace from those ~6 minutes to<br>
&gt; ~6 seconds which is good enough I believe. Thanks for the pointer! I was<br>
&gt; thinking for a while why sync_inodes_sb() is so much faster than the<br>
&gt; original XFS implementation and I believe it&#39;s because we don&#39;t force the<br>
&gt; log on each sync now.<br>
<br>
I think it&#39;s detter because we now don&#39;t scan every inode in the<br>
inode cache doing a mapping_tagged(PAGECACHE_TAG_DIRTY) check to see<br>
if they are dirty or not to decide whether it needs writeback. The<br>
overhead of doing that adds up very quickly when you have lots of<br>
cached inodes and you are scanning them for every page that is<br>
written to....<br>
<br>
Cheers,<br>
<br>
Dave.<br>
--<br>
Dave Chinner<br>
<a href="mailto:david@fromorbit.com">david@fromorbit.com</a><br>
<br>
<br>
<br>_______________________________________________<br>
xfs mailing list<br>
<a href="mailto:xfs@oss.sgi.com">xfs@oss.sgi.com</a><br>
<a href="http://oss.sgi.com/mailman/listinfo/xfs" target="_blank">http://oss.sgi.com/mailman/listinfo/xfs</a><br>
<br></blockquote></div>