Commit c1488c97 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull nfsd fixes from Chuck Lever:

 - Fix a write performance regression

 - Fix crashes during request deferral on RDMA transports

* tag 'nfsd-5.18-1' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux:
  SUNRPC: Fix the svc_deferred_event trace class
  SUNRPC: Fix NFSD's request deferral on RDMA transports
  nfsd: Clean up nfsd_file_put()
  nfsd: Fix a write performance regression
  SUNRPC: Return true/false (not 1/0) from bool functions
parents 453096eb 4d500445
...@@ -236,6 +236,13 @@ nfsd_file_check_write_error(struct nfsd_file *nf) ...@@ -236,6 +236,13 @@ nfsd_file_check_write_error(struct nfsd_file *nf)
return filemap_check_wb_err(file->f_mapping, READ_ONCE(file->f_wb_err)); return filemap_check_wb_err(file->f_mapping, READ_ONCE(file->f_wb_err));
} }
static void
nfsd_file_flush(struct nfsd_file *nf)
{
if (nf->nf_file && vfs_fsync(nf->nf_file, 1) != 0)
nfsd_reset_write_verifier(net_generic(nf->nf_net, nfsd_net_id));
}
static void static void
nfsd_file_do_unhash(struct nfsd_file *nf) nfsd_file_do_unhash(struct nfsd_file *nf)
{ {
...@@ -295,19 +302,15 @@ nfsd_file_put_noref(struct nfsd_file *nf) ...@@ -295,19 +302,15 @@ nfsd_file_put_noref(struct nfsd_file *nf)
void void
nfsd_file_put(struct nfsd_file *nf) nfsd_file_put(struct nfsd_file *nf)
{ {
bool is_hashed;
set_bit(NFSD_FILE_REFERENCED, &nf->nf_flags); set_bit(NFSD_FILE_REFERENCED, &nf->nf_flags);
if (refcount_read(&nf->nf_ref) > 2 || !nf->nf_file) { if (test_bit(NFSD_FILE_HASHED, &nf->nf_flags) == 0) {
nfsd_file_flush(nf);
nfsd_file_put_noref(nf); nfsd_file_put_noref(nf);
return; } else {
nfsd_file_put_noref(nf);
if (nf->nf_file)
nfsd_file_schedule_laundrette();
} }
filemap_flush(nf->nf_file->f_mapping);
is_hashed = test_bit(NFSD_FILE_HASHED, &nf->nf_flags) != 0;
nfsd_file_put_noref(nf);
if (is_hashed)
nfsd_file_schedule_laundrette();
if (atomic_long_read(&nfsd_filecache_count) >= NFSD_FILE_LRU_LIMIT) if (atomic_long_read(&nfsd_filecache_count) >= NFSD_FILE_LRU_LIMIT)
nfsd_file_gc(); nfsd_file_gc();
} }
...@@ -328,6 +331,7 @@ nfsd_file_dispose_list(struct list_head *dispose) ...@@ -328,6 +331,7 @@ nfsd_file_dispose_list(struct list_head *dispose)
while(!list_empty(dispose)) { while(!list_empty(dispose)) {
nf = list_first_entry(dispose, struct nfsd_file, nf_lru); nf = list_first_entry(dispose, struct nfsd_file, nf_lru);
list_del(&nf->nf_lru); list_del(&nf->nf_lru);
nfsd_file_flush(nf);
nfsd_file_put_noref(nf); nfsd_file_put_noref(nf);
} }
} }
...@@ -341,6 +345,7 @@ nfsd_file_dispose_list_sync(struct list_head *dispose) ...@@ -341,6 +345,7 @@ nfsd_file_dispose_list_sync(struct list_head *dispose)
while(!list_empty(dispose)) { while(!list_empty(dispose)) {
nf = list_first_entry(dispose, struct nfsd_file, nf_lru); nf = list_first_entry(dispose, struct nfsd_file, nf_lru);
list_del(&nf->nf_lru); list_del(&nf->nf_lru);
nfsd_file_flush(nf);
if (!refcount_dec_and_test(&nf->nf_ref)) if (!refcount_dec_and_test(&nf->nf_ref))
continue; continue;
if (nfsd_file_free(nf)) if (nfsd_file_free(nf))
......
...@@ -249,34 +249,34 @@ nfsaclsvc_encode_getaclres(struct svc_rqst *rqstp, struct xdr_stream *xdr) ...@@ -249,34 +249,34 @@ nfsaclsvc_encode_getaclres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
int w; int w;
if (!svcxdr_encode_stat(xdr, resp->status)) if (!svcxdr_encode_stat(xdr, resp->status))
return 0; return false;
if (dentry == NULL || d_really_is_negative(dentry)) if (dentry == NULL || d_really_is_negative(dentry))
return 1; return true;
inode = d_inode(dentry); inode = d_inode(dentry);
if (!svcxdr_encode_fattr(rqstp, xdr, &resp->fh, &resp->stat)) if (!svcxdr_encode_fattr(rqstp, xdr, &resp->fh, &resp->stat))
return 0; return false;
if (xdr_stream_encode_u32(xdr, resp->mask) < 0) if (xdr_stream_encode_u32(xdr, resp->mask) < 0)
return 0; return false;
rqstp->rq_res.page_len = w = nfsacl_size( rqstp->rq_res.page_len = w = nfsacl_size(
(resp->mask & NFS_ACL) ? resp->acl_access : NULL, (resp->mask & NFS_ACL) ? resp->acl_access : NULL,
(resp->mask & NFS_DFACL) ? resp->acl_default : NULL); (resp->mask & NFS_DFACL) ? resp->acl_default : NULL);
while (w > 0) { while (w > 0) {
if (!*(rqstp->rq_next_page++)) if (!*(rqstp->rq_next_page++))
return 1; return true;
w -= PAGE_SIZE; w -= PAGE_SIZE;
} }
if (!nfs_stream_encode_acl(xdr, inode, resp->acl_access, if (!nfs_stream_encode_acl(xdr, inode, resp->acl_access,
resp->mask & NFS_ACL, 0)) resp->mask & NFS_ACL, 0))
return 0; return false;
if (!nfs_stream_encode_acl(xdr, inode, resp->acl_default, if (!nfs_stream_encode_acl(xdr, inode, resp->acl_default,
resp->mask & NFS_DFACL, NFS_ACL_DEFAULT)) resp->mask & NFS_DFACL, NFS_ACL_DEFAULT))
return 0; return false;
return 1; return true;
} }
/* ACCESS */ /* ACCESS */
...@@ -286,17 +286,17 @@ nfsaclsvc_encode_accessres(struct svc_rqst *rqstp, struct xdr_stream *xdr) ...@@ -286,17 +286,17 @@ nfsaclsvc_encode_accessres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
struct nfsd3_accessres *resp = rqstp->rq_resp; struct nfsd3_accessres *resp = rqstp->rq_resp;
if (!svcxdr_encode_stat(xdr, resp->status)) if (!svcxdr_encode_stat(xdr, resp->status))
return 0; return false;
switch (resp->status) { switch (resp->status) {
case nfs_ok: case nfs_ok:
if (!svcxdr_encode_fattr(rqstp, xdr, &resp->fh, &resp->stat)) if (!svcxdr_encode_fattr(rqstp, xdr, &resp->fh, &resp->stat))
return 0; return false;
if (xdr_stream_encode_u32(xdr, resp->access) < 0) if (xdr_stream_encode_u32(xdr, resp->access) < 0)
return 0; return false;
break; break;
} }
return 1; return true;
} }
/* /*
......
...@@ -395,6 +395,7 @@ struct svc_deferred_req { ...@@ -395,6 +395,7 @@ struct svc_deferred_req {
size_t addrlen; size_t addrlen;
struct sockaddr_storage daddr; /* where reply must come from */ struct sockaddr_storage daddr; /* where reply must come from */
size_t daddrlen; size_t daddrlen;
void *xprt_ctxt;
struct cache_deferred_req handle; struct cache_deferred_req handle;
size_t xprt_hlen; size_t xprt_hlen;
int argslen; int argslen;
......
...@@ -2015,17 +2015,18 @@ DECLARE_EVENT_CLASS(svc_deferred_event, ...@@ -2015,17 +2015,18 @@ DECLARE_EVENT_CLASS(svc_deferred_event,
TP_STRUCT__entry( TP_STRUCT__entry(
__field(const void *, dr) __field(const void *, dr)
__field(u32, xid) __field(u32, xid)
__string(addr, dr->xprt->xpt_remotebuf) __array(__u8, addr, INET6_ADDRSTRLEN + 10)
), ),
TP_fast_assign( TP_fast_assign(
__entry->dr = dr; __entry->dr = dr;
__entry->xid = be32_to_cpu(*(__be32 *)(dr->args + __entry->xid = be32_to_cpu(*(__be32 *)(dr->args +
(dr->xprt_hlen>>2))); (dr->xprt_hlen>>2)));
__assign_str(addr, dr->xprt->xpt_remotebuf); snprintf(__entry->addr, sizeof(__entry->addr) - 1,
"%pISpc", (struct sockaddr *)&dr->addr);
), ),
TP_printk("addr=%s dr=%p xid=0x%08x", __get_str(addr), __entry->dr, TP_printk("addr=%s dr=%p xid=0x%08x", __entry->addr, __entry->dr,
__entry->xid) __entry->xid)
); );
......
...@@ -1231,6 +1231,8 @@ static struct cache_deferred_req *svc_defer(struct cache_req *req) ...@@ -1231,6 +1231,8 @@ static struct cache_deferred_req *svc_defer(struct cache_req *req)
dr->daddr = rqstp->rq_daddr; dr->daddr = rqstp->rq_daddr;
dr->argslen = rqstp->rq_arg.len >> 2; dr->argslen = rqstp->rq_arg.len >> 2;
dr->xprt_hlen = rqstp->rq_xprt_hlen; dr->xprt_hlen = rqstp->rq_xprt_hlen;
dr->xprt_ctxt = rqstp->rq_xprt_ctxt;
rqstp->rq_xprt_ctxt = NULL;
/* back up head to the start of the buffer and copy */ /* back up head to the start of the buffer and copy */
skip = rqstp->rq_arg.len - rqstp->rq_arg.head[0].iov_len; skip = rqstp->rq_arg.len - rqstp->rq_arg.head[0].iov_len;
...@@ -1269,6 +1271,7 @@ static noinline int svc_deferred_recv(struct svc_rqst *rqstp) ...@@ -1269,6 +1271,7 @@ static noinline int svc_deferred_recv(struct svc_rqst *rqstp)
rqstp->rq_xprt_hlen = dr->xprt_hlen; rqstp->rq_xprt_hlen = dr->xprt_hlen;
rqstp->rq_daddr = dr->daddr; rqstp->rq_daddr = dr->daddr;
rqstp->rq_respages = rqstp->rq_pages; rqstp->rq_respages = rqstp->rq_pages;
rqstp->rq_xprt_ctxt = dr->xprt_ctxt;
svc_xprt_received(rqstp->rq_xprt); svc_xprt_received(rqstp->rq_xprt);
return (dr->argslen<<2) - dr->xprt_hlen; return (dr->argslen<<2) - dr->xprt_hlen;
} }
......
...@@ -831,7 +831,7 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp) ...@@ -831,7 +831,7 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp)
goto out_err; goto out_err;
if (ret == 0) if (ret == 0)
goto out_drop; goto out_drop;
rqstp->rq_xprt_hlen = ret; rqstp->rq_xprt_hlen = 0;
if (svc_rdma_is_reverse_direction_reply(xprt, ctxt)) if (svc_rdma_is_reverse_direction_reply(xprt, ctxt))
goto out_backchannel; goto out_backchannel;
......
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