[go: nahoru, domu]

1279afbad4e54acbd61bf88a54a73af3bbfdeb5ddKent Overstreet#ifndef _BCACHE_WRITEBACK_H
2279afbad4e54acbd61bf88a54a73af3bbfdeb5ddKent Overstreet#define _BCACHE_WRITEBACK_H
3279afbad4e54acbd61bf88a54a73af3bbfdeb5ddKent Overstreet
472c270612bd33192fa836ad0f2939af1ca218292Kent Overstreet#define CUTOFF_WRITEBACK	40
572c270612bd33192fa836ad0f2939af1ca218292Kent Overstreet#define CUTOFF_WRITEBACK_SYNC	70
672c270612bd33192fa836ad0f2939af1ca218292Kent Overstreet
7279afbad4e54acbd61bf88a54a73af3bbfdeb5ddKent Overstreetstatic inline uint64_t bcache_dev_sectors_dirty(struct bcache_device *d)
8279afbad4e54acbd61bf88a54a73af3bbfdeb5ddKent Overstreet{
9279afbad4e54acbd61bf88a54a73af3bbfdeb5ddKent Overstreet	uint64_t i, ret = 0;
10279afbad4e54acbd61bf88a54a73af3bbfdeb5ddKent Overstreet
11279afbad4e54acbd61bf88a54a73af3bbfdeb5ddKent Overstreet	for (i = 0; i < d->nr_stripes; i++)
12279afbad4e54acbd61bf88a54a73af3bbfdeb5ddKent Overstreet		ret += atomic_read(d->stripe_sectors_dirty + i);
13279afbad4e54acbd61bf88a54a73af3bbfdeb5ddKent Overstreet
14279afbad4e54acbd61bf88a54a73af3bbfdeb5ddKent Overstreet	return ret;
15279afbad4e54acbd61bf88a54a73af3bbfdeb5ddKent Overstreet}
16279afbad4e54acbd61bf88a54a73af3bbfdeb5ddKent Overstreet
1748a915a87f0bd98c3d68d029acf223a2e5116f07Kent Overstreetstatic inline unsigned offset_to_stripe(struct bcache_device *d,
1848a915a87f0bd98c3d68d029acf223a2e5116f07Kent Overstreet					uint64_t offset)
1948a915a87f0bd98c3d68d029acf223a2e5116f07Kent Overstreet{
2048a915a87f0bd98c3d68d029acf223a2e5116f07Kent Overstreet	do_div(offset, d->stripe_size);
2148a915a87f0bd98c3d68d029acf223a2e5116f07Kent Overstreet	return offset;
2248a915a87f0bd98c3d68d029acf223a2e5116f07Kent Overstreet}
2348a915a87f0bd98c3d68d029acf223a2e5116f07Kent Overstreet
2448a915a87f0bd98c3d68d029acf223a2e5116f07Kent Overstreetstatic inline bool bcache_dev_stripe_dirty(struct cached_dev *dc,
2572c270612bd33192fa836ad0f2939af1ca218292Kent Overstreet					   uint64_t offset,
2672c270612bd33192fa836ad0f2939af1ca218292Kent Overstreet					   unsigned nr_sectors)
2772c270612bd33192fa836ad0f2939af1ca218292Kent Overstreet{
2848a915a87f0bd98c3d68d029acf223a2e5116f07Kent Overstreet	unsigned stripe = offset_to_stripe(&dc->disk, offset);
2972c270612bd33192fa836ad0f2939af1ca218292Kent Overstreet
3072c270612bd33192fa836ad0f2939af1ca218292Kent Overstreet	while (1) {
3148a915a87f0bd98c3d68d029acf223a2e5116f07Kent Overstreet		if (atomic_read(dc->disk.stripe_sectors_dirty + stripe))
3272c270612bd33192fa836ad0f2939af1ca218292Kent Overstreet			return true;
3372c270612bd33192fa836ad0f2939af1ca218292Kent Overstreet
3448a915a87f0bd98c3d68d029acf223a2e5116f07Kent Overstreet		if (nr_sectors <= dc->disk.stripe_size)
3572c270612bd33192fa836ad0f2939af1ca218292Kent Overstreet			return false;
3672c270612bd33192fa836ad0f2939af1ca218292Kent Overstreet
3748a915a87f0bd98c3d68d029acf223a2e5116f07Kent Overstreet		nr_sectors -= dc->disk.stripe_size;
3872c270612bd33192fa836ad0f2939af1ca218292Kent Overstreet		stripe++;
3972c270612bd33192fa836ad0f2939af1ca218292Kent Overstreet	}
4072c270612bd33192fa836ad0f2939af1ca218292Kent Overstreet}
4172c270612bd33192fa836ad0f2939af1ca218292Kent Overstreet
4272c270612bd33192fa836ad0f2939af1ca218292Kent Overstreetstatic inline bool should_writeback(struct cached_dev *dc, struct bio *bio,
4372c270612bd33192fa836ad0f2939af1ca218292Kent Overstreet				    unsigned cache_mode, bool would_skip)
4472c270612bd33192fa836ad0f2939af1ca218292Kent Overstreet{
4572c270612bd33192fa836ad0f2939af1ca218292Kent Overstreet	unsigned in_use = dc->disk.c->gc_stats.in_use;
4672c270612bd33192fa836ad0f2939af1ca218292Kent Overstreet
4772c270612bd33192fa836ad0f2939af1ca218292Kent Overstreet	if (cache_mode != CACHE_MODE_WRITEBACK ||
48c4d951ddb66fe1d087447b0ba65c4fa4446f1083Kent Overstreet	    test_bit(BCACHE_DEV_DETACHING, &dc->disk.flags) ||
4972c270612bd33192fa836ad0f2939af1ca218292Kent Overstreet	    in_use > CUTOFF_WRITEBACK_SYNC)
5072c270612bd33192fa836ad0f2939af1ca218292Kent Overstreet		return false;
5172c270612bd33192fa836ad0f2939af1ca218292Kent Overstreet
5272c270612bd33192fa836ad0f2939af1ca218292Kent Overstreet	if (dc->partial_stripes_expensive &&
534f024f3797c43cb4b73cd2c50cec728842d0e49eKent Overstreet	    bcache_dev_stripe_dirty(dc, bio->bi_iter.bi_sector,
5472c270612bd33192fa836ad0f2939af1ca218292Kent Overstreet				    bio_sectors(bio)))
5572c270612bd33192fa836ad0f2939af1ca218292Kent Overstreet		return true;
5672c270612bd33192fa836ad0f2939af1ca218292Kent Overstreet
5772c270612bd33192fa836ad0f2939af1ca218292Kent Overstreet	if (would_skip)
5872c270612bd33192fa836ad0f2939af1ca218292Kent Overstreet		return false;
5972c270612bd33192fa836ad0f2939af1ca218292Kent Overstreet
6072c270612bd33192fa836ad0f2939af1ca218292Kent Overstreet	return bio->bi_rw & REQ_SYNC ||
6172c270612bd33192fa836ad0f2939af1ca218292Kent Overstreet		in_use <= CUTOFF_WRITEBACK;
6272c270612bd33192fa836ad0f2939af1ca218292Kent Overstreet}
6372c270612bd33192fa836ad0f2939af1ca218292Kent Overstreet
645e6926daac267dd99552ae613f041a9e88bbf258Kent Overstreetstatic inline void bch_writeback_queue(struct cached_dev *dc)
655e6926daac267dd99552ae613f041a9e88bbf258Kent Overstreet{
665e6926daac267dd99552ae613f041a9e88bbf258Kent Overstreet	wake_up_process(dc->writeback_thread);
675e6926daac267dd99552ae613f041a9e88bbf258Kent Overstreet}
685e6926daac267dd99552ae613f041a9e88bbf258Kent Overstreet
695e6926daac267dd99552ae613f041a9e88bbf258Kent Overstreetstatic inline void bch_writeback_add(struct cached_dev *dc)
705e6926daac267dd99552ae613f041a9e88bbf258Kent Overstreet{
715e6926daac267dd99552ae613f041a9e88bbf258Kent Overstreet	if (!atomic_read(&dc->has_dirty) &&
725e6926daac267dd99552ae613f041a9e88bbf258Kent Overstreet	    !atomic_xchg(&dc->has_dirty, 1)) {
735e6926daac267dd99552ae613f041a9e88bbf258Kent Overstreet		atomic_inc(&dc->count);
745e6926daac267dd99552ae613f041a9e88bbf258Kent Overstreet
755e6926daac267dd99552ae613f041a9e88bbf258Kent Overstreet		if (BDEV_STATE(&dc->sb) != BDEV_STATE_DIRTY) {
765e6926daac267dd99552ae613f041a9e88bbf258Kent Overstreet			SET_BDEV_STATE(&dc->sb, BDEV_STATE_DIRTY);
775e6926daac267dd99552ae613f041a9e88bbf258Kent Overstreet			/* XXX: should do this synchronously */
785e6926daac267dd99552ae613f041a9e88bbf258Kent Overstreet			bch_write_bdev_super(dc, NULL);
795e6926daac267dd99552ae613f041a9e88bbf258Kent Overstreet		}
805e6926daac267dd99552ae613f041a9e88bbf258Kent Overstreet
815e6926daac267dd99552ae613f041a9e88bbf258Kent Overstreet		bch_writeback_queue(dc);
825e6926daac267dd99552ae613f041a9e88bbf258Kent Overstreet	}
835e6926daac267dd99552ae613f041a9e88bbf258Kent Overstreet}
845e6926daac267dd99552ae613f041a9e88bbf258Kent Overstreet
85279afbad4e54acbd61bf88a54a73af3bbfdeb5ddKent Overstreetvoid bcache_dev_sectors_dirty_add(struct cache_set *, unsigned, uint64_t, int);
86279afbad4e54acbd61bf88a54a73af3bbfdeb5ddKent Overstreet
87279afbad4e54acbd61bf88a54a73af3bbfdeb5ddKent Overstreetvoid bch_sectors_dirty_init(struct cached_dev *dc);
889e5c353510b26500bd6b8309823ac9ef2837b761Slava Pestovvoid bch_cached_dev_writeback_init(struct cached_dev *);
899e5c353510b26500bd6b8309823ac9ef2837b761Slava Pestovint bch_cached_dev_writeback_start(struct cached_dev *);
90279afbad4e54acbd61bf88a54a73af3bbfdeb5ddKent Overstreet
91279afbad4e54acbd61bf88a54a73af3bbfdeb5ddKent Overstreet#endif
92