* [PATCH v2 1/2] f2fs: unify add/remove ino entry API for all ino types
@ 2026-08-09 1:26 ` Chao Yu via Linux-f2fs-devel
0 siblings, 0 replies; 4+ messages in thread
From: Chao Yu @ 2026-08-09 1:26 UTC (permalink / raw)
To: jaegeuk; +Cc: linux-f2fs-devel, linux-kernel, Chao Yu
- Call f2fs_add_ino_entry() and f2fs_remove_ino_entry() for ORPHAN_INO
- introduce __f2fs_add_ino_entry() to wrap __add_ino_entry(), so that
both f2fs_add_ino_entry() and f2fs_set_dirty_device() will call
__f2fs_add_ino_entry().
So, after this change:
add delete lookup
ORPHAN_INO f2fs_add_ino_entry f2fs_remove_ino_entry N/A
FLUSH_INO f2fs_set_dirty_device f2fs_remove_ino_entry f2fs_is_dirty_device
APPEND_INO f2fs_add_ino_entry f2fs_remove_ino_entry f2fs_exist_written_data
UPDATA_INO f2fs_add_ino_entry f2fs_remove_ino_entry f2fs_exist_written_data
TRANS_DIR_INO f2fs_add_ino_entry N/A f2fs_exist_written_data
XATTR_DIR_INO f2fs_add_ino_entry N/A f2fs_exist_written_data
Signed-off-by: Chao Yu <chao@kernel.org>
---
fs/f2fs/checkpoint.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index 4413eccb5ecb..eb2f955b1e2a 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -775,10 +775,16 @@ static void f2fs_wait_for_inode_record(struct f2fs_sb_info *sbi, int mode)
flush_workqueue(sbi->evict_wq);
}
-void f2fs_add_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type)
+static void __f2fs_add_ino_entry(struct f2fs_sb_info *sbi, nid_t ino,
+ unsigned int devidx, int type)
{
/* add new dirty ino entry into list */
- __add_ino_entry(sbi, ino, 0, type);
+ __add_ino_entry(sbi, ino, devidx, type);
+}
+
+void f2fs_add_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type)
+{
+ __f2fs_add_ino_entry(sbi, ino, 0, type);
}
void f2fs_remove_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type)
@@ -823,7 +829,7 @@ void f2fs_release_ino_entry(struct f2fs_sb_info *sbi, bool all)
void f2fs_set_dirty_device(struct f2fs_sb_info *sbi, nid_t ino,
unsigned int devidx, int type)
{
- __add_ino_entry(sbi, ino, devidx, type);
+ __f2fs_add_ino_entry(sbi, ino, devidx, type);
}
bool f2fs_is_dirty_device(struct f2fs_sb_info *sbi, nid_t ino,
@@ -875,14 +881,14 @@ void f2fs_release_orphan_inode(struct f2fs_sb_info *sbi)
void f2fs_add_orphan_inode(struct inode *inode)
{
/* add new orphan ino entry into list */
- __add_ino_entry(F2FS_I_SB(inode), inode->i_ino, 0, ORPHAN_INO);
+ f2fs_add_ino_entry(F2FS_I_SB(inode), inode->i_ino, ORPHAN_INO);
f2fs_update_inode_page(inode);
}
void f2fs_remove_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino)
{
/* remove orphan entry from orphan list */
- __remove_ino_entry(sbi, ino, ORPHAN_INO);
+ f2fs_remove_ino_entry(sbi, ino, ORPHAN_INO);
}
static int recover_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino)
--
2.49.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [f2fs-dev] [PATCH v2 1/2] f2fs: unify add/remove ino entry API for all ino types
@ 2026-08-09 1:26 ` Chao Yu via Linux-f2fs-devel
0 siblings, 0 replies; 4+ messages in thread
From: Chao Yu via Linux-f2fs-devel @ 2026-08-09 1:26 UTC (permalink / raw)
To: jaegeuk; +Cc: linux-kernel, linux-f2fs-devel
- Call f2fs_add_ino_entry() and f2fs_remove_ino_entry() for ORPHAN_INO
- introduce __f2fs_add_ino_entry() to wrap __add_ino_entry(), so that
both f2fs_add_ino_entry() and f2fs_set_dirty_device() will call
__f2fs_add_ino_entry().
So, after this change:
add delete lookup
ORPHAN_INO f2fs_add_ino_entry f2fs_remove_ino_entry N/A
FLUSH_INO f2fs_set_dirty_device f2fs_remove_ino_entry f2fs_is_dirty_device
APPEND_INO f2fs_add_ino_entry f2fs_remove_ino_entry f2fs_exist_written_data
UPDATA_INO f2fs_add_ino_entry f2fs_remove_ino_entry f2fs_exist_written_data
TRANS_DIR_INO f2fs_add_ino_entry N/A f2fs_exist_written_data
XATTR_DIR_INO f2fs_add_ino_entry N/A f2fs_exist_written_data
Signed-off-by: Chao Yu <chao@kernel.org>
---
fs/f2fs/checkpoint.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index 4413eccb5ecb..eb2f955b1e2a 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -775,10 +775,16 @@ static void f2fs_wait_for_inode_record(struct f2fs_sb_info *sbi, int mode)
flush_workqueue(sbi->evict_wq);
}
-void f2fs_add_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type)
+static void __f2fs_add_ino_entry(struct f2fs_sb_info *sbi, nid_t ino,
+ unsigned int devidx, int type)
{
/* add new dirty ino entry into list */
- __add_ino_entry(sbi, ino, 0, type);
+ __add_ino_entry(sbi, ino, devidx, type);
+}
+
+void f2fs_add_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type)
+{
+ __f2fs_add_ino_entry(sbi, ino, 0, type);
}
void f2fs_remove_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type)
@@ -823,7 +829,7 @@ void f2fs_release_ino_entry(struct f2fs_sb_info *sbi, bool all)
void f2fs_set_dirty_device(struct f2fs_sb_info *sbi, nid_t ino,
unsigned int devidx, int type)
{
- __add_ino_entry(sbi, ino, devidx, type);
+ __f2fs_add_ino_entry(sbi, ino, devidx, type);
}
bool f2fs_is_dirty_device(struct f2fs_sb_info *sbi, nid_t ino,
@@ -875,14 +881,14 @@ void f2fs_release_orphan_inode(struct f2fs_sb_info *sbi)
void f2fs_add_orphan_inode(struct inode *inode)
{
/* add new orphan ino entry into list */
- __add_ino_entry(F2FS_I_SB(inode), inode->i_ino, 0, ORPHAN_INO);
+ f2fs_add_ino_entry(F2FS_I_SB(inode), inode->i_ino, ORPHAN_INO);
f2fs_update_inode_page(inode);
}
void f2fs_remove_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino)
{
/* remove orphan entry from orphan list */
- __remove_ino_entry(sbi, ino, ORPHAN_INO);
+ f2fs_remove_ino_entry(sbi, ino, ORPHAN_INO);
}
static int recover_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino)
--
2.49.0
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH v2 2/2] f2fs: reduce memory footprint of ino management
2026-08-09 1:26 ` [f2fs-dev] " Chao Yu via Linux-f2fs-devel
@ 2026-08-09 1:26 ` Chao Yu via Linux-f2fs-devel
-1 siblings, 0 replies; 4+ messages in thread
From: Chao Yu @ 2026-08-09 1:26 UTC (permalink / raw)
To: jaegeuk; +Cc: linux-f2fs-devel, linux-kernel, Chao Yu
Currently, ino entries for APPEND_INO, UPDATE_INO, TRANS_DIR_INO, and
XATTR_DIR_INO allocate a 'struct ino_entry' slab object and attach it to
both a list and a radix tree solely for existence checks via
f2fs_exist_written_data().
Since these ino types only track binary existence status, we can embed
the information directly into radix tree value entries as a bitmap:
- The Linux radix tree/XArray supports in-place value entries via
xa_mk_value() / xa_to_value(), which tag the least significant bit
to store an unallocated integer value of BITS_PER_XA_VALUE bits
(BITS_PER_LONG - 1) directly in the slot pointer.
- For each inode, (ino / BITS_PER_XA_VALUE) serves as the radix tree
slot index, and (ino % BITS_PER_XA_VALUE) is used as the bit offset
within the slot's bitmap.
For example, when tracking ino = 7:
- Before: Allocate a 'struct ino_entry' ({ .ino = 7 }), insert its
pointer into the radix tree at index = 7, and link it to im->ino_list.
- After: Compute slot_index = 7 / BITS_PER_XA_VALUE (index 0) and
bit_offset = 7 % BITS_PER_XA_VALUE (bit 7), then set bit 7 in the
value entry via xa_mk_value(bitmap) at index 0, without allocating
a slab object or linking to a list.
Additionally:
- In-place slot updates are performed via radix_tree_replace_slot(), and
slots are deleted with radix_tree_delete() once the bitmap is zeroed.
- Reorder the ino list enum so ORPHAN_INO and FLUSH_INO (which still
require struct ino_entry and list traversal) remain separated, while
bitmap-based trees are torn down using xa_destroy().
This eliminates 'struct ino_entry' slab allocations and linked-list
tracking for these ino types, significantly reducing memory consumption.
Signed-off-by: Chao Yu <chao@kernel.org>
---
v2:
- fix to call __remove_ino_entry correctly for FLUSH_INO
fs/f2fs/checkpoint.c | 99 ++++++++++++++++++++++++++++++++++++++++----
fs/f2fs/f2fs.h | 6 ++-
2 files changed, 95 insertions(+), 10 deletions(-)
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index eb2f955b1e2a..f81ba8cc861a 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -766,6 +766,64 @@ static void __remove_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type)
spin_unlock(&im->ino_lock);
}
+static void __set_ino_bitmap(struct f2fs_sb_info *sbi, nid_t ino, int type)
+{
+ struct inode_management *im = &sbi->im[type];
+ unsigned long index = INO_SLOT_INDEX(ino);
+ unsigned int ofs = INO_BIT_OFFSET(ino);
+ void **slot, *entry;
+ unsigned long bitmap = 0;
+ int ret;
+
+ ret = radix_tree_preload(GFP_NOFS | __GFP_NOFAIL);
+ f2fs_bug_on(sbi, ret);
+
+ spin_lock(&im->ino_lock);
+ slot = radix_tree_lookup_slot(&im->ino_root, index);
+ if (slot) {
+ entry = radix_tree_deref_slot(slot);
+ bitmap = xa_to_value(entry);
+ if (!(bitmap & (1UL << ofs))) {
+ bitmap |= (1UL << ofs);
+ entry = xa_mk_value(bitmap);
+ radix_tree_replace_slot(&im->ino_root, slot, entry);
+ }
+ } else {
+ bitmap |= (1UL << ofs);
+ entry = xa_mk_value(bitmap);
+ if (unlikely(radix_tree_insert(&im->ino_root, index, entry)))
+ f2fs_bug_on(sbi, 1);
+ }
+ spin_unlock(&im->ino_lock);
+ radix_tree_preload_end();
+}
+
+static void __clear_ino_bitmap(struct f2fs_sb_info *sbi, nid_t ino, int type)
+{
+ struct inode_management *im = &sbi->im[type];
+ unsigned long index = INO_SLOT_INDEX(ino);
+ unsigned int ofs = INO_BIT_OFFSET(ino);
+ void **slot, *entry;
+ unsigned long bitmap;
+
+ spin_lock(&im->ino_lock);
+ slot = radix_tree_lookup_slot(&im->ino_root, index);
+ if (slot) {
+ entry = radix_tree_deref_slot(slot);
+ bitmap = xa_to_value(entry);
+ if (bitmap & (1UL << ofs))
+ bitmap &= ~(1UL << ofs);
+
+ if (bitmap) {
+ entry = xa_mk_value(bitmap);
+ radix_tree_replace_slot(&im->ino_root, slot, entry);
+ } else {
+ radix_tree_delete(&im->ino_root, index);
+ }
+ }
+ spin_unlock(&im->ino_lock);
+}
+
static void f2fs_wait_for_inode_record(struct f2fs_sb_info *sbi, int mode)
{
if (mode != APPEND_INO && mode != UPDATE_INO)
@@ -778,8 +836,10 @@ static void f2fs_wait_for_inode_record(struct f2fs_sb_info *sbi, int mode)
static void __f2fs_add_ino_entry(struct f2fs_sb_info *sbi, nid_t ino,
unsigned int devidx, int type)
{
- /* add new dirty ino entry into list */
- __add_ino_entry(sbi, ino, devidx, type);
+ if (type <= FLUSH_INO)
+ __add_ino_entry(sbi, ino, devidx, type);
+ else
+ __set_ino_bitmap(sbi, ino, type);
}
void f2fs_add_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type)
@@ -789,20 +849,33 @@ void f2fs_add_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type)
void f2fs_remove_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type)
{
- /* remove dirty ino entry from list */
- __remove_ino_entry(sbi, ino, type);
+ if (type <= FLUSH_INO)
+ __remove_ino_entry(sbi, ino, type);
+ else
+ __clear_ino_bitmap(sbi, ino, type);
}
-/* mode should be APPEND_INO, UPDATE_INO or TRANS_DIR_INO */
+/* mode should be APPEND_INO, UPDATE_INO, TRANS_DIR_INO and XATTR_DIR_INO */
bool f2fs_exist_written_data(struct f2fs_sb_info *sbi, nid_t ino, int mode)
{
struct inode_management *im = &sbi->im[mode];
- struct ino_entry *e;
+ unsigned long index = INO_SLOT_INDEX(ino);
+ unsigned int ofs = INO_BIT_OFFSET(ino);
+ void *entry;
+ unsigned long bitmap;
+
+ f2fs_bug_on(sbi, mode <= FLUSH_INO);
spin_lock(&im->ino_lock);
- e = radix_tree_lookup(&im->ino_root, ino);
+ entry = radix_tree_lookup(&im->ino_root, index);
+ if (!entry) {
+ spin_unlock(&im->ino_lock);
+ return false;
+ }
+ bitmap = xa_to_value(entry);
spin_unlock(&im->ino_lock);
- return e ? true : false;
+
+ return bitmap & (1UL << ofs);
}
void f2fs_release_ino_entry(struct f2fs_sb_info *sbi, bool all)
@@ -810,7 +883,7 @@ void f2fs_release_ino_entry(struct f2fs_sb_info *sbi, bool all)
struct ino_entry *e, *tmp;
int i;
- for (i = all ? ORPHAN_INO : APPEND_INO; i < MAX_INO_ENTRY; i++) {
+ for (i = all ? ORPHAN_INO : FLUSH_INO; i <= FLUSH_INO; i++) {
struct inode_management *im = &sbi->im[i];
f2fs_wait_for_inode_record(sbi, i);
@@ -824,6 +897,14 @@ void f2fs_release_ino_entry(struct f2fs_sb_info *sbi, bool all)
}
spin_unlock(&im->ino_lock);
}
+
+ for (i = APPEND_INO; i < MAX_INO_ENTRY; i++) {
+ struct inode_management *im = &sbi->im[i];
+
+ spin_lock(&im->ino_lock);
+ xa_destroy(&im->ino_root);
+ spin_unlock(&im->ino_lock);
+ }
}
void f2fs_set_dirty_device(struct f2fs_sb_info *sbi, nid_t ino,
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 160e7db0674e..5ae2d347c3ce 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -389,14 +389,18 @@ enum {
/* for the list of ino */
enum {
ORPHAN_INO, /* for orphan ino list */
+ FLUSH_INO, /* for multiple device flushing */
APPEND_INO, /* for append ino list */
UPDATE_INO, /* for update ino list */
TRANS_DIR_INO, /* for transactions dir ino list */
XATTR_DIR_INO, /* for xattr updated dir ino list */
- FLUSH_INO, /* for multiple device flushing */
MAX_INO_ENTRY, /* max. list */
};
+#define INO_BITS_PER_SLOT BITS_PER_XA_VALUE
+#define INO_SLOT_INDEX(ino) ((ino) / INO_BITS_PER_SLOT)
+#define INO_BIT_OFFSET(ino) ((ino) % INO_BITS_PER_SLOT)
+
struct ino_entry {
struct list_head list; /* list head */
nid_t ino; /* inode number */
--
2.49.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [f2fs-dev] [PATCH v2 2/2] f2fs: reduce memory footprint of ino management
@ 2026-08-09 1:26 ` Chao Yu via Linux-f2fs-devel
0 siblings, 0 replies; 4+ messages in thread
From: Chao Yu via Linux-f2fs-devel @ 2026-08-09 1:26 UTC (permalink / raw)
To: jaegeuk; +Cc: linux-kernel, linux-f2fs-devel
Currently, ino entries for APPEND_INO, UPDATE_INO, TRANS_DIR_INO, and
XATTR_DIR_INO allocate a 'struct ino_entry' slab object and attach it to
both a list and a radix tree solely for existence checks via
f2fs_exist_written_data().
Since these ino types only track binary existence status, we can embed
the information directly into radix tree value entries as a bitmap:
- The Linux radix tree/XArray supports in-place value entries via
xa_mk_value() / xa_to_value(), which tag the least significant bit
to store an unallocated integer value of BITS_PER_XA_VALUE bits
(BITS_PER_LONG - 1) directly in the slot pointer.
- For each inode, (ino / BITS_PER_XA_VALUE) serves as the radix tree
slot index, and (ino % BITS_PER_XA_VALUE) is used as the bit offset
within the slot's bitmap.
For example, when tracking ino = 7:
- Before: Allocate a 'struct ino_entry' ({ .ino = 7 }), insert its
pointer into the radix tree at index = 7, and link it to im->ino_list.
- After: Compute slot_index = 7 / BITS_PER_XA_VALUE (index 0) and
bit_offset = 7 % BITS_PER_XA_VALUE (bit 7), then set bit 7 in the
value entry via xa_mk_value(bitmap) at index 0, without allocating
a slab object or linking to a list.
Additionally:
- In-place slot updates are performed via radix_tree_replace_slot(), and
slots are deleted with radix_tree_delete() once the bitmap is zeroed.
- Reorder the ino list enum so ORPHAN_INO and FLUSH_INO (which still
require struct ino_entry and list traversal) remain separated, while
bitmap-based trees are torn down using xa_destroy().
This eliminates 'struct ino_entry' slab allocations and linked-list
tracking for these ino types, significantly reducing memory consumption.
Signed-off-by: Chao Yu <chao@kernel.org>
---
v2:
- fix to call __remove_ino_entry correctly for FLUSH_INO
fs/f2fs/checkpoint.c | 99 ++++++++++++++++++++++++++++++++++++++++----
fs/f2fs/f2fs.h | 6 ++-
2 files changed, 95 insertions(+), 10 deletions(-)
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index eb2f955b1e2a..f81ba8cc861a 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -766,6 +766,64 @@ static void __remove_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type)
spin_unlock(&im->ino_lock);
}
+static void __set_ino_bitmap(struct f2fs_sb_info *sbi, nid_t ino, int type)
+{
+ struct inode_management *im = &sbi->im[type];
+ unsigned long index = INO_SLOT_INDEX(ino);
+ unsigned int ofs = INO_BIT_OFFSET(ino);
+ void **slot, *entry;
+ unsigned long bitmap = 0;
+ int ret;
+
+ ret = radix_tree_preload(GFP_NOFS | __GFP_NOFAIL);
+ f2fs_bug_on(sbi, ret);
+
+ spin_lock(&im->ino_lock);
+ slot = radix_tree_lookup_slot(&im->ino_root, index);
+ if (slot) {
+ entry = radix_tree_deref_slot(slot);
+ bitmap = xa_to_value(entry);
+ if (!(bitmap & (1UL << ofs))) {
+ bitmap |= (1UL << ofs);
+ entry = xa_mk_value(bitmap);
+ radix_tree_replace_slot(&im->ino_root, slot, entry);
+ }
+ } else {
+ bitmap |= (1UL << ofs);
+ entry = xa_mk_value(bitmap);
+ if (unlikely(radix_tree_insert(&im->ino_root, index, entry)))
+ f2fs_bug_on(sbi, 1);
+ }
+ spin_unlock(&im->ino_lock);
+ radix_tree_preload_end();
+}
+
+static void __clear_ino_bitmap(struct f2fs_sb_info *sbi, nid_t ino, int type)
+{
+ struct inode_management *im = &sbi->im[type];
+ unsigned long index = INO_SLOT_INDEX(ino);
+ unsigned int ofs = INO_BIT_OFFSET(ino);
+ void **slot, *entry;
+ unsigned long bitmap;
+
+ spin_lock(&im->ino_lock);
+ slot = radix_tree_lookup_slot(&im->ino_root, index);
+ if (slot) {
+ entry = radix_tree_deref_slot(slot);
+ bitmap = xa_to_value(entry);
+ if (bitmap & (1UL << ofs))
+ bitmap &= ~(1UL << ofs);
+
+ if (bitmap) {
+ entry = xa_mk_value(bitmap);
+ radix_tree_replace_slot(&im->ino_root, slot, entry);
+ } else {
+ radix_tree_delete(&im->ino_root, index);
+ }
+ }
+ spin_unlock(&im->ino_lock);
+}
+
static void f2fs_wait_for_inode_record(struct f2fs_sb_info *sbi, int mode)
{
if (mode != APPEND_INO && mode != UPDATE_INO)
@@ -778,8 +836,10 @@ static void f2fs_wait_for_inode_record(struct f2fs_sb_info *sbi, int mode)
static void __f2fs_add_ino_entry(struct f2fs_sb_info *sbi, nid_t ino,
unsigned int devidx, int type)
{
- /* add new dirty ino entry into list */
- __add_ino_entry(sbi, ino, devidx, type);
+ if (type <= FLUSH_INO)
+ __add_ino_entry(sbi, ino, devidx, type);
+ else
+ __set_ino_bitmap(sbi, ino, type);
}
void f2fs_add_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type)
@@ -789,20 +849,33 @@ void f2fs_add_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type)
void f2fs_remove_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type)
{
- /* remove dirty ino entry from list */
- __remove_ino_entry(sbi, ino, type);
+ if (type <= FLUSH_INO)
+ __remove_ino_entry(sbi, ino, type);
+ else
+ __clear_ino_bitmap(sbi, ino, type);
}
-/* mode should be APPEND_INO, UPDATE_INO or TRANS_DIR_INO */
+/* mode should be APPEND_INO, UPDATE_INO, TRANS_DIR_INO and XATTR_DIR_INO */
bool f2fs_exist_written_data(struct f2fs_sb_info *sbi, nid_t ino, int mode)
{
struct inode_management *im = &sbi->im[mode];
- struct ino_entry *e;
+ unsigned long index = INO_SLOT_INDEX(ino);
+ unsigned int ofs = INO_BIT_OFFSET(ino);
+ void *entry;
+ unsigned long bitmap;
+
+ f2fs_bug_on(sbi, mode <= FLUSH_INO);
spin_lock(&im->ino_lock);
- e = radix_tree_lookup(&im->ino_root, ino);
+ entry = radix_tree_lookup(&im->ino_root, index);
+ if (!entry) {
+ spin_unlock(&im->ino_lock);
+ return false;
+ }
+ bitmap = xa_to_value(entry);
spin_unlock(&im->ino_lock);
- return e ? true : false;
+
+ return bitmap & (1UL << ofs);
}
void f2fs_release_ino_entry(struct f2fs_sb_info *sbi, bool all)
@@ -810,7 +883,7 @@ void f2fs_release_ino_entry(struct f2fs_sb_info *sbi, bool all)
struct ino_entry *e, *tmp;
int i;
- for (i = all ? ORPHAN_INO : APPEND_INO; i < MAX_INO_ENTRY; i++) {
+ for (i = all ? ORPHAN_INO : FLUSH_INO; i <= FLUSH_INO; i++) {
struct inode_management *im = &sbi->im[i];
f2fs_wait_for_inode_record(sbi, i);
@@ -824,6 +897,14 @@ void f2fs_release_ino_entry(struct f2fs_sb_info *sbi, bool all)
}
spin_unlock(&im->ino_lock);
}
+
+ for (i = APPEND_INO; i < MAX_INO_ENTRY; i++) {
+ struct inode_management *im = &sbi->im[i];
+
+ spin_lock(&im->ino_lock);
+ xa_destroy(&im->ino_root);
+ spin_unlock(&im->ino_lock);
+ }
}
void f2fs_set_dirty_device(struct f2fs_sb_info *sbi, nid_t ino,
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 160e7db0674e..5ae2d347c3ce 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -389,14 +389,18 @@ enum {
/* for the list of ino */
enum {
ORPHAN_INO, /* for orphan ino list */
+ FLUSH_INO, /* for multiple device flushing */
APPEND_INO, /* for append ino list */
UPDATE_INO, /* for update ino list */
TRANS_DIR_INO, /* for transactions dir ino list */
XATTR_DIR_INO, /* for xattr updated dir ino list */
- FLUSH_INO, /* for multiple device flushing */
MAX_INO_ENTRY, /* max. list */
};
+#define INO_BITS_PER_SLOT BITS_PER_XA_VALUE
+#define INO_SLOT_INDEX(ino) ((ino) / INO_BITS_PER_SLOT)
+#define INO_BIT_OFFSET(ino) ((ino) % INO_BITS_PER_SLOT)
+
struct ino_entry {
struct list_head list; /* list head */
nid_t ino; /* inode number */
--
2.49.0
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-08-09 1:26 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-09 1:26 [PATCH v2 1/2] f2fs: unify add/remove ino entry API for all ino types Chao Yu
2026-08-09 1:26 ` [f2fs-dev] " Chao Yu via Linux-f2fs-devel
2026-08-09 1:26 ` [PATCH v2 2/2] f2fs: reduce memory footprint of ino management Chao Yu
2026-08-09 1:26 ` [f2fs-dev] " Chao Yu via Linux-f2fs-devel
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.