bfs
struct bfs_super_block *bfs = (void *)buf;
bfs->header.magic = BFS_MAGIC;
bfs->header.data_start_byte = DEV_BSIZE * 2; /* super block + inode */
bfs->header.data_end_byte = nsectors * BFS_BSIZE - 1;
bfs->compaction.from = 0xffffffff;
bfs->compaction.to = 0xffffffff;
bfs->compaction.from_backup = 0xffffffff;
bfs->compaction.to_backup = 0xffffffff;
bfs = &vtoc->partition[3];
bfs->tag = VTOC_TAG_STAND;
bfs->flags = 0;
bfs->start_sector = _BOOTBLOCK_SIZE;
res = nsectors - bfs->start_sector;
bfs->nsectors = res > _BFS_SIZE ? _BFS_SIZE : res;
struct ux_partition *bfs;
int bfs_init(struct bfs **);
bfs_init(struct bfs **bfsp)
FS_DEF(bfs);
struct bfs *bfs;
if (bfs_init(&file->bfs) != 0) {
if (!bfs_file_lookup(file->bfs, name, &file->start, &file->end,
bfs_fini(file->bfs);
bfs_fini(file->bfs);
struct bfs *bfs;
if (bfs_init(&bfs) != 0)
for (file = bfs->dirent, i = 0; i < bfs->max_dirent; i++, file++) {
inode = &bfs->inode[file->inode - BFS_ROOT_INODE];
bfs_fini(bfs);
if (bfs_file_write(bfs, filename, p, size) != 0)
bfs_fini(bfs);
if (bfs_file_read(bfs, filename, p, size, 0) != 0)
bfs_fini(bfs);
if (bfs_file_write(bfs, filename, p, size) != 0)
bfs_fini(bfs);
struct bfs *bfs;
if (bfs_init(&bfs) != 0) {
struct bfs *bfs;
if (bfs_init(&bfs) != 0) {
if (bfs_file_write(bfs, "boot.log", __log, LOG_SIZE) != 0)
bfs_fini(bfs);
if ((err = bfs_init_superblock(bfs, bfs_sector, &memsize)) != 0) {
bfs_fini(bfs);
bfs->super_block_size = memsize;
bfs_fini(bfs);
if ((err = bfs_init_inode(bfs, p, &memsize)) != 0) {
bfs_fini(bfs);
bfs->dirent_size = memsize;
bfs_fini(bfs);
if ((err = bfs_init_dirent(bfs, p)) != 0) {
bfs_fini(bfs);
bfs_dump(bfs);
*bfsp = bfs;
bfs_fini(struct bfs *bfs)
if (bfs == 0)
if (bfs->super_block)
__FREE(bfs->super_block, bfs->super_block_size, M_BFS);
if (bfs->dirent)
__FREE(bfs->dirent, bfs->dirent_size, M_BFS);
__FREE(bfs, sizeof(struct bfs), M_BFS);
bfs_init_superblock(struct bfs *bfs, int bfs_sector, size_t *required_memory)
bfs->start_sector = bfs_sector;
if (!bfs->io->read(bfs->io, (uint8_t *)&super, bfs_sector))
bfs->data_start = super.header.data_start_byte;
bfs->data_end = super.header.data_end_byte;
bfs->max_inode = (bfs->data_start - sizeof(struct bfs_super_block)) /
*required_memory = ROUND_SECTOR(bfs->data_start);
bfs_init_inode(struct bfs *bfs, uint8_t *p, size_t *required_memory)
if (!bfs->io->read_n(bfs->io, p, bfs->start_sector,
bfs->data_start >> DEV_BSHIFT))
bfs->super_block = (struct bfs_super_block *)p;
bfs->inode = (struct bfs_inode *)(p + sizeof(struct bfs_super_block));
p += bfs->data_start;
bfs->n_inode = 0;
inode = bfs->inode;
for (i = 0; i < bfs->max_inode; i++, inode++) {
bfs->n_inode++;
DPRINTF(bfs->debug, "inode: %d/%d\n", bfs->n_inode, bfs->max_inode);
DPRINTF(bfs->debug, "no root directory.\n");
DPRINTF(bfs->debug, "root inode: %d-%d\n", root_inode->start_sector,
bfs->root_inode = root_inode;
bfs_init_dirent(struct bfs *bfs, uint8_t *p)
struct bfs_inode *inode = bfs->root_inode;
if (!bfs->io->read_n(bfs->io, p,
bfs->start_sector + inode->start_sector, n))
bfs->dirent = (struct bfs_dirent *)p;
bfs->max_dirent = (n << DEV_BSHIFT) / sizeof(struct bfs_dirent);
file = bfs->dirent;
bfs->n_dirent = 0;
for (i = 0; i < bfs->max_dirent; i++, file++)
bfs->n_dirent++;
DPRINTF(bfs->debug, "dirent: %d/%d\n", bfs->n_dirent, bfs->max_dirent);
bfs_file_read(const struct bfs *bfs, const char *fname, void *buf, size_t bufsz,
if (!bfs_file_lookup(bfs, fname, &start, &end, &sz))
if (!bfs->io->read_n(bfs->io, p, start, n))
if (!bfs->io->read(bfs->io, tmpbuf, end))
bfs_file_write(struct bfs *bfs, const char *fname, void *buf,
if (bfs_dirent_lookup_by_name(bfs, name, &dirent)) {
if (!bfs_inode_lookup(bfs, dirent->inode, &inode)) {
DPRINTF(bfs->debug, "%s: dirent found, but inode "
bfs_file_delete(bfs, name, false);
if ((err = bfs_file_create(bfs, name, buf, bufsz, &attr)) != 0)
if ((err = bfs_file_create(bfs, name, buf, bufsz, &attr)) != 0)
bfs_file_delete(struct bfs *bfs, const char *fname, bool keep_inode)
if (!bfs_dirent_lookup_by_name(bfs, fname, &dirent))
if (!keep_inode && !bfs_inode_lookup(bfs, dirent->inode, &inode))
bfs->n_dirent--;
bfs_writeback_dirent(bfs, dirent, false);
bfs->n_inode--;
bfs_writeback_inode(bfs, inode);
DPRINTF(bfs->debug, "%s: \"%s\" deleted.\n", __func__, fname);
bfs_file_rename(struct bfs *bfs, const char *from_name, const char *to_name)
if (!bfs_dirent_lookup_by_name(bfs, from_name, &dirent)) {
bfs_writeback_dirent(bfs, dirent, false);
DPRINTF(bfs->debug, "%s: \"%s\" -> \"%s\" error=%d.\n", __func__,
bfs_file_create(struct bfs *bfs, const char *fname, void *buf, size_t bufsz,
if ((err = bfs_inode_alloc(bfs, &inode, &j, &start)) != 0)
if ((start + n) * DEV_BSIZE >= bfs->data_end) {
DPRINTF(bfs->debug, "disk full.\n");
for (file = bfs->dirent, i = 0; i < bfs->max_dirent; i++, file++)
if (i == bfs->max_dirent) {
DPRINTF(bfs->debug, "dirent full.\n");
bfs_inode_set_attr(bfs, inode, attr);
DPRINTF(bfs->debug, "%s: start %d end %d\n", __func__,
if (!bfs->io->write(bfs->io, p, bfs->start_sector + i))
if (!bfs->io->write(bfs->io, tmpbuf, bfs->start_sector + i))
bfs->n_inode++;
bfs->n_dirent++;
bfs_writeback_dirent(bfs, file, true);
bfs_writeback_inode(bfs, inode);
bfs_writeback_dirent(const struct bfs *bfs, struct bfs_dirent *dir,
struct bfs_dirent *dir_base = bfs->dirent;
struct bfs_inode *root_inode = bfs->root_inode;
bfs_writeback_inode(bfs, root_inode);
return bfs->io->write(bfs->io, (uint8_t *)dir_base + (i << DEV_BSHIFT),
bfs->start_sector + bfs->root_inode->start_sector + i);
bfs_writeback_inode(const struct bfs *bfs, struct bfs_inode *inode)
struct bfs_inode *inode_base = bfs->inode;
return bfs->io->write(bfs->io,
bfs->start_sector + 1/*super block*/ + i);
bfs_file_lookup(const struct bfs *bfs, const char *fname, int *start, int *end,
if (!bfs_dirent_lookup_by_name(bfs, fname, &dirent))
if (!bfs_inode_lookup(bfs, dirent->inode, &inode))
*start = inode->start_sector + bfs->start_sector;
*end = inode->end_sector + bfs->start_sector;
DPRINTF(bfs->debug, "%s: %d + %d -> %d (%zd)\n",
fname, bfs->start_sector, inode->start_sector,
bfs_dirent_lookup_by_inode(const struct bfs *bfs, int inode,
for (file = bfs->dirent, i = 0; i < bfs->max_dirent; i++, file++)
if (i == bfs->max_dirent)
bfs_dirent_lookup_by_name(const struct bfs *bfs, const char *fname,
for (file = bfs->dirent, i = 0; i < bfs->max_dirent; i++, file++)
if (i == bfs->max_dirent)
bfs_inode_lookup(const struct bfs *bfs, ino_t n, struct bfs_inode **iinode)
for (inode = bfs->inode, i = 0; i < bfs->max_inode; i++, inode++)
if (i == bfs->max_inode)
bfs_inode_delete(struct bfs *bfs, ino_t ino)
if (!bfs_inode_lookup(bfs, ino, &inode))
bfs->n_inode--;
bfs_writeback_inode(bfs, inode);
DPRINTF(bfs->debug, "%s: %lld deleted.\n", __func__, (long long)ino);
bfs_inode_alloc(const struct bfs *bfs, struct bfs_inode **free_inode,
inode = bfs->inode;
for (i = BFS_ROOT_INODE; i < bfs->max_inode; i++, inode++) {
DPRINTF(bfs->debug, "i-node full.\n");
if (start * DEV_BSIZE >= bfs->data_end) {
DPRINTF(bfs->debug, "data block full.\n");
bfs_inode_set_attr(const struct bfs *bfs, struct bfs_inode *inode,
bfs_writeback_inode(bfs, inode);
bfs_dump(const struct bfs *bfs)
if (!bfs_superblock_valid(bfs->super_block)) {
DPRINTF(bfs->debug, "invalid bfs super block.\n");
h = &bfs->super_block->header;
compaction = &bfs->super_block->compaction;
DPRINTF(bfs->debug, "super block %zdbyte, inode %zdbyte, dirent %zdbyte\n",
sizeof *bfs->super_block, sizeof *inode, sizeof *file);
DPRINTF(bfs->debug, "magic=%x\n", h->magic);
DPRINTF(bfs->debug, "data_start_byte=0x%x\n", h->data_start_byte);
DPRINTF(bfs->debug, "data_end_byte=0x%x\n", h->data_end_byte);
DPRINTF(bfs->debug, "from=%#x\n", compaction->from);
DPRINTF(bfs->debug, "to=%#x\n", compaction->to);
DPRINTF(bfs->debug, "from_backup=%#x\n", compaction->from_backup);
DPRINTF(bfs->debug, "to_backup=%#x\n", compaction->to_backup);
DPRINTF(bfs->debug, "fsname=%s\n", bfs->super_block->fsname);
DPRINTF(bfs->debug, "volume=%s\n", bfs->super_block->volume);
DPRINTF(bfs->debug, "[inode index list]\n");
for (inode = bfs->inode, i = j = 0; i < bfs->max_inode; inode++, i++) {
DPRINTF(bfs->debug, "%3d %8d %8d %8d (%d) ",
DPRINTF(bfs->debug, "%d %d %d %d %d %08x %08x %08x\n",
STATIC int bfs_init_superblock(struct bfs *, int, size_t *);
if (j != bfs->n_inode) {
DPRINTF(bfs->debug, "inconsistent cached data. (i-node)\n");
DPRINTF(bfs->debug, "total %d i-node.\n", j);
DPRINTF(bfs->debug, "[dirent index list]\n");
DPRINTF(bfs->debug, "%d file entries.\n", bfs->max_dirent);
file = bfs->dirent;
STATIC int bfs_init_inode(struct bfs *, uint8_t *, size_t *);
for (i = j = 0; i < bfs->max_dirent; i++, file++) {
if (bfs_file_lookup(bfs, file->name, &s, &e, &bytes))
DPRINTF(bfs->debug, "%3d %14s %8d %8d %8zd\n",
if (j != bfs->n_dirent) {
DPRINTF(bfs->debug, "inconsistent cached data. (dirent)\n");
STATIC int bfs_init_dirent(struct bfs *, uint8_t *);
DPRINTF(bfs->debug, "%d files.\n", j);
STATIC bool bfs_writeback_dirent(const struct bfs *, struct bfs_dirent *,
STATIC bool bfs_writeback_inode(const struct bfs *, struct bfs_inode *);
bfs_init2(struct bfs **bfsp, int bfs_sector, struct sector_io_ops *io,
struct bfs *bfs;
if ((bfs = (void *)__MALLOC(sizeof(struct bfs), M_BFS, M_WAITOK)) == 0)
memset(bfs, 0, sizeof *bfs);
bfs->io = io;
bfs->debug = debug;
int bfs_init2(struct bfs **, int, struct sector_io_ops *, bool);
void bfs_fini(struct bfs *);
int bfs_file_read(const struct bfs *, const char *, void *, size_t, size_t *);
int bfs_file_write(struct bfs *, const char *, void *, size_t);
int bfs_file_create(struct bfs *, const char *, void *, size_t,
int bfs_file_delete(struct bfs *, const char *, bool);
int bfs_file_rename(struct bfs *, const char *, const char *);
bool bfs_file_lookup(const struct bfs *, const char *, int *, int *,
bool bfs_dump(const struct bfs *);
int sysvbfs_bfs_init(struct bfs **, struct vnode *);
void sysvbfs_bfs_fini(struct bfs *);
bool bfs_inode_lookup(const struct bfs *, ino_t, struct bfs_inode **);
int bfs_inode_delete(struct bfs *, ino_t);
bool bfs_dirent_lookup_by_name(const struct bfs *, const char *,
bool bfs_dirent_lookup_by_inode(const struct bfs *, int,
void bfs_inode_set_attr(const struct bfs *, struct bfs_inode *,
int bfs_inode_alloc(const struct bfs *, struct bfs_inode **, int *,
sysvbfs_bfs_init(struct bfs **bfsp, struct vnode *vp)
sysvbfs_bfs_fini(struct bfs *bfs)
free(bfs->io, M_TEMP);
bfs_fini(bfs);
struct bfs;
struct bfs *bfs;
if ((error = sysvbfs_bfs_init(&bmp->bfs, devvp)) != 0) {
sysvbfs_bfs_fini(bmp->bfs);
struct bfs *bfs = bmp->bfs;
data_block = (bfs->data_end - bfs->data_start) >> BFS_BSHIFT;
if (bfs_inode_alloc(bfs, 0, 0, &free_block) != 0)
free_block = (bfs->data_end >> BFS_BSHIFT) - free_block;
DPRINTF("%s: %d %d %d\n", __func__, bfs->data_start,
bfs->data_end, free_block);
f->f_files = bfs->max_inode;
f->f_ffree = bfs->max_inode - bfs->n_inode;
struct bfs *bfs;
bfs = bmp->bfs;
if (!bfs_inode_lookup(bfs, ino, &inode)) {
if (!bfs_dirent_lookup_by_name(bfs, cnp->cn_nameptr,
struct bfs *bfs = bmp->bfs;
if ((err = bfs_file_create(bfs, a->a_cnp->cn_nameptr, 0, 0, &attr))
if (!bfs_dirent_lookup_by_name(bfs, a->a_cnp->cn_nameptr, &dirent))
bfs_inode_set_attr(bnode->bmp->bfs, bnode->inode, &attr);
struct bfs *bfs = bnode->bmp->bfs;
bfs_inode_set_attr(bfs, inode, attr);
struct bfs *bfs = bmp->bfs;
if ((err = bfs_file_delete(bfs, ap->a_cnp->cn_nameptr, true)) != 0)
struct bfs *bfs = bnode->bmp->bfs;
error = bfs_file_delete(bfs, to_name, true);
error = bfs_file_rename(bfs, from_name, to_name);
struct bfs *bfs = bnode->bmp->bfs;
if ((i + n) > bfs->n_dirent)
n = bfs->n_dirent - i;
DPRINTF("%s 1: %d %d %d\n", __func__, i, n, bfs->n_dirent);
for (file = &bfs->dirent[i]; n > 0; file++, i++) {
if (i == bfs->max_dirent) {
DPRINTF("%s 2: %d %d %d\n", __func__, i, n, bfs->n_dirent);
*ap->a_eofflag = (i == bfs->n_dirent);
struct bfs *bfs = bnode->bmp->bfs;
if (bfs_inode_delete(bfs, bnode->inode->number) != 0)
if (blk * BFS_BSIZE > bmp->bfs->data_end)
struct bfs *bfs = bnode->bmp->bfs; /* my filesystem */
bfs_dump(bnode->bmp->bfs);
bfs_inode_set_attr(bnode->bmp->bfs, bnode->inode, &attr);
struct fs *bfs;
bfs = (struct fs *)bp->b_data;
bfs->fs_flags &= ~FS_INTERNAL;
KASSERT(bfs->fs_magic == FS_UFS2_MAGIC);
bfs->fs_magic = FS_UFS2EA_MAGIC;
ffs_sb_swap(bfs, bfs);
bfs[0].counter = BF_ALLOC; /* pass out the first buffer */
bfs[1].counter = BF_FREE;
return (struct tftphdr *)(void *)bfs[0].buf;
bfs[current].counter = BF_FREE; /* free old one */
b = &bfs[current]; /* look at new buffer */
b = &bfs[nextone]; /* look at "next" buffer */
bfs[current].counter = ct; /* set size of data to write */
if (bfs[current].counter != BF_FREE) /* if not free */
bfs[current].counter = BF_ALLOC; /* mark as alloc'd */
*dpp = (struct tftphdr *)(void *)bfs[current].buf;
b = &bfs[nextone];
} bfs[2];