📄 mkfs.c
字号:
rc = init_inode_map(aggr_block_size, dev_ptr, secondary_ait_address, INODE_EXTENT_SIZE, secondary_aimap_address, aggr_inode_map_sz, INIT_NUM_AGGR_INODES + 1, AGsize, AGGREGATE_I); if (rc != 0) return rc; /* * Modify the aggregate inodes ixpxd fields */ PXDaddress(&(aggr_inodes[BMAP_I].di_ixpxd), secondary_ait_address / aggr_block_size); rc = init_aggr_inode_table(aggr_block_size, dev_ptr, aggr_inodes, INIT_NUM_AGGR_INODES, secondary_ait_address, secondary_aimap_address, aggr_inode_map_sz, inostamp); if (rc != 0) return rc; /* * Mark blocks for the block map */ first_block = BMAP_OFF / aggr_block_size; last_block = first_block + aggr_inodes[BMAP_I].di_nblocks; for (index = first_block; ((index < last_block) && (rc == 0)); index++) { rc = markit(index, ALLOC); } if (rc != 0) return rc; /* * Now we will create a fileset as necessary. * * Determine the end of the metadata written for the aggregate to tell * where to put the fileset to be created. Since the secondary * aggregate inode table is the last thing written to the aggregate, * the fileset will start following it. */ rc = create_fileset(dev_ptr, aggr_block_size, secondary_ait_end, inostamp); if (rc != 0) return rc; /* * Copy the fileset inode to the secondary aggregate inode table */ rc = ujfs_rwinode(dev_ptr, &fileset_inode, FILESYSTEM_I, GET, aggr_block_size, AGGREGATE_I, type_jfs); if (rc != 0) return rc; PXDaddress(&(fileset_inode.di_ixpxd), secondary_ait_address / aggr_block_size); /* swap if on big endian machine */ ujfs_swap_dinode(&fileset_inode, PUT, type_jfs); rc = ujfs_rw_diskblocks(dev_ptr, secondary_ait_address + FILESYSTEM_I * sizeof (struct dinode), sizeof (fileset_inode), &fileset_inode, PUT); ujfs_swap_dinode(&fileset_inode, GET, type_jfs); if (rc != 0) return rc; /* * If we are supposed to verify all blocks, now is the time to do it * * First we tell the LVM to stop doing Bad Block Relocation so we can * catch (and record) any bad blocks ourselves. Next we run through * the available file system space looking for bad blocks. Finally * we tell the LVM to go back to doing Bad Block Relocation. */ PXDaddress(&(aggr_inodes[BADBLOCK_I].di_ixpxd), AITBL_OFF / aggr_block_size); if (verify_blocks == true) { rc = verify_last_blocks(dev_ptr, aggr_block_size, &(aggr_inodes[BADBLOCK_I])); if (rc != 0) return rc; } /* * Copy the bad block inode to the secondary aggregate inode table */ PXDaddress(&(aggr_inodes[BADBLOCK_I].di_ixpxd), secondary_ait_address / aggr_block_size); /* swap if on big endian machine */ ujfs_swap_dinode(&aggr_inodes[BADBLOCK_I], PUT, type_jfs); rc = ujfs_rw_diskblocks(dev_ptr, secondary_ait_address + BADBLOCK_I * sizeof (struct dinode), sizeof (struct dinode), &(aggr_inodes[BADBLOCK_I]), PUT); ujfs_swap_dinode(&aggr_inodes[BADBLOCK_I], GET, type_jfs); if (rc != 0) return rc; /* * Now our block allocation map should be complete, write to disk */ rc = write_block_map(dev_ptr, number_of_blocks, aggr_block_size); if (rc != 0) return rc; /* * Initialize Aggregate Superblock - Both primary and secondary */ memcpy(aggr_superblock.s_magic, JFS_MAGIC, strlen(JFS_MAGIC)); /* * JFS_VERSION should have been upped to 2 when the linux-native format * split from OS/2. However, we don't want to force the use of the * latest JFS kernel code unless we're using an outline log. In that * case we want to set s_version to 2 to mandate a recent JFS driver. */ aggr_superblock.s_version = (type_jfs & JFS_INLINELOG) ? 1 : JFS_VERSION; aggr_superblock.s_size = number_of_blocks * (aggr_block_size / phys_block_size); aggr_superblock.s_bsize = aggr_block_size; aggr_superblock.s_l2bsize = log2shift(aggr_block_size); aggr_superblock.s_l2bfactor = log2shift(aggr_block_size / phys_block_size); aggr_superblock.s_pbsize = phys_block_size; aggr_superblock.s_l2pbsize = log2shift(phys_block_size); aggr_superblock.pad = 0; aggr_superblock.s_agsize = AGsize; aggr_superblock.s_flag = type_jfs; aggr_superblock.s_state = FM_CLEAN; aggr_superblock.s_compress = 0; PXDaddress(&aggr_superblock.s_ait2, secondary_ait_address / aggr_block_size); PXDlength(&aggr_superblock.s_ait2, INODE_EXTENT_SIZE / aggr_block_size); PXDaddress(&aggr_superblock.s_aim2, secondary_aimap_address); PXDlength(&aggr_superblock.s_aim2, aggr_inode_map_sz / aggr_block_size); if (logdev[0]) { struct stat st; if (stat(logdev, &st)) return errno; aggr_superblock.s_logdev = st.st_rdev; memset(&aggr_superblock.s_logpxd, 0, sizeof (pxd_t)); uuid_copy(aggr_superblock.s_loguuid, log_uuid); } else { aggr_superblock.s_logdev = 0; PXDaddress(&aggr_superblock.s_logpxd, logloc); PXDlength(&aggr_superblock.s_logpxd, logsize); } aggr_superblock.s_logserial = 0; PXDaddress(&aggr_superblock.s_fsckpxd, fsck_wspace_address); PXDlength(&aggr_superblock.s_fsckpxd, fsck_wspace_length); aggr_superblock.s_time.tv_sec = time(NULL); aggr_superblock.s_time.tv_nsec = 0; aggr_superblock.s_fsckloglen = fsck_svclog_length; aggr_superblock.s_fscklog = 0; strncpy(aggr_superblock.s_fpack, volume_label, LV_NAME_SIZE); /* extendfs stuff */ aggr_superblock.s_xsize = 0; memset(&aggr_superblock.s_xfsckpxd, 0, sizeof (pxd_t)); memset(&aggr_superblock.s_xlogpxd, 0, sizeof (pxd_t)); uuid_generate(aggr_superblock.s_uuid); strncpy(aggr_superblock.s_label, volume_label, 16); /* TODO: store log uuid */ /* Write both the primary and secondary superblocks to disk */ rc = ujfs_validate_super(&aggr_superblock); if (rc) return rc; rc = ujfs_put_superblk(dev_ptr, &aggr_superblock, 1); if (rc) return rc; rc = ujfs_put_superblk(dev_ptr, &aggr_superblock, 0); return rc;}/*-------------------------------------------------------------------- * NAME: parse_journal_opts * * FUNCTION: parse journal (-J) options * set log device name (global logdev) * set appropriate external journal flag * * PARAMETERS: * opts - options string * ext_journal_opt - external journal flag * journal_device - external journal device name */void parse_journal_opts(const char *opts, int *ext_journal_opt, char *journal_device){ int journal_usage = 0; FILE *log_fd = NULL; uuid_t log_uuid; int in_use; /* * -J device= means we're going to attach an existing * external journal to a newly formatted file system */ if (strncmp(opts, "device=", 7) == 0) { LogOpenMode = O_RDONLY; /* see if device is specified by UUID */ if (strncmp(opts + 7, "UUID=", 5) == 0) { if (uuid_parse((char *) opts + 7 + 5, log_uuid)) { fprintf(stderr, "\nError: UUID entered in improper format.\n"); exit(-1); } else { log_fd = open_by_label(log_uuid, 0, 1, journal_device, &in_use); /* * If successful, open_by_label returns a file * descriptor to an open file. For jfs_mkfs * purposes, we do not yet need that file to be * open, so close it here. */ if (log_fd == NULL) { fclose(log_fd); } else { fprintf(stderr, "\nError: Could not find/open device specified by UUID %s.\n", (char *) opts + 7 + 5); exit(-1); } } /* see if device is specified by volume label */ } else if (strncmp(opts + 7, "LABEL=", 6) == 0) { log_fd = open_by_label((char *) opts + 7 + 6, 1, 1, journal_device, &in_use); /* * If successful, open_by_label returns a file descriptor * to an open file. For jfs_mkfs purposes, we do not yet * need that file to be open, so close it here. */ if (log_fd == NULL) { fclose(log_fd); } else { fprintf(stderr, "\nError: Could not find/open device specified by LABEL %s.\n", (char *) opts + 7 + 6); exit(-1); } /* device is specified by device name */ } else { strcpy(journal_device, ((char *) opts + 7)); } if (journal_device) { *ext_journal_opt = use_existing_journal; } else { journal_usage++; } /* * -J journal_dev means we're going to * format a new external journal ONLY */ } else if (strncmp(opts, "journal_dev", 11) == 0) { *ext_journal_opt = create_journal_only; } else /* error in specified options */ journal_usage++; if (journal_usage) { fprintf(stderr, "\nInvalid journal options specified.\n\n" "Valid options for -J are:\n" "\tdevice=<journal device>\n" "\tdevice=UUID=<UUID of journal device>\n" "\tdevice=LABEL=<label of journal device>\n" "\tjournal_dev\n\n"); exit(1); } return;}/*-------------------------------------------------------------------- * NAME: format * * FUNCTION: format the specified partition as a JFS file system. * * PARAMETERS: * * RETURNS: * success: 0 * failure: any other value */int main(int argc, char *argv[]){ int c; int l2absize; char *device_name = NULL; int rc = 0; char volume_label[16] = { "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" }; int64_t number_of_bytes = 0, bytes_on_device; int64_t number_of_blocks = 0, logloc = 0, logsize_in_bytes = 0; int64_t requested_blocks = 0; char logdev[255] = { '\0' }; /* Need to use a macro for this size */ int aggr_block_size = PSIZE; /* 4096 */ int phys_block_size = PBSIZE, logsize = 0; FILE *dev_handle = NULL; unsigned type_commit = JFS_GROUPCOMMIT; bool verify_blocks = false; bool no_questions_asked = false; uuid_t log_uuid; int ext_journal_opt = 0; bool j_selected = false; char *label_ptr = NULL; if (argc && **argv) program_name = *argv; else program_name = "jfs_mkfs"; printf("%s version %s, %s\n", program_name, VERSION, JFSUTILS_DATE); type_jfs = JFS_LINUX | JFS_DIR_INDEX; /* * Parse command line arguments */ while ((c = getopt(argc, argv, "cj:J:fL:Oqs:V")) != EOF) { switch (c) {#ifdef BLOCK_SIZE /* add b: to getopt call */ case 'b': /* block size */ aggr_block_size = strtol(optarg, NULL, 0); break;#endif case 'c': /* check for bad blocks */ verify_blocks = true; break; case 'j': /* external journal device */ if (j_selected) { mkfs_usage(); return EINVAL; } else { strcpy(logdev, optarg); j_selected = true; } break; case 'J': /* external journal device */ if (j_selected) { mkfs_usage(); return EINVAL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -