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); }
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); }
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 }
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; }