<feed xmlns='http://www.w3.org/2005/Atom'>
<title>linux/fs/ext4/fsync.c, branch v3.4.33</title>
<subtitle>Linux kernel source tree</subtitle>
<id>https://git.amat.us/linux/atom/fs/ext4/fsync.c?h=v3.4.33</id>
<link rel='self' href='https://git.amat.us/linux/atom/fs/ext4/fsync.c?h=v3.4.33'/>
<link rel='alternate' type='text/html' href='https://git.amat.us/linux/'/>
<updated>2012-03-05T15:29:52Z</updated>
<entry>
<title>ext4: fix race between sync and completed io work</title>
<updated>2012-03-05T15:29:52Z</updated>
<author>
<name>Jeff Moyer</name>
<email>jmoyer@redhat.com</email>
</author>
<published>2012-03-05T15:29:52Z</published>
<link rel='alternate' type='text/html' href='https://git.amat.us/linux/commit/?id=491caa43639abcffaa645fbab372a7ef4ce2975c'/>
<id>urn:sha1:491caa43639abcffaa645fbab372a7ef4ce2975c</id>
<content type='text'>
The following command line will leave the aio-stress process unkillable
on an ext4 file system (in my case, mounted on /mnt/test):

aio-stress -t 20 -s 10 -O -S -o 2 -I 1000 /mnt/test/aiostress.3561.4 /mnt/test/aiostress.3561.4.20 /mnt/test/aiostress.3561.4.19 /mnt/test/aiostress.3561.4.18 /mnt/test/aiostress.3561.4.17 /mnt/test/aiostress.3561.4.16 /mnt/test/aiostress.3561.4.15 /mnt/test/aiostress.3561.4.14 /mnt/test/aiostress.3561.4.13 /mnt/test/aiostress.3561.4.12 /mnt/test/aiostress.3561.4.11 /mnt/test/aiostress.3561.4.10 /mnt/test/aiostress.3561.4.9 /mnt/test/aiostress.3561.4.8 /mnt/test/aiostress.3561.4.7 /mnt/test/aiostress.3561.4.6 /mnt/test/aiostress.3561.4.5 /mnt/test/aiostress.3561.4.4 /mnt/test/aiostress.3561.4.3 /mnt/test/aiostress.3561.4.2

This is using the aio-stress program from the xfstests test suite.
That particular command line tells aio-stress to do random writes to
20 files from 20 threads (one thread per file).  The files are NOT
preallocated, so you will get writes to random offsets within the
file, thus creating holes and extending i_size.  It also opens the
file with O_DIRECT and O_SYNC.

On to the problem.  When an I/O requires unwritten extent conversion,
it is queued onto the completed_io_list for the ext4 inode.  Two code
paths will pull work items from this list.  The first is the
ext4_end_io_work routine, and the second is ext4_flush_completed_IO,
which is called via the fsync path (and O_SYNC handling, as well).
There are two issues I've found in these code paths.  First, if the
fsync path beats the work routine to a particular I/O, the work
routine will free the io_end structure!  It does not take into account
the fact that the io_end may still be in use by the fsync path.  I've
fixed this issue by adding yet another IO_END flag, indicating that
the io_end is being processed by the fsync path.

The second problem is that the work routine will make an assignment to
io-&gt;flag outside of the lock.  I have witnessed this result in a hang
at umount.  Moving the flag setting inside the lock resolved that
problem.

