Hi Scott- > On Jul 10, 2020, at 4:33 PM, Scott Mayhew <smayhew@xxxxxxxxxx> wrote: > > If the rpc_pipefs is unmounted, then the rpc_pipe->dentry becomes NULL > and dereferencing the dentry->d_sb will trigger an oops. The only > reason we're doing that is to determine the nfsd_net, which could > instead be passed in by the caller. So do that instead. > > Signed-off-by: Scott Mayhew <smayhew@xxxxxxxxxx> Looks straightforward. Applied to the nfsd-5.9 testing tree. I'm wondering about automatic backports to stable. This fix does not apply to kernels before v5.6, but IIUC addresses a crash introduced in f3f8014862d8 ("nfsd: add the infrastructure to handle the cld upcall") [2012] ? Is "Cc: <stable@xxxxxxxxxx> # v5.6+" appropriate? Also, is there a bug report that documents the crash? > --- > fs/nfsd/nfs4recover.c | 24 +++++++++++------------- > 1 file changed, 11 insertions(+), 13 deletions(-) > > diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c > index 9e40dfecf1b1..186fa2c2c6ba 100644 > --- a/fs/nfsd/nfs4recover.c > +++ b/fs/nfsd/nfs4recover.c > @@ -747,13 +747,11 @@ struct cld_upcall { > }; > > static int > -__cld_pipe_upcall(struct rpc_pipe *pipe, void *cmsg) > +__cld_pipe_upcall(struct rpc_pipe *pipe, void *cmsg, struct nfsd_net *nn) > { > int ret; > struct rpc_pipe_msg msg; > struct cld_upcall *cup = container_of(cmsg, struct cld_upcall, cu_u); > - struct nfsd_net *nn = net_generic(pipe->dentry->d_sb->s_fs_info, > - nfsd_net_id); > > memset(&msg, 0, sizeof(msg)); > msg.data = cmsg; > @@ -773,7 +771,7 @@ __cld_pipe_upcall(struct rpc_pipe *pipe, void *cmsg) > } > > static int > -cld_pipe_upcall(struct rpc_pipe *pipe, void *cmsg) > +cld_pipe_upcall(struct rpc_pipe *pipe, void *cmsg, struct nfsd_net *nn) > { > int ret; > > @@ -782,7 +780,7 @@ cld_pipe_upcall(struct rpc_pipe *pipe, void *cmsg) > * upcalls queued. > */ > do { > - ret = __cld_pipe_upcall(pipe, cmsg); > + ret = __cld_pipe_upcall(pipe, cmsg, nn); > } while (ret == -EAGAIN); > > return ret; > @@ -1115,7 +1113,7 @@ nfsd4_cld_create(struct nfs4_client *clp) > memcpy(cup->cu_u.cu_msg.cm_u.cm_name.cn_id, clp->cl_name.data, > clp->cl_name.len); > > - ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg); > + ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg, nn); > if (!ret) { > ret = cup->cu_u.cu_msg.cm_status; > set_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags); > @@ -1180,7 +1178,7 @@ nfsd4_cld_create_v2(struct nfs4_client *clp) > } else > cmsg->cm_u.cm_clntinfo.cc_princhash.cp_len = 0; > > - ret = cld_pipe_upcall(cn->cn_pipe, cmsg); > + ret = cld_pipe_upcall(cn->cn_pipe, cmsg, nn); > if (!ret) { > ret = cmsg->cm_status; > set_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags); > @@ -1218,7 +1216,7 @@ nfsd4_cld_remove(struct nfs4_client *clp) > memcpy(cup->cu_u.cu_msg.cm_u.cm_name.cn_id, clp->cl_name.data, > clp->cl_name.len); > > - ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg); > + ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg, nn); > if (!ret) { > ret = cup->cu_u.cu_msg.cm_status; > clear_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags); > @@ -1261,7 +1259,7 @@ nfsd4_cld_check_v0(struct nfs4_client *clp) > memcpy(cup->cu_u.cu_msg.cm_u.cm_name.cn_id, clp->cl_name.data, > clp->cl_name.len); > > - ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg); > + ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg, nn); > if (!ret) { > ret = cup->cu_u.cu_msg.cm_status; > set_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags); > @@ -1404,7 +1402,7 @@ nfsd4_cld_grace_start(struct nfsd_net *nn) > } > > cup->cu_u.cu_msg.cm_cmd = Cld_GraceStart; > - ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg); > + ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg, nn); > if (!ret) > ret = cup->cu_u.cu_msg.cm_status; > > @@ -1432,7 +1430,7 @@ nfsd4_cld_grace_done_v0(struct nfsd_net *nn) > > cup->cu_u.cu_msg.cm_cmd = Cld_GraceDone; > cup->cu_u.cu_msg.cm_u.cm_gracetime = nn->boot_time; > - ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg); > + ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg, nn); > if (!ret) > ret = cup->cu_u.cu_msg.cm_status; > > @@ -1460,7 +1458,7 @@ nfsd4_cld_grace_done(struct nfsd_net *nn) > } > > cup->cu_u.cu_msg.cm_cmd = Cld_GraceDone; > - ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg); > + ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg, nn); > if (!ret) > ret = cup->cu_u.cu_msg.cm_status; > > @@ -1524,7 +1522,7 @@ nfsd4_cld_get_version(struct nfsd_net *nn) > goto out_err; > } > cup->cu_u.cu_msg.cm_cmd = Cld_GetVersion; > - ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg); > + ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg, nn); > if (!ret) { > ret = cup->cu_u.cu_msg.cm_status; > if (ret) > -- > 2.25.4 > -- Chuck Lever