diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2024-03-11 10:52:34 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2024-03-11 10:52:34 -0700 |
commit | 910202f00a435c56cf000bc6d45ecaabac4dd598 (patch) | |
tree | 293a580752fec1848f40e22e168c9f4ef4711fea /drivers/mtd | |
parent | 0c750012e8f30d26930ae13e815635258aee92b3 (diff) | |
parent | 40ebc18b991bdb867bc693a4ac1b5d7db44838f3 (diff) |
Merge tag 'vfs-6.9.super' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
Pull block handle updates from Christian Brauner:
"Last cycle we changed opening of block devices, and opening a block
device would return a bdev_handle. This allowed us to implement
support for restricting and forbidding writes to mounted block
devices. It was accompanied by converting and adding helpers to
operate on bdev_handles instead of plain block devices.
That was already a good step forward but ultimately it isn't necessary
to have special purpose helpers for opening block devices internally
that return a bdev_handle.
Fundamentally, opening a block device internally should just be
equivalent to opening files. So now all internal opens of block
devices return files just as a userspace open would. Instead of
introducing a separate indirection into bdev_open_by_*() via struct
bdev_handle bdev_file_open_by_*() is made to just return a struct
file. Opening and closing a block device just becomes equivalent to
opening and closing a file.
This all works well because internally we already have a pseudo fs for
block devices and so opening block devices is simple. There's a few
places where we needed to be careful such as during boot when the
kernel is supposed to mount the rootfs directly without init doing it.
Here we need to take care to ensure that we flush out any asynchronous
file close. That's what we already do for opening, unpacking, and
closing the initramfs. So nothing new here.
The equivalence of opening and closing block devices to regular files
is a win in and of itself. But it also has various other advantages.
We can remove struct bdev_handle completely. Various low-level helpers
are now private to the block layer. Other helpers were simply
removable completely.
A follow-up series that is already reviewed build on this and makes it
possible to remove bdev->bd_inode and allows various clean ups of the
buffer head code as well. All places where we stashed a bdev_handle
now just stash a file and use simple accessors to get to the actual
block device which was already the case for bdev_handle"
* tag 'vfs-6.9.super' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: (35 commits)
block: remove bdev_handle completely
block: don't rely on BLK_OPEN_RESTRICT_WRITES when yielding write access
bdev: remove bdev pointer from struct bdev_handle
bdev: make struct bdev_handle private to the block layer
bdev: make bdev_{release, open_by_dev}() private to block layer
bdev: remove bdev_open_by_path()
reiserfs: port block device access to file
ocfs2: port block device access to file
nfs: port block device access to files
jfs: port block device access to file
f2fs: port block device access to files
ext4: port block device access to file
erofs: port device access to file
btrfs: port device access to file
bcachefs: port block device access to file
target: port block device access to file
s390: port block device access to file
nvme: port block device access to file
block2mtd: port device access to files
bcache: port block device access to files
...
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/devices/block2mtd.c | 46 |
1 files changed, 21 insertions, 25 deletions
diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c index aa44a23ec045..97a00ec9a4d4 100644 --- a/drivers/mtd/devices/block2mtd.c +++ b/drivers/mtd/devices/block2mtd.c @@ -37,7 +37,7 @@ /* Info for the block device */ struct block2mtd_dev { struct list_head list; - struct bdev_handle *bdev_handle; + struct file *bdev_file; struct mtd_info mtd; struct mutex write_mutex; }; @@ -55,8 +55,7 @@ static struct page *page_read(struct address_space *mapping, pgoff_t index) /* 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_handle->bdev->bd_inode->i_mapping; + 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; @@ -106,8 +105,7 @@ 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_handle->bdev->bd_inode->i_mapping; + struct address_space *mapping = dev->bdev_file->f_mapping; struct page *page; pgoff_t index = from >> PAGE_SHIFT; int offset = from & (PAGE_SIZE-1); @@ -142,8 +140,7 @@ static int _block2mtd_write(struct block2mtd_dev *dev, const u_char *buf, loff_t to, size_t len, size_t *retlen) { struct page *page; - struct address_space *mapping = - dev->bdev_handle->bdev->bd_inode->i_mapping; + struct address_space *mapping = dev->bdev_file->f_mapping; pgoff_t index = to >> PAGE_SHIFT; // page index int offset = to & ~PAGE_MASK; // page offset int cpylen; @@ -198,7 +195,7 @@ static int block2mtd_write(struct mtd_info *mtd, loff_t to, size_t len, static void block2mtd_sync(struct mtd_info *mtd) { struct block2mtd_dev *dev = mtd->priv; - sync_blockdev(dev->bdev_handle->bdev); + sync_blockdev(file_bdev(dev->bdev_file)); return; } @@ -210,10 +207,9 @@ static void block2mtd_free_device(struct block2mtd_dev *dev) kfree(dev->mtd.name); - if (dev->bdev_handle) { - invalidate_mapping_pages( - dev->bdev_handle->bdev->bd_inode->i_mapping, 0, -1); - bdev_release(dev->bdev_handle); + if (dev->bdev_file) { + invalidate_mapping_pages(dev->bdev_file->f_mapping, 0, -1); + fput(dev->bdev_file); } kfree(dev); @@ -223,10 +219,10 @@ static void block2mtd_free_device(struct block2mtd_dev *dev) * This function is marked __ref because it calls the __init marked * early_lookup_bdev when called from the early boot code. */ -static struct bdev_handle __ref *mdtblock_early_get_bdev(const char *devname, +static struct file __ref *mdtblock_early_get_bdev(const char *devname, blk_mode_t mode, int timeout, struct block2mtd_dev *dev) { - struct bdev_handle *bdev_handle = ERR_PTR(-ENODEV); + struct file *bdev_file = ERR_PTR(-ENODEV); #ifndef MODULE int i; @@ -234,7 +230,7 @@ static struct bdev_handle __ref *mdtblock_early_get_bdev(const char *devname, * We can't use early_lookup_bdev from a running system. */ if (system_state >= SYSTEM_RUNNING) - return bdev_handle; + return bdev_file; /* * We might not have the root device mounted at this point. @@ -253,20 +249,20 @@ static struct bdev_handle __ref *mdtblock_early_get_bdev(const char *devname, wait_for_device_probe(); if (!early_lookup_bdev(devname, &devt)) { - bdev_handle = bdev_open_by_dev(devt, mode, dev, NULL); - if (!IS_ERR(bdev_handle)) + bdev_file = bdev_file_open_by_dev(devt, mode, dev, NULL); + if (!IS_ERR(bdev_file)) break; } } #endif - return bdev_handle; + return bdev_file; } static struct block2mtd_dev *add_device(char *devname, int erase_size, char *label, int timeout) { const blk_mode_t mode = BLK_OPEN_READ | BLK_OPEN_WRITE; - struct bdev_handle *bdev_handle; + struct file *bdev_file; struct block_device *bdev; struct block2mtd_dev *dev; char *name; @@ -279,16 +275,16 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size, return NULL; /* Get a handle on the device */ - bdev_handle = bdev_open_by_path(devname, mode, dev, NULL); - if (IS_ERR(bdev_handle)) - bdev_handle = mdtblock_early_get_bdev(devname, mode, timeout, + bdev_file = bdev_file_open_by_path(devname, mode, dev, NULL); + if (IS_ERR(bdev_file)) + bdev_file = mdtblock_early_get_bdev(devname, mode, timeout, dev); - if (IS_ERR(bdev_handle)) { + if (IS_ERR(bdev_file)) { pr_err("error: cannot open device %s\n", devname); goto err_free_block2mtd; } - dev->bdev_handle = bdev_handle; - bdev = bdev_handle->bdev; + dev->bdev_file = bdev_file; + bdev = file_bdev(bdev_file); if (MAJOR(bdev->bd_dev) == MTD_BLOCK_MAJOR) { pr_err("attempting to use an MTD device as a block device\n"); |