From: Jérôme Glisse <jglisse@xxxxxxxxxx> This is part of patchset to remove dependency on struct page.mapping field so that we can temporarily update it to point to a special structure tracking temporary page state (note that original mapping pointer is preserved and can still be accessed but at a cost). Add struct address_space to set_page_dirty() callback arguments. Note that this patch does not make use of the new argument, nor does it use a valid one at call site (by default this patch just use NULL for new argument value). Use following script (from root of linux kernel tree): ./that-script.sh that-semantic-patch.spatch %<-------------------------------------------------------------------- #!/bin/sh spatch_file=$1 echo PART1 =========================================================== # P1 find callback functions name spatch --dir . --no-includes -D part1 --sp-file $spatch_file echo PART2 =========================================================== # P2 change callback function prototype cat /tmp/unicorn-functions | sort | uniq | while read func ; do for file in $( git grep -l $func -- '*.[ch]' ) ; do echo $file spatch --no-includes --in-place -D part2 \ -D fn=$func --sp-file $spatch_file $file done done echo PART 3 ========================================================== # P3 find all function which call the callback spatch --dir . --include-headers -D part3 --sp-file $spatch_file echo PART 4=========================================================== # P4 change all funcitons which call the callback cat /tmp/unicorn-files | sort | uniq | while read file ; do echo $file spatch --no-includes --in-place -D part4 \ --sp-file $spatch_file $file done -------------------------------------------------------------------->% With the following semantic patch: %<-------------------------------------------------------------------- virtual part1, part2, part3, part4 // ---------------------------------------------------------------------------- // Part 1 is grepping all function that are use as callback for set_page_dirty. // initialize file where we collect all function name (erase it) @initialize:python depends on part1@ @@ file=open('/tmp/unicorn-functions', 'w') file.close() // match function name use as a callback @p1r2 depends on part1@ identifier I1, FN; @@ struct address_space_operations I1 = {..., .set_page_dirty = FN, ...}; @script:python p1r3 depends on p1r2@ funcname << p1r2.FN; @@ if funcname != "NULL": file=open('/tmp/unicorn-functions', 'a') file.write(funcname + '\n') file.close() // ------------------------------------------------------------------- // Part 2 modify callback // Add address_space argument to the function (set_page_dirty callback one) @p2r1 depends on part2@ identifier virtual.fn; identifier I1; type T1; @@ int fn( +struct address_space *__mapping, T1 I1) { ... } @p2r2 depends on part2@ identifier virtual.fn; identifier I1; type T1; @@ int fn( +struct address_space *__mapping, T1 I1); @p2r3 depends on part2@ identifier virtual.fn; type T1; @@ int fn( +struct address_space *, T1); @p2r4 depends on part2@ identifier virtual.fn; expression E1; @@ fn( +MAPPING_NULL, E1) // ---------------------------------------------------------------------------- // Part 3 is grepping all function that are use the callback for set_page_dirty. // initialize file where we collect all function name (erase it) @initialize:python depends on part3@ @@ file=open('/tmp/unicorn-files', 'w') file.write("./include/linux/pagemap.h\n") file.write("./mm/page-writeback.c\n") file.write("./include/linux/mm.h\n") file.write("./include/linux/fs.h\n") file.close() @p3r1 depends on part3 exists@ expression E1, E2; identifier FN; position P; @@ FN@P(...) {... ( E1.a_ops->set_page_dirty(E2) | E1->a_ops->set_page_dirty(E2) ) ...} @script:python p3r2 depends on p3r1@ P << p3r1.P; @@ file=open('/tmp/unicorn-files', 'a') file.write(P[0].file + '\n') file.close() // ------------------------------------------------------------------- // Part 4 generic modification @p4r1 depends on part4@ @@ struct address_space_operations { ... int (*set_page_dirty)( +struct address_space *, struct page *page); ... }; @p4r2 depends on part4@ expression E1, E2; @@ E1.a_ops->set_page_dirty( +MAPPING_NULL, E2) @p4r3 depends on part4@ expression E1, E2; @@ E1->a_ops->set_page_dirty( +MAPPING_NULL, E2) @p4r4 depends on part4@ @@ {... -int (*spd)(struct page *) = mapping->a_ops->set_page_dirty; +int (*spd)(struct address_space *, struct page *) = mapping->a_ops->set_page_dirty; ... return (*spd)( +MAPPING_NULL, page); ...} -------------------------------------------------------------------->% Signed-off-by: Jérôme Glisse <jglisse@xxxxxxxxxx> Cc: linux-mm@xxxxxxxxx Cc: linux-fsdevel@xxxxxxxxxxxxxxx Cc: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> Cc: Alexander Viro <viro@xxxxxxxxxxxxxxxxxx> Cc: linux-fsdevel@xxxxxxxxxxxxxxx Cc: Tejun Heo <tj@xxxxxxxxxx> Cc: Jan Kara <jack@xxxxxxx> Cc: Josef Bacik <jbacik@xxxxxx> --- drivers/video/fbdev/core/fb_defio.c | 3 ++- fs/afs/dir.c | 3 ++- fs/afs/internal.h | 2 +- fs/afs/write.c | 4 ++-- fs/btrfs/disk-io.c | 5 +++-- fs/btrfs/extent_io.c | 2 +- fs/btrfs/inode.c | 8 +++++--- fs/buffer.c | 3 ++- fs/ceph/addr.c | 5 +++-- fs/cifs/cifssmb.c | 2 +- fs/ext4/inode.c | 10 ++++++---- fs/f2fs/checkpoint.c | 5 +++-- fs/f2fs/data.c | 7 ++++--- fs/f2fs/node.c | 5 +++-- fs/gfs2/aops.c | 5 +++-- fs/hugetlbfs/inode.c | 3 ++- fs/iomap/buffered-io.c | 4 ++-- fs/libfs.c | 5 +++-- fs/nfs/write.c | 6 +++--- fs/nilfs2/inode.c | 5 +++-- fs/nilfs2/page.c | 2 +- fs/nilfs2/segment.c | 4 ++-- fs/ntfs/aops.c | 2 +- fs/ntfs/file.c | 2 +- fs/reiserfs/inode.c | 7 ++++--- fs/ubifs/file.c | 9 +++++---- include/linux/buffer_head.h | 3 ++- include/linux/fs.h | 5 +++-- include/linux/iomap.h | 2 +- include/linux/mm.h | 6 ++++-- include/linux/swap.h | 3 ++- mm/page-writeback.c | 12 +++++++----- mm/page_io.c | 6 +++--- 33 files changed, 90 insertions(+), 65 deletions(-) diff --git a/drivers/video/fbdev/core/fb_defio.c b/drivers/video/fbdev/core/fb_defio.c index a591d291b231a..32340ff1d7243 100644 --- a/drivers/video/fbdev/core/fb_defio.c +++ b/drivers/video/fbdev/core/fb_defio.c @@ -151,7 +151,8 @@ static const struct vm_operations_struct fb_deferred_io_vm_ops = { .page_mkwrite = fb_deferred_io_mkwrite, }; -static int fb_deferred_io_set_page_dirty(struct page *page) +static int fb_deferred_io_set_page_dirty(struct address_space *__mapping, + struct page *page) { if (!PageDirty(page)) SetPageDirty(page); diff --git a/fs/afs/dir.c b/fs/afs/dir.c index 1d2e61e0ab047..ebcf074bcaaa2 100644 --- a/fs/afs/dir.c +++ b/fs/afs/dir.c @@ -44,7 +44,8 @@ static int afs_dir_releasepage(struct page *page, gfp_t gfp_flags); static void afs_dir_invalidatepage(struct page *page, unsigned int offset, unsigned int length); -static int afs_dir_set_page_dirty(struct page *page) +static int afs_dir_set_page_dirty(struct address_space *__mapping, + struct page *page) { BUG(); /* This should never happen. */ } diff --git a/fs/afs/internal.h b/fs/afs/internal.h index fc1c80c5ddb88..264f28759c737 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h @@ -1422,7 +1422,7 @@ extern int afs_check_volume_status(struct afs_volume *, struct afs_operation *); /* * write.c */ -extern int afs_set_page_dirty(struct page *); +extern int afs_set_page_dirty(struct address_space *, struct page *); extern int afs_write_begin(struct file *file, struct address_space *mapping, loff_t pos, unsigned len, unsigned flags, struct page **pagep, void **fsdata); diff --git a/fs/afs/write.c b/fs/afs/write.c index ef0ea031130af..199cbf73b9be4 100644 --- a/fs/afs/write.c +++ b/fs/afs/write.c @@ -16,10 +16,10 @@ /* * mark a page as having been made dirty and thus needing writeback */ -int afs_set_page_dirty(struct page *page) +int afs_set_page_dirty(struct address_space *__mapping, struct page *page) { _enter(""); - return __set_page_dirty_nobuffers(page); + return __set_page_dirty_nobuffers(MAPPING_NULL, page); } /* diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 51ca16ab59e07..7f548f9f5ace1 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -980,7 +980,8 @@ static void btree_invalidatepage(struct page *page, unsigned int offset, } } -static int btree_set_page_dirty(struct page *page) +static int btree_set_page_dirty(struct address_space *__mapping, + struct page *page) { #ifdef DEBUG struct extent_buffer *eb; @@ -992,7 +993,7 @@ static int btree_set_page_dirty(struct page *page) BUG_ON(!atomic_read(&eb->refs)); btrfs_assert_tree_locked(eb); #endif - return __set_page_dirty_nobuffers(page); + return __set_page_dirty_nobuffers(MAPPING_NULL, page); } static const struct address_space_operations btree_aops = { diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index a940edb1e64f2..02569dffe8e14 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -1514,7 +1514,7 @@ void extent_range_redirty_for_io(struct inode *inode, u64 start, u64 end) while (index <= end_index) { page = find_get_page(inode->i_mapping, index); BUG_ON(!page); /* Pages should be in the extent_io_tree */ - __set_page_dirty_nobuffers(page); + __set_page_dirty_nobuffers(MAPPING_NULL, page); account_page_redirty(page); put_page(page); index++; diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index e73dc72dbd984..9f35648ba06d8 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -735,7 +735,8 @@ static noinline int compress_file_range(struct async_chunk *async_chunk) if (async_chunk->locked_page && (page_offset(async_chunk->locked_page) >= start && page_offset(async_chunk->locked_page)) <= end) { - __set_page_dirty_nobuffers(async_chunk->locked_page); + __set_page_dirty_nobuffers(MAPPING_NULL, + async_chunk->locked_page); /* unlocked later on in the async handlers */ } @@ -9814,9 +9815,10 @@ int btrfs_prealloc_file_range_trans(struct inode *inode, min_size, actual_len, alloc_hint, trans); } -static int btrfs_set_page_dirty(struct page *page) +static int btrfs_set_page_dirty(struct address_space *__mapping, + struct page *page) { - return __set_page_dirty_nobuffers(page); + return __set_page_dirty_nobuffers(MAPPING_NULL, page); } static int btrfs_permission(struct inode *inode, int mask) diff --git a/fs/buffer.c b/fs/buffer.c index c99a468833828..6fb6cf497feb8 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -638,7 +638,8 @@ EXPORT_SYMBOL_GPL(__set_page_dirty); * FIXME: may need to call ->reservepage here as well. That's rather up to the * address_space though. */ -int __set_page_dirty_buffers(struct page *page) +int __set_page_dirty_buffers(struct address_space *__mapping, + struct page *page) { int newly_dirty; struct address_space *mapping = page_mapping(page); diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index 8d348fb29102f..b2b2c8f8118e4 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c @@ -72,7 +72,8 @@ static inline struct ceph_snap_context *page_snap_context(struct page *page) * Dirty a page. Optimistically adjust accounting, on the assumption * that we won't race with invalidate. If we do, readjust. */ -static int ceph_set_page_dirty(struct page *page) +static int ceph_set_page_dirty(struct address_space *__mapping, + struct page *page) { struct address_space *mapping = page->mapping; struct inode *inode; @@ -127,7 +128,7 @@ static int ceph_set_page_dirty(struct page *page) page->private = (unsigned long)snapc; SetPagePrivate(page); - ret = __set_page_dirty_nobuffers(page); + ret = __set_page_dirty_nobuffers(MAPPING_NULL, page); WARN_ON(!PageLocked(page)); WARN_ON(!page->mapping); diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 0496934feecb7..a555efb817b0c 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -2105,7 +2105,7 @@ cifs_writev_complete(struct work_struct *work) for (i = 0; i < wdata->nr_pages; i++) { struct page *page = wdata->pages[i]; if (wdata->result == -EAGAIN) - __set_page_dirty_nobuffers(page); + __set_page_dirty_nobuffers(MAPPING_NULL, page); else if (wdata->result < 0) SetPageError(page); end_page_writeback(page); diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index f8a4d324a6041..528eec0b02bf2 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -3589,17 +3589,19 @@ const struct iomap_ops ext4_iomap_report_ops = { * So what we do is to mark the page "pending dirty" and next time writepage * is called, propagate that into the buffers appropriately. */ -static int ext4_journalled_set_page_dirty(struct page *page) +static int ext4_journalled_set_page_dirty(struct address_space *__mapping, + struct page *page) { SetPageChecked(page); - return __set_page_dirty_nobuffers(page); + return __set_page_dirty_nobuffers(MAPPING_NULL, page); } -static int ext4_set_page_dirty(struct page *page) +static int ext4_set_page_dirty(struct address_space *__mapping, + struct page *page) { WARN_ON_ONCE(!PageLocked(page) && !PageDirty(page)); WARN_ON_ONCE(!page_has_buffers(page)); - return __set_page_dirty_buffers(page); + return __set_page_dirty_buffers(MAPPING_NULL, page); } static const struct address_space_operations ext4_aops = { diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index 4c3c1299c628d..f4594b08270a4 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -432,14 +432,15 @@ long f2fs_sync_meta_pages(struct f2fs_sb_info *sbi, enum page_type type, return nwritten; } -static int f2fs_set_meta_page_dirty(struct page *page) +static int f2fs_set_meta_page_dirty(struct address_space *__mapping, + struct page *page) { trace_f2fs_set_page_dirty(page, META); if (!PageUptodate(page)) SetPageUptodate(page); if (!PageDirty(page)) { - __set_page_dirty_nobuffers(page); + __set_page_dirty_nobuffers(MAPPING_NULL, page); inc_page_count(F2FS_P_SB(page), F2FS_DIRTY_META); f2fs_set_page_private(page, 0); f2fs_trace_pid(page); diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 888569093c9f5..12350175133aa 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -3734,7 +3734,8 @@ int f2fs_release_page(struct page *page, gfp_t wait) return 1; } -static int f2fs_set_data_page_dirty(struct page *page) +static int f2fs_set_data_page_dirty(struct address_space *__mapping, + struct page *page) { struct inode *inode = page_file_mapping(page)->host; @@ -3743,7 +3744,7 @@ static int f2fs_set_data_page_dirty(struct page *page) if (!PageUptodate(page)) SetPageUptodate(page); if (PageSwapCache(page)) - return __set_page_dirty_nobuffers(page); + return __set_page_dirty_nobuffers(MAPPING_NULL, page); if (f2fs_is_atomic_file(inode) && !f2fs_is_commit_atomic_write(inode)) { if (!IS_ATOMIC_WRITTEN_PAGE(page)) { @@ -3758,7 +3759,7 @@ static int f2fs_set_data_page_dirty(struct page *page) } if (!PageDirty(page)) { - __set_page_dirty_nobuffers(page); + __set_page_dirty_nobuffers(MAPPING_NULL, page); f2fs_update_dirty_page(inode, page); return 1; } diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 290e5fdc3bfb9..648a2d7f307bd 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -2072,7 +2072,8 @@ static int f2fs_write_node_pages(struct address_space *mapping, return 0; } -static int f2fs_set_node_page_dirty(struct page *page) +static int f2fs_set_node_page_dirty(struct address_space *__mapping, + struct page *page) { trace_f2fs_set_page_dirty(page, NODE); @@ -2083,7 +2084,7 @@ static int f2fs_set_node_page_dirty(struct page *page) f2fs_inode_chksum_set(F2FS_P_SB(page), page); #endif if (!PageDirty(page)) { - __set_page_dirty_nobuffers(page); + __set_page_dirty_nobuffers(MAPPING_NULL, page); inc_page_count(F2FS_P_SB(page), F2FS_DIRTY_NODES); f2fs_set_page_private(page, 0); f2fs_trace_pid(page); diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c index 826dd0677fdb9..8911771f95c5c 100644 --- a/fs/gfs2/aops.c +++ b/fs/gfs2/aops.c @@ -624,10 +624,11 @@ void adjust_fs_space(struct inode *inode) * Returns: 1 if it dirtyed the page, or 0 otherwise */ -static int jdata_set_page_dirty(struct page *page) +static int jdata_set_page_dirty(struct address_space *__mapping, + struct page *page) { SetPageChecked(page); - return __set_page_dirty_buffers(page); + return __set_page_dirty_buffers(MAPPING_NULL, page); } /** diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index b5c109703daaf..b675b615cead0 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -947,7 +947,8 @@ static int hugetlbfs_symlink(struct inode *dir, /* * mark the head page dirty */ -static int hugetlbfs_set_page_dirty(struct page *page) +static int hugetlbfs_set_page_dirty(struct address_space *__mapping, + struct page *page) { struct page *head = compound_head(page); diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c index bcfc288dba3fb..26f7fe7c80adc 100644 --- a/fs/iomap/buffered-io.c +++ b/fs/iomap/buffered-io.c @@ -661,7 +661,7 @@ iomap_write_begin(struct inode *inode, loff_t pos, unsigned len, unsigned flags, } int -iomap_set_page_dirty(struct page *page) +iomap_set_page_dirty(struct address_space *__mapping, struct page *page) { struct address_space *mapping = page_mapping(page); int newly_dirty; @@ -705,7 +705,7 @@ __iomap_write_end(struct inode *inode, loff_t pos, unsigned len, if (unlikely(copied < len && !PageUptodate(page))) return 0; iomap_set_range_uptodate(page, offset_in_page(pos), len); - iomap_set_page_dirty(page); + iomap_set_page_dirty(MAPPING_NULL, page); return copied; } diff --git a/fs/libfs.c b/fs/libfs.c index 7df05487cdde6..899feec2eb683 100644 --- a/fs/libfs.c +++ b/fs/libfs.c @@ -1156,7 +1156,7 @@ int noop_fsync(struct file *file, loff_t start, loff_t end, int datasync) } EXPORT_SYMBOL(noop_fsync); -int noop_set_page_dirty(struct page *page) +int noop_set_page_dirty(struct address_space *__mapping, struct page *page) { /* * Unlike __set_page_dirty_no_writeback that handles dirty page @@ -1206,7 +1206,8 @@ EXPORT_SYMBOL(kfree_link); * nop .set_page_dirty method so that people can use .page_mkwrite on * anon inodes. */ -static int anon_set_page_dirty(struct page *page) +static int anon_set_page_dirty(struct address_space *__mapping, + struct page *page) { return 0; }; diff --git a/fs/nfs/write.c b/fs/nfs/write.c index b7fe16714d9cc..c4f04b191b72f 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -808,7 +808,7 @@ static void nfs_mark_request_dirty(struct nfs_page *req) { if (req->wb_page) - __set_page_dirty_nobuffers(req->wb_page); + __set_page_dirty_nobuffers(MAPPING_NULL, req->wb_page); } /* @@ -1376,7 +1376,7 @@ int nfs_updatepage(struct file *file, struct page *page, if (status < 0) nfs_set_pageerror(mapping); else - __set_page_dirty_nobuffers(page); + __set_page_dirty_nobuffers(MAPPING_NULL, page); out: dprintk("NFS: nfs_updatepage returns %d (isize %lld)\n", status, (long long)i_size_read(inode)); @@ -1792,7 +1792,7 @@ static void nfs_commit_resched_write(struct nfs_commit_info *cinfo, struct nfs_page *req) { - __set_page_dirty_nobuffers(req->wb_page); + __set_page_dirty_nobuffers(MAPPING_NULL, req->wb_page); } /* diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c index 00a22de8e2376..1cedff7bc4e13 100644 --- a/fs/nilfs2/inode.c +++ b/fs/nilfs2/inode.c @@ -201,10 +201,11 @@ static int nilfs_writepage(struct address_space *__mapping, struct page *page, return 0; } -static int nilfs_set_page_dirty(struct page *page) +static int nilfs_set_page_dirty(struct address_space *__mapping, + struct page *page) { struct inode *inode = page->mapping->host; - int ret = __set_page_dirty_nobuffers(page); + int ret = __set_page_dirty_nobuffers(MAPPING_NULL, page); if (page_has_buffers(page)) { unsigned int nr_dirty = 0; diff --git a/fs/nilfs2/page.c b/fs/nilfs2/page.c index b175f1330408a..5137b82fb43d5 100644 --- a/fs/nilfs2/page.c +++ b/fs/nilfs2/page.c @@ -270,7 +270,7 @@ int nilfs_copy_dirty_pages(struct address_space *dmap, "found empty page in dat page cache"); nilfs_copy_page(dpage, page, 1); - __set_page_dirty_nobuffers(dpage); + __set_page_dirty_nobuffers(MAPPING_NULL, dpage); unlock_page(dpage); put_page(dpage); diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c index e3726aca28ed6..1a4ea72ad50f1 100644 --- a/fs/nilfs2/segment.c +++ b/fs/nilfs2/segment.c @@ -1732,10 +1732,10 @@ static void nilfs_end_page_io(struct page *page, int err) if (!err) { if (!nilfs_page_buffers_clean(page)) - __set_page_dirty_nobuffers(page); + __set_page_dirty_nobuffers(MAPPING_NULL, page); ClearPageError(page); } else { - __set_page_dirty_nobuffers(page); + __set_page_dirty_nobuffers(MAPPING_NULL, page); SetPageError(page); } diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c index d920cb780a4ea..3d3a6b6bc6717 100644 --- a/fs/ntfs/aops.c +++ b/fs/ntfs/aops.c @@ -1749,7 +1749,7 @@ void mark_ntfs_record_dirty(struct page *page, const unsigned int ofs) { set_buffer_dirty(bh); } while ((bh = bh->b_this_page) != head); spin_unlock(&mapping->private_lock); - __set_page_dirty_nobuffers(page); + __set_page_dirty_nobuffers(MAPPING_NULL, page); if (unlikely(buffers_to_free)) { do { bh = buffers_to_free->b_this_page; diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c index f42967b738eb6..c863f62351a62 100644 --- a/fs/ntfs/file.c +++ b/fs/ntfs/file.c @@ -1660,7 +1660,7 @@ static int ntfs_commit_pages_after_write(struct page **pages, * Put the page on mapping->dirty_pages, but leave its * buffers' dirty state as-is. */ - __set_page_dirty_nobuffers(page); + __set_page_dirty_nobuffers(MAPPING_NULL, page); err = 0; } else ntfs_error(vi->i_sb, "Page is not uptodate. Written " diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 5a34ab78f66cd..9ef4365c07fdd 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c @@ -3209,14 +3209,15 @@ static void reiserfs_invalidatepage(struct page *page, unsigned int offset, return; } -static int reiserfs_set_page_dirty(struct page *page) +static int reiserfs_set_page_dirty(struct address_space *__mapping, + struct page *page) { struct inode *inode = page->mapping->host; if (reiserfs_file_data_log(inode)) { SetPageChecked(page); - return __set_page_dirty_nobuffers(page); + return __set_page_dirty_nobuffers(MAPPING_NULL, page); } - return __set_page_dirty_buffers(page); + return __set_page_dirty_buffers(MAPPING_NULL, page); } /* diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c index fcc6c307313f2..5af8c311d38f0 100644 --- a/fs/ubifs/file.c +++ b/fs/ubifs/file.c @@ -572,7 +572,7 @@ static int ubifs_write_end(struct file *file, struct address_space *mapping, if (!PagePrivate(page)) { SetPagePrivate(page); atomic_long_inc(&c->dirty_pg_cnt); - __set_page_dirty_nobuffers(page); + __set_page_dirty_nobuffers(MAPPING_NULL, page); } if (appending) { @@ -1446,13 +1446,14 @@ static ssize_t ubifs_write_iter(struct kiocb *iocb, struct iov_iter *from) return generic_file_write_iter(iocb, from); } -static int ubifs_set_page_dirty(struct page *page) +static int ubifs_set_page_dirty(struct address_space *__mapping, + struct page *page) { int ret; struct inode *inode = page->mapping->host; struct ubifs_info *c = inode->i_sb->s_fs_info; - ret = __set_page_dirty_nobuffers(page); + ret = __set_page_dirty_nobuffers(MAPPING_NULL, page); /* * An attempt to dirty a page without budgeting for it - should not * happen. @@ -1570,7 +1571,7 @@ static vm_fault_t ubifs_vm_page_mkwrite(struct vm_fault *vmf) ubifs_convert_page_budget(c); SetPagePrivate(page); atomic_long_inc(&c->dirty_pg_cnt); - __set_page_dirty_nobuffers(page); + __set_page_dirty_nobuffers(MAPPING_NULL, page); } if (update_time) { diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h index 6b47f94378c5a..07fe6d613ed9f 100644 --- a/include/linux/buffer_head.h +++ b/include/linux/buffer_head.h @@ -396,7 +396,8 @@ __bread(struct block_device *bdev, sector_t block, unsigned size) return __bread_gfp(bdev, block, size, __GFP_MOVABLE); } -extern int __set_page_dirty_buffers(struct page *page); +extern int __set_page_dirty_buffers(struct address_space *__mapping, + struct page *page); #else /* CONFIG_BLOCK */ diff --git a/include/linux/fs.h b/include/linux/fs.h index acd51e3880762..0b1e2c231dcf8 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -378,7 +378,7 @@ struct address_space_operations { int (*writepages)(struct address_space *, struct writeback_control *); /* Set a page dirty. Return true if this dirtied it */ - int (*set_page_dirty)(struct page *page); + int (*set_page_dirty)(struct address_space *, struct page *page); /* * Reads in the requested pages. Unlike ->readpage(), this is @@ -3223,7 +3223,8 @@ extern int simple_rename(struct inode *, struct dentry *, extern void simple_recursive_removal(struct dentry *, void (*callback)(struct dentry *)); extern int noop_fsync(struct file *, loff_t, loff_t, int); -extern int noop_set_page_dirty(struct page *page); +extern int noop_set_page_dirty(struct address_space *__mapping, + struct page *page); extern void noop_invalidatepage(struct page *page, unsigned int offset, unsigned int length); extern ssize_t noop_direct_IO(struct kiocb *iocb, struct iov_iter *iter); diff --git a/include/linux/iomap.h b/include/linux/iomap.h index 4d1d3c3469e9a..781f22ee0a53b 100644 --- a/include/linux/iomap.h +++ b/include/linux/iomap.h @@ -156,7 +156,7 @@ ssize_t iomap_file_buffered_write(struct kiocb *iocb, struct iov_iter *from, const struct iomap_ops *ops); int iomap_readpage(struct page *page, const struct iomap_ops *ops); void iomap_readahead(struct readahead_control *, const struct iomap_ops *ops); -int iomap_set_page_dirty(struct page *page); +int iomap_set_page_dirty(struct address_space *__mapping, struct page *page); int iomap_is_partially_uptodate(struct page *page, unsigned long from, unsigned long count); int iomap_releasepage(struct page *page, gfp_t gfp_mask); diff --git a/include/linux/mm.h b/include/linux/mm.h index d165961c58c45..1bf229c4176bc 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1796,8 +1796,10 @@ extern void do_invalidatepage(struct page *page, unsigned int offset, unsigned int length); void __set_page_dirty(struct page *, struct address_space *, int warn); -int __set_page_dirty_nobuffers(struct page *page); -int __set_page_dirty_no_writeback(struct page *page); +int __set_page_dirty_nobuffers(struct address_space *__mapping, + struct page *page); +int __set_page_dirty_no_writeback(struct address_space *__mapping, + struct page *page); int redirty_page_for_writepage(struct writeback_control *wbc, struct page *page); void account_page_dirtied(struct page *page, struct address_space *mapping); diff --git a/include/linux/swap.h b/include/linux/swap.h index f2355fca8b38b..b0316c44869d2 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -397,7 +397,8 @@ extern int swap_writepage(struct address_space *__mapping, struct page *page, extern void end_swap_bio_write(struct bio *bio); extern int __swap_writepage(struct page *page, struct writeback_control *wbc, bio_end_io_t end_write_func); -extern int swap_set_page_dirty(struct page *page); +extern int swap_set_page_dirty(struct address_space *__mapping, + struct page *page); int add_swap_extent(struct swap_info_struct *sis, unsigned long start_page, unsigned long nr_pages, sector_t start_block); diff --git a/mm/page-writeback.c b/mm/page-writeback.c index de15d2febc5ae..78ead3581040e 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c @@ -2403,7 +2403,8 @@ EXPORT_SYMBOL(write_one_page); /* * For address_spaces which do not use buffers nor write back. */ -int __set_page_dirty_no_writeback(struct page *page) +int __set_page_dirty_no_writeback(struct address_space *__mapping, + struct page *page) { if (!PageDirty(page)) return !TestSetPageDirty(page); @@ -2470,7 +2471,8 @@ void account_page_cleaned(struct page *page, struct address_space *mapping, * hold the page lock, but e.g. zap_pte_range() calls with the page mapped and * the pte lock held, which also locks out truncation. */ -int __set_page_dirty_nobuffers(struct page *page) +int __set_page_dirty_nobuffers(struct address_space *__mapping, + struct page *page) { lock_page_memcg(page); if (!TestSetPageDirty(page)) { @@ -2537,7 +2539,7 @@ int redirty_page_for_writepage(struct writeback_control *wbc, struct page *page) int ret; wbc->pages_skipped++; - ret = __set_page_dirty_nobuffers(page); + ret = __set_page_dirty_nobuffers(MAPPING_NULL, page); account_page_redirty(page); return ret; } @@ -2560,7 +2562,7 @@ int set_page_dirty(struct page *page) page = compound_head(page); if (likely(mapping)) { - int (*spd)(struct page *) = mapping->a_ops->set_page_dirty; + int (*spd)(struct address_space *, struct page *) = mapping->a_ops->set_page_dirty; /* * readahead/lru_deactivate_page could remain * PG_readahead/PG_reclaim due to race with end_page_writeback @@ -2577,7 +2579,7 @@ int set_page_dirty(struct page *page) if (!spd) spd = __set_page_dirty_buffers; #endif - return (*spd)(page); + return (*spd)(MAPPING_NULL, page); } if (!PageDirty(page)) { if (!TestSetPageDirty(page)) diff --git a/mm/page_io.c b/mm/page_io.c index 067159b23ee54..60617b6420c01 100644 --- a/mm/page_io.c +++ b/mm/page_io.c @@ -452,7 +452,7 @@ int swap_readpage(struct page *page, bool synchronous) return ret; } -int swap_set_page_dirty(struct page *page) +int swap_set_page_dirty(struct address_space *__mapping, struct page *page) { struct swap_info_struct *sis = page_swap_info(page); @@ -460,8 +460,8 @@ int swap_set_page_dirty(struct page *page) struct address_space *mapping = sis->swap_file->f_mapping; VM_BUG_ON_PAGE(!PageSwapCache(page), page); - return mapping->a_ops->set_page_dirty(page); + return mapping->a_ops->set_page_dirty(MAPPING_NULL, page); } else { - return __set_page_dirty_no_writeback(page); + return __set_page_dirty_no_writeback(MAPPING_NULL, page); } } -- 2.26.2