<feed xmlns='http://www.w3.org/2005/Atom'>
<title>kernel.git/fs/nfsd/filecache.c, branch linux-6.15.y</title>
<subtitle>Hosts the 0x221E linux distro kernel.
</subtitle>
<id>https://git.0xinfinity.dev/distro/kernel.git/atom?h=linux-6.15.y</id>
<link rel='self' href='https://git.0xinfinity.dev/distro/kernel.git/atom?h=linux-6.15.y'/>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/'/>
<updated>2025-06-19T13:40:25Z</updated>
<entry>
<title>nfs_localio: change nfsd_file_put_local() to take a pointer to __rcu pointer</title>
<updated>2025-06-19T13:40:25Z</updated>
<author>
<name>NeilBrown</name>
</author>
<published>2025-05-09T00:46:43Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=3f28e08941e340ecdea818323777a909c40f824c'/>
<id>urn:sha1:3f28e08941e340ecdea818323777a909c40f824c</id>
<content type='text'>
[ Upstream commit c25a89770d1f216dcedfc2d25d56b604f62ce0bd ]

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;
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
</content>
</entry>
<entry>
<title>nfs_localio: always hold nfsd net ref with nfsd_file ref</title>
<updated>2025-06-19T13:40:24Z</updated>
<author>
<name>NeilBrown</name>
</author>
<published>2025-05-09T00:46:39Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=9afc61e93d94fc805476b8a1c885c291d97341b3'/>
<id>urn:sha1:9afc61e93d94fc805476b8a1c885c291d97341b3</id>
<content type='text'>
[ Upstream commit 77e82fb2c6c27c122e785f543ae0062f7783c886 ]

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;
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
</content>
</entry>
<entry>
<title>nfsd: filecache: drop the list_lru lock during lock gc scans</title>
<updated>2025-03-10T13:11:08Z</updated>
<author>
<name>NeilBrown</name>
</author>
<published>2025-02-18T15:39:37Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=fbfdc9fc0f66e7877a6d1a6e44c6acac46c5b811'/>
<id>urn:sha1:fbfdc9fc0f66e7877a6d1a6e44c6acac46c5b811</id>
<content type='text'>
Under a high NFSv3 load with lots of different files being accessed,
the LRU list of garbage-collectable files can become quite long.

Asking list_lru_scan_node() to scan the whole list can result in a long
period during which a spinlock is held, blocking the addition of new LRU
items.

So ask list_lru_scan_node() to scan only a few entries at a time, and
repeat until the scan is complete.

If the shrinker runs between two consecutive calls of
list_lru_scan_node() it could invalidate the "remaining" counter which
could lead to premature freeing.  So add a spinlock to avoid that.

Signed-off-by: NeilBrown &lt;neilb@suse.de&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>nfsd: filecache: don't repeatedly add/remove files on the lru list</title>
<updated>2025-03-10T13:11:07Z</updated>
<author>
<name>NeilBrown</name>
</author>
<published>2025-02-18T15:39:36Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=56221b42d71781e49dcead6ed34b0766daecf90d'/>
<id>urn:sha1:56221b42d71781e49dcead6ed34b0766daecf90d</id>
<content type='text'>
There is no need to remove a file from the lru every time we access it,
and then add it back.  It is sufficient to set the REFERENCED flag every
time we put the file.  The order in the lru of REFERENCED files is
largely irrelevant as they will all be moved to the end.

With this patch, files are added only when they are allocated (if
want_gc) and they are removed only by the list_lru_(shrink_)walk
callback or when forcibly removing a file.

This should reduce contention on the list_lru spinlock(s) and reduce
memory traffic a little.

Signed-off-by: NeilBrown &lt;neilb@suse.de&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>nfsd: filecache: introduce NFSD_FILE_RECENT</title>
<updated>2025-03-10T13:11:07Z</updated>
<author>
<name>NeilBrown</name>
</author>
<published>2025-02-18T15:39:35Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=64912122a4f86f8c7e232c5b92482b46364c40a2'/>
<id>urn:sha1:64912122a4f86f8c7e232c5b92482b46364c40a2</id>
<content type='text'>
The filecache lru is walked in 2 circumstances for 2 different reasons.

