Skip to content

Commit 6254d53

Browse files
committed
Merge tag 'nfs-for-6.12-2' of git://git.linux-nfs.org/projects/anna/linux-nfs
Pull NFS client fixes from Anna Schumaker: "Localio Bugfixes: - remove duplicated include in localio.c - fix race in NFS calls to nfsd_file_put_local() and nfsd_serv_put() - fix Kconfig for NFS_COMMON_LOCALIO_SUPPORT - fix nfsd_file tracepoints to handle NULL rqstp pointers Other Bugfixes: - fix program selection loop in svc_process_common - fix integer overflow in decode_rc_list() - prevent NULL-pointer dereference in nfs42_complete_copies() - fix CB_RECALL performance issues when using a large number of delegations" * tag 'nfs-for-6.12-2' of git://git.linux-nfs.org/projects/anna/linux-nfs: NFS: remove revoked delegation from server's delegation list nfsd/localio: fix nfsd_file tracepoints to handle NULL rqstp nfs_common: fix Kconfig for NFS_COMMON_LOCALIO_SUPPORT nfs_common: fix race in NFS calls to nfsd_file_put_local() and nfsd_serv_put() NFSv4: Prevent NULL-pointer dereference in nfs42_complete_copies() SUNRPC: Fix integer overflow in decode_rc_list() sunrpc: fix prog selection loop in svc_process_common nfs: Remove duplicated include in localio.c
2 parents a102976 + 7ef6010 commit 6254d53

File tree

15 files changed

+45
-22
lines changed

15 files changed

+45
-22
lines changed

fs/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,7 @@ config NFS_COMMON
388388

389389
config NFS_COMMON_LOCALIO_SUPPORT
390390
tristate
391-
default n
391+
depends on NFS_LOCALIO
392392
default y if NFSD=y || NFS_FS=y
393393
default m if NFSD=m && NFS_FS=m
394394
select SUNRPC

fs/nfs/callback_xdr.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,8 @@ static __be32 decode_rc_list(struct xdr_stream *xdr,
375375

376376
rc_list->rcl_nrefcalls = ntohl(*p++);
377377
if (rc_list->rcl_nrefcalls) {
378+
if (unlikely(rc_list->rcl_nrefcalls > xdr->buf->len))
379+
goto out;
378380
p = xdr_inline_decode(xdr,
379381
rc_list->rcl_nrefcalls * 2 * sizeof(uint32_t));
380382
if (unlikely(p == NULL))

fs/nfs/client.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -996,6 +996,7 @@ struct nfs_server *nfs_alloc_server(void)
996996
INIT_LIST_HEAD(&server->layouts);
997997
INIT_LIST_HEAD(&server->state_owners_lru);
998998
INIT_LIST_HEAD(&server->ss_copies);
999+
INIT_LIST_HEAD(&server->ss_src_copies);
9991000

10001001
atomic_set(&server->active, 0);
10011002

fs/nfs/delegation.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,6 +1001,11 @@ void nfs_delegation_mark_returned(struct inode *inode,
10011001
}
10021002

10031003
nfs_mark_delegation_revoked(delegation);
1004+
clear_bit(NFS_DELEGATION_RETURNING, &delegation->flags);
1005+
spin_unlock(&delegation->lock);
1006+
if (nfs_detach_delegation(NFS_I(inode), delegation, NFS_SERVER(inode)))
1007+
nfs_put_delegation(delegation);
1008+
goto out_rcu_unlock;
10041009

10051010
out_clear_returning:
10061011
clear_bit(NFS_DELEGATION_RETURNING, &delegation->flags);

fs/nfs/localio.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
#include <net/addrconf.h>
1919
#include <linux/nfs_common.h>
2020
#include <linux/nfslocalio.h>
21-
#include <linux/module.h>
2221
#include <linux/bvec.h>
2322

2423
#include <linux/nfs.h>
@@ -341,7 +340,7 @@ nfs_local_pgio_release(struct nfs_local_kiocb *iocb)
341340
{
342341
struct nfs_pgio_header *hdr = iocb->hdr;
343342

344-
nfs_to->nfsd_file_put_local(iocb->localio);
343+
nfs_to_nfsd_file_put_local(iocb->localio);
345344
nfs_local_iocb_free(iocb);
346345
nfs_local_hdr_release(hdr, hdr->task.tk_ops);
347346
}
@@ -622,7 +621,7 @@ int nfs_local_doio(struct nfs_client *clp, struct nfsd_file *localio,
622621
}
623622
out:
624623
if (status != 0) {
625-
nfs_to->nfsd_file_put_local(localio);
624+
nfs_to_nfsd_file_put_local(localio);
626625
hdr->task.tk_status = status;
627626
nfs_local_hdr_release(hdr, call_ops);
628627
}
@@ -673,7 +672,7 @@ nfs_local_release_commit_data(struct nfsd_file *localio,
673672
struct nfs_commit_data *data,
674673
const struct rpc_call_ops *call_ops)
675674
{
676-
nfs_to->nfsd_file_put_local(localio);
675+
nfs_to_nfsd_file_put_local(localio);
677676
call_ops->rpc_call_done(&data->task, data);
678677
call_ops->rpc_release(data);
679678
}

fs/nfs/nfs42proc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ static int handle_async_copy(struct nfs42_copy_res *res,
218218

219219
if (dst_server != src_server) {
220220
spin_lock(&src_server->nfs_client->cl_lock);
221-
list_add_tail(&copy->src_copies, &src_server->ss_copies);
221+
list_add_tail(&copy->src_copies, &src_server->ss_src_copies);
222222
spin_unlock(&src_server->nfs_client->cl_lock);
223223
}
224224

fs/nfs/nfs4state.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1585,7 +1585,7 @@ static void nfs42_complete_copies(struct nfs4_state_owner *sp, struct nfs4_state
15851585
complete(&copy->completion);
15861586
}
15871587
}
1588-
list_for_each_entry(copy, &sp->so_server->ss_copies, src_copies) {
1588+
list_for_each_entry(copy, &sp->so_server->ss_src_copies, src_copies) {
15891589
if ((test_bit(NFS_CLNT_SRC_SSC_COPY_STATE, &state->flags) &&
15901590
!nfs4_stateid_match_other(&state->stateid,
15911591
&copy->parent_src_state->stateid)))

fs/nfs_common/nfslocalio.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,11 @@ struct nfsd_file *nfs_open_local_fh(nfs_uuid_t *uuid,
142142
/* We have an implied reference to net thanks to nfsd_serv_try_get */
143143
localio = nfs_to->nfsd_open_local_fh(net, uuid->dom, rpc_clnt,
144144
cred, nfs_fh, fmode);
145-
if (IS_ERR(localio))
145+
if (IS_ERR(localio)) {
146+
rcu_read_lock();
146147
nfs_to->nfsd_serv_put(net);
148+
rcu_read_unlock();
149+
}
147150
return localio;
148151
}
149152
EXPORT_SYMBOL_GPL(nfs_open_local_fh);

fs/nfsd/filecache.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,7 @@ nfsd_file_put(struct nfsd_file *nf)
398398
* reference to the associated nn->nfsd_serv.
399399
*/
400400
void
401-
nfsd_file_put_local(struct nfsd_file *nf)
401+
nfsd_file_put_local(struct nfsd_file *nf) __must_hold(rcu)
402402
{
403403
struct net *net = nf->nf_net;
404404

fs/nfsd/localio.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ void nfsd_localio_ops_init(void)
5353
*
5454
* On successful return, returned nfsd_file will have its nf_net member
5555
* set. Caller (NFS client) is responsible for calling nfsd_serv_put and
56-
* nfsd_file_put (via nfs_to->nfsd_file_put_local).
56+
* nfsd_file_put (via nfs_to_nfsd_file_put_local).
5757
*/
5858
struct nfsd_file *
5959
nfsd_open_local_fh(struct net *net, struct auth_domain *dom,

0 commit comments

Comments
 (0)