0001
0002
0003
0004
0005
0006
0007
0008 #ifndef DM_ZONED_H
0009 #define DM_ZONED_H
0010
0011 #include <linux/types.h>
0012 #include <linux/blkdev.h>
0013 #include <linux/device-mapper.h>
0014 #include <linux/dm-kcopyd.h>
0015 #include <linux/list.h>
0016 #include <linux/spinlock.h>
0017 #include <linux/mutex.h>
0018 #include <linux/workqueue.h>
0019 #include <linux/rwsem.h>
0020 #include <linux/rbtree.h>
0021 #include <linux/radix-tree.h>
0022 #include <linux/shrinker.h>
0023
0024
0025
0026
0027 #define DMZ_BLOCK_SHIFT 12
0028 #define DMZ_BLOCK_SIZE (1 << DMZ_BLOCK_SHIFT)
0029 #define DMZ_BLOCK_MASK (DMZ_BLOCK_SIZE - 1)
0030
0031 #define DMZ_BLOCK_SHIFT_BITS (DMZ_BLOCK_SHIFT + 3)
0032 #define DMZ_BLOCK_SIZE_BITS (1 << DMZ_BLOCK_SHIFT_BITS)
0033 #define DMZ_BLOCK_MASK_BITS (DMZ_BLOCK_SIZE_BITS - 1)
0034
0035 #define DMZ_BLOCK_SECTORS_SHIFT (DMZ_BLOCK_SHIFT - SECTOR_SHIFT)
0036 #define DMZ_BLOCK_SECTORS (DMZ_BLOCK_SIZE >> SECTOR_SHIFT)
0037 #define DMZ_BLOCK_SECTORS_MASK (DMZ_BLOCK_SECTORS - 1)
0038
0039
0040
0041
0042 #define dmz_blk2sect(b) ((sector_t)(b) << DMZ_BLOCK_SECTORS_SHIFT)
0043 #define dmz_sect2blk(s) ((sector_t)(s) >> DMZ_BLOCK_SECTORS_SHIFT)
0044
0045 #define dmz_bio_block(bio) dmz_sect2blk((bio)->bi_iter.bi_sector)
0046 #define dmz_bio_blocks(bio) dmz_sect2blk(bio_sectors(bio))
0047
0048 struct dmz_metadata;
0049 struct dmz_reclaim;
0050
0051
0052
0053
0054 struct dmz_dev {
0055 struct block_device *bdev;
0056 struct dmz_metadata *metadata;
0057 struct dmz_reclaim *reclaim;
0058
0059 uuid_t uuid;
0060
0061 sector_t capacity;
0062
0063 unsigned int dev_idx;
0064
0065 unsigned int nr_zones;
0066 unsigned int zone_offset;
0067
0068 unsigned int flags;
0069
0070 sector_t zone_nr_sectors;
0071
0072 unsigned int nr_rnd;
0073 atomic_t unmap_nr_rnd;
0074 struct list_head unmap_rnd_list;
0075 struct list_head map_rnd_list;
0076
0077 unsigned int nr_seq;
0078 atomic_t unmap_nr_seq;
0079 struct list_head unmap_seq_list;
0080 struct list_head map_seq_list;
0081 };
0082
0083 #define dmz_bio_chunk(zmd, bio) ((bio)->bi_iter.bi_sector >> \
0084 dmz_zone_nr_sectors_shift(zmd))
0085 #define dmz_chunk_block(zmd, b) ((b) & (dmz_zone_nr_blocks(zmd) - 1))
0086
0087
0088 #define DMZ_BDEV_DYING (1 << 0)
0089 #define DMZ_CHECK_BDEV (2 << 0)
0090 #define DMZ_BDEV_REGULAR (4 << 0)
0091
0092
0093
0094
0095 struct dm_zone {
0096
0097 struct list_head link;
0098
0099
0100 struct dmz_dev *dev;
0101
0102
0103 unsigned long flags;
0104
0105
0106 atomic_t refcount;
0107
0108
0109 unsigned int id;
0110
0111
0112 unsigned int wp_block;
0113
0114
0115 unsigned int weight;
0116
0117
0118 unsigned int chunk;
0119
0120
0121
0122
0123
0124
0125 struct dm_zone *bzone;
0126 };
0127
0128
0129
0130
0131 enum {
0132
0133 DMZ_CACHE,
0134 DMZ_RND,
0135 DMZ_SEQ,
0136
0137
0138 DMZ_OFFLINE,
0139 DMZ_READ_ONLY,
0140
0141
0142 DMZ_META,
0143 DMZ_DATA,
0144 DMZ_BUF,
0145 DMZ_RESERVED,
0146
0147
0148 DMZ_RECLAIM,
0149 DMZ_SEQ_WRITE_ERR,
0150 DMZ_RECLAIM_TERMINATE,
0151 };
0152
0153
0154
0155
0156 #define dmz_is_cache(z) test_bit(DMZ_CACHE, &(z)->flags)
0157 #define dmz_is_rnd(z) test_bit(DMZ_RND, &(z)->flags)
0158 #define dmz_is_seq(z) test_bit(DMZ_SEQ, &(z)->flags)
0159 #define dmz_is_empty(z) ((z)->wp_block == 0)
0160 #define dmz_is_offline(z) test_bit(DMZ_OFFLINE, &(z)->flags)
0161 #define dmz_is_readonly(z) test_bit(DMZ_READ_ONLY, &(z)->flags)
0162 #define dmz_in_reclaim(z) test_bit(DMZ_RECLAIM, &(z)->flags)
0163 #define dmz_is_reserved(z) test_bit(DMZ_RESERVED, &(z)->flags)
0164 #define dmz_seq_write_err(z) test_bit(DMZ_SEQ_WRITE_ERR, &(z)->flags)
0165 #define dmz_reclaim_should_terminate(z) \
0166 test_bit(DMZ_RECLAIM_TERMINATE, &(z)->flags)
0167
0168 #define dmz_is_meta(z) test_bit(DMZ_META, &(z)->flags)
0169 #define dmz_is_buf(z) test_bit(DMZ_BUF, &(z)->flags)
0170 #define dmz_is_data(z) test_bit(DMZ_DATA, &(z)->flags)
0171
0172 #define dmz_weight(z) ((z)->weight)
0173
0174
0175
0176
0177 #define dmz_dev_info(dev, format, args...) \
0178 DMINFO("(%pg): " format, (dev)->bdev, ## args)
0179
0180 #define dmz_dev_err(dev, format, args...) \
0181 DMERR("(%pg): " format, (dev)->bdev, ## args)
0182
0183 #define dmz_dev_warn(dev, format, args...) \
0184 DMWARN("(%pg): " format, (dev)->bdev, ## args)
0185
0186 #define dmz_dev_debug(dev, format, args...) \
0187 DMDEBUG("(%pg): " format, (dev)->bdev, ## args)
0188
0189
0190
0191
0192 int dmz_ctr_metadata(struct dmz_dev *dev, int num_dev,
0193 struct dmz_metadata **zmd, const char *devname);
0194 void dmz_dtr_metadata(struct dmz_metadata *zmd);
0195 int dmz_resume_metadata(struct dmz_metadata *zmd);
0196
0197 void dmz_lock_map(struct dmz_metadata *zmd);
0198 void dmz_unlock_map(struct dmz_metadata *zmd);
0199 void dmz_lock_metadata(struct dmz_metadata *zmd);
0200 void dmz_unlock_metadata(struct dmz_metadata *zmd);
0201 void dmz_lock_flush(struct dmz_metadata *zmd);
0202 void dmz_unlock_flush(struct dmz_metadata *zmd);
0203 int dmz_flush_metadata(struct dmz_metadata *zmd);
0204 const char *dmz_metadata_label(struct dmz_metadata *zmd);
0205
0206 sector_t dmz_start_sect(struct dmz_metadata *zmd, struct dm_zone *zone);
0207 sector_t dmz_start_block(struct dmz_metadata *zmd, struct dm_zone *zone);
0208 unsigned int dmz_nr_chunks(struct dmz_metadata *zmd);
0209
0210 bool dmz_check_dev(struct dmz_metadata *zmd);
0211 bool dmz_dev_is_dying(struct dmz_metadata *zmd);
0212
0213 #define DMZ_ALLOC_RND 0x01
0214 #define DMZ_ALLOC_CACHE 0x02
0215 #define DMZ_ALLOC_SEQ 0x04
0216 #define DMZ_ALLOC_RECLAIM 0x10
0217
0218 struct dm_zone *dmz_alloc_zone(struct dmz_metadata *zmd,
0219 unsigned int dev_idx, unsigned long flags);
0220 void dmz_free_zone(struct dmz_metadata *zmd, struct dm_zone *zone);
0221
0222 void dmz_map_zone(struct dmz_metadata *zmd, struct dm_zone *zone,
0223 unsigned int chunk);
0224 void dmz_unmap_zone(struct dmz_metadata *zmd, struct dm_zone *zone);
0225 unsigned int dmz_nr_zones(struct dmz_metadata *zmd);
0226 unsigned int dmz_nr_cache_zones(struct dmz_metadata *zmd);
0227 unsigned int dmz_nr_unmap_cache_zones(struct dmz_metadata *zmd);
0228 unsigned int dmz_nr_rnd_zones(struct dmz_metadata *zmd, int idx);
0229 unsigned int dmz_nr_unmap_rnd_zones(struct dmz_metadata *zmd, int idx);
0230 unsigned int dmz_nr_seq_zones(struct dmz_metadata *zmd, int idx);
0231 unsigned int dmz_nr_unmap_seq_zones(struct dmz_metadata *zmd, int idx);
0232 unsigned int dmz_zone_nr_blocks(struct dmz_metadata *zmd);
0233 unsigned int dmz_zone_nr_blocks_shift(struct dmz_metadata *zmd);
0234 unsigned int dmz_zone_nr_sectors(struct dmz_metadata *zmd);
0235 unsigned int dmz_zone_nr_sectors_shift(struct dmz_metadata *zmd);
0236
0237
0238
0239
0240 static inline void dmz_activate_zone(struct dm_zone *zone)
0241 {
0242 atomic_inc(&zone->refcount);
0243 }
0244
0245 int dmz_lock_zone_reclaim(struct dm_zone *zone);
0246 void dmz_unlock_zone_reclaim(struct dm_zone *zone);
0247 struct dm_zone *dmz_get_zone_for_reclaim(struct dmz_metadata *zmd,
0248 unsigned int dev_idx, bool idle);
0249
0250 struct dm_zone *dmz_get_chunk_mapping(struct dmz_metadata *zmd,
0251 unsigned int chunk, enum req_op op);
0252 void dmz_put_chunk_mapping(struct dmz_metadata *zmd, struct dm_zone *zone);
0253 struct dm_zone *dmz_get_chunk_buffer(struct dmz_metadata *zmd,
0254 struct dm_zone *dzone);
0255
0256 int dmz_validate_blocks(struct dmz_metadata *zmd, struct dm_zone *zone,
0257 sector_t chunk_block, unsigned int nr_blocks);
0258 int dmz_invalidate_blocks(struct dmz_metadata *zmd, struct dm_zone *zone,
0259 sector_t chunk_block, unsigned int nr_blocks);
0260 int dmz_block_valid(struct dmz_metadata *zmd, struct dm_zone *zone,
0261 sector_t chunk_block);
0262 int dmz_first_valid_block(struct dmz_metadata *zmd, struct dm_zone *zone,
0263 sector_t *chunk_block);
0264 int dmz_copy_valid_blocks(struct dmz_metadata *zmd, struct dm_zone *from_zone,
0265 struct dm_zone *to_zone);
0266 int dmz_merge_valid_blocks(struct dmz_metadata *zmd, struct dm_zone *from_zone,
0267 struct dm_zone *to_zone, sector_t chunk_block);
0268
0269
0270
0271
0272 int dmz_ctr_reclaim(struct dmz_metadata *zmd, struct dmz_reclaim **zrc, int idx);
0273 void dmz_dtr_reclaim(struct dmz_reclaim *zrc);
0274 void dmz_suspend_reclaim(struct dmz_reclaim *zrc);
0275 void dmz_resume_reclaim(struct dmz_reclaim *zrc);
0276 void dmz_reclaim_bio_acc(struct dmz_reclaim *zrc);
0277 void dmz_schedule_reclaim(struct dmz_reclaim *zrc);
0278
0279
0280
0281
0282 bool dmz_bdev_is_dying(struct dmz_dev *dmz_dev);
0283 bool dmz_check_bdev(struct dmz_dev *dmz_dev);
0284
0285
0286
0287
0288
0289 static inline void dmz_deactivate_zone(struct dm_zone *zone)
0290 {
0291 dmz_reclaim_bio_acc(zone->dev->reclaim);
0292 atomic_dec(&zone->refcount);
0293 }
0294
0295
0296
0297
0298 static inline bool dmz_is_active(struct dm_zone *zone)
0299 {
0300 return atomic_read(&zone->refcount);
0301 }
0302
0303 #endif