From 3fc469968284310acec1256a5285fba4b71ac026 Mon Sep 17 00:00:00 2001 From: Adrien Schildknecht Date: Wed, 23 Nov 2016 13:02:16 -0800 Subject: [PATCH] AOSP: libext2fs: add context to get_alloc_block This patch add some contexts to the allocator about the block that is about to be allocated. The custom Android block allocator need a way to differentiate data block and metadata block. Test: cd external/e2fsprogs/lib && mma Change-Id: I2899936a3a0043d26e062bf1e542483e9a6ac98f From AOSP commit: 127a599529a0c31d8e3bc4da82a5debd670254b6 Signed-off-by: Theodore Ts'o --- lib/ext2fs/alloc.c | 59 +++++++++++++++++++++++++++++++++------------ lib/ext2fs/bmap.c | 36 ++++++++++++++++++++++----- lib/ext2fs/ext2fs.h | 21 ++++++++++++++++ 3 files changed, 94 insertions(+), 22 deletions(-) diff --git a/lib/ext2fs/alloc.c b/lib/ext2fs/alloc.c index f96ac4bf8..af2141068 100644 --- a/lib/ext2fs/alloc.c +++ b/lib/ext2fs/alloc.c @@ -144,27 +144,38 @@ errcode_t ext2fs_new_inode(ext2_filsys fs, ext2_ino_t dir, * Stupid algorithm --- we now just search forward starting from the * goal. Should put in a smarter one someday.... */ -errcode_t ext2fs_new_block2(ext2_filsys fs, blk64_t goal, - ext2fs_block_bitmap map, blk64_t *ret) +errcode_t ext2fs_new_block3(ext2_filsys fs, blk64_t goal, + ext2fs_block_bitmap map, blk64_t *ret, + struct blk_alloc_ctx *ctx) { errcode_t retval; blk64_t b = 0; errcode_t (*gab)(ext2_filsys fs, blk64_t goal, blk64_t *ret); + errcode_t (*gab2)(ext2_filsys, blk64_t, blk64_t *, + struct blk_alloc_ctx *); EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); - if (!map && fs->get_alloc_block) { + if (!map) { /* * In case there are clients out there whose get_alloc_block * handlers call ext2fs_new_block2 with a NULL block map, * temporarily swap out the function pointer so that we don't * end up in an infinite loop. */ - gab = fs->get_alloc_block; - fs->get_alloc_block = NULL; - retval = gab(fs, goal, &b); - fs->get_alloc_block = gab; - goto allocated; + if (fs->get_alloc_block2) { + gab2 = fs->get_alloc_block2; + fs->get_alloc_block2 = NULL; + retval = gab2(fs, goal, &b, ctx); + fs->get_alloc_block2 = gab2; + goto allocated; + } else if (fs->get_alloc_block) { + gab = fs->get_alloc_block; + fs->get_alloc_block = NULL; + retval = gab(fs, goal, &b); + fs->get_alloc_block = gab; + goto allocated; + } } if (!map) map = fs->block_map; @@ -190,6 +201,12 @@ allocated: return 0; } +errcode_t ext2fs_new_block2(ext2_filsys fs, blk64_t goal, + ext2fs_block_bitmap map, blk64_t *ret) +{ + return ext2fs_new_block3(fs, goal, map, ret, NULL); +} + errcode_t ext2fs_new_block(ext2_filsys fs, blk_t goal, ext2fs_block_bitmap map, blk_t *ret) { @@ -205,13 +222,17 @@ errcode_t ext2fs_new_block(ext2_filsys fs, blk_t goal, * This function zeros out the allocated block, and updates all of the * appropriate filesystem records. */ -errcode_t ext2fs_alloc_block2(ext2_filsys fs, blk64_t goal, - char *block_buf, blk64_t *ret) +errcode_t ext2fs_alloc_block3(ext2_filsys fs, blk64_t goal, char *block_buf, + blk64_t *ret, struct blk_alloc_ctx *ctx) { errcode_t retval; blk64_t block; - if (fs->get_alloc_block) { + if (fs->get_alloc_block2) { + retval = (fs->get_alloc_block2)(fs, goal, &block, ctx); + if (retval) + goto fail; + } else if (fs->get_alloc_block) { retval = (fs->get_alloc_block)(fs, goal, &block); if (retval) goto fail; @@ -222,7 +243,7 @@ errcode_t ext2fs_alloc_block2(ext2_filsys fs, blk64_t goal, goto fail; } - retval = ext2fs_new_block2(fs, goal, 0, &block); + retval = ext2fs_new_block3(fs, goal, 0, &block, ctx); if (retval) goto fail; } @@ -242,15 +263,21 @@ fail: return retval; } +errcode_t ext2fs_alloc_block2(ext2_filsys fs, blk64_t goal, + char *block_buf, blk64_t *ret) +{ + return ext2fs_alloc_block3(fs, goal, block_buf, ret, NULL); +} + errcode_t ext2fs_alloc_block(ext2_filsys fs, blk_t goal, char *block_buf, blk_t *ret) { errcode_t retval; - blk64_t val; - retval = ext2fs_alloc_block2(fs, goal, block_buf, &val); + blk64_t ret64, goal64 = goal; + retval = ext2fs_alloc_block3(fs, goal64, block_buf, &ret64, NULL); if (!retval) - *ret = (blk_t) val; - return retval; + *ret = (blk_t)ret64; + return retval; } errcode_t ext2fs_get_free_blocks2(ext2_filsys fs, blk64_t start, blk64_t finish, diff --git a/lib/ext2fs/bmap.c b/lib/ext2fs/bmap.c index 29da4ef5f..1ed98aa43 100644 --- a/lib/ext2fs/bmap.c +++ b/lib/ext2fs/bmap.c @@ -207,6 +207,7 @@ static errcode_t extent_bmap(ext2_filsys fs, ext2_ino_t ino, int *ret_flags, int *blocks_alloc, blk64_t *phys_blk) { + struct blk_alloc_ctx alloc_ctx; struct ext2fs_extent extent; unsigned int offset; errcode_t retval = 0; @@ -246,8 +247,12 @@ got_block: 0, block-1, 0, blocks_alloc, &blk64); if (retval) blk64 = ext2fs_find_inode_goal(fs, ino, inode, block); - retval = ext2fs_alloc_block2(fs, blk64, block_buf, - &blk64); + alloc_ctx.ino = ino; + alloc_ctx.inode = inode; + alloc_ctx.lblk = extent.e_lblk; + alloc_ctx.flags = BLOCK_ALLOC_DATA; + retval = ext2fs_alloc_block3(fs, blk64, block_buf, &blk64, + &alloc_ctx); if (retval) return retval; blk64 &= ~EXT2FS_CLUSTER_MASK(fs); @@ -300,9 +305,16 @@ errcode_t ext2fs_bmap2(ext2_filsys fs, ext2_ino_t ino, struct ext2_inode *inode, ext2_extent_handle_t handle = 0; blk_t addr_per_block; blk_t b, blk32; + blk64_t b64; char *buf = 0; errcode_t retval = 0; int blocks_alloc = 0, inode_dirty = 0; + struct blk_alloc_ctx alloc_ctx = { + .ino = ino, + .inode = inode, + .lblk = 0, + .flags = BLOCK_ALLOC_DATA, + }; if (!(bmap_flags & BMAP_SET)) *phys_blk = 0; @@ -359,7 +371,10 @@ errcode_t ext2fs_bmap2(ext2_filsys fs, ext2_ino_t ino, struct ext2_inode *inode, ext2fs_find_inode_goal(fs, ino, inode, block); if ((*phys_blk == 0) && (bmap_flags & BMAP_ALLOC)) { - retval = ext2fs_alloc_block(fs, b, block_buf, &b); + b64 = b; + retval = ext2fs_alloc_block3(fs, b64, block_buf, &b64, + &alloc_ctx); + b = b64; if (retval) goto done; inode_bmap(inode, block) = b; @@ -382,7 +397,10 @@ errcode_t ext2fs_bmap2(ext2_filsys fs, ext2_ino_t ino, struct ext2_inode *inode, } b = inode_bmap(inode, EXT2_IND_BLOCK-1); - retval = ext2fs_alloc_block(fs, b, block_buf, &b); + b64 = b; + retval = ext2fs_alloc_block3(fs, b64, block_buf, &b64, + &alloc_ctx); + b = b64; if (retval) goto done; inode_bmap(inode, EXT2_IND_BLOCK) = b; @@ -407,7 +425,10 @@ errcode_t ext2fs_bmap2(ext2_filsys fs, ext2_ino_t ino, struct ext2_inode *inode, } b = inode_bmap(inode, EXT2_IND_BLOCK); - retval = ext2fs_alloc_block(fs, b, block_buf, &b); + b64 = b; + retval = ext2fs_alloc_block3(fs, b64, block_buf, &b64, + &alloc_ctx); + b = b64; if (retval) goto done; inode_bmap(inode, EXT2_DIND_BLOCK) = b; @@ -431,7 +452,10 @@ errcode_t ext2fs_bmap2(ext2_filsys fs, ext2_ino_t ino, struct ext2_inode *inode, } b = inode_bmap(inode, EXT2_DIND_BLOCK); - retval = ext2fs_alloc_block(fs, b, block_buf, &b); + b64 = b; + retval = ext2fs_alloc_block3(fs, b64, block_buf, &b64, + &alloc_ctx); + b = b64; if (retval) goto done; inode_bmap(inode, EXT2_TIND_BLOCK) = b; diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h index 3f4fe1369..c18ea5f82 100644 --- a/lib/ext2fs/ext2fs.h +++ b/lib/ext2fs/ext2fs.h @@ -209,6 +209,7 @@ typedef struct ext2_file *ext2_file_t; #define EXT2_MKJOURNAL_LAZYINIT 0x0000002 /* don't zero journal inode before use*/ #define EXT2_MKJOURNAL_NO_MNT_CHECK 0x0000004 /* don't check mount status */ +struct blk_alloc_ctx; struct opaque_ext2_group_desc; struct struct_ext2_filsys { @@ -264,6 +265,8 @@ struct struct_ext2_filsys { */ errcode_t (*get_alloc_block)(ext2_filsys fs, blk64_t goal, blk64_t *ret); + errcode_t (*get_alloc_block2)(ext2_filsys fs, blk64_t goal, + blk64_t *ret, struct blk_alloc_ctx *ctx); void (*block_alloc_stats)(ext2_filsys fs, blk64_t blk, int inuse); /* @@ -355,6 +358,17 @@ struct struct_ext2_filsys { #define BLOCK_COUNT_TIND (-3) #define BLOCK_COUNT_TRANSLATOR (-4) +#define BLOCK_ALLOC_UNKNOWN 0 +#define BLOCK_ALLOC_DATA 1 +#define BLOCK_ALLOC_METADATA 2 + +struct blk_alloc_ctx { + ext2_ino_t ino; + struct ext2_inode *inode; + blk64_t lblk; + int flags; +}; + #if 0 /* * Flags for ext2fs_move_blocks @@ -663,6 +677,9 @@ extern errcode_t ext2fs_new_block(ext2_filsys fs, blk_t goal, ext2fs_block_bitmap map, blk_t *ret); extern errcode_t ext2fs_new_block2(ext2_filsys fs, blk64_t goal, ext2fs_block_bitmap map, blk64_t *ret); +extern errcode_t ext2fs_new_block3(ext2_filsys fs, blk64_t goal, + ext2fs_block_bitmap map, blk64_t *ret, + struct blk_alloc_ctx *ctx); extern errcode_t ext2fs_get_free_blocks(ext2_filsys fs, blk_t start, blk_t finish, int num, ext2fs_block_bitmap map, @@ -675,6 +692,10 @@ extern errcode_t ext2fs_alloc_block(ext2_filsys fs, blk_t goal, char *block_buf, blk_t *ret); extern errcode_t ext2fs_alloc_block2(ext2_filsys fs, blk64_t goal, char *block_buf, blk64_t *ret); +extern errcode_t ext2fs_alloc_block3(ext2_filsys fs, blk64_t goal, + char *block_buf, blk64_t *ret, + struct blk_alloc_ctx *ctx); + extern void ext2fs_set_alloc_block_callback(ext2_filsys fs, errcode_t (*func)(ext2_filsys fs, blk64_t goal, -- 2.47.2