Read super brick instead of mkfs

Now that we have a working userspace mkfs we can read the supers on
mount instead of always initializing a new file system.  We still don't
know how to read items from blocks so mount fails when it can't find the
root dir inode.

Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
Zach Brown
2016-02-12 19:37:48 -08:00
parent 82ec91d1e0
commit 3483133cdf
5 changed files with 81 additions and 61 deletions

View File

@@ -1,3 +1,3 @@
obj-$(CONFIG_SCOUTFS_FS) := scoutfs.o
scoutfs-y += dir.o inode.o item.o lsm.o mkfs.o super.o
scoutfs-y += dir.o inode.o item.o lsm.o msg.o super.o

View File

@@ -1,52 +0,0 @@
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/time.h>
#include <linux/random.h>
#include "super.h"
#include "item.h"
#include "key.h"
#include "mkfs.h"
/*
* For now a file system system only exists in the item cache for the
* duration of the mount. This "mkfs" hack creates a root dir inode in
* the item cache on mount so that we can run tests in memory and not
* worry about user space or persistent storage.
*/
int scoutfs_mkfs(struct super_block *sb)
{
const struct timespec ts = current_kernel_time();
struct scoutfs_sb_info *sbi = SCOUTFS_SB(sb);
struct scoutfs_inode *cinode;
struct scoutfs_item *item;
struct scoutfs_key key;
int i;
atomic64_set(&sbi->next_ino, SCOUTFS_ROOT_INO + 1);
atomic64_set(&sbi->next_blkno, 2);
for (i = 0; i < ARRAY_SIZE(sbi->bloom_hash_keys); i++) {
get_random_bytes(&sbi->bloom_hash_keys[i],
sizeof(sbi->bloom_hash_keys[i]));
}
scoutfs_set_key(&key, SCOUTFS_ROOT_INO, SCOUTFS_INODE_KEY, 0);
item = scoutfs_item_create(sb, &key, sizeof(struct scoutfs_inode));
if (IS_ERR(item))
return PTR_ERR(item);
cinode = item->val;
memset(cinode, 0, sizeof(struct scoutfs_inode));
cinode->nlink = cpu_to_le32(2);
cinode->mode = cpu_to_le32(S_IFDIR | 0755);
cinode->atime.sec = cpu_to_le64(ts.tv_sec);
cinode->atime.nsec = cpu_to_le32(ts.tv_nsec);
cinode->ctime = cinode->atime;
cinode->mtime = cinode->atime;
get_random_bytes(&cinode->salt, sizeof(cinode->salt));
scoutfs_item_put(item);
return 0;
}

View File

@@ -1,6 +0,0 @@
#ifndef _SCOUTFS_MKFS_H_
#define _SCOUTFS_MKFS_H_
int scoutfs_mkfs(struct super_block *sb);
#endif

View File

@@ -15,13 +15,16 @@
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/magic.h>
#include <linux/buffer_head.h>
#include <linux/crc32c.h>
#include <linux/random.h>
#include "super.h"
#include "format.h"
#include "mkfs.h"
#include "inode.h"
#include "dir.h"
#include "lsm.h"
#include "msg.h"
static const struct super_operations scoutfs_super_ops = {
.alloc_inode = scoutfs_alloc_inode,
@@ -29,6 +32,73 @@ static const struct super_operations scoutfs_super_ops = {
.sync_fs = scoutfs_sync_fs,
};
static int read_supers(struct super_block *sb)
{
struct scoutfs_sb_info *sbi = SCOUTFS_SB(sb);
struct buffer_head *bh = NULL;
struct scoutfs_super *super;
int found = -1;
u32 crc;
int i;
for (i = 0; i < 2; i++) {
if (bh)
brelse(bh);
bh = sb_bread(sb, SCOUTFS_SUPER_BRICK + i);
if (!bh) {
scoutfs_warn(sb, "couldn't read super brick %u", i);
continue;
}
super = (void *)bh->b_data;
if (super->id != cpu_to_le64(SCOUTFS_SUPER_ID)) {
scoutfs_warn(sb, "super brick %u has invalid id %llx",
i, le64_to_cpu(super->id));
continue;
}
crc = crc32c(~0, (char *)&super->hdr.crc + sizeof(crc),
SCOUTFS_BRICK_SIZE - sizeof(crc));
if (crc != le32_to_cpu(super->hdr.crc)) {
scoutfs_warn(sb, "super brick %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,
sizeof(struct scoutfs_super));
found = i;
}
}
if (bh)
brelse(bh);
if (found < 0) {
scoutfs_err(sb, "unable to read valid super brick");
return -EINVAL;
}
scoutfs_info(sb, "using super %u with seq %llu",
found, le64_to_cpu(sbi->super.hdr.seq));
/*
* XXX These don't exist in the super yet. They should soon.
*/
atomic64_set(&sbi->next_ino, SCOUTFS_ROOT_INO + 1);
atomic64_set(&sbi->next_blkno, 2);
for (i = 0; i < ARRAY_SIZE(sbi->bloom_hash_keys); i++) {
get_random_bytes(&sbi->bloom_hash_keys[i],
sizeof(sbi->bloom_hash_keys[i]));
}
return 0;
}
static int scoutfs_fill_super(struct super_block *sb, void *data, int silent)
{
struct scoutfs_sb_info *sbi;
@@ -48,7 +118,12 @@ static int scoutfs_fill_super(struct super_block *sb, void *data, int silent)
sbi->item_root = RB_ROOT;
sbi->dirty_item_root = RB_ROOT;
ret = scoutfs_mkfs(sb);
if (!sb_set_blocksize(sb, SCOUTFS_BRICK_SIZE)) {
printk(KERN_ERR "couldn't set blocksize\n");
return -EINVAL;
}
ret = read_supers(sb);
if (ret)
return ret;

View File

@@ -2,8 +2,11 @@
#define _SCOUTFS_SUPER_H_
#include <linux/rbtree.h>
#include "format.h"
struct scoutfs_sb_info {
struct scoutfs_super super;
atomic64_t next_ino;
atomic64_t next_blkno;