STRUCT UBI_DEVICE(9)
π struct ubi_device(9) π
okay bestie, so this is the manual page for struct ubi_device β literally the UBI device description structure in the Linux kernel, and it's a lot, but we're gonna get through it together π«Ά
β¨ NAME β¨
struct ubi_device β the UBI device description structure, no cap, it's the whole vibe of a UBI device
π SYNOPSIS π
struct ubi_device {
struct cdev cdev;
struct device dev;
int ubi_num;
char ubi_name[sizeof(UBI_NAME_STR)+5];
int vol_count;
struct ubi_volume *volumes[UBI_MAX_VOLUMES+UBI_INT_VOL_COUNT];
spinlock_t volumes_lock;
int ref_count;
int image_seq;
bool is_dead;
int rsvd_pebs;
int avail_pebs;
int beb_rsvd_pebs;
int beb_rsvd_level;
int bad_peb_limit;
int autoresize_vol_id;
int vtbl_slots;
int vtbl_size;
struct ubi_vtbl_record *vtbl;
struct mutex device_mutex;
int max_ec;
int mean_ec;
unsigned long long global_sqnum;
spinlock_t ltree_lock;
struct rb_root ltree;
struct mutex alc_mutex;
int fm_disabled;
struct ubi_fastmap_layout *fm;
struct ubi_fm_pool fm_pool;
struct ubi_fm_pool fm_wl_pool;
struct rw_semaphore fm_eba_sem;
struct rw_semaphore fm_protect;
void *fm_buf;
size_t fm_size;
struct work_struct fm_work;
int fm_work_scheduled;
int fast_attach;
struct ubi_wl_entry *fm_anchor;
int fm_do_produce_anchor;
int fm_pool_rsv_cnt;
struct rb_root used;
struct rb_root erroneous;
struct rb_root free;
int free_count;
struct rb_root scrub;
struct list_head pq[UBI_PROT_QUEUE_LEN];
int pq_head;
spinlock_t wl_lock;
struct mutex move_mutex;
struct rw_semaphore work_sem;
int wl_scheduled;
struct ubi_wl_entry **lookuptbl;
struct ubi_wl_entry *move_from;
struct ubi_wl_entry *move_to;
int move_to_put;
struct list_head works;
int works_count;
struct task_struct *bgt_thread;
int thread_enabled;
char bgt_name[sizeof(UBI_BGT_NAME_PATTERN)+2];
int wl_threshold;
int wl_free_max_diff;
long long flash_size;
int peb_count;
int peb_size;
int bad_peb_count;
int good_peb_count;
int corr_peb_count;
int erroneous_peb_count;
int max_erroneous;
int min_io_size;
int hdrs_min_io_size;
int ro_mode;
int leb_size;
int leb_start;
int ec_hdr_alsize;
int vid_hdr_alsize;
int vid_hdr_offset;
int vid_hdr_aloffset;
int vid_hdr_shift;
unsigned int bad_allowed:1;
unsigned int nor_flash:1;
int max_write_size;
struct mtd_info *mtd;
void *peb_buf;
struct mutex buf_mutex;
struct mutex ckvol_mutex;
struct ubi_debug_info dbg;
};
like, that's the whole struct, periodt π
πΈ DESCRIPTION πΈ
so this struct is literally the main character energy of a UBI device β it holds every single thing the kernel needs to know about one UBI device. we're talking volumes, eraseblocks, wear-leveling, fastmap, debug infoβ¦ the whole situation β¨
π Members π
here's the tea on every single field, bestie, buckle up:
cdevβ character device object to create character device πdevβ UBI device object to use the Linux device modelubi_numβ UBI device numberubi_nameβ UBI device namevol_countβ number of volumes in this UBI devicevolumesβ volumes of this UBI devicevolumes_lockβ protectsvolumes,rsvd_pebs,avail_pebs,beb_rsvd_pebs,beb_rsvd_level,bad_peb_count,good_peb_count,vol_count,vol->readers,vol->writers,vol->exclusive,vol->metaonly,vol->ref_count,vol->mappingandvol->eba_tbl. lowkey that's a lot but okay π«Άref_countβ count of references on the UBI deviceimage_seqβ image sequence number recorded on EC headersrsvd_pebsβ count of reserved physical eraseblocksavail_pebsβ count of available physical eraseblocksbeb_rsvd_pebsβ how many physical eraseblocks are reserved for bad PEB handlingbeb_rsvd_levelβ normal level of PEBs reserved for bad PEB handlingbad_peb_limitβ top limit of expected bad physical eraseblocksautoresize_vol_idβ ID of the volume which has to be auto-resized at the end of UBI initializationvtbl_slotsβ how many slots are available in the volume tablevtbl_sizeβ size of the volume table in bytesvtblβ in-RAM volume table copydevice_mutexβ protects on-flash volume table and serializes volume creation, deletion, update, re-size, re-name and set property. it's giving "one at a time please" πmax_ecβ current highest erase counter valuemean_ecβ current mean erase counter valueglobal_sqnumβ global sequence numberltree_lockβ protects the lock tree andglobal_sqnumltreeβ the lock treealc_mutexβ serializes "atomic LEB change" operationsfm_disabledβ non-zero if fastmap is disabled (default)fmβ in-memory data structure of the currently used fastmapfm_poolβ in-memory data structure of the fastmap poolfm_wl_poolβ in-memory data structure of the fastmap pool used by the WL sub-systemfm_eba_semβ allowsubi_update_fastmapto block EBA table changesfm_protectβ serializesubi_update_fastmap, protectsfm_bufand makes sure that critical sections cannot be interrupted byubi_update_fastmapfm_bufβvmalloc'd buffer which holds the raw fastmapfm_sizeβ fastmap size in bytesfm_workβ fastmap work queuefm_work_scheduledβ non-zero if fastmap work was scheduledfast_attachβ non-zero if UBI was attached by fastmapfm_anchorβ the next anchor PEB to use for fastmapfm_do_produce_anchorβ if true produce an anchor PEB inwlfm_pool_rsv_cntβ number of reserved PEBs for fillingpool/wl_poolusedβ RB-tree of used physical eraseblockserroneousβ RB-tree of erroneous used physical eraseblocksfreeβ RB-tree of free physical eraseblocksfree_countβ contains the number of elements infreescrubβ RB-tree of physical eraseblocks which need scrubbing π§pqβ protection queue (contain physical eraseblocks which are temporarily protected from the wear-leveling worker)pq_headβ protection queue headwl_lockβ protects theused,free,pq,pq_head,lookuptbl,move_from,move_to,move_to_puterase_pending,wl_scheduled,works,erroneous,erroneous_peb_count,fm_work_scheduled,fm_pool, andfm_wl_poolfields. like, it protects everything, it's the bodyguard of the struct πmove_mutexβ serializes eraseblock moveswork_semβ used to wait for all the scheduled works to finish and prevent new works from being submittedwl_scheduledβ non-zero if the wear-leveling was scheduledlookuptblβ a table to quickly find astruct ubi_wl_entryobject for any physical eraseblockmove_fromβ physical eraseblock from where the data is being movedmove_toβ physical eraseblock where the data is being moved tomove_to_putβ if the "to" PEB was putworksβ list of pending worksworks_countβ count of pending worksbgt_threadβ background thread description objectthread_enabledβ if the background thread is enabledbgt_nameβ background thread namewl_thresholdβ maximum difference between two erase counters. if this threshold is exceeded, the WL sub-system starts moving data from used physical eraseblocks with low erase counter to free physical eraseblocks with high erase counter. it's giving "balance is key" βοΈwl_free_max_diffβ okay so when a physical eraseblock is moved, the WL sub-system has to pick the target physical eraseblock to move to. the simplest way would be just to pick the one with the highest erase counter. but in certain workloads this could lead to an unlimited wear of one or few physical eraseblock. indeed, imagine a situation when the picked physical eraseblock is constantly erased after the data is written to it. so, we have a constant which limits the highest erase counter of the free physical eraseblock to pick. namely, the WL sub-system does not pick eraseblocks with erase counter greater than the lowest erase counter pluswl_free_max_diff. ngl that's a whole paragraph but it's important, don't skip it bestie πflash_sizeβ underlying MTD device size (in bytes)peb_countβ count of physical eraseblocks on the MTD devicepeb_sizeβ physical eraseblock sizebad_peb_countβ count of bad physical eraseblocksgood_peb_countβ count of good physical eraseblockscorr_peb_countβ count of corrupted physical eraseblocks (preserved and not used by UBI)erroneous_peb_countβ count of erroneous physical eraseblocks inerroneousmax_erroneousβ maximum allowed amount of erroneous physical eraseblocksmin_io_sizeβ minimal input/output unit size of the underlying MTD devicehdrs_min_io_sizeβ minimal I/O unit size used for VID and EC headersro_modeβ if the UBI device is in read-only modeleb_sizeβ logical eraseblock sizeleb_startβ starting offset of logical eraseblocks within physical eraseblocksec_hdr_alsizeβ size of the EC header aligned tohdrs_min_io_sizevid_hdr_alsizeβ size of the VID header aligned tohdrs_min_io_sizevid_hdr_offsetβ starting offset of the volume identifier header (might be unaligned)vid_hdr_aloffsetβ starting offset of the VID header aligned tohdrs_min_io_sizevid_hdr_shiftβ containsvid_hdr_offset - vid_hdr_aloffsetbad_allowedβ whether the MTD device admits bad physical eraseblocks or notnor_flashβ non-zero if working on top of NOR flashmax_write_sizeβ maximum amount of bytes the underlying flash can write at a time (MTD write buffer size)mtdβ MTD device descriptorpeb_bufβ a buffer of PEB size used for different purposesbuf_mutexβ protectspeb_bufckvol_mutexβ serializes static volume checking when openingdbgβ debugging information for this UBI device
honestly, that's the whole list, and every single field is here, no gatekeeping π
π¦ SEE ALSO π¦
bestie, there's a whole squad of related kernel file things, go check them out iykyk:
Kernel file ./drivers/mtd/ubi/ubi.h struct ubi_vid_io_buf(9), struct ubi_wl_entry(9), struct ubi_ltree_entry(9), struct ubi_rename_entry(9), struct ubi_fastmap_layout(9), struct ubi_fm_pool(9), struct ubi_eba_leb_desc(9), struct ubi_volume(9), struct ubi_volume_desc(9), struct ubi_debug_info(9), struct ubi_ainf_peb(9), struct ubi_ainf_volume(9), struct ubi_attach_info(9), struct ubi_work(9), ubi_init_vid_buf(9), ubi_free_vid_buf(9), ubi_get_vid_hdr(9), ubi_ro_mode(9), vol_id2idx(9), idx2vol_id(9), ubi_is_fm_vol(9), ubi_find_fm_block(9)
and that's the whole manual page, bestie! every single field, every single detail, no cap. you're now officially obsessed with struct ubi_device whether you like it or not π
β¨
signed off with love from ./drivers/mtd/ubi, October 2026 β stay iconic, kernel queen ππ
π¦ where this page comes from
- nixpkgs unstable: linux-manual 7.3.1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms