18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Block Translation Table library 48c2ecf20Sopenharmony_ci * Copyright (c) 2014-2015, Intel Corporation. 58c2ecf20Sopenharmony_ci */ 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#ifndef _LINUX_BTT_H 88c2ecf20Sopenharmony_ci#define _LINUX_BTT_H 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include <linux/badblocks.h> 118c2ecf20Sopenharmony_ci#include <linux/types.h> 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#define BTT_SIG_LEN 16 148c2ecf20Sopenharmony_ci#define BTT_SIG "BTT_ARENA_INFO\0" 158c2ecf20Sopenharmony_ci#define MAP_ENT_SIZE 4 168c2ecf20Sopenharmony_ci#define MAP_TRIM_SHIFT 31 178c2ecf20Sopenharmony_ci#define MAP_TRIM_MASK (1 << MAP_TRIM_SHIFT) 188c2ecf20Sopenharmony_ci#define MAP_ERR_SHIFT 30 198c2ecf20Sopenharmony_ci#define MAP_ERR_MASK (1 << MAP_ERR_SHIFT) 208c2ecf20Sopenharmony_ci#define MAP_LBA_MASK (~((1 << MAP_TRIM_SHIFT) | (1 << MAP_ERR_SHIFT))) 218c2ecf20Sopenharmony_ci#define MAP_ENT_NORMAL 0xC0000000 228c2ecf20Sopenharmony_ci#define LOG_GRP_SIZE sizeof(struct log_group) 238c2ecf20Sopenharmony_ci#define LOG_ENT_SIZE sizeof(struct log_entry) 248c2ecf20Sopenharmony_ci#define ARENA_MIN_SIZE (1UL << 24) /* 16 MB */ 258c2ecf20Sopenharmony_ci#define ARENA_MAX_SIZE (1ULL << 39) /* 512 GB */ 268c2ecf20Sopenharmony_ci#define RTT_VALID (1UL << 31) 278c2ecf20Sopenharmony_ci#define RTT_INVALID 0 288c2ecf20Sopenharmony_ci#define BTT_PG_SIZE 4096 298c2ecf20Sopenharmony_ci#define BTT_DEFAULT_NFREE ND_MAX_LANES 308c2ecf20Sopenharmony_ci#define LOG_SEQ_INIT 1 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci#define IB_FLAG_ERROR 0x00000001 338c2ecf20Sopenharmony_ci#define IB_FLAG_ERROR_MASK 0x00000001 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci#define ent_lba(ent) (ent & MAP_LBA_MASK) 368c2ecf20Sopenharmony_ci#define ent_e_flag(ent) (!!(ent & MAP_ERR_MASK)) 378c2ecf20Sopenharmony_ci#define ent_z_flag(ent) (!!(ent & MAP_TRIM_MASK)) 388c2ecf20Sopenharmony_ci#define set_e_flag(ent) (ent |= MAP_ERR_MASK) 398c2ecf20Sopenharmony_ci/* 'normal' is both e and z flags set */ 408c2ecf20Sopenharmony_ci#define ent_normal(ent) (ent_e_flag(ent) && ent_z_flag(ent)) 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_cienum btt_init_state { 438c2ecf20Sopenharmony_ci INIT_UNCHECKED = 0, 448c2ecf20Sopenharmony_ci INIT_NOTFOUND, 458c2ecf20Sopenharmony_ci INIT_READY 468c2ecf20Sopenharmony_ci}; 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci/* 498c2ecf20Sopenharmony_ci * A log group represents one log 'lane', and consists of four log entries. 508c2ecf20Sopenharmony_ci * Two of the four entries are valid entries, and the remaining two are 518c2ecf20Sopenharmony_ci * padding. Due to an old bug in the padding location, we need to perform a 528c2ecf20Sopenharmony_ci * test to determine the padding scheme being used, and use that scheme 538c2ecf20Sopenharmony_ci * thereafter. 548c2ecf20Sopenharmony_ci * 558c2ecf20Sopenharmony_ci * In kernels prior to 4.15, 'log group' would have actual log entries at 568c2ecf20Sopenharmony_ci * indices (0, 2) and padding at indices (1, 3), where as the correct/updated 578c2ecf20Sopenharmony_ci * format has log entries at indices (0, 1) and padding at indices (2, 3). 588c2ecf20Sopenharmony_ci * 598c2ecf20Sopenharmony_ci * Old (pre 4.15) format: 608c2ecf20Sopenharmony_ci * +-----------------+-----------------+ 618c2ecf20Sopenharmony_ci * | ent[0] | ent[1] | 628c2ecf20Sopenharmony_ci * | 16B | 16B | 638c2ecf20Sopenharmony_ci * | lba/old/new/seq | pad | 648c2ecf20Sopenharmony_ci * +-----------------------------------+ 658c2ecf20Sopenharmony_ci * | ent[2] | ent[3] | 668c2ecf20Sopenharmony_ci * | 16B | 16B | 678c2ecf20Sopenharmony_ci * | lba/old/new/seq | pad | 688c2ecf20Sopenharmony_ci * +-----------------+-----------------+ 698c2ecf20Sopenharmony_ci * 708c2ecf20Sopenharmony_ci * New format: 718c2ecf20Sopenharmony_ci * +-----------------+-----------------+ 728c2ecf20Sopenharmony_ci * | ent[0] | ent[1] | 738c2ecf20Sopenharmony_ci * | 16B | 16B | 748c2ecf20Sopenharmony_ci * | lba/old/new/seq | lba/old/new/seq | 758c2ecf20Sopenharmony_ci * +-----------------------------------+ 768c2ecf20Sopenharmony_ci * | ent[2] | ent[3] | 778c2ecf20Sopenharmony_ci * | 16B | 16B | 788c2ecf20Sopenharmony_ci * | pad | pad | 798c2ecf20Sopenharmony_ci * +-----------------+-----------------+ 808c2ecf20Sopenharmony_ci * 818c2ecf20Sopenharmony_ci * We detect during start-up which format is in use, and set 828c2ecf20Sopenharmony_ci * arena->log_index[(0, 1)] with the detected format. 838c2ecf20Sopenharmony_ci */ 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_cistruct log_entry { 868c2ecf20Sopenharmony_ci __le32 lba; 878c2ecf20Sopenharmony_ci __le32 old_map; 888c2ecf20Sopenharmony_ci __le32 new_map; 898c2ecf20Sopenharmony_ci __le32 seq; 908c2ecf20Sopenharmony_ci}; 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_cistruct log_group { 938c2ecf20Sopenharmony_ci struct log_entry ent[4]; 948c2ecf20Sopenharmony_ci}; 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_cistruct btt_sb { 978c2ecf20Sopenharmony_ci u8 signature[BTT_SIG_LEN]; 988c2ecf20Sopenharmony_ci u8 uuid[16]; 998c2ecf20Sopenharmony_ci u8 parent_uuid[16]; 1008c2ecf20Sopenharmony_ci __le32 flags; 1018c2ecf20Sopenharmony_ci __le16 version_major; 1028c2ecf20Sopenharmony_ci __le16 version_minor; 1038c2ecf20Sopenharmony_ci __le32 external_lbasize; 1048c2ecf20Sopenharmony_ci __le32 external_nlba; 1058c2ecf20Sopenharmony_ci __le32 internal_lbasize; 1068c2ecf20Sopenharmony_ci __le32 internal_nlba; 1078c2ecf20Sopenharmony_ci __le32 nfree; 1088c2ecf20Sopenharmony_ci __le32 infosize; 1098c2ecf20Sopenharmony_ci __le64 nextoff; 1108c2ecf20Sopenharmony_ci __le64 dataoff; 1118c2ecf20Sopenharmony_ci __le64 mapoff; 1128c2ecf20Sopenharmony_ci __le64 logoff; 1138c2ecf20Sopenharmony_ci __le64 info2off; 1148c2ecf20Sopenharmony_ci u8 padding[3968]; 1158c2ecf20Sopenharmony_ci __le64 checksum; 1168c2ecf20Sopenharmony_ci}; 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_cistruct free_entry { 1198c2ecf20Sopenharmony_ci u32 block; 1208c2ecf20Sopenharmony_ci u8 sub; 1218c2ecf20Sopenharmony_ci u8 seq; 1228c2ecf20Sopenharmony_ci u8 has_err; 1238c2ecf20Sopenharmony_ci}; 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_cistruct aligned_lock { 1268c2ecf20Sopenharmony_ci union { 1278c2ecf20Sopenharmony_ci spinlock_t lock; 1288c2ecf20Sopenharmony_ci u8 cacheline_padding[L1_CACHE_BYTES]; 1298c2ecf20Sopenharmony_ci }; 1308c2ecf20Sopenharmony_ci}; 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_ci/** 1338c2ecf20Sopenharmony_ci * struct arena_info - handle for an arena 1348c2ecf20Sopenharmony_ci * @size: Size in bytes this arena occupies on the raw device. 1358c2ecf20Sopenharmony_ci * This includes arena metadata. 1368c2ecf20Sopenharmony_ci * @external_lba_start: The first external LBA in this arena. 1378c2ecf20Sopenharmony_ci * @internal_nlba: Number of internal blocks available in the arena 1388c2ecf20Sopenharmony_ci * including nfree reserved blocks 1398c2ecf20Sopenharmony_ci * @internal_lbasize: Internal and external lba sizes may be different as 1408c2ecf20Sopenharmony_ci * we can round up 'odd' external lbasizes such as 520B 1418c2ecf20Sopenharmony_ci * to be aligned. 1428c2ecf20Sopenharmony_ci * @external_nlba: Number of blocks contributed by the arena to the number 1438c2ecf20Sopenharmony_ci * reported to upper layers. (internal_nlba - nfree) 1448c2ecf20Sopenharmony_ci * @external_lbasize: LBA size as exposed to upper layers. 1458c2ecf20Sopenharmony_ci * @nfree: A reserve number of 'free' blocks that is used to 1468c2ecf20Sopenharmony_ci * handle incoming writes. 1478c2ecf20Sopenharmony_ci * @version_major: Metadata layout version major. 1488c2ecf20Sopenharmony_ci * @version_minor: Metadata layout version minor. 1498c2ecf20Sopenharmony_ci * @sector_size: The Linux sector size - 512 or 4096 1508c2ecf20Sopenharmony_ci * @nextoff: Offset in bytes to the start of the next arena. 1518c2ecf20Sopenharmony_ci * @infooff: Offset in bytes to the info block of this arena. 1528c2ecf20Sopenharmony_ci * @dataoff: Offset in bytes to the data area of this arena. 1538c2ecf20Sopenharmony_ci * @mapoff: Offset in bytes to the map area of this arena. 1548c2ecf20Sopenharmony_ci * @logoff: Offset in bytes to the log area of this arena. 1558c2ecf20Sopenharmony_ci * @info2off: Offset in bytes to the backup info block of this arena. 1568c2ecf20Sopenharmony_ci * @freelist: Pointer to in-memory list of free blocks 1578c2ecf20Sopenharmony_ci * @rtt: Pointer to in-memory "Read Tracking Table" 1588c2ecf20Sopenharmony_ci * @map_locks: Spinlocks protecting concurrent map writes 1598c2ecf20Sopenharmony_ci * @nd_btt: Pointer to parent nd_btt structure. 1608c2ecf20Sopenharmony_ci * @list: List head for list of arenas 1618c2ecf20Sopenharmony_ci * @debugfs_dir: Debugfs dentry 1628c2ecf20Sopenharmony_ci * @flags: Arena flags - may signify error states. 1638c2ecf20Sopenharmony_ci * @err_lock: Mutex for synchronizing error clearing. 1648c2ecf20Sopenharmony_ci * @log_index: Indices of the valid log entries in a log_group 1658c2ecf20Sopenharmony_ci * 1668c2ecf20Sopenharmony_ci * arena_info is a per-arena handle. Once an arena is narrowed down for an 1678c2ecf20Sopenharmony_ci * IO, this struct is passed around for the duration of the IO. 1688c2ecf20Sopenharmony_ci */ 1698c2ecf20Sopenharmony_cistruct arena_info { 1708c2ecf20Sopenharmony_ci u64 size; /* Total bytes for this arena */ 1718c2ecf20Sopenharmony_ci u64 external_lba_start; 1728c2ecf20Sopenharmony_ci u32 internal_nlba; 1738c2ecf20Sopenharmony_ci u32 internal_lbasize; 1748c2ecf20Sopenharmony_ci u32 external_nlba; 1758c2ecf20Sopenharmony_ci u32 external_lbasize; 1768c2ecf20Sopenharmony_ci u32 nfree; 1778c2ecf20Sopenharmony_ci u16 version_major; 1788c2ecf20Sopenharmony_ci u16 version_minor; 1798c2ecf20Sopenharmony_ci u32 sector_size; 1808c2ecf20Sopenharmony_ci /* Byte offsets to the different on-media structures */ 1818c2ecf20Sopenharmony_ci u64 nextoff; 1828c2ecf20Sopenharmony_ci u64 infooff; 1838c2ecf20Sopenharmony_ci u64 dataoff; 1848c2ecf20Sopenharmony_ci u64 mapoff; 1858c2ecf20Sopenharmony_ci u64 logoff; 1868c2ecf20Sopenharmony_ci u64 info2off; 1878c2ecf20Sopenharmony_ci /* Pointers to other in-memory structures for this arena */ 1888c2ecf20Sopenharmony_ci struct free_entry *freelist; 1898c2ecf20Sopenharmony_ci u32 *rtt; 1908c2ecf20Sopenharmony_ci struct aligned_lock *map_locks; 1918c2ecf20Sopenharmony_ci struct nd_btt *nd_btt; 1928c2ecf20Sopenharmony_ci struct list_head list; 1938c2ecf20Sopenharmony_ci struct dentry *debugfs_dir; 1948c2ecf20Sopenharmony_ci /* Arena flags */ 1958c2ecf20Sopenharmony_ci u32 flags; 1968c2ecf20Sopenharmony_ci struct mutex err_lock; 1978c2ecf20Sopenharmony_ci int log_index[2]; 1988c2ecf20Sopenharmony_ci}; 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_ci/** 2018c2ecf20Sopenharmony_ci * struct btt - handle for a BTT instance 2028c2ecf20Sopenharmony_ci * @btt_disk: Pointer to the gendisk for BTT device 2038c2ecf20Sopenharmony_ci * @btt_queue: Pointer to the request queue for the BTT device 2048c2ecf20Sopenharmony_ci * @arena_list: Head of the list of arenas 2058c2ecf20Sopenharmony_ci * @debugfs_dir: Debugfs dentry 2068c2ecf20Sopenharmony_ci * @nd_btt: Parent nd_btt struct 2078c2ecf20Sopenharmony_ci * @nlba: Number of logical blocks exposed to the upper layers 2088c2ecf20Sopenharmony_ci * after removing the amount of space needed by metadata 2098c2ecf20Sopenharmony_ci * @rawsize: Total size in bytes of the available backing device 2108c2ecf20Sopenharmony_ci * @lbasize: LBA size as requested and presented to upper layers. 2118c2ecf20Sopenharmony_ci * This is sector_size + size of any metadata. 2128c2ecf20Sopenharmony_ci * @sector_size: The Linux sector size - 512 or 4096 2138c2ecf20Sopenharmony_ci * @lanes: Per-lane spinlocks 2148c2ecf20Sopenharmony_ci * @init_lock: Mutex used for the BTT initialization 2158c2ecf20Sopenharmony_ci * @init_state: Flag describing the initialization state for the BTT 2168c2ecf20Sopenharmony_ci * @num_arenas: Number of arenas in the BTT instance 2178c2ecf20Sopenharmony_ci * @phys_bb: Pointer to the namespace's badblocks structure 2188c2ecf20Sopenharmony_ci */ 2198c2ecf20Sopenharmony_cistruct btt { 2208c2ecf20Sopenharmony_ci struct gendisk *btt_disk; 2218c2ecf20Sopenharmony_ci struct request_queue *btt_queue; 2228c2ecf20Sopenharmony_ci struct list_head arena_list; 2238c2ecf20Sopenharmony_ci struct dentry *debugfs_dir; 2248c2ecf20Sopenharmony_ci struct nd_btt *nd_btt; 2258c2ecf20Sopenharmony_ci u64 nlba; 2268c2ecf20Sopenharmony_ci unsigned long long rawsize; 2278c2ecf20Sopenharmony_ci u32 lbasize; 2288c2ecf20Sopenharmony_ci u32 sector_size; 2298c2ecf20Sopenharmony_ci struct nd_region *nd_region; 2308c2ecf20Sopenharmony_ci struct mutex init_lock; 2318c2ecf20Sopenharmony_ci int init_state; 2328c2ecf20Sopenharmony_ci int num_arenas; 2338c2ecf20Sopenharmony_ci struct badblocks *phys_bb; 2348c2ecf20Sopenharmony_ci}; 2358c2ecf20Sopenharmony_ci 2368c2ecf20Sopenharmony_cibool nd_btt_arena_is_valid(struct nd_btt *nd_btt, struct btt_sb *super); 2378c2ecf20Sopenharmony_ciint nd_btt_version(struct nd_btt *nd_btt, struct nd_namespace_common *ndns, 2388c2ecf20Sopenharmony_ci struct btt_sb *btt_sb); 2398c2ecf20Sopenharmony_ci 2408c2ecf20Sopenharmony_ci#endif 241