summaryrefslogtreecommitdiff
path: root/sys/gnu
diff options
context:
space:
mode:
authorBruce Evans <bde@FreeBSD.org>2000-11-05 19:17:40 +0000
committerBruce Evans <bde@FreeBSD.org>2000-11-05 19:17:40 +0000
commit319d05c53eff86a2e2947bd5d23750a7b5d6e0b1 (patch)
treef517ded83d36d25405fa5520d094a911558b2c00 /sys/gnu
parent1e977ddff9f1b7655d4c6c56afe2da5aca8ab636 (diff)
Notes
Diffstat (limited to 'sys/gnu')
-rw-r--r--sys/gnu/ext2fs/ext2_extern.h2
-rw-r--r--sys/gnu/ext2fs/ext2_fs.h2
-rw-r--r--sys/gnu/ext2fs/ext2_linux_balloc.c36
-rw-r--r--sys/gnu/ext2fs/ext2_vfsops.c20
4 files changed, 45 insertions, 15 deletions
diff --git a/sys/gnu/ext2fs/ext2_extern.h b/sys/gnu/ext2fs/ext2_extern.h
index 317f540af1e1..b37b3ec634ee 100644
--- a/sys/gnu/ext2fs/ext2_extern.h
+++ b/sys/gnu/ext2fs/ext2_extern.h
@@ -37,6 +37,7 @@
* SUCH DAMAGE.
*
* @(#)ffs_extern.h 8.3 (Berkeley) 4/16/94
+ * $FreeBSD$
*/
#ifndef _SYS_GNU_EXT2FS_EXT2_EXTERN_H_
@@ -78,6 +79,7 @@ int ext2_dirempty __P((struct inode *, ino_t, struct ucred *));
int ext2_checkpath __P((struct inode *, struct inode *, struct ucred *));
struct ext2_group_desc * get_group_desc __P((struct mount * ,
unsigned int , struct buf ** ));
+int ext2_group_sparse __P((int group));
void ext2_discard_prealloc __P((struct inode *));
int ext2_inactive __P((struct vop_inactive_args *));
int ext2_new_block __P ((struct mount * mp, unsigned long goal,
diff --git a/sys/gnu/ext2fs/ext2_fs.h b/sys/gnu/ext2fs/ext2_fs.h
index 64aff0d17bfc..8d5a56d00b61 100644
--- a/sys/gnu/ext2fs/ext2_fs.h
+++ b/sys/gnu/ext2fs/ext2_fs.h
@@ -509,7 +509,7 @@ struct ext2_super_block {
EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \
EXT2_FEATURE_RO_COMPAT_BTREE_DIR)
#else
-#define EXT2_FEATURE_RO_COMPAT_SUPP 0
+#define EXT2_FEATURE_RO_COMPAT_SUPP EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER
#endif
/*
diff --git a/sys/gnu/ext2fs/ext2_linux_balloc.c b/sys/gnu/ext2fs/ext2_linux_balloc.c
index 5c5c7006179e..cf2c0844ba4f 100644
--- a/sys/gnu/ext2fs/ext2_linux_balloc.c
+++ b/sys/gnu/ext2fs/ext2_linux_balloc.c
@@ -495,6 +495,25 @@ static __inline int block_in_use (unsigned long block,
EXT2_BLOCKS_PER_GROUP(sb), map);
}
+static int test_root(int a, int b)
+{
+ if (a == 0)
+ return 1;
+ while (1) {
+ if (a == 1)
+ return 1;
+ if (a % b)
+ return 0;
+ a = a / b;
+ }
+}
+
+int ext2_group_sparse(int group)
+{
+ return (test_root(group, 3) || test_root(group, 5) ||
+ test_root(group, 7));
+}
+
#ifdef unused
static void ext2_check_blocks_bitmap (struct mount * mp)
{
@@ -520,15 +539,20 @@ static void ext2_check_blocks_bitmap (struct mount * mp)
bitmap_nr = load_block_bitmap (mp, i);
bh = sb->s_block_bitmap[bitmap_nr];
- if (!test_bit (0, bh->b_data))
- printf ( "ext2_check_blocks_bitmap: "
- "Superblock in group %d is marked free", i);
-
- for (j = 0; j < desc_blocks; j++)
- if (!test_bit (j + 1, bh->b_data))
+ if (!(es->s_feature_ro_compat &
+ EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER) ||
+ ext2_group_sparse(i)) {
+ if (!test_bit (0, bh->b_data))
printf ("ext2_check_blocks_bitmap: "
+ "Superblock in group %d "
+ "is marked free", i);
+
+ for (j = 0; j < desc_blocks; j++)
+ if (!test_bit (j + 1, bh->b_data))
+ printf ("ext2_check_blocks_bitmap: "
"Descriptor block #%d in group "
"%d is marked free", j, i);
+ }
if (!block_in_use (gdp->bg_block_bitmap, sb, bh->b_data))
printf ("ext2_check_blocks_bitmap: "
diff --git a/sys/gnu/ext2fs/ext2_vfsops.c b/sys/gnu/ext2fs/ext2_vfsops.c
index a56a443de578..4358a2d6fc7d 100644
--- a/sys/gnu/ext2fs/ext2_vfsops.c
+++ b/sys/gnu/ext2fs/ext2_vfsops.c
@@ -843,11 +843,10 @@ ext2_statfs(mp, sbp, p)
struct proc *p;
{
unsigned long overhead;
- unsigned long overhead_per_group;
-
register struct ufsmount *ump;
register struct ext2_sb_info *fs;
register struct ext2_super_block *es;
+ int i, nsb;
ump = VFSTOUFS(mp);
fs = ump->um_e2fs;
@@ -859,13 +858,18 @@ ext2_statfs(mp, sbp, p)
/*
* Compute the overhead (FS structures)
*/
- overhead_per_group = 1 /* super block */ +
- fs->s_db_per_group +
- 1 /* block bitmap */ +
- 1 /* inode bitmap */ +
- fs->s_itb_per_group;
+ if (es->s_feature_ro_compat & EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER) {
+ nsb = 0;
+ for (i = 0 ; i < fs->s_groups_count; i++)
+ if (ext2_group_sparse(i))
+ nsb++;
+ } else
+ nsb = fs->s_groups_count;
overhead = es->s_first_data_block +
- fs->s_groups_count * overhead_per_group;
+ /* Superblocks and block group descriptors: */
+ nsb * (1 + fs->s_db_per_group) +
+ /* Inode bitmap, block bitmap, and inode table: */
+ fs->s_groups_count * (1 + 1 + fs->s_itb_per_group);
sbp->f_bsize = EXT2_FRAG_SIZE(fs);
sbp->f_iosize = EXT2_BLOCK_SIZE(fs);