f2fs: introduce device aliasing file

F2FS should understand how the device aliasing file works and support
deleting the file after use. A device aliasing file can be created by
mkfs.f2fs tool and it can map the whole device with an extent, not
using node blocks. The file space should be pinned and normally used for
read-only usages.

Signed-off-by: Daeho Jeong <daehojeong@google.com>
Signed-off-by: Chao Yu <chao@kernel.org>
Reviewed-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
This commit is contained in:
Daeho Jeong
2024-10-17 10:31:53 -07:00
committed by Jaegeuk Kim
parent fa08972bcb
commit 128d333f0d
9 changed files with 164 additions and 6 deletions

View File

@@ -24,6 +24,7 @@ bool sanity_check_extent_cache(struct inode *inode, struct page *ipage)
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
struct f2fs_extent *i_ext = &F2FS_INODE(ipage)->i_ext;
struct extent_info ei;
int devi;
get_read_extent_info(&ei, i_ext);
@@ -38,7 +39,36 @@ bool sanity_check_extent_cache(struct inode *inode, struct page *ipage)
ei.blk, ei.fofs, ei.len);
return false;
}
return true;
if (!IS_DEVICE_ALIASING(inode))
return true;
for (devi = 0; devi < sbi->s_ndevs; devi++) {
if (FDEV(devi).start_blk != ei.blk ||
FDEV(devi).end_blk != ei.blk + ei.len - 1)
continue;
if (devi == 0) {
f2fs_warn(sbi,
"%s: inode (ino=%lx) is an alias of meta device",
__func__, inode->i_ino);
return false;
}
if (bdev_is_zoned(FDEV(devi).bdev)) {
f2fs_warn(sbi,
"%s: device alias inode (ino=%lx)'s extent info "
"[%u, %u, %u] maps to zoned block device",
__func__, inode->i_ino, ei.blk, ei.fofs, ei.len);
return false;
}
return true;
}
f2fs_warn(sbi, "%s: device alias inode (ino=%lx)'s extent info "
"[%u, %u, %u] is inconsistent w/ any devices",
__func__, inode->i_ino, ei.blk, ei.fofs, ei.len);
return false;
}
static void __set_extent_info(struct extent_info *ei,
@@ -76,6 +106,9 @@ static bool __init_may_extent_tree(struct inode *inode, enum extent_type type)
static bool __may_extent_tree(struct inode *inode, enum extent_type type)
{
if (IS_DEVICE_ALIASING(inode) && type == EX_READ)
return true;
/*
* for recovered files during mount do not create extents
* if shrinker is not registered.
@@ -401,6 +434,11 @@ void f2fs_init_read_extent_tree(struct inode *inode, struct page *ipage)
if (atomic_read(&et->node_cnt) || !ei.len)
goto skip;
if (IS_DEVICE_ALIASING(inode)) {
et->largest = ei;
goto skip;
}
en = __attach_extent_node(sbi, et, &ei, NULL,
&et->root.rb_root.rb_node, true);
if (en) {
@@ -463,6 +501,11 @@ static bool __lookup_extent_tree(struct inode *inode, pgoff_t pgofs,
goto out;
}
if (IS_DEVICE_ALIASING(inode)) {
ret = false;
goto out;
}
en = __lookup_extent_node(&et->root, et->cached_en, pgofs);
if (!en)
goto out;