Messages in this thread Patch in this message | | | From | Nigel Cunningham <> | Subject | [Suspend2][ 29/32] [Suspend2] Read or write a chunk of the header. | Date | Tue, 27 Jun 2006 08:38:49 +1000 |
| |
Submit a buffer with data to write, or a buffer to be filled. In contrast to the functions for the main portion of the image, the buffer is normally less than a full page.
Signed-off-by: Nigel Cunningham <nigel@suspend2.net>
kernel/power/suspend_block_io.c | 67 +++++++++++++++++++++++++++++++++++++++ 1 files changed, 67 insertions(+), 0 deletions(-)
diff --git a/kernel/power/suspend_block_io.c b/kernel/power/suspend_block_io.c index f881fc7..e822b19 100644 --- a/kernel/power/suspend_block_io.c +++ b/kernel/power/suspend_block_io.c @@ -961,3 +961,70 @@ static int suspend_write_chunk(struct pa return suspend_rw_page(WRITE, buffer_page, -1, 0, 0); } +static int suspend_rw_header_chunk(int rw, struct suspend_module_ops *owner, + char *buffer, int buffer_size) +{ + int bytes_left = buffer_size; + + if (owner) { + owner->header_used += buffer_size; + if (owner->header_used > owner->header_requested) { + printk(KERN_EMERG "Suspend2 module %s is using more" + "header space (%lu) than it requested (%lu).\n", + owner->name, + owner->header_used, + owner->header_requested); + BUG(); + } + } + + /* Read a chunk of the header */ + while (bytes_left) { + char *source_start = buffer + buffer_size - bytes_left; + char *dest_start = suspend_writer_buffer + suspend_writer_buffer_posn; + int capacity = PAGE_SIZE - suspend_writer_buffer_posn; + char *to = rw ? dest_start : source_start; + char *from = rw ? source_start : dest_start; + + if (bytes_left <= capacity) { + if (test_debug_state(SUSPEND_HEADER)) + printk("Copy %d bytes %d-%d from %p to %p.\n", + bytes_left, + suspend_header_bytes_used, + suspend_header_bytes_used + bytes_left, + from, to); + memcpy(to, from, bytes_left); + suspend_writer_buffer_posn += bytes_left; + suspend_header_bytes_used += bytes_left; + return rw ? 0 : buffer_size; + } + + /* Next to read the next page */ + if (test_debug_state(SUSPEND_HEADER)) + printk("Copy %d bytes (%d-%d) from %p to %p.\n", + capacity, + suspend_header_bytes_used, + suspend_header_bytes_used + capacity, + from, to); + memcpy(to, from, capacity); + bytes_left -= capacity; + suspend_header_bytes_used += capacity; + + if (rw == READ && test_suspend_state(SUSPEND_TRY_RESUME_RD)) + sys_read(suspend_read_fd, + suspend_writer_buffer, BLOCK_SIZE); + else { + if (suspend_rw_page(rw, + virt_to_page(suspend_writer_buffer), + -1, !rw, + test_debug_state(SUSPEND_HEADER))) + return -EIO; + } + + suspend_writer_buffer_posn = 0; + suspend_cond_pause(0, NULL); + } + + return rw ? 0 : buffer_size; +} + -- Nigel Cunningham nigel at suspend2 dot net - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |