linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH V2 0/9] Introduce attach/clear_page_private to cleanup code
@ 2020-04-30 21:44 Guoqing Jiang
  2020-04-30 21:44 ` [RFC PATCH V2 1/9] include/linux/pagemap.h: introduce attach/clear_page_private Guoqing Jiang
                   ` (9 more replies)
  0 siblings, 10 replies; 21+ messages in thread
From: Guoqing Jiang @ 2020-04-30 21:44 UTC (permalink / raw)
  To: linux-fsdevel, linux-kernel; +Cc: hch, david, willy, Guoqing Jiang

Hi,

Based on the previous thread [1], this patchset introduces attach_page_private
and clear_page_private to replace attach_page_buffers and __clear_page_buffers.
Thanks a lot for the constructive suggestions and comments from Christoph,
Matthew and Dave.

And sorry for cross post to different lists since it modifies different subsystems.

RFC -> RFC V2:

1. rename the new functions and add comments for them.
2. change the return type of attach_page_private.
3. call attach_page_private(newpage, clear_page_private(page)) to cleanup code further.
4. avoid potential use-after-free in orangefs.

[1]. https://lore.kernel.org/linux-fsdevel/20200420221424.GH5820@bombadil.infradead.org/

Thanks,
Guoqing

Guoqing Jiang (9):
  include/linux/pagemap.h: introduce attach/clear_page_private
  md: remove __clear_page_buffers and use attach/clear_page_private
  btrfs: use attach/clear_page_private
  fs/buffer.c: use attach/clear_page_private
  f2fs: use attach/clear_page_private
  iomap: use attach/clear_page_private
  ntfs: replace attach_page_buffers with attach_page_private
  orangefs: use attach/clear_page_private
  buffer_head.h: remove attach_page_buffers

 drivers/md/md-bitmap.c      | 12 ++----------
 fs/btrfs/disk-io.c          |  4 +---
 fs/btrfs/extent_io.c        | 21 ++++++---------------
 fs/btrfs/inode.c            | 23 +++++------------------
 fs/buffer.c                 | 16 ++++------------
 fs/f2fs/f2fs.h              | 11 ++---------
 fs/iomap/buffered-io.c      | 19 ++++---------------
 fs/ntfs/aops.c              |  2 +-
 fs/ntfs/mft.c               |  2 +-
 fs/orangefs/inode.c         | 32 ++++++--------------------------
 include/linux/buffer_head.h |  8 --------
 include/linux/pagemap.h     | 35 +++++++++++++++++++++++++++++++++++
 12 files changed, 67 insertions(+), 118 deletions(-)

-- 
2.17.1


^ permalink raw reply	[flat|nested] 21+ messages in thread

* [RFC PATCH V2 1/9] include/linux/pagemap.h: introduce attach/clear_page_private
  2020-04-30 21:44 [RFC PATCH V2 0/9] Introduce attach/clear_page_private to cleanup code Guoqing Jiang
@ 2020-04-30 21:44 ` Guoqing Jiang
  2020-04-30 22:10   ` Andreas Grünbacher
  2020-04-30 22:13   ` Matthew Wilcox
  2020-04-30 21:44 ` [RFC PATCH V2 2/9] md: remove __clear_page_buffers and use attach/clear_page_private Guoqing Jiang
                   ` (8 subsequent siblings)
  9 siblings, 2 replies; 21+ messages in thread
From: Guoqing Jiang @ 2020-04-30 21:44 UTC (permalink / raw)
  To: linux-fsdevel, linux-kernel
  Cc: hch, david, willy, Guoqing Jiang, Andrew Morton, Darrick J. Wong,
	William Kucharski, Kirill A. Shutemov, Andreas Gruenbacher,
	Yang Shi, Yafang Shao, Song Liu, linux-raid, Chris Mason,
	Josef Bacik, David Sterba, linux-btrfs, Alexander Viro,
	Jaegeuk Kim, Chao Yu, linux-f2fs-devel, linux-xfs,
	Anton Altaparmakov, linux-ntfs-dev, Mike Marshall,
	Martin Brandenburg, devel, Thomas Gleixner,
	Sebastian Andrzej Siewior, Roman Gushchin, Andreas Dilger

The logic in attach_page_buffers and  __clear_page_buffers are quite
paired, but

1. they are located in different files.

2. attach_page_buffers is implemented in buffer_head.h, so it could be
   used by other files. But __clear_page_buffers is static function in
   buffer.c and other potential users can't call the function, md-bitmap
   even copied the function.

So, introduce the new attach/clear_page_private to replace them. With
the new pair of function, we will remove the usage of attach_page_buffers
and  __clear_page_buffers in next patches. Thanks for the new names from
Christoph Hellwig.

Suggested-by: Matthew Wilcox <willy@infradead.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: "Darrick J. Wong" <darrick.wong@oracle.com>
Cc: William Kucharski <william.kucharski@oracle.com>
Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
Cc: Andreas Gruenbacher <agruenba@redhat.com>
Cc: Yang Shi <yang.shi@linux.alibaba.com>
Cc: Yafang Shao <laoar.shao@gmail.com>
Cc: Song Liu <song@kernel.org>
Cc: linux-raid@vger.kernel.org
Cc: Chris Mason <clm@fb.com>
Cc: Josef Bacik <josef@toxicpanda.com>
Cc: David Sterba <dsterba@suse.com>
Cc: linux-btrfs@vger.kernel.org
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Jaegeuk Kim <jaegeuk@kernel.org>
Cc: Chao Yu <chao@kernel.org>
Cc: linux-f2fs-devel@lists.sourceforge.net
Cc: Christoph Hellwig <hch@infradead.org>
Cc: linux-xfs@vger.kernel.org
Cc: Anton Altaparmakov <anton@tuxera.com>
Cc: linux-ntfs-dev@lists.sourceforge.net
Cc: Mike Marshall <hubcap@omnibond.com>
Cc: Martin Brandenburg <martin@omnibond.com>
Cc: devel@lists.orangefs.org
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: Roman Gushchin <guro@fb.com>
Cc: Andreas Dilger <adilger@dilger.ca>
Signed-off-by: Guoqing Jiang <guoqing.jiang@cloud.ionos.com>
---
RFC -> RFC V2:  Address the comments from Christoph Hellwig
1. change function names to attach/clear_page_private and add comments.
2. change the return type of attach_page_private.

 include/linux/pagemap.h | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index a8f7bd8ea1c6..2e515f210b18 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -205,6 +205,41 @@ static inline int page_cache_add_speculative(struct page *page, int count)
 	return __page_cache_add_speculative(page, count);
 }
 
+/**
+ * attach_page_private - attach data to page's private field and set PG_private.
+ * @page: page to be attached and set flag.
+ * @data: data to attach to page's private field.
+ *
+ * Need to take reference as mm.h said "Setting PG_private should also increment
+ * the refcount".
+ */
+static inline void attach_page_private(struct page *page, void *data)
+{
+	get_page(page);
+	set_page_private(page, (unsigned long)data);
+	SetPagePrivate(page);
+}
+
+/**
+ * clear_page_private - clear page's private field and PG_private.
+ * @page: page to be cleared.
+ *
+ * The counterpart function of attach_page_private.
+ * Return: private data of page or NULL if page doesn't have private data.
+ */
+static inline void *clear_page_private(struct page *page)
+{
+	void *data = (void *)page_private(page);
+
+	if (!PagePrivate(page))
+		return NULL;
+	ClearPagePrivate(page);
+	set_page_private(page, 0);
+	put_page(page);
+
+	return data;
+}
+
 #ifdef CONFIG_NUMA
 extern struct page *__page_cache_alloc(gfp_t gfp);
 #else
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [RFC PATCH V2 2/9] md: remove __clear_page_buffers and use attach/clear_page_private
  2020-04-30 21:44 [RFC PATCH V2 0/9] Introduce attach/clear_page_private to cleanup code Guoqing Jiang
  2020-04-30 21:44 ` [RFC PATCH V2 1/9] include/linux/pagemap.h: introduce attach/clear_page_private Guoqing Jiang
@ 2020-04-30 21:44 ` Guoqing Jiang
  2020-04-30 21:44 ` [RFC PATCH V2 3/9] btrfs: " Guoqing Jiang
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 21+ messages in thread
From: Guoqing Jiang @ 2020-04-30 21:44 UTC (permalink / raw)
  To: linux-fsdevel, linux-kernel
  Cc: hch, david, willy, Guoqing Jiang, Song Liu, linux-raid

