<feed xmlns='http://www.w3.org/2005/Atom'>
<title>linux.git/fs/d_path.c, branch v7.3-rc2</title>
<subtitle>Linux kernel source tree</subtitle>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/'/>
<entry>
<title>fs: add failfs</title>
<updated>2026-07-27T15:17:59+00:00</updated>
<author>
<name>Christian Brauner</name>
<email>brauner@kernel.org</email>
</author>
<published>2026-07-24T13:41:17+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=fa0d6d945e5ce96cff14b114eec7527f13d7f23a'/>
<id>fa0d6d945e5ce96cff14b114eec7527f13d7f23a</id>
<content type='text'>
nullfs provides a permanently empty and immutable directory. Lookups
fail with ENOENT. The directory can be opened, read, stat, mounted upon.
It behaves like nothing is there.

Add its counterpart failfs where the semantics are not "there is
nothing here" but "nothing is supported here". Every operation that
reaches the filesystem fails with EOPNOTSUPP. Even statfs()/fstatfs()
fail so the filesystem cannot be discovered through an fd to it.

EOPNOTSUPP rather than a permission errno keeps that coherent. There
is no permission model in which anything could ever be allowed and
EACCES or EPERM would merely suggest that different credentials might
succeed while EIO would suggest corruption. It also makes hitting the
failfs boundary mostly quite dinstinguishable. A task anchoring its
lookups at real directory file descriptors may be able to tell a failfs
refusal from an ordinary permission failure. I wouldn't go so far as
guaranteeing that but it should mostly work.

No path lookup can open the root, not even with O_PATH. It is never
reached by a lookup in a parent directory. The only way to a path-walk
terminal at the root is a jump through a /proc/&lt;pid&gt;/{root,cwd} magic
link or by mountpoint traversal. The root also refuses
-&gt;d_weak_revalidate() which the VFS calls for jumped terminals. That
covers the jump-based references too: an O_PATH open is refused,
name_to_handle_at() cannot encode it into a file handle, and following a
magic link into it fails. A plain readlink() of such a link still works
and shows "failfs:/".

There is a single instance of failfs mounted during early boot via
kern_mount() making it logically distinct from every mount namespace.

Since the mount is a member of no mount namespace mounting onto it
fails. So nothing can ever be mounted on top of it. It cannot be cloned
via OPEN_TREE_CLONE and it does not show up in statmount()/listmount()
or /proc/&lt;pid&gt;/mountinfo. The filesystem is not registered so it is
not visible in /proc/filesystems and cannot be mounted from userspace.

This lets tasks shed their filesystem state completely. A process with
its root directory or working directory in failfs must anchor every path
lookup at an explicit file descriptor or is doomed to fail any lookup.
Absolute paths, absolute symlinks, and AT_FDCWD-relative lookups
simply fail. Followup patches will expose it via a new FD_FAILFS_ROOT
file descriptor sentinel understood by fchdir() and the new fchroot()
system call.

Link: https://patch.msgid.link/20260724-work-failfs-v2-1-485dabbae185@kernel.org
Signed-off-by: Christian Brauner (Amutable) &lt;brauner@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
nullfs provides a permanently empty and immutable directory. Lookups
fail with ENOENT. The directory can be opened, read, stat, mounted upon.
It behaves like nothing is there.

Add its counterpart failfs where the semantics are not "there is
nothing here" but "nothing is supported here". Every operation that
reaches the filesystem fails with EOPNOTSUPP. Even statfs()/fstatfs()
fail so the filesystem cannot be discovered through an fd to it.

EOPNOTSUPP rather than a permission errno keeps that coherent. There
is no permission model in which anything could ever be allowed and
EACCES or EPERM would merely suggest that different credentials might
succeed while EIO would suggest corruption. It also makes hitting the
failfs boundary mostly quite dinstinguishable. A task anchoring its
lookups at real directory file descriptors may be able to tell a failfs
refusal from an ordinary permission failure. I wouldn't go so far as
guaranteeing that but it should mostly work.

No path lookup can open the root, not even with O_PATH. It is never
reached by a lookup in a parent directory. The only way to a path-walk
terminal at the root is a jump through a /proc/&lt;pid&gt;/{root,cwd} magic
link or by mountpoint traversal. The root also refuses
-&gt;d_weak_revalidate() which the VFS calls for jumped terminals. That
covers the jump-based references too: an O_PATH open is refused,
name_to_handle_at() cannot encode it into a file handle, and following a
magic link into it fails. A plain readlink() of such a link still works
and shows "failfs:/".