The problem was introduced by commit b82e384c7b ("ext4: optimize
locking for end_io extent conversion"), which first appeared in 3.2.
As such, the fix should be backported to that release (probably along
with the unwritten extent conversion race fix).

Signed-off-by: Jeff Moyer &lt;jmoyer@redhat.com&gt;
Signed-off-by: "Theodore Ts'o" &lt;tytso@mit.edu&gt;
CC: stable@kernel.org

</content>
</entry>
<entry>
<title>ext4: optimize locking for end_io extent conversion</title>
<updated>2011-10-31T14:56:32Z</updated>
<author>
<name>Theodore Ts'o</name>
<email>tytso@mit.edu</email>
</author>
<published>2011-10-31T14:56:32Z</published>
<link rel='alternate' type='text/html' href='https://git.amat.us/linux/commit/?id=b82e384c7bb9a19036b4daf58fa216df7cd48aa0'/>
<id>urn:sha1:b82e384c7bb9a19036b4daf58fa216df7cd48aa0</id>
<content type='text'>
Now that we are doing the locking correctly, we need to grab the
i_completed_io_lock() twice per end_io.  We can clean this up by
removing the structure from the i_complted_io_list, and use this as
the locking mechanism to prevent ext4_flush_completed_IO() racing
against ext4_end_io_work(), instead of clearing the
EXT4_IO_END_UNWRITTEN in io-&gt;flag.

In addition, if the ext4_convert_unwritten_extents() returns an error,
we no longer keep the end_io structure on the linked list.  This
doesn't help, because it tends to lock up the file system and wedges
the system.  That's one way to call attention to the problem, but it
doesn't help the overall robustness of the system.

Signed-off-by: "Theodore Ts'o" &lt;tytso@mit.edu&gt;
</content>
</entry>
<entry>
<title>ext4: Use correct locking for ext4_end_io_nolock()</title>
<updated>2011-10-30T22:26:08Z</updated>
<author>
<name>Tao Ma</name>
<email>boyu.mt@taobao.com</email>
</author>
<published>2011-10-30T22:26:08Z</published>
<link rel='alternate' type='text/html' href='https://git.amat.us/linux/commit/?id=d73d5046a72467d4510825b99e2269e09ad80e15'/>
<id>urn:sha1:d73d5046a72467d4510825b99e2269e09ad80e15</id>
<content type='text'>
We must hold i_completed_io_lock when manipulating anything on the
i_completed_io_list linked list.  This includes io-&gt;lock, which we
were checking in ext4_end_io_nolock().

So move this check to ext4_end_io_work().  This also has the bonus of
avoiding extra work if it is already done without needing to take the
mutex.

Signed-off-by: Tao Ma &lt;boyu.mt@taobao.com&gt;
Signed-off-by: "Theodore Ts'o" &lt;tytso@mit.edu&gt;
</content>
</entry>
<entry>
<title>ext4: functions should not be declared extern</title>
<updated>2011-10-18T14:57:51Z</updated>
<author>
<name>H Hartley Sweeten</name>
<email>hartleys@visionengravers.com</email>
</author>
<published>2011-10-18T14:57:51Z</published>
<link rel='alternate' type='text/html' href='https://git.amat.us/linux/commit/?id=e0cbee3e14195ef07b8ab6ff30930fb93d2e510a'/>
<id>urn:sha1:e0cbee3e14195ef07b8ab6ff30930fb93d2e510a</id>
<content type='text'>
The function declarations in ext4.h are already marked extern, so it's
not necessary to do so in the .c files.

This quiets the sparse noise:

warning: function 'ext4_flush_completed_IO' with external linkage has definition
warning: function 'ext4_init_inode_table' with external linkage has definition

Signed-off-by: H Hartley Sweeten &lt;hsweeten@visionengravers.com&gt;
Signed-off-by: "Theodore Ts'o" &lt;tytso@mit.edu&gt;
</content>
</entry>
<entry>
<title>Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4</title>
<updated>2011-08-01T23:56:03Z</updated>
<author>
<name>Linus Torvalds</name>
<email>torvalds@linux-foundation.org</email>
</author>
<published>2011-08-01T23:56:03Z</published>
<link rel='alternate' type='text/html' href='https://git.amat.us/linux/commit/?id=60ad4466821a96913a9b567115e194ed1087c2d7'/>
<id>urn:sha1:60ad4466821a96913a9b567115e194ed1087c2d7</id>
<content type='text'>
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: (60 commits)
  ext4: prevent memory leaks from ext4_mb_init_backend() on error path
  ext4: use EXT4_BAD_INO for buddy cache to avoid colliding with valid inode #
  ext4: use ext4_msg() instead of printk in mballoc
  ext4: use ext4_kvzalloc()/ext4_kvmalloc() for s_group_desc and s_group_info
  ext4: introduce ext4_kvmalloc(), ext4_kzalloc(), and ext4_kvfree()
  ext4: use the correct error exit path in ext4_init_inode_table()
  ext4: add missing kfree() on error return path in add_new_gdb()
  ext4: change umode_t in tracepoint headers to be an explicit __u16
  ext4: fix races in ext4_sync_parent()
  ext4: Fix overflow caused by missing cast in ext4_fallocate()
  ext4: add action of moving index in ext4_ext_rm_idx for Punch Hole
  ext4: simplify parameters of reserve_backup_gdb()
  ext4: simplify parameters of add_new_gdb()
  ext4: remove lock_buffer in bclean() and setup_new_group_blocks()
  ext4: simplify journal handling in setup_new_group_blocks()
  ext4: let setup_new_group_blocks() set multiple bits at a time
  ext4: fix a typo in ext4_group_extend()
  ext4: let ext4_group_add_blocks() handle 0 blocks quickly
  ext4: let ext4_group_add_blocks() return an error code
  ext4: rename ext4_add_groupblocks() to ext4_group_add_blocks()
  ...

Fix up conflict in fs/ext4/inode.c: commit aacfc19c626e ("fs: simplify
the blockdev_direct_IO prototype") had changed the ext4_ind_direct_IO()
function for the new simplified calling convention, while commit
dae1e52cb126 ("ext4: move ext4_ind_* functions from inode.c to
indirect.c") moved the function to another file.
</content>
</entry>
<entry>
<title>ext4: fix races in ext4_sync_parent()</title>
<updated>2011-07-30T16:34:19Z</updated>
<author>
<name>Theodore Ts'o</name>
<email>tytso@mit.edu</email>
</author>
<published>2011-07-30T16:34:19Z</published>
<link rel='alternate' type='text/html' href='https://git.amat.us/linux/commit/?id=d59729f4e794f814b25ccd2aebfbe606242c4544'/>
<id>urn:sha1:d59729f4e794f814b25ccd2aebfbe606242c4544</id>
<content type='text'>
Fix problems if fsync() races against a rename of a parent directory
as pointed out by Al Viro in his own inimitable way:

&gt;While we are at it, could somebody please explain what the hell is ext4
&gt;doing in
&gt;static int ext4_sync_parent(struct inode *inode)
&gt;{
&gt;        struct writeback_control wbc;
&gt;        struct dentry *dentry = NULL;
&gt;        int ret = 0;
&gt;
&gt;        while (inode &amp;&amp; ext4_test_inode_state(inode, EXT4_STATE_NEWENTRY)) {
&gt;                ext4_clear_inode_state(inode, EXT4_STATE_NEWENTRY);
&gt;                dentry = list_entry(inode-&gt;i_dentry.next,
&gt;                                    struct dentry, d_alias);
&gt;                if (!dentry || !dentry-&gt;d_parent || !dentry-&gt;d_parent-&gt;d_inode)
&gt;                        break;
&gt;                inode = dentry-&gt;d_parent-&gt;d_inode;
&gt;                ret = sync_mapping_buffers(inode-&gt;i_mapping);
&gt;                ...
&gt;Note that dentry obviously can't be NULL there.  dentry-&gt;d_parent is never
&gt;NULL.  And dentry-&gt;d_parent would better not be negative, for crying out
&gt;loud!  What's worse, there's no guarantees that dentry-&gt;d_parent will
&gt;remain our parent over that sync_mapping_buffers() *and* that inode won't
&gt;just be freed under us (after rename() and memory pressure leading to
&gt;eviction of what used to be our dentry-&gt;d_parent)......

Reported-by: Al Viro &lt;viro@ZenIV.linux.org.uk&gt;
Signed-off-by: "Theodore Ts'o" &lt;tytso@mit.edu&gt;
</content>
</entry>
<entry>
<title>fs: push i_mutex and filemap_write_and_wait down into -&gt;fsync() handlers</title>
<updated>2011-07-21T00:47:59Z</updated>
<author>
<name>Josef Bacik</name>
<email>josef@redhat.com</email>
</author>
<published>2011-07-17T00:44:56Z</published>
<link rel='alternate' type='text/html' href='https://git.amat.us/linux/commit/?id=02c24a82187d5a628c68edfe71ae60dc135cd178'/>
<id>urn:sha1:02c24a82187d5a628c68edfe71ae60dc135cd178</id>
<content type='text'>
Btrfs needs to be able to control how filemap_write_and_wait_range() is called
in fsync to make it less of a painful operation, so push down taking i_mutex and
the calling of filemap_write_and_wait() down into the -&gt;fsync() handlers.  Some
file systems can drop taking the i_mutex altogether it seems, like ext3 and
ocfs2.  For correctness sake I just pushed everything down in all cases to make
sure that we keep the current behavior the same for everybody, and then each
individual fs maintainer can make up their mind about what to do from there.
Thanks,

Acked-by: Jan Kara &lt;jack@suse.cz&gt;
Signed-off-by: Josef Bacik &lt;josef@redhat.com&gt;
Signed-off-by: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
</content>
</entry>
<entry>
<title>ext4: fix waiting and sending of a barrier in ext4_sync_file()</title>
<updated>2011-05-24T16:00:54Z</updated>
<author>
<name>Jan Kara</name>
<email>jack@suse.cz</email>
</author>
<published>2011-05-24T16:00:54Z</published>
<link rel='alternate' type='text/html' href='https://git.amat.us/linux/commit/?id=93628ffb9ba67c154849ac6c387f98f5e3198b84'/>
<id>urn:sha1:93628ffb9ba67c154849ac6c387f98f5e3198b84</id>
<content type='text'>
jbd2_log_start_commit() returns 1 only when we really start a
transaction.  But we also need to wait for a transaction when the
commit is already running.  Fix this problem by waiting for
transaction commit unconditionally (which is just a quick check if the
transaction is already committed).

Also we have to be more careful with sending of a barrier because when
transaction is being committed in parallel to ext4_sync_file()
running, we cannot be sure that the barrier the journalling code sends
happens after we wrote all the data for fsync (note that not every
data writeout needs to trigger metadata changes thus commit of some
metadata changes can be running while other data is still written
out). So use jbd2_will_send_data_barrier() helper to detect the common
cases when we can be sure barrier will be issued by the commit code
and issue the barrier ourselves in the remaining cases.

Reported-by: Edward Goggin &lt;egoggin@vmware.com&gt;
Signed-off-by: Jan Kara &lt;jack@suse.cz&gt;
Signed-off-by: "Theodore Ts'o" &lt;tytso@mit.edu&gt;
</content>
</entry>
<entry>
<title>ext4: use EXT4FS_DEBUG instead of EXT4_DEBUG in fsync.c</title>
<updated>2011-05-09T14:25:54Z</updated>
<author>
<name>Tao Ma</name>
<email>boyu.mt@taobao.com</email>
</author>
<published>2011-05-09T14:25:54Z</published>
<link rel='alternate' type='text/html' href='https://git.amat.us/linux/commit/?id=e8bbe8c401c61408ea226b33b824f231c8f9ccae'/>
<id>urn:sha1:e8bbe8c401c61408ea226b33b824f231c8f9ccae</id>
<content type='text'>
We have EXT4FS_DEBUG for some old debug and CONFIG_EXT4_DEBUG
for the new mballoc debug, but there isn't any EXT4_DEBUG.

As CONFIG_EXT4_DEBUG seems to be only used in mballoc, use
EXT4FS_DEBUG in fsync.c.

[ It doesn't really matter; although I'm including this commit for
  consistency's sake.  The whole point of the #ifdef's is to disable
  the debugging code.  In general you're not going to want to enable
  all of the code protected by EXT4FS_DEBUG at the same time.  -- Ted ]

Signed-off-by: Tao Ma &lt;boyu.mt@taobao.com&gt;
Signed-off-by: "Theodore Ts'o" &lt;tytso@mit.edu&gt;
</content>
</entry>
<entry>
<title>Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4</title>
<updated>2011-04-11T22:45:47Z</updated>
<author>
<name>Linus Torvalds</name>
<email>torvalds@linux-foundation.org</email>
</author>
<published>2011-04-11T22:45:47Z</published>
<link rel='alternate' type='text/html' href='https://git.amat.us/linux/commit/?id=a97b52022a73ec12e43f0b2c7d4bd1f40f89c81d'/>
<id>urn:sha1:a97b52022a73ec12e43f0b2c7d4bd1f40f89c81d</id>
<content type='text'>
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4:
  ext4: fix data corruption regression by reverting commit 6de9843dab3f
  ext4: Allow indirect-block file to grow the file size to max file size
  ext4: allow an active handle to be started when freezing
  ext4: sync the directory inode in ext4_sync_parent()
  ext4: init timer earlier to avoid a kernel panic in __save_error_info
  jbd2: fix potential memory leak on transaction commit
  ext4: fix a double free in ext4_register_li_request
  ext4: fix credits computing for indirect mapped files
  ext4: remove unnecessary [cm]time update of quota file
  jbd2: move bdget out of critical section
</content>
</entry>
</feed>
