ext4: main fast-commit commit path
This patch adds main fast commit commit path handlers. The overall
patch can be divided into two inter-related parts:
(A) Metadata updates tracking
This part consists of helper functions to track changes that need
to be committed during a commit operation. These updates are
maintained by Ext4 in different in-memory queues. Following are
the APIs and their short description that are implemented in this
patch:
- ext4_fc_track_link/unlink/creat() - Track unlink. link and creat
operations
- ext4_fc_track_range() - Track changed logical block offsets
inodes
- ext4_fc_track_inode() - Track inodes
- ext4_fc_mark_ineligible() - Mark file system fast commit
ineligible()
- ext4_fc_start_update() / ext4_fc_stop_update() /
ext4_fc_start_ineligible() / ext4_fc_stop_ineligible() These
functions are useful for co-ordinating inode updates with
commits.
(B) Main commit Path
This part consists of functions to convert updates tracked in
in-memory data structures into on-disk commits. Function
ext4_fc_commit() is the main entry point to commit path.
Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Harshad Shirwadkar <harshadshirwadkar@gmail.com>
Link: https://lore.kernel.org/r/20201015203802.3597742-6-harshadshirwadkar@gmail.com
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
This commit is contained in:
committed by
Theodore Ts'o
parent
ff780b91ef
commit
aa75f4d3da
@@ -95,6 +95,16 @@ TRACE_DEFINE_ENUM(ES_REFERENCED_B);
|
||||
{ FALLOC_FL_COLLAPSE_RANGE, "COLLAPSE_RANGE"}, \
|
||||
{ FALLOC_FL_ZERO_RANGE, "ZERO_RANGE"})
|
||||
|
||||
#define show_fc_reason(reason) \
|
||||
__print_symbolic(reason, \
|
||||
{ EXT4_FC_REASON_XATTR, "XATTR"}, \
|
||||
{ EXT4_FC_REASON_CROSS_RENAME, "CROSS_RENAME"}, \
|
||||
{ EXT4_FC_REASON_JOURNAL_FLAG_CHANGE, "JOURNAL_FLAG_CHANGE"}, \
|
||||
{ EXT4_FC_REASON_MEM, "NO_MEM"}, \
|
||||
{ EXT4_FC_REASON_SWAP_BOOT, "SWAP_BOOT"}, \
|
||||
{ EXT4_FC_REASON_RESIZE, "RESIZE"}, \
|
||||
{ EXT4_FC_REASON_RENAME_DIR, "RENAME_DIR"}, \
|
||||
{ EXT4_FC_REASON_FALLOC_RANGE, "FALLOC_RANGE"})
|
||||
|
||||
TRACE_EVENT(ext4_other_inode_update_time,
|
||||
TP_PROTO(struct inode *inode, ino_t orig_ino),
|
||||
@@ -2791,6 +2801,168 @@ TRACE_EVENT(ext4_lazy_itable_init,
|
||||
MAJOR(__entry->dev), MINOR(__entry->dev), __entry->group)
|
||||
);
|
||||
|
||||
TRACE_EVENT(ext4_fc_commit_start,
|
||||
TP_PROTO(struct super_block *sb),
|
||||
|
||||
TP_ARGS(sb),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(dev_t, dev)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->dev = sb->s_dev;
|
||||
),
|
||||
|
||||
TP_printk("fast_commit started on dev %d,%d",
|
||||
MAJOR(__entry->dev), MINOR(__entry->dev))
|
||||
);
|
||||
|
||||
TRACE_EVENT(ext4_fc_commit_stop,
|
||||
TP_PROTO(struct super_block *sb, int nblks, int reason),
|
||||
|
||||
TP_ARGS(sb, nblks, reason),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(dev_t, dev)
|
||||
__field(int, nblks)
|
||||
__field(int, reason)
|
||||
__field(int, num_fc)
|
||||
__field(int, num_fc_ineligible)
|
||||
__field(int, nblks_agg)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->dev = sb->s_dev;
|
||||
__entry->nblks = nblks;
|
||||
__entry->reason = reason;
|
||||
__entry->num_fc = EXT4_SB(sb)->s_fc_stats.fc_num_commits;
|
||||
__entry->num_fc_ineligible =
|
||||
EXT4_SB(sb)->s_fc_stats.fc_ineligible_commits;
|
||||
__entry->nblks_agg = EXT4_SB(sb)->s_fc_stats.fc_numblks;
|
||||
),
|
||||
|
||||
TP_printk("fc on [%d,%d] nblks %d, reason %d, fc = %d, ineligible = %d, agg_nblks %d",
|
||||
MAJOR(__entry->dev), MINOR(__entry->dev),
|
||||
__entry->nblks, __entry->reason, __entry->num_fc,
|
||||
__entry->num_fc_ineligible, __entry->nblks_agg)
|
||||
);
|
||||
|
||||
#define FC_REASON_NAME_STAT(reason) \
|
||||
show_fc_reason(reason), \
|
||||
__entry->sbi->s_fc_stats.fc_ineligible_reason_count[reason]
|
||||
|
||||
TRACE_EVENT(ext4_fc_stats,
|
||||
TP_PROTO(struct super_block *sb),
|
||||
|
||||
TP_ARGS(sb),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(dev_t, dev)
|
||||
__field(struct ext4_sb_info *, sbi)
|
||||
__field(int, count)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->dev = sb->s_dev;
|
||||
__entry->sbi = EXT4_SB(sb);
|
||||
),
|
||||
|
||||
TP_printk("dev %d:%d fc ineligible reasons:\n"
|
||||
"%s:%d, %s:%d, %s:%d, %s:%d, %s:%d, %s:%d, %s:%d, %s,%d; "
|
||||
"num_commits:%ld, ineligible: %ld, numblks: %ld",
|
||||
MAJOR(__entry->dev), MINOR(__entry->dev),
|
||||
FC_REASON_NAME_STAT(EXT4_FC_REASON_XATTR),
|
||||
FC_REASON_NAME_STAT(EXT4_FC_REASON_CROSS_RENAME),
|
||||
FC_REASON_NAME_STAT(EXT4_FC_REASON_JOURNAL_FLAG_CHANGE),
|
||||
FC_REASON_NAME_STAT(EXT4_FC_REASON_MEM),
|
||||
FC_REASON_NAME_STAT(EXT4_FC_REASON_SWAP_BOOT),
|
||||
FC_REASON_NAME_STAT(EXT4_FC_REASON_RESIZE),
|
||||
FC_REASON_NAME_STAT(EXT4_FC_REASON_RENAME_DIR),
|
||||
FC_REASON_NAME_STAT(EXT4_FC_REASON_FALLOC_RANGE),
|
||||
__entry->sbi->s_fc_stats.fc_num_commits,
|
||||
__entry->sbi->s_fc_stats.fc_ineligible_commits,
|
||||
__entry->sbi->s_fc_stats.fc_numblks)
|
||||
|
||||
);
|
||||
|
||||
#define DEFINE_TRACE_DENTRY_EVENT(__type) \
|
||||
TRACE_EVENT(ext4_fc_track_##__type, \
|
||||
TP_PROTO(struct inode *inode, struct dentry *dentry, int ret), \
|
||||
\
|
||||
TP_ARGS(inode, dentry, ret), \
|
||||
\
|
||||
TP_STRUCT__entry( \
|
||||
__field(dev_t, dev) \
|
||||
__field(int, ino) \
|
||||
__field(int, error) \
|
||||
), \
|
||||
\
|
||||
TP_fast_assign( \
|
||||
__entry->dev = inode->i_sb->s_dev; \
|
||||
__entry->ino = inode->i_ino; \
|
||||
__entry->error = ret; \
|
||||
), \
|
||||
\
|
||||
TP_printk("dev %d:%d, inode %d, error %d, fc_%s", \
|
||||
MAJOR(__entry->dev), MINOR(__entry->dev), \
|
||||
__entry->ino, __entry->error, \
|
||||
#__type) \
|
||||
)
|
||||
|
||||
DEFINE_TRACE_DENTRY_EVENT(create);
|
||||
DEFINE_TRACE_DENTRY_EVENT(link);
|
||||
DEFINE_TRACE_DENTRY_EVENT(unlink);
|
||||
|
||||
TRACE_EVENT(ext4_fc_track_inode,
|
||||
TP_PROTO(struct inode *inode, int ret),
|
||||
|
||||
TP_ARGS(inode, ret),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(dev_t, dev)
|
||||
__field(int, ino)
|
||||
__field(int, error)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->dev = inode->i_sb->s_dev;
|
||||
__entry->ino = inode->i_ino;
|
||||
__entry->error = ret;
|
||||
),
|
||||
|
||||
TP_printk("dev %d:%d, inode %d, error %d",
|
||||
MAJOR(__entry->dev), MINOR(__entry->dev),
|
||||
__entry->ino, __entry->error)
|
||||
);
|
||||
|
||||
TRACE_EVENT(ext4_fc_track_range,
|
||||
TP_PROTO(struct inode *inode, long start, long end, int ret),
|
||||
|
||||
TP_ARGS(inode, start, end, ret),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(dev_t, dev)
|
||||
__field(int, ino)
|
||||
__field(long, start)
|
||||
__field(long, end)
|
||||
__field(int, error)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->dev = inode->i_sb->s_dev;
|
||||
__entry->ino = inode->i_ino;
|
||||
__entry->start = start;
|
||||
__entry->end = end;
|
||||
__entry->error = ret;
|
||||
),
|
||||
|
||||
TP_printk("dev %d:%d, inode %d, error %d, start %ld, end %ld",
|
||||
MAJOR(__entry->dev), MINOR(__entry->dev),
|
||||
__entry->ino, __entry->error, __entry->start,
|
||||
__entry->end)
|
||||
);
|
||||
|
||||
#endif /* _TRACE_EXT4_H */
|
||||
|
||||
/* This part must be outside protection */
|
||||
|
||||
Reference in New Issue
Block a user