drivers/mtd/devices/block2mtd.c
Source file repositories/reference/linux-study-clean/drivers/mtd/devices/block2mtd.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/mtd/devices/block2mtd.c- Extension
.c- Size
- 12223 bytes
- Lines
- 533
- Domain
- Driver Families
- Bucket
- drivers/mtd
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/module.hlinux/delay.hlinux/fs.hlinux/blkdev.hlinux/backing-dev.hlinux/bio.hlinux/pagemap.hlinux/list.hlinux/init.hlinux/mtd/mtd.hlinux/mutex.hlinux/mount.hlinux/slab.hlinux/major.h
Detected Declarations
struct block2mtd_devfunction _block2mtd_erasefunction block2mtd_erasefunction block2mtd_readfunction _block2mtd_writefunction block2mtd_writefunction block2mtd_syncfunction block2mtd_free_devicefunction ustrtoulfunction parse_numfunction kill_final_newlinefunction block2mtd_setup2function block2mtd_setupfunction block2mtd_initfunction block2mtd_exit
Annotated Snippet
struct block2mtd_dev {
struct list_head list;
struct file *bdev_file;
struct mtd_info mtd;
struct mutex write_mutex;
};
/* Static info about the MTD, used in cleanup_module */
static LIST_HEAD(blkmtd_device_list);
static struct page *page_read(struct address_space *mapping, pgoff_t index)
{
return read_mapping_page(mapping, index, NULL);
}
/* erase a specified part of the device */
static int _block2mtd_erase(struct block2mtd_dev *dev, loff_t to, size_t len)
{
struct address_space *mapping = dev->bdev_file->f_mapping;
struct page *page;
pgoff_t index = to >> PAGE_SHIFT; // page index
int pages = len >> PAGE_SHIFT;
u_long *p;
u_long *max;
while (pages) {
page = page_read(mapping, index);
if (IS_ERR(page))
return PTR_ERR(page);
max = page_address(page) + PAGE_SIZE;
for (p=page_address(page); p<max; p++)
if (*p != -1UL) {
lock_page(page);
memset(page_address(page), 0xff, PAGE_SIZE);
set_page_dirty(page);
unlock_page(page);
balance_dirty_pages_ratelimited(mapping);
break;
}
put_page(page);
pages--;
index++;
}
return 0;
}
static int block2mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
{
struct block2mtd_dev *dev = mtd->priv;
size_t from = instr->addr;
size_t len = instr->len;
int err;
mutex_lock(&dev->write_mutex);
err = _block2mtd_erase(dev, from, len);
mutex_unlock(&dev->write_mutex);
if (err)
pr_err("erase failed err = %d\n", err);
return err;
}
static int block2mtd_read(struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, u_char *buf)
{
struct block2mtd_dev *dev = mtd->priv;
struct address_space *mapping = dev->bdev_file->f_mapping;
struct page *page;
pgoff_t index = from >> PAGE_SHIFT;
int offset = from & (PAGE_SIZE-1);
int cpylen;
while (len) {
if ((offset + len) > PAGE_SIZE)
cpylen = PAGE_SIZE - offset; // multiple pages
else
cpylen = len; // this page
len = len - cpylen;
page = page_read(mapping, index);
if (IS_ERR(page))
return PTR_ERR(page);
memcpy(buf, page_address(page) + offset, cpylen);
put_page(page);
Annotation
- Immediate include surface: `linux/module.h`, `linux/delay.h`, `linux/fs.h`, `linux/blkdev.h`, `linux/backing-dev.h`, `linux/bio.h`, `linux/pagemap.h`, `linux/list.h`.
- Detected declarations: `struct block2mtd_dev`, `function _block2mtd_erase`, `function block2mtd_erase`, `function block2mtd_read`, `function _block2mtd_write`, `function block2mtd_write`, `function block2mtd_sync`, `function block2mtd_free_device`, `function ustrtoul`, `function parse_num`.
- Atlas domain: Driver Families / drivers/mtd.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.