/* SPDX-License-Identifier: GPL-2.0 */1#ifndef _FS_CEPH_SUBVOLUME_METRICS_H2#define _FS_CEPH_SUBVOLUME_METRICS_H34#include <linux/types.h>5#include <linux/rbtree.h>6#include <linux/spinlock.h>7#include <linux/ktime.h>8#include <linux/atomic.h>910struct seq_file;11struct ceph_mds_client;12struct ceph_inode_info;1314/**15* struct ceph_subvol_metric_snapshot - Point-in-time snapshot of subvolume metrics16* @subvolume_id: Subvolume identifier (inode number of subvolume root)17* @read_ops: Number of read operations since last snapshot18* @write_ops: Number of write operations since last snapshot19* @read_bytes: Total bytes read since last snapshot20* @write_bytes: Total bytes written since last snapshot21* @read_latency_us: Sum of read latencies in microseconds (for avg calculation)22* @write_latency_us: Sum of write latencies in microseconds (for avg calculation)23*/24struct ceph_subvol_metric_snapshot {25u64 subvolume_id;26u64 read_ops;27u64 write_ops;28u64 read_bytes;29u64 write_bytes;30u64 read_latency_us;31u64 write_latency_us;32};3334/**35* struct ceph_subvolume_metrics_tracker - Tracks per-subvolume I/O metrics36* @lock: Protects @tree and @nr_entries during concurrent access37* @tree: Red-black tree of per-subvolume entries, keyed by subvolume_id38* @nr_entries: Number of entries currently in @tree39* @enabled: Whether collection is enabled (requires MDS feature support)40* @snapshot_attempts: Debug counter: total ceph_subvolume_metrics_snapshot() calls41* @snapshot_empty: Debug counter: snapshots that found no data to report42* @snapshot_failures: Debug counter: snapshots that failed to allocate memory43* @record_calls: Debug counter: total ceph_subvolume_metrics_record() calls44* @record_disabled: Debug counter: record calls skipped because disabled45* @record_no_subvol: Debug counter: record calls skipped (no subvolume_id)46* @total_read_ops: Cumulative read ops across all snapshots (never reset)47* @total_read_bytes: Cumulative bytes read across all snapshots (never reset)48* @total_write_ops: Cumulative write ops across all snapshots (never reset)49* @total_write_bytes: Cumulative bytes written across all snapshots (never reset)50*/51struct ceph_subvolume_metrics_tracker {52spinlock_t lock;53struct rb_root_cached tree;54u32 nr_entries;55bool enabled;56atomic64_t snapshot_attempts;57atomic64_t snapshot_empty;58atomic64_t snapshot_failures;59atomic64_t record_calls;60atomic64_t record_disabled;61atomic64_t record_no_subvol;62atomic64_t total_read_ops;63atomic64_t total_read_bytes;64atomic64_t total_write_ops;65atomic64_t total_write_bytes;66};6768void ceph_subvolume_metrics_init(struct ceph_subvolume_metrics_tracker *tracker);69void ceph_subvolume_metrics_destroy(struct ceph_subvolume_metrics_tracker *tracker);70void ceph_subvolume_metrics_enable(struct ceph_subvolume_metrics_tracker *tracker,71bool enable);72void ceph_subvolume_metrics_record(struct ceph_subvolume_metrics_tracker *tracker,73u64 subvol_id, bool is_write,74size_t size, u64 latency_us);75int ceph_subvolume_metrics_snapshot(struct ceph_subvolume_metrics_tracker *tracker,76struct ceph_subvol_metric_snapshot **out,77u32 *nr, bool consume);78void ceph_subvolume_metrics_free_snapshot(struct ceph_subvol_metric_snapshot *snapshot);79void ceph_subvolume_metrics_dump(struct ceph_subvolume_metrics_tracker *tracker,80struct seq_file *s);8182void ceph_subvolume_metrics_record_io(struct ceph_mds_client *mdsc,83struct ceph_inode_info *ci,84bool is_write, size_t bytes,85ktime_t start, ktime_t end);8687static inline bool ceph_subvolume_metrics_enabled(88const struct ceph_subvolume_metrics_tracker *tracker)89{90return READ_ONCE(tracker->enabled);91}9293int __init ceph_subvolume_metrics_cache_init(void);94void ceph_subvolume_metrics_cache_destroy(void);9596#endif /* _FS_CEPH_SUBVOLUME_METRICS_H */979899