summaryrefslogtreecommitdiff
path: root/fs/erofs/internal.h
diff options
context:
space:
mode:
authorGao Xiang <hsiangkao@redhat.com>2021-04-07 07:39:26 +0300
committerGao Xiang <hsiangkao@redhat.com>2021-04-09 22:20:19 +0300
commit598162d050801e556750defff4ddab499e5d76ed (patch)
tree60ba72dc02fbae69c6407bcb983c54fb7722855c /fs/erofs/internal.h
parentb86269f43892316ef5a177d7180d09d101a46f22 (diff)
downloadlinux-598162d050801e556750defff4ddab499e5d76ed.tar.xz
erofs: support decompress big pcluster for lz4 backend
Prior to big pcluster, there was only one compressed page so it'd easy to map this. However, when big pcluster is enabled, more work needs to be done to handle multiple compressed pages. In detail, - (maptype 0) if there is only one compressed page + no need to copy inplace I/O, just map it directly what we did before; - (maptype 1) if there are more compressed pages + no need to copy inplace I/O, vmap such compressed pages instead; - (maptype 2) if inplace I/O needs to be copied, use per-CPU buffers for decompression then. Another thing is how to detect inplace decompression is feasable or not (it's still quite easy for non big pclusters), apart from the inplace margin calculation, inplace I/O page reusing order is also needed to be considered for each compressed page. Currently, if the compressed page is the xth page, it shouldn't be reused as [0 ... nrpages_out - nrpages_in + x], otherwise a full copy will be triggered. Although there are some extra optimization ideas for this, I'd like to make big pcluster work correctly first and obviously it can be further optimized later since it has nothing with the on-disk format at all. Link: https://lore.kernel.org/r/20210407043927.10623-10-xiang@kernel.org Acked-by: Chao Yu <yuchao0@huawei.com> Signed-off-by: Gao Xiang <hsiangkao@redhat.com>
Diffstat (limited to 'fs/erofs/internal.h')
-rw-r--r--fs/erofs/internal.h15
1 files changed, 15 insertions, 0 deletions
diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h
index 5c2388daee6e..f92e3e32b9f4 100644
--- a/fs/erofs/internal.h
+++ b/fs/erofs/internal.h
@@ -402,6 +402,21 @@ int erofs_namei(struct inode *dir, struct qstr *name,
/* dir.c */
extern const struct file_operations erofs_dir_fops;
+static inline void *erofs_vm_map_ram(struct page **pages, unsigned int count)
+{
+ int retried = 0;
+
+ while (1) {
+ void *p = vm_map_ram(pages, count, -1);
+
+ /* retry two more times (totally 3 times) */
+ if (p || ++retried >= 3)
+ return p;
+ vm_unmap_aliases();
+ }
+ return NULL;
+}
+
/* pcpubuf.c */
void *erofs_get_pcpubuf(unsigned int requiredpages);
void erofs_put_pcpubuf(void *ptr);