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_write_block_aligned_base()
Provide helper functions disk_write_block_buffer_align() and add_component_buffer_align() to align offset of the record on specified block size boundary and to save the offset, where the record was made at. 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
2ae44cb794
commit
bbeb0f8445
@@ -117,7 +117,12 @@ int disk_write_block_aligned(int fd, const void* data, size_t bytecount,
|
||||
blocknum_t disk_write_block_buffer(int fd, int fd_is_basedisk,
|
||||
const void* buffer, size_t bytecount,
|
||||
disk_blockptr_t** blocklist,
|
||||
struct disk_info* info);
|
||||
struct disk_info *info);
|
||||
blocknum_t disk_write_block_buffer_align(int fd, int fd_is_basedisk,
|
||||
const void *buffer, size_t bytecount,
|
||||
disk_blockptr_t **blocklist,
|
||||
struct disk_info *info, int align,
|
||||
off_t *offset);
|
||||
void disk_print_devt(dev_t d);
|
||||
void disk_print_info(struct disk_info* info);
|
||||
int disk_is_zero_block(disk_blockptr_t* block, struct disk_info* info);
|
||||
|
||||
@@ -372,9 +372,11 @@ add_component_file(int fd, const char *filename, address_t load_address,
|
||||
}
|
||||
|
||||
static int
|
||||
add_component_buffer(int fd, void* buffer, size_t size, component_data data,
|
||||
void* component, struct disk_info* info,
|
||||
struct component_loc *location, int type)
|
||||
add_component_buffer_align(int fd, void *buffer, size_t size,
|
||||
component_data data, void *component,
|
||||
struct disk_info *info,
|
||||
struct component_loc *location, int type,
|
||||
int align, off_t *offset)
|
||||
{
|
||||
struct component_loc loc;
|
||||
disk_blockptr_t segment;
|
||||
@@ -383,7 +385,8 @@ add_component_buffer(int fd, void* buffer, size_t size, component_data data,
|
||||
int rc;
|
||||
|
||||
/* Write buffer */
|
||||
count = disk_write_block_buffer(fd, 0, buffer, size, &list, info);
|
||||
count = disk_write_block_buffer_align(fd, 0, buffer, size, &list, info,
|
||||
align, offset);
|
||||
if (count == 0) {
|
||||
error_text("Could not write to bootmap file");
|
||||
return -1;
|
||||
@@ -410,6 +413,15 @@ add_component_buffer(int fd, void* buffer, size_t size, component_data data,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
add_component_buffer(int fd, void *buffer, size_t size, component_data data,
|
||||
void *component, struct disk_info *info,
|
||||
struct component_loc *location, int type)
|
||||
{
|
||||
return add_component_buffer_align(fd, buffer, size, data, component,
|
||||
info, location, type,
|
||||
info->phy_block_size, NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
add_dummy_buffer(int fd, size_t size, address_t addr, void *component,
|
||||
|
||||
@@ -727,22 +727,26 @@ disk_blockptr_from_blocknum(disk_blockptr_t* ptr, blocknum_t blocknum,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Write BYTECOUNT bytes of data from memory at location DATA as a block to
|
||||
* the file identified by file descriptor FD. Make sure that the data is
|
||||
* aligned on a block size boundary and that at most INFO->PHY_BLOCK_SIZE
|
||||
* bytes are written. INFO provides information about the disk layout. Upon
|
||||
* success, return 0 and store the pointer to the resulting disk block to BLOCK
|
||||
* (if BLOCK is not NULL). Return non-zero otherwise. */
|
||||
/**
|
||||
* Write BYTECOUNT bytes of data from memory at location DATA as a block to
|
||||
* the file identified by file descriptor FD at the current position in that
|
||||
* file aligned on ALIGN block size boundary and make sure that at most
|
||||
* INFO->PHY_BLOCK_SIZE bytes are written. INFO provides information about
|
||||
* the disk layout. Upon success, store the pointer to the resulting disk
|
||||
* block to BLOCK (if BLOCK is not NULL) and return 0. Return non-zero
|
||||
* otherwise. On success OFFSET contains offset of the first written byte
|
||||
*/
|
||||
static int
|
||||
disk_write_block_aligned_base(int fd, int is_base_disk, const void* data,
|
||||
size_t bytecount, disk_blockptr_t* block,
|
||||
struct disk_info* info)
|
||||
struct disk_info *info, int align, off_t *offset)
|
||||
{
|
||||
blocknum_t current_block;
|
||||
blocknum_t blocknum;
|
||||
off_t current_pos;
|
||||
int align;
|
||||
|
||||
if (align == 0)
|
||||
align = info->phy_block_size;
|
||||
|
||||
current_pos = lseek(fd, 0, SEEK_CUR);
|
||||
if (current_pos == -1) {
|
||||
@@ -750,18 +754,18 @@ disk_write_block_aligned_base(int fd, int is_base_disk, const void* data,
|
||||
return -1;
|
||||
}
|
||||
/* Ensure block alignment of current file pos */
|
||||
align = info->phy_block_size;
|
||||
|
||||
if (current_pos % align != 0) {
|
||||
current_pos = lseek(fd, align - current_pos % align, SEEK_CUR);
|
||||
if (current_pos == -1) {
|
||||
if (current_pos == -1) {
|
||||
error_text(strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
current_block = current_pos / align;
|
||||
current_block = current_pos / info->phy_block_size;
|
||||
/* Ensure maximum size */
|
||||
if (bytecount > (size_t) align)
|
||||
bytecount = align;
|
||||
if (bytecount > (size_t)info->phy_block_size)
|
||||
bytecount = info->phy_block_size;
|
||||
/* Write data block */
|
||||
if (misc_write(fd, data, bytecount))
|
||||
return -1;
|
||||
@@ -772,33 +776,38 @@ disk_write_block_aligned_base(int fd, int is_base_disk, const void* data,
|
||||
return -1;
|
||||
disk_blockptr_from_blocknum(block, blocknum, info);
|
||||
}
|
||||
if (offset)
|
||||
*offset = current_pos;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
disk_write_block_aligned(int fd, const void* data, size_t bytecount,
|
||||
disk_blockptr_t* block, struct disk_info* info)
|
||||
int disk_write_block_aligned(int fd, const void *data, size_t bytecount,
|
||||
disk_blockptr_t *block, struct disk_info *info)
|
||||
{
|
||||
return disk_write_block_aligned_base(fd, 0, data, bytecount, block,
|
||||
info);
|
||||
info, info->phy_block_size, NULL);
|
||||
}
|
||||
|
||||
/* Write BYTECOUNT bytes from memory at location BUFFER to the file identified
|
||||
* by file descriptor FD and return the list of pointers to the disk blocks
|
||||
* that make up the respective part of the file. Upon success return the number
|
||||
* of blocks and set BLOCKLIST to point to the uncompressed list. Return zero
|
||||
* otherwise. Note that the data is written to a file position which is aligned
|
||||
* on a block size boundary. */
|
||||
/**
|
||||
* Write BYTECOUNT bytes from memory at location BUFFER to the file identified
|
||||
* by file descriptor FD at the current position in that file aligned on ALIGN
|
||||
* block size boundary and return the list of pointers to the disk blocks that
|
||||
* make up the respective part of the file. Upon success return the number of
|
||||
* blocks, set BLOCKLIST to point to the uncompressed list, and store offset of
|
||||
* the first written byte in OFFSET (if OFFSET is not NULL). Return zero
|
||||
* otherwise.
|
||||
*/
|
||||
blocknum_t
|
||||
disk_write_block_buffer(int fd, int fd_is_basedisk, const void* buffer,
|
||||
size_t bytecount, disk_blockptr_t** blocklist,
|
||||
struct disk_info* info)
|
||||
disk_write_block_buffer_align(int fd, int fd_is_basedisk, const void *buffer,
|
||||
size_t bytecount, disk_blockptr_t **blocklist,
|
||||
struct disk_info *info, int align, off_t *offset)
|
||||
{
|
||||
disk_blockptr_t* list;
|
||||
blocknum_t count;
|
||||
blocknum_t i;
|
||||
size_t written;
|
||||
size_t chunk_size;
|
||||
off_t pos;
|
||||
int rc;
|
||||
|
||||
count = (bytecount + info->phy_block_size - 1) / info->phy_block_size;
|
||||
@@ -815,18 +824,30 @@ disk_write_block_buffer(int fd, int fd_is_basedisk, const void* buffer,
|
||||
if (chunk_size > (size_t) info->phy_block_size)
|
||||
chunk_size = info->phy_block_size;
|
||||
rc = disk_write_block_aligned_base(fd, fd_is_basedisk,
|
||||
VOID_ADD(buffer, written),
|
||||
chunk_size,
|
||||
&list[i], info);
|
||||
VOID_ADD(buffer, written),
|
||||
chunk_size, &list[i], info,
|
||||
i == 0 ? align : info->phy_block_size,
|
||||
&pos);
|
||||
if (rc) {
|
||||
free(list);
|
||||
return 0;
|
||||
}
|
||||
if (offset != NULL && i == 0)
|
||||
*offset = pos;
|
||||
}
|
||||
*blocklist = list;
|
||||
return count;
|
||||
}
|
||||
|
||||
blocknum_t
|
||||
disk_write_block_buffer(int fd, int fd_is_basedisk, const void *buffer,
|
||||
size_t bytecount, disk_blockptr_t **blocklist,
|
||||
struct disk_info *info)
|
||||
{
|
||||
return disk_write_block_buffer_align(fd, fd_is_basedisk, buffer,
|
||||
bytecount, blocklist, info,
|
||||
info->phy_block_size, NULL);
|
||||
}
|
||||
|
||||
/* Print device node. */
|
||||
void
|
||||
|
||||
Reference in New Issue
Block a user