<feed xmlns='http://www.w3.org/2005/Atom'>
<title>linux-toradex.git/fs, branch v3.18.13</title>
<subtitle>Linux kernel for Apalis and Colibri modules</subtitle>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/'/>
<entry>
<title>xfs: ensure truncate forces zeroed blocks to disk</title>
<updated>2015-04-24T21:14:13+00:00</updated>
<author>
<name>Dave Chinner</name>
<email>dchinner@redhat.com</email>
</author>
<published>2015-02-23T11:37:08+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=48ca7d78ff4efccbf3d670774d29dd52b7af912d'/>
<id>48ca7d78ff4efccbf3d670774d29dd52b7af912d</id>
<content type='text'>
[ Upstream commit 5885ebda878b47c4b4602d4b0410cb4b282af024 ]

A new fsync vs power fail test in xfstests indicated that XFS can
have unreliable data consistency when doing extending truncates that
require block zeroing. The blocks beyond EOF get zeroed in memory,
but we never force those changes to disk before we run the
transaction that extends the file size and exposes those blocks to
userspace. This can result in the blocks not being correctly zeroed
after a crash.

Because in-memory behaviour is correct, tools like fsx don't pick up
any coherency problems - it's not until the filesystem is shutdown
or the system crashes after writing the truncate transaction to the
journal but before the zeroed data in the page cache is flushed that
the issue is exposed.

Fix this by also flushing the dirty data in memory region between
the old size and new size when we've found blocks that need zeroing
in the truncate process.

Reported-by: Liu Bo &lt;bo.li.liu@oracle.com&gt;
cc: &lt;stable@vger.kernel.org&gt;
Signed-off-by: Dave Chinner &lt;dchinner@redhat.com&gt;
Reviewed-by: Brian Foster &lt;bfoster@redhat.com&gt;
Signed-off-by: Dave Chinner &lt;david@fromorbit.com&gt;
Signed-off-by: Sasha Levin &lt;sasha.levin@oracle.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[ Upstream commit 5885ebda878b47c4b4602d4b0410cb4b282af024 ]

A new fsync vs power fail test in xfstests indicated that XFS can
have unreliable data consistency when doing extending truncates that
require block zeroing. The blocks beyond EOF get zeroed in memory,
but we never force those changes to disk before we run the
transaction that extends the file size and exposes those blocks to
userspace. This can result in the blocks not being correctly zeroed
after a crash.

Because in-memory behaviour is correct, tools like fsx don't pick up
any coherency problems - it's not until the filesystem is shutdown
or the system crashes after writing the truncate transaction to the
journal but before the zeroed data in the page cache is flushed that
the issue is exposed.

Fix this by also flushing the dirty data in memory region between
the old size and new size when we've found blocks that need zeroing
in the truncate process.

Reported-by: Liu Bo &lt;bo.li.liu@oracle.com&gt;
cc: &lt;stable@vger.kernel.org&gt;
Signed-off-by: Dave Chinner &lt;dchinner@redhat.com&gt;
Reviewed-by: Brian Foster &lt;bfoster@redhat.com&gt;
Signed-off-by: Dave Chinner &lt;david@fromorbit.com&gt;
Signed-off-by: Sasha Levin &lt;sasha.levin@oracle.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>ext4: fix indirect punch hole corruption</title>
<updated>2015-04-24T21:14:13+00:00</updated>
<author>
<name>Omar Sandoval</name>
<email>osandov@osandov.com</email>
</author>
<published>2015-02-15T01:08:51+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=a69957362258b8932fe4df1433b1fdea8072ba04'/>
<id>a69957362258b8932fe4df1433b1fdea8072ba04</id>
<content type='text'>
[ Upstream commit 6f30b7e37a8239f9d27db626a1d3427bc7951908 ]

Commit 4f579ae7de56 (ext4: fix punch hole on files with indirect
mapping) rewrote FALLOC_FL_PUNCH_HOLE for ext4 files with indirect
mapping. However, there are bugs in several corner cases. This fixes 5
distinct bugs:

1. When there is at least one entire level of indirection between the
start and end of the punch range and the end of the punch range is the
first block of its level, we can't return early; we have to free the
intervening levels.

2. When the end is at a higher level of indirection than the start and
ext4_find_shared returns a top branch for the end, we still need to free
the rest of the shared branch it returns; we can't decrement partial2.

3. When a punch happens within one level of indirection, we need to
converge on an indirect block that contains the start and end. However,
because the branches returned from ext4_find_shared do not necessarily
start at the same level (e.g., the partial2 chain will be shallower if
the last block occurs at the beginning of an indirect group), the walk
of the two chains can end up "missing" each other and freeing a bunch of
extra blocks in the process. This mismatch can be handled by first
making sure that the chains are at the same level, then walking them
together until they converge.

4. When the punch happens within one level of indirection and
ext4_find_shared returns a top branch for the start, we must free it,
but only if the end does not occur within that branch.

5. When the punch happens within one level of indirection and
ext4_find_shared returns a top branch for the end, then we shouldn't
free the block referenced by the end of the returned chain (this mirrors
the different levels case).

Signed-off-by: Omar Sandoval &lt;osandov@osandov.com&gt;
Signed-off-by: Sasha Levin &lt;sasha.levin@oracle.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[ Upstream commit 6f30b7e37a8239f9d27db626a1d3427bc7951908 ]

Commit 4f579ae7de56 (ext4: fix punch hole on files with indirect
mapping) rewrote FALLOC_FL_PUNCH_HOLE for ext4 files with indirect
mapping. However, there are bugs in several corner cases. This fixes 5
distinct bugs:

1. When there is at least one entire level of indirection between the
start and end of the punch range and the end of the punch range is the
first block of its level, we can't return early; we have to free the
intervening levels.

2. When the end is at a higher level of indirection than the start and
ext4_find_shared returns a top branch for the end, we still need to free
the rest of the shared branch it returns; we can't decrement partial2.

3. When a punch happens within one level of indirection, we need to
converge on an indirect block that contains the start and end. However,
because the branches returned from ext4_find_shared do not necessarily
start at the same level (e.g., the partial2 chain will be shallower if
the last block occurs at the beginning of an indirect group), the walk
of the two chains can end up "missing" each other and freeing a bunch of
extra blocks in the process. This mismatch can be handled by first
making sure that the chains are at the same level, then walking them
together until they converge.

4. When the punch happens within one level of indirection and
ext4_find_shared returns a top branch for the start, we must free it,
but only if the end does not occur within that branch.

5. When the punch happens within one level of indirection and
ext4_find_shared returns a top branch for the end, then we shouldn't
free the block referenced by the end of the returned chain (this mirrors
the different levels case).

Signed-off-by: Omar Sandoval &lt;osandov@osandov.com&gt;
Signed-off-by: Sasha Levin &lt;sasha.levin@oracle.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>ioctx_alloc(): fix vma (and file) leak on failure</title>
<updated>2015-04-24T21:14:06+00:00</updated>
<author>
<name>Al Viro</name>
<email>viro@zeniv.linux.org.uk</email>
</author>
<published>2015-04-06T21:57:44+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=fe4a6fceff3949a6389c582ccedc393670355469'/>
<id>fe4a6fceff3949a6389c582ccedc393670355469</id>
<content type='text'>
[ Upstream commit deeb8525f9bcea60f5e86521880c1161de7a5829 ]

If we fail past the aio_setup_ring(), we need to destroy the
mapping.  We don't need to care about anybody having found ctx,
or added requests to it, since the last failure exit is exactly
the failure to make ctx visible to lookups.

Reproducer (based on one by Joe Mario &lt;jmario@redhat.com&gt;):

