Initialize root directory to have proper i_size.
[omfsprogs.git] / create_fs.c
blob84ce57cdfb9ba5215631bbcb4018e98842ce9bd9
1 #include <sys/types.h>
2 #include <sys/stat.h>
3 #include <unistd.h>
4 #include <stdlib.h>
6 #include <time.h>
7 #include <string.h>
9 #include "omfs.h"
10 #include "create_fs.h"
11 #include "crc.h"
13 #define ROOT_BLK 1
14 #define ROOT_DIR_BLK 3
15 #define BITMAP_BLK 5
16 #define SECTOR_SIZE 512
18 void safe_strncpy(char *dest, char *src, int dest_size)
20 strncpy(dest, src, dest_size-1);
21 dest[dest_size-1] = 0;
24 void clear_dev(FILE *fp, u64 sectors)
26 int i;
27 char blk[SECTOR_SIZE];
29 // clear the device
31 memset(blk, 0, sizeof(blk));
32 for (i=0; i<sectors; i++)
34 fwrite(blk, 1, sizeof(blk), fp);
36 rewind(fp);
39 int create_fs(FILE *fp, u64 sectors, fs_config_t *config)
41 int i;
42 int block_size = config->block_size;
43 char *label = "omfs";
44 omfs_info_t info;
46 int blocks_per_sector = block_size / SECTOR_SIZE;
47 int blocks = sectors / blocks_per_sector;
49 if (config->clear_dev)
50 clear_dev(fp, sectors);
52 omfs_super_t super =
54 .root_block = swap_be64(ROOT_BLK),
55 .num_blocks = swap_be64(blocks),
56 .magic = swap_be32(OMFS_MAGIC),
57 .blocksize = swap_be32(block_size),
58 .mirrors = swap_be32(2),
59 .sys_blocksize = swap_be32(block_size/4), // ??
62 omfs_root_t root =
64 .head.self = swap_be64(ROOT_BLK),
65 .head.body_size = swap_be32(sizeof(omfs_root_t) - sizeof(struct omfs_header)),
66 .head.version = 1,
67 .head.type = OMFS_INODE_SYSTEM,
68 .head.magic = OMFS_IMAGIC,
69 .num_blocks = super.num_blocks,
70 .root_dir = swap_be64(ROOT_DIR_BLK),
71 .bitmap = swap_be64(BITMAP_BLK),
72 .blocksize = super.blocksize,
73 .clustersize = swap_be32(config->cluster_size),
74 .mirrors = swap_be64(super.mirrors),
77 safe_strncpy(super.name, label, OMFS_SUPER_NAMELEN);
78 safe_strncpy(root.name, label, OMFS_NAMELEN);
80 // super block
81 omfs_write_super(fp, &super);
82 omfs_write_root_block(fp, &super, &root);
84 u64 now = time(NULL) * 1000LL;
86 // root directory
87 omfs_inode_t root_ino = {
88 .head.self = swap_be64(ROOT_DIR_BLK),
89 .head.body_size = swap_be32(swap_be32(super.sys_blocksize) - sizeof(omfs_header_t)),
90 .head.version = 1,
91 .head.type = OMFS_INODE_NORMAL,
92 .head.magic = OMFS_IMAGIC,
93 .parent = ~0,
94 .sibling = ~0,
95 .ctime = swap_be64(now),
96 .type = 'D',
97 .one_goes_here = swap_be32(1),
98 .size = swap_be64(swap_be32(super.sys_blocksize))
101 u8 *data = calloc(1, swap_be32(super.sys_blocksize));
102 if (!data)
103 return 0;
105 memcpy(data, &root_ino, sizeof (omfs_inode_t));
106 memset(data + OMFS_DIR_START, 0xff,
107 swap_be32(super.sys_blocksize) - OMFS_DIR_START);
109 info.dev = fp;
110 info.super = &super;
111 info.root = &root;
112 omfs_write_inode(&info, (omfs_inode_t *) data);
114 free(data);
116 // free space bitmap. We already know that blocks 0-5 are
117 // going to be set; the first available cluster has to take
118 // into account the size of the free space bitmap.
119 int bitmap_size = (swap_be64(super.num_blocks) + 7)/8;
120 int first_blk = BITMAP_BLK + (bitmap_size +
121 swap_be32(super.blocksize)-1) / swap_be32(super.blocksize);
123 u8 *bitmap = calloc(1, bitmap_size);
125 for (i=0; i<first_blk; i++)
127 bitmap[i/8] |= 1<<(i & 7);
129 omfs_write_bitmap(&info, bitmap);
131 return 1;