After introduce attach/clear_page_private in pagemap.h, we can remove
the duplicat code and call the new functions.

Cc: Song Liu <song@kernel.org>
Cc: linux-raid@vger.kernel.org
Signed-off-by: Guoqing Jiang <guoqing.jiang@cloud.ionos.com>
---
RFC -> RFC V2
1. change the name of new functions to attach/clear_page_private.

 drivers/md/md-bitmap.c | 12 ++----------
 1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c
index b952bd45bd6a..033d12063600 100644
--- a/drivers/md/md-bitmap.c
+++ b/drivers/md/md-bitmap.c
@@ -324,14 +324,6 @@ static void end_bitmap_write(struct buffer_head *bh, int uptodate)
 		wake_up(&bitmap->write_wait);
 }
 
-/* copied from buffer.c */
-static void
-__clear_page_buffers(struct page *page)
-{
-	ClearPagePrivate(page);
-	set_page_private(page, 0);
-	put_page(page);
-}
 static void free_buffers(struct page *page)
 {
 	struct buffer_head *bh;
@@ -345,7 +337,7 @@ static void free_buffers(struct page *page)
 		free_buffer_head(bh);
 		bh = next;
 	}
-	__clear_page_buffers(page);
+	clear_page_private(page);
 	put_page(page);
 }
 
@@ -374,7 +366,7 @@ static int read_page(struct file *file, unsigned long index,
 		ret = -ENOMEM;
 		goto out;
 	}
