[PATCH 06/14] mm: add struct address_space to set_page_dirty() callback

From: jglisse
Date: Tue Oct 06 2020 - 21:08:05 EST


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