summaryrefslogtreecommitdiffstats
path: root/drivers/staging/erofs/data.c
diff options
context:
space:
mode:
authorGao Xiang <gaoxiang25@huawei.com>2018-07-26 20:21:58 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-07-27 17:24:08 +0200
commit02827e1796b33f1794966f5c3101f8da2dfa9c1d (patch)
treeaa1cac00b2a3c4c85eb0d06037db9b4e1835d18d /drivers/staging/erofs/data.c
parent5eb20ec3e52496dfd0a2cf6a817993dd01ab2067 (diff)
staging: erofs: add erofs_map_blocks_iter
This patch introduces an iterable L2P mapping operation 'erofs_map_blocks_iter'. Compared with 'erofs_map_blocks', it avoids a number of redundant 'release and regrab' processes if they request the same meta page. Signed-off-by: Gao Xiang <gaoxiang25@huawei.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/erofs/data.c')
-rw-r--r--drivers/staging/erofs/data.c36
1 files changed, 34 insertions, 2 deletions
diff --git a/drivers/staging/erofs/data.c b/drivers/staging/erofs/data.c
index 47d1787e99ef..163bfe6eaa69 100644
--- a/drivers/staging/erofs/data.c
+++ b/drivers/staging/erofs/data.c
@@ -157,12 +157,44 @@ out:
return 0;
}
+#ifdef CONFIG_EROFS_FS_ZIP
+extern int z_erofs_map_blocks_iter(struct inode *,
+ struct erofs_map_blocks *, struct page **, int);
+#endif
+
+int erofs_map_blocks_iter(struct inode *inode,
+ struct erofs_map_blocks *map,
+ struct page **mpage_ret, int flags)
+{
+ /* by default, reading raw data never use erofs_map_blocks_iter */
+ if (unlikely(!is_inode_layout_compression(inode))) {
+ if (*mpage_ret != NULL)
+ put_page(*mpage_ret);
+ *mpage_ret = NULL;
+
+ return erofs_map_blocks(inode, map, flags);
+ }
+
+#ifdef CONFIG_EROFS_FS_ZIP
+ return z_erofs_map_blocks_iter(inode, map, mpage_ret, flags);
+#else
+ /* data compression is not available */
+ return -ENOTSUPP;
+#endif
+}
+
int erofs_map_blocks(struct inode *inode,
struct erofs_map_blocks *map, int flags)
{
- if (unlikely(is_inode_layout_compression(inode)))
- return -ENOTSUPP;
+ if (unlikely(is_inode_layout_compression(inode))) {
+ struct page *mpage = NULL;
+ int err;
+ err = erofs_map_blocks_iter(inode, map, &mpage, flags);
+ if (mpage != NULL)
+ put_page(mpage);
+ return err;
+ }
return erofs_map_blocks_flatmode(inode, map, flags);
}