-	attach_page_buffers(page, bh);
+	attach_page_private(page, bh);
 	blk_cur = index << (PAGE_SHIFT - inode->i_blkbits);
 	while (bh) {
 		block = blk_cur;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [RFC PATCH V2 3/9] btrfs: use attach/clear_page_private
  2020-04-30 21:44 [RFC PATCH V2 0/9] Introduce attach/clear_page_private to cleanup code Guoqing Jiang
  2020-04-30 21:44 ` [RFC PATCH V2 1/9] include/linux/pagemap.h: introduce attach/clear_page_private Guoqing Jiang
  2020-04-30 21:44 ` [RFC PATCH V2 2/9] md: remove __clear_page_buffers and use attach/clear_page_private Guoqing Jiang
@ 2020-04-30 21:44 ` Guoqing Jiang
  2020-04-30 21:44 ` [RFC PATCH V2 4/9] fs/buffer.c: " Guoqing Jiang
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 21+ messages in thread
From: Guoqing Jiang @ 2020-04-30 21:44 UTC (permalink / raw)
  To: linux-fsdevel, linux-kernel
  Cc: hch, david, willy, Guoqing Jiang, Chris Mason, Josef Bacik,
	David Sterba, linux-btrfs

Since the new pair function is introduced, we can call them to clean the
code in btrfs.

Cc: Chris Mason <clm@fb.com>
Cc: Josef Bacik <josef@toxicpanda.com>
Cc: David Sterba <dsterba@suse.com>
Cc: linux-btrfs@vger.kernel.org
Signed-off-by: Guoqing Jiang <guoqing.jiang@cloud.ionos.com>
---
RFC -> RFC V2
1. change the name of new functions to attach/clear_page_private.
2. call attach_page_private(newpage, clear_page_private(page)) to
   cleanup code further as suggested by Dave Chinner.

 fs/btrfs/disk-io.c   |  4 +---
 fs/btrfs/extent_io.c | 21 ++++++---------------
 fs/btrfs/inode.c     | 23 +++++------------------
 3 files changed, 12 insertions(+), 36 deletions(-)

diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index a6cb5cbbdb9f..fe4acf821110 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -980,9 +980,7 @@ static void btree_invalidatepage(struct page *page, unsigned int offset,
 		btrfs_warn(BTRFS_I(page->mapping->host)->root->fs_info,
 			   "page private not zero on page %llu",
 			   (unsigned long long)page_offset(page));
-		ClearPagePrivate(page);
-		set_page_private(page, 0);
-		put_page(page);
+		clear_page_private(page);
 	}
 }
 
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index 39e45b8a5031..095a5e83e660 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -3076,22 +3076,16 @@ static int submit_extent_page(unsigned int opf,
 static void attach_extent_buffer_page(struct extent_buffer *eb,
 				      struct page *page)
 {
-	if (!PagePrivate(page)) {
-		SetPagePrivate(page);
-		get_page(page);
-		set_page_private(page, (unsigned long)eb);
-	} else {
+	if (!PagePrivate(page))
+		attach_page_private(page, eb);
+	else
 		WARN_ON(page->private != (unsigned long)eb);
-	}
 }
 
 void set_page_extent_mapped(struct page *page)
 {
-	if (!PagePrivate(page)) {
-		SetPagePrivate(page);
-		get_page(page);
-		set_page_private(page, EXTENT_PAGE_PRIVATE);
-	}
+	if (!PagePrivate(page))
+		attach_page_private(page, (void *)EXTENT_PAGE_PRIVATE);
 }
 
 static struct extent_map *
@@ -4929,10 +4923,7 @@ static void btrfs_release_extent_buffer_pages(struct extent_buffer *eb)
 			 * We need to make sure we haven't be attached
 			 * to a new eb.
 			 */
-			ClearPagePrivate(page);
-			set_page_private(page, 0);
-			/* One for the page private */
-			put_page(page);
+			clear_page_private(page);
 		}
 
 		if (mapped)
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 320d1062068d..34b09ab2c32a 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -8303,11 +8303,8 @@ btrfs_readpages(struct file *file, struct address_space *mapping,
 static int __btrfs_releasepage(struct page *page, gfp_t gfp_flags)
 {
 	int ret = try_release_extent_mapping(page, gfp_flags);
-	if (ret == 1) {
-		ClearPagePrivate(page);
-		set_page_private(page, 0);
-		put_page(page);
-	}
+	if (ret == 1)
+		clear_page_private(page);
 	return ret;
 }
 
@@ -8329,14 +8326,8 @@ static int btrfs_migratepage(struct address_space *mapping,
 	if (ret != MIGRATEPAGE_SUCCESS)
 		return ret;
 
-	if (page_has_private(page)) {
-		ClearPagePrivate(page);
-		get_page(newpage);
-		set_page_private(newpage, page_private(page));
-		set_page_private(page, 0);
-		put_page(page);
-		SetPagePrivate(newpage);
-	}
+	if (page_has_private(page))
+		attach_page_private(newpage, clear_page_private(page));
 
 	if (PagePrivate2(page)) {
 		ClearPagePrivate2(page);
@@ -8458,11 +8449,7 @@ static void btrfs_invalidatepage(struct page *page, unsigned int offset,
 	}
 
 	ClearPageChecked(page);
-	if (PagePrivate(page)) {
-		ClearPagePrivate(page);
-		set_page_private(page, 0);
-		put_page(page);
-	}
+	clear_page_private(page);
 }
 
 /*
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [RFC PATCH V2 4/9] fs/buffer.c: use attach/clear_page_private
  2020-04-30 21:44 [RFC PATCH V2 0/9] Introduce attach/clear_page_private to cleanup code Guoqing Jiang
                   ` (2 preceding siblings ...)
  2020-04-30 21:44 ` [RFC PATCH V2 3/9] btrfs: " Guoqing Jiang
@ 2020-04-30 21:44 ` Guoqing Jiang
  2020-04-30 21:44 ` [RFC PATCH V2 5/9] f2fs: " Guoqing Jiang
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 21+ messages in thread
From: Guoqing Jiang @ 2020-04-30 21:44 UTC (permalink / raw)
  To: linux-fsdevel, linux-kernel
  Cc: hch, david, willy, Guoqing Jiang, Alexander Viro

Since the new pair function is introduced, we can call them to clean the
code in buffer.c.

Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Guoqing Jiang <guoqing.jiang@cloud.ionos.com>
---
RFC -> RFC V2
1. change the name of new functions to attach/clear_page_private.

 fs/buffer.c | 16 ++++------------
 1 file changed, 4 insertions(+), 12 deletions(-)

diff --git a/fs/buffer.c b/fs/buffer.c
index a60f60396cfa..60dd61384b13 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -123,14 +123,6 @@ void __wait_on_buffer(struct buffer_head * bh)
 }
 EXPORT_SYMBOL(__wait_on_buffer);
 
-static void
-__clear_page_buffers(struct page *page)
-{
-	ClearPagePrivate(page);
-	set_page_private(page, 0);
-	put_page(page);
-}
-
 static void buffer_io_error(struct buffer_head *bh, char *msg)
 {
 	if (!test_bit(BH_Quiet, &bh->b_state))
@@ -906,7 +898,7 @@ link_dev_buffers(struct page *page, struct buffer_head *head)
 		bh = bh->b_this_page;
 	} while (bh);
 	tail->b_this_page = head;
-	attach_page_buffers(page, head);
+	attach_page_private(page, head);
 }
 
 static sector_t blkdev_max_block(struct block_device *bdev, unsigned int size)
@@ -1580,7 +1572,7 @@ void create_empty_buffers(struct page *page,
 			bh = bh->b_this_page;
 		} while (bh != head);
 	}
-	attach_page_buffers(page, head);
+	attach_page_private(page, head);
 	spin_unlock(&page->mapping->private_lock);
 }
 EXPORT_SYMBOL(create_empty_buffers);
@@ -2567,7 +2559,7 @@ static void attach_nobh_buffers(struct page *page, struct buffer_head *head)
 			bh->b_this_page = head;
 		bh = bh->b_this_page;
 	} while (bh != head);
-	attach_page_buffers(page, head);
+	attach_page_private(page, head);
 	spin_unlock(&page->mapping->private_lock);
 }
 
@@ -3227,7 +3219,7 @@ drop_buffers(struct page *page, struct buffer_head **buffers_to_free)
 		bh = next;
 	} while (bh != head);
 	*buffers_to_free = head;
-	__clear_page_buffers(page);
+	clear_page_private(page);
 	return 1;
 failed:
 	return 0;
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [RFC PATCH V2 5/9] f2fs: use attach/clear_page_private
  2020-04-30 21:44 [RFC PATCH V2 0/9] Introduce attach/clear_page_private to cleanup code Guoqing Jiang
                   ` (3 preceding siblings ...)
  2020-04-30 21:44 ` [RFC PATCH V2 4/9] fs/buffer.c: " Guoqing Jiang
@ 2020-04-30 21:44 ` Guoqing Jiang
  2020-04-30 21:44 ` [RFC PATCH V2 6/9] iomap: " Guoqing Jiang
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 21+ messages in thread
From: Guoqing Jiang @ 2020-04-30 21:44 UTC (permalink / raw)
  To: linux-fsdevel, linux-kernel
  Cc: hch, david, willy, Guoqing Jiang, Jaegeuk Kim, linux-f2fs-devel

Since the new pair function is introduced, we can call them to clean the
code in f2fs.h.

Cc: Jaegeuk Kim <jaegeuk@kernel.org>
Cc: linux-f2fs-devel@lists.sourceforge.net
Acked-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Guoqing Jiang <guoqing.jiang@cloud.ionos.com>
---
RFC -> RFC V2
1. change the name of new functions to attach/clear_page_private.

 fs/f2fs/f2fs.h | 11 ++---------
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index ba470d5687fe..24d22bd7352d 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -3051,19 +3051,12 @@ static inline void f2fs_set_page_private(struct page *page,
 	if (PagePrivate(page))
 		return;
 
-	get_page(page);
-	SetPagePrivate(page);
-	set_page_private(page, data);
+	attach_page_private(page, (void *)data);
 }
 
 static inline void f2fs_clear_page_private(struct page *page)
 {
-	if (!PagePrivate(page))
-		return;
-
-	set_page_private(page, 0);
-	ClearPagePrivate(page);
-	f2fs_put_page(page, 0);
+	clear_page_private(page);
 }
 
 /*
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [RFC PATCH V2 6/9] iomap: use attach/clear_page_private
  2020-04-30 21:44 [RFC PATCH V2 0/9] Introduce attach/clear_page_private to cleanup code Guoqing Jiang
                   ` (4 preceding siblings ...)
  2020-04-30 21:44 ` [RFC PATCH V2 5/9] f2fs: " Guoqing Jiang
@ 2020-04-30 21:44 ` Guoqing Jiang
  2020-04-30 21:44 ` [RFC PATCH V2 7/9] ntfs: replace attach_page_buffers with attach_page_private Guoqing Jiang
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 21+ messages in thread
From: Guoqing Jiang @ 2020-04-30 21:44 UTC (permalink / raw)
  To: linux-fsdevel, linux-kernel
  Cc: hch, david, willy, Guoqing Jiang, Darrick J. Wong, linux-xfs

Since the new pair function is introduced, we can call them to clean the
code in iomap.

Cc: Christoph Hellwig <hch@infradead.org>
Cc: "Darrick J. Wong" <darrick.wong@oracle.com>
Cc: linux-xfs@vger.kernel.org
Signed-off-by: Guoqing Jiang <guoqing.jiang@cloud.ionos.com>
---
RFC -> RFC V2
1. change the name of new functions to attach/clear_page_private.
2. call attach_page_private(newpage, clear_page_private(page)) to
   cleanup code further as suggested by Matthew Wilcox.
3. don't return attach_page_private in iomap_page_create per the
   comment from Christoph Hellwig.

 fs/iomap/buffered-io.c | 19 ++++---------------
 1 file changed, 4 insertions(+), 15 deletions(-)

diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c
index 89e21961d1ad..cf4c1b02a9d8 100644
--- a/fs/iomap/buffered-io.c
+++ b/fs/iomap/buffered-io.c
@@ -59,24 +59,19 @@ iomap_page_create(struct inode *inode, struct page *page)
 	 * migrate_page_move_mapping() assumes that pages with private data have
 	 * their count elevated by 1.
 	 */
-	get_page(page);
-	set_page_private(page, (unsigned long)iop);
-	SetPagePrivate(page);
+	attach_page_private(page, iop);
 	return iop;
 }
 
 static void
 iomap_page_release(struct page *page)
 {
-	struct iomap_page *iop = to_iomap_page(page);
+	struct iomap_page *iop = clear_page_private(page);
 
 	if (!iop)
 		return;
 	WARN_ON_ONCE(atomic_read(&iop->read_count));
 	WARN_ON_ONCE(atomic_read(&iop->write_count));
-	ClearPagePrivate(page);
-	set_page_private(page, 0);
-	put_page(page);
 	kfree(iop);
 }
 
@@ -554,14 +549,8 @@ iomap_migrate_page(struct address_space *mapping, struct page *newpage,
 	if (ret != MIGRATEPAGE_SUCCESS)
 		return ret;
 
-	if (page_has_private(page)) {
-		ClearPagePrivate(page);
-		get_page(newpage);
-		set_page_private(newpage, page_private(page));
-		set_page_private(page, 0);
-		put_page(page);
-		SetPagePrivate(newpage);
-	}
+	if (page_has_private(page))
+		attach_page_private(newpage, clear_page_private(page));
 
 	if (mode != MIGRATE_SYNC_NO_COPY)
 		migrate_page_copy(newpage, page);
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [RFC PATCH V2 7/9] ntfs: replace attach_page_buffers with attach_page_private
  2020-04-30 21:44 [RFC PATCH V2 0/9] Introduce attach/clear_page_private to cleanup code Guoqing Jiang
                   ` (5 preceding siblings ...)
  2020-04-30 21:44 ` [RFC PATCH V2 6/9] iomap: " Guoqing Jiang
@ 2020-04-30 21:44 ` Guoqing Jiang
  2020-04-30 21:44 ` [RFC PATCH V2 8/9] orangefs: use attach/clear_page_private Guoqing Jiang
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 21+ messages in thread
From: Guoqing Jiang @ 2020-04-30 21:44 UTC (permalink / raw)
  To: linux-fsdevel, linux-kernel
  Cc: hch, david, willy, Guoqing Jiang, Anton Altaparmakov, linux-ntfs-dev

Call the new function since attach_page_buffers will be removed.

Cc: Anton Altaparmakov <anton@tuxera.com>
Cc: linux-ntfs-dev@lists.sourceforge.net
Signed-off-by: Guoqing Jiang <guoqing.jiang@cloud.ionos.com>
---
RFC -> RFC V2
1. change the name of new function to attach_page_private.

 fs/ntfs/aops.c | 2 +-
 fs/ntfs/mft.c  | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c
index 554b744f41bf..bb0a43860ad2 100644
--- a/fs/ntfs/aops.c
+++ b/fs/ntfs/aops.c
@@ -1732,7 +1732,7 @@ void mark_ntfs_record_dirty(struct page *page, const unsigned int ofs) {
 				bh = bh->b_this_page;
 			} while (bh);
 			tail->b_this_page = head;
-			attach_page_buffers(page, head);
+			attach_page_private(page, head);
 		} else
 			buffers_to_free = bh;
 	}
