Skip to content

Commit c1f10ac

Browse files
committed
Merge tag 'nfs-for-6.9-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
Pull NFS client updates from Trond Myklebust: "Highlights include: Bugfixes: - Fix for an Oops in the NFSv4.2 listxattr handler - Correct an incorrect buffer size in listxattr - Fix for an Oops in the pNFS flexfiles layout - Fix a refcount leak in NFS O_DIRECT writes - Fix missing locking in NFS O_DIRECT - Avoid an infinite loop in pnfs_update_layout - Fix an overflow in the RPC waitqueue queue length counter - Ensure that pNFS I/O is also protected by TLS when xprtsec is specified by the mount options - Fix a leaked folio lock in the netfs read code - Fix a potential deadlock in fscache - Allow setting the fscache uniquifier in NFSv4 - Fix an off by one in root_nfs_cat() - Fix another off by one in rpc_sockaddr2uaddr() - nfs4_do_open() can incorrectly trigger state recovery - Various fixes for connection shutdown Features and cleanups: - Ensure that containers only see their own RPC and NFS stats - Enable nconnect for RDMA - Remove dead code from nfs_writepage_locked() - Various tracepoint additions to track EXCHANGE_ID, GETDEVICEINFO, and mount options" * tag 'nfs-for-6.9-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: (29 commits) nfs: fix panic when nfs4_ff_layout_prepare_ds() fails NFS: trace the uniquifier of fscache NFS: Read unlock folio on nfs_page_create_from_folio() error NFS: remove unused variable nfs_rpcstat nfs: fix UAF in direct writes nfs: properly protect nfs_direct_req fields NFS: enable nconnect for RDMA NFSv4: nfs4_do_open() is incorrectly triggering state recovery NFS: avoid infinite loop in pnfs_update_layout. NFS: remove sync_mode test from nfs_writepage_locked() NFSv4.1/pnfs: fix NFS with TLS in pnfs NFS: Fix an off by one in root_nfs_cat() nfs: make the rpc_stat per net namespace nfs: expose /proc/net/sunrpc/nfs in net namespaces sunrpc: add a struct rpc_stats arg to rpc_create_args nfs: remove unused NFS_CALL macro NFSv4.1: add tracepoint to trunked nfs4_exchange_id calls NFS: Fix nfs_netfs_issue_read() xarray locking for writeback interrupt SUNRPC: increase size of rpc_wait_queue.qlen from unsigned short to unsigned int nfs: fix regression in handling of fsc= option in NFSv4 ...
2 parents 90a498f + 719fcaf commit c1f10ac

36 files changed

+258
-71
lines changed

fs/nfs/client.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,14 +73,9 @@ const struct rpc_program nfs_program = {
7373
.number = NFS_PROGRAM,
7474
.nrvers = ARRAY_SIZE(nfs_version),
7575
.version = nfs_version,
76-
.stats = &nfs_rpcstat,
7776
.pipe_dir_name = NFS_PIPE_DIRNAME,
7877
};
7978

80-
struct rpc_stat nfs_rpcstat = {
81-
.program = &nfs_program
82-
};
83-
8479
static struct nfs_subversion *find_nfs_version(unsigned int version)
8580
{
8681
struct nfs_subversion *nfs;
@@ -502,6 +497,7 @@ int nfs_create_rpc_client(struct nfs_client *clp,
502497
const struct nfs_client_initdata *cl_init,
503498
rpc_authflavor_t flavor)
504499
{
500+
struct nfs_net *nn = net_generic(clp->cl_net, nfs_net_id);
505501
struct rpc_clnt *clnt = NULL;
506502
struct rpc_create_args args = {
507503
.net = clp->cl_net,
@@ -513,6 +509,7 @@ int nfs_create_rpc_client(struct nfs_client *clp,
513509
.servername = clp->cl_hostname,
514510
.nodename = cl_init->nodename,
515511
.program = &nfs_program,
512+
.stats = &nn->rpcstats,
516513
.version = clp->rpc_ops->version,
517514
.authflavor = flavor,
518515
.cred = cl_init->cred,
@@ -1182,6 +1179,8 @@ void nfs_clients_init(struct net *net)
11821179
#endif
11831180
spin_lock_init(&nn->nfs_client_lock);
11841181
nn->boot_time = ktime_get_real();
1182+
memset(&nn->rpcstats, 0, sizeof(nn->rpcstats));
1183+
nn->rpcstats.program = &nfs_program;
11851184

11861185
nfs_netns_sysfs_setup(nn, net);
11871186
}

fs/nfs/delegation.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,6 @@ static int nfs_delegation_claim_opens(struct inode *inode,
181181
struct nfs_open_context *ctx;
182182
struct nfs4_state_owner *sp;
183183
struct nfs4_state *state;
184-
unsigned int seq;
185184
int err;
186185

187186
again:
@@ -202,12 +201,9 @@ static int nfs_delegation_claim_opens(struct inode *inode,
202201
sp = state->owner;
203202
/* Block nfs4_proc_unlck */
204203
mutex_lock(&sp->so_delegreturn_mutex);
205-
seq = raw_seqcount_begin(&sp->so_reclaim_seqcount);
206204
err = nfs4_open_delegation_recall(ctx, state, stateid);
207205
if (!err)
208206
err = nfs_delegation_claim_locks(state, stateid);
209-
if (!err && read_seqcount_retry(&sp->so_reclaim_seqcount, seq))
210-
err = -EAGAIN;
211207
mutex_unlock(&sp->so_delegreturn_mutex);
212208
put_nfs_open_context(ctx);
213209
if (err != 0)

fs/nfs/direct.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -606,13 +606,15 @@ static void nfs_direct_commit_complete(struct nfs_commit_data *data)
606606

607607
trace_nfs_direct_commit_complete(dreq);
608608

609+
spin_lock(&dreq->lock);
609610
if (status < 0) {
610611
/* Errors in commit are fatal */
611612
dreq->error = status;
612613
dreq->flags = NFS_ODIRECT_DONE;
613614
} else {
614615
status = dreq->error;
615616
}
617+
spin_unlock(&dreq->lock);
616618

617619
nfs_init_cinfo_from_dreq(&cinfo, dreq);
618620

@@ -625,7 +627,10 @@ static void nfs_direct_commit_complete(struct nfs_commit_data *data)
625627
spin_unlock(&dreq->lock);
626628
nfs_release_request(req);
627629
} else if (!nfs_write_match_verf(verf, req)) {
628-
dreq->flags = NFS_ODIRECT_RESCHED_WRITES;
630+
spin_lock(&dreq->lock);
631+
if (dreq->flags == 0)
632+
dreq->flags = NFS_ODIRECT_RESCHED_WRITES;
633+
spin_unlock(&dreq->lock);
629634
/*
630635
* Despite the reboot, the write was successful,
631636
* so reset wb_nio.
@@ -667,10 +672,17 @@ static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq)
667672
LIST_HEAD(mds_list);
668673

669674
nfs_init_cinfo_from_dreq(&cinfo, dreq);
675+
nfs_commit_begin(cinfo.mds);
670676
nfs_scan_commit(dreq->inode, &mds_list, &cinfo);
671677
res = nfs_generic_commit_list(dreq->inode, &mds_list, 0, &cinfo);
672-
if (res < 0) /* res == -ENOMEM */
673-
nfs_direct_write_reschedule(dreq);
678+
if (res < 0) { /* res == -ENOMEM */
679+
spin_lock(&dreq->lock);
680+
if (dreq->flags == 0)
681+
dreq->flags = NFS_ODIRECT_RESCHED_WRITES;
682+
spin_unlock(&dreq->lock);
683+
}
684+
if (nfs_commit_end(cinfo.mds))
685+
nfs_direct_write_complete(dreq);
674686
}
675687

676688
static void nfs_direct_write_clear_reqs(struct nfs_direct_req *dreq)

fs/nfs/filelayout/filelayoutdev.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "../internal.h"
3636
#include "../nfs4session.h"
3737
#include "filelayout.h"
38+
#include "../nfs4trace.h"
3839

3940
#define NFSDBG_FACILITY NFSDBG_PNFS_LD
4041

@@ -172,6 +173,7 @@ nfs4_fl_alloc_deviceid_node(struct nfs_server *server, struct pnfs_device *pdev,
172173
dsaddr->ds_list[i] = nfs4_pnfs_ds_add(&dsaddrs, gfp_flags);
173174
if (!dsaddr->ds_list[i])
174175
goto out_err_drain_dsaddrs;
176+
trace_fl_getdevinfo(server, &pdev->dev_id, dsaddr->ds_list[i]->ds_remotestr);
175177

176178
/* If DS was already in cache, free ds addrs */
177179
while (!list_empty(&dsaddrs)) {

fs/nfs/flexfilelayout/flexfilelayout.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2016,7 +2016,7 @@ static void ff_layout_cancel_io(struct pnfs_layout_segment *lseg)
20162016
for (idx = 0; idx < flseg->mirror_array_cnt; idx++) {
20172017
mirror = flseg->mirror_array[idx];
20182018
mirror_ds = mirror->mirror_ds;
2019-
if (!mirror_ds)
2019+
if (IS_ERR_OR_NULL(mirror_ds))
20202020
continue;
20212021
ds = mirror->mirror_ds->ds;
20222022
if (!ds)

fs/nfs/fs_context.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,7 @@ static int nfs_fs_context_parse_param(struct fs_context *fc,
652652
ctx->fscache_uniq = NULL;
653653
break;
654654
case Opt_fscache:
655+
trace_nfs_mount_assign(param->key, param->string);
655656
ctx->options |= NFS_OPTION_FSCACHE;
656657
kfree(ctx->fscache_uniq);
657658
ctx->fscache_uniq = param->string;

fs/nfs/fscache.c

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -301,11 +301,11 @@ static void nfs_netfs_issue_read(struct netfs_io_subrequest *sreq)
301301
struct inode *inode = sreq->rreq->inode;
302302
struct nfs_open_context *ctx = sreq->rreq->netfs_priv;
303303
struct page *page;
304+
unsigned long idx;
304305
int err;
305306
pgoff_t start = (sreq->start + sreq->transferred) >> PAGE_SHIFT;
306307
pgoff_t last = ((sreq->start + sreq->len -
307308
sreq->transferred - 1) >> PAGE_SHIFT);
308-
XA_STATE(xas, &sreq->rreq->mapping->i_pages, start);
309309

310310
nfs_pageio_init_read(&pgio, inode, false,
311311
&nfs_async_read_completion_ops);
@@ -316,19 +316,14 @@ static void nfs_netfs_issue_read(struct netfs_io_subrequest *sreq)
316316

317317
pgio.pg_netfs = netfs; /* used in completion */
318318

319-
xas_lock(&xas);
320-
xas_for_each(&xas, page, last) {
319+
xa_for_each_range(&sreq->rreq->mapping->i_pages, idx, page, start, last) {
321320
/* nfs_read_add_folio() may schedule() due to pNFS layout and other RPCs */
322-
xas_pause(&xas);
323-
xas_unlock(&xas);
324321
err = nfs_read_add_folio(&pgio, ctx, page_folio(page));
325322
if (err < 0) {
326323
netfs->error = err;
327324
goto out;
328325
}
329-
xas_lock(&xas);
330326
}
331-
xas_unlock(&xas);
332327
out:
333328
nfs_pageio_complete_read(&pgio);
334329
nfs_netfs_put(netfs);

fs/nfs/inode.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2426,12 +2426,16 @@ EXPORT_SYMBOL_GPL(nfs_net_id);
24262426

24272427
static int nfs_net_init(struct net *net)
24282428
{
2429+
struct nfs_net *nn = net_generic(net, nfs_net_id);
2430+
24292431
nfs_clients_init(net);
2432+
rpc_proc_register(net, &nn->rpcstats);
24302433
return nfs_fs_proc_net_init(net);
24312434
}
24322435

24332436
static void nfs_net_exit(struct net *net)
24342437
{
2438+
rpc_proc_unregister(net, "nfs");
24352439
nfs_fs_proc_net_exit(net);
24362440
nfs_clients_exit(net);
24372441
}
@@ -2486,15 +2490,12 @@ static int __init init_nfs_fs(void)
24862490
if (err)
24872491
goto out1;
24882492

2489-
rpc_proc_register(&init_net, &nfs_rpcstat);
2490-
24912493
err = register_nfs_fs();
24922494
if (err)
24932495
goto out0;
24942496

24952497
return 0;
24962498
out0:
2497-
rpc_proc_unregister(&init_net, "nfs");
24982499
nfs_destroy_directcache();
24992500
out1:
25002501
nfs_destroy_writepagecache();
@@ -2524,7 +2525,6 @@ static void __exit exit_nfs_fs(void)
25242525
nfs_destroy_inodecache();
25252526
nfs_destroy_nfspagecache();
25262527
unregister_pernet_subsys(&nfs_net_ops);
2527-
rpc_proc_unregister(&init_net, "nfs");
25282528
unregister_nfs_fs();
25292529
nfs_fs_proc_exit();
25302530
nfsiod_stop();

fs/nfs/internal.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -449,8 +449,6 @@ int nfs_try_get_tree(struct fs_context *);
449449
int nfs_get_tree_common(struct fs_context *);
450450
void nfs_kill_super(struct super_block *);
451451

452-
extern struct rpc_stat nfs_rpcstat;
453-
454452
extern int __init register_nfs_fs(void);
455453
extern void __exit unregister_nfs_fs(void);
456454
extern bool nfs_sb_active(struct super_block *sb);

fs/nfs/netns.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <linux/nfs4.h>
1010
#include <net/net_namespace.h>
1111
#include <net/netns/generic.h>
12+
#include <linux/sunrpc/stats.h>
1213

1314
struct bl_dev_msg {
1415
int32_t status;
@@ -34,6 +35,7 @@ struct nfs_net {
3435
struct nfs_netns_client *nfs_client;
3536
spinlock_t nfs_client_lock;
3637
ktime_t boot_time;
38+
struct rpc_stat rpcstats;
3739
#ifdef CONFIG_PROC_FS
3840
struct proc_dir_entry *proc_nfsfs;
3941
#endif

0 commit comments

Comments
 (0)