<feed xmlns='http://www.w3.org/2005/Atom'>
<title>kernel/linux.git/fs/nfs_common, branch v6.19.12</title>
<subtitle>Linux kernel stable tree (mirror)</subtitle>
<id>https://git.radix-linux.su/kernel/linux.git/atom?h=v6.19.12</id>
<link rel='self' href='https://git.radix-linux.su/kernel/linux.git/atom?h=v6.19.12'/>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/'/>
<updated>2026-01-02T18:43:41+00:00</updated>
<entry>
<title>NFSD: Remove NFSERR_EAGAIN</title>
<updated>2026-01-02T18:43:41+00:00</updated>
<author>
<name>Chuck Lever</name>
<email>chuck.lever@oracle.com</email>
</author>
<published>2025-12-10T00:28:49+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=c6c209ceb87f64a6ceebe61761951dcbbf4a0baa'/>
<id>urn:sha1:c6c209ceb87f64a6ceebe61761951dcbbf4a0baa</id>
<content type='text'>
I haven't found an NFSERR_EAGAIN in RFCs 1094, 1813, 7530, or 8881.
None of these RFCs have an NFS status code that match the numeric
value "11".

Based on the meaning of the EAGAIN errno, I presume the use of this
status in NFSD means NFS4ERR_DELAY. So replace the one usage of
nfserr_eagain, and remove it from NFSD's NFS status conversion
tables.

