Пример #1
0
static void setup_roots(struct sb *sb, struct disksuper *super)
{
	u64 iroot_val = be64_to_cpu(super->iroot);
	u64 oroot_val = be64_to_cpu(sb->super.oroot);
	init_btree(itable_btree(sb), sb, unpack_root(iroot_val), &itable_ops);
	init_btree(otable_btree(sb), sb, unpack_root(oroot_val), &otable_ops);
}
Пример #2
0
int save_sb(struct sb *sb)
{
	struct disksuper *super = &sb->super;

	super->blockbits = cpu_to_be16(sb->blockbits);
	super->volblocks = cpu_to_be64(sb->volblocks);

	/* Probably does not belong here (maybe metablock) */
	super->iroot = cpu_to_be64(pack_root(&itable_btree(sb)->root));
	super->oroot = cpu_to_be64(pack_root(&otable_btree(sb)->root));
	super->nextalloc = cpu_to_be64(sb->nextalloc);
	super->atomdictsize = cpu_to_be64(sb->atomdictsize);
	super->freeatom = cpu_to_be32(sb->freeatom);
	super->atomgen = cpu_to_be32(sb->atomgen);
	/* logchain and logcount are written to super directly */

	return devio(WRITE, sb_dev(sb), SB_LOC, super, SB_LEN);
}
Пример #3
0
int make_tux3(struct sb *sb)
{
	struct inode *dir = &(struct inode){
		.i_sb = sb,
		.i_mode = S_IFDIR | 0755,
	};
	struct tux_iattr *iattr = &(struct tux_iattr){};
	int err;

	err = clear_other_magic(sb);
	if (err)
		return err;

	trace("create inode table");
	init_btree(itable_btree(sb), sb, no_root, &itable_ops);

	trace("create bitmap");
	sb->bitmap = __tux_create_inode(dir, TUX_BITMAP_INO, iattr, 0);
	if (IS_ERR(sb->bitmap)) {
		err = PTR_ERR(sb->bitmap);
		goto eek;
	}
	assert(sb->bitmap->inum == TUX_BITMAP_INO);
	sb->bitmap->i_size = (sb->volblocks + 7) >> 3;
	/* should this?, tuxtruncate(sb->bitmap, (sb->volblocks + 7) >> 3); */

	trace("reserve superblock");
	/* Always 8K regardless of blocksize */
	int reserve = 1 << (sb->blockbits > 13 ? 0 : 13 - sb->blockbits);
	for (int i = 0; i < reserve; i++) {
		block_t block = balloc_from_range(sb, i, 1, 1);
		if (block == -1)
			goto eek;
		trace("reserve %Lx", (L)block); // error ???
	}

	trace("create version table");
	sb->vtable = __tux_create_inode(dir, TUX_VTABLE_INO, iattr, 0);
	if (IS_ERR(sb->vtable)) {
		err = PTR_ERR(sb->vtable);
		goto eek;
	}
	assert(sb->vtable->inum == TUX_VTABLE_INO);

	trace("create atom dictionary");
	sb->atable = __tux_create_inode(dir, TUX_ATABLE_INO, iattr, 0);
	if (IS_ERR(sb->atable)) {
		err = PTR_ERR(sb->atable);
		goto eek;
	}
	assert(sb->atable->inum == TUX_ATABLE_INO);
	sb->atomref_base = 1 << (40 - sb->blockbits); // see xattr.c
	sb->unatom_base = sb->atomref_base + (1 << (34 - sb->blockbits));
	sb->atomgen = 1; // atom 0 not allowed, means end of atom freelist

	trace("create root directory");
	struct tux_iattr root_iattr = { .mode = S_IFDIR | 0755, };
	sb->rootdir = __tux_create_inode(dir, TUX_ROOTDIR_INO, &root_iattr, 0);
	if (IS_ERR(sb->rootdir)) {
		err = PTR_ERR(sb->rootdir);
		goto eek;
	}
	assert(sb->rootdir->inum == TUX_ROOTDIR_INO);

	if ((err = sync_super(sb)))
		goto eek;

	show_buffers(mapping(sb->bitmap));
	show_buffers(mapping(sb->rootdir));
	show_buffers(sb->volmap->map);
	return 0;
eek:
	if (err)
		warn("eek, %s", strerror(-err));
	iput(sb->bitmap);
	sb->bitmap = NULL;
	return err ? err : -ENOSPC; // just guess
}
Пример #4
0
static int tux3_fill_super(struct super_block *sb, void *data, int silent)
{
	static struct tux_iattr iattr;
	struct sb *sbi;
	struct root iroot;
	int err, blocksize;

	sbi = kzalloc(sizeof(struct sb), GFP_KERNEL);
	if (!sbi)
		return -ENOMEM;
	sbi->vfs_sb = sb;
	sb->s_fs_info = sbi;
	sb->s_maxbytes = MAX_LFS_FILESIZE;
	sb->s_magic = 0x54555833;
	sb->s_op = &tux3_super_ops;
	sb->s_time_gran = 1;

	mutex_init(&sbi->loglock);

	err = -EIO;
	blocksize = sb_min_blocksize(sb, BLOCK_SIZE);
	if (!blocksize) {
		if (!silent)
			printk(KERN_ERR "TUX3: unable to set blocksize\n");
		goto error;
	}

	err = tux_load_sb(sb, &iroot, silent);
	if (err)
		goto error;
	printk("%s: depth %Lu, block %Lu\n",
	       __func__, (L)iroot.depth, (L)iroot.block);
	printk("%s: blocksize %u, blockbits %u, blockmask %08x\n",
	       __func__, sbi->blocksize, sbi->blockbits, sbi->blockmask);
	printk("%s: volblocks %Lu, freeblocks %Lu, nextalloc %Lu\n",
	       __func__, sbi->volblocks, sbi->freeblocks, sbi->nextalloc);
	printk("%s: freeatom %u, atomgen %u\n",
	       __func__, sbi->freeatom, sbi->atomgen);

	if (sbi->blocksize != blocksize) {
		if (!sb_set_blocksize(sb, sbi->blocksize)) {
			printk(KERN_ERR "TUX3: blocksize too small for device.\n");
			goto error;
		}
	}
	printk("%s: s_blocksize %lu\n", __func__, sb->s_blocksize);

	err = -ENOMEM;
	sbi->volmap = tux_new_volmap(tux_sb(sb));
	if (!sbi->volmap)
		goto error;

	/* Initialize itable btree */
	init_btree(itable_btree(sbi), sbi, iroot, &itable_ops);

//	struct inode *vtable;
	sbi->bitmap = tux3_iget(sb, TUX_BITMAP_INO);
	err = PTR_ERR(sbi->bitmap);
	if (IS_ERR(sbi->bitmap))
		goto error_bitmap;

	sbi->rootdir = tux3_iget(sb, TUX_ROOTDIR_INO);
	err = PTR_ERR(sbi->rootdir);
	if (IS_ERR(sbi->rootdir))
		goto error_rootdir;

	sbi->atable = tux3_iget(sb, TUX_ATABLE_INO);
	err = PTR_ERR(sbi->atable);
	if (IS_ERR(sbi->atable))
		goto error_atable;

	err = -ENOMEM;
	sbi->logmap = tux_new_inode(sbi->rootdir, &iattr, 0);
	if (!sbi->logmap)
		goto error_logmap;

	sb->s_root = d_alloc_root(sbi->rootdir);
	if (!sb->s_root)
		goto error_alloc_root;

	return 0;

error_alloc_root:
	iput(sbi->logmap);
error_logmap:
	iput(sbi->atable);
error_atable:
	iput(sbi->rootdir);
error_rootdir:
	iput(sbi->bitmap);
error_bitmap:
	iput(sbi->volmap);
error:
	kfree(sbi);
	return err;
}