1/ When called from the shrinker we want to discard the first few
   entries on the list, ignoring any with NFSD_FILE_REFERENCED set
   because they should really be at the end of the LRU as they have been
   referenced recently.  So those ones are ROTATED.

2/ When called from the nfsd_file_gc() timer function we want to discard
   anything that hasn't been used since before the previous call, and
   mark everything else as unused at this point in time.

Using the same flag for both of these can result in some unexpected
outcomes.  If the shrinker callback clears NFSD_FILE_REFERENCED then
nfsd_file_gc() will think the file hasn't been used in a while, while
really it has.

I think it is easier to reason about the behaviour if we instead have
two flags.

 NFSD_FILE_REFERENCED means "this should be at the end of the LRU, please
     put it there when convenient"
 NFSD_FILE_RECENT means "this has been used recently - since the last
     run of nfsd_file_gc()

When either caller finds an NFSD_FILE_REFERENCED entry, that entry
should be moved to the end of the LRU and the flag cleared.  This can
safely happen at any time.  The actual order on the lru might not be
strictly least-recently-used, but that is normal for linux lrus.

The shrinker callback can ignore the "recent" flag.  If it ends up
freeing something that is "recent" that simply means that memory
pressure is sufficient to limit the acceptable cache age to less than
the nfsd_file_gc frequency.

The gc callback should primarily focus on NFSD_FILE_RECENT.  It should
free everything that doesn't have this flag set, and should clear the
flag on everything else.  When it clears the flag it is convenient to
clear the "REFERENCED" flag and move to the end of the LRU too.

With this, calls from the shrinker do not prematurely age files.  It
will focus only on freeing those that are least recently used.

Signed-off-by: NeilBrown &lt;neilb@suse.de&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>nfsd: filecache: use list_lru_walk_node() in nfsd_file_gc()</title>
<updated>2025-03-10T13:11:06Z</updated>
<author>
<name>NeilBrown</name>
</author>
<published>2025-02-18T15:39:34Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=8017afd66cbc98b838ac6d5b469e733a608a1211'/>
<id>urn:sha1:8017afd66cbc98b838ac6d5b469e733a608a1211</id>
<content type='text'>
list_lru_walk() is only useful when the aim is to remove all elements
from the list_lru.  It will repeatedly visit rotated elements of the
first per-node sublist before proceeding to subsequent sublists.

This patch changes nfsd_file_gc() to use list_lru_walk_node() and
list_lru_count_node() on each NUMA node.

Signed-off-by: NeilBrown &lt;neilb@suse.de&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>nfsd: filecache: use nfsd_file_dispose_list() in nfsd_file_close_inode_sync()</title>
<updated>2025-03-10T13:11:06Z</updated>
<author>
<name>NeilBrown</name>
</author>
<published>2025-02-18T15:39:33Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=e8e6f5cdbc2324dca40aa43242bc7b058fecf1a1'/>
<id>urn:sha1:e8e6f5cdbc2324dca40aa43242bc7b058fecf1a1</id>
<content type='text'>
nfsd_file_close_inode_sync() contains an exact copy of
nfsd_file_dispose_list().

This patch removes that copy and calls nfsd_file_dispose_list()
instead.

Reviewed-by: Jeff Layton &lt;jlayton@kernel.org&gt;
Signed-off-by: NeilBrown &lt;neilb@suse.de&gt;
Signed-off-by: Chuck Lever &lt;chuck.lever@oracle.com&gt;
</content>
</entry>
<entry>
<title>NFSD: Re-organize nfsd_file_gc_worker()</title>
<updated>2025-03-10T13:11:05Z</updated>
<author>
<name>Chuck Lever</name>
</author>
<published>2025-02-18T15:39:32Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=1601e2fde937a8abf29c9f62743d22c3eaeccb58'/>
<id>urn:sha1:1601e2fde937a8abf29c9f62743d22c3eaeccb58</id>
<content type='text'>
Dave opines:

