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:
Eduard Shishkin
2020-10-15 14:44:56 +02:00
committed by Jan Höppner
parent 2ae44cb794
commit bbeb0f8445
3 changed files with 73 additions and 35 deletions

View File

@@ -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);

View File

@@ -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,

View File

@@ -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