Skip to content

Commit 60f0560

Browse files
committed
Merge tag 'nfs-for-6.11-2' of git://git.linux-nfs.org/projects/anna/linux-nfs
Pull NFS client fixes from Anna Schumaker: - Fix rpcrdma refcounting in xa_alloc - Fix rpcrdma usage of XA_FLAGS_ALLOC - Fix requesting FATTR4_WORD2_OPEN_ARGUMENTS - Fix attribute bitmap decoder to handle a 3rd word - Add reschedule points when returning delegations to avoid soft lockups - Fix clearing layout segments in layoutreturn - Avoid unnecessary rescanning of the per-server delegation list * tag 'nfs-for-6.11-2' of git://git.linux-nfs.org/projects/anna/linux-nfs: NFS: Avoid unnecessary rescanning of the per-server delegation list NFSv4: Fix clearing of layout segments in layoutreturn NFSv4: Add missing rescheduling points in nfs_client_return_marked_delegations nfs: fix bitmap decoder to handle a 3rd word nfs: fix the fetch of FATTR4_OPEN_ARGUMENTS rpcrdma: Trace connection registration and unregistration rpcrdma: Use XA_FLAGS_ALLOC instead of XA_FLAGS_ALLOC1 rpcrdma: Device kref is over-incremented on error from xa_alloc
2 parents 66ace9a + f92214e commit 60f0560

File tree

7 files changed

+61
-21
lines changed

7 files changed

+61
-21
lines changed

fs/nfs/callback_xdr.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,9 @@ static __be32 decode_bitmap(struct xdr_stream *xdr, uint32_t *bitmap)
118118
if (likely(attrlen > 0))
119119
bitmap[0] = ntohl(*p++);
120120
if (attrlen > 1)
121-
bitmap[1] = ntohl(*p);
121+
bitmap[1] = ntohl(*p++);
122+
if (attrlen > 2)
123+
bitmap[2] = ntohl(*p);
122124
return 0;
123125
}
124126

@@ -446,7 +448,7 @@ static __be32 decode_recallany_args(struct svc_rqst *rqstp,
446448
void *argp)
447449
{
448450
struct cb_recallanyargs *args = argp;
449-
uint32_t bitmap[2];
451+
uint32_t bitmap[3];
450452
__be32 *p, status;
451453

452454
p = xdr_inline_decode(xdr, 4);

fs/nfs/delegation.c

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,9 @@ static int nfs_server_return_marked_delegations(struct nfs_server *server,
647647
prev = delegation;
648648
continue;
649649
}
650+
inode = nfs_delegation_grab_inode(delegation);
651+
if (inode == NULL)
652+
continue;
650653

651654
if (prev) {
652655
struct inode *tmp = nfs_delegation_grab_inode(prev);
@@ -657,12 +660,6 @@ static int nfs_server_return_marked_delegations(struct nfs_server *server,
657660
}
658661
}
659662

660-
inode = nfs_delegation_grab_inode(delegation);
661-
if (inode == NULL) {
662-
rcu_read_unlock();
663-
iput(to_put);
664-
goto restart;
665-
}
666663
delegation = nfs_start_delegation_return_locked(NFS_I(inode));
667664
rcu_read_unlock();
668665

@@ -1184,7 +1181,6 @@ static int nfs_server_reap_unclaimed_delegations(struct nfs_server *server,
11841181
struct inode *inode;
11851182
restart:
11861183
rcu_read_lock();
1187-
restart_locked:
11881184
list_for_each_entry_rcu(delegation, &server->delegations, super_list) {
11891185
if (test_bit(NFS_DELEGATION_INODE_FREEING,
11901186
&delegation->flags) ||
@@ -1195,7 +1191,7 @@ static int nfs_server_reap_unclaimed_delegations(struct nfs_server *server,
11951191
continue;
11961192
inode = nfs_delegation_grab_inode(delegation);
11971193
if (inode == NULL)
1198-
goto restart_locked;
1194+
continue;
11991195
delegation = nfs_start_delegation_return_locked(NFS_I(inode));
12001196
rcu_read_unlock();
12011197
if (delegation != NULL) {
@@ -1318,7 +1314,6 @@ static int nfs_server_reap_expired_delegations(struct nfs_server *server,
13181314

13191315
restart:
13201316
rcu_read_lock();
1321-
restart_locked:
13221317
list_for_each_entry_rcu(delegation, &server->delegations, super_list) {
13231318
if (test_bit(NFS_DELEGATION_INODE_FREEING,
13241319
&delegation->flags) ||
@@ -1330,7 +1325,7 @@ static int nfs_server_reap_expired_delegations(struct nfs_server *server,
13301325
continue;
13311326
inode = nfs_delegation_grab_inode(delegation);
13321327
if (inode == NULL)
1333-
goto restart_locked;
1328+
continue;
13341329
spin_lock(&delegation->lock);
13351330
cred = get_cred_rcu(delegation->cred);
13361331
nfs4_stateid_copy(&stateid, &delegation->stateid);

fs/nfs/nfs4proc.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3931,7 +3931,8 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f
39313931
FATTR4_WORD0_CASE_INSENSITIVE |
39323932
FATTR4_WORD0_CASE_PRESERVING;
39333933
if (minorversion)
3934-
bitmask[2] = FATTR4_WORD2_SUPPATTR_EXCLCREAT;
3934+
bitmask[2] = FATTR4_WORD2_SUPPATTR_EXCLCREAT |
3935+
FATTR4_WORD2_OPEN_ARGUMENTS;
39353936

39363937
status = nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0);
39373938
if (status == 0) {
@@ -9997,6 +9998,7 @@ static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata)
99979998
fallthrough;
99989999
default:
999910000
task->tk_status = 0;
10001+
lrp->res.lrs_present = 0;
1000010002
fallthrough;
1000110003
case 0:
1000210004
break;
@@ -10010,9 +10012,11 @@ static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata)
1001010012
task->tk_status = 0;
1001110013
break;
1001210014
case -NFS4ERR_DELAY:
10013-
if (nfs4_async_handle_error(task, server, NULL, NULL) != -EAGAIN)
10014-
break;
10015-
goto out_restart;
10015+
if (nfs4_async_handle_error(task, server, NULL, NULL) ==
10016+
-EAGAIN)
10017+
goto out_restart;
10018+
lrp->res.lrs_present = 0;
10019+
break;
1001610020
}
1001710021
return;
1001810022
out_restart:

fs/nfs/pnfs.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1284,10 +1284,9 @@ void pnfs_layoutreturn_free_lsegs(struct pnfs_layout_hdr *lo,
12841284
LIST_HEAD(freeme);
12851285

12861286
spin_lock(&inode->i_lock);
1287-
if (!pnfs_layout_is_valid(lo) ||
1288-
!nfs4_stateid_match_other(&lo->plh_stateid, arg_stateid))
1287+
if (!nfs4_stateid_match_other(&lo->plh_stateid, arg_stateid))
12891288
goto out_unlock;
1290-
if (stateid) {
1289+
if (stateid && pnfs_layout_is_valid(lo)) {
12911290
u32 seq = be32_to_cpu(arg_stateid->seqid);
12921291

12931292
pnfs_mark_matching_lsegs_invalid(lo, &freeme, range, seq);

fs/nfs/super.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
#include <linux/vfs.h>
4848
#include <linux/inet.h>
4949
#include <linux/in6.h>
50+
#include <linux/sched.h>
5051
#include <linux/slab.h>
5152
#include <net/ipv6.h>
5253
#include <linux/netdevice.h>
@@ -228,6 +229,7 @@ static int __nfs_list_for_each_server(struct list_head *head,
228229
ret = fn(server, data);
229230
if (ret)
230231
goto out;
232+
cond_resched();
231233
rcu_read_lock();
232234
}
233235
rcu_read_unlock();

include/trace/events/rpcrdma.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2277,6 +2277,42 @@ DEFINE_CLIENT_DEVICE_EVENT(rpcrdma_client_remove_one);
22772277
DEFINE_CLIENT_DEVICE_EVENT(rpcrdma_client_wait_on);
22782278
DEFINE_CLIENT_DEVICE_EVENT(rpcrdma_client_remove_one_done);
22792279

2280+
DECLARE_EVENT_CLASS(rpcrdma_client_register_class,
2281+
TP_PROTO(
2282+
const struct ib_device *device,
2283+
const struct rpcrdma_notification *rn
2284+
),
2285+
2286+
TP_ARGS(device, rn),
2287+
2288+
TP_STRUCT__entry(
2289+
__string(name, device->name)
2290+
__field(void *, callback)
2291+
__field(u32, index)
2292+
),
2293+
2294+
TP_fast_assign(
2295+
__assign_str(name);
2296+
__entry->callback = rn->rn_done;
2297+
__entry->index = rn->rn_index;
2298+
),
2299+
2300+
TP_printk("device=%s index=%u done callback=%pS\n",
2301+
__get_str(name), __entry->index, __entry->callback
2302+
)
2303+
);
2304+
2305+
#define DEFINE_CLIENT_REGISTER_EVENT(name) \
2306+
DEFINE_EVENT(rpcrdma_client_register_class, name, \
2307+
TP_PROTO( \
2308+
const struct ib_device *device, \
2309+
const struct rpcrdma_notification *rn \
2310+
), \
2311+
TP_ARGS(device, rn))
2312+
2313+
DEFINE_CLIENT_REGISTER_EVENT(rpcrdma_client_register);
2314+
DEFINE_CLIENT_REGISTER_EVENT(rpcrdma_client_unregister);
2315+
22802316
#endif /* _TRACE_RPCRDMA_H */
22812317

22822318
#include <trace/define_trace.h>

net/sunrpc/xprtrdma/ib_client.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,11 @@ int rpcrdma_rn_register(struct ib_device *device,
6262
if (!rd || test_bit(RPCRDMA_RD_F_REMOVING, &rd->rd_flags))
6363
return -ENETUNREACH;
6464

65-
kref_get(&rd->rd_kref);
6665
if (xa_alloc(&rd->rd_xa, &rn->rn_index, rn, xa_limit_32b, GFP_KERNEL) < 0)
6766
return -ENOMEM;
67+
kref_get(&rd->rd_kref);
6868
rn->rn_done = done;
69+
trace_rpcrdma_client_register(device, rn);
6970
return 0;
7071
}
7172

@@ -91,6 +92,7 @@ void rpcrdma_rn_unregister(struct ib_device *device,
9192
if (!rd)
9293
return;
9394

95+
trace_rpcrdma_client_unregister(device, rn);
9496
xa_erase(&rd->rd_xa, rn->rn_index);
9597
kref_put(&rd->rd_kref, rpcrdma_rn_release);
9698
}
@@ -111,7 +113,7 @@ static int rpcrdma_add_one(struct ib_device *device)
111113
return -ENOMEM;
112114

113115
kref_init(&rd->rd_kref);
114-
xa_init_flags(&rd->rd_xa, XA_FLAGS_ALLOC1);
116+
xa_init_flags(&rd->rd_xa, XA_FLAGS_ALLOC);
115117
rd->rd_device = device;
116118
init_completion(&rd->rd_done);
117119
ib_set_client_data(device, &rpcrdma_ib_client, rd);

0 commit comments

Comments
 (0)