Commit 732c2753 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'erofs-for-6.11-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs

Pull more erofs updates from Gao Xiang:

 - Support STATX_DIOALIGN and FS_IOC_GETFSSYSFSPATH

 - Fix a race of LZ4 decompression due to recent refactoring

 - Another multi-page folio adaption in erofs_bread()

* tag 'erofs-for-6.11-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs:
  erofs: convert comma to semicolon
  erofs: support multi-page folios for erofs_bread()
  erofs: add support for FS_IOC_GETFSSYSFSPATH
  erofs: fix race in z_erofs_get_gbuf()
  erofs: support STATX_DIOALIGN
parents dd90ad50 14e9283f
...@@ -21,38 +21,32 @@ void erofs_put_metabuf(struct erofs_buf *buf) ...@@ -21,38 +21,32 @@ void erofs_put_metabuf(struct erofs_buf *buf)
if (!buf->page) if (!buf->page)
return; return;
erofs_unmap_metabuf(buf); erofs_unmap_metabuf(buf);
put_page(buf->page); folio_put(page_folio(buf->page));
buf->page = NULL; buf->page = NULL;
} }
/*
* Derive the block size from inode->i_blkbits to make compatible with
* anonymous inode in fscache mode.
*/
void *erofs_bread(struct erofs_buf *buf, erofs_off_t offset, void *erofs_bread(struct erofs_buf *buf, erofs_off_t offset,
enum erofs_kmap_type type) enum erofs_kmap_type type)
{ {
pgoff_t index = offset >> PAGE_SHIFT; pgoff_t index = offset >> PAGE_SHIFT;
struct page *page = buf->page; struct folio *folio = NULL;
struct folio *folio;
unsigned int nofs_flag;
if (!page || page->index != index) { if (buf->page) {
folio = page_folio(buf->page);
if (folio_file_page(folio, index) != buf->page)
erofs_unmap_metabuf(buf);
}
if (!folio || !folio_contains(folio, index)) {
erofs_put_metabuf(buf); erofs_put_metabuf(buf);
folio = read_mapping_folio(buf->mapping, index, NULL);
nofs_flag = memalloc_nofs_save();
folio = read_cache_folio(buf->mapping, index, NULL, NULL);
memalloc_nofs_restore(nofs_flag);
if (IS_ERR(folio)) if (IS_ERR(folio))
return folio; return folio;
/* should already be PageUptodate, no need to lock page */
page = folio_file_page(folio, index);
buf->page = page;
} }
buf->page = folio_file_page(folio, index);
if (buf->kmap_type == EROFS_NO_KMAP) { if (buf->kmap_type == EROFS_NO_KMAP) {
if (type == EROFS_KMAP) if (type == EROFS_KMAP)
buf->base = kmap_local_page(page); buf->base = kmap_local_page(buf->page);
buf->kmap_type = type; buf->kmap_type = type;
} else if (buf->kmap_type != type) { } else if (buf->kmap_type != type) {
DBG_BUGON(1); DBG_BUGON(1);
......
...@@ -188,7 +188,7 @@ static int z_erofs_lzma_decompress(struct z_erofs_decompress_req *rq, ...@@ -188,7 +188,7 @@ static int z_erofs_lzma_decompress(struct z_erofs_decompress_req *rq,
!rq->partial_decoding); !rq->partial_decoding);
buf.in_size = min(rq->inputsize, PAGE_SIZE - rq->pageofs_in); buf.in_size = min(rq->inputsize, PAGE_SIZE - rq->pageofs_in);
rq->inputsize -= buf.in_size; rq->inputsize -= buf.in_size;
buf.in = dctx.kin + rq->pageofs_in, buf.in = dctx.kin + rq->pageofs_in;
dctx.bounce = strm->bounce; dctx.bounce = strm->bounce;
do { do {
dctx.avail_out = buf.out_size - buf.out_pos; dctx.avail_out = buf.out_size - buf.out_pos;
......
...@@ -334,14 +334,29 @@ int erofs_getattr(struct mnt_idmap *idmap, const struct path *path, ...@@ -334,14 +334,29 @@ int erofs_getattr(struct mnt_idmap *idmap, const struct path *path,
unsigned int query_flags) unsigned int query_flags)
{ {
struct inode *const inode = d_inode(path->dentry); struct inode *const inode = d_inode(path->dentry);
bool compressed =
erofs_inode_is_data_compressed(EROFS_I(inode)->datalayout);
if (erofs_inode_is_data_compressed(EROFS_I(inode)->datalayout)) if (compressed)
stat->attributes |= STATX_ATTR_COMPRESSED; stat->attributes |= STATX_ATTR_COMPRESSED;
stat->attributes |= STATX_ATTR_IMMUTABLE; stat->attributes |= STATX_ATTR_IMMUTABLE;
stat->attributes_mask |= (STATX_ATTR_COMPRESSED | stat->attributes_mask |= (STATX_ATTR_COMPRESSED |
STATX_ATTR_IMMUTABLE); STATX_ATTR_IMMUTABLE);
/*
* Return the DIO alignment restrictions if requested.
*
* In EROFS, STATX_DIOALIGN is not supported in ondemand mode and
* compressed files, so in these cases we report no DIO support.
*/
if ((request_mask & STATX_DIOALIGN) && S_ISREG(inode->i_mode)) {
stat->result_mask |= STATX_DIOALIGN;
if (!erofs_is_fscache_mode(inode->i_sb) && !compressed) {
stat->dio_mem_align =
bdev_logical_block_size(inode->i_sb->s_bdev);
stat->dio_offset_align = stat->dio_mem_align;
}
}
generic_fillattr(idmap, request_mask, inode, stat); generic_fillattr(idmap, request_mask, inode, stat);
return 0; return 0;
} }
......
...@@ -576,6 +576,21 @@ static const struct export_operations erofs_export_ops = { ...@@ -576,6 +576,21 @@ static const struct export_operations erofs_export_ops = {
.get_parent = erofs_get_parent, .get_parent = erofs_get_parent,
}; };
static void erofs_set_sysfs_name(struct super_block *sb)
{
struct erofs_sb_info *sbi = EROFS_SB(sb);
if (erofs_is_fscache_mode(sb)) {
if (sbi->domain_id)
super_set_sysfs_name_generic(sb, "%s,%s",sbi->domain_id,
sbi->fsid);
else
super_set_sysfs_name_generic(sb, "%s", sbi->fsid);
return;
}
super_set_sysfs_name_id(sb);
}
static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc) static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc)
{ {
struct inode *inode; struct inode *inode;
...@@ -643,6 +658,7 @@ static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc) ...@@ -643,6 +658,7 @@ static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc)
sb->s_flags |= SB_POSIXACL; sb->s_flags |= SB_POSIXACL;
else else
sb->s_flags &= ~SB_POSIXACL; sb->s_flags &= ~SB_POSIXACL;
erofs_set_sysfs_name(sb);
#ifdef CONFIG_EROFS_FS_ZIP #ifdef CONFIG_EROFS_FS_ZIP
xa_init(&sbi->managed_pslots); xa_init(&sbi->managed_pslots);
......
...@@ -38,11 +38,13 @@ void *z_erofs_get_gbuf(unsigned int requiredpages) ...@@ -38,11 +38,13 @@ void *z_erofs_get_gbuf(unsigned int requiredpages)
{ {
struct z_erofs_gbuf *gbuf; struct z_erofs_gbuf *gbuf;
migrate_disable();
gbuf = &z_erofs_gbufpool[z_erofs_gbuf_id()]; gbuf = &z_erofs_gbufpool[z_erofs_gbuf_id()];
spin_lock(&gbuf->lock); spin_lock(&gbuf->lock);
/* check if the buffer is too small */ /* check if the buffer is too small */
if (requiredpages > gbuf->nrpages) { if (requiredpages > gbuf->nrpages) {
spin_unlock(&gbuf->lock); spin_unlock(&gbuf->lock);
migrate_enable();
/* (for sparse checker) pretend gbuf->lock is still taken */ /* (for sparse checker) pretend gbuf->lock is still taken */
__acquire(gbuf->lock); __acquire(gbuf->lock);
return NULL; return NULL;
...@@ -57,6 +59,7 @@ void z_erofs_put_gbuf(void *ptr) __releases(gbuf->lock) ...@@ -57,6 +59,7 @@ void z_erofs_put_gbuf(void *ptr) __releases(gbuf->lock)
gbuf = &z_erofs_gbufpool[z_erofs_gbuf_id()]; gbuf = &z_erofs_gbufpool[z_erofs_gbuf_id()];
DBG_BUGON(gbuf->ptr != ptr); DBG_BUGON(gbuf->ptr != ptr);
spin_unlock(&gbuf->lock); spin_unlock(&gbuf->lock);
migrate_enable();
} }
int z_erofs_gbuf_growsize(unsigned int nrpages) int z_erofs_gbuf_growsize(unsigned int nrpages)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment