Commit c1488c97 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
Loading
Loading
Loading
Loading
+15 −10
Original line number Diff line number Diff line
@@ -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));
}

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
nfsd_file_do_unhash(struct nfsd_file *nf)
{
@@ -295,19 +302,15 @@ nfsd_file_put_noref(struct nfsd_file *nf)
void
nfsd_file_put(struct nfsd_file *nf)
{
	bool is_hashed;

	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);
		return;
	}

	filemap_flush(nf->nf_file->f_mapping);
	is_hashed = test_bit(NFSD_FILE_HASHED, &nf->nf_flags) != 0;
	} else {
		nfsd_file_put_noref(nf);
	if (is_hashed)
		if (nf->nf_file)
			nfsd_file_schedule_laundrette();
	}
	if (atomic_long_read(&nfsd_filecache_count) >= NFSD_FILE_LRU_LIMIT)
		nfsd_file_gc();
}
@@ -328,6 +331,7 @@ nfsd_file_dispose_list(struct list_head *dispose)
	while(!list_empty(dispose)) {
		nf = list_first_entry(dispose, struct nfsd_file, nf_lru);
		list_del(&nf->nf_lru);
		nfsd_file_flush(nf);
		nfsd_file_put_noref(nf);
	}
}
@@ -341,6 +345,7 @@ nfsd_file_dispose_list_sync(struct list_head *dispose)
	while(!list_empty(dispose)) {
		nf = list_first_entry(dispose, struct nfsd_file, nf_lru);
		list_del(&nf->nf_lru);
		nfsd_file_flush(nf);
		if (!refcount_dec_and_test(&nf->nf_ref))
			continue;
		if (nfsd_file_free(nf))
+12 −12
Original line number Diff line number Diff line
@@ -249,34 +249,34 @@ nfsaclsvc_encode_getaclres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
	int w;

	if (!svcxdr_encode_stat(xdr, resp->status))
		return 0;
		return false;

	if (dentry == NULL || d_really_is_negative(dentry))
		return 1;
		return true;
	inode = d_inode(dentry);

	if (!svcxdr_encode_fattr(rqstp, xdr, &resp->fh, &resp->stat))
		return 0;
		return false;
	if (xdr_stream_encode_u32(xdr, resp->mask) < 0)
		return 0;
		return false;

	rqstp->rq_res.page_len = w = nfsacl_size(
		(resp->mask & NFS_ACL)   ? resp->acl_access  : NULL,
		(resp->mask & NFS_DFACL) ? resp->acl_default : NULL);
	while (w > 0) {
		if (!*(rqstp->rq_next_page++))
			return 1;
			return true;
		w -= PAGE_SIZE;
	}

	if (!nfs_stream_encode_acl(xdr, inode, resp->acl_access,
				   resp->mask & NFS_ACL, 0))
		return 0;
		return false;
	if (!nfs_stream_encode_acl(xdr, inode, resp->acl_default,
				   resp->mask & NFS_DFACL, NFS_ACL_DEFAULT))
		return 0;
		return false;

	return 1;
	return true;
}

/* ACCESS */
@@ -286,17 +286,17 @@ nfsaclsvc_encode_accessres(struct svc_rqst *rqstp, struct xdr_stream *xdr)
	struct nfsd3_accessres *resp = rqstp->rq_resp;

	if (!svcxdr_encode_stat(xdr, resp->status))
		return 0;
		return false;
	switch (resp->status) {
	case nfs_ok:
		if (!svcxdr_encode_fattr(rqstp, xdr, &resp->fh, &resp->stat))
			return 0;
			return false;
		if (xdr_stream_encode_u32(xdr, resp->access) < 0)
			return 0;
			return false;
		break;
	}

	return 1;
	return true;
}

/*
+1 −0
Original line number Diff line number Diff line
@@ -395,6 +395,7 @@ struct svc_deferred_req {
	size_t			addrlen;
	struct sockaddr_storage	daddr;	/* where reply must come from */
	size_t			daddrlen;
	void			*xprt_ctxt;
	struct cache_deferred_req handle;
	size_t			xprt_hlen;
	int			argslen;
+4 −3
Original line number Diff line number Diff line
@@ -2015,17 +2015,18 @@ DECLARE_EVENT_CLASS(svc_deferred_event,
	TP_STRUCT__entry(
		__field(const void *, dr)
		__field(u32, xid)
		__string(addr, dr->xprt->xpt_remotebuf)
		__array(__u8, addr, INET6_ADDRSTRLEN + 10)
	),

	TP_fast_assign(
		__entry->dr = dr;
		__entry->xid = be32_to_cpu(*(__be32 *)(dr->args +
						       (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)
);

+3 −0
Original line number Diff line number Diff line
@@ -1231,6 +1231,8 @@ static struct cache_deferred_req *svc_defer(struct cache_req *req)
		dr->daddr = rqstp->rq_daddr;
		dr->argslen = rqstp->rq_arg.len >> 2;
		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 */
		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)
	rqstp->rq_xprt_hlen   = dr->xprt_hlen;
	rqstp->rq_daddr       = dr->daddr;
	rqstp->rq_respages    = rqstp->rq_pages;
	rqstp->rq_xprt_ctxt   = dr->xprt_ctxt;
	svc_xprt_received(rqstp->rq_xprt);
	return (dr->argslen<<2) - dr->xprt_hlen;
}
Loading