linux/fs/bcachefs/disk_accounting.c

// SPDX-License-Identifier: GPL-2.0

#include "bcachefs.h"
#include "bcachefs_ioctl.h"
#include "btree_cache.h"
#include "btree_journal_iter.h"
#include "btree_update.h"
#include "btree_write_buffer.h"
#include "buckets.h"
#include "compress.h"
#include "disk_accounting.h"
#include "error.h"
#include "journal_io.h"
#include "replicas.h"

/*
 * Notes on disk accounting:
 *
 * We have two parallel sets of counters to be concerned with, and both must be
 * kept in sync.
 *
 *  - Persistent/on disk accounting, stored in the accounting btree and updated
 *    via btree write buffer updates that treat new accounting keys as deltas to
 *    apply to existing values. But reading from a write buffer btree is
 *    expensive, so we also have
 *
 *  - In memory accounting, where accounting is stored as an array of percpu
 *    counters, indexed by an eytzinger array of disk acounting keys/bpos (which
 *    are the same thing, excepting byte swabbing on big endian).
 *
 *    Cheap to read, but non persistent.
 *
 * Disk accounting updates are generated by transactional triggers; these run as
 * keys enter and leave the btree, and can compare old and new versions of keys;
 * the output of these triggers are deltas to the various counters.
 *
 * Disk accounting updates are done as btree write buffer updates, where the
 * counters in the disk accounting key are deltas that will be applied to the
 * counter in the btree when the key is flushed by the write buffer (or journal
 * replay).
 *
 * To do a disk accounting update:
 * - initialize a disk_accounting_pos, to specify which counter is being update
 * - initialize counter deltas, as an array of 1-3 s64s
 * - call bch2_disk_accounting_mod()
 *
 * This queues up the accounting update to be done at transaction commit time.
 * Underneath, it's a normal btree write buffer update.
 *
 * The transaction commit path is responsible for propagating updates to the in
 * memory counters, with bch2_accounting_mem_mod().
 *
 * The commit path also assigns every disk accounting update a unique version
 * number, based on the journal sequence number and offset within that journal
 * buffer; this is used by journal replay to determine which updates have been
 * done.
 *
 * The transaction commit path also ensures that replicas entry accounting
 * updates are properly marked in the superblock (so that we know whether we can
 * mount without data being unavailable); it will update the superblock if
 * bch2_accounting_mem_mod() tells it to.
 */

static const char * const disk_accounting_type_strs[] =;

static inline void accounting_key_init(struct bkey_i *k, struct disk_accounting_pos *pos,
				       s64 *d, unsigned nr)
{}

int bch2_disk_accounting_mod(struct btree_trans *trans,
			     struct disk_accounting_pos *k,
			     s64 *d, unsigned nr, bool gc)
{}

int bch2_mod_dev_cached_sectors(struct btree_trans *trans,
				unsigned dev, s64 sectors,
				bool gc)
{}

int bch2_accounting_invalid(struct bch_fs *c, struct bkey_s_c k,
			    enum bch_validate_flags flags,
			    struct printbuf *err)
{}

void bch2_accounting_key_to_text(struct printbuf *out, struct disk_accounting_pos *k)
{}

void bch2_accounting_to_text(struct printbuf *out, struct bch_fs *c, struct bkey_s_c k)
{}

void bch2_accounting_swab(struct bkey_s k)
{}

static inline bool accounting_to_replicas(struct bch_replicas_entry_v1 *r, struct bpos p)
{}

static int bch2_accounting_update_sb_one(struct bch_fs *c, struct bpos p)
{}

/*
 * Ensure accounting keys being updated are present in the superblock, when
 * applicable (i.e. replicas updates)
 */
int bch2_accounting_update_sb(struct btree_trans *trans)
{}

static int __bch2_accounting_mem_insert(struct bch_fs *c, struct bkey_s_c_accounting a)
{}

int bch2_accounting_mem_insert(struct bch_fs *c, struct bkey_s_c_accounting a, bool gc)
{}

static bool accounting_mem_entry_is_zero(struct accounting_mem_entry *e)
{}

void bch2_accounting_mem_gc(struct bch_fs *c)
{}

/*
 * Read out accounting keys for replicas entries, as an array of
 * bch_replicas_usage entries.
 *
 * Note: this may be deprecated/removed at smoe point in the future and replaced
 * with something more general, it exists to support the ioctl used by the
 * 'bcachefs fs usage' command.
 */
int bch2_fs_replicas_usage_read(struct bch_fs *c, darray_char *usage)
{}

int bch2_fs_accounting_read(struct bch_fs *c, darray_char *out_buf, unsigned accounting_types_mask)
{}

void bch2_fs_accounting_to_text(struct printbuf *out, struct bch_fs *c)
{}

static void bch2_accounting_free_counters(struct bch_accounting_mem *acc, bool gc)
{}

int bch2_gc_accounting_start(struct bch_fs *c)
{}

int bch2_gc_accounting_done(struct bch_fs *c)
{}

static int accounting_read_key(struct btree_trans *trans, struct bkey_s_c k)
{}

/*
 * At startup time, initialize the in memory accounting from the btree (and
 * journal)
 */
int bch2_accounting_read(struct bch_fs *c)
{}

int bch2_dev_usage_remove(struct bch_fs *c, unsigned dev)
{}

int bch2_dev_usage_init(struct bch_dev *ca, bool gc)
{}

void bch2_verify_accounting_clean(struct bch_fs *c)
{}

void bch2_accounting_gc_free(struct bch_fs *c)
{}

void bch2_fs_accounting_exit(struct bch_fs *c)
{}