[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1319354488-6050-2-git-send-email-xiaoqiangnk@gmail.com>
Date: Sun, 23 Oct 2011 15:21:21 +0800
From: Yongqiang Yang <xiaoqiangnk@...il.com>
To: linux-ext4@...r.kernel.org
Cc: amir73il@...rs.sf.net, Yongqiang Yang <xiaoqiangnk@...il.com>
Subject: [PATCH 1/8] e2fsprogs: add exclude bitmap support in libext2fs
Exclude bitmap is needed by ext4 snapshot. This patch adds
exclude bitmap support in libext2fs.
Signed-off-by: Yongqiang Yang <xiaoqiangnk@...il.com>
Signed-off-by: Amir Goldstein <amir73il@...rs.sf.net>
---
lib/e2p/ls.c | 13 ++++
lib/ext2fs/alloc.c | 3 +
lib/ext2fs/alloc_tables.c | 44 ++++++++++++++-
lib/ext2fs/bitmaps.c | 70 +++++++++++++++++++++++
lib/ext2fs/blknum.c | 27 +++++++++
lib/ext2fs/bmap64.h | 2 +
lib/ext2fs/csum.c | 5 +-
lib/ext2fs/dupfs.c | 5 ++
lib/ext2fs/ext2_err.et.in | 21 +++++++
lib/ext2fs/ext2_fs.h | 2 +
lib/ext2fs/ext2fs.h | 28 +++++++++
lib/ext2fs/freefs.c | 2 +
lib/ext2fs/gen_bitmap.c | 48 ++++++++++++++++
lib/ext2fs/gen_bitmap64.c | 3 +
lib/ext2fs/initialize.c | 16 +++++
lib/ext2fs/openfs.c | 2 +
lib/ext2fs/rw_bitmaps.c | 136 ++++++++++++++++++++++++++++++++++++++++-----
lib/ext2fs/swapfs.c | 2 +
18 files changed, 409 insertions(+), 20 deletions(-)
diff --git a/lib/e2p/ls.c b/lib/e2p/ls.c
index f05e16d..0cd5b37 100644
--- a/lib/e2p/ls.c
+++ b/lib/e2p/ls.c
@@ -161,6 +161,19 @@ static void print_super_flags(struct ext2_super_block * s, FILE *f)
fputs("test_filesystem ", f);
flags_found++;
}
+ if (s->s_flags & EXT2_FLAGS_IS_SNAPSHOT) {
+ fputs("is_snapshot ", f);
+ flags_found++;
+ }
+ if (s->s_flags & EXT2_FLAGS_FIX_SNAPSHOT) {
+ fputs("fix_snapshot ", f);
+ flags_found++;
+ }
+ if (s->s_flags & EXT2_FLAGS_FIX_EXCLUDE) {
+ fputs("fix_snapshot_bitmap ", f);
+ flags_found++;
+ }
+
if (flags_found)
fputs("\n", f);
else
diff --git a/lib/ext2fs/alloc.c b/lib/ext2fs/alloc.c
index 948a0ec..a0b91dd 100644
--- a/lib/ext2fs/alloc.c
+++ b/lib/ext2fs/alloc.c
@@ -65,6 +65,9 @@ static void check_block_uninit(ext2_filsys fs, ext2fs_block_bitmap map,
(blk < old_desc_blk + old_desc_blocks)) ||
(new_desc_blk && (blk == new_desc_blk)) ||
(blk == ext2fs_block_bitmap_loc(fs, group)) ||
+ (EXT2_HAS_COMPAT_FEATURE(fs->super,
+ EXT2_FEATURE_COMPAT_EXCLUDE_BITMAP) &&
+ (blk == ext2fs_exclude_bitmap_loc(fs, group))) ||
(blk == ext2fs_inode_bitmap_loc(fs, group)) ||
(blk >= ext2fs_inode_table_loc(fs, group) &&
(blk < ext2fs_inode_table_loc(fs, group)
diff --git a/lib/ext2fs/alloc_tables.c b/lib/ext2fs/alloc_tables.c
index 9f3d4e0..b5e2f0c 100644
--- a/lib/ext2fs/alloc_tables.c
+++ b/lib/ext2fs/alloc_tables.c
@@ -87,7 +87,7 @@ errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
errcode_t retval;
blk64_t group_blk, start_blk, last_blk, new_blk, blk;
dgrp_t last_grp = 0;
- int rem_grps = 0, flexbg_size = 0;
+ int rem_grps = 0, flexbg_size = 0, exclude_bitmap = 0;
group_blk = ext2fs_group_first_block2(fs, group);
last_blk = ext2fs_group_last_block2(fs, group);
@@ -105,8 +105,12 @@ errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
rem_grps = last_grp - group + 1;
}
+ if (EXT2_HAS_COMPAT_FEATURE(fs->super,
+ EXT2_FEATURE_COMPAT_EXCLUDE_BITMAP))
+ exclude_bitmap = 1;
+
/*
- * Allocate the block and inode bitmaps, if necessary
+ * Allocate the block, exclude and inode bitmaps, if necessary
*/
if (fs->stride) {
retval = ext2fs_get_free_blocks2(fs, group_blk, last_blk,
@@ -150,13 +154,47 @@ errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
}
}
+ if (exclude_bitmap && flexbg_size) {
+ blk64_t prev_block = 0;
+
+ if (group % flexbg_size)
+ prev_block = ext2fs_exclude_bitmap_loc(fs, group - 1) + 1;
+ else
+ prev_block = ext2fs_block_bitmap_loc(fs, group) +
+ flexbg_size;
+ start_blk = flexbg_offset(fs, group, prev_block, bmap,
+ rem_grps, 1);
+ last_blk = ext2fs_group_last_block2(fs, last_grp);
+ }
+
+ if (exclude_bitmap && !ext2fs_exclude_bitmap_loc(fs, group)) {
+ retval = ext2fs_get_free_blocks2(fs, start_blk, last_blk,
+ 1, bmap, &new_blk);
+ if (retval == EXT2_ET_BLOCK_ALLOC_FAIL)
+ retval = ext2fs_get_free_blocks2(fs, group_blk,
+ last_blk, 1, bmap, &new_blk);
+ if (retval)
+ return retval;
+ ext2fs_mark_block_bitmap2(bmap, new_blk);
+ ext2fs_exclude_bitmap_loc_set(fs, group, new_blk);
+ if (flexbg_size) {
+ dgrp_t gr = ext2fs_group_of_blk2(fs, new_blk);
+ ext2fs_bg_free_blocks_count_set(fs, gr,
+ ext2fs_bg_free_blocks_count(fs, gr) - 1);
+ ext2fs_free_blocks_count_add(fs->super, -1);
+ ext2fs_bg_flags_clear(fs, gr, EXT2_BG_BLOCK_UNINIT);
+ ext2fs_group_desc_csum_set(fs, gr);
+ }
+ }
+
if (flexbg_size) {
blk64_t prev_block = 0;
if (group % flexbg_size)
prev_block = ext2fs_inode_bitmap_loc(fs, group - 1) + 1;
else
- prev_block = ext2fs_block_bitmap_loc(fs, group) +
+ prev_block = ext2fs_exclude_bitmap_loc(fs, group) +
flexbg_size;
+
start_blk = flexbg_offset(fs, group, prev_block, bmap,
rem_grps, 1);
last_blk = ext2fs_group_last_block2(fs, last_grp);
diff --git a/lib/ext2fs/bitmaps.c b/lib/ext2fs/bitmaps.c
index e518295..4709fa2 100644
--- a/lib/ext2fs/bitmaps.c
+++ b/lib/ext2fs/bitmaps.c
@@ -35,6 +35,11 @@ void ext2fs_free_inode_bitmap(ext2fs_inode_bitmap bitmap)
ext2fs_free_generic_bmap(bitmap);
}
+void ext2fs_free_exclude_bitmap(ext2fs_exclude_bitmap bitmap)
+{
+ ext2fs_free_generic_bmap(bitmap);
+}
+
void ext2fs_free_block_bitmap(ext2fs_block_bitmap bitmap)
{
ext2fs_free_generic_bmap(bitmap);
@@ -82,6 +87,39 @@ errcode_t ext2fs_allocate_inode_bitmap(ext2_filsys fs,
(ext2fs_generic_bitmap *) ret));
}
+errcode_t ext2fs_allocate_exclude_bitmap(ext2_filsys fs,
+ const char *descr,
+ ext2fs_exclude_bitmap *ret)
+{
+ __u32 start, end, real_end;
+
+ if (!EXT2_HAS_COMPAT_FEATURE(fs->super,
+ EXT2_FEATURE_COMPAT_EXCLUDE_BITMAP))
+ return 0;
+
+ EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+
+ fs->write_bitmaps = ext2fs_write_bitmaps;
+
+ start = fs->super->s_first_data_block;
+ end = fs->super->s_blocks_count-1;
+ real_end = (EXT2_BLOCKS_PER_GROUP(fs->super)
+ * fs->group_desc_count)-1 + start;
+
+ if (fs->flags & EXT2_FLAG_64BITS)
+ return ext2fs_alloc_generic_bmap(fs,
+ EXT2_ET_MAGIC_EXCLUDE_BITMAP64,
+ EXT2FS_BMAP64_BITARRAY,
+ start, end, real_end, descr, ret);
+
+ if ((end > ~0U) || (real_end > ~0U))
+ return EXT2_ET_CANT_USE_LEGACY_BITMAPS;
+
+ return ext2fs_make_generic_bitmap(EXT2_ET_MAGIC_EXCLUDE_BITMAP, fs,
+ start, end, real_end,
+ descr, 0, ret);
+}
+
errcode_t ext2fs_allocate_block_bitmap(ext2_filsys fs,
const char *descr,
ext2fs_block_bitmap *ret)
@@ -268,6 +306,38 @@ errcode_t ext2fs_get_inode_bitmap_range(ext2fs_inode_bitmap bmap,
start, num, out));
}
+errcode_t ext2fs_set_exclude_bitmap_range(ext2fs_exclude_bitmap bmap,
+ blk_t start, unsigned int num,
+ void *in)
+{
+ return ext2fs_set_generic_bitmap_range(bmap,
+ EXT2_ET_MAGIC_EXCLUDE_BITMAP,
+ start, num, in);
+}
+
+errcode_t ext2fs_set_exclude_bitmap_range2(ext2fs_exclude_bitmap bmap,
+ blk64_t start, size_t num,
+ void *in)
+{
+ return ext2fs_set_generic_bmap_range(bmap, start, num, in);
+}
+
+errcode_t ext2fs_get_exclude_bitmap_range(ext2fs_exclude_bitmap bmap,
+ blk_t start, unsigned int num,
+ void *out)
+{
+ return ext2fs_get_generic_bitmap_range(bmap,
+ EXT2_ET_MAGIC_EXCLUDE_BITMAP,
+ start, num, out);
+}
+
+errcode_t ext2fs_get_exclude_bitmap_range2(ext2fs_exclude_bitmap bmap,
+ blk64_t start, size_t num,
+ void *out)
+{
+ return ext2fs_get_generic_bmap_range(bmap, start, num, out);
+}
+
errcode_t ext2fs_get_inode_bitmap_range2(ext2fs_inode_bitmap bmap,
__u64 start, size_t num,
void *out)
diff --git a/lib/ext2fs/blknum.c b/lib/ext2fs/blknum.c
index fd203b4..17df8c7 100644
--- a/lib/ext2fs/blknum.c
+++ b/lib/ext2fs/blknum.c
@@ -230,6 +230,33 @@ void ext2fs_block_bitmap_loc_set(ext2_filsys fs, dgrp_t group, blk64_t blk)
}
/*
+ * Return the exclude bitmap block of a group
+ */
+blk64_t ext2fs_exclude_bitmap_loc(ext2_filsys fs, dgrp_t group)
+{
+ struct ext4_group_desc *gdp;
+
+ gdp = ext4fs_group_desc(fs, fs->group_desc, group);
+ return gdp->bg_exclude_bitmap_lo |
+ (fs->super->s_feature_incompat
+ & EXT4_FEATURE_INCOMPAT_64BIT ?
+ (__u64)gdp->bg_exclude_bitmap_hi << 32 : 0);
+}
+
+/*
+ * Set the exclude bitmap block of a group
+ */
+void ext2fs_exclude_bitmap_loc_set(ext2_filsys fs, dgrp_t group, blk64_t blk)
+{
+ struct ext4_group_desc *gdp;
+
+ gdp = ext4fs_group_desc(fs, fs->group_desc, group);
+ gdp->bg_exclude_bitmap_lo = blk;
+ if (fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT)
+ gdp->bg_exclude_bitmap_hi = (__u64) blk >> 32;
+}
+
+/*
* Return the inode bitmap block of a group
*/
blk64_t ext2fs_inode_bitmap_loc(ext2_filsys fs, dgrp_t group)
diff --git a/lib/ext2fs/bmap64.h b/lib/ext2fs/bmap64.h
index 3056544..d1baef2 100644
--- a/lib/ext2fs/bmap64.h
+++ b/lib/ext2fs/bmap64.h
@@ -25,11 +25,13 @@ struct ext2fs_struct_generic_bitmap {
#define EXT2FS_IS_32_BITMAP(bmap) \
(((bmap)->magic == EXT2_ET_MAGIC_GENERIC_BITMAP) || \
((bmap)->magic == EXT2_ET_MAGIC_BLOCK_BITMAP) || \
+ ((bmap)->magic == EXT2_ET_MAGIC_EXCLUDE_BITMAP) || \
((bmap)->magic == EXT2_ET_MAGIC_INODE_BITMAP))
#define EXT2FS_IS_64_BITMAP(bmap) \
(((bmap)->magic == EXT2_ET_MAGIC_GENERIC_BITMAP64) || \
((bmap)->magic == EXT2_ET_MAGIC_BLOCK_BITMAP64) || \
+ ((bmap)->magic == EXT2_ET_MAGIC_EXCLUDE_BITMAP64) || \
((bmap)->magic == EXT2_ET_MAGIC_INODE_BITMAP64))
struct ext2_bitmap_ops {
diff --git a/lib/ext2fs/csum.c b/lib/ext2fs/csum.c
index 596923e..d6158e1 100644
--- a/lib/ext2fs/csum.c
+++ b/lib/ext2fs/csum.c
@@ -229,8 +229,9 @@ int main(int argc, char **argv)
for (i=0; i < fs->group_desc_count; i++) {
ext2fs_block_bitmap_loc_set(fs, i, 124);
- ext2fs_inode_bitmap_loc_set(fs, i, 125);
- ext2fs_inode_table_loc_set(fs, i, 126);
+ ext2fs_exclude_bitmap_loc_set(fs, i, 125);
+ ext2fs_inode_bitmap_loc_set(fs, i, 126);
+ ext2fs_inode_table_loc_set(fs, i, 127);
ext2fs_bg_free_blocks_count_set(fs, i, 31119);
ext2fs_bg_free_inodes_count_set(fs, i, 15701);
ext2fs_bg_used_dirs_count_set(fs, i, 2);
diff --git a/lib/ext2fs/dupfs.c b/lib/ext2fs/dupfs.c
index 64d3124..e7c00c1 100644
--- a/lib/ext2fs/dupfs.c
+++ b/lib/ext2fs/dupfs.c
@@ -77,6 +77,11 @@ errcode_t ext2fs_dup_handle(ext2_filsys src, ext2_filsys *dest)
if (retval)
goto errout;
}
+ if (src->exclude_map) {
+ retval = ext2fs_copy_bitmap(src->exclude_map, &fs->exclude_map);
+ if (retval)
+ goto errout;
+ }
if (src->badblocks) {
retval = ext2fs_badblocks_copy(src->badblocks, &fs->badblocks);
if (retval)
diff --git a/lib/ext2fs/ext2_err.et.in b/lib/ext2fs/ext2_err.et.in
index e759b6f..c49f0d0 100644
--- a/lib/ext2fs/ext2_err.et.in
+++ b/lib/ext2fs/ext2_err.et.in
@@ -38,6 +38,9 @@ ec EXT2_ET_MAGIC_BLOCK_BITMAP,
ec EXT2_ET_MAGIC_INODE_BITMAP,
"Wrong magic number for inode_bitmap structure"
+ec EXT2_ET_MAGIC_EXCLUDE_BITMAP,
+ "Wrong magic number for snapshot_bitmap structure"
+
ec EXT2_ET_MAGIC_GENERIC_BITMAP,
"Wrong magic number for generic_bitmap structure"
@@ -101,6 +104,12 @@ ec EXT2_ET_BLOCK_BITMAP_WRITE,
ec EXT2_ET_BLOCK_BITMAP_READ,
"Can't read an block bitmap"
+ec EXT2_ET_EXCLUDE_BITMAP_WRITE,
+ "Can't write an snapshot bitmap"
+
+ec EXT2_ET_EXCLUDE_BITMAP_READ,
+ "Can't read an snapshot bitmap"
+
ec EXT2_ET_INODE_TABLE_WRITE,
"Can't write an inode table"
@@ -344,6 +353,9 @@ ec EXT2_ET_MAGIC_BLOCK_BITMAP64,
ec EXT2_ET_MAGIC_INODE_BITMAP64,
"Wrong magic number for 64-bit inode bitmap"
+ec EXT2_ET_MAGIC_EXCLUDE_BITMAP64,
+ "Wrong magic number for 64-bit exclude bitmap"
+
ec EXT2_ET_MAGIC_RESERVED_13,
"Wrong magic number --- RESERVED_13"
@@ -443,4 +455,13 @@ ec EXT2_ET_MMP_CHANGE_ABORT,
ec EXT2_ET_MMP_OPEN_DIRECT,
"MMP: open with O_DIRECT failed"
+ec EXT2_ET_BAD_EXCLUDE_TEST,
+ "Illegal block number passed to ext2fs_test_exclude_bitmap"
+
+ec EXT2_ET_BAD_EXCLUDE_MARK,
+ "Illegal block number passed to ext2fs_mark_exclude_bitmap"
+
+ec EXT2_ET_BAD_EXCLUDE_UNMARK,
+ "Illegal block number passed to ext2fs_unmark_exclude_bitmap"
+
end
diff --git a/lib/ext2fs/ext2_fs.h b/lib/ext2fs/ext2_fs.h
index 0f8cde8..a1e29d0 100644
--- a/lib/ext2fs/ext2_fs.h
+++ b/lib/ext2fs/ext2_fs.h
@@ -194,6 +194,7 @@ struct ext4_group_desc
#define EXT2_BG_INODE_UNINIT 0x0001 /* Inode table/bitmap not initialized */
#define EXT2_BG_BLOCK_UNINIT 0x0002 /* Block bitmap not initialized */
#define EXT2_BG_INODE_ZEROED 0x0004 /* On-disk itable initialized to zero */
+#define EXT2_BG_EXCLUDE_UNINIT 0x0008 /* Exclude bitmap not initialized */
/*
* Data structures used by the directory indexing feature
@@ -724,6 +725,7 @@ struct ext2_super_block {
#define EXT2_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE| \
EXT4_FEATURE_INCOMPAT_MMP)
#define EXT2_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \
+ EXT4_FEATURE_RO_COMPAT_HAS_SNAPSHOT|\
EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \
EXT4_FEATURE_RO_COMPAT_DIR_NLINK| \
EXT2_FEATURE_RO_COMPAT_BTREE_DIR)
diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
index 203d222..d1f0d98 100644
--- a/lib/ext2fs/ext2fs.h
+++ b/lib/ext2fs/ext2fs.h
@@ -113,7 +113,9 @@ typedef struct struct_ext2_filsys *ext2_filsys;
typedef struct ext2fs_struct_generic_bitmap *ext2fs_generic_bitmap;
typedef struct ext2fs_struct_generic_bitmap *ext2fs_inode_bitmap;
+typedef struct ext2fs_struct_generic_bitmap *ext2fs_exclude_bitmap;
typedef struct ext2fs_struct_generic_bitmap *ext2fs_block_bitmap;
+typedef struct ext2fs_struct_generic_bitmap *ext2fs_exclude_bitmap;
#define EXT2_FIRST_INODE(s) EXT2_FIRST_INO(s)
@@ -196,6 +198,7 @@ typedef struct ext2_file *ext2_file_t;
#define EXT2_FLAG_PRINT_PROGRESS 0x40000
#define EXT2_FLAG_DIRECT_IO 0x80000
#define EXT2_FLAG_SKIP_MMP 0x100000
+#define EXT2_FLAG_EB_DIRTY 0x200000
/*
* Special flag in the ext2 inode i_flag field that means that this is
@@ -225,6 +228,7 @@ struct struct_ext2_filsys {
unsigned int inode_blocks_per_group;
ext2fs_inode_bitmap inode_map;
ext2fs_block_bitmap block_map;
+ ext2fs_exclude_bitmap exclude_map;
/* XXX FIXME-64: not 64-bit safe, but not used? */
errcode_t (*get_blocks)(ext2_filsys fs, ext2_ino_t ino, blk_t *blocks);
errcode_t (*check_directory)(ext2_filsys fs, ext2_ino_t ino);
@@ -543,6 +547,7 @@ typedef struct ext2_icount *ext2_icount_t;
#define EXT2_LIB_FEATURE_COMPAT_SUPP (EXT2_FEATURE_COMPAT_DIR_PREALLOC|\
EXT2_FEATURE_COMPAT_IMAGIC_INODES|\
EXT3_FEATURE_COMPAT_HAS_JOURNAL|\
+ EXT2_FEATURE_COMPAT_EXCLUDE_BITMAP|\
EXT2_FEATURE_COMPAT_RESIZE_INODE|\
EXT2_FEATURE_COMPAT_DIR_INDEX|\
EXT2_FEATURE_COMPAT_EXT_ATTR)
@@ -721,8 +726,10 @@ extern errcode_t ext2fs_copy_bitmap(ext2fs_generic_bitmap src,
ext2fs_generic_bitmap *dest);
extern errcode_t ext2fs_write_inode_bitmap(ext2_filsys fs);
extern errcode_t ext2fs_write_block_bitmap (ext2_filsys fs);
+extern errcode_t ext2fs_write_exclude_bitmap (ext2_filsys fs);
extern errcode_t ext2fs_read_inode_bitmap (ext2_filsys fs);
extern errcode_t ext2fs_read_block_bitmap(ext2_filsys fs);
+extern errcode_t ext2fs_read_exclude_bitmap (ext2_filsys fs);
extern errcode_t ext2fs_allocate_block_bitmap(ext2_filsys fs,
const char *descr,
ext2fs_block_bitmap *ret);
@@ -813,6 +820,9 @@ extern struct ext2_group_desc *ext2fs_group_desc(ext2_filsys fs,
extern blk64_t ext2fs_block_bitmap_loc(ext2_filsys fs, dgrp_t group);
extern void ext2fs_block_bitmap_loc_set(ext2_filsys fs, dgrp_t group,
blk64_t blk);
+extern blk64_t ext2fs_exclude_bitmap_loc(ext2_filsys fs, dgrp_t group);
+extern void ext2fs_block_exclude_loc_set(ext2_filsys fs, dgrp_t group,
+ blk64_t blk);
extern blk64_t ext2fs_inode_bitmap_loc(ext2_filsys fs, dgrp_t group);
extern void ext2fs_inode_bitmap_loc_set(ext2_filsys fs, dgrp_t group,
blk64_t blk);
@@ -1619,6 +1629,16 @@ _INLINE_ void ext2fs_mark_bb_dirty(ext2_filsys fs)
}
/*
+ * Mark the exclude bitmap as dirty
+ */
+_INLINE_ void ext2fs_mark_eb_dirty(ext2_filsys fs)
+{
+ if (EXT2_HAS_COMPAT_FEATURE(fs->super,
+ EXT2_FEATURE_COMPAT_EXCLUDE_BITMAP))
+ fs->flags |= EXT2_FLAG_EB_DIRTY | EXT2_FLAG_CHANGED;
+}
+
+/*
* Check to see if a filesystem's inode bitmap is dirty
*/
_INLINE_ int ext2fs_test_ib_dirty(ext2_filsys fs)
@@ -1635,6 +1655,14 @@ _INLINE_ int ext2fs_test_bb_dirty(ext2_filsys fs)
}
/*
+ * Check to see if a filesystem's exclude bitmap is dirty
+ */
+_INLINE_ int ext2fs_test_eb_dirty(ext2_filsys fs)
+{
+ return fs->flags & EXT2_FLAG_EB_DIRTY;
+}
+
+/*
* Return the group # of a block
*/
_INLINE_ int ext2fs_group_of_blk(ext2_filsys fs, blk_t blk)
diff --git a/lib/ext2fs/freefs.c b/lib/ext2fs/freefs.c
index 28c4132..488f077 100644
--- a/lib/ext2fs/freefs.c
+++ b/lib/ext2fs/freefs.c
@@ -43,6 +43,8 @@ void ext2fs_free(ext2_filsys fs)
ext2fs_free_block_bitmap(fs->block_map);
if (fs->inode_map)
ext2fs_free_inode_bitmap(fs->inode_map);
+ if (fs->exclude_map)
+ ext2fs_free_exclude_bitmap(fs->exclude_map);
if (fs->badblocks)
ext2fs_badblocks_list_free(fs->badblocks);
diff --git a/lib/ext2fs/gen_bitmap.c b/lib/ext2fs/gen_bitmap.c
index 6679bff..0285c33 100644
--- a/lib/ext2fs/gen_bitmap.c
+++ b/lib/ext2fs/gen_bitmap.c
@@ -42,11 +42,13 @@ struct ext2fs_struct_generic_bitmap {
#define EXT2FS_IS_32_BITMAP(bmap) \
(((bmap)->magic == EXT2_ET_MAGIC_GENERIC_BITMAP) || \
((bmap)->magic == EXT2_ET_MAGIC_BLOCK_BITMAP) || \
+ ((bmap)->magic == EXT2_ET_MAGIC_EXCLUDE_BITMAP) || \
((bmap)->magic == EXT2_ET_MAGIC_INODE_BITMAP))
#define EXT2FS_IS_64_BITMAP(bmap) \
(((bmap)->magic == EXT2_ET_MAGIC_GENERIC_BITMAP64) || \
((bmap)->magic == EXT2_ET_MAGIC_BLOCK_BITMAP64) || \
+ ((bmap)->magic == EXT2_ET_MAGIC_EXCLUDE_BITMAP64) || \
((bmap)->magic == EXT2_ET_MAGIC_INODE_BITMAP64))
/*
@@ -69,6 +71,7 @@ static errcode_t check_magic(ext2fs_generic_bitmap bitmap)
{
if (!bitmap || !((bitmap->magic == EXT2_ET_MAGIC_GENERIC_BITMAP) ||
(bitmap->magic == EXT2_ET_MAGIC_INODE_BITMAP) ||
+ (bitmap->magic == EXT2_ET_MAGIC_EXCLUDE_BITMAP) ||
(bitmap->magic == EXT2_ET_MAGIC_BLOCK_BITMAP)))
return EXT2_ET_MAGIC_GENERIC_BITMAP;
return 0;
@@ -100,6 +103,9 @@ errcode_t ext2fs_make_generic_bitmap(errcode_t magic, ext2_filsys fs,
case EXT2_ET_MAGIC_BLOCK_BITMAP:
bitmap->base_error_code = EXT2_ET_BAD_BLOCK_MARK;
break;
+ case EXT2_ET_MAGIC_EXCLUDE_BITMAP:
+ bitmap->base_error_code = EXT2_ET_BAD_EXCLUDE_MARK;
+ break;
default:
bitmap->base_error_code = EXT2_ET_BAD_GENERIC_MARK;
}
@@ -517,6 +523,19 @@ int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
bitmap, block, num);
}
+int ext2fs_test_exlucde_bitmap_range(ext2fs_exclude_bitmap bitmap,
+ blk_t block, int num)
+{
+ EXT2_CHECK_MAGIC(bitmap, EXT2_ET_MAGIC_EXCLUDE_BITMAP);
+ if ((block < bitmap->start) || (block+num-1 > bitmap->real_end)) {
+ ext2fs_warn_bitmap(EXT2_ET_BAD_EXCLUDE_TEST,
+ block, bitmap->description);
+ return 0;
+ }
+ return ext2fs_test_clear_generic_bitmap_range((ext2fs_generic_bitmap)
+ bitmap, block, num);
+}
+
int ext2fs_test_inode_bitmap_range(ext2fs_inode_bitmap bitmap,
ino_t inode, int num)
{
@@ -558,3 +577,32 @@ void ext2fs_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
ext2fs_fast_clear_bit(block + i - bitmap->start,
bitmap->bitmap);
}
+
+void ext2fs_mark_exclude_bitmap_range(ext2fs_exclude_bitmap bitmap,
+ blk_t block, int num)
+{
+ int i;
+
+ if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
+ ext2fs_warn_bitmap(EXT2_ET_BAD_EXCLUDE_MARK, block,
+ bitmap->description);
+ return;
+ }
+ for (i = 0; i < num; i++)
+ ext2fs_fast_set_bit(block + i - bitmap->start, bitmap->bitmap);
+}
+
+void ext2fs_unmark_exclude_bitmap_range(ext2fs_exclude_bitmap bitmap,
+ blk_t block, int num)
+{
+ int i;
+
+ if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
+ ext2fs_warn_bitmap(EXT2_ET_BAD_EXCLUDE_UNMARK, block,
+ bitmap->description);
+ return;
+ }
+ for (i = 0; i < num; i++)
+ ext2fs_fast_clear_bit(block + i - bitmap->start,
+ bitmap->bitmap);
+}
diff --git a/lib/ext2fs/gen_bitmap64.c b/lib/ext2fs/gen_bitmap64.c
index 9dbbf9f..abceb0f 100644
--- a/lib/ext2fs/gen_bitmap64.c
+++ b/lib/ext2fs/gen_bitmap64.c
@@ -117,6 +117,9 @@ errcode_t ext2fs_alloc_generic_bmap(ext2_filsys fs, errcode_t magic,
bitmap->base_error_code = EXT2_ET_BAD_BLOCK_MARK;
bitmap->cluster_bits = fs->cluster_ratio_bits;
break;
+ case EXT2_ET_MAGIC_EXCLUDE_BITMAP64:
+ bitmap->base_error_code = EXT2_ET_BAD_EXCLUDE_MARK;
+ break;
default:
bitmap->base_error_code = EXT2_ET_BAD_GENERIC_MARK;
}
diff --git a/lib/ext2fs/initialize.c b/lib/ext2fs/initialize.c
index 47f0b1c..0dc8852 100644
--- a/lib/ext2fs/initialize.c
+++ b/lib/ext2fs/initialize.c
@@ -97,6 +97,7 @@ errcode_t ext2fs_initialize(const char *name, int flags,
int rsv_gdt;
int csum_flag;
int bigalloc_flag;
+ int exclude_flag;
int io_flags;
char *buf = 0;
char c;
@@ -407,6 +408,17 @@ ipg_retry:
if (retval)
goto cleanup;
+ exclude_flag = EXT2_HAS_COMPAT_FEATURE(fs->super,
+ EXT2_FEATURE_COMPAT_EXCLUDE_BITMAP);
+ if (exclude_flag) {
+ strcpy(buf, "exclude bitmap for ");
+ strcat(buf, fs->device_name);
+ retval = ext2fs_allocate_exclude_bitmap(fs, buf,
+ &fs->exclude_map);
+ if (retval)
+ goto cleanup;
+ }
+
strcpy(buf, "inode bitmap for ");
strcat(buf, fs->device_name);
retval = ext2fs_allocate_inode_bitmap(fs, buf, &fs->inode_map);
@@ -445,6 +457,9 @@ ipg_retry:
if (i != fs->group_desc_count - 1)
ext2fs_bg_flags_set(fs, i,
EXT2_BG_BLOCK_UNINIT);
+ if (exclude_flag)
+ ext2fs_bg_flags_set(fs, i,
+ EXT2_BG_EXCLUDE_UNINIT);
ext2fs_bg_flags_set(fs, i, EXT2_BG_INODE_UNINIT);
numblocks = super->s_inodes_per_group;
if (i == 0)
@@ -473,6 +488,7 @@ ipg_retry:
ext2fs_mark_super_dirty(fs);
ext2fs_mark_bb_dirty(fs);
+ ext2fs_mark_eb_dirty(fs);
ext2fs_mark_ib_dirty(fs);
io_channel_set_blksize(fs->io, fs->blocksize);
diff --git a/lib/ext2fs/openfs.c b/lib/ext2fs/openfs.c
index 0cefe3f..a047d0d 100644
--- a/lib/ext2fs/openfs.c
+++ b/lib/ext2fs/openfs.c
@@ -376,6 +376,8 @@ errcode_t ext2fs_open2(const char *name, const char *io_options,
for (group = 0; group < fs->group_desc_count; group++) {
ext2fs_bg_flags_clear(fs, group, EXT2_BG_BLOCK_UNINIT);
+ ext2fs_bg_flags_clear(fs, group,
+ EXT2_BG_EXCLUDE_UNINIT);
ext2fs_bg_flags_clear(fs, group, EXT2_BG_INODE_UNINIT);
ext2fs_bg_itable_unused_set(fs, group, 0);
}
diff --git a/lib/ext2fs/rw_bitmaps.c b/lib/ext2fs/rw_bitmaps.c
index 1d5f7b2..3126733 100644
--- a/lib/ext2fs/rw_bitmaps.c
+++ b/lib/ext2fs/rw_bitmaps.c
@@ -28,17 +28,21 @@
#include "ext2fs.h"
#include "e2image.h"
-static errcode_t write_bitmaps(ext2_filsys fs, int do_inode, int do_block)
+static errcode_t write_bitmaps(ext2_filsys fs, int do_inode, int do_block,
+ int do_exclude)
{
dgrp_t i;
unsigned int j;
int block_nbytes, inode_nbytes;
unsigned int nbits;
errcode_t retval;
- char *block_buf = NULL, *inode_buf = NULL;
+ char *block_buf = NULL, *inode_buf = NULL,
+ *exclude_buf = NULL;
int csum_flag = 0;
blk64_t blk;
blk64_t blk_itr = EXT2FS_B2C(fs, fs->super->s_first_data_block);
+ blk64_t exclude_itr =
+ EXT2FS_B2C(fs, fs->super->s_first_data_block);
ext2_ino_t ino_itr = 1;
EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
@@ -46,6 +50,10 @@ static errcode_t write_bitmaps(ext2_filsys fs, int do_inode, int do_block)
if (!(fs->flags & EXT2_FLAG_RW))
return EXT2_ET_RO_FILSYS;
+ if (!EXT2_HAS_COMPAT_FEATURE(fs->super,
+ EXT2_FEATURE_COMPAT_EXCLUDE_BITMAP))
+ do_exclude = 0;
+
if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
EXT4_FEATURE_RO_COMPAT_GDT_CSUM))
csum_flag = 1;
@@ -59,6 +67,14 @@ static errcode_t write_bitmaps(ext2_filsys fs, int do_inode, int do_block)
goto errout;
memset(block_buf, 0xff, fs->blocksize);
}
+ if (do_exclude) {
+ block_nbytes = EXT2_BLOCKS_PER_GROUP(fs->super) / 8;
+ retval = ext2fs_get_memalign(fs->blocksize, fs->blocksize,
+ &exclude_buf);
+ if (retval)
+ return retval;
+ memset(exclude_buf, 0x0, fs->blocksize);
+ }
if (do_inode) {
inode_nbytes = (size_t)
((EXT2_INODES_PER_GROUP(fs->super)+7) / 8);
@@ -104,6 +120,26 @@ static errcode_t write_bitmaps(ext2_filsys fs, int do_inode, int do_block)
skip_this_block_bitmap:
blk_itr += block_nbytes << 3;
skip_block_bitmap:
+ if (!do_exclude)
+ goto skip_exclude_bitmap;
+ if (csum_flag && ext2fs_bg_flags_test(fs, i, EXT2_BG_EXCLUDE_UNINIT)
+ )
+ goto skip_this_exclude_bitmap;
+
+ retval = ext2fs_get_block_bitmap_range2(fs->exclude_map,
+ exclude_itr, block_nbytes << 3, exclude_buf);
+ if (retval)
+ goto errout;
+ blk = ext2fs_exclude_bitmap_loc(fs, i);
+ if (blk) {
+ retval = io_channel_write_blk64(fs->io, blk, 1,
+ exclude_buf);
+ if (retval)
+ return EXT2_ET_EXCLUDE_BITMAP_WRITE;
+ }
+ skip_this_exclude_bitmap:
+ exclude_itr += block_nbytes << 3;
+ skip_exclude_bitmap:
if (!do_inode)
continue;
@@ -126,7 +162,7 @@ static errcode_t write_bitmaps(ext2_filsys fs, int do_inode, int do_block)
goto errout;
}
}
- skip_this_inode_bitmap:
+skip_this_inode_bitmap:
ino_itr += inode_nbytes << 3;
}
@@ -134,6 +170,10 @@ static errcode_t write_bitmaps(ext2_filsys fs, int do_inode, int do_block)
fs->flags &= ~EXT2_FLAG_BB_DIRTY;
ext2fs_free_mem(&block_buf);
}
+ if (do_exclude) {
+ fs->flags &= ~EXT2_FLAG_EB_DIRTY;
+ ext2fs_free_mem(&exclude_buf);
+ }
if (do_inode) {
fs->flags &= ~EXT2_FLAG_IB_DIRTY;
ext2fs_free_mem(&inode_buf);
@@ -147,10 +187,11 @@ errout:
return retval;
}
-static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block)
+static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block,
+ int do_exclude)
{
dgrp_t i;
- char *block_bitmap = 0, *inode_bitmap = 0;
+ char *block_bitmap = 0, *inode_bitmap = 0, *exclude_bitmap = 0;
char *buf;
errcode_t retval;
int block_nbytes = EXT2_CLUSTERS_PER_GROUP(fs->super) / 8;
@@ -168,6 +209,10 @@ static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block)
fs->write_bitmaps = ext2fs_write_bitmaps;
+ if (!EXT2_HAS_COMPAT_FEATURE(fs->super,
+ EXT2_FEATURE_COMPAT_EXCLUDE_BITMAP))
+ do_exclude = 0;
+
if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
EXT4_FEATURE_RO_COMPAT_GDT_CSUM))
csum_flag = 1;
@@ -192,7 +237,25 @@ static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block)
if (retval)
goto cleanup;
- } else
+ }
+ if (do_exclude) {
+ if (fs->exclude_map)
+ ext2fs_free_block_bitmap(fs->exclude_map);
+ strcpy(buf, "exclude bitmap for ");
+ strcat(buf, fs->device_name);
+ retval = ext2fs_allocate_block_bitmap(fs, buf, &fs->exclude_map);
+ if (retval)
+ goto cleanup;
+ if (do_image)
+ retval = ext2fs_get_mem(fs->blocksize, &exclude_bitmap);
+ else
+ retval = ext2fs_get_memalign((unsigned) block_nbytes,
+ fs->blocksize,
+ &exclude_bitmap);
+ if (retval)
+ goto cleanup;
+ }
+ if (!do_block && !do_exclude)
block_nbytes = 0;
if (do_inode) {
if (fs->inode_map)
@@ -234,6 +297,11 @@ static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block)
blk_cnt = (blk64_t)EXT2_CLUSTERS_PER_GROUP(fs->super) *
fs->group_desc_count;
while (block_nbytes > 0) {
+ if (do_exclude) {
+ retval = EXT2_ET_EXCLUDE_BITMAP_READ;
+ goto cleanup;
+ }
+
retval = io_channel_read_blk64(fs->image_io, blk++,
1, block_bitmap);
if (retval)
@@ -273,8 +341,30 @@ static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block)
blk_itr, cnt, block_bitmap);
if (retval)
goto cleanup;
- blk_itr += block_nbytes << 3;
}
+ if (exclude_bitmap) {
+ blk = ext2fs_exclude_bitmap_loc(fs, i);
+ if (csum_flag &&
+ ext2fs_bg_flags_test(fs, i, EXT2_BG_EXCLUDE_UNINIT) &&
+ ext2fs_group_desc_csum_verify(fs, i))
+ blk = 0;
+ if (blk) {
+ retval = io_channel_read_blk64(fs->io, blk,
+ -block_nbytes, exclude_bitmap);
+ if (retval) {
+ retval = EXT2_ET_EXCLUDE_BITMAP_READ;
+ goto cleanup;
+ }
+ } else
+ memset(exclude_bitmap, 0, block_nbytes);
+ cnt = block_nbytes << 3;
+ retval = ext2fs_set_block_bitmap_range2(fs->exclude_map,
+ blk_itr, cnt, exclude_bitmap);
+ if (retval)
+ goto cleanup;
+ }
+ if (block_nbytes)
+ blk_itr += block_nbytes << 3;
if (inode_bitmap) {
blk = ext2fs_inode_bitmap_loc(fs, i);
if (csum_flag &&
@@ -303,6 +393,8 @@ success_cleanup:
ext2fs_free_mem(&inode_bitmap);
if (block_bitmap)
ext2fs_free_mem(&block_bitmap);
+ if (exclude_bitmap)
+ ext2fs_free_mem(&exclude_bitmap);
return 0;
cleanup:
@@ -318,6 +410,8 @@ cleanup:
ext2fs_free_mem(&inode_bitmap);
if (block_bitmap)
ext2fs_free_mem(&block_bitmap);
+ if (exclude_bitmap)
+ ext2fs_free_mem(&exclude_bitmap);
if (buf)
ext2fs_free_mem(&buf);
return retval;
@@ -325,39 +419,51 @@ cleanup:
errcode_t ext2fs_read_inode_bitmap(ext2_filsys fs)
{
- return read_bitmaps(fs, 1, 0);
+ return read_bitmaps(fs, 1, 0, 0);
}
errcode_t ext2fs_read_block_bitmap(ext2_filsys fs)
{
- return read_bitmaps(fs, 0, 1);
+ return read_bitmaps(fs, 0, 1, 0);
+}
+
+errcode_t ext2fs_read_exclude_bitmap (ext2_filsys fs)
+{
+ return read_bitmaps(fs, 0, 0, 1);
}
errcode_t ext2fs_write_inode_bitmap(ext2_filsys fs)
{
- return write_bitmaps(fs, 1, 0);
+ return write_bitmaps(fs, 1, 0, 0);
}
errcode_t ext2fs_write_block_bitmap (ext2_filsys fs)
{
- return write_bitmaps(fs, 0, 1);
+ return write_bitmaps(fs, 0, 1, 0);
+}
+
+errcode_t ext2fs_write_exclude_bitmap (ext2_filsys fs)
+{
+ return write_bitmaps(fs, 0, 0, 1);
}
errcode_t ext2fs_read_bitmaps(ext2_filsys fs)
{
- if (fs->inode_map && fs->block_map)
+ if (fs->inode_map && fs->block_map && fs->exclude_map)
return 0;
- return read_bitmaps(fs, !fs->inode_map, !fs->block_map);
+ return read_bitmaps(fs, !fs->inode_map, !fs->block_map,
+ !fs->exclude_map);
}
errcode_t ext2fs_write_bitmaps(ext2_filsys fs)
{
int do_inode = fs->inode_map && ext2fs_test_ib_dirty(fs);
int do_block = fs->block_map && ext2fs_test_bb_dirty(fs);
+ int do_exclude = fs->exclude_map && ext2fs_test_eb_dirty(fs);
- if (!do_inode && !do_block)
+ if (!do_inode && !do_block && !do_exclude)
return 0;
- return write_bitmaps(fs, do_inode, do_block);
+ return write_bitmaps(fs, do_inode, do_block, do_exclude);
}
diff --git a/lib/ext2fs/swapfs.c b/lib/ext2fs/swapfs.c
index 7962472..07ba1cd 100644
--- a/lib/ext2fs/swapfs.c
+++ b/lib/ext2fs/swapfs.c
@@ -105,6 +105,7 @@ void ext2fs_swap_group_desc2(ext2_filsys fs, struct ext2_group_desc *gdp)
{
/* Do the 32-bit parts first */
gdp->bg_block_bitmap = ext2fs_swab32(gdp->bg_block_bitmap);
+ gdp->bg_exclude_bitmap = ext2fs_swab32(gdp->bg_exclude_bitmap);
gdp->bg_inode_bitmap = ext2fs_swab32(gdp->bg_inode_bitmap);
gdp->bg_inode_table = ext2fs_swab32(gdp->bg_inode_table);
gdp->bg_free_blocks_count = ext2fs_swab16(gdp->bg_free_blocks_count);
@@ -126,6 +127,7 @@ void ext2fs_swap_group_desc2(ext2_filsys fs, struct ext2_group_desc *gdp)
/* Swap the 64-bit parts */
struct ext4_group_desc *gdp4 = (struct ext4_group_desc *) gdp;
gdp4->bg_block_bitmap_hi = ext2fs_swab32(gdp4->bg_block_bitmap_hi);
+ gdp4->bg_exclude_bitmap_hi = ext2fs_swab32(gdp4->bg_exclude_bitmap_hi);
gdp4->bg_inode_bitmap_hi = ext2fs_swab32(gdp4->bg_inode_bitmap_hi);
gdp4->bg_inode_table_hi = ext2fs_swab32(gdp4->bg_inode_table_hi);
gdp4->bg_free_blocks_count_hi =
--
1.7.5.1
--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists