diff options
-rw-r--r-- | drivers/md/bcache/extents.h | 23 | ||||
-rw-r--r-- | drivers/md/bcache/fs-io.c | 12 |
2 files changed, 29 insertions, 6 deletions
diff --git a/drivers/md/bcache/extents.h b/drivers/md/bcache/extents.h index 42db3d1ca933..e861492c731e 100644 --- a/drivers/md/bcache/extents.h +++ b/drivers/md/bcache/extents.h @@ -354,6 +354,29 @@ static inline struct bch_extent_crc64 crc_to_64(const union bch_extent_crc *crc) } } +static inline bool bkey_extent_is_compressed(struct cache_set *c, + struct bkey_s_c k) +{ + struct bkey_s_c_extent e; + const struct bch_extent_ptr *ptr; + const union bch_extent_crc *crc; + + switch (k.k->type) { + case BCH_EXTENT: + case BCH_EXTENT_CACHED: + e = bkey_s_c_to_extent(k); + + extent_for_each_ptr_crc(e, ptr, crc) + if (bch_extent_ptr_is_dirty(c, e, ptr) && + crc_to_64(crc).compression_type != BCH_COMPRESSION_NONE && + crc_to_64(crc).compressed_size < k.k->size) + return true; + return true; + default: + return false; + } +} + void extent_adjust_pointers(struct bkey_s_extent, union bch_extent_entry *); /* Doesn't cleanup redundant crcs */ diff --git a/drivers/md/bcache/fs-io.c b/drivers/md/bcache/fs-io.c index 5c8ff61cee69..0ffe10fb0b98 100644 --- a/drivers/md/bcache/fs-io.c +++ b/drivers/md/bcache/fs-io.c @@ -699,6 +699,10 @@ static void bchfs_read(struct cache_set *c, struct bch_read_bio *rbio, u64 inode unsigned bytes, sectors; bool is_last; + if (!bkey_extent_is_allocation(k.k) || + bkey_extent_is_compressed(c, k)) + bch_mark_pages_unalloc(bio); + bch_extent_pick_ptr(c, k, &pick); bch_btree_iter_unlock(&iter); @@ -715,11 +719,6 @@ static void bchfs_read(struct cache_set *c, struct bch_read_bio *rbio, u64 inode is_last = bytes == bio->bi_iter.bi_size; swap(bio->bi_iter.bi_size, bytes); - if (!(k.k->type == BCH_RESERVATION || - (pick.ca && - pick.crc.compression_type == BCH_COMPRESSION_NONE))) - bch_mark_pages_unalloc(bio); - if (bkey_extent_is_allocation(k.k)) bch_add_page_sectors(bio, k.k); @@ -2350,7 +2349,8 @@ static long bch_fallocate(struct inode *inode, int mode, sectors = reservation.k.size; - if (!bkey_extent_is_allocation(k.k)) { + if (!bkey_extent_is_allocation(k.k) || + bkey_extent_is_compressed(c, k)) { ret = bch_disk_reservation_get(c, &disk_res, sectors); if (ret) goto err_put_sectors_dirty; |