On 7/29/23 9:32 PM, Gao Xiang wrote:
> -int erofs_blob_remap(struct erofs_sb_info *sbi)
> +int tarerofs_write_chunk_data(struct erofs_inode *inode, erofs_off_t 
> data_offset)
> +{
> +     struct erofs_sb_info *sbi = inode->sbi;
> +     unsigned int chunkbits = ilog2(inode->i_size - 1) + 1;
> +     unsigned int count, unit, device_id;
> +     erofs_off_t chunksize, len, pos;
> +     erofs_blk_t blkaddr;
> +     struct erofs_inode_chunk_index *idx;
> +
> +     if (chunkbits < sbi->blkszbits)
> +             chunkbits = sbi->blkszbits;
> +     if (chunkbits - sbi->blkszbits > EROFS_CHUNK_FORMAT_BLKBITS_MASK)
> +             chunkbits = EROFS_CHUNK_FORMAT_BLKBITS_MASK + sbi->blkszbits;
> +
> +     inode->u.chunkformat |= chunkbits - sbi->blkszbits;
> +     if (sbi->extra_devices) {
> +             device_id = 1;
> +             inode->u.chunkformat |= EROFS_CHUNK_FORMAT_INDEXES;
> +             unit = sizeof(struct erofs_inode_chunk_index);
> +             DBG_BUGON(erofs_blkoff(sbi, data_offset));
> +             blkaddr = erofs_blknr(sbi, data_offset);
> +     } else {
> +             device_id = 0;
> +             unit = EROFS_BLOCK_MAP_ENTRY_SIZE;
> +             DBG_BUGON(erofs_blkoff(sbi, datablob_size));
> +             blkaddr = erofs_blknr(sbi, datablob_size);
> +             datablob_size += round_up(inode->i_size, erofs_blksiz(sbi));
> +     }
> +     chunksize = 1ULL << chunkbits;
> +     count = DIV_ROUND_UP(inode->i_size, chunksize);
> +
> +     inode->extent_isize = count * unit;
> +     idx = calloc(count, max(sizeof(*idx), sizeof(void *)));
> +     if (!idx)
> +             return -ENOMEM;
> +     inode->chunkindexes = idx;
> +
> +     for (pos = 0; pos < inode->i_size; pos += len) {
> +             struct erofs_blobchunk *chunk;
> +
> +             len = min_t(erofs_off_t, inode->i_size - pos, chunksize);
> +
> +             chunk = erofs_get_unhashed_chunk(device_id, blkaddr,
> +                                              data_offset);
> +             if (IS_ERR(chunk))
> +                     return PTR_ERR(chunk);

inode->chunkindexes needs to be freed on error path.

> +
> +             *(void **)idx++ = chunk;
> +             blkaddr += erofs_blknr(sbi, len);
> +             data_offset += len;
> +     }
> +     inode->datalayout = EROFS_INODE_CHUNK_BASED;
> +     return 0;
> +}
> +


-- 
Thanks,
Jingbo

Reply via email to