Skip to content

Commit 90a19b7

Browse files
committed
Merge tag 'erofs-for-6.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs
Pull erofs updates from Gao Xiang: "There is no outstanding feature for this cycle. The most useful changes are SEEK_{DATA,HOLE} support and some decompression micro-optimization. Other than those, there are some bugfixes and cleanups as usual: - Add SEEK_{DATA,HOLE} support - Free redundant pclusters if no cached compressed data is valid - Add sysfs entry to drop internal caches - Several bugfixes & cleanups" * tag 'erofs-for-6.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs: erofs: handle NONHEAD !delta[1] lclusters gracefully erofs: clarify direct I/O support erofs: fix blksize < PAGE_SIZE for file-backed mounts erofs: get rid of `buf->kmap_type` erofs: fix file-backed mounts over FUSE erofs: simplify definition of the log functions erofs: add sysfs node to drop internal caches erofs: free pclusters if no cached folio is attached erofs: sunset `struct erofs_workgroup` erofs: move erofs_workgroup operations into zdata.c erofs: get rid of erofs_{find,insert}_workgroup erofs: add SEEK_{DATA,HOLE} support
2 parents fcc79e1 + 0bc8061 commit 90a19b7

File tree

9 files changed

+276
-296
lines changed

9 files changed

+276
-296
lines changed

Documentation/ABI/testing/sysfs-fs-erofs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,14 @@ Description: Control strategy of sync decompression:
1616
readahead on atomic contexts only.
1717
- 1 (force on): enable for readpage and readahead.
1818
- 2 (force off): disable for all situations.
19+
20+
What: /sys/fs/erofs/<disk>/drop_caches
21+
Date: November 2024
22+
Contact: "Guo Chunhai" <guochunhai@vivo.com>
23+
Description: Writing to this will drop compression-related caches,
24+
currently used to drop in-memory pclusters and cached
25+
compressed folios:
26+
27+
- 1 : invalidate cached compressed folios
28+
- 2 : drop in-memory pclusters
29+
- 3 : drop in-memory pclusters and cached compressed folios

fs/erofs/data.c

Lines changed: 37 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@
1010

1111
void erofs_unmap_metabuf(struct erofs_buf *buf)
1212
{
13-
if (buf->kmap_type == EROFS_KMAP)
14-
kunmap_local(buf->base);
13+
if (!buf->base)
14+
return;
15+
kunmap_local(buf->base);
1516
buf->base = NULL;
16-
buf->kmap_type = EROFS_NO_KMAP;
1717
}
1818

1919
void erofs_put_metabuf(struct erofs_buf *buf)
@@ -38,20 +38,13 @@ void *erofs_bread(struct erofs_buf *buf, erofs_off_t offset,
3838
}
3939
if (!folio || !folio_contains(folio, index)) {
4040
erofs_put_metabuf(buf);
41-
folio = read_mapping_folio(buf->mapping, index, NULL);
41+
folio = read_mapping_folio(buf->mapping, index, buf->file);
4242
if (IS_ERR(folio))
4343
return folio;
4444
}
4545
buf->page = folio_file_page(folio, index);
46-
47-
if (buf->kmap_type == EROFS_NO_KMAP) {
48-
if (type == EROFS_KMAP)
49-
buf->base = kmap_local_page(buf->page);
50-
buf->kmap_type = type;
51-
} else if (buf->kmap_type != type) {
52-
DBG_BUGON(1);
53-
return ERR_PTR(-EFAULT);
54-
}
46+
if (!buf->base && type == EROFS_KMAP)
47+
buf->base = kmap_local_page(buf->page);
5548
if (type == EROFS_NO_KMAP)
5649
return NULL;
5750
return buf->base + (offset & ~PAGE_MASK);
@@ -61,9 +54,11 @@ void erofs_init_metabuf(struct erofs_buf *buf, struct super_block *sb)
6154
{
6255
struct erofs_sb_info *sbi = EROFS_SB(sb);
6356

64-
if (erofs_is_fileio_mode(sbi))
65-
buf->mapping = file_inode(sbi->fdev)->i_mapping;
66-
else if (erofs_is_fscache_mode(sb))
57+
buf->file = NULL;
58+
if (erofs_is_fileio_mode(sbi)) {
59+
buf->file = sbi->fdev; /* some fs like FUSE needs it */
60+
buf->mapping = buf->file->f_mapping;
61+
} else if (erofs_is_fscache_mode(sb))
6762
buf->mapping = sbi->s_fscache->inode->i_mapping;
6863
else
6964
buf->mapping = sb->s_bdev->bd_mapping;
@@ -350,7 +345,6 @@ static int erofs_iomap_end(struct inode *inode, loff_t pos, loff_t length,
350345
struct erofs_buf buf = {
351346
.page = kmap_to_page(ptr),
352347
.base = ptr,
353-
.kmap_type = EROFS_KMAP,
354348
};
355349

356350
DBG_BUGON(iomap->type != IOMAP_INLINE);
@@ -411,22 +405,9 @@ static ssize_t erofs_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
411405
if (IS_DAX(inode))
412406
return dax_iomap_rw(iocb, to, &erofs_iomap_ops);
413407
#endif
414-
if (iocb->ki_flags & IOCB_DIRECT) {
415-
struct block_device *bdev = inode->i_sb->s_bdev;
416-
unsigned int blksize_mask;
417-
418-
if (bdev)
419-
blksize_mask = bdev_logical_block_size(bdev) - 1;
420-
else
421-
blksize_mask = i_blocksize(inode) - 1;
422-
423-
if ((iocb->ki_pos | iov_iter_count(to) |
424-
iov_iter_alignment(to)) & blksize_mask)
425-
return -EINVAL;
426-
408+
if ((iocb->ki_flags & IOCB_DIRECT) && inode->i_sb->s_bdev)
427409
return iomap_dio_rw(iocb, to, &erofs_iomap_ops,
428410
NULL, 0, NULL, 0);
429-
}
430411
return filemap_read(iocb, to, 0);
431412
}
432413

@@ -473,8 +454,32 @@ static int erofs_file_mmap(struct file *file, struct vm_area_struct *vma)
473454
#define erofs_file_mmap generic_file_readonly_mmap
474455
#endif
475456

457+
static loff_t erofs_file_llseek(struct file *file, loff_t offset, int whence)
458+
{
459+
struct inode *inode = file->f_mapping->host;
460+
const struct iomap_ops *ops = &erofs_iomap_ops;
461+
462+
if (erofs_inode_is_data_compressed(EROFS_I(inode)->datalayout))
463+
#ifdef CONFIG_EROFS_FS_ZIP
464+
ops = &z_erofs_iomap_report_ops;
465+
#else
466+
return generic_file_llseek(file, offset, whence);
467+
#endif
468+
469+
if (whence == SEEK_HOLE)
470+
offset = iomap_seek_hole(inode, offset, ops);
471+
else if (whence == SEEK_DATA)
472+
offset = iomap_seek_data(inode, offset, ops);
473+
else
474+
return generic_file_llseek(file, offset, whence);
475+
476+
if (offset < 0)
477+
return offset;
478+
return vfs_setpos(file, offset, inode->i_sb->s_maxbytes);
479+
}
480+
476481
const struct file_operations erofs_file_fops = {
477-
.llseek = generic_file_llseek,
482+
.llseek = erofs_file_llseek,
478483
.read_iter = erofs_file_read_iter,
479484
.mmap = erofs_file_mmap,
480485
.get_unmapped_area = thp_get_unmapped_area,

fs/erofs/inode.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,7 @@ int erofs_getattr(struct mnt_idmap *idmap, const struct path *path,
318318
unsigned int query_flags)
319319
{
320320
struct inode *const inode = d_inode(path->dentry);
321+
struct block_device *bdev = inode->i_sb->s_bdev;
321322
bool compressed =
322323
erofs_inode_is_data_compressed(EROFS_I(inode)->datalayout);
323324

@@ -330,15 +331,14 @@ int erofs_getattr(struct mnt_idmap *idmap, const struct path *path,
330331
/*
331332
* Return the DIO alignment restrictions if requested.
332333
*
333-
* In EROFS, STATX_DIOALIGN is not supported in ondemand mode and
334-
* compressed files, so in these cases we report no DIO support.
334+
* In EROFS, STATX_DIOALIGN is only supported in bdev-based mode
335+
* and uncompressed inodes, otherwise we report no DIO support.
335336
*/
336337
if ((request_mask & STATX_DIOALIGN) && S_ISREG(inode->i_mode)) {
337338
stat->result_mask |= STATX_DIOALIGN;
338-
if (!erofs_is_fscache_mode(inode->i_sb) && !compressed) {
339-
stat->dio_mem_align =
340-
bdev_logical_block_size(inode->i_sb->s_bdev);
341-
stat->dio_offset_align = stat->dio_mem_align;
339+
if (bdev && !compressed) {
340+
stat->dio_mem_align = bdev_dma_alignment(bdev) + 1;
341+
stat->dio_offset_align = bdev_logical_block_size(bdev);
342342
}
343343
}
344344
generic_fillattr(idmap, request_mask, inode, stat);

fs/erofs/internal.h

Lines changed: 10 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,12 @@
2020
#include <linux/iomap.h>
2121
#include "erofs_fs.h"
2222

23-
/* redefine pr_fmt "erofs: " */
24-
#undef pr_fmt
25-
#define pr_fmt(fmt) "erofs: " fmt
26-
27-
__printf(3, 4) void _erofs_err(struct super_block *sb,
28-
const char *function, const char *fmt, ...);
23+
__printf(2, 3) void _erofs_printk(struct super_block *sb, const char *fmt, ...);
2924
#define erofs_err(sb, fmt, ...) \
30-
_erofs_err(sb, __func__, fmt "\n", ##__VA_ARGS__)
31-
__printf(3, 4) void _erofs_info(struct super_block *sb,
32-
const char *function, const char *fmt, ...);
25+
_erofs_printk(sb, KERN_ERR fmt "\n", ##__VA_ARGS__)
3326
#define erofs_info(sb, fmt, ...) \
34-
_erofs_info(sb, __func__, fmt "\n", ##__VA_ARGS__)
27+
_erofs_printk(sb, KERN_INFO fmt "\n", ##__VA_ARGS__)
28+
3529
#ifdef CONFIG_EROFS_FS_DEBUG
3630
#define DBG_BUGON BUG_ON
3731
#else
@@ -208,22 +202,16 @@ enum {
208202
EROFS_ZIP_CACHE_READAROUND
209203
};
210204

211-
/* basic unit of the workstation of a super_block */
212-
struct erofs_workgroup {
213-
pgoff_t index;
214-
struct lockref lockref;
215-
};
216-
217205
enum erofs_kmap_type {
218206
EROFS_NO_KMAP, /* don't map the buffer */
219207
EROFS_KMAP, /* use kmap_local_page() to map the buffer */
220208
};
221209

222210
struct erofs_buf {
223211
struct address_space *mapping;
212+
struct file *file;
224213
struct page *page;
225214
void *base;
226-
enum erofs_kmap_type kmap_type;
227215
};
228216
#define __EROFS_BUF_INITIALIZER ((struct erofs_buf){ .page = NULL })
229217

@@ -456,20 +444,17 @@ static inline void erofs_pagepool_add(struct page **pagepool, struct page *page)
456444
void erofs_release_pages(struct page **pagepool);
457445

458446
#ifdef CONFIG_EROFS_FS_ZIP
459-
void erofs_workgroup_put(struct erofs_workgroup *grp);
460-
struct erofs_workgroup *erofs_find_workgroup(struct super_block *sb,
461-
pgoff_t index);
462-
struct erofs_workgroup *erofs_insert_workgroup(struct super_block *sb,
463-
struct erofs_workgroup *grp);
464-
void erofs_workgroup_free_rcu(struct erofs_workgroup *grp);
447+
#define MNGD_MAPPING(sbi) ((sbi)->managed_cache->i_mapping)
448+
449+
extern atomic_long_t erofs_global_shrink_cnt;
465450
void erofs_shrinker_register(struct super_block *sb);
466451
void erofs_shrinker_unregister(struct super_block *sb);
467452
int __init erofs_init_shrinker(void);
468453
void erofs_exit_shrinker(void);
469454
int __init z_erofs_init_subsystem(void);
470455
void z_erofs_exit_subsystem(void);
471-
int erofs_try_to_free_all_cached_folios(struct erofs_sb_info *sbi,
472-
struct erofs_workgroup *egrp);
456+
unsigned long z_erofs_shrink_scan(struct erofs_sb_info *sbi,
457+
unsigned long nr_shrink);
473458
int z_erofs_map_blocks_iter(struct inode *inode, struct erofs_map_blocks *map,
474459
int flags);
475460
void *z_erofs_get_gbuf(unsigned int requiredpages);

fs/erofs/super.c

Lines changed: 12 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -18,37 +18,22 @@
1818

1919
static struct kmem_cache *erofs_inode_cachep __read_mostly;
2020

21-
void _erofs_err(struct super_block *sb, const char *func, const char *fmt, ...)
21+
void _erofs_printk(struct super_block *sb, const char *fmt, ...)
2222
{
2323
struct va_format vaf;
2424
va_list args;
25+
int level;
2526

2627
va_start(args, fmt);
2728

28-
vaf.fmt = fmt;
29+
level = printk_get_level(fmt);
30+
vaf.fmt = printk_skip_level(fmt);
2931
vaf.va = &args;
30-
3132
if (sb)
32-
pr_err("(device %s): %s: %pV", sb->s_id, func, &vaf);
33+
printk("%c%cerofs (device %s): %pV",
34+
KERN_SOH_ASCII, level, sb->s_id, &vaf);
3335
else
34-
pr_err("%s: %pV", func, &vaf);
35-
va_end(args);
36-
}
37-
38-
void _erofs_info(struct super_block *sb, const char *func, const char *fmt, ...)
39-
{
40-
struct va_format vaf;
41-
va_list args;
42-
43-
va_start(args, fmt);
44-
45-
vaf.fmt = fmt;
46-
vaf.va = &args;
47-
48-
if (sb)
49-
pr_info("(device %s): %pV", sb->s_id, &vaf);
50-
else
51-
pr_info("%pV", &vaf);
36+
printk("%c%cerofs: %pV", KERN_SOH_ASCII, level, &vaf);
5237
va_end(args);
5338
}
5439

@@ -631,7 +616,11 @@ static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc)
631616
errorfc(fc, "unsupported blksize for fscache mode");
632617
return -EINVAL;
633618
}
634-
if (!sb_set_blocksize(sb, 1 << sbi->blkszbits)) {
619+
620+
if (erofs_is_fileio_mode(sbi)) {
621+
sb->s_blocksize = 1 << sbi->blkszbits;
622+
sb->s_blocksize_bits = sbi->blkszbits;
623+
} else if (!sb_set_blocksize(sb, 1 << sbi->blkszbits)) {
635624
errorfc(fc, "failed to set erofs blksize");
636625
return -EINVAL;
637626
}

fs/erofs/sysfs.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
enum {
1212
attr_feature,
13+
attr_drop_caches,
1314
attr_pointer_ui,
1415
attr_pointer_bool,
1516
};
@@ -57,11 +58,13 @@ static struct erofs_attr erofs_attr_##_name = { \
5758

5859
#ifdef CONFIG_EROFS_FS_ZIP
5960
EROFS_ATTR_RW_UI(sync_decompress, erofs_mount_opts);
61+
EROFS_ATTR_FUNC(drop_caches, 0200);
6062
#endif
6163

6264
static struct attribute *erofs_attrs[] = {
6365
#ifdef CONFIG_EROFS_FS_ZIP
6466
ATTR_LIST(sync_decompress),
67+
ATTR_LIST(drop_caches),
6568
#endif
6669
NULL,
6770
};
@@ -163,6 +166,20 @@ static ssize_t erofs_attr_store(struct kobject *kobj, struct attribute *attr,
163166
return -EINVAL;
164167
*(bool *)ptr = !!t;
165168
return len;
169+
#ifdef CONFIG_EROFS_FS_ZIP
170+
case attr_drop_caches:
171+
ret = kstrtoul(skip_spaces(buf), 0, &t);
172+
if (ret)
173+
return ret;
174+
if (t < 1 || t > 3)
175+
return -EINVAL;
176+
177+
if (t & 2)
178+
z_erofs_shrink_scan(sbi, ~0UL);
179+
if (t & 1)
180+
invalidate_mapping_pages(MNGD_MAPPING(sbi), 0, -1);
181+
return len;
182+
#endif
166183
}
167184
return 0;
168185
}

0 commit comments

Comments
 (0)