Skip to content

Commit 4a6bff1

Browse files
committed
Merge tag 'erofs-for-6.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs
Pull erofs updates from Gao Xiang: "In this cycle, large folios are now enabled in the iomap/fscache mode for uncompressed files first. In order to do that, we've also cleaned up better interfaces between erofs and fscache, which are acked by fscache/netfs folks and included in this pull request. Other than that, there are random fixes around erofs over fscache and crafted images by syzbot, minor cleanups and documentation updates. Summary: - Enable large folios for iomap/fscache mode - Avoid sysfs warning due to mounting twice with the same fsid and domain_id in fscache mode - Refine fscache interface among erofs, fscache, and cachefiles - Use kmap_local_page() only for metabuf - Fixes around crafted images found by syzbot - Minor cleanups and documentation updates" * tag 'erofs-for-6.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs: erofs: validate the extent length for uncompressed pclusters erofs: fix missing unmap if z_erofs_get_extent_compressedlen() fails erofs: Fix pcluster memleak when its block address is zero erofs: use kmap_local_page() only for erofs_bread() erofs: enable large folios for fscache mode erofs: support large folios for fscache mode erofs: switch to prepare_ondemand_read() in fscache mode fscache,cachefiles: add prepare_ondemand_read() callback erofs: clean up cached I/O strategies erofs: update documentation erofs: check the uniqueness of fsid in shared domain in advance erofs: enable large folios for iomap mode
2 parents ad0d9da + c505feb commit 4a6bff1

File tree

12 files changed

+344
-344
lines changed

12 files changed

+344
-344
lines changed

Documentation/filesystems/erofs.rst

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,18 @@ It is implemented to be a better choice for the following scenarios:
3030
especially for those embedded devices with limited memory and high-density
3131
hosts with numerous containers.
3232

33-
Here is the main features of EROFS:
33+
Here are the main features of EROFS:
3434

3535
- Little endian on-disk design;
3636

37-
- 4KiB block size and 32-bit block addresses, therefore 16TiB address space
38-
at most for now;
37+
- Block-based distribution and file-based distribution over fscache are
38+
supported;
39+
40+
- Support multiple devices to refer to external blobs, which can be used
41+
for container images;
42+
43+
- 4KiB block size and 32-bit block addresses for each device, therefore
44+
16TiB address space at most for now;
3945

4046
- Two inode layouts for different requirements:
4147

@@ -50,28 +56,31 @@ Here is the main features of EROFS:
5056
Metadata reserved 8 bytes 18 bytes
5157
===================== ============ ======================================
5258

53-
- Metadata and data could be mixed as an option;
54-
55-
- Support extended attributes (xattrs) as an option;
59+
- Support extended attributes as an option;
5660

57-
- Support tailpacking data and xattr inline compared to byte-addressed
58-
unaligned metadata or smaller block size alternatives;
59-
60-
- Support POSIX.1e ACLs by using xattrs;
61+
- Support POSIX.1e ACLs by using extended attributes;
6162

6263
- Support transparent data compression as an option:
6364
LZ4 and MicroLZMA algorithms can be used on a per-file basis; In addition,
6465
inplace decompression is also supported to avoid bounce compressed buffers
6566
and page cache thrashing.
6667

68+
- Support chunk-based data deduplication and rolling-hash compressed data
69+
deduplication;
70+
71+
- Support tailpacking inline compared to byte-addressed unaligned metadata
72+
or smaller block size alternatives;
73+
74+
- Support merging tail-end data into a special inode as fragments.
75+
76+
- Support large folios for uncompressed files.
77+
6778
- Support direct I/O on uncompressed files to avoid double caching for loop
6879
devices;
6980

7081
- Support FSDAX on uncompressed images for secure containers and ramdisks in
7182
order to get rid of unnecessary page cache.
7283

73-
- Support multiple devices for multi blob container images;
74-
7584
- Support file-based on-demand loading with the Fscache infrastructure.
7685

7786
The following git tree provides the file system user-space tools under
@@ -259,7 +268,7 @@ By the way, chunk-based files are all uncompressed for now.
259268

260269
Data compression
261270
----------------
262-
EROFS implements LZ4 fixed-sized output compression which generates fixed-sized
271+
EROFS implements fixed-sized output compression which generates fixed-sized
263272
compressed data blocks from variable-sized input in contrast to other existing
264273
fixed-sized input solutions. Relatively higher compression ratios can be gotten
265274
by using fixed-sized output compression since nowadays popular data compression
@@ -314,3 +323,6 @@ to understand its delta0 is constantly 1, as illustrated below::
314323

315324
If another HEAD follows a HEAD lcluster, there is no room to record CBLKCNT,
316325
but it's easy to know the size of such pcluster is 1 lcluster as well.
326+
327+
Since Linux v6.1, each pcluster can be used for multiple variable-sized extents,
328+
therefore it can be used for compressed data deduplication.

fs/cachefiles/io.c

Lines changed: 50 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -385,38 +385,35 @@ static int cachefiles_write(struct netfs_cache_resources *cres,
385385
term_func, term_func_priv);
386386
}
387387

388-
/*
389-
* Prepare a read operation, shortening it to a cached/uncached
390-
* boundary as appropriate.
391-
*/
392-
static enum netfs_io_source cachefiles_prepare_read(struct netfs_io_subrequest *subreq,
393-
loff_t i_size)
388+
static inline enum netfs_io_source
389+
cachefiles_do_prepare_read(struct netfs_cache_resources *cres,
390+
loff_t start, size_t *_len, loff_t i_size,
391+
unsigned long *_flags, ino_t netfs_ino)
394392
{
395393
enum cachefiles_prepare_read_trace why;
396-
struct netfs_io_request *rreq = subreq->rreq;
397-
struct netfs_cache_resources *cres = &rreq->cache_resources;
398-
struct cachefiles_object *object;
394+
struct cachefiles_object *object = NULL;
399395
struct cachefiles_cache *cache;
400396
struct fscache_cookie *cookie = fscache_cres_cookie(cres);
401397
const struct cred *saved_cred;
402398
struct file *file = cachefiles_cres_file(cres);
403399
enum netfs_io_source ret = NETFS_DOWNLOAD_FROM_SERVER;
400+
size_t len = *_len;
404401
loff_t off, to;
405402
ino_t ino = file ? file_inode(file)->i_ino : 0;
406403
int rc;
407404

408-
_enter("%zx @%llx/%llx", subreq->len, subreq->start, i_size);
405+
_enter("%zx @%llx/%llx", len, start, i_size);
409406

410-
if (subreq->start >= i_size) {
407+
if (start >= i_size) {
411408
ret = NETFS_FILL_WITH_ZEROES;
412409
why = cachefiles_trace_read_after_eof;
413410
goto out_no_object;
414411
}
415412

416413
if (test_bit(FSCACHE_COOKIE_NO_DATA_TO_READ, &cookie->flags)) {
417-
__set_bit(NETFS_SREQ_COPY_TO_CACHE, &subreq->flags);
414+
__set_bit(NETFS_SREQ_COPY_TO_CACHE, _flags);
418415
why = cachefiles_trace_read_no_data;
419-
if (!test_bit(NETFS_SREQ_ONDEMAND, &subreq->flags))
416+
if (!test_bit(NETFS_SREQ_ONDEMAND, _flags))
420417
goto out_no_object;
421418
}
422419

@@ -437,7 +434,7 @@ static enum netfs_io_source cachefiles_prepare_read(struct netfs_io_subrequest *
437434
retry:
438435
off = cachefiles_inject_read_error();
439436
if (off == 0)
440-
off = vfs_llseek(file, subreq->start, SEEK_DATA);
437+
off = vfs_llseek(file, start, SEEK_DATA);
441438
if (off < 0 && off >= (loff_t)-MAX_ERRNO) {
442439
if (off == (loff_t)-ENXIO) {
443440
why = cachefiles_trace_read_seek_nxio;
@@ -449,58 +446,83 @@ static enum netfs_io_source cachefiles_prepare_read(struct netfs_io_subrequest *
449446
goto out;
450447
}
451448

452-
if (off >= subreq->start + subreq->len) {
449+
if (off >= start + len) {
453450
why = cachefiles_trace_read_found_hole;
454451
goto download_and_store;
455452
}
456453

457-
if (off > subreq->start) {
454+
if (off > start) {
458455
off = round_up(off, cache->bsize);
459-
subreq->len = off - subreq->start;
456+
len = off - start;
457+
*_len = len;
460458
why = cachefiles_trace_read_found_part;
461459
goto download_and_store;
462460
}
463461

464462
to = cachefiles_inject_read_error();
465463
if (to == 0)
466-
to = vfs_llseek(file, subreq->start, SEEK_HOLE);
464+
to = vfs_llseek(file, start, SEEK_HOLE);
467465
if (to < 0 && to >= (loff_t)-MAX_ERRNO) {
468466
trace_cachefiles_io_error(object, file_inode(file), to,
469467
cachefiles_trace_seek_error);
470468
why = cachefiles_trace_read_seek_error;
471469
goto out;
472470
}
473471

474-
if (to < subreq->start + subreq->len) {
475-
if (subreq->start + subreq->len >= i_size)
472+
if (to < start + len) {
473+
if (start + len >= i_size)
476474
to = round_up(to, cache->bsize);
477475
else
478476
to = round_down(to, cache->bsize);
479-
subreq->len = to - subreq->start;
477+
len = to - start;
478+
*_len = len;
480479
}
481480

482481
why = cachefiles_trace_read_have_data;
483482
ret = NETFS_READ_FROM_CACHE;
484483
goto out;
485484

486485
download_and_store:
487-
__set_bit(NETFS_SREQ_COPY_TO_CACHE, &subreq->flags);
488-
if (test_bit(NETFS_SREQ_ONDEMAND, &subreq->flags)) {
489-
rc = cachefiles_ondemand_read(object, subreq->start,
490-
subreq->len);
486+
__set_bit(NETFS_SREQ_COPY_TO_CACHE, _flags);
487+
if (test_bit(NETFS_SREQ_ONDEMAND, _flags)) {
488+
rc = cachefiles_ondemand_read(object, start, len);
491489
if (!rc) {
492-
__clear_bit(NETFS_SREQ_ONDEMAND, &subreq->flags);
490+
__clear_bit(NETFS_SREQ_ONDEMAND, _flags);
493491
goto retry;
494492
}
495493
ret = NETFS_INVALID_READ;
496494
}
497495
out:
498496
cachefiles_end_secure(cache, saved_cred);
499497
out_no_object:
500-
trace_cachefiles_prep_read(subreq, ret, why, ino);
498+
trace_cachefiles_prep_read(object, start, len, *_flags, ret, why, ino, netfs_ino);
501499
return ret;
502500
}
503501

502+
/*
503+
* Prepare a read operation, shortening it to a cached/uncached
504+
* boundary as appropriate.
505+
*/
506+
static enum netfs_io_source cachefiles_prepare_read(struct netfs_io_subrequest *subreq,
507+
loff_t i_size)
508+
{
509+
return cachefiles_do_prepare_read(&subreq->rreq->cache_resources,
510+
subreq->start, &subreq->len, i_size,
511+
&subreq->flags, subreq->rreq->inode->i_ino);
512+
}
513+
514+
/*
515+
* Prepare an on-demand read operation, shortening it to a cached/uncached
516+
* boundary as appropriate.
517+
*/
518+
static enum netfs_io_source
519+
cachefiles_prepare_ondemand_read(struct netfs_cache_resources *cres,
520+
loff_t start, size_t *_len, loff_t i_size,
521+
unsigned long *_flags, ino_t ino)
522+
{
523+
return cachefiles_do_prepare_read(cres, start, _len, i_size, _flags, ino);
524+
}
525+
504526
/*
505527
* Prepare for a write to occur.
506528
*/
@@ -621,6 +643,7 @@ static const struct netfs_cache_ops cachefiles_netfs_cache_ops = {
621643
.write = cachefiles_write,
622644
.prepare_read = cachefiles_prepare_read,
623645
.prepare_write = cachefiles_prepare_write,
646+
.prepare_ondemand_read = cachefiles_prepare_ondemand_read,
624647
.query_occupancy = cachefiles_query_occupancy,
625648
};
626649

fs/erofs/data.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,7 @@
1313
void erofs_unmap_metabuf(struct erofs_buf *buf)
1414
{
1515
if (buf->kmap_type == EROFS_KMAP)
16-
kunmap(buf->page);
17-
else if (buf->kmap_type == EROFS_KMAP_ATOMIC)
18-
kunmap_atomic(buf->base);
16+
kunmap_local(buf->base);
1917
buf->base = NULL;
2018
buf->kmap_type = EROFS_NO_KMAP;
2119
}
@@ -54,9 +52,7 @@ void *erofs_bread(struct erofs_buf *buf, struct inode *inode,
5452
}
5553
if (buf->kmap_type == EROFS_NO_KMAP) {
5654
if (type == EROFS_KMAP)
57-
buf->base = kmap(page);
58-
else if (type == EROFS_KMAP_ATOMIC)
59-
buf->base = kmap_atomic(page);
55+
buf->base = kmap_local_page(page);
6056
buf->kmap_type = type;
6157
} else if (buf->kmap_type != type) {
6258
DBG_BUGON(1);
@@ -403,6 +399,8 @@ const struct address_space_operations erofs_raw_access_aops = {
403399
.readahead = erofs_readahead,
404400
.bmap = erofs_bmap,
405401
.direct_IO = noop_direct_IO,
402+
.release_folio = iomap_release_folio,
403+
.invalidate_folio = iomap_invalidate_folio,
406404
};
407405

408406
#ifdef CONFIG_FS_DAX

0 commit comments

Comments
 (0)