diff --git a/zipl/include/disk.h b/zipl/include/disk.h index cce69f73..ff64fda7 100644 --- a/zipl/include/disk.h +++ b/zipl/include/disk.h @@ -93,6 +93,7 @@ struct device_info { * as retrieved from "/proc/devices", or evaluated */ int fs_block_size; + int align; /* alignment of component location in bootmap */ struct disk_info base[MAX_TARGETS]; /* array of physical disks for * bootstrap blocks recording */ @@ -133,13 +134,13 @@ int disk_write_block_aligned(struct misc_fd *mfd, const void *data, blocknum_t disk_write_block_buffer(struct misc_fd *fd, int fd_is_basedisk, const void* buffer, size_t bytecount, disk_blockptr_t** blocklist, - int fs_block_size, struct disk_info *info); + int fs_block_size, int align, + struct disk_info *info); blocknum_t disk_write_block_buffer_align(struct misc_fd *mfd, int fd_is_basedisk, const void *buffer, size_t bytecount, disk_blockptr_t **blocklist, - int fs_block_size, - struct disk_info *info, int align, - off_t *offset); + int fs_block_size, int align, + struct disk_info *info, off_t *offset); void disk_print_devt(dev_t d); void disk_print_devname(dev_t d); void prepare_footnote_ptr(int source, char *ptr); diff --git a/zipl/include/install.h b/zipl/include/install.h index 71dc33d9..cc1f39b7 100644 --- a/zipl/include/install.h +++ b/zipl/include/install.h @@ -160,13 +160,13 @@ int install_mvdump(char* const device[], struct job_target_data* target, int install_fba_stage1b(struct misc_fd *mfd, disk_blockptr_t **stage1b_list, blocknum_t *stage1b_count, disk_blockptr_t *stage2_list, - blocknum_t stage2_count, int fs_block_size, + blocknum_t stage2_count, int fs_block_size, int align, struct disk_info *info); int install_eckd_stage1b(struct misc_fd *mfd, disk_blockptr_t **stage1b_list, blocknum_t *stage1b_count, disk_blockptr_t *stage2_list, blocknum_t stage2_count, int fs_block_size, - struct disk_info *info); + int align, struct disk_info *info); int rewind_tape(int fd); #endif /* INSTALL_H */ diff --git a/zipl/src/bootmap.c b/zipl/src/bootmap.c index 6a72d28c..9b5d2a12 100644 --- a/zipl/src/bootmap.c +++ b/zipl/src/bootmap.c @@ -383,8 +383,8 @@ static int add_component_file_range(struct install_set *bis, 0 /* not a base disk */, buffer, size, list, bis->info->fs_block_size, + bis->info->align, info, - info->phy_block_size, /* * save component offset */ @@ -478,7 +478,7 @@ static int add_component_buffer_base(struct install_set *bis, void *buffer, align = fs_block_aligned_by_id(comp_id) ? bis->info->fs_block_size : - info->phy_block_size; + bis->info->align; if (bis->skip_prepare_device && bis->mirrors[mirror_id].skip_prepare_blocklist) @@ -486,8 +486,8 @@ static int add_component_buffer_base(struct install_set *bis, void *buffer, goto write_segment_table; /* Write buffer */ *count = disk_write_block_buffer_align(&bis->mfd, 0, buffer, size, list, - bis->info->fs_block_size, - info, align, &offset); + bis->info->fs_block_size, align, + info, &offset); if (*count == 0) { error_text("Could not write to bootmap file"); return -1; @@ -1265,7 +1265,7 @@ write_empty_block(struct misc_fd *mfd, disk_blockptr_t *block, static int install_stages_dasd_fba(struct misc_fd *mfd, char *filename, struct job_data *job, - int fs_block_size, + int fs_block_size, int align, struct disk_info *info, disk_blockptr_t **stage1b_list, blocknum_t *stage1b_count, @@ -1289,6 +1289,7 @@ static int install_stages_dasd_fba(struct misc_fd *mfd, char *filename, stage2_size, &stage2_list, fs_block_size, + align, info); free(stage2_data); if (stage2_count == 0) { @@ -1297,7 +1298,7 @@ static int install_stages_dasd_fba(struct misc_fd *mfd, char *filename, } if (install_fba_stage1b(mfd, stage1b_list, stage1b_count, stage2_list, stage2_count, - fs_block_size, info)) + fs_block_size, align, info)) return -1; free(stage2_list); break; @@ -1317,7 +1318,7 @@ static int install_stages_dasd_fba(struct misc_fd *mfd, char *filename, static int install_stages_eckd_dasd(struct misc_fd *mfd, char *filename, struct job_data *job, - int fs_block_size, + int fs_block_size, int align, struct disk_info *info, disk_blockptr_t *program_table, disk_blockptr_t **stage1b_list, @@ -1341,6 +1342,7 @@ static int install_stages_eckd_dasd(struct misc_fd *mfd, char *filename, stage2b_size, &stage2b_list, fs_block_size, + align, info); free(stage2b_data); if (stage2b_count == 0) { @@ -1349,7 +1351,7 @@ static int install_stages_eckd_dasd(struct misc_fd *mfd, char *filename, } if (install_eckd_stage1b(mfd, stage1b_list, stage1b_count, stage2b_list, stage2b_count, - fs_block_size, info)) + fs_block_size, align, info)) return -1; free(stage2b_list); break; @@ -1367,6 +1369,7 @@ static int install_stages_eckd_dasd(struct misc_fd *mfd, char *filename, stage2b_size, stage1b_list, fs_block_size, + align, info); free(stage2b_data); if (stage2b_count == 0) { @@ -1395,6 +1398,7 @@ static int bootmap_install_stages(struct job_data *job, struct install_set *bis, case disk_type_fba: rc = install_stages_dasd_fba(&bis->mfd, bis->filename, job, bis->info->fs_block_size, + bis->info->align, info, &pt->stage1b_list, &pt->stage1b_count, @@ -1404,6 +1408,7 @@ static int bootmap_install_stages(struct job_data *job, struct install_set *bis, case disk_type_eckd_cdl: rc = install_stages_eckd_dasd(&bis->mfd, bis->filename, job, bis->info->fs_block_size, + bis->info->align, info, &pt->table, &pt->stage1b_list, diff --git a/zipl/src/disk.c b/zipl/src/disk.c index 673224fb..b2f2561d 100644 --- a/zipl/src/disk.c +++ b/zipl/src/disk.c @@ -575,7 +575,21 @@ static int disk_set_info_complete(struct job_target_data *td, return 0; } -static int device_set_info_complete(struct device_info *dev_info) +static void device_get_alignment(struct device_info *dev_info, + struct job_target_data *td) +{ + struct disk_info *base; + int i; + + for (i = 0; i < td->nr_targets; i++) { + base = &dev_info->base[i]; + if (dev_info->align < base->phy_block_size) + dev_info->align = base->phy_block_size; + } +} + +static int device_set_info_complete(struct device_info *dev_info, + struct job_target_data *td) { struct util_proc_part_entry part_entry; @@ -588,6 +602,7 @@ static int device_set_info_complete(struct device_info *dev_info) } /* Initialize file system block size with invalid value */ dev_info->fs_block_size = -1; + device_get_alignment(dev_info, td); return 0; } @@ -689,7 +704,7 @@ int device_get_info(const char *device, struct job_target_data *td, if (disk_set_info_complete(td, &data->base[i], &stats, fd)) goto error; } - if (device_set_info_complete(data)) + if (device_set_info_complete(data, td)) goto error; free(script_file); close(fd); @@ -1017,7 +1032,7 @@ blocknum_t disk_write_block_buffer_align(struct misc_fd *mfd, int fd_is_basedisk, const void *buffer, size_t bytecount, disk_blockptr_t **blocklist, int fs_block_size, - struct disk_info *info, int align, off_t *offset) + int align, struct disk_info *info, off_t *offset) { blocknum_t count; blocknum_t i; @@ -1058,12 +1073,12 @@ blocknum_t disk_write_block_buffer(struct misc_fd *mfd, int fd_is_basedisk, const void *buffer, size_t bytecount, disk_blockptr_t **blocklist, int fs_block_size, - struct disk_info *info) + int align, struct disk_info *info) { return disk_write_block_buffer_align(mfd, fd_is_basedisk, buffer, bytecount, blocklist, - fs_block_size, info, - info->phy_block_size, NULL); + fs_block_size, align, info, + NULL); } /* Print device node. */ diff --git a/zipl/src/install.c b/zipl/src/install.c index 176a0043..1baf153f 100644 --- a/zipl/src/install.c +++ b/zipl/src/install.c @@ -172,7 +172,7 @@ install_fba_ccw(int fd, disk_blockptr_t *program_table, int install_eckd_stage1b(struct misc_fd *mfd, disk_blockptr_t **stage1b_list, blocknum_t *stage1b_count, disk_blockptr_t *stage2_list, - blocknum_t stage2_count, int fs_block_size, + blocknum_t stage2_count, int fs_block_size, int align, struct disk_info *info) { struct boot_eckd_stage1b *stage1b; @@ -189,7 +189,7 @@ install_eckd_stage1b(struct misc_fd *mfd, disk_blockptr_t **stage1b_list, goto out_free_stage1b; *stage1b_count = disk_write_block_buffer(mfd, 1, stage1b, stage1b_size, stage1b_list, fs_block_size, - info); + align, info); if (*stage1b_count == 0) goto out_free_stage1b; rc = 0; @@ -855,7 +855,7 @@ static void eckd_dump_store_param(struct eckd_dump_param *param, static int install_svdump_eckd_ldl(struct misc_fd *mfd, int fs_block_size, - struct disk_info *info, + int align, struct disk_info *info, const struct stage2dump_parm_tail *stage2dump_parms) { disk_blockptr_t *stage2_list, *stage1b_list; @@ -879,13 +879,13 @@ install_svdump_eckd_ldl(struct misc_fd *mfd, int fs_block_size, if (misc_seek(mfd->fd, info->geo.start * info->phy_block_size)) goto out_free_stage2; stage2_count = disk_write_block_buffer(mfd, 1, stage2, stage2_size, - &stage2_list, - fs_block_size, info); + &stage2_list, fs_block_size, + align, info); if (stage2_count == 0) goto out_free_stage2_list; if (install_eckd_stage1b(mfd, &stage1b_list, &stage1b_count, stage2_list, stage2_count, fs_block_size, - info)) + align, info)) goto out_free_stage2_list; /* Install stage 0 - afterwards we are at stage 1 position*/ boot_init_eckd_ldl_stage0(&stage0); @@ -913,8 +913,8 @@ out: } static int install_dump_eckd_cdl(struct misc_fd *mfd, int fs_block_size, - struct disk_info *info, void *stage2, - size_t stage2_size, int mvdump, + int align, struct disk_info *info, + void *stage2, size_t stage2_size, int mvdump, int force) { blocknum_t count, stage2_count, stage1b_count; @@ -939,13 +939,13 @@ static int install_dump_eckd_cdl(struct misc_fd *mfd, int fs_block_size, goto out; stage2_count = disk_write_block_buffer(mfd, 1, stage2, stage2_size, &stage2_list, fs_block_size, - info); + align, info); if (stage2_count == 0) goto out; /* Install stage 1b behind stage 2*/ if (install_eckd_stage1b(mfd, &stage1b_list, &stage1b_count, stage2_list, stage2_count, fs_block_size, - info)) + align, info)) goto out_free_stage2_list; /* Install stage 0 */ boot_init_eckd_cdl_stage0(&stage0_cdl); @@ -973,7 +973,7 @@ out: static int install_svdump_eckd_cdl(struct misc_fd *mfd, int fs_block_size, - struct disk_info *info, + int align, struct disk_info *info, const struct stage2dump_parm_tail *stage2dump_parms) { size_t stage2_size; @@ -982,7 +982,7 @@ install_svdump_eckd_cdl(struct misc_fd *mfd, int fs_block_size, if (boot_get_eckd_dump_stage2(&stage2, &stage2_size, stage2dump_parms)) return -1; - rc = install_dump_eckd_cdl(mfd, fs_block_size, + rc = install_dump_eckd_cdl(mfd, fs_block_size, align, info, stage2, stage2_size, 0, 0); free(stage2); return rc; @@ -990,7 +990,7 @@ install_svdump_eckd_cdl(struct misc_fd *mfd, int fs_block_size, static int install_mvdump_eckd_cdl(struct misc_fd *mfd, int fs_block_size, - struct disk_info *info, + int align, struct disk_info *info, const struct stage2dump_parm_tail *stage2dump_parms, const struct mvdump_parm_table *mv_parm_table) { @@ -1002,7 +1002,7 @@ install_mvdump_eckd_cdl(struct misc_fd *mfd, int fs_block_size, if (boot_get_eckd_mvdump_stage2(&stage2, &stage2_size, stage2dump_parms, mv_parm_table)) return -1; - rc = install_dump_eckd_cdl(mfd, fs_block_size, info, stage2, + rc = install_dump_eckd_cdl(mfd, fs_block_size, align, info, stage2, stage2_size, 1, stage2dump_parms->mvdump_force); free(stage2); @@ -1012,7 +1012,7 @@ install_mvdump_eckd_cdl(struct misc_fd *mfd, int fs_block_size, int install_fba_stage1b(struct misc_fd *mfd, disk_blockptr_t **stage1b_list, blocknum_t *stage1b_count, disk_blockptr_t *stage2_list, - blocknum_t stage2_count, int fs_block_size, + blocknum_t stage2_count, int fs_block_size, int align, struct disk_info *info) { struct boot_fba_stage1b *stage1b; @@ -1029,7 +1029,7 @@ install_fba_stage1b(struct misc_fd *mfd, disk_blockptr_t **stage1b_list, goto out_free_stage1b; *stage1b_count = disk_write_block_buffer(mfd, 1, stage1b, stage1b_size, stage1b_list, fs_block_size, - info); + align, info); if (*stage1b_count == 0) goto out_free_stage1b; rc = 0; @@ -1041,7 +1041,7 @@ out: static int install_svdump_fba(struct misc_fd *mfd, int fs_block_size, - struct disk_info *info, + int align, struct disk_info *info, const struct stage2dump_parm_tail *stage2dump_parms) { blocknum_t stage1b_count, stage2_count, blk; @@ -1067,7 +1067,7 @@ install_svdump_fba(struct misc_fd *mfd, int fs_block_size, goto out_free_stage2; stage2_count = disk_write_block_buffer(mfd, 1, stage2, stage2_size, &stage2_list, fs_block_size, - info); + align, info); if (stage2_count == 0) goto out_free_stage2; /* Install stage 1b in front of stage 2 */ @@ -1075,7 +1075,8 @@ install_svdump_fba(struct misc_fd *mfd, int fs_block_size, if (misc_seek(mfd->fd, blk * info->phy_block_size)) goto out_free_stage2_list; if (install_fba_stage1b(mfd, &stage1b_list, &stage1b_count, - stage2_list, stage2_count, fs_block_size, info)) + stage2_list, stage2_count, fs_block_size, + align, info)) goto out_free_stage2_list; /* Install stage 0/1 fill in dump partition parameter */ if (boot_init_fba_stage0(&stage0, stage1b_list, stage1b_count)) @@ -1219,14 +1220,17 @@ install_dump(const char *device, struct job_target_data *target, uint64_t mem, if (info->type == disk_type_eckd_ldl) rc = install_svdump_eckd_ldl(&mfd, dev_info->fs_block_size, - info, &stage2dump_parms); + dev_info->align, info, + &stage2dump_parms); else if (info->type == disk_type_eckd_cdl) rc = install_svdump_eckd_cdl(&mfd, dev_info->fs_block_size, - info, &stage2dump_parms); + dev_info->align, info, + &stage2dump_parms); else rc = install_svdump_fba(&mfd, dev_info->fs_block_size, - info, &stage2dump_parms); + dev_info->align, info, + &stage2dump_parms); break; case disk_type_scsi: error_reason("%s: Unsupported disk type '%s' (try --dumptofs)", @@ -1382,8 +1386,8 @@ install_mvdump(char* const device[], struct job_target_data* target, int count, printf("Installing dump record on target partition " "'%s'\n", device[i]); rc = install_mvdump_eckd_cdl(&mfd, dev_info[i]->fs_block_size, - info[i], &stage2dump_parms, - &mvdump_parms); + dev_info[i]->align, info[i], + &stage2dump_parms, &mvdump_parms); misc_free_temp_dev(tempdev); if (fsync(mfd.fd))