Commit 925c86a1 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Jens Axboe
Browse files

fs: add CONFIG_BUFFER_HEAD



Add a new config option that controls building the buffer_head code, and
select it from all file systems and stacking drivers that need it.

For the block device nodes and alternative iomap based buffered I/O path
is provided when buffer_head support is not enabled, and iomap needs a
a small tweak to define the IOMAP_F_BUFFER_HEAD flag to 0 to not call
into the buffer_head code when it doesn't exist.

Otherwise this is just Kconfig and ifdef changes.

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarLuis Chamberlain <mcgrof@kernel.org>
Reviewed-by: default avatarJohannes Thumshirn <johannes.thumshirn@wdc.com>
Link: https://lore.kernel.org/r/20230801172201.1923299-7-hch@lst.de


Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 487c607d
Loading
Loading
Loading
Loading
+60 −10
Original line number Diff line number Diff line
@@ -24,15 +24,6 @@ static inline struct inode *bdev_file_inode(struct file *file)
	return file->f_mapping->host;
}

static int blkdev_get_block(struct inode *inode, sector_t iblock,
		struct buffer_head *bh, int create)
{
	bh->b_bdev = I_BDEV(inode);
	bh->b_blocknr = iblock;
	set_buffer_mapped(bh);
	return 0;
}

static blk_opf_t dio_bio_write_op(struct kiocb *iocb)
{
	blk_opf_t opf = REQ_OP_WRITE | REQ_SYNC | REQ_IDLE;
@@ -400,7 +391,7 @@ static int blkdev_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
	iomap->type = IOMAP_MAPPED;
	iomap->addr = iomap->offset;
	iomap->length = isize - iomap->offset;
	iomap->flags |= IOMAP_F_BUFFER_HEAD;
	iomap->flags |= IOMAP_F_BUFFER_HEAD; /* noop for !CONFIG_BUFFER_HEAD */
	return 0;
}

@@ -408,6 +399,16 @@ static const struct iomap_ops blkdev_iomap_ops = {
	.iomap_begin		= blkdev_iomap_begin,
};

#ifdef CONFIG_BUFFER_HEAD
static int blkdev_get_block(struct inode *inode, sector_t iblock,
		struct buffer_head *bh, int create)
{
	bh->b_bdev = I_BDEV(inode);
	bh->b_blocknr = iblock;
	set_buffer_mapped(bh);
	return 0;
}

static int blkdev_writepage(struct page *page, struct writeback_control *wbc)
{
	return block_write_full_page(page, blkdev_get_block, wbc);
@@ -453,6 +454,55 @@ const struct address_space_operations def_blk_aops = {
	.migrate_folio	= buffer_migrate_folio_norefs,
	.is_dirty_writeback = buffer_check_dirty_writeback,
};
#else /* CONFIG_BUFFER_HEAD */
static int blkdev_read_folio(struct file *file, struct folio *folio)
{
	return iomap_read_folio(folio, &blkdev_iomap_ops);
}

static void blkdev_readahead(struct readahead_control *rac)
{
	iomap_readahead(rac, &blkdev_iomap_ops);
}

static int blkdev_map_blocks(struct iomap_writepage_ctx *wpc,
		struct inode *inode, loff_t offset)
{
	loff_t isize = i_size_read(inode);

	if (WARN_ON_ONCE(offset >= isize))
		return -EIO;
	if (offset >= wpc->iomap.offset &&
	    offset < wpc->iomap.offset + wpc->iomap.length)
		return 0;
	return blkdev_iomap_begin(inode, offset, isize - offset,
				  IOMAP_WRITE, &wpc->iomap, NULL);
}

static const struct iomap_writeback_ops blkdev_writeback_ops = {
	.map_blocks		= blkdev_map_blocks,
};

static int blkdev_writepages(struct address_space *mapping,
		struct writeback_control *wbc)
{
	struct iomap_writepage_ctx wpc = { };

	return iomap_writepages(mapping, wbc, &wpc, &blkdev_writeback_ops);
}

const struct address_space_operations def_blk_aops = {
	.dirty_folio	= filemap_dirty_folio,
	.release_folio		= iomap_release_folio,
	.invalidate_folio	= iomap_invalidate_folio,
	.read_folio		= blkdev_read_folio,
	.readahead		= blkdev_readahead,
	.writepages		= blkdev_writepages,
	.is_partially_uptodate  = iomap_is_partially_uptodate,
	.error_remove_page	= generic_error_remove_page,
	.migrate_folio		= filemap_migrate_folio,
};
#endif /* CONFIG_BUFFER_HEAD */

/*
 * for a block special file file_inode(file)->i_size is zero
+1 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@ if MD
config BLK_DEV_MD
	tristate "RAID support"
	select BLOCK_HOLDER_DEPRECATED if SYSFS
	select BUFFER_HEAD
	# BLOCK_LEGACY_AUTOLOAD requirement should be removed
	# after relevant mdadm enhancements - to make "names=yes"
	# the default - are widely available.
+4 −0
Original line number Diff line number Diff line
@@ -18,8 +18,12 @@ config VALIDATE_FS_PARSER
config FS_IOMAP
	bool

config BUFFER_HEAD
	bool

# old blockdev_direct_IO implementation.  Use iomap for new code instead
config LEGACY_DIRECT_IO
	depends on BUFFER_HEAD
	bool

if BLOCK
+1 −1
Original line number Diff line number Diff line
@@ -17,7 +17,7 @@ obj-y := open.o read_write.o file_table.o super.o \
		fs_types.o fs_context.o fs_parser.o fsopen.o init.o \
		kernel_read_file.o mnt_idmapping.o remap_range.o

obj-$(CONFIG_BLOCK)		+= buffer.o mpage.o
obj-$(CONFIG_BUFFER_HEAD)	+= buffer.o mpage.o
obj-$(CONFIG_PROC_FS)		+= proc_namespace.o
obj-$(CONFIG_LEGACY_DIRECT_IO)	+= direct-io.o
obj-y				+= notify/
+1 −0
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@
config ADFS_FS
	tristate "ADFS file system support"
	depends on BLOCK
	select BUFFER_HEAD
	help
	  The Acorn Disc Filing System is the standard file system of the
	  RiscOS operating system which runs on Acorn's ARM-based Risc PC
Loading