#include "compress.h"
#include "sysfs.h"
#include "btree_cache.h"
+#include "btree_io.h"
#include "btree_iter.h"
#include "btree_update.h"
+#include "btree_update_interior.h"
#include "btree_gc.h"
#include "buckets.h"
#include "inode.h"
read_attribute(compression_stats);
read_attribute(journal_debug);
read_attribute(journal_pins);
+read_attribute(btree_updates);
+read_attribute(dirty_btree_nodes);
read_attribute(internal_uuid);
rw_attribute(journal_write_delay_ms);
rw_attribute(journal_reclaim_delay_ms);
+rw_attribute(writeback_pages_max);
+
rw_attribute(discard);
rw_attribute(cache_replacement_policy);
sysfs_print(journal_write_delay_ms, c->journal.write_delay_ms);
sysfs_print(journal_reclaim_delay_ms, c->journal.reclaim_delay_ms);
+ sysfs_print(writeback_pages_max, c->writeback_pages_max);
+
sysfs_print(block_size, block_bytes(c));
sysfs_print(btree_node_size, btree_bytes(c));
sysfs_hprint(btree_cache_size, bch2_btree_cache_size(c));
if (attr == &sysfs_journal_pins)
return bch2_journal_print_pins(&c->journal, buf);
+ if (attr == &sysfs_btree_updates)
+ return bch2_btree_updates_print(c, buf);
+
+ if (attr == &sysfs_dirty_btree_nodes)
+ return bch2_dirty_btree_nodes_print(c, buf);
+
if (attr == &sysfs_compression_stats)
return bch2_compression_stats(c, buf);
sysfs_strtoul(journal_write_delay_ms, c->journal.write_delay_ms);
sysfs_strtoul(journal_reclaim_delay_ms, c->journal.reclaim_delay_ms);
+ if (attr == &sysfs_writeback_pages_max)
+ c->writeback_pages_max = strtoul_restrict_or_return(buf, 1, UINT_MAX);
+
if (attr == &sysfs_btree_gc_periodic) {
ssize_t ret = strtoul_safe(buf, c->btree_gc_periodic)
?: (ssize_t) size;
&sysfs_journal_write_delay_ms,
&sysfs_journal_reclaim_delay_ms,
+ &sysfs_writeback_pages_max,
+
&sysfs_tiering_percent,
&sysfs_compression_stats,
&sysfs_alloc_debug,
&sysfs_journal_debug,
&sysfs_journal_pins,
+ &sysfs_btree_updates,
+ &sysfs_dirty_btree_nodes,
&sysfs_read_realloc_races,
&sysfs_extent_migrate_done,
NULL
};
-typedef unsigned (bucket_map_fn)(struct bch_dev *, struct bucket *, void *);
+typedef unsigned (bucket_map_fn)(struct bch_dev *, size_t, void *);
-static unsigned bucket_priority_fn(struct bch_dev *ca, struct bucket *g,
+static unsigned bucket_priority_fn(struct bch_dev *ca, size_t b,
void *private)
{
+ struct bucket *g = bucket(ca, b);
int rw = (private ? 1 : 0);
return ca->fs->prio_clock[rw].hand - g->prio[rw];
}
-static unsigned bucket_sectors_used_fn(struct bch_dev *ca, struct bucket *g,
+static unsigned bucket_sectors_used_fn(struct bch_dev *ca, size_t b,
void *private)
{
+ struct bucket *g = bucket(ca, b);
return bucket_sectors_used(g->mark);
}
-static unsigned bucket_oldest_gen_fn(struct bch_dev *ca, struct bucket *g,
+static unsigned bucket_oldest_gen_fn(struct bch_dev *ca, size_t b,
void *private)
{
- return bucket_gc_gen(ca, g);
+ return bucket_gc_gen(ca, b);
}
static ssize_t show_quantiles(struct bch_dev *ca, char *buf,
int cmp(const void *l, const void *r)
{ return *((unsigned *) r) - *((unsigned *) l); }
- size_t n = ca->mi.nbuckets, i;
+ size_t i, n;
/* Compute 31 quantiles */
unsigned q[31], *p;
ssize_t ret = 0;
- p = vzalloc(ca->mi.nbuckets * sizeof(unsigned));
- if (!p)
+ down_read(&ca->bucket_lock);
+ n = ca->mi.nbuckets;
+
+ p = vzalloc(n * sizeof(unsigned));
+ if (!p) {
+ up_read(&ca->bucket_lock);
return -ENOMEM;
+ }
for (i = ca->mi.first_bucket; i < n; i++)
- p[i] = fn(ca, &ca->buckets[i], private);
+ p[i] = fn(ca, i, private);
sort(p, n, sizeof(unsigned), cmp, NULL);
+ up_read(&ca->bucket_lock);
while (n &&
!p[n - 1])
buf[ret - 1] = '\n';
return ret;
-
}
static ssize_t show_reserve_stats(struct bch_dev *ca, char *buf)