void count(char *p)
{
	char s[80];
	printf("%s: ", p);
	fflush(stdout);
	sprintf(s, "/bin/cat /proc/%d/maps|/bin/fgrep -c '/[aio] (deleted)'", getpid());
	system(s);
}

int main()
{
	io_context_t *ctx;
	int created, limit, i, destroyed;
	FILE *f;

	count("before");
	if ((f = fopen("/proc/sys/fs/aio-max-nr", "r")) == NULL)
		perror("opening aio-max-nr");
	else if (fscanf(f, "%d", &amp;limit) != 1)
		fprintf(stderr, "can't parse aio-max-nr\n");
	else if ((ctx = calloc(limit, sizeof(io_context_t))) == NULL)
		perror("allocating aio_context_t array");
	else {
		for (i = 0, created = 0; i &lt; limit; i++) {
			if (io_setup(1000, ctx + created) == 0)
				created++;
		}
		for (i = 0, destroyed = 0; i &lt; created; i++)
			if (io_destroy(ctx[i]) == 0)
				destroyed++;
		printf("created %d, failed %d, destroyed %d\n",
			created, limit - created, destroyed);
		count("after");
	}
}

Found-by: Joe Mario &lt;jmario@redhat.com&gt;
Cc: stable@vger.kernel.org
Signed-off-by: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
Signed-off-by: Sasha Levin &lt;sasha.levin@oracle.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[ Upstream commit deeb8525f9bcea60f5e86521880c1161de7a5829 ]

If we fail past the aio_setup_ring(), we need to destroy the
mapping.  We don't need to care about anybody having found ctx,
or added requests to it, since the last failure exit is exactly
the failure to make ctx visible to lookups.

Reproducer (based on one by Joe Mario &lt;jmario@redhat.com&gt;):

void count(char *p)
{
	char s[80];
	printf("%s: ", p);
	fflush(stdout);
	sprintf(s, "/bin/cat /proc/%d/maps|/bin/fgrep -c '/[aio] (deleted)'", getpid());
	system(s);
}

int main()
{
	io_context_t *ctx;
	int created, limit, i, destroyed;
	FILE *f;

	count("before");
	if ((f = fopen("/proc/sys/fs/aio-max-nr", "r")) == NULL)
		perror("opening aio-max-nr");
	else if (fscanf(f, "%d", &amp;limit) != 1)
		fprintf(stderr, "can't parse aio-max-nr\n");
	else if ((ctx = calloc(limit, sizeof(io_context_t))) == NULL)
		perror("allocating aio_context_t array");
	else {
		for (i = 0, created = 0; i &lt; limit; i++) {
			if (io_setup(1000, ctx + created) == 0)
				created++;
		}
		for (i = 0, destroyed = 0; i &lt; created; i++)
			if (io_destroy(ctx[i]) == 0)
				destroyed++;
		printf("created %d, failed %d, destroyed %d\n",
			created, limit - created, destroyed);
		count("after");
	}
}

Found-by: Joe Mario &lt;jmario@redhat.com&gt;
Cc: stable@vger.kernel.org
Signed-off-by: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
Signed-off-by: Sasha Levin &lt;sasha.levin@oracle.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>ocfs2: _really_ sync the right range</title>
<updated>2015-04-24T21:14:05+00:00</updated>
<author>
<name>Al Viro</name>
<email>viro@zeniv.linux.org.uk</email>
</author>
<published>2015-04-08T21:00:32+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=67041680ff381e6e5ba8f9620695e79b512a01be'/>
<id>67041680ff381e6e5ba8f9620695e79b512a01be</id>
<content type='text'>
[ Upstream commit 64b4e2526d1cf6e6a4db6213d6e2b6e6ab59479a ]

"ocfs2 syncs the wrong range" had been broken; prior to it the
code was doing the wrong thing in case of O_APPEND, all right,
but _after_ it we were syncing the wrong range in 100% cases.
*ppos, aka iocb-&gt;ki_pos is incremented prior to that point,
so we are always doing sync on the area _after_ the one we'd
written to.