diff --git a/fs/ntfs/mft.c b/fs/ntfs/mft.c
index 3aac5c917afe..fbb9f1bc623d 100644
--- a/fs/ntfs/mft.c
+++ b/fs/ntfs/mft.c
@@ -504,7 +504,7 @@ int ntfs_sync_mft_mirror(ntfs_volume *vol, const unsigned long mft_no,
 			bh = bh->b_this_page;
 		} while (bh);
 		tail->b_this_page = head;
-		attach_page_buffers(page, head);
+		attach_page_private(page, head);
 	}
 	bh = head = page_buffers(page);
 	BUG_ON(!bh);
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [RFC PATCH V2 8/9] orangefs: use attach/clear_page_private
  2020-04-30 21:44 [RFC PATCH V2 0/9] Introduce attach/clear_page_private to cleanup code Guoqing Jiang
                   ` (6 preceding siblings ...)
  2020-04-30 21:44 ` [RFC PATCH V2 7/9] ntfs: replace attach_page_buffers with attach_page_private Guoqing Jiang
@ 2020-04-30 21:44 ` Guoqing Jiang
  2020-04-30 21:44 ` [RFC PATCH V2 9/9] buffer_head.h: remove attach_page_buffers Guoqing Jiang
  2020-05-01 22:16 ` [RFC PATCH V2 0/9] Introduce attach/clear_page_private to cleanup code Matthew Wilcox
  9 siblings, 0 replies; 21+ messages in thread
From: Guoqing Jiang @ 2020-04-30 21:44 UTC (permalink / raw)
  To: linux-fsdevel, linux-kernel
  Cc: hch, david, willy, Guoqing Jiang, Mike Marshall,
	Martin Brandenburg, devel

Since the new pair function is introduced, we can call them to clean the
code in orangefs.

Cc: Mike Marshall <hubcap@omnibond.com>
Cc: Martin Brandenburg <martin@omnibond.com>
Cc: devel@lists.orangefs.org
Signed-off-by: Guoqing Jiang <guoqing.jiang@cloud.ionos.com>
---
RFC -> RFC V2
1. change the name of new functions to attach/clear_page_private.
2. avoid potential use-after-free as suggested by Dave Chinner.

 fs/orangefs/inode.c | 32 ++++++--------------------------
 1 file changed, 6 insertions(+), 26 deletions(-)

diff --git a/fs/orangefs/inode.c b/fs/orangefs/inode.c
index 12ae630fbed7..139c450aca68 100644
--- a/fs/orangefs/inode.c
+++ b/fs/orangefs/inode.c
@@ -62,12 +62,7 @@ static int orangefs_writepage_locked(struct page *page,
 	} else {
 		ret = 0;
 	}
-	if (wr) {
-		kfree(wr);
-		set_page_private(page, 0);
-		ClearPagePrivate(page);
-		put_page(page);
-	}
+	kfree(clear_page_private(page));
 	return ret;
 }
 
@@ -409,9 +404,7 @@ static int orangefs_write_begin(struct file *file,
 	wr->len = len;
 	wr->uid = current_fsuid();
 	wr->gid = current_fsgid();
-	SetPagePrivate(page);
-	set_page_private(page, (unsigned long)wr);
-	get_page(page);
+	attach_page_private(page, wr);
 okay:
 	return 0;
 }
@@ -459,18 +452,12 @@ static void orangefs_invalidatepage(struct page *page,
 	wr = (struct orangefs_write_range *)page_private(page);
 
 	if (offset == 0 && length == PAGE_SIZE) {
-		kfree((struct orangefs_write_range *)page_private(page));
-		set_page_private(page, 0);
-		ClearPagePrivate(page);
-		put_page(page);
+		kfree(clear_page_private(page));
 		return;
 	/* write range entirely within invalidate range (or equal) */
 	} else if (page_offset(page) + offset <= wr->pos &&
 	    wr->pos + wr->len <= page_offset(page) + offset + length) {
-		kfree((struct orangefs_write_range *)page_private(page));
-		set_page_private(page, 0);
-		ClearPagePrivate(page);
-		put_page(page);
+		kfree(clear_page_private(page));
 		/* XXX is this right? only caller in fs */
 		cancel_dirty_page(page);
 		return;
@@ -535,12 +522,7 @@ static int orangefs_releasepage(struct page *page, gfp_t foo)
 
 static void orangefs_freepage(struct page *page)
 {
-	if (PagePrivate(page)) {
-		kfree((struct orangefs_write_range *)page_private(page));
-		set_page_private(page, 0);
-		ClearPagePrivate(page);
-		put_page(page);
-	}
+	kfree(clear_page_private(page));
 }
 
 static int orangefs_launder_page(struct page *page)
@@ -740,9 +722,7 @@ vm_fault_t orangefs_page_mkwrite(struct vm_fault *vmf)
 	wr->len = PAGE_SIZE;
 	wr->uid = current_fsuid();
 	wr->gid = current_fsgid();
-	SetPagePrivate(page);
-	set_page_private(page, (unsigned long)wr);
-	get_page(page);
+	attach_page_private(page, wr);
 okay:
 
 	file_update_time(vmf->vma->vm_file);
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [RFC PATCH V2 9/9] buffer_head.h: remove attach_page_buffers
  2020-04-30 21:44 [RFC PATCH V2 0/9] Introduce attach/clear_page_private to cleanup code Guoqing Jiang
                   ` (7 preceding siblings ...)
  2020-04-30 21:44 ` [RFC PATCH V2 8/9] orangefs: use attach/clear_page_private Guoqing Jiang
@ 2020-04-30 21:44 ` Guoqing Jiang
  2020-05-01 22:16 ` [RFC PATCH V2 0/9] Introduce attach/clear_page_private to cleanup code Matthew Wilcox
  9 siblings, 0 replies; 21+ messages in thread
From: Guoqing Jiang @ 2020-04-30 21:44 UTC (permalink / raw)
  To: linux-fsdevel, linux-kernel
  Cc: hch, david, willy, Guoqing Jiang, Thomas Gleixner,
	Sebastian Andrzej Siewior, Roman Gushchin, Andreas Dilger

All the callers have replaced attach_page_buffers with the new function
attach_page_private, so remove it.

Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: Roman Gushchin <guro@fb.com>
Cc: Andreas Dilger <adilger@dilger.ca>
Signed-off-by: Guoqing Jiang <guoqing.jiang@cloud.ionos.com>
---
 include/linux/buffer_head.h | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h
index 15b765a181b8..22fb11e2d2e0 100644
--- a/include/linux/buffer_head.h
+++ b/include/linux/buffer_head.h
@@ -272,14 +272,6 @@ void buffer_init(void);
  * inline definitions
  */
 
-static inline void attach_page_buffers(struct page *page,
-		struct buffer_head *head)
-{
-	get_page(page);
-	SetPagePrivate(page);
-	set_page_private(page, (unsigned long)head);
-}
-
 static inline void get_bh(struct buffer_head *bh)
 {
         atomic_inc(&bh->b_count);
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* Re: [RFC PATCH V2 1/9] include/linux/pagemap.h: introduce attach/clear_page_private
  2020-04-30 21:44 ` [RFC PATCH V2 1/9] include/linux/pagemap.h: introduce attach/clear_page_private Guoqing Jiang
