Initial support of journaling

- 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)
This commit is contained in:
Azat Khuzhin 2014-07-13 00:00:36 +04:00
parent 072ef5bff6
commit dad5b1c50e
3 changed files with 125 additions and 38 deletions

View File

@ -9,8 +9,8 @@
#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)
{
@ -18,10 +18,9 @@ static int write_superblock(int fd)
.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;
@ -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;
@ -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;
static int write_inode(int fd, const struct simplefs_inode *i)
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;
}
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;
@ -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
@ -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;
@ -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))

View File

@ -14,6 +14,7 @@
#include <linux/slab.h>
#include <linux/random.h>
#include <linux/version.h>
#include <linux/jbd2.h>
#include "super.h"
@ -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)
{
@ -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;
}
@ -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)
@ -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);

View File

@ -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
@ -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 */
@ -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;
@ -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];
};