As far as I can tell, NFSERR_EAGAIN has existed since the pre-git
era, but was not actually used by any code until commit f4e44b393389
("NFSD: delay unmount source's export after inter-server copy
completed."), at which time it become possible for NFSD to return
a status code of 11 (which is not valid NFS protocol).

Fixes: f4e44b393389 ("NFSD: delay unmount source's export after inter-server copy completed.")
Cc: stable@vger.kernel.org
Reviewed-by: NeilBrown &lt;neil@brown.name&gt;
Reviewed-by: Jeff Layton &lt;jlayton@kernel.org&gt;
Signed-off-by: Chuck Lever &lt;chuck.lever@oracle.com&gt;
</content>
</entry>
<entry>
<title>NFS/localio: nfs_uuid_put() fix the wake up after unlinking the file</title>
<updated>2025-08-05T23:45:40+00:00</updated>
<author>
<name>Trond Myklebust</name>
<email>trond.myklebust@hammerspace.com</email>
</author>
<published>2025-07-15T18:29:51+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=4ec752ce6debd5a0e7e0febf6bcf780ccda6ab5e'/>
<id>urn:sha1:4ec752ce6debd5a0e7e0febf6bcf780ccda6ab5e</id>
<content type='text'>
Use store_release_wake_up() instead of wake_up_var_locked(), because the
waiter cannot retake the nfs_uuid-&gt;lock.

Acked-by: Mike Snitzer &lt;snitzer@kernel.org&gt;
Tested-by: Mike Snitzer &lt;snitzer@kernel.org&gt;
Suggested-by: NeilBrown &lt;neil@brown.name&gt;
Link: https://lore.kernel.org/all/175262948827.2234665.1891349021754495573@noble.neil.brown.name/
Fixes: 21fb44034695 ("nfs_localio: protect race between nfs_uuid_put() and nfs_close_local_fh()")
Signed-off-by: Trond Myklebust &lt;trond.myklebust@hammerspace.com&gt;
</content>
</entry>
<entry>
<title>NFS/localio: nfs_uuid_put() fix races with nfs_open/close_local_fh()</title>
<updated>2025-08-05T23:45:40+00:00</updated>
<author>
<name>Trond Myklebust</name>
<email>trond.myklebust@hammerspace.com</email>
</author>
<published>2025-07-15T19:49:00+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=fdd015de767977f21892329af5e12276eb80375f'/>
<id>urn:sha1:fdd015de767977f21892329af5e12276eb80375f</id>
<content type='text'>
In order for the wait in nfs_uuid_put() to be safe, it is necessary to
ensure that nfs_uuid_add_file() doesn't add a new entry once the
nfs_uuid-&gt;net has been NULLed out.

Also fix up the wake_up_var_locked() / wait_var_event_spinlock() to both
use the nfs_uuid address, since nfl, and &amp;nfl-&gt;uuid could be used elsewhere.

Acked-by: Mike Snitzer &lt;snitzer@kernel.org&gt;
Tested-by: Mike Snitzer &lt;snitzer@kernel.org&gt;
Link: https://lore.kernel.org/all/175262893035.2234665.1735173020338594784@noble.neil.brown.name/
Fixes: 21fb44034695 ("nfs_localio: protect race between nfs_uuid_put() and nfs_close_local_fh()")
Signed-off-by: Trond Myklebust &lt;trond.myklebust@hammerspace.com&gt;
</content>
</entry>
<entry>
<title>NFS/localio: nfs_close_local_fh() fix check for file closed</title>
<updated>2025-08-05T23:45:39+00:00</updated>
<author>
<name>Trond Myklebust</name>
<email>trond.myklebust@hammerspace.com</email>
</author>
<published>2025-07-15T19:43:41+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=e144d53cf21fb9d02626c669533788c6bdc61ce3'/>
<id>urn:sha1:e144d53cf21fb9d02626c669533788c6bdc61ce3</id>
<content type='text'>
If the struct nfs_file_localio is closed, its list entry will be empty,
but the nfs_uuid-&gt;files list might still contain other entries.

Acked-by: Mike Snitzer &lt;snitzer@kernel.org&gt;
Tested-by: Mike Snitzer &lt;snitzer@kernel.org&gt;
Reviewed-by: NeilBrown &lt;neil@brown.name&gt;
Fixes: 21fb44034695 ("nfs_localio: protect race between nfs_uuid_put() and nfs_close_local_fh()")
Signed-off-by: Trond Myklebust &lt;trond.myklebust@hammerspace.com&gt;
</content>
</entry>
<entry>
<title>nfs_localio: change nfsd_file_put_local() to take a pointer to __rcu pointer</title>
<updated>2025-05-28T21:17:14+00:00</updated>
<author>
<name>NeilBrown</name>
<email>neil@brown.name</email>
</author>
<published>2025-05-09T00:46:43+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=c25a89770d1f216dcedfc2d25d56b604f62ce0bd'/>
<id>urn:sha1:c25a89770d1f216dcedfc2d25d56b604f62ce0bd</id>
<content type='text'>
Instead of calling xchg() and unrcu_pointer() before
nfsd_file_put_local(), we now pass pointer to the __rcu pointer and call
xchg() and unrcu_pointer() inside that function.

Where unrcu_pointer() is currently called the internals of "struct
nfsd_file" are not known and that causes older compilers such as gcc-8
to complain.

In some cases we have a __kernel (aka normal) pointer not an __rcu
pointer so we need to cast it to __rcu first.  This is strictly a
weakening so no information is lost.  Somewhat surprisingly, this cast
is accepted by gcc-8.

This has the pleasing result that the cmpxchg() which sets ro_file and
rw_file, and also the xchg() which clears them, are both now in the nfsd
code.

Reported-by: Pali Rohár &lt;pali@kernel.org&gt;
Reported-by: Vincent Mailhol &lt;mailhol.vincent@wanadoo.fr&gt;
Fixes: 86e00412254a ("nfs: cache all open LOCALIO nfsd_file(s) in client")
Signed-off-by: NeilBrown &lt;neil@brown.name&gt;
Signed-off-by: Anna Schumaker &lt;anna.schumaker@oracle.com&gt;
</content>
</entry>
<entry>
<title>nfs_localio: protect race between nfs_uuid_put() and nfs_close_local_fh()</title>
<updated>2025-05-28T21:17:14+00:00</updated>
<author>
<name>NeilBrown</name>
<email>neil@brown.name</email>
</author>
<published>2025-05-09T00:46:42+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=21fb44034695185f1dcbcb37354c842cabfe83c1'/>
<id>urn:sha1:21fb44034695185f1dcbcb37354c842cabfe83c1</id>
<content type='text'>
nfs_uuid_put() and nfs_close_local_fh() can race if a "struct
nfs_file_localio" is released at the same time that nfsd calls
nfs_localio_invalidate_clients().

It is important that neither of these functions completes after the
other has started looking at a given nfs_file_localio and before it
finishes.

If nfs_uuid_put() exits while nfs_close_local_fh() is closing ro_file
and rw_file it could return to __nfd_file_cache_purge() while some files
are still referenced so the purge may not succeed.

If nfs_close_local_fh() exits while nfsd_uuid_put() is still closing the
files then the "struct nfs_file_localio" could be freed while
nfsd_uuid_put() is still looking at it.  This side is currently handled
by copying the pointers out of ro_file and rw_file before deleting from
the list in nfsd_uuid.  We need to preserve this while ensuring that
nfsd_uuid_put() does wait for nfs_close_local_fh().

This patch use nfl-&gt;uuid and nfl-&gt;list to provide the required
interlock.

nfs_uuid_put() removes the nfs_file_localio from the list, then drops
locks and puts the two files, then reclaims the spinlock and sets
-&gt;nfs_uuid to NULL.

nfs_close_local_fh() operates in the reverse order, setting -&gt;nfs_uuid
to NULL, then closing the files, then unlinking from the list.

If nfs_uuid_put() finds that -&gt;nfs_uuid is already NULL, it waits for
the nfs_file_localio to be removed from the list.  If
nfs_close_local_fh() find that it has already been unlinked it waits for
-&gt;nfs_uuid to become NULL.  This ensure that one of the two tries to
close the files, but they each waits for the other.

As nfs_uuid_put() is making the list empty, change from a
list_for_each_safe loop to a while that always takes the first entry.
This makes the intent more clear.
Also don't move the list to a temporary local list as this would defeat
the guarantees required for the interlock.

Fixes: 86e00412254a ("nfs: cache all open LOCALIO nfsd_file(s) in client")
Signed-off-by: NeilBrown &lt;neil@brown.name&gt;
Signed-off-by: Anna Schumaker &lt;anna.schumaker@oracle.com&gt;
</content>
</entry>
<entry>
<title>nfs_localio: duplicate nfs_close_local_fh()</title>
<updated>2025-05-28T21:17:14+00:00</updated>
<author>
<name>NeilBrown</name>
<email>neil@brown.name</email>
</author>
<published>2025-05-09T00:46:41+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=74fc55ab2a6a0c71628fcf3b9783aae7119b5199'/>
<id>urn:sha1:74fc55ab2a6a0c71628fcf3b9783aae7119b5199</id>
<content type='text'>
nfs_close_local_fh() is called from two different places for quite
different use case.

It is called from nfs_uuid_put() when the nfs_uuid is being detached -
possibly because the nfs server is not longer serving that filesystem.
In this case there will always be an nfs_uuid and so rcu_read_lock() is
not needed.

It is also called when the nfs_file_localio is no longer needed.  In
this case there may not be an active nfs_uuid.

These two can race, and handling the race properly while avoiding
excessive locking will require different handling on each side.

This patch prepares the way by opencoding nfs_close_local_fh() into
nfs_uuid_put(), then simplifying the code there as befits the context.

Fixes: 86e00412254a ("nfs: cache all open LOCALIO nfsd_file(s) in client")
Signed-off-by: NeilBrown &lt;neil@brown.name&gt;
Signed-off-by: Anna Schumaker &lt;anna.schumaker@oracle.com&gt;
</content>
</entry>
<entry>
<title>nfs_localio: simplify interface to nfsd for getting nfsd_file</title>
<updated>2025-05-28T21:17:14+00:00</updated>
<author>
<name>NeilBrown</name>
<email>neil@brown.name</email>
</author>
<published>2025-05-09T00:46:40+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=e6f7e1487ab528a6c653bd0d42812ff2942846cd'/>
<id>urn:sha1:e6f7e1487ab528a6c653bd0d42812ff2942846cd</id>
<content type='text'>
The nfsd_localio_operations structure contains nfsd_file_get() to get a
reference to an nfsd_file.  This is only used in one place, where
nfsd_open_local_fh() is also used.

This patch combines the two, calling nfsd_open_local_fh() passing a
pointer to where the nfsd_file pointer might be stored.  If there is a
pointer there an nfsd_file_get() can get a reference, that reference is
returned.  If not a new nfsd_file is acquired, stored at the pointer,
and returned.  When we store a reference we also increase the refcount
on the net, as that refcount is decrements when we clear the stored
pointer.

We now get an extra reference *before* storing the new nfsd_file at the
given location.  This avoids possible races with the nfsd_file being
freed before the final reference can be taken.

This patch moves the rcu_dereference() needed after fetching from
ro_file or rw_file into the nfsd code where the 'struct nfs_file' is
fully defined.  This avoids an error reported by older versions of gcc
such as gcc-8 which complain about rcu_dereference() use in contexts
where the structure (which will supposedly be accessed) is not fully
defined.

Reported-by: Pali Rohár &lt;pali@kernel.org&gt;
Reported-by: Vincent Mailhol &lt;mailhol.vincent@wanadoo.fr&gt;
Fixes: 86e00412254a ("nfs: cache all open LOCALIO nfsd_file(s) in client")
Signed-off-by: NeilBrown &lt;neil@brown.name&gt;
Signed-off-by: Anna Schumaker &lt;anna.schumaker@oracle.com&gt;
</content>
</entry>
<entry>
<title>nfs_localio: always hold nfsd net ref with nfsd_file ref</title>
<updated>2025-05-28T21:17:14+00:00</updated>
<author>
<name>NeilBrown</name>
<email>neil@brown.name</email>
</author>
<published>2025-05-09T00:46:39+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=77e82fb2c6c27c122e785f543ae0062f7783c886'/>
<id>urn:sha1:77e82fb2c6c27c122e785f543ae0062f7783c886</id>
<content type='text'>
Having separate nfsd_file_put and nfsd_file_put_local in struct
nfsd_localio_operations doesn't make much sense.  The difference is that
nfsd_file_put doesn't drop a reference to the nfs_net which is what
keeps nfsd from shutting down.

Currently, if nfsd tries to shutdown it will invalidate the files stored
in the list from the nfs_uuid and this will drop all references to the
nfsd net that the client holds.  But the client could still hold some
references to nfsd_files for active IO.  So nfsd might think is has
completely shut down local IO, but hasn't and has no way to wait for
those active IO requests to complete.

So this patch changes nfsd_file_get to nfsd_file_get_local and has it
increase the ref count on the nfsd net and it replaces all calls to
-&gt;nfsd_put_file to -&gt;nfsd_put_file_local.

It also changes -&gt;nfsd_open_local_fh to return with the refcount on the
net elevated precisely when a valid nfsd_file is returned.

This means that whenever the client holds a valid nfsd_file, there will
be an associated count on the nfsd net, and so the count can only reach
zero when all nfsd_files have been returned.

nfs_local_file_put() is changed to call nfs_to_nfsd_file_put_local()
instead of replacing calls to one with calls to the other because this
will help a later patch which changes nfs_to_nfsd_file_put_local() to
take an __rcu pointer while nfs_local_file_put() doesn't.

Fixes: 86e00412254a ("nfs: cache all open LOCALIO nfsd_file(s) in client")
Signed-off-by: NeilBrown &lt;neil@brown.name&gt;
Signed-off-by: Anna Schumaker &lt;anna.schumaker@oracle.com&gt;
</content>
</entry>
<entry>
<title>nfs_localio: use cmpxchg() to install new nfs_file_localio</title>
<updated>2025-05-28T21:17:14+00:00</updated>
<author>
<name>NeilBrown</name>
<email>neil@brown.name</email>
</author>
<published>2025-05-09T00:46:38+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=ed9be317330c7390df7db9e1d046698c02001bd2'/>
<id>urn:sha1:ed9be317330c7390df7db9e1d046698c02001bd2</id>
<content type='text'>
Rather than using nfs_uuid.lock to protect installing
a new ro_file or rw_file, change to use cmpxchg().
Removing the file already uses xchg() so this improves symmetry
and also makes the code a little simpler.

Also remove the optimisation of not taking the lock, and not removing
the nfs_file_localio from the linked list, when both -&gt;ro_file and
-&gt;rw_file are already NULL.  Given that -&gt;nfs_uuid was not NULL, it is
extremely unlikely that neither -&gt;ro_file or -&gt;rw_file is NULL so
this optimisation can be of little value and it complicates
understanding of the code - why can the list_del_init() be skipped?

Finally, move the assignment of NULL to -&gt;nfs_uuid until after
the last action on the nfs_file_localio (the list_del_init).  As soon as
this is NULL a racing nfs_close_local_fh() can bypass all the locking
and go on to free the nfs_file_localio, so we must be certain to be
finished with it first.

Fixes: 86e00412254a ("nfs: cache all open LOCALIO nfsd_file(s) in client")
Signed-off-by: NeilBrown &lt;neil@brown.name&gt;
Signed-off-by: Anna Schumaker &lt;anna.schumaker@oracle.com&gt;
</content>
</entry>
</feed>
