Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/ufs/ext2fs add support for GDT_CSUM AKA uninit_bg feature
details: https://anonhg.NetBSD.org/src/rev/d85fd3fe9b41
branches: trunk
changeset: 347318:d85fd3fe9b41
user: jdolecek <jdolecek%NetBSD.org@localhost>
date: Sat Aug 20 19:47:44 2016 +0000
description:
add support for GDT_CSUM AKA uninit_bg feature
diffstat:
sys/ufs/ext2fs/ext2fs.h | 52 ++++++--
sys/ufs/ext2fs/ext2fs_alloc.c | 222 ++++++++++++++++++++++++++++++++++++----
sys/ufs/ext2fs/ext2fs_bswap.c | 19 +---
sys/ufs/ext2fs/ext2fs_extern.h | 3 +-
sys/ufs/ext2fs/ext2fs_vfsops.c | 20 +++-
5 files changed, 257 insertions(+), 59 deletions(-)
diffs (truncated from 574 to 300 lines):
diff -r 792f03850be0 -r d85fd3fe9b41 sys/ufs/ext2fs/ext2fs.h
--- a/sys/ufs/ext2fs/ext2fs.h Sat Aug 20 19:46:54 2016 +0000
+++ b/sys/ufs/ext2fs/ext2fs.h Sat Aug 20 19:47:44 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ext2fs.h,v 1.47 2016/08/15 18:46:11 jdolecek Exp $ */
+/* $NetBSD: ext2fs.h,v 1.48 2016/08/20 19:47:44 jdolecek Exp $ */
/*
* Copyright (c) 1982, 1986, 1993
@@ -249,10 +249,10 @@
int64_t e2fs_qbmask; /* ~fs_bmask - for use with quad size */
int32_t e2fs_fsbtodb; /* fsbtodb and dbtofsb shift constant */
int32_t e2fs_ncg; /* number of cylinder groups */
- int32_t e2fs_ngdb; /* number of group descriptor block */
+ int32_t e2fs_ngdb; /* number of group descriptor blocks */
int32_t e2fs_ipb; /* number of inodes per block */
- int32_t e2fs_itpg; /* number of inode table per group */
- struct ext2_gd *e2fs_gd; /* group descripors */
+ int32_t e2fs_itpg; /* number of inode table blocks per group */
+ struct ext2_gd *e2fs_gd; /* group descriptors (data not byteswapped) */
};
@@ -366,7 +366,8 @@
| EXT2F_ROCOMPAT_LARGEFILE \
| EXT2F_ROCOMPAT_HUGE_FILE \
| EXT2F_ROCOMPAT_EXTRA_ISIZE \
- | EXT2F_ROCOMPAT_DIR_NLINK)
+ | EXT2F_ROCOMPAT_DIR_NLINK \
+ | EXT2F_ROCOMPAT_GDT_CSUM)
#define EXT2F_INCOMPAT_SUPP (EXT2F_INCOMPAT_FTYPE \
| EXT2F_INCOMPAT_EXTENTS \
| EXT2F_INCOMPAT_FLEX_BG)
@@ -415,15 +416,35 @@
struct ext2_gd {
uint32_t ext2bgd_b_bitmap; /* blocks bitmap block */
uint32_t ext2bgd_i_bitmap; /* inodes bitmap block */
- uint32_t ext2bgd_i_tables; /* inodes table block */
+ uint32_t ext2bgd_i_tables; /* first inodes table block */
uint16_t ext2bgd_nbfree; /* number of free blocks */
uint16_t ext2bgd_nifree; /* number of free inodes */
uint16_t ext2bgd_ndirs; /* number of directories */
- uint16_t reserved;
- uint32_t reserved2[3];
+
+ /*
+ * Following only valid when either GDT_CSUM (AKA uninit_bg)
+ * or METADATA_CKSUM feature is on
+ */
+ uint16_t ext2bgd_flags; /* ext4 bg flags (INODE_UNINIT, ...)*/
+ uint32_t ext2bgd_exclude_bitmap_lo; /* snapshot exclude bitmap */
+ uint16_t ext2bgd_block_bitmap_csum_lo; /* Low block bitmap checksum */
+ uint16_t ext2bgd_inode_bitmap_csum_lo; /* Low inode bitmap checksum */
+ uint16_t ext2bgd_itable_unused_lo; /* Low unused inode offset */
+ uint16_t ext2bgd_checksum; /* Group desc checksum */
+
+ /*
+ * XXX disk32 Further fields only exist if 64BIT feature is on
+ * and superblock desc_size > 32, not supported for now.
+ */
};
+#define E2FS_BG_INODE_UNINIT 0x0001 /* Inode bitmap not used/initialized */
+#define E2FS_BG_BLOCK_UNINIT 0x0002 /* Block bitmap not used/initialized */
+#define E2FS_BG_INODE_ZEROED 0x0004 /* On-disk inode table initialized */
+#define E2FS_HAS_GD_CSUM(fs) \
+ EXT2F_HAS_ROCOMPAT_FEATURE(fs, EXT2F_ROCOMPAT_GDT_CSUM|EXT2F_ROCOMPAT_METADATA_CKSUM) != 0
+
/*
* If the EXT2F_ROCOMPAT_SPARSESUPER flag is set, the cylinder group has a
* copy of the super and cylinder group descriptors blocks only if it's
@@ -457,13 +478,10 @@
# define fs2h16(x) (x)
# define fs2h32(x) (x)
# define fs2h64(x) (x)
-# define e2fs_sbload(old, new) memcpy((new), (old), SBSIZE);
-# define e2fs_cgload(old, new, size) memcpy((new), (old), (size));
-# define e2fs_sbsave(old, new) memcpy((new), (old), SBSIZE);
-# define e2fs_cgsave(old, new, size) memcpy((new), (old), (size));
+# define e2fs_sbload(old, new) memcpy((new), (old), SBSIZE)
+# define e2fs_sbsave(old, new) memcpy((new), (old), SBSIZE)
#else
void e2fs_sb_bswap(struct ext2fs *, struct ext2fs *);
-void e2fs_cg_bswap(struct ext2_gd *, struct ext2_gd *, int);
# define h2fs16(x) bswap16(x)
# define h2fs32(x) bswap32(x)
# define h2fs64(x) bswap64(x)
@@ -471,11 +489,13 @@
# define fs2h32(x) bswap32(x)
# define fs2h64(x) bswap64(x)
# define e2fs_sbload(old, new) e2fs_sb_bswap((old), (new))
-# define e2fs_cgload(old, new, size) e2fs_cg_bswap((old), (new), (size));
# define e2fs_sbsave(old, new) e2fs_sb_bswap((old), (new))
-# define e2fs_cgsave(old, new, size) e2fs_cg_bswap((old), (new), (size));
#endif
+/* Group descriptors are not byte swapped */
+#define e2fs_cgload(old, new, size) memcpy((new), (old), (size))
+#define e2fs_cgsave(old, new, size) memcpy((new), (old), (size))
+
/*
* Turn file system block numbers into disk block addresses.
* This maps file system blocks to device size blocks.
@@ -491,7 +511,7 @@
*/
#define ino_to_cg(fs, x) (((x) - 1) / (fs)->e2fs.e2fs_ipg)
#define ino_to_fsba(fs, x) \
- ((fs)->e2fs_gd[ino_to_cg((fs), (x))].ext2bgd_i_tables + \
+ (fs2h32((fs)->e2fs_gd[ino_to_cg((fs), (x))].ext2bgd_i_tables) + \
(((x) - 1) % (fs)->e2fs.e2fs_ipg) / (fs)->e2fs_ipb)
#define ino_to_fsbo(fs, x) (((x) - 1) % (fs)->e2fs_ipb)
diff -r 792f03850be0 -r d85fd3fe9b41 sys/ufs/ext2fs/ext2fs_alloc.c
--- a/sys/ufs/ext2fs/ext2fs_alloc.c Sat Aug 20 19:46:54 2016 +0000
+++ b/sys/ufs/ext2fs/ext2fs_alloc.c Sat Aug 20 19:47:44 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ext2fs_alloc.c,v 1.48 2016/08/13 07:40:10 christos Exp $ */
+/* $NetBSD: ext2fs_alloc.c,v 1.49 2016/08/20 19:47:44 jdolecek Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1993
@@ -60,7 +60,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ext2fs_alloc.c,v 1.48 2016/08/13 07:40:10 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ext2fs_alloc.c,v 1.49 2016/08/20 19:47:44 jdolecek Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -72,6 +72,8 @@
#include <sys/syslog.h>
#include <sys/kauth.h>
+#include <lib/libkern/crc16.h>
+
#include <ufs/ufs/inode.h>
#include <ufs/ufs/ufs_extern.h>
#include <ufs/ufs/ufsmount.h>
@@ -88,6 +90,9 @@
daddr_t (*)(struct inode *, int, daddr_t, int));
static daddr_t ext2fs_nodealloccg(struct inode *, int, daddr_t, int);
static daddr_t ext2fs_mapsearch(struct m_ext2fs *, char *, daddr_t);
+static __inline void ext2fs_cg_update(struct m_ext2fs *, int, struct ext2_gd *, int, int, int, daddr_t);
+static uint16_t ext2fs_cg_get_csum(struct m_ext2fs *, int, struct ext2_gd *);
+static void ext2fs_init_bb(struct m_ext2fs *, int, struct ext2_gd *, char *);
/*
* Allocate a block in the file system.
@@ -191,7 +196,11 @@
return error;
}
ip = VTOI(*vpp);
- if (ip->i_e2fs_mode && ip->i_e2fs_nlink != 0) {
+
+ KASSERT(!E2FS_HAS_GD_CSUM(fs) || (fs->e2fs_gd[ino_to_cg(fs, ino)].ext2bgd_flags & h2fs16(E2FS_BG_INODE_ZEROED)) != 0);
+
+ /* check for already used inode; makes sense only for ZEROED itable */
+ if (__predict_false(ip->i_e2fs_mode && ip->i_e2fs_nlink != 0)) {
printf("mode = 0%o, nlinks %d, inum = %llu, fs = %s\n",
ip->i_e2fs_mode, ip->i_e2fs_nlink,
(unsigned long long)ip->i_number, fs->e2fs_fsmnt);
@@ -229,10 +238,10 @@
maxspace = 0;
mincg = -1;
for (cg = 0; cg < fs->e2fs_ncg; cg++)
- if ( fs->e2fs_gd[cg].ext2bgd_nifree >= avgifree) {
- if (mincg == -1 || fs->e2fs_gd[cg].ext2bgd_nbfree > maxspace) {
+ if (fs2h16(fs->e2fs_gd[cg].ext2bgd_nifree) >= avgifree) {
+ if (mincg == -1 || fs2h16(fs->e2fs_gd[cg].ext2bgd_nbfree) > maxspace) {
mincg = cg;
- maxspace = fs->e2fs_gd[cg].ext2bgd_nbfree;
+ maxspace = fs2h16(fs->e2fs_gd[cg].ext2bgd_nbfree);
}
}
return mincg;
@@ -356,7 +365,7 @@
if (fs->e2fs_gd[cg].ext2bgd_nbfree == 0)
return 0;
error = bread(ip->i_devvp, EXT2_FSBTODB(fs,
- fs->e2fs_gd[cg].ext2bgd_b_bitmap),
+ fs2h32(fs->e2fs_gd[cg].ext2bgd_b_bitmap)),
(int)fs->e2fs_bsize, B_MODIFY, &bp);
if (error) {
return 0;
@@ -365,6 +374,14 @@
if (dtog(fs, bpref) != cg)
bpref = 0;
+
+ /* initialize block bitmap now if uninit */
+ if (__predict_false(E2FS_HAS_GD_CSUM(fs) &&
+ (fs->e2fs_gd[cg].ext2bgd_flags & h2fs16(E2FS_BG_BLOCK_UNINIT)))) {
+ ext2fs_init_bb(fs, cg, &fs->e2fs_gd[cg], bbp);
+ fs->e2fs_gd[cg].ext2bgd_flags &= h2fs16(~E2FS_BG_BLOCK_UNINIT);
+ }
+
if (bpref != 0) {
bpref = dtogd(fs, bpref);
/*
@@ -412,7 +429,7 @@
#endif
setbit(bbp, (daddr_t)bno);
fs->e2fs.e2fs_fbcount--;
- fs->e2fs_gd[cg].ext2bgd_nbfree--;
+ ext2fs_cg_update(fs, cg, &fs->e2fs_gd[cg], -1, 0, 0, 0);
fs->e2fs_fmod = 1;
bdwrite(bp);
return cg * fs->e2fs.e2fs_fpg + fs->e2fs.e2fs_first_dblock + bno;
@@ -442,12 +459,23 @@
if (fs->e2fs_gd[cg].ext2bgd_nifree == 0)
return 0;
error = bread(ip->i_devvp, EXT2_FSBTODB(fs,
- fs->e2fs_gd[cg].ext2bgd_i_bitmap),
+ fs2h32(fs->e2fs_gd[cg].ext2bgd_i_bitmap)),
(int)fs->e2fs_bsize, B_MODIFY, &bp);
if (error) {
return 0;
}
ibp = (char *)bp->b_data;
+
+ KASSERT(!E2FS_HAS_GD_CSUM(fs) || (fs->e2fs_gd[cg].ext2bgd_flags & h2fs16(E2FS_BG_INODE_ZEROED)) != 0);
+
+ /* initialize inode bitmap now if uninit */
+ if (__predict_false(E2FS_HAS_GD_CSUM(fs) &&
+ (fs->e2fs_gd[cg].ext2bgd_flags & h2fs16(E2FS_BG_INODE_UNINIT)))) {
+ KASSERT(fs2h16(fs->e2fs_gd[cg].ext2bgd_nifree) == fs->e2fs.e2fs_ipg);
+ memset(ibp, 0, fs->e2fs_bsize);
+ fs->e2fs_gd[cg].ext2bgd_flags &= h2fs16(~E2FS_BG_INODE_UNINIT);
+ }
+
if (ipref) {
ipref %= fs->e2fs.e2fs_ipg;
if (isclr(ibp, ipref))
@@ -471,17 +499,15 @@
map = ibp[i] ^ 0xff;
if (map == 0) {
printf("fs = %s\n", fs->e2fs_fsmnt);
- panic("ext2fs_nodealloccg: block not in map");
+ panic("ext2fs_nodealloccg: inode not in map");
}
ipref = i * NBBY + ffs(map) - 1;
gotit:
setbit(ibp, ipref);
fs->e2fs.e2fs_ficount--;
- fs->e2fs_gd[cg].ext2bgd_nifree--;
+ ext2fs_cg_update(fs, cg, &fs->e2fs_gd[cg],
+ 0, -1, ((mode & IFMT) == IFDIR) ? 1 : 0, ipref);
fs->e2fs_fmod = 1;
- if ((mode & IFMT) == IFDIR) {
- fs->e2fs_gd[cg].ext2bgd_ndirs++;
- }
bdwrite(bp);
return cg * fs->e2fs.e2fs_ipg + ipref + 1;
}
@@ -502,6 +528,9 @@
fs = ip->i_e2fs;
cg = dtog(fs, bno);
+
+ KASSERT(!E2FS_HAS_GD_CSUM(fs) || (fs->e2fs_gd[cg].ext2bgd_flags & h2fs16(E2FS_BG_BLOCK_UNINIT)) == 0);
+
if ((u_int)bno >= fs->e2fs.e2fs_bcount) {
printf("bad block %lld, ino %llu\n", (long long)bno,
(unsigned long long)ip->i_number);
@@ -509,7 +538,7 @@
return;
}
error = bread(ip->i_devvp,
- EXT2_FSBTODB(fs, fs->e2fs_gd[cg].ext2bgd_b_bitmap),
+ EXT2_FSBTODB(fs, fs2h32(fs->e2fs_gd[cg].ext2bgd_b_bitmap)),
(int)fs->e2fs_bsize, B_MODIFY, &bp);
if (error) {
return;
@@ -524,8 +553,7 @@
}
clrbit(bbp, bno);
fs->e2fs.e2fs_fbcount++;
- fs->e2fs_gd[cg].ext2bgd_nbfree++;
-
+ ext2fs_cg_update(fs, cg, &fs->e2fs_gd[cg], 1, 0, 0, 0);
fs->e2fs_fmod = 1;
bdwrite(bp);
}
@@ -546,13 +574,18 @@
pip = VTOI(pvp);
fs = pip->i_e2fs;
+
if ((u_int)ino > fs->e2fs.e2fs_icount || (u_int)ino < EXT2_FIRSTINO)
panic("ifree: range: dev = 0x%llx, ino = %llu, fs = %s",
(unsigned long long)pip->i_dev, (unsigned long long)ino,
fs->e2fs_fsmnt);
+
cg = ino_to_cg(fs, ino);
+
+ KASSERT(!E2FS_HAS_GD_CSUM(fs) || (fs->e2fs_gd[cg].ext2bgd_flags & h2fs16(E2FS_BG_INODE_UNINIT)) == 0);
+
error = bread(pip->i_devvp,
Home |
Main Index |
Thread Index |
Old Index