2121#include < dirent.h>
2222#include < vector>
2323
24+ struct ErofsFileSystem ::ErofsFileSystemInt {
25+ struct erofs_sb_info sbi;
26+ struct liberofs_file target_file;
27+ };
28+ struct ErofsFile ::ErofsFileInt {
29+ struct erofs_inode inode;
30+ };
31+
2432// ErofsFile
2533ErofsFile::ErofsFile (ErofsFileSystem *fs): fs(fs)
2634{
27- memset (&inode, 0 , sizeof (struct erofs_inode ));
35+ ErofsFileSystem::ErofsFileSystemInt *fs_private = fs->fs_private ;
36+
37+ file_private = new ErofsFileInt;
38+ if (!file_private)
39+ LOG_ERROR (" [erofs_fs] fail to prepare for file_private" );
40+
41+ memset (&file_private->inode , 0 , sizeof (struct erofs_inode ));
42+ file_private->inode .sbi = &fs_private->sbi ;
43+ }
44+
45+ ErofsFile::~ErofsFile () {
46+ delete file_private;
47+ file_private = NULL ;
2848}
49+
2950photon::fs::IFileSystem *ErofsFile::filesystem () { return fs; }
3051
3152struct liberofs_nameidata {
@@ -185,15 +206,16 @@ static int do_erofs_ilookup(const char *path, struct erofs_inode *vi)
185206
186207int ErofsFile::fstat (struct stat *buf)
187208{
188- buf->st_mode = inode.i_mode ;
189- buf->st_nlink = inode.i_nlink ;
190- buf->st_size = inode.i_size ;
191- buf->st_blocks = roundup (inode.i_size , erofs_blksiz (inode.sbi )) >> 9 ;
192- buf->st_uid = inode.i_uid ;
193- buf->st_gid = inode.i_gid ;
194- buf->st_ctime = inode.i_mtime ;
195- buf->st_mtime = inode.i_mtime ;
196- buf->st_atime = inode.i_mtime ;
209+ buf->st_mode = file_private->inode .i_mode ;
210+ buf->st_nlink = file_private->inode .i_nlink ;
211+ buf->st_size = file_private->inode .i_size ;
212+ buf->st_blocks = roundup (file_private->inode .i_size ,
213+ erofs_blksiz (file_private->inode .sbi )) >> 9 ;
214+ buf->st_uid = file_private->inode .i_uid ;
215+ buf->st_gid = file_private->inode .i_gid ;
216+ buf->st_ctime = file_private->inode .i_mtime ;
217+ buf->st_mtime = file_private->inode .i_mtime ;
218+ buf->st_atime = file_private->inode .i_mtime ;
197219 return 0 ;
198220}
199221
@@ -207,8 +229,8 @@ int ErofsFile::fiemap(struct photon::fs::fiemap *map)
207229 erofs_map.index = UINT_MAX;
208230 erofs_map.m_la = 0 ;
209231
210- while (erofs_map.m_la < inode.i_size ) {
211- err = erofs_map_blocks (&inode, &erofs_map, 0 );
232+ while (erofs_map.m_la < file_private-> inode .i_size ) {
233+ err = erofs_map_blocks (&file_private-> inode , &erofs_map, 0 );
212234 if (err)
213235 LOG_ERROR_RETURN (err, err, " [erofs] Fail to map erofs blocks" );
214236 ext_buf[map->fm_mapped_extents ].fe_physical = erofs_map.m_pa ;
@@ -245,38 +267,49 @@ EROFS_UNIMPLEMENTED_FUNC(int, ErofsFileSystem, syncfs(), -EROFS_UNIMPLEMENTED)
245267
246268ErofsFileSystem::ErofsFileSystem(photon::fs::IFile *imgfile, uint64_t blksize)
247269{
248- target_file.ops .pread = erofs_target_pread;
249- target_file.ops .pwrite = erofs_target_pwrite;
250- target_file.ops .pread = erofs_target_pread;
251- target_file.ops .pwrite = erofs_target_pwrite;
252- target_file.ops .fsync = erofs_target_fsync;
253- target_file.ops .fallocate = erofs_target_fallocate;
254- target_file.ops .ftruncate = erofs_target_ftruncate;
255- target_file.ops .read = erofs_target_read;
256- target_file.ops .lseek = erofs_target_lseek;
257- target_file.file = imgfile;
258- target_file.cache = new ErofsCache (target_file.file , 128 );
259-
260- memset (&sbi, 0 , sizeof (struct erofs_sb_info ));
261- sbi.blkszbits = ilog2 (blksize);
262- sbi.bdev .ops = &target_file.ops ;
263- target_file.file ->lseek (0 ,0 );
264- sbi.devsz = INT64_MAX;
265- if (erofs_read_superblock (&sbi))
270+ fs_private = new ErofsFileSystemInt;
271+
272+ if (!fs_private)
273+ LOG_ERROR (" [erofs] Fail to prepare fs_private: no mem." );
274+
275+ // init target_file
276+ fs_private->target_file .ops .pread = erofs_target_pread;
277+ fs_private->target_file .ops .pwrite = erofs_target_pwrite;
278+ fs_private->target_file .ops .pread = erofs_target_pread;
279+ fs_private->target_file .ops .pwrite = erofs_target_pwrite;
280+ fs_private->target_file .ops .fsync = erofs_target_fsync;
281+ fs_private->target_file .ops .fallocate = erofs_target_fallocate;
282+ fs_private->target_file .ops .ftruncate = erofs_target_ftruncate;
283+ fs_private->target_file .ops .read = erofs_target_read;
284+ fs_private->target_file .ops .lseek = erofs_target_lseek;
285+ fs_private->target_file .file = imgfile;
286+ fs_private->target_file .cache = new ErofsCache (imgfile, 128 );
287+ if (!fs_private->target_file .cache )
288+ LOG_ERROR (" [erofs] Fail to prepare target_file.cache: no mem." );
289+
290+ // init sbi
291+ memset (&fs_private->sbi , 0 , sizeof (struct erofs_sb_info ));
292+ fs_private->sbi .blkszbits = ilog2 (blksize);
293+ fs_private->sbi .bdev .ops = &fs_private->target_file .ops ;
294+ fs_private->target_file .file ->lseek (0 ,0 );
295+ fs_private->sbi .devsz = INT64_MAX;
296+ if (erofs_read_superblock (&fs_private->sbi ))
266297 LOG_ERROR (" [erofs] Fail to read_super_block" );
267298}
268299
269300ErofsFileSystem::~ErofsFileSystem ()
270301{
271- delete target_file.cache ;
302+ delete fs_private->target_file .cache ;
303+ delete fs_private;
304+ fs_private = NULL ;
272305}
273306
274307int ErofsFileSystem::stat (const char *path, struct stat *buf)
275308{
276309 struct erofs_inode vi;
277310 int err;
278311
279- vi.sbi = &sbi;
312+ vi.sbi = &fs_private-> sbi ;
280313 err = do_erofs_ilookup (path, &vi);
281314 if (err)
282315 LOG_ERRNO_RETURN (err, err, " [erofs] Fail to lookup inode" );
@@ -297,8 +330,7 @@ photon::fs::IFile* ErofsFileSystem::open(const char *pathname, int flags)
297330 ErofsFile *file = new ErofsFile (this );
298331 int err;
299332
300- file->inode .sbi = &sbi;
301- err = do_erofs_ilookup (pathname, &file->inode );
333+ err = do_erofs_ilookup (pathname, &file->file_private ->inode );
302334 if (err) {
303335 delete file;
304336 LOG_ERROR_RETURN (-err, nullptr , " [erofs] Fail to lookup inode by path" );
@@ -354,7 +386,7 @@ photon::fs::DIR* ErofsFileSystem::opendir(const char *name)
354386{
355387 std::vector<::dirent> dirs;
356388
357- auto ret = do_erofs_readdir (&sbi, name, &dirs);
389+ auto ret = do_erofs_readdir (&fs_private-> sbi , name, &dirs);
358390 if (ret) {
359391 errno = -ret;
360392 return nullptr ;
0 commit comments