IMO, there is no need to do this unnecessary work on every object
that is added to the LRU.  Changing the gc worker to always run
every 2s and check if it has work to do like so:

 static void
 nfsd_file_gc_worker(struct work_struct *work)
 {
-	nfsd_file_gc();
-	if (list_lru_count(&amp;nfsd_file_lru))
-		nfsd_file_schedule_laundrette();
+	if (list_lru_count(&amp;nfsd_file_lru))
+		nfsd_file_gc();
+	nfsd_file_schedule_laundrette();
 }

means that nfsd_file_gc() will be run the same way and have the same
behaviour as the current code. When the system it idle, it does a
list_lru_count() check every 2 seconds and goes back to sleep.
That's going to be pretty much unnoticable on most machines that run
NFS servers.

Suggested-by: Dave Chinner &lt;david@fromorbit.com&gt;
Signed-off-by: Chuck Lever &lt;chuck.lever@oracle.com&gt;
</content>
</entry>
<entry>
<title>nfsd: filecache: remove race handling.</title>
<updated>2025-03-10T13:11:05Z</updated>
<author>
<name>NeilBrown</name>
</author>
<published>2025-02-18T15:39:31Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=f77ce2e5708b3201244fcc61e4a22acb44fd919b'/>
<id>urn:sha1:f77ce2e5708b3201244fcc61e4a22acb44fd919b</id>
<content type='text'>
The race that this code tries to protect against is not interesting.
The code is problematic as we access the "nf" after we have given our
reference to the lru system.  While that takes 2+ seconds to free
things, it is still poor form.

The only interesting race I can find would be with
nfsd_file_close_inode_sync();
This is the only place that really doesn't want the file to stay on the
LRU when unhashed (which is the direct consequence of the race).

However for the race to happen, some other thread must own a reference
to a file and be putting it while nfsd_file_close_inode_sync() is trying
to close all files for an inode.  If this is possible, that other thread
could simply call nfsd_file_put() a little bit later and the result
would be the same: not all files are closed when
nfsd_file_close_inode_sync() completes.

If this was really a problem, we would need to wait in close_inode_sync
for the other references to be dropped.  We probably don't want to do
that.

So it is best to simply remove this code.

Reviewed-by: Jeff Layton &lt;jlayton@kernel.org&gt;
Signed-off-by: NeilBrown &lt;neilb@suse.de&gt;
Signed-off-by: Chuck Lever &lt;chuck.lever@oracle.com&gt;
</content>
</entry>
<entry>
<title>Merge tag 'nfsd-6.14-1' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux</title>
<updated>2025-02-10T21:11:24Z</updated>
<author>
<name>Linus Torvalds</name>
</author>
<published>2025-02-10T21:11:24Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=febbc555cf0fff895546ddb8ba2c9a523692fb55'/>
<id>urn:sha1:febbc555cf0fff895546ddb8ba2c9a523692fb55</id>
<content type='text'>
Pull nfsd fixes from Chuck Lever:
 "Fixes for new bugs:
   - A fix for CB_GETATTR reply decoding was not quite correct
   - Fix the NFSD connection limiting logic
   - Fix a bug in the new session table resizing logic

  Bugs that pre-date v6.14:
   - Support for courteous clients (5.19) introduced a shutdown hang
   - Fix a crash in the filecache laundrette (6.9)
   - Fix a zero-day crash in NFSD's NFSv3 ACL implementation"

* tag 'nfsd-6.14-1' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux:
  NFSD: Fix CB_GETATTR status fix
  NFSD: fix hang in nfsd4_shutdown_callback
  nfsd: fix __fh_verify for localio
  nfsd: fix uninitialised slot info when a request is retried
  nfsd: validate the nfsd_serv pointer before calling svc_wake_up
  nfsd: clear acl_access/acl_default after releasing them
</content>
</entry>
</feed>
