Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F153386539
D11211.id29808.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
17 KB
Referenced Files
None
Subscribers
None
D11211.id29808.diff
View Options
Index: sys/conf/files
===================================================================
--- sys/conf/files
+++ sys/conf/files
@@ -3532,6 +3532,7 @@
fs/ext2fs/ext2_alloc.c optional ext2fs
fs/ext2fs/ext2_balloc.c optional ext2fs
fs/ext2fs/ext2_bmap.c optional ext2fs
+fs/ext2fs/ext2_csum.c optional ext2fs
fs/ext2fs/ext2_extattr.c optional ext2fs
fs/ext2fs/ext2_extents.c optional ext2fs
fs/ext2fs/ext2_inode.c optional ext2fs
Index: sys/fs/ext2fs/ext2_alloc.c
===================================================================
--- sys/fs/ext2fs/ext2_alloc.c
+++ sys/fs/ext2fs/ext2_alloc.c
@@ -45,6 +45,7 @@
#include <sys/sysctl.h>
#include <sys/syslog.h>
#include <sys/buf.h>
+#include <sys/endian.h>
#include <fs/ext2fs/fs.h>
#include <fs/ext2fs/inode.h>
@@ -657,6 +658,135 @@
return (0);
}
+static unsigned long
+ext2_cg_num_gdb(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_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 (cg == first || cg == first + 1 || cg == last)
+ return (1);
+ return (0);
+
+}
+
+static int
+ext2_num_base_meta_blocks(struct m_ext2fs *fs, int cg)
+{
+ int num, gd_per_block;
+
+ gd_per_block = fs->e2fs_bsize / sizeof(struct ext2_gd);
+ num = 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;
+ }
+ } else {
+ num += ext2_cg_num_gdb(fs, cg);
+ }
+
+ return (num);
+}
+
+static int
+ext2_get_cg_number(struct m_ext2fs *fs, daddr_t blk)
+{
+ int cg;
+
+ if (fs->e2fs->e2fs_bpg == fs->e2fs_bsize * 8)
+ cg = (blk - fs->e2fs->e2fs_first_dblock) / (fs->e2fs_bsize * 8);
+ else
+ cg = blk - fs->e2fs->e2fs_first_dblock;
+
+ return (cg);
+}
+
+static void
+ext2_mark_bitmap_end(int start_bit, int end_bit, char *bitmap)
+{
+ int i;
+
+ if (start_bit >= end_bit)
+ return;
+
+ for (i = start_bit; i < ((start_bit + 7) & ~7UL); i++)
+ setbit(bitmap, i);
+ if (i < end_bit)
+ memset(bitmap + (i >> 3), 0xff, (end_bit - i) >> 3);
+}
+
+static int
+ext2_cg_block_bitmap_init(struct m_ext2fs *fs, int cg, struct buf *bp)
+{
+ int bit, bit_max, inodes_per_block;
+ uint32_t start, tmp;
+
+ if (!EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_GDT_CSUM) ||
+ !(fs->e2fs_gd[cg].ext4bgd_flags & EXT2_BG_BLOCK_UNINIT))
+ return (0);
+
+ memset(bp->b_data, 0, fs->e2fs_bsize);
+
+ bit_max = ext2_num_base_meta_blocks(fs, cg);
+ if ((bit_max >> 3) >= fs->e2fs_bsize)
+ return (EINVAL);
+
+ for (bit = 0; bit < bit_max; bit++)
+ setbit(bp->b_data, bit);
+
+ start = cg * fs->e2fs->e2fs_bpg + fs->e2fs->e2fs_first_dblock;
+
+ /* Set bits for block and inode bitmaps, and inode table */
+ tmp = fs->e2fs_gd[cg].ext2bgd_b_bitmap;
+ if (!EXT2_HAS_INCOMPAT_FEATURE(fs, EXT2F_INCOMPAT_FLEX_BG) ||
+ tmp == ext2_get_cg_number(fs, cg))
+ setbit(bp->b_data, tmp - start);
+
+ tmp = fs->e2fs_gd[cg].ext2bgd_i_bitmap;
+ if (!EXT2_HAS_INCOMPAT_FEATURE(fs, EXT2F_INCOMPAT_FLEX_BG) ||
+ tmp == ext2_get_cg_number(fs, cg))
+ setbit(bp->b_data, tmp - start);
+
+ tmp = fs->e2fs_gd[cg].ext2bgd_i_tables;
+ inodes_per_block = fs->e2fs_bsize/EXT2_INODE_SIZE(fs);
+ while( tmp < fs->e2fs_gd[cg].ext2bgd_i_tables +
+ fs->e2fs->e2fs_ipg / inodes_per_block ) {
+ if (!EXT2_HAS_INCOMPAT_FEATURE(fs, EXT2F_INCOMPAT_FLEX_BG) ||
+ tmp == ext2_get_cg_number(fs, cg))
+ setbit(bp->b_data, tmp - start);
+ tmp++;
+ }
+
+ /*
+ * Also if the number of blocks within the group is less than
+ * the blocksize * 8 ( which is the size of bitmap ), set rest
+ * of the block bitmap to 1
+ */
+ ext2_mark_bitmap_end(fs->e2fs->e2fs_bpg, fs->e2fs_bsize * 8,
+ bp->b_data);
+
+ /* Clean the flag */
+ fs->e2fs_gd[cg].ext4bgd_flags &= ~EXT2_BG_BLOCK_UNINIT;
+
+ return (0);
+}
+
/*
* Determine whether a block can be allocated.
*
@@ -686,6 +816,14 @@
EXT2_LOCK(ump);
return (0);
}
+ if (EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_GDT_CSUM)) {
+ error = ext2_cg_block_bitmap_init(fs, cg, bp);
+ if (error) {
+ brelse(bp);
+ EXT2_LOCK(ump);
+ return (0);
+ }
+ }
if (fs->e2fs_gd[cg].ext2bgd_nbfree == 0) {
/*
* Another thread allocated the last block in this
@@ -899,6 +1037,41 @@
return (0);
}
+static int
+ext2_zero_inode_table(struct inode *ip, int cg)
+{
+ struct m_ext2fs *fs;
+ struct buf *bp;
+ int i, all_blks, used_blks;
+
+ fs = ip->i_e2fs;
+
+ if (fs->e2fs_gd[cg].ext4bgd_flags & EXT2_BG_INODE_ZEROED)
+ return (0);
+
+ all_blks = fs->e2fs->e2fs_inode_size * fs->e2fs->e2fs_ipg /
+ fs->e2fs_bsize;
+
+ used_blks = howmany(fs->e2fs->e2fs_ipg -
+ fs->e2fs_gd[cg].ext4bgd_i_unused,
+ fs->e2fs_bsize / EXT2_INODE_SIZE(fs));
+
+ for (i = 0; i < all_blks - used_blks; i++) {
+ bp = getblk(ip->i_devvp, fsbtodb(fs,
+ fs->e2fs_gd[cg].ext2bgd_i_tables + used_blks + i),
+ fs->e2fs_bsize, 0, 0, 0);
+ if (!bp)
+ return (EIO);
+
+ vfs_bio_bzero_buf(bp, 0, fs->e2fs_bsize);
+ bawrite(bp);
+ }
+
+ fs->e2fs_gd[cg].ext4bgd_flags |= EXT2_BG_INODE_ZEROED;
+
+ return (0);
+}
+
/*
* Determine whether an inode can be allocated.
*
@@ -930,6 +1103,18 @@
EXT2_LOCK(ump);
return (0);
}
+ if (EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_GDT_CSUM)) {
+ if (fs->e2fs_gd[cg].ext4bgd_flags & EXT2_BG_INODE_UNINIT) {
+ memset(bp->b_data, 0, fs->e2fs_bsize);
+ fs->e2fs_gd[cg].ext4bgd_flags &= ~EXT2_BG_INODE_UNINIT;
+ }
+ error = ext2_zero_inode_table(ip, cg);
+ if (error) {
+ brelse(bp);
+ EXT2_LOCK(ump);
+ return (0);
+ }
+ }
if (fs->e2fs_gd[cg].ext2bgd_nifree == 0) {
/*
* Another thread allocated the last i-node in this
@@ -964,6 +1149,8 @@
setbit(ibp, ipref);
EXT2_LOCK(ump);
fs->e2fs_gd[cg].ext2bgd_nifree--;
+ if (EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_GDT_CSUM))
+ fs->e2fs_gd[cg].ext4bgd_i_unused--;
fs->e2fs->e2fs_ficount--;
fs->e2fs_fmod = 1;
if ((mode & IFMT) == IFDIR) {
@@ -1062,6 +1249,8 @@
EXT2_LOCK(ump);
fs->e2fs->e2fs_ficount++;
fs->e2fs_gd[cg].ext2bgd_nifree++;
+ if (EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_GDT_CSUM))
+ fs->e2fs_gd[cg].ext4bgd_i_unused++;
if ((mode & IFMT) == IFDIR) {
fs->e2fs_gd[cg].ext2bgd_ndirs--;
fs->e2fs_total_dir--;
@@ -1122,16 +1311,31 @@
}
int
-cg_has_sb(int i)
+ext2_cg_has_sb(struct m_ext2fs *fs, int cg)
{
int a3, a5, a7;
- if (i == 0 || i == 1)
- return 1;
+ if (cg == 0)
+ return (1);
+
+ if (EXT2_HAS_COMPAT_FEATURE(fs, EXT2F_COMPAT_SPARSESUPER2)) {
+ if (cg == fs->e2fs->e4fs_backup_bgs[0] ||
+ cg == fs->e2fs->e4fs_backup_bgs[1])
+ return (1);
+ return (0);
+ }
+
+ if ((cg <= 1) ||
+ !EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_SPARSESUPER))
+ return (1);
+
+ if (!(cg & 1))
+ return (0);
+
for (a3 = 3, a5 = 5, a7 = 7;
- a3 <= i || a5 <= i || a7 <= i;
+ a3 <= cg || a5 <= cg || a7 <= cg;
a3 *= 3, a5 *= 5, a7 *= 7)
- if (i == a3 || i == a5 || i == a7)
- return 1;
- return 0;
+ if (cg == a3 || cg == a5 || cg == a7)
+ return (1);
+ return (0);
}
Index: sys/fs/ext2fs/ext2_csum.c
===================================================================
--- /dev/null
+++ sys/fs/ext2fs/ext2_csum.c
@@ -0,0 +1,146 @@
+/*-
+ * Copyright (c) 2017, Fedor Uporov
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/vnode.h>
+#include <sys/bio.h>
+#include <sys/buf.h>
+#include <sys/endian.h>
+#include <sys/conf.h>
+#include <sys/mount.h>
+
+#include <fs/ext2fs/fs.h>
+#include <fs/ext2fs/ext2fs.h>
+#include <fs/ext2fs/inode.h>
+#include <fs/ext2fs/ext2_extern.h>
+
+static uint16_t
+ext2_crc16(uint16_t crc, const void *buffer, unsigned int len)
+{
+ const unsigned char *cp = buffer;
+ /** CRC table for the CRC-16. The poly is 0x8005 (x16 + x15 + x2 + 1) */
+ static uint16_t const crc16_table[256] = {
+ 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
+ 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
+ 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
+ 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
+ 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
+ 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
+ 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
+ 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
+ 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
+ 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
+ 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
+ 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
+ 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
+ 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
+ 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
+ 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
+ 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
+ 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
+ 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
+ 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
+ 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
+ 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
+ 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
+ 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
+ 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
+ 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
+ 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
+ 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
+ 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
+ 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
+ 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
+ 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
+ };
+
+ while (len--)
+ crc = (((crc >> 8) & 0xffU) ^
+ crc16_table[(crc ^ *cp++) & 0xffU]) & 0x0000ffffU;
+ return crc;
+}
+
+static uint16_t
+ext2_gd_csum(struct m_ext2fs *fs, uint32_t block_group, struct ext2_gd *gd)
+{
+ size_t offset;
+ uint16_t crc;
+
+ offset = offsetof(struct ext2_gd, ext4bgd_csum);
+
+ if (EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_GDT_CSUM)) {
+ crc = ext2_crc16(~0, fs->e2fs->e2fs_uuid,
+ sizeof(fs->e2fs->e2fs_uuid));
+ crc = ext2_crc16(crc, (uint8_t *)&block_group,
+ sizeof(block_group));
+ crc = ext2_crc16(crc, (uint8_t *)gd, offset);
+ offset += sizeof(gd->ext4bgd_csum); /* skip checksum */
+ if (EXT2_HAS_INCOMPAT_FEATURE(fs, EXT2F_INCOMPAT_64BIT) &&
+ offset < fs->e2fs->e3fs_desc_size)
+ crc = ext2_crc16(crc, (uint8_t *)gd + offset,
+ fs->e2fs->e3fs_desc_size - offset);
+ return (crc);
+ }
+
+ return (0);
+}
+
+int
+ext2_gd_csum_verify(struct m_ext2fs *fs, struct cdev *dev)
+{
+ unsigned int i;
+ int error = 0;
+
+ for (i = 0; i < fs->e2fs_gcount; i++) {
+ if (fs->e2fs_gd[i].ext4bgd_csum !=
+ ext2_gd_csum(fs, i, &fs->e2fs_gd[i])) {
+ printf(
+"WARNING: mount of %s denied due bad gd=%d csum=0x%x, expected=0x%x - run fsck\n",
+ devtoname(dev), i, fs->e2fs_gd[i].ext4bgd_csum,
+ ext2_gd_csum(fs, i, &fs->e2fs_gd[i]));
+ error = EINVAL;
+ break;
+ }
+ }
+
+ return (error);
+}
+
+void
+ext2_gd_csum_set(struct m_ext2fs *fs)
+{
+ unsigned int i;
+
+ for (i = 0; i < fs->e2fs_gcount; i++)
+ fs->e2fs_gd[i].ext4bgd_csum = ext2_gd_csum(fs, i, &fs->e2fs_gd[i]);
+}
Index: sys/fs/ext2fs/ext2_extern.h
===================================================================
--- sys/fs/ext2fs/ext2_extern.h
+++ sys/fs/ext2fs/ext2_extern.h
@@ -85,7 +85,7 @@
struct inode *, struct componentname *);
int ext2_dirempty(struct inode *, ino_t, struct ucred *);
int ext2_checkpath(struct inode *, struct inode *, struct ucred *);
-int cg_has_sb(int i);
+int ext2_cg_has_sb(struct m_ext2fs *fs, int cg);
int ext2_inactive(struct vop_inactive_args *);
int ext2_htree_add_entry(struct vnode *, struct ext2fs_direct_2 *,
struct componentname *);
@@ -98,6 +98,8 @@
int *, doff_t *, doff_t *, doff_t *, struct ext2fs_searchslot *);
int ext2_search_dirblock(struct inode *, void *, int *, const char *, int,
int *, doff_t *, doff_t *, doff_t *, struct ext2fs_searchslot *);
+int ext2_gd_csum_verify(struct m_ext2fs *fs, struct cdev *dev);
+void ext2_gd_csum_set(struct m_ext2fs *fs);
/* Flags to low-level allocation routines.
Index: sys/fs/ext2fs/ext2_vfsops.c
===================================================================
--- sys/fs/ext2fs/ext2_vfsops.c
+++ sys/fs/ext2fs/ext2_vfsops.c
@@ -349,6 +349,13 @@
printf("ext2fs: no space for extra inode timestamps\n");
return (EINVAL);
}
+ /* Check for group descriptor size */
+ if (EXT2_HAS_INCOMPAT_FEATURE(fs, EXT2F_INCOMPAT_64BIT) &&
+ (es->e3fs_desc_size != sizeof(struct ext2_gd))) {
+ printf("ext2fs: group descriptor size unsupported %d\n",
+ es->e3fs_desc_size);
+ return (EINVAL);
+ }
fs->e2fs_ipb = fs->e2fs_bsize / EXT2_INODE_SIZE(fs);
fs->e2fs_itpg = fs->e2fs_ipg / fs->e2fs_ipb;
@@ -387,6 +394,12 @@
brelse(bp);
bp = NULL;
}
+ /* Verify cg csum */
+ if (EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_GDT_CSUM)) {
+ error = ext2_gd_csum_verify(fs, devvp->v_rdev);
+ if (error)
+ return (error);
+ }
/* Initialization for the ext2 Orlov allocator variant. */
fs->e2fs_total_dir = 0;
for (i = 0; i < fs->e2fs_gcount; i++)
@@ -781,7 +794,7 @@
if (fs->e2fs->e2fs_rev > E2FS_REV0 &&
fs->e2fs->e2fs_features_rocompat & EXT2F_ROCOMPAT_SPARSESUPER) {
for (i = 0, ngroups = 0; i < fs->e2fs_gcount; i++) {
- if (cg_has_sb(i))
+ if (ext2_cg_has_sb(fs, i))
ngroups++;
}
} else {
@@ -1062,6 +1075,11 @@
int i, error = 0, allerror = 0;
allerror = ext2_sbupdate(mp, waitfor);
+
+ /* Update gd csums */
+ if (EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_GDT_CSUM))
+ ext2_gd_csum_set(fs);
+
for (i = 0; i < fs->e2fs_gdbcount; i++) {
bp = getblk(mp->um_devvp, fsbtodb(fs,
fs->e2fs->e2fs_first_dblock +
Index: sys/fs/ext2fs/ext2fs.h
===================================================================
--- sys/fs/ext2fs/ext2fs.h
+++ sys/fs/ext2fs/ext2fs.h
@@ -259,6 +259,7 @@
#define EXT2F_COMPAT_SUPP EXT2F_COMPAT_DIRHASHINDEX
#define EXT2F_ROCOMPAT_SUPP (EXT2F_ROCOMPAT_SPARSESUPER | \
EXT2F_ROCOMPAT_LARGEFILE | \
+ EXT2F_ROCOMPAT_GDT_CSUM | \
EXT2F_ROCOMPAT_HUGE_FILE | \
EXT2F_ROCOMPAT_EXTRA_ISIZE)
#define EXT2F_INCOMPAT_SUPP EXT2F_INCOMPAT_FTYPE
@@ -311,6 +312,10 @@
uint16_t ext4bgd_csum; /* group descriptor checksum */
};
+#define EXT2_BG_INODE_UNINIT 0x0001 /* Inode table/bitmap not in use */
+#define EXT2_BG_BLOCK_UNINIT 0x0002 /* Block bitmap not in use */
+#define EXT2_BG_INODE_ZEROED 0x0004 /* On-disk itable initialized to zero */
+
/* EXT2FS metadatas are stored in little-endian byte order. These macros
* helps reading these metadatas
Index: sys/modules/ext2fs/Makefile
===================================================================
--- sys/modules/ext2fs/Makefile
+++ sys/modules/ext2fs/Makefile
@@ -3,8 +3,9 @@
.PATH: ${SRCTOP}/sys/fs/ext2fs
KMOD= ext2fs
SRCS= opt_ddb.h opt_directio.h opt_quota.h opt_suiddir.h vnode_if.h \
- ext2_acl.c ext2_alloc.c ext2_balloc.c ext2_bmap.c ext2_extattr.c \
- ext2_extents.c ext2_hash.c ext2_htree.c ext2_inode.c ext2_inode_cnv.c \
- ext2_lookup.c ext2_subr.c ext2_vfsops.c ext2_vnops.c
+ ext2_acl.c ext2_alloc.c ext2_balloc.c ext2_bmap.c ext2_csum.c \
+ ext2_extattr.c ext2_extents.c ext2_hash.c ext2_htree.c \
+ ext2_inode.c ext2_inode_cnv.c ext2_lookup.c ext2_subr.c \
+ ext2_vfsops.c ext2_vnops.c
.include <bsd.kmod.mk>
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Apr 21, 8:54 PM (17 h, 4 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31911335
Default Alt Text
D11211.id29808.diff (17 KB)
Attached To
Mode
D11211: ext2fs: Add uninit_bg feature support.
Attached
Detach File
Event Timeline
Log In to Comment