1124 lines
36 KiB
Diff
1124 lines
36 KiB
Diff
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);
|
|
return;
|
|
}
|
|
|
|
@@ -1823,6 +1938,7 @@ swap_badblocks(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))
|
|
@@ -1830,35 +1946,44 @@ swap_badblocks(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;
|
|
/* See comment in swap_goodblocks */
|
|
assert(nod->i_block[EXT2_DIND_BLOCK] != 0);
|
|
- swap_block(get_blk(fs, nod->i_block[EXT2_DIND_BLOCK]));
|
|
+ swap_block(get_blk(fs, nod->i_block[EXT2_DIND_BLOCK], &bi));
|
|
+ put_blk(bi);
|
|
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]));
|
|
+ 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);
|
|
+ }
|
|
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);
|
|
swap_block((uint8 *)b);
|
|
for(i=0;i < BLOCKSIZE/4 && !done ; i++) {
|
|
- b2 = (uint32*)get_blk(fs,b[i]);
|
|
+ b2 = (uint32*)get_blk(fs,b[i],&bi2);
|
|
swap_block((uint8 *)b2);
|
|
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;
|
|
}
|
|
}
|
|
+ put_blk(bi2);
|
|
}
|
|
+ put_blk(bi);
|
|
return;
|
|
}
|
|
|
|
@@ -1867,9 +1992,11 @@ static void
|
|
swap_goodfs(filesystem *fs)
|
|
{
|
|
uint32 i;
|
|
+ nod_info *ni;
|
|
+
|
|
for(i = 1; i < fs->sb.s_inodes_count; i++)
|
|
{
|
|
- inode *nod = get_nod(fs, i);
|
|
+ inode *nod = get_nod(fs, i, &ni);
|
|
if(nod->i_mode & FM_IFDIR)
|
|
{
|
|
blockwalker bw;
|
|
@@ -1879,13 +2006,16 @@ swap_goodfs(filesystem *fs)
|
|
{
|
|
directory *d;
|
|
uint8 *b;
|
|
- b = get_blk(fs, bk);
|
|
+ blk_info *bi;
|
|
+ b = get_blk(fs, bk, &bi);
|
|
for(d = (directory*)b; (int8*)d + sizeof(*d) < (int8*)b + BLOCKSIZE; d = (directory*)((int8*)d + swab16(d->d_rec_len)))
|
|
swap_dir(d);
|
|
+ put_blk(bi);
|
|
}
|
|
}
|
|
swap_goodblocks(fs, nod);
|
|
swap_nod(nod);
|
|
+ put_nod(ni);
|
|
}
|
|
for(i=0;i<GRP_NBGROUPS(fs);i++)
|
|
swap_gd(&(fs->gd[i]));
|
|
@@ -1901,7 +2031,8 @@ swap_badfs(filesystem *fs)
|
|
swap_gd(&(fs->gd[i]));
|
|
for(i = 1; i < fs->sb.s_inodes_count; i++)
|
|
{
|
|
- inode *nod = get_nod(fs, i);
|
|
+ nod_info *ni;
|
|
+ inode *nod = get_nod(fs, i, &ni);
|
|
swap_nod(nod);
|
|
swap_badblocks(fs, nod);
|
|
if(nod->i_mode & FM_IFDIR)
|
|
@@ -1913,9 +2044,11 @@ swap_badfs(filesystem *fs)
|
|
{
|
|
directory *d;
|
|
uint8 *b;
|
|
- b = get_blk(fs, bk);
|
|
+ blk_info *bi;
|
|
+ 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))
|
|
swap_dir(d);
|
|
+ put_blk(bi);
|
|
}
|
|
}
|
|
}
|
|
@@ -1936,6 +2069,8 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp
|
|
uint32 j;
|
|
uint8 *bbm,*ibm;
|
|
inode *itab0;
|
|
+ blk_info *bi;
|
|
+ nod_info *ni;
|
|
|
|
if(nbresrvd < 0)
|
|
error_msg_and_die("reserved blocks value is invalid. Note: options have changed, see --help or the man page.");
|
|
@@ -2014,9 +2149,8 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp
|
|
/* Mark non-filesystem blocks and inodes as allocated */
|
|
/* Mark system blocks and inodes as allocated */
|
|
for(i = 0; i<nbgroups;i++) {
|
|
-
|
|
/* Block bitmap */
|
|
- bbm = get_blk(fs,fs->gd[i].bg_block_bitmap);
|
|
+ bbm = get_blk(fs,fs->gd[i].bg_block_bitmap, &bi);
|
|
//non-filesystem blocks
|
|
for(j = fs->gd[i].bg_free_blocks_count
|
|
+ overhead_per_group + 1; j <= BLOCKSIZE * 8; j++)
|
|
@@ -2024,9 +2158,10 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp
|
|
//system blocks
|
|
for(j = 1; j <= overhead_per_group; j++)
|
|
allocate(bbm, j);
|
|
+ put_blk(bi);
|
|
|
|
/* Inode bitmap */
|
|
- ibm = get_blk(fs,fs->gd[i].bg_inode_bitmap);
|
|
+ ibm = get_blk(fs,fs->gd[i].bg_inode_bitmap, &bi);
|
|
//non-filesystem inodes
|
|
for(j = fs->sb.s_inodes_per_group+1; j <= BLOCKSIZE * 8; j++)
|
|
allocate(ibm, j);
|
|
@@ -2035,6 +2170,7 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp
|
|
if(i == 0)
|
|
for(j = 1; j < EXT2_FIRST_INO; j++)
|
|
allocate(ibm, j);
|
|
+ put_blk(bi);
|
|
}
|
|
|
|
// make root inode and directory
|
|
@@ -2042,13 +2178,14 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp
|
|
/* Also increment the directory count for group 0 */
|
|
fs->gd[0].bg_free_inodes_count--;
|
|
fs->gd[0].bg_used_dirs_count = 1;
|
|
- itab0 = (inode *)get_blk(fs,fs->gd[0].bg_inode_table);
|
|
- itab0[EXT2_ROOT_INO-1].i_mode = FM_IFDIR | FM_IRWXU | FM_IRGRP | FM_IROTH | FM_IXGRP | FM_IXOTH;
|
|
- itab0[EXT2_ROOT_INO-1].i_ctime = fs_timestamp;
|
|
- itab0[EXT2_ROOT_INO-1].i_mtime = fs_timestamp;
|
|
- itab0[EXT2_ROOT_INO-1].i_atime = fs_timestamp;
|
|
- itab0[EXT2_ROOT_INO-1].i_size = BLOCKSIZE;
|
|
- itab0[EXT2_ROOT_INO-1].i_links_count = 2;
|
|
+ itab0 = get_nod(fs, EXT2_ROOT_INO, &ni);
|
|
+ itab0->i_mode = FM_IFDIR | FM_IRWXU | FM_IRGRP | FM_IROTH | FM_IXGRP | FM_IXOTH;
|
|
+ itab0->i_ctime = fs_timestamp;
|
|
+ itab0->i_mtime = fs_timestamp;
|
|
+ itab0->i_atime = fs_timestamp;
|
|
+ itab0->i_size = BLOCKSIZE;
|
|
+ itab0->i_links_count = 2;
|
|
+ put_nod(ni);
|
|
|
|
if(!(b = get_workblk()))
|
|
error_msg_and_die("get_workblk() failed.");
|
|
@@ -2067,6 +2204,8 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp
|
|
// make lost+found directory and reserve blocks
|
|
if(fs->sb.s_r_blocks_count)
|
|
{
|
|
+ inode *node;
|
|
+
|
|
nod = mkdir_fs(fs, EXT2_ROOT_INO, "lost+found", FM_IRWXU, 0, 0, fs_timestamp, fs_timestamp);
|
|
memset(b, 0, BLOCKSIZE);
|
|
((directory*)b)->d_rec_len = BLOCKSIZE;
|
|
@@ -2077,7 +2216,9 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes, uint32 fs_timestamp
|
|
fs->sb.s_r_blocks_count = fs->sb.s_blocks_count * MAX_RESERVED_BLOCKS;
|
|
for(i = 1; i < fs->sb.s_r_blocks_count; i++)
|
|
extend_blk(fs, nod, b, 1);
|
|
- get_nod(fs, nod)->i_size = fs->sb.s_r_blocks_count * BLOCKSIZE;
|
|
+ node = get_nod(fs, nod, &ni);
|
|
+ node->i_size = fs->sb.s_r_blocks_count * BLOCKSIZE;
|
|
+ put_nod(ni);
|
|
}
|
|
free_workblk(b);
|
|
|
|
@@ -2153,16 +2294,23 @@ write_blocks(filesystem *fs, uint32 nod, FILE* f)
|
|
{
|
|
blockwalker bw;
|
|
uint32 bk;
|
|
- int32 fsize = get_nod(fs, nod)->i_size;
|
|
+ nod_info *ni;
|
|
+ inode *node = get_nod(fs, nod, &ni);
|
|
+ int32 fsize = node->i_size;
|
|
+ blk_info *bi;
|
|
+
|
|
init_bw(&bw);
|
|
while((bk = walk_bw(fs, nod, &bw, 0, 0)) != WALK_END)
|
|
{
|
|
if(fsize <= 0)
|
|
error_msg_and_die("wrong size while saving inode %d", nod);
|
|
- if(fwrite(get_blk(fs, bk), (fsize > BLOCKSIZE) ? BLOCKSIZE : fsize, 1, f) != 1)
|
|
+ if(fwrite(get_blk(fs, bk, &bi),
|
|
+ (fsize > BLOCKSIZE) ? BLOCKSIZE : fsize, 1, f) != 1)
|
|
error_msg_and_die("error while saving inode %d", nod);
|
|
+ put_blk(bi);
|
|
fsize -= BLOCKSIZE;
|
|
}
|
|
+ put_nod(ni);
|
|
}
|
|
|
|
|
|
@@ -2171,8 +2319,11 @@ static void
|
|
print_dev(filesystem *fs, uint32 nod)
|
|
{
|
|
int minor, major;
|
|
- minor = ((uint8*)get_nod(fs, nod)->i_block)[0];
|
|
- major = ((uint8*)get_nod(fs, nod)->i_block)[1];
|
|
+ nod_info *ni;
|
|
+ inode *node = get_nod(fs, nod, &ni);
|
|
+ minor = ((uint8*)node->i_block)[0];
|
|
+ major = ((uint8*)node->i_block)[1];
|
|
+ put_nod(ni);
|
|
printf("major: %d, minor: %d\n", major, minor);
|
|
}
|
|
|
|
@@ -2188,7 +2339,8 @@ print_dir(filesystem *fs, uint32 nod)
|
|
{
|
|
directory *d;
|
|
uint8 *b;
|
|
- b = get_blk(fs, bk);
|
|
+ blk_info *bi;
|
|
+ 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)
|
|
{
|
|
@@ -2198,6 +2350,7 @@ print_dir(filesystem *fs, uint32 nod)
|
|
putchar(d->d_name[i]);
|
|
printf("' (inode %d): rec_len: %d (name_len: %d)\n", d->d_inode, d->d_rec_len, d->d_name_len);
|
|
}
|
|
+ put_blk(bi);
|
|
}
|
|
}
|
|
|
|
@@ -2205,14 +2358,18 @@ print_dir(filesystem *fs, uint32 nod)
|
|
static void
|
|
print_link(filesystem *fs, uint32 nod)
|
|
{
|
|
- if(!get_nod(fs, nod)->i_blocks)
|
|
- printf("links to '%s'\n", (char*)get_nod(fs, nod)->i_block);
|
|
+ nod_info *ni;
|
|
+ inode *node = get_nod(fs, nod, &ni);
|
|
+
|
|
+ if(!node->i_blocks)
|
|
+ printf("links to '%s'\n", (char*)node->i_block);
|
|
else
|
|
{
|
|
printf("links to '");
|
|
write_blocks(fs, nod, stdout);
|
|
printf("'\n");
|
|
}
|
|
+ put_nod(ni);
|
|
}
|
|
|
|
// make a ls-like printout of permissions
|
|
@@ -2281,8 +2438,12 @@ print_inode(filesystem *fs, uint32 nod)
|
|
{
|
|
char *s;
|
|
char perms[11];
|
|
- if(!get_nod(fs, nod)->i_mode)
|
|
- return;
|
|
+ nod_info *ni;
|
|
+ inode *node = get_nod(fs, nod, &ni);
|
|
+ blk_info *bi;
|
|
+
|
|
+ if(!node->i_mode)
|
|
+ goto out;
|
|
switch(nod)
|
|
{
|
|
case EXT2_BAD_INO:
|
|
@@ -2304,15 +2465,18 @@ print_inode(filesystem *fs, uint32 nod)
|
|
default:
|
|
s = (nod >= EXT2_FIRST_INO) ? "normal" : "unknown reserved";
|
|
}
|
|
- printf("inode %d (%s, %d links): ", nod, s, get_nod(fs, nod)->i_links_count);
|
|
- if(!allocated(GRP_GET_INODE_BITMAP(fs,nod), GRP_IBM_OFFSET(fs,nod)))
|
|
+ printf("inode %d (%s, %d links): ", nod, s, node->i_links_count);
|
|
+ if(!allocated(GRP_GET_INODE_BITMAP(fs,nod,&bi), GRP_IBM_OFFSET(fs,nod)))
|
|
{
|
|
+ GRP_PUT_INODE_BITMAP(bi);
|
|
printf("unallocated\n");
|
|
- return;
|
|
+ goto out;
|
|
}
|
|
- make_perms(get_nod(fs, nod)->i_mode, perms);
|
|
- 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));
|
|
- switch(get_nod(fs, nod)->i_mode & FM_IFMT)
|
|
+ GRP_PUT_INODE_BITMAP(bi);
|
|
+ make_perms(node->i_mode, perms);
|
|
+ printf("%s, size: %d byte%s (%d block%s)\n", perms,
|
|
+ plural(node->i_size), plural(node->i_blocks / INOBLK));
|
|
+ switch(node->i_mode & FM_IFMT)
|
|
{
|
|
case FM_IFSOCK:
|
|
list_blocks(fs, nod);
|
|
@@ -2340,6 +2504,8 @@ print_inode(filesystem *fs, uint32 nod)
|
|
list_blocks(fs, nod);
|
|
}
|
|
printf("Done with inode %d\n",nod);
|
|
+out:
|
|
+ put_nod(ni);
|
|
}
|
|
|
|
// describes various fields in a filesystem
|
|
@@ -2347,6 +2513,7 @@ static void
|
|
print_fs(filesystem *fs)
|
|
{
|
|
uint32 i;
|
|
+ blk_info *bi;
|
|
uint8 *ibm;
|
|
|
|
printf("%d blocks (%d free, %d reserved), first data block: %d\n",
|
|
@@ -2369,13 +2536,16 @@ print_fs(filesystem *fs)
|
|
fs->gd[i].bg_block_bitmap, fs->gd[i].bg_inode_bitmap,
|
|
fs->gd[i].bg_inode_table);
|
|
printf("block bitmap allocation:\n");
|
|
- print_bm(GRP_GET_GROUP_BBM(fs, i),fs->sb.s_blocks_per_group);
|
|
+ print_bm(GRP_GET_GROUP_BBM(fs, i, &bi),
|
|
+ fs->sb.s_blocks_per_group);
|
|
+ GRP_PUT_GROUP_BBM(bi);
|
|
printf("inode bitmap allocation:\n");
|
|
- ibm = GRP_GET_GROUP_IBM(fs, i);
|
|
+ ibm = GRP_GET_GROUP_IBM(fs, i, &bi);
|
|
print_bm(ibm, fs->sb.s_inodes_per_group);
|
|
for (i = 1; i <= fs->sb.s_inodes_per_group; i++)
|
|
if (allocated(ibm, i))
|
|
print_inode(fs, i);
|
|
+ GRP_PUT_GROUP_IBM(bi);
|
|
}
|
|
}
|
|
|
|
@@ -2646,9 +2816,17 @@ main(int argc, char **argv)
|
|
|
|
if(emptyval) {
|
|
uint32 b;
|
|
- for(b = 1; b < fs->sb.s_blocks_count; b++)
|
|
- if(!allocated(GRP_GET_BLOCK_BITMAP(fs,b),GRP_BBM_OFFSET(fs,b)))
|
|
- memset(get_blk(fs, b), emptyval, BLOCKSIZE);
|
|
+ for(b = 1; b < fs->sb.s_blocks_count; b++) {
|
|
+ blk_info *bi;
|
|
+ if(!allocated(GRP_GET_BLOCK_BITMAP(fs,b,&bi),
|
|
+ GRP_BBM_OFFSET(fs,b))) {
|
|
+ blk_info *bi2;
|
|
+ memset(get_blk(fs, b, &bi2), emptyval,
|
|
+ BLOCKSIZE);
|
|
+ put_blk(bi2);
|
|
+ }
|
|
+ GRP_PUT_BLOCK_BITMAP(bi);
|
|
+ }
|
|
}
|
|
if(verbose)
|
|
print_fs(fs);
|
|
@@ -2658,13 +2836,15 @@ main(int argc, char **argv)
|
|
char fname[MAX_FILENAME];
|
|
char *p;
|
|
FILE *fh;
|
|
+ nod_info *ni;
|
|
if(!(nod = find_path(fs, EXT2_ROOT_INO, gopt[i])))
|
|
error_msg_and_die("path %s not found in filesystem", gopt[i]);
|
|
while((p = strchr(gopt[i], '/')))
|
|
*p = '_';
|
|
SNPRINTF(fname, MAX_FILENAME-1, "%s.blk", gopt[i]);
|
|
fh = xfopen(fname, "wb");
|
|
- fprintf(fh, "%d:", get_nod(fs, nod)->i_size);
|
|
+ fprintf(fh, "%d:", get_nod(fs, nod, &ni)->i_size);
|
|
+ put_nod(ni);
|
|
flist_blocks(fs, nod, fh);
|
|
fclose(fh);
|
|
}
|
|
--
|
|
1.7.4.1
|
|
|