Skip to content

Commit 4a48922

Browse files
Mike SnitzerAnna Schumaker
authored andcommitted
nfs: probe for LOCALIO when v3 client reconnects to server
Re-enabling NFSv3 LOCALIO is made more complex (than NFSv4) because v3 is stateless. As such, the hueristic used to identify a LOCALIO probe point is more adhoc by nature: if/when NFSv3 client IO begins to complete again in terms of normal RPC-based NFSv3 server IO, attempt nfs_local_probe_async(). Care is taken to throttle the frequency of nfs_local_probe_async(), otherwise there could be a flood of repeat calls to nfs_local_probe_async(). The throttle is admin controlled using a new module parameter for nfsv3, e.g.: echo 512 > /sys/module/nfsv3/parameters/nfs3_localio_probe_throttle Probe for NFSv3 LOCALIO every N IO requests (512 in this case). Must be power-of-2, defaults to 0 (probing disabled). On systems that expect to use LOCALIO with NFSv3 the admin should configure the 'nfs3_localio_probe_throttle' module parameter. This commit backfills module parameter documentation in localio.rst Signed-off-by: Mike Snitzer <[email protected]> Reviewed-by: Jeff Layton <[email protected]> Signed-off-by: Anna Schumaker <[email protected]>
1 parent 76d4cb6 commit 4a48922

File tree

4 files changed

+65
-5
lines changed

4 files changed

+65
-5
lines changed

Documentation/filesystems/nfs/localio.rst

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ align their IO).
291291
Security
292292
========
293293

294-
Localio is only supported when UNIX-style authentication (AUTH_UNIX, aka
294+
LOCALIO is only supported when UNIX-style authentication (AUTH_UNIX, aka
295295
AUTH_SYS) is used.
296296

297297
Care is taken to ensure the same NFS security mechanisms are used
@@ -306,6 +306,24 @@ client is afforded this same level of access (albeit in terms of the NFS
306306
protocol via SUNRPC). No other namespaces (user, mount, etc) have been
307307
altered or purposely extended from the server to the client.
308308

309+
Module Parameters
310+
=================
311+
312+
/sys/module/nfs/parameters/localio_enabled (bool)
313+
controls if LOCALIO is enabled, defaults to Y. If client and server are
314+
local but 'localio_enabled' is set to N then LOCALIO will not be used.
315+
316+
/sys/module/nfs/parameters/localio_O_DIRECT_semantics (bool)
317+
controls if O_DIRECT extends down to the underlying filesystem, defaults
318+
to N. Application IO must be logical blocksize aligned, otherwise
319+
O_DIRECT will fail.
320+
321+
/sys/module/nfsv3/parameters/nfs3_localio_probe_throttle (uint)
322+
controls if NFSv3 read and write IOs will trigger (re)enabling of
323+
LOCALIO every N (nfs3_localio_probe_throttle) IOs, defaults to 0
324+
(disabled). Must be power-of-2, admin keeps all the pieces if they
325+
misconfigure (too low a value or non-power-of-2).
326+
309327
Testing
310328
=======
311329

fs/nfs/nfs3proc.c

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -844,6 +844,41 @@ nfs3_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
844844
return status;
845845
}
846846

847+
#if IS_ENABLED(CONFIG_NFS_LOCALIO)
848+
849+
static unsigned nfs3_localio_probe_throttle __read_mostly = 0;
850+
module_param(nfs3_localio_probe_throttle, uint, 0644);
851+
MODULE_PARM_DESC(nfs3_localio_probe_throttle,
852+
"Probe for NFSv3 LOCALIO every N IO requests. Must be power-of-2, defaults to 0 (probing disabled).");
853+
854+
static void nfs3_localio_probe(struct nfs_server *server)
855+
{
856+
struct nfs_client *clp = server->nfs_client;
857+
858+
/* Throttled to reduce nfs_local_probe_async() frequency */
859+
if (!nfs3_localio_probe_throttle || nfs_server_is_local(clp))
860+
return;
861+
862+
/*
863+
* Try (re)enabling LOCALIO if isn't enabled -- admin deems
864+
* it worthwhile to periodically check if LOCALIO possible by
865+
* setting the 'nfs3_localio_probe_throttle' module parameter.
866+
*
867+
* This is useful if LOCALIO was previously enabled, but was
868+
* disabled due to server restart, and IO has successfully
869+
* completed in terms of normal RPC.
870+
*/
871+
if ((clp->cl_uuid.nfs3_localio_probe_count++ &
872+
(nfs3_localio_probe_throttle - 1)) == 0) {
873+
if (!nfs_server_is_local(clp))
874+
nfs_local_probe_async(clp);
875+
}
876+
}
877+
878+
#else
879+
static void nfs3_localio_probe(struct nfs_server *server) {}
880+
#endif
881+
847882
static int nfs3_read_done(struct rpc_task *task, struct nfs_pgio_header *hdr)
848883
{
849884
struct inode *inode = hdr->inode;
@@ -855,8 +890,11 @@ static int nfs3_read_done(struct rpc_task *task, struct nfs_pgio_header *hdr)
855890
if (nfs3_async_handle_jukebox(task, inode))
856891
return -EAGAIN;
857892

858-
if (task->tk_status >= 0 && !server->read_hdrsize)
859-
cmpxchg(&server->read_hdrsize, 0, hdr->res.replen);
893+
if (task->tk_status >= 0) {
894+
if (!server->read_hdrsize)
895+
cmpxchg(&server->read_hdrsize, 0, hdr->res.replen);
896+
nfs3_localio_probe(server);
897+
}
860898

861899
nfs_invalidate_atime(inode);
862900
nfs_refresh_inode(inode, &hdr->fattr);
@@ -886,8 +924,10 @@ static int nfs3_write_done(struct rpc_task *task, struct nfs_pgio_header *hdr)
886924

887925
if (nfs3_async_handle_jukebox(task, inode))
888926
return -EAGAIN;
889-
if (task->tk_status >= 0)
927+
if (task->tk_status >= 0) {
890928
nfs_writeback_update_inode(hdr);
929+
nfs3_localio_probe(NFS_SERVER(inode));
930+
}
891931
return 0;
892932
}
893933

fs/nfs_common/nfslocalio.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ void nfs_uuid_init(nfs_uuid_t *nfs_uuid)
4343
INIT_LIST_HEAD(&nfs_uuid->list);
4444
INIT_LIST_HEAD(&nfs_uuid->files);
4545
spin_lock_init(&nfs_uuid->lock);
46+
nfs_uuid->nfs3_localio_probe_count = 0;
4647
}
4748
EXPORT_SYMBOL_GPL(nfs_uuid_init);
4849

include/linux/nfslocalio.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ struct nfs_file_localio;
2727
*/
2828
typedef struct {
2929
uuid_t uuid;
30-
/* sadly this struct is just over a cacheline, avoid bouncing */
30+
unsigned nfs3_localio_probe_count;
31+
/* this struct is over a cacheline, avoid bouncing */
3132
spinlock_t ____cacheline_aligned lock;
3233
struct list_head list;
3334
spinlock_t *list_lock; /* nn->local_clients_lock */

0 commit comments

Comments
 (0)