mirror of
https://github.com/psankar/simplefs.git
synced 2025-07-23 22:15:03 +02:00
Create and retrieve the rootdir inode from the inode store instead of the super block
This commit is contained in:
parent
f2ae6c1536
commit
ec223623dc
@ -12,6 +12,7 @@ int main(int argc, char *argv[])
|
||||
int fd;
|
||||
ssize_t ret;
|
||||
struct simplefs_super_block sb;
|
||||
struct simplefs_inode root_inode;
|
||||
|
||||
if (argc != 2) {
|
||||
printf("Usage: mkfs-simplefs <device>\n");
|
||||
@ -27,24 +28,39 @@ int main(int argc, char *argv[])
|
||||
sb.version = 1;
|
||||
sb.magic = SIMPLEFS_MAGIC;
|
||||
sb.block_size = SIMPLEFS_DEFAULT_BLOCK_SIZE;
|
||||
sb.free_blocks = ~0;
|
||||
|
||||
sb.root_inode.mode = S_IFDIR;
|
||||
sb.root_inode.inode_no = SIMPLEFS_ROOT_INODE_NUMBER;
|
||||
sb.root_inode.data_block_number = SIMPLEFS_ROOTDIR_DATABLOCK_NUMBER;
|
||||
sb.root_inode.dir_children_count = 0;
|
||||
/* Only the root dir will have an inode now */
|
||||
sb.inodes_count = 1;
|
||||
sb.free_blocks = ~0;
|
||||
|
||||
ret = write(fd, (char *)&sb, sizeof(sb));
|
||||
|
||||
/* Just a redundant check. Not required ideally. */
|
||||
if (ret != SIMPLEFS_DEFAULT_BLOCK_SIZE)
|
||||
if (ret != SIMPLEFS_DEFAULT_BLOCK_SIZE) {
|
||||
printf
|
||||
("bytes written [%d] are not equal to the default block size\n",
|
||||
(int)ret);
|
||||
else
|
||||
printf("Super block written succesfully\n");
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
printf("Super block written succesfully\n");
|
||||
|
||||
root_inode.mode = S_IFDIR;
|
||||
root_inode.inode_no = SIMPLEFS_ROOTDIR_INODE_NUMBER;
|
||||
root_inode.data_block_number = SIMPLEFS_ROOTDIR_DATABLOCK_NUMBER;
|
||||
root_inode.dir_children_count = 0;
|
||||
|
||||
ret = write(fd, (char *)&root_inode, sizeof(root_inode));
|
||||
|
||||
if (ret != sizeof(root_inode)) {
|
||||
printf("The inode store was not written properly. Retry your mkfs\n");
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
printf("inode store written succesfully\n");
|
||||
ret = 0;
|
||||
|
||||
exit:
|
||||
close(fd);
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
59
simple.c
59
simple.c
@ -28,7 +28,7 @@ static int simplefs_readdir(struct file *filp, void *dirent, filldir_t filldir)
|
||||
sfs_inode = inode->i_private;
|
||||
|
||||
if (unlikely(!S_ISDIR(sfs_inode->mode))) {
|
||||
printk(KERN_ERR "inode %u not a directory", sfs_inode->inode_no);
|
||||
printk(KERN_ERR "inode %llu not a directory", sfs_inode->inode_no);
|
||||
return -ENOTDIR;
|
||||
}
|
||||
|
||||
@ -63,39 +63,31 @@ static struct inode_operations simplefs_inode_ops = {
|
||||
.lookup = simplefs_lookup,
|
||||
};
|
||||
|
||||
/* This function creates, configures and returns an inode,
|
||||
* for the asked file (or) directory (differentiated by the mode param),
|
||||
* under the directory specified by the dir param
|
||||
* on the device dev, managed by the superblock sb param) */
|
||||
struct inode *simplefs_get_inode(struct super_block *sb,
|
||||
const struct inode *dir, umode_t mode,
|
||||
dev_t dev)
|
||||
/* This functions returns a simplefs_inode with the given inode_no
|
||||
* from the inode store, if it exists. */
|
||||
struct simplefs_inode * simplefs_get_inode(struct super_block *sb, uint64_t inode_no)
|
||||
{
|
||||
struct inode *inode = new_inode(sb);
|
||||
struct simplefs_super_block *sfs_sb = sb->s_fs_info;
|
||||
struct simplefs_inode *sfs_inode = NULL;
|
||||
|
||||
if (inode) {
|
||||
inode->i_ino = get_next_ino();
|
||||
inode_init_owner(inode, dir, mode);
|
||||
int i;
|
||||
struct buffer_head *bh;
|
||||
|
||||
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
|
||||
/* The inode store can be read once and kept in memory permanently while mounting.
|
||||
* But such a model will not be scalable in a filesystem with
|
||||
* millions or billions of files (inodes) */
|
||||
bh = (struct buffer_head *)sb_bread(sb, SIMPLEFS_INODESTORE_BLOCK_NUMBER);
|
||||
sfs_inode = (struct simplefs_inode *) bh->b_data;
|
||||
|
||||
switch (mode & S_IFMT) {
|
||||
case S_IFDIR:
|
||||
/* i_nlink will be initialized to 1 in the inode_init_always function
|
||||
* (that gets called inside the new_inode function),
|
||||
* We change it to 2 for directories, for covering the "." entry */
|
||||
inc_nlink(inode);
|
||||
break;
|
||||
case S_IFREG:
|
||||
case S_IFLNK:
|
||||
default:
|
||||
printk(KERN_ERR
|
||||
"simplefs can create meaningful inode for only root directory at the moment\n");
|
||||
return NULL;
|
||||
break;
|
||||
for (i=0;i < sfs_sb->inodes_count; i++) {
|
||||
if (sfs_inode->inode_no == inode_no) {
|
||||
/* FIXME: bh->b_data is probably leaking */
|
||||
return sfs_inode;
|
||||
}
|
||||
sfs_inode++;
|
||||
}
|
||||
return inode;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* This function, as the name implies, Makes the super_block valid and
|
||||
@ -106,11 +98,12 @@ int simplefs_fill_super(struct super_block *sb, void *data, int silent)
|
||||
struct buffer_head *bh;
|
||||
struct simplefs_super_block *sb_disk;
|
||||
|
||||
bh = (struct buffer_head *)sb_bread(sb, 0);
|
||||
bh = (struct buffer_head *)sb_bread(sb, SIMPLEFS_SUPERBLOCK_BLOCK_NUMBER);
|
||||
|
||||
sb_disk = (struct simplefs_super_block *)bh->b_data;
|
||||
/* FIXME: bh->b_data is probably leaking */
|
||||
|
||||
printk(KERN_INFO "The magic number obtained in disk is: [%d]\n",
|
||||
printk(KERN_INFO "The magic number obtained in disk is: [%llu]\n",
|
||||
sb_disk->magic);
|
||||
|
||||
if (unlikely(sb_disk->magic != SIMPLEFS_MAGIC)) {
|
||||
@ -126,7 +119,7 @@ int simplefs_fill_super(struct super_block *sb, void *data, int silent)
|
||||
}
|
||||
|
||||
printk(KERN_INFO
|
||||
"simplefs filesystem of version [%d] formatted with a block size of [%d] detected in the device.\n",
|
||||
"simplefs filesystem of version [%llu] formatted with a block size of [%llu] detected in the device.\n",
|
||||
sb_disk->version, sb_disk->block_size);
|
||||
|
||||
/* A magic number that uniquely identifies our filesystem type */
|
||||
@ -136,14 +129,14 @@ int simplefs_fill_super(struct super_block *sb, void *data, int silent)
|
||||
sb->s_fs_info = sb_disk;
|
||||
|
||||
root_inode = new_inode(sb);
|
||||
root_inode->i_ino = SIMPLEFS_ROOT_INODE_NUMBER;
|
||||
root_inode->i_ino = SIMPLEFS_ROOTDIR_INODE_NUMBER;
|
||||
inode_init_owner(root_inode, NULL, S_IFDIR);
|
||||
root_inode->i_sb = sb;
|
||||
root_inode->i_op = &simplefs_inode_ops;
|
||||
root_inode->i_fop = &simplefs_dir_operations;
|
||||
root_inode->i_atime = root_inode->i_mtime = root_inode->i_ctime = CURRENT_TIME;
|
||||
|
||||
root_inode->i_private = &(sb_disk->root_inode);
|
||||
root_inode->i_private = simplefs_get_inode(sb, SIMPLEFS_ROOTDIR_INODE_NUMBER);
|
||||
|
||||
sb->s_root = d_make_root(root_inode);
|
||||
if (!sb->s_root)
|
||||
|
25
simple.h
25
simple.h
@ -3,7 +3,7 @@
|
||||
#define SIMPLEFS_FILENAME_MAXLEN 255
|
||||
|
||||
/* Hard-coded inode number for the root directory */
|
||||
const int SIMPLEFS_ROOT_INODE_NUMBER = 1;
|
||||
const int SIMPLEFS_ROOTDIR_INODE_NUMBER = 1;
|
||||
|
||||
/* The disk block where super block is stored */
|
||||
const int SIMPLEFS_SUPERBLOCK_BLOCK_NUMBER = 0;
|
||||
@ -19,27 +19,26 @@ const int SIMPLEFS_ROOTDIR_DATABLOCK_NUMBER = 2;
|
||||
* This gets stored as the data for a directory */
|
||||
struct simplefs_dir_record {
|
||||
char filename[SIMPLEFS_FILENAME_MAXLEN];
|
||||
uint32_t inode_no;
|
||||
uint64_t inode_no;
|
||||
};
|
||||
|
||||
struct simplefs_inode {
|
||||
mode_t mode;
|
||||
uint32_t inode_no;
|
||||
uint32_t data_block_number;
|
||||
uint64_t inode_no;
|
||||
uint64_t data_block_number;
|
||||
|
||||
union {
|
||||
uint32_t file_size;
|
||||
uint32_t dir_children_count;
|
||||
uint64_t file_size;
|
||||
uint64_t dir_children_count;
|
||||
};
|
||||
};
|
||||
|
||||
struct simplefs_super_block {
|
||||
uint32_t version;
|
||||
uint32_t magic;
|
||||
uint32_t block_size;
|
||||
uint32_t free_blocks;
|
||||
uint64_t version;
|
||||
uint64_t magic;
|
||||
uint64_t block_size;
|
||||
uint64_t inodes_count;
|
||||
uint64_t free_blocks;
|
||||
|
||||
struct simplefs_inode root_inode;
|
||||
|
||||
char padding[SIMPLEFS_DEFAULT_BLOCK_SIZE - (4 * sizeof(uint32_t)) - sizeof(struct simplefs_inode)];
|
||||
char padding[SIMPLEFS_DEFAULT_BLOCK_SIZE - (5 * sizeof(uint64_t))];
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user