mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
zipl: expand interface of disk_get_blocklist_from_file
. expand interface of disk_get_blocklist_from_file() to get block pointers for a specific range of data within a file. . provide a helper function add_component_file_range() to add a specific range of data within a file as a boot component. This will be used by a later patch. Reviewed-by: Stefan Haberland <sth@linux.ibm.com> Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com> Signed-off-by: Eduard Shishkin <edward6@linux.ibm.com> Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
committed by
Jan Höppner
parent
a0b8033088
commit
2ae44cb794
@@ -90,6 +90,11 @@ struct disk_info {
|
||||
definition_t targetbase;
|
||||
};
|
||||
|
||||
struct file_range {
|
||||
off_t offset;
|
||||
size_t len;
|
||||
};
|
||||
|
||||
struct job_target_data;
|
||||
|
||||
int disk_get_info(const char* device, struct job_target_data* target,
|
||||
@@ -119,6 +124,7 @@ int disk_is_zero_block(disk_blockptr_t* block, struct disk_info* info);
|
||||
blocknum_t disk_compact_blocklist(disk_blockptr_t* list, blocknum_t count,
|
||||
struct disk_info* info);
|
||||
blocknum_t disk_get_blocklist_from_file(const char* filename,
|
||||
struct file_range *reg,
|
||||
disk_blockptr_t** blocklist,
|
||||
struct disk_info* pinfo);
|
||||
int disk_check_subchannel_set(int devno, dev_t device, char* dev_name);
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "lib/zt_common.h"
|
||||
#include "lib/util_part.h"
|
||||
@@ -291,10 +292,11 @@ struct component_loc {
|
||||
};
|
||||
|
||||
static int
|
||||
add_component_file(int fd, const char* filename, address_t load_address,
|
||||
size_t trailer, void *component, int add_files,
|
||||
struct disk_info* info, struct job_target_data* target,
|
||||
struct component_loc *location)
|
||||
add_component_file_range(int fd, const char *filename, struct file_range *reg,
|
||||
address_t load_address,
|
||||
size_t trailer, void *component, int add_files,
|
||||
struct disk_info *info, struct job_target_data *target,
|
||||
struct component_loc *location)
|
||||
{
|
||||
struct disk_info* file_info;
|
||||
struct component_loc loc;
|
||||
@@ -306,6 +308,7 @@ add_component_file(int fd, const char* filename, address_t load_address,
|
||||
int rc;
|
||||
|
||||
if (add_files) {
|
||||
assert(reg == NULL); /* not implemented */
|
||||
/* Read file to buffer */
|
||||
rc = misc_read_file(filename, &buffer, &size, 0);
|
||||
if (rc) {
|
||||
@@ -332,8 +335,8 @@ add_component_file(int fd, const char* filename, address_t load_address,
|
||||
return -1;
|
||||
}
|
||||
/* Get block list from existing file */
|
||||
count = disk_get_blocklist_from_file(filename, &list,
|
||||
file_info);
|
||||
count = disk_get_blocklist_from_file(filename, reg,
|
||||
&list, file_info);
|
||||
disk_free_info(file_info);
|
||||
if (count == 0)
|
||||
return -1;
|
||||
@@ -357,6 +360,17 @@ add_component_file(int fd, const char* filename, address_t load_address,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
add_component_file(int fd, const char *filename, address_t load_address,
|
||||
size_t trailer, void *component, int add_files,
|
||||
struct disk_info *info, struct job_target_data *target,
|
||||
struct component_loc *location)
|
||||
{
|
||||
return add_component_file_range(fd, filename, NULL, load_address,
|
||||
trailer, component, add_files,
|
||||
info, target, location);
|
||||
}
|
||||
|
||||
static int
|
||||
add_component_buffer(int fd, void* buffer, size_t size, component_data data,
|
||||
void* component, struct disk_info* info,
|
||||
@@ -834,7 +848,7 @@ add_segment_program(int fd, struct job_segment_data* segment,
|
||||
rc = add_component_file(fd, segment->segment, segment->segment_addr, 0,
|
||||
VOID_ADD(table, offset), add_files, info,
|
||||
target, &comp_loc[0]);
|
||||
if (rc) {
|
||||
if (rc) {
|
||||
error_text("Could not add segment file '%s'",
|
||||
segment->segment);
|
||||
free(table);
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
#include <unistd.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/fiemap.h>
|
||||
|
||||
#include "lib/util_proc.h"
|
||||
#include "lib/util_sys.h"
|
||||
|
||||
@@ -1064,19 +1063,26 @@ disk_compact_blocklist(disk_blockptr_t* list, blocknum_t count,
|
||||
return last + 1;
|
||||
}
|
||||
|
||||
|
||||
/* Retrieve a list of pointers to the disk blocks that make up the file
|
||||
* specified by FILENAME. Upon success, return the number of blocks and set
|
||||
* BLOCKLIST to point to the uncompacted list. INFO provides information
|
||||
* about the device which contains the file. Return zero otherwise. */
|
||||
/**
|
||||
* Retrieve a list of pointers to the disk blocks that make up the whole
|
||||
* file specified by FILENAME, or only its part specified by REG (if the
|
||||
* last one is not NULL).
|
||||
* Upon success, return the number of blocks and set BLOCKLIST to point to
|
||||
* the uncompacted list. INFO provides information about the device which
|
||||
* contains the file. Return zero otherwise
|
||||
*/
|
||||
blocknum_t
|
||||
disk_get_blocklist_from_file(const char* filename, disk_blockptr_t** blocklist,
|
||||
disk_get_blocklist_from_file(const char *filename, struct file_range *reg,
|
||||
disk_blockptr_t **blocklist,
|
||||
struct disk_info* info)
|
||||
{
|
||||
disk_blockptr_t* list;
|
||||
struct stat stats;
|
||||
int fd;
|
||||
blocknum_t count;
|
||||
off_t off;
|
||||
size_t count;
|
||||
blocknum_t blk_off;
|
||||
blocknum_t blk_count;
|
||||
blocknum_t i;
|
||||
blocknum_t blocknum;
|
||||
|
||||
@@ -1093,24 +1099,36 @@ disk_get_blocklist_from_file(const char* filename, disk_blockptr_t** blocklist,
|
||||
close (fd);
|
||||
return 0;
|
||||
}
|
||||
/* Get number of blocks */
|
||||
count = ((blocknum_t) stats.st_size +
|
||||
info->phy_block_size - 1) / info->phy_block_size;
|
||||
if (count == 0) {
|
||||
error_reason("Could not read empty file '%s'", filename);
|
||||
if (reg) {
|
||||
off = reg->offset;
|
||||
count = reg->len;
|
||||
} else {
|
||||
off = 0;
|
||||
count = stats.st_size;
|
||||
}
|
||||
if (off >= stats.st_size) {
|
||||
error_reason("Offset %llu is outside the file '%s'",
|
||||
off, filename);
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
if (off + count > (size_t)stats.st_size)
|
||||
count = stats.st_size - off;
|
||||
|
||||
blk_off = off / info->phy_block_size;
|
||||
blk_count = ((blocknum_t) count +
|
||||
info->phy_block_size - 1) / info->phy_block_size;
|
||||
|
||||
list = (disk_blockptr_t *) misc_malloc(sizeof(disk_blockptr_t) *
|
||||
count);
|
||||
blk_count);
|
||||
if (list == NULL) {
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
memset((void *) list, 0, sizeof(disk_blockptr_t) * count);
|
||||
memset((void *) list, 0, sizeof(disk_blockptr_t) * blk_count);
|
||||
/* Build list */
|
||||
for (i=0; i < count; i++) {
|
||||
if (disk_get_blocknum(fd, 0, i, &blocknum, info)) {
|
||||
for (i = 0; i < blk_count; i++) {
|
||||
if (disk_get_blocknum(fd, 0, blk_off + i, &blocknum, info)) {
|
||||
free(list);
|
||||
close(fd);
|
||||
return 0;
|
||||
@@ -1119,7 +1137,7 @@ disk_get_blocklist_from_file(const char* filename, disk_blockptr_t** blocklist,
|
||||
}
|
||||
close(fd);
|
||||
*blocklist = list;
|
||||
return count;
|
||||
return blk_count;
|
||||
}
|
||||
|
||||
/* Check whether input device is in subchannel set 0.
|
||||
|
||||
Reference in New Issue
Block a user