summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0001-Fix-warnings-remove-some-unused-macros.patch72
-rw-r--r--meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0002-Add-put_blk-and-put_nod-routines.patch1123
-rw-r--r--meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0003-Add-get_blkmap-and-put_blkmap.patch222
-rw-r--r--meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0004-Add-a-dirwalker-for-walking-through-directory-entrie.patch357
-rw-r--r--meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0005-Make-filesystem-struct-not-an-overloay.patch374
-rw-r--r--meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0006-Improve-the-efficiency-of-extend_blk.patch272
-rw-r--r--meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0007-Move-hdlinks-into-the-filesystem-structure.patch175
-rw-r--r--meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0008-Separate-out-the-creation-of-the-filesystem-structur.patch95
-rw-r--r--meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0009-Move-byte-swapping-into-the-get-put-routines.patch421
-rw-r--r--meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0010-Convert-over-to-keeping-the-filesystem-on-disk.patch839
-rw-r--r--meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0011-Copy-files-into-the-filesystem-a-piece-at-a-time.patch103
-rw-r--r--meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0012-Add-rev-1-support-large-file-support-and-rework-hole.patch211
-rw-r--r--meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0013-Add-volume-id-support.patch86
-rw-r--r--meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0014-Remove-unneeded-setting-of-s_reserved.patch28
-rw-r--r--meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0015-Rework-creating-the-lost-found-directory.patch57
-rw-r--r--meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0016-Fix-the-documentation-for-the-new-L-option.patch29
-rw-r--r--meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0017-Fix-file-same-comparison.patch30
-rw-r--r--meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0018-Handle-files-changing-while-we-are-working.patch89
-rw-r--r--meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0019-Make-sure-superblock-is-clear-on-allocation.patch42
-rw-r--r--meta/recipes-devtools/genext2fs/genext2fs-1.4.1/fix-nbblocks-cast.patch18
-rw-r--r--meta/recipes-devtools/genext2fs/genext2fs-1.4.1/update_to_1.95.patch119
-rw-r--r--meta/recipes-devtools/genext2fs/genext2fs_1.4.1.bb24
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 @@
+Upstream-Status: inappropriate
+
+From 1399df7672ec309523bcd067da24d72aa624f783 Mon Sep 17 00:00:00 2001
+From: Corey Minyard <cminyard@mvista.com>
+Date: Wed, 1 Jun 2011 07:51:24 -0500
+Subject: [PATCH 01/19] Fix warnings, remove some unused macros.
+
+These are some annoying warnings with newer toolchains. And NAMLEN is
+never used, so just get rid of it.
+---
+ genext2fs.c | 15 +++++++++------
+ 1 files changed, 9 insertions(+), 6 deletions(-)
+
+diff --git a/genext2fs.c b/genext2fs.c
+index f0d797d..284862d 100644
+--- a/genext2fs.c
++++ b/genext2fs.c
+@@ -107,10 +107,8 @@
+
+ #if HAVE_DIRENT_H
+ # include <dirent.h>
+-# define NAMLEN(dirent) strlen((dirent)->d_name)
+ #else
+ # define dirent direct
+-# define NAMLEN(dirent) (dirent)->d_namlen
+ # if HAVE_SYS_NDIR_H
+ # include <sys/ndir.h>
+ # endif
+@@ -1441,7 +1439,8 @@ mkfile_fs(filesystem *fs, uint32 parent_nod, const char *name, uint32 mode, size
+ if(!(b = (uint8*)calloc(rndup(size, BLOCKSIZE), 1)))
+ error_msg_and_die("not enough mem to read file '%s'", name);
+ if(f)
+- fread(b, size, 1, f); // FIXME: ugly. use mmap() ...
++ if (fread(b, size, 1, f) != 1) // FIXME: ugly. use mmap() ...
++ error_msg_and_die("fread failed");
+ extend_blk(fs, nod, b, rndup(size, BLOCKSIZE) / BLOCKSIZE);
+ free(b);
+ }
+@@ -1673,7 +1672,9 @@ add2fs_from_dir(filesystem *fs, uint32 this_nod, int squash_uids, int squash_per
+ if(chdir(dent->d_name) < 0)
+ perror_msg_and_die(dent->d_name);
+ add2fs_from_dir(fs, this_nod, squash_uids, squash_perms, fs_timestamp, stats);
+- chdir("..");
++ if (chdir("..") == -1)
++ perror_msg_and_die("..");
++
+ break;
+ default:
+ break;
+@@ -1687,7 +1688,8 @@ add2fs_from_dir(filesystem *fs, uint32 this_nod, int squash_uids, int squash_per
+ if(chdir(dent->d_name) < 0)
+ perror_msg_and_die(name);
+ add2fs_from_dir(fs, nod, squash_uids, squash_perms, fs_timestamp, stats);
+- chdir("..");
++ if (chdir("..") == -1)
++ perror_msg_and_die("..");
+ }
+ continue;
+ }
+@@ -1733,7 +1735,8 @@ add2fs_from_dir(filesystem *fs, uint32 this_nod, int squash_uids, int squash_per
+ if(chdir(dent->d_name) < 0)
+ perror_msg_and_die(name);
+ add2fs_from_dir(fs, nod, squash_uids, squash_perms, fs_timestamp, stats);
+- chdir("..");
++ if (chdir("..") == -1)
++ perror_msg_and_die("..");
+ break;
+ default:
+ error_msg("ignoring entry %s", name);
+--
+1.7.4.1
+
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 @@
+Upstream-Status: inappropriate
+
+From 8dd6e604777ffeb4d30921592f199cd9bcc8a3e2 Mon Sep 17 00:00:00 2001
+From: Corey Minyard <cminyard@mvista.com>
+Date: Sat, 4 Jun 2011 15:23:29 -0500
+Subject: [PATCH 02/19] Add put_blk and put_nod routines
+
+Add the routines to mark that we are done with a block or inode, and
+add the info structures so that get and put will work. This doesn't
+do anything functionally, just getting ready for future changes.
+
+Most of the changes are pretty straightforward. There were changes in
+get_nod() because it could use a later block than the one actually
+fetches. And walk_bw() needed some special handling to avoid using data
+after the put routine.
+---
+ genext2fs.c | 480 ++++++++++++++++++++++++++++++++++++++++-------------------
+ 1 files changed, 330 insertions(+), 150 deletions(-)
+
+diff --git a/genext2fs.c b/genext2fs.c
+index 284862d..bd06369 100644
+--- a/genext2fs.c
++++ b/genext2fs.c
+@@ -236,18 +236,22 @@ struct stats {
+ (((fs)->sb.s_blocks_count - fs->sb.s_first_data_block + \
+ (fs)->sb.s_blocks_per_group - 1) / (fs)->sb.s_blocks_per_group)
+
+-// Get group block bitmap (bbm) given the group number
+-#define GRP_GET_GROUP_BBM(fs,grp) ( get_blk((fs),(fs)->gd[(grp)].bg_block_bitmap) )
++// Get/put group block bitmap (bbm) given the group number
++#define GRP_GET_GROUP_BBM(fs,grp,bi) ( get_blk((fs),(fs)->gd[(grp)].bg_block_bitmap,(bi)) )
++#define GRP_PUT_GROUP_BBM(bi) ( put_blk((bi)) )
+
+-// Get group inode bitmap (ibm) given the group number
+-#define GRP_GET_GROUP_IBM(fs,grp) ( get_blk((fs),(fs)->gd[(grp)].bg_inode_bitmap) )
++// Get/put group inode bitmap (ibm) given the group number
++#define GRP_GET_GROUP_IBM(fs,grp,bi) ( get_blk((fs),(fs)->gd[(grp)].bg_inode_bitmap,(bi)) )
++#define GRP_PUT_GROUP_IBM(bi) ( put_blk((bi)) )
+
+ // Given an inode number find the group it belongs to
+ #define GRP_GROUP_OF_INODE(fs,nod) ( ((nod)-1) / (fs)->sb.s_inodes_per_group)
+
+-//Given an inode number get the inode bitmap that covers it
+-#define GRP_GET_INODE_BITMAP(fs,nod) \
+- ( GRP_GET_GROUP_IBM((fs),GRP_GROUP_OF_INODE((fs),(nod))) )
++//Given an inode number get/put the inode bitmap that covers it
++#define GRP_GET_INODE_BITMAP(fs,nod,bi) \
++ ( GRP_GET_GROUP_IBM((fs),GRP_GROUP_OF_INODE((fs),(nod)),(bi)) )
++#define GRP_PUT_INODE_BITMAP(bi) \
++ ( GRP_PUT_GROUP_IBM((bi)) )
+
+ //Given an inode number find its offset within the inode bitmap that covers it
+ #define GRP_IBM_OFFSET(fs,nod) \
+@@ -256,9 +260,11 @@ struct stats {
+ // Given a block number find the group it belongs to
+ #define GRP_GROUP_OF_BLOCK(fs,blk) ( ((blk)-1) / (fs)->sb.s_blocks_per_group)
+
+-//Given a block number get the block bitmap that covers it
+-#define GRP_GET_BLOCK_BITMAP(fs,blk) \
+- ( GRP_GET_GROUP_BBM((fs),GRP_GROUP_OF_BLOCK((fs),(blk))) )
++//Given a block number get/put the block bitmap that covers it
++#define GRP_GET_BLOCK_BITMAP(fs,blk,bi) \
++ ( GRP_GET_GROUP_BBM((fs),GRP_GROUP_OF_BLOCK((fs),(blk)),(bi)) )
++#define GRP_PUT_BLOCK_BITMAP(bi) \
++ ( GRP_PUT_GROUP_BBM((bi)) )
+
+ //Given a block number find its offset within the block bitmap that covers it
+ #define GRP_BBM_OFFSET(fs,blk) \
+@@ -811,24 +817,59 @@ allocated(block b, uint32 item)
+ return b[(item-1) / 8] & (1 << ((item-1) % 8));
+ }
+
+-// return a given block from a filesystem
++// Used by get_blk/put_blk to hold information about a block owned
++// by the user.
++typedef struct
++{
++ int dummy;
++} blk_info;
++
++// Return a given block from a filesystem. Make sure to call
++// put_blk when you are done with it.
+ static inline uint8 *
+-get_blk(filesystem *fs, uint32 blk)
++get_blk(filesystem *fs, uint32 blk, blk_info **rbi)
+ {
+ return (uint8*)fs + blk*BLOCKSIZE;
+ }
+
+-// return a given inode from a filesystem
++static inline void
++put_blk(blk_info *bi)
++{
++}
++
++// Used by get_nod/put_nod to hold information about an inode owned
++// by the user.
++typedef struct
++{
++ blk_info *bi;
++} nod_info;
++
++// Return a given inode from a filesystem. Make sure to call put_nod()
++// when you are done with the inode.
+ static inline inode *
+-get_nod(filesystem *fs, uint32 nod)
++get_nod(filesystem *fs, uint32 nod, nod_info **rni)
+ {
+- int grp,offset;
++ int grp, offset, boffset;
+ inode *itab;
++ nod_info *ni;
+
+- offset = GRP_IBM_OFFSET(fs,nod);
++ offset = GRP_IBM_OFFSET(fs,nod) - 1;
++ boffset = offset / (BLOCKSIZE / sizeof(inode));
++ offset %= BLOCKSIZE / sizeof(inode);
+ grp = GRP_GROUP_OF_INODE(fs,nod);
+- itab = (inode *)get_blk(fs, fs->gd[grp].bg_inode_table);
+- return itab+offset-1;
++ ni = malloc(sizeof(*ni));
++ if (!ni)
++ error_msg_and_die("get_nod: out of memory");
++ itab = (inode *)get_blk(fs, fs->gd[grp].bg_inode_table + boffset, &ni->bi);
++ *rni = ni;
++ return itab+offset;
++}
++
++static inline void
++put_nod(nod_info *ni)
++{
++ put_blk(ni->bi);
++ free(ni);
+ }
+
+ // allocate a given block/inode in the bitmap
+@@ -870,12 +911,17 @@ alloc_blk(filesystem *fs, uint32 nod)
+ {
+ uint32 bk=0;
+ uint32 grp,nbgroups;
++ blk_info *bi;
+
+ grp = GRP_GROUP_OF_INODE(fs,nod);
+ nbgroups = GRP_NBGROUPS(fs);
+- if(!(bk = allocate(get_blk(fs,fs->gd[grp].bg_block_bitmap), 0))) {
+- for(grp=0;grp<nbgroups && !bk;grp++)
+- bk=allocate(get_blk(fs,fs->gd[grp].bg_block_bitmap),0);
++ bk = allocate(get_blk(fs, fs->gd[grp].bg_block_bitmap, &bi), 0);
++ put_blk(bi);
++ if (!bk) {
++ for (grp=0; grp<nbgroups && !bk; grp++) {
++ bk = allocate(get_blk(fs, fs->gd[grp].bg_block_bitmap, &bi), 0);
++ put_blk(bi);
++ }
+ grp--;
+ }
+ if (!bk)
+@@ -892,10 +938,12 @@ static void
+ free_blk(filesystem *fs, uint32 bk)
+ {
+ uint32 grp;
++ blk_info *bi;
+
+ grp = bk / fs->sb.s_blocks_per_group;
+ bk %= fs->sb.s_blocks_per_group;
+- deallocate(get_blk(fs,fs->gd[grp].bg_block_bitmap), bk);
++ deallocate(get_blk(fs, fs->gd[grp].bg_block_bitmap, &bi), bk);
++ put_blk(bi);
+ fs->gd[grp].bg_free_blocks_count++;
+ fs->sb.s_free_blocks_count++;
+ }
+@@ -906,6 +954,7 @@ alloc_nod(filesystem *fs)
+ {
+ uint32 nod,best_group=0;
+ uint32 grp,nbgroups,avefreei;
++ blk_info *bi;
+
+ nbgroups = GRP_NBGROUPS(fs);
+
+@@ -923,8 +972,10 @@ alloc_nod(filesystem *fs)
+ fs->gd[grp].bg_free_blocks_count > fs->gd[best_group].bg_free_blocks_count)
+ best_group = grp;
+ }
+- if (!(nod = allocate(get_blk(fs,fs->gd[best_group].bg_inode_bitmap),0)))
++ if (!(nod = allocate(get_blk(fs, fs->gd[best_group].bg_inode_bitmap,
++ &bi), 0)))
+ error_msg_and_die("couldn't allocate an inode (no free inode)");
++ put_blk(bi);
+ if(!(fs->gd[best_group].bg_free_inodes_count--))
+ error_msg_and_die("group descr. free blocks count == 0 (corrupted fs?)");
+ if(!(fs->sb.s_free_inodes_count--))
+@@ -968,24 +1019,35 @@ static uint32
+ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole)
+ {
+ uint32 *bkref = 0;
++ uint32 bk = 0;
+ uint32 *b;
+ int extend = 0, reduce = 0;
++ inode *inod;
++ nod_info *ni;
++ uint32 *iblk;
++ blk_info *bi1 = NULL, *bi2 = NULL, *bi3 = NULL;
++
+ if(create && (*create) < 0)
+ reduce = 1;
+- if(bw->bnum >= get_nod(fs, nod)->i_blocks / INOBLK)
++ inod = get_nod(fs, nod, &ni);
++ if(bw->bnum >= inod->i_blocks / INOBLK)
+ {
+ if(create && (*create) > 0)
+ {
+ (*create)--;
+ extend = 1;
+ }
+- else
++ else
++ {
++ put_nod(ni);
+ return WALK_END;
++ }
+ }
++ iblk = inod->i_block;
+ // first direct block
+ if(bw->bpdir == EXT2_INIT_BLOCK)
+ {
+- bkref = &get_nod(fs, nod)->i_block[bw->bpdir = 0];
++ bkref = &iblk[bw->bpdir = 0];
+ if(extend) // allocate first block
+ *bkref = hole ? 0 : alloc_blk(fs,nod);
+ if(reduce) // free first block
+@@ -994,7 +1056,7 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole)
+ // direct block
+ else if(bw->bpdir < EXT2_NDIR_BLOCKS)
+ {
+- bkref = &get_nod(fs, nod)->i_block[++bw->bpdir];
++ bkref = &iblk[++bw->bpdir];
+ if(extend) // allocate block
+ *bkref = hole ? 0 : alloc_blk(fs,nod);
+ if(reduce) // free block
+@@ -1007,10 +1069,10 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole)
+ bw->bpdir = EXT2_IND_BLOCK;
+ bw->bpind = 0;
+ if(extend) // allocate indirect block
+- get_nod(fs, nod)->i_block[bw->bpdir] = alloc_blk(fs,nod);
++ iblk[bw->bpdir] = alloc_blk(fs,nod);
+ if(reduce) // free indirect block
+- free_blk(fs, get_nod(fs, nod)->i_block[bw->bpdir]);
+- b = (uint32*)get_blk(fs, get_nod(fs, nod)->i_block[bw->bpdir]);
++ free_blk(fs, iblk[bw->bpdir]);
++ b = (uint32*)get_blk(fs, iblk[bw->bpdir], &bi1);
+ bkref = &b[bw->bpind];
+ if(extend) // allocate first block
+ *bkref = hole ? 0 : alloc_blk(fs,nod);
+@@ -1021,7 +1083,7 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole)
+ else if((bw->bpdir == EXT2_IND_BLOCK) && (bw->bpind < BLOCKSIZE/4 - 1))
+ {
+ bw->bpind++;
+- b = (uint32*)get_blk(fs, get_nod(fs, nod)->i_block[bw->bpdir]);
++ b = (uint32*)get_blk(fs, iblk[bw->bpdir], &bi1);
+ bkref = &b[bw->bpind];
+ if(extend) // allocate block
+ *bkref = hole ? 0 : alloc_blk(fs,nod);
+@@ -1036,15 +1098,15 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole)
+ bw->bpind = 0;
+ bw->bpdind = 0;
+ if(extend) // allocate double indirect block
+- get_nod(fs, nod)->i_block[bw->bpdir] = alloc_blk(fs,nod);
++ iblk[bw->bpdir] = alloc_blk(fs,nod);
+ if(reduce) // free double indirect block
+- free_blk(fs, get_nod(fs, nod)->i_block[bw->bpdir]);
+- b = (uint32*)get_blk(fs, get_nod(fs, nod)->i_block[bw->bpdir]);
++ free_blk(fs, iblk[bw->bpdir]);
++ b = (uint32*)get_blk(fs, iblk[bw->bpdir], &bi1);
+ if(extend) // allocate first indirect block
+ b[bw->bpind] = alloc_blk(fs,nod);
+ if(reduce) // free firstindirect block
+ free_blk(fs, b[bw->bpind]);
+- b = (uint32*)get_blk(fs, b[bw->bpind]);
++ b = (uint32*)get_blk(fs, b[bw->bpind], &bi1);
+ bkref = &b[bw->bpdind];
+ if(extend) // allocate first block
+ *bkref = hole ? 0 : alloc_blk(fs,nod);
+@@ -1055,8 +1117,8 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole)
+ else if((bw->bpdir == EXT2_DIND_BLOCK) && (bw->bpdind < BLOCKSIZE/4 - 1))
+ {
+ bw->bpdind++;
+- b = (uint32*)get_blk(fs, get_nod(fs, nod)->i_block[bw->bpdir]);
+- b = (uint32*)get_blk(fs, b[bw->bpind]);
++ b = (uint32*)get_blk(fs, iblk[bw->bpdir], &bi1);
++ b = (uint32*)get_blk(fs, b[bw->bpind], &bi2);
+ bkref = &b[bw->bpdind];
+ if(extend) // allocate block
+ *bkref = hole ? 0 : alloc_blk(fs,nod);
+@@ -1069,12 +1131,12 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole)
+ bw->bnum++;
+ bw->bpdind = 0;
+ bw->bpind++;
+- b = (uint32*)get_blk(fs, get_nod(fs, nod)->i_block[bw->bpdir]);
++ b = (uint32*)get_blk(fs, iblk[bw->bpdir], &bi1);
+ if(extend) // allocate indirect block
+ b[bw->bpind] = alloc_blk(fs,nod);
+ if(reduce) // free indirect block
+ free_blk(fs, b[bw->bpind]);
+- b = (uint32*)get_blk(fs, b[bw->bpind]);
++ b = (uint32*)get_blk(fs, b[bw->bpind], &bi2);
+ bkref = &b[bw->bpdind];
+ if(extend) // allocate first block
+ *bkref = hole ? 0 : alloc_blk(fs,nod);
+@@ -1094,20 +1156,20 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole)
+ bw->bpdind = 0;
+ bw->bptind = 0;
+ if(extend) // allocate triple indirect block
+- get_nod(fs, nod)->i_block[bw->bpdir] = alloc_blk(fs,nod);
++ iblk[bw->bpdir] = alloc_blk(fs,nod);
+ if(reduce) // free triple indirect block
+- free_blk(fs, get_nod(fs, nod)->i_block[bw->bpdir]);
+- b = (uint32*)get_blk(fs, get_nod(fs, nod)->i_block[bw->bpdir]);
++ free_blk(fs, iblk[bw->bpdir]);
++ b = (uint32*)get_blk(fs, iblk[bw->bpdir], &bi1);
+ if(extend) // allocate first double indirect block
+ b[bw->bpind] = alloc_blk(fs,nod);
+ if(reduce) // free first double indirect block
+ free_blk(fs, b[bw->bpind]);
+- b = (uint32*)get_blk(fs, b[bw->bpind]);
++ b = (uint32*)get_blk(fs, b[bw->bpind], &bi2);
+ if(extend) // allocate first indirect block
+ b[bw->bpdind] = alloc_blk(fs,nod);
+ if(reduce) // free first indirect block
+ free_blk(fs, b[bw->bpind]);
+- b = (uint32*)get_blk(fs, b[bw->bpdind]);
++ b = (uint32*)get_blk(fs, b[bw->bpdind], &bi3);
+ bkref = &b[bw->bptind];
+ if(extend) // allocate first data block
+ *bkref = hole ? 0 : alloc_blk(fs,nod);
+@@ -1121,9 +1183,9 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole)
+ (bw->bptind < BLOCKSIZE/4 -1) )
+ {
+ bw->bptind++;
+- b = (uint32*)get_blk(fs, get_nod(fs, nod)->i_block[bw->bpdir]);
+- b = (uint32*)get_blk(fs, b[bw->bpind]);
+- b = (uint32*)get_blk(fs, b[bw->bpdind]);
++ b = (uint32*)get_blk(fs, iblk[bw->bpdir], &bi1);
++ b = (uint32*)get_blk(fs, b[bw->bpind], &bi2);
++ b = (uint32*)get_blk(fs, b[bw->bpdind], &bi3);
+ bkref = &b[bw->bptind];
+ if(extend) // allocate data block
+ *bkref = hole ? 0 : alloc_blk(fs,nod);
+@@ -1140,13 +1202,13 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole)
+ bw->bnum++;
+ bw->bptind = 0;
+ bw->bpdind++;
+- b = (uint32*)get_blk(fs, get_nod(fs, nod)->i_block[bw->bpdir]);
+- b = (uint32*)get_blk(fs, b[bw->bpind]);
++ b = (uint32*)get_blk(fs, iblk[bw->bpdir], &bi1);
++ b = (uint32*)get_blk(fs, b[bw->bpind], &bi2);
+ if(extend) // allocate single indirect block
+ b[bw->bpdind] = alloc_blk(fs,nod);
+ if(reduce) // free indirect block
+ free_blk(fs, b[bw->bpind]);
+- b = (uint32*)get_blk(fs, b[bw->bpdind]);
++ b = (uint32*)get_blk(fs, b[bw->bpdind], &bi3);
+ bkref = &b[bw->bptind];
+ if(extend) // allocate first data block
+ *bkref = hole ? 0 : alloc_blk(fs,nod);
+@@ -1163,17 +1225,17 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole)
+ bw->bpdind = 0;
+ bw->bptind = 0;
+ bw->bpind++;
+- b = (uint32*)get_blk(fs, get_nod(fs, nod)->i_block[bw->bpdir]);
++ b = (uint32*)get_blk(fs, iblk[bw->bpdir], &bi1);
+ if(extend) // allocate double indirect block
+ b[bw->bpind] = alloc_blk(fs,nod);
+ if(reduce) // free double indirect block
+ free_blk(fs, b[bw->bpind]);
+- b = (uint32*)get_blk(fs, b[bw->bpind]);
++ b = (uint32*)get_blk(fs, b[bw->bpind], &bi2);
+ if(extend) // allocate single indirect block
+ b[bw->bpdind] = alloc_blk(fs,nod);
+ if(reduce) // free indirect block
+ free_blk(fs, b[bw->bpind]);
+- b = (uint32*)get_blk(fs, b[bw->bpdind]);
++ b = (uint32*)get_blk(fs, b[bw->bpdind], &bi3);
+ bkref = &b[bw->bptind];
+ if(extend) // allocate first block
+ *bkref = hole ? 0 : alloc_blk(fs,nod);
+@@ -1184,15 +1246,28 @@ walk_bw(filesystem *fs, uint32 nod, blockwalker *bw, int32 *create, uint32 hole)
+ error_msg_and_die("file too big !");
+ /* End change for walking triple indirection */
+
+- if(*bkref)
++ bk = *bkref;
++ if (bi3)
++ put_blk(bi3);
++ if (bi2)
++ put_blk(bi2);
++ if (bi1)
++ put_blk(bi1);
++
++ if(bk)
+ {
++ blk_info *bi;
++ uint8 *block;
+ bw->bnum++;
+- if(!reduce && !allocated(GRP_GET_BLOCK_BITMAP(fs,*bkref), GRP_BBM_OFFSET(fs,*bkref)))
+- error_msg_and_die("[block %d of inode %d is unallocated !]", *bkref, nod);
++ block = GRP_GET_BLOCK_BITMAP(fs,bk,&bi);
++ if(!reduce && !allocated(block, GRP_BBM_OFFSET(fs,bk)))
++ error_msg_and_die("[block %d of inode %d is unallocated !]", bk, nod);
++ GRP_PUT_BLOCK_BITMAP(bi);
+ }
+ if(extend)
+- get_nod(fs, nod)->i_blocks = bw->bnum * INOBLK;
+- return *bkref;
++ inod->i_blocks = bw->bnum * INOBLK;
++ put_nod(ni);
++ return bk;
+ }
+
+ // add blocks to an inode (file/dir/etc...)
+@@ -1202,15 +1277,19 @@ extend_blk(filesystem *fs, uint32 nod, block b, int amount)
+ int create = amount;
+ blockwalker bw, lbw;
+ uint32 bk;
++ nod_info *ni;
++ inode *inod;
++
++ inod = get_nod(fs, nod, &ni);
+ init_bw(&bw);
+ if(amount < 0)
+ {
+ uint32 i;
+- for(i = 0; i < get_nod(fs, nod)->i_blocks / INOBLK + amount; i++)
++ for(i = 0; i < inod->i_blocks / INOBLK + amount; i++)
+ walk_bw(fs, nod, &bw, 0, 0);
+ while(walk_bw(fs, nod, &bw, &create, 0) != WALK_END)
+ /*nop*/;
+- get_nod(fs, nod)->i_blocks += amount * INOBLK;
++ inod->i_blocks += amount * INOBLK;
+ }
+ else
+ {
+@@ -1232,8 +1311,11 @@ extend_blk(filesystem *fs, uint32 nod, block b, int amount)
+ }
+ if((bk = walk_bw(fs, nod, &bw, &create, !copyb)) == WALK_END)
+ break;
+- if(copyb)
+- memcpy(get_blk(fs, bk), b + BLOCKSIZE * (amount - create - 1), BLOCKSIZE);
++ if(copyb) {
++ blk_info *bi;
++ memcpy(get_blk(fs, bk, &bi), b + BLOCKSIZE * (amount - create - 1), BLOCKSIZE);
++ put_blk(bi);
++ }
+ }
+ }
+ }
+@@ -1245,12 +1327,14 @@ add2dir(filesystem *fs, uint32 dnod, uint32 nod, const char* name)
+ blockwalker bw;
+ uint32 bk;
+ uint8 *b;
++ blk_info *bi;
+ directory *d;
+ int reclen, nlen;
+ inode *node;
+ inode *pnode;
++ nod_info *dni, *ni;
+
+- pnode = get_nod(fs, dnod);
++ pnode = get_nod(fs, dnod, &dni);
+ if((pnode->i_mode & FM_IFMT) != FM_IFDIR)
+ error_msg_and_die("can't add '%s' to a non-directory", name);
+ if(!*name)
+@@ -1264,7 +1348,7 @@ add2dir(filesystem *fs, uint32 dnod, uint32 nod, const char* name)
+ init_bw(&bw);
+ while((bk = walk_bw(fs, dnod, &bw, 0, 0)) != WALK_END) // for all blocks in dir
+ {
+- b = get_blk(fs, bk);
++ b = get_blk(fs, bk, &bi);
+ // for all dir entries in block
+ for(d = (directory*)b; (int8*)d + sizeof(*d) < (int8*)b + BLOCKSIZE; d = (directory*)((int8*)d + d->d_rec_len))
+ {
+@@ -1272,11 +1356,12 @@ add2dir(filesystem *fs, uint32 dnod, uint32 nod, const char* name)
+ if((!d->d_inode) && (d->d_rec_len >= reclen))
+ {
+ d->d_inode = nod;
+- node = get_nod(fs, nod);
++ node = get_nod(fs, nod, &ni);
+ node->i_links_count++;
+ d->d_name_len = nlen;
+ strncpy(d->d_name, name, nlen);
+- return;
++ put_nod(ni);
++ goto out;
+ }
+ // if entry with enough room (last one?), shrink it & use it
+ if(d->d_rec_len >= (sizeof(directory) + rndup(d->d_name_len, 4) + reclen))
+@@ -1287,11 +1372,12 @@ add2dir(filesystem *fs, uint32 dnod, uint32 nod, const char* name)
+ d = (directory*) (((int8*)d) + d->d_rec_len);
+ d->d_rec_len = reclen;
+ d->d_inode = nod;
+- node = get_nod(fs, nod);
++ node = get_nod(fs, nod, &ni);
+ node->i_links_count++;
+ d->d_name_len = nlen;
+ strncpy(d->d_name, name, nlen);
+- return;
++ put_nod(ni);
++ goto out;
+ }
+ }
+ }
+@@ -1300,14 +1386,17 @@ add2dir(filesystem *fs, uint32 dnod, uint32 nod, const char* name)
+ error_msg_and_die("get_workblk() failed.");
+ d = (directory*)b;
+ d->d_inode = nod;
+- node = get_nod(fs, nod);
++ node = get_nod(fs, nod, &ni);
+ node->i_links_count++;
++ put_nod(ni);
+ d->d_rec_len = BLOCKSIZE;
+ d->d_name_len = nlen;
+ strncpy(d->d_name, name, nlen);
+ extend_blk(fs, dnod, b, 1);
+- get_nod(fs, dnod)->i_size += BLOCKSIZE;
++ pnode->i_size += BLOCKSIZE;
+ free_workblk(b);
++out:
++ put_nod(dni);
+ }
+
+ // find an entry in a directory
+@@ -1316,16 +1405,20 @@ find_dir(filesystem *fs, uint32 nod, const char * name)
+ {
+ blockwalker bw;
+ uint32 bk;
++ blk_info *bi;
+ int nlen = strlen(name);
+ init_bw(&bw);
+ while((bk = walk_bw(fs, nod, &bw, 0, 0)) != WALK_END)
+ {
+ directory *d;
+ uint8 *b;
+- b = get_blk(fs, bk);
++ b = get_blk(fs, bk, &bi);
+ for(d = (directory*)b; (int8*)d + sizeof(*d) < (int8*)b + BLOCKSIZE; d = (directory*)((int8*)d + d->d_rec_len))
+- if(d->d_inode && (nlen == d->d_name_len) && !strncmp(d->d_name, name, nlen))
++ if(d->d_inode && (nlen == d->d_name_len) && !strncmp(d->d_name, name, nlen)) {
++ put_blk(bi);
+ return d->d_inode;
++ }
++ put_blk(bi);
+ }
+ return 0;
+ }
+@@ -1361,10 +1454,12 @@ void
+ chmod_fs(filesystem *fs, uint32 nod, uint16 mode, uint16 uid, uint16 gid)
+ {
+ inode *node;
+- node = get_nod(fs, nod);
++ nod_info *ni;
++ node = get_nod(fs, nod, &ni);
+ node->i_mode = (node->i_mode & ~FM_IMASK) | (mode & FM_IMASK);
+ node->i_uid = uid;
+ node->i_gid = gid;
++ put_nod(ni);
+ }
+
+ // create a simple inode
+@@ -1373,33 +1468,34 @@ mknod_fs(filesystem *fs, uint32 parent_nod, const char *name, uint16 mode, uint1
+ {
+ uint32 nod;
+ inode *node;
++ nod_info *ni;
++
++ nod = alloc_nod(fs);
++ node = get_nod(fs, nod, &ni);
++ node->i_mode = mode;
++ add2dir(fs, parent_nod, nod, name);
++ switch(mode & FM_IFMT)
+ {
+- nod = alloc_nod(fs);
+- node = get_nod(fs, nod);
+- node->i_mode = mode;
+- add2dir(fs, parent_nod, nod, name);
+- switch(mode & FM_IFMT)
+- {
+- case FM_IFLNK:
+- mode = FM_IFLNK | FM_IRWXU | FM_IRWXG | FM_IRWXO;
+- break;
+- case FM_IFBLK:
+- case FM_IFCHR:
+- ((uint8*)get_nod(fs, nod)->i_block)[0] = minor;
+- ((uint8*)get_nod(fs, nod)->i_block)[1] = major;
+- break;
+- case FM_IFDIR:
+- add2dir(fs, nod, nod, ".");
+- add2dir(fs, nod, parent_nod, "..");
+- fs->gd[GRP_GROUP_OF_INODE(fs,nod)].bg_used_dirs_count++;
+- break;
+- }
++ case FM_IFLNK:
++ mode = FM_IFLNK | FM_IRWXU | FM_IRWXG | FM_IRWXO;
++ break;
++ case FM_IFBLK:
++ case FM_IFCHR:
++ ((uint8*)node->i_block)[0] = minor;
++ ((uint8*)node->i_block)[1] = major;
++ break;
++ case FM_IFDIR:
++ add2dir(fs, nod, nod, ".");
++ add2dir(fs, nod, parent_nod, "..");
++ fs->gd[GRP_GROUP_OF_INODE(fs,nod)].bg_used_dirs_count++;
++ break;
+ }
+ node->i_uid = uid;
+ node->i_gid = gid;
+ node->i_atime = mtime;
+ node->i_ctime = ctime;
+ node->i_mtime = mtime;
++ put_nod(ni);
+ return nod;
+ }
+
+@@ -1416,14 +1512,19 @@ static uint32
+ 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)
+ {
+ uint32 nod = mknod_fs(fs, parent_nod, name, FM_IFLNK | FM_IRWXU | FM_IRWXG | FM_IRWXO, uid, gid, 0, 0, ctime, mtime);
+- extend_blk(fs, nod, 0, - (int)get_nod(fs, nod)->i_blocks / INOBLK);
+- get_nod(fs, nod)->i_size = size;
++ nod_info *ni;
++ inode *node = get_nod(fs, nod, &ni);
++
++ extend_blk(fs, nod, 0, - (int)node->i_blocks / INOBLK);
++ node->i_size = size;
+ if(size <= 4 * (EXT2_TIND_BLOCK+1))
+ {
+- strncpy((char*)get_nod(fs, nod)->i_block, (char*)b, size);
++ strncpy((char *)node->i_block, (char *)b, size);
++ put_nod(ni);
+ return nod;
+ }
+ extend_blk(fs, nod, b, rndup(size, BLOCKSIZE) / BLOCKSIZE);
++ put_nod(ni);
+ return nod;
+ }
+
+@@ -1433,8 +1534,11 @@ mkfile_fs(filesystem *fs, uint32 parent_nod, const char *name, uint32 mode, size
+ {
+ uint8 * b;
+ uint32 nod = mknod_fs(fs, parent_nod, name, mode|FM_IFREG, uid, gid, 0, 0, ctime, mtime);
+- extend_blk(fs, nod, 0, - (int)get_nod(fs, nod)->i_blocks / INOBLK);
+- get_nod(fs, nod)->i_size = size;
++ nod_info *ni;
++ inode *node = get_nod(fs, nod, &ni);
++
++ extend_blk(fs, nod, 0, - (int)node->i_blocks / INOBLK);
++ node->i_size = size;
+ if (size) {
+ if(!(b = (uint8*)calloc(rndup(size, BLOCKSIZE), 1)))
+ error_msg_and_die("not enough mem to read file '%s'", name);
+@@ -1444,6 +1548,7 @@ mkfile_fs(filesystem *fs, uint32 parent_nod, const char *name, uint32 mode, size
+ extend_blk(fs, nod, b, rndup(size, BLOCKSIZE) / BLOCKSIZE);
+ free(b);
+ }
++ put_nod(ni);
+ return nod;
+ }
+
+@@ -1766,6 +1871,7 @@ swap_goodblocks(filesystem *fs, inode *nod)
+ uint32 i,j;
+ int done=0;
+ uint32 *b,*b2;
++ blk_info *bi, *bi2, *bi3;
+
+ uint32 nblk = nod->i_blocks / INOBLK;
+ if((nod->i_size && !nblk) || ((nod->i_mode & FM_IFBLK) == FM_IFBLK) || ((nod->i_mode & FM_IFCHR) == FM_IFCHR))
+@@ -1773,7 +1879,8 @@ swap_goodblocks(filesystem *fs, inode *nod)
+ nod->i_block[i] = swab32(nod->i_block[i]);
+ if(nblk <= EXT2_IND_BLOCK)
+ return;
+- swap_block(get_blk(fs, nod->i_block[EXT2_IND_BLOCK]));
++ swap_block(get_blk(fs, nod->i_block[EXT2_IND_BLOCK], &bi));
++ put_blk(bi);
+ if(nblk <= EXT2_DIND_BLOCK + BLOCKSIZE/4)
+ return;
+ /* Currently this will fail b'cos the number of blocks as stored
+@@ -1791,29 +1898,37 @@ swap_goodblocks(filesystem *fs, inode *nod)
+ // ths function needs to be fixed for the same reasons - Xav
+ assert(nod->i_block[EXT2_DIND_BLOCK] != 0);
+ for(i = 0; i < BLOCKSIZE/4; i++)
+- if(nblk > EXT2_IND_BLOCK + BLOCKSIZE/4 + (BLOCKSIZE/4)*i )
+- swap_block(get_blk(fs, ((uint32*)get_blk(fs, nod->i_block[EXT2_DIND_BLOCK]))[i]));
+- swap_block(get_blk(fs, nod->i_block[EXT2_DIND_BLOCK]));
++ if(nblk > EXT2_IND_BLOCK + BLOCKSIZE/4 + (BLOCKSIZE/4)*i ) {
++ swap_block(get_blk(fs, ((uint32*)get_blk(fs, nod->i_block[EXT2_DIND_BLOCK], &bi))[i], &bi2));
++ put_blk(bi);
++ put_blk(bi2);
++ }
++ swap_block(get_blk(fs, nod->i_block[EXT2_DIND_BLOCK], &bi));
++ put_blk(bi);
+ if(nblk <= EXT2_IND_BLOCK + BLOCKSIZE/4 + BLOCKSIZE/4 * BLOCKSIZE/4)
+ return;
+ /* Adding support for triple indirection */
+- b = (uint32*)get_blk(fs,nod->i_block[EXT2_TIND_BLOCK]);
++ b = (uint32*)get_blk(fs,nod->i_block[EXT2_TIND_BLOCK], &bi);
+ for(i=0;i < BLOCKSIZE/4 && !done ; i++) {
+- b2 = (uint32*)get_blk(fs,b[i]);
++ b2 = (uint32*)get_blk(fs,b[i], &bi2);
+ for(j=0; j<BLOCKSIZE/4;j++) {
+ if (nblk > ( EXT2_IND_BLOCK + BLOCKSIZE/4 +
+ (BLOCKSIZE/4)*(BLOCKSIZE/4) +
+ i*(BLOCKSIZE/4)*(BLOCKSIZE/4) +
+- j*(BLOCKSIZE/4)) )
+- swap_block(get_blk(fs,b2[j]));
++ j*(BLOCKSIZE/4)) ) {
++ swap_block(get_blk(fs,b2[j],&bi3));
++ put_blk(bi3);
++ }
+ else {
+ done = 1;
+ break;
+ }
+ }
+ swap_block((uint8 *)b2);
++ put_blk(bi2);
+ }
+ swap_block((uint8 *)b);
++ put_blk(bi);