Spotted by Joseph Qi &lt;joseph.qi@huawei.com&gt; back in January;
unfortunately, I'd missed his mail back then ;-/

Cc: stable@vger.kernel.org
Signed-off-by: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
Signed-off-by: Sasha Levin &lt;sasha.levin@oracle.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[ Upstream commit 64b4e2526d1cf6e6a4db6213d6e2b6e6ab59479a ]

"ocfs2 syncs the wrong range" had been broken; prior to it the
code was doing the wrong thing in case of O_APPEND, all right,
but _after_ it we were syncing the wrong range in 100% cases.
*ppos, aka iocb-&gt;ki_pos is incremented prior to that point,
so we are always doing sync on the area _after_ the one we'd
written to.

Spotted by Joseph Qi &lt;joseph.qi@huawei.com&gt; back in January;
unfortunately, I'd missed his mail back then ;-/

Cc: stable@vger.kernel.org
Signed-off-by: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
Signed-off-by: Sasha Levin &lt;sasha.levin@oracle.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>cifs: fix use-after-free bug in find_writable_file</title>
<updated>2015-04-24T21:14:01+00:00</updated>
<author>
<name>David Disseldorp</name>
<email>ddiss@suse.de</email>
</author>
<published>2015-03-13T13:20:29+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=e9c75e69d6f20cc14dd86eeab712226fd191015b'/>
<id>e9c75e69d6f20cc14dd86eeab712226fd191015b</id>
<content type='text'>
[ Upstream commit e1e9bda22d7ddf88515e8fe401887e313922823e ]

Under intermittent network outages, find_writable_file() is susceptible
to the following race condition, which results in a user-after-free in
the cifs_writepages code-path:

Thread 1                                        Thread 2
========                                        ========

inv_file = NULL
refind = 0
spin_lock(&amp;cifs_file_list_lock)

// invalidHandle found on openFileList

inv_file = open_file
// inv_file-&gt;count currently 1

cifsFileInfo_get(inv_file)
// inv_file-&gt;count = 2

spin_unlock(&amp;cifs_file_list_lock);

cifs_reopen_file()                            cifs_close()
// fails (rc != 0)                            -&gt;cifsFileInfo_put()
                                       spin_lock(&amp;cifs_file_list_lock)
                                       // inv_file-&gt;count = 1
                                       spin_unlock(&amp;cifs_file_list_lock)

spin_lock(&amp;cifs_file_list_lock);
list_move_tail(&amp;inv_file-&gt;flist,
      &amp;cifs_inode-&gt;openFileList);
spin_unlock(&amp;cifs_file_list_lock);

cifsFileInfo_put(inv_file);
-&gt;spin_lock(&amp;cifs_file_list_lock)

  // inv_file-&gt;count = 0
  list_del(&amp;cifs_file-&gt;flist);
  // cleanup!!
  kfree(cifs_file);

  spin_unlock(&amp;cifs_file_list_lock);

spin_lock(&amp;cifs_file_list_lock);
++refind;
// refind = 1
goto refind_writable;

At this point we loop back through with an invalid inv_file pointer
and a refind value of 1. On second pass, inv_file is not overwritten on
openFileList traversal, and is subsequently dereferenced.

Signed-off-by: David Disseldorp &lt;ddiss@suse.de&gt;
Reviewed-by: Jeff Layton &lt;jlayton@samba.org&gt;
CC: &lt;stable@vger.kernel.org&gt;
Signed-off-by: Steve French &lt;smfrench@gmail.com&gt;
Signed-off-by: Sasha Levin &lt;sasha.levin@oracle.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[ Upstream commit e1e9bda22d7ddf88515e8fe401887e313922823e ]

Under intermittent network outages, find_writable_file() is susceptible
to the following race condition, which results in a user-after-free in
the cifs_writepages code-path:

