diff options
22 files changed, 4776 insertions, 10 deletions
diff --git a/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0001-Fix-warnings-remove-some-unused-macros.patch b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0001-Fix-warnings-remove-some-unused-macros.patch new file mode 100644 index 0000000000..f981b449ba --- /dev/null +++ b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0001-Fix-warnings-remove-some-unused-macros.patch | |||
| @@ -0,0 +1,72 @@ | |||
| 1 | Upstream-Status: inappropriate | ||
| 2 | |||
| 3 | From 1399df7672ec309523bcd067da24d72aa624f783 Mon Sep 17 00:00:00 2001 | ||
| 4 | From: Corey Minyard <cminyard@mvista.com> | ||
| 5 | Date: Wed, 1 Jun 2011 07:51:24 -0500 | ||
| 6 | Subject: [PATCH 01/19] Fix warnings, remove some unused macros. | ||
| 7 | |||
| 8 | These are some annoying warnings with newer toolchains. And NAMLEN is | ||
| 9 | never used, so just get rid of it. | ||
| 10 | --- | ||
| 11 | genext2fs.c | 15 +++++++++------ | ||
| 12 | 1 files changed, 9 insertions(+), 6 deletions(-) | ||
| 13 | |||
| 14 | diff --git a/genext2fs.c b/genext2fs.c | ||
| 15 | index f0d797d..284862d 100644 | ||
| 16 | --- a/genext2fs.c | ||
| 17 | +++ b/genext2fs.c | ||
| 18 | @@ -107,10 +107,8 @@ | ||
| 19 | |||
| 20 | #if HAVE_DIRENT_H | ||
| 21 | # include <dirent.h> | ||
| 22 | -# define NAMLEN(dirent) strlen((dirent)->d_name) | ||
| 23 | #else | ||
| 24 | # define dirent direct | ||
| 25 | -# define NAMLEN(dirent) (dirent)->d_namlen | ||
| 26 | # if HAVE_SYS_NDIR_H | ||
| 27 | # include <sys/ndir.h> | ||
| 28 | # endif | ||
| 29 | @@ -1441,7 +1439,8 @@ mkfile_fs(filesystem *fs, uint32 parent_nod, const char *name, uint32 mode, size | ||
| 30 | if(!(b = (uint8*)calloc(rndup(size, BLOCKSIZE), 1))) | ||
| 31 | error_msg_and_die("not enough mem to read file '%s'", name); | ||
| 32 | if(f) | ||
| 33 | - fread(b, size, 1, f); // FIXME: ugly. use mmap() ... | ||
| 34 | + if (fread(b, size, 1, f) != 1) // FIXME: ugly. use mmap() ... | ||
| 35 | + error_msg_and_die("fread failed"); | ||
| 36 | extend_blk(fs, nod, b, rndup(size, BLOCKSIZE) / BLOCKSIZE); | ||
| 37 | free(b); | ||
| 38 | } | ||
| 39 | @@ -1673,7 +1672,9 @@ add2fs_from_dir(filesystem *fs, uint32 this_nod, int squash_uids, int squash_per | ||
| 40 | if(chdir(dent->d_name) < 0) | ||
| 41 | perror_msg_and_die(dent->d_name); | ||
| 42 | add2fs_from_dir(fs, this_nod, squash_uids, squash_perms, fs_timestamp, stats); | ||
| 43 | - chdir(".."); | ||
| 44 | + if (chdir("..") == -1) | ||
| 45 | + perror_msg_and_die(".."); | ||
| 46 | + | ||
| 47 | break; | ||
| 48 | default: | ||
| 49 | break; | ||
| 50 | @@ -1687,7 +1688,8 @@ add2fs_from_dir(filesystem *fs, uint32 this_nod, int squash_uids, int squash_per | ||
| 51 | if(chdir(dent->d_name) < 0) | ||
| 52 | perror_msg_and_die(name); | ||
| 53 | add2fs_from_dir(fs, nod, squash_uids, squash_perms, fs_timestamp, stats); | ||
| 54 | - chdir(".."); | ||
| 55 | + if (chdir("..") == -1) | ||
| 56 | + perror_msg_and_die(".."); | ||
| 57 | } | ||
| 58 | continue; | ||
| 59 | } | ||
| 60 | @@ -1733,7 +1735,8 @@ add2fs_from_dir(filesystem *fs, uint32 this_nod, int squash_uids, int squash_per | ||
| 61 | if(chdir(dent->d_name) < 0) | ||
| 62 | perror_msg_and_die(name); | ||
| 63 | add2fs_from_dir(fs, nod, squash_uids, squash_perms, fs_timestamp, stats); | ||
| 64 | - chdir(".."); | ||
| 65 | + if (chdir("..") == -1) | ||
| 66 | + perror_msg_and_die(".."); | ||
| 67 | break; | ||
| 68 | default: | ||
| 69 | error_msg("ignoring entry %s", name); | ||
| 70 | -- | ||
| 71 | 1.7.4.1 | ||
| 72 | |||
diff --git a/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0002-Add-put_blk-and-put_nod-routines.patch b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0002-Add-put_blk-and-put_nod-routines.patch new file mode 100644 index 0000000000..ddcd052edc --- /dev/null +++ b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0002-Add-put_blk-and-put_nod-routines.patch | |||
| @@ -0,0 +1,1123 @@ | |||
| 1 | Upstream-Status: inappropriate | ||
| 2 | |||
| 3 | From 8dd6e604777ffeb4d30921592f199cd9bcc8a3e2 Mon Sep 17 00:00:00 2001 | ||
| 4 | From: Corey Minyard <cminyard@mvista.com> | ||
| 5 | Date: Sat, 4 Jun 2011 15:23:29 -0500 | ||
| 6 | Subject: [PATCH 02/19] Add put_blk and put_nod routines | ||
| 7 | |||
| 8 | Add the routines to mark that we are done with a block or inode, and | ||
| 9 | add the info structures so that get and put will work. This doesn't | ||
| 10 | do anything functionally, just getting ready for future changes. | ||
| 11 | |||
| 12 | Most of the changes are pretty straightforward. There were changes in | ||
| 13 | get_nod() because it could use a later block than the one actually | ||
| 14 | fetches. And walk_bw() needed some special handling to avoid using data | ||
| 15 | after the put routine. | ||
| 16 | --- | ||
| 17 | genext2fs.c | 480 ++++++++++++++++++++++++++++++++++++++++------------------- | ||
| 18 | 1 files changed, 330 insertions(+), 150 deletions(-) | ||
| 19 | |||
| 20 | diff --git a/genext2fs.c b/genext2fs.c | ||
| 21 | index 284862d..bd06369 100644 | ||
| 22 | --- a/genext2fs.c | ||
| 23 | +++ b/genext2fs.c | ||
| 24 | @@ -236,18 +236,22 @@ struct stats { | ||
| 25 | (((fs)->sb.s_blocks_count - fs->sb.s_first_data_block + \ | ||
| 26 | (fs)->sb.s_blocks_per_group - 1) / (fs)->sb.s_blocks_per_group) | ||
| 27 | |||
| 28 | -// Get group block bitmap (bbm) given the group number | ||
| 29 | -#define GRP_GET_GROUP_BBM(fs,grp) ( get_blk((fs),(fs)->gd[(grp)].bg_block_bitmap) ) | ||
| 30 | +// Get/put group block bitmap (bbm) given the group number | ||
| 31 | +#define GRP_GET_GROUP_BBM(fs,grp,bi) ( get_blk((fs),(fs)->gd[(grp)].bg_block_bitmap,(bi)) ) | ||
| 32 | +#define GRP_PUT_GROUP_BBM(bi) ( put_blk((bi)) ) | ||
| 33 | |||
| 34 | -// Get group inode bitmap (ibm) given the group number | ||
| 35 | -#define GRP_GET_GROUP_IBM(fs,grp) ( get_blk((fs),(fs)->gd[(grp)].bg_inode_bitmap) ) | ||
| 36 | +// Get/put group inode bitmap (ibm) given the group number | ||
| 37 | +#define GRP_GET_GROUP_IBM(fs,grp,bi) ( get_blk((fs),(fs)->gd[(grp)].bg_inode_bitmap,(bi)) ) | ||
| 38 | +#define GRP_PUT_GROUP_IBM(bi) ( put_blk((bi)) ) | ||
| 39 | |||
| 40 | // Given an inode number find the group it belongs to | ||
| 41 | #define GRP_GROUP_OF_INODE(fs,nod) ( ((nod)-1) / (fs)->sb.s_inodes_per_group) | ||
| 42 | |||
| 43 | -//Given an inode number get the inode bitmap that covers it | ||
| 44 | -#define GRP_GET_INODE_BITMAP(fs,nod) \ | ||
| 45 | - ( GRP_GET_GROUP_IBM((fs),GRP_GROUP_OF_INODE((fs),(nod))) ) | ||
| 46 | +//Given an inode number get/put the inode bitmap that covers it | ||
| 47 | +#define GRP_GET_INODE_BITMAP(fs,nod,bi) \ | ||
| 48 | + ( GRP_GET_GROUP_IBM((fs),GRP_GROUP_OF_INODE((fs),(nod)),(bi)) ) | ||
| 49 | +#define GRP_PUT_INODE_BITMAP(bi) \ | ||
| 50 | + ( GRP_PUT_GROUP_IBM((bi)) ) | ||
| 51 | |||
| 52 | //Given an inode number find its offset within the inode bitmap that covers it | ||
| 53 | #define GRP_IBM_OFFSET(fs,nod) \ | ||
| 54 | @@ -256,9 +260,11 @@ struct stats { | ||
| 55 | // Given a block number find the group it belongs to | ||
| 56 | #define GRP_GROUP_OF_BLOCK(fs,blk) ( ((blk)-1) / (fs)->sb.s_blocks_per_group) | ||
| 57 | |||
| 58 | -//Given a block number get the block bitmap that covers it | ||
| 59 | -#define GRP_GET_BLOCK_BITMAP(fs,blk) \ | ||
| 60 | - ( GRP_GET_GROUP_BBM((fs),GRP_GROUP_OF_BLOCK((fs),(blk))) ) | ||
| 61 | +//Given a block number get/put the block bitmap that covers it | ||
| 62 | +#define GRP_GET_BLOCK_BITMAP(fs,blk,bi) \ | ||
| 63 | + ( GRP_GET_GROUP_BBM((fs),GRP_GROUP_OF_BLOCK((fs),(blk)),(bi)) ) | ||
| 64 | +#define GRP_PUT_BLOCK_BITMAP(bi) \ | ||
| 65 | + ( GRP_PUT_GROUP_BBM((bi)) ) | ||
| 66 | |||
| 67 | //Given a block number find its offset within the block bitmap that covers it | ||
| 68 | #define GRP_BBM_OFFSET(fs,blk) \ | ||
| 69 | @@ -811,24 +817,59 @@ allocated(block b, uint32 item) | ||
| 70 | return b[(item-1) / 8] & (1 << ((item-1) % 8)); | ||
| 71 | } | ||
| 72 | |||
| 73 | -// return a given block from a filesystem | ||
| 74 | +// Used by get_blk/put_blk to hold information about a block owned | ||
| 75 | +// by the user. | ||
| 76 | +typedef struct | ||
| 77 | +{ | ||
| 78 | + int dummy; | ||
| 79 | +} blk_info; | ||
| 80 | + | ||
| 81 | +// Return a given block from a filesystem. Make sure to call | ||
| 82 | +// put_blk when you are done with it. | ||
| 83 | static inline uint8 * | ||
| 84 | -get_blk(filesystem *fs, uint32 blk) | ||
| 85 | +get_blk(filesystem *fs, uint32 blk, blk_info **rbi) | ||
| 86 | { | ||
| 87 | return (uint8*)fs + blk*BLOCKSIZE; | ||
| 88 | } | ||
| 89 | |||
| 90 | -// return a given inode from a filesystem | ||
| 91 | +static inline void | ||
| 92 | +put_blk(blk_info *bi) | ||
| 93 | +{ | ||
| 94 | +} | ||
| 95 | + | ||
| 96 | +// Used by get_nod/put_nod to hold information about an inode owned | ||
| 97 | +// by the user. | ||
| 98 | +typedef struct | ||
| 99 | +{ | ||
| 100 | + blk_info *bi; | ||
| 101 | +} nod_info; | ||
| 102 | + | ||
| 103 | +// Return a given inode from a filesystem. Make sure to call put_nod() | ||
| 104 | +// when you are done with the inode. | ||
| 105 | static inline inode * | ||
| 106 | -get_nod(filesystem *fs, uint32 nod) | ||
| 107 | +get_nod(filesystem *fs, uint32 nod, nod_info **rni) | ||
| 108 | { | ||
| 109 | - int grp,offset; | ||
| 110 | + int grp, offset, boffset; | ||
| 111 | inode *itab; | ||
| 112 | + nod_info *ni; | ||
| 113 | |||
| 114 | - offset = GRP_IBM_OFFSET(fs,nod); | ||
| 115 | + offset = GRP_IBM_OFFSET(fs,nod) - 1; | ||
| 116 | + boffset = offset / (BLOCKSIZE / sizeof(inode)); | ||
| 117 | + offset %= BLOCKSIZE / sizeof(inode); | ||
| 118 | grp = GRP_GROUP_OF_INODE(fs,nod); | ||
| 119 | - itab = (inode *)get_blk(fs, fs->gd[grp].bg_inode_table); | ||
| 120 | - return itab+offset-1; | ||
| 121 | + ni = malloc(sizeof(*ni)); | ||
| 122 | + if (!ni) | ||
| 123 | + error_msg_and_die("get_nod: out of memory"); | ||
| 124 | + itab = (inode *)get_blk(fs, fs->gd[grp].bg_inode_table + boffset, &ni->bi); | ||
| 125 | + *rni = ni; | ||
| 126 | + return itab+offset; | ||
| 127 | +} | ||
| 128 | + | ||
| 129 | +static inline void | ||
| 130 | +put_nod(nod_info *ni) | ||
| 131 | +{ | ||
| 132 | + put_blk(ni->bi); | ||
| 133 | + free(ni); | ||
| 134 | } | ||
| 135 | |||
| 136 | // allocate a given block/inode in the bitmap | ||
| 137 | @@ -870,12 +911,17 @@ alloc_blk(filesystem *fs, uint32 nod) | ||
| 138 | { | ||
| 139 | uint32 bk=0; | ||
| 140 | uint32 grp,nbgroups; | ||
| 141 | + blk_info *bi; | ||
| 142 | |||
| 143 | grp = GRP_GROUP_OF_INODE(fs,nod); | ||
| 144 | nbgroups = GRP_NBGROUPS(fs); | ||
| 145 | - if(!(bk = allocate(get_blk(fs,fs->gd[grp].bg_block_bitmap), 0))) { | ||
| 146 | - for(grp=0;grp<nbgroups && !bk;grp++) | ||
| 147 | - bk=allocate(get_blk(fs,fs->gd[grp].bg_block_bitmap),0); | ||
| 148 | + bk = allocate(get_blk(fs, fs->gd[grp].bg_block_bitmap, &bi), 0); | ||
| 149 | + put_blk(bi); | ||
| 150 | + if (!bk) { | ||
| 151 | + for (grp=0; grp<nbgroups && !bk; grp++) { | ||
| 152 | + bk = allocate(get_blk(fs, fs->gd[grp].bg_block_bitmap, &bi), 0); | ||
| 153 | + put_blk(bi); | ||
| 154 | + } | ||
| 155 | grp--; | ||
| 156 | } | ||
| 157 | if (!bk) | ||
| 158 | @@ -892,10 +938,12 @@ static void | ||
| 159 | free_blk(filesystem *fs, uint32 bk) | ||
| 160 | { | ||
| 161 | uint32 grp; | ||
| 162 | + blk_info *bi; | ||
| 163 | |||
| 164 | grp = bk / fs->sb.s_blocks_per_group; | ||
| 165 | bk %= fs->sb.s_blocks_per_group; | ||
| 166 | - deallocate(get_blk(fs,fs->gd[grp].bg_block_bitmap), bk); | ||
| 167 | + deallocate(get_blk(fs, fs->gd[grp].bg_block_bitmap, &bi), bk); | ||
| 168 | + put_blk(bi); | ||
| 169 | fs->gd[grp].bg_free_blocks_count++; | ||
| 170 | fs->sb.s_free_blocks_count++; | ||
| 171 | } | ||
| 172 | @@ -906,6 +954,7 @@ alloc_nod(filesystem *fs) | ||
| 173 | { | ||
| 174 | uint32 nod,best_group=0; | ||
| 175 | uint32 grp,nbgroups,avefreei; | ||
| 176 | + blk_info *bi; | ||
| 177 | |||
| 178 | nbgroups = GRP_NBGROUPS(fs); | ||
| 179 | |||
| 180 | @@ -923,8 +972,10 @@ alloc_nod(filesystem *fs) | ||
| 181 | fs->gd[grp].bg_free_blocks_count > fs->gd[best_group].bg_free_blocks_count) | ||
| 182 | best_group = grp; | ||
| 183 | } | ||
| 184 | - if (!(nod = allocate(get_blk(fs,fs->gd[best_group].bg_inode_bitmap),0))) | ||
| 185 | + if (!(nod = allocate(get_blk(fs, fs->gd[best_group].bg_inode_bitmap, | ||
| 186 | + &bi), 0))) | ||
| 187 | error_msg_and_die("couldn't allocate an inode (no free inode)"); | ||
| 188 | + put_blk(bi); | ||
| 189 | if(!(fs->gd[best_group].bg_free_inodes_count--)) | ||
| 190 | error_msg_and_die("group descr. free blocks count == 0 (corrupted fs?)"); | ||
| 191 | if(!(fs->sb.s_free_inodes_count--)) | ||
| 192 | @@ -968,24 +1019,35 @@ static uint32 | ||
| 193 | walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole) | ||
| 194 | { | ||
| 195 | uint32 *bkref = 0; | ||
| 196 | + uint32 bk = 0; | ||
| 197 | uint32 *b; | ||
| 198 | int extend = 0, reduce = 0; | ||
| 199 | + inode *inod; | ||
| 200 | + nod_info *ni; | ||
| 201 | + uint32 *iblk; | ||
| 202 | + blk_info *bi1 = NULL, *bi2 = NULL, *bi3 = NULL; | ||
| 203 | + | ||
| 204 | if(create && (*create) < 0) | ||
| 205 | reduce = 1; | ||
| 206 | - if(bw->bnum >= get_nod(fs, nod)->i_blocks / INOBLK) | ||
| 207 | + inod = get_nod(fs, nod, &ni); | ||
| 208 | + if(bw->bnum >= inod->i_blocks / INOBLK) | ||
| 209 | { | ||
| 210 | if(create && (*create) > 0) | ||
| 211 | { | ||
| 212 | (*create)--; | ||
| 213 | extend = 1; | ||
| 214 | } | ||
| 215 | - else | ||
| 216 | + else | ||
| 217 | + { | ||
| 218 | + put_nod(ni); | ||
| 219 | return WALK_END; | ||
| 220 | + } | ||
| 221 | } | ||
| 222 | + iblk = inod->i_block; | ||
| 223 | // first direct block | ||
| 224 | if(bw->bpdir == EXT2_INIT_BLOCK) | ||
| 225 | { | ||
| 226 | - bkref = &get_nod(fs, nod)->i_block[bw->bpdir = 0]; | ||
| 227 | + bkref = &iblk[bw->bpdir = 0]; | ||
| 228 | if(extend) // allocate first block | ||
| 229 | *bkref = hole ? 0 : alloc_blk(fs,nod); | ||
| 230 | if(reduce) // free first block | ||
| 231 | @@ -994,7 +1056,7 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole) | ||
| 232 | // direct block | ||
| 233 | else if(bw->bpdir < EXT2_NDIR_BLOCKS) | ||
| 234 | { | ||
| 235 | - bkref = &get_nod(fs, nod)->i_block[++bw->bpdir]; | ||
| 236 | + bkref = &iblk[++bw->bpdir]; | ||
| 237 | if(extend) // allocate block | ||
| 238 | *bkref = hole ? 0 : alloc_blk(fs,nod); | ||
| 239 | if(reduce) // free block | ||
| 240 | @@ -1007,10 +1069,10 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole) | ||
| 241 | bw->bpdir = EXT2_IND_BLOCK; | ||
| 242 | bw->bpind = 0; | ||
| 243 | if(extend) // allocate indirect block | ||
| 244 | - get_nod(fs, nod)->i_block[bw->bpdir] = alloc_blk(fs,nod); | ||
| 245 | + iblk[bw->bpdir] = alloc_blk(fs,nod); | ||
| 246 | if(reduce) // free indirect block | ||
| 247 | - free_blk(fs, get_nod(fs, nod)->i_block[bw->bpdir]); | ||
| 248 | - b = (uint32*)get_blk(fs, get_nod(fs, nod)->i_block[bw->bpdir]); | ||
| 249 | + free_blk(fs, iblk[bw->bpdir]); | ||
| 250 | + b = (uint32*)get_blk(fs, iblk[bw->bpdir], &bi1); | ||
| 251 | bkref = &b[bw->bpind]; | ||
| 252 | if(extend) // allocate first block | ||
| 253 | *bkref = hole ? 0 : alloc_blk(fs,nod); | ||
| 254 | @@ -1021,7 +1083,7 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole) | ||
| 255 | else if((bw->bpdir == EXT2_IND_BLOCK) && (bw->bpind < BLOCKSIZE/4 - 1)) | ||
| 256 | { | ||
| 257 | bw->bpind++; | ||
| 258 | - b = (uint32*)get_blk(fs, get_nod(fs, nod)->i_block[bw->bpdir]); | ||
| 259 | + b = (uint32*)get_blk(fs, iblk[bw->bpdir], &bi1); | ||
| 260 | bkref = &b[bw->bpind]; | ||
| 261 | if(extend) // allocate block | ||
| 262 | *bkref = hole ? 0 : alloc_blk(fs,nod); | ||
| 263 | @@ -1036,15 +1098,15 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole) | ||
| 264 | bw->bpind = 0; | ||
| 265 | bw->bpdind = 0; | ||
| 266 | if(extend) // allocate double indirect block | ||
| 267 | - get_nod(fs, nod)->i_block[bw->bpdir] = alloc_blk(fs,nod); | ||
| 268 | + iblk[bw->bpdir] = alloc_blk(fs,nod); | ||
| 269 | if(reduce) // free double indirect block | ||
| 270 | - free_blk(fs, get_nod(fs, nod)->i_block[bw->bpdir]); | ||
| 271 | - b = (uint32*)get_blk(fs, get_nod(fs, nod)->i_block[bw->bpdir]); | ||
| 272 | + free_blk(fs, iblk[bw->bpdir]); | ||
| 273 | + b = (uint32*)get_blk(fs, iblk[bw->bpdir], &bi1); | ||
| 274 | if(extend) // allocate first indirect block | ||
| 275 | b[bw->bpind] = alloc_blk(fs,nod); | ||
| 276 | if(reduce) // free firstindirect block | ||
| 277 | free_blk(fs, b[bw->bpind]); | ||
| 278 | - b = (uint32*)get_blk(fs, b[bw->bpind]); | ||
| 279 | + b = (uint32*)get_blk(fs, b[bw->bpind], &bi1); | ||
| 280 | bkref = &b[bw->bpdind]; | ||
| 281 | if(extend) // allocate first block | ||
| 282 | *bkref = hole ? 0 : alloc_blk(fs,nod); | ||
| 283 | @@ -1055,8 +1117,8 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole) | ||
| 284 | else if((bw->bpdir == EXT2_DIND_BLOCK) && (bw->bpdind < BLOCKSIZE/4 - 1)) | ||
| 285 | { | ||
| 286 | bw->bpdind++; | ||
| 287 | - b = (uint32*)get_blk(fs, get_nod(fs, nod)->i_block[bw->bpdir]); | ||
| 288 | - b = (uint32*)get_blk(fs, b[bw->bpind]); | ||
| 289 | + b = (uint32*)get_blk(fs, iblk[bw->bpdir], &bi1); | ||
| 290 | + b = (uint32*)get_blk(fs, b[bw->bpind], &bi2); | ||
| 291 | bkref = &b[bw->bpdind]; | ||
| 292 | if(extend) // allocate block | ||
| 293 | *bkref = hole ? 0 : alloc_blk(fs,nod); | ||
| 294 | @@ -1069,12 +1131,12 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole) | ||
| 295 | bw->bnum++; | ||
| 296 | bw->bpdind = 0; | ||
| 297 | bw->bpind++; | ||
| 298 | - b = (uint32*)get_blk(fs, get_nod(fs, nod)->i_block[bw->bpdir]); | ||
| 299 | + b = (uint32*)get_blk(fs, iblk[bw->bpdir], &bi1); | ||
| 300 | if(extend) // allocate indirect block | ||
| 301 | b[bw->bpind] = alloc_blk(fs,nod); | ||
| 302 | if(reduce) // free indirect block | ||
| 303 | free_blk(fs, b[bw->bpind]); | ||
| 304 | - b = (uint32*)get_blk(fs, b[bw->bpind]); | ||
| 305 | + b = (uint32*)get_blk(fs, b[bw->bpind], &bi2); | ||
| 306 | bkref = &b[bw->bpdind]; | ||
| 307 | if(extend) // allocate first block | ||
| 308 | *bkref = hole ? 0 : alloc_blk(fs,nod); | ||
| 309 | @@ -1094,20 +1156,20 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole) | ||
| 310 | bw->bpdind = 0; | ||
| 311 | bw->bptind = 0; | ||
| 312 | if(extend) // allocate triple indirect block | ||
| 313 | - get_nod(fs, nod)->i_block[bw->bpdir] = alloc_blk(fs,nod); | ||
| 314 | + iblk[bw->bpdir] = alloc_blk(fs,nod); | ||
| 315 | if(reduce) // free triple indirect block | ||
| 316 | - free_blk(fs, get_nod(fs, nod)->i_block[bw->bpdir]); | ||
| 317 | - b = (uint32*)get_blk(fs, get_nod(fs, nod)->i_block[bw->bpdir]); | ||
| 318 | + free_blk(fs, iblk[bw->bpdir]); | ||
| 319 | + b = (uint32*)get_blk(fs, iblk[bw->bpdir], &bi1); | ||
| 320 | if(extend) // allocate first double indirect block | ||
| 321 | b[bw->bpind] = alloc_blk(fs,nod); | ||
| 322 | if(reduce) // free first double indirect block | ||
| 323 | free_blk(fs, b[bw->bpind]); | ||
| 324 | - b = (uint32*)get_blk(fs, b[bw->bpind]); | ||
| 325 | + b = (uint32*)get_blk(fs, b[bw->bpind], &bi2); | ||
| 326 | if(extend) // allocate first indirect block | ||
| 327 | b[bw->bpdind] = alloc_blk(fs,nod); | ||
| 328 | if(reduce) // free first indirect block | ||
| 329 | free_blk(fs, b[bw->bpind]); | ||
| 330 | - b = (uint32*)get_blk(fs, b[bw->bpdind]); | ||
| 331 | + b = (uint32*)get_blk(fs, b[bw->bpdind], &bi3); | ||
| 332 | bkref = &b[bw->bptind]; | ||
| 333 | if(extend) // allocate first data block | ||
| 334 | *bkref = hole ? 0 : alloc_blk(fs,nod); | ||
| 335 | @@ -1121,9 +1183,9 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole) | ||
| 336 | (bw->bptind < BLOCKSIZE/4 -1) ) | ||
| 337 | { | ||
| 338 | bw->bptind++; | ||
| 339 | - b = (uint32*)get_blk(fs, get_nod(fs, nod)->i_block[bw->bpdir]); | ||
| 340 | - b = (uint32*)get_blk(fs, b[bw->bpind]); | ||
| 341 | - b = (uint32*)get_blk(fs, b[bw->bpdind]); | ||
| 342 | + b = (uint32*)get_blk(fs, iblk[bw->bpdir], &bi1); | ||
| 343 | + b = (uint32*)get_blk(fs, b[bw->bpind], &bi2); | ||
| 344 | + b = (uint32*)get_blk(fs, b[bw->bpdind], &bi3); | ||
| 345 | bkref = &b[bw->bptind]; | ||
| 346 | if(extend) // allocate data block | ||
| 347 | *bkref = hole ? 0 : alloc_blk(fs,nod); | ||
| 348 | @@ -1140,13 +1202,13 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole) | ||
| 349 | bw->bnum++; | ||
| 350 | bw->bptind = 0; | ||
| 351 | bw->bpdind++; | ||
| 352 | - b = (uint32*)get_blk(fs, get_nod(fs, nod)->i_block[bw->bpdir]); | ||
| 353 | - b = (uint32*)get_blk(fs, b[bw->bpind]); | ||
| 354 | + b = (uint32*)get_blk(fs, iblk[bw->bpdir], &bi1); | ||
| 355 | + b = (uint32*)get_blk(fs, b[bw->bpind], &bi2); | ||
| 356 | if(extend) // allocate single indirect block | ||
| 357 | b[bw->bpdind] = alloc_blk(fs,nod); | ||
| 358 | if(reduce) // free indirect block | ||
| 359 | free_blk(fs, b[bw->bpind]); | ||
| 360 | - b = (uint32*)get_blk(fs, b[bw->bpdind]); | ||
| 361 | + b = (uint32*)get_blk(fs, b[bw->bpdind], &bi3); | ||
| 362 | bkref = &b[bw->bptind]; | ||
| 363 | if(extend) // allocate first data block | ||
| 364 | *bkref = hole ? 0 : alloc_blk(fs,nod); | ||
| 365 | @@ -1163,17 +1225,17 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole) | ||
| 366 | bw->bpdind = 0; | ||
| 367 | bw->bptind = 0; | ||
| 368 | bw->bpind++; | ||
| 369 | - b = (uint32*)get_blk(fs, get_nod(fs, nod)->i_block[bw->bpdir]); | ||
| 370 | + b = (uint32*)get_blk(fs, iblk[bw->bpdir], &bi1); | ||
| 371 | if(extend) // allocate double indirect block | ||
| 372 | b[bw->bpind] = alloc_blk(fs,nod); | ||
| 373 | if(reduce) // free double indirect block | ||
| 374 | free_blk(fs, b[bw->bpind]); | ||
| 375 | - b = (uint32*)get_blk(fs, b[bw->bpind]); | ||
| 376 | + b = (uint32*)get_blk(fs, b[bw->bpind], &bi2); | ||
| 377 | if(extend) // allocate single indirect block | ||
| 378 | b[bw->bpdind] = alloc_blk(fs,nod); | ||
| 379 | if(reduce) // free indirect block | ||
| 380 | free_blk(fs, b[bw->bpind]); | ||
| 381 | - b = (uint32*)get_blk(fs, b[bw->bpdind]); | ||
| 382 | + b = (uint32*)get_blk(fs, b[bw->bpdind], &bi3); | ||
| 383 | bkref = &b[bw->bptind]; | ||
| 384 | if(extend) // allocate first block | ||
| 385 | *bkref = hole ? 0 : alloc_blk(fs,nod); | ||
| 386 | @@ -1184,15 +1246,28 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole) | ||
| 387 | error_msg_and_die("file too big !"); | ||
| 388 | /* End change for walking triple indirection */ | ||
| 389 | |||
| 390 | - if(*bkref) | ||
| 391 | + bk = *bkref; | ||
| 392 | + if (bi3) | ||
| 393 | + put_blk(bi3); | ||
| 394 | + if (bi2) | ||
| 395 | + put_blk(bi2); | ||
| 396 | + if (bi1) | ||
| 397 | + put_blk(bi1); | ||
| 398 | + | ||
| 399 | + if(bk) | ||
| 400 | { | ||
| 401 | + blk_info *bi; | ||
| 402 | + uint8 *block; | ||
| 403 | bw->bnum++; | ||
| 404 | - if(!reduce && !allocated(GRP_GET_BLOCK_BITMAP(fs,*bkref), GRP_BBM_OFFSET(fs,*bkref))) | ||
| 405 | - error_msg_and_die("[block %d of inode %d is unallocated !]", *bkref, nod); | ||
| 406 | + block = GRP_GET_BLOCK_BITMAP(fs,bk,&bi); | ||
| 407 | + if(!reduce && !allocated(block, GRP_BBM_OFFSET(fs,bk))) | ||
| 408 | + error_msg_and_die("[block %d of inode %d is unallocated !]", bk, nod); | ||
| 409 | + GRP_PUT_BLOCK_BITMAP(bi); | ||
| 410 | } | ||
| 411 | if(extend) | ||
| 412 | - get_nod(fs, nod)->i_blocks = bw->bnum * INOBLK; | ||
| 413 | - return *bkref; | ||
| 414 | + inod->i_blocks = bw->bnum * INOBLK; | ||
| 415 | + put_nod(ni); | ||
| 416 | + return bk; | ||
| 417 | } | ||
| 418 | |||
| 419 | // add blocks to an inode (file/dir/etc...) | ||
| 420 | @@ -1202,15 +1277,19 @@ extend_blk(filesystem *fs, uint32 nod, block b, int amount) | ||
| 421 | int create = amount; | ||
| 422 | blockwalker bw, lbw; | ||
| 423 | uint32 bk; | ||
| 424 | + nod_info *ni; | ||
| 425 | + inode *inod; | ||
| 426 | + | ||
| 427 | + inod = get_nod(fs, nod, &ni); | ||
| 428 | init_bw(&bw); | ||
| 429 | if(amount < 0) | ||
| 430 | { | ||
| 431 | uint32 i; | ||
| 432 | - for(i = 0; i < get_nod(fs, nod)->i_blocks / INOBLK + amount; i++) | ||
| 433 | + for(i = 0; i < inod->i_blocks / INOBLK + amount; i++) | ||
| 434 | walk_bw(fs, nod, &bw, 0, 0); | ||
| 435 | while(walk_bw(fs, nod, &bw, &create, 0) != WALK_END) | ||
| 436 | /*nop*/; | ||
| 437 | - get_nod(fs, nod)->i_blocks += amount * INOBLK; | ||
| 438 | + inod->i_blocks += amount * INOBLK; | ||
| 439 | } | ||
| 440 | else | ||
| 441 | { | ||
| 442 | @@ -1232,8 +1311,11 @@ extend_blk(filesystem *fs, uint32 nod, block b, int amount) | ||
| 443 | } | ||
| 444 | if((bk = walk_bw(fs, nod, &bw, &create, !copyb)) == WALK_END) | ||
| 445 | break; | ||
| 446 | - if(copyb) | ||
| 447 | - memcpy(get_blk(fs, bk), b + BLOCKSIZE * (amount - create - 1), BLOCKSIZE); | ||
| 448 | + if(copyb) { | ||
| 449 | + blk_info *bi; | ||
| 450 | + memcpy(get_blk(fs, bk, &bi), b + BLOCKSIZE * (amount - create - 1), BLOCKSIZE); | ||
| 451 | + put_blk(bi); | ||
| 452 | + } | ||
| 453 | } | ||
| 454 | } | ||
| 455 | } | ||
| 456 | @@ -1245,12 +1327,14 @@ add2dir(filesystem *fs, uint32 dnod, uint32 nod, const char* name) | ||
| 457 | blockwalker bw; | ||
| 458 | uint32 bk; | ||
| 459 | uint8 *b; | ||
| 460 | + blk_info *bi; | ||
| 461 | directory *d; | ||
| 462 | int reclen, nlen; | ||
| 463 | inode *node; | ||
| 464 | inode *pnode; | ||
| 465 | + nod_info *dni, *ni; | ||
| 466 | |||
| 467 | - pnode = get_nod(fs, dnod); | ||
| 468 | + pnode = get_nod(fs, dnod, &dni); | ||
| 469 | if((pnode->i_mode & FM_IFMT) != FM_IFDIR) | ||
| 470 | error_msg_and_die("can't add '%s' to a non-directory", name); | ||
| 471 | if(!*name) | ||
| 472 | @@ -1264,7 +1348,7 @@ add2dir(filesystem *fs, uint32 dnod, uint32 nod, const char* name) | ||
| 473 | init_bw(&bw); | ||
| 474 | while((bk = walk_bw(fs, dnod, &bw, 0, 0)) != WALK_END) // for all blocks in dir | ||
| 475 | { | ||
| 476 | - b = get_blk(fs, bk); | ||
| 477 | + b = get_blk(fs, bk, &bi); | ||
| 478 | // for all dir entries in block | ||
| 479 | for(d = (directory*)b; (int8*)d + sizeof(*d) < (int8*)b + BLOCKSIZE; d = (directory*)((int8*)d + d->d_rec_len)) | ||
| 480 | { | ||
| 481 | @@ -1272,11 +1356,12 @@ add2dir(filesystem *fs, uint32 dnod, uint32 nod, const char* name) | ||
| 482 | if((!d->d_inode) && (d->d_rec_len >= reclen)) | ||
| 483 | { | ||
| 484 | d->d_inode = nod; | ||
| 485 | - node = get_nod(fs, nod); | ||
| 486 | + node = get_nod(fs, nod, &ni); | ||
| 487 | node->i_links_count++; | ||
| 488 | d->d_name_len = nlen; | ||
| 489 | strncpy(d->d_name, name, nlen); | ||
| 490 | - return; | ||
| 491 | + put_nod(ni); | ||
| 492 | + goto out; | ||
| 493 | } | ||
| 494 | // if entry with enough room (last one?), shrink it & use it | ||
| 495 | if(d->d_rec_len >= (sizeof(directory) + rndup(d->d_name_len, 4) + reclen)) | ||
| 496 | @@ -1287,11 +1372,12 @@ add2dir(filesystem *fs, uint32 dnod, uint32 nod, const char* name) | ||
| 497 | d = (directory*) (((int8*)d) + d->d_rec_len); | ||
| 498 | d->d_rec_len = reclen; | ||
| 499 | d->d_inode = nod; | ||
| 500 | - node = get_nod(fs, nod); | ||
| 501 | + node = get_nod(fs, nod, &ni); | ||
| 502 | node->i_links_count++; | ||
| 503 | d->d_name_len = nlen; | ||
| 504 | strncpy(d->d_name, name, nlen); | ||
| 505 | - return; | ||
| 506 | + put_nod(ni); | ||
| 507 | + goto out; | ||
| 508 | } | ||
| 509 | } | ||
| 510 | } | ||
| 511 | @@ -1300,14 +1386,17 @@ add2dir(filesystem *fs, uint32 dnod, uint32 nod, const char* name) | ||
| 512 | error_msg_and_die("get_workblk() failed."); | ||
| 513 | d = (directory*)b; | ||
| 514 | d->d_inode = nod; | ||
| 515 | - node = get_nod(fs, nod); | ||
| 516 | + node = get_nod(fs, nod, &ni); | ||
| 517 | node->i_links_count++; | ||
| 518 | + put_nod(ni); | ||
| 519 | d->d_rec_len = BLOCKSIZE; | ||
| 520 | d->d_name_len = nlen; | ||
| 521 | strncpy(d->d_name, name, nlen); | ||
| 522 | extend_blk(fs, dnod, b, 1); | ||
| 523 | - get_nod(fs, dnod)->i_size += BLOCKSIZE; | ||
| 524 | + pnode->i_size += BLOCKSIZE; | ||
| 525 | free_workblk(b); | ||
| 526 | +out: | ||
| 527 | + put_nod(dni); | ||
| 528 | } | ||
| 529 | |||
| 530 | // find an entry in a directory | ||
| 531 | @@ -1316,16 +1405,20 @@ find_dir(filesystem *fs, uint32 nod, const char * name) | ||
| 532 | { | ||
| 533 | blockwalker bw; | ||
| 534 | uint32 bk; | ||
| 535 | + blk_info *bi; | ||
| 536 | int nlen = strlen(name); | ||
| 537 | init_bw(&bw); | ||
| 538 | while((bk = walk_bw(fs, nod, &bw, 0, 0)) != WALK_END) | ||
| 539 | { | ||
| 540 | directory *d; | ||
| 541 | uint8 *b; | ||
| 542 | - b = get_blk(fs, bk); | ||
| 543 | + b = get_blk(fs, bk, &bi); | ||
| 544 | for(d = (directory*)b; (int8*)d + sizeof(*d) < (int8*)b + BLOCKSIZE; d = (directory*)((int8*)d + d->d_rec_len)) | ||
| 545 | - if(d->d_inode && (nlen == d->d_name_len) && !strncmp(d->d_name, name, nlen)) | ||
| 546 | + if(d->d_inode && (nlen == d->d_name_len) && !strncmp(d->d_name, name, nlen)) { | ||
| 547 | + put_blk(bi); | ||
| 548 | return d->d_inode; | ||
| 549 | + } | ||
| 550 | + put_blk(bi); | ||
| 551 | } | ||
| 552 | return 0; | ||
| 553 | } | ||
| 554 | @@ -1361,10 +1454,12 @@ void | ||
| 555 | chmod_fs(filesystem *fs, uint32 nod, uint16 mode, uint16 uid, uint16 gid) | ||
| 556 | { | ||
| 557 | inode *node; | ||
| 558 | - node = get_nod(fs, nod); | ||
| 559 | + nod_info *ni; | ||
| 560 | + node = get_nod(fs, nod, &ni); | ||
| 561 | node->i_mode = (node->i_mode & ~FM_IMASK) | (mode & FM_IMASK); | ||
| 562 | node->i_uid = uid; | ||
| 563 | node->i_gid = gid; | ||
| 564 | + put_nod(ni); | ||
| 565 | } | ||
| 566 | |||
| 567 | // create a simple inode | ||
| 568 | @@ -1373,33 +1468,34 @@ mknod_fs(filesystem *fs, uint32 parent_nod, const char *name, uint16 mode, uint1 | ||
| 569 | { | ||
| 570 | uint32 nod; | ||
| 571 | inode *node; | ||
| 572 | + nod_info *ni; | ||
| 573 | + | ||
| 574 | + nod = alloc_nod(fs); | ||
| 575 | + node = get_nod(fs, nod, &ni); | ||
| 576 | + node->i_mode = mode; | ||
| 577 | + add2dir(fs, parent_nod, nod, name); | ||
| 578 | + switch(mode & FM_IFMT) | ||
| 579 | { | ||
| 580 | - nod = alloc_nod(fs); | ||
| 581 | - node = get_nod(fs, nod); | ||
| 582 | - node->i_mode = mode; | ||
| 583 | - add2dir(fs, parent_nod, nod, name); | ||
| 584 | - switch(mode & FM_IFMT) | ||
| 585 | - { | ||
| 586 | - case FM_IFLNK: | ||
| 587 | - mode = FM_IFLNK | FM_IRWXU | FM_IRWXG | FM_IRWXO; | ||
| 588 | - break; | ||
| 589 | - case FM_IFBLK: | ||
| 590 | - case FM_IFCHR: | ||
| 591 | - ((uint8*)get_nod(fs, nod)->i_block)[0] = minor; | ||
| 592 | - ((uint8*)get_nod(fs, nod)->i_block)[1] = major; | ||
| 593 | - break; | ||
| 594 | - case FM_IFDIR: | ||
| 595 | - add2dir(fs, nod, nod, "."); | ||
| 596 | - add2dir(fs, nod, parent_nod, ".."); | ||
| 597 | - fs->gd[GRP_GROUP_OF_INODE(fs,nod)].bg_used_dirs_count++; | ||
| 598 | - break; | ||
| 599 | - } | ||
| 600 | + case FM_IFLNK: | ||
| 601 | + mode = FM_IFLNK | FM_IRWXU | FM_IRWXG | FM_IRWXO; | ||
| 602 | + break; | ||
| 603 | + case FM_IFBLK: | ||
| 604 | + case FM_IFCHR: | ||
| 605 | + ((uint8*)node->i_block)[0] = minor; | ||
| 606 | + ((uint8*)node->i_block)[1] = major; | ||
| 607 | + break; | ||
| 608 | + case FM_IFDIR: | ||
| 609 | + add2dir(fs, nod, nod, "."); | ||
| 610 | + add2dir(fs, nod, parent_nod, ".."); | ||
| 611 | + fs->gd[GRP_GROUP_OF_INODE(fs,nod)].bg_used_dirs_count++; | ||
| 612 | + break; | ||
| 613 | } | ||
| 614 | node->i_uid = uid; | ||
| 615 | node->i_gid = gid; | ||
| 616 | node->i_atime = mtime; | ||
| 617 | node->i_ctime = ctime; | ||
| 618 | node->i_mtime = mtime; | ||
| 619 | + put_nod(ni); | ||
| 620 | return nod; | ||
| 621 | } | ||
| 622 | |||
| 623 | @@ -1416,14 +1512,19 @@ static uint32 | ||
| 624 | mklink_fs(filesystem *fs, uint32 parent_nod, const char *name, size_t size, uint8 *b, uid_t uid, gid_t gid, uint32 ctime, uint32 mtime) | ||
| 625 | { | ||
| 626 | uint32 nod = mknod_fs(fs, parent_nod, name, FM_IFLNK | FM_IRWXU | FM_IRWXG | FM_IRWXO, uid, gid, 0, 0, ctime, mtime); | ||
| 627 | - extend_blk(fs, nod, 0, - (int)get_nod(fs, nod)->i_blocks / INOBLK); | ||
| 628 | - get_nod(fs, nod)->i_size = size; | ||
| 629 | + nod_info *ni; | ||
| 630 | + inode *node = get_nod(fs, nod, &ni); | ||
| 631 | + | ||
| 632 | + extend_blk(fs, nod, 0, - (int)node->i_blocks / INOBLK); | ||
| 633 | + node->i_size = size; | ||
| 634 | if(size <= 4 * (EXT2_TIND_BLOCK+1)) | ||
| 635 | { | ||
| 636 | - strncpy((char*)get_nod(fs, nod)->i_block, (char*)b, size); | ||
| 637 | + strncpy((char *)node->i_block, (char *)b, size); | ||
| 638 | + put_nod(ni); | ||
| 639 | return nod; | ||
| 640 | } | ||
| 641 | extend_blk(fs, nod, b, rndup(size, BLOCKSIZE) / BLOCKSIZE); | ||
| 642 | + put_nod(ni); | ||
| 643 | return nod; | ||
| 644 | } | ||
| 645 | |||
| 646 | @@ -1433,8 +1534,11 @@ mkfile_fs(filesystem *fs, uint32 parent_nod, const char *name, uint32 mode, size | ||
| 647 | { | ||
| 648 | uint8 * b; | ||
| 649 | uint32 nod = mknod_fs(fs, parent_nod, name, mode|FM_IFREG, uid, gid, 0, 0, ctime, mtime); | ||
| 650 | - extend_blk(fs, nod, 0, - (int)get_nod(fs, nod)->i_blocks / INOBLK); | ||
| 651 | - get_nod(fs, nod)->i_size = size; | ||
| 652 | + nod_info *ni; | ||
| 653 | + inode *node = get_nod(fs, nod, &ni); | ||
| 654 | + | ||
| 655 | + extend_blk(fs, nod, 0, - (int)node->i_blocks / INOBLK); | ||
| 656 | + node->i_size = size; | ||
| 657 | if (size) { | ||
| 658 | if(!(b = (uint8*)calloc(rndup(size, BLOCKSIZE), 1))) | ||
| 659 | error_msg_and_die("not enough mem to read file '%s'", name); | ||
| 660 | @@ -1444,6 +1548,7 @@ mkfile_fs(filesystem *fs, uint32 parent_nod, const char *name, uint32 mode, size | ||
| 661 | extend_blk(fs, nod, b, rndup(size, BLOCKSIZE) / BLOCKSIZE); | ||
| 662 | free(b); | ||
| 663 | } | ||
| 664 | + put_nod(ni); | ||
| 665 | return nod; | ||
| 666 | } | ||
| 667 | |||
| 668 | @@ -1766,6 +1871,7 @@ swap_goodblocks(filesystem *fs, inode *nod) | ||
| 669 | uint32 i,j; | ||
| 670 | int done=0; | ||
| 671 | uint32 *b,*b2; | ||
| 672 | + blk_info *bi, *bi2, *bi3; | ||
| 673 | |||
| 674 | uint32 nblk = nod->i_blocks / INOBLK; | ||
| 675 | if((nod->i_size && !nblk) || ((nod->i_mode & FM_IFBLK) == FM_IFBLK) || ((nod->i_mode & FM_IFCHR) == FM_IFCHR)) | ||
| 676 | @@ -1773,7 +1879,8 @@ swap_goodblocks(filesystem *fs, inode *nod) | ||
| 677 | nod->i_block[i] = swab32(nod->i_block[i]); | ||
| 678 | if(nblk <= EXT2_IND_BLOCK) | ||
| 679 | return; | ||
| 680 | - swap_block(get_blk(fs, nod->i_block[EXT2_IND_BLOCK])); | ||
| 681 | + swap_block(get_blk(fs, nod->i_block[EXT2_IND_BLOCK], &bi)); | ||
| 682 | + put_blk(bi); | ||
| 683 | if(nblk <= EXT2_DIND_BLOCK + BLOCKSIZE/4) | ||
| 684 | return; | ||
| 685 | /* Currently this will fail b'cos the number of blocks as stored | ||
| 686 | @@ -1791,29 +1898,37 @@ swap_goodblocks(filesystem *fs, inode *nod) | ||
| 687 | // ths function needs to be fixed for the same reasons - Xav | ||
| 688 | assert(nod->i_block[EXT2_DIND_BLOCK] != 0); | ||
| 689 | for(i = 0; i < BLOCKSIZE/4; i++) | ||
| 690 | - if(nblk > EXT2_IND_BLOCK + BLOCKSIZE/4 + (BLOCKSIZE/4)*i ) | ||
| 691 | - swap_block(get_blk(fs, ((uint32*)get_blk(fs, nod->i_block[EXT2_DIND_BLOCK]))[i])); | ||
| 692 | - swap_block(get_blk(fs, nod->i_block[EXT2_DIND_BLOCK])); | ||
| 693 | + if(nblk > EXT2_IND_BLOCK + BLOCKSIZE/4 + (BLOCKSIZE/4)*i ) { | ||
| 694 | + swap_block(get_blk(fs, ((uint32*)get_blk(fs, nod->i_block[EXT2_DIND_BLOCK], &bi))[i], &bi2)); | ||
| 695 | + put_blk(bi); | ||
| 696 | + put_blk(bi2); | ||
| 697 | + } | ||
| 698 | + swap_block(get_blk(fs, nod->i_block[EXT2_DIND_BLOCK], &bi)); | ||
| 699 | + put_blk(bi); | ||
| 700 | if(nblk <= EXT2_IND_BLOCK + BLOCKSIZE/4 + BLOCKSIZE/4 * BLOCKSIZE/4) | ||
| 701 | return; | ||
| 702 | /* Adding support for triple indirection */ | ||
| 703 | - b = (uint32*)get_blk(fs,nod->i_block[EXT2_TIND_BLOCK]); | ||
| 704 | + b = (uint32*)get_blk(fs,nod->i_block[EXT2_TIND_BLOCK], &bi); | ||
| 705 | for(i=0;i < BLOCKSIZE/4 && !done ; i++) { | ||
| 706 | - b2 = (uint32*)get_blk(fs,b[i]); | ||
| 707 | + b2 = (uint32*)get_blk(fs,b[i], &bi2); | ||
| 708 | for(j=0; j<BLOCKSIZE/4;j++) { | ||
| 709 | if (nblk > ( EXT2_IND_BLOCK + BLOCKSIZE/4 + | ||
| 710 | (BLOCKSIZE/4)*(BLOCKSIZE/4) + | ||
| 711 | i*(BLOCKSIZE/4)*(BLOCKSIZE/4) + | ||
| 712 | - j*(BLOCKSIZE/4)) ) | ||
| 713 | - swap_block(get_blk(fs,b2[j])); | ||
| 714 | + j*(BLOCKSIZE/4)) ) { | ||
| 715 | + swap_block(get_blk(fs,b2[j],&bi3)); | ||
| 716 | + put_blk(bi3); | ||
| 717 | + } | ||
| 718 | else { | ||
| 719 | done = 1; | ||
| 720 | break; | ||
| 721 | } | ||
| 722 | } | ||
| 723 | swap_block((uint8 *)b2); | ||
| 724 | + put_blk(bi2); | ||
| 725 | } | ||
| 726 | swap_block((uint8 *)b); | ||
| 727 | + put_blk(bi); | ||
| 728 | return; | ||
| 729 | } | ||
| 730 | |||
| 731 | @@ -1823,6 +1938,7 @@ swap_badblocks(filesystem *fs, inode *nod) | ||
| 732 | uint32 i,j; | ||
| 733 | int done=0; | ||
| 734 | uint32 *b,*b2; | ||
| 735 | + blk_info *bi, *bi2, *bi3; | ||
| 736 | |||
| 737 | uint32 nblk = nod->i_blocks / INOBLK; | ||
| 738 | if((nod->i_size && !nblk) || ((nod->i_mode & FM_IFBLK) == FM_IFBLK) || ((nod->i_mode & FM_IFCHR) == FM_IFCHR)) | ||
| 739 | @@ -1830,35 +1946,44 @@ swap_badblocks(filesystem *fs, inode *nod) | ||
| 740 | nod->i_block[i] = swab32(nod->i_block[i]); | ||
| 741 | if(nblk <= EXT2_IND_BLOCK) | ||
| 742 | return; | ||
| 743 | - swap_block(get_blk(fs, nod->i_block[EXT2_IND_BLOCK])); | ||
| 744 | + swap_block(get_blk(fs, nod->i_block[EXT2_IND_BLOCK], &bi)); | ||
| 745 | + put_blk(bi); | ||
| 746 | if(nblk <= EXT2_DIND_BLOCK + BLOCKSIZE/4) | ||
| 747 | return; | ||
| 748 | /* See comment in swap_goodblocks */ | ||
| 749 | assert(nod->i_block[EXT2_DIND_BLOCK] != 0); | ||
| 750 | - swap_block(get_blk(fs, nod->i_block[EXT2_DIND_BLOCK])); | ||
| 751 | + swap_block(get_blk(fs, nod->i_block[EXT2_DIND_BLOCK], &bi)); | ||
| 752 | + put_blk(bi); | ||
| 753 | for(i = 0; i < BLOCKSIZE/4; i++) | ||
| 754 | - if(nblk > EXT2_IND_BLOCK + BLOCKSIZE/4 + (BLOCKSIZE/4)*i ) | ||
| 755 | - swap_block(get_blk(fs, ((uint32*)get_blk(fs, nod->i_block[EXT2_DIND_BLOCK]))[i])); | ||
| 756 | + if(nblk > EXT2_IND_BLOCK + BLOCKSIZE/4 + (BLOCKSIZE/4)*i ) { | ||
| 757 | + swap_block(get_blk(fs, ((uint32*)get_blk(fs, nod->i_block[EXT2_DIND_BLOCK],&bi))[i], &bi2)); | ||
| 758 | + put_blk(bi); | ||
| 759 | + put_blk(bi2); | ||
| 760 | + } | ||
| 761 | if(nblk <= EXT2_IND_BLOCK + BLOCKSIZE/4 + BLOCKSIZE/4 * BLOCKSIZE/4) | ||
| 762 | return; | ||
| 763 | /* Adding support for triple indirection */ | ||
| 764 | - b = (uint32*)get_blk(fs,nod->i_block[EXT2_TIND_BLOCK]); | ||
| 765 | + b = (uint32*)get_blk(fs,nod->i_block[EXT2_TIND_BLOCK],&bi); | ||
| 766 | swap_block((uint8 *)b); | ||
| 767 | for(i=0;i < BLOCKSIZE/4 && !done ; i++) { | ||
| 768 | - b2 = (uint32*)get_blk(fs,b[i]); | ||
| 769 | + b2 = (uint32*)get_blk(fs,b[i],&bi2); | ||
| 770 | swap_block((uint8 *)b2); | ||
| 771 | for(j=0; j<BLOCKSIZE/4;j++) { | ||
| 772 | if (nblk > ( EXT2_IND_BLOCK + BLOCKSIZE/4 + | ||
| 773 | (BLOCKSIZE/4)*(BLOCKSIZE/4) + | ||
| 774 | i*(BLOCKSIZE/4)*(BLOCKSIZE/4) + | ||
| 775 | - j*(BLOCKSIZE/4)) ) | ||
| 776 | - swap_block(get_blk(fs,b2[j])); | ||
| 777 | + j*(BLOCKSIZE/4)) ) { | ||
| 778 | + swap_block(get_blk(fs,b2[j],&bi3)); | ||
| 779 | + put_blk(bi3); | ||
| 780 | + } | ||
| 781 | else { | ||
| 782 | done = 1; | ||
| 783 | break; | ||
| 784 | } | ||
| 785 | } | ||
| 786 | + put_blk(bi2); | ||
| 787 | } | ||
| 788 | + put_blk(bi); | ||
| 789 | return; | ||
| 790 | } | ||
| 791 | |||
| 792 | @@ -1867,9 +1992,11 @@ static void | ||
| 793 | swap_goodfs(filesystem *fs) | ||
| 794 | { | ||
| 795 | uint32 i; | ||
| 796 | + nod_info *ni; | ||
| 797 | + | ||
| 798 | for(i = 1; i < fs->sb.s_inodes_count; i++) | ||
| 799 | { | ||
| 800 | - inode *nod = get_nod(fs, i); | ||
| 801 | + inode *nod = get_nod(fs, i, &ni); | ||
| 802 | if(nod->i_mode & FM_IFDIR) | ||
| 803 | { | ||
| 804 | blockwalker bw; | ||
| 805 | @@ -1879,13 +2006,16 @@ swap_goodfs(filesystem *fs) | ||
| 806 | { | ||
| 807 | directory *d; | ||
| 808 | uint8 *b; | ||
| 809 | - b = get_blk(fs, bk); | ||
| 810 | + blk_info *bi; | ||
| 811 | + b = get_blk(fs, bk, &bi); | ||
| 812 | for(d = (directory*)b; (int8*)d + sizeof(*d) < (int8*)b + BLOCKSIZE; d = (directory*)((int8*)d + swab16(d->d_rec_len))) | ||
| 813 | swap_dir(d); | ||
| 814 | + put_blk(bi); | ||
| 815 | } | ||
| 816 | } | ||
| 817 | swap_goodblocks(fs, nod); | ||
| 818 | swap_nod(nod); | ||
| 819 | + put_nod(ni); | ||
| 820 | } | ||
| 821 | for(i=0;i<GRP_NBGROUPS(fs);i++) | ||
| 822 | swap_gd(&(fs->gd[i])); | ||
| 823 | @@ -1901,7 +2031,8 @@ swap_badfs(filesystem *fs) | ||
| 824 | swap_gd(&(fs->gd[i])); | ||
| 825 | for(i = 1; i < fs->sb.s_inodes_count; i++) | ||
| 826 | { | ||
| 827 | - inode *nod = get_nod(fs, i); | ||
| 828 | + nod_info *ni; | ||
| 829 | + inode *nod = get_nod(fs, i, &ni); | ||
| 830 | swap_nod(nod); | ||
| 831 | swap_badblocks(fs, nod); | ||
| 832 | if(nod->i_mode & FM_IFDIR) | ||
| 833 | @@ -1913,9 +2044,11 @@ swap_badfs(filesystem *fs) | ||
| 834 | { | ||
| 835 | directory *d; | ||
| 836 | uint8 *b; | ||
| 837 | - b = get_blk(fs, bk); | ||
| 838 | + blk_info *bi; | ||
| 839 | + b = get_blk(fs, bk, &bi); | ||
| 840 | for(d = (directory*)b; (int8*)d + sizeof(*d) < (int8*)b + BLOCKSIZE; d = (directory*)((int8*)d + d->d_rec_len)) | ||
| 841 | swap_dir(d); | ||
| 842 | + put_blk(bi); | ||
| 843 | } | ||
| 844 | } | ||
| 845 | } | ||
| 846 | @@ -1936,6 +2069,8 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp | ||
| 847 | uint32 j; | ||
| 848 | uint8 *bbm,*ibm; | ||
| 849 | inode *itab0; | ||
| 850 | + blk_info *bi; | ||
| 851 | + nod_info *ni; | ||
| 852 | |||
| 853 | if(nbresrvd < 0) | ||
| 854 | error_msg_and_die("reserved blocks value is invalid. Note: options have changed, see --help or the man page."); | ||
| 855 | @@ -2014,9 +2149,8 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp | ||
| 856 | /* Mark non-filesystem blocks and inodes as allocated */ | ||
| 857 | /* Mark system blocks and inodes as allocated */ | ||
| 858 | for(i = 0; i<nbgroups;i++) { | ||
| 859 | - | ||
| 860 | /* Block bitmap */ | ||
| 861 | - bbm = get_blk(fs,fs->gd[i].bg_block_bitmap); | ||
| 862 | + bbm = get_blk(fs,fs->gd[i].bg_block_bitmap, &bi); | ||
| 863 | //non-filesystem blocks | ||
| 864 | for(j = fs->gd[i].bg_free_blocks_count | ||
| 865 | + overhead_per_group + 1; j <= BLOCKSIZE * 8; j++) | ||
| 866 | @@ -2024,9 +2158,10 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp | ||
| 867 | //system blocks | ||
| 868 | for(j = 1; j <= overhead_per_group; j++) | ||
| 869 | allocate(bbm, j); | ||
| 870 | + put_blk(bi); | ||
| 871 | |||
| 872 | /* Inode bitmap */ | ||
| 873 | - ibm = get_blk(fs,fs->gd[i].bg_inode_bitmap); | ||
| 874 | + ibm = get_blk(fs,fs->gd[i].bg_inode_bitmap, &bi); | ||
| 875 | //non-filesystem inodes | ||
| 876 | for(j = fs->sb.s_inodes_per_group+1; j <= BLOCKSIZE * 8; j++) | ||
| 877 | allocate(ibm, j); | ||
| 878 | @@ -2035,6 +2170,7 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp | ||
| 879 | if(i == 0) | ||
| 880 | for(j = 1; j < EXT2_FIRST_INO; j++) | ||
| 881 | allocate(ibm, j); | ||
| 882 | + put_blk(bi); | ||
| 883 | } | ||
| 884 | |||
| 885 | // make root inode and directory | ||
| 886 | @@ -2042,13 +2178,14 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp | ||
| 887 | /* Also increment the directory count for group 0 */ | ||
| 888 | fs->gd[0].bg_free_inodes_count--; | ||
| 889 | fs->gd[0].bg_used_dirs_count = 1; | ||
| 890 | - itab0 = (inode *)get_blk(fs,fs->gd[0].bg_inode_table); | ||
| 891 | - itab0[EXT2_ROOT_INO-1].i_mode = FM_IFDIR | FM_IRWXU | FM_IRGRP | FM_IROTH | FM_IXGRP | FM_IXOTH; | ||
| 892 | - itab0[EXT2_ROOT_INO-1].i_ctime = fs_timestamp; | ||
| 893 | - itab0[EXT2_ROOT_INO-1].i_mtime = fs_timestamp; | ||
| 894 | - itab0[EXT2_ROOT_INO-1].i_atime = fs_timestamp; | ||
| 895 | - itab0[EXT2_ROOT_INO-1].i_size = BLOCKSIZE; | ||
| 896 | - itab0[EXT2_ROOT_INO-1].i_links_count = 2; | ||
| 897 | + itab0 = get_nod(fs, EXT2_ROOT_INO, &ni); | ||
| 898 | + itab0->i_mode = FM_IFDIR | FM_IRWXU | FM_IRGRP | FM_IROTH | FM_IXGRP | FM_IXOTH; | ||
| 899 | + itab0->i_ctime = fs_timestamp; | ||
| 900 | + itab0->i_mtime = fs_timestamp; | ||
| 901 | + itab0->i_atime = fs_timestamp; | ||
| 902 | + itab0->i_size = BLOCKSIZE; | ||
| 903 | + itab0->i_links_count = 2; | ||
| 904 | + put_nod(ni); | ||
| 905 | |||
| 906 | if(!(b = get_workblk())) | ||
| 907 | error_msg_and_die("get_workblk() failed."); | ||
| 908 | @@ -2067,6 +2204,8 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp | ||
| 909 | // make lost+found directory and reserve blocks | ||
| 910 | if(fs->sb.s_r_blocks_count) | ||
| 911 | { | ||
| 912 | + inode *node; | ||
| 913 | + | ||
| 914 | nod = mkdir_fs(fs, EXT2_ROOT_INO, "lost+found", FM_IRWXU, 0, 0, fs_timestamp, fs_timestamp); | ||
| 915 | memset(b, 0, BLOCKSIZE); | ||
| 916 | ((directory*)b)->d_rec_len = BLOCKSIZE; | ||
| 917 | @@ -2077,7 +2216,9 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp | ||
| 918 | fs->sb.s_r_blocks_count = fs->sb.s_blocks_count * MAX_RESERVED_BLOCKS; | ||
| 919 | for(i = 1; i < fs->sb.s_r_blocks_count; i++) | ||
| 920 | extend_blk(fs, nod, b, 1); | ||
| 921 | - get_nod(fs, nod)->i_size = fs->sb.s_r_blocks_count * BLOCKSIZE; | ||
| 922 | + node = get_nod(fs, nod, &ni); | ||
| 923 | + node->i_size = fs->sb.s_r_blocks_count * BLOCKSIZE; | ||
| 924 | + put_nod(ni); | ||
| 925 | } | ||
| 926 | free_workblk(b); | ||
| 927 | |||
| 928 | @@ -2153,16 +2294,23 @@ write_blocks(filesystem *fs, uint32 nod, FILE* f) | ||
| 929 | { | ||
| 930 | blockwalker bw; | ||
| 931 | uint32 bk; | ||
| 932 | - int32 fsize = get_nod(fs, nod)->i_size; | ||
| 933 | + nod_info *ni; | ||
| 934 | + inode *node = get_nod(fs, nod, &ni); | ||
| 935 | + int32 fsize = node->i_size; | ||
| 936 | + blk_info *bi; | ||
| 937 | + | ||
| 938 | init_bw(&bw); | ||
| 939 | while((bk = walk_bw(fs, nod, &bw, 0, 0)) != WALK_END) | ||
| 940 | { | ||
| 941 | if(fsize <= 0) | ||
| 942 | error_msg_and_die("wrong size while saving inode %d", nod); | ||
| 943 | - if(fwrite(get_blk(fs, bk), (fsize > BLOCKSIZE) ? BLOCKSIZE : fsize, 1, f) != 1) | ||
| 944 | + if(fwrite(get_blk(fs, bk, &bi), | ||
| 945 | + (fsize > BLOCKSIZE) ? BLOCKSIZE : fsize, 1, f) != 1) | ||
| 946 | error_msg_and_die("error while saving inode %d", nod); | ||
| 947 | + put_blk(bi); | ||
| 948 | fsize -= BLOCKSIZE; | ||
| 949 | } | ||
| 950 | + put_nod(ni); | ||
| 951 | } | ||
| 952 | |||
| 953 | |||
| 954 | @@ -2171,8 +2319,11 @@ static void | ||
| 955 | print_dev(filesystem *fs, uint32 nod) | ||
| 956 | { | ||
| 957 | int minor, major; | ||
| 958 | - minor = ((uint8*)get_nod(fs, nod)->i_block)[0]; | ||
| 959 | - major = ((uint8*)get_nod(fs, nod)->i_block)[1]; | ||
| 960 | + nod_info *ni; | ||
| 961 | + inode *node = get_nod(fs, nod, &ni); | ||
| 962 | + minor = ((uint8*)node->i_block)[0]; | ||
| 963 | + major = ((uint8*)node->i_block)[1]; | ||
| 964 | + put_nod(ni); | ||
| 965 | printf("major: %d, minor: %d\n", major, minor); | ||
| 966 | } | ||
| 967 | |||
| 968 | @@ -2188,7 +2339,8 @@ print_dir(filesystem *fs, uint32 nod) | ||
| 969 | { | ||
| 970 | directory *d; | ||
| 971 | uint8 *b; | ||
| 972 | - b = get_blk(fs, bk); | ||
| 973 | + blk_info *bi; | ||
| 974 | + b = get_blk(fs, bk, &bi); | ||
| 975 | for(d = (directory*)b; (int8*)d + sizeof(*d) < (int8*)b + BLOCKSIZE; d = (directory*)((int8*)d + d->d_rec_len)) | ||
| 976 | if(d->d_inode) | ||
| 977 | { | ||
| 978 | @@ -2198,6 +2350,7 @@ print_dir(filesystem *fs, uint32 nod) | ||
| 979 | putchar(d->d_name[i]); | ||
| 980 | printf("' (inode %d): rec_len: %d (name_len: %d)\n", d->d_inode, d->d_rec_len, d->d_name_len); | ||
| 981 | } | ||
| 982 | + put_blk(bi); | ||
| 983 | } | ||
| 984 | } | ||
| 985 | |||
| 986 | @@ -2205,14 +2358,18 @@ print_dir(filesystem *fs, uint32 nod) | ||
| 987 | static void | ||
| 988 | print_link(filesystem *fs, uint32 nod) | ||
| 989 | { | ||
| 990 | - if(!get_nod(fs, nod)->i_blocks) | ||
| 991 | - printf("links to '%s'\n", (char*)get_nod(fs, nod)->i_block); | ||
| 992 | + nod_info *ni; | ||
| 993 | + inode *node = get_nod(fs, nod, &ni); | ||
| 994 | + | ||
| 995 | + if(!node->i_blocks) | ||
| 996 | + printf("links to '%s'\n", (char*)node->i_block); | ||
| 997 | else | ||
| 998 | { | ||
| 999 | printf("links to '"); | ||
| 1000 | write_blocks(fs, nod, stdout); | ||
| 1001 | printf("'\n"); | ||
| 1002 | } | ||
| 1003 | + put_nod(ni); | ||
| 1004 | } | ||
| 1005 | |||
| 1006 | // make a ls-like printout of permissions | ||
| 1007 | @@ -2281,8 +2438,12 @@ print_inode(filesystem *fs, uint32 nod) | ||
| 1008 | { | ||
| 1009 | char *s; | ||
| 1010 | char perms[11]; | ||
| 1011 | - if(!get_nod(fs, nod)->i_mode) | ||
| 1012 | - return; | ||
| 1013 | + nod_info *ni; | ||
| 1014 | + inode *node = get_nod(fs, nod, &ni); | ||
| 1015 | + blk_info *bi; | ||
| 1016 | + | ||
| 1017 | + if(!node->i_mode) | ||
| 1018 | + goto out; | ||
| 1019 | switch(nod) | ||
| 1020 | { | ||
| 1021 | case EXT2_BAD_INO: | ||
| 1022 | @@ -2304,15 +2465,18 @@ print_inode(filesystem *fs, uint32 nod) | ||
| 1023 | default: | ||
| 1024 | s = (nod >= EXT2_FIRST_INO) ? "normal" : "unknown reserved"; | ||
| 1025 | } | ||
| 1026 | - printf("inode %d (%s, %d links): ", nod, s, get_nod(fs, nod)->i_links_count); | ||
| 1027 | - if(!allocated(GRP_GET_INODE_BITMAP(fs,nod), GRP_IBM_OFFSET(fs,nod))) | ||
| 1028 | + printf("inode %d (%s, %d links): ", nod, s, node->i_links_count); | ||
| 1029 | + if(!allocated(GRP_GET_INODE_BITMAP(fs,nod,&bi), GRP_IBM_OFFSET(fs,nod))) | ||
| 1030 | { | ||
| 1031 | + GRP_PUT_INODE_BITMAP(bi); | ||
| 1032 | printf("unallocated\n"); | ||
| 1033 | - return; | ||
| 1034 | + goto out; | ||
| 1035 | } | ||
| 1036 | - make_perms(get_nod(fs, nod)->i_mode, perms); | ||
| 1037 | - printf("%s, size: %d byte%s (%d block%s)\n", perms, plural(get_nod(fs, nod)->i_size), plural(get_nod(fs, nod)->i_blocks / INOBLK)); | ||
| 1038 | - switch(get_nod(fs, nod)->i_mode & FM_IFMT) | ||
| 1039 | + GRP_PUT_INODE_BITMAP(bi); | ||
| 1040 | + make_perms(node->i_mode, perms); | ||
| 1041 | + printf("%s, size: %d byte%s (%d block%s)\n", perms, | ||
| 1042 | + plural(node->i_size), plural(node->i_blocks / INOBLK)); | ||
| 1043 | + switch(node->i_mode & FM_IFMT) | ||
| 1044 | { | ||
| 1045 | case FM_IFSOCK: | ||
| 1046 | list_blocks(fs, nod); | ||
| 1047 | @@ -2340,6 +2504,8 @@ print_inode(filesystem *fs, uint32 nod) | ||
| 1048 | list_blocks(fs, nod); | ||
| 1049 | } | ||
| 1050 | printf("Done with inode %d\n",nod); | ||
| 1051 | +out: | ||
| 1052 | + put_nod(ni); | ||
| 1053 | } | ||
| 1054 | |||
| 1055 | // describes various fields in a filesystem | ||
| 1056 | @@ -2347,6 +2513,7 @@ static void | ||
| 1057 | print_fs(filesystem *fs) | ||
| 1058 | { | ||
| 1059 | uint32 i; | ||
| 1060 | + blk_info *bi; | ||
| 1061 | uint8 *ibm; | ||
| 1062 | |||
| 1063 | printf("%d blocks (%d free, %d reserved), first data block: %d\n", | ||
| 1064 | @@ -2369,13 +2536,16 @@ print_fs(filesystem *fs) | ||
| 1065 | fs->gd[i].bg_block_bitmap, fs->gd[i].bg_inode_bitmap, | ||
| 1066 | fs->gd[i].bg_inode_table); | ||
| 1067 | printf("block bitmap allocation:\n"); | ||
| 1068 | - print_bm(GRP_GET_GROUP_BBM(fs, i),fs->sb.s_blocks_per_group); | ||
| 1069 | + print_bm(GRP_GET_GROUP_BBM(fs, i, &bi), | ||
| 1070 | + fs->sb.s_blocks_per_group); | ||
| 1071 | + GRP_PUT_GROUP_BBM(bi); | ||
| 1072 | printf("inode bitmap allocation:\n"); | ||
| 1073 | - ibm = GRP_GET_GROUP_IBM(fs, i); | ||
| 1074 | + ibm = GRP_GET_GROUP_IBM(fs, i, &bi); | ||
| 1075 | print_bm(ibm, fs->sb.s_inodes_per_group); | ||
| 1076 | for (i = 1; i <= fs->sb.s_inodes_per_group; i++) | ||
| 1077 | if (allocated(ibm, i)) | ||
| 1078 | print_inode(fs, i); | ||
| 1079 | + GRP_PUT_GROUP_IBM(bi); | ||
| 1080 | } | ||
| 1081 | } | ||
| 1082 | |||
| 1083 | @@ -2646,9 +2816,17 @@ main(int argc, char **argv) | ||
| 1084 | |||
| 1085 | if(emptyval) { | ||
| 1086 | uint32 b; | ||
| 1087 | - for(b = 1; b < fs->sb.s_blocks_count; b++) | ||
| 1088 | - if(!allocated(GRP_GET_BLOCK_BITMAP(fs,b),GRP_BBM_OFFSET(fs,b))) | ||
| 1089 | - memset(get_blk(fs, b), emptyval, BLOCKSIZE); | ||
| 1090 | + for(b = 1; b < fs->sb.s_blocks_count; b++) { | ||
| 1091 | + blk_info *bi; | ||
| 1092 | + if(!allocated(GRP_GET_BLOCK_BITMAP(fs,b,&bi), | ||
| 1093 | + GRP_BBM_OFFSET(fs,b))) { | ||
| 1094 | + blk_info *bi2; | ||
| 1095 | + memset(get_blk(fs, b, &bi2), emptyval, | ||
| 1096 | + BLOCKSIZE); | ||
| 1097 | + put_blk(bi2); | ||
| 1098 | + } | ||
| 1099 | + GRP_PUT_BLOCK_BITMAP(bi); | ||
| 1100 | + } | ||
| 1101 | } | ||
| 1102 | if(verbose) | ||
| 1103 | print_fs(fs); | ||
| 1104 | @@ -2658,13 +2836,15 @@ main(int argc, char **argv) | ||
| 1105 | char fname[MAX_FILENAME]; | ||
| 1106 | char *p; | ||
| 1107 | FILE *fh; | ||
| 1108 | + nod_info *ni; | ||
| 1109 | if(!(nod = find_path(fs, EXT2_ROOT_INO, gopt[i]))) | ||
| 1110 | error_msg_and_die("path %s not found in filesystem", gopt[i]); | ||
| 1111 | while((p = strchr(gopt[i], '/'))) | ||
| 1112 | *p = '_'; | ||
| 1113 | SNPRINTF(fname, MAX_FILENAME-1, "%s.blk", gopt[i]); | ||
| 1114 | fh = xfopen(fname, "wb"); | ||
| 1115 | - fprintf(fh, "%d:", get_nod(fs, nod)->i_size); | ||
| 1116 | + fprintf(fh, "%d:", get_nod(fs, nod, &ni)->i_size); | ||
| 1117 | + put_nod(ni); | ||
| 1118 | flist_blocks(fs, nod, fh); | ||
| 1119 | fclose(fh); | ||
| 1120 | } | ||
| 1121 | -- | ||
| 1122 | 1.7.4.1 | ||
| 1123 | |||
diff --git a/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0003-Add-get_blkmap-and-put_blkmap.patch b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0003-Add-get_blkmap-and-put_blkmap.patch new file mode 100644 index 0000000000..1442dfaaed --- /dev/null +++ b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0003-Add-get_blkmap-and-put_blkmap.patch | |||
| @@ -0,0 +1,222 @@ | |||
| 1 | Upstream-Status: inappropriate | ||
| 2 | |||
| 3 | From c196bdeae7932c5d54bbdb7e7574d3cdae46ad02 Mon Sep 17 00:00:00 2001 | ||
| 4 | From: Corey Minyard <cminyard@mvista.com> | ||
| 5 | Date: Sat, 4 Jun 2011 22:04:24 -0500 | ||
| 6 | Subject: [PATCH 03/19] Add get_blkmap and put_blkmap. | ||
| 7 | |||
| 8 | Add routines for getting an putting a block map. This does not do | ||
| 9 | anything functional, but is getting ready for when blockmaps are | ||
| 10 | byteswapped when being read and written. | ||
| 11 | --- | ||
| 12 | genext2fs.c | 84 ++++++++++++++++++++++++++++++++++++++++------------------- | ||
| 13 | 1 files changed, 57 insertions(+), 27 deletions(-) | ||
| 14 | |||
| 15 | diff --git a/genext2fs.c b/genext2fs.c | ||
| 16 | index bd06369..0b5ba6f 100644 | ||
| 17 | --- a/genext2fs.c | ||
| 18 | +++ b/genext2fs.c | ||
| 19 | @@ -837,6 +837,36 @@ put_blk(blk_info *bi) | ||
| 20 | { | ||
| 21 | } | ||
| 22 | |||
| 23 | +// Used by get_blkmap/put_blkmap to hold information about an block map | ||
| 24 | +// owned by the user. | ||
| 25 | +typedef struct | ||
| 26 | +{ | ||
| 27 | + blk_info *bi; | ||
| 28 | +} blkmap_info; | ||
| 29 | + | ||
| 30 | +// Return a given block map from a filesystem. Make sure to call | ||
| 31 | +// put_blkmap when you are done with it. | ||
| 32 | +static inline uint32 * | ||
| 33 | +get_blkmap(filesystem *fs, uint32 blk, blkmap_info **rbmi) | ||
| 34 | +{ | ||
| 35 | + blkmap_info *bmi; | ||
| 36 | + uint8 *b; | ||
| 37 | + | ||
| 38 | + bmi = malloc(sizeof(*bmi)); | ||
| 39 | + if (!bmi) | ||
| 40 | + error_msg_and_die("get_blkmap: out of memory"); | ||
| 41 | + b = get_blk(fs, blk, &bmi->bi); | ||
| 42 | + *rbmi = bmi; | ||
| 43 | + return (uint32 *) b; | ||
| 44 | +} | ||
| 45 | + | ||
| 46 | +static inline void | ||
| 47 | +put_blkmap(blkmap_info *bmi) | ||
| 48 | +{ | ||
| 49 | + put_blk(bmi->bi); | ||
| 50 | + free(bmi); | ||
| 51 | +} | ||
| 52 | + | ||
| 53 | // Used by get_nod/put_nod to hold information about an inode owned | ||
| 54 | // by the user. | ||
| 55 | typedef struct | ||
| 56 | @@ -1020,12 +1050,12 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole) | ||
| 57 | { | ||
| 58 | uint32 *bkref = 0; | ||
| 59 | uint32 bk = 0; | ||
| 60 | + blkmap_info *bmi1 = NULL, *bmi2 = NULL, *bmi3 = NULL; | ||
| 61 | uint32 *b; | ||
| 62 | int extend = 0, reduce = 0; | ||
| 63 | inode *inod; | ||
| 64 | nod_info *ni; | ||
| 65 | uint32 *iblk; | ||
| 66 | - blk_info *bi1 = NULL, *bi2 = NULL, *bi3 = NULL; | ||
| 67 | |||
| 68 | if(create && (*create) < 0) | ||
| 69 | reduce = 1; | ||
| 70 | @@ -1072,7 +1102,7 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole) | ||
| 71 | iblk[bw->bpdir] = alloc_blk(fs,nod); | ||
| 72 | if(reduce) // free indirect block | ||
| 73 | free_blk(fs, iblk[bw->bpdir]); | ||
| 74 | - b = (uint32*)get_blk(fs, iblk[bw->bpdir], &bi1); | ||
| 75 | + b = get_blkmap(fs, iblk[bw->bpdir], &bmi1); | ||
| 76 | bkref = &b[bw->bpind]; | ||
| 77 | if(extend) // allocate first block | ||
| 78 | *bkref = hole ? 0 : alloc_blk(fs,nod); | ||
| 79 | @@ -1083,7 +1113,7 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole) | ||
| 80 | else if((bw->bpdir == EXT2_IND_BLOCK) && (bw->bpind < BLOCKSIZE/4 - 1)) | ||
| 81 | { | ||
| 82 | bw->bpind++; | ||
| 83 | - b = (uint32*)get_blk(fs, iblk[bw->bpdir], &bi1); | ||
| 84 | + b = get_blkmap(fs, iblk[bw->bpdir], &bmi1); | ||
| 85 | bkref = &b[bw->bpind]; | ||
| 86 | if(extend) // allocate block | ||
| 87 | *bkref = hole ? 0 : alloc_blk(fs,nod); | ||
| 88 | @@ -1101,12 +1131,12 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole) | ||
| 89 | iblk[bw->bpdir] = alloc_blk(fs,nod); | ||
| 90 | if(reduce) // free double indirect block | ||
| 91 | free_blk(fs, iblk[bw->bpdir]); | ||
| 92 | - b = (uint32*)get_blk(fs, iblk[bw->bpdir], &bi1); | ||
| 93 | + b = get_blkmap(fs, iblk[bw->bpdir], &bmi1); | ||
| 94 | if(extend) // allocate first indirect block | ||
| 95 | b[bw->bpind] = alloc_blk(fs,nod); | ||
| 96 | if(reduce) // free firstindirect block | ||
| 97 | free_blk(fs, b[bw->bpind]); | ||
| 98 | - b = (uint32*)get_blk(fs, b[bw->bpind], &bi1); | ||
| 99 | + b = get_blkmap(fs, b[bw->bpind], &bmi2); | ||
| 100 | bkref = &b[bw->bpdind]; | ||
| 101 | if(extend) // allocate first block | ||
| 102 | *bkref = hole ? 0 : alloc_blk(fs,nod); | ||
| 103 | @@ -1117,8 +1147,8 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole) | ||
| 104 | else if((bw->bpdir == EXT2_DIND_BLOCK) && (bw->bpdind < BLOCKSIZE/4 - 1)) | ||
| 105 | { | ||
| 106 | bw->bpdind++; | ||
| 107 | - b = (uint32*)get_blk(fs, iblk[bw->bpdir], &bi1); | ||
| 108 | - b = (uint32*)get_blk(fs, b[bw->bpind], &bi2); | ||
| 109 | + b = get_blkmap(fs, iblk[bw->bpdir], &bmi1); | ||
| 110 | + b = get_blkmap(fs, b[bw->bpind], &bmi2); | ||
| 111 | bkref = &b[bw->bpdind]; | ||
| 112 | if(extend) // allocate block | ||
| 113 | *bkref = hole ? 0 : alloc_blk(fs,nod); | ||
| 114 | @@ -1131,12 +1161,12 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole) | ||
| 115 | bw->bnum++; | ||
| 116 | bw->bpdind = 0; | ||
| 117 | bw->bpind++; | ||
| 118 | - b = (uint32*)get_blk(fs, iblk[bw->bpdir], &bi1); | ||
| 119 | + b = get_blkmap(fs, iblk[bw->bpdir], &bmi1); | ||
| 120 | if(extend) // allocate indirect block | ||
| 121 | b[bw->bpind] = alloc_blk(fs,nod); | ||
| 122 | if(reduce) // free indirect block | ||
| 123 | free_blk(fs, b[bw->bpind]); | ||
| 124 | - b = (uint32*)get_blk(fs, b[bw->bpind], &bi2); | ||
| 125 | + b = get_blkmap(fs, b[bw->bpind], &bmi2); | ||
| 126 | bkref = &b[bw->bpdind]; | ||
| 127 | if(extend) // allocate first block | ||
| 128 | *bkref = hole ? 0 : alloc_blk(fs,nod); | ||
| 129 | @@ -1159,17 +1189,17 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole) | ||
| 130 | iblk[bw->bpdir] = alloc_blk(fs,nod); | ||
| 131 | if(reduce) // free triple indirect block | ||
| 132 | free_blk(fs, iblk[bw->bpdir]); | ||
| 133 | - b = (uint32*)get_blk(fs, iblk[bw->bpdir], &bi1); | ||
| 134 | + b = get_blkmap(fs, iblk[bw->bpdir], &bmi1); | ||
| 135 | if(extend) // allocate first double indirect block | ||
| 136 | b[bw->bpind] = alloc_blk(fs,nod); | ||
| 137 | if(reduce) // free first double indirect block | ||
| 138 | free_blk(fs, b[bw->bpind]); | ||
| 139 | - b = (uint32*)get_blk(fs, b[bw->bpind], &bi2); | ||
| 140 | + b = get_blkmap(fs, b[bw->bpind], &bmi2); | ||
| 141 | if(extend) // allocate first indirect block | ||
| 142 | b[bw->bpdind] = alloc_blk(fs,nod); | ||
| 143 | if(reduce) // free first indirect block | ||
| 144 | free_blk(fs, b[bw->bpind]); | ||
| 145 | - b = (uint32*)get_blk(fs, b[bw->bpdind], &bi3); | ||
| 146 | + b = get_blkmap(fs, b[bw->bpdind], &bmi3); | ||
| 147 | bkref = &b[bw->bptind]; | ||
| 148 | if(extend) // allocate first data block | ||
| 149 | *bkref = hole ? 0 : alloc_blk(fs,nod); | ||
| 150 | @@ -1183,9 +1213,9 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole) | ||
| 151 | (bw->bptind < BLOCKSIZE/4 -1) ) | ||
| 152 | { | ||
| 153 | bw->bptind++; | ||
| 154 | - b = (uint32*)get_blk(fs, iblk[bw->bpdir], &bi1); | ||
| 155 | - b = (uint32*)get_blk(fs, b[bw->bpind], &bi2); | ||
| 156 | - b = (uint32*)get_blk(fs, b[bw->bpdind], &bi3); | ||
| 157 | + b = get_blkmap(fs, iblk[bw->bpdir], &bmi1); | ||
| 158 | + b = get_blkmap(fs, b[bw->bpind], &bmi2); | ||
| 159 | + b = get_blkmap(fs, b[bw->bpdind], &bmi3); | ||
| 160 | bkref = &b[bw->bptind]; | ||
| 161 | if(extend) // allocate data block | ||
| 162 | *bkref = hole ? 0 : alloc_blk(fs,nod); | ||
| 163 | @@ -1202,13 +1232,13 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole) | ||
| 164 | bw->bnum++; | ||
| 165 | bw->bptind = 0; | ||
| 166 | bw->bpdind++; | ||
| 167 | - b = (uint32*)get_blk(fs, iblk[bw->bpdir], &bi1); | ||
| 168 | - b = (uint32*)get_blk(fs, b[bw->bpind], &bi2); | ||
| 169 | + b = get_blkmap(fs, iblk[bw->bpdir], &bmi1); | ||
| 170 | + b = get_blkmap(fs, b[bw->bpind], &bmi2); | ||
| 171 | if(extend) // allocate single indirect block | ||
| 172 | b[bw->bpdind] = alloc_blk(fs,nod); | ||
| 173 | if(reduce) // free indirect block | ||
| 174 | free_blk(fs, b[bw->bpind]); | ||
| 175 | - b = (uint32*)get_blk(fs, b[bw->bpdind], &bi3); | ||
| 176 | + b = get_blkmap(fs, b[bw->bpdind], &bmi3); | ||
| 177 | bkref = &b[bw->bptind]; | ||
| 178 | if(extend) // allocate first data block | ||
| 179 | *bkref = hole ? 0 : alloc_blk(fs,nod); | ||
| 180 | @@ -1225,17 +1255,17 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole) | ||
| 181 | bw->bpdind = 0; | ||
| 182 | bw->bptind = 0; | ||
| 183 | bw->bpind++; | ||
| 184 | - b = (uint32*)get_blk(fs, iblk[bw->bpdir], &bi1); | ||
| 185 | + b = get_blkmap(fs, iblk[bw->bpdir], &bmi1); | ||
| 186 | if(extend) // allocate double indirect block | ||
| 187 | b[bw->bpind] = alloc_blk(fs,nod); | ||
| 188 | if(reduce) // free double indirect block | ||
| 189 | free_blk(fs, b[bw->bpind]); | ||
| 190 | - b = (uint32*)get_blk(fs, b[bw->bpind], &bi2); | ||
| 191 | + b = get_blkmap(fs, b[bw->bpind], &bmi2); | ||
| 192 | if(extend) // allocate single indirect block | ||
| 193 | b[bw->bpdind] = alloc_blk(fs,nod); | ||
| 194 | if(reduce) // free indirect block | ||
| 195 | free_blk(fs, b[bw->bpind]); | ||
| 196 | - b = (uint32*)get_blk(fs, b[bw->bpdind], &bi3); | ||
| 197 | + b = get_blkmap(fs, b[bw->bpdind], &bmi3); | ||
| 198 | bkref = &b[bw->bptind]; | ||
| 199 | if(extend) // allocate first block | ||
| 200 | *bkref = hole ? 0 : alloc_blk(fs,nod); | ||
| 201 | @@ -1247,12 +1277,12 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole) | ||
| 202 | /* End change for walking triple indirection */ | ||
| 203 | |||
| 204 | bk = *bkref; | ||
| 205 | - if (bi3) | ||
| 206 | - put_blk(bi3); | ||
| 207 | - if (bi2) | ||
| 208 | - put_blk(bi2); | ||
| 209 | - if (bi1) | ||
| 210 | - put_blk(bi1); | ||
| 211 | + if (bmi3) | ||
| 212 | + put_blkmap(bmi3); | ||
| 213 | + if (bmi2) | ||
| 214 | + put_blkmap(bmi2); | ||
| 215 | + if (bmi1) | ||
| 216 | + put_blkmap(bmi1); | ||
| 217 | |||
| 218 | if(bk) | ||
| 219 | { | ||
| 220 | -- | ||
| 221 | 1.7.4.1 | ||
| 222 | |||
diff --git a/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0004-Add-a-dirwalker-for-walking-through-directory-entrie.patch b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0004-Add-a-dirwalker-for-walking-through-directory-entrie.patch new file mode 100644 index 0000000000..014a69409f --- /dev/null +++ b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0004-Add-a-dirwalker-for-walking-through-directory-entrie.patch | |||
| @@ -0,0 +1,357 @@ | |||
| 1 | Upstream-Status: inappropriate | ||
| 2 | |||
| 3 | From 3d47e37e21f6a2ced489d49e8bf5a5c24bb9baaf Mon Sep 17 00:00:00 2001 | ||
| 4 | From: Corey Minyard <cminyard@mvista.com> | ||
| 5 | Date: Sun, 5 Jun 2011 09:36:11 -0500 | ||
| 6 | Subject: [PATCH 04/19] Add a dirwalker for walking through directory entries | ||
| 7 | |||
| 8 | The code to walk directory items was messy, to say the least. Write a | ||
| 9 | clean structure to do this. | ||
| 10 | |||
| 11 | Also, remove d_name[0]. This is bad style, and newer compilers will | ||
| 12 | think it is really a zero-length array and will abort if trying to write | ||
| 13 | any data to it, since the compiler thinks it has no contents. | ||
| 14 | --- | ||
| 15 | genext2fs.c | 210 +++++++++++++++++++++++++++++++++++++++++++---------------- | ||
| 16 | 1 files changed, 154 insertions(+), 56 deletions(-) | ||
| 17 | |||
| 18 | diff --git a/genext2fs.c b/genext2fs.c | ||
| 19 | index 0b5ba6f..03d1b27 100644 | ||
| 20 | --- a/genext2fs.c | ||
| 21 | +++ b/genext2fs.c | ||
| 22 | @@ -533,7 +533,6 @@ typedef struct | ||
| 23 | typedef struct | ||
| 24 | { | ||
| 25 | directory_decl | ||
| 26 | - char d_name[0]; | ||
| 27 | } directory; | ||
| 28 | |||
| 29 | typedef uint8 block[BLOCKSIZE]; | ||
| 30 | @@ -795,6 +794,8 @@ static inline uint8 * | ||
| 31 | get_workblk(void) | ||
| 32 | { | ||
| 33 | unsigned char* b=calloc(1,BLOCKSIZE); | ||
| 34 | + if (!b) | ||
| 35 | + error_msg_and_die("get_workblk() failed, out of memory"); | ||
| 36 | return b; | ||
| 37 | } | ||
| 38 | static inline void | ||
| 39 | @@ -902,6 +903,126 @@ put_nod(nod_info *ni) | ||
| 40 | free(ni); | ||
| 41 | } | ||
| 42 | |||
| 43 | +// Used to hold state information while walking a directory inode. | ||
| 44 | +typedef struct | ||
| 45 | +{ | ||
| 46 | + directory d; | ||
| 47 | + filesystem *fs; | ||
| 48 | + uint32 nod; | ||
| 49 | + directory *last_d; | ||
| 50 | + uint8 *b; | ||
| 51 | + blk_info *bi; | ||
| 52 | +} dirwalker; | ||
| 53 | + | ||
| 54 | +// Start a directory walk on the given inode. You must pass in a | ||
| 55 | +// dirwalker structure, then use that dirwalker for future operations. | ||
| 56 | +// Call put_dir when you are done walking the directory. | ||
| 57 | +static inline directory * | ||
| 58 | +get_dir(filesystem *fs, uint32 nod, dirwalker *dw) | ||
| 59 | +{ | ||
| 60 | + dw->fs = fs; | ||
| 61 | + dw->b = get_blk(fs, nod, &dw->bi); | ||
| 62 | + dw->nod = nod; | ||
| 63 | + dw->last_d = (directory *) dw->b; | ||
| 64 | + | ||
| 65 | + memcpy(&dw->d, dw->last_d, sizeof(directory)); | ||
| 66 | + return &dw->d; | ||
| 67 | +} | ||
| 68 | + | ||
| 69 | +// Move to the next directory. | ||
| 70 | +static inline directory * | ||
| 71 | +next_dir(dirwalker *dw) | ||
| 72 | +{ | ||
| 73 | + directory *next_d = (directory *)((int8*)dw->last_d + dw->d.d_rec_len); | ||
| 74 | + | ||
| 75 | + memcpy(dw->last_d, &dw->d, sizeof(directory)); | ||
| 76 | + | ||
| 77 | + if (((int8 *) next_d) >= ((int8 *) dw->b + BLOCKSIZE)) | ||
| 78 | + return NULL; | ||
| 79 | + | ||
| 80 | + dw->last_d = next_d; | ||
| 81 | + memcpy(&dw->d, next_d, sizeof(directory)); | ||
| 82 | + return &dw->d; | ||
| 83 | +} | ||
| 84 | + | ||
| 85 | +// Call then when you are done with the directory walk. | ||
| 86 | +static inline void | ||
| 87 | +put_dir(dirwalker *dw) | ||
| 88 | +{ | ||
| 89 | + memcpy(dw->last_d, &dw->d, sizeof(directory)); | ||
| 90 | + | ||
| 91 | + if (dw->nod == 0) | ||
| 92 | + free_workblk(dw->b); | ||
| 93 | + else | ||
| 94 | + put_blk(dw->bi); | ||
| 95 | +} | ||
| 96 | + | ||
| 97 | +// Create a new directory block with the given inode as it's destination | ||
| 98 | +// and append it to the current dirwalker. | ||
| 99 | +static directory * | ||
| 100 | +new_dir(filesystem *fs, uint32 dnod, const char *name, int nlen, dirwalker *dw) | ||
| 101 | +{ | ||
| 102 | + directory *d; | ||
| 103 | + | ||
| 104 | + dw->fs = fs; | ||
| 105 | + dw->b = get_workblk(); | ||
| 106 | + dw->nod = 0; | ||
| 107 | + dw->last_d = (directory *) dw->b; | ||
| 108 | + d = &dw->d; | ||
| 109 | + d->d_inode = dnod; | ||
| 110 | + d->d_rec_len = BLOCKSIZE; | ||
| 111 | + d->d_name_len = nlen; | ||
| 112 | + strncpy(((char *) dw->last_d) + sizeof(directory), name, nlen); | ||
| 113 | + return d; | ||
| 114 | +} | ||
| 115 | + | ||
| 116 | +// Shrink the current directory entry, make a new one with the free | ||
| 117 | +// space, and return the new directory entry (making it current). | ||
| 118 | +static inline directory * | ||
| 119 | +shrink_dir(dirwalker *dw, uint32 nod, const char *name, int nlen) | ||
| 120 | +{ | ||
| 121 | + int reclen, preclen; | ||
| 122 | + directory *d = &dw->d; | ||
| 123 | + | ||
| 124 | + reclen = d->d_rec_len; | ||
| 125 | + d->d_rec_len = sizeof(directory) + rndup(d->d_name_len, 4); | ||
| 126 | + preclen = d->d_rec_len; | ||
| 127 | + reclen -= preclen; | ||
| 128 | + memcpy(dw->last_d, &dw->d, sizeof(directory)); | ||
| 129 | + | ||
| 130 | + dw->last_d = (directory *) (((int8 *) dw->last_d) + preclen); | ||
| 131 | + d->d_rec_len = reclen; | ||
| 132 | + d->d_inode = nod; | ||
| 133 | + d->d_name_len = nlen; | ||
| 134 | + strncpy(((char *) dw->last_d) + sizeof(directory), name, nlen); | ||
| 135 | + | ||
| 136 | + return d; | ||
| 137 | +} | ||
| 138 | + | ||
| 139 | +// Return the current block the directory is walking | ||
| 140 | +static inline uint8 * | ||
| 141 | +dir_data(dirwalker *dw) | ||
| 142 | +{ | ||
| 143 | + return dw->b; | ||
| 144 | +} | ||
| 145 | + | ||
| 146 | +// Return the pointer to the name for the current directory | ||
| 147 | +static inline char * | ||
| 148 | +dir_name(dirwalker *dw) | ||
| 149 | +{ | ||
| 150 | + return ((char *) dw->last_d) + sizeof(directory); | ||
| 151 | +} | ||
| 152 | + | ||
| 153 | +// Set the name for the current directory. Note that this doesn't | ||
| 154 | +// verify that there is space for the directory name, you must do | ||
| 155 | +// that yourself. | ||
| 156 | +static void | ||
| 157 | +dir_set_name(dirwalker *dw, const char *name, int nlen) | ||
| 158 | +{ | ||
| 159 | + dw->d.d_name_len = nlen; | ||
| 160 | + strncpy(((char *) dw->last_d) + sizeof(directory), name, nlen); | ||
| 161 | +} | ||
| 162 | + | ||
| 163 | // allocate a given block/inode in the bitmap | ||
| 164 | // allocate first free if item == 0 | ||
| 165 | static uint32 | ||
| 166 | @@ -1354,11 +1475,10 @@ extend_blk(filesystem *fs, uint32 nod, block b, int amount) | ||
| 167 | static void | ||
| 168 | add2dir(filesystem *fs, uint32 dnod, uint32 nod, const char* name) | ||
| 169 | { | ||
| 170 | - blockwalker bw; | ||
| 171 | + blockwalker bw, lbw; | ||
| 172 | uint32 bk; | ||
| 173 | - uint8 *b; | ||
| 174 | - blk_info *bi; | ||
| 175 | directory *d; | ||
| 176 | + dirwalker dw; | ||
| 177 | int reclen, nlen; | ||
| 178 | inode *node; | ||
| 179 | inode *pnode; | ||
| 180 | @@ -1376,55 +1496,46 @@ add2dir(filesystem *fs, uint32 dnod, uint32 nod, const char* name) | ||
| 181 | if(reclen > BLOCKSIZE) | ||
| 182 | error_msg_and_die("bad name '%s' (too long)", name); | ||
| 183 | init_bw(&bw); | ||
| 184 | + lbw = bw; | ||
| 185 | while((bk = walk_bw(fs, dnod, &bw, 0, 0)) != WALK_END) // for all blocks in dir | ||
| 186 | { | ||
| 187 | - b = get_blk(fs, bk, &bi); | ||
| 188 | // for all dir entries in block | ||
| 189 | - for(d = (directory*)b; (int8*)d + sizeof(*d) < (int8*)b + BLOCKSIZE; d = (directory*)((int8*)d + d->d_rec_len)) | ||
| 190 | + for(d = get_dir(fs, bk, &dw); d; d = next_dir(&dw)) | ||
| 191 | { | ||
| 192 | // if empty dir entry, large enough, use it | ||
| 193 | if((!d->d_inode) && (d->d_rec_len >= reclen)) | ||
| 194 | { | ||
| 195 | d->d_inode = nod; | ||
| 196 | node = get_nod(fs, nod, &ni); | ||
| 197 | + dir_set_name(&dw, name, nlen); | ||
| 198 | + put_dir(&dw); | ||
| 199 | node->i_links_count++; | ||
| 200 | - d->d_name_len = nlen; | ||
| 201 | - strncpy(d->d_name, name, nlen); | ||
| 202 | put_nod(ni); | ||
| 203 | goto out; | ||
| 204 | } | ||
| 205 | // if entry with enough room (last one?), shrink it & use it | ||
| 206 | if(d->d_rec_len >= (sizeof(directory) + rndup(d->d_name_len, 4) + reclen)) | ||
| 207 | { | ||
| 208 | - reclen = d->d_rec_len; | ||
| 209 | - d->d_rec_len = sizeof(directory) + rndup(d->d_name_len, 4); | ||
| 210 | - reclen -= d->d_rec_len; | ||
| 211 | - d = (directory*) (((int8*)d) + d->d_rec_len); | ||
| 212 | - d->d_rec_len = reclen; | ||
| 213 | - d->d_inode = nod; | ||
| 214 | node = get_nod(fs, nod, &ni); | ||
| 215 | + d = shrink_dir(&dw, nod, name, nlen); | ||
| 216 | + put_dir(&dw); | ||
| 217 | node->i_links_count++; | ||
| 218 | - d->d_name_len = nlen; | ||
| 219 | - strncpy(d->d_name, name, nlen); | ||
| 220 | put_nod(ni); | ||
| 221 | goto out; | ||
| 222 | } | ||
| 223 | } | ||
| 224 | + put_dir(&dw); | ||
| 225 | + lbw = bw; | ||
| 226 | } | ||
| 227 | // we found no free entry in the directory, so we add a block | ||
| 228 | - if(!(b = get_workblk())) | ||
| 229 | - error_msg_and_die("get_workblk() failed."); | ||
| 230 | - d = (directory*)b; | ||
| 231 | - d->d_inode = nod; | ||
| 232 | node = get_nod(fs, nod, &ni); | ||
| 233 | + d = new_dir(fs, nod, name, nlen, &dw); | ||
| 234 | node->i_links_count++; | ||
| 235 | put_nod(ni); | ||
| 236 | - d->d_rec_len = BLOCKSIZE; | ||
| 237 | - d->d_name_len = nlen; | ||
| 238 | - strncpy(d->d_name, name, nlen); | ||
| 239 | - extend_blk(fs, dnod, b, 1); | ||
| 240 | + next_dir(&dw); // Force the data into the buffer | ||
| 241 | + extend_blk(fs, dnod, dir_data(&dw), 1); | ||
| 242 | + put_dir(&dw); | ||
| 243 | pnode->i_size += BLOCKSIZE; | ||
| 244 | - free_workblk(b); | ||
| 245 | out: | ||
| 246 | put_nod(dni); | ||
| 247 | } | ||
| 248 | @@ -1435,20 +1546,18 @@ find_dir(filesystem *fs, uint32 nod, const char * name) | ||
| 249 | { | ||
| 250 | blockwalker bw; | ||
| 251 | uint32 bk; | ||
| 252 | - blk_info *bi; | ||
| 253 | int nlen = strlen(name); | ||
| 254 | init_bw(&bw); | ||
| 255 | while((bk = walk_bw(fs, nod, &bw, 0, 0)) != WALK_END) | ||
| 256 | { | ||
| 257 | directory *d; | ||
| 258 | - uint8 *b; | ||
| 259 | - b = get_blk(fs, bk, &bi); | ||
| 260 | - for(d = (directory*)b; (int8*)d + sizeof(*d) < (int8*)b + BLOCKSIZE; d = (directory*)((int8*)d + d->d_rec_len)) | ||
| 261 | - if(d->d_inode && (nlen == d->d_name_len) && !strncmp(d->d_name, name, nlen)) { | ||
| 262 | - put_blk(bi); | ||
| 263 | + dirwalker dw; | ||
| 264 | + for (d = get_dir(fs, bk, &dw); d; d=next_dir(&dw)) | ||
| 265 | + if(d->d_inode && (nlen == d->d_name_len) && !strncmp(dir_name(&dw), name, nlen)) { | ||
| 266 | + put_dir(&dw); | ||
| 267 | return d->d_inode; | ||
| 268 | } | ||
| 269 | - put_blk(bi); | ||
| 270 | + put_dir(&dw); | ||
| 271 | } | ||
| 272 | return 0; | ||
| 273 | } | ||
| 274 | @@ -2090,8 +2199,7 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp | ||
| 275 | { | ||
| 276 | uint32 i; | ||
| 277 | filesystem *fs; | ||
| 278 | - directory *d; | ||
| 279 | - uint8 * b; | ||
| 280 | + dirwalker dw; | ||
| 281 | uint32 nod, first_block; | ||
| 282 | uint32 nbgroups,nbinodes_per_group,overhead_per_group,free_blocks, | ||
| 283 | free_blocks_per_group,nbblocks_per_group,min_nbgroups; | ||
| 284 | @@ -2217,26 +2325,20 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp | ||
| 285 | itab0->i_links_count = 2; | ||
| 286 | put_nod(ni); | ||
| 287 | |||
| 288 | - if(!(b = get_workblk())) | ||
| 289 | - error_msg_and_die("get_workblk() failed."); | ||
| 290 | - d = (directory*)b; | ||
| 291 | - d->d_inode = EXT2_ROOT_INO; | ||
| 292 | - d->d_rec_len = sizeof(directory)+4; | ||
| 293 | - d->d_name_len = 1; | ||
| 294 | - strcpy(d->d_name, "."); | ||
| 295 | - d = (directory*)(b + d->d_rec_len); | ||
| 296 | - d->d_inode = EXT2_ROOT_INO; | ||
| 297 | - d->d_rec_len = BLOCKSIZE - (sizeof(directory)+4); | ||
| 298 | - d->d_name_len = 2; | ||
| 299 | - strcpy(d->d_name, ".."); | ||
| 300 | - extend_blk(fs, EXT2_ROOT_INO, b, 1); | ||
| 301 | + new_dir(fs, EXT2_ROOT_INO, ".", 1, &dw); | ||
| 302 | + shrink_dir(&dw, EXT2_ROOT_INO, "..", 2); | ||
| 303 | + next_dir(&dw); // Force the data into the buffer | ||
| 304 | + extend_blk(fs, EXT2_ROOT_INO, dir_data(&dw), 1); | ||
| 305 | + put_dir(&dw); | ||
| 306 | |||
| 307 | // make lost+found directory and reserve blocks | ||
| 308 | if(fs->sb.s_r_blocks_count) | ||
| 309 | { | ||
| 310 | inode *node; | ||
| 311 | + uint8 *b; | ||
| 312 | |||
| 313 | nod = mkdir_fs(fs, EXT2_ROOT_INO, "lost+found", FM_IRWXU, 0, 0, fs_timestamp, fs_timestamp); | ||
| 314 | + b = get_workblk(); | ||
| 315 | memset(b, 0, BLOCKSIZE); | ||
| 316 | ((directory*)b)->d_rec_len = BLOCKSIZE; | ||
| 317 | /* We run into problems with e2fsck if directory lost+found grows | ||
| 318 | @@ -2246,11 +2348,11 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp | ||
| 319 | fs->sb.s_r_blocks_count = fs->sb.s_blocks_count * MAX_RESERVED_BLOCKS; | ||
| 320 | for(i = 1; i < fs->sb.s_r_blocks_count; i++) | ||
| 321 | extend_blk(fs, nod, b, 1); | ||
| 322 | + free_workblk(b); | ||
| 323 | node = get_nod(fs, nod, &ni); | ||
| 324 | node->i_size = fs->sb.s_r_blocks_count * BLOCKSIZE; | ||
| 325 | put_nod(ni); | ||
| 326 | } | ||
| 327 | - free_workblk(b); | ||
| 328 | |||
| 329 | // administrative info | ||
| 330 | fs->sb.s_state = 1; | ||
| 331 | @@ -2368,19 +2470,15 @@ print_dir(filesystem *fs, uint32 nod) | ||
| 332 | while((bk = walk_bw(fs, nod, &bw, 0, 0)) != WALK_END) | ||
| 333 | { | ||
| 334 | directory *d; | ||
| 335 | - uint8 *b; | ||
| 336 | - blk_info *bi; | ||
| 337 | - b = get_blk(fs, bk, &bi); | ||
| 338 | - for(d = (directory*)b; (int8*)d + sizeof(*d) < (int8*)b + BLOCKSIZE; d = (directory*)((int8*)d + d->d_rec_len)) | ||
| 339 | + dirwalker dw; | ||
| 340 | + for (d = get_dir(fs, bk, &dw); d; d = next_dir(&dw)) | ||
| 341 | if(d->d_inode) | ||
| 342 | { | ||
| 343 | - int i; | ||
| 344 | printf("entry '"); | ||
| 345 | - for(i = 0; i < d->d_name_len; i++) | ||
| 346 | - putchar(d->d_name[i]); | ||
| 347 | + fwrite(dir_name(&dw), 1, d->d_name_len, stdout); | ||
| 348 | printf("' (inode %d): rec_len: %d (name_len: %d)\n", d->d_inode, d->d_rec_len, d->d_name_len); | ||
| 349 | } | ||
| 350 | - put_blk(bi); | ||
| 351 | + put_dir(&dw); | ||
| 352 | } | ||
| 353 | } | ||
| 354 | |||
| 355 | -- | ||
| 356 | 1.7.4.1 | ||
| 357 | |||
diff --git a/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0005-Make-filesystem-struct-not-an-overloay.patch b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0005-Make-filesystem-struct-not-an-overloay.patch new file mode 100644 index 0000000000..ccc33feaac --- /dev/null +++ b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0005-Make-filesystem-struct-not-an-overloay.patch | |||
| @@ -0,0 +1,374 @@ | |||
| 1 | Upstream-Status: inappropriate | ||
| 2 | |||
| 3 | From f2090608aef32f3012b1c5943b73314176bce832 Mon Sep 17 00:00:00 2001 | ||
| 4 | From: Corey Minyard <cminyard@mvista.com> | ||
| 5 | Date: Sun, 5 Jun 2011 10:09:51 -0500 | ||
| 6 | Subject: [PATCH 05/19] Make filesystem struct not an overloay | ||
| 7 | |||
| 8 | Having the filesystem structure just be a big overlay for the raw data | ||
| 9 | means you can't easily carry along any useful metadata in it. So | ||
| 10 | modify the filesystem structure to not be an overlay, but allocate the | ||
| 11 | data and various pieces to be components inside the structure. | ||
| 12 | --- | ||
| 13 | genext2fs.c | 150 +++++++++++++++++++++++++++++++++-------------------------- | ||
| 14 | 1 files changed, 84 insertions(+), 66 deletions(-) | ||
| 15 | |||
| 16 | diff --git a/genext2fs.c b/genext2fs.c | ||
| 17 | index 03d1b27..46c9605 100644 | ||
| 18 | --- a/genext2fs.c | ||
| 19 | +++ b/genext2fs.c | ||
| 20 | @@ -233,8 +233,8 @@ struct stats { | ||
| 21 | |||
| 22 | // Number of groups in the filesystem | ||
| 23 | #define GRP_NBGROUPS(fs) \ | ||
| 24 | - (((fs)->sb.s_blocks_count - fs->sb.s_first_data_block + \ | ||
| 25 | - (fs)->sb.s_blocks_per_group - 1) / (fs)->sb.s_blocks_per_group) | ||
| 26 | + (((fs)->sb->s_blocks_count - fs->sb->s_first_data_block + \ | ||
| 27 | + (fs)->sb->s_blocks_per_group - 1) / (fs)->sb->s_blocks_per_group) | ||
| 28 | |||
| 29 | // Get/put group block bitmap (bbm) given the group number | ||
| 30 | #define GRP_GET_GROUP_BBM(fs,grp,bi) ( get_blk((fs),(fs)->gd[(grp)].bg_block_bitmap,(bi)) ) | ||
| 31 | @@ -245,7 +245,7 @@ struct stats { | ||
| 32 | #define GRP_PUT_GROUP_IBM(bi) ( put_blk((bi)) ) | ||
| 33 | |||
| 34 | // Given an inode number find the group it belongs to | ||
| 35 | -#define GRP_GROUP_OF_INODE(fs,nod) ( ((nod)-1) / (fs)->sb.s_inodes_per_group) | ||
| 36 | +#define GRP_GROUP_OF_INODE(fs,nod) ( ((nod)-1) / (fs)->sb->s_inodes_per_group) | ||
| 37 | |||
| 38 | //Given an inode number get/put the inode bitmap that covers it | ||
| 39 | #define GRP_GET_INODE_BITMAP(fs,nod,bi) \ | ||
| 40 | @@ -255,10 +255,10 @@ struct stats { | ||
| 41 | |||
| 42 | //Given an inode number find its offset within the inode bitmap that covers it | ||
| 43 | #define GRP_IBM_OFFSET(fs,nod) \ | ||
| 44 | - ( (nod) - GRP_GROUP_OF_INODE((fs),(nod))*(fs)->sb.s_inodes_per_group ) | ||
| 45 | + ( (nod) - GRP_GROUP_OF_INODE((fs),(nod))*(fs)->sb->s_inodes_per_group ) | ||
| 46 | |||
| 47 | // Given a block number find the group it belongs to | ||
| 48 | -#define GRP_GROUP_OF_BLOCK(fs,blk) ( ((blk)-1) / (fs)->sb.s_blocks_per_group) | ||
| 49 | +#define GRP_GROUP_OF_BLOCK(fs,blk) ( ((blk)-1) / (fs)->sb->s_blocks_per_group) | ||
| 50 | |||
| 51 | //Given a block number get/put the block bitmap that covers it | ||
| 52 | #define GRP_GET_BLOCK_BITMAP(fs,blk,bi) \ | ||
| 53 | @@ -268,7 +268,7 @@ struct stats { | ||
| 54 | |||
| 55 | //Given a block number find its offset within the block bitmap that covers it | ||
| 56 | #define GRP_BBM_OFFSET(fs,blk) \ | ||
| 57 | - ( (blk) - GRP_GROUP_OF_BLOCK((fs),(blk))*(fs)->sb.s_blocks_per_group ) | ||
| 58 | + ( (blk) - GRP_GROUP_OF_BLOCK((fs),(blk))*(fs)->sb->s_blocks_per_group ) | ||
| 59 | |||
| 60 | |||
| 61 | // used types | ||
| 62 | @@ -577,9 +577,10 @@ typedef struct | ||
| 63 | #if BLOCKSIZE == 1024 | ||
| 64 | typedef struct | ||
| 65 | { | ||
| 66 | - block zero; // The famous block 0 | ||
| 67 | - superblock sb; // The superblock | ||
| 68 | - groupdescriptor gd[0]; // The group descriptors | ||
| 69 | + uint8 *data; | ||
| 70 | + superblock *sb; | ||
| 71 | + groupdescriptor *gd; | ||
| 72 | + uint32 nheadblocks; | ||
| 73 | } filesystem; | ||
| 74 | #else | ||
| 75 | #error UNHANDLED BLOCKSIZE | ||
| 76 | @@ -830,7 +831,7 @@ typedef struct | ||
| 77 | static inline uint8 * | ||
| 78 | get_blk(filesystem *fs, uint32 blk, blk_info **rbi) | ||
| 79 | { | ||
| 80 | - return (uint8*)fs + blk*BLOCKSIZE; | ||
| 81 | + return fs->data + blk*BLOCKSIZE; | ||
| 82 | } | ||
| 83 | |||
| 84 | static inline void | ||
| 85 | @@ -1079,9 +1080,9 @@ alloc_blk(filesystem *fs, uint32 nod) | ||
| 86 | error_msg_and_die("couldn't allocate a block (no free space)"); | ||
| 87 | if(!(fs->gd[grp].bg_free_blocks_count--)) | ||
| 88 | error_msg_and_die("group descr %d. free blocks count == 0 (corrupted fs?)",grp); | ||
| 89 | - if(!(fs->sb.s_free_blocks_count--)) | ||
| 90 | + if(!(fs->sb->s_free_blocks_count--)) | ||
| 91 | error_msg_and_die("superblock free blocks count == 0 (corrupted fs?)"); | ||
| 92 | - return fs->sb.s_blocks_per_group*grp + bk; | ||
| 93 | + return fs->sb->s_blocks_per_group*grp + bk; | ||
| 94 | } | ||
| 95 | |||
| 96 | // free a block | ||
| 97 | @@ -1091,12 +1092,12 @@ free_blk(filesystem *fs, uint32 bk) | ||
| 98 | uint32 grp; | ||
| 99 | blk_info *bi; | ||
| 100 | |||
| 101 | - grp = bk / fs->sb.s_blocks_per_group; | ||
| 102 | - bk %= fs->sb.s_blocks_per_group; | ||
| 103 | + grp = bk / fs->sb->s_blocks_per_group; | ||
| 104 | + bk %= fs->sb->s_blocks_per_group; | ||
| 105 | deallocate(get_blk(fs, fs->gd[grp].bg_block_bitmap, &bi), bk); | ||
| 106 | put_blk(bi); | ||
| 107 | fs->gd[grp].bg_free_blocks_count++; | ||
| 108 | - fs->sb.s_free_blocks_count++; | ||
| 109 | + fs->sb->s_free_blocks_count++; | ||
| 110 | } | ||
| 111 | |||
| 112 | // allocate an inode | ||
| 113 | @@ -1114,7 +1115,7 @@ alloc_nod(filesystem *fs) | ||
| 114 | /* find the one with the most free blocks and allocate node there */ | ||
| 115 | /* Idea from find_group_dir in fs/ext2/ialloc.c in 2.4.19 kernel */ | ||
| 116 | /* We do it for all inodes. */ | ||
| 117 | - avefreei = fs->sb.s_free_inodes_count / nbgroups; | ||
| 118 | + avefreei = fs->sb->s_free_inodes_count / nbgroups; | ||
| 119 | for(grp=0; grp<nbgroups; grp++) { | ||
| 120 | if (fs->gd[grp].bg_free_inodes_count < avefreei || | ||
| 121 | fs->gd[grp].bg_free_inodes_count == 0) | ||
| 122 | @@ -1129,9 +1130,9 @@ alloc_nod(filesystem *fs) | ||
| 123 | put_blk(bi); | ||
| 124 | if(!(fs->gd[best_group].bg_free_inodes_count--)) | ||
| 125 | error_msg_and_die("group descr. free blocks count == 0 (corrupted fs?)"); | ||
| 126 | - if(!(fs->sb.s_free_inodes_count--)) | ||
| 127 | + if(!(fs->sb->s_free_inodes_count--)) | ||
| 128 | error_msg_and_die("superblock free blocks count == 0 (corrupted fs?)"); | ||
| 129 | - return fs->sb.s_inodes_per_group*best_group+nod; | ||
| 130 | + return fs->sb->s_inodes_per_group*best_group+nod; | ||
| 131 | } | ||
| 132 | |||
| 133 | // print a bitmap allocation | ||
| 134 | @@ -1451,7 +1452,7 @@ extend_blk(filesystem *fs, uint32 nod, block b, int amount) | ||
| 135 | while(create) | ||
| 136 | { | ||
| 137 | int i, copyb = 0; | ||
| 138 | - if(!(fs->sb.s_reserved[200] & OP_HOLES)) | ||
| 139 | + if(!(fs->sb->s_reserved[200] & OP_HOLES)) | ||
| 140 | copyb = 1; | ||
| 141 | else | ||
| 142 | for(i = 0; i < BLOCKSIZE / 4; i++) | ||
| 143 | @@ -2133,7 +2134,7 @@ swap_goodfs(filesystem *fs) | ||
| 144 | uint32 i; | ||
| 145 | nod_info *ni; | ||
| 146 | |||
| 147 | - for(i = 1; i < fs->sb.s_inodes_count; i++) | ||
| 148 | + for(i = 1; i < fs->sb->s_inodes_count; i++) | ||
| 149 | { | ||
| 150 | inode *nod = get_nod(fs, i, &ni); | ||
| 151 | if(nod->i_mode & FM_IFDIR) | ||
| 152 | @@ -2158,17 +2159,17 @@ swap_goodfs(filesystem *fs) | ||
| 153 | } | ||
| 154 | for(i=0;i<GRP_NBGROUPS(fs);i++) | ||
| 155 | swap_gd(&(fs->gd[i])); | ||
| 156 | - swap_sb(&fs->sb); | ||
| 157 | + swap_sb(fs->sb); | ||
| 158 | } | ||
| 159 | |||
| 160 | static void | ||
| 161 | swap_badfs(filesystem *fs) | ||
| 162 | { | ||
| 163 | uint32 i; | ||
| 164 | - swap_sb(&fs->sb); | ||
| 165 | + swap_sb(fs->sb); | ||
| 166 | for(i=0;i<GRP_NBGROUPS(fs);i++) | ||
| 167 | swap_gd(&(fs->gd[i])); | ||
| 168 | - for(i = 1; i < fs->sb.s_inodes_count; i++) | ||
| 169 | + for(i = 1; i < fs->sb->s_inodes_count; i++) | ||
| 170 | { | ||
| 171 | nod_info *ni; | ||
| 172 | inode *nod = get_nod(fs, i, &ni); | ||
| 173 | @@ -2242,24 +2243,32 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp | ||
| 174 | free_blocks = nbblocks - overhead_per_group*nbgroups - 1 /*boot block*/; | ||
| 175 | free_blocks_per_group = nbblocks_per_group - overhead_per_group; | ||
| 176 | |||
| 177 | - if(!(fs = (filesystem*)calloc(nbblocks, BLOCKSIZE))) | ||
| 178 | + fs = malloc(sizeof(*fs)); | ||
| 179 | + if (!fs) | ||
| 180 | error_msg_and_die("not enough memory for filesystem"); | ||
| 181 | + fs->nheadblocks = (((nbgroups * sizeof(groupdescriptor)) | ||
| 182 | + + sizeof(superblock) + (BLOCKSIZE - 1)) | ||
| 183 | + / BLOCKSIZE); | ||
| 184 | + if(!(fs->data = calloc(nbblocks, BLOCKSIZE))) | ||
| 185 | + error_msg_and_die("not enough memory for filesystem"); | ||
| 186 | + fs->sb = (superblock *) (fs->data + BLOCKSIZE); | ||
| 187 | + fs->gd = (groupdescriptor *) (fs->sb + 1); | ||
| 188 | |||
| 189 | // create the superblock for an empty filesystem | ||
| 190 | - fs->sb.s_inodes_count = nbinodes_per_group * nbgroups; | ||
| 191 | - fs->sb.s_blocks_count = nbblocks; | ||
| 192 | - fs->sb.s_r_blocks_count = nbresrvd; | ||
| 193 | - fs->sb.s_free_blocks_count = free_blocks; | ||
| 194 | - fs->sb.s_free_inodes_count = fs->sb.s_inodes_count - EXT2_FIRST_INO + 1; | ||
| 195 | - fs->sb.s_first_data_block = first_block; | ||
| 196 | - fs->sb.s_log_block_size = BLOCKSIZE >> 11; | ||
| 197 | - fs->sb.s_log_frag_size = BLOCKSIZE >> 11; | ||
| 198 | - fs->sb.s_blocks_per_group = nbblocks_per_group; | ||
| 199 | - fs->sb.s_frags_per_group = nbblocks_per_group; | ||
| 200 | - fs->sb.s_inodes_per_group = nbinodes_per_group; | ||
| 201 | - fs->sb.s_wtime = fs_timestamp; | ||
| 202 | - fs->sb.s_magic = EXT2_MAGIC_NUMBER; | ||
| 203 | - fs->sb.s_lastcheck = fs_timestamp; | ||
| 204 | + fs->sb->s_inodes_count = nbinodes_per_group * nbgroups; | ||
| 205 | + fs->sb->s_blocks_count = nbblocks; | ||
| 206 | + fs->sb->s_r_blocks_count = nbresrvd; | ||
| 207 | + fs->sb->s_free_blocks_count = free_blocks; | ||
| 208 | + fs->sb->s_free_inodes_count = fs->sb->s_inodes_count - EXT2_FIRST_INO + 1; | ||
| 209 | + fs->sb->s_first_data_block = first_block; | ||
| 210 | + fs->sb->s_log_block_size = BLOCKSIZE >> 11; | ||
| 211 | + fs->sb->s_log_frag_size = BLOCKSIZE >> 11; | ||
| 212 | + fs->sb->s_blocks_per_group = nbblocks_per_group; | ||
| 213 | + fs->sb->s_frags_per_group = nbblocks_per_group; | ||
| 214 | + fs->sb->s_inodes_per_group = nbinodes_per_group; | ||
| 215 | + fs->sb->s_wtime = fs_timestamp; | ||
| 216 | + fs->sb->s_magic = EXT2_MAGIC_NUMBER; | ||
| 217 | + fs->sb->s_lastcheck = fs_timestamp; | ||
| 218 | |||
| 219 | // set up groupdescriptors | ||
| 220 | for(i=0, bbmpos=gdsz+2, ibmpos=bbmpos+1, itblpos=ibmpos+1; | ||
| 221 | @@ -2301,7 +2310,7 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp | ||
| 222 | /* Inode bitmap */ | ||
| 223 | ibm = get_blk(fs,fs->gd[i].bg_inode_bitmap, &bi); | ||
| 224 | //non-filesystem inodes | ||
| 225 | - for(j = fs->sb.s_inodes_per_group+1; j <= BLOCKSIZE * 8; j++) | ||
| 226 | + for(j = fs->sb->s_inodes_per_group+1; j <= BLOCKSIZE * 8; j++) | ||
| 227 | allocate(ibm, j); | ||
| 228 | |||
| 229 | //system inodes | ||
| 230 | @@ -2332,7 +2341,7 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp | ||
| 231 | put_dir(&dw); | ||
| 232 | |||
| 233 | // make lost+found directory and reserve blocks | ||
| 234 | - if(fs->sb.s_r_blocks_count) | ||
| 235 | + if(fs->sb->s_r_blocks_count) | ||
| 236 | { | ||
| 237 | inode *node; | ||
| 238 | uint8 *b; | ||
| 239 | @@ -2344,23 +2353,23 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp | ||
| 240 | /* We run into problems with e2fsck if directory lost+found grows | ||
| 241 | * bigger than this. Need to find out why this happens - sundar | ||
| 242 | */ | ||
| 243 | - if (fs->sb.s_r_blocks_count > fs->sb.s_blocks_count * MAX_RESERVED_BLOCKS ) | ||
| 244 | - fs->sb.s_r_blocks_count = fs->sb.s_blocks_count * MAX_RESERVED_BLOCKS; | ||
| 245 | - for(i = 1; i < fs->sb.s_r_blocks_count; i++) | ||
| 246 | + if (fs->sb->s_r_blocks_count > fs->sb->s_blocks_count * MAX_RESERVED_BLOCKS ) | ||
| 247 | + fs->sb->s_r_blocks_count = fs->sb->s_blocks_count * MAX_RESERVED_BLOCKS; | ||
| 248 | + for(i = 1; i < fs->sb->s_r_blocks_count; i++) | ||
| 249 | extend_blk(fs, nod, b, 1); | ||
| 250 | free_workblk(b); | ||
| 251 | node = get_nod(fs, nod, &ni); | ||
| 252 | - node->i_size = fs->sb.s_r_blocks_count * BLOCKSIZE; | ||
| 253 | + node->i_size = fs->sb->s_r_blocks_count * BLOCKSIZE; | ||
| 254 | put_nod(ni); | ||
| 255 | } | ||
| 256 | |||
| 257 | // administrative info | ||
| 258 | - fs->sb.s_state = 1; | ||
| 259 | - fs->sb.s_max_mnt_count = 20; | ||
| 260 | + fs->sb->s_state = 1; | ||
| 261 | + fs->sb->s_max_mnt_count = 20; | ||
| 262 | |||
| 263 | // options for me | ||
| 264 | if(holes) | ||
| 265 | - fs->sb.s_reserved[200] |= OP_HOLES; | ||
| 266 | + fs->sb->s_reserved[200] |= OP_HOLES; | ||
| 267 | |||
| 268 | return fs; | ||
| 269 | } | ||
| 270 | @@ -2377,20 +2386,29 @@ load_fs(FILE * fh, int swapit) | ||
| 271 | fssize = (fssize + BLOCKSIZE - 1) / BLOCKSIZE; | ||
| 272 | if(fssize < 16) // totally arbitrary | ||
| 273 | error_msg_and_die("too small filesystem"); | ||
| 274 | - if(!(fs = (filesystem*)calloc(fssize, BLOCKSIZE))) | ||
| 275 | + fs = malloc(sizeof(*fs)); | ||
| 276 | + if (!fs) | ||
| 277 | + error_msg_and_die("not enough memory for filesystem"); | ||
| 278 | + if(!(fs->data = calloc(fssize, BLOCKSIZE))) | ||
| 279 | error_msg_and_die("not enough memory for filesystem"); | ||
| 280 | - if(fread(fs, BLOCKSIZE, fssize, fh) != fssize) | ||
| 281 | + if(fread(fs->data, BLOCKSIZE, fssize, fh) != fssize) | ||
| 282 | perror_msg_and_die("input filesystem image"); | ||
| 283 | + fs->sb = (superblock *) (fs->data + BLOCKSIZE); | ||
| 284 | + fs->gd = (groupdescriptor *) (fs->sb + 1); | ||
| 285 | if(swapit) | ||
| 286 | swap_badfs(fs); | ||
| 287 | - if(fs->sb.s_rev_level || (fs->sb.s_magic != EXT2_MAGIC_NUMBER)) | ||
| 288 | + if(fs->sb->s_rev_level || (fs->sb->s_magic != EXT2_MAGIC_NUMBER)) | ||
| 289 | error_msg_and_die("not a suitable ext2 filesystem"); | ||
| 290 | + fs->nheadblocks = (((GRP_NBGROUPS(fs) * sizeof(groupdescriptor)) | ||
| 291 | + + sizeof(superblock) + (BLOCKSIZE - 1)) | ||
| 292 | + / BLOCKSIZE); | ||
| 293 | return fs; | ||
| 294 | } | ||
| 295 | |||
| 296 | static void | ||
| 297 | free_fs(filesystem *fs) | ||
| 298 | { | ||
| 299 | + free(fs->data); | ||
| 300 | free(fs); | ||
| 301 | } | ||
| 302 | |||
| 303 | @@ -2645,19 +2663,19 @@ print_fs(filesystem *fs) | ||
| 304 | uint8 *ibm; | ||
| 305 | |||
| 306 | printf("%d blocks (%d free, %d reserved), first data block: %d\n", | ||
| 307 | - fs->sb.s_blocks_count, fs->sb.s_free_blocks_count, | ||
| 308 | - fs->sb.s_r_blocks_count, fs->sb.s_first_data_block); | ||
| 309 | - printf("%d inodes (%d free)\n", fs->sb.s_inodes_count, | ||
| 310 | - fs->sb.s_free_inodes_count); | ||
| 311 | + fs->sb->s_blocks_count, fs->sb->s_free_blocks_count, | ||
| 312 | + fs->sb->s_r_blocks_count, fs->sb->s_first_data_block); | ||
| 313 | + printf("%d inodes (%d free)\n", fs->sb->s_inodes_count, | ||
| 314 | + fs->sb->s_free_inodes_count); | ||
| 315 | printf("block size = %d, frag size = %d\n", | ||
| 316 | - fs->sb.s_log_block_size ? (fs->sb.s_log_block_size << 11) : 1024, | ||
| 317 | - fs->sb.s_log_frag_size ? (fs->sb.s_log_frag_size << 11) : 1024); | ||
| 318 | + fs->sb->s_log_block_size ? (fs->sb->s_log_block_size << 11) : 1024, | ||
| 319 | + fs->sb->s_log_frag_size ? (fs->sb->s_log_frag_size << 11) : 1024); | ||
| 320 | printf("number of groups: %d\n",GRP_NBGROUPS(fs)); | ||
| 321 | printf("%d blocks per group,%d frags per group,%d inodes per group\n", | ||
| 322 | - fs->sb.s_blocks_per_group, fs->sb.s_frags_per_group, | ||
| 323 | - fs->sb.s_inodes_per_group); | ||
| 324 | + fs->sb->s_blocks_per_group, fs->sb->s_frags_per_group, | ||
| 325 | + fs->sb->s_inodes_per_group); | ||
| 326 | printf("Size of inode table: %d blocks\n", | ||
| 327 | - (int)(fs->sb.s_inodes_per_group * sizeof(inode) / BLOCKSIZE)); | ||
| 328 | + (int)(fs->sb->s_inodes_per_group * sizeof(inode) / BLOCKSIZE)); | ||
| 329 | for (i = 0; i < GRP_NBGROUPS(fs); i++) { | ||
| 330 | printf("Group No: %d\n", i+1); | ||
| 331 | printf("block bitmap: block %d,inode bitmap: block %d, inode table: block %d\n", | ||
| 332 | @@ -2665,12 +2683,12 @@ print_fs(filesystem *fs) | ||
| 333 | fs->gd[i].bg_inode_table); | ||
| 334 | printf("block bitmap allocation:\n"); | ||
| 335 | print_bm(GRP_GET_GROUP_BBM(fs, i, &bi), | ||
| 336 | - fs->sb.s_blocks_per_group); | ||
| 337 | + fs->sb->s_blocks_per_group); | ||
| 338 | GRP_PUT_GROUP_BBM(bi); | ||
| 339 | printf("inode bitmap allocation:\n"); | ||
| 340 | ibm = GRP_GET_GROUP_IBM(fs, i, &bi); | ||
| 341 | - print_bm(ibm, fs->sb.s_inodes_per_group); | ||
| 342 | - for (i = 1; i <= fs->sb.s_inodes_per_group; i++) | ||
| 343 | + print_bm(ibm, fs->sb->s_inodes_per_group); | ||
| 344 | + for (i = 1; i <= fs->sb->s_inodes_per_group; i++) | ||
| 345 | if (allocated(ibm, i)) | ||
| 346 | print_inode(fs, i); | ||
| 347 | GRP_PUT_GROUP_IBM(bi); | ||
| 348 | @@ -2680,11 +2698,11 @@ print_fs(filesystem *fs) | ||
| 349 | static void | ||
| 350 | dump_fs(filesystem *fs, FILE * fh, int swapit) | ||
| 351 | { | ||
| 352 | - uint32 nbblocks = fs->sb.s_blocks_count; | ||
| 353 | - fs->sb.s_reserved[200] = 0; | ||
| 354 | + uint32 nbblocks = fs->sb->s_blocks_count; | ||
| 355 | + fs->sb->s_reserved[200] = 0; | ||
| 356 | if(swapit) | ||
| 357 | swap_goodfs(fs); | ||
| 358 | - if(fwrite(fs, BLOCKSIZE, nbblocks, fh) < nbblocks) | ||
| 359 | + if(fwrite(fs->data, BLOCKSIZE, nbblocks, fh) < nbblocks) | ||
| 360 | perror_msg_and_die("output filesystem image"); | ||
| 361 | if(swapit) | ||
| 362 | swap_badfs(fs); | ||
| 363 | @@ -2944,7 +2962,7 @@ main(int argc, char **argv) | ||
| 364 | |||
| 365 | if(emptyval) { | ||
| 366 | uint32 b; | ||
| 367 | - for(b = 1; b < fs->sb.s_blocks_count; b++) { | ||
| 368 | + for(b = 1; b < fs->sb->s_blocks_count; b++) { | ||
| 369 | blk_info *bi; | ||
| 370 | if(!allocated(GRP_GET_BLOCK_BITMAP(fs,b,&bi), | ||
| 371 | GRP_BBM_OFFSET(fs,b))) { | ||
| 372 | -- | ||
| 373 | 1.7.4.1 | ||
| 374 | |||
diff --git a/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0006-Improve-the-efficiency-of-extend_blk.patch b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0006-Improve-the-efficiency-of-extend_blk.patch new file mode 100644 index 0000000000..494e3f9e8d --- /dev/null +++ b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0006-Improve-the-efficiency-of-extend_blk.patch | |||
| @@ -0,0 +1,272 @@ | |||
| 1 | Upstream-Status: inappropriate | ||
| 2 | |||
| 3 | From ea6cbe2880e02026667b9007db9a742be7dcd52b Mon Sep 17 00:00:00 2001 | ||
| 4 | From: Corey Minyard <cminyard@mvista.com> | ||
| 5 | Date: Sun, 5 Jun 2011 10:26:11 -0500 | ||
| 6 | Subject: [PATCH 06/19] Improve the efficiency of extend_blk | ||
| 7 | |||
| 8 | When doing multiple extensions operations on the same inode, extend_blk() | ||
| 9 | would search to the end every time. In the current structure, that means | ||
| 10 | when creating the reserved blocks, it could parse over the block list | ||
| 11 | many thousands of time on a large filesystem. For an 800MB filesystem, | ||
| 12 | that took 2/3rds of the time. | ||
| 13 | |||
| 14 | So create a structure for holding the inode position and use it to | ||
| 15 | know where the end is. This neatens things up a bit, too, more | ||
| 16 | clearly showing when a truncate or extend is occuring. In future | ||
| 17 | changes, this will also make it efficient for supporting very large | ||
| 18 | files that cannot be fully allocated in memory. | ||
| 19 | --- | ||
| 20 | genext2fs.c | 147 ++++++++++++++++++++++++++++++++++++++++------------------- | ||
| 21 | 1 files changed, 100 insertions(+), 47 deletions(-) | ||
| 22 | |||
| 23 | diff --git a/genext2fs.c b/genext2fs.c | ||
| 24 | index 46c9605..e45e520 100644 | ||
| 25 | --- a/genext2fs.c | ||
| 26 | +++ b/genext2fs.c | ||
| 27 | @@ -436,6 +436,17 @@ swab32(uint32 val) | ||
| 28 | ((val<<8)&0xFF0000) | (val<<24)); | ||
| 29 | } | ||
| 30 | |||
| 31 | +static inline int | ||
| 32 | +is_blk_empty(uint8 *b) | ||
| 33 | +{ | ||
| 34 | + uint32 i; | ||
| 35 | + uint32 *v = (uint32 *) b; | ||
| 36 | + | ||
| 37 | + for(i = 0; i < BLOCKSIZE / 4; i++) | ||
| 38 | + if (*v++) | ||
| 39 | + return 0; | ||
| 40 | + return 1; | ||
| 41 | +} | ||
| 42 | |||
| 43 | // on-disk structures | ||
| 44 | // this trick makes me declare things only once | ||
| 45 | @@ -1165,7 +1176,6 @@ init_bw(blockwalker *bw) | ||
| 46 | // used after being freed, so once you start | ||
| 47 | // freeing blocks don't stop until the end of | ||
| 48 | // the file. moreover, i_blocks isn't updated. | ||
| 49 | -// in fact, don't do that, just use extend_blk | ||
| 50 | // if hole!=0, create a hole in the file | ||
| 51 | static uint32 | ||
| 52 | walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole) | ||
| 53 | @@ -1422,52 +1432,80 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole) | ||
| 54 | return bk; | ||
| 55 | } | ||
| 56 | |||
| 57 | -// add blocks to an inode (file/dir/etc...) | ||
| 58 | -static void | ||
| 59 | -extend_blk(filesystem *fs, uint32 nod, block b, int amount) | ||
| 60 | +typedef struct | ||
| 61 | { | ||
| 62 | - int create = amount; | ||
| 63 | - blockwalker bw, lbw; | ||
| 64 | - uint32 bk; | ||
| 65 | + blockwalker bw; | ||
| 66 | + uint32 nod; | ||
| 67 | nod_info *ni; | ||
| 68 | inode *inod; | ||
| 69 | +} inode_pos; | ||
| 70 | +#define INODE_POS_TRUNCATE 0 | ||
| 71 | +#define INODE_POS_EXTEND 1 | ||
| 72 | + | ||
| 73 | +// Call this to set up an ipos structure for future use with | ||
| 74 | +// extend_inode_blk to append blocks to the given inode. If | ||
| 75 | +// op is INODE_POS_TRUNCATE, the inode is truncated to zero size. | ||
| 76 | +// If op is INODE_POS_EXTEND, the position is moved to the end | ||
| 77 | +// of the inode's data blocks. | ||
| 78 | +// Call inode_pos_finish when done with the inode_pos structure. | ||
| 79 | +static void | ||
| 80 | +inode_pos_init(filesystem *fs, inode_pos *ipos, uint32 nod, int op, | ||
| 81 | + blockwalker *endbw) | ||
| 82 | +{ | ||
| 83 | + blockwalker lbw; | ||
| 84 | |||
| 85 | - inod = get_nod(fs, nod, &ni); | ||
| 86 | - init_bw(&bw); | ||
| 87 | - if(amount < 0) | ||
| 88 | - { | ||
| 89 | - uint32 i; | ||
| 90 | - for(i = 0; i < inod->i_blocks / INOBLK + amount; i++) | ||
| 91 | - walk_bw(fs, nod, &bw, 0, 0); | ||
| 92 | - while(walk_bw(fs, nod, &bw, &create, 0) != WALK_END) | ||
| 93 | + init_bw(&ipos->bw); | ||
| 94 | + ipos->nod = nod; | ||
| 95 | + ipos->inod = get_nod(fs, nod, &ipos->ni); | ||
| 96 | + if (op == INODE_POS_TRUNCATE) { | ||
| 97 | + int32 create = -1; | ||
| 98 | + while(walk_bw(fs, nod, &ipos->bw, &create, 0) != WALK_END) | ||
| 99 | /*nop*/; | ||
| 100 | - inod->i_blocks += amount * INOBLK; | ||
| 101 | + ipos->inod->i_blocks = 0; | ||
| 102 | } | ||
| 103 | - else | ||
| 104 | + | ||
| 105 | + if (endbw) | ||
| 106 | + ipos->bw = *endbw; | ||
| 107 | + else { | ||
| 108 | + /* Seek to the end */ | ||
| 109 | + init_bw(&ipos->bw); | ||
| 110 | + lbw = ipos->bw; | ||
| 111 | + while(walk_bw(fs, nod, &ipos->bw, 0, 0) != WALK_END) | ||
| 112 | + lbw = ipos->bw; | ||
| 113 | + ipos->bw = lbw; | ||
| 114 | + } | ||
| 115 | +} | ||
| 116 | + | ||
| 117 | +// Clean up the inode_pos structure. | ||
| 118 | +static void | ||
| 119 | +inode_pos_finish(filesystem *fs, inode_pos *ipos) | ||
| 120 | +{ | ||
| 121 | + put_nod(ipos->ni); | ||
| 122 | +} | ||
| 123 | + | ||
| 124 | +// add blocks to an inode (file/dir/etc...) at the given position. | ||
| 125 | +// This will only work when appending to the end of an inode. | ||
| 126 | +static void | ||
| 127 | +extend_inode_blk(filesystem *fs, inode_pos *ipos, block b, int amount) | ||
| 128 | +{ | ||
| 129 | + uint32 bk; | ||
| 130 | + uint32 pos; | ||
| 131 | + | ||
| 132 | + if (amount < 0) | ||
| 133 | + error_msg_and_die("extend_inode_blk: Got negative amount"); | ||
| 134 | + | ||
| 135 | + for (pos = 0; amount; pos += BLOCKSIZE) | ||
| 136 | { | ||
| 137 | - lbw = bw; | ||
| 138 | - while((bk = walk_bw(fs, nod, &bw, 0, 0)) != WALK_END) | ||
| 139 | - lbw = bw; | ||
| 140 | - bw = lbw; | ||
| 141 | - while(create) | ||
| 142 | - { | ||
| 143 | - int i, copyb = 0; | ||
| 144 | - if(!(fs->sb->s_reserved[200] & OP_HOLES)) | ||
| 145 | - copyb = 1; | ||
| 146 | - else | ||
| 147 | - for(i = 0; i < BLOCKSIZE / 4; i++) | ||
| 148 | - if(((int32*)(b + BLOCKSIZE * (amount - create)))[i]) | ||
| 149 | - { | ||
| 150 | - copyb = 1; | ||
| 151 | - break; | ||
| 152 | - } | ||
| 153 | - if((bk = walk_bw(fs, nod, &bw, &create, !copyb)) == WALK_END) | ||
| 154 | - break; | ||
| 155 | - if(copyb) { | ||
| 156 | - blk_info *bi; | ||
| 157 | - memcpy(get_blk(fs, bk, &bi), b + BLOCKSIZE * (amount - create - 1), BLOCKSIZE); | ||
| 158 | - put_blk(bi); | ||
| 159 | - } | ||
| 160 | + int hole = ((fs->sb->s_reserved[200] & OP_HOLES) && is_blk_empty(b + pos)); | ||
| 161 | + | ||
| 162 | + bk = walk_bw(fs, ipos->nod, &ipos->bw, &amount, hole); | ||
| 163 | + if (bk == WALK_END) | ||
| 164 | + error_msg_and_die("extend_inode_blk: extend failed"); | ||
| 165 | + if (!hole) { | ||
| 166 | + blk_info *bi; | ||
| 167 | + uint8 *block = get_blk(fs, bk, &bi); | ||
| 168 | + memcpy(block, b + pos, BLOCKSIZE); | ||
| 169 | + put_blk(bi); | ||
| 170 | } | ||
| 171 | } | ||
| 172 | } | ||
| 173 | @@ -1484,6 +1522,7 @@ add2dir(filesystem *fs, uint32 dnod, uint32 nod, const char* name) | ||
| 174 | inode *node; | ||
| 175 | inode *pnode; | ||
| 176 | nod_info *dni, *ni; | ||
| 177 | + inode_pos ipos; | ||
| 178 | |||
| 179 | pnode = get_nod(fs, dnod, &dni); | ||
| 180 | if((pnode->i_mode & FM_IFMT) != FM_IFDIR) | ||
| 181 | @@ -1534,7 +1573,11 @@ add2dir(filesystem *fs, uint32 dnod, uint32 nod, const char* name) | ||
| 182 | node->i_links_count++; | ||
| 183 | put_nod(ni); | ||
| 184 | next_dir(&dw); // Force the data into the buffer | ||
| 185 | - extend_blk(fs, dnod, dir_data(&dw), 1); | ||
| 186 | + | ||
| 187 | + inode_pos_init(fs, &ipos, dnod, INODE_POS_EXTEND, &lbw); | ||
| 188 | + extend_inode_blk(fs, &ipos, dir_data(&dw), 1); | ||
| 189 | + inode_pos_finish(fs, &ipos); | ||
| 190 | + | ||
| 191 | put_dir(&dw); | ||
| 192 | pnode->i_size += BLOCKSIZE; | ||
| 193 | out: | ||
| 194 | @@ -1654,8 +1697,9 @@ mklink_fs(filesystem *fs, uint32 parent_nod, const char *name, size_t size, uint | ||
| 195 | uint32 nod = mknod_fs(fs, parent_nod, name, FM_IFLNK | FM_IRWXU | FM_IRWXG | FM_IRWXO, uid, gid, 0, 0, ctime, mtime); | ||
| 196 | nod_info *ni; | ||
| 197 | inode *node = get_nod(fs, nod, &ni); | ||
| 198 | + inode_pos ipos; | ||
| 199 | |||
| 200 | - extend_blk(fs, nod, 0, - (int)node->i_blocks / INOBLK); | ||
| 201 | + inode_pos_init(fs, &ipos, nod, INODE_POS_TRUNCATE, NULL); | ||
| 202 | node->i_size = size; | ||
| 203 | if(size <= 4 * (EXT2_TIND_BLOCK+1)) | ||
| 204 | { | ||
| 205 | @@ -1663,7 +1707,8 @@ mklink_fs(filesystem *fs, uint32 parent_nod, const char *name, size_t size, uint | ||
| 206 | put_nod(ni); | ||
| 207 | return nod; | ||
| 208 | } | ||
| 209 | - extend_blk(fs, nod, b, rndup(size, BLOCKSIZE) / BLOCKSIZE); | ||
| 210 | + extend_inode_blk(fs, &ipos, b, rndup(size, BLOCKSIZE) / BLOCKSIZE); | ||
| 211 | + inode_pos_finish(fs, &ipos); | ||
| 212 | put_nod(ni); | ||
| 213 | return nod; | ||
| 214 | } | ||
| 215 | @@ -1676,8 +1721,9 @@ mkfile_fs(filesystem *fs, uint32 parent_nod, const char *name, uint32 mode, size | ||
| 216 | uint32 nod = mknod_fs(fs, parent_nod, name, mode|FM_IFREG, uid, gid, 0, 0, ctime, mtime); | ||
| 217 | nod_info *ni; | ||
| 218 | inode *node = get_nod(fs, nod, &ni); | ||
| 219 | + inode_pos ipos; | ||
| 220 | |||
| 221 | - extend_blk(fs, nod, 0, - (int)node->i_blocks / INOBLK); | ||
| 222 | + inode_pos_init(fs, &ipos, nod, INODE_POS_TRUNCATE, NULL); | ||
| 223 | node->i_size = size; | ||
| 224 | if (size) { | ||
| 225 | if(!(b = (uint8*)calloc(rndup(size, BLOCKSIZE), 1))) | ||
| 226 | @@ -1685,9 +1731,11 @@ mkfile_fs(filesystem *fs, uint32 parent_nod, const char *name, uint32 mode, size | ||
| 227 | if(f) | ||
| 228 | if (fread(b, size, 1, f) != 1) // FIXME: ugly. use mmap() ... | ||
| 229 | error_msg_and_die("fread failed"); | ||
| 230 | - extend_blk(fs, nod, b, rndup(size, BLOCKSIZE) / BLOCKSIZE); | ||
| 231 | + extend_inode_blk(fs, &ipos, b, | ||
| 232 | + rndup(size, BLOCKSIZE) / BLOCKSIZE); | ||
| 233 | free(b); | ||
| 234 | } | ||
| 235 | + inode_pos_finish(fs, &ipos); | ||
| 236 | put_nod(ni); | ||
| 237 | return nod; | ||
| 238 | } | ||
| 239 | @@ -2210,6 +2258,7 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp | ||
| 240 | inode *itab0; | ||
| 241 | blk_info *bi; | ||
| 242 | nod_info *ni; | ||
| 243 | + inode_pos ipos; | ||
| 244 | |||
| 245 | if(nbresrvd < 0) | ||
| 246 | error_msg_and_die("reserved blocks value is invalid. Note: options have changed, see --help or the man page."); | ||
| 247 | @@ -2337,7 +2386,9 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp | ||
| 248 | new_dir(fs, EXT2_ROOT_INO, ".", 1, &dw); | ||
| 249 | shrink_dir(&dw, EXT2_ROOT_INO, "..", 2); | ||
| 250 | next_dir(&dw); // Force the data into the buffer | ||
| 251 | - extend_blk(fs, EXT2_ROOT_INO, dir_data(&dw), 1); | ||
| 252 | + inode_pos_init(fs, &ipos, EXT2_ROOT_INO, INODE_POS_EXTEND, NULL); | ||
| 253 | + extend_inode_blk(fs, &ipos, dir_data(&dw), 1); | ||
| 254 | + inode_pos_finish(fs, &ipos); | ||
| 255 | put_dir(&dw); | ||
| 256 | |||
| 257 | // make lost+found directory and reserve blocks | ||
| 258 | @@ -2355,8 +2406,10 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp | ||
| 259 | */ | ||
| 260 | if (fs->sb->s_r_blocks_count > fs->sb->s_blocks_count * MAX_RESERVED_BLOCKS ) | ||
| 261 | fs->sb->s_r_blocks_count = fs->sb->s_blocks_count * MAX_RESERVED_BLOCKS; | ||
| 262 | + inode_pos_init(fs, &ipos, nod, INODE_POS_EXTEND, NULL); | ||
| 263 | for(i = 1; i < fs->sb->s_r_blocks_count; i++) | ||
| 264 | - extend_blk(fs, nod, b, 1); | ||
| 265 | + extend_inode_blk(fs, &ipos, b, 1); | ||
| 266 | + inode_pos_finish(fs, &ipos); | ||
| 267 | free_workblk(b); | ||
| 268 | node = get_nod(fs, nod, &ni); | ||
| 269 | node->i_size = fs->sb->s_r_blocks_count * BLOCKSIZE; | ||
| 270 | -- | ||
| 271 | 1.7.4.1 | ||
| 272 | |||
diff --git a/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0007-Move-hdlinks-into-the-filesystem-structure.patch b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0007-Move-hdlinks-into-the-filesystem-structure.patch new file mode 100644 index 0000000000..52215c8e7a --- /dev/null +++ b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0007-Move-hdlinks-into-the-filesystem-structure.patch | |||
| @@ -0,0 +1,175 @@ | |||
| 1 | Upstream-Status: inappropriate | ||
| 2 | |||
| 3 | From 1ea2332c6cec1fb979a7cb4502360005bed50da4 Mon Sep 17 00:00:00 2001 | ||
| 4 | From: Corey Minyard <cminyard@mvista.com> | ||
| 5 | Date: Sun, 5 Jun 2011 14:08:02 -0500 | ||
| 6 | Subject: [PATCH 07/19] Move hdlinks into the filesystem structure. | ||
| 7 | |||
| 8 | Since the hard links structures are associated with a filesystem, put | ||
| 9 | them in the filesystem structure since it can hold other stuff now. | ||
| 10 | --- | ||
| 11 | genext2fs.c | 71 +++++++++++++++++++++++++++++++--------------------------- | ||
| 12 | 1 files changed, 38 insertions(+), 33 deletions(-) | ||
| 13 | |||
| 14 | diff --git a/genext2fs.c b/genext2fs.c | ||
| 15 | index e45e520..d130362 100644 | ||
| 16 | --- a/genext2fs.c | ||
| 17 | +++ b/genext2fs.c | ||
| 18 | @@ -583,6 +583,18 @@ typedef struct | ||
| 19 | uint32 bptind; | ||
| 20 | } blockwalker; | ||
| 21 | |||
| 22 | +#define HDLINK_CNT 16 | ||
| 23 | +struct hdlink_s | ||
| 24 | +{ | ||
| 25 | + uint32 src_inode; | ||
| 26 | + uint32 dst_nod; | ||
| 27 | +}; | ||
| 28 | + | ||
| 29 | +struct hdlinks_s | ||
| 30 | +{ | ||
| 31 | + int32 count; | ||
| 32 | + struct hdlink_s *hdl; | ||
| 33 | +}; | ||
| 34 | |||
| 35 | /* Filesystem structure that support groups */ | ||
| 36 | #if BLOCKSIZE == 1024 | ||
| 37 | @@ -592,6 +604,8 @@ typedef struct | ||
| 38 | superblock *sb; | ||
| 39 | groupdescriptor *gd; | ||
| 40 | uint32 nheadblocks; | ||
| 41 | + int32 hdlink_cnt; | ||
| 42 | + struct hdlinks_s hdlinks; | ||
| 43 | } filesystem; | ||
| 44 | #else | ||
| 45 | #error UNHANDLED BLOCKSIZE | ||
| 46 | @@ -615,22 +629,6 @@ typedef struct | ||
| 47 | #define udecl32(x) this->x = swab32(this->x); | ||
| 48 | #define utdecl32(x,n) { int i; for(i=0; i<n; i++) this->x[i] = swab32(this->x[i]); } | ||
| 49 | |||
| 50 | -#define HDLINK_CNT 16 | ||
| 51 | -static int32 hdlink_cnt = HDLINK_CNT; | ||
| 52 | -struct hdlink_s | ||
| 53 | -{ | ||
| 54 | - uint32 src_inode; | ||
| 55 | - uint32 dst_nod; | ||
| 56 | -}; | ||
| 57 | - | ||
| 58 | -struct hdlinks_s | ||
| 59 | -{ | ||
| 60 | - int32 count; | ||
| 61 | - struct hdlink_s *hdl; | ||
| 62 | -}; | ||
| 63 | - | ||
| 64 | -static struct hdlinks_s hdlinks; | ||
| 65 | - | ||
| 66 | static void | ||
| 67 | swap_sb(superblock *sb) | ||
| 68 | { | ||
| 69 | @@ -787,12 +785,12 @@ xreadlink(const char *path) | ||
| 70 | } | ||
| 71 | |||
| 72 | int | ||
| 73 | -is_hardlink(ino_t inode) | ||
| 74 | +is_hardlink(filesystem *fs, ino_t inode) | ||
| 75 | { | ||
| 76 | int i; | ||
| 77 | |||
| 78 | - for(i = 0; i < hdlinks.count; i++) { | ||
| 79 | - if(hdlinks.hdl[i].src_inode == inode) | ||
| 80 | + for(i = 0; i < fs->hdlinks.count; i++) { | ||
| 81 | + if(fs->hdlinks.hdl[i].src_inode == inode) | ||
| 82 | return i; | ||
| 83 | } | ||
| 84 | return -1; | ||
| 85 | @@ -1989,9 +1987,9 @@ add2fs_from_dir(filesystem *fs, uint32 this_nod, int squash_uids, int squash_per | ||
| 86 | save_nod = 0; | ||
| 87 | /* Check for hardlinks */ | ||
| 88 | if (!S_ISDIR(st.st_mode) && !S_ISLNK(st.st_mode) && st.st_nlink > 1) { | ||
| 89 | - int32 hdlink = is_hardlink(st.st_ino); | ||
| 90 | + int32 hdlink = is_hardlink(fs, st.st_ino); | ||
| 91 | if (hdlink >= 0) { | ||
| 92 | - add2dir(fs, this_nod, hdlinks.hdl[hdlink].dst_nod, name); | ||
| 93 | + add2dir(fs, this_nod, fs->hdlinks.hdl[hdlink].dst_nod, name); | ||
| 94 | continue; | ||
| 95 | } else { | ||
| 96 | save_nod = 1; | ||
| 97 | @@ -2035,17 +2033,17 @@ add2fs_from_dir(filesystem *fs, uint32 this_nod, int squash_uids, int squash_per | ||
| 98 | error_msg("ignoring entry %s", name); | ||
| 99 | } | ||
| 100 | if (save_nod) { | ||
| 101 | - if (hdlinks.count == hdlink_cnt) { | ||
| 102 | - if ((hdlinks.hdl = | ||
| 103 | - realloc (hdlinks.hdl, (hdlink_cnt + HDLINK_CNT) * | ||
| 104 | + if (fs->hdlinks.count == fs->hdlink_cnt) { | ||
| 105 | + if ((fs->hdlinks.hdl = | ||
| 106 | + realloc (fs->hdlinks.hdl, (fs->hdlink_cnt + HDLINK_CNT) * | ||
| 107 | sizeof (struct hdlink_s))) == NULL) { | ||
| 108 | error_msg_and_die("Not enough memory"); | ||
| 109 | } | ||
| 110 | - hdlink_cnt += HDLINK_CNT; | ||
| 111 | + fs->hdlink_cnt += HDLINK_CNT; | ||
| 112 | } | ||
| 113 | - hdlinks.hdl[hdlinks.count].src_inode = st.st_ino; | ||
| 114 | - hdlinks.hdl[hdlinks.count].dst_nod = nod; | ||
| 115 | - hdlinks.count++; | ||
| 116 | + fs->hdlinks.hdl[fs->hdlinks.count].src_inode = st.st_ino; | ||
| 117 | + fs->hdlinks.hdl[fs->hdlinks.count].dst_nod = nod; | ||
| 118 | + fs->hdlinks.count++; | ||
| 119 | } | ||
| 120 | } | ||
| 121 | } | ||
| 122 | @@ -2300,6 +2298,11 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp | ||
| 123 | / BLOCKSIZE); | ||
| 124 | if(!(fs->data = calloc(nbblocks, BLOCKSIZE))) | ||
| 125 | error_msg_and_die("not enough memory for filesystem"); | ||
| 126 | + fs->hdlink_cnt = HDLINK_CNT; | ||
| 127 | + fs->hdlinks.hdl = calloc(sizeof(struct hdlink_s), fs->hdlink_cnt); | ||
| 128 | + if (!fs->hdlinks.hdl) | ||
| 129 | + error_msg_and_die("Not enough memory"); | ||
| 130 | + fs->hdlinks.count = 0 ; | ||
| 131 | fs->sb = (superblock *) (fs->data + BLOCKSIZE); | ||
| 132 | fs->gd = (groupdescriptor *) (fs->sb + 1); | ||
| 133 | |||
| 134 | @@ -2442,12 +2445,18 @@ load_fs(FILE * fh, int swapit) | ||
| 135 | fs = malloc(sizeof(*fs)); | ||
| 136 | if (!fs) | ||
| 137 | error_msg_and_die("not enough memory for filesystem"); | ||
| 138 | + fs->hdlink_cnt = HDLINK_CNT; | ||
| 139 | + fs->hdlinks.hdl = calloc(sizeof(struct hdlink_s), fs->hdlink_cnt); | ||
| 140 | + if (!fs->hdlinks.hdl) | ||
| 141 | + error_msg_and_die("Not enough memory"); | ||
| 142 | + fs->hdlinks.count = 0 ; | ||
| 143 | if(!(fs->data = calloc(fssize, BLOCKSIZE))) | ||
| 144 | error_msg_and_die("not enough memory for filesystem"); | ||
| 145 | if(fread(fs->data, BLOCKSIZE, fssize, fh) != fssize) | ||
| 146 | perror_msg_and_die("input filesystem image"); | ||
| 147 | fs->sb = (superblock *) (fs->data + BLOCKSIZE); | ||
| 148 | fs->gd = (groupdescriptor *) (fs->sb + 1); | ||
| 149 | + | ||
| 150 | if(swapit) | ||
| 151 | swap_badfs(fs); | ||
| 152 | if(fs->sb->s_rev_level || (fs->sb->s_magic != EXT2_MAGIC_NUMBER)) | ||
| 153 | @@ -2461,6 +2470,7 @@ load_fs(FILE * fh, int swapit) | ||
| 154 | static void | ||
| 155 | free_fs(filesystem *fs) | ||
| 156 | { | ||
| 157 | + free(fs->hdlinks.hdl); | ||
| 158 | free(fs->data); | ||
| 159 | free(fs); | ||
| 160 | } | ||
| 161 | @@ -2964,11 +2974,6 @@ main(int argc, char **argv) | ||
| 162 | error_msg_and_die("Not enough arguments. Try --help or else see the man page."); | ||
| 163 | fsout = argv[optind]; | ||
| 164 | |||
| 165 | - hdlinks.hdl = (struct hdlink_s *)malloc(hdlink_cnt * sizeof(struct hdlink_s)); | ||
| 166 | - if (!hdlinks.hdl) | ||
| 167 | - error_msg_and_die("Not enough memory"); | ||
| 168 | - hdlinks.count = 0 ; | ||
| 169 | - | ||
| 170 | if(fsin) | ||
| 171 | { | ||
| 172 | if(strcmp(fsin, "-")) | ||
| 173 | -- | ||
| 174 | 1.7.4.1 | ||
| 175 | |||
diff --git a/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0008-Separate-out-the-creation-of-the-filesystem-structur.patch b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0008-Separate-out-the-creation-of-the-filesystem-structur.patch new file mode 100644 index 0000000000..25adeb63c0 --- /dev/null +++ b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0008-Separate-out-the-creation-of-the-filesystem-structur.patch | |||
| @@ -0,0 +1,95 @@ | |||
| 1 | Upstream-Status: inappropriate | ||
| 2 | |||
| 3 | From 797e8548e5857b7a0586b27a9bdcadbea1561d8d Mon Sep 17 00:00:00 2001 | ||
| 4 | From: Corey Minyard <cminyard@mvista.com> | ||
| 5 | Date: Sun, 5 Jun 2011 14:53:57 -0500 | ||
| 6 | Subject: [PATCH 08/19] Separate out the creation of the filesystem structure. | ||
| 7 | |||
| 8 | Consolidate some processing that occurs when allocating a filesystem | ||
| 9 | structure. | ||
| 10 | --- | ||
| 11 | genext2fs.c | 49 +++++++++++++++++++++++++------------------------ | ||
| 12 | 1 files changed, 25 insertions(+), 24 deletions(-) | ||
| 13 | |||
| 14 | diff --git a/genext2fs.c b/genext2fs.c | ||
| 15 | index d130362..497c9af 100644 | ||
| 16 | --- a/genext2fs.c | ||
| 17 | +++ b/genext2fs.c | ||
| 18 | @@ -2240,6 +2240,29 @@ swap_badfs(filesystem *fs) | ||
| 19 | } | ||
| 20 | } | ||
| 21 | |||
| 22 | +// Allocate a new filesystem structure, allocate internal memory, | ||
| 23 | +// and initialize the contents. | ||
| 24 | +static filesystem * | ||
| 25 | +alloc_fs(uint32 nbblocks) | ||
| 26 | +{ | ||
| 27 | + filesystem *fs; | ||
| 28 | + | ||
| 29 | + fs = malloc(sizeof(*fs)); | ||
| 30 | + if (!fs) | ||
| 31 | + error_msg_and_die("not enough memory for filesystem"); | ||
| 32 | + memset(fs, 0, sizeof(*fs)); | ||
| 33 | + if(!(fs->data = calloc(nbblocks, BLOCKSIZE))) | ||
| 34 | + error_msg_and_die("not enough memory for filesystem"); | ||
| 35 | + fs->hdlink_cnt = HDLINK_CNT; | ||
| 36 | + fs->hdlinks.hdl = calloc(sizeof(struct hdlink_s), fs->hdlink_cnt); | ||
| 37 | + if (!fs->hdlinks.hdl) | ||
| 38 | + error_msg_and_die("Not enough memory"); | ||
| 39 | + fs->hdlinks.count = 0 ; | ||
| 40 | + fs->sb = (superblock *) (fs->data + BLOCKSIZE); | ||
| 41 | + fs->gd = (groupdescriptor *) (fs->sb + 1); | ||
| 42 | + return fs; | ||
| 43 | +} | ||
| 44 | + | ||
| 45 | // initialize an empty filesystem | ||
| 46 | static filesystem * | ||
| 47 | init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp) | ||
| 48 | @@ -2290,21 +2313,10 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp | ||
| 49 | free_blocks = nbblocks - overhead_per_group*nbgroups - 1 /*boot block*/; | ||
| 50 | free_blocks_per_group = nbblocks_per_group - overhead_per_group; | ||
| 51 | |||
| 52 | - fs = malloc(sizeof(*fs)); | ||
| 53 | - if (!fs) | ||
| 54 | - error_msg_and_die("not enough memory for filesystem"); | ||
| 55 | + fs = alloc_fs(nbblocks); | ||
| 56 | fs->nheadblocks = (((nbgroups * sizeof(groupdescriptor)) | ||
| 57 | + sizeof(superblock) + (BLOCKSIZE - 1)) | ||
| 58 | / BLOCKSIZE); | ||
| 59 | - if(!(fs->data = calloc(nbblocks, BLOCKSIZE))) | ||
| 60 | - error_msg_and_die("not enough memory for filesystem"); | ||
| 61 | - fs->hdlink_cnt = HDLINK_CNT; | ||
| 62 | - fs->hdlinks.hdl = calloc(sizeof(struct hdlink_s), fs->hdlink_cnt); | ||
| 63 | - if (!fs->hdlinks.hdl) | ||
| 64 | - error_msg_and_die("Not enough memory"); | ||
| 65 | - fs->hdlinks.count = 0 ; | ||
| 66 | - fs->sb = (superblock *) (fs->data + BLOCKSIZE); | ||
| 67 | - fs->gd = (groupdescriptor *) (fs->sb + 1); | ||
| 68 | |||
| 69 | // create the superblock for an empty filesystem | ||
| 70 | fs->sb->s_inodes_count = nbinodes_per_group * nbgroups; | ||
| 71 | @@ -2442,20 +2454,9 @@ load_fs(FILE * fh, int swapit) | ||
| 72 | fssize = (fssize + BLOCKSIZE - 1) / BLOCKSIZE; | ||
| 73 | if(fssize < 16) // totally arbitrary | ||
| 74 | error_msg_and_die("too small filesystem"); | ||
| 75 | - fs = malloc(sizeof(*fs)); | ||
| 76 | - if (!fs) | ||
| 77 | - error_msg_and_die("not enough memory for filesystem"); | ||
| 78 | - fs->hdlink_cnt = HDLINK_CNT; | ||
| 79 | - fs->hdlinks.hdl = calloc(sizeof(struct hdlink_s), fs->hdlink_cnt); | ||
| 80 | - if (!fs->hdlinks.hdl) | ||
| 81 | - error_msg_and_die("Not enough memory"); | ||
| 82 | - fs->hdlinks.count = 0 ; | ||
| 83 | - if(!(fs->data = calloc(fssize, BLOCKSIZE))) | ||
| 84 | - error_msg_and_die("not enough memory for filesystem"); | ||
| 85 | + fs = alloc_fs(fssize); | ||
| 86 | if(fread(fs->data, BLOCKSIZE, fssize, fh) != fssize) | ||
| 87 | perror_msg_and_die("input filesystem image"); | ||
| 88 | - fs->sb = (superblock *) (fs->data + BLOCKSIZE); | ||
| 89 | - fs->gd = (groupdescriptor *) (fs->sb + 1); | ||
| 90 | |||
| 91 | if(swapit) | ||
| 92 | swap_badfs(fs); | ||
| 93 | -- | ||
| 94 | 1.7.4.1 | ||
| 95 | |||
diff --git a/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0009-Move-byte-swapping-into-the-get-put-routines.patch b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0009-Move-byte-swapping-into-the-get-put-routines.patch new file mode 100644 index 0000000000..028fbb6b28 --- /dev/null +++ b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0009-Move-byte-swapping-into-the-get-put-routines.patch | |||
| @@ -0,0 +1,421 @@ | |||
| 1 | Upstream-Status: inappropriate | ||
| 2 | |||
| 3 | From 46d57a42a2185970807971f4d6d8f62b4facbaf5 Mon Sep 17 00:00:00 2001 | ||
| 4 | From: Corey Minyard <cminyard@mvista.com> | ||
| 5 | Date: Sun, 5 Jun 2011 15:00:15 -0500 | ||
| 6 | Subject: [PATCH 09/19] Move byte swapping into the get/put routines. | ||
| 7 | |||
| 8 | Remove the full byte-swapping of the filesystem at start/end time, and | ||
| 9 | instead byteswap each inode/block map/directory as it is read and written. | ||
| 10 | This is getting ready for the change of not holding the entire filesystem | ||
| 11 | in memory. | ||
| 12 | --- | ||
| 13 | genext2fs.c | 234 +++++++++++++--------------------------------------------- | ||
| 14 | 1 files changed, 53 insertions(+), 181 deletions(-) | ||
| 15 | |||
| 16 | diff --git a/genext2fs.c b/genext2fs.c | ||
| 17 | index 497c9af..51403a2 100644 | ||
| 18 | --- a/genext2fs.c | ||
| 19 | +++ b/genext2fs.c | ||
| 20 | @@ -604,6 +604,7 @@ typedef struct | ||
| 21 | superblock *sb; | ||
| 22 | groupdescriptor *gd; | ||
| 23 | uint32 nheadblocks; | ||
| 24 | + int swapit; | ||
| 25 | int32 hdlink_cnt; | ||
| 26 | struct hdlinks_s hdlinks; | ||
| 27 | } filesystem; | ||
| 28 | @@ -648,9 +649,24 @@ swap_gd(groupdescriptor *gd) | ||
| 29 | static void | ||
| 30 | swap_nod(inode *nod) | ||
| 31 | { | ||
| 32 | + uint32 nblk; | ||
| 33 | + | ||
| 34 | #define this nod | ||
| 35 | inode_decl | ||
| 36 | #undef this | ||
| 37 | + | ||
| 38 | + // block and character inodes store the major and minor in the | ||
| 39 | + // i_block, so we need to unswap to get those. Also, if it's | ||
| 40 | + // zero iblocks, put the data back like it belongs. | ||
| 41 | + nblk = nod->i_blocks / INOBLK; | ||
| 42 | + if ((nod->i_size && !nblk) | ||
| 43 | + || ((nod->i_mode & FM_IFBLK) == FM_IFBLK) | ||
| 44 | + || ((nod->i_mode & FM_IFCHR) == FM_IFCHR)) | ||
| 45 | + { | ||
| 46 | + int i; | ||
| 47 | + for(i = 0; i <= EXT2_TIND_BLOCK; i++) | ||
| 48 | + nod->i_block[i] = swab32(nod->i_block[i]); | ||
| 49 | + } | ||
| 50 | } | ||
| 51 | |||
| 52 | static void | ||
| 53 | @@ -852,6 +868,8 @@ put_blk(blk_info *bi) | ||
| 54 | // owned by the user. | ||
| 55 | typedef struct | ||
| 56 | { | ||
| 57 | + filesystem *fs; | ||
| 58 | + uint8 *b; | ||
| 59 | blk_info *bi; | ||
| 60 | } blkmap_info; | ||
| 61 | |||
| 62 | @@ -861,19 +879,23 @@ static inline uint32 * | ||
| 63 | get_blkmap(filesystem *fs, uint32 blk, blkmap_info **rbmi) | ||
| 64 | { | ||
| 65 | blkmap_info *bmi; | ||
| 66 | - uint8 *b; | ||
| 67 | |||
| 68 | bmi = malloc(sizeof(*bmi)); | ||
| 69 | if (!bmi) | ||
| 70 | error_msg_and_die("get_blkmap: out of memory"); | ||
| 71 | - b = get_blk(fs, blk, &bmi->bi); | ||
| 72 | + bmi->fs = fs; | ||
| 73 | + bmi->b = get_blk(fs, blk, &bmi->bi); | ||
| 74 | + if (bmi->fs->swapit) | ||
| 75 | + swap_block(bmi->b); | ||
| 76 | *rbmi = bmi; | ||
| 77 | - return (uint32 *) b; | ||
| 78 | + return (uint32 *) bmi->b; | ||
| 79 | } | ||
| 80 | |||
| 81 | static inline void | ||
| 82 | put_blkmap(blkmap_info *bmi) | ||
| 83 | { | ||
| 84 | + if (bmi->fs->swapit) | ||
| 85 | + swap_block(bmi->b); | ||
| 86 | put_blk(bmi->bi); | ||
| 87 | free(bmi); | ||
| 88 | } | ||
| 89 | @@ -882,7 +904,9 @@ put_blkmap(blkmap_info *bmi) | ||
| 90 | // by the user. | ||
| 91 | typedef struct | ||
| 92 | { | ||
| 93 | + filesystem *fs; | ||
| 94 | blk_info *bi; | ||
| 95 | + inode *itab; | ||
| 96 | } nod_info; | ||
| 97 | |||
| 98 | // Return a given inode from a filesystem. Make sure to call put_nod() | ||
| 99 | @@ -891,8 +915,8 @@ static inline inode * | ||
| 100 | get_nod(filesystem *fs, uint32 nod, nod_info **rni) | ||
| 101 | { | ||
| 102 | int grp, offset, boffset; | ||
| 103 | - inode *itab; | ||
| 104 | nod_info *ni; | ||
| 105 | + uint8 *b; | ||
| 106 | |||
| 107 | offset = GRP_IBM_OFFSET(fs,nod) - 1; | ||
| 108 | boffset = offset / (BLOCKSIZE / sizeof(inode)); | ||
| 109 | @@ -901,14 +925,20 @@ get_nod(filesystem *fs, uint32 nod, nod_info **rni) | ||
| 110 | ni = malloc(sizeof(*ni)); | ||
| 111 | if (!ni) | ||
| 112 | error_msg_and_die("get_nod: out of memory"); | ||
| 113 | - itab = (inode *)get_blk(fs, fs->gd[grp].bg_inode_table + boffset, &ni->bi); | ||
| 114 | + ni->fs = fs; | ||
| 115 | + b = get_blk(fs, fs->gd[grp].bg_inode_table + boffset, &ni->bi); | ||
| 116 | + ni->itab = ((inode *) b) + offset; | ||
| 117 | + if (fs->swapit) | ||
| 118 | + swap_nod(ni->itab); | ||
| 119 | *rni = ni; | ||
| 120 | - return itab+offset; | ||
| 121 | + return ni->itab; | ||
| 122 | } | ||
| 123 | |||
| 124 | static inline void | ||
| 125 | put_nod(nod_info *ni) | ||
| 126 | { | ||
| 127 | + if (ni->fs->swapit) | ||
| 128 | + swap_nod(ni->itab); | ||
| 129 | put_blk(ni->bi); | ||
| 130 | free(ni); | ||
| 131 | } | ||
| 132 | @@ -936,6 +966,8 @@ get_dir(filesystem *fs, uint32 nod, dirwalker *dw) | ||
| 133 | dw->last_d = (directory *) dw->b; | ||
| 134 | |||
| 135 | memcpy(&dw->d, dw->last_d, sizeof(directory)); | ||
| 136 | + if (fs->swapit) | ||
| 137 | + swap_dir(&dw->d); | ||
| 138 | return &dw->d; | ||
| 139 | } | ||
| 140 | |||
| 141 | @@ -945,6 +977,8 @@ next_dir(dirwalker *dw) | ||
| 142 | { | ||
| 143 | directory *next_d = (directory *)((int8*)dw->last_d + dw->d.d_rec_len); | ||
| 144 | |||
| 145 | + if (dw->fs->swapit) | ||
| 146 | + swap_dir(&dw->d); | ||
| 147 | memcpy(dw->last_d, &dw->d, sizeof(directory)); | ||
| 148 | |||
| 149 | if (((int8 *) next_d) >= ((int8 *) dw->b + BLOCKSIZE)) | ||
| 150 | @@ -952,6 +986,8 @@ next_dir(dirwalker *dw) | ||
| 151 | |||
| 152 | dw->last_d = next_d; | ||
| 153 | memcpy(&dw->d, next_d, sizeof(directory)); | ||
| 154 | + if (dw->fs->swapit) | ||
| 155 | + swap_dir(&dw->d); | ||
| 156 | return &dw->d; | ||
| 157 | } | ||
| 158 | |||
| 159 | @@ -959,6 +995,8 @@ next_dir(dirwalker *dw) | ||
| 160 | static inline void | ||
| 161 | put_dir(dirwalker *dw) | ||
| 162 | { | ||
| 163 | + if (dw->fs->swapit) | ||
| 164 | + swap_dir(&dw->d); | ||
| 165 | memcpy(dw->last_d, &dw->d, sizeof(directory)); | ||
| 166 | |||
| 167 | if (dw->nod == 0) | ||
| 168 | @@ -998,6 +1036,8 @@ shrink_dir(dirwalker *dw, uint32 nod, const char *name, int nlen) | ||
| 169 | d->d_rec_len = sizeof(directory) + rndup(d->d_name_len, 4); | ||
| 170 | preclen = d->d_rec_len; | ||
| 171 | reclen -= preclen; | ||
| 172 | + if (dw->fs->swapit) | ||
| 173 | + swap_dir(&dw->d); | ||
| 174 | memcpy(dw->last_d, &dw->d, sizeof(directory)); | ||
| 175 | |||
| 176 | dw->last_d = (directory *) (((int8 *) dw->last_d) + preclen); | ||
| 177 | @@ -2050,159 +2090,12 @@ add2fs_from_dir(filesystem *fs, uint32 this_nod, int squash_uids, int squash_per | ||
| 178 | closedir(dh); | ||
| 179 | } | ||
| 180 | |||
| 181 | -// endianness swap of x-indirect blocks | ||
| 182 | -static void | ||
| 183 | -swap_goodblocks(filesystem *fs, inode *nod) | ||
| 184 | -{ | ||
| 185 | - uint32 i,j; | ||
| 186 | - int done=0; | ||
| 187 | - uint32 *b,*b2; | ||
| 188 | - blk_info *bi, *bi2, *bi3; | ||
| 189 | - | ||
| 190 | - uint32 nblk = nod->i_blocks / INOBLK; | ||
| 191 | - if((nod->i_size && !nblk) || ((nod->i_mode & FM_IFBLK) == FM_IFBLK) || ((nod->i_mode & FM_IFCHR) == FM_IFCHR)) | ||
| 192 | - for(i = 0; i <= EXT2_TIND_BLOCK; i++) | ||
| 193 | - nod->i_block[i] = swab32(nod->i_block[i]); | ||
| 194 | - if(nblk <= EXT2_IND_BLOCK) | ||
| 195 | - return; | ||
| 196 | - swap_block(get_blk(fs, nod->i_block[EXT2_IND_BLOCK], &bi)); | ||
| 197 | - put_blk(bi); | ||
| 198 | - if(nblk <= EXT2_DIND_BLOCK + BLOCKSIZE/4) | ||
| 199 | - return; | ||
| 200 | - /* Currently this will fail b'cos the number of blocks as stored | ||
| 201 | - in i_blocks also includes the indirection blocks (see | ||
| 202 | - walk_bw). But this function assumes that i_blocks only | ||
| 203 | - stores the count of data blocks ( Actually according to | ||
| 204 | - "Understanding the Linux Kernel" (Table 17-3 p502 1st Ed) | ||
| 205 | - i_blocks IS supposed to store the count of data blocks). so | ||
| 206 | - with a file of size 268K nblk would be 269.The above check | ||
| 207 | - will be false even though double indirection hasn't been | ||
| 208 | - started.This is benign as 0 means block 0 which has been | ||
| 209 | - zeroed out and therefore points back to itself from any offset | ||
| 210 | - */ | ||
| 211 | - // FIXME: I have fixed that, but I have the feeling the rest of | ||
| 212 | - // ths function needs to be fixed for the same reasons - Xav | ||
| 213 | - assert(nod->i_block[EXT2_DIND_BLOCK] != 0); | ||
| 214 | - for(i = 0; i < BLOCKSIZE/4; i++) | ||
| 215 | - if(nblk > EXT2_IND_BLOCK + BLOCKSIZE/4 + (BLOCKSIZE/4)*i ) { | ||
| 216 | - swap_block(get_blk(fs, ((uint32*)get_blk(fs, nod->i_block[EXT2_DIND_BLOCK], &bi))[i], &bi2)); | ||
| 217 | - put_blk(bi); | ||
| 218 | - put_blk(bi2); | ||
| 219 | - } | ||
| 220 | - swap_block(get_blk(fs, nod->i_block[EXT2_DIND_BLOCK], &bi)); | ||
| 221 | - put_blk(bi); | ||
| 222 | - if(nblk <= EXT2_IND_BLOCK + BLOCKSIZE/4 + BLOCKSIZE/4 * BLOCKSIZE/4) | ||
| 223 | - return; | ||
| 224 | - /* Adding support for triple indirection */ | ||
| 225 | - b = (uint32*)get_blk(fs,nod->i_block[EXT2_TIND_BLOCK], &bi); | ||
| 226 | - for(i=0;i < BLOCKSIZE/4 && !done ; i++) { | ||
| 227 | - b2 = (uint32*)get_blk(fs,b[i], &bi2); | ||
| 228 | - for(j=0; j<BLOCKSIZE/4;j++) { | ||
| 229 | - if (nblk > ( EXT2_IND_BLOCK + BLOCKSIZE/4 + | ||
| 230 | - (BLOCKSIZE/4)*(BLOCKSIZE/4) + | ||
| 231 | - i*(BLOCKSIZE/4)*(BLOCKSIZE/4) + | ||
| 232 | - j*(BLOCKSIZE/4)) ) { | ||
| 233 | - swap_block(get_blk(fs,b2[j],&bi3)); | ||
| 234 | - put_blk(bi3); | ||
| 235 | - } | ||
| 236 | - else { | ||
| 237 | - done = 1; | ||
| 238 | - break; | ||
| 239 | - } | ||
| 240 | - } | ||
| 241 | - swap_block((uint8 *)b2); | ||
| 242 | - put_blk(bi2); | ||
| 243 | - } | ||
| 244 | - swap_block((uint8 *)b); | ||
| 245 | - put_blk(bi); | ||
| 246 | - return; | ||
| 247 | -} | ||
| 248 | - | ||
| 249 | -static void | ||
| 250 | -swap_badblocks(filesystem *fs, inode *nod) | ||
| 251 | -{ | ||
| 252 | - uint32 i,j; | ||
| 253 | - int done=0; | ||
| 254 | - uint32 *b,*b2; | ||
| 255 | - blk_info *bi, *bi2, *bi3; | ||
| 256 | - | ||
| 257 | - uint32 nblk = nod->i_blocks / INOBLK; | ||
| 258 | - if((nod->i_size && !nblk) || ((nod->i_mode & FM_IFBLK) == FM_IFBLK) || ((nod->i_mode & FM_IFCHR) == FM_IFCHR)) | ||
| 259 | - for(i = 0; i <= EXT2_TIND_BLOCK; i++) | ||
| 260 | - nod->i_block[i] = swab32(nod->i_block[i]); | ||
| 261 | - if(nblk <= EXT2_IND_BLOCK) | ||
| 262 | - return; | ||
| 263 | - swap_block(get_blk(fs, nod->i_block[EXT2_IND_BLOCK], &bi)); | ||
| 264 | - put_blk(bi); | ||
| 265 | - if(nblk <= EXT2_DIND_BLOCK + BLOCKSIZE/4) | ||
| 266 | - return; | ||
| 267 | - /* See comment in swap_goodblocks */ | ||
| 268 | - assert(nod->i_block[EXT2_DIND_BLOCK] != 0); | ||
| 269 | - swap_block(get_blk(fs, nod->i_block[EXT2_DIND_BLOCK], &bi)); | ||
| 270 | - put_blk(bi); | ||
| 271 | - for(i = 0; i < BLOCKSIZE/4; i++) | ||
| 272 | - if(nblk > EXT2_IND_BLOCK + BLOCKSIZE/4 + (BLOCKSIZE/4)*i ) { | ||
| 273 | - swap_block(get_blk(fs, ((uint32*)get_blk(fs, nod->i_block[EXT2_DIND_BLOCK],&bi))[i], &bi2)); | ||
| 274 | - put_blk(bi); | ||
| 275 | - put_blk(bi2); | ||
| 276 | - } | ||
| 277 | - if(nblk <= EXT2_IND_BLOCK + BLOCKSIZE/4 + BLOCKSIZE/4 * BLOCKSIZE/4) | ||
| 278 | - return; | ||
| 279 | - /* Adding support for triple indirection */ | ||
| 280 | - b = (uint32*)get_blk(fs,nod->i_block[EXT2_TIND_BLOCK],&bi); | ||
| 281 | - swap_block((uint8 *)b); | ||
| 282 | - for(i=0;i < BLOCKSIZE/4 && !done ; i++) { | ||
| 283 | - b2 = (uint32*)get_blk(fs,b[i],&bi2); | ||
| 284 | - swap_block((uint8 *)b2); | ||
| 285 | - for(j=0; j<BLOCKSIZE/4;j++) { | ||
| 286 | - if (nblk > ( EXT2_IND_BLOCK + BLOCKSIZE/4 + | ||
| 287 | - (BLOCKSIZE/4)*(BLOCKSIZE/4) + | ||
| 288 | - i*(BLOCKSIZE/4)*(BLOCKSIZE/4) + | ||
| 289 | - j*(BLOCKSIZE/4)) ) { | ||
| 290 | - swap_block(get_blk(fs,b2[j],&bi3)); | ||
| 291 | - put_blk(bi3); | ||
| 292 | - } | ||
| 293 | - else { | ||
| 294 | - done = 1; | ||
| 295 | - break; | ||
| 296 | - } | ||
| 297 | - } | ||
| 298 | - put_blk(bi2); | ||
| 299 | - } | ||
| 300 | - put_blk(bi); | ||
| 301 | - return; | ||
| 302 | -} | ||
| 303 | - | ||
| 304 | // endianness swap of the whole filesystem | ||
| 305 | static void | ||
| 306 | swap_goodfs(filesystem *fs) | ||
| 307 | { | ||
| 308 | uint32 i; | ||
| 309 | - nod_info *ni; | ||
| 310 | |||
| 311 | - for(i = 1; i < fs->sb->s_inodes_count; i++) | ||
| 312 | - { | ||
| 313 | - inode *nod = get_nod(fs, i, &ni); | ||
| 314 | - if(nod->i_mode & FM_IFDIR) | ||
| 315 | - { | ||
| 316 | - blockwalker bw; | ||
| 317 | - uint32 bk; | ||
| 318 | - init_bw(&bw); | ||
| 319 | - while((bk = walk_bw(fs, i, &bw, 0, 0)) != WALK_END) | ||
| 320 | - { | ||
| 321 | - directory *d; | ||
| 322 | - uint8 *b; | ||
| 323 | - blk_info *bi; | ||
| 324 | - b = get_blk(fs, bk, &bi); | ||
| 325 | - for(d = (directory*)b; (int8*)d + sizeof(*d) < (int8*)b + BLOCKSIZE; d = (directory*)((int8*)d + swab16(d->d_rec_len))) | ||
| 326 | - swap_dir(d); | ||
| 327 | - put_blk(bi); | ||
| 328 | - } | ||
| 329 | - } | ||
| 330 | - swap_goodblocks(fs, nod); | ||
| 331 | - swap_nod(nod); | ||
| 332 | - put_nod(ni); | ||
| 333 | - } | ||
| 334 | for(i=0;i<GRP_NBGROUPS(fs);i++) | ||
| 335 | swap_gd(&(fs->gd[i])); | ||
| 336 | swap_sb(fs->sb); | ||
| 337 | @@ -2215,35 +2108,12 @@ swap_badfs(filesystem *fs) | ||
| 338 | swap_sb(fs->sb); | ||
| 339 | for(i=0;i<GRP_NBGROUPS(fs);i++) | ||
| 340 | swap_gd(&(fs->gd[i])); | ||
| 341 | - for(i = 1; i < fs->sb->s_inodes_count; i++) | ||
| 342 | - { | ||
| 343 | - nod_info *ni; | ||
| 344 | - inode *nod = get_nod(fs, i, &ni); | ||
| 345 | - swap_nod(nod); | ||
| 346 | - swap_badblocks(fs, nod); | ||
| 347 | - if(nod->i_mode & FM_IFDIR) | ||
| 348 | - { | ||
| 349 | - blockwalker bw; | ||
| 350 | - uint32 bk; | ||
| 351 | - init_bw(&bw); | ||
| 352 | - while((bk = walk_bw(fs, i, &bw, 0, 0)) != WALK_END) | ||
| 353 | - { | ||
| 354 | - directory *d; | ||
| 355 | - uint8 *b; | ||
| 356 | - blk_info *bi; | ||
| 357 | - b = get_blk(fs, bk, &bi); | ||
| 358 | - for(d = (directory*)b; (int8*)d + sizeof(*d) < (int8*)b + BLOCKSIZE; d = (directory*)((int8*)d + d->d_rec_len)) | ||
| 359 | - swap_dir(d); | ||
| 360 | - put_blk(bi); | ||
| 361 | - } | ||
| 362 | - } | ||
| 363 | - } | ||
| 364 | } | ||
| 365 | |||
| 366 | // Allocate a new filesystem structure, allocate internal memory, | ||
| 367 | // and initialize the contents. | ||
| 368 | static filesystem * | ||
| 369 | -alloc_fs(uint32 nbblocks) | ||
| 370 | +alloc_fs(uint32 nbblocks, int swapit) | ||
| 371 | { | ||
| 372 | filesystem *fs; | ||
| 373 | |||
| 374 | @@ -2251,6 +2121,7 @@ alloc_fs(uint32 nbblocks) | ||
| 375 | if (!fs) | ||
| 376 | error_msg_and_die("not enough memory for filesystem"); | ||
| 377 | memset(fs, 0, sizeof(*fs)); | ||
| 378 | + fs->swapit = swapit; | ||
| 379 | if(!(fs->data = calloc(nbblocks, BLOCKSIZE))) | ||
| 380 | error_msg_and_die("not enough memory for filesystem"); | ||
| 381 | fs->hdlink_cnt = HDLINK_CNT; | ||
| 382 | @@ -2265,7 +2136,7 @@ alloc_fs(uint32 nbblocks) | ||
| 383 | |||
| 384 | // initialize an empty filesystem | ||
| 385 | static filesystem * | ||
| 386 | -init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp) | ||
| 387 | +init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp, int swapit) | ||
| 388 | { | ||
| 389 | uint32 i; | ||
| 390 | filesystem *fs; | ||
| 391 | @@ -2313,7 +2184,7 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp | ||
| 392 | free_blocks = nbblocks - overhead_per_group*nbgroups - 1 /*boot block*/; | ||
| 393 | free_blocks_per_group = nbblocks_per_group - overhead_per_group; | ||
| 394 | |||
| 395 | - fs = alloc_fs(nbblocks); | ||
| 396 | + fs = alloc_fs(nbblocks, swapit); | ||
| 397 | fs->nheadblocks = (((nbgroups * sizeof(groupdescriptor)) | ||
| 398 | + sizeof(superblock) + (BLOCKSIZE - 1)) | ||
| 399 | / BLOCKSIZE); | ||
| 400 | @@ -2454,7 +2325,7 @@ load_fs(FILE * fh, int swapit) | ||
| 401 | fssize = (fssize + BLOCKSIZE - 1) / BLOCKSIZE; | ||
| 402 | if(fssize < 16) // totally arbitrary | ||
| 403 | error_msg_and_die("too small filesystem"); | ||
| 404 | - fs = alloc_fs(fssize); | ||
| 405 | + fs = alloc_fs(fssize, swapit); | ||
| 406 | if(fread(fs->data, BLOCKSIZE, fssize, fh) != fssize) | ||
| 407 | perror_msg_and_die("input filesystem image"); | ||
| 408 | |||
| 409 | @@ -3014,7 +2885,8 @@ main(int argc, char **argv) | ||
| 410 | } | ||
| 411 | if(fs_timestamp == -1) | ||
| 412 | fs_timestamp = time(NULL); | ||
| 413 | - fs = init_fs(nbblocks, nbinodes, nbresrvd, holes, fs_timestamp); | ||
| 414 | + fs = init_fs(nbblocks, nbinodes, nbresrvd, holes, fs_timestamp, | ||
| 415 | + bigendian); | ||
| 416 | } | ||
| 417 | |||
| 418 | populate_fs(fs, dopt, didx, squash_uids, squash_perms, fs_timestamp, NULL); | ||
| 419 | -- | ||
| 420 | 1.7.4.1 | ||
| 421 | |||
diff --git a/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0010-Convert-over-to-keeping-the-filesystem-on-disk.patch b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0010-Convert-over-to-keeping-the-filesystem-on-disk.patch new file mode 100644 index 0000000000..79e82c8c73 --- /dev/null +++ b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0010-Convert-over-to-keeping-the-filesystem-on-disk.patch | |||
| @@ -0,0 +1,839 @@ | |||
| 1 | Upstream-Status: inappropriate | ||
| 2 | |||
| 3 | From 29a36b0b91ee009ee4219934c7a70278b1361834 Mon Sep 17 00:00:00 2001 | ||
| 4 | From: Corey Minyard <cminyard@mvista.com> | ||
| 5 | Date: Sun, 5 Jun 2011 15:24:57 -0500 | ||
| 6 | Subject: [PATCH 10/19] Convert over to keeping the filesystem on disk | ||
| 7 | |||
| 8 | This makes the actual filesystem be on disk and not in memory. It | ||
| 9 | adds caching of the filesystem data to help keep oft-accessed blocks | ||
| 10 | in memory and byteswapped. | ||
| 11 | --- | ||
| 12 | cache.h | 128 ++++++++++++++++++++ | ||
| 13 | genext2fs.c | 377 +++++++++++++++++++++++++++++++++++++++++++++++++---------- | ||
| 14 | list.h | 78 ++++++++++++ | ||
| 15 | 3 files changed, 521 insertions(+), 62 deletions(-) | ||
| 16 | create mode 100644 cache.h | ||
| 17 | create mode 100644 list.h | ||
| 18 | |||
| 19 | diff --git a/cache.h b/cache.h | ||
| 20 | new file mode 100644 | ||
| 21 | index 0000000..5275be6 | ||
| 22 | --- /dev/null | ||
| 23 | +++ b/cache.h | ||
| 24 | @@ -0,0 +1,128 @@ | ||
| 25 | +#ifndef __CACHE_H__ | ||
| 26 | +#define __CACHE_H__ | ||
| 27 | + | ||
| 28 | +#include "list.h" | ||
| 29 | + | ||
| 30 | +#define CACHE_LISTS 256 | ||
| 31 | + | ||
| 32 | +typedef struct | ||
| 33 | +{ | ||
| 34 | + list_elem link; | ||
| 35 | + list_elem lru_link; | ||
| 36 | +} cache_link; | ||
| 37 | + | ||
| 38 | +typedef struct | ||
| 39 | +{ | ||
| 40 | + /* LRU list holds unused items */ | ||
| 41 | + unsigned int lru_entries; | ||
| 42 | + list_elem lru_list; | ||
| 43 | + unsigned int max_free_entries; | ||
| 44 | + | ||
| 45 | + unsigned int entries; | ||
| 46 | + list_elem lists[CACHE_LISTS]; | ||
| 47 | + unsigned int (*elem_val)(cache_link *elem); | ||
| 48 | + void (*freed)(cache_link *elem); | ||
| 49 | +} listcache; | ||
| 50 | + | ||
| 51 | +static inline void | ||
| 52 | +cache_add(listcache *c, cache_link *elem) | ||
| 53 | +{ | ||
| 54 | + unsigned int hash = c->elem_val(elem) % CACHE_LISTS; | ||
| 55 | + int delcount = c->lru_entries - c->max_free_entries; | ||
| 56 | + | ||
| 57 | + if (delcount > 0) { | ||
| 58 | + /* Delete some unused items. */ | ||
| 59 | + list_elem *lru, *next; | ||
| 60 | + cache_link *l; | ||
| 61 | + list_for_each_elem_safe(&c->lru_list, lru, next) { | ||
| 62 | + l = container_of(lru, cache_link, lru_link); | ||
| 63 | + list_del(lru); | ||
| 64 | + list_del(&l->link); | ||
| 65 | + c->entries--; | ||
| 66 | + c->lru_entries--; | ||
| 67 | + c->freed(l); | ||
| 68 | + delcount--; | ||
| 69 | + if (delcount <= 0) | ||
| 70 | + break; | ||
| 71 | + } | ||
| 72 | + } | ||
| 73 | + | ||
| 74 | + c->entries++; | ||
| 75 | + list_item_init(&elem->lru_link); /* Mark it not in the LRU list */ | ||
| 76 | + list_add_after(&c->lists[hash], &elem->link); | ||
| 77 | +} | ||
| 78 | + | ||
| 79 | +static inline void | ||
| 80 | +cache_item_set_unused(listcache *c, cache_link *elem) | ||
| 81 | +{ | ||
| 82 | + list_add_before(&c->lru_list, &elem->lru_link); | ||
| 83 | + c->lru_entries++; | ||
| 84 | +} | ||
| 85 | + | ||
| 86 | +static inline cache_link * | ||
| 87 | +cache_find(listcache *c, unsigned int val) | ||
| 88 | +{ | ||
| 89 | + unsigned int hash = val % CACHE_LISTS; | ||
| 90 | + list_elem *elem; | ||
| 91 | + | ||
| 92 | + list_for_each_elem(&c->lists[hash], elem) { | ||
| 93 | + cache_link *l = container_of(elem, cache_link, link); | ||
| 94 | + if (c->elem_val(l) == val) { | ||
| 95 | + if (!list_empty(&l->lru_link)) { | ||
| 96 | + /* It's in the unused list, remove it. */ | ||
| 97 | + list_del(&l->lru_link); | ||
| 98 | + list_item_init(&l->lru_link); | ||
| 99 | + c->lru_entries--; | ||
| 100 | + } | ||
| 101 | + return l; | ||
| 102 | + } | ||
| 103 | + } | ||
| 104 | + return NULL; | ||
| 105 | +} | ||
| 106 | + | ||
| 107 | +static inline int | ||
| 108 | +cache_flush(listcache *c) | ||
| 109 | +{ | ||
| 110 | + list_elem *elem, *next; | ||
| 111 | + cache_link *l; | ||
| 112 | + int i; | ||
| 113 | + | ||
| 114 | + list_for_each_elem_safe(&c->lru_list, elem, next) { | ||
| 115 | + l = container_of(elem, cache_link, lru_link); | ||
| 116 | + list_del(elem); | ||
| 117 | + list_del(&l->link); | ||
| 118 | + c->entries--; | ||
| 119 | + c->lru_entries--; | ||
| 120 | + c->freed(l); | ||
| 121 | + } | ||
| 122 | + | ||
| 123 | + for (i = 0; i < CACHE_LISTS; i++) { | ||
| 124 | + list_for_each_elem_safe(&c->lists[i], elem, next) { | ||
| 125 | + l = container_of(elem, cache_link, link); | ||
| 126 | + list_del(&l->link); | ||
| 127 | + c->entries--; | ||
| 128 | + c->freed(l); | ||
| 129 | + } | ||
| 130 | + } | ||
| 131 | + | ||
| 132 | + return c->entries || c->lru_entries; | ||
| 133 | +} | ||
| 134 | + | ||
| 135 | +static inline void | ||
| 136 | +cache_init(listcache *c, unsigned int max_free_entries, | ||
| 137 | + unsigned int (*elem_val)(cache_link *elem), | ||
| 138 | + void (*freed)(cache_link *elem)) | ||
| 139 | +{ | ||
| 140 | + int i; | ||
| 141 | + | ||
| 142 | + c->entries = 0; | ||
| 143 | + c->lru_entries = 0; | ||
| 144 | + c->max_free_entries = max_free_entries; | ||
| 145 | + list_init(&c->lru_list); | ||
| 146 | + for (i = 0; i < CACHE_LISTS; i++) | ||
| 147 | + list_init(&c->lists[i]); | ||
| 148 | + c->elem_val = elem_val; | ||
| 149 | + c->freed = freed; | ||
| 150 | +} | ||
| 151 | + | ||
| 152 | +#endif /* __CACHE_H__ */ | ||
| 153 | diff --git a/genext2fs.c b/genext2fs.c | ||
| 154 | index 51403a2..f79438d 100644 | ||
| 155 | --- a/genext2fs.c | ||
| 156 | +++ b/genext2fs.c | ||
| 157 | @@ -142,6 +142,8 @@ | ||
| 158 | # include <limits.h> | ||
| 159 | #endif | ||
| 160 | |||
| 161 | +#include "cache.h" | ||
| 162 | + | ||
| 163 | struct stats { | ||
| 164 | unsigned long nblocks; | ||
| 165 | unsigned long ninodes; | ||
| 166 | @@ -600,6 +602,7 @@ struct hdlinks_s | ||
| 167 | #if BLOCKSIZE == 1024 | ||
| 168 | typedef struct | ||
| 169 | { | ||
| 170 | + FILE *f; | ||
| 171 | uint8 *data; | ||
| 172 | superblock *sb; | ||
| 173 | groupdescriptor *gd; | ||
| 174 | @@ -607,6 +610,10 @@ typedef struct | ||
| 175 | int swapit; | ||
| 176 | int32 hdlink_cnt; | ||
| 177 | struct hdlinks_s hdlinks; | ||
| 178 | + | ||
| 179 | + listcache blks; | ||
| 180 | + listcache inodes; | ||
| 181 | + listcache blkmaps; | ||
| 182 | } filesystem; | ||
| 183 | #else | ||
| 184 | #error UNHANDLED BLOCKSIZE | ||
| 185 | @@ -848,45 +855,150 @@ allocated(block b, uint32 item) | ||
| 186 | // by the user. | ||
| 187 | typedef struct | ||
| 188 | { | ||
| 189 | - int dummy; | ||
| 190 | + cache_link link; | ||
| 191 | + | ||
| 192 | + filesystem *fs; | ||
| 193 | + uint32 blk; | ||
| 194 | + uint8 *b; | ||
| 195 | + uint32 usecount; | ||
| 196 | } blk_info; | ||
| 197 | |||
| 198 | +#define MAX_FREE_CACHE_BLOCKS 100 | ||
| 199 | + | ||
| 200 | +static uint32 | ||
| 201 | +blk_elem_val(cache_link *elem) | ||
| 202 | +{ | ||
| 203 | + blk_info *bi = container_of(elem, blk_info, link); | ||
| 204 | + return bi->blk; | ||
| 205 | +} | ||
| 206 | + | ||
| 207 | +static void | ||
| 208 | +blk_freed(cache_link *elem) | ||
| 209 | +{ | ||
| 210 | + blk_info *bi = container_of(elem, blk_info, link); | ||
| 211 | + | ||
| 212 | + if (fseeko(bi->fs->f, ((off_t) bi->blk) * BLOCKSIZE, SEEK_SET)) | ||
| 213 | + perror_msg_and_die("fseek"); | ||
| 214 | + if (fwrite(bi->b, BLOCKSIZE, 1, bi->fs->f) != 1) | ||
| 215 | + perror_msg_and_die("get_blk: write"); | ||
| 216 | + free(bi->b); | ||
| 217 | + free(bi); | ||
| 218 | +} | ||
| 219 | + | ||
| 220 | // Return a given block from a filesystem. Make sure to call | ||
| 221 | // put_blk when you are done with it. | ||
| 222 | static inline uint8 * | ||
| 223 | get_blk(filesystem *fs, uint32 blk, blk_info **rbi) | ||
| 224 | { | ||
| 225 | - return fs->data + blk*BLOCKSIZE; | ||
| 226 | + cache_link *curr; | ||
| 227 | + blk_info *bi; | ||
| 228 | + | ||
| 229 | + if (blk < fs->nheadblocks) | ||
| 230 | + error_msg_and_die("Internal error, request for head block"); | ||
| 231 | + if (blk >= fs->sb->s_blocks_count) | ||
| 232 | + error_msg_and_die("Internal error, block out of range"); | ||
| 233 | + | ||
| 234 | + curr = cache_find(&fs->blks, blk); | ||
| 235 | + if (curr) { | ||
| 236 | + bi = container_of(curr, blk_info, link); | ||
| 237 | + bi->usecount++; | ||
| 238 | + goto out; | ||
| 239 | + } | ||
| 240 | + | ||
| 241 | + bi = malloc(sizeof(*bi)); | ||
| 242 | + if (!bi) | ||
| 243 | + error_msg_and_die("get_blk: out of memory"); | ||
| 244 | + bi->fs = fs; | ||
| 245 | + bi->blk = blk; | ||
| 246 | + bi->usecount = 1; | ||
| 247 | + bi->b = malloc(BLOCKSIZE); | ||
| 248 | + if (!bi->b) | ||
| 249 | + error_msg_and_die("get_blk: out of memory"); | ||
| 250 | + cache_add(&fs->blks, &bi->link); | ||
| 251 | + if (fseeko(fs->f, ((off_t) blk) * BLOCKSIZE, SEEK_SET)) | ||
| 252 | + perror_msg_and_die("fseek"); | ||
| 253 | + if (fread(bi->b, BLOCKSIZE, 1, fs->f) != 1) { | ||
| 254 | + if (ferror(fs->f)) | ||
| 255 | + perror_msg_and_die("fread"); | ||
| 256 | + memset(bi->b, 0, BLOCKSIZE); | ||
| 257 | + } | ||
| 258 | + | ||
| 259 | +out: | ||
| 260 | + *rbi = bi; | ||
| 261 | + return bi->b; | ||
| 262 | } | ||
| 263 | |||
| 264 | static inline void | ||
| 265 | put_blk(blk_info *bi) | ||
| 266 | { | ||
| 267 | + if (bi->usecount == 0) | ||
| 268 | + error_msg_and_die("Internal error: put_blk usecount zero"); | ||
| 269 | + bi->usecount--; | ||
| 270 | + if (bi->usecount == 0) | ||
| 271 | + /* Free happens in the cache code */ | ||
| 272 | + cache_item_set_unused(&bi->fs->blks, &bi->link); | ||
| 273 | } | ||
| 274 | |||
| 275 | // Used by get_blkmap/put_blkmap to hold information about an block map | ||
| 276 | // owned by the user. | ||
| 277 | typedef struct | ||
| 278 | { | ||
| 279 | + cache_link link; | ||
| 280 | + | ||
| 281 | filesystem *fs; | ||
| 282 | + uint32 blk; | ||
| 283 | uint8 *b; | ||
| 284 | blk_info *bi; | ||
| 285 | + uint32 usecount; | ||
| 286 | } blkmap_info; | ||
| 287 | |||
| 288 | +#define MAX_FREE_CACHE_BLOCKMAPS 100 | ||
| 289 | + | ||
| 290 | +static uint32 | ||
| 291 | +blkmap_elem_val(cache_link *elem) | ||
| 292 | +{ | ||
| 293 | + blkmap_info *bmi = container_of(elem, blkmap_info, link); | ||
| 294 | + return bmi->blk; | ||
| 295 | +} | ||
| 296 | + | ||
| 297 | +static void | ||
| 298 | +blkmap_freed(cache_link *elem) | ||
| 299 | +{ | ||
| 300 | + blkmap_info *bmi = container_of(elem, blkmap_info, link); | ||
| 301 | + | ||
| 302 | + if (bmi->fs->swapit) | ||
| 303 | + swap_block(bmi->b); | ||
| 304 | + put_blk(bmi->bi); | ||
| 305 | + free(bmi); | ||
| 306 | +} | ||
| 307 | + | ||
| 308 | // Return a given block map from a filesystem. Make sure to call | ||
| 309 | // put_blkmap when you are done with it. | ||
| 310 | static inline uint32 * | ||
| 311 | get_blkmap(filesystem *fs, uint32 blk, blkmap_info **rbmi) | ||
| 312 | { | ||
| 313 | blkmap_info *bmi; | ||
| 314 | + cache_link *curr; | ||
| 315 | + | ||
| 316 | + curr = cache_find(&fs->blkmaps, blk); | ||
| 317 | + if (curr) { | ||
| 318 | + bmi = container_of(curr, blkmap_info, link); | ||
| 319 | + bmi->usecount++; | ||
| 320 | + goto out; | ||
| 321 | + } | ||
| 322 | |||
| 323 | bmi = malloc(sizeof(*bmi)); | ||
| 324 | if (!bmi) | ||
| 325 | error_msg_and_die("get_blkmap: out of memory"); | ||
| 326 | bmi->fs = fs; | ||
| 327 | + bmi->blk = blk; | ||
| 328 | bmi->b = get_blk(fs, blk, &bmi->bi); | ||
| 329 | - if (bmi->fs->swapit) | ||
| 330 | + bmi->usecount = 1; | ||
| 331 | + cache_add(&fs->blkmaps, &bmi->link); | ||
| 332 | + | ||
| 333 | + if (fs->swapit) | ||
| 334 | swap_block(bmi->b); | ||
| 335 | +out: | ||
| 336 | *rbmi = bmi; | ||
| 337 | return (uint32 *) bmi->b; | ||
| 338 | } | ||
| 339 | @@ -894,42 +1006,83 @@ get_blkmap(filesystem *fs, uint32 blk, blkmap_info **rbmi) | ||
| 340 | static inline void | ||
| 341 | put_blkmap(blkmap_info *bmi) | ||
| 342 | { | ||
| 343 | - if (bmi->fs->swapit) | ||
| 344 | - swap_block(bmi->b); | ||
| 345 | - put_blk(bmi->bi); | ||
| 346 | - free(bmi); | ||
| 347 | + if (bmi->usecount == 0) | ||
| 348 | + error_msg_and_die("Internal error: put_blkmap usecount zero"); | ||
| 349 | + | ||
| 350 | + bmi->usecount--; | ||
| 351 | + if (bmi->usecount == 0) | ||
| 352 | + /* Free happens in the cache code */ | ||
| 353 | + cache_item_set_unused(&bmi->fs->blkmaps, &bmi->link); | ||
| 354 | } | ||
| 355 | |||
| 356 | // Used by get_nod/put_nod to hold information about an inode owned | ||
| 357 | // by the user. | ||
| 358 | typedef struct | ||
| 359 | { | ||
| 360 | + cache_link link; | ||
| 361 | + | ||
| 362 | filesystem *fs; | ||
| 363 | + uint32 nod; | ||
| 364 | + uint8 *b; | ||
| 365 | blk_info *bi; | ||
| 366 | inode *itab; | ||
| 367 | + uint32 usecount; | ||
| 368 | } nod_info; | ||
| 369 | |||
| 370 | +#define MAX_FREE_CACHE_INODES 100 | ||
| 371 | + | ||
| 372 | +static uint32 | ||
| 373 | +inode_elem_val(cache_link *elem) | ||
| 374 | +{ | ||
| 375 | + nod_info *ni = container_of(elem, nod_info, link); | ||
| 376 | + return ni->nod; | ||
| 377 | +} | ||
| 378 | + | ||
| 379 | +static void | ||
| 380 | +inode_freed(cache_link *elem) | ||
| 381 | +{ | ||
| 382 | + nod_info *ni = container_of(elem, nod_info, link); | ||
| 383 | + | ||
| 384 | + if (ni->fs->swapit) | ||
| 385 | + swap_nod(ni->itab); | ||
| 386 | + put_blk(ni->bi); | ||
| 387 | + free(ni); | ||
| 388 | +} | ||
| 389 | + | ||
| 390 | // Return a given inode from a filesystem. Make sure to call put_nod() | ||
| 391 | // when you are done with the inode. | ||
| 392 | static inline inode * | ||
| 393 | get_nod(filesystem *fs, uint32 nod, nod_info **rni) | ||
| 394 | { | ||
| 395 | int grp, offset, boffset; | ||
| 396 | + cache_link *curr; | ||
| 397 | nod_info *ni; | ||
| 398 | - uint8 *b; | ||
| 399 | |||
| 400 | - offset = GRP_IBM_OFFSET(fs,nod) - 1; | ||
| 401 | - boffset = offset / (BLOCKSIZE / sizeof(inode)); | ||
| 402 | - offset %= BLOCKSIZE / sizeof(inode); | ||
| 403 | - grp = GRP_GROUP_OF_INODE(fs,nod); | ||
| 404 | + curr = cache_find(&fs->inodes, nod); | ||
| 405 | + if (curr) { | ||
| 406 | + ni = container_of(curr, nod_info, link); | ||
| 407 | + ni->usecount++; | ||
| 408 | + goto out; | ||
| 409 | + } | ||
| 410 | + | ||
| 411 | ni = malloc(sizeof(*ni)); | ||
| 412 | if (!ni) | ||
| 413 | error_msg_and_die("get_nod: out of memory"); | ||
| 414 | ni->fs = fs; | ||
| 415 | - b = get_blk(fs, fs->gd[grp].bg_inode_table + boffset, &ni->bi); | ||
| 416 | - ni->itab = ((inode *) b) + offset; | ||
| 417 | + ni->nod = nod; | ||
| 418 | + ni->usecount = 1; | ||
| 419 | + cache_add(&fs->inodes, &ni->link); | ||
| 420 | + | ||
| 421 | + offset = GRP_IBM_OFFSET(fs, nod) - 1; | ||
| 422 | + boffset = offset / (BLOCKSIZE / sizeof(inode)); | ||
| 423 | + offset %= BLOCKSIZE / sizeof(inode); | ||
| 424 | + grp = GRP_GROUP_OF_INODE(fs,nod); | ||
| 425 | + ni->b = get_blk(fs, fs->gd[grp].bg_inode_table + boffset, &ni->bi); | ||
| 426 | + ni->itab = ((inode *) ni->b) + offset; | ||
| 427 | if (fs->swapit) | ||
| 428 | swap_nod(ni->itab); | ||
| 429 | + | ||
| 430 | +out: | ||
| 431 | *rni = ni; | ||
| 432 | return ni->itab; | ||
| 433 | } | ||
| 434 | @@ -937,10 +1090,13 @@ get_nod(filesystem *fs, uint32 nod, nod_info **rni) | ||
| 435 | static inline void | ||
| 436 | put_nod(nod_info *ni) | ||
| 437 | { | ||
| 438 | - if (ni->fs->swapit) | ||
| 439 | - swap_nod(ni->itab); | ||
| 440 | - put_blk(ni->bi); | ||
| 441 | - free(ni); | ||
| 442 | + if (ni->usecount == 0) | ||
| 443 | + error_msg_and_die("Internal error: put_nod usecount zero"); | ||
| 444 | + | ||
| 445 | + ni->usecount--; | ||
| 446 | + if (ni->usecount == 0) | ||
| 447 | + /* Free happens in the cache code */ | ||
| 448 | + cache_item_set_unused(&ni->fs->inodes, &ni->link); | ||
| 449 | } | ||
| 450 | |||
| 451 | // Used to hold state information while walking a directory inode. | ||
| 452 | @@ -2090,40 +2246,61 @@ add2fs_from_dir(filesystem *fs, uint32 this_nod, int squash_uids, int squash_per | ||
| 453 | closedir(dh); | ||
| 454 | } | ||
| 455 | |||
| 456 | -// endianness swap of the whole filesystem | ||
| 457 | static void | ||
| 458 | -swap_goodfs(filesystem *fs) | ||
| 459 | +swap_gds(filesystem *fs) | ||
| 460 | { | ||
| 461 | uint32 i; | ||
| 462 | - | ||
| 463 | for(i=0;i<GRP_NBGROUPS(fs);i++) | ||
| 464 | swap_gd(&(fs->gd[i])); | ||
| 465 | - swap_sb(fs->sb); | ||
| 466 | } | ||
| 467 | |||
| 468 | +// Copy size blocks from src to dst, putting holes in the output | ||
| 469 | +// file (if possible) if the input block is all zeros. | ||
| 470 | static void | ||
| 471 | -swap_badfs(filesystem *fs) | ||
| 472 | +copy_file(filesystem *fs, FILE *dst, FILE *src, size_t size) | ||
| 473 | { | ||
| 474 | - uint32 i; | ||
| 475 | - swap_sb(fs->sb); | ||
| 476 | - for(i=0;i<GRP_NBGROUPS(fs);i++) | ||
| 477 | - swap_gd(&(fs->gd[i])); | ||
| 478 | + uint8 *b; | ||
| 479 | + | ||
| 480 | + b = malloc(BLOCKSIZE); | ||
| 481 | + if (!b) | ||
| 482 | + error_msg_and_die("copy_file: out of memory"); | ||
| 483 | + if (fseek(src, 0, SEEK_SET)) | ||
| 484 | + perror_msg_and_die("fseek"); | ||
| 485 | + if (ftruncate(fileno(dst), 0)) | ||
| 486 | + perror_msg_and_die("copy_file: ftruncate"); | ||
| 487 | + while (size > 0) { | ||
| 488 | + if (fread(b, BLOCKSIZE, 1, src) != 1) | ||
| 489 | + perror_msg_and_die("copy failed on read"); | ||
| 490 | + if ((dst != stdout) && is_blk_empty(b)) { | ||
| 491 | + /* Empty block, just skip it */ | ||
| 492 | + if (fseek(dst, BLOCKSIZE, SEEK_CUR)) | ||
| 493 | + perror_msg_and_die("fseek"); | ||
| 494 | + } else { | ||
| 495 | + if (fwrite(b, BLOCKSIZE, 1, dst) != 1) | ||
| 496 | + perror_msg_and_die("copy failed on write"); | ||
| 497 | + } | ||
| 498 | + size --; | ||
| 499 | + } | ||
| 500 | } | ||
| 501 | |||
| 502 | // Allocate a new filesystem structure, allocate internal memory, | ||
| 503 | // and initialize the contents. | ||
| 504 | static filesystem * | ||
| 505 | -alloc_fs(uint32 nbblocks, int swapit) | ||
| 506 | +alloc_fs(int swapit, char *fname, uint32 nbblocks, FILE *srcfile) | ||
| 507 | { | ||
| 508 | filesystem *fs; | ||
| 509 | + struct stat srcstat, dststat; | ||
| 510 | |||
| 511 | fs = malloc(sizeof(*fs)); | ||
| 512 | if (!fs) | ||
| 513 | error_msg_and_die("not enough memory for filesystem"); | ||
| 514 | memset(fs, 0, sizeof(*fs)); | ||
| 515 | fs->swapit = swapit; | ||
| 516 | - if(!(fs->data = calloc(nbblocks, BLOCKSIZE))) | ||
| 517 | - error_msg_and_die("not enough memory for filesystem"); | ||
| 518 | + cache_init(&fs->blks, MAX_FREE_CACHE_BLOCKS, blk_elem_val, blk_freed); | ||
| 519 | + cache_init(&fs->blkmaps, MAX_FREE_CACHE_BLOCKMAPS, | ||
| 520 | + blkmap_elem_val, blkmap_freed); | ||
| 521 | + cache_init(&fs->inodes, MAX_FREE_CACHE_INODES, | ||
| 522 | + inode_elem_val, inode_freed); | ||
| 523 | fs->hdlink_cnt = HDLINK_CNT; | ||
| 524 | fs->hdlinks.hdl = calloc(sizeof(struct hdlink_s), fs->hdlink_cnt); | ||
| 525 | if (!fs->hdlinks.hdl) | ||
| 526 | @@ -2131,12 +2308,44 @@ alloc_fs(uint32 nbblocks, int swapit) | ||
| 527 | fs->hdlinks.count = 0 ; | ||
| 528 | fs->sb = (superblock *) (fs->data + BLOCKSIZE); | ||
| 529 | fs->gd = (groupdescriptor *) (fs->sb + 1); | ||
| 530 | + | ||
| 531 | + if (strcmp(fname, "-") == 0) | ||
| 532 | + fs->f = tmpfile(); | ||
| 533 | + else if (srcfile) { | ||
| 534 | + if (fstat(fileno(srcfile), &srcstat)) | ||
| 535 | + perror_msg_and_die("fstat srcfile"); | ||
| 536 | + if (stat(fname, &dststat)) | ||
| 537 | + perror_msg_and_die("stat-ing %s", fname); | ||
| 538 | + if (srcstat.st_ino == dststat.st_ino) { | ||
| 539 | + // source and destination are the same file, don't | ||
| 540 | + // truncate or copy, just use the file. | ||
| 541 | + fs->f = fopen(fname, "r+b"); | ||
| 542 | + } else { | ||
| 543 | + fs->f = fopen(fname, "w+b"); | ||
| 544 | + if (fs->f) | ||
| 545 | + copy_file(fs, fs->f, srcfile, | ||
| 546 | + nbblocks * BLOCKSIZE); | ||
| 547 | + } | ||
| 548 | + } else | ||
| 549 | + fs->f = fopen(fname, "w+b"); | ||
| 550 | + if (!fs->f) | ||
| 551 | + perror_msg_and_die("opening %s", fname); | ||
| 552 | return fs; | ||
| 553 | } | ||
| 554 | |||
| 555 | +/* Make sure the output file is the right size */ | ||
| 556 | +static void | ||
| 557 | +set_file_size(filesystem *fs) | ||
| 558 | +{ | ||
| 559 | + if (ftruncate(fileno(fs->f), | ||
| 560 | + ((off_t) fs->sb->s_blocks_count) * BLOCKSIZE)) | ||
| 561 | + perror_msg_and_die("set_file_size: ftruncate"); | ||
| 562 | +} | ||
| 563 | + | ||
| 564 | // initialize an empty filesystem | ||
| 565 | static filesystem * | ||
| 566 | -init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp, int swapit) | ||
| 567 | +init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, | ||
| 568 | + uint32 fs_timestamp, int swapit, char *fname) | ||
| 569 | { | ||
| 570 | uint32 i; | ||
| 571 | filesystem *fs; | ||
| 572 | @@ -2184,10 +2393,16 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp | ||
| 573 | free_blocks = nbblocks - overhead_per_group*nbgroups - 1 /*boot block*/; | ||
| 574 | free_blocks_per_group = nbblocks_per_group - overhead_per_group; | ||
| 575 | |||
| 576 | - fs = alloc_fs(nbblocks, swapit); | ||
| 577 | + fs = alloc_fs(swapit, fname, nbblocks, NULL); | ||
| 578 | fs->nheadblocks = (((nbgroups * sizeof(groupdescriptor)) | ||
| 579 | + sizeof(superblock) + (BLOCKSIZE - 1)) | ||
| 580 | / BLOCKSIZE); | ||
| 581 | + fs->sb = (superblock *) malloc(BLOCKSIZE); | ||
| 582 | + if (!fs->sb) | ||
| 583 | + error_msg_and_die("error allocating header memory"); | ||
| 584 | + fs->gd = (groupdescriptor *) calloc(fs->nheadblocks - 1, BLOCKSIZE); | ||
| 585 | + if (!fs->gd) | ||
| 586 | + error_msg_and_die("error allocating header memory"); | ||
| 587 | |||
| 588 | // create the superblock for an empty filesystem | ||
| 589 | fs->sb->s_inodes_count = nbinodes_per_group * nbgroups; | ||
| 590 | @@ -2205,6 +2420,10 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp | ||
| 591 | fs->sb->s_magic = EXT2_MAGIC_NUMBER; | ||
| 592 | fs->sb->s_lastcheck = fs_timestamp; | ||
| 593 | |||
| 594 | + fs->sb->s_reserved[200] = 0; | ||
| 595 | + | ||
| 596 | + set_file_size(fs); | ||
| 597 | + | ||
| 598 | // set up groupdescriptors | ||
| 599 | for(i=0, bbmpos=gdsz+2, ibmpos=bbmpos+1, itblpos=ibmpos+1; | ||
| 600 | i<nbgroups; | ||
| 601 | @@ -2315,27 +2534,49 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp | ||
| 602 | |||
| 603 | // loads a filesystem from disk | ||
| 604 | static filesystem * | ||
| 605 | -load_fs(FILE * fh, int swapit) | ||
| 606 | +load_fs(FILE * fh, int swapit, char *fname) | ||
| 607 | { | ||
| 608 | - size_t fssize; | ||
| 609 | + off_t fssize; | ||
| 610 | filesystem *fs; | ||
| 611 | - if((fseek(fh, 0, SEEK_END) < 0) || ((ssize_t)(fssize = ftell(fh)) == -1)) | ||
| 612 | + | ||
| 613 | + if((fseek(fh, 0, SEEK_END) < 0) || ((fssize = ftello(fh)) == -1)) | ||
| 614 | perror_msg_and_die("input filesystem image"); | ||
| 615 | rewind(fh); | ||
| 616 | - fssize = (fssize + BLOCKSIZE - 1) / BLOCKSIZE; | ||
| 617 | + if ((fssize % BLOCKSIZE) != 0) | ||
| 618 | + error_msg_and_die("Input file not a multiple of block size"); | ||
| 619 | + fssize /= BLOCKSIZE; | ||
| 620 | if(fssize < 16) // totally arbitrary | ||
| 621 | error_msg_and_die("too small filesystem"); | ||
| 622 | - fs = alloc_fs(fssize, swapit); | ||
| 623 | - if(fread(fs->data, BLOCKSIZE, fssize, fh) != fssize) | ||
| 624 | - perror_msg_and_die("input filesystem image"); | ||
| 625 | - | ||
| 626 | + fs = alloc_fs(swapit, fname, fssize, fh); | ||
| 627 | + | ||
| 628 | + /* Read and check the superblock, then read the superblock | ||
| 629 | + * and all the group descriptors */ | ||
| 630 | + fs->sb = malloc(BLOCKSIZE); | ||
| 631 | + if (!fs->sb) | ||
| 632 | + error_msg_and_die("error allocating header memory"); | ||
| 633 | + if (fseek(fs->f, BLOCKSIZE, SEEK_SET)) | ||
| 634 | + perror_msg_and_die("fseek"); | ||
| 635 | + if (fread(fs->sb, BLOCKSIZE, 1, fs->f) != 1) | ||
| 636 | + perror_msg_and_die("fread filesystem image superblock"); | ||
| 637 | if(swapit) | ||
| 638 | - swap_badfs(fs); | ||
| 639 | + swap_sb(fs->sb); | ||
| 640 | if(fs->sb->s_rev_level || (fs->sb->s_magic != EXT2_MAGIC_NUMBER)) | ||
| 641 | error_msg_and_die("not a suitable ext2 filesystem"); | ||
| 642 | fs->nheadblocks = (((GRP_NBGROUPS(fs) * sizeof(groupdescriptor)) | ||
| 643 | + sizeof(superblock) + (BLOCKSIZE - 1)) | ||
| 644 | / BLOCKSIZE); | ||
| 645 | + | ||
| 646 | + fs->gd = calloc(fs->nheadblocks - 1, BLOCKSIZE); | ||
| 647 | + if (!fs->gd) | ||
| 648 | + error_msg_and_die("error allocating header memory"); | ||
| 649 | + if (fread(fs->gd, BLOCKSIZE, fs->nheadblocks - 1, fs->f) | ||
| 650 | + != (fs->nheadblocks - 1)) | ||
| 651 | + perror_msg_and_die("fread filesystem image group descriptors"); | ||
| 652 | + | ||
| 653 | + if(swapit) | ||
| 654 | + swap_gds(fs); | ||
| 655 | + | ||
| 656 | + set_file_size(fs); | ||
| 657 | return fs; | ||
| 658 | } | ||
| 659 | |||
| 660 | @@ -2343,7 +2584,9 @@ static void | ||
| 661 | free_fs(filesystem *fs) | ||
| 662 | { | ||
| 663 | free(fs->hdlinks.hdl); | ||
| 664 | - free(fs->data); | ||
| 665 | + fclose(fs->f); | ||
| 666 | + free(fs->sb); | ||
| 667 | + free(fs->gd); | ||
| 668 | free(fs); | ||
| 669 | } | ||
| 670 | |||
| 671 | @@ -2631,16 +2874,30 @@ print_fs(filesystem *fs) | ||
| 672 | } | ||
| 673 | |||
| 674 | static void | ||
| 675 | -dump_fs(filesystem *fs, FILE * fh, int swapit) | ||
| 676 | -{ | ||
| 677 | - uint32 nbblocks = fs->sb->s_blocks_count; | ||
| 678 | +finish_fs(filesystem *fs) | ||
| 679 | +{ | ||
| 680 | + if (cache_flush(&fs->inodes)) | ||
| 681 | + error_msg_and_die("entry mismatch on inode cache flush"); | ||
| 682 | + if (cache_flush(&fs->blkmaps)) | ||
| 683 | + error_msg_and_die("entry mismatch on blockmap cache flush"); | ||
| 684 | + if (cache_flush(&fs->blks)) | ||
| 685 | + error_msg_and_die("entry mismatch on block cache flush"); | ||
| 686 | fs->sb->s_reserved[200] = 0; | ||
| 687 | - if(swapit) | ||
| 688 | - swap_goodfs(fs); | ||
| 689 | - if(fwrite(fs->data, BLOCKSIZE, nbblocks, fh) < nbblocks) | ||
| 690 | - perror_msg_and_die("output filesystem image"); | ||
| 691 | - if(swapit) | ||
| 692 | - swap_badfs(fs); | ||
| 693 | + if(fs->swapit) { | ||
| 694 | + swap_sb(fs->sb); | ||
| 695 | + swap_gds(fs); | ||
| 696 | + } | ||
| 697 | + if (fseek(fs->f, BLOCKSIZE, SEEK_SET)) | ||
| 698 | + perror_msg_and_die("fseek"); | ||
| 699 | + if(fwrite(fs->sb, BLOCKSIZE, 1, fs->f) != 1) | ||
| 700 | + perror_msg_and_die("output filesystem superblock"); | ||
| 701 | + if(fwrite(fs->gd, BLOCKSIZE, fs->nheadblocks - 1, fs->f) | ||
| 702 | + != (fs->nheadblocks - 1)) | ||
| 703 | + perror_msg_and_die("output filesystem group descriptors"); | ||
| 704 | + if(fs->swapit) { | ||
| 705 | + swap_sb(fs->sb); | ||
| 706 | + swap_gds(fs); | ||
| 707 | + } | ||
| 708 | } | ||
| 709 | |||
| 710 | static void | ||
| 711 | @@ -2851,11 +3108,11 @@ main(int argc, char **argv) | ||
| 712 | if(strcmp(fsin, "-")) | ||
| 713 | { | ||
| 714 | FILE * fh = xfopen(fsin, "rb"); | ||
| 715 | - fs = load_fs(fh, bigendian); | ||
| 716 | + fs = load_fs(fh, bigendian, fsout); | ||
| 717 | fclose(fh); | ||
| 718 | } | ||
| 719 | else | ||
| 720 | - fs = load_fs(stdin, bigendian); | ||
| 721 | + fs = load_fs(stdin, bigendian, fsout); | ||
| 722 | } | ||
| 723 | else | ||
| 724 | { | ||
| 725 | @@ -2886,7 +3143,7 @@ main(int argc, char **argv) | ||
| 726 | if(fs_timestamp == -1) | ||
| 727 | fs_timestamp = time(NULL); | ||
| 728 | fs = init_fs(nbblocks, nbinodes, nbresrvd, holes, fs_timestamp, | ||
| 729 | - bigendian); | ||
| 730 | + bigendian, fsout); | ||
| 731 | } | ||
| 732 | |||
| 733 | populate_fs(fs, dopt, didx, squash_uids, squash_perms, fs_timestamp, NULL); | ||
| 734 | @@ -2925,14 +3182,10 @@ main(int argc, char **argv) | ||
| 735 | flist_blocks(fs, nod, fh); | ||
| 736 | fclose(fh); | ||
| 737 | } | ||
| 738 | - if(strcmp(fsout, "-")) | ||
| 739 | - { | ||
| 740 | - FILE * fh = xfopen(fsout, "wb"); | ||
| 741 | - dump_fs(fs, fh, bigendian); | ||
| 742 | - fclose(fh); | ||
| 743 | - } | ||
| 744 | - else | ||
| 745 | - dump_fs(fs, stdout, bigendian); | ||
| 746 | + finish_fs(fs); | ||
| 747 | + if(strcmp(fsout, "-") == 0) | ||
| 748 | + copy_file(fs, stdout, fs->f, fs->sb->s_blocks_count); | ||
| 749 | + | ||
| 750 | free_fs(fs); | ||
| 751 | return 0; | ||
| 752 | } | ||
| 753 | diff --git a/list.h b/list.h | ||
| 754 | new file mode 100644 | ||
| 755 | index 0000000..52bb181 | ||
| 756 | --- /dev/null | ||
| 757 | +++ b/list.h | ||
| 758 | @@ -0,0 +1,78 @@ | ||
| 759 | +#ifndef __LIST_H__ | ||
| 760 | +#define __LIST_H__ | ||
| 761 | + | ||
| 762 | +#if STDC_HEADERS | ||
| 763 | +# include <stdlib.h> | ||
| 764 | +# include <stddef.h> | ||
| 765 | +#else | ||
| 766 | +# if HAVE_STDLIB_H | ||
| 767 | +# include <stdlib.h> | ||
| 768 | +# endif | ||
| 769 | +# if HAVE_STDDEF_H | ||
| 770 | +# include <stddef.h> | ||
| 771 | +# endif | ||
| 772 | +#endif | ||
| 773 | + | ||
| 774 | +#ifndef offsetof | ||
| 775 | +#define offsetof(st, m) \ | ||
| 776 | + ((size_t) ( (char *)&((st *)(0))->m - (char *)0 )) | ||
| 777 | +#endif | ||
| 778 | + | ||
| 779 | +#define container_of(ptr, type, member) ({ \ | ||
| 780 | + const typeof( ((type *)0)->member ) *__mptr = (ptr); \ | ||
| 781 | + (type *)( (char *)__mptr - offsetof(type,member) );}) | ||
| 782 | + | ||
| 783 | +typedef struct list_elem | ||
| 784 | +{ | ||
| 785 | + struct list_elem *next; | ||
| 786 | + struct list_elem *prev; | ||
| 787 | +} list_elem; | ||
| 788 | + | ||
| 789 | +static inline void list_init(list_elem *list) | ||
| 790 | +{ | ||
| 791 | + list->next = list; | ||
| 792 | + list->prev = list; | ||
| 793 | +} | ||
| 794 | + | ||
| 795 | +static inline void list_add_after(list_elem *pos, list_elem *elem) | ||
| 796 | +{ | ||
| 797 | + elem->next = pos->next; | ||
| 798 | + elem->prev = pos; | ||
| 799 | + pos->next->prev = elem; | ||
| 800 | + pos->next = elem; | ||
| 801 | +} | ||
| 802 | + | ||
| 803 | +static inline void list_add_before(list_elem *pos, list_elem *elem) | ||
| 804 | +{ | ||
| 805 | + elem->prev = pos->prev; | ||
| 806 | + elem->next = pos; | ||
| 807 | + pos->prev->next = elem; | ||
| 808 | + pos->prev = elem; | ||
| 809 | +} | ||
| 810 | + | ||
| 811 | +static inline void list_del(list_elem *elem) | ||
| 812 | +{ | ||
| 813 | + elem->next->prev = elem->prev; | ||
| 814 | + elem->prev->next = elem->next; | ||
| 815 | +} | ||
| 816 | + | ||
| 817 | +static inline void list_item_init(list_elem *elem) | ||
| 818 | +{ | ||
| 819 | + elem->next = elem; | ||
| 820 | + elem->prev = elem; | ||
| 821 | +} | ||
| 822 | + | ||
| 823 | +static inline int list_empty(list_elem *elem) | ||
| 824 | +{ | ||
| 825 | + return elem->next == elem; | ||
| 826 | +} | ||
| 827 | + | ||
| 828 | +#define list_for_each_elem(list, curr) \ | ||
| 829 | + for ((curr) = (list)->next; (curr) != (list); (curr) = (curr)->next) | ||
| 830 | + | ||
| 831 | +#define list_for_each_elem_safe(list, curr, next) \ | ||
| 832 | + for ((curr) = (list)->next, (next) = (curr)->next; \ | ||
| 833 | + (curr) != (list); \ | ||
| 834 | + (curr) = (next), (next) = (curr)->next) | ||
| 835 | + | ||
| 836 | +#endif /* __LIST_H__ */ | ||
| 837 | -- | ||
| 838 | 1.7.4.1 | ||
| 839 | |||
diff --git a/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0011-Copy-files-into-the-filesystem-a-piece-at-a-time.patch b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0011-Copy-files-into-the-filesystem-a-piece-at-a-time.patch new file mode 100644 index 0000000000..52dec56d5f --- /dev/null +++ b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0011-Copy-files-into-the-filesystem-a-piece-at-a-time.patch | |||
| @@ -0,0 +1,103 @@ | |||
| 1 | Upstream-Status: inappropriate | ||
| 2 | |||
| 3 | From 0a7d5b11e62e54f88ce3a49d0c2327d537b3f531 Mon Sep 17 00:00:00 2001 | ||
| 4 | From: Corey Minyard <cminyard@mvista.com> | ||
| 5 | Date: Sun, 5 Jun 2011 15:42:24 -0500 | ||
| 6 | Subject: [PATCH 11/19] Copy files into the filesystem a piece at a time | ||
| 7 | |||
| 8 | Instead of malloc-ing and entire files-worth of memory, reading it in, | ||
| 9 | and writing it to the filesystem, do it a piece at a time. This allows | ||
| 10 | very large files to be supported. | ||
| 11 | |||
| 12 | Also, use off_t and make it 64-bits so it supports filesystems and files | ||
| 13 | larger than 2GB. Full support for >2GB files is not quite here, that | ||
| 14 | requires rev 1 filesystem support, which is coming later. | ||
| 15 | --- | ||
| 16 | genext2fs.c | 35 +++++++++++++++++++++++------------ | ||
| 17 | 1 files changed, 23 insertions(+), 12 deletions(-) | ||
| 18 | |||
| 19 | diff --git a/genext2fs.c b/genext2fs.c | ||
| 20 | index f79438d..8a7f589 100644 | ||
| 21 | --- a/genext2fs.c | ||
| 22 | +++ b/genext2fs.c | ||
| 23 | @@ -53,6 +53,12 @@ | ||
| 24 | // along with -q, -P, -U | ||
| 25 | |||
| 26 | |||
| 27 | +/* | ||
| 28 | + * Allow fseeko/off_t to be 64-bit offsets to allow filesystems and | ||
| 29 | + * individual files >2GB. | ||
| 30 | + */ | ||
| 31 | +#define _FILE_OFFSET_BITS 64 | ||
| 32 | + | ||
| 33 | #include <config.h> | ||
| 34 | #include <stdio.h> | ||
| 35 | |||
| 36 | @@ -603,7 +609,6 @@ struct hdlinks_s | ||
| 37 | typedef struct | ||
| 38 | { | ||
| 39 | FILE *f; | ||
| 40 | - uint8 *data; | ||
| 41 | superblock *sb; | ||
| 42 | groupdescriptor *gd; | ||
| 43 | uint32 nheadblocks; | ||
| 44 | @@ -1907,30 +1912,38 @@ mklink_fs(filesystem *fs, uint32 parent_nod, const char *name, size_t size, uint | ||
| 45 | return nod; | ||
| 46 | } | ||
| 47 | |||
| 48 | +#define COPY_BLOCKS 16 | ||
| 49 | +#define CB_SIZE (COPY_BLOCKS * BLOCKSIZE) | ||
| 50 | + | ||
| 51 | // make a file from a FILE* | ||
| 52 | static uint32 | ||
| 53 | -mkfile_fs(filesystem *fs, uint32 parent_nod, const char *name, uint32 mode, size_t size, FILE *f, uid_t uid, gid_t gid, uint32 ctime, uint32 mtime) | ||
| 54 | +mkfile_fs(filesystem *fs, uint32 parent_nod, const char *name, uint32 mode, off_t size, FILE *f, uid_t uid, gid_t gid, uint32 ctime, uint32 mtime) | ||
| 55 | { | ||
| 56 | uint8 * b; | ||
| 57 | uint32 nod = mknod_fs(fs, parent_nod, name, mode|FM_IFREG, uid, gid, 0, 0, ctime, mtime); | ||
| 58 | nod_info *ni; | ||
| 59 | inode *node = get_nod(fs, nod, &ni); | ||
| 60 | + size_t readbytes; | ||
| 61 | inode_pos ipos; | ||
| 62 | |||
| 63 | + | ||
| 64 | + b = malloc(CB_SIZE); | ||
| 65 | + if (!b) | ||
| 66 | + error_msg_and_die("mkfile_fs: out of memory"); | ||
| 67 | inode_pos_init(fs, &ipos, nod, INODE_POS_TRUNCATE, NULL); | ||
| 68 | node->i_size = size; | ||
| 69 | - if (size) { | ||
| 70 | - if(!(b = (uint8*)calloc(rndup(size, BLOCKSIZE), 1))) | ||
| 71 | - error_msg_and_die("not enough mem to read file '%s'", name); | ||
| 72 | - if(f) | ||
| 73 | - if (fread(b, size, 1, f) != 1) // FIXME: ugly. use mmap() ... | ||
| 74 | - error_msg_and_die("fread failed"); | ||
| 75 | + while (size) { | ||
| 76 | + readbytes = fread(b, 1, CB_SIZE, f); | ||
| 77 | + if ((size < CB_SIZE && readbytes != size) | ||
| 78 | + || (size >= CB_SIZE && readbytes != CB_SIZE)) | ||
| 79 | + error_msg_and_die("fread failed"); | ||
| 80 | extend_inode_blk(fs, &ipos, b, | ||
| 81 | - rndup(size, BLOCKSIZE) / BLOCKSIZE); | ||
| 82 | - free(b); | ||
| 83 | + rndup(readbytes, BLOCKSIZE) / BLOCKSIZE); | ||
| 84 | + size -= readbytes; | ||
| 85 | } | ||
| 86 | inode_pos_finish(fs, &ipos); | ||
| 87 | put_nod(ni); | ||
| 88 | + free(b); | ||
| 89 | return nod; | ||
| 90 | } | ||
| 91 | |||
| 92 | @@ -2306,8 +2319,6 @@ alloc_fs(int swapit, char *fname, uint32 nbblocks, FILE *srcfile) | ||
| 93 | if (!fs->hdlinks.hdl) | ||
| 94 | error_msg_and_die("Not enough memory"); | ||
| 95 | fs->hdlinks.count = 0 ; | ||
| 96 | - fs->sb = (superblock *) (fs->data + BLOCKSIZE); | ||
| 97 | - fs->gd = (groupdescriptor *) (fs->sb + 1); | ||
| 98 | |||
| 99 | if (strcmp(fname, "-") == 0) | ||
| 100 | fs->f = tmpfile(); | ||
| 101 | -- | ||
| 102 | 1.7.4.1 | ||
| 103 | |||
diff --git a/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0012-Add-rev-1-support-large-file-support-and-rework-hole.patch b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0012-Add-rev-1-support-large-file-support-and-rework-hole.patch new file mode 100644 index 0000000000..2de6608c0c --- /dev/null +++ b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0012-Add-rev-1-support-large-file-support-and-rework-hole.patch | |||
| @@ -0,0 +1,211 @@ | |||
| 1 | Upstream-Status: inappropriate | ||
| 2 | |||
| 3 | From fbcbbba3b65402bd43a9e36593d544ff3451620e Mon Sep 17 00:00:00 2001 | ||
| 4 | From: Corey Minyard <cminyard@mvista.com> | ||
| 5 | Date: Fri, 3 Jun 2011 21:09:25 -0500 | ||
| 6 | Subject: [PATCH 12/19] Add rev 1 support, large file support, and rework holes | ||
| 7 | |||
| 8 | Add support for individual files larger than 2GB, which requires some | ||
| 9 | rev 1 filesystem support. | ||
| 10 | |||
| 11 | Also, since we have a non-overly filesystem structure, rework the | ||
| 12 | OP_HOLES hack and just put that flag in the filesystem structure. | ||
| 13 | This avoid having to mess around with the reserved bytes (which | ||
| 14 | changed with rev 1 support). | ||
| 15 | --- | ||
| 16 | genext2fs.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++----------- | ||
| 17 | 1 files changed, 56 insertions(+), 13 deletions(-) | ||
| 18 | |||
| 19 | diff --git a/genext2fs.c b/genext2fs.c | ||
| 20 | index 8a7f589..e420bba 100644 | ||
| 21 | --- a/genext2fs.c | ||
| 22 | +++ b/genext2fs.c | ||
| 23 | @@ -233,10 +233,6 @@ struct stats { | ||
| 24 | #define FM_IWOTH 0000002 // write | ||
| 25 | #define FM_IXOTH 0000001 // execute | ||
| 26 | |||
| 27 | -// options | ||
| 28 | - | ||
| 29 | -#define OP_HOLES 0x01 // make files with holes | ||
| 30 | - | ||
| 31 | /* Defines for accessing group details */ | ||
| 32 | |||
| 33 | // Number of groups in the filesystem | ||
| 34 | @@ -485,7 +481,22 @@ is_blk_empty(uint8 *b) | ||
| 35 | udecl32(s_creator_os) /* Indicator of which OS created the filesystem */ \ | ||
| 36 | udecl32(s_rev_level) /* The revision level of the filesystem */ \ | ||
| 37 | udecl16(s_def_resuid) /* The default uid for reserved blocks */ \ | ||
| 38 | - udecl16(s_def_resgid) /* The default gid for reserved blocks */ | ||
| 39 | + udecl16(s_def_resgid) /* The default gid for reserved blocks */ \ | ||
| 40 | + /* rev 1 version fields start here */ \ | ||
| 41 | + udecl32(s_first_ino) /* First non-reserved inode */ \ | ||
| 42 | + udecl16(s_inode_size) /* size of inode structure */ \ | ||
| 43 | + udecl16(s_block_group_nr) /* block group # of this superblock */ \ | ||
| 44 | + udecl32(s_feature_compat) /* compatible feature set */ \ | ||
| 45 | + udecl32(s_feature_incompat) /* incompatible feature set */ \ | ||
| 46 | + udecl32(s_feature_ro_compat) /* readonly-compatible feature set */ \ | ||
| 47 | + utdecl8(s_uuid,16) /* 128-bit uuid for volume */ \ | ||
| 48 | + utdecl8(s_volume_name,16) /* volume name */ \ | ||
| 49 | + utdecl8(s_last_mounted,64) /* directory where last mounted */ \ | ||
| 50 | + udecl32(s_algorithm_usage_bitmap) /* For compression */ | ||
| 51 | + | ||
| 52 | +#define EXT2_GOOD_OLD_FIRST_INO 11 | ||
| 53 | +#define EXT2_GOOD_OLD_INODE_SIZE 128 | ||
| 54 | +#define EXT2_FEATURE_RO_COMPAT_LARGE_FILE 0x0002 | ||
| 55 | |||
| 56 | #define groupdescriptor_decl \ | ||
| 57 | udecl32(bg_block_bitmap) /* Block number of the block bitmap */ \ | ||
| 58 | @@ -525,6 +536,7 @@ is_blk_empty(uint8 *b) | ||
| 59 | |||
| 60 | #define decl8(x) int8 x; | ||
| 61 | #define udecl8(x) uint8 x; | ||
| 62 | +#define utdecl8(x,n) uint8 x[n]; | ||
| 63 | #define decl16(x) int16 x; | ||
| 64 | #define udecl16(x) uint16 x; | ||
| 65 | #define decl32(x) int32 x; | ||
| 66 | @@ -534,7 +546,7 @@ is_blk_empty(uint8 *b) | ||
| 67 | typedef struct | ||
| 68 | { | ||
| 69 | superblock_decl | ||
| 70 | - uint32 s_reserved[235]; // Reserved | ||
| 71 | + uint32 s_reserved[205]; // Reserved | ||
| 72 | } superblock; | ||
| 73 | |||
| 74 | typedef struct | ||
| 75 | @@ -616,6 +628,8 @@ typedef struct | ||
| 76 | int32 hdlink_cnt; | ||
| 77 | struct hdlinks_s hdlinks; | ||
| 78 | |||
| 79 | + int holes; | ||
| 80 | + | ||
| 81 | listcache blks; | ||
| 82 | listcache inodes; | ||
| 83 | listcache blkmaps; | ||
| 84 | @@ -628,6 +642,7 @@ typedef struct | ||
| 85 | |||
| 86 | #undef decl8 | ||
| 87 | #undef udecl8 | ||
| 88 | +#undef utdecl8 | ||
| 89 | #undef decl16 | ||
| 90 | #undef udecl16 | ||
| 91 | #undef decl32 | ||
| 92 | @@ -636,6 +651,7 @@ typedef struct | ||
| 93 | |||
| 94 | #define decl8(x) | ||
| 95 | #define udecl8(x) | ||
| 96 | +#define utdecl8(x,n) | ||
| 97 | #define decl16(x) this->x = swab16(this->x); | ||
| 98 | #define udecl16(x) this->x = swab16(this->x); | ||
| 99 | #define decl32(x) this->x = swab32(this->x); | ||
| 100 | @@ -700,6 +716,7 @@ swap_block(block b) | ||
| 101 | |||
| 102 | #undef decl8 | ||
| 103 | #undef udecl8 | ||
| 104 | +#undef utdecl8 | ||
| 105 | #undef decl16 | ||
| 106 | #undef udecl16 | ||
| 107 | #undef decl32 | ||
| 108 | @@ -1695,7 +1712,7 @@ extend_inode_blk(filesystem *fs, inode_pos *ipos, block b, int amount) | ||
| 109 | |||
| 110 | for (pos = 0; amount; pos += BLOCKSIZE) | ||
| 111 | { | ||
| 112 | - int hole = ((fs->sb->s_reserved[200] & OP_HOLES) && is_blk_empty(b + pos)); | ||
| 113 | + int hole = (fs->holes && is_blk_empty(b + pos)); | ||
| 114 | |||
| 115 | bk = walk_bw(fs, ipos->nod, &ipos->bw, &amount, hole); | ||
| 116 | if (bk == WALK_END) | ||
| 117 | @@ -1912,6 +1929,14 @@ mklink_fs(filesystem *fs, uint32 parent_nod, const char *name, size_t size, uint | ||
| 118 | return nod; | ||
| 119 | } | ||
| 120 | |||
| 121 | +static void | ||
| 122 | +fs_upgrade_rev1_largefile(filesystem *fs) | ||
| 123 | +{ | ||
| 124 | + fs->sb->s_rev_level = 1; | ||
| 125 | + fs->sb->s_first_ino = EXT2_GOOD_OLD_FIRST_INO; | ||
| 126 | + fs->sb->s_inode_size = EXT2_GOOD_OLD_INODE_SIZE; | ||
| 127 | +} | ||
| 128 | + | ||
| 129 | #define COPY_BLOCKS 16 | ||
| 130 | #define CB_SIZE (COPY_BLOCKS * BLOCKSIZE) | ||
| 131 | |||
| 132 | @@ -1926,11 +1951,16 @@ mkfile_fs(filesystem *fs, uint32 parent_nod, const char *name, uint32 mode, off_ | ||
| 133 | size_t readbytes; | ||
| 134 | inode_pos ipos; | ||
| 135 | |||
| 136 | - | ||
| 137 | b = malloc(CB_SIZE); | ||
| 138 | if (!b) | ||
| 139 | error_msg_and_die("mkfile_fs: out of memory"); | ||
| 140 | inode_pos_init(fs, &ipos, nod, INODE_POS_TRUNCATE, NULL); | ||
| 141 | + if (size > 0x7fffffff) { | ||
| 142 | + if (fs->sb->s_rev_level < 1) | ||
| 143 | + fs_upgrade_rev1_largefile(fs); | ||
| 144 | + fs->sb->s_feature_ro_compat |= EXT2_FEATURE_RO_COMPAT_LARGE_FILE; | ||
| 145 | + } | ||
| 146 | + node->i_dir_acl = size >> 32; | ||
| 147 | node->i_size = size; | ||
| 148 | while (size) { | ||
| 149 | readbytes = fread(b, 1, CB_SIZE, f); | ||
| 150 | @@ -2269,6 +2299,8 @@ swap_gds(filesystem *fs) | ||
| 151 | |||
| 152 | // Copy size blocks from src to dst, putting holes in the output | ||
| 153 | // file (if possible) if the input block is all zeros. | ||
| 154 | +// Copy size blocks from src to dst, putting holes in the output | ||
| 155 | +// file (if possible) if the input block is all zeros. | ||
| 156 | static void | ||
| 157 | copy_file(filesystem *fs, FILE *dst, FILE *src, size_t size) | ||
| 158 | { | ||
| 159 | @@ -2284,7 +2316,7 @@ copy_file(filesystem *fs, FILE *dst, FILE *src, size_t size) | ||
| 160 | while (size > 0) { | ||
| 161 | if (fread(b, BLOCKSIZE, 1, src) != 1) | ||
| 162 | perror_msg_and_die("copy failed on read"); | ||
| 163 | - if ((dst != stdout) && is_blk_empty(b)) { | ||
| 164 | + if ((dst != stdout) && fs->holes && is_blk_empty(b)) { | ||
| 165 | /* Empty block, just skip it */ | ||
| 166 | if (fseek(dst, BLOCKSIZE, SEEK_CUR)) | ||
| 167 | perror_msg_and_die("fseek"); | ||
| 168 | @@ -2537,8 +2569,7 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, | ||
| 169 | fs->sb->s_max_mnt_count = 20; | ||
| 170 | |||
| 171 | // options for me | ||
| 172 | - if(holes) | ||
| 173 | - fs->sb->s_reserved[200] |= OP_HOLES; | ||
| 174 | + fs->holes = holes; | ||
| 175 | |||
| 176 | return fs; | ||
| 177 | } | ||
| 178 | @@ -2571,8 +2602,21 @@ load_fs(FILE * fh, int swapit, char *fname) | ||
| 179 | perror_msg_and_die("fread filesystem image superblock"); | ||
| 180 | if(swapit) | ||
| 181 | swap_sb(fs->sb); | ||
| 182 | - if(fs->sb->s_rev_level || (fs->sb->s_magic != EXT2_MAGIC_NUMBER)) | ||
| 183 | + if((fs->sb->s_rev_level > 1) || (fs->sb->s_magic != EXT2_MAGIC_NUMBER)) | ||
| 184 | error_msg_and_die("not a suitable ext2 filesystem"); | ||
| 185 | + if (fs->sb->s_rev_level > 0) { | ||
| 186 | + if (fs->sb->s_first_ino != EXT2_GOOD_OLD_FIRST_INO) | ||
| 187 | + error_msg_and_die("First inode incompatible"); | ||
| 188 | + if (fs->sb->s_inode_size != EXT2_GOOD_OLD_INODE_SIZE) | ||
| 189 | + error_msg_and_die("inode size incompatible"); | ||
| 190 | + if (fs->sb->s_feature_compat) | ||
| 191 | + error_msg_and_die("Unsupported compat features"); | ||
| 192 | + if (fs->sb->s_feature_incompat) | ||
| 193 | + error_msg_and_die("Unsupported incompat features"); | ||
| 194 | + if (fs->sb->s_feature_ro_compat | ||
| 195 | + & ~EXT2_FEATURE_RO_COMPAT_LARGE_FILE) | ||
| 196 | + error_msg_and_die("Unsupported ro compat features"); | ||
| 197 | + } | ||
| 198 | fs->nheadblocks = (((GRP_NBGROUPS(fs) * sizeof(groupdescriptor)) | ||
| 199 | + sizeof(superblock) + (BLOCKSIZE - 1)) | ||
| 200 | / BLOCKSIZE); | ||
| 201 | @@ -2893,7 +2937,6 @@ finish_fs(filesystem *fs) | ||
| 202 | error_msg_and_die("entry mismatch on blockmap cache flush"); | ||
| 203 | if (cache_flush(&fs->blks)) | ||
| 204 | error_msg_and_die("entry mismatch on block cache flush"); | ||
| 205 | - fs->sb->s_reserved[200] = 0; | ||
| 206 | if(fs->swapit) { | ||
| 207 | swap_sb(fs->sb); | ||
| 208 | swap_gds(fs); | ||
| 209 | -- | ||
| 210 | 1.7.4.1 | ||
| 211 | |||
diff --git a/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0013-Add-volume-id-support.patch b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0013-Add-volume-id-support.patch new file mode 100644 index 0000000000..1777dd6b0f --- /dev/null +++ b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0013-Add-volume-id-support.patch | |||
| @@ -0,0 +1,86 @@ | |||
| 1 | Upstream-Status: inappropriate | ||
| 2 | |||
| 3 | From 3b9edc3e7c809f64dc164d73b64ab4a606ccfea1 Mon Sep 17 00:00:00 2001 | ||
| 4 | From: Corey Minyard <cminyard@mvista.com> | ||
| 5 | Date: Fri, 3 Jun 2011 21:24:49 -0500 | ||
| 6 | Subject: [PATCH 13/19] Add volume id support. | ||
| 7 | |||
| 8 | Add support for setting the volume id of the filesystem. This is | ||
| 9 | functionally the same as the patch from OpenEmbedded, but is built | ||
| 10 | on previous changes in this patch set. | ||
| 11 | --- | ||
| 12 | genext2fs.8 | 3 +++ | ||
| 13 | genext2fs.c | 12 ++++++++++-- | ||
| 14 | 2 files changed, 13 insertions(+), 2 deletions(-) | ||
| 15 | |||
| 16 | diff --git a/genext2fs.8 b/genext2fs.8 | ||
| 17 | index 0f77e7c..8b8db25 100644 | ||
| 18 | --- a/genext2fs.8 | ||
| 19 | +++ b/genext2fs.8 | ||
| 20 | @@ -61,6 +61,9 @@ Size of the image in blocks. | ||
| 21 | .BI "\-N, \-\-number\-of\-inodes inodes" | ||
| 22 | Maximum number of inodes. | ||
| 23 | .TP | ||
| 24 | +.BI "\-L, \-\-volume\-id name" | ||
| 25 | +Set the volume id (volume name) for the filesystem. | ||
| 26 | +.TP | ||
| 27 | .BI "\-i, \-\-bytes\-per\-inode ratio" | ||
| 28 | Used to calculate the maximum number of inodes from the available blocks. | ||
| 29 | .TP | ||
| 30 | diff --git a/genext2fs.c b/genext2fs.c | ||
| 31 | index e420bba..4d01bc4 100644 | ||
| 32 | --- a/genext2fs.c | ||
| 33 | +++ b/genext2fs.c | ||
| 34 | @@ -3058,6 +3058,7 @@ main(int argc, char **argv) | ||
| 35 | int squash_perms = 0; | ||
| 36 | uint16 endian = 1; | ||
| 37 | int bigendian = !*(char*)&endian; | ||
| 38 | + char *volumelabel = NULL; | ||
| 39 | filesystem *fs; | ||
| 40 | int i; | ||
| 41 | int c; | ||
| 42 | @@ -3071,6 +3072,7 @@ main(int argc, char **argv) | ||
| 43 | { "size-in-blocks", required_argument, NULL, 'b' }, | ||
| 44 | { "bytes-per-inode", required_argument, NULL, 'i' }, | ||
| 45 | { "number-of-inodes", required_argument, NULL, 'N' }, | ||
| 46 | + { "volume-label", required_argument, NULL, 'L' }, | ||
| 47 | { "reserved-percentage", required_argument, NULL, 'm' }, | ||
| 48 | { "block-map", required_argument, NULL, 'g' }, | ||
| 49 | { "fill-value", required_argument, NULL, 'e' }, | ||
| 50 | @@ -3087,11 +3089,11 @@ main(int argc, char **argv) | ||
| 51 | |||
| 52 | app_name = argv[0]; | ||
| 53 | |||
| 54 | - while((c = getopt_long(argc, argv, "x:d:D:b:i:N:m:g:e:zfqUPhVv", longopts, NULL)) != EOF) { | ||
| 55 | + while((c = getopt_long(argc, argv, "x:d:D:b:i:N:L:m:g:e:zfqUPhVv", longopts, NULL)) != EOF) { | ||
| 56 | #else | ||
| 57 | app_name = argv[0]; | ||
| 58 | |||
| 59 | - while((c = getopt(argc, argv, "x:d:D:b:i:N:m:g:e:zfqUPhVv")) != EOF) { | ||
| 60 | + while((c = getopt(argc, argv, "x:d:D:b:i:N:L:m:g:e:zfqUPhVv")) != EOF) { | ||
| 61 | #endif /* HAVE_GETOPT_LONG */ | ||
| 62 | switch(c) | ||
| 63 | { | ||
| 64 | @@ -3111,6 +3113,9 @@ main(int argc, char **argv) | ||
| 65 | case 'N': | ||
| 66 | nbinodes = SI_atof(optarg); | ||
| 67 | break; | ||
| 68 | + case 'L': | ||
| 69 | + volumelabel = optarg; | ||
| 70 | + break; | ||
| 71 | case 'm': | ||
| 72 | reserved_frac = SI_atof(optarg) / 100; | ||
| 73 | break; | ||
| 74 | @@ -3199,6 +3204,9 @@ main(int argc, char **argv) | ||
| 75 | fs = init_fs(nbblocks, nbinodes, nbresrvd, holes, fs_timestamp, | ||
| 76 | bigendian, fsout); | ||
| 77 | } | ||
| 78 | + if (volumelabel != NULL) | ||
| 79 | + strncpy((char *)fs->sb->s_volume_name, volumelabel, | ||
| 80 | + sizeof(fs->sb->s_volume_name)); | ||
| 81 | |||
| 82 | populate_fs(fs, dopt, didx, squash_uids, squash_perms, fs_timestamp, NULL); | ||
| 83 | |||
| 84 | -- | ||
| 85 | 1.7.4.1 | ||
| 86 | |||
diff --git a/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0014-Remove-unneeded-setting-of-s_reserved.patch b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0014-Remove-unneeded-setting-of-s_reserved.patch new file mode 100644 index 0000000000..de196b0716 --- /dev/null +++ b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0014-Remove-unneeded-setting-of-s_reserved.patch | |||
| @@ -0,0 +1,28 @@ | |||
| 1 | Upstream-Status: inappropriate | ||
| 2 | |||
| 3 | From d20116479700bdc8a3b63b0025562671292728d6 Mon Sep 17 00:00:00 2001 | ||
| 4 | From: Corey Minyard <cminyard@mvista.com> | ||
| 5 | Date: Mon, 6 Jun 2011 13:39:50 -0500 | ||
| 6 | Subject: [PATCH 14/19] Remove unneeded setting of s_reserved. | ||
| 7 | |||
| 8 | This was missed in the previous patch to remove OP_HOLES. | ||
| 9 | --- | ||
| 10 | genext2fs.c | 2 -- | ||
| 11 | 1 files changed, 0 insertions(+), 2 deletions(-) | ||
| 12 | |||
| 13 | diff --git a/genext2fs.c b/genext2fs.c | ||
| 14 | index 4d01bc4..b466a6d 100644 | ||
| 15 | --- a/genext2fs.c | ||
| 16 | +++ b/genext2fs.c | ||
| 17 | @@ -2463,8 +2463,6 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, | ||
| 18 | fs->sb->s_magic = EXT2_MAGIC_NUMBER; | ||
| 19 | fs->sb->s_lastcheck = fs_timestamp; | ||
| 20 | |||
| 21 | - fs->sb->s_reserved[200] = 0; | ||
| 22 | - | ||
| 23 | set_file_size(fs); | ||
| 24 | |||
| 25 | // set up groupdescriptors | ||
| 26 | -- | ||
| 27 | 1.7.4.1 | ||
| 28 | |||
diff --git a/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0015-Rework-creating-the-lost-found-directory.patch b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0015-Rework-creating-the-lost-found-directory.patch new file mode 100644 index 0000000000..fbde366854 --- /dev/null +++ b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0015-Rework-creating-the-lost-found-directory.patch | |||
| @@ -0,0 +1,57 @@ | |||
| 1 | Upstream-Status: inappropriate | ||
| 2 | |||
| 3 | From 34a2d139e3cbc9fec1b07171fd13684d4239aa6b Mon Sep 17 00:00:00 2001 | ||
| 4 | From: Corey Minyard <cminyard@mvista.com> | ||
| 5 | Date: Mon, 6 Jun 2011 13:51:50 -0500 | ||
| 6 | Subject: [PATCH 15/19] Rework creating the lost+found directory | ||
| 7 | |||
| 8 | For some reason the lost+found directory was being created with | ||
| 9 | the size of the number of reserved blocks. I can't find any rationale | ||
| 10 | for that, mke2fs creates it with 16 blocks. So just create it with | ||
| 11 | 16 blocks, too. | ||
| 12 | --- | ||
| 13 | genext2fs.c | 15 ++++++--------- | ||
| 14 | 1 files changed, 6 insertions(+), 9 deletions(-) | ||
| 15 | |||
| 16 | diff --git a/genext2fs.c b/genext2fs.c | ||
| 17 | index b466a6d..fc7fe5f 100644 | ||
| 18 | --- a/genext2fs.c | ||
| 19 | +++ b/genext2fs.c | ||
| 20 | @@ -2537,28 +2537,25 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, | ||
| 21 | inode_pos_finish(fs, &ipos); | ||
| 22 | put_dir(&dw); | ||
| 23 | |||
| 24 | - // make lost+found directory and reserve blocks | ||
| 25 | + // make lost+found directory | ||
| 26 | if(fs->sb->s_r_blocks_count) | ||
| 27 | { | ||
| 28 | inode *node; | ||
| 29 | uint8 *b; | ||
| 30 | |||
| 31 | - nod = mkdir_fs(fs, EXT2_ROOT_INO, "lost+found", FM_IRWXU, 0, 0, fs_timestamp, fs_timestamp); | ||
| 32 | + nod = mkdir_fs(fs, EXT2_ROOT_INO, "lost+found", FM_IRWXU, | ||
| 33 | + 0, 0, fs_timestamp, fs_timestamp); | ||
| 34 | b = get_workblk(); | ||
| 35 | memset(b, 0, BLOCKSIZE); | ||
| 36 | ((directory*)b)->d_rec_len = BLOCKSIZE; | ||
| 37 | - /* We run into problems with e2fsck if directory lost+found grows | ||
| 38 | - * bigger than this. Need to find out why this happens - sundar | ||
| 39 | - */ | ||
| 40 | - if (fs->sb->s_r_blocks_count > fs->sb->s_blocks_count * MAX_RESERVED_BLOCKS ) | ||
| 41 | - fs->sb->s_r_blocks_count = fs->sb->s_blocks_count * MAX_RESERVED_BLOCKS; | ||
| 42 | inode_pos_init(fs, &ipos, nod, INODE_POS_EXTEND, NULL); | ||
| 43 | - for(i = 1; i < fs->sb->s_r_blocks_count; i++) | ||
| 44 | + // It is always 16 blocks to start out with | ||
| 45 | + for(i = 0; i < 16; i++) | ||
| 46 | extend_inode_blk(fs, &ipos, b, 1); | ||
| 47 | inode_pos_finish(fs, &ipos); | ||
| 48 | free_workblk(b); | ||
| 49 | node = get_nod(fs, nod, &ni); | ||
| 50 | - node->i_size = fs->sb->s_r_blocks_count * BLOCKSIZE; | ||
| 51 | + node->i_size = 16 * BLOCKSIZE; | ||
| 52 | put_nod(ni); | ||
| 53 | } | ||
| 54 | |||
| 55 | -- | ||
| 56 | 1.7.4.1 | ||
| 57 | |||
diff --git a/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0016-Fix-the-documentation-for-the-new-L-option.patch b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0016-Fix-the-documentation-for-the-new-L-option.patch new file mode 100644 index 0000000000..8c24db107e --- /dev/null +++ b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0016-Fix-the-documentation-for-the-new-L-option.patch | |||
| @@ -0,0 +1,29 @@ | |||
| 1 | Upstream-Status: inappropriate | ||
| 2 | |||
| 3 | From 1b5007ee27b9dbf5e84341dceadb83b96e6530d5 Mon Sep 17 00:00:00 2001 | ||
| 4 | From: Corey Minyard <cminyard@mvista.com> | ||
| 5 | Date: Mon, 6 Jun 2011 13:58:57 -0500 | ||
| 6 | Subject: [PATCH 16/19] Fix the documentation for the new -L option | ||
| 7 | |||
| 8 | --- | ||
| 9 | genext2fs.8 | 4 ++-- | ||
| 10 | 1 files changed, 2 insertions(+), 2 deletions(-) | ||
| 11 | |||
| 12 | diff --git a/genext2fs.8 b/genext2fs.8 | ||
| 13 | index 8b8db25..35e1588 100644 | ||
| 14 | --- a/genext2fs.8 | ||
| 15 | +++ b/genext2fs.8 | ||
| 16 | @@ -61,8 +61,8 @@ Size of the image in blocks. | ||
| 17 | .BI "\-N, \-\-number\-of\-inodes inodes" | ||
| 18 | Maximum number of inodes. | ||
| 19 | .TP | ||
| 20 | -.BI "\-L, \-\-volume\-id name" | ||
| 21 | -Set the volume id (volume name) for the filesystem. | ||
| 22 | +.BI "\-L, \-\-volume\-label name" | ||
| 23 | +Set the volume label for the filesystem. | ||
| 24 | .TP | ||
| 25 | .BI "\-i, \-\-bytes\-per\-inode ratio" | ||
| 26 | Used to calculate the maximum number of inodes from the available blocks. | ||
| 27 | -- | ||
| 28 | 1.7.4.1 | ||
| 29 | |||
diff --git a/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0017-Fix-file-same-comparison.patch b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0017-Fix-file-same-comparison.patch new file mode 100644 index 0000000000..40a7807b0d --- /dev/null +++ b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0017-Fix-file-same-comparison.patch | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | Upstream-Status: inappropriate | ||
| 2 | |||
| 3 | From 33c92a0b663d16d2260b391d39aa745acd4b360e Mon Sep 17 00:00:00 2001 | ||
| 4 | From: Corey Minyard <cminyard@mvista.com> | ||
| 5 | Date: Tue, 7 Jun 2011 07:23:23 -0500 | ||
| 6 | Subject: [PATCH 17/19] Fix "file same" comparison | ||
| 7 | |||
| 8 | It's not enough to check the inode, you also have to check the device | ||
| 9 | to make sure a file is the same. | ||
| 10 | --- | ||
| 11 | genext2fs.c | 3 ++- | ||
| 12 | 1 files changed, 2 insertions(+), 1 deletions(-) | ||
| 13 | |||
| 14 | diff --git a/genext2fs.c b/genext2fs.c | ||
| 15 | index fc7fe5f..485393c 100644 | ||
| 16 | --- a/genext2fs.c | ||
| 17 | +++ b/genext2fs.c | ||
| 18 | @@ -2359,7 +2359,8 @@ alloc_fs(int swapit, char *fname, uint32 nbblocks, FILE *srcfile) | ||
| 19 | perror_msg_and_die("fstat srcfile"); | ||
| 20 | if (stat(fname, &dststat)) | ||
| 21 | perror_msg_and_die("stat-ing %s", fname); | ||
| 22 | - if (srcstat.st_ino == dststat.st_ino) { | ||
| 23 | + if (srcstat.st_ino == dststat.st_ino | ||
| 24 | + && srcstat.st_dev == dststat.st_dev) { | ||
| 25 | // source and destination are the same file, don't | ||
| 26 | // truncate or copy, just use the file. | ||
| 27 | fs->f = fopen(fname, "r+b"); | ||
| 28 | -- | ||
| 29 | 1.7.4.1 | ||
| 30 | |||
diff --git a/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0018-Handle-files-changing-while-we-are-working.patch b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0018-Handle-files-changing-while-we-are-working.patch new file mode 100644 index 0000000000..3ea877c4d4 --- /dev/null +++ b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0018-Handle-files-changing-while-we-are-working.patch | |||
| @@ -0,0 +1,89 @@ | |||
| 1 | Upstream-Status: inappropriate | ||
| 2 | |||
| 3 | From fd1f52c435099eab199f2b06eb411aab337d7f47 Mon Sep 17 00:00:00 2001 | ||
| 4 | From: Corey Minyard <cminyard@mvista.com> | ||
| 5 | Date: Tue, 7 Jun 2011 07:29:53 -0500 | ||
| 6 | Subject: [PATCH 18/19] Handle files changing while we are working | ||
| 7 | |||
| 8 | Files may change or be deleted between the lstat and the actual | ||
| 9 | operation to read them and put them into the target filesystem. | ||
| 10 | Handle this more gracefully. Warn on file deletions, and handle | ||
| 11 | whatever size is read, not whatever size happens to be in the | ||
| 12 | inode when we stat-ed it. | ||
| 13 | |||
| 14 | Also clear the data to the end of an file's last block, to keep | ||
| 15 | things clean. | ||
| 16 | --- | ||
| 17 | genext2fs.c | 30 ++++++++++++++++++------------ | ||
| 18 | 1 files changed, 18 insertions(+), 12 deletions(-) | ||
| 19 | |||
| 20 | diff --git a/genext2fs.c b/genext2fs.c | ||
| 21 | index 485393c..28ba94f 100644 | ||
| 22 | --- a/genext2fs.c | ||
| 23 | +++ b/genext2fs.c | ||
| 24 | @@ -1942,19 +1942,30 @@ fs_upgrade_rev1_largefile(filesystem *fs) | ||
| 25 | |||
| 26 | // make a file from a FILE* | ||
| 27 | static uint32 | ||
| 28 | -mkfile_fs(filesystem *fs, uint32 parent_nod, const char *name, uint32 mode, off_t size, FILE *f, uid_t uid, gid_t gid, uint32 ctime, uint32 mtime) | ||
| 29 | +mkfile_fs(filesystem *fs, uint32 parent_nod, const char *name, uint32 mode, FILE *f, uid_t uid, gid_t gid, uint32 ctime, uint32 mtime) | ||
| 30 | { | ||
| 31 | uint8 * b; | ||
| 32 | uint32 nod = mknod_fs(fs, parent_nod, name, mode|FM_IFREG, uid, gid, 0, 0, ctime, mtime); | ||
| 33 | nod_info *ni; | ||
| 34 | inode *node = get_nod(fs, nod, &ni); | ||
| 35 | + off_t size = 0; | ||
| 36 | size_t readbytes; | ||
| 37 | inode_pos ipos; | ||
| 38 | + int fullsize; | ||
| 39 | |||
| 40 | b = malloc(CB_SIZE); | ||
| 41 | if (!b) | ||
| 42 | error_msg_and_die("mkfile_fs: out of memory"); | ||
| 43 | inode_pos_init(fs, &ipos, nod, INODE_POS_TRUNCATE, NULL); | ||
| 44 | + readbytes = fread(b, 1, CB_SIZE, f); | ||
| 45 | + while (readbytes) { | ||
| 46 | + fullsize = rndup(readbytes, BLOCKSIZE); | ||
| 47 | + // Fill to end of block with zeros. | ||
| 48 | + memset(b + readbytes, 0, fullsize - readbytes); | ||
| 49 | + extend_inode_blk(fs, &ipos, b, fullsize / BLOCKSIZE); | ||
| 50 | + size += readbytes; | ||
| 51 | + readbytes = fread(b, 1, CB_SIZE, f); | ||
| 52 | + } | ||
| 53 | if (size > 0x7fffffff) { | ||
| 54 | if (fs->sb->s_rev_level < 1) | ||
| 55 | fs_upgrade_rev1_largefile(fs); | ||
| 56 | @@ -1962,15 +1973,6 @@ mkfile_fs(filesystem *fs, uint32 parent_nod, const char *name, uint32 mode, off_ | ||
| 57 | } | ||
| 58 | node->i_dir_acl = size >> 32; | ||
| 59 | node->i_size = size; | ||
| 60 | - while (size) { | ||
| 61 | - readbytes = fread(b, 1, CB_SIZE, f); | ||
| 62 | - if ((size < CB_SIZE && readbytes != size) | ||
| 63 | - || (size >= CB_SIZE && readbytes != CB_SIZE)) | ||
| 64 | - error_msg_and_die("fread failed"); | ||
| 65 | - extend_inode_blk(fs, &ipos, b, | ||
| 66 | - rndup(readbytes, BLOCKSIZE) / BLOCKSIZE); | ||
| 67 | - size -= readbytes; | ||
| 68 | - } | ||
| 69 | inode_pos_finish(fs, &ipos); | ||
| 70 | put_nod(ni); | ||
| 71 | free(b); | ||
| 72 | @@ -2256,8 +2258,12 @@ add2fs_from_dir(filesystem *fs, uint32 this_nod, int squash_uids, int squash_per | ||
| 73 | free(lnk); | ||
| 74 | break; | ||
| 75 | case S_IFREG: | ||
| 76 | - fh = xfopen(dent->d_name, "rb"); | ||
| 77 | - nod = mkfile_fs(fs, this_nod, name, mode, st.st_size, fh, uid, gid, ctime, mtime); | ||
| 78 | + fh = fopen(dent->d_name, "rb"); | ||
| 79 | + if (!fh) { | ||
| 80 | + error_msg("Unable to open file %s", dent->d_name); | ||
| 81 | + break; | ||
| 82 | + } | ||
| 83 | + nod = mkfile_fs(fs, this_nod, name, mode, fh, uid, gid, ctime, mtime); | ||
| 84 | fclose(fh); | ||
| 85 | break; | ||
| 86 | case S_IFDIR: | ||
| 87 | -- | ||
| 88 | 1.7.4.1 | ||
| 89 | |||
diff --git a/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0019-Make-sure-superblock-is-clear-on-allocation.patch b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0019-Make-sure-superblock-is-clear-on-allocation.patch new file mode 100644 index 0000000000..a75a8128cc --- /dev/null +++ b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0019-Make-sure-superblock-is-clear-on-allocation.patch | |||
| @@ -0,0 +1,42 @@ | |||
| 1 | Upstream-Status: inappropriate | ||
| 2 | |||
| 3 | From a263cdabad01ba99581b26d1753cd459f2669413 Mon Sep 17 00:00:00 2001 | ||
| 4 | From: Corey Minyard <cminyard@mvista.com> | ||
| 5 | Date: Tue, 7 Jun 2011 09:14:19 -0500 | ||
| 6 | Subject: [PATCH 19/19] Make sure superblock is clear on allocation | ||
| 7 | |||
| 8 | Use calloc, not malloc, so the allocated superblock is zero-ed. Also, | ||
| 9 | get rid of some unnecessary casts. | ||
| 10 | --- | ||
| 11 | genext2fs.c | 6 +++--- | ||
| 12 | 1 files changed, 3 insertions(+), 3 deletions(-) | ||
| 13 | |||
| 14 | diff --git a/genext2fs.c b/genext2fs.c | ||
| 15 | index 28ba94f..fab90be 100644 | ||
| 16 | --- a/genext2fs.c | ||
| 17 | +++ b/genext2fs.c | ||
| 18 | @@ -2447,10 +2447,10 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, | ||
| 19 | fs->nheadblocks = (((nbgroups * sizeof(groupdescriptor)) | ||
| 20 | + sizeof(superblock) + (BLOCKSIZE - 1)) | ||
| 21 | / BLOCKSIZE); | ||
| 22 | - fs->sb = (superblock *) malloc(BLOCKSIZE); | ||
| 23 | + fs->sb = calloc(1, BLOCKSIZE); | ||
| 24 | if (!fs->sb) | ||
| 25 | error_msg_and_die("error allocating header memory"); | ||
| 26 | - fs->gd = (groupdescriptor *) calloc(fs->nheadblocks - 1, BLOCKSIZE); | ||
| 27 | + fs->gd = calloc(fs->nheadblocks - 1, BLOCKSIZE); | ||
| 28 | if (!fs->gd) | ||
| 29 | error_msg_and_die("error allocating header memory"); | ||
| 30 | |||
| 31 | @@ -2595,7 +2595,7 @@ load_fs(FILE * fh, int swapit, char *fname) | ||
| 32 | |||
| 33 | /* Read and check the superblock, then read the superblock | ||
| 34 | * and all the group descriptors */ | ||
| 35 | - fs->sb = malloc(BLOCKSIZE); | ||
| 36 | + fs->sb = calloc(1, BLOCKSIZE); | ||
| 37 | if (!fs->sb) | ||
| 38 | error_msg_and_die("error allocating header memory"); | ||
| 39 | if (fseek(fs->f, BLOCKSIZE, SEEK_SET)) | ||
| 40 | -- | ||
| 41 | 1.7.4.1 | ||
| 42 | |||
diff --git a/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/fix-nbblocks-cast.patch b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/fix-nbblocks-cast.patch index 3fd15e058b..05b095edf0 100644 --- a/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/fix-nbblocks-cast.patch +++ b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/fix-nbblocks-cast.patch | |||
| @@ -11,11 +11,13 @@ int tmp_nbinodes = nbblocks * BLOCKSIZE / bytes_per_inode; | |||
| 11 | Upstream-Status: Submitted | 11 | Upstream-Status: Submitted |
| 12 | Signed-off-by: Saul Wold <sgw@linux.intel.com> | 12 | Signed-off-by: Saul Wold <sgw@linux.intel.com> |
| 13 | 13 | ||
| 14 | Rebased by Dexuan Cui <dexuan.cui@intel.com> | ||
| 15 | |||
| 14 | Index: genext2fs-1.4.1/genext2fs.c | 16 | Index: genext2fs-1.4.1/genext2fs.c |
| 15 | =================================================================== | 17 | =================================================================== |
| 16 | --- genext2fs-1.4.1.orig/genext2fs.c | 18 | --- a/genext2fs.c 2012-03-29 00:07:20.308856017 +0800 |
| 17 | +++ genext2fs-1.4.1/genext2fs.c | 19 | +++ b/genext2fs.c 2012-03-29 00:09:06.848856005 +0800 |
| 18 | @@ -2447,7 +2447,7 @@ extern int optind, opterr, optopt; | 20 | @@ -3041,7 +3041,7 @@ |
| 19 | int | 21 | int |
| 20 | main(int argc, char **argv) | 22 | main(int argc, char **argv) |
| 21 | { | 23 | { |
| @@ -24,12 +26,12 @@ Index: genext2fs-1.4.1/genext2fs.c | |||
| 24 | int nbinodes = -1; | 26 | int nbinodes = -1; |
| 25 | int nbresrvd = -1; | 27 | int nbresrvd = -1; |
| 26 | float bytes_per_inode = -1; | 28 | float bytes_per_inode = -1; |
| 27 | @@ -2609,7 +2609,7 @@ main(int argc, char **argv) | 29 | @@ -3203,7 +3203,7 @@ |
| 28 | } | 30 | } |
| 29 | if(fs_timestamp == -1) | 31 | if(fs_timestamp == -1) |
| 30 | fs_timestamp = time(NULL); | 32 | fs_timestamp = time(NULL); |
| 31 | - fs = init_fs(nbblocks, nbinodes, nbresrvd, holes, fs_timestamp); | 33 | - fs = init_fs(nbblocks, nbinodes, nbresrvd, holes, fs_timestamp, |
| 32 | + fs = init_fs((int)nbblocks, nbinodes, nbresrvd, holes, fs_timestamp); | 34 | + fs = init_fs((int)nbblocks, nbinodes, nbresrvd, holes, fs_timestamp, |
| 35 | bigendian, fsout); | ||
| 33 | } | 36 | } |
| 34 | 37 | if (volumelabel != NULL) | |
| 35 | populate_fs(fs, dopt, didx, squash_uids, squash_perms, fs_timestamp, NULL); | ||
diff --git a/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/update_to_1.95.patch b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/update_to_1.95.patch new file mode 100644 index 0000000000..ea2b16ccf9 --- /dev/null +++ b/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/update_to_1.95.patch | |||
| @@ -0,0 +1,119 @@ | |||
| 1 | See http://genext2fs.cvs.sourceforge.net/viewvc/genext2fs/genext2fs/genext2fs.c?view=log | ||
| 2 | |||
| 3 | The latest version of genext2fs.c is the v1.95 in the cvs repo: | ||
| 4 | http://genext2fs.cvs.sourceforge.net/viewvc/genext2fs/genext2fs/genext2fs.c?revision=1.95 | ||
| 5 | |||
| 6 | First let's upgrade to the version. | ||
| 7 | |||
| 8 | Upstream-Status: inappropriate | ||
| 9 | |||
| 10 | Signed-off-by: Dexuan Cui <dexuan.cui@intel.com> | ||
| 11 | |||
| 12 | --- a/genext2fs.c 2007-03-26 22:19:59.000000000 +0800 | ||
| 13 | +++ b/genext2fs.c 2012-03-28 22:15:03.678856820 +0800 | ||
| 14 | @@ -286,7 +286,9 @@ | ||
| 15 | // older solaris. Note that this is still not very portable, in that | ||
| 16 | // the return value cannot be trusted. | ||
| 17 | |||
| 18 | -#if SCANF_CAN_MALLOC | ||
| 19 | +#if 0 // SCANF_CAN_MALLOC | ||
| 20 | +// C99 define "a" for floating point, so you can have runtime surprise | ||
| 21 | +// according the library versions | ||
| 22 | # define SCANF_PREFIX "a" | ||
| 23 | # define SCANF_STRING(s) (&s) | ||
| 24 | #else | ||
| 25 | @@ -778,7 +780,7 @@ | ||
| 26 | if(hdlinks.hdl[i].src_inode == inode) | ||
| 27 | return i; | ||
| 28 | } | ||
| 29 | - return -1; | ||
| 30 | + return -1; | ||
| 31 | } | ||
| 32 | |||
| 33 | // printf helper macro | ||
| 34 | @@ -1356,20 +1358,23 @@ | ||
| 35 | return nod; | ||
| 36 | } | ||
| 37 | |||
| 38 | +// chmod an inode | ||
| 39 | +void | ||
| 40 | +chmod_fs(filesystem *fs, uint32 nod, uint16 mode, uint16 uid, uint16 gid) | ||
| 41 | +{ | ||
| 42 | + inode *node; | ||
| 43 | + node = get_nod(fs, nod); | ||
| 44 | + node->i_mode = (node->i_mode & ~FM_IMASK) | (mode & FM_IMASK); | ||
| 45 | + node->i_uid = uid; | ||
| 46 | + node->i_gid = gid; | ||
| 47 | +} | ||
| 48 | + | ||
| 49 | // create a simple inode | ||
| 50 | static uint32 | ||
| 51 | mknod_fs(filesystem *fs, uint32 parent_nod, const char *name, uint16 mode, uint16 uid, uint16 gid, uint8 major, uint8 minor, uint32 ctime, uint32 mtime) | ||
| 52 | { | ||
| 53 | uint32 nod; | ||
| 54 | inode *node; | ||
| 55 | - if((nod = find_dir(fs, parent_nod, name))) | ||
| 56 | - { | ||
| 57 | - node = get_nod(fs, nod); | ||
| 58 | - if((node->i_mode & FM_IFMT) != (mode & FM_IFMT)) | ||
| 59 | - error_msg_and_die("node '%s' already exists and isn't of the same type", name); | ||
| 60 | - node->i_mode = mode; | ||
| 61 | - } | ||
| 62 | - else | ||
| 63 | { | ||
| 64 | nod = alloc_nod(fs); | ||
| 65 | node = get_nod(fs, nod); | ||
| 66 | @@ -1591,13 +1596,24 @@ | ||
| 67 | dname = malloc(len + 1); | ||
| 68 | for(i = start; i < count; i++) | ||
| 69 | { | ||
| 70 | + uint32 oldnod; | ||
| 71 | SNPRINTF(dname, len, "%s%lu", name, i); | ||
| 72 | - mknod_fs(fs, nod, dname, mode, uid, gid, major, minor + (i * increment - start), ctime, mtime); | ||
| 73 | + oldnod = find_dir(fs, nod, dname); | ||
| 74 | + if(oldnod) | ||
| 75 | + chmod_fs(fs, oldnod, mode, uid, gid); | ||
| 76 | + else | ||
| 77 | + mknod_fs(fs, nod, dname, mode, uid, gid, major, minor + (i * increment - start), ctime, mtime); | ||
| 78 | } | ||
| 79 | free(dname); | ||
| 80 | } | ||
| 81 | else | ||
| 82 | - mknod_fs(fs, nod, name, mode, uid, gid, major, minor, ctime, mtime); | ||
| 83 | + { | ||
| 84 | + uint32 oldnod = find_dir(fs, nod, name); | ||
| 85 | + if(oldnod) | ||
| 86 | + chmod_fs(fs, oldnod, mode, uid, gid); | ||
| 87 | + else | ||
| 88 | + mknod_fs(fs, nod, name, mode, uid, gid, major, minor, ctime, mtime); | ||
| 89 | + } | ||
| 90 | } | ||
| 91 | } | ||
| 92 | if (line) | ||
| 93 | @@ -1664,6 +1680,17 @@ | ||
| 94 | } | ||
| 95 | else | ||
| 96 | { | ||
| 97 | + if((nod = find_dir(fs, this_nod, name))) | ||
| 98 | + { | ||
| 99 | + error_msg("ignoring duplicate entry %s", name); | ||
| 100 | + if(S_ISDIR(st.st_mode)) { | ||
| 101 | + if(chdir(dent->d_name) < 0) | ||
| 102 | + perror_msg_and_die(name); | ||
| 103 | + add2fs_from_dir(fs, nod, squash_uids, squash_perms, fs_timestamp, stats); | ||
| 104 | + chdir(".."); | ||
| 105 | + } | ||
| 106 | + continue; | ||
| 107 | + } | ||
| 108 | save_nod = 0; | ||
| 109 | /* Check for hardlinks */ | ||
| 110 | if (!S_ISDIR(st.st_mode) && !S_ISLNK(st.st_mode) && st.st_nlink > 1) { | ||
| 111 | @@ -1994,7 +2021,7 @@ | ||
| 112 | //system blocks | ||
| 113 | for(j = 1; j <= overhead_per_group; j++) | ||
| 114 | allocate(bbm, j); | ||
| 115 | - | ||
| 116 | + | ||
| 117 | /* Inode bitmap */ | ||
| 118 | ibm = get_blk(fs,fs->gd[i].bg_inode_bitmap); | ||
| 119 | //non-filesystem inodes | ||
diff --git a/meta/recipes-devtools/genext2fs/genext2fs_1.4.1.bb b/meta/recipes-devtools/genext2fs/genext2fs_1.4.1.bb index 012ec6c4fb..702245ff75 100644 --- a/meta/recipes-devtools/genext2fs/genext2fs_1.4.1.bb +++ b/meta/recipes-devtools/genext2fs/genext2fs_1.4.1.bb | |||
| @@ -1,8 +1,28 @@ | |||
| 1 | require genext2fs.inc | 1 | require genext2fs.inc |
| 2 | 2 | ||
| 3 | PR = "r1" | 3 | PR = "r2" |
| 4 | 4 | ||
| 5 | SRC_URI += "file://fix-nbblocks-cast.patch" | 5 | SRC_URI += "file://update_to_1.95.patch \ |
| 6 | file://0001-Fix-warnings-remove-some-unused-macros.patch \ | ||
| 7 | file://0002-Add-put_blk-and-put_nod-routines.patch \ | ||
| 8 | file://0003-Add-get_blkmap-and-put_blkmap.patch \ | ||
| 9 | file://0004-Add-a-dirwalker-for-walking-through-directory-entrie.patch \ | ||
| 10 | file://0005-Make-filesystem-struct-not-an-overloay.patch \ | ||
| 11 | file://0006-Improve-the-efficiency-of-extend_blk.patch \ | ||
| 12 | file://0007-Move-hdlinks-into-the-filesystem-structure.patch \ | ||
| 13 | file://0008-Separate-out-the-creation-of-the-filesystem-structur.patch \ | ||
| 14 | file://0009-Move-byte-swapping-into-the-get-put-routines.patch \ | ||
| 15 | file://0010-Convert-over-to-keeping-the-filesystem-on-disk.patch \ | ||
| 16 | file://0011-Copy-files-into-the-filesystem-a-piece-at-a-time.patch \ | ||
| 17 | file://0012-Add-rev-1-support-large-file-support-and-rework-hole.patch \ | ||
| 18 | file://0013-Add-volume-id-support.patch \ | ||
| 19 | file://0014-Remove-unneeded-setting-of-s_reserved.patch \ | ||
| 20 | file://0015-Rework-creating-the-lost-found-directory.patch \ | ||
| 21 | file://0016-Fix-the-documentation-for-the-new-L-option.patch \ | ||
| 22 | file://0017-Fix-file-same-comparison.patch \ | ||
| 23 | file://0018-Handle-files-changing-while-we-are-working.patch \ | ||
| 24 | file://0019-Make-sure-superblock-is-clear-on-allocation.patch \ | ||
| 25 | file://fix-nbblocks-cast.patch" | ||
| 6 | 26 | ||
| 7 | SRC_URI[md5sum] = "b7b6361bcce2cedff1ae437fadafe53b" | 27 | SRC_URI[md5sum] = "b7b6361bcce2cedff1ae437fadafe53b" |
| 8 | SRC_URI[sha256sum] = "404dbbfa7a86a6c3de8225c8da254d026b17fd288e05cec4df2cc7e1f4feecfc" | 28 | SRC_URI[sha256sum] = "404dbbfa7a86a6c3de8225c8da254d026b17fd288e05cec4df2cc7e1f4feecfc" |
