@@ -70,58 +70,39 @@ void *erofs_read_metabuf(struct erofs_buf *buf, struct super_block *sb,
7070 return erofs_bread (buf , offset , need_kmap );
7171}
7272
73- static int erofs_map_blocks_flatmode (struct inode * inode ,
74- struct erofs_map_blocks * map )
75- {
76- struct erofs_inode * vi = EROFS_I (inode );
77- struct super_block * sb = inode -> i_sb ;
78- bool tailendpacking = (vi -> datalayout == EROFS_INODE_FLAT_INLINE );
79- erofs_blk_t lastblk = erofs_iblks (inode ) - tailendpacking ;
80-
81- map -> m_flags = EROFS_MAP_MAPPED ; /* no hole in flat inodes */
82- if (map -> m_la < erofs_pos (sb , lastblk )) {
83- map -> m_pa = erofs_pos (sb , vi -> raw_blkaddr ) + map -> m_la ;
84- map -> m_plen = erofs_pos (sb , lastblk ) - map -> m_la ;
85- } else {
86- DBG_BUGON (!tailendpacking );
87- map -> m_pa = erofs_iloc (inode ) + vi -> inode_isize +
88- vi -> xattr_isize + erofs_blkoff (sb , map -> m_la );
89- map -> m_plen = inode -> i_size - map -> m_la ;
90-
91- /* inline data should be located in the same meta block */
92- if (erofs_blkoff (sb , map -> m_pa ) + map -> m_plen > sb -> s_blocksize ) {
93- erofs_err (sb , "inline data across blocks @ nid %llu" , vi -> nid );
94- DBG_BUGON (1 );
95- return - EFSCORRUPTED ;
96- }
97- map -> m_flags |= EROFS_MAP_META ;
98- }
99- return 0 ;
100- }
101-
10273int erofs_map_blocks (struct inode * inode , struct erofs_map_blocks * map )
10374{
75+ struct erofs_buf buf = __EROFS_BUF_INITIALIZER ;
10476 struct super_block * sb = inode -> i_sb ;
77+ unsigned int unit , blksz = sb -> s_blocksize ;
10578 struct erofs_inode * vi = EROFS_I (inode );
10679 struct erofs_inode_chunk_index * idx ;
107- struct erofs_buf buf = __EROFS_BUF_INITIALIZER ;
108- u64 chunknr ;
109- unsigned int unit ;
80+ erofs_blk_t startblk ;
81+ bool tailpacking ;
11082 erofs_off_t pos ;
111- void * kaddr ;
83+ u64 chunknr ;
11284 int err = 0 ;
11385
11486 trace_erofs_map_blocks_enter (inode , map , 0 );
11587 map -> m_deviceid = 0 ;
116- if (map -> m_la >= inode -> i_size ) {
117- /* leave out-of-bound access unmapped */
118- map -> m_flags = 0 ;
119- map -> m_plen = map -> m_llen ;
88+ map -> m_flags = 0 ;
89+ if (map -> m_la >= inode -> i_size )
12090 goto out ;
121- }
12291
12392 if (vi -> datalayout != EROFS_INODE_CHUNK_BASED ) {
124- err = erofs_map_blocks_flatmode (inode , map );
93+ tailpacking = (vi -> datalayout == EROFS_INODE_FLAT_INLINE );
94+ pos = erofs_pos (sb , erofs_iblks (inode ) - tailpacking );
95+
96+ map -> m_flags = EROFS_MAP_MAPPED ;
97+ if (map -> m_la < pos ) {
98+ map -> m_pa = erofs_pos (sb , vi -> raw_blkaddr ) + map -> m_la ;
99+ map -> m_llen = pos - map -> m_la ;
100+ } else {
101+ map -> m_pa = erofs_iloc (inode ) + vi -> inode_isize +
102+ vi -> xattr_isize + erofs_blkoff (sb , map -> m_la );
103+ map -> m_llen = inode -> i_size - map -> m_la ;
104+ map -> m_flags |= EROFS_MAP_META ;
105+ }
125106 goto out ;
126107 }
127108
@@ -134,45 +115,41 @@ int erofs_map_blocks(struct inode *inode, struct erofs_map_blocks *map)
134115 pos = ALIGN (erofs_iloc (inode ) + vi -> inode_isize +
135116 vi -> xattr_isize , unit ) + unit * chunknr ;
136117
137- kaddr = erofs_read_metabuf (& buf , sb , pos , true);
138- if (IS_ERR (kaddr )) {
139- err = PTR_ERR (kaddr );
118+ idx = erofs_read_metabuf (& buf , sb , pos , true);
119+ if (IS_ERR (idx )) {
120+ err = PTR_ERR (idx );
140121 goto out ;
141122 }
142123 map -> m_la = chunknr << vi -> chunkbits ;
143- map -> m_plen = min_t (erofs_off_t , 1UL << vi -> chunkbits ,
144- round_up (inode -> i_size - map -> m_la , sb -> s_blocksize ));
145-
146- /* handle block map */
147- if (!(vi -> chunkformat & EROFS_CHUNK_FORMAT_INDEXES )) {
148- __le32 * blkaddr = kaddr ;
149-
150- if (le32_to_cpu (* blkaddr ) == EROFS_NULL_ADDR ) {
151- map -> m_flags = 0 ;
152- } else {
153- map -> m_pa = erofs_pos (sb , le32_to_cpu (* blkaddr ));
124+ map -> m_llen = min_t (erofs_off_t , 1UL << vi -> chunkbits ,
125+ round_up (inode -> i_size - map -> m_la , blksz ));
126+ if (vi -> chunkformat & EROFS_CHUNK_FORMAT_INDEXES ) {
127+ startblk = le32_to_cpu (idx -> blkaddr );
128+ if (startblk != EROFS_NULL_ADDR ) {
129+ map -> m_deviceid = le16_to_cpu (idx -> device_id ) &
130+ EROFS_SB (sb )-> device_id_mask ;
131+ map -> m_pa = erofs_pos (sb , startblk );
132+ map -> m_flags = EROFS_MAP_MAPPED ;
133+ }
134+ } else {
135+ startblk = le32_to_cpu (* (__le32 * )idx );
136+ if (startblk != EROFS_NULL_ADDR ) {
137+ map -> m_pa = erofs_pos (sb , startblk );
154138 map -> m_flags = EROFS_MAP_MAPPED ;
155139 }
156- goto out_unlock ;
157- }
158- /* parse chunk indexes */
159- idx = kaddr ;
160- switch (le32_to_cpu (idx -> blkaddr )) {
161- case EROFS_NULL_ADDR :
162- map -> m_flags = 0 ;
163- break ;
164- default :
165- map -> m_deviceid = le16_to_cpu (idx -> device_id ) &
166- EROFS_SB (sb )-> device_id_mask ;
167- map -> m_pa = erofs_pos (sb , le32_to_cpu (idx -> blkaddr ));
168- map -> m_flags = EROFS_MAP_MAPPED ;
169- break ;
170140 }
171- out_unlock :
172141 erofs_put_metabuf (& buf );
173142out :
174- if (!err )
175- map -> m_llen = map -> m_plen ;
143+ if (!err ) {
144+ map -> m_plen = map -> m_llen ;
145+ /* inline data should be located in the same meta block */
146+ if ((map -> m_flags & EROFS_MAP_META ) &&
147+ erofs_blkoff (sb , map -> m_pa ) + map -> m_plen > blksz ) {
148+ erofs_err (sb , "inline data across blocks @ nid %llu" , vi -> nid );
149+ DBG_BUGON (1 );
150+ return - EFSCORRUPTED ;
151+ }
152+ }
176153 trace_erofs_map_blocks_exit (inode , map , 0 , err );
177154 return err ;
178155}
0 commit comments