Example #1
0
File: dir.c Project: pipul/simplefs
static struct dentry *simplefs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) {
	struct inode *inode = NULL;
	struct page *pagep = NULL;
	struct simplefs_dentry *raw_de;
	long ino;

	dentry->d_op = dir->i_sb->s_root->d_op;
	if (dentry->d_name.len > SIMPLEFS_NAME_LEN)
		return ERR_PTR(-ENAMETOOLONG);
	raw_de = simplefs_find_dentry(dir, dentry, &pagep);
	if (raw_de) {
		ino = raw_de->inode;
		simplefs_put_page(pagep);

		inode = simplefs_iget(dir->i_sb, ino);
		if (IS_ERR(inode))
			return ERR_CAST(inode);
	}
	//dentry->d_op = &d_op;
	if (inode) {
		printk(KERN_INFO "simplefs_lookup: dentry %d", dentry->d_count.counter);
		printk(KERN_INFO "simplefs_lookup: inode %ld %ld %d %d", inode->i_ino, inode->i_state, inode->i_count.counter, inode->i_nlink);
	}

	return d_splice_alias(inode, dentry);
}
Example #2
0
File: dir.c Project: pipul/simplefs
static int simplefs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd) {
	struct inode *inode = NULL;
	long ino;
	int err = 0;

	ino = bitmap_alloc_inode(dir->i_sb);
	if (ino < 0)
		return -EIO;
	inode = simplefs_iget(dir->i_sb, ino);
	if (IS_ERR(inode))
		return -EIO;

	inode->i_state = 0;
	inode->i_mode = mode | S_IFREG;
	inode->i_nlink = 1;
	inode->i_size = inode->i_blocks = inode->i_bytes = 0;
	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
	mark_inode_dirty(inode);
	err = simplefs_insert_dentry(dentry, inode);
	if (!err) {
		//dentry->d_op = &d_op;
		d_instantiate(dentry, inode);
		if (inode) {
			printk(KERN_INFO "simplefs_create: dentry %d", dentry->d_count.counter);
			printk(KERN_INFO "simplefs_create: inode %ld %ld %d %d", inode->i_ino, inode->i_state, inode->i_count.counter, inode->i_nlink);
		}

		return 0;
	}
	inode_dec_link_count(inode);
	iput(inode);
	return err;
}
Example #3
0
struct dentry *simplefs_lookup(struct inode *parent_inode,
                               struct dentry *child_dentry, unsigned int flags)
{
    struct simplefs_inode *parent = SIMPLEFS_INODE(parent_inode);
    struct super_block *sb = parent_inode->i_sb;
    struct buffer_head *bh;
    struct simplefs_dir_record *record;
    int i;

    bh = sb_bread(sb, parent->data_block_number);
    BUG_ON(!bh);
    sfs_trace("Lookup in: ino=%llu, b=%llu\n",
              parent->inode_no, parent->data_block_number);

    record = (struct simplefs_dir_record *)bh->b_data;
    for (i = 0; i < parent->dir_children_count; i++) {
        sfs_trace("Have file: '%s' (ino=%llu)\n",
                  record->filename, record->inode_no);

        if (!strcmp(record->filename, child_dentry->d_name.name)) {
            /* FIXME: There is a corner case where if an allocated inode,
             * is not written to the inode store, but the inodes_count is
             * incremented. Then if the random string on the disk matches
             * with the filename that we are comparing above, then we
             * will use an invalid uninitialized 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;
        }
        record++;
    }

    printk(KERN_ERR
           "No inode found for the filename [%s]\n",
           child_dentry->d_name.name);

    return NULL;
}
Example #4
0
File: dir.c Project: pipul/simplefs
static int simplefs_mkdir(struct inode *dir, struct dentry *dentry, int mode) {
	struct inode *inode = NULL;
	long ino;
	int err = 0;

	printk(KERN_INFO "simplefs_mkdir: %s %d\n", dentry->d_name.name, mode);
	inode_inc_link_count(dir);
	
	ino = bitmap_alloc_inode(dir->i_sb);
	if (ino < 0)
		return -EIO;
	inode = simplefs_iget(dir->i_sb, ino);
	if (IS_ERR(inode))
		return -EIO;

	// set inode operations
	inode->i_op = &simplefs_file_inode_operations;
	inode->i_fop = &simplefs_file_operations;
	inode->i_mapping->a_ops = &simplefs_aops;

	inode->i_mode = mode | S_IFDIR;
	inode->i_nlink = 2;
	inode->i_size = inode->i_blocks = inode->i_bytes = 0;
	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;

	mark_inode_dirty(inode);
	err = simplefs_insert_dentry(dentry, inode);
	if (!err) {
		d_instantiate(dentry, inode);
		return 0;
	}

	inode_dec_link_count(inode);
	inode_dec_link_count(inode);
	iput(inode);
	inode_dec_link_count(dir);
	return err;
}
Example #5
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)
{
    struct inode *root_inode;
    struct buffer_head *bh;
    struct simplefs_super_block *sb_disk;
    int ret = -EPERM;

    bh = sb_bread(sb, SIMPLEFS_SUPERBLOCK_BLOCK_NUMBER);
    BUG_ON(!bh);

    sb_disk = (struct simplefs_super_block *)bh->b_data;

    printk(KERN_INFO "The magic number obtained in disk is: [%llu]\n",
           sb_disk->magic);

    if (unlikely(sb_disk->magic != SIMPLEFS_MAGIC)) {
        printk(KERN_ERR
               "The filesystem that you try to mount is not of type simplefs. Magicnumber mismatch.");
        goto release;
    }

    if (unlikely(sb_disk->block_size != SIMPLEFS_DEFAULT_BLOCK_SIZE)) {
        printk(KERN_ERR
               "simplefs seem to be formatted using a non-standard block size.");
        goto release;
    }
    /** XXX: Avoid this hack, by adding one more sb wrapper, but non-disk */
    sb_disk->journal = NULL;

    printk(KERN_INFO
           "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 */
    sb->s_magic = SIMPLEFS_MAGIC;

    /* For all practical purposes, we will be using this s_fs_info as the super block */
    sb->s_fs_info = sb_disk;

    sb->s_maxbytes = SIMPLEFS_DEFAULT_BLOCK_SIZE;
    sb->s_op = &simplefs_sops;

    root_inode = new_inode(sb);
    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 =
        simplefs_get_inode(sb, SIMPLEFS_ROOTDIR_INODE_NUMBER);

    /* TODO: move such stuff into separate header. */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
    sb->s_root = d_make_root(root_inode);
#else
    sb->s_root = d_alloc_root(root_inode);
    if (!sb->s_root)
        iput(root_inode);
#endif

    if (!sb->s_root) {
        ret = -ENOMEM;
        goto release;
    }

    if ((ret = simplefs_parse_options(sb, data)))
        goto release;

    if (!sb_disk->journal) {
        struct inode *journal_inode;
        journal_inode = simplefs_iget(sb, SIMPLEFS_JOURNAL_INODE_NUMBER);

        ret = simplefs_sb_load_journal(sb, journal_inode);
        goto release;
    }
    ret = jbd2_journal_load(sb_disk->journal);

release:
    brelse(bh);

    return ret;
}
Example #6
0
static int simplefs_fill_super(struct super_block *sb, void *data, int silent) {
	struct buffer_head *bh;
	struct simplefs_super *rsb;
	struct simplefs_super_info *sbi;
	struct inode *root;
	int i, j, cnt, ret = 0;

	printk(KERN_INFO "simplefs_fill_super\n");
	if (!(bh = sb_bread(sb, SIMPLEFS_SUPER_BNO))) {
		printk(KERN_ERR "Simplefs: unable to read superblock\n");
		return -ENOMEM;
	}
	sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
	if (!sbi) {
		ret = -ENOMEM;
		goto out;
	}
	sbi->s_sb = bh;
	memcpy(&sbi->raw_super, bh->b_data, sizeof(sbi->raw_super));
	sb->s_fs_info = sbi;
	sb->s_blocksize = SIMPLEFS_BLOCKSIZE;
	sb->s_flags = sb->s_flags & ~MS_POSIXACL;

	/*
	 * set up enough so that it can read an inode
	 */
	sb->s_op = &simplefs_super_operations;
	root = simplefs_iget(sb, SIMPLEFS_ROOT_INO);
	if (!root) {
		printk(KERN_ERR "Simplefs: corrupt root inode\n");
		ret = -EINVAL;
		goto failed_root;
	}
	printk(KERN_INFO "simplefs_fill_super -> simplefs_iget ok: %ld\n", root->i_ino);
	
	sb->s_root = d_alloc_root(root);
	if (!sb->s_root) {
		iput(root);
		printk(KERN_ERR "Simplefs: get root dentry failed\n");
		ret = -ENOMEM;
		goto failed_root;
	}
	printk(KERN_INFO "simplefs_fill_super -> d_alloc_root ok\n");

	
	cnt = sbi->raw_super.s_inode_bitmap_blknr + sbi->raw_super.s_block_bitmap_blknr;
	if (!(sbi->s_bitmaps = kzalloc(sizeof(struct buffer_head *) * cnt, GFP_KERNEL)))
		goto failed_bitmap;
	for (i = 0, j = 0; i < cnt; i++) {
		if (!(bh = bitmap_load(sb, SIMPLEFS_SUPER_BNO + 1 + i)))
			goto failed_load;
		sbi->s_bitmaps[j++] = bh;
		printk(KERN_INFO "simplefs_fill_super bitmap ok:%d -> %d\n", cnt, i);
	}
	rsb = &sbi->raw_super;
	printk("fill super ok: (inode %d %d %d) (block %d %d %d)\n",
	       rsb->s_inode_bitmap_blknr, rsb->s_inode_blknr, rsb->s_free_inodes_count,
	       rsb->s_block_bitmap_blknr, rsb->s_block_blknr, rsb->s_free_blocks_count);
	return 0;
 failed_load:
	for (i = 0; i < j; i++) {
		brelse(sbi->s_bitmaps[i]);
	}
 failed_bitmap:
	dput(sb->s_root);
 failed_root:
	kfree(sbi);
 out:
	brelse(bh);
	sbi->s_sb = NULL;
	printk("simplefs get sb failed.\n");
	return ret;
}