[Devel] [PATCH RH7 2/3] ext4: Introduce ext4_fastmap()
Kirill Tkhai
ktkhai at virtuozzo.com
Wed Jun 17 19:09:30 MSK 2020
This introduces a new function, which is rather similar to ext4_overwrite_io()
except:
1)new flag EXT4_GET_BLOCKS_EXTENT_TREE_ONLY is passed;
it says we're interested in cached extents in extent
tree, and we don't want initiate any IO to get extent;
2)ext4_unaligned_aio() check is added, which is one of
the check we have on direct IO path (ext4_file_write_iter).
The function is supposed to be used as replacement in ploop's extent tree from
io_direct.c on fastpath, and for the introduction fastpath for io_kaio.c.
Note: in case of io_direct.c it looks strange to have duplicate extent tree
in io_direct_map.c: 1)io_direct is for ext4 only; 2)ext4 already caches
extents in rbtree.
Next patch introduces fastpath for io_kaio, but io_direct.c should be converted
to use ext4 extent tree in the future too.
Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
---
fs/ext4/ext4.h | 3 +++
fs/ext4/file.c | 21 +++++++++++++++++++++
fs/ext4/inode.c | 3 +++
include/linux/fs.h | 1 +
4 files changed, 28 insertions(+)
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index f2d849c05cde..193ef8903a36 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -578,6 +578,9 @@ enum {
* allows jbd2 to avoid submitting data before commit. */
#define EXT4_GET_BLOCKS_IO_SUBMIT 0x0400
+ /* Search in extent tree only */
+#define EXT4_GET_BLOCKS_EXTENT_TREE_ONLY 0x8000
+
/*
* The bit position of these flags must not overlap with any of the
* EXT4_GET_BLOCKS_*. They are used by ext4_ext_find_extent(),
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index b187b9bbe5fc..2ee774a54ad4 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -125,6 +125,26 @@ static bool ext4_overwrite_io(struct inode *inode, loff_t pos, loff_t len)
return __ext4_overwrite_io(inode, pos, len, &map, 0);
}
+static int ext4_fastmap(struct inode *inode, sector_t lblk_sec,
+ unsigned int len, sector_t *pblk_sec)
+{
+ struct ext4_map_blocks map;
+ loff_t pos = lblk_sec << 9;
+ bool unaligned_aio, found;
+
+ unaligned_aio = ext4_unaligned_aio(inode, len, pos);
+ if (unaligned_aio)
+ return -ENOENT;
+
+ found = __ext4_overwrite_io(inode, lblk_sec << 9, len, &map,
+ EXT4_GET_BLOCKS_EXTENT_TREE_ONLY);
+ if (!found)
+ return -ENOENT;
+
+ *pblk_sec = map.m_pblk << (inode->i_blkbits - 9);
+ return 0;
+}
+
static ssize_t ext4_write_checks(struct kiocb *iocb, struct iov_iter *iter, loff_t *pos)
{
struct file *file = iocb->ki_filp;
@@ -605,5 +625,6 @@ const struct inode_operations ext4_file_inode_operations = {
.removexattr = generic_removexattr,
.get_acl = ext4_get_acl,
.fiemap = ext4_fiemap,
+ .fastmap = ext4_fastmap,
};
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index c2bc8c7ccfca..a4c1ab7c9a7c 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -524,6 +524,9 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode,
goto found;
}
+ if (flags & EXT4_GET_BLOCKS_EXTENT_TREE_ONLY)
+ return -ENOENT;
+
/*
* Try to see if we can get the block without requesting a new
* file system block.
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 4037bf4dd62b..598d7ec03578 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2013,6 +2013,7 @@ struct inode_operations {
int (*atomic_open)(struct inode *, struct dentry *,
struct file *, unsigned open_flag,
umode_t create_mode, int *opened);
+ int (*fastmap)(struct inode *, sector_t, unsigned int, sector_t *);
} ____cacheline_aligned;
More information about the Devel
mailing list