Skip to content

Commit fada32e

Browse files
Christoph Hellwigamschuma-ntap
authored andcommitted
nfs: pass explicit offset/count to trace events
nfs_folio_length is unsafe to use without having the folio locked and a check for a NULL ->f_mapping that protects against truncations and can lead to kernel crashes. E.g. when running xfstests generic/065 with all nfs trace points enabled. Follow the model of the XFS trace points and pass in an explіcit offset and length. This has the additional benefit that these values can be more accurate as some of the users touch partial folio ranges. Fixes: eb5654b ("NFS: Enable tracing of nfs_invalidate_folio() and nfs_launder_folio()") Reported-by: Chuck Lever <[email protected]> Signed-off-by: Christoph Hellwig <[email protected]> Signed-off-by: Anna Schumaker <[email protected]>
1 parent 39c910a commit fada32e

File tree

4 files changed

+33
-26
lines changed

4 files changed

+33
-26
lines changed

fs/nfs/file.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,7 @@ static void nfs_invalidate_folio(struct folio *folio, size_t offset,
436436
/* Cancel any unstarted writes on this page */
437437
nfs_wb_folio_cancel(inode, folio);
438438
folio_wait_private_2(folio); /* [DEPRECATED] */
439-
trace_nfs_invalidate_folio(inode, folio);
439+
trace_nfs_invalidate_folio(inode, folio_pos(folio) + offset, length);
440440
}
441441

442442
/*
@@ -504,7 +504,8 @@ static int nfs_launder_folio(struct folio *folio)
504504

505505
folio_wait_private_2(folio); /* [DEPRECATED] */
506506
ret = nfs_wb_folio(inode, folio);
507-
trace_nfs_launder_folio_done(inode, folio, ret);
507+
trace_nfs_launder_folio_done(inode, folio_pos(folio),
508+
folio_size(folio), ret);
508509
return ret;
509510
}
510511

