generic_cont_expand_simple() and cont_expand_zero() currently call ->write_begin and ->write_end, so will also need to be converted to use buffered_write_operations. Use macro magic again to pass in optional buffered_write_operations. Signed-off-by: Matthew Wilcox (Oracle) <willy@xxxxxxxxxxxxx> --- fs/buffer.c | 62 +++++++++++++++++++++++++++---------- include/linux/buffer_head.h | 22 ++++++++++--- 2 files changed, 64 insertions(+), 20 deletions(-) diff --git a/fs/buffer.c b/fs/buffer.c index d3bcf601d3e5..8ed76fc6cff0 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -2441,11 +2441,13 @@ EXPORT_SYMBOL(block_read_full_folio); * truncates. Uses filesystem pagecache writes to allow the filesystem to * deal with the hole. */ -int generic_cont_expand_simple(struct inode *inode, loff_t size) +int generic_cont_expand_simple(struct inode *inode, loff_t size, + const struct buffered_write_operations *ops) { struct address_space *mapping = inode->i_mapping; const struct address_space_operations *aops = mapping->a_ops; struct page *page; + struct folio *folio; void *fsdata = NULL; int err; @@ -2453,11 +2455,17 @@ int generic_cont_expand_simple(struct inode *inode, loff_t size) if (err) goto out; - err = aops->write_begin(NULL, mapping, size, 0, &page, &fsdata); + if (ops) + err = ops->write_begin(NULL, mapping, size, 0, &folio, &fsdata); + else + err = aops->write_begin(NULL, mapping, size, 0, &page, &fsdata); if (err) goto out; - err = aops->write_end(NULL, mapping, size, 0, 0, page, fsdata); + if (ops) + err = ops->write_end(NULL, mapping, size, 0, 0, folio, &fsdata); + else + err = aops->write_end(NULL, mapping, size, 0, 0, page, fsdata); BUG_ON(err > 0); out: @@ -2466,12 +2474,14 @@ int generic_cont_expand_simple(struct inode *inode, loff_t size) EXPORT_SYMBOL(generic_cont_expand_simple); static int cont_expand_zero(struct file *file, struct address_space *mapping, - loff_t pos, loff_t *bytes) + loff_t pos, loff_t *bytes, + const struct buffered_write_operations *ops) { struct inode *inode = mapping->host; const struct address_space_operations *aops = mapping->a_ops; unsigned int blocksize = i_blocksize(inode); struct page *page; + struct folio *folio; void *fsdata = NULL; pgoff_t index, curidx; loff_t curpos; @@ -2489,13 +2499,23 @@ static int cont_expand_zero(struct file *file, struct address_space *mapping, } len = PAGE_SIZE - zerofrom; - err = aops->write_begin(file, mapping, curpos, len, - &page, &fsdata); + if (ops) { + err = ops->write_begin(file, mapping, curpos, len, + &folio, &fsdata); + page = &folio->page; + } else { + err = aops->write_begin(file, mapping, curpos, len, + &page, &fsdata); + } if (err) goto out; zero_user(page, zerofrom, len); - err = aops->write_end(file, mapping, curpos, len, len, - page, fsdata); + if (ops) + err = ops->write_end(file, mapping, curpos, len, len, + folio, &fsdata); + else + err = aops->write_end(file, mapping, curpos, len, len, + page, fsdata); if (err < 0) goto out; BUG_ON(err != len); @@ -2522,13 +2542,23 @@ static int cont_expand_zero(struct file *file, struct address_space *mapping, } len = offset - zerofrom; - err = aops->write_begin(file, mapping, curpos, len, - &page, &fsdata); + if (ops) { + err = ops->write_begin(file, mapping, curpos, len, + &folio, &fsdata); + page = &folio->page; + } else { + err = aops->write_begin(file, mapping, curpos, len, + &page, &fsdata); + } if (err) goto out; zero_user(page, zerofrom, len); - err = aops->write_end(file, mapping, curpos, len, len, - page, fsdata); + if (ops) + err = ops->write_end(file, mapping, curpos, len, len, + folio, &fsdata); + else + err = aops->write_end(file, mapping, curpos, len, len, + page, fsdata); if (err < 0) goto out; BUG_ON(err != len); @@ -2543,16 +2573,16 @@ static int cont_expand_zero(struct file *file, struct address_space *mapping, * We may have to extend the file. */ int cont_write_begin(struct file *file, struct address_space *mapping, - loff_t pos, unsigned len, - struct page **pagep, void **fsdata, - get_block_t *get_block, loff_t *bytes) + loff_t pos, unsigned len, struct page **pagep, void **fsdata, + get_block_t *get_block, loff_t *bytes, + const struct buffered_write_operations *ops) { struct inode *inode = mapping->host; unsigned int blocksize = i_blocksize(inode); unsigned int zerofrom; int err; - err = cont_expand_zero(file, mapping, pos, bytes); + err = cont_expand_zero(file, mapping, pos, bytes, ops); if (err) return err; diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h index d78454a4dd1f..80de88c12d23 100644 --- a/include/linux/buffer_head.h +++ b/include/linux/buffer_head.h @@ -268,16 +268,30 @@ int generic_write_end(struct file *, struct address_space *, loff_t, unsigned, unsigned, struct page *, void *); void folio_zero_new_buffers(struct folio *folio, size_t from, size_t to); -int cont_write_begin(struct file *, struct address_space *, loff_t, - unsigned, struct page **, void **, - get_block_t *, loff_t *); -int generic_cont_expand_simple(struct inode *inode, loff_t size); +int cont_write_begin(struct file *, struct address_space *, loff_t pos, + unsigned len, struct page **, void **fsdata, get_block_t *, + loff_t *bytes, const struct buffered_write_operations *); +int generic_cont_expand_simple(struct inode *inode, loff_t size, + const struct buffered_write_operations *ops); void block_commit_write(struct page *page, unsigned int from, unsigned int to); int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, get_block_t get_block); sector_t generic_block_bmap(struct address_space *, sector_t, get_block_t *); int block_truncate_page(struct address_space *, loff_t, get_block_t *); +#define _cont_write_begin(file, mapping, pos, len, pagep, fsdata, \ + getblk, bytes, ops, extra...) \ + cont_write_begin(file, mapping, pos, len, pagep, fsdata, \ + getblk,bytes, ops) +#define cont_write_begin(file, mapping, pos, len, pagep, fsdata, \ + getblk, bytes, ops...) \ + _cont_write_begin(file, mapping, pos, len, pagep, fsdata, \ + getblk, bytes, ## ops, NULL) +#define _generic_cont_expand_simple(inode, size, ops, extra...) \ + generic_cont_expand_simple(inode, size, ops) +#define generic_cont_expand_simple(inode, size, ops...) \ + _generic_cont_expand_simple(inode, size, ## ops, NULL) + #ifdef CONFIG_MIGRATION extern int buffer_migrate_folio(struct address_space *, struct folio *dst, struct folio *src, enum migrate_mode); -- 2.43.0