mirror of
https://github.com/versity/scoutfs.git
synced 2026-06-09 13:12:35 +00:00
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:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
#ifndef _SCOUTFS_MKFS_H_
|
||||
#define _SCOUTFS_MKFS_H_
|
||||
|
||||
int scoutfs_mkfs(struct super_block *sb);
|
||||
|
||||
#endif
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user