Skip to content

Commit

Permalink
Initial support of journaling
Browse files Browse the repository at this point in the history
- Reorder block numbers to make it more sequental for mkfs
- mkfs: adjust writing, to make it correct write journal blocks and ino too
- simplefs_iget: use fops for journal inode
- simplefs_iget: check sfs_inode->mode instead of i_mode (not initialized yet)
  • Loading branch information
azat committed Oct 1, 2014
1 parent 072ef5b commit dad5b1c
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 38 deletions.
59 changes: 48 additions & 11 deletions mkfs-simplefs.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,18 @@

#include "simple.h"

const uint64_t WELCOMEFILE_DATABLOCK_NUMBER = 3;
const uint64_t WELCOMEFILE_INODE_NUMBER = 2;
#define WELCOMEFILE_DATABLOCK_NUMBER (SIMPLEFS_LAST_RESERVED_BLOCK + 1)
#define WELCOMEFILE_INODE_NUMBER (SIMPLEFS_LAST_RESERVED_INODE + 1)

static int write_superblock(int fd)
{
struct simplefs_super_block sb = {
.version = 1,
.magic = SIMPLEFS_MAGIC,
.block_size = SIMPLEFS_DEFAULT_BLOCK_SIZE,
/* One inode for rootdirectory and another for a welcome file that we are going to create */
.inodes_count = 2,
.inodes_count = WELCOMEFILE_INODE_NUMBER,
/* FIXME: Free blocks management is not implemented yet */
.free_blocks = (~0) & ~(1 << WELCOMEFILE_DATABLOCK_NUMBER),
.free_blocks = (~0) & ~(1 << SIMPLEFS_LAST_RESERVED_BLOCK),
};
ssize_t ret;

Expand All @@ -37,7 +36,7 @@ static int write_superblock(int fd)
return 0;
}

static int write_inode_store(int fd)
static int write_root_inode(int fd)
{
ssize_t ret;

Expand All @@ -59,8 +58,26 @@ static int write_inode_store(int fd)
printf("root directory inode written succesfully\n");
return 0;
}
static int write_journal_inode(int fd)
{
ssize_t ret;

struct simplefs_inode journal;

journal.inode_no = SIMPLEFS_JOURNAL_INODE_NUMBER;
journal.data_block_number = SIMPLEFS_JOURNAL_BLOCK_NUMBER;

ret = write(fd, &journal, sizeof(journal));

if (ret != sizeof(journal)) {
printf("Error while writing journal inode. Retry your mkfs\n");
return -1;
}

static int write_inode(int fd, const struct simplefs_inode *i)
printf("journal inode written succesfully\n");
return 0;
}
static int write_welcome_inode(int fd, const struct simplefs_inode *i)
{
off_t nbytes;
ssize_t ret;
Expand All @@ -73,7 +90,7 @@ static int write_inode(int fd, const struct simplefs_inode *i)
}
printf("welcomefile inode written succesfully\n");

nbytes = SIMPLEFS_DEFAULT_BLOCK_SIZE - sizeof(*i) - sizeof(*i);
nbytes = SIMPLEFS_DEFAULT_BLOCK_SIZE - (sizeof(*i) * 3);
ret = lseek(fd, nbytes, SEEK_CUR);
if (ret == (off_t)-1) {
printf
Expand All @@ -82,9 +99,23 @@ static int write_inode(int fd, const struct simplefs_inode *i)
}

printf
("inode store padding bytes (after the two inodes) written sucessfully\n");
("inode store padding bytes (after the three inodes) written sucessfully\n");
return 0;
}

int write_journal(int fd)
{
ssize_t ret;
ret = lseek(fd, SIMPLEFS_DEFAULT_BLOCK_SIZE * SIMPLEFS_JOURNAL_BLOCKS, SEEK_CUR);
if (ret == (off_t)-1) {
printf("Can't write journal. Retry you mkfs\n");
return -1;
}

printf("Journal written successfully\n");
return 0;
}

