Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+45 -22
+1 -1
fs/Kconfig
··· 388 388 389 389 config NFS_COMMON_LOCALIO_SUPPORT 390 390 tristate 391 - default n 391 + depends on NFS_LOCALIO 392 392 default y if NFSD=y || NFS_FS=y 393 393 default m if NFSD=m && NFS_FS=m 394 394 select SUNRPC
+2
fs/nfs/callback_xdr.c
··· 375 375 376 376 rc_list->rcl_nrefcalls = ntohl(*p++); 377 377 if (rc_list->rcl_nrefcalls) { 378 + if (unlikely(rc_list->rcl_nrefcalls > xdr->buf->len)) 379 + goto out; 378 380 p = xdr_inline_decode(xdr, 379 381 rc_list->rcl_nrefcalls * 2 * sizeof(uint32_t)); 380 382 if (unlikely(p == NULL))
+1
fs/nfs/client.c
··· 996 996 INIT_LIST_HEAD(&server->layouts); 997 997 INIT_LIST_HEAD(&server->state_owners_lru); 998 998 INIT_LIST_HEAD(&server->ss_copies); 999 + INIT_LIST_HEAD(&server->ss_src_copies); 999 1000 1000 1001 atomic_set(&server->active, 0); 1001 1002
+5
fs/nfs/delegation.c
··· 1001 1001 } 1002 1002 1003 1003 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; 1004 1009 1005 1010 out_clear_returning: 1006 1011 clear_bit(NFS_DELEGATION_RETURNING, &delegation->flags);
+3 -4
fs/nfs/localio.c
··· 18 18 #include <net/addrconf.h> 19 19 #include <linux/nfs_common.h> 20 20 #include <linux/nfslocalio.h> 21 - #include <linux/module.h> 22 21 #include <linux/bvec.h> 23 22 24 23 #include <linux/nfs.h> ··· 340 341 { 341 342 struct nfs_pgio_header *hdr = iocb->hdr; 342 343 343 - nfs_to->nfsd_file_put_local(iocb->localio); 344 + nfs_to_nfsd_file_put_local(iocb->localio); 344 345 nfs_local_iocb_free(iocb); 345 346 nfs_local_hdr_release(hdr, hdr->task.tk_ops); 346 347 } ··· 621 622 } 622 623 out: 623 624 if (status != 0) { 624 - nfs_to->nfsd_file_put_local(localio); 625 + nfs_to_nfsd_file_put_local(localio); 625 626 hdr->task.tk_status = status; 626 627 nfs_local_hdr_release(hdr, call_ops); 627 628 } ··· 672 673 struct nfs_commit_data *data, 673 674 const struct rpc_call_ops *call_ops) 674 675 { 675 - nfs_to->nfsd_file_put_local(localio); 676 + nfs_to_nfsd_file_put_local(localio); 676 677 call_ops->rpc_call_done(&data->task, data); 677 678 call_ops->rpc_release(data); 678 679 }
+1 -1
fs/nfs/nfs42proc.c
··· 218 218 219 219 if (dst_server != src_server) { 220 220 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); 222 222 spin_unlock(&src_server->nfs_client->cl_lock); 223 223 } 224 224
+1 -1
fs/nfs/nfs4state.c
··· 1585 1585 complete(&copy->completion); 1586 1586 } 1587 1587 } 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) { 1589 1589 if ((test_bit(NFS_CLNT_SRC_SSC_COPY_STATE, &state->flags) && 1590 1590 !nfs4_stateid_match_other(&state->stateid, 1591 1591 &copy->parent_src_state->stateid)))
+4 -1
fs/nfs_common/nfslocalio.c
··· 142 142 /* We have an implied reference to net thanks to nfsd_serv_try_get */ 143 143 localio = nfs_to->nfsd_open_local_fh(net, uuid->dom, rpc_clnt, 144 144 cred, nfs_fh, fmode); 145 - if (IS_ERR(localio)) 145 + if (IS_ERR(localio)) { 146 + rcu_read_lock(); 146 147 nfs_to->nfsd_serv_put(net); 148 + rcu_read_unlock(); 149 + } 147 150 return localio; 148 151 } 149 152 EXPORT_SYMBOL_GPL(nfs_open_local_fh);
+1 -1
fs/nfsd/filecache.c
··· 398 398 * reference to the associated nn->nfsd_serv. 399 399 */ 400 400 void 401 - nfsd_file_put_local(struct nfsd_file *nf) 401 + nfsd_file_put_local(struct nfsd_file *nf) __must_hold(rcu) 402 402 { 403 403 struct net *net = nf->nf_net; 404 404
+1 -1
fs/nfsd/localio.c
··· 53 53 * 54 54 * On successful return, returned nfsd_file will have its nf_net member 55 55 * 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). 57 57 */ 58 58 struct nfsd_file * 59 59 nfsd_open_local_fh(struct net *net, struct auth_domain *dom,
+2 -2
fs/nfsd/nfssvc.c
··· 214 214 return 0; 215 215 } 216 216 217 - bool nfsd_serv_try_get(struct net *net) 217 + bool nfsd_serv_try_get(struct net *net) __must_hold(rcu) 218 218 { 219 219 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 220 220 221 221 return (nn && percpu_ref_tryget_live(&nn->nfsd_serv_ref)); 222 222 } 223 223 224 - void nfsd_serv_put(struct net *net) 224 + void nfsd_serv_put(struct net *net) __must_hold(rcu) 225 225 { 226 226 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 227 227
+3 -3
fs/nfsd/trace.h
··· 1113 1113 ), 1114 1114 1115 1115 TP_fast_assign( 1116 - __entry->xid = be32_to_cpu(rqstp->rq_xid); 1116 + __entry->xid = rqstp ? be32_to_cpu(rqstp->rq_xid) : 0; 1117 1117 __entry->inode = inode; 1118 1118 __entry->may_flags = may_flags; 1119 1119 __entry->nf_ref = nf ? refcount_read(&nf->nf_ref) : 0; ··· 1147 1147 __field(long, error) 1148 1148 ), 1149 1149 TP_fast_assign( 1150 - __entry->xid = be32_to_cpu(rqstp->rq_xid); 1150 + __entry->xid = rqstp ? be32_to_cpu(rqstp->rq_xid) : 0; 1151 1151 __entry->inode = inode; 1152 1152 __entry->may_flags = may_flags; 1153 1153 __entry->error = error; ··· 1177 1177 __field(const void *, nf_file) 1178 1178 ), 1179 1179 TP_fast_assign( 1180 - __entry->xid = be32_to_cpu(rqstp->rq_xid); 1180 + __entry->xid = rqstp ? be32_to_cpu(rqstp->rq_xid) : 0; 1181 1181 __entry->inode = inode; 1182 1182 __entry->may_flags = may_flags; 1183 1183 __entry->nf_ref = refcount_read(&nf->nf_ref);
+1
include/linux/nfs_fs_sb.h
··· 249 249 struct list_head layouts; 250 250 struct list_head delegations; 251 251 struct list_head ss_copies; 252 + struct list_head ss_src_copies; 252 253 253 254 unsigned long delegation_gen; 254 255 unsigned long mig_gen;
+15
include/linux/nfslocalio.h
··· 65 65 struct rpc_clnt *, const struct cred *, 66 66 const struct nfs_fh *, const fmode_t); 67 67 68 + static inline void nfs_to_nfsd_file_put_local(struct nfsd_file *localio) 69 + { 70 + /* 71 + * Once reference to nfsd_serv is dropped, NFSD could be 72 + * unloaded, so ensure safe return from nfsd_file_put_local() 73 + * by always taking RCU. 74 + */ 75 + rcu_read_lock(); 76 + nfs_to->nfsd_file_put_local(localio); 77 + rcu_read_unlock(); 78 + } 79 + 68 80 #else /* CONFIG_NFS_LOCALIO */ 69 81 static inline void nfsd_localio_ops_init(void) 82 + { 83 + } 84 + static inline void nfs_to_nfsd_file_put_local(struct nfsd_file *localio) 70 85 { 71 86 } 72 87 #endif /* CONFIG_NFS_LOCALIO */
+4 -7
net/sunrpc/svc.c
··· 1321 1321 svc_process_common(struct svc_rqst *rqstp) 1322 1322 { 1323 1323 struct xdr_stream *xdr = &rqstp->rq_res_stream; 1324 - struct svc_program *progp; 1324 + struct svc_program *progp = NULL; 1325 1325 const struct svc_procedure *procp = NULL; 1326 1326 struct svc_serv *serv = rqstp->rq_server; 1327 1327 struct svc_process_info process; ··· 1351 1351 rqstp->rq_vers = be32_to_cpup(p++); 1352 1352 rqstp->rq_proc = be32_to_cpup(p); 1353 1353 1354 - for (pr = 0; pr < serv->sv_nprogs; pr++) { 1355 - progp = &serv->sv_programs[pr]; 1356 - 1357 - if (rqstp->rq_prog == progp->pg_prog) 1358 - break; 1359 - } 1354 + for (pr = 0; pr < serv->sv_nprogs; pr++) 1355 + if (rqstp->rq_prog == serv->sv_programs[pr].pg_prog) 1356 + progp = &serv->sv_programs[pr]; 1360 1357 1361 1358 /* 1362 1359 * Decode auth data, and add verifier to reply buffer.