mirror of
https://github.com/psankar/simplefs.git
synced 2025-07-16 10:34:32 +02:00
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:
parent
072ef5bff6
commit
dad5b1c50e
@ -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))
|
||||
|
85
simple.c
85
simple.c
@ -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);
|
||||
|
19
simple.h
19
simple.h
@ -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];
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user