Changeset 59e670e in mainline
- Timestamp:
- 2011-03-08T15:38:55Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 410a065
- Parents:
- f5cbd4f
- Location:
- uspace
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/mkminix/mkminix.c
rf5cbd4f r59e670e 62 62 } help_level_t; 63 63 64 typedef struct mfs_params { 65 int fs_version; 66 devmap_handle_t handle; 67 uint16_t fs_magic; 68 uint32_t block_size; 69 size_t devblock_size; 70 unsigned long n_inodes; 71 aoff64_t dev_nblocks; 72 bool fs_longnames; 73 } mfs_params_t; 64 /*Generic MFS superblock*/ 65 struct mfs_sb_info { 66 devmap_handle_t handle; 67 uint64_t n_inodes; 68 uint64_t n_zones; 69 aoff64_t dev_nblocks; 70 aoff64_t devblock_size; 71 unsigned long ibmap_blocks; 72 unsigned long zbmap_blocks; 73 unsigned long first_data_zone; 74 int log2_zone_size; 75 int ino_per_block; 76 uint32_t max_file_size; 77 uint16_t magic; 78 uint32_t block_size; 79 int fs_version; 80 bool longnames; 81 }; 74 82 75 83 static void help_cmd_mkminix(help_level_t level); 76 84 static int num_of_set_bits(uint32_t n); 77 static void init_superblock(struct mfs_superblock *sb, mfs_params_t *opt); 78 static void init_superblock_v3(struct mfs3_superblock *sb, 79 mfs_params_t *opt); 80 static void init_bitmaps(uint32_t ninodes, uint32_t nzones, 81 int bsize, mfs_params_t *opt); 82 static void mark_bmap(uint8_t *bmap, int idx, int v); 85 static void init_superblock(struct mfs_sb_info *sb); 86 static void write_superblock(struct mfs_sb_info *sbi); 87 static void write_superblock3(struct mfs_sb_info *sbi); 88 static void init_bitmaps(struct mfs_sb_info *sb); 89 static void mark_bmap(uint32_t *bmap, int idx, int v); 83 90 84 91 static struct option const long_options[] = { … … 97 104 int rc, c, opt_ind; 98 105 char *device_name; 99 100 struct mfs_superblock *sb; 101 struct mfs3_superblock *sb3; 102 103 mfs_params_t opt; 106 107 struct mfs_sb_info sb; 104 108 105 109 /*Default is MinixFS V3*/ 106 opt.fs_magic = MFS_MAGIC_V3;110 sb.magic = MFS_MAGIC_V3; 107 111 108 112 /*Default block size is 4Kb*/ 109 opt.block_size = MFS_MAX_BLOCKSIZE; 110 opt.n_inodes = 0; 111 opt.fs_longnames = false; 113 sb.block_size = MFS_MAX_BLOCKSIZE; 114 sb.n_inodes = 0; 115 sb.longnames = false; 116 sb.ino_per_block = V3_INODES_PER_BLOCK(MFS_MAX_BLOCKSIZE); 112 117 113 118 if (argc == 1) { … … 124 129 exit(0); 125 130 case '1': 126 opt.fs_magic = MFS_MAGIC_V1; 127 opt.block_size = MFS_BLOCKSIZE; 128 opt.fs_version = 1; 131 sb.magic = MFS_MAGIC_V1; 132 sb.block_size = MFS_BLOCKSIZE; 133 sb.fs_version = 1; 134 sb.ino_per_block = V1_INODES_PER_BLOCK; 129 135 break; 130 136 case '2': 131 opt.fs_magic = MFS_MAGIC_V2; 132 opt.block_size = MFS_BLOCKSIZE; 133 opt.fs_version = 2; 137 sb.magic = MFS_MAGIC_V2; 138 sb.block_size = MFS_BLOCKSIZE; 139 sb.fs_version = 2; 140 sb.ino_per_block = V2_INODES_PER_BLOCK; 134 141 break; 135 142 case '3': 136 opt.fs_magic = MFS_MAGIC_V3; 137 opt.fs_version = 3; 143 sb.magic = MFS_MAGIC_V3; 144 sb.fs_version = 3; 145 sb.block_size = MFS_MAX_BLOCKSIZE; 138 146 break; 139 147 case 'b': 140 opt.block_size = (uint32_t) strtol(optarg, NULL, 10);148 sb.block_size = (uint32_t) strtol(optarg, NULL, 10); 141 149 break; 142 150 case 'i': 143 opt.n_inodes = (unsigned long) strtol(optarg, NULL, 10);151 sb.n_inodes = (unsigned long) strtol(optarg, NULL, 10); 144 152 break; 145 153 case 'l': 146 opt.fs_longnames = true;154 sb.longnames = true; 147 155 break; 148 156 } 149 157 } 150 158 151 if ( opt.block_size < MFS_MIN_BLOCKSIZE ||152 opt.block_size > MFS_MAX_BLOCKSIZE) {159 if (sb.block_size < MFS_MIN_BLOCKSIZE || 160 sb.block_size > MFS_MAX_BLOCKSIZE) { 153 161 printf(NAME ":Error! Invalid block size.\n"); 154 162 exit(0); 155 } else if (num_of_set_bits( opt.block_size) != 1) {163 } else if (num_of_set_bits(sb.block_size) != 1) { 156 164 /*Block size must be a power of 2.*/ 157 165 printf(NAME ":Error! Invalid block size.\n"); 158 166 exit(0); 159 } else if ( opt.block_size > MFS_BLOCKSIZE &&160 opt.fs_magic != MFS_MAGIC_V3) {167 } else if (sb.block_size > MFS_BLOCKSIZE && 168 sb.fs_version != 3) { 161 169 printf(NAME ":Error! Block size > 1024 is supported by V3 filesystem only.\n"); 162 170 exit(0); 163 } else if ( opt.fs_magic == MFS_MAGIC_V3 && opt.fs_longnames) {171 } else if (sb.fs_version == 3 && sb.longnames) { 164 172 printf(NAME ":Error! Long filenames are supported by V1/V2 filesystem only.\n"); 165 173 exit(0); … … 175 183 } 176 184 177 rc = devmap_device_get_handle(device_name, & opt.handle, 0);185 rc = devmap_device_get_handle(device_name, &sb.handle, 0); 178 186 if (rc != EOK) { 179 187 printf(NAME ": Error resolving device `%s'.\n", device_name); … … 181 189 } 182 190 183 rc = block_init( opt.handle, MFS_MIN_BLOCKSIZE);191 rc = block_init(sb.handle, MFS_MIN_BLOCKSIZE); 184 192 if (rc != EOK) { 185 193 printf(NAME ": Error initializing libblock.\n"); … … 187 195 } 188 196 189 rc = block_get_bsize( opt.handle, &opt.devblock_size);197 rc = block_get_bsize(sb.handle, &sb.devblock_size); 190 198 if (rc != EOK) { 191 199 printf(NAME ": Error determining device block size.\n"); … … 193 201 } 194 202 195 rc = block_get_nblocks( opt.handle, &opt.dev_nblocks);203 rc = block_get_nblocks(sb.handle, &sb.dev_nblocks); 196 204 if (rc != EOK) { 197 205 printf(NAME ": Warning, failed to obtain block device size.\n"); 198 206 } else { 199 207 printf(NAME ": Block device has %" PRIuOFF64 " blocks.\n", 200 opt.dev_nblocks);201 } 202 203 if ( opt.devblock_size != 512) {208 sb.dev_nblocks); 209 } 210 211 if (sb.devblock_size != 512) { 204 212 printf(NAME ": Error. Device block size is not 512 bytes.\n"); 205 213 return 2; … … 207 215 208 216 /*Minimum block size is 1 Kb*/ 209 opt.dev_nblocks /= 2;217 sb.dev_nblocks /= 2; 210 218 211 219 printf(NAME ": Creating Minix file system on device\n"); 212 220 213 /*Setting up superblock*/ 214 215 if (opt.fs_magic == MFS_MAGIC_V3) { 216 sb3 = (struct mfs3_superblock *) malloc(sizeof(struct mfs3_superblock)); 217 if (!sb3) { 218 printf(NAME ": Error, not enough memory"); 219 return 2; 221 /*Initialize superblock*/ 222 init_superblock(&sb); 223 224 /*Initialize bitmaps*/ 225 init_bitmaps(&sb); 226 227 return 0; 228 } 229 230 static void init_superblock(struct mfs_sb_info *sb) 231 { 232 aoff64_t inodes; 233 234 if (sb->longnames) 235 sb->magic = sb->fs_version == 1 ? MFS_MAGIC_V1L : MFS_MAGIC_V2L; 236 237 /*Compute the number of zones on disk*/ 238 239 if (sb->fs_version == 1) { 240 /*Valid only for MFS V1*/ 241 sb->n_zones = sb->dev_nblocks > UINT16_MAX ? 242 UINT16_MAX : sb->dev_nblocks; 243 } else { 244 /*Valid for MFS V2/V3*/ 245 sb->n_zones = sb->dev_nblocks > UINT32_MAX ? 246 UINT32_MAX : sb->dev_nblocks; 247 248 if (sb->fs_version == 3) { 249 sb->ino_per_block = V3_INODES_PER_BLOCK(sb->block_size); 250 sb->n_zones /= (sb->block_size / MFS_MIN_BLOCKSIZE); 220 251 } 221 init_superblock_v3(sb3, &opt); 222 init_bitmaps(sb3->s_ninodes, sb3->s_nzones, sb3->s_block_size, &opt); 223 } else { 224 sb = (struct mfs_superblock *) malloc(sizeof(struct mfs_superblock)); 225 if (!sb) { 226 printf(NAME ": Error, not enough memory"); 227 return 2; 228 } 229 init_superblock(sb, &opt); 230 init_bitmaps(sb->s_ninodes, sb->s_nzones, MFS_BLOCKSIZE, &opt); 231 } 232 233 return 0; 234 } 235 236 static void init_superblock(struct mfs_superblock *sb, mfs_params_t *opt) 237 { 238 int ino_per_block = 0; 239 aoff64_t inodes; 240 241 if (opt->fs_version == 1) { 242 ino_per_block = V1_INODES_PER_BLOCK; 243 if (opt->fs_longnames) 244 opt->fs_magic = MFS_MAGIC_V1L; 245 } else { 246 ino_per_block = V2_INODES_PER_BLOCK; 247 if (opt->fs_longnames) 248 opt->fs_magic = MFS_MAGIC_V2L; 249 } 250 251 sb->s_magic = opt->fs_magic; 252 253 /*Compute the number of zones on disk*/ 254 255 /*Valid only for MFS V1*/ 256 sb->s_nzones = opt->dev_nblocks > UINT16_MAX ? 257 UINT16_MAX : opt->dev_nblocks; 258 259 /*Valid only for MFS V2*/ 260 sb->s_nzones2 = opt->dev_nblocks > UINT32_MAX ? 261 UINT32_MAX : opt->dev_nblocks; 252 } 262 253 263 254 /*Round up the number of inodes to fill block size*/ 264 if (opt->n_inodes == 0) 265 inodes = opt->dev_nblocks / 3; 255 if (sb->n_inodes == 0) 256 inodes = sb->dev_nblocks / 3; 257 258 if (inodes % sb->ino_per_block) 259 inodes = ((inodes / sb->ino_per_block) + 1) * sb->ino_per_block; 260 261 if (sb->fs_version < 3) 262 sb->n_inodes = inodes > UINT16_MAX ? UINT16_MAX : inodes; 266 263 else 267 inodes = opt->n_inodes; 268 269 if (inodes % ino_per_block) 270 inodes = ((inodes / ino_per_block) + 1) * ino_per_block; 271 sb->s_ninodes = inodes > UINT16_MAX ? UINT16_MAX : inodes; 264 sb->n_inodes = inodes > UINT32_MAX ? UINT32_MAX : inodes; 272 265 273 266 /*Compute inode bitmap size in blocks*/ 274 sb-> s_ibmap_blocks = UPPER(sb->s_ninodes, MFS_BLOCKSIZE* 8);267 sb->ibmap_blocks = UPPER(sb->n_inodes, sb->block_size * 8); 275 268 276 269 /*Compute zone bitmap size in blocks*/ 277 if (opt->fs_version == 1) 278 sb->s_zbmap_blocks = UPPER(sb->s_nzones, MFS_BLOCKSIZE * 8); 270 sb->zbmap_blocks = UPPER(sb->n_zones, sb->block_size * 8); 271 272 /*Compute inode table size*/ 273 unsigned long ninodes_blocks = sb->n_inodes / sb->ino_per_block; 274 275 /*Compute first data zone position*/ 276 sb->first_data_zone = 2 + ninodes_blocks + 277 sb->zbmap_blocks + sb->ibmap_blocks; 278 279 /*Set log2 of zone to block ratio to zero*/ 280 sb->log2_zone_size = 0; 281 282 /*Superblock is now ready to be written on disk*/ 283 printf(NAME ": %d inodes\n", (uint32_t) sb->n_inodes); 284 printf(NAME ": %d zones\n", (uint32_t) sb->n_zones); 285 printf(NAME ": inode table blocks = %ld\n", ninodes_blocks); 286 printf(NAME ": first data zone = %d\n", (uint32_t) sb->first_data_zone); 287 printf(NAME ": long fnames = %s\n", sb->longnames ? "Yes" : "No"); 288 289 if (sb->fs_version == 3) 290 write_superblock3(sb); 279 291 else 280 sb->s_zbmap_blocks = UPPER(sb->s_nzones2, MFS_BLOCKSIZE * 8); 281 282 /*Compute inode table size*/ 283 unsigned long ninodes_blocks = sb->s_ninodes / ino_per_block; 284 285 /*Compute first data zone position*/ 286 sb->s_first_data_zone = 2 + ninodes_blocks + 287 sb->s_zbmap_blocks + sb->s_ibmap_blocks; 288 289 /*Set log2 of zone to block ratio to zero*/ 290 sb->s_log2_zone_size = 0; 291 292 /*Superblock is now ready to be written on disk*/ 293 printf(NAME ": %d inodes\n", sb->s_ninodes); 294 printf(NAME ": %d zones\n", sb->s_nzones2); 295 printf(NAME ": inode table blocks = %ld\n", ninodes_blocks); 296 printf(NAME ": first data zone = %d\n", sb->s_first_data_zone); 297 printf(NAME ": long fnames = %s\n", opt->fs_longnames ? "Yes" : "No"); 298 299 block_write_direct(opt->handle, MFS_SUPERBLOCK, 1, sb); 300 } 301 302 static void init_superblock_v3(struct mfs3_superblock *sb, mfs_params_t *opt) 303 { 304 int ino_per_block; 305 int bs; 306 aoff64_t inodes; 307 308 sb->s_magic = opt->fs_magic; 309 bs = opt->block_size; 310 311 if (opt->n_inodes == 0) 312 inodes = opt->dev_nblocks / 3; 292 write_superblock(sb); 293 } 294 295 static void write_superblock(struct mfs_sb_info *sbi) 296 { 297 struct mfs_superblock *sb; 298 uint8_t *superblock_buf; 299 300 superblock_buf = malloc(1024); 301 302 sb = (struct mfs_superblock *) superblock_buf; 303 304 sb->s_ninodes = (uint16_t) sbi->n_inodes; 305 sb->s_nzones = (uint16_t) sbi->n_zones; 306 sb->s_nzones2 = (uint32_t) sbi->n_zones; 307 sb->s_ibmap_blocks = (uint16_t) sbi->ibmap_blocks; 308 sb->s_zbmap_blocks = (uint16_t) sbi->zbmap_blocks; 309 sb->s_first_data_zone = (uint16_t) sbi->first_data_zone; 310 sb->s_log2_zone_size = sbi->log2_zone_size; 311 sb->s_max_file_size = UINT32_MAX; 312 sb->s_magic = sbi->magic; 313 sb->s_state = MFS_VALID_FS; 314 315 block_write_direct(sbi->handle, MFS_SUPERBLOCK, 1, sb); 316 free(superblock_buf); 317 } 318 319 static void write_superblock3(struct mfs_sb_info *sbi) 320 { 321 struct mfs3_superblock *sb; 322 uint8_t *superblock_buf; 323 324 superblock_buf = malloc(1024); 325 326 sb = (struct mfs3_superblock *) superblock_buf; 327 328 sb->s_ninodes = (uint32_t) sbi->n_inodes; 329 sb->s_nzones = (uint32_t) sbi->n_zones; 330 sb->s_ibmap_blocks = (uint16_t) sbi->ibmap_blocks; 331 sb->s_zbmap_blocks = (uint16_t) sbi->zbmap_blocks; 332 sb->s_first_data_zone = (uint16_t) sbi->first_data_zone; 333 sb->s_log2_zone_size = sbi->log2_zone_size; 334 sb->s_max_file_size = UINT32_MAX; 335 sb->s_magic = sbi->magic; 336 sb->s_block_size = sbi->block_size; 337 sb->s_disk_version = 3; 338 339 block_write_direct(sbi->handle, MFS_SUPERBLOCK, 1, sb); 340 free(superblock_buf); 341 } 342 343 static void init_bitmaps(struct mfs_sb_info *sb) 344 { 345 uint32_t *ibmap_buf, *zbmap_buf; 346 int ibmap_nblocks = 1 + (sb->n_inodes / 8) / sb->block_size; 347 int zbmap_nblocks = 1 + (sb->n_zones / 8) / sb->block_size; 348 unsigned int i; 349 350 ibmap_buf = (uint32_t *) malloc(ibmap_nblocks * sb->block_size); 351 zbmap_buf = (uint32_t *) malloc(zbmap_nblocks * sb->block_size); 352 353 memset(ibmap_buf, 0xFF, ibmap_nblocks * sb->block_size); 354 memset(zbmap_buf, 0xFF, zbmap_nblocks * sb->block_size); 355 356 for (i = 2; i < sb->n_inodes; ++i) 357 mark_bmap(ibmap_buf, i, FREE); 358 359 for (i = 2; i < sb->n_zones; ++i) 360 mark_bmap(zbmap_buf, i, FREE); 361 362 ibmap_nblocks *= sb->block_size / MFS_BLOCKSIZE; 363 zbmap_nblocks *= sb->block_size / MFS_BLOCKSIZE; 364 365 block_write_direct(sb->handle, 2, ibmap_nblocks, ibmap_buf); 366 block_write_direct(sb->handle, 2 + ibmap_nblocks, zbmap_nblocks, zbmap_buf); 367 } 368 369 static void mark_bmap(uint32_t *bmap, int idx, int v) 370 { 371 if (v == FREE) 372 bmap[idx / 32] &= ~(1 << (idx % 32)); 313 373 else 314 inodes = opt->n_inodes; 315 316 /*Round up the number of inodes to fill block size*/ 317 ino_per_block = V3_INODES_PER_BLOCK(bs); 318 if (inodes % ino_per_block) 319 inodes = ((inodes / ino_per_block) + 1) * ino_per_block; 320 sb->s_ninodes = inodes > UINT32_MAX ? UINT32_MAX : inodes; 321 322 /*Compute the number of zones on disk*/ 323 sb->s_nzones = opt->dev_nblocks > UINT32_MAX ? 324 UINT32_MAX : opt->dev_nblocks; 325 sb->s_nzones /= (bs / MFS_MIN_BLOCKSIZE); 326 327 /*Compute inode bitmap size in blocks*/ 328 sb->s_ibmap_blocks = UPPER(sb->s_ninodes, bs * 8); 329 330 /*Compute zone bitmap size in blocks*/ 331 sb->s_zbmap_blocks = UPPER(sb->s_nzones, bs * 8); 332 333 /*Compute inode table size*/ 334 unsigned long ninodes_blocks = sb->s_ninodes / ino_per_block; 335 336 /*Compute first data zone position*/ 337 sb->s_first_data_zone = 2 + ninodes_blocks + 338 sb->s_zbmap_blocks + sb->s_ibmap_blocks; 339 340 /*Set log2 of zone to block ratio to zero*/ 341 sb->s_log2_zone_size = 0; 342 sb->s_disk_version = 3; 343 sb->s_block_size = bs; 344 345 /*Superblock is now ready to be written on disk*/ 346 printf(NAME ": %d inodes\n", sb->s_ninodes); 347 printf(NAME ": %d zones\n", sb->s_nzones); 348 printf(NAME ": block size = %d\n", sb->s_block_size); 349 printf(NAME ": inode table blocks = %ld\n", ninodes_blocks); 350 printf(NAME ": first data zone = %d\n", sb->s_first_data_zone); 351 352 block_write_direct(opt->handle, MFS_SUPERBLOCK, 1, sb); 353 } 354 355 static void init_bitmaps(uint32_t ninodes, uint32_t nzones, 356 int bsize, mfs_params_t *opt) 357 { 358 uint8_t *ibmap_buf, *zbmap_buf; 359 int ibmap_nblocks = 1 + (ninodes / 8) / bsize; 360 int zbmap_nblocks = 1 + (nzones / 8) / bsize; 361 unsigned int i; 362 363 ibmap_buf = (uint8_t *) malloc(ibmap_nblocks * bsize); 364 zbmap_buf = (uint8_t *) malloc(zbmap_nblocks * bsize); 365 366 memset(ibmap_buf, 0xFF, ibmap_nblocks * bsize); 367 memset(zbmap_buf, 0xFF, zbmap_nblocks * bsize); 368 369 for (i = 2; i < ninodes; ++i) 370 mark_bmap(ibmap_buf, i, FREE); 371 372 for (i = 2; i < nzones; ++i) 373 mark_bmap(zbmap_buf, i, FREE); 374 375 ibmap_nblocks *= bsize / MFS_BLOCKSIZE; 376 zbmap_nblocks *= bsize / MFS_BLOCKSIZE; 377 378 block_write_direct(opt->handle, 2, ibmap_nblocks, ibmap_buf); 379 block_write_direct(opt->handle, 2 + ibmap_nblocks, zbmap_nblocks, zbmap_buf); 380 } 381 382 static void mark_bmap(uint8_t *bmap, int idx, int v) 383 { 384 if (v == FREE) 385 bmap[idx / 8] &= ~(1 << (idx % 8)); 386 else 387 bmap[idx / 8] |= 1 << (idx % 8); 374 bmap[idx / 32] |= 1 << (idx % 32); 388 375 } 389 376 -
uspace/lib/minix/minix.h
rf5cbd4f r59e670e 75 75 #define MFS_MAGIC_V3R 0x5A4D 76 76 77 #define MFS_VALID_FS 0x0001 78 #define MFS_ERROR_FS 0x0002 79 77 80 /*MFS V1/V2 superblock data on disk*/ 78 81 struct mfs_superblock { … … 118 121 int16_t s_pad1; 119 122 /*Maximum file size expressed in bytes*/ 120 int32_ts_max_file_size;123 uint32_t s_max_file_size; 121 124 /*Total number of zones on the device*/ 122 125 uint32_t s_nzones;
Note:
See TracChangeset
for help on using the changeset viewer.