Thread 1                                        Thread 2
========                                        ========

inv_file = NULL
refind = 0
spin_lock(&amp;cifs_file_list_lock)

// invalidHandle found on openFileList

inv_file = open_file
// inv_file-&gt;count currently 1

cifsFileInfo_get(inv_file)
// inv_file-&gt;count = 2

spin_unlock(&amp;cifs_file_list_lock);

cifs_reopen_file()                            cifs_close()
// fails (rc != 0)                            -&gt;cifsFileInfo_put()
                                       spin_lock(&amp;cifs_file_list_lock)
                                       // inv_file-&gt;count = 1
                                       spin_unlock(&amp;cifs_file_list_lock)

spin_lock(&amp;cifs_file_list_lock);
list_move_tail(&amp;inv_file-&gt;flist,
      &amp;cifs_inode-&gt;openFileList);
spin_unlock(&amp;cifs_file_list_lock);

cifsFileInfo_put(inv_file);
-&gt;spin_lock(&amp;cifs_file_list_lock)

  // inv_file-&gt;count = 0
  list_del(&amp;cifs_file-&gt;flist);
  // cleanup!!
  kfree(cifs_file);

  spin_unlock(&amp;cifs_file_list_lock);

spin_lock(&amp;cifs_file_list_lock);
++refind;
// refind = 1
goto refind_writable;

At this point we loop back through with an invalid inv_file pointer
and a refind value of 1. On second pass, inv_file is not overwritten on
openFileList traversal, and is subsequently dereferenced.

Signed-off-by: David Disseldorp &lt;ddiss@suse.de&gt;
Reviewed-by: Jeff Layton &lt;jlayton@samba.org&gt;
CC: &lt;stable@vger.kernel.org&gt;
Signed-off-by: Steve French &lt;smfrench@gmail.com&gt;
Signed-off-by: Sasha Levin &lt;sasha.levin@oracle.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>cifs: smb2_clone_range() - exit on unhandled error</title>
<updated>2015-04-24T21:14:00+00:00</updated>
<author>
<name>Sachin Prabhu</name>
<email>sprabhu@redhat.com</email>
</author>
<published>2015-02-04T13:10:26+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=6bb88677e8e9a47b643ae03959f3a216d22432ac'/>
<id>6bb88677e8e9a47b643ae03959f3a216d22432ac</id>
<content type='text'>
[ Upstream commit 2477bc58d49edb1c0baf59df7dc093dce682af2b ]

While attempting to clone a file on a samba server, we receive a
STATUS_INVALID_DEVICE_REQUEST. This is mapped to -EOPNOTSUPP which
isn't handled in smb2_clone_range(). We end up looping in the while loop
making same call to the samba server over and over again.

The proposed fix is to exit and return the error value when encountered
with an unhandled error.

Cc: &lt;stable@vger.kernel.org&gt;
Signed-off-by: Sachin Prabhu &lt;sprabhu@redhat.com&gt;
Signed-off-by: Steve French &lt;steve.french@primarydata.com&gt;
Signed-off-by: Steve French &lt;smfrench@gmail.com&gt;
Signed-off-by: Sasha Levin &lt;sasha.levin@oracle.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[ Upstream commit 2477bc58d49edb1c0baf59df7dc093dce682af2b ]

While attempting to clone a file on a samba server, we receive a
STATUS_INVALID_DEVICE_REQUEST. This is mapped to -EOPNOTSUPP which
isn't handled in smb2_clone_range(). We end up looping in the while loop
making same call to the samba server over and over again.

The proposed fix is to exit and return the error value when encountered
with an unhandled error.

Cc: &lt;stable@vger.kernel.org&gt;
Signed-off-by: Sachin Prabhu &lt;sprabhu@redhat.com&gt;
Signed-off-by: Steve French &lt;steve.french@primarydata.com&gt;
Signed-off-by: Steve French &lt;smfrench@gmail.com&gt;
Signed-off-by: Sasha Levin &lt;sasha.levin@oracle.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>nfsd: return correct lockowner when there is a race on hash insert</title>
<updated>2015-04-23T18:58:27+00:00</updated>
<author>
<name>J. Bruce Fields</name>
<email>bfields@redhat.com</email>
</author>
<published>2015-03-23T15:02:30+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=604696d8b5d9ebf2f5af9bf46ac76519b831435f'/>
<id>604696d8b5d9ebf2f5af9bf46ac76519b831435f</id>
<content type='text'>
[ Upstream commit 340f0ba1c6c8412aa35fd6476044836b84361ea6 ]

alloc_init_lock_stateowner can return an already freed entry if there is
a race to put openowners in the hashtable.

Noticed by inspection after Jeff Layton fixed the same bug for open
owners.  Depending on client behavior, this one may be trickier to
trigger in practice.

Fixes: c58c6610ec24 "nfsd: Protect adding/removing lock owners using client_lock"
Cc: &lt;stable@vger.kernel.org&gt;
Cc: Trond Myklebust &lt;trond.myklebust@primarydata.com&gt;
Acked-by: Jeff Layton &lt;jeff.layton@primarydata.com&gt;
Signed-off-by: J. Bruce Fields &lt;bfields@redhat.com&gt;
Signed-off-by: Sasha Levin &lt;sasha.levin@oracle.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[ Upstream commit 340f0ba1c6c8412aa35fd6476044836b84361ea6 ]

alloc_init_lock_stateowner can return an already freed entry if there is
a race to put openowners in the hashtable.

Noticed by inspection after Jeff Layton fixed the same bug for open
owners.  Depending on client behavior, this one may be trickier to
trigger in practice.

Fixes: c58c6610ec24 "nfsd: Protect adding/removing lock owners using client_lock"
Cc: &lt;stable@vger.kernel.org&gt;
Cc: Trond Myklebust &lt;trond.myklebust@primarydata.com&gt;
Acked-by: Jeff Layton &lt;jeff.layton@primarydata.com&gt;
Signed-off-by: J. Bruce Fields &lt;bfields@redhat.com&gt;
Signed-off-by: Sasha Levin &lt;sasha.levin@oracle.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>nfsd: return correct openowner when there is a race to put one in the hash</title>
<updated>2015-04-23T18:58:26+00:00</updated>
<author>
<name>Jeff Layton</name>
<email>jlayton@poochiereds.net</email>
</author>
<published>2015-03-23T14:53:42+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=5a472b11c0afd6457e4f4222083efa1536562496'/>
<id>5a472b11c0afd6457e4f4222083efa1536562496</id>
<content type='text'>
[ Upstream commit c5952338bfc234e54deda45b7228f610a545e28a ]

alloc_init_open_stateowner can return an already freed entry if there is
a race to put openowners in the hashtable.

In commit 7ffb588086e9, we changed it so that we allocate and initialize
an openowner, and then check to see if a matching one got stuffed into
the hashtable in the meantime. If it did, then we free the one we just
allocated and take a reference on the one already there. There is a bug
here though. The code will then return the pointer to the one that was
allocated (and has now been freed).

This wasn't evident before as this race almost never occurred. The Linux
kernel client used to serialize requests for a single openowner.  That
has changed now with v4.0 kernels, and this race can now easily occur.

Fixes: 7ffb588086e9
Cc: &lt;stable@vger.kernel.org&gt; # v3.17+
Cc: Trond Myklebust &lt;trond.myklebust@primarydata.com&gt;
Reported-by: Christoph Hellwig &lt;hch@infradead.org&gt;
Reviewed-by: Christoph Hellwig &lt;hch@lst.de&gt;
Signed-off-by: Jeff Layton &lt;jeff.layton@primarydata.com&gt;
Signed-off-by: J. Bruce Fields &lt;bfields@redhat.com&gt;
Signed-off-by: Sasha Levin &lt;sasha.levin@oracle.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[ Upstream commit c5952338bfc234e54deda45b7228f610a545e28a ]

