* [PATCH v2 0/29] block: Make blkdev_get_by_*() return handle
@ 2023-08-11 11:04 Jan Kara
2023-08-11 11:04 ` [PATCH 22/29] ext4: Convert to bdev_open_by_dev() Jan Kara
` (2 more replies)
0 siblings, 3 replies; 9+ messages in thread
From: Jan Kara @ 2023-08-11 11:04 UTC (permalink / raw)
To: linux-fsdevel
Cc: linux-block, Christoph Hellwig, Jan Kara, Alasdair Kergon,
Andrew Morton, Anna Schumaker, Chao Yu, Christian Borntraeger,
Darrick J. Wong, Dave Kleikamp, David Sterba, dm-devel, drbd-dev,
Gao Xiang, Jack Wang, Jaegeuk Kim, jfs-discussion, Joern Engel,
Joseph Qi, Kent Overstreet, linux-bcache, linux-btrfs,
linux-erofs, linux-ext4, linux-f2fs-devel, linux-mm, linux-mtd,
linux-nfs, linux-nilfs, linux-nvme, linux-pm, linux-raid,
linux-s390, linux-scsi, linux-xfs, Md. Haris Iqbal, Mike Snitzer,
Minchan Kim, ocfs2-devel, reiserfs-devel, Sergey Senozhatsky,
Song Liu, Sven Schnelle, target-devel, Ted Tso, Trond Myklebust,
xen-devel
Hello,
this is a v2 of the patch series which implements the idea of blkdev_get_by_*()
calls returning bdev_handle which is then passed to blkdev_put() [1]. This
makes the get and put calls for bdevs more obviously matching and allows us to
propagate context from get to put without having to modify all the users
(again!). In particular I need to propagate used open flags to blkdev_put() to
be able count writeable opens and add support for blocking writes to mounted
block devices. I'll send that series separately.
The series is based on Christian's vfs tree as of yesterday as there is quite
some overlap. Patches have passed some reasonable testing - I've tested block
changes, md, dm, bcache, xfs, btrfs, ext4, swap. This obviously doesn't cover
everything so I'd like to ask respective maintainers to review / test their
changes. Thanks! I've pushed out the full branch to:
git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs.git bdev_handle
to ease review / testing.
Changes since v1:
* Rebased on top of current vfs tree
* Renamed final functions to bdev_open_by_*() and bdev_release()
* Fixed detection of exclusive open in blkdev_ioctl() and blkdev_fallocate()
* Fixed swap conversion to properly reinitialize swap_info->bdev_handle
* Fixed xfs conversion to not oops with rtdev without logdev
* Couple other minor fixups
Honza
[1] https://lore.kernel.org/all/ZJGNsVDhZx0Xgs2H@infradead.org
CC: Alasdair Kergon <agk@redhat.com>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: Anna Schumaker <anna@kernel.org>
CC: Chao Yu <chao@kernel.org>
CC: Christian Borntraeger <borntraeger@linux.ibm.com>
CC: Coly Li <colyli@suse.de
CC: "Darrick J. Wong" <djwong@kernel.org>
CC: Dave Kleikamp <shaggy@kernel.org>
CC: David Sterba <dsterba@suse.com>
CC: dm-devel@redhat.com
CC: drbd-dev@lists.linbit.com
CC: Gao Xiang <xiang@kernel.org>
CC: Jack Wang <jinpu.wang@ionos.com>
CC: Jaegeuk Kim <jaegeuk@kernel.org>
CC: jfs-discussion@lists.sourceforge.net
CC: Joern Engel <joern@lazybastard.org>
CC: Joseph Qi <joseph.qi@linux.alibaba.com>
CC: Kent Overstreet <kent.overstreet@gmail.com>
CC: linux-bcache@vger.kernel.org
CC: linux-btrfs@vger.kernel.org
CC: linux-erofs@lists.ozlabs.org
CC: <linux-ext4@vger.kernel.org>
CC: linux-f2fs-devel@lists.sourceforge.net
CC: linux-mm@kvack.org
CC: linux-mtd@lists.infradead.org
CC: linux-nfs@vger.kernel.org
CC: linux-nilfs@vger.kernel.org
CC: linux-nvme@lists.infradead.org
CC: linux-pm@vger.kernel.org
CC: linux-raid@vger.kernel.org
CC: linux-s390@vger.kernel.org
CC: linux-scsi@vger.kernel.org
CC: linux-xfs@vger.kernel.org
CC: "Md. Haris Iqbal" <haris.iqbal@ionos.com>
CC: Mike Snitzer <snitzer@kernel.org>
CC: Minchan Kim <minchan@kernel.org>
CC: ocfs2-devel@oss.oracle.com
CC: reiserfs-devel@vger.kernel.org
CC: Sergey Senozhatsky <senozhatsky@chromium.org>
CC: Song Liu <song@kernel.org>
CC: Sven Schnelle <svens@linux.ibm.com>
CC: target-devel@vger.kernel.org
CC: Ted Tso <tytso@mit.edu>
CC: Trond Myklebust <trond.myklebust@hammerspace.com>
CC: xen-devel@lists.xenproject.org
Previous versions:
Link: http://lore.kernel.org/r/20230629165206.383-1-jack@suse.cz # v1
^ permalink raw reply [flat|nested] 9+ messages in thread* [PATCH 22/29] ext4: Convert to bdev_open_by_dev() 2023-08-11 11:04 [PATCH v2 0/29] block: Make blkdev_get_by_*() return handle Jan Kara @ 2023-08-11 11:04 ` Jan Kara 2023-08-11 12:27 ` [PATCH v2 0/29] block: Make blkdev_get_by_*() return handle Christoph Hellwig 2023-08-25 1:58 ` Al Viro 2 siblings, 0 replies; 9+ messages in thread From: Jan Kara @ 2023-08-11 11:04 UTC (permalink / raw) To: linux-fsdevel Cc: linux-block, Christoph Hellwig, Jan Kara, linux-ext4, Ted Tso Convert ext4 to use bdev_open_by_dev() and pass the handle around. CC: <linux-ext4@vger.kernel.org> CC: Ted Tso <tytso@mit.edu> Signed-off-by: Jan Kara <jack@suse.cz> --- fs/ext4/ext4.h | 2 +- fs/ext4/fsmap.c | 9 +++++---- fs/ext4/super.c | 40 ++++++++++++++++++++-------------------- 3 files changed, 26 insertions(+), 25 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 1e2259d9967d..6856e80abf70 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -1541,7 +1541,7 @@ struct ext4_sb_info { unsigned long s_commit_interval; u32 s_max_batch_time; u32 s_min_batch_time; - struct block_device *s_journal_bdev; + struct bdev_handle *s_journal_bdev_handle; #ifdef CONFIG_QUOTA /* Names of quota files with journalled quota */ char __rcu *s_qf_names[EXT4_MAXQUOTAS]; diff --git a/fs/ext4/fsmap.c b/fs/ext4/fsmap.c index cdf9bfe10137..11e6f33677a2 100644 --- a/fs/ext4/fsmap.c +++ b/fs/ext4/fsmap.c @@ -576,8 +576,9 @@ static bool ext4_getfsmap_is_valid_device(struct super_block *sb, if (fm->fmr_device == 0 || fm->fmr_device == UINT_MAX || fm->fmr_device == new_encode_dev(sb->s_bdev->bd_dev)) return true; - if (EXT4_SB(sb)->s_journal_bdev && - fm->fmr_device == new_encode_dev(EXT4_SB(sb)->s_journal_bdev->bd_dev)) + if (EXT4_SB(sb)->s_journal_bdev_handle && + fm->fmr_device == + new_encode_dev(EXT4_SB(sb)->s_journal_bdev_handle->bdev->bd_dev)) return true; return false; } @@ -647,9 +648,9 @@ int ext4_getfsmap(struct super_block *sb, struct ext4_fsmap_head *head, memset(handlers, 0, sizeof(handlers)); handlers[0].gfd_dev = new_encode_dev(sb->s_bdev->bd_dev); handlers[0].gfd_fn = ext4_getfsmap_datadev; - if (EXT4_SB(sb)->s_journal_bdev) { + if (EXT4_SB(sb)->s_journal_bdev_handle) { handlers[1].gfd_dev = new_encode_dev( - EXT4_SB(sb)->s_journal_bdev->bd_dev); + EXT4_SB(sb)->s_journal_bdev_handle->bdev->bd_dev); handlers[1].gfd_fn = ext4_getfsmap_logdev; } diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 45fd5372bf8a..9ca3665e1b92 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1099,20 +1099,20 @@ void ext4_update_dynamic_rev(struct super_block *sb) /* * Open the external journal device */ -static struct block_device *ext4_blkdev_get(dev_t dev, struct super_block *sb) +static struct bdev_handle *ext4_blkdev_get(dev_t dev, struct super_block *sb) { - struct block_device *bdev; + struct bdev_handle *handle; - bdev = blkdev_get_by_dev(dev, BLK_OPEN_READ | BLK_OPEN_WRITE, sb, - &fs_holder_ops); - if (IS_ERR(bdev)) + handle = bdev_open_by_dev(dev, BLK_OPEN_READ | BLK_OPEN_WRITE, sb, + &fs_holder_ops); + if (IS_ERR(handle)) goto fail; - return bdev; + return handle; fail: ext4_msg(sb, KERN_ERR, "failed to open journal device unknown-block(%u,%u) %ld", - MAJOR(dev), MINOR(dev), PTR_ERR(bdev)); + MAJOR(dev), MINOR(dev), PTR_ERR(handle)); return NULL; } @@ -1121,17 +1121,15 @@ static struct block_device *ext4_blkdev_get(dev_t dev, struct super_block *sb) */ static void ext4_blkdev_remove(struct ext4_sb_info *sbi) { - struct block_device *bdev; - bdev = sbi->s_journal_bdev; - if (bdev) { + if (sbi->s_journal_bdev_handle) { /* * Invalidate the journal device's buffers. We don't want them * floating about in memory - the physical journal device may * hotswapped, and it breaks the `ro-after' testing code. */ - invalidate_bdev(bdev); - blkdev_put(bdev, sbi->s_sb); - sbi->s_journal_bdev = NULL; + invalidate_bdev(sbi->s_journal_bdev_handle->bdev); + bdev_release(sbi->s_journal_bdev_handle); + sbi->s_journal_bdev_handle = NULL; } } @@ -1329,8 +1327,8 @@ static void ext4_put_super(struct super_block *sb) sync_blockdev(sb->s_bdev); invalidate_bdev(sb->s_bdev); - if (sbi->s_journal_bdev) { - sync_blockdev(sbi->s_journal_bdev); + if (sbi->s_journal_bdev_handle) { + sync_blockdev(sbi->s_journal_bdev_handle->bdev); ext4_blkdev_remove(sbi); } @@ -4218,7 +4216,7 @@ int ext4_calculate_overhead(struct super_block *sb) * Add the internal journal blocks whether the journal has been * loaded or not */ - if (sbi->s_journal && !sbi->s_journal_bdev) + if (sbi->s_journal && !sbi->s_journal_bdev_handle) overhead += EXT4_NUM_B2C(sbi, sbi->s_journal->j_total_len); else if (ext4_has_feature_journal(sb) && !sbi->s_journal && j_inum) { /* j_inum for internal journal is non-zero */ @@ -5840,17 +5838,19 @@ static journal_t *ext4_get_dev_journal(struct super_block *sb, unsigned long offset; struct ext4_super_block *es; struct block_device *bdev; + struct bdev_handle *bdev_handle; if (WARN_ON_ONCE(!ext4_has_feature_journal(sb))) return NULL; /* see get_tree_bdev why this is needed and safe */ up_write(&sb->s_umount); - bdev = ext4_blkdev_get(j_dev, sb); + bdev_handle = ext4_blkdev_get(j_dev, sb); down_write(&sb->s_umount); - if (bdev == NULL) + if (!bdev_handle) return NULL; + bdev = bdev_handle->bdev; blocksize = sb->s_blocksize; hblock = bdev_logical_block_size(bdev); if (blocksize < hblock) { @@ -5914,14 +5914,14 @@ static journal_t *ext4_get_dev_journal(struct super_block *sb, be32_to_cpu(journal->j_superblock->s_nr_users)); goto out_journal; } - EXT4_SB(sb)->s_journal_bdev = bdev; + EXT4_SB(sb)->s_journal_bdev_handle = bdev_handle; ext4_init_journal_params(sb, journal); return journal; out_journal: jbd2_journal_destroy(journal); out_bdev: - blkdev_put(bdev, sb); + bdev_release(bdev_handle); return NULL; } -- 2.35.3 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v2 0/29] block: Make blkdev_get_by_*() return handle 2023-08-11 11:04 [PATCH v2 0/29] block: Make blkdev_get_by_*() return handle Jan Kara 2023-08-11 11:04 ` [PATCH 22/29] ext4: Convert to bdev_open_by_dev() Jan Kara @ 2023-08-11 12:27 ` Christoph Hellwig 2023-08-25 1:58 ` Al Viro 2 siblings, 0 replies; 9+ messages in thread From: Christoph Hellwig @ 2023-08-11 12:27 UTC (permalink / raw) To: Jan Kara Cc: linux-fsdevel, linux-block, Christoph Hellwig, Alasdair Kergon, Andrew Morton, Anna Schumaker, Chao Yu, Christian Borntraeger, Darrick J. Wong, Dave Kleikamp, David Sterba, dm-devel, drbd-dev, Gao Xiang, Jack Wang, Jaegeuk Kim, jfs-discussion, Joern Engel, Joseph Qi, Kent Overstreet, linux-bcache, linux-btrfs, linux-erofs, linux-ext4, linux-f2fs-devel, linux-mm, linux-mtd, linux-nfs, linux-nilfs, linux-nvme, linux-pm, linux-raid, linux-s390, linux-scsi, linux-xfs, Md. Haris Iqbal, Mike Snitzer, Minchan Kim, ocfs2-devel, reiserfs-devel, Sergey Senozhatsky, Song Liu, Sven Schnelle, target-devel, Ted Tso, Trond Myklebust, xen-devel Except for a mostly cosmetic nitpick this looks good to me: Acked-by: Christoph Hellwig <hch@lst.de> That's not eactly the deep review I'd like to do, but as I'm about to head out for vacation that's probably as good as it gets. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 0/29] block: Make blkdev_get_by_*() return handle 2023-08-11 11:04 [PATCH v2 0/29] block: Make blkdev_get_by_*() return handle Jan Kara 2023-08-11 11:04 ` [PATCH 22/29] ext4: Convert to bdev_open_by_dev() Jan Kara 2023-08-11 12:27 ` [PATCH v2 0/29] block: Make blkdev_get_by_*() return handle Christoph Hellwig @ 2023-08-25 1:58 ` Al Viro 2023-08-25 13:47 ` Jan Kara 2 siblings, 1 reply; 9+ messages in thread From: Al Viro @ 2023-08-25 1:58 UTC (permalink / raw) To: Jan Kara Cc: linux-fsdevel, linux-block, Christoph Hellwig, Alasdair Kergon, Andrew Morton, Anna Schumaker, Chao Yu, Christian Borntraeger, Darrick J. Wong, Dave Kleikamp, David Sterba, dm-devel, drbd-dev, Gao Xiang, Jack Wang, Jaegeuk Kim, jfs-discussion, Joern Engel, Joseph Qi, Kent Overstreet, linux-bcache, linux-btrfs, linux-erofs, linux-ext4, linux-f2fs-devel, linux-mm, linux-mtd, linux-nfs, linux-nilfs, linux-nvme, linux-pm, linux-raid, linux-s390, linux-scsi, linux-xfs, Md. Haris Iqbal, Mike Snitzer, Minchan Kim, ocfs2-devel, reiserfs-devel, Sergey Senozhatsky, Song Liu, Sven Schnelle, target-devel, Ted Tso, Trond Myklebust, xen-devel On Fri, Aug 11, 2023 at 01:04:31PM +0200, Jan Kara wrote: > Hello, > > this is a v2 of the patch series which implements the idea of blkdev_get_by_*() > calls returning bdev_handle which is then passed to blkdev_put() [1]. This > makes the get and put calls for bdevs more obviously matching and allows us to > propagate context from get to put without having to modify all the users > (again!). In particular I need to propagate used open flags to blkdev_put() to > be able count writeable opens and add support for blocking writes to mounted > block devices. I'll send that series separately. > > The series is based on Christian's vfs tree as of yesterday as there is quite > some overlap. Patches have passed some reasonable testing - I've tested block > changes, md, dm, bcache, xfs, btrfs, ext4, swap. This obviously doesn't cover > everything so I'd like to ask respective maintainers to review / test their > changes. Thanks! I've pushed out the full branch to: > > git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs.git bdev_handle > > to ease review / testing. Hmm... Completely Insane Idea(tm): how about turning that thing inside out and having your bdev_open_by... return an actual opened struct file? After all, we do that for sockets and pipes just fine and that's a whole lot hotter area. Suppose we leave blkdev_open()/blkdev_release() as-is. No need to mess with what we have for normal opened files for block devices. And have block_open_by_dev() that would find bdev, etc., same yours does and shove it into anon file. Paired with plain fput() - no need to bother with new primitives for closing. With a helper returning I_BDEV(bdev_file_inode(file)) to get from those to bdev. NOTE: I'm not suggesting replacing ->s_bdev with struct file * if we do that - we want that value cached, obviously. Just store both... Not saying it's a good idea, but... might be interesting to look into. Comments? ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 0/29] block: Make blkdev_get_by_*() return handle 2023-08-25 1:58 ` Al Viro @ 2023-08-25 13:47 ` Jan Kara 2023-08-26 2:28 ` Al Viro ` (2 more replies) 0 siblings, 3 replies; 9+ messages in thread From: Jan Kara @ 2023-08-25 13:47 UTC (permalink / raw) To: Al Viro Cc: Jan Kara, linux-fsdevel, linux-block, Christoph Hellwig, Alasdair Kergon, Andrew Morton, Anna Schumaker, Chao Yu, Christian Borntraeger, Darrick J. Wong, Dave Kleikamp, David Sterba, dm-devel, drbd-dev, Gao Xiang, Jack Wang, Jaegeuk Kim, jfs-discussion, Joern Engel, Joseph Qi, Kent Overstreet, linux-bcache, linux-btrfs, linux-erofs, linux-ext4, linux-f2fs-devel, linux-mm, linux-mtd, linux-nfs, linux-nilfs, linux-nvme, linux-pm, linux-raid, linux-s390, linux-scsi, linux-xfs, Md. Haris Iqbal, Mike Snitzer, Minchan Kim, ocfs2-devel, reiserfs-devel, Sergey Senozhatsky, Song Liu, Sven Schnelle, target-devel, Ted Tso, Trond Myklebust, xen-devel, Jens Axboe, Christian Brauner On Fri 25-08-23 02:58:43, Al Viro wrote: > On Fri, Aug 11, 2023 at 01:04:31PM +0200, Jan Kara wrote: > > Hello, > > > > this is a v2 of the patch series which implements the idea of blkdev_get_by_*() > > calls returning bdev_handle which is then passed to blkdev_put() [1]. This > > makes the get and put calls for bdevs more obviously matching and allows us to > > propagate context from get to put without having to modify all the users > > (again!). In particular I need to propagate used open flags to blkdev_put() to > > be able count writeable opens and add support for blocking writes to mounted > > block devices. I'll send that series separately. > > > > The series is based on Christian's vfs tree as of yesterday as there is quite > > some overlap. Patches have passed some reasonable testing - I've tested block > > changes, md, dm, bcache, xfs, btrfs, ext4, swap. This obviously doesn't cover > > everything so I'd like to ask respective maintainers to review / test their > > changes. Thanks! I've pushed out the full branch to: > > > > git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs.git bdev_handle > > > > to ease review / testing. > > Hmm... Completely Insane Idea(tm): how about turning that thing inside out and > having your bdev_open_by... return an actual opened struct file? > > After all, we do that for sockets and pipes just fine and that's a whole lot > hotter area. > > Suppose we leave blkdev_open()/blkdev_release() as-is. No need to mess with > what we have for normal opened files for block devices. And have block_open_by_dev() > that would find bdev, etc., same yours does and shove it into anon file. > > Paired with plain fput() - no need to bother with new primitives for closing. > With a helper returning I_BDEV(bdev_file_inode(file)) to get from those to bdev. > > NOTE: I'm not suggesting replacing ->s_bdev with struct file * if we do that - > we want that value cached, obviously. Just store both... > > Not saying it's a good idea, but... might be interesting to look into. > Comments? I can see the appeal of not having to introduce the new bdev_handle type and just using struct file which unifies in-kernel and userspace block device opens. But I can see downsides too - the last fput() happening from task work makes me a bit nervous whether it will not break something somewhere with exclusive bdev opens. Getting from struct file to bdev is somewhat harder but I guess a helper like F_BDEV() would solve that just fine. So besides my last fput() worry about I think this could work and would be probably a bit nicer than what I have. But before going and redoing the whole series let me gather some more feedback so that we don't go back and forth. Christoph, Christian, Jens, any opinion? Honza -- Jan Kara <jack@suse.com> SUSE Labs, CR ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 0/29] block: Make blkdev_get_by_*() return handle 2023-08-25 13:47 ` Jan Kara @ 2023-08-26 2:28 ` Al Viro 2023-08-28 14:27 ` Christoph Hellwig 2023-08-28 13:20 ` Christian Brauner 2023-08-28 14:22 ` Christoph Hellwig 2 siblings, 1 reply; 9+ messages in thread From: Al Viro @ 2023-08-26 2:28 UTC (permalink / raw) To: Jan Kara Cc: linux-fsdevel, linux-block, Christoph Hellwig, Alasdair Kergon, Andrew Morton, Anna Schumaker, Chao Yu, Christian Borntraeger, Darrick J. Wong, Dave Kleikamp, David Sterba, dm-devel, drbd-dev, Gao Xiang, Jack Wang, Jaegeuk Kim, jfs-discussion, Joern Engel, Joseph Qi, Kent Overstreet, linux-bcache, linux-btrfs, linux-erofs, linux-ext4, linux-f2fs-devel, linux-mm, linux-mtd, linux-nfs, linux-nilfs, linux-nvme, linux-pm, linux-raid, linux-s390, linux-scsi, linux-xfs, Md. Haris Iqbal, Mike Snitzer, Minchan Kim, ocfs2-devel, reiserfs-devel, Sergey Senozhatsky, Song Liu, Sven Schnelle, target-devel, Ted Tso, Trond Myklebust, xen-devel, Jens Axboe, Christian Brauner On Fri, Aug 25, 2023 at 03:47:56PM +0200, Jan Kara wrote: > I can see the appeal of not having to introduce the new bdev_handle type > and just using struct file which unifies in-kernel and userspace block > device opens. But I can see downsides too - the last fput() happening from > task work makes me a bit nervous whether it will not break something > somewhere with exclusive bdev opens. Getting from struct file to bdev is > somewhat harder but I guess a helper like F_BDEV() would solve that just > fine. > > So besides my last fput() worry about I think this could work and would be > probably a bit nicer than what I have. But before going and redoing the whole > series let me gather some more feedback so that we don't go back and forth. > Christoph, Christian, Jens, any opinion? Redoing is not an issue - it can be done on top of your series just as well. Async behaviour of fput() might be, but... need to look through the actual users; for a lot of them it's perfectly fine. FWIW, from a cursory look there appears to be a missing primitive: take an opened bdev (or bdev_handle, with your variant, or opened file if we go that way eventually) and claim it. I mean, look at claim_swapfile() for example: p->bdev = blkdev_get_by_dev(inode->i_rdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL, p); if (IS_ERR(p->bdev)) { error = PTR_ERR(p->bdev); p->bdev = NULL; return error; } p->old_block_size = block_size(p->bdev); error = set_blocksize(p->bdev, PAGE_SIZE); if (error < 0) return error; we already have the file opened, and we keep it opened all the way until the swapoff(2); here we have noticed that it's a block device and we * open the fucker again (by device number), this time claiming it with our swap_info_struct as holder, to be closed at swapoff(2) time (just before we close the file) * flip the block size to PAGE_SIZE, to be reverted at swapoff(2) time That really looks like it ought to be * take the opened file, see that it's a block device * try to claim it with that holder * on success, flip the block size with close_filp() in the swapoff(2) (or failure exit path in swapon(2)) doing what it would've done for an O_EXCL opened block device. The only difference from O_EXCL userland open is that here we would end up with holder pointing not to struct file in question, but to our swap_info_struct. It will do the right thing. This extra open is entirely due to "well, we need to claim it and the primitive that does that happens to be tied to opening"; feels rather counter-intuitive. For that matter, we could add an explicit "unclaim" primitive - might be easier to follow. That would add another example where that could be used - in blkdev_bszset() we have an opened block device (it's an ioctl, after all), we want to change block size and we *really* don't want to have that happen under a mounted filesystem. So if it's not opened exclusive, we do a temporary exclusive open of own and act on that instead. Might as well go for a temporary claim... BTW, what happens if two threads call ioctl(fd, BLKBSZSET, &n) for the same descriptor that happens to have been opened O_EXCL? Without O_EXCL they would've been unable to claim the sucker at the same time - the holder we are using is the address of a function argument, i.e. something that points to kernel stack of the caller. Those would conflict and we either get set_blocksize() calls fully serialized, or one of the callers would eat -EBUSY. Not so in "opened with O_EXCL" case - they can very well overlap and IIRC set_blocksize() does *not* expect that kind of crap... It's all under CAP_SYS_ADMIN, so it's not as if it was a meaningful security hole anyway, but it does look fishy. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 0/29] block: Make blkdev_get_by_*() return handle 2023-08-26 2:28 ` Al Viro @ 2023-08-28 14:27 ` Christoph Hellwig 0 siblings, 0 replies; 9+ messages in thread From: Christoph Hellwig @ 2023-08-28 14:27 UTC (permalink / raw) To: Al Viro Cc: Jan Kara, linux-fsdevel, linux-block, Christoph Hellwig, Alasdair Kergon, Andrew Morton, Anna Schumaker, Chao Yu, Christian Borntraeger, Darrick J. Wong, Dave Kleikamp, David Sterba, dm-devel, drbd-dev, Gao Xiang, Jack Wang, Jaegeuk Kim, jfs-discussion, Joern Engel, Joseph Qi, Kent Overstreet, linux-bcache, linux-btrfs, linux-erofs, linux-ext4, linux-f2fs-devel, linux-mm, linux-mtd, linux-nfs, linux-nilfs, linux-nvme, linux-pm, linux-raid, linux-s390, linux-scsi, linux-xfs, Md. Haris Iqbal, Mike Snitzer, Minchan Kim, ocfs2-devel, reiserfs-devel, Sergey Senozhatsky, Song Liu, Sven Schnelle, target-devel, Ted Tso, Trond Myklebust, xen-devel, Jens Axboe, Christian Brauner On Sat, Aug 26, 2023 at 03:28:52AM +0100, Al Viro wrote: > I mean, look at claim_swapfile() for example: > p->bdev = blkdev_get_by_dev(inode->i_rdev, > FMODE_READ | FMODE_WRITE | FMODE_EXCL, p); > if (IS_ERR(p->bdev)) { > error = PTR_ERR(p->bdev); > p->bdev = NULL; > return error; > } > p->old_block_size = block_size(p->bdev); > error = set_blocksize(p->bdev, PAGE_SIZE); > if (error < 0) > return error; > we already have the file opened, and we keep it opened all the way until > the swapoff(2); here we have noticed that it's a block device and we > * open the fucker again (by device number), this time claiming > it with our swap_info_struct as holder, to be closed at swapoff(2) time > (just before we close the file) Note that some drivers look at FMODE_EXCL/BLK_OPEN_EXCL in ->open. These are probably bogus and maybe we want to kill them, but that will need an audit first. > BTW, what happens if two threads call ioctl(fd, BLKBSZSET, &n) > for the same descriptor that happens to have been opened O_EXCL? > Without O_EXCL they would've been unable to claim the sucker at the same > time - the holder we are using is the address of a function argument, > i.e. something that points to kernel stack of the caller. Those would > conflict and we either get set_blocksize() calls fully serialized, or > one of the callers would eat -EBUSY. Not so in "opened with O_EXCL" > case - they can very well overlap and IIRC set_blocksize() does *not* > expect that kind of crap... It's all under CAP_SYS_ADMIN, so it's not > as if it was a meaningful security hole anyway, but it does look fishy. The user get to keep the pieces.. BLKBSZSET is kinda bogus anyway as the soft blocksize only matters for buffer_head-like I/O, and there only for file systems. Not idea why anyone would set it manually. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 0/29] block: Make blkdev_get_by_*() return handle 2023-08-25 13:47 ` Jan Kara 2023-08-26 2:28 ` Al Viro @ 2023-08-28 13:20 ` Christian Brauner 2023-08-28 14:22 ` Christoph Hellwig 2 siblings, 0 replies; 9+ messages in thread From: Christian Brauner @ 2023-08-28 13:20 UTC (permalink / raw) To: Jan Kara Cc: Al Viro, linux-fsdevel, linux-block, Christoph Hellwig, Alasdair Kergon, Andrew Morton, Anna Schumaker, Chao Yu, Christian Borntraeger, Darrick J. Wong, Dave Kleikamp, David Sterba, dm-devel, drbd-dev, Gao Xiang, Jack Wang, Jaegeuk Kim, jfs-discussion, Joern Engel, Joseph Qi, Kent Overstreet, linux-bcache, linux-btrfs, linux-erofs, linux-ext4, linux-f2fs-devel, linux-mm, linux-mtd, linux-nfs, linux-nilfs, linux-nvme, linux-pm, linux-raid, linux-s390, linux-scsi, linux-xfs, Md. Haris Iqbal, Mike Snitzer, Minchan Kim, ocfs2-devel, reiserfs-devel, Sergey Senozhatsky, Song Liu, Sven Schnelle, target-devel, Ted Tso, Trond Myklebust, xen-devel, Jens Axboe > So besides my last fput() worry about I think this could work and would be > probably a bit nicer than what I have. But before going and redoing the whole > series let me gather some more feedback so that we don't go back and forth. > Christoph, Christian, Jens, any opinion? I'll be a bit under water for the next few days, I expect but I'll get back to this. I think not making you redo this whole thing from scratch is what I'd prefer unless there's really clear advantages. But I don't want to offer a haphazard opinion in the middle of the merge window. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 0/29] block: Make blkdev_get_by_*() return handle 2023-08-25 13:47 ` Jan Kara 2023-08-26 2:28 ` Al Viro 2023-08-28 13:20 ` Christian Brauner @ 2023-08-28 14:22 ` Christoph Hellwig 2 siblings, 0 replies; 9+ messages in thread From: Christoph Hellwig @ 2023-08-28 14:22 UTC (permalink / raw) To: Jan Kara Cc: Al Viro, linux-fsdevel, linux-block, Christoph Hellwig, Alasdair Kergon, Andrew Morton, Anna Schumaker, Chao Yu, Christian Borntraeger, Darrick J. Wong, Dave Kleikamp, David Sterba, dm-devel, drbd-dev, Gao Xiang, Jack Wang, Jaegeuk Kim, jfs-discussion, Joern Engel, Joseph Qi, Kent Overstreet, linux-bcache, linux-btrfs, linux-erofs, linux-ext4, linux-f2fs-devel, linux-mm, linux-mtd, linux-nfs, linux-nilfs, linux-nvme, linux-pm, linux-raid, linux-s390, linux-scsi, linux-xfs, Md. Haris Iqbal, Mike Snitzer, Minchan Kim, ocfs2-devel, reiserfs-devel, Sergey Senozhatsky, Song Liu, Sven Schnelle, target-devel, Ted Tso, Trond Myklebust, xen-devel, Jens Axboe, Christian Brauner On Fri, Aug 25, 2023 at 03:47:56PM +0200, Jan Kara wrote: > I can see the appeal of not having to introduce the new bdev_handle type > and just using struct file which unifies in-kernel and userspace block > device opens. But I can see downsides too - the last fput() happening from > task work makes me a bit nervous whether it will not break something > somewhere with exclusive bdev opens. Getting from struct file to bdev is > somewhat harder but I guess a helper like F_BDEV() would solve that just > fine. > > So besides my last fput() worry about I think this could work and would be > probably a bit nicer than what I have. But before going and redoing the whole > series let me gather some more feedback so that we don't go back and forth. > Christoph, Christian, Jens, any opinion? I did think about the file a bit. The fact that we'd need something like an anon_file for the by_dev open was always a huge turn off for me, but maybe my concern is overblown. Having a struct file would actually be really useful for a bunch of users. ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2023-08-28 14:28 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2023-08-11 11:04 [PATCH v2 0/29] block: Make blkdev_get_by_*() return handle Jan Kara 2023-08-11 11:04 ` [PATCH 22/29] ext4: Convert to bdev_open_by_dev() Jan Kara 2023-08-11 12:27 ` [PATCH v2 0/29] block: Make blkdev_get_by_*() return handle Christoph Hellwig 2023-08-25 1:58 ` Al Viro 2023-08-25 13:47 ` Jan Kara 2023-08-26 2:28 ` Al Viro 2023-08-28 14:27 ` Christoph Hellwig 2023-08-28 13:20 ` Christian Brauner 2023-08-28 14:22 ` Christoph Hellwig
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).