xref: /aosp_15_r20/external/erofs-utils/lib/block_list.c (revision 33b1fccf6a0fada2c2875d400ed01119b7676ee5)
1*33b1fccfSAndroid Build Coastguard Worker // SPDX-License-Identifier: GPL-2.0+ OR Apache-2.0
2*33b1fccfSAndroid Build Coastguard Worker /*
3*33b1fccfSAndroid Build Coastguard Worker  * Copyright (C), 2021, Coolpad Group Limited.
4*33b1fccfSAndroid Build Coastguard Worker  * Created by Yue Hu <[email protected]>
5*33b1fccfSAndroid Build Coastguard Worker  */
6*33b1fccfSAndroid Build Coastguard Worker #include <stdio.h>
7*33b1fccfSAndroid Build Coastguard Worker #include <sys/stat.h>
8*33b1fccfSAndroid Build Coastguard Worker #include "erofs/block_list.h"
9*33b1fccfSAndroid Build Coastguard Worker 
10*33b1fccfSAndroid Build Coastguard Worker #define EROFS_MODNAME	"erofs block_list"
11*33b1fccfSAndroid Build Coastguard Worker #include "erofs/print.h"
12*33b1fccfSAndroid Build Coastguard Worker 
13*33b1fccfSAndroid Build Coastguard Worker static FILE *block_list_fp;
14*33b1fccfSAndroid Build Coastguard Worker bool srcmap_enabled;
15*33b1fccfSAndroid Build Coastguard Worker 
erofs_blocklist_open(FILE * fp,bool srcmap)16*33b1fccfSAndroid Build Coastguard Worker int erofs_blocklist_open(FILE *fp, bool srcmap)
17*33b1fccfSAndroid Build Coastguard Worker {
18*33b1fccfSAndroid Build Coastguard Worker 	if (!fp)
19*33b1fccfSAndroid Build Coastguard Worker 		return -ENOENT;
20*33b1fccfSAndroid Build Coastguard Worker 	block_list_fp = fp;
21*33b1fccfSAndroid Build Coastguard Worker 	srcmap_enabled = srcmap;
22*33b1fccfSAndroid Build Coastguard Worker 	return 0;
23*33b1fccfSAndroid Build Coastguard Worker }
24*33b1fccfSAndroid Build Coastguard Worker 
erofs_blocklist_close(void)25*33b1fccfSAndroid Build Coastguard Worker FILE *erofs_blocklist_close(void)
26*33b1fccfSAndroid Build Coastguard Worker {
27*33b1fccfSAndroid Build Coastguard Worker 	FILE *fp = block_list_fp;
28*33b1fccfSAndroid Build Coastguard Worker 
29*33b1fccfSAndroid Build Coastguard Worker 	block_list_fp = NULL;
30*33b1fccfSAndroid Build Coastguard Worker 	return fp;
31*33b1fccfSAndroid Build Coastguard Worker }
32*33b1fccfSAndroid Build Coastguard Worker 
33*33b1fccfSAndroid Build Coastguard Worker /* XXX: really need to be cleaned up */
tarerofs_blocklist_write(erofs_blk_t blkaddr,erofs_blk_t nblocks,erofs_off_t srcoff)34*33b1fccfSAndroid Build Coastguard Worker void tarerofs_blocklist_write(erofs_blk_t blkaddr, erofs_blk_t nblocks,
35*33b1fccfSAndroid Build Coastguard Worker 			      erofs_off_t srcoff)
36*33b1fccfSAndroid Build Coastguard Worker {
37*33b1fccfSAndroid Build Coastguard Worker 	if (!block_list_fp || !nblocks || !srcmap_enabled)
38*33b1fccfSAndroid Build Coastguard Worker 		return;
39*33b1fccfSAndroid Build Coastguard Worker 
40*33b1fccfSAndroid Build Coastguard Worker 	fprintf(block_list_fp, "%08x %8x %08" PRIx64 "\n",
41*33b1fccfSAndroid Build Coastguard Worker 		blkaddr, nblocks, srcoff);
42*33b1fccfSAndroid Build Coastguard Worker }
43*33b1fccfSAndroid Build Coastguard Worker 
44*33b1fccfSAndroid Build Coastguard Worker #ifdef WITH_ANDROID
blocklist_write(const char * path,erofs_blk_t blk_start,erofs_blk_t nblocks,bool first_extent,bool last_extent)45*33b1fccfSAndroid Build Coastguard Worker static void blocklist_write(const char *path, erofs_blk_t blk_start,
46*33b1fccfSAndroid Build Coastguard Worker 			    erofs_blk_t nblocks, bool first_extent,
47*33b1fccfSAndroid Build Coastguard Worker 			    bool last_extent)
48*33b1fccfSAndroid Build Coastguard Worker {
49*33b1fccfSAndroid Build Coastguard Worker 	const char *fspath = erofs_fspath(path);
50*33b1fccfSAndroid Build Coastguard Worker 
51*33b1fccfSAndroid Build Coastguard Worker 	if (first_extent) {
52*33b1fccfSAndroid Build Coastguard Worker 		fprintf(block_list_fp, "/%s", cfg.mount_point);
53*33b1fccfSAndroid Build Coastguard Worker 
54*33b1fccfSAndroid Build Coastguard Worker 		if (fspath[0] != '/')
55*33b1fccfSAndroid Build Coastguard Worker 			fprintf(block_list_fp, "/");
56*33b1fccfSAndroid Build Coastguard Worker 
57*33b1fccfSAndroid Build Coastguard Worker 		fprintf(block_list_fp, "%s", fspath);
58*33b1fccfSAndroid Build Coastguard Worker 	}
59*33b1fccfSAndroid Build Coastguard Worker 
60*33b1fccfSAndroid Build Coastguard Worker 	if (nblocks == 1)
61*33b1fccfSAndroid Build Coastguard Worker 		fprintf(block_list_fp, " %u", blk_start);
62*33b1fccfSAndroid Build Coastguard Worker 	else
63*33b1fccfSAndroid Build Coastguard Worker 		fprintf(block_list_fp, " %u-%u", blk_start,
64*33b1fccfSAndroid Build Coastguard Worker 			blk_start + nblocks - 1);
65*33b1fccfSAndroid Build Coastguard Worker 
66*33b1fccfSAndroid Build Coastguard Worker 	if (last_extent)
67*33b1fccfSAndroid Build Coastguard Worker 		fprintf(block_list_fp, "\n");
68*33b1fccfSAndroid Build Coastguard Worker }
69*33b1fccfSAndroid Build Coastguard Worker 
erofs_droid_blocklist_write_extent(struct erofs_inode * inode,erofs_blk_t blk_start,erofs_blk_t nblocks,bool first_extent,bool last_extent)70*33b1fccfSAndroid Build Coastguard Worker void erofs_droid_blocklist_write_extent(struct erofs_inode *inode,
71*33b1fccfSAndroid Build Coastguard Worker 					erofs_blk_t blk_start,
72*33b1fccfSAndroid Build Coastguard Worker 					erofs_blk_t nblocks, bool first_extent,
73*33b1fccfSAndroid Build Coastguard Worker 					bool last_extent)
74*33b1fccfSAndroid Build Coastguard Worker {
75*33b1fccfSAndroid Build Coastguard Worker 	if (!block_list_fp || !cfg.mount_point)
76*33b1fccfSAndroid Build Coastguard Worker 		return;
77*33b1fccfSAndroid Build Coastguard Worker 
78*33b1fccfSAndroid Build Coastguard Worker 	if (!nblocks) {
79*33b1fccfSAndroid Build Coastguard Worker 		if (last_extent)
80*33b1fccfSAndroid Build Coastguard Worker 			fprintf(block_list_fp, "\n");
81*33b1fccfSAndroid Build Coastguard Worker 		return;
82*33b1fccfSAndroid Build Coastguard Worker 	}
83*33b1fccfSAndroid Build Coastguard Worker 
84*33b1fccfSAndroid Build Coastguard Worker 	blocklist_write(inode->i_srcpath, blk_start, nblocks, first_extent,
85*33b1fccfSAndroid Build Coastguard Worker 			last_extent);
86*33b1fccfSAndroid Build Coastguard Worker }
87*33b1fccfSAndroid Build Coastguard Worker 
erofs_droid_blocklist_write(struct erofs_inode * inode,erofs_blk_t blk_start,erofs_blk_t nblocks)88*33b1fccfSAndroid Build Coastguard Worker void erofs_droid_blocklist_write(struct erofs_inode *inode,
89*33b1fccfSAndroid Build Coastguard Worker 				 erofs_blk_t blk_start, erofs_blk_t nblocks)
90*33b1fccfSAndroid Build Coastguard Worker {
91*33b1fccfSAndroid Build Coastguard Worker 	if (!block_list_fp || !cfg.mount_point || !nblocks)
92*33b1fccfSAndroid Build Coastguard Worker 		return;
93*33b1fccfSAndroid Build Coastguard Worker 
94*33b1fccfSAndroid Build Coastguard Worker 	blocklist_write(inode->i_srcpath, blk_start, nblocks,
95*33b1fccfSAndroid Build Coastguard Worker 			true, !inode->idata_size);
96*33b1fccfSAndroid Build Coastguard Worker }
97*33b1fccfSAndroid Build Coastguard Worker 
erofs_droid_blocklist_write_tail_end(struct erofs_inode * inode,erofs_blk_t blkaddr)98*33b1fccfSAndroid Build Coastguard Worker void erofs_droid_blocklist_write_tail_end(struct erofs_inode *inode,
99*33b1fccfSAndroid Build Coastguard Worker 					  erofs_blk_t blkaddr)
100*33b1fccfSAndroid Build Coastguard Worker {
101*33b1fccfSAndroid Build Coastguard Worker 	if (!block_list_fp || !cfg.mount_point)
102*33b1fccfSAndroid Build Coastguard Worker 		return;
103*33b1fccfSAndroid Build Coastguard Worker 
104*33b1fccfSAndroid Build Coastguard Worker 	/* XXX: a bit hacky.. may need a better approach */
105*33b1fccfSAndroid Build Coastguard Worker 	if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))
106*33b1fccfSAndroid Build Coastguard Worker 		return;
107*33b1fccfSAndroid Build Coastguard Worker 
108*33b1fccfSAndroid Build Coastguard Worker 	/* XXX: another hack, which means it has been outputed before */
109*33b1fccfSAndroid Build Coastguard Worker 	if (erofs_blknr(inode->sbi, inode->i_size)) {
110*33b1fccfSAndroid Build Coastguard Worker 		if (blkaddr == NULL_ADDR)
111*33b1fccfSAndroid Build Coastguard Worker 			fprintf(block_list_fp, "\n");
112*33b1fccfSAndroid Build Coastguard Worker 		else
113*33b1fccfSAndroid Build Coastguard Worker 			fprintf(block_list_fp, " %u\n", blkaddr);
114*33b1fccfSAndroid Build Coastguard Worker 		return;
115*33b1fccfSAndroid Build Coastguard Worker 	}
116*33b1fccfSAndroid Build Coastguard Worker 	if (blkaddr != NULL_ADDR)
117*33b1fccfSAndroid Build Coastguard Worker 		blocklist_write(inode->i_srcpath, blkaddr, 1, true, true);
118*33b1fccfSAndroid Build Coastguard Worker }
119*33b1fccfSAndroid Build Coastguard Worker #endif
120