@ 2020-04-30 22:10   ` Andreas Grünbacher
  2020-05-01  6:38     ` Guoqing Jiang
  2020-04-30 22:13   ` Matthew Wilcox
  1 sibling, 1 reply; 21+ messages in thread
From: Andreas Grünbacher @ 2020-04-30 22:10 UTC (permalink / raw)
  To: Guoqing Jiang
  Cc: Linux FS-devel Mailing List, Linux Kernel Mailing List,
	Christoph Hellwig, Dave Chinner, willy, Andrew Morton,
	Darrick J. Wong, William Kucharski, Kirill A. Shutemov,
	Andreas Gruenbacher, Yang Shi, Yafang Shao, Song Liu, linux-raid,
	Chris Mason, Josef Bacik, David Sterba, linux-btrfs,
	Alexander Viro, Jaegeuk Kim, Chao Yu, linux-f2fs-devel,
	linux-xfs, Anton Altaparmakov, linux-ntfs-dev, Mike Marshall,
	Martin Brandenburg, devel, Thomas Gleixner,
	Sebastian Andrzej Siewior, Roman Gushchin, Andreas Dilger

Hi,

Am Do., 30. Apr. 2020 um 23:56 Uhr schrieb Guoqing Jiang
<guoqing.jiang@cloud.ionos.com>:
> The logic in attach_page_buffers and  __clear_page_buffers are quite
> paired, but
>
> 1. they are located in different files.
>
> 2. attach_page_buffers is implemented in buffer_head.h, so it could be
>    used by other files. But __clear_page_buffers is static function in
>    buffer.c and other potential users can't call the function, md-bitmap
>    even copied the function.
>
> So, introduce the new attach/clear_page_private to replace them. With
> the new pair of function, we will remove the usage of attach_page_buffers
> and  __clear_page_buffers in next patches. Thanks for the new names from
> Christoph Hellwig.
>
> Suggested-by: Matthew Wilcox <willy@infradead.org>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: "Darrick J. Wong" <darrick.wong@oracle.com>
> Cc: William Kucharski <william.kucharski@oracle.com>
> Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
> Cc: Andreas Gruenbacher <agruenba@redhat.com>
> Cc: Yang Shi <yang.shi@linux.alibaba.com>
> Cc: Yafang Shao <laoar.shao@gmail.com>
> Cc: Song Liu <song@kernel.org>
> Cc: linux-raid@vger.kernel.org
> Cc: Chris Mason <clm@fb.com>
> Cc: Josef Bacik <josef@toxicpanda.com>
> Cc: David Sterba <dsterba@suse.com>
> Cc: linux-btrfs@vger.kernel.org
> Cc: Alexander Viro <viro@zeniv.linux.org.uk>
> Cc: Jaegeuk Kim <jaegeuk@kernel.org>
> Cc: Chao Yu <chao@kernel.org>
> Cc: linux-f2fs-devel@lists.sourceforge.net
> Cc: Christoph Hellwig <hch@infradead.org>
> Cc: linux-xfs@vger.kernel.org
> Cc: Anton Altaparmakov <anton@tuxera.com>
> Cc: linux-ntfs-dev@lists.sourceforge.net
> Cc: Mike Marshall <hubcap@omnibond.com>
> Cc: Martin Brandenburg <martin@omnibond.com>
> Cc: devel@lists.orangefs.org
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> Cc: Roman Gushchin <guro@fb.com>
> Cc: Andreas Dilger <adilger@dilger.ca>
> Signed-off-by: Guoqing Jiang <guoqing.jiang@cloud.ionos.com>
> ---
> RFC -> RFC V2:  Address the comments from Christoph Hellwig
> 1. change function names to attach/clear_page_private and add comments.
> 2. change the return type of attach_page_private.
>
>  include/linux/pagemap.h | 35 +++++++++++++++++++++++++++++++++++
>  1 file changed, 35 insertions(+)
>
> diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
> index a8f7bd8ea1c6..2e515f210b18 100644
> --- a/include/linux/pagemap.h
> +++ b/include/linux/pagemap.h
> @@ -205,6 +205,41 @@ static inline int page_cache_add_speculative(struct page *page, int count)
>         return __page_cache_add_speculative(page, count);
>  }
>
> +/**
> + * attach_page_private - attach data to page's private field and set PG_private.
> + * @page: page to be attached and set flag.
> + * @data: data to attach to page's private field.
> + *
> + * Need to take reference as mm.h said "Setting PG_private should also increment
> + * the refcount".
> + */
> +static inline void attach_page_private(struct page *page, void *data)
> +{
> +       get_page(page);
> +       set_page_private(page, (unsigned long)data);
> +       SetPagePrivate(page);
> +}
> +
> +/**
> + * clear_page_private - clear page's private field and PG_private.
> + * @page: page to be cleared.
> + *
> + * The counterpart function of attach_page_private.
> + * Return: private data of page or NULL if page doesn't have private data.
> + */
> +static inline void *clear_page_private(struct page *page)
> +{
> +       void *data = (void *)page_private(page);
> +
> +       if (!PagePrivate(page))
> +               return NULL;
> +       ClearPagePrivate(page);
> +       set_page_private(page, 0);
> +       put_page(page);
> +
> +       return data;
> +}
> +

I like this in general, but the name clear_page_private suggests that
this might be the inverse operation of set_page_private, which it is
not. So maybe this can be renamed to detach_page_private to more
clearly indicate that it pairs with attach_page_private?

>  #ifdef CONFIG_NUMA
>  extern struct page *__page_cache_alloc(gfp_t gfp);
>  #else
> --
> 2.17.1
>

Thanks,
Andreas

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [RFC PATCH V2 1/9] include/linux/pagemap.h: introduce attach/clear_page_private
  2020-04-30 21:44 ` [RFC PATCH V2 1/9] include/linux/pagemap.h: introduce attach/clear_page_private Guoqing Jiang
  2020-04-30 22:10   ` Andreas Grünbacher
@ 2020-04-30 22:13   ` Matthew Wilcox
  2020-05-01  1:42     ` Al Viro
  2020-05-01  6:39     ` Guoqing Jiang
  1 sibling, 2 replies; 21+ messages in thread
From: Matthew Wilcox @ 2020-04-30 22:13 UTC (permalink / raw)
  To: Guoqing Jiang
  Cc: linux-fsdevel, linux-kernel, hch, david, Andrew Morton,
	Darrick J. Wong, William Kucharski, Kirill A. Shutemov,
	Andreas Gruenbacher, Yang Shi, Yafang Shao, Song Liu, linux-raid,
	Chris Mason, Josef Bacik, David Sterba, linux-btrfs,
	Alexander Viro, Jaegeuk Kim, Chao Yu, linux-f2fs-devel,
	linux-xfs, Anton Altaparmakov, linux-ntfs-dev, Mike Marshall,
	Martin Brandenburg, devel, Thomas Gleixner,
	Sebastian Andrzej Siewior, Roman Gushchin, Andreas Dilger

On Thu, Apr 30, 2020 at 11:44:42PM +0200, Guoqing Jiang wrote:
> +/**
> + * attach_page_private - attach data to page's private field and set PG_private.
> + * @page: page to be attached and set flag.
> + * @data: data to attach to page's private field.
> + *
> + * Need to take reference as mm.h said "Setting PG_private should also increment
> + * the refcount".
> + */

I don't think this will read well when added to the API documentation.
Try this:

/**
 * attach_page_private - Attach private data to a page.
 * @page: Page to attach data to.
 * @data: Data to attach to page.
 *
 * Attaching private data to a page increments the page's reference count.
 * The data must be detached before the page will be freed.
 */

> +/**
> + * clear_page_private - clear page's private field and PG_private.
> + * @page: page to be cleared.
> + *
> + * The counterpart function of attach_page_private.
> + * Return: private data of page or NULL if page doesn't have private data.
> + */

Seems to me that the opposite of "attach" is "detach", not "clear".

/**
 * detach_page_private - Detach private data from a page.
 * @page: Page to detach data from.
 *
 * Removes the data that was previously attached to the page and decrements
 * the refcount on the page.
 *
 * Return: Data that was attached to the page.
 */

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [RFC PATCH V2 1/9] include/linux/pagemap.h: introduce attach/clear_page_private
  2020-04-30 22:13   ` Matthew Wilcox
@ 2020-05-01  1:42     ` Al Viro
  2020-05-01  1:49       ` Al Viro
  2020-05-01  6:39     ` Guoqing Jiang
  1 sibling, 1 reply; 21+ messages in thread
From: Al Viro @ 2020-05-01  1:42 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: Guoqing Jiang, linux-fsdevel, linux-kernel, hch, david,
	Andrew Morton, Darrick J. Wong, William Kucharski,
	Kirill A. Shutemov, Andreas Gruenbacher, Yang Shi, Yafang Shao,
	Song Liu, linux-raid, Chris Mason, Josef Bacik, David Sterba,
	linux-btrfs, Jaegeuk Kim, Chao Yu, linux-f2fs-devel, linux-xfs,
	Anton Altaparmakov, linux-ntfs-dev, Mike Marshall,
	Martin Brandenburg, devel, Thomas Gleixner,
	Sebastian Andrzej Siewior, Roman Gushchin, Andreas Dilger

On Thu, Apr 30, 2020 at 03:13:38PM -0700, Matthew Wilcox wrote:

> > +/**
> > + * clear_page_private - clear page's private field and PG_private.
> > + * @page: page to be cleared.
> > + *
> > + * The counterpart function of attach_page_private.
> > + * Return: private data of page or NULL if page doesn't have private data.
> > + */
> 
> Seems to me that the opposite of "attach" is "detach", not "clear".

