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:
Zach Brown
2016-02-23 21:13:56 -08:00
parent 71df879f07
commit 28521e8c45
6 changed files with 97 additions and 12 deletions

View File

@@ -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
View 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
View 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
View 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
View File

@@ -0,0 +1,6 @@
#ifndef _SCOUTFS_CRC_H_
#define _SCOUTFS_CRC_H_
u32 scoutfs_crc_block(struct scoutfs_block_header *hdr);
#endif

View File

@@ -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,