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