Or "remove", perhaps...

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [RFC PATCH V2 1/9] include/linux/pagemap.h: introduce attach/clear_page_private
  2020-05-01  1:42     ` Al Viro
@ 2020-05-01  1:49       ` Al Viro
  2020-05-01  6:41         ` Guoqing Jiang
  0 siblings, 1 reply; 21+ messages in thread
From: Al Viro @ 2020-05-01  1:49 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: Guoqing Jiang, linux-fsdevel, linux-kernel, hch, david,
	Andrew Morton, Darrick J. Wong, William Kucharski,
	Kirill A. Shutemov, Andreas Gruenbacher, Yang Shi, Yafang Shao,
	Song Liu, linux-raid, Chris Mason, Josef Bacik, David Sterba,
	linux-btrfs, Jaegeuk Kim, Chao Yu, linux-f2fs-devel, linux-xfs,
	Anton Altaparmakov, linux-ntfs-dev, Mike Marshall,
	Martin Brandenburg, devel, Thomas Gleixner,
	Sebastian Andrzej Siewior, Roman Gushchin, Andreas Dilger

On Fri, May 01, 2020 at 02:42:29AM +0100, Al Viro wrote:
> On Thu, Apr 30, 2020 at 03:13:38PM -0700, Matthew Wilcox wrote:
> 
> > > +/**
> > > + * clear_page_private - clear page's private field and PG_private.
> > > + * @page: page to be cleared.
> > > + *
> > > + * The counterpart function of attach_page_private.
> > > + * Return: private data of page or NULL if page doesn't have private data.
> > > + */
> > 
> > Seems to me that the opposite of "attach" is "detach", not "clear".
> 
> Or "remove", perhaps...

Actually, "detach" is better - neither "clear" nor "remove" imply "... and give
me what used to be attached there", as this thing is doing.

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [RFC PATCH V2 1/9] include/linux/pagemap.h: introduce attach/clear_page_private
  2020-04-30 22:10   ` Andreas Grünbacher
@ 2020-05-01  6:38     ` Guoqing Jiang
  0 siblings, 0 replies; 21+ messages in thread
From: Guoqing Jiang @ 2020-05-01  6:38 UTC (permalink / raw)
  To: Andreas Grünbacher
  Cc: Linux FS-devel Mailing List, Linux Kernel Mailing List,
	Christoph Hellwig, Dave Chinner, willy, Andrew Morton,
	Darrick J. Wong, William Kucharski, Kirill A. Shutemov,
	Andreas Gruenbacher, Yang Shi, Yafang Shao, Song Liu, linux-raid,
	Chris Mason, Josef Bacik, David Sterba, linux-btrfs,
	Alexander Viro, Jaegeuk Kim, Chao Yu, linux-f2fs-devel,
	linux-xfs, Anton Altaparmakov, linux-ntfs-dev, Mike Marshall,
	Martin Brandenburg, devel, Thomas Gleixner,
	Sebastian Andrzej Siewior, Roman Gushchin, Andreas Dilger

On 5/1/20 12:10 AM, Andreas Grünbacher wrote:
> Hi,
>
> Am Do., 30. Apr. 2020 um 23:56 Uhr schrieb Guoqing Jiang
> <guoqing.jiang@cloud.ionos.com>:
>> The logic in attach_page_buffers and  __clear_page_buffers are quite
>> paired, but
>>
>> 1. they are located in different files.
>>
>> 2. attach_page_buffers is implemented in buffer_head.h, so it could be
>>     used by other files. But __clear_page_buffers is static function in
>>     buffer.c and other potential users can't call the function, md-bitmap
>>     even copied the function.
>>
>> So, introduce the new attach/clear_page_private to replace them. With
>> the new pair of function, we will remove the usage of attach_page_buffers
>> and  __clear_page_buffers in next patches. Thanks for the new names from
>> Christoph Hellwig.
>>
>> Suggested-by: Matthew Wilcox <willy@infradead.org>
>> Cc: Andrew Morton <akpm@linux-foundation.org>
>> Cc: "Darrick J. Wong" <darrick.wong@oracle.com>
>> Cc: William Kucharski <william.kucharski@oracle.com>
>> Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
>> Cc: Andreas Gruenbacher <agruenba@redhat.com>
>> Cc: Yang Shi <yang.shi@linux.alibaba.com>
>> Cc: Yafang Shao <laoar.shao@gmail.com>
>> Cc: Song Liu <song@kernel.org>
>> Cc: linux-raid@vger.kernel.org
>> Cc: Chris Mason <clm@fb.com>
>> Cc: Josef Bacik <josef@toxicpanda.com>
>> Cc: David Sterba <dsterba@suse.com>
>> Cc: linux-btrfs@vger.kernel.org
>> Cc: Alexander Viro <viro@zeniv.linux.org.uk>
>> Cc: Jaegeuk Kim <jaegeuk@kernel.org>
>> Cc: Chao Yu <chao@kernel.org>
>> Cc: linux-f2fs-devel@lists.sourceforge.net
>> Cc: Christoph Hellwig <hch@infradead.org>
>> Cc: linux-xfs@vger.kernel.org
>> Cc: Anton Altaparmakov <anton@tuxera.com>
>> Cc: linux-ntfs-dev@lists.sourceforge.net
>> Cc: Mike Marshall <hubcap@omnibond.com>
>> Cc: Martin Brandenburg <martin@omnibond.com>
>> Cc: devel@lists.orangefs.org
>> Cc: Thomas Gleixner <tglx@linutronix.de>
>> Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
>> Cc: Roman Gushchin <guro@fb.com>
>> Cc: Andreas Dilger <adilger@dilger.ca>
>> Signed-off-by: Guoqing Jiang <guoqing.jiang@cloud.ionos.com>
>> ---
>> RFC -> RFC V2:  Address the comments from Christoph Hellwig
>> 1. change function names to attach/clear_page_private and add comments.
>> 2. change the return type of attach_page_private.
>>
>>   include/linux/pagemap.h | 35 +++++++++++++++++++++++++++++++++++
>>   1 file changed, 35 insertions(+)
>>
>> diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
>> index a8f7bd8ea1c6..2e515f210b18 100644
>> --- a/include/linux/pagemap.h
>> +++ b/include/linux/pagemap.h
>> @@ -205,6 +205,41 @@ static inline int page_cache_add_speculative(struct page *page, int count)
>>          return __page_cache_add_speculative(page, count);
>>   }
>>
>> +/**
>> + * attach_page_private - attach data to page's private field and set PG_private.
>> + * @page: page to be attached and set flag.
>> + * @data: data to attach to page's private field.
>> + *
>> + * Need to take reference as mm.h said "Setting PG_private should also increment
>> + * the refcount".
>> + */
>> +static inline void attach_page_private(struct page *page, void *data)
>> +{
>> +       get_page(page);
>> +       set_page_private(page, (unsigned long)data);
>> +       SetPagePrivate(page);
>> +}
>> +
>> +/**
>> + * clear_page_private - clear page's private field and PG_private.
>> + * @page: page to be cleared.
>> + *
>> + * The counterpart function of attach_page_private.
>> + * Return: private data of page or NULL if page doesn't have private data.
>> + */
>> +static inline void *clear_page_private(struct page *page)
>> +{
>> +       void *data = (void *)page_private(page);
>> +
>> +       if (!PagePrivate(page))
>> +               return NULL;
>> +       ClearPagePrivate(page);
>> +       set_page_private(page, 0);
>> +       put_page(page);
>> +
>> +       return data;
>> +}
>> +
> I like this in general, but the name clear_page_private suggests that
> this might be the inverse operation of set_page_private, which it is
> not. So maybe this can be renamed to detach_page_private to more
> clearly indicate that it pairs with attach_page_private?

Yes, the new name is better, thank you!

Cheers,
Guoqing

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [RFC PATCH V2 1/9] include/linux/pagemap.h: introduce attach/clear_page_private
  2020-04-30 22:13   ` Matthew Wilcox
  2020-05-01  1:42     ` Al Viro
@ 2020-05-01  6:39     ` Guoqing Jiang
  1 sibling, 0 replies; 21+ messages in thread
