Adds support for short read requests. This is a permitted behaviour for filesystems.

This commit is contained in:
Andrea Mazzoleni 2012-03-13 19:11:09 +01:00
parent 22b05dc57d
commit 53124d3484
2 changed files with 46 additions and 26 deletions

View file

@ -229,6 +229,7 @@ int handle_read(struct snapraid_handle* handle, struct snapraid_block* block, un
ssize_t read_ret;
data_off_t offset;
unsigned read_size;
unsigned count;
offset = block_file_pos(block) * (data_off_t)block_size;
@ -240,24 +241,34 @@ int handle_read(struct snapraid_handle* handle, struct snapraid_block* block, un
read_size = block_file_size(block, block_size);
#if HAVE_PREAD
read_ret = pread(handle->f, block_buffer, read_size, offset);
#else
#if !HAVE_PREAD
if (lseek(handle->f, offset, SEEK_SET) != offset) {
fprintf(stderr, "Error seeking file '%s' at offset %"PRIu64". %s.\n", handle->path, offset, strerror(errno));
return -1;
}
read_ret = read(handle->f, block_buffer, read_size);
#endif
if (read_ret < 0) {
fprintf(stderr, "Error reading file '%s' at offset %"PRIu64". %s.\n", handle->path, offset, strerror(errno));
return -1;
}
if (read_ret != (ssize_t)read_size) { /* signed conversion is safe because block_size is always small */
fprintf(stderr, "File '%s' is smaller than expected. Read %d bytes instead of %d at offset %"PRIu64".\n", handle->path, (int)read_ret, read_size, offset);
return -1;
}
count = 0;
do {
#if HAVE_PREAD
read_ret = pread(handle->f, block_buffer + count, read_size - count, offset + count);
#else
read_ret = read(handle->f, block_buffer + count, read_size - count);
#endif
if (read_ret < 0) {
fprintf(stderr, "Error reading file '%s' at offset %"PRIu64". %s.\n", handle->path, offset, strerror(errno));
return -1;
}
if (read_ret == 0) {
fprintf(stderr, "Unexpected end of file '%s' at offset %"PRIu64". %s.\n", handle->path, offset, strerror(errno));
return -1;
}
count += read_ret;
} while (count < read_size);
/* pad with 0 */
if (read_size < block_size) {

View file

@ -263,6 +263,7 @@ int parity_read(struct snapraid_parity* parity, block_off_t pos, unsigned char*
{
ssize_t read_ret;
data_off_t offset;
unsigned count;
offset = pos * (data_off_t)block_size;
@ -272,24 +273,32 @@ int parity_read(struct snapraid_parity* parity, block_off_t pos, unsigned char*
return -1;
}
#if HAVE_PREAD
read_ret = pread(parity->f, block_buffer, block_size, offset);
#else
#if !HAVE_PREAD
if (lseek(parity->f, offset, SEEK_SET) != offset) {
fprintf(stderr, "Error seeking file '%s' at offset %"PRIu64". %s.\n", parity->path, offset, strerror(errno));
return -1;
}
read_ret = read(parity->f, block_buffer, block_size);
#endif
if (read_ret < 0) {
fprintf(stderr, "Error reading file '%s' at offset %"PRIu64". %s.\n", parity->path, offset, strerror(errno));
return -1;
}
if (read_ret != (ssize_t)block_size) { /* signed conversion is safe because block_size is always small */
fprintf(stderr, "File '%s' is smaller than expected. Read %d bytes instead of %d at offset %"PRIu64".\n", parity->path, (int)read_ret, block_size, offset);
return -1;
}
count = 0;
do {
#if HAVE_PREAD
read_ret = pread(parity->f, block_buffer + count, block_size - count, offset + count);
#else
read_ret = read(parity->f, block_buffer + count, block_size - count);
#endif
if (read_ret < 0) {
fprintf(stderr, "Error reading file '%s' at offset %"PRIu64". %s.\n", parity->path, offset, strerror(errno));
return -1;
}
if (read_ret == 0) {
fprintf(stderr, "Unexpected end of file '%s' at offset %"PRIu64". %s.\n", parity->path, offset, strerror(errno));
return -1;
}
count += read_ret;
} while (count < block_size);
/* Here isn't needed to call posix_fadvise(..., POSIX_FADV_DONTNEED) */
/* because we already advised sequential access with POSIX_FADV_SEQUENTIAL. */