Re: [PATCH v2] erofs: use kmap_local_page() only for erofs_bread()

From: Fabio M. De Francesco
Date: Tue Oct 18 2022 - 12:28:41 EST


On Tuesday, October 18, 2022 12:53:13 PM CEST Gao Xiang wrote:
> Convert all mapped erofs_bread() users to use kmap_local_page()
> instead of kmap() or kmap_atomic().
>
> Signed-off-by: Gao Xiang <hsiangkao@xxxxxxxxxxxxxxxxx>
> ---
> fs/erofs/data.c | 8 ++------
> fs/erofs/internal.h | 3 +--
> fs/erofs/xattr.c | 8 ++++----
> fs/erofs/zmap.c | 4 ++--
> 4 files changed, 9 insertions(+), 14 deletions(-)
>
> diff --git a/fs/erofs/data.c b/fs/erofs/data.c
> index fe8ac0e163f7..fe1ae80284bf 100644
> --- a/fs/erofs/data.c
> +++ b/fs/erofs/data.c
> @@ -13,9 +13,7 @@
> void erofs_unmap_metabuf(struct erofs_buf *buf)
> {
> if (buf->kmap_type == EROFS_KMAP)
> - kunmap(buf->page);
> - else if (buf->kmap_type == EROFS_KMAP_ATOMIC)
> - kunmap_atomic(buf->base);
> + kunmap_local(buf->base);
> buf->base = NULL;
> buf->kmap_type = EROFS_NO_KMAP;
> }
> @@ -54,9 +52,7 @@ void *erofs_bread(struct erofs_buf *buf, struct inode
*inode,
> }
> if (buf->kmap_type == EROFS_NO_KMAP) {
> if (type == EROFS_KMAP)
> - buf->base = kmap(page);
> - else if (type == EROFS_KMAP_ATOMIC)
> - buf->base = kmap_atomic(page);
> + buf->base = kmap_local_page(page);
> buf->kmap_type = type;
> } else if (buf->kmap_type != type) {
> DBG_BUGON(1);
> diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h
> index 1701df48c446..67dc8e177211 100644
> --- a/fs/erofs/internal.h
> +++ b/fs/erofs/internal.h
> @@ -253,8 +253,7 @@ static inline int erofs_wait_on_workgroup_freezed(struct
erofs_workgroup *grp)
>
> enum erofs_kmap_type {
> EROFS_NO_KMAP, /* don't map the buffer */
> - EROFS_KMAP, /* use kmap() to map the buffer */
> - EROFS_KMAP_ATOMIC, /* use kmap_atomic() to map the buffer */
> + EROFS_KMAP, /* use kmap_local_page() to map the
buffer */
> };
>
> struct erofs_buf {
> diff --git a/fs/erofs/xattr.c b/fs/erofs/xattr.c
> index 8106bcb5a38d..a62fb8a3318a 100644
> --- a/fs/erofs/xattr.c
> +++ b/fs/erofs/xattr.c
> @@ -148,7 +148,7 @@ static inline int xattr_iter_fixup(struct xattr_iter *it)
>
> it->blkaddr += erofs_blknr(it->ofs);
> it->kaddr = erofs_read_metabuf(&it->buf, it->sb, it->blkaddr,
> - EROFS_KMAP_ATOMIC);
> + EROFS_KMAP);
> if (IS_ERR(it->kaddr))
> return PTR_ERR(it->kaddr);
> it->ofs = erofs_blkoff(it->ofs);
> @@ -174,7 +174,7 @@ static int inline_xattr_iter_begin(struct xattr_iter
*it,
> it->ofs = erofs_blkoff(iloc(sbi, vi->nid) + inline_xattr_ofs);
>
> it->kaddr = erofs_read_metabuf(&it->buf, inode->i_sb, it->blkaddr,
> - EROFS_KMAP_ATOMIC);
> + EROFS_KMAP);
> if (IS_ERR(it->kaddr))
> return PTR_ERR(it->kaddr);
> return vi->xattr_isize - xattr_header_sz;
> @@ -368,7 +368,7 @@ static int shared_getxattr(struct inode *inode, struct
getxattr_iter *it)
>
> it->it.ofs = xattrblock_offset(sbi, vi-
>xattr_shared_xattrs[i]);
> it->it.kaddr = erofs_read_metabuf(&it->it.buf, sb,
blkaddr,
> -
EROFS_KMAP_ATOMIC);
> +
EROFS_KMAP);
> if (IS_ERR(it->it.kaddr))
> return PTR_ERR(it->it.kaddr);
> it->it.blkaddr = blkaddr;
> @@ -580,7 +580,7 @@ static int shared_listxattr(struct listxattr_iter *it)
>
> it->it.ofs = xattrblock_offset(sbi, vi-
>xattr_shared_xattrs[i]);
> it->it.kaddr = erofs_read_metabuf(&it->it.buf, sb,
blkaddr,
> -
EROFS_KMAP_ATOMIC);
> +
EROFS_KMAP);
> if (IS_ERR(it->it.kaddr))
> return PTR_ERR(it->it.kaddr);
> it->it.blkaddr = blkaddr;
> diff --git a/fs/erofs/zmap.c b/fs/erofs/zmap.c
> index 0bb66927e3d0..749a5ac943f4 100644
> --- a/fs/erofs/zmap.c
> +++ b/fs/erofs/zmap.c
> @@ -178,7 +178,7 @@ static int legacy_load_cluster_from_disk(struct
z_erofs_maprecorder *m,
> unsigned int advise, type;
>
> m->kaddr = erofs_read_metabuf(&m->map->buf, inode->i_sb,
> - erofs_blknr(pos),
EROFS_KMAP_ATOMIC);
> + erofs_blknr(pos),
EROFS_KMAP);
> if (IS_ERR(m->kaddr))
> return PTR_ERR(m->kaddr);
>
> @@ -416,7 +416,7 @@ static int compacted_load_cluster_from_disk(struct
z_erofs_maprecorder *m,
> out:
> pos += lcn * (1 << amortizedshift);
> m->kaddr = erofs_read_metabuf(&m->map->buf, inode->i_sb,
> - erofs_blknr(pos),
EROFS_KMAP_ATOMIC);
> + erofs_blknr(pos),
EROFS_KMAP);
> if (IS_ERR(m->kaddr))
> return PTR_ERR(m->kaddr);
> return unpack_compacted_index(m, amortizedshift, pos, lookahead);
> --
> 2.24.4
>
>
Can you please say whether or not you ran some tests on a 32 bits machine,
possibly QEMU/KVM x86_32 with enough RAM (I'd suggest 6GB), booting a kernel
with HIGHMEM4G or HIGHMEM64G enabled?

Did you check whether or not the pointers are handed to other contexts?

You didn't say anything about the safety of these conversions. And you also
didn't say why you did them (I don't care but many might ignore why).

Therefore, can you please say at least how you checked that these conversions
are safe so that they won't break the filesystem in 32bit machines?

Thanks,

Fabio M. De Francesco