<feed xmlns='http://www.w3.org/2005/Atom'>
<title>kernel.git/fs/namei.c, branch linux-3.17.y</title>
<subtitle>Hosts the 0x221E linux distro kernel.
</subtitle>
<id>https://git.0xinfinity.dev/distro/kernel.git/atom?h=linux-3.17.y</id>
<link rel='self' href='https://git.0xinfinity.dev/distro/kernel.git/atom?h=linux-3.17.y'/>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/'/>
<updated>2014-11-14T18:10:23Z</updated>
<entry>
<title>fs: allow open(dir, O_TMPFILE|..., 0) with mode 0</title>
<updated>2014-11-14T18:10:23Z</updated>
<author>
<name>Eric Rannaud</name>
</author>
<published>2014-10-30T08:51:01Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=d35f2f8cf099c4036ba5854b44fe72c53b12c582'/>
<id>urn:sha1:d35f2f8cf099c4036ba5854b44fe72c53b12c582</id>
<content type='text'>
commit 69a91c237ab0ebe4e9fdeaf6d0090c85275594ec upstream.

The man page for open(2) indicates that when O_CREAT is specified, the
'mode' argument applies only to future accesses to the file:

	Note that this mode applies only to future accesses of the newly
	created file; the open() call that creates a read-only file
	may well return a read/write file descriptor.

The man page for open(2) implies that 'mode' is treated identically by
O_CREAT and O_TMPFILE.

O_TMPFILE, however, behaves differently:

	int fd = open("/tmp", O_TMPFILE | O_RDWR, 0);
	assert(fd == -1);
	assert(errno == EACCES);

	int fd = open("/tmp", O_TMPFILE | O_RDWR, 0600);
	assert(fd &gt; 0);

For O_CREAT, do_last() sets acc_mode to MAY_OPEN only:

	if (*opened &amp; FILE_CREATED) {
		/* Don't check for write permission, don't truncate */
		open_flag &amp;= ~O_TRUNC;
		will_truncate = false;
		acc_mode = MAY_OPEN;
		path_to_nameidata(path, nd);
		goto finish_open_created;
	}

But for O_TMPFILE, do_tmpfile() passes the full op-&gt;acc_mode to
may_open().

This patch lines up the behavior of O_TMPFILE with O_CREAT. After the
inode is created, may_open() is called with acc_mode = MAY_OPEN, in
do_tmpfile().

A different, but related glibc bug revealed the discrepancy:
https://sourceware.org/bugzilla/show_bug.cgi?id=17523

The glibc lazily loads the 'mode' argument of open() and openat() using
va_arg() only if O_CREAT is present in 'flags' (to support both the 2
argument and the 3 argument forms of open; same idea for openat()).
However, the glibc ignores the 'mode' argument if O_TMPFILE is in
'flags'.

On x86_64, for open(), it magically works anyway, as 'mode' is in
RDX when entering open(), and is still in RDX on SYSCALL, which is where
the kernel looks for the 3rd argument of a syscall.

But openat() is not quite so lucky: 'mode' is in RCX when entering the
glibc wrapper for openat(), while the kernel looks for the 4th argument
of a syscall in R10. Indeed, the syscall calling convention differs from
the regular calling convention in this respect on x86_64. So the kernel
sees mode = 0 when trying to use glibc openat() with O_TMPFILE, and
fails with EACCES.

Signed-off-by: Eric Rannaud &lt;e@nanocritical.com&gt;
Acked-by: Andy Lutomirski &lt;luto@amacapital.net&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</content>
</entry>
<entry>
<title>ima: pass 'opened' flag to identify newly created files</title>
<updated>2014-10-30T16:43:16Z</updated>
<author>
<name>Dmitry Kasatkin</name>
</author>
<published>2014-06-27T15:15:44Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=8006fece344df5eb1d82593402a6cdcf5dce71b3'/>
<id>urn:sha1:8006fece344df5eb1d82593402a6cdcf5dce71b3</id>
<content type='text'>
commit 3034a146820c26fe6da66a45f6340fe87fe0983a upstream.

Empty files and missing xattrs do not guarantee that a file was
just created.  This patch passes FILE_CREATED flag to IMA to
reliably identify new files.

Signed-off-by: Dmitry Kasatkin &lt;d.kasatkin@samsung.com&gt;
Signed-off-by: Mimi Zohar &lt;zohar@linux.vnet.ibm.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;

</content>
</entry>
<entry>
<title>vfs: workaround gcc &lt;4.6 build error in link_path_walk()</title>
<updated>2014-09-16T14:44:54Z</updated>
<author>
<name>James Hogan</name>
</author>
<published>2014-09-16T12:07:35Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=a060dc5010ffa32f3a83e5336f6eeb6551fa137a'/>
<id>urn:sha1:a060dc5010ffa32f3a83e5336f6eeb6551fa137a</id>
<content type='text'>
Commit d6bb3e9075bb ("vfs: simplify and shrink stack frame of
link_path_walk()") introduced build problems with GCC versions older
than 4.6 due to the initialisation of a member of an anonymous union in
struct qstr without enclosing braces.

This hits GCC bug 10676 [1] (which was fixed in GCC 4.6 by [2]), and
causes the following build error:

  fs/namei.c: In function 'link_path_walk':
  fs/namei.c:1778: error: unknown field 'hash_len' specified in initializer

This is worked around by adding explicit braces.

[1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=10676
[2] https://gcc.gnu.org/viewcvs/gcc?view=revision&amp;revision=159206

Fixes: d6bb3e9075bb (vfs: simplify and shrink stack frame of link_path_walk())
Signed-off-by: James Hogan &lt;james.hogan@imgtec.com&gt;
Cc: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
Cc: Alexander Viro &lt;viro@zeniv.linux.org.uk&gt;
Cc: Geert Uytterhoeven &lt;geert@linux-m68k.org&gt;
Cc: linux-fsdevel@vger.kernel.org
Cc: linux-metag@vger.kernel.org
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
</entry>
<entry>
<title>vfs: simplify and shrink stack frame of link_path_walk()</title>
<updated>2014-09-15T17:51:07Z</updated>
<author>
<name>Linus Torvalds</name>
</author>
<published>2014-09-15T17:51:07Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=d6bb3e9075bbcf758d6084bb581f797bb6ea24c6'/>
<id>urn:sha1:d6bb3e9075bbcf758d6084bb581f797bb6ea24c6</id>
<content type='text'>
Commit 9226b5b440f2 ("vfs: avoid non-forwarding large load after small
store in path lookup") made link_path_walk() always access the
"hash_len" field as a single 64-bit entity, in order to avoid mixed size
accesses to the members.

However, what I didn't notice was that that effectively means that the
whole "struct qstr this" is now basically redundant.  We already
explicitly track the "const char *name", and if we just use "u64
hash_len" instead of "long len", there is nothing else left of the
"struct qstr".

We do end up wanting the "struct qstr" if we have a filesystem with a
"d_hash()" function, but that's a rare case, and we might as well then
just squirrell away the name and hash_len at that point.

End result: fewer live variables in the loop, a smaller stack frame, and
better code generation.  And we don't need to pass in pointers variables
to helper functions any more, because the return value contains all the
relevant information.  So this removes more lines than it adds, and the
source code is clearer too.

Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
</entry>
<entry>
<title>Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs</title>
<updated>2014-09-15T00:37:36Z</updated>
<author>
<name>Linus Torvalds</name>
</author>
<published>2014-09-15T00:37:36Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=83373f702829dd9f6dcc56d275978d986fafee48'/>
<id>urn:sha1:83373f702829dd9f6dcc56d275978d986fafee48</id>
<content type='text'>
Pull vfs fixes from Al Viro:
 "double iput() on failure exit in lustre, racy removal of spliced
  dentries from -&gt;s_anon in __d_materialise_dentry() plus a bunch of
  assorted RCU pathwalk fixes"

The RCU pathwalk fixes end up fixing a couple of cases where we
incorrectly dropped out of RCU walking, due to incorrect initialization
and testing of the sequence locks in some corner cases.  Since dropping
out of RCU walk mode forces the slow locked accesses, those corner cases
slowed down quite dramatically.

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  be careful with nd-&gt;inode in path_init() and follow_dotdot_rcu()
  don't bugger nd-&gt;seq on set_root_rcu() from follow_dotdot_rcu()
  fix bogus read_seqretry() checks introduced in b37199e
  move the call of __d_drop(anon) into __d_materialise_unique(dentry, anon)
  [fix] lustre: d_make_root() does iput() on dentry allocation failure
</content>
</entry>
<entry>
<title>vfs: avoid non-forwarding large load after small store in path lookup</title>
<updated>2014-09-15T00:28:32Z</updated>
<author>
<name>Linus Torvalds</name>
</author>
<published>2014-09-15T00:28:32Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=9226b5b440f2b4fbb3b797f3cb74a9a627220660'/>
<id>urn:sha1:9226b5b440f2b4fbb3b797f3cb74a9a627220660</id>
<content type='text'>
The performance regression that Josef Bacik reported in the pathname
lookup (see commit 99d263d4c5b2 "vfs: fix bad hashing of dentries") made
me look at performance stability of the dcache code, just to verify that
the problem was actually fixed.  That turned up a few other problems in
this area.

There are a few cases where we exit RCU lookup mode and go to the slow
serializing case when we shouldn't, Al has fixed those and they'll come
in with the next VFS pull.

But my performance verification also shows that link_path_walk() turns
out to have a very unfortunate 32-bit store of the length and hash of
the name we look up, followed by a 64-bit read of the combined hash_len
field.  That screws up the processor store to load forwarding, causing
an unnecessary hickup in this critical routine.

It's caused by the ugly calling convention for the "hash_name()"
function, and easily fixed by just making hash_name() fill in the whole
'struct qstr' rather than passing it a pointer to just the hash value.

With that, the profile for this function looks much smoother.

Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
</entry>
<entry>
<title>be careful with nd-&gt;inode in path_init() and follow_dotdot_rcu()</title>
<updated>2014-09-14T18:24:47Z</updated>
<author>
<name>Al Viro</name>
</author>
<published>2014-09-14T01:59:43Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=4023bfc9f351a7994fb6a7d515476c320f94a574'/>
<id>urn:sha1:4023bfc9f351a7994fb6a7d515476c320f94a574</id>
<content type='text'>
in the former we simply check if dentry is still valid after picking
its -&gt;d_inode; in the latter we fetch -&gt;d_inode in the same places
where we fetch dentry and its -&gt;d_seq, under the same checks.

Cc: stable@vger.kernel.org # 2.6.38+
Signed-off-by: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
</content>
</entry>
<entry>
<title>don't bugger nd-&gt;seq on set_root_rcu() from follow_dotdot_rcu()</title>
<updated>2014-09-14T18:19:44Z</updated>
<author>
<name>Al Viro</name>
</author>
<published>2014-09-14T01:55:46Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=7bd88377d482e1eae3c5329b12e33cfd664fa6a9'/>
<id>urn:sha1:7bd88377d482e1eae3c5329b12e33cfd664fa6a9</id>
<content type='text'>
return the value instead, and have path_init() do the assignment.  Broken by
"vfs: Fix absolute RCU path walk failures due to uninitialized seq number",
which was Cc-stable with 2.6.38+ as destination.  This one should go where
it went.

To avoid dummy value returned in case when root is already set (it would do
no harm, actually, since the only caller that doesn't ignore the return value
is guaranteed to have nd-&gt;root *not* set, but it's more obvious that way),
lift the check into callers.  And do the same to set_root(), to keep them
in sync.

Cc: stable@vger.kernel.org # 2.6.38+
Signed-off-by: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
</content>
</entry>
<entry>
<title>fix bogus read_seqretry() checks introduced in b37199e</title>
<updated>2014-09-14T02:14:16Z</updated>
<author>
<name>Al Viro</name>
</author>
<published>2014-09-14T01:50:45Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=f5be3e29127aec8c87f883aadadff337f8c2cfd7'/>
<id>urn:sha1:f5be3e29127aec8c87f883aadadff337f8c2cfd7</id>
<content type='text'>
read_seqretry() returns true on mismatch, not on match...

Cc: stable@vger.kernel.org # 3.15+
Signed-off-by: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
</content>
</entry>
<entry>
<title>vfs: fix bad hashing of dentries</title>
<updated>2014-09-13T18:30:10Z</updated>
<author>
<name>Linus Torvalds</name>
</author>
<published>2014-09-13T18:30:10Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=99d263d4c5b2f541dfacb5391e22e8c91ea982a6'/>
<id>urn:sha1:99d263d4c5b2f541dfacb5391e22e8c91ea982a6</id>
<content type='text'>
Josef Bacik found a performance regression between 3.2 and 3.10 and
narrowed it down to commit bfcfaa77bdf0 ("vfs: use 'unsigned long'
accesses for dcache name comparison and hashing"). He reports:

 "The test case is essentially

      for (i = 0; i &lt; 1000000; i++)
              mkdir("a$i");

  On xfs on a fio card this goes at about 20k dir/sec with 3.2, and 12k
  dir/sec with 3.10.  This is because we spend waaaaay more time in
  __d_lookup on 3.10 than in 3.2.

  The new hashing function for strings is suboptimal for &lt;
  sizeof(unsigned long) string names (and hell even &gt; sizeof(unsigned
  long) string names that I've tested).  I broke out the old hashing
  function and the new one into a userspace helper to get real numbers
  and this is what I'm getting:

      Old hash table had 1000000 entries, 0 dupes, 0 max dupes
      New hash table had 12628 entries, 987372 dupes, 900 max dupes
      We had 11400 buckets with a p50 of 30 dupes, p90 of 240 dupes, p99 of 567 dupes for the new hash

  My test does the hash, and then does the d_hash into a integer pointer
  array the same size as the dentry hash table on my system, and then
  just increments the value at the address we got to see how many
  entries we overlap with.

  As you can see the old hash function ended up with all 1 million
  entries in their own bucket, whereas the new one they are only
  distributed among ~12.5k buckets, which is why we're using so much
  more CPU in __d_lookup".

The reason for this hash regression is two-fold:

 - On 64-bit architectures the down-mixing of the original 64-bit
   word-at-a-time hash into the final 32-bit hash value is very
   simplistic and suboptimal, and just adds the two 32-bit parts
   together.

   In particular, because there is no bit shuffling and the mixing
   boundary is also a byte boundary, similar character patterns in the
   low and high word easily end up just canceling each other out.

 - the old byte-at-a-time hash mixed each byte into the final hash as it
   hashed the path component name, resulting in the low bits of the hash
   generally being a good source of hash data.  That is not true for the
   word-at-a-time case, and the hash data is distributed among all the
   bits.

The fix is the same in both cases: do a better job of mixing the bits up
and using as much of the hash data as possible.  We already have the
"hash_32|64()" functions to do that.

Reported-by: Josef Bacik &lt;jbacik@fb.com&gt;
Cc: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
Cc: Christoph Hellwig &lt;hch@infradead.org&gt;
Cc: Chris Mason &lt;clm@fb.com&gt;
Cc: linux-fsdevel@vger.kernel.org
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
</entry>
</feed>