alloc_init_open_stateowner can return an already freed entry if there is
a race to put openowners in the hashtable.

In commit 7ffb588086e9, we changed it so that we allocate and initialize
an openowner, and then check to see if a matching one got stuffed into
the hashtable in the meantime. If it did, then we free the one we just
allocated and take a reference on the one already there. There is a bug
here though. The code will then return the pointer to the one that was
allocated (and has now been freed).

This wasn't evident before as this race almost never occurred. The Linux
kernel client used to serialize requests for a single openowner.  That
has changed now with v4.0 kernels, and this race can now easily occur.

Fixes: 7ffb588086e9
Cc: &lt;stable@vger.kernel.org&gt; # v3.17+
Cc: Trond Myklebust &lt;trond.myklebust@primarydata.com&gt;
Reported-by: Christoph Hellwig &lt;hch@infradead.org&gt;
Reviewed-by: Christoph Hellwig &lt;hch@lst.de&gt;
Signed-off-by: Jeff Layton &lt;jeff.layton@primarydata.com&gt;
Signed-off-by: J. Bruce Fields &lt;bfields@redhat.com&gt;
Signed-off-by: Sasha Levin &lt;sasha.levin@oracle.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>btrfs: simplify insert_orphan_item</title>
<updated>2015-04-23T18:58:24+00:00</updated>
<author>
<name>David Sterba</name>
<email>dsterba@suse.cz</email>
</author>
<published>2015-01-02T18:12:57+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=b3d55b2f8587c96f82878b984383390509dd9a05'/>
<id>b3d55b2f8587c96f82878b984383390509dd9a05</id>
<content type='text'>
[ Upstream commit 9c4f61f01d269815bb7c37be3ede59c5587747c6 ]

We can search and add the orphan item in one go,
btrfs_insert_orphan_item will find out if the item already exists.

Signed-off-by: David Sterba &lt;dsterba@suse.cz&gt;
Signed-off-by: Sasha Levin &lt;sasha.levin@oracle.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[ Upstream commit 9c4f61f01d269815bb7c37be3ede59c5587747c6 ]

We can search and add the orphan item in one go,
btrfs_insert_orphan_item will find out if the item already exists.

Signed-off-by: David Sterba &lt;dsterba@suse.cz&gt;
Signed-off-by: Sasha Levin &lt;sasha.levin@oracle.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>hfsplus: fix B-tree corruption after insertion at position 0</title>
<updated>2015-04-17T00:13:14+00:00</updated>
<author>
<name>Sergei Antonov</name>
<email>saproj@gmail.com</email>
</author>
<published>2015-03-25T22:55:34+00:00</published>
<link rel='alternate' type='text/html' href='https://git.toradex.cn/cgit/linux-toradex.git/commit/?id=44f6282e373e266db7c0c02c8a6bd0c5ce9e3746'/>
<id>44f6282e373e266db7c0c02c8a6bd0c5ce9e3746</id>
<content type='text'>
[ Upstream commit 98cf21c61a7f5419d82f847c4d77bf6e96a76f5f ]

Fix B-tree corruption when a new record is inserted at position 0 in the
node in hfs_brec_insert().  In this case a hfs_brec_update_parent() is
called to update the parent index node (if exists) and it is passed
hfs_find_data with a search_key containing a newly inserted key instead
of the key to be updated.  This results in an inconsistent index node.
The bug reproduces on my machine after an extents overflow record for
the catalog file (CNID=4) is inserted into the extents overflow B-tree.
Because of a low (reserved) value of CNID=4, it has to become the first
record in the first leaf node.

The resulting first leaf node is correct:

  ----------------------------------------------------
  | key0.CNID=4 | key1.CNID=123 | key2.CNID=456, ... |
  ----------------------------------------------------

