Commit 635a52da authored by Chao Yu's avatar Chao Yu Committed by Jaegeuk Kim
Browse files

f2fs: remove folio_detach_private() in .invalidate_folio and .release_folio



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: default avatarChao Yu <chao@kernel.org>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent 33560f80
Loading
Loading
Loading
Loading
+2 −23
Original line number Diff line number Diff line
@@ -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;
}

+1 −5
Original line number Diff line number Diff line
@@ -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);

+74 −80
Original line number Diff line number Diff line
@@ -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)