Changeset View
Changeset View
Standalone View
Standalone View
head/sys/fs/ext2fs/ext2_csum.c
Show All 25 Lines | |||||
* SUCH DAMAGE. | * SUCH DAMAGE. | ||||
* | * | ||||
* $FreeBSD$ | * $FreeBSD$ | ||||
*/ | */ | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/systm.h> | #include <sys/systm.h> | ||||
#include <sys/types.h> | #include <sys/types.h> | ||||
#include <sys/sdt.h> | |||||
#include <sys/stat.h> | #include <sys/stat.h> | ||||
#include <sys/kernel.h> | #include <sys/kernel.h> | ||||
#include <sys/malloc.h> | #include <sys/malloc.h> | ||||
#include <sys/vnode.h> | #include <sys/vnode.h> | ||||
#include <sys/bio.h> | #include <sys/bio.h> | ||||
#include <sys/buf.h> | #include <sys/buf.h> | ||||
#include <sys/endian.h> | #include <sys/endian.h> | ||||
#include <sys/conf.h> | #include <sys/conf.h> | ||||
#include <sys/mount.h> | #include <sys/mount.h> | ||||
#include <fs/ext2fs/fs.h> | #include <fs/ext2fs/fs.h> | ||||
#include <fs/ext2fs/ext2fs.h> | #include <fs/ext2fs/ext2fs.h> | ||||
#include <fs/ext2fs/ext2_dinode.h> | #include <fs/ext2fs/ext2_dinode.h> | ||||
#include <fs/ext2fs/inode.h> | #include <fs/ext2fs/inode.h> | ||||
#include <fs/ext2fs/ext2_dir.h> | #include <fs/ext2fs/ext2_dir.h> | ||||
#include <fs/ext2fs/htree.h> | #include <fs/ext2fs/htree.h> | ||||
#include <fs/ext2fs/ext2_extattr.h> | #include <fs/ext2fs/ext2_extattr.h> | ||||
#include <fs/ext2fs/ext2_extern.h> | #include <fs/ext2fs/ext2_extern.h> | ||||
SDT_PROVIDER_DECLARE(ext2fs); | |||||
/* | |||||
* ext2fs trace probe: | |||||
* arg0: verbosity. Higher numbers give more verbose messages | |||||
* arg1: Textual message | |||||
*/ | |||||
SDT_PROBE_DEFINE2(ext2fs, , trace, csum, "int", "char*"); | |||||
#define EXT2_BG_INODE_BITMAP_CSUM_HI_END \ | #define EXT2_BG_INODE_BITMAP_CSUM_HI_END \ | ||||
(offsetof(struct ext2_gd, ext4bgd_i_bmap_csum_hi) + \ | (offsetof(struct ext2_gd, ext4bgd_i_bmap_csum_hi) + \ | ||||
sizeof(uint16_t)) | sizeof(uint16_t)) | ||||
#define EXT2_INODE_CSUM_HI_EXTRA_END \ | #define EXT2_INODE_CSUM_HI_EXTRA_END \ | ||||
(offsetof(struct ext2fs_dinode, e2di_chksum_hi) + sizeof(uint16_t) - \ | (offsetof(struct ext2fs_dinode, e2di_chksum_hi) + sizeof(uint16_t) - \ | ||||
E2FS_REV0_INODE_SIZE) | E2FS_REV0_INODE_SIZE) | ||||
▲ Show 20 Lines • Show All 68 Lines • ▼ Show 20 Lines | |||||
ext2_extattr_blk_csum_verify(struct inode *ip, struct buf *bp) | ext2_extattr_blk_csum_verify(struct inode *ip, struct buf *bp) | ||||
{ | { | ||||
struct ext2fs_extattr_header *header; | struct ext2fs_extattr_header *header; | ||||
header = (struct ext2fs_extattr_header *)bp->b_data; | header = (struct ext2fs_extattr_header *)bp->b_data; | ||||
if (EXT2_HAS_RO_COMPAT_FEATURE(ip->i_e2fs, EXT2F_ROCOMPAT_METADATA_CKSUM) && | if (EXT2_HAS_RO_COMPAT_FEATURE(ip->i_e2fs, EXT2F_ROCOMPAT_METADATA_CKSUM) && | ||||
(header->h_checksum != ext2_extattr_blk_csum(ip, ip->i_facl, header))) { | (header->h_checksum != ext2_extattr_blk_csum(ip, ip->i_facl, header))) { | ||||
printf("WARNING: bad extattr csum detected, ip=%lu - run fsck\n", | SDT_PROBE2(ext2fs, , trace, csum, 1, "bad extattr csum detected"); | ||||
(unsigned long)ip->i_number); | |||||
return (EIO); | return (EIO); | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
void | void | ||||
ext2_extattr_blk_csum_set(struct inode *ip, struct buf *bp) | ext2_extattr_blk_csum_set(struct inode *ip, struct buf *bp) | ||||
▲ Show 20 Lines • Show All 199 Lines • ▼ Show 20 Lines | ext2_dir_blk_csum_verify(struct inode *ip, struct buf *bp) | ||||
ep = (struct ext2fs_direct_2 *)bp->b_data; | ep = (struct ext2fs_direct_2 *)bp->b_data; | ||||
if (ext2_dirent_get_tail(ip, ep) != NULL) | if (ext2_dirent_get_tail(ip, ep) != NULL) | ||||
error = ext2_dirent_csum_verify(ip, ep); | error = ext2_dirent_csum_verify(ip, ep); | ||||
else if (ext2_get_dx_count(ip, ep, NULL) != NULL) | else if (ext2_get_dx_count(ip, ep, NULL) != NULL) | ||||
error = ext2_dx_csum_verify(ip, ep); | error = ext2_dx_csum_verify(ip, ep); | ||||
if (error) | if (error) | ||||
printf("WARNING: bad directory csum detected, ip=%lu" | SDT_PROBE2(ext2fs, , trace, csum, 1, "bad directory csum detected"); | ||||
" - run fsck\n", (unsigned long)ip->i_number); | |||||
return (error); | return (error); | ||||
} | } | ||||
void | void | ||||
ext2_dirent_csum_set(struct inode *ip, struct ext2fs_direct_2 *ep) | ext2_dirent_csum_set(struct inode *ip, struct ext2fs_direct_2 *ep) | ||||
{ | { | ||||
struct m_ext2fs *fs; | struct m_ext2fs *fs; | ||||
▲ Show 20 Lines • Show All 76 Lines • ▼ Show 20 Lines | ext2_extent_blk_csum_verify(struct inode *ip, void *data) | ||||
ehp = (struct ext4_extent_header *)data; | ehp = (struct ext4_extent_header *)data; | ||||
etp = (struct ext4_extent_tail *)(((char *)ehp) + | etp = (struct ext4_extent_tail *)(((char *)ehp) + | ||||
EXT4_EXTENT_TAIL_OFFSET(ehp)); | EXT4_EXTENT_TAIL_OFFSET(ehp)); | ||||
provided = etp->et_checksum; | provided = etp->et_checksum; | ||||
calculated = ext2_extent_blk_csum(ip, ehp); | calculated = ext2_extent_blk_csum(ip, ehp); | ||||
if (provided != calculated) { | if (provided != calculated) { | ||||
printf("WARNING: bad extent csum detected, ip=%lu - run fsck\n", | SDT_PROBE2(ext2fs, , trace, csum, 1, "bad extent csum detected"); | ||||
(unsigned long)ip->i_number); | |||||
return (EIO); | return (EIO); | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
void | void | ||||
ext2_extent_blk_csum_set(struct inode *ip, void *data) | ext2_extent_blk_csum_set(struct inode *ip, void *data) | ||||
Show All 28 Lines | calculated = calculate_crc32c(fs->e2fs_csum_seed, bp->b_data, | ||||
fs->e2fs->e2fs_ipg / 8); | fs->e2fs->e2fs_ipg / 8); | ||||
if (fs->e2fs->e3fs_desc_size >= EXT2_BG_INODE_BITMAP_CSUM_HI_END) { | if (fs->e2fs->e3fs_desc_size >= EXT2_BG_INODE_BITMAP_CSUM_HI_END) { | ||||
hi = fs->e2fs_gd[cg].ext4bgd_i_bmap_csum_hi; | hi = fs->e2fs_gd[cg].ext4bgd_i_bmap_csum_hi; | ||||
provided |= (hi << 16); | provided |= (hi << 16); | ||||
} else | } else | ||||
calculated &= 0xFFFF; | calculated &= 0xFFFF; | ||||
if (provided != calculated) { | if (provided != calculated) { | ||||
printf("WARNING: bad inode bitmap csum detected, " | SDT_PROBE2(ext2fs, , trace, csum, 1, "bad inode bitmap csum detected"); | ||||
"cg=%d - run fsck\n", cg); | |||||
return (EIO); | return (EIO); | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
void | void | ||||
ext2_gd_i_bitmap_csum_set(struct m_ext2fs *fs, int cg, struct buf *bp) | ext2_gd_i_bitmap_csum_set(struct m_ext2fs *fs, int cg, struct buf *bp) | ||||
Show All 23 Lines | ext2_gd_b_bitmap_csum_verify(struct m_ext2fs *fs, int cg, struct buf *bp) | ||||
calculated = calculate_crc32c(fs->e2fs_csum_seed, bp->b_data, size); | calculated = calculate_crc32c(fs->e2fs_csum_seed, bp->b_data, size); | ||||
if (fs->e2fs->e3fs_desc_size >= EXT2_BG_BLOCK_BITMAP_CSUM_HI_LOCATION) { | if (fs->e2fs->e3fs_desc_size >= EXT2_BG_BLOCK_BITMAP_CSUM_HI_LOCATION) { | ||||
hi = fs->e2fs_gd[cg].ext4bgd_b_bmap_csum_hi; | hi = fs->e2fs_gd[cg].ext4bgd_b_bmap_csum_hi; | ||||
provided |= (hi << 16); | provided |= (hi << 16); | ||||
} else | } else | ||||
calculated &= 0xFFFF; | calculated &= 0xFFFF; | ||||
if (provided != calculated) { | if (provided != calculated) { | ||||
printf("WARNING: bad block bitmap csum detected, " | SDT_PROBE2(ext2fs, , trace, csum, 1, "bad block bitmap csum detected"); | ||||
"cg=%d - run fsck\n", cg); | |||||
return (EIO); | return (EIO); | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
void | void | ||||
ext2_gd_b_bitmap_csum_set(struct m_ext2fs *fs, int cg, struct buf *bp) | ext2_gd_b_bitmap_csum_set(struct m_ext2fs *fs, int cg, struct buf *bp) | ||||
▲ Show 20 Lines • Show All 79 Lines • ▼ Show 20 Lines | if (provided != calculated) { | ||||
/* | /* | ||||
* If it is first time used dinode, | * If it is first time used dinode, | ||||
* it is expected that it will be zeroed | * it is expected that it will be zeroed | ||||
* and we will not return checksum error in this case. | * and we will not return checksum error in this case. | ||||
*/ | */ | ||||
if (!memcmp(ei, &ei_zero, sizeof(struct ext2fs_dinode))) | if (!memcmp(ei, &ei_zero, sizeof(struct ext2fs_dinode))) | ||||
return (0); | return (0); | ||||
printf("WARNING: Bad inode %ju csum - run fsck\n", ip->i_number); | SDT_PROBE2(ext2fs, , trace, csum, 1, "bad inode csum"); | ||||
return (EIO); | return (EIO); | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
void | void | ||||
▲ Show 20 Lines • Show All 134 Lines • Show Last 20 Lines |