But the parent index key0 still contains the previous key CNID=123:

  -----------------------
  | key0.CNID=123 | ... |
  -----------------------

A change in hfs_brec_insert() makes hfs_brec_update_parent() work
correctly by preventing it from getting fd-&gt;record=-1 value from
__hfs_brec_find().

Along the way, I removed duplicate code with unification of the if
condition.  The resulting code is equivalent to the original code
because node is never 0.

Also hfs_brec_update_parent() will now return an error after getting a
negative fd-&gt;record value.  However, the return value of
hfs_brec_update_parent() is not checked anywhere in the file and I'm
leaving it unchanged by this patch.  brec.c lacks error checking after
some other calls too, but this issue is of less importance than the one
being fixed by this patch.

Signed-off-by: Sergei Antonov &lt;saproj@gmail.com&gt;
Cc: Joe Perches &lt;joe@perches.com&gt;
Reviewed-by: Vyacheslav Dubeyko &lt;slava@dubeyko.com&gt;
Acked-by: Hin-Tak Leung &lt;htl10@users.sourceforge.net&gt;
Cc: Anton Altaparmakov &lt;aia21@cam.ac.uk&gt;
Cc: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
Cc: Christoph Hellwig &lt;hch@infradead.org&gt;
Cc: &lt;stable@vger.kernel.org&gt;
Signed-off-by: Andrew Morton &lt;akpm@linux-foundation.org&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
Signed-off-by: Sasha Levin &lt;sasha.levin@oracle.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[ Upstream commit 98cf21c61a7f5419d82f847c4d77bf6e96a76f5f ]

Fix B-tree corruption when a new record is inserted at position 0 in the
node in hfs_brec_insert().  In this case a hfs_brec_update_parent() is
called to update the parent index node (if exists) and it is passed
hfs_find_data with a search_key containing a newly inserted key instead
of the key to be updated.  This results in an inconsistent index node.
The bug reproduces on my machine after an extents overflow record for
the catalog file (CNID=4) is inserted into the extents overflow B-tree.
Because of a low (reserved) value of CNID=4, it has to become the first
record in the first leaf node.

The resulting first leaf node is correct:

  ----------------------------------------------------
  | key0.CNID=4 | key1.CNID=123 | key2.CNID=456, ... |
  ----------------------------------------------------

But the parent index key0 still contains the previous key CNID=123:

  -----------------------
  | key0.CNID=123 | ... |
  -----------------------

A change in hfs_brec_insert() makes hfs_brec_update_parent() work
correctly by preventing it from getting fd-&gt;record=-1 value from
__hfs_brec_find().

Along the way, I removed duplicate code with unification of the if
condition.  The resulting code is equivalent to the original code
because node is never 0.

Also hfs_brec_update_parent() will now return an error after getting a
negative fd-&gt;record value.  However, the return value of
hfs_brec_update_parent() is not checked anywhere in the file and I'm
leaving it unchanged by this patch.  brec.c lacks error checking after
some other calls too, but this issue is of less importance than the one
being fixed by this patch.

Signed-off-by: Sergei Antonov &lt;saproj@gmail.com&gt;
Cc: Joe Perches &lt;joe@perches.com&gt;
Reviewed-by: Vyacheslav Dubeyko &lt;slava@dubeyko.com&gt;
Acked-by: Hin-Tak Leung &lt;htl10@users.sourceforge.net&gt;
Cc: Anton Altaparmakov &lt;aia21@cam.ac.uk&gt;
Cc: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
Cc: Christoph Hellwig &lt;hch@infradead.org&gt;
Cc: &lt;stable@vger.kernel.org&gt;
Signed-off-by: Andrew Morton &lt;akpm@linux-foundation.org&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
Signed-off-by: Sasha Levin &lt;sasha.levin@oracle.com&gt;
</pre>
</div>
</content>
</entry>
</feed>
