Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F137803089
D13964.id38649.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D13964.id38649.diff
View Options
Index: head/sys/fs/ext2fs/ext2_alloc.c
===================================================================
--- head/sys/fs/ext2fs/ext2_alloc.c
+++ head/sys/fs/ext2fs/ext2_alloc.c
@@ -755,49 +755,68 @@
}
static unsigned long
-ext2_cg_num_gdb(struct m_ext2fs *fs, int cg)
+ext2_cg_number_gdb_nometa(struct m_ext2fs *fs, int cg)
{
- int gd_per_block, metagroup, first, last;
- gd_per_block = fs->e2fs_bsize / sizeof(struct ext2_gd);
- metagroup = cg / gd_per_block;
- first = metagroup * gd_per_block;
- last = first + gd_per_block - 1;
+ if (!ext2_cg_has_sb(fs, cg))
+ return (0);
- if (!EXT2_HAS_INCOMPAT_FEATURE(fs, EXT2F_INCOMPAT_META_BG) ||
- metagroup < fs->e2fs->e3fs_first_meta_bg) {
- if (!ext2_cg_has_sb(fs, cg))
- return (0);
- if (EXT2_HAS_INCOMPAT_FEATURE(fs, EXT2F_INCOMPAT_META_BG))
- return (fs->e2fs->e3fs_first_meta_bg);
- return (fs->e2fs_gdbcount);
- }
+ if (EXT2_HAS_INCOMPAT_FEATURE(fs, EXT2F_INCOMPAT_META_BG))
+ return (fs->e2fs->e3fs_first_meta_bg);
+ return ((fs->e2fs_gcount + EXT2_DESCS_PER_BLOCK(fs) - 1) /
+ EXT2_DESCS_PER_BLOCK(fs));
+}
+
+static unsigned long
+ext2_cg_number_gdb_meta(struct m_ext2fs *fs, int cg)
+{
+ unsigned long metagroup;
+ int first, last;
+
+ metagroup = cg / EXT2_DESCS_PER_BLOCK(fs);
+ first = metagroup * EXT2_DESCS_PER_BLOCK(fs);
+ last = first + EXT2_DESCS_PER_BLOCK(fs) - 1;
+
if (cg == first || cg == first + 1 || cg == last)
return (1);
+
return (0);
+}
+static unsigned long
+ext2_cg_number_gdb(struct m_ext2fs *fs, int cg)
+{
+ unsigned long first_meta_bg, metagroup;
+
+ first_meta_bg = fs->e2fs->e3fs_first_meta_bg;
+ metagroup = cg / EXT2_DESCS_PER_BLOCK(fs);
+
+ if (!EXT2_HAS_INCOMPAT_FEATURE(fs, EXT2F_INCOMPAT_META_BG) ||
+ metagroup < first_meta_bg)
+ return (ext2_cg_number_gdb_nometa(fs, cg));
+
+ return ext2_cg_number_gdb_meta(fs, cg);
}
static int
-ext2_num_base_meta_blocks(struct m_ext2fs *fs, int cg)
+ext2_number_base_meta_blocks(struct m_ext2fs *fs, int cg)
{
- int num, gd_per_block;
+ int number;
- gd_per_block = fs->e2fs_bsize / sizeof(struct ext2_gd);
- num = ext2_cg_has_sb(fs, cg);
+ number = ext2_cg_has_sb(fs, cg);
if (!EXT2_HAS_INCOMPAT_FEATURE(fs, EXT2F_INCOMPAT_META_BG) ||
- cg < fs->e2fs->e3fs_first_meta_bg * gd_per_block) {
- if (num) {
- num += ext2_cg_num_gdb(fs, cg);
- num += fs->e2fs->e2fs_reserved_ngdb;
+ cg < fs->e2fs->e3fs_first_meta_bg * EXT2_DESCS_PER_BLOCK(fs)) {
+ if (number) {
+ number += ext2_cg_number_gdb(fs, cg);
+ number += fs->e2fs->e2fs_reserved_ngdb;
}
} else {
- num += ext2_cg_num_gdb(fs, cg);
+ number += ext2_cg_number_gdb(fs, cg);
}
-
- return (num);
+
+ return (number);
}
static void
@@ -815,6 +834,20 @@
}
static int
+ext2_get_group_number(struct m_ext2fs *fs, e4fs_daddr_t block)
+{
+
+ return ((block - fs->e2fs->e2fs_first_dblock) / fs->e2fs_bsize);
+}
+
+static int
+ext2_block_in_group(struct m_ext2fs *fs, e4fs_daddr_t block, int cg)
+{
+
+ return ((ext2_get_group_number(fs, block) == cg) ? 1 : 0);
+}
+
+static int
ext2_cg_block_bitmap_init(struct m_ext2fs *fs, int cg, struct buf *bp)
{
int bit, bit_max, inodes_per_block;
@@ -825,7 +858,7 @@
memset(bp->b_data, 0, fs->e2fs_bsize);
- bit_max = ext2_num_base_meta_blocks(fs, cg);
+ bit_max = ext2_number_base_meta_blocks(fs, cg);
if ((bit_max >> 3) >= fs->e2fs_bsize)
return (EINVAL);
@@ -837,12 +870,12 @@
/* Set bits for block and inode bitmaps, and inode table. */
tmp = e2fs_gd_get_b_bitmap(&fs->e2fs_gd[cg]);
if (!EXT2_HAS_INCOMPAT_FEATURE(fs, EXT2F_INCOMPAT_FLEX_BG) ||
- cg == dtogd(fs, tmp))
+ ext2_block_in_group(fs, tmp, cg))
setbit(bp->b_data, tmp - start);
tmp = e2fs_gd_get_i_bitmap(&fs->e2fs_gd[cg]);
if (!EXT2_HAS_INCOMPAT_FEATURE(fs, EXT2F_INCOMPAT_FLEX_BG) ||
- cg == dtogd(fs, tmp))
+ ext2_block_in_group(fs, tmp, cg))
setbit(bp->b_data, tmp - start);
tmp = e2fs_gd_get_i_tables(&fs->e2fs_gd[cg]);
@@ -850,7 +883,7 @@
while( tmp < e2fs_gd_get_i_tables(&fs->e2fs_gd[cg]) +
fs->e2fs->e2fs_ipg / inodes_per_block ) {
if (!EXT2_HAS_INCOMPAT_FEATURE(fs, EXT2F_INCOMPAT_FLEX_BG) ||
- cg == dtogd(fs, tmp))
+ ext2_block_in_group(fs, tmp, cg))
setbit(bp->b_data, tmp - start);
tmp++;
}
Index: head/sys/fs/ext2fs/ext2_vfsops.c
===================================================================
--- head/sys/fs/ext2fs/ext2_vfsops.c
+++ head/sys/fs/ext2fs/ext2_vfsops.c
@@ -154,7 +154,8 @@
if (mp->mnt_flag & MNT_FORCE)
flags |= FORCECLOSE;
error = ext2_flushfiles(mp, flags, td);
- if (error == 0 && fs->e2fs_wasvalid && ext2_cgupdate(ump, MNT_WAIT) == 0) {
+ if (error == 0 && fs->e2fs_wasvalid &&
+ ext2_cgupdate(ump, MNT_WAIT) == 0) {
fs->e2fs->e2fs_state |= E2FS_ISCLEAN;
ext2_sbupdate(ump, MNT_WAIT);
}
@@ -318,6 +319,36 @@
return (0);
}
+static e4fs_daddr_t
+cg_location(struct m_ext2fs *fs, int number)
+{
+ int cg, descpb, logical_sb, has_super = 0;
+
+ /*
+ * Adjust logical superblock block number.
+ * Godmar thinks: if the blocksize is greater than 1024, then
+ * the superblock is logically part of block zero.
+ */
+ logical_sb = fs->e2fs_bsize > SBSIZE ? 0 : 1;
+
+ if (!EXT2_HAS_INCOMPAT_FEATURE(fs, EXT2F_INCOMPAT_META_BG) ||
+ number < fs->e2fs->e3fs_first_meta_bg)
+ return (logical_sb + number + 1);
+
+ if (EXT2_HAS_INCOMPAT_FEATURE(fs, EXT2F_INCOMPAT_64BIT))
+ descpb = fs->e2fs_bsize / sizeof(struct ext2_gd);
+ else
+ descpb = fs->e2fs_bsize / E2FS_REV0_GD_SIZE;
+
+ cg = descpb * number;
+
+ if (ext2_cg_has_sb(fs, cg))
+ has_super = 1;
+
+ return (has_super + cg * (e4fs_daddr_t)EXT2_BLOCKS_PER_GROUP(fs) +
+ fs->e2fs->e2fs_first_dblock);
+}
+
/*
* This computes the fields of the m_ext2fs structure from the
* data in the ext2fs structure read in.
@@ -328,7 +359,6 @@
{
int g_count = 0, error;
int i, j;
- int logic_sb_block = 1; /* XXX for now */
struct buf *bp;
uint32_t e2fs_descpb, e2fs_gdbcount_alloc;
@@ -385,6 +415,12 @@
es->e3fs_desc_size);
return (EINVAL);
}
+ /* Check for group size */
+ if (fs->e2fs_bpg != fs->e2fs_bsize * 8) {
+ printf("ext2fs: non-standard group size unsupported %d\n",
+ fs->e2fs_bpg);
+ return (EINVAL);
+ }
fs->e2fs_ipb = fs->e2fs_bsize / EXT2_INODE_SIZE(fs);
fs->e2fs_itpg = fs->e2fs_ipg / fs->e2fs_ipb;
@@ -405,16 +441,9 @@
fs->e2fs_contigdirs = malloc(fs->e2fs_gcount *
sizeof(*fs->e2fs_contigdirs), M_EXT2MNT, M_WAITOK | M_ZERO);
- /*
- * Adjust logic_sb_block.
- * Godmar thinks: if the blocksize is greater than 1024, then
- * the superblock is logically part of block zero.
- */
- if (fs->e2fs_bsize > SBSIZE)
- logic_sb_block = 0;
for (i = 0; i < fs->e2fs_gdbcount; i++) {
error = bread(devvp,
- fsbtodb(fs, logic_sb_block + i + 1),
+ fsbtodb(fs, cg_location(fs, i)),
fs->e2fs_bsize, NOCRED, &bp);
if (error) {
free(fs->e2fs_contigdirs, M_EXT2MNT);
@@ -1151,8 +1180,8 @@
for (i = 0; i < fs->e2fs_gdbcount; i++) {
bp = getblk(mp->um_devvp, fsbtodb(fs,
- fs->e2fs->e2fs_first_dblock +
- 1 /* superblock */ + i), fs->e2fs_bsize, 0, 0, 0);
+ cg_location(fs, i)),
+ fs->e2fs_bsize, 0, 0, 0);
if (EXT2_HAS_INCOMPAT_FEATURE(fs, EXT2F_INCOMPAT_64BIT)) {
memcpy(bp->b_data, &fs->e2fs_gd[
i * fs->e2fs_bsize / sizeof(struct ext2_gd)],
Index: head/sys/fs/ext2fs/ext2fs.h
===================================================================
--- head/sys/fs/ext2fs/ext2fs.h
+++ head/sys/fs/ext2fs/ext2fs.h
@@ -334,12 +334,12 @@
EXT2F_ROCOMPAT_HUGE_FILE | \
EXT2F_ROCOMPAT_EXTRA_ISIZE)
#define EXT2F_INCOMPAT_SUPP (EXT2F_INCOMPAT_FTYPE | \
+ EXT2F_INCOMPAT_META_BG | \
EXT2F_INCOMPAT_EXTENTS | \
EXT2F_INCOMPAT_64BIT | \
- EXT2F_INCOMPAT_CSUM_SEED)
-#define EXT4F_RO_INCOMPAT_SUPP (EXT2F_INCOMPAT_RECOVER | \
EXT2F_INCOMPAT_FLEX_BG | \
- EXT2F_INCOMPAT_META_BG )
+ EXT2F_INCOMPAT_CSUM_SEED)
+#define EXT4F_RO_INCOMPAT_SUPP EXT2F_INCOMPAT_RECOVER
/* Assume that user mode programs are passing in an ext2fs superblock, not
* a kernel struct super_block. This will allow us to call the feature-test
@@ -423,5 +423,8 @@
* Macro-instructions used to manage group descriptors
*/
#define EXT2_BLOCKS_PER_GROUP(s) (EXT2_SB(s)->e2fs_bpg)
+#define EXT2_DESCS_PER_BLOCK(s) (EXT2_HAS_INCOMPAT_FEATURE((s), \
+ EXT2F_INCOMPAT_64BIT) ? ((s)->e2fs_bsize / sizeof(struct ext2_gd)) : \
+ ((s)->e2fs_bsize / E2FS_REV0_GD_SIZE))
#endif /* !_FS_EXT2FS_EXT2FS_H_ */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Nov 26, 11:13 PM (3 h, 49 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
26234628
Default Alt Text
D13964.id38649.diff (8 KB)
Attached To
Mode
D13964: Add flex_bg/meta_bg features RW support.
Attached
Detach File
Event Timeline
Log In to Comment