diff --git a/mkfs-simplefs.c b/mkfs-simplefs.c index 44a8955..b75a651 100644 --- a/mkfs-simplefs.c +++ b/mkfs-simplefs.c @@ -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)) diff --git a/simple.c b/simple.c index 53c384a..7b1e2a8 100644 --- a/simple.c +++ b/simple.c @@ -14,6 +14,7 @@ #include #include #include +#include #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); diff --git a/simple.h b/simple.h index e7f1f96..a6e7aa1 100644 --- a/simple.h +++ b/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]; };