From d41f4304007d2954f8513f3c3d845028fefe79ec Mon Sep 17 00:00:00 2001 From: Anna Schumaker Date: Wed, 14 Jun 2023 16:49:37 -0400 Subject: [RFC v2] NFS: Add debugging printk()s to trace the xdr->scratch buffer I'm trying to figure out at what point the xdr->scratch buffer is allocated, freed, set, and reset to figure out why READ_PLUS suddenly thinks it's a NULL pointer with length 16. Signed-off-by: Anna Schumaker --- fs/nfs/nfs42xdr.c | 2 ++ fs/nfs/read.c | 8 +++++++- include/linux/sunrpc/xdr.h | 1 + net/sunrpc/xdr.c | 4 ++++ 4 files changed, 14 insertions(+), 1 deletion(-) diff --git a/fs/nfs/nfs42xdr.c b/fs/nfs/nfs42xdr.c index 20aa5e746497..6a4eade2400b 100644 --- a/fs/nfs/nfs42xdr.c +++ b/fs/nfs/nfs42xdr.c @@ -1351,6 +1351,8 @@ static int nfs4_xdr_dec_read_plus(struct rpc_rqst *rqstp, struct compound_hdr hdr; int status; + printk(KERN_INFO "%s(hdr=%px, scratch=%px)\n", __func__, + container_of(res, struct nfs_pgio_header, res), res->scratch); xdr_set_scratch_buffer(xdr, res->scratch, READ_PLUS_SCRATCH_SIZE); status = decode_compound_hdr(xdr, &hdr); diff --git a/fs/nfs/read.c b/fs/nfs/read.c index 7dc21a48e3e7..7b93316a52de 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c @@ -47,8 +47,11 @@ static struct nfs_pgio_header *nfs_readhdr_alloc(void) static void nfs_readhdr_free(struct nfs_pgio_header *rhdr) { - if (rhdr->res.scratch != NULL) + if (rhdr->res.scratch != NULL) { + printk(KERN_INFO "%s(hdr=%px, scratch=%px)\n", + __func__, rhdr, rhdr->res.scratch); kfree(rhdr->res.scratch); + } kmem_cache_free(nfs_rdata_cachep, rhdr); } @@ -114,6 +117,9 @@ bool nfs_read_alloc_scratch(struct nfs_pgio_header *hdr, size_t size) { WARN_ON(hdr->res.scratch != NULL); hdr->res.scratch = kmalloc(size, GFP_KERNEL); + printk(KERN_INFO "\n"); + printk(KERN_INFO "%s(hdr=%px, size=%zd) = %px\n", + __func__, hdr, size, hdr->res.scratch); return hdr->res.scratch != NULL; } EXPORT_SYMBOL_GPL(nfs_read_alloc_scratch); diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h index d917618a3058..1c9a54e9efac 100644 --- a/include/linux/sunrpc/xdr.h +++ b/include/linux/sunrpc/xdr.h @@ -286,6 +286,7 @@ extern unsigned int xdr_stream_zero(struct xdr_stream *xdr, unsigned int offset, static inline void xdr_set_scratch_buffer(struct xdr_stream *xdr, void *buf, size_t buflen) { + WARN_ON(buf != NULL && xdr->scratch.iov_base != NULL); xdr->scratch.iov_base = buf; xdr->scratch.iov_len = buflen; } diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index 391b336d97de..37c8f7e519dd 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c @@ -1440,6 +1440,8 @@ static __be32 *xdr_copy_to_scratch(struct xdr_stream *xdr, size_t nbytes) p = __xdr_inline_decode(xdr, cplen); if (p == NULL) return NULL; + printk(KERN_INFO " %s(%d): memcpy(%px, %px, %zd)\n", + __func__, __LINE__, cpdest, p, cplen); memcpy(cpdest, p, cplen); if (!xdr_set_next_buffer(xdr)) goto out_overflow; @@ -1448,6 +1450,8 @@ static __be32 *xdr_copy_to_scratch(struct xdr_stream *xdr, size_t nbytes) p = __xdr_inline_decode(xdr, nbytes); if (p == NULL) return NULL; + printk(KERN_INFO " %s(%d): memcpy(%px, %px, %zd)\n", + __func__, __LINE__, cpdest, p, nbytes); memcpy(cpdest, p, nbytes); return xdr->scratch.iov_base; out_overflow: -- 2.41.0