nfsd: Add a tracepoint for errors in nfsd4_clone_file_range()

Since a clone error commit can cause the boot verifier to change,
we should trace those errors.

Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
[ cel: Addressed a checkpatch.pl splat in fs/nfsd/vfs.h ]
This commit is contained in:
Trond Myklebust 2021-12-18 20:38:00 -05:00 committed by Chuck Lever
parent 2c445a0e72
commit a2f4c3fa4d
4 changed files with 69 additions and 4 deletions

View File

@ -1101,7 +1101,7 @@ nfsd4_clone(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
if (status)
goto out;
status = nfsd4_clone_file_range(src, clone->cl_src_pos,
status = nfsd4_clone_file_range(rqstp, src, clone->cl_src_pos,
dst, clone->cl_dst_pos, clone->cl_count,
EX_ISSYNC(cstate->current_fh.fh_export));

View File

@ -399,6 +399,56 @@ TRACE_EVENT(nfsd_dirent,
)
)
DECLARE_EVENT_CLASS(nfsd_copy_err_class,
TP_PROTO(struct svc_rqst *rqstp,
struct svc_fh *src_fhp,
loff_t src_offset,
struct svc_fh *dst_fhp,
loff_t dst_offset,
u64 count,
int status),
TP_ARGS(rqstp, src_fhp, src_offset, dst_fhp, dst_offset, count, status),
TP_STRUCT__entry(
__field(u32, xid)
__field(u32, src_fh_hash)
__field(loff_t, src_offset)
__field(u32, dst_fh_hash)
__field(loff_t, dst_offset)
__field(u64, count)
__field(int, status)
),
TP_fast_assign(
__entry->xid = be32_to_cpu(rqstp->rq_xid);
__entry->src_fh_hash = knfsd_fh_hash(&src_fhp->fh_handle);
__entry->src_offset = src_offset;
__entry->dst_fh_hash = knfsd_fh_hash(&dst_fhp->fh_handle);
__entry->dst_offset = dst_offset;
__entry->count = count;
__entry->status = status;
),
TP_printk("xid=0x%08x src_fh_hash=0x%08x src_offset=%lld "
"dst_fh_hash=0x%08x dst_offset=%lld "
"count=%llu status=%d",
__entry->xid, __entry->src_fh_hash, __entry->src_offset,
__entry->dst_fh_hash, __entry->dst_offset,
(unsigned long long)__entry->count,
__entry->status)
)
#define DEFINE_NFSD_COPY_ERR_EVENT(name) \
DEFINE_EVENT(nfsd_copy_err_class, nfsd_##name, \
TP_PROTO(struct svc_rqst *rqstp, \
struct svc_fh *src_fhp, \
loff_t src_offset, \
struct svc_fh *dst_fhp, \
loff_t dst_offset, \
u64 count, \
int status), \
TP_ARGS(rqstp, src_fhp, src_offset, dst_fhp, dst_offset, \
count, status))
DEFINE_NFSD_COPY_ERR_EVENT(clone_file_range_err);
#include "state.h"
#include "filecache.h"
#include "vfs.h"

View File

@ -40,6 +40,7 @@
#include "../internal.h"
#include "acl.h"
#include "idmap.h"
#include "xdr4.h"
#endif /* CONFIG_NFSD_V4 */
#include "nfsd.h"
@ -517,8 +518,15 @@ __be32 nfsd4_set_nfs4_label(struct svc_rqst *rqstp, struct svc_fh *fhp,
}
#endif
__be32 nfsd4_clone_file_range(struct nfsd_file *nf_src, u64 src_pos,
struct nfsd_file *nf_dst, u64 dst_pos, u64 count, bool sync)
static struct nfsd4_compound_state *nfsd4_get_cstate(struct svc_rqst *rqstp)
{
return &((struct nfsd4_compoundres *)rqstp->rq_resp)->cstate;
}
__be32 nfsd4_clone_file_range(struct svc_rqst *rqstp,
struct nfsd_file *nf_src, u64 src_pos,
struct nfsd_file *nf_dst, u64 dst_pos,
u64 count, bool sync)
{
struct file *src = nf_src->nf_file;
struct file *dst = nf_dst->nf_file;
@ -545,6 +553,12 @@ __be32 nfsd4_clone_file_range(struct nfsd_file *nf_src, u64 src_pos,
if (!status)
status = commit_inode_metadata(file_inode(src));
if (status < 0) {
trace_nfsd_clone_file_range_err(rqstp,
&nfsd4_get_cstate(rqstp)->save_fh,
src_pos,
&nfsd4_get_cstate(rqstp)->current_fh,
dst_pos,
count, status);
nfsd_reset_boot_verifier(net_generic(nf_dst->nf_net,
nfsd_net_id));
ret = nfserrno(status);

View File

@ -57,7 +57,8 @@ __be32 nfsd4_set_nfs4_label(struct svc_rqst *, struct svc_fh *,
struct xdr_netobj *);
__be32 nfsd4_vfs_fallocate(struct svc_rqst *, struct svc_fh *,
struct file *, loff_t, loff_t, int);
__be32 nfsd4_clone_file_range(struct nfsd_file *nf_src, u64 src_pos,
__be32 nfsd4_clone_file_range(struct svc_rqst *rqstp,
struct nfsd_file *nf_src, u64 src_pos,
struct nfsd_file *nf_dst, u64 dst_pos,
u64 count, bool sync);
#endif /* CONFIG_NFSD_V4 */