@@ -49,11 +49,18 @@ void *erofs_bread(struct erofs_buf *buf, erofs_off_t offset, bool need_kmap)
4949 return buf -> base + (offset & ~PAGE_MASK );
5050}
5151
52- void erofs_init_metabuf (struct erofs_buf * buf , struct super_block * sb )
52+ int erofs_init_metabuf (struct erofs_buf * buf , struct super_block * sb ,
53+ bool in_metabox )
5354{
5455 struct erofs_sb_info * sbi = EROFS_SB (sb );
5556
5657 buf -> file = NULL ;
58+ if (in_metabox ) {
59+ if (unlikely (!sbi -> metabox_inode ))
60+ return - EFSCORRUPTED ;
61+ buf -> mapping = sbi -> metabox_inode -> i_mapping ;
62+ return 0 ;
63+ }
5764 buf -> off = sbi -> dif0 .fsoff ;
5865 if (erofs_is_fileio_mode (sbi )) {
5966 buf -> file = sbi -> dif0 .file ; /* some fs like FUSE needs it */
@@ -62,12 +69,17 @@ void erofs_init_metabuf(struct erofs_buf *buf, struct super_block *sb)
6269 buf -> mapping = sbi -> dif0 .fscache -> inode -> i_mapping ;
6370 else
6471 buf -> mapping = sb -> s_bdev -> bd_mapping ;
72+ return 0 ;
6573}
6674
6775void * erofs_read_metabuf (struct erofs_buf * buf , struct super_block * sb ,
68- erofs_off_t offset )
76+ erofs_off_t offset , bool in_metabox )
6977{
70- erofs_init_metabuf (buf , sb );
78+ int err ;
79+
80+ err = erofs_init_metabuf (buf , sb , in_metabox );
81+ if (err )
82+ return ERR_PTR (err );
7183 return erofs_bread (buf , offset , true);
7284}
7385
@@ -118,7 +130,7 @@ int erofs_map_blocks(struct inode *inode, struct erofs_map_blocks *map)
118130 pos = ALIGN (erofs_iloc (inode ) + vi -> inode_isize +
119131 vi -> xattr_isize , unit ) + unit * chunknr ;
120132
121- idx = erofs_read_metabuf (& buf , sb , pos );
133+ idx = erofs_read_metabuf (& buf , sb , pos , erofs_inode_in_metabox ( inode ) );
122134 if (IS_ERR (idx )) {
123135 err = PTR_ERR (idx );
124136 goto out ;
@@ -264,7 +276,6 @@ static int erofs_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
264276
265277 map .m_la = offset ;
266278 map .m_llen = length ;
267-
268279 ret = erofs_map_blocks (inode , & map );
269280 if (ret < 0 )
270281 return ret ;
@@ -273,35 +284,37 @@ static int erofs_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
273284 iomap -> length = map .m_llen ;
274285 iomap -> flags = 0 ;
275286 iomap -> private = NULL ;
287+ iomap -> addr = IOMAP_NULL_ADDR ;
276288 if (!(map .m_flags & EROFS_MAP_MAPPED )) {
277289 iomap -> type = IOMAP_HOLE ;
278- iomap -> addr = IOMAP_NULL_ADDR ;
279290 return 0 ;
280291 }
281292
282- mdev = (struct erofs_map_dev ) {
283- .m_deviceid = map .m_deviceid ,
284- .m_pa = map .m_pa ,
285- };
286- ret = erofs_map_dev (sb , & mdev );
287- if (ret )
288- return ret ;
289-
290- if (flags & IOMAP_DAX )
291- iomap -> dax_dev = mdev .m_dif -> dax_dev ;
292- else
293- iomap -> bdev = mdev .m_bdev ;
294-
295- iomap -> addr = mdev .m_dif -> fsoff + mdev .m_pa ;
296- if (flags & IOMAP_DAX )
297- iomap -> addr += mdev .m_dif -> dax_part_off ;
293+ if (!(map .m_flags & EROFS_MAP_META ) || !erofs_inode_in_metabox (inode )) {
294+ mdev = (struct erofs_map_dev ) {
295+ .m_deviceid = map .m_deviceid ,
296+ .m_pa = map .m_pa ,
297+ };
298+ ret = erofs_map_dev (sb , & mdev );
299+ if (ret )
300+ return ret ;
301+
302+ if (flags & IOMAP_DAX )
303+ iomap -> dax_dev = mdev .m_dif -> dax_dev ;
304+ else
305+ iomap -> bdev = mdev .m_bdev ;
306+ iomap -> addr = mdev .m_dif -> fsoff + mdev .m_pa ;
307+ if (flags & IOMAP_DAX )
308+ iomap -> addr += mdev .m_dif -> dax_part_off ;
309+ }
298310
299311 if (map .m_flags & EROFS_MAP_META ) {
300312 void * ptr ;
301313 struct erofs_buf buf = __EROFS_BUF_INITIALIZER ;
302314
303315 iomap -> type = IOMAP_INLINE ;
304- ptr = erofs_read_metabuf (& buf , sb , mdev .m_pa );
316+ ptr = erofs_read_metabuf (& buf , sb , map .m_pa ,
317+ erofs_inode_in_metabox (inode ));
305318 if (IS_ERR (ptr ))
306319 return PTR_ERR (ptr );
307320 iomap -> inline_data = ptr ;
0 commit comments