Changeset View
Changeset View
Standalone View
Standalone View
head/sys/fs/ext2fs/ext2_vfsops.c
Show First 20 Lines • Show All 366 Lines • ▼ Show 20 Lines | if (es->e2fs_rev == E2FS_REV0) { | ||||
} | } | ||||
} | } | ||||
/* Check for extra isize in big inodes. */ | /* Check for extra isize in big inodes. */ | ||||
if (EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_EXTRA_ISIZE) && | if (EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_EXTRA_ISIZE) && | ||||
EXT2_INODE_SIZE(fs) < sizeof(struct ext2fs_dinode)) { | EXT2_INODE_SIZE(fs) < sizeof(struct ext2fs_dinode)) { | ||||
printf("ext2fs: no space for extra inode timestamps\n"); | printf("ext2fs: no space for extra inode timestamps\n"); | ||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
/* Check checksum features */ | |||||
if (EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_GDT_CSUM) && | |||||
EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_METADATA_CKSUM)) { | |||||
printf("ext2fs: incorrect checksum features combination\n"); | |||||
return (EINVAL); | |||||
} | |||||
/* Check for group descriptor size */ | /* Check for group descriptor size */ | ||||
if (EXT2_HAS_INCOMPAT_FEATURE(fs, EXT2F_INCOMPAT_64BIT) && | if (EXT2_HAS_INCOMPAT_FEATURE(fs, EXT2F_INCOMPAT_64BIT) && | ||||
(es->e3fs_desc_size != sizeof(struct ext2_gd))) { | (es->e3fs_desc_size != sizeof(struct ext2_gd))) { | ||||
printf("ext2fs: group descriptor size unsupported %d\n", | printf("ext2fs: group descriptor size unsupported %d\n", | ||||
es->e3fs_desc_size); | es->e3fs_desc_size); | ||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | if (EXT2_HAS_INCOMPAT_FEATURE(fs, EXT2F_INCOMPAT_64BIT)) { | ||||
g_count < fs->e2fs_gcount; j++, g_count++) | g_count < fs->e2fs_gcount; j++, g_count++) | ||||
memcpy(&fs->e2fs_gd[g_count], | memcpy(&fs->e2fs_gd[g_count], | ||||
bp->b_data + j * E2FS_REV0_GD_SIZE, | bp->b_data + j * E2FS_REV0_GD_SIZE, | ||||
E2FS_REV0_GD_SIZE); | E2FS_REV0_GD_SIZE); | ||||
} | } | ||||
brelse(bp); | brelse(bp); | ||||
bp = NULL; | bp = NULL; | ||||
} | } | ||||
/* Verify cg csum */ | /* Precompute checksum seed for all metadata */ | ||||
if (EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_GDT_CSUM)) { | ext2_sb_csum_set_seed(fs); | ||||
/* Verfy cg csum */ | |||||
if (EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_GDT_CSUM) || | |||||
EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_METADATA_CKSUM)) { | |||||
error = ext2_gd_csum_verify(fs, devvp->v_rdev); | error = ext2_gd_csum_verify(fs, devvp->v_rdev); | ||||
if (error) | if (error) | ||||
return (error); | return (error); | ||||
} | } | ||||
/* Initialization for the ext2 Orlov allocator variant. */ | /* Initialization for the ext2 Orlov allocator variant. */ | ||||
fs->e2fs_total_dir = 0; | fs->e2fs_total_dir = 0; | ||||
for (i = 0; i < fs->e2fs_gcount; i++) | for (i = 0; i < fs->e2fs_gcount; i++) | ||||
fs->e2fs_total_dir += fs->e2fs_gd[i].ext2bgd_ndirs; | fs->e2fs_total_dir += e2fs_gd_get_ndirs(&fs->e2fs_gd[i]); | ||||
if (es->e2fs_rev == E2FS_REV0 || | if (es->e2fs_rev == E2FS_REV0 || | ||||
!EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_LARGEFILE)) | !EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_LARGEFILE)) | ||||
fs->e2fs_maxfilesize = 0x7fffffff; | fs->e2fs_maxfilesize = 0x7fffffff; | ||||
else { | else { | ||||
fs->e2fs_maxfilesize = 0xffffffffffff; | fs->e2fs_maxfilesize = 0xffffffffffff; | ||||
if (EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_HUGE_FILE)) | if (EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_HUGE_FILE)) | ||||
fs->e2fs_maxfilesize = 0x7fffffffffffffff; | fs->e2fs_maxfilesize = 0x7fffffffffffffff; | ||||
} | } | ||||
if (es->e4fs_flags & E2FS_UNSIGNED_HASH) { | if (es->e4fs_flags & E2FS_UNSIGNED_HASH) { | ||||
fs->e2fs_uhash = 3; | fs->e2fs_uhash = 3; | ||||
} else if ((es->e4fs_flags & E2FS_SIGNED_HASH) == 0) { | } else if ((es->e4fs_flags & E2FS_SIGNED_HASH) == 0) { | ||||
#ifdef __CHAR_UNSIGNED__ | #ifdef __CHAR_UNSIGNED__ | ||||
es->e4fs_flags |= E2FS_UNSIGNED_HASH; | es->e4fs_flags |= E2FS_UNSIGNED_HASH; | ||||
fs->e2fs_uhash = 3; | fs->e2fs_uhash = 3; | ||||
#else | #else | ||||
es->e4fs_flags |= E2FS_SIGNED_HASH; | es->e4fs_flags |= E2FS_SIGNED_HASH; | ||||
#endif | #endif | ||||
} | } | ||||
if (EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_METADATA_CKSUM)) | |||||
error = ext2_sb_csum_verify(fs); | |||||
return (0); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* Reload all incore data for a filesystem (used after running fsck on | * Reload all incore data for a filesystem (used after running fsck on | ||||
* the root filesystem and finding things to fix). The filesystem must | * the root filesystem and finding things to fix). The filesystem must | ||||
* be mounted read-only. | * be mounted read-only. | ||||
* | * | ||||
* Things to do to update the mount: | * Things to do to update the mount: | ||||
▲ Show 20 Lines • Show All 516 Lines • ▼ Show 20 Lines | if ((error = bread(ump->um_devvp, fsbtodb(fs, ino_to_fsba(fs, ino)), | ||||
* list by vput(). | * list by vput(). | ||||
*/ | */ | ||||
brelse(bp); | brelse(bp); | ||||
vput(vp); | vput(vp); | ||||
*vpp = NULL; | *vpp = NULL; | ||||
return (error); | return (error); | ||||
} | } | ||||
/* convert ext2 inode to dinode */ | /* convert ext2 inode to dinode */ | ||||
ext2_ei2i((struct ext2fs_dinode *)((char *)bp->b_data + EXT2_INODE_SIZE(fs) * | error = ext2_ei2i((struct ext2fs_dinode *)((char *)bp->b_data + | ||||
ino_to_fsbo(fs, ino)), ip); | EXT2_INODE_SIZE(fs) * ino_to_fsbo(fs, ino)), ip); | ||||
if (error) { | |||||
printf("ext2fs: Bad inode %lu csum - run fsck\n", | |||||
(unsigned long)ino); | |||||
brelse(bp); | |||||
vput(vp); | |||||
*vpp = NULL; | |||||
return (error); | |||||
} | |||||
ip->i_block_group = ino_to_cg(fs, ino); | ip->i_block_group = ino_to_cg(fs, ino); | ||||
ip->i_next_alloc_block = 0; | ip->i_next_alloc_block = 0; | ||||
ip->i_next_alloc_goal = 0; | ip->i_next_alloc_goal = 0; | ||||
/* | /* | ||||
* Now we want to make sure that block pointers for unused | * Now we want to make sure that block pointers for unused | ||||
* blocks are zeroed out - ext2_balloc depends on this | * blocks are zeroed out - ext2_balloc depends on this | ||||
* although for regular files and directories only | * although for regular files and directories only | ||||
▲ Show 20 Lines • Show All 88 Lines • ▼ Show 20 Lines | ext2_sbupdate(struct ext2mount *mp, int waitfor) | ||||
es->e2fs_rbcount = fs->e2fs_rbcount & 0xffffffff; | es->e2fs_rbcount = fs->e2fs_rbcount & 0xffffffff; | ||||
es->e2fs_fbcount = fs->e2fs_fbcount & 0xffffffff; | es->e2fs_fbcount = fs->e2fs_fbcount & 0xffffffff; | ||||
if (EXT2_HAS_INCOMPAT_FEATURE(fs, EXT2F_INCOMPAT_64BIT)) { | if (EXT2_HAS_INCOMPAT_FEATURE(fs, EXT2F_INCOMPAT_64BIT)) { | ||||
es->e4fs_bcount_hi = fs->e2fs_bcount >> 32; | es->e4fs_bcount_hi = fs->e2fs_bcount >> 32; | ||||
es->e4fs_rbcount_hi = fs->e2fs_rbcount >> 32; | es->e4fs_rbcount_hi = fs->e2fs_rbcount >> 32; | ||||
es->e4fs_fbcount_hi = fs->e2fs_fbcount >> 32; | es->e4fs_fbcount_hi = fs->e2fs_fbcount >> 32; | ||||
} | } | ||||
if (EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_METADATA_CKSUM)) | |||||
ext2_sb_csum_set(fs); | |||||
bp = getblk(mp->um_devvp, SBLOCK, SBSIZE, 0, 0, 0); | bp = getblk(mp->um_devvp, SBLOCK, SBSIZE, 0, 0, 0); | ||||
bcopy((caddr_t)es, bp->b_data, (u_int)sizeof(struct ext2fs)); | bcopy((caddr_t)es, bp->b_data, (u_int)sizeof(struct ext2fs)); | ||||
if (waitfor == MNT_WAIT) | if (waitfor == MNT_WAIT) | ||||
error = bwrite(bp); | error = bwrite(bp); | ||||
else | else | ||||
bawrite(bp); | bawrite(bp); | ||||
/* | /* | ||||
* The buffers for group descriptors, inode bitmaps and block bitmaps | * The buffers for group descriptors, inode bitmaps and block bitmaps | ||||
* are not busy at this point and are (hopefully) written by the | * are not busy at this point and are (hopefully) written by the | ||||
* usual sync mechanism. No need to write them here. | * usual sync mechanism. No need to write them here. | ||||
*/ | */ | ||||
return (error); | return (error); | ||||
} | } | ||||
int | int | ||||
ext2_cgupdate(struct ext2mount *mp, int waitfor) | ext2_cgupdate(struct ext2mount *mp, int waitfor) | ||||
{ | { | ||||
struct m_ext2fs *fs = mp->um_e2fs; | struct m_ext2fs *fs = mp->um_e2fs; | ||||
struct buf *bp; | struct buf *bp; | ||||
int i, j, g_count = 0, error = 0, allerror = 0; | int i, j, g_count = 0, error = 0, allerror = 0; | ||||
allerror = ext2_sbupdate(mp, waitfor); | allerror = ext2_sbupdate(mp, waitfor); | ||||
/* Update gd csums */ | /* Update gd csums */ | ||||
if (EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_GDT_CSUM)) | if (EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_GDT_CSUM) || | ||||
EXT2_HAS_RO_COMPAT_FEATURE(fs, EXT2F_ROCOMPAT_METADATA_CKSUM)) | |||||
ext2_gd_csum_set(fs); | ext2_gd_csum_set(fs); | ||||
for (i = 0; i < fs->e2fs_gdbcount; i++) { | for (i = 0; i < fs->e2fs_gdbcount; i++) { | ||||
bp = getblk(mp->um_devvp, fsbtodb(fs, | bp = getblk(mp->um_devvp, fsbtodb(fs, | ||||
fs->e2fs->e2fs_first_dblock + | fs->e2fs->e2fs_first_dblock + | ||||
1 /* superblock */ + i), fs->e2fs_bsize, 0, 0, 0); | 1 /* superblock */ + i), fs->e2fs_bsize, 0, 0, 0); | ||||
if (EXT2_HAS_INCOMPAT_FEATURE(fs, EXT2F_INCOMPAT_64BIT)) { | if (EXT2_HAS_INCOMPAT_FEATURE(fs, EXT2F_INCOMPAT_64BIT)) { | ||||
memcpy(bp->b_data, &fs->e2fs_gd[ | memcpy(bp->b_data, &fs->e2fs_gd[ | ||||
Show All 34 Lines |