There is a single instance of failfs mounted during early boot via
kern_mount() making it logically distinct from every mount namespace.

Since the mount is a member of no mount namespace mounting onto it
fails. So nothing can ever be mounted on top of it. It cannot be cloned
via OPEN_TREE_CLONE and it does not show up in statmount()/listmount()
or /proc/&lt;pid&gt;/mountinfo. The filesystem is not registered so it is
not visible in /proc/filesystems and cannot be mounted from userspace.

This lets tasks shed their filesystem state completely. A process with
its root directory or working directory in failfs must anchor every path
lookup at an explicit file descriptor or is doomed to fail any lookup.
Absolute paths, absolute symlinks, and AT_FDCWD-relative lookups
simply fail. Followup patches will expose it via a new FD_FAILFS_ROOT
file descriptor sentinel understood by fchdir() and the new fchroot()
system call.

Link: https://patch.msgid.link/20260724-work-failfs-v2-1-485dabbae185@kernel.org
Signed-off-by: Christian Brauner (Amutable) &lt;brauner@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>dcache: permit dynamic_dname()s up to NAME_MAX</title>
<updated>2026-04-07T10:32:22+00:00</updated>
<author>
<name>Aleksa Sarai</name>
<email>aleksa@amutable.com</email>
</author>
<published>2026-03-31T14:46:21+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=97b67e64affb0e709eeecc50f6a9222fc20bd14b'/>
<id>97b67e64affb0e709eeecc50f6a9222fc20bd14b</id>
<content type='text'>
dynamic_dname() has had an implicit limit of 64 characters since it was
introduced in commit c23fbb6bcb3e ("VFS: delay the dentry name
generation on sockets and pipes"), however it seems that this was a
fairly arbitrary number (suspiciously it was double the previously
hardcoded buffer size).

NAME_MAX seems like a more reasonable and consistent limit for d_name
lengths. While we're at it, we can also remove the unnecessary
stack-allocated array and just memmove() the formatted string to the end
of the buffer.

It should also be noted that at least one driver (in particular,
liveupdate's usage of anon_inode for session files) already exceeded
this limit without noticing that readlink(/proc/self/fd/$n) always
returns -ENAMETOOLONG, so this fixes those drivers as well.

Fixes: 0153094d03df ("liveupdate: luo_session: add sessions support")
Fixes: c23fbb6bcb3e ("VFS: delay the dentry name generation on sockets and pipes")
Signed-off-by: Aleksa Sarai &lt;aleksa@amutable.com&gt;
Link: https://patch.msgid.link/20260401-dynamic-dname-name_max-v1-1-8ca20ab2642e@amutable.com
Tested-by: Luca Boccassi &lt;luca.boccassi@gmail.com&gt;
Signed-off-by: Christian Brauner &lt;brauner@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
dynamic_dname() has had an implicit limit of 64 characters since it was
introduced in commit c23fbb6bcb3e ("VFS: delay the dentry name
generation on sockets and pipes"), however it seems that this was a
fairly arbitrary number (suspiciously it was double the previously
hardcoded buffer size).

NAME_MAX seems like a more reasonable and consistent limit for d_name
lengths. While we're at it, we can also remove the unnecessary
stack-allocated array and just memmove() the formatted string to the end
of the buffer.

It should also be noted that at least one driver (in particular,
liveupdate's usage of anon_inode for session files) already exceeded
this limit without noticing that readlink(/proc/self/fd/$n) always
returns -ENAMETOOLONG, so this fixes those drivers as well.

Fixes: 0153094d03df ("liveupdate: luo_session: add sessions support")
Fixes: c23fbb6bcb3e ("VFS: delay the dentry name generation on sockets and pipes")
Signed-off-by: Aleksa Sarai &lt;aleksa@amutable.com&gt;
Link: https://patch.msgid.link/20260401-dynamic-dname-name_max-v1-1-8ca20ab2642e@amutable.com
Tested-by: Luca Boccassi &lt;luca.boccassi@gmail.com&gt;
Signed-off-by: Christian Brauner &lt;brauner@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>fold fs_struct-&gt;{lock,seq} into a seqlock</title>
<updated>2025-07-08T08:25:19+00:00</updated>
<author>
<name>Al Viro</name>
<email>viro@zeniv.linux.org.uk</email>
</author>
<published>2025-07-02T05:34:37+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=a683a5b2ba23598ad343e5ec10a4ef4077497fc9'/>
<id>a683a5b2ba23598ad343e5ec10a4ef4077497fc9</id>
<content type='text'>
	The combination of spinlock_t lock and seqcount_spinlock_t seq
in struct fs_struct is an open-coded seqlock_t (see linux/seqlock_types.h).
	Combine and switch to equivalent seqlock_t primitives.  AFAICS,
that does end up with the same sequence of underlying operations in all
cases.
	While we are at it, get_fs_pwd() is open-coded verbatim in
get_path_from_fd(); rather than applying conversion to it, replace with
the call of get_fs_pwd() there.  Not worth splitting the commit for that,
IMO...

	A bit of historical background - conversion of seqlock_t to
use of seqcount_spinlock_t happened several months after the same
had been done to struct fs_struct; switching fs_struct to seqlock_t
could've been done immediately after that, but it looks like nobody
had gotten around to that until now.

Signed-off-by: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
Link: https://lore.kernel.org/20250702053437.GC1880847@ZenIV
Acked-by: Ahmed S. Darwish &lt;darwi@linutronix.de&gt;
Acked-by: Peter Zijlstra (Intel) &lt;peterz@infradead.org&gt;
Reviewed-by: Christian Brauner &lt;brauner@kernel.org&gt;
Signed-off-by: Christian Brauner &lt;brauner@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
	The combination of spinlock_t lock and seqcount_spinlock_t seq
in struct fs_struct is an open-coded seqlock_t (see linux/seqlock_types.h).
	Combine and switch to equivalent seqlock_t primitives.  AFAICS,
that does end up with the same sequence of underlying operations in all
cases.
	While we are at it, get_fs_pwd() is open-coded verbatim in
get_path_from_fd(); rather than applying conversion to it, replace with
the call of get_fs_pwd() there.  Not worth splitting the commit for that,
IMO...

	A bit of historical background - conversion of seqlock_t to
use of seqcount_spinlock_t happened several months after the same
had been done to struct fs_struct; switching fs_struct to seqlock_t
could've been done immediately after that, but it looks like nobody
had gotten around to that until now.

Signed-off-by: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
Link: https://lore.kernel.org/20250702053437.GC1880847@ZenIV
Acked-by: Ahmed S. Darwish &lt;darwi@linutronix.de&gt;
Acked-by: Peter Zijlstra (Intel) &lt;peterz@infradead.org&gt;
Reviewed-by: Christian Brauner &lt;brauner@kernel.org&gt;
Signed-off-by: Christian Brauner &lt;brauner@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>fs: d_path: include internal.h</title>
<updated>2023-05-17T07:16:59+00:00</updated>
<author>
<name>Arnd Bergmann</name>
<email>arnd@arndb.de</email>
</author>
<published>2023-05-16T19:54:38+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=df67cb4c58fbb80399a99d47a554a67829f90dda'/>
<id>df67cb4c58fbb80399a99d47a554a67829f90dda</id>
<content type='text'>
make W=1 warns about a missing prototype that is defined but
not visible at point where simple_dname() is defined:

fs/d_path.c:317:7: error: no previous prototype for 'simple_dname' [-Werror=missing-prototypes]

Signed-off-by: Arnd Bergmann &lt;arnd@arndb.de&gt;
Message-Id: &lt;20230516195444.551461-1-arnd@kernel.org&gt;
Signed-off-by: Christian Brauner &lt;brauner@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
make W=1 warns about a missing prototype that is defined but
not visible at point where simple_dname() is defined:

fs/d_path.c:317:7: error: no previous prototype for 'simple_dname' [-Werror=missing-prototypes]

Signed-off-by: Arnd Bergmann &lt;arnd@arndb.de&gt;
Message-Id: &lt;20230516195444.551461-1-arnd@kernel.org&gt;
Signed-off-by: Christian Brauner &lt;brauner@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>d_path.c: typo fix...</title>
<updated>2022-08-20T15:34:33+00:00</updated>
<author>
<name>Al Viro</name>
<email>viro@zeniv.linux.org.uk</email>
</author>
<published>2022-01-31T02:12:26+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=c4c8451147da569a79eff5edcd2864e8ee21d7aa'/>
<id>c4c8451147da569a79eff5edcd2864e8ee21d7aa</id>
<content type='text'>
Signed-off-by: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Signed-off-by: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>dynamic_dname(): drop unused dentry argument</title>
<updated>2022-08-20T15:34:04+00:00</updated>
<author>
<name>Al Viro</name>
<email>viro@zeniv.linux.org.uk</email>
</author>
<published>2022-01-30T20:03:49+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=0f60d28828dd94779c6527440289e1c36a05115a'/>
<id>0f60d28828dd94779c6527440289e1c36a05115a</id>
<content type='text'>
Signed-off-by: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Signed-off-by: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>d_path: fix Kernel doc validator complaining</title>
<updated>2021-11-06T20:30:32+00:00</updated>
<author>
<name>Jia He</name>
<email>justin.he@arm.com</email>
</author>
<published>2021-11-05T20:35:04+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=d41b60359ffb24a39c93ea1f4bffaafd651118c3'/>
<id>d41b60359ffb24a39c93ea1f4bffaafd651118c3</id>
<content type='text'>
Kernel doc validator complains:
  Function parameter or member 'p' not described in 'prepend_name'
  Excess function parameter 'buffer' description in 'prepend_name'

Link: https://lkml.kernel.org/r/20211011005614.26189-1-justin.he@arm.com
Fixes: ad08ae586586 ("d_path: introduce struct prepend_buffer")
Signed-off-by: Jia He &lt;justin.he@arm.com&gt;
Reviewed-by: Andy Shevchenko &lt;andriy.shevchenko@linux.intel.com&gt;
Acked-by: Randy Dunlap &lt;rdunlap@infradead.org&gt;
Cc: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
Signed-off-by: Andrew Morton &lt;akpm@linux-foundation.org&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Kernel doc validator complains:
  Function parameter or member 'p' not described in 'prepend_name'
  Excess function parameter 'buffer' description in 'prepend_name'

Link: https://lkml.kernel.org/r/20211011005614.26189-1-justin.he@arm.com
Fixes: ad08ae586586 ("d_path: introduce struct prepend_buffer")
Signed-off-by: Jia He &lt;justin.he@arm.com&gt;
Reviewed-by: Andy Shevchenko &lt;andriy.shevchenko@linux.intel.com&gt;
Acked-by: Randy Dunlap &lt;rdunlap@infradead.org&gt;
Cc: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
Signed-off-by: Andrew Morton &lt;akpm@linux-foundation.org&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>d_path: make 'prepend()' fill up the buffer exactly on overflow</title>
<updated>2021-09-02T17:07:29+00:00</updated>
<author>
<name>Linus Torvalds</name>
<email>torvalds@linux-foundation.org</email>
</author>
<published>2021-07-16T21:01:12+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=b0cfcdd9b9672ea90642f33d6c0dd8516553adf2'/>
<id>b0cfcdd9b9672ea90642f33d6c0dd8516553adf2</id>
<content type='text'>
Instead of just marking the buffer as having overflowed, fill it up as
much as we can.  That will allow the overflow case to then return
whatever truncated result if it wants to.

Cc: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Instead of just marking the buffer as having overflowed, fill it up as
much as we can.  That will allow the overflow case to then return
whatever truncated result if it wants to.

Cc: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>getcwd(2): clean up error handling</title>
<updated>2021-05-19T00:15:58+00:00</updated>
<author>
<name>Al Viro</name>
<email>viro@zeniv.linux.org.uk</email>
</author>
<published>2021-05-17T00:24:00+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=e4b275531887fef7f7d8a7284bfc32f0fbbd4208'/>
<id>e4b275531887fef7f7d8a7284bfc32f0fbbd4208</id>
<content type='text'>
Signed-off-by: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Signed-off-by: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>d_path: prepend_path() is unlikely to return non-zero</title>
<updated>2021-05-19T00:15:58+00:00</updated>
<author>
<name>Al Viro</name>
<email>viro@zeniv.linux.org.uk</email>
</author>
<published>2021-05-17T00:19:06+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux.git/commit/?id=cf4febc1adc8e5cd11ca3386e1e3ea356e0792f0'/>
<id>cf4febc1adc8e5cd11ca3386e1e3ea356e0792f0</id>
<content type='text'>
Signed-off-by: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Signed-off-by: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
</pre>
</div>
</content>
</entry>
</feed>
