1 | /* 2 | mkfs.c 3 | ------ 4 | $Id: mkfs.c,v 1.23 2003/11/03 19:29:16 stewart Exp $ 5 | (C)2003 Stewart Smith 6 | Distributed under the GNU Public License 7 | 8 | This is the 'mkfs' utility for FCFS - the new Walnut object store. 9 | The name mkfs is kept purely 'cause it says what it does. 10 | 11 | Some data structures have been constructed out of those 12 | present in the Linux Kernel (v2.5.69). They are copyright 13 | of their respective owners. 14 | */ 15 | 16 | #include <stdio.h> 17 | #include <stdlib.h> 18 | #include <sys/stat.h> 19 | #include <unistd.h> 20 | #include <fcntl.h> 21 | #include <string.h> 22 | #include <time.h> 23 | 24 | 25 | #include "testkit/block_dev.h" 26 | #include "testkit/types.h" 27 | #include "testkit/bitops.h" 28 | #include "disk.h" 29 | 30 | #include "super_block.h" 31 | #include "onode.h" 32 | #include "onode_index.h" 33 | #include "space_bitmap.h" 34 | 35 | #define EXPERIMENTAL 36 | 37 | u64 atou64(const char *nptr) 38 | { 39 | u64 out,i; 40 | for(out=0,i=0;nptr[i]!='\0';i++) 41 | { 42 | out*=10; 43 | out+=nptr[i]-'0'; 44 | } 45 | 46 | return out; 47 | } 48 | 49 | int make_sb(void *sb_v, u32 bsize,u64 bcount, char* name) 50 | { 51 | struct fcfs_sb *sb = (struct fcfs_sb*) sb_v; 52 | 53 | sb->magic1 = FCFS_SB_MAGIC1; 54 | sb->version = FCFS_SB_VERSION1; 55 | sb->bits = 64; 56 | sb->sblength = sizeof(struct fcfs_sb); 57 | sb->flags = 0; 58 | set_bit(FCFS_FLAG_JournalMeta,&(sb->flags)); 59 | #ifdef EXPERIMENTAL 60 | set_bit(FCFS_FLAG_Experimental,&(sb->flags)); 61 | #endif 62 | 63 | sb->bsize = bsize; 64 | sb->blocksnr = bcount; 65 | strcpy(sb->name,name); 66 | sb->magic2 = FCFS_SB_MAGIC2; 67 | 68 | sb->time_created = time(NULL); 69 | sb->time_clean = time(NULL); 70 | sb->time_dirtymount = 0x0ULL; 71 | 72 | sb->num_mounts = 0x0ULL; 73 | sb->num_dirtymounts = 0x0ULL; 74 | 75 | /* We simply steal the number of allocation groups from XFS. :) 76 | They use 8, so we'll steal that. 77 | */ 78 | sb->allocation_groupsnr = 8; 79 | sb->ag_blocksnr = bcount / sb->allocation_groupsnr; 80 | 81 | fprintf(stderr,"ALLOCATION GROUPS: 0x%x, each 0x%x\n", 82 | sb->allocation_groupsnr, 83 | sb->ag_blocksnr); 84 | 85 | sb->onindex_num_onodes = 0; /* Num onodes in index */ 86 | sb->onindex_used = 0; /* Num of used inodes in index */ 87 | sb->onindex_free = 0; /* Num of free onodes in index */ 88 | sb->onindex_next_id = 0; /* Next ID to use */ 89 | 90 | /* FIXME: Potentially do real nasty things that can't be described 91 | * in polite circles when our structs change size... */ 92 | sb->onindex_node_size = ((sb->bsize - 4*sizeof(u64)) / sizeof(u64))/2; 93 | /* In number of keys */ 94 | 95 | return 1; /* success, although we don't check it*/ 96 | } 97 | 98 | int write_superblocks(struct fcfs_disk* disk) 99 | { 100 | struct fcfs_disk_block *block; 101 | u32 i; 102 | 103 | /* Write start of volume master SB */ 104 | block = disk_getblock(disk,0); 105 | 106 | disk->sb->flags = disk->sb->flags | FCFS_SBloc_start_volume; /* start of volume*/ 107 | 108 | disk_writeblock(block); 109 | disk_freeblock(block); 110 | fprintf(stderr,"SuperBlock at Block 0\n"); 111 | 112 | /* Write end of volume Backup SB */ 113 | block = disk_newblock(disk,disk->blocksnr-1ULL); 114 | 115 | 116 | // disk->sb->flags = disk->sb->flags & ~0x03ULL; 117 | disk->sb->flags = disk->sb->flags ^ FCFS_SBloc_start_volume; /* start of volume*/ 118 | disk->sb->flags = disk->sb->flags | FCFS_SBloc_end_volume; /* end of volume*/ 119 | 120 | memcpy(block->data,disk->sb,disk->bsize); 121 | 122 | disk_writeblock(block); 123 | disk_freeblock(block); 124 | fprintf(stderr,"BACKUP SuperBlock at Block 0x%llx\n",disk->blocksnr-1ULL); 125 | 126 | disk->sb->flags = disk->sb->flags ^ FCFS_SBloc_end_volume; /* end of volume*/ 127 | 128 | for(i=1;i<disk->sb->allocation_groupsnr;i++) 129 | { 130 | block = disk_newblock(disk,i*disk->sb->ag_blocksnr); 131 | 132 | disk->sb->flags = disk->sb->flags | FCFS_SBloc_start_ag; /* start of ag*/ 133 | memcpy(block->data,disk->sb,disk->bsize); 134 | disk_writeblock(block); 135 | disk_freeblock(block); 136 | fprintf(stderr,"BACKUP SuperBlock at Block 0x%llx (offset 0x%llx)\n",i*disk->sb->ag_blocksnr,(i*disk->sb->ag_blocksnr)*disk->bsize); 137 | } 138 | return 0; 139 | } 140 | 141 | int write_block_bitmaps(struct fcfs_disk* disk) 142 | { 143 | struct fcfs_disk_block *block; 144 | struct fcfs_block_run br; 145 | int i,j; 146 | 147 | /* Create initial empty Block Bitmap */ 148 | for(i=0;i<(disk->sb->allocation_groupsnr);i++) 149 | { 150 | /* For each ag, blank one of the right size */ 151 | for(j=0;j<space_bitmap_size(disk->sb,i);j++) 152 | { 153 | block = disk_newblock(disk,i*disk->sb->ag_blocksnr+2); 154 | memset(block->data,0,disk->bsize); 155 | fprintf(stderr,"BITMAP: Zeroing 0x%x (offset %x) length %u\n", 156 | i*disk->sb->ag_blocksnr+2, 157 | (i*disk->sb->ag_blocksnr+2)*disk->bsize, 158 | space_bitmap_size(disk->sb,i)); 159 | disk_writeblock(block); 160 | disk_freeblock(block); 161 | } 162 | } 163 | 164 | for(i=0;i<(disk->sb->allocation_groupsnr);i++) 165 | { 166 | /* Setup our Block Run */ 167 | br.allocation_group = i; 168 | br.start = 1; 169 | br.len = space_bitmap_size(disk->sb,i); 170 | 171 | space_bitmap_allocate_block(disk,i,0); 172 | 173 | for(j=0;j<space_bitmap_size(disk->sb,i);j++) 174 | space_bitmap_allocate_block(disk,i,j+1); 175 | 176 | } 177 | 178 | return 0; 179 | } 180 | 181 | int main(int argc,char* argv[]) 182 | { 183 | struct block_device bdev; 184 | struct fcfs_disk *disk; 185 | struct fcfs_disk_block *block; 186 | struct fcfs_sb *sb; 187 | struct fcfs_onode_index *index; 188 | u64 bsize; 189 | u64 bcount; 190 | char* buffer; 191 | int i; 192 | 193 | if(argc<5) 194 | { 195 | fprintf(stderr,"FCFS Make Object Store Utility (mkfs)\n"); 196 | fprintf(stderr,"-------------------------------------\n"); 197 | fprintf(stderr,"$Id: mkfs.c,v 1.23 2003/11/03 19:29:16 stewart Exp $\n\n"); 198 | fprintf(stderr,"Written by: Stewart Smith (stewart@flamingspork.com)\n\n"); 199 | fprintf(stderr,"Usage:\n\t./mkfs device blocksize blockcount name [initial objects]\n\n"); 200 | exit(0); 201 | } 202 | 203 | bsize = atou64(argv[2]); 204 | bcount = atou64(argv[3]); 205 | 206 | fprintf(stderr,"Going to create volume '%s' with 0x%llx blocks at 0x%llx bytes each\n\n",argv[4],bcount,bsize); 207 | 208 | block_dev_init(); 209 | block_dev_new(&bdev,argv[1],bsize,bcount); 210 | disk = disk_new(&bdev); 211 | 212 | if((buffer = (char*)malloc(sizeof(char*)*bsize))==0) 213 | { 214 | fprintf(stderr,"Unable to allocate buffer\n"); 215 | abort(); 216 | } 217 | 218 | /* Make a new Super Block */ 219 | block = disk_newblock(disk,0); 220 | sb = (struct fcfs_sb*)block->data; 221 | 222 | if(!make_sb(sb,disk->bsize,disk->blocksnr,argv[4])) 223 | { 224 | fprintf(stderr,"Make_sb failed\n"); 225 | abort(); 226 | } 227 | 228 | disk->sb = sb; 229 | 230 | write_superblocks(disk); 231 | 232 | write_block_bitmaps(disk); 233 | 234 | index = onode_index_new(disk); 235 | onode_index_new_root(index); 236 | 237 | for(i=5;i<argc;i++) 238 | { 239 | struct fcfs_onode1 *node; 240 | struct fcfs_block_run *onode_br; 241 | int forknr; 242 | char data[1024]; int j; 243 | FILE* a; 244 | 245 | node = onode1_new(disk); 246 | onode_br = onode_index_insert(index,node); 247 | // onode1_grow(disk,onode_br,10); 248 | // onode1_grow(disk,onode_br,20); 249 | onode1_fork_new(disk,onode_br,0x42,strlen(argv[i]),argv[i],1); 250 | forknr = onode1_fork_new(disk,onode_br,0x69,0,NULL,0); 251 | fprintf(stderr,"+++++++GOING TO GO AND WRITE %s++++++++\n",argv[5]); 252 | a = fopen(argv[i],"r"); 253 | j=0; 254 | while(!feof(a)) 255 | { 256 | fgets(data,1000,a); 257 | fprintf(stderr,"*******WRITING %d bytes*******\n",strlen(data)); 258 | onode1_fork_write(disk,onode_br,forknr,j,(u64)strlen(data),data); 259 | j+=strlen(data); 260 | } 261 | fclose(a); 262 | } 263 | 264 | disk_freeblock(block); 265 | 266 | /* Clean up and exit */ 267 | block_dev_close(&bdev); 268 | 269 | return 0; 270 | }