From: Guoqing Jiang @ 2020-05-01  6:39 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: linux-fsdevel, linux-kernel, hch, david, Andrew Morton,
	Darrick J. Wong, William Kucharski, Kirill A. Shutemov,
	Andreas Gruenbacher, Yang Shi, Yafang Shao, Song Liu, linux-raid,
	Chris Mason, Josef Bacik, David Sterba, linux-btrfs,
	Alexander Viro, Jaegeuk Kim, Chao Yu, linux-f2fs-devel,
	linux-xfs, Anton Altaparmakov, linux-ntfs-dev, Mike Marshall,
	Martin Brandenburg, devel, Thomas Gleixner,
	Sebastian Andrzej Siewior, Roman Gushchin, Andreas Dilger

On 5/1/20 12:13 AM, Matthew Wilcox wrote:
> On Thu, Apr 30, 2020 at 11:44:42PM +0200, Guoqing Jiang wrote:
>> +/**
>> + * attach_page_private - attach data to page's private field and set PG_private.
>> + * @page: page to be attached and set flag.
>> + * @data: data to attach to page's private field.
>> + *
>> + * Need to take reference as mm.h said "Setting PG_private should also increment
>> + * the refcount".
>> + */
> I don't think this will read well when added to the API documentation.
> Try this:
>
> /**
>   * attach_page_private - Attach private data to a page.
>   * @page: Page to attach data to.
>   * @data: Data to attach to page.
>   *
>   * Attaching private data to a page increments the page's reference count.
>   * The data must be detached before the page will be freed.
>   */
>
>> +/**
>> + * clear_page_private - clear page's private field and PG_private.
>> + * @page: page to be cleared.
>> + *
>> + * The counterpart function of attach_page_private.
>> + * Return: private data of page or NULL if page doesn't have private data.
>> + */
> Seems to me that the opposite of "attach" is "detach", not "clear".
>
> /**
>   * detach_page_private - Detach private data from a page.
>   * @page: Page to detach data from.
>   *
>   * Removes the data that was previously attached to the page and decrements
>   * the refcount on the page.
>   *
>   * Return: Data that was attached to the page.
>   */

Thanks you very much, Mattew! Will change them in next version.

Best Regards,
Guoqing

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [RFC PATCH V2 1/9] include/linux/pagemap.h: introduce attach/clear_page_private
  2020-05-01  1:49       ` Al Viro
@ 2020-05-01  6:41         ` Guoqing Jiang
  0 siblings, 0 replies; 21+ messages in thread
From: Guoqing Jiang @ 2020-05-01  6:41 UTC (permalink / raw)
  To: Al Viro, Matthew Wilcox
  Cc: linux-fsdevel, linux-kernel, hch, david, Andrew Morton,
	Darrick J. Wong, William Kucharski, Kirill A. Shutemov,
	Andreas Gruenbacher, Yang Shi, Yafang Shao, Song Liu, linux-raid,
	Chris Mason, Josef Bacik, David Sterba, linux-btrfs, Jaegeuk Kim,
	Chao Yu, linux-f2fs-devel, linux-xfs, Anton Altaparmakov,
	linux-ntfs-dev, Mike Marshall, Martin Brandenburg, devel,
	Thomas Gleixner, Sebastian Andrzej Siewior, Roman Gushchin,
	Andreas Dilger

On 5/1/20 3:49 AM, Al Viro wrote:
> On Fri, May 01, 2020 at 02:42:29AM +0100, Al Viro wrote:
>> On Thu, Apr 30, 2020 at 03:13:38PM -0700, Matthew Wilcox wrote:
>>
>>>> +/**
>>>> + * clear_page_private - clear page's private field and PG_private.
>>>> + * @page: page to be cleared.
>>>> + *
>>>> + * The counterpart function of attach_page_private.
>>>> + * Return: private data of page or NULL if page doesn't have private data.
>>>> + */
>>> Seems to me that the opposite of "attach" is "detach", not "clear".
>> Or "remove", perhaps...
> Actually, "detach" is better - neither "clear" nor "remove" imply "... and give
> me what used to be attached there", as this thing is doing.

Ok, seems we have reached the agreement about the new name ;-), will 
follow the instruction.

Thanks & Regards,
Guoqing

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [RFC PATCH V2 0/9] Introduce attach/clear_page_private to cleanup code
  2020-04-30 21:44 [RFC PATCH V2 0/9] Introduce attach/clear_page_private to cleanup code Guoqing Jiang
                   ` (8 preceding siblings ...)
  2020-04-30 21:44 ` [RFC PATCH V2 9/9] buffer_head.h: remove attach_page_buffers Guoqing Jiang
@ 2020-05-01 22:16 ` Matthew Wilcox
  2020-05-01 22:42   ` Guoqing Jiang
  9 siblings, 1 reply; 21+ messages in thread
From: Matthew Wilcox @ 2020-05-01 22:16 UTC (permalink / raw)
  To: Guoqing Jiang; +Cc: linux-fsdevel, linux-kernel, hch, david

On Thu, Apr 30, 2020 at 11:44:41PM +0200, Guoqing Jiang wrote:
>   include/linux/pagemap.h: introduce attach/clear_page_private
>   md: remove __clear_page_buffers and use attach/clear_page_private
>   btrfs: use attach/clear_page_private
>   fs/buffer.c: use attach/clear_page_private
>   f2fs: use attach/clear_page_private
>   iomap: use attach/clear_page_private
>   ntfs: replace attach_page_buffers with attach_page_private
>   orangefs: use attach/clear_page_private
>   buffer_head.h: remove attach_page_buffers

I think mm/migrate.c could also use this:

        ClearPagePrivate(page);
        set_page_private(newpage, page_private(page));
        set_page_private(page, 0);
        put_page(page);
        get_page(newpage);


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [RFC PATCH V2 0/9] Introduce attach/clear_page_private to cleanup code
  2020-05-01 22:16 ` [RFC PATCH V2 0/9] Introduce attach/clear_page_private to cleanup code Matthew Wilcox
@ 2020-05-01 22:42   ` Guoqing Jiang
  2020-05-02  0:41     ` Matthew Wilcox
  0 siblings, 1 reply; 21+ messages in thread
From: Guoqing Jiang @ 2020-05-01 22:42 UTC (permalink / raw)
  To: Matthew Wilcox; +Cc: linux-fsdevel, linux-kernel, hch, david

On 5/2/20 12:16 AM, Matthew Wilcox wrote:
> On Thu, Apr 30, 2020 at 11:44:41PM +0200, Guoqing Jiang wrote:
>>    include/linux/pagemap.h: introduce attach/clear_page_private
>>    md: remove __clear_page_buffers and use attach/clear_page_private
>>    btrfs: use attach/clear_page_private
>>    fs/buffer.c: use attach/clear_page_private
>>    f2fs: use attach/clear_page_private
>>    iomap: use attach/clear_page_private
>>    ntfs: replace attach_page_buffers with attach_page_private
>>    orangefs: use attach/clear_page_private
>>    buffer_head.h: remove attach_page_buffers
> I think mm/migrate.c could also use this:
>
>          ClearPagePrivate(page);
>          set_page_private(newpage, page_private(page));
>          set_page_private(page, 0);
>          put_page(page);
>          get_page(newpage);
>

Thanks for checking!  Assume the below change is appropriate.

diff --git a/mm/migrate.c b/mm/migrate.c
index 7160c1556f79..f214adfb3fa4 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -797,10 +797,7 @@ static int __buffer_migrate_page(struct 
address_space *mapping,
         if (rc != MIGRATEPAGE_SUCCESS)
                 goto unlock_buffers;

-       ClearPagePrivate(page);
-       set_page_private(newpage, page_private(page));
-       set_page_private(page, 0);
-       put_page(page);
+       set_page_private(newpage, detach_page_private(page));
         get_page(newpage);

         bh = head;


Cheers,
Guoqing


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* Re: [RFC PATCH V2 0/9] Introduce attach/clear_page_private to cleanup code
  2020-05-01 22:42   ` Guoqing Jiang
@ 2020-05-02  0:41     ` Matthew Wilcox
  2020-05-02  8:56       ` Guoqing Jiang
  0 siblings, 1 reply; 21+ messages in thread
From: Matthew Wilcox @ 2020-05-02  0:41 UTC (permalink / raw)
  To: Guoqing Jiang; +Cc: linux-fsdevel, linux-kernel, hch, david