fs/nfs/nfstrace.h

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -939,18 +939,19 @@ TRACE_EVENT(nfs_sillyrename_unlink,
939939
DECLARE_EVENT_CLASS(nfs_folio_event,
940940
TP_PROTO(
941941
const struct inode *inode,
942-
struct folio *folio
942+
loff_t offset,
943+
size_t count
943944
),
944945

945-
TP_ARGS(inode, folio),
946+
TP_ARGS(inode, offset, count),
946947

947948
TP_STRUCT__entry(
948949
__field(dev_t, dev)
949950
__field(u32, fhandle)
950951
__field(u64, fileid)
951952
__field(u64, version)
952953
__field(loff_t, offset)
953-
__field(u32, count)
954+
__field(size_t, count)
954955
),
955956

956957
TP_fast_assign(
@@ -960,13 +961,13 @@ DECLARE_EVENT_CLASS(nfs_folio_event,
960961
__entry->fileid = nfsi->fileid;
961962
__entry->fhandle = nfs_fhandle_hash(&nfsi->fh);
962963
__entry->version = inode_peek_iversion_raw(inode);
963-
__entry->offset = folio_file_pos(folio);
964-
__entry->count = nfs_folio_length(folio);
964+
__entry->offset = offset,
965+
__entry->count = count;
965966
),
966967

967968
TP_printk(
968969
"fileid=%02x:%02x:%llu fhandle=0x%08x version=%llu "
969-
"offset=%lld count=%u",
970+
"offset=%lld count=%zu",
970971
MAJOR(__entry->dev), MINOR(__entry->dev),
971972
(unsigned long long)__entry->fileid,
972973
__entry->fhandle, __entry->version,
@@ -978,18 +979,20 @@ DECLARE_EVENT_CLASS(nfs_folio_event,
978979
DEFINE_EVENT(nfs_folio_event, name, \
979980
TP_PROTO( \
980981
const struct inode *inode, \
981-
struct folio *folio \
982+
loff_t offset, \
983+
size_t count \
982984
), \
983-
TP_ARGS(inode, folio))
985+
TP_ARGS(inode, offset, count))
984986

985987
DECLARE_EVENT_CLASS(nfs_folio_event_done,
986988
TP_PROTO(
987989
const struct inode *inode,
988-
struct folio *folio,
990+
loff_t offset,
991+
size_t count,
989992
int ret
990993
),
991994

992-
TP_ARGS(inode, folio, ret),
995+
TP_ARGS(inode, offset, count, ret),
993996

994997
TP_STRUCT__entry(
995998
__field(dev_t, dev)
@@ -998,7 +1001,7 @@ DECLARE_EVENT_CLASS(nfs_folio_event_done,
9981001
__field(u64, fileid)
9991002
__field(u64, version)
10001003
__field(loff_t, offset)
1001-
__field(u32, count)
1004+
__field(size_t, count)
10021005
),
10031006

10041007
TP_fast_assign(
@@ -1008,14 +1011,14 @@ DECLARE_EVENT_CLASS(nfs_folio_event_done,
10081011
__entry->fileid = nfsi->fileid;
10091012
__entry->fhandle = nfs_fhandle_hash(&nfsi->fh);
10101013
__entry->version = inode_peek_iversion_raw(inode);
1011-
__entry->offset = folio_file_pos(folio);
1012-
__entry->count = nfs_folio_length(folio);
1014+
__entry->offset = offset,
1015+
__entry->count = count,
10131016
__entry->ret = ret;
10141017
),
10151018

10161019
TP_printk(
10171020
"fileid=%02x:%02x:%llu fhandle=0x%08x version=%llu "
1018-
"offset=%lld count=%u ret=%d",
1021+
"offset=%lld count=%zu ret=%d",
10191022
MAJOR(__entry->dev), MINOR(__entry->dev),
10201023
(unsigned long long)__entry->fileid,
10211024
__entry->fhandle, __entry->version,
@@ -1027,10 +1030,11 @@ DECLARE_EVENT_CLASS(nfs_folio_event_done,
10271030
DEFINE_EVENT(nfs_folio_event_done, name, \
10281031
TP_PROTO( \
10291032
const struct inode *inode, \
1030-
struct folio *folio, \
1033+
loff_t offset, \
1034+
size_t count, \
10311035
int ret \
10321036
), \
1033-
TP_ARGS(inode, folio, ret))
1037+
TP_ARGS(inode, offset, count, ret))
10341038

10351039
DEFINE_NFS_FOLIO_EVENT(nfs_aop_readpage);
10361040
DEFINE_NFS_FOLIO_EVENT_DONE(nfs_aop_readpage_done);

fs/nfs/read.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -333,13 +333,15 @@ int nfs_read_add_folio(struct nfs_pageio_descriptor *pgio,
333333
int nfs_read_folio(struct file *file, struct folio *folio)
334334
{
335335
struct inode *inode = file_inode(file);
336+
loff_t pos = folio_pos(folio);
337+
size_t len = folio_size(folio);
336338
struct nfs_pageio_descriptor pgio;
337339
struct nfs_open_context *ctx;
338340
int ret;
339341

340-
trace_nfs_aop_readpage(inode, folio);
342+
trace_nfs_aop_readpage(inode, pos, len);
341343
nfs_inc_stats(inode, NFSIOS_VFSREADPAGE);
342-
task_io_account_read(folio_size(folio));
344+
task_io_account_read(len);
343345

344346
/*
345347
* Try to flush any pending writes to the file..
@@ -383,7 +385,7 @@ int nfs_read_folio(struct file *file, struct folio *folio)
383385
out_put:
384386
put_nfs_open_context(ctx);
385387
out:
386-
trace_nfs_aop_readpage_done(inode, folio, ret);
388+
trace_nfs_aop_readpage_done(inode, pos, len, ret);
387389
return ret;
388390
out_unlock:
389391
folio_unlock(folio);

fs/nfs/write.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2063,17 +2063,17 @@ int nfs_wb_folio_cancel(struct inode *inode, struct folio *folio)
20632063
*/
20642064
int nfs_wb_folio(struct inode *inode, struct folio *folio)
20652065
{
2066-
loff_t range_start = folio_file_pos(folio);
2067-
loff_t range_end = range_start + (loff_t)folio_size(folio) - 1;
2066+
loff_t range_start = folio_pos(folio);
2067+
size_t len = folio_size(folio);
20682068
struct writeback_control wbc = {
20692069
.sync_mode = WB_SYNC_ALL,
20702070
.nr_to_write = 0,
20712071
.range_start = range_start,
2072-
.range_end = range_end,
2072+
.range_end = range_start + len - 1,
20732073
};
20742074
int ret;
20752075

2076-
trace_nfs_writeback_folio(inode, folio);
2076+
trace_nfs_writeback_folio(inode, range_start, len);
20772077

20782078
for (;;) {
20792079
folio_wait_writeback(folio);
@@ -2091,7 +2091,7 @@ int nfs_wb_folio(struct inode *inode, struct folio *folio)
20912091
goto out_error;
20922092
}
20932093
out_error:
2094-
trace_nfs_writeback_folio_done(inode, folio, ret);
2094+
trace_nfs_writeback_folio_done(inode, range_start, len, ret);
20952095
return ret;
20962096
}
20972097

0 commit comments

Comments
 (0)