* [PATCH 2/2] f2fs: remove folio_detach_private() in .invalidate_folio and .release_folio
2023-04-12 16:08 [PATCH 1/2] f2fs: remove set|get_private_inline to clean up Jaegeuk Kim
@ 2023-04-12 16:08 ` Jaegeuk Kim
2023-04-12 19:53 ` [PATCH 1/2] f2fs: remove set|get_private_inline to clean up Jaegeuk Kim
2023-04-12 21:51 ` [PATCH 1/2 v2] " Jaegeuk Kim
2 siblings, 0 replies; 4+ messages in thread
From: Jaegeuk Kim @ 2023-04-12 16:08 UTC (permalink / raw)
To: linux-kernel, linux-f2fs-devel; +Cc: Chao Yu, Jaegeuk Kim
From: Chao Yu <chao@kernel.org>
We have maintain PagePrivate and page_private and page reference
w/ {set,clear}_page_private_*, it doesn't need to call
folio_detach_private() in the end of .invalidate_folio and
.release_folio, remove it and use f2fs_bug_on instead.
This patch should be applied along with
("f2fs: remove set|get_private_inline to clean up").
Signed-off-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
fs/f2fs/data.c | 4 ++--
fs/f2fs/dir.c | 5 ++---
fs/f2fs/f2fs.h | 32 ++++++++------------------------
3 files changed, 12 insertions(+), 29 deletions(-)
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 14cd647d727d..037e70e85f63 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -3732,7 +3732,7 @@ void f2fs_invalidate_folio(struct folio *folio, size_t offset, size_t length)
inode->i_ino == F2FS_COMPRESS_INO(sbi))
clear_page_private_data(&folio->page);
- folio_detach_private(folio);
+ f2fs_bug_on(sbi, page_private(&folio->page));
}
bool f2fs_release_folio(struct folio *folio, gfp_t wait)
@@ -3754,7 +3754,7 @@ bool f2fs_release_folio(struct folio *folio, gfp_t wait)
clear_page_private_reference(&folio->page);
clear_page_private_gcing(&folio->page);
- folio_detach_private(folio);
+ f2fs_bug_on(sbi, page_private(&folio->page));
return true;
}
diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
index d6dd8327e82d..cea179dec3b6 100644
--- a/fs/f2fs/dir.c
+++ b/fs/f2fs/dir.c
@@ -906,13 +906,12 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page,
clear_page_dirty_for_io(page);
ClearPageUptodate(page);
+ clear_page_private_reference(page);
clear_page_private_gcing(page);
+ f2fs_bug_on(F2FS_I_SB(dir), page_private(page));
inode_dec_dirty_pages(dir);
f2fs_remove_dirty_inode(dir);
-
- detach_page_private(page);
- set_page_private(page, 0);
}
f2fs_put_page(page, 1);
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 200fb2243e8a..48fbd8b54e69 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -1407,11 +1407,8 @@ static inline bool page_private_##name(struct page *page) \
#define PAGE_PRIVATE_SET_FUNC(name, flagname) \
static inline void set_page_private_##name(struct page *page) \
{ \
- if (!PagePrivate(page)) { \
- get_page(page); \
- SetPagePrivate(page); \
- set_page_private(page, 0); \
- } \
+ if (!PagePrivate(page)) \
+ attach_page_private(page, (void *)0); \
set_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page)); \
set_bit(PAGE_PRIVATE_##flagname, &page_private(page)); \
}
@@ -1420,13 +1417,8 @@ static inline void set_page_private_##name(struct page *page) \
static inline void clear_page_private_##name(struct page *page) \
{ \
clear_bit(PAGE_PRIVATE_##flagname, &page_private(page)); \
- if (page_private(page) == BIT(PAGE_PRIVATE_NOT_POINTER)) { \
- set_page_private(page, 0); \
- if (PagePrivate(page)) { \
- ClearPagePrivate(page); \
- put_page(page); \
- }\
- } \
+ if (page_private(page) == BIT(PAGE_PRIVATE_NOT_POINTER)) \
+ detach_page_private(page); \
}
PAGE_PRIVATE_GET_FUNC(nonpointer, NOT_POINTER);
@@ -1452,11 +1444,8 @@ static inline unsigned long get_page_private_data(struct page *page)
static inline void set_page_private_data(struct page *page, unsigned long data)
{
- if (!PagePrivate(page)) {
- get_page(page);
- SetPagePrivate(page);
- set_page_private(page, 0);
- }
+ if (!PagePrivate(page))
+ attach_page_private(page, (void *)0);
set_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page));
page_private(page) |= data << PAGE_PRIVATE_MAX;
}
@@ -1464,13 +1453,8 @@ static inline void set_page_private_data(struct page *page, unsigned long data)
static inline void clear_page_private_data(struct page *page)
{
page_private(page) &= GENMASK(PAGE_PRIVATE_MAX - 1, 0);
- if (page_private(page) == BIT(PAGE_PRIVATE_NOT_POINTER)) {
- set_page_private(page, 0);
- if (PagePrivate(page)) {
- ClearPagePrivate(page);
- put_page(page);
- }
- }
+ if (page_private(page) == BIT(PAGE_PRIVATE_NOT_POINTER))
+ detach_page_private(page);
}
/* For compression */
--
2.40.0.577.gac1e443424-goog
^ permalink raw reply related [flat|nested] 4+ messages in thread* Re: [PATCH 1/2] f2fs: remove set|get_private_inline to clean up
2023-04-12 16:08 [PATCH 1/2] f2fs: remove set|get_private_inline to clean up Jaegeuk Kim
2023-04-12 16:08 ` [PATCH 2/2] f2fs: remove folio_detach_private() in .invalidate_folio and .release_folio Jaegeuk Kim
@ 2023-04-12 19:53 ` Jaegeuk Kim
2023-04-12 21:51 ` [PATCH 1/2 v2] " Jaegeuk Kim
2 siblings, 0 replies; 4+ messages in thread
From: Jaegeuk Kim @ 2023-04-12 19:53 UTC (permalink / raw)
To: linux-kernel, linux-f2fs-devel
On 04/12, Jaegeuk Kim wrote:
> 2049d4fcb057 ("f2fs: avoid multiple node page writes due to inline_data")
> introduced flushing inline_data when flushing node pages.
>
> b763f3bedc2d ("f2fs: restructure f2fs page.private layout")
> Replace PageChecked with PagePrivate
>
> But, it turned out the bit was not cleared in corner case.
> Let's revert the original hack and rely on the generic write path to flush
> inline_data.
Ok, this gives generic/204 failure. Let me check in other way to address private
usage.
>
> Fixes: 2049d4fcb057 ("f2fs: avoid multiple node page writes due to inline_data")
> Fixes: b763f3bedc2d ("f2fs: restructure f2fs page.private layout")
> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
> ---
> fs/f2fs/data.c | 2 --
> fs/f2fs/f2fs.h | 9 ++-------
> fs/f2fs/inline.c | 2 --
> fs/f2fs/inode.c | 4 ----
> fs/f2fs/node.c | 52 ------------------------------------------------
> 5 files changed, 2 insertions(+), 67 deletions(-)
>
> diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
> index 5a3636b70f48..14cd647d727d 100644
> --- a/fs/f2fs/data.c
> +++ b/fs/f2fs/data.c
> @@ -3389,8 +3389,6 @@ static int prepare_write_begin(struct f2fs_sb_info *sbi,
> if (pos + len <= MAX_INLINE_DATA(inode)) {
> f2fs_do_read_inline_data(page, ipage);
> set_inode_flag(inode, FI_DATA_EXIST);
> - if (inode->i_nlink)
> - set_page_private_inline(ipage);
> goto out;
> }
> err = f2fs_convert_inline_page(&dn, page);
> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> index ede38bcef80e..200fb2243e8a 100644
> --- a/fs/f2fs/f2fs.h
> +++ b/fs/f2fs/f2fs.h
> @@ -1382,9 +1382,8 @@ static inline void f2fs_clear_bit(unsigned int nr, char *addr);
> * bit 0 PAGE_PRIVATE_NOT_POINTER
> * bit 1 PAGE_PRIVATE_DUMMY_WRITE
> * bit 2 PAGE_PRIVATE_ONGOING_MIGRATION
> - * bit 3 PAGE_PRIVATE_INLINE_INODE
> - * bit 4 PAGE_PRIVATE_REF_RESOURCE
> - * bit 5- f2fs private data
> + * bit 3 PAGE_PRIVATE_REF_RESOURCE
> + * bit 4- f2fs private data
> *
> * Layout B: lowest bit should be 0
> * page.private is a wrapped pointer.
> @@ -1393,7 +1392,6 @@ enum {
> PAGE_PRIVATE_NOT_POINTER, /* private contains non-pointer data */
> PAGE_PRIVATE_DUMMY_WRITE, /* data page for padding aligned IO */
> PAGE_PRIVATE_ONGOING_MIGRATION, /* data page which is on-going migrating */
> - PAGE_PRIVATE_INLINE_INODE, /* inode page contains inline data */
> PAGE_PRIVATE_REF_RESOURCE, /* dirty page has referenced resources */
> PAGE_PRIVATE_MAX
> };
> @@ -1432,17 +1430,14 @@ static inline void clear_page_private_##name(struct page *page) \
> }
>
> PAGE_PRIVATE_GET_FUNC(nonpointer, NOT_POINTER);
> -PAGE_PRIVATE_GET_FUNC(inline, INLINE_INODE);
> PAGE_PRIVATE_GET_FUNC(gcing, ONGOING_MIGRATION);
> PAGE_PRIVATE_GET_FUNC(dummy, DUMMY_WRITE);
>
> PAGE_PRIVATE_SET_FUNC(reference, REF_RESOURCE);
> -PAGE_PRIVATE_SET_FUNC(inline, INLINE_INODE);
> PAGE_PRIVATE_SET_FUNC(gcing, ONGOING_MIGRATION);
> PAGE_PRIVATE_SET_FUNC(dummy, DUMMY_WRITE);
>
> PAGE_PRIVATE_CLEAR_FUNC(reference, REF_RESOURCE);
> -PAGE_PRIVATE_CLEAR_FUNC(inline, INLINE_INODE);
> PAGE_PRIVATE_CLEAR_FUNC(gcing, ONGOING_MIGRATION);
> PAGE_PRIVATE_CLEAR_FUNC(dummy, DUMMY_WRITE);
>
> diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c
> index 4638fee16a91..c9ede493f8cc 100644
> --- a/fs/f2fs/inline.c
> +++ b/fs/f2fs/inline.c
> @@ -188,7 +188,6 @@ int f2fs_convert_inline_page(struct dnode_of_data *dn, struct page *page)
>
> /* clear inline data and flag after data writeback */
> f2fs_truncate_inline_inode(dn->inode, dn->inode_page, 0);
> - clear_page_private_inline(dn->inode_page);
> clear_out:
> stat_dec_inline_inode(dn->inode);
> clear_inode_flag(dn->inode, FI_INLINE_DATA);
> @@ -267,7 +266,6 @@ int f2fs_write_inline_data(struct inode *inode, struct page *page)
> set_inode_flag(inode, FI_APPEND_WRITE);
> set_inode_flag(inode, FI_DATA_EXIST);
>
> - clear_page_private_inline(dn.inode_page);
> f2fs_put_dnode(&dn);
> return 0;
> }
> diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c
> index cf4327ad106c..336f92afb7e7 100644
> --- a/fs/f2fs/inode.c
> +++ b/fs/f2fs/inode.c
> @@ -699,10 +699,6 @@ void f2fs_update_inode(struct inode *inode, struct page *node_page)
>
> __set_inode_rdev(inode, ri);
>
> - /* deleted inode */
> - if (inode->i_nlink == 0)
> - clear_page_private_inline(node_page);
> -
> init_idisk_time(inode);
> #ifdef CONFIG_F2FS_CHECK_FS
> f2fs_inode_chksum_set(F2FS_I_SB(inode), node_page);
> diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
> index bd1dad523796..8bdcf80ca07a 100644
> --- a/fs/f2fs/node.c
> +++ b/fs/f2fs/node.c
> @@ -1479,42 +1479,6 @@ struct page *f2fs_get_node_page_ra(struct page *parent, int start)
> return __get_node_page(sbi, nid, parent, start);
> }
>
> -static void flush_inline_data(struct f2fs_sb_info *sbi, nid_t ino)
> -{
> - struct inode *inode;
> - struct page *page;
> - int ret;
> -
> - /* should flush inline_data before evict_inode */
> - inode = ilookup(sbi->sb, ino);
> - if (!inode)
> - return;
> -
> - page = f2fs_pagecache_get_page(inode->i_mapping, 0,
> - FGP_LOCK|FGP_NOWAIT, 0);
> - if (!page)
> - goto iput_out;
> -
> - if (!PageUptodate(page))
> - goto page_out;
> -
> - if (!PageDirty(page))
> - goto page_out;
> -
> - if (!clear_page_dirty_for_io(page))
> - goto page_out;
> -
> - ret = f2fs_write_inline_data(inode, page);
> - inode_dec_dirty_pages(inode);
> - f2fs_remove_dirty_inode(inode);
> - if (ret)
> - set_page_dirty(page);
> -page_out:
> - f2fs_put_page(page, 1);
> -iput_out:
> - iput(inode);
> -}
> -
> static struct page *last_fsync_dnode(struct f2fs_sb_info *sbi, nid_t ino)
> {
> pgoff_t index;
> @@ -1918,14 +1882,6 @@ void f2fs_flush_inline_data(struct f2fs_sb_info *sbi)
> /* someone wrote it for us */
> goto continue_unlock;
> }
> -
> - /* flush inline_data, if it's async context. */
> - if (page_private_inline(page)) {
> - clear_page_private_inline(page);
> - unlock_page(page);
> - flush_inline_data(sbi, ino_of_node(page));
> - continue;
> - }
> unlock_page(page);
> }
> folio_batch_release(&fbatch);
> @@ -2000,14 +1956,6 @@ int f2fs_sync_node_pages(struct f2fs_sb_info *sbi,
> if (!do_balance)
> goto write_node;
>
> - /* flush inline_data */
> - if (page_private_inline(page)) {
> - clear_page_private_inline(page);
> - unlock_page(page);
> - flush_inline_data(sbi, ino_of_node(page));
> - goto lock_node;
> - }
> -
> /* flush dirty inode */
> if (IS_INODE(page) && flush_dirty_inode(page))
> goto lock_node;
> --
> 2.40.0.577.gac1e443424-goog
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH 1/2 v2] f2fs: remove set|get_private_inline to clean up
2023-04-12 16:08 [PATCH 1/2] f2fs: remove set|get_private_inline to clean up Jaegeuk Kim
2023-04-12 16:08 ` [PATCH 2/2] f2fs: remove folio_detach_private() in .invalidate_folio and .release_folio Jaegeuk Kim
2023-04-12 19:53 ` [PATCH 1/2] f2fs: remove set|get_private_inline to clean up Jaegeuk Kim
@ 2023-04-12 21:51 ` Jaegeuk Kim
2 siblings, 0 replies; 4+ messages in thread
From: Jaegeuk Kim @ 2023-04-12 21:51 UTC (permalink / raw)
To: linux-kernel, linux-f2fs-devel
We have maintain PagePrivate and page_private and page reference
w/ {set,clear}_page_private_*, it doesn't need to call
folio_detach_private() in the end of .invalidate_folio and
.release_folio, remove it and use f2fs_bug_on instead.
Signed-off-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
---
- Testing this version which avoid remaining inline_data bit.
fs/f2fs/data.c | 25 +-------
fs/f2fs/dir.c | 6 +-
fs/f2fs/f2fs.h | 154 ++++++++++++++++++++++++-------------------------
3 files changed, 77 insertions(+), 108 deletions(-)
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 5a3636b70f48..f21e3aaa2474 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -3726,37 +3726,16 @@ void f2fs_invalidate_folio(struct folio *folio, size_t offset, size_t length)
f2fs_remove_dirty_inode(inode);
}
}
-
- clear_page_private_reference(&folio->page);
- clear_page_private_gcing(&folio->page);
-
- if (test_opt(sbi, COMPRESS_CACHE) &&
- inode->i_ino == F2FS_COMPRESS_INO(sbi))
- clear_page_private_data(&folio->page);
-
- folio_detach_private(folio);
+ clear_page_private_all(&folio->page);
}
bool f2fs_release_folio(struct folio *folio, gfp_t wait)
{
- struct f2fs_sb_info *sbi;
-
/* If this is dirty folio, keep private data */
if (folio_test_dirty(folio))
return false;
- sbi = F2FS_M_SB(folio->mapping);
- if (test_opt(sbi, COMPRESS_CACHE)) {
- struct inode *inode = folio->mapping->host;
-
- if (inode->i_ino == F2FS_COMPRESS_INO(sbi))
- clear_page_private_data(&folio->page);
- }
-
- clear_page_private_reference(&folio->page);
- clear_page_private_gcing(&folio->page);
-
- folio_detach_private(folio);
+ clear_page_private_all(&folio->page);
return true;
}
diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c
index d6dd8327e82d..887e55988450 100644
--- a/fs/f2fs/dir.c
+++ b/fs/f2fs/dir.c
@@ -905,14 +905,10 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page,
f2fs_clear_page_cache_dirty_tag(page);
clear_page_dirty_for_io(page);
ClearPageUptodate(page);
-
- clear_page_private_gcing(page);
+ clear_page_private_all(page);
inode_dec_dirty_pages(dir);
f2fs_remove_dirty_inode(dir);
-
- detach_page_private(page);
- set_page_private(page, 0);
}
f2fs_put_page(page, 1);
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index ede38bcef80e..6cae94d51821 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -1398,86 +1398,6 @@ enum {
PAGE_PRIVATE_MAX
};
-#define PAGE_PRIVATE_GET_FUNC(name, flagname) \
-static inline bool page_private_##name(struct page *page) \
-{ \
- return PagePrivate(page) && \
- test_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page)) && \
- test_bit(PAGE_PRIVATE_##flagname, &page_private(page)); \
-}
-
-#define PAGE_PRIVATE_SET_FUNC(name, flagname) \
-static inline void set_page_private_##name(struct page *page) \
-{ \
- if (!PagePrivate(page)) { \
- get_page(page); \
- SetPagePrivate(page); \
- set_page_private(page, 0); \
- } \
- set_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page)); \
- set_bit(PAGE_PRIVATE_##flagname, &page_private(page)); \
-}
-
-#define PAGE_PRIVATE_CLEAR_FUNC(name, flagname) \
-static inline void clear_page_private_##name(struct page *page) \
-{ \
- clear_bit(PAGE_PRIVATE_##flagname, &page_private(page)); \
- if (page_private(page) == BIT(PAGE_PRIVATE_NOT_POINTER)) { \
- set_page_private(page, 0); \
- if (PagePrivate(page)) { \
- ClearPagePrivate(page); \
- put_page(page); \
- }\
- } \
-}
-
-PAGE_PRIVATE_GET_FUNC(nonpointer, NOT_POINTER);
-PAGE_PRIVATE_GET_FUNC(inline, INLINE_INODE);
-PAGE_PRIVATE_GET_FUNC(gcing, ONGOING_MIGRATION);
-PAGE_PRIVATE_GET_FUNC(dummy, DUMMY_WRITE);
-
-PAGE_PRIVATE_SET_FUNC(reference, REF_RESOURCE);
-PAGE_PRIVATE_SET_FUNC(inline, INLINE_INODE);
-PAGE_PRIVATE_SET_FUNC(gcing, ONGOING_MIGRATION);
-PAGE_PRIVATE_SET_FUNC(dummy, DUMMY_WRITE);
-
-PAGE_PRIVATE_CLEAR_FUNC(reference, REF_RESOURCE);
-PAGE_PRIVATE_CLEAR_FUNC(inline, INLINE_INODE);
-PAGE_PRIVATE_CLEAR_FUNC(gcing, ONGOING_MIGRATION);
-PAGE_PRIVATE_CLEAR_FUNC(dummy, DUMMY_WRITE);
-
-static inline unsigned long get_page_private_data(struct page *page)
-{
- unsigned long data = page_private(page);
-
- if (!test_bit(PAGE_PRIVATE_NOT_POINTER, &data))
- return 0;
- return data >> PAGE_PRIVATE_MAX;
-}
-
-static inline void set_page_private_data(struct page *page, unsigned long data)
-{
- if (!PagePrivate(page)) {
- get_page(page);
- SetPagePrivate(page);
- set_page_private(page, 0);
- }
- set_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page));
- page_private(page) |= data << PAGE_PRIVATE_MAX;
-}
-
-static inline void clear_page_private_data(struct page *page)
-{
- page_private(page) &= GENMASK(PAGE_PRIVATE_MAX - 1, 0);
- if (page_private(page) == BIT(PAGE_PRIVATE_NOT_POINTER)) {
- set_page_private(page, 0);
- if (PagePrivate(page)) {
- ClearPagePrivate(page);
- put_page(page);
- }
- }
-}
-
/* For compression */
enum compress_algorithm_type {
COMPRESS_LZO,
@@ -2372,6 +2292,80 @@ void f2fs_printk(struct f2fs_sb_info *sbi, const char *fmt, ...);
#define f2fs_debug(sbi, fmt, ...) \
f2fs_printk(sbi, KERN_DEBUG fmt, ##__VA_ARGS__)
+#define PAGE_PRIVATE_GET_FUNC(name, flagname) \
+static inline bool page_private_##name(struct page *page) \
+{ \
+ return PagePrivate(page) && \
+ test_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page)) && \
+ test_bit(PAGE_PRIVATE_##flagname, &page_private(page)); \
+}
+
+#define PAGE_PRIVATE_SET_FUNC(name, flagname) \
+static inline void set_page_private_##name(struct page *page) \
+{ \
+ if (!PagePrivate(page)) \
+ attach_page_private(page, (void *)0); \
+ set_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page)); \
+ set_bit(PAGE_PRIVATE_##flagname, &page_private(page)); \
+}
+
+#define PAGE_PRIVATE_CLEAR_FUNC(name, flagname) \
+static inline void clear_page_private_##name(struct page *page) \
+{ \
+ clear_bit(PAGE_PRIVATE_##flagname, &page_private(page)); \
+ if (page_private(page) == BIT(PAGE_PRIVATE_NOT_POINTER)) \
+ detach_page_private(page); \
+}
+
+PAGE_PRIVATE_GET_FUNC(nonpointer, NOT_POINTER);
+PAGE_PRIVATE_GET_FUNC(inline, INLINE_INODE);
+PAGE_PRIVATE_GET_FUNC(gcing, ONGOING_MIGRATION);
+PAGE_PRIVATE_GET_FUNC(dummy, DUMMY_WRITE);
+
+PAGE_PRIVATE_SET_FUNC(reference, REF_RESOURCE);
+PAGE_PRIVATE_SET_FUNC(inline, INLINE_INODE);
+PAGE_PRIVATE_SET_FUNC(gcing, ONGOING_MIGRATION);
+PAGE_PRIVATE_SET_FUNC(dummy, DUMMY_WRITE);
+
+PAGE_PRIVATE_CLEAR_FUNC(reference, REF_RESOURCE);
+PAGE_PRIVATE_CLEAR_FUNC(inline, INLINE_INODE);
+PAGE_PRIVATE_CLEAR_FUNC(gcing, ONGOING_MIGRATION);
+PAGE_PRIVATE_CLEAR_FUNC(dummy, DUMMY_WRITE);
+
+static inline unsigned long get_page_private_data(struct page *page)
+{
+ unsigned long data = page_private(page);
+
+ if (!test_bit(PAGE_PRIVATE_NOT_POINTER, &data))
+ return 0;
+ return data >> PAGE_PRIVATE_MAX;
+}
+
+static inline void set_page_private_data(struct page *page, unsigned long data)
+{
+ if (!PagePrivate(page))
+ attach_page_private(page, (void *)0);
+ set_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page));
+ page_private(page) |= data << PAGE_PRIVATE_MAX;
+}
+
+static inline void clear_page_private_data(struct page *page)
+{
+ page_private(page) &= GENMASK(PAGE_PRIVATE_MAX - 1, 0);
+ if (page_private(page) == BIT(PAGE_PRIVATE_NOT_POINTER))
+ detach_page_private(page);
+}
+
+static inline void clear_page_private_all(struct page *page)
+{
+ clear_page_private_data(page);
+ clear_page_private_reference(page);
+ clear_page_private_gcing(page);
+ clear_page_private_inline(page);
+
+ f2fs_bug_on(F2FS_P_SB(page), page_private(page));
+}
+
static inline void dec_valid_block_count(struct f2fs_sb_info *sbi,
struct inode *inode,
block_t count)
--
2.40.0.577.gac1e443424-goog
^ permalink raw reply related [flat|nested] 4+ messages in thread