int write_dirent(int fd, const struct simplefs_dir_record *record)
{
ssize_t nbytes = sizeof(*record), ret;
Expand Down Expand Up @@ -154,11 +185,17 @@ int main(int argc, char *argv[])
do {
if (write_superblock(fd))
break;
if (write_inode_store(fd))

if (write_root_inode(fd))
break;
if (write_journal_inode(fd))
break;
if (write_welcome_inode(fd, &welcome))
break;

if (write_inode(fd, &welcome))
if (write_journal(fd))
break;

if (write_dirent(fd, &record))
break;
if (write_block(fd, welcomefile_body, welcome.file_size))
Expand Down
85 changes: 60 additions & 25 deletions simple.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <linux/slab.h>
#include <linux/random.h>
#include <linux/version.h>
#include <linux/jbd2.h>

#include "super.h"

Expand Down Expand Up @@ -584,6 +585,35 @@ static int simplefs_create(struct inode *dir, struct dentry *dentry,
return simplefs_create_fs_object(dir, dentry, mode);
}

static struct inode *simplefs_iget(struct super_block *sb, int ino)
{
struct inode *inode;
struct simplefs_inode *sfs_inode;

sfs_inode = simplefs_get_inode(sb, ino);

inode = new_inode(sb);
inode->i_ino = ino;
inode->i_sb = sb;
inode->i_op = &simplefs_inode_ops;

if (S_ISDIR(sfs_inode->mode))
inode->i_fop = &simplefs_dir_operations;
else if (S_ISREG(sfs_inode->mode) || ino == SIMPLEFS_JOURNAL_INODE_NUMBER)
inode->i_fop = &simplefs_file_operations;
else
printk(KERN_ERR
"Unknown inode type. Neither a directory nor a file");

/* FIXME: We should store these times to disk and retrieve them */
inode->i_atime = inode->i_mtime = inode->i_ctime =
CURRENT_TIME;

inode->i_private = sfs_inode;

return inode;
}

struct dentry *simplefs_lookup(struct inode *parent_inode,
struct dentry *child_dentry, unsigned int flags)
{
Expand All @@ -605,31 +635,8 @@ struct dentry *simplefs_lookup(struct inode *parent_inode,
* with the filename that we are comparing above, then we
* will use an invalid uninitialized inode */

struct inode *inode;
struct simplefs_inode *sfs_inode;

sfs_inode = simplefs_get_inode(sb, record->inode_no);

inode = new_inode(sb);
inode->i_ino = record->inode_no;
inode_init_owner(inode, parent_inode, sfs_inode->mode);
inode->i_sb = sb;
inode->i_op = &simplefs_inode_ops;

if (S_ISDIR(inode->i_mode))
inode->i_fop = &simplefs_dir_operations;
else if (S_ISREG(inode->i_mode))
inode->i_fop = &simplefs_file_operations;
else
printk(KERN_ERR
"Unknown inode type. Neither a directory nor a file");

/* FIXME: We should store these times to disk and retrieve them */
inode->i_atime = inode->i_mtime = inode->i_ctime =
CURRENT_TIME;

inode->i_private = sfs_inode;

struct inode *inode = simplefs_iget(sb, record->inode_no);
inode_init_owner(inode, parent_inode, SIMPLEFS_INODE(inode)->mode);
d_add(child_dentry, inode);
return NULL;
}
Expand All @@ -656,10 +663,35 @@ void simplefs_destory_inode(struct inode *inode)
kmem_cache_free(sfs_inode_cachep, sfs_inode);
}

static void simplefs_put_super(struct super_block *sb)
{
struct simplefs_super_block *sfs_sb = SIMPLEFS_SB(sb);
if (sfs_sb->journal)
WARN_ON(jbd2_journal_destroy(sfs_sb->journal) < 0);
sfs_sb->journal = NULL;
}

static const struct super_operations simplefs_sops = {
.destroy_inode = simplefs_destory_inode,
.put_super = simplefs_put_super,
};

static int simplefs_load_journal(struct super_block *sb)
{
struct journal_s *journal;
struct inode *inode;
struct simplefs_super_block *sfs_sb = SIMPLEFS_SB(sb);

inode = simplefs_iget(sb, SIMPLEFS_JOURNAL_INODE_NUMBER);

journal = jbd2_journal_init_inode(inode);
journal->j_private = sb;

sfs_sb->journal = journal;

return 0;
}

/* This function, as the name implies, Makes the super_block valid and
* fills filesystem specific information in the super block */
int simplefs_fill_super(struct super_block *sb, void *data, int silent)
Expand Down Expand Up @@ -728,6 +760,9 @@ int simplefs_fill_super(struct super_block *sb, void *data, int silent)
goto release;
}

if ((ret = simplefs_load_journal(sb)))
goto release;

ret = 0;
release:
brelse(bh);
Expand Down
19 changes: 17 additions & 2 deletions simple.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@


#define SIMPLEFS_MAGIC 0x10032013
#define SIMPLEFS_JOURNAL_MAGIC = 0x20032013

#define SIMPLEFS_DEFAULT_BLOCK_SIZE 4096
#define SIMPLEFS_FILENAME_MAXLEN 255
#define SIMPLEFS_START_INO 10
Expand Down Expand Up @@ -32,9 +34,17 @@ const int SIMPLEFS_SUPERBLOCK_BLOCK_NUMBER = 0;
/* The disk block where the inodes are stored */
const int SIMPLEFS_INODESTORE_BLOCK_NUMBER = 1;

/** Journal settings */
const int SIMPLEFS_JOURNAL_INODE_NUMBER = 2;
const int SIMPLEFS_JOURNAL_BLOCK_NUMBER = 2;
const int SIMPLEFS_JOURNAL_BLOCKS = 2;

/* The disk block where the name+inode_number pairs of the
* contents of the root directory are stored */
const int SIMPLEFS_ROOTDIR_DATABLOCK_NUMBER = 2;
const int SIMPLEFS_ROOTDIR_DATABLOCK_NUMBER = 4;

#define SIMPLEFS_LAST_RESERVED_BLOCK SIMPLEFS_ROOTDIR_DATABLOCK_NUMBER
#define SIMPLEFS_LAST_RESERVED_INODE SIMPLEFS_JOURNAL_INODE_NUMBER

/* The name+inode_number pair for each file in a directory.
* This gets stored as the data for a directory */
Expand Down Expand Up @@ -63,6 +73,8 @@ const int SIMPLEFS_MAX_FILESYSTEM_OBJECTS_SUPPORTED = 64;
/* FIXME: Move the struct to its own file and not expose the members
* Always access using the simplefs_sb_* functions and
* do not access the members directly */

struct journal_s;
struct simplefs_super_block {
uint64_t version;
uint64_t magic;
Expand All @@ -73,5 +85,8 @@ struct simplefs_super_block {

uint64_t free_blocks;

char padding[SIMPLEFS_DEFAULT_BLOCK_SIZE - (5 * sizeof(uint64_t))];
/** FIXME: move this into separate struct */
struct journal_s *journal;

char padding[4048];
};

0 comments on commit dad5b1c

Please sign in to comment.