@@ -388,7 +388,7 @@ static int blkdev_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
struct block_device *bdev = I_BDEV(inode);
loff_t isize = i_size_read(inode);
- iomap->bdev = bdev;
+ iomap_set_bdev_file(iomap, inode->i_private);
iomap->offset = ALIGN_DOWN(offset, bdev_logical_block_size(bdev));
if (iomap->offset >= isize)
return -EIO;
@@ -7709,7 +7709,7 @@ static int btrfs_dio_iomap_begin(struct inode *inode, loff_t start,
iomap->type = IOMAP_MAPPED;
}
iomap->offset = start;
- iomap->bdev = fs_info->fs_devices->latest_dev->bdev;
+ iomap_set_bdev_file(iomap, fs_info->fs_devices->latest_dev->bdev_file);
iomap->length = len;
free_extent_map(em);
@@ -2005,7 +2005,7 @@ iomap_to_bh(struct inode *inode, sector_t block, struct buffer_head *bh,
{
loff_t offset = (loff_t)block << inode->i_blkbits;
- bh->b_bdev = iomap->bdev;
+ bh->b_bdev = iomap_bdev(iomap);
/*
* Block points to offset in file we need to map, iomap contains
@@ -204,6 +204,7 @@ int erofs_map_dev(struct super_block *sb, struct erofs_map_dev *map)
int id;
map->m_bdev = sb->s_bdev;
+ map->m_bdev_file = sb->s_bdev_file;
map->m_daxdev = EROFS_SB(sb)->dax_dev;
map->m_dax_part_off = EROFS_SB(sb)->dax_part_off;
map->m_fscache = EROFS_SB(sb)->s_fscache;
@@ -220,7 +221,13 @@ int erofs_map_dev(struct super_block *sb, struct erofs_map_dev *map)
up_read(&devs->rwsem);
return 0;
}
- map->m_bdev = dif->bdev_file ? file_bdev(dif->bdev_file) : NULL;
+ if (dif->bdev_file) {
+ map->m_bdev = file_bdev(dif->bdev_file);
+ map->m_bdev_file = dif->bdev_file;
+ } else {
+ map->m_bdev = NULL;
+ map->m_bdev_file = NULL;
+ }
map->m_daxdev = dif->dax_dev;
map->m_dax_part_off = dif->dax_part_off;
map->m_fscache = dif->fscache;
@@ -238,8 +245,13 @@ int erofs_map_dev(struct super_block *sb, struct erofs_map_dev *map)
if (map->m_pa >= startoff &&
map->m_pa < startoff + length) {
map->m_pa -= startoff;
- map->m_bdev = dif->bdev_file ?
- file_bdev(dif->bdev_file) : NULL;
+ if (dif->bdev_file) {
+ map->m_bdev = file_bdev(dif->bdev_file);
+ map->m_bdev_file = dif->bdev_file;
+ } else {
+ map->m_bdev = NULL;
+ map->m_bdev_file = NULL;
+ }
map->m_daxdev = dif->dax_dev;
map->m_dax_part_off = dif->dax_part_off;
map->m_fscache = dif->fscache;
@@ -278,7 +290,7 @@ static int erofs_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
if (flags & IOMAP_DAX)
iomap->dax_dev = mdev.m_daxdev;
else
- iomap->bdev = mdev.m_bdev;
+ iomap_set_bdev_file(iomap, mdev.m_bdev_file);
iomap->length = map.m_llen;
iomap->flags = 0;
iomap->private = NULL;
@@ -378,6 +378,7 @@ enum {
struct erofs_map_dev {
struct erofs_fscache *m_fscache;
struct block_device *m_bdev;
+ struct file *m_bdev_file;
struct dax_device *m_daxdev;
u64 m_dax_part_off;
@@ -739,7 +739,7 @@ static int z_erofs_iomap_begin_report(struct inode *inode, loff_t offset,
if (ret < 0)
return ret;
- iomap->bdev = inode->i_sb->s_bdev;
+ iomap_set_bdev_file(iomap, inode->i_sb->s_bdev_file);
iomap->offset = map.m_la;
iomap->length = map.m_llen;
if (map.m_flags & EROFS_MAP_MAPPED) {
@@ -842,7 +842,7 @@ static int ext2_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
if (flags & IOMAP_DAX)
iomap->dax_dev = sbi->s_daxdev;
else
- iomap->bdev = inode->i_sb->s_bdev;
+ iomap_set_bdev_file(iomap, inode->i_sb->s_bdev_file);
if (ret == 0) {
/*
@@ -3235,7 +3235,7 @@ static void ext4_set_iomap(struct inode *inode, struct iomap *iomap,
if (flags & IOMAP_DAX)
iomap->dax_dev = EXT4_SB(inode->i_sb)->s_daxdev;
else
- iomap->bdev = inode->i_sb->s_bdev;
+ iomap_set_bdev_file(iomap, inode->i_sb->s_bdev_file);
iomap->offset = (u64) map->m_lblk << blkbits;
iomap->length = (u64) map->m_len << blkbits;
@@ -1499,10 +1499,12 @@ static bool f2fs_map_blocks_cached(struct inode *inode,
struct f2fs_dev_info *dev = &sbi->devs[bidx];
map->m_bdev = dev->bdev;
+ map->m_bdev_file = dev->bdev_file;
map->m_pblk -= dev->start_blk;
map->m_len = min(map->m_len, dev->end_blk + 1 - map->m_pblk);
} else {
map->m_bdev = inode->i_sb->s_bdev;
+ map->m_bdev_file = inode->i_sb->s_bdev_file;
}
return true;
}
@@ -1534,6 +1536,7 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map, int flag)
goto out;
map->m_bdev = inode->i_sb->s_bdev;
+ map->m_bdev_file = inode->i_sb->s_bdev_file;
map->m_multidev_dio =
f2fs_allow_multi_device_dio(F2FS_I_SB(inode), flag);
@@ -1651,8 +1654,10 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map, int flag)
map->m_pblk = blkaddr;
map->m_len = 1;
- if (map->m_multidev_dio)
+ if (map->m_multidev_dio) {
map->m_bdev = FDEV(bidx).bdev;
+ map->m_bdev_file = FDEV(bidx).bdev_file;
+ }
} else if ((map->m_pblk != NEW_ADDR &&
blkaddr == (map->m_pblk + ofs)) ||
(map->m_pblk == NEW_ADDR && blkaddr == NEW_ADDR) ||
@@ -1725,6 +1730,7 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map, int flag)
bidx = f2fs_target_device_index(sbi, map->m_pblk);
map->m_bdev = FDEV(bidx).bdev;
+ map->m_bdev_file = FDEV(bidx).bdev_file;
map->m_pblk -= FDEV(bidx).start_blk;
if (map->m_may_create)
@@ -4189,7 +4195,7 @@ static int f2fs_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
iomap->length = blks_to_bytes(inode, map.m_len);
iomap->type = IOMAP_MAPPED;
iomap->flags |= IOMAP_F_MERGED;
- iomap->bdev = map.m_bdev;
+ iomap_set_bdev_file(iomap, map.m_bdev_file);
iomap->addr = blks_to_bytes(inode, map.m_pblk);
} else {
if (flags & IOMAP_WRITE)
@@ -699,6 +699,7 @@ struct extent_tree_info {
struct f2fs_map_blocks {
struct block_device *m_bdev; /* for multi-device dio */
+ struct file *m_bdev_file; /* for multi-device dio */
block_t m_pblk;
block_t m_lblk;
unsigned int m_len;
@@ -575,7 +575,7 @@ static int fuse_iomap_begin(struct inode *inode, loff_t pos, loff_t length,
iomap->offset = pos;
iomap->flags = 0;
- iomap->bdev = NULL;
+ iomap_set_bdev_file(iomap, NULL);
iomap->dax_dev = fc->dax->dev;
/*
@@ -926,7 +926,7 @@ static int __gfs2_iomap_get(struct inode *inode, loff_t pos, loff_t length,
iomap->flags |= IOMAP_F_GFS2_BOUNDARY;
out:
- iomap->bdev = inode->i_sb->s_bdev;
+ iomap_set_bdev_file(iomap, inode->i_sb->s_bdev_file);
unlock:
up_read(&ip->i_rw_mutex);
return ret;
@@ -128,7 +128,7 @@ static int hpfs_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
if (WARN_ON_ONCE(flags & (IOMAP_WRITE | IOMAP_ZERO)))
return -EINVAL;
- iomap->bdev = inode->i_sb->s_bdev;
+ iomap_set_bdev_file(iomap, inode->i_sb->s_bdev_file);
iomap->offset = offset;
hpfs_lock(sb);
@@ -415,7 +415,7 @@ static loff_t iomap_readpage_iter(const struct iomap_iter *iter,
if (ctx->rac) /* same as readahead_gfp_mask */
gfp |= __GFP_NORETRY | __GFP_NOWARN;
- ctx->bio = bio_alloc(iomap->bdev, bio_max_segs(nr_vecs),
+ ctx->bio = bio_alloc(iomap_bdev(iomap), bio_max_segs(nr_vecs),
REQ_OP_READ, gfp);
/*
* If the bio_alloc fails, try it again for a single page to
@@ -423,7 +423,7 @@ static loff_t iomap_readpage_iter(const struct iomap_iter *iter,
* what do_mpage_read_folio does.
*/
if (!ctx->bio) {
- ctx->bio = bio_alloc(iomap->bdev, 1, REQ_OP_READ,
+ ctx->bio = bio_alloc(iomap_bdev(iomap), 1, REQ_OP_READ,
orig_gfp);
}
if (ctx->rac)
@@ -662,7 +662,7 @@ static int iomap_read_folio_sync(loff_t block_start, struct folio *folio,
struct bio_vec bvec;
struct bio bio;
- bio_init(&bio, iomap->bdev, &bvec, 1, REQ_OP_READ);
+ bio_init(&bio, iomap_bdev(iomap), &bvec, 1, REQ_OP_READ);
bio.bi_iter.bi_sector = iomap_sector(iomap, block_start);
bio_add_folio_nofail(&bio, folio, plen, poff);
return submit_bio_wait(&bio);
@@ -1684,7 +1684,7 @@ static struct iomap_ioend *iomap_alloc_ioend(struct iomap_writepage_ctx *wpc,
struct iomap_ioend *ioend;
struct bio *bio;
- bio = bio_alloc_bioset(wpc->iomap.bdev, BIO_MAX_VECS,
+ bio = bio_alloc_bioset(iomap_bdev(&wpc->iomap), BIO_MAX_VECS,
REQ_OP_WRITE | wbc_to_write_flags(wbc),
GFP_NOFS, &iomap_ioend_bioset);
bio->bi_iter.bi_sector = iomap_sector(&wpc->iomap, pos);
@@ -56,9 +56,9 @@ static struct bio *iomap_dio_alloc_bio(const struct iomap_iter *iter,
struct iomap_dio *dio, unsigned short nr_vecs, blk_opf_t opf)
{
if (dio->dops && dio->dops->bio_set)
- return bio_alloc_bioset(iter->iomap.bdev, nr_vecs, opf,
+ return bio_alloc_bioset(iomap_bdev(&iter->iomap), nr_vecs, opf,
GFP_KERNEL, dio->dops->bio_set);
- return bio_alloc(iter->iomap.bdev, nr_vecs, opf, GFP_KERNEL);
+ return bio_alloc(iomap_bdev(&iter->iomap), nr_vecs, opf, GFP_KERNEL);
}
static void iomap_dio_submit_bio(const struct iomap_iter *iter,
@@ -288,8 +288,8 @@ static loff_t iomap_dio_bio_iter(const struct iomap_iter *iter,
size_t copied = 0;
size_t orig_count;
- if ((pos | length) & (bdev_logical_block_size(iomap->bdev) - 1) ||
- !bdev_iter_is_aligned(iomap->bdev, dio->submit.iter))
+ if ((pos | length) & (bdev_logical_block_size(iomap_bdev(iomap)) - 1) ||
+ !bdev_iter_is_aligned(iomap_bdev(iomap), dio->submit.iter))
return -EINVAL;
if (iomap->type == IOMAP_UNWRITTEN) {
@@ -316,7 +316,8 @@ static loff_t iomap_dio_bio_iter(const struct iomap_iter *iter,
*/
if (!(iomap->flags & (IOMAP_F_SHARED|IOMAP_F_DIRTY)) &&
(dio->flags & IOMAP_DIO_WRITE_THROUGH) &&
- (bdev_fua(iomap->bdev) || !bdev_write_cache(iomap->bdev)))
+ (bdev_fua(iomap_bdev(iomap)) ||
+ !bdev_write_cache(iomap_bdev(iomap))))
use_fua = true;
else if (dio->flags & IOMAP_DIO_NEED_SYNC)
dio->flags &= ~IOMAP_DIO_CALLER_COMP;
@@ -116,7 +116,7 @@ static loff_t iomap_swapfile_iter(const struct iomap_iter *iter,
return iomap_swapfile_fail(isi, "has shared extents");
/* Only one bdev per swap file. */
- if (iomap->bdev != isi->sis->bdev)
+ if (iomap_bdev(iomap) != isi->sis->bdev)
return iomap_swapfile_fail(isi, "outside the main device");
if (isi->iomap.length == 0) {
@@ -134,7 +134,8 @@ DECLARE_EVENT_CLASS(iomap_class,
__entry->length = iomap->length;
__entry->type = iomap->type;
__entry->flags = iomap->flags;
- __entry->bdev = iomap->bdev ? iomap->bdev->bd_dev : 0;
+ __entry->bdev = iomap_bdev(iomap) ?
+ iomap_bdev(iomap)->bd_dev : 0;
),
TP_printk("dev %d:%d ino 0x%llx bdev %d:%d addr 0x%llx offset 0x%llx "
"length 0x%llx type %s flags %s",
@@ -181,7 +182,8 @@ TRACE_EVENT(iomap_writepage_map,
__entry->length = iomap->length;
__entry->type = iomap->type;
__entry->flags = iomap->flags;
- __entry->bdev = iomap->bdev ? iomap->bdev->bd_dev : 0;
+ __entry->bdev = iomap_bdev(iomap) ?
+ iomap_bdev(iomap)->bd_dev : 0;
),
TP_printk("dev %d:%d ino 0x%llx bdev %d:%d pos 0x%llx dirty len 0x%llx "
"addr 0x%llx offset 0x%llx length 0x%llx type %s flags %s",
@@ -129,7 +129,7 @@ xfs_bmbt_to_iomap(
if (mapping_flags & IOMAP_DAX)
iomap->dax_dev = target->bt_daxdev;
else
- iomap->bdev = target->bt_bdev;
+ iomap_set_bdev_file(iomap, target->bt_bdev_file);
iomap->flags = iomap_flags;
if (xfs_ipincount(ip) &&
@@ -154,7 +154,7 @@ xfs_hole_to_iomap(
iomap->type = IOMAP_HOLE;
iomap->offset = XFS_FSB_TO_B(ip->i_mount, offset_fsb);
iomap->length = XFS_FSB_TO_B(ip->i_mount, end_fsb - offset_fsb);
- iomap->bdev = target->bt_bdev;
+ iomap_set_bdev_file(iomap, target->bt_bdev_file);
iomap->dax_dev = target->bt_daxdev;
}
@@ -38,7 +38,7 @@ static int zonefs_read_iomap_begin(struct inode *inode, loff_t offset,
* act as if there is a hole up to the file maximum size.
*/
mutex_lock(&zi->i_truncate_mutex);
- iomap->bdev = inode->i_sb->s_bdev;
+ iomap_set_bdev_file(iomap, inode->i_sb->s_bdev_file);
iomap->offset = ALIGN_DOWN(offset, sb->s_blocksize);
isize = i_size_read(inode);
if (iomap->offset >= isize) {
@@ -88,7 +88,7 @@ static int zonefs_write_iomap_begin(struct inode *inode, loff_t offset,
* write pointer) and unwriten beyond.
*/
mutex_lock(&zi->i_truncate_mutex);
- iomap->bdev = inode->i_sb->s_bdev;
+ iomap_set_bdev_file(iomap, inode->i_sb->s_bdev_file);
iomap->offset = ALIGN_DOWN(offset, sb->s_blocksize);
iomap->addr = (z->z_sector << SECTOR_SHIFT) + iomap->offset;
isize = i_size_read(inode);
@@ -105,6 +105,17 @@ struct iomap {
u64 validity_cookie; /* used with .iomap_valid() */
};
+static inline struct block_device *iomap_bdev(const struct iomap *iomap)
+{
+ return iomap->bdev;
+}
+
+static inline void iomap_set_bdev_file(struct iomap *iomap,
+ struct file *bdev_file)
+{
+ iomap->bdev = bdev_file ? file_bdev(bdev_file) : NULL;
+}
+
static inline sector_t iomap_sector(const struct iomap *iomap, loff_t pos)
{
return (iomap->addr + pos - iomap->offset) >> SECTOR_SHIFT;