On Sat, May 02, 2020 at 12:42:15AM +0200, Guoqing Jiang wrote:
> On 5/2/20 12:16 AM, Matthew Wilcox wrote:
> > On Thu, Apr 30, 2020 at 11:44:41PM +0200, Guoqing Jiang wrote:
> > >    include/linux/pagemap.h: introduce attach/clear_page_private
> > >    md: remove __clear_page_buffers and use attach/clear_page_private
> > >    btrfs: use attach/clear_page_private
> > >    fs/buffer.c: use attach/clear_page_private
> > >    f2fs: use attach/clear_page_private
> > >    iomap: use attach/clear_page_private
> > >    ntfs: replace attach_page_buffers with attach_page_private
> > >    orangefs: use attach/clear_page_private
> > >    buffer_head.h: remove attach_page_buffers
> > I think mm/migrate.c could also use this:
> > 
> >          ClearPagePrivate(page);
> >          set_page_private(newpage, page_private(page));
> >          set_page_private(page, 0);
> >          put_page(page);
> >          get_page(newpage);
> > 
> 
> Thanks for checking!  Assume the below change is appropriate.
> 
> diff --git a/mm/migrate.c b/mm/migrate.c
> index 7160c1556f79..f214adfb3fa4 100644
> --- a/mm/migrate.c
> +++ b/mm/migrate.c
> @@ -797,10 +797,7 @@ static int __buffer_migrate_page(struct address_space
> *mapping,
>         if (rc != MIGRATEPAGE_SUCCESS)
>                 goto unlock_buffers;
> 
> -       ClearPagePrivate(page);
> -       set_page_private(newpage, page_private(page));
> -       set_page_private(page, 0);
> -       put_page(page);
> +       set_page_private(newpage, detach_page_private(page));
>         get_page(newpage);

I think you can do:

@@ -797,11 +797,7 @@ static int __buffer_migrate_page(struct address_space *mapping,
        if (rc != MIGRATEPAGE_SUCCESS)
                goto unlock_buffers;
 
-       ClearPagePrivate(page);
-       set_page_private(newpage, page_private(page));
-       set_page_private(page, 0);
-       put_page(page);
-       get_page(newpage);
+       attach_page_private(newpage, detach_page_private(page));
 
        bh = head;
        do {
@@ -810,8 +806,6 @@ static int __buffer_migrate_page(struct address_space *mapping,
 
        } while (bh != head);
 
-       SetPagePrivate(newpage);
-
        if (mode != MIGRATE_SYNC_NO_COPY)

... but maybe there's a subtlety to the ordering of the setup of the bh
and setting PagePrivate that means what you have there is a better patch.
Anybody know?

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [RFC PATCH V2 0/9] Introduce attach/clear_page_private to cleanup code
  2020-05-02  0:41     ` Matthew Wilcox
@ 2020-05-02  8:56       ` Guoqing Jiang
  0 siblings, 0 replies; 21+ messages in thread
From: Guoqing Jiang @ 2020-05-02  8:56 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: linux-fsdevel, linux-kernel, hch, david, Andrew Morton, linux-mm,
	cl, mike.kravetz

On 5/2/20 2:41 AM, Matthew Wilcox wrote:
> On Sat, May 02, 2020 at 12:42:15AM +0200, Guoqing Jiang wrote:
>> On 5/2/20 12:16 AM, Matthew Wilcox wrote:
>>> On Thu, Apr 30, 2020 at 11:44:41PM +0200, Guoqing Jiang wrote:
>>>>     include/linux/pagemap.h: introduce attach/clear_page_private
>>>>     md: remove __clear_page_buffers and use attach/clear_page_private
>>>>     btrfs: use attach/clear_page_private
>>>>     fs/buffer.c: use attach/clear_page_private
>>>>     f2fs: use attach/clear_page_private
>>>>     iomap: use attach/clear_page_private
>>>>     ntfs: replace attach_page_buffers with attach_page_private
>>>>     orangefs: use attach/clear_page_private
>>>>     buffer_head.h: remove attach_page_buffers
>>> I think mm/migrate.c could also use this:
>>>
>>>           ClearPagePrivate(page);
>>>           set_page_private(newpage, page_private(page));
>>>           set_page_private(page, 0);
>>>           put_page(page);
>>>           get_page(newpage);
>>>
>> Thanks for checking!  Assume the below change is appropriate.
>>
>> diff --git a/mm/migrate.c b/mm/migrate.c
>> index 7160c1556f79..f214adfb3fa4 100644
>> --- a/mm/migrate.c
>> +++ b/mm/migrate.c
>> @@ -797,10 +797,7 @@ static int __buffer_migrate_page(struct address_space
>> *mapping,
>>          if (rc != MIGRATEPAGE_SUCCESS)
>>                  goto unlock_buffers;
>>
>> -       ClearPagePrivate(page);
>> -       set_page_private(newpage, page_private(page));
>> -       set_page_private(page, 0);
>> -       put_page(page);
>> +       set_page_private(newpage, detach_page_private(page));
>>          get_page(newpage);
> I think you can do:
>
> @@ -797,11 +797,7 @@ static int __buffer_migrate_page(struct address_space *mapping,
>          if (rc != MIGRATEPAGE_SUCCESS)
>                  goto unlock_buffers;
>   
> -       ClearPagePrivate(page);
> -       set_page_private(newpage, page_private(page));
> -       set_page_private(page, 0);
> -       put_page(page);
> -       get_page(newpage);
> +       attach_page_private(newpage, detach_page_private(page));
>   
>          bh = head;
>          do {
> @@ -810,8 +806,6 @@ static int __buffer_migrate_page(struct address_space *mapping,
>   
>          } while (bh != head);
>   
> -       SetPagePrivate(newpage);
> -
>          if (mode != MIGRATE_SYNC_NO_COPY)
>
> ... but maybe there's a subtlety to the ordering of the setup of the bh
> and setting PagePrivate that means what you have there is a better patch.

Yes, it is better but not sure if the order can be changed here. And seems
the original commit is this one.

commit e965f9630c651fa4249039fd4b80c9392d07a856
Author: Christoph Lameter <clameter@sgi.com>
Date:   Wed Feb 1 03:05:41 2006 -0800

     [PATCH] Direct Migration V9: Avoid writeback / page_migrate() method

     Migrate a page with buffers without requiring writeback

     This introduces a new address space operation migratepage() that 
may be used
     by a filesystem to implement its own version of page migration.

     A version is provided that migrates buffers attached to pages. Some
     filesystems (ext2, ext3, xfs) are modified to utilize this feature.

     The swapper address space operation are modified so that a regular
     migrate_page() will occur for anonymous pages without writeback 
(migrate_pages
     forces every anonymous page to have a swap entry).

Hope mm experts could take a look, so CC more people and mm list. And
the question is that if we can setting PagePrivate before setup bh in the
__buffer_migrate_page, thanks for your any further input.

Thanks,
Guoqing

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2020-05-02  8:57 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-30 21:44 [RFC PATCH V2 0/9] Introduce attach/clear_page_private to cleanup code Guoqing Jiang
2020-04-30 21:44 ` [RFC PATCH V2 1/9] include/linux/pagemap.h: introduce attach/clear_page_private Guoqing Jiang
2020-04-30 22:10   ` Andreas Grünbacher
2020-05-01  6:38     ` Guoqing Jiang
2020-04-30 22:13   ` Matthew Wilcox
2020-05-01  1:42     ` Al Viro
2020-05-01  1:49       ` Al Viro
2020-05-01  6:41         ` Guoqing Jiang
2020-05-01  6:39     ` Guoqing Jiang
2020-04-30 21:44 ` [RFC PATCH V2 2/9] md: remove __clear_page_buffers and use attach/clear_page_private Guoqing Jiang
2020-04-30 21:44 ` [RFC PATCH V2 3/9] btrfs: " Guoqing Jiang
2020-04-30 21:44 ` [RFC PATCH V2 4/9] fs/buffer.c: " Guoqing Jiang
2020-04-30 21:44 ` [RFC PATCH V2 5/9] f2fs: " Guoqing Jiang
2020-04-30 21:44 ` [RFC PATCH V2 6/9] iomap: " Guoqing Jiang
2020-04-30 21:44 ` [RFC PATCH V2 7/9] ntfs: replace attach_page_buffers with attach_page_private Guoqing Jiang
2020-04-30 21:44 ` [RFC PATCH V2 8/9] orangefs: use attach/clear_page_private Guoqing Jiang
2020-04-30 21:44 ` [RFC PATCH V2 9/9] buffer_head.h: remove attach_page_buffers Guoqing Jiang
2020-05-01 22:16 ` [RFC PATCH V2 0/9] Introduce attach/clear_page_private to cleanup code Matthew Wilcox
2020-05-01 22:42   ` Guoqing Jiang
2020-05-02  0:41     ` Matthew Wilcox
2020-05-02  8:56       ` Guoqing Jiang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).