Commit a79cdfba authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'nfsd-5.13-1' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux

Pull more nfsd updates from Chuck Lever:
 "Additional fixes and clean-ups for NFSD since tags/nfsd-5.13,
  including a fix to grant read delegations for files open for writing"

* tag 'nfsd-5.13-1' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux:
  SUNRPC: Fix null pointer dereference in svc_rqst_free()
  SUNRPC: fix ternary sign expansion bug in tracing
  nfsd: Fix fall-through warnings for Clang
  nfsd: grant read delegations to clients holding writes
  nfsd: reshuffle some code
  nfsd: track filehandle aliasing in nfs4_files
  nfsd: hash nfs4_files by inode number
  nfsd: ensure new clients break delegations
  nfsd: removed unused argument in nfsd_startup_generic()
  nfsd: remove unused function
  svcrdma: Pass a useful error code to the send_err tracepoint
  svcrdma: Rename goto labels in svc_rdma_sendto()
  svcrdma: Don't leak send_ctxt on Send errors
parents 7c9e41e0 b9f83ffa
...@@ -1808,6 +1808,9 @@ check_conflicting_open(struct file *filp, const long arg, int flags) ...@@ -1808,6 +1808,9 @@ check_conflicting_open(struct file *filp, const long arg, int flags)
if (flags & FL_LAYOUT) if (flags & FL_LAYOUT)
return 0; return 0;
if (flags & FL_DELEG)
/* We leave these checks to the caller */
return 0;
if (arg == F_RDLCK) if (arg == F_RDLCK)
return inode_is_open_for_write(inode) ? -EAGAIN : 0; return inode_is_open_for_write(inode) ? -EAGAIN : 0;
......
This diff is collapsed.
...@@ -1166,6 +1166,7 @@ static struct inode *nfsd_get_inode(struct super_block *sb, umode_t mode) ...@@ -1166,6 +1166,7 @@ static struct inode *nfsd_get_inode(struct super_block *sb, umode_t mode)
inode->i_fop = &simple_dir_operations; inode->i_fop = &simple_dir_operations;
inode->i_op = &simple_dir_inode_operations; inode->i_op = &simple_dir_inode_operations;
inc_nlink(inode); inc_nlink(inode);
break;
default: default:
break; break;
} }
......
...@@ -308,7 +308,7 @@ static int nfsd_init_socks(struct net *net, const struct cred *cred) ...@@ -308,7 +308,7 @@ static int nfsd_init_socks(struct net *net, const struct cred *cred)
static int nfsd_users = 0; static int nfsd_users = 0;
static int nfsd_startup_generic(int nrservs) static int nfsd_startup_generic(void)
{ {
int ret; int ret;
...@@ -374,7 +374,7 @@ void nfsd_reset_boot_verifier(struct nfsd_net *nn) ...@@ -374,7 +374,7 @@ void nfsd_reset_boot_verifier(struct nfsd_net *nn)
write_sequnlock(&nn->boot_lock); write_sequnlock(&nn->boot_lock);
} }
static int nfsd_startup_net(int nrservs, struct net *net, const struct cred *cred) static int nfsd_startup_net(struct net *net, const struct cred *cred)
{ {
struct nfsd_net *nn = net_generic(net, nfsd_net_id); struct nfsd_net *nn = net_generic(net, nfsd_net_id);
int ret; int ret;
...@@ -382,7 +382,7 @@ static int nfsd_startup_net(int nrservs, struct net *net, const struct cred *cre ...@@ -382,7 +382,7 @@ static int nfsd_startup_net(int nrservs, struct net *net, const struct cred *cre
if (nn->nfsd_net_up) if (nn->nfsd_net_up)
return 0; return 0;
ret = nfsd_startup_generic(nrservs); ret = nfsd_startup_generic();
if (ret) if (ret)
return ret; return ret;
ret = nfsd_init_socks(net, cred); ret = nfsd_init_socks(net, cred);
...@@ -790,7 +790,7 @@ nfsd_svc(int nrservs, struct net *net, const struct cred *cred) ...@@ -790,7 +790,7 @@ nfsd_svc(int nrservs, struct net *net, const struct cred *cred)
nfsd_up_before = nn->nfsd_net_up; nfsd_up_before = nn->nfsd_net_up;
error = nfsd_startup_net(nrservs, net, cred); error = nfsd_startup_net(net, cred);
if (error) if (error)
goto out_destroy; goto out_destroy;
error = nn->nfsd_serv->sv_ops->svo_setup(nn->nfsd_serv, error = nn->nfsd_serv->sv_ops->svo_setup(nn->nfsd_serv,
......
...@@ -516,6 +516,8 @@ struct nfs4_clnt_odstate { ...@@ -516,6 +516,8 @@ struct nfs4_clnt_odstate {
*/ */
struct nfs4_file { struct nfs4_file {
refcount_t fi_ref; refcount_t fi_ref;
struct inode * fi_inode;
bool fi_aliased;
spinlock_t fi_lock; spinlock_t fi_lock;
struct hlist_node fi_hash; /* hash on fi_fhandle */ struct hlist_node fi_hash; /* hash on fi_fhandle */
struct list_head fi_stateids; struct list_head fi_stateids;
...@@ -669,7 +671,6 @@ extern struct nfs4_client_reclaim *nfs4_client_to_reclaim(struct xdr_netobj name ...@@ -669,7 +671,6 @@ extern struct nfs4_client_reclaim *nfs4_client_to_reclaim(struct xdr_netobj name
struct xdr_netobj princhash, struct nfsd_net *nn); struct xdr_netobj princhash, struct nfsd_net *nn);
extern bool nfs4_has_reclaimed_state(struct xdr_netobj name, struct nfsd_net *nn); extern bool nfs4_has_reclaimed_state(struct xdr_netobj name, struct nfsd_net *nn);
struct nfs4_file *find_file(struct knfsd_fh *fh);
void put_nfs4_file(struct nfs4_file *fi); void put_nfs4_file(struct nfs4_file *fi);
extern void nfs4_put_copy(struct nfsd4_copy *copy); extern void nfs4_put_copy(struct nfsd4_copy *copy);
extern struct nfsd4_copy * extern struct nfsd4_copy *
......
...@@ -846,7 +846,8 @@ void ...@@ -846,7 +846,8 @@ void
svc_rqst_free(struct svc_rqst *rqstp) svc_rqst_free(struct svc_rqst *rqstp)
{ {
svc_release_buffer(rqstp); svc_release_buffer(rqstp);
put_page(rqstp->rq_scratch_page); if (rqstp->rq_scratch_page)
put_page(rqstp->rq_scratch_page);
kfree(rqstp->rq_resp); kfree(rqstp->rq_resp);
kfree(rqstp->rq_argp); kfree(rqstp->rq_argp);
kfree(rqstp->rq_auth_data); kfree(rqstp->rq_auth_data);
......
...@@ -1174,7 +1174,7 @@ static int svc_tcp_sendto(struct svc_rqst *rqstp) ...@@ -1174,7 +1174,7 @@ static int svc_tcp_sendto(struct svc_rqst *rqstp)
tcp_sock_set_cork(svsk->sk_sk, true); tcp_sock_set_cork(svsk->sk_sk, true);
err = svc_tcp_sendmsg(svsk->sk_sock, xdr, marker, &sent); err = svc_tcp_sendmsg(svsk->sk_sock, xdr, marker, &sent);
xdr_free_bvec(xdr); xdr_free_bvec(xdr);
trace_svcsock_tcp_send(xprt, err < 0 ? err : sent); trace_svcsock_tcp_send(xprt, err < 0 ? (long)err : sent);
if (err < 0 || sent != (xdr->len + sizeof(marker))) if (err < 0 || sent != (xdr->len + sizeof(marker)))
goto out_close; goto out_close;
if (atomic_dec_and_test(&svsk->sk_sendqlen)) if (atomic_dec_and_test(&svsk->sk_sendqlen))
......
...@@ -921,42 +921,48 @@ int svc_rdma_sendto(struct svc_rqst *rqstp) ...@@ -921,42 +921,48 @@ int svc_rdma_sendto(struct svc_rqst *rqstp)
struct svc_rdma_recv_ctxt *rctxt = rqstp->rq_xprt_ctxt; struct svc_rdma_recv_ctxt *rctxt = rqstp->rq_xprt_ctxt;
__be32 *rdma_argp = rctxt->rc_recv_buf; __be32 *rdma_argp = rctxt->rc_recv_buf;
struct svc_rdma_send_ctxt *sctxt; struct svc_rdma_send_ctxt *sctxt;
unsigned int rc_size;
__be32 *p; __be32 *p;
int ret; int ret;
ret = -ENOTCONN; ret = -ENOTCONN;
if (svc_xprt_is_dead(xprt)) if (svc_xprt_is_dead(xprt))
goto err0; goto drop_connection;
ret = -ENOMEM; ret = -ENOMEM;
sctxt = svc_rdma_send_ctxt_get(rdma); sctxt = svc_rdma_send_ctxt_get(rdma);
if (!sctxt) if (!sctxt)
goto err0; goto drop_connection;
ret = -EMSGSIZE;
p = xdr_reserve_space(&sctxt->sc_stream, p = xdr_reserve_space(&sctxt->sc_stream,
rpcrdma_fixed_maxsz * sizeof(*p)); rpcrdma_fixed_maxsz * sizeof(*p));
if (!p) if (!p)
goto err0; goto put_ctxt;
ret = svc_rdma_send_reply_chunk(rdma, rctxt, &rqstp->rq_res); ret = svc_rdma_send_reply_chunk(rdma, rctxt, &rqstp->rq_res);
if (ret < 0) if (ret < 0)
goto err2; goto reply_chunk;
rc_size = ret;
*p++ = *rdma_argp; *p++ = *rdma_argp;
*p++ = *(rdma_argp + 1); *p++ = *(rdma_argp + 1);
*p++ = rdma->sc_fc_credits; *p++ = rdma->sc_fc_credits;
*p = pcl_is_empty(&rctxt->rc_reply_pcl) ? rdma_msg : rdma_nomsg; *p = pcl_is_empty(&rctxt->rc_reply_pcl) ? rdma_msg : rdma_nomsg;
if (svc_rdma_encode_read_list(sctxt) < 0) ret = svc_rdma_encode_read_list(sctxt);
goto err0; if (ret < 0)
if (svc_rdma_encode_write_list(rctxt, sctxt) < 0) goto put_ctxt;
goto err0; ret = svc_rdma_encode_write_list(rctxt, sctxt);
if (svc_rdma_encode_reply_chunk(rctxt, sctxt, ret) < 0) if (ret < 0)
goto err0; goto put_ctxt;
ret = svc_rdma_encode_reply_chunk(rctxt, sctxt, rc_size);
if (ret < 0)
goto put_ctxt;
ret = svc_rdma_send_reply_msg(rdma, sctxt, rctxt, rqstp); ret = svc_rdma_send_reply_msg(rdma, sctxt, rctxt, rqstp);
if (ret < 0) if (ret < 0)
goto err1; goto put_ctxt;
/* Prevent svc_xprt_release() from releasing the page backing /* Prevent svc_xprt_release() from releasing the page backing
* rq_res.head[0].iov_base. It's no longer being accessed by * rq_res.head[0].iov_base. It's no longer being accessed by
...@@ -964,16 +970,16 @@ int svc_rdma_sendto(struct svc_rqst *rqstp) ...@@ -964,16 +970,16 @@ int svc_rdma_sendto(struct svc_rqst *rqstp)
rqstp->rq_respages++; rqstp->rq_respages++;
return 0; return 0;
err2: reply_chunk:
if (ret != -E2BIG && ret != -EINVAL) if (ret != -E2BIG && ret != -EINVAL)
goto err1; goto put_ctxt;
svc_rdma_send_error_msg(rdma, sctxt, rctxt, ret); svc_rdma_send_error_msg(rdma, sctxt, rctxt, ret);
return 0; return 0;
err1: put_ctxt:
svc_rdma_send_ctxt_put(rdma, sctxt); svc_rdma_send_ctxt_put(rdma, sctxt);
err0: drop_connection:
trace_svcrdma_send_err(rqstp, ret); trace_svcrdma_send_err(rqstp, ret);
svc_xprt_deferred_close(&rdma->sc_xprt); svc_xprt_deferred_close(&rdma->sc_xprt);
return -ENOTCONN; return -ENOTCONN;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment