mirror of
https://github.com/versity/scoutfs.git
synced 2026-01-03 10:55:20 +00:00
scoutfs: add block read helper
Add a trivial helper function which verifies the block header in metadata blocks. Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
@@ -1,3 +1,3 @@
|
||||
obj-$(CONFIG_SCOUTFS_FS) := scoutfs.o
|
||||
|
||||
scoutfs-y += dir.o inode.o item.o msg.o super.o
|
||||
scoutfs-y += block.o dir.o inode.o item.o msg.o super.o
|
||||
|
||||
60
kmod/src/block.c
Normal file
60
kmod/src/block.c
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Versity Software, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License v2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*/
|
||||
#include <linux/buffer_head.h>
|
||||
|
||||
#include "super.h"
|
||||
#include "format.h"
|
||||
#include "block.h"
|
||||
#include "crc.h"
|
||||
|
||||
#define BH_Private_Verified BH_PrivateStart
|
||||
|
||||
BUFFER_FNS(Private_Verified, private_verified)
|
||||
|
||||
|
||||
/*
|
||||
* A quick metadata read wrapper which knows how to validate the
|
||||
* block header.
|
||||
*/
|
||||
struct buffer_head *scoutfs_read_block(struct super_block *sb, u64 blkno)
|
||||
{
|
||||
struct scoutfs_sb_info *sbi = SCOUTFS_SB(sb);
|
||||
struct scoutfs_super_block *super = &sbi->super;
|
||||
struct scoutfs_block_header *hdr;
|
||||
struct buffer_head *bh;
|
||||
u32 crc;
|
||||
|
||||
bh = sb_bread(sb, blkno);
|
||||
if (!bh || buffer_private_verified(bh))
|
||||
return bh;
|
||||
|
||||
hdr = (void *)bh->b_data;
|
||||
crc = scoutfs_crc_block(hdr);
|
||||
|
||||
if (le32_to_cpu(hdr->crc) != crc) {
|
||||
printk("blkno %llu hdr crc %x != calculated %x\n", blkno,
|
||||
le32_to_cpu(hdr->crc), crc);
|
||||
} else if (super->hdr.fsid && hdr->fsid != super->hdr.fsid) {
|
||||
printk("blkno %llu fsid %llx != super fsid %llx\n", blkno,
|
||||
le64_to_cpu(hdr->fsid), le64_to_cpu(super->hdr.fsid));
|
||||
} else if (le64_to_cpu(hdr->blkno) != blkno) {
|
||||
printk("blkno %llu invalid hdr blkno %llx\n", blkno,
|
||||
le64_to_cpu(hdr->blkno));
|
||||
} else {
|
||||
set_buffer_private_verified(bh);
|
||||
return bh;
|
||||
}
|
||||
|
||||
brelse(bh);
|
||||
return NULL;
|
||||
}
|
||||
6
kmod/src/block.h
Normal file
6
kmod/src/block.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#ifndef _SCOUTFS_BLOCK_H_
|
||||
#define _SCOUTFS_BLOCK_H_
|
||||
|
||||
struct buffer_head *scoutfs_read_block(struct super_block *sb, u64 blkno);
|
||||
|
||||
#endif
|
||||
22
kmod/src/crc.c
Normal file
22
kmod/src/crc.c
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Versity Software, Inc. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License v2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*/
|
||||
#include <linux/crc32c.h>
|
||||
|
||||
#include "format.h"
|
||||
#include "crc.h"
|
||||
|
||||
u32 scoutfs_crc_block(struct scoutfs_block_header *hdr)
|
||||
{
|
||||
return crc32c(~0, (char *)hdr + sizeof(hdr->crc),
|
||||
SCOUTFS_BLOCK_SIZE - sizeof(hdr->crc));
|
||||
}
|
||||
6
kmod/src/crc.h
Normal file
6
kmod/src/crc.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#ifndef _SCOUTFS_CRC_H_
|
||||
#define _SCOUTFS_CRC_H_
|
||||
|
||||
u32 scoutfs_crc_block(struct scoutfs_block_header *hdr);
|
||||
|
||||
#endif
|
||||
@@ -16,7 +16,6 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/magic.h>
|
||||
#include <linux/buffer_head.h>
|
||||
#include <linux/crc32c.h>
|
||||
#include <linux/random.h>
|
||||
|
||||
#include "super.h"
|
||||
@@ -24,6 +23,7 @@
|
||||
#include "inode.h"
|
||||
#include "dir.h"
|
||||
#include "msg.h"
|
||||
#include "block.h"
|
||||
|
||||
static const struct super_operations scoutfs_super_ops = {
|
||||
.alloc_inode = scoutfs_alloc_inode,
|
||||
@@ -36,13 +36,12 @@ static int read_supers(struct super_block *sb)
|
||||
struct scoutfs_super_block *super;
|
||||
struct buffer_head *bh = NULL;
|
||||
int found = -1;
|
||||
u32 crc;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < SCOUTFS_SUPER_NR; i++) {
|
||||
if (bh)
|
||||
brelse(bh);
|
||||
bh = sb_bread(sb, SCOUTFS_SUPER_BLKNO + i);
|
||||
bh = scoutfs_read_block(sb, SCOUTFS_SUPER_BLKNO + i);
|
||||
if (!bh) {
|
||||
scoutfs_warn(sb, "couldn't read super block %u", i);
|
||||
continue;
|
||||
@@ -56,14 +55,6 @@ static int read_supers(struct super_block *sb)
|
||||
continue;
|
||||
}
|
||||
|
||||
crc = crc32c(~0, (char *)&super->hdr.crc + sizeof(crc),
|
||||
SCOUTFS_BLOCK_SIZE - sizeof(crc));
|
||||
if (crc != le32_to_cpu(super->hdr.crc)) {
|
||||
scoutfs_warn(sb, "super block %u has bad crc %x (expected %x)",
|
||||
i, crc, le32_to_cpu(super->hdr.crc));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (found < 0 || (le64_to_cpu(super->hdr.seq) >
|
||||
le64_to_cpu(sbi->super.hdr.seq))) {
|
||||
memcpy(&sbi->super, super,
|
||||
|
||||
Reference in New Issue
Block a user