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.

nfsd/sunrpc: add svc_rqst->rq_private pointer and remove rq_lease_breaker

rq_lease_breaker has always been a NFSv4 specific layering violation in
svc_rqst. The reason it's there though is that we need a place that is
thread-local, and accessible from the svc_rqst pointer.

Add a new rq_private pointer to struct svc_rqst. This is intended for
use by the threads that are handling the service. sunrpc code doesn't
touch it.

In nfsd, define a new struct nfsd_thread_local_info. nfsd declares one
of these on the stack and puts a pointer to it in rq_private.

Add a new ntli_lease_breaker field to the new struct and convert all of
the places that access rq_lease_breaker to use the new field instead.

Signed-off-by: Jeff Layton <jlayton@kernel.org>
Reviewed-by: Benjamin Coddington <bcodding@hammerspace.com>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>

authored by

Jeff Layton and committed by
Chuck Lever
55b6dd54 7aaa8047

+21 -5
+2 -1
fs/nfsd/nfs4proc.c
··· 3043 3043 struct svc_fh *current_fh = &cstate->current_fh; 3044 3044 struct svc_fh *save_fh = &cstate->save_fh; 3045 3045 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); 3046 + struct nfsd_thread_local_info *ntli = rqstp->rq_private; 3046 3047 __be32 status; 3047 3048 3048 3049 resp->xdr = &rqstp->rq_res_stream; ··· 3082 3081 } 3083 3082 check_if_stalefh_allowed(args); 3084 3083 3085 - rqstp->rq_lease_breaker = (void **)&cstate->clp; 3084 + ntli->ntli_lease_breaker = &cstate->clp; 3086 3085 3087 3086 trace_nfsd_compound(rqstp, args->tag, args->taglen, args->client_opcnt); 3088 3087 while (!status && resp->opcnt < args->opcnt) {
+6 -3
fs/nfsd/nfs4state.c
··· 5535 5535 static bool nfsd_breaker_owns_lease(struct file_lease *fl) 5536 5536 { 5537 5537 struct nfs4_delegation *dl = fl->c.flc_owner; 5538 + struct nfsd_thread_local_info *ntli; 5538 5539 struct svc_rqst *rqst; 5539 5540 struct nfs4_client *clp; 5540 5541 5541 5542 rqst = nfsd_current_rqst(); 5542 5543 if (!nfsd_v4client(rqst)) 5543 5544 return false; 5544 - clp = *(rqst->rq_lease_breaker); 5545 + ntli = rqst->rq_private; 5546 + clp = *ntli->ntli_lease_breaker; 5545 5547 return dl->dl_stid.sc_client == clp; 5546 5548 } 5547 5549 ··· 9350 9348 nfsd4_deleg_getattr_conflict(struct svc_rqst *rqstp, struct dentry *dentry, 9351 9349 struct nfs4_delegation **pdp) 9352 9350 { 9353 - __be32 status; 9354 9351 struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); 9352 + struct nfsd_thread_local_info *ntli = rqstp->rq_private; 9355 9353 struct file_lock_context *ctx; 9356 9354 struct nfs4_delegation *dp = NULL; 9357 9355 struct file_lease *fl; 9358 9356 struct nfs4_cb_fattr *ncf; 9359 9357 struct inode *inode = d_inode(dentry); 9358 + __be32 status; 9360 9359 9361 9360 ctx = locks_inode_context(inode); 9362 9361 if (!ctx) ··· 9378 9375 break; 9379 9376 } 9380 9377 if (dp == NULL || dp == NON_NFSD_LEASE || 9381 - dp->dl_recall.cb_clp == *(rqstp->rq_lease_breaker)) { 9378 + dp->dl_recall.cb_clp == *(ntli->ntli_lease_breaker)) { 9382 9379 spin_unlock(&ctx->flc_lock); 9383 9380 if (dp == NON_NFSD_LEASE) { 9384 9381 status = nfserrno(nfsd_open_break_lease(inode,
+4
fs/nfsd/nfsd.h
··· 82 82 83 83 extern const struct seq_operations nfs_exports_op; 84 84 85 + struct nfsd_thread_local_info { 86 + struct nfs4_client **ntli_lease_breaker; 87 + }; 88 + 85 89 /* 86 90 * Common void argument and result helpers 87 91 */
+5
fs/nfsd/nfssvc.c
··· 887 887 struct svc_xprt *perm_sock = list_entry(rqstp->rq_server->sv_permsocks.next, typeof(struct svc_xprt), xpt_list); 888 888 struct net *net = perm_sock->xpt_net; 889 889 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 890 + struct nfsd_thread_local_info ntli = { }; 890 891 bool have_mutex = false; 891 892 892 893 /* At this point, the thread shares current->fs ··· 901 900 atomic_inc(&nfsd_th_cnt); 902 901 903 902 set_freezable(); 903 + 904 + /* use dynamic allocation if ntli should ever become large */ 905 + static_assert(sizeof(struct nfsd_thread_local_info) < 256); 906 + rqstp->rq_private = &ntli; 904 907 905 908 /* 906 909 * The main request loop
+4 -1
include/linux/sunrpc/svc.h
··· 175 175 /* 176 176 * The context of a single thread, including the request currently being 177 177 * processed. 178 + * 179 + * RPC programs are free to use rq_private to stash thread-local information. 180 + * The sunrpc layer will not access it. 178 181 */ 179 182 struct svc_rqst { 180 183 struct list_head rq_all; /* all threads list */ ··· 254 251 unsigned long bc_to_initval; 255 252 unsigned int bc_to_retries; 256 253 unsigned int rq_status_counter; /* RPC processing counter */ 257 - void **rq_lease_breaker; /* The v4 client breaking a lease */ 254 + void *rq_private; /* For use by the service thread */ 258 255 }; 259 256 260 257 /* bits for rq_flags */