Rio: remember read/write error conditions.
This commit is contained in:
parent
c56b4ddc6f
commit
48d91cf4cc
@ -2168,7 +2168,6 @@ int rdbLoadRio(rio *rdb, rdbSaveInfo *rsi, int loading_aof) {
|
|||||||
eoferr: /* unexpected end of file is handled here with a fatal exit */
|
eoferr: /* unexpected end of file is handled here with a fatal exit */
|
||||||
serverLog(LL_WARNING,"Short read or OOM loading DB. Unrecoverable error, aborting now.");
|
serverLog(LL_WARNING,"Short read or OOM loading DB. Unrecoverable error, aborting now.");
|
||||||
rdbReportReadError("Unexpected EOF reading RDB file");
|
rdbReportReadError("Unexpected EOF reading RDB file");
|
||||||
err:
|
|
||||||
return C_ERR;
|
return C_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,6 +92,7 @@ static const rio rioBufferIO = {
|
|||||||
rioBufferFlush,
|
rioBufferFlush,
|
||||||
NULL, /* update_checksum */
|
NULL, /* update_checksum */
|
||||||
0, /* current checksum */
|
0, /* current checksum */
|
||||||
|
0, /* flags */
|
||||||
0, /* bytes read or written */
|
0, /* bytes read or written */
|
||||||
0, /* read/write chunk size */
|
0, /* read/write chunk size */
|
||||||
{ { NULL, 0 } } /* union for io-specific vars */
|
{ { NULL, 0 } } /* union for io-specific vars */
|
||||||
@ -145,6 +146,7 @@ static const rio rioFileIO = {
|
|||||||
rioFileFlush,
|
rioFileFlush,
|
||||||
NULL, /* update_checksum */
|
NULL, /* update_checksum */
|
||||||
0, /* current checksum */
|
0, /* current checksum */
|
||||||
|
0, /* flags */
|
||||||
0, /* bytes read or written */
|
0, /* bytes read or written */
|
||||||
0, /* read/write chunk size */
|
0, /* read/write chunk size */
|
||||||
{ { NULL, 0 } } /* union for io-specific vars */
|
{ { NULL, 0 } } /* union for io-specific vars */
|
||||||
@ -239,6 +241,7 @@ static const rio rioFdIO = {
|
|||||||
rioFdFlush,
|
rioFdFlush,
|
||||||
NULL, /* update_checksum */
|
NULL, /* update_checksum */
|
||||||
0, /* current checksum */
|
0, /* current checksum */
|
||||||
|
0, /* flags */
|
||||||
0, /* bytes read or written */
|
0, /* bytes read or written */
|
||||||
0, /* read/write chunk size */
|
0, /* read/write chunk size */
|
||||||
{ { NULL, 0 } } /* union for io-specific vars */
|
{ { NULL, 0 } } /* union for io-specific vars */
|
||||||
@ -374,6 +377,7 @@ static const rio rioFdsetIO = {
|
|||||||
rioFdsetFlush,
|
rioFdsetFlush,
|
||||||
NULL, /* update_checksum */
|
NULL, /* update_checksum */
|
||||||
0, /* current checksum */
|
0, /* current checksum */
|
||||||
|
0, /* flags */
|
||||||
0, /* bytes read or written */
|
0, /* bytes read or written */
|
||||||
0, /* read/write chunk size */
|
0, /* read/write chunk size */
|
||||||
{ { NULL, 0 } } /* union for io-specific vars */
|
{ { NULL, 0 } } /* union for io-specific vars */
|
||||||
|
33
src/rio.h
33
src/rio.h
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2009-2012, Pieter Noordhuis <pcnoordhuis at gmail dot com>
|
* Copyright (c) 2009-2012, Pieter Noordhuis <pcnoordhuis at gmail dot com>
|
||||||
* Copyright (c) 2009-2012, Salvatore Sanfilippo <antirez at gmail dot com>
|
* Copyright (c) 2009-2019, Salvatore Sanfilippo <antirez at gmail dot com>
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -36,6 +36,9 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "sds.h"
|
#include "sds.h"
|
||||||
|
|
||||||
|
#define RIO_FLAG_READ_ERROR (1<<0)
|
||||||
|
#define RIO_FLAG_WRITE_ERROR (1<<1)
|
||||||
|
|
||||||
struct _rio {
|
struct _rio {
|
||||||
/* Backend functions.
|
/* Backend functions.
|
||||||
* Since this functions do not tolerate short writes or reads the return
|
* Since this functions do not tolerate short writes or reads the return
|
||||||
@ -51,8 +54,8 @@ struct _rio {
|
|||||||
* computation. */
|
* computation. */
|
||||||
void (*update_cksum)(struct _rio *, const void *buf, size_t len);
|
void (*update_cksum)(struct _rio *, const void *buf, size_t len);
|
||||||
|
|
||||||
/* The current checksum */
|
/* The current checksum and flags (see RIO_FLAG_*) */
|
||||||
uint64_t cksum;
|
uint64_t cksum, flags;
|
||||||
|
|
||||||
/* number of bytes read or written */
|
/* number of bytes read or written */
|
||||||
size_t processed_bytes;
|
size_t processed_bytes;
|
||||||
@ -102,8 +105,10 @@ static inline size_t rioWrite(rio *r, const void *buf, size_t len) {
|
|||||||
while (len) {
|
while (len) {
|
||||||
size_t bytes_to_write = (r->max_processing_chunk && r->max_processing_chunk < len) ? r->max_processing_chunk : len;
|
size_t bytes_to_write = (r->max_processing_chunk && r->max_processing_chunk < len) ? r->max_processing_chunk : len;
|
||||||
if (r->update_cksum) r->update_cksum(r,buf,bytes_to_write);
|
if (r->update_cksum) r->update_cksum(r,buf,bytes_to_write);
|
||||||
if (r->write(r,buf,bytes_to_write) == 0)
|
if (r->write(r,buf,bytes_to_write) == 0) {
|
||||||
|
r->flags |= RIO_FLAG_WRITE_ERROR;
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
buf = (char*)buf + bytes_to_write;
|
buf = (char*)buf + bytes_to_write;
|
||||||
len -= bytes_to_write;
|
len -= bytes_to_write;
|
||||||
r->processed_bytes += bytes_to_write;
|
r->processed_bytes += bytes_to_write;
|
||||||
@ -114,8 +119,10 @@ static inline size_t rioWrite(rio *r, const void *buf, size_t len) {
|
|||||||
static inline size_t rioRead(rio *r, void *buf, size_t len) {
|
static inline size_t rioRead(rio *r, void *buf, size_t len) {
|
||||||
while (len) {
|
while (len) {
|
||||||
size_t bytes_to_read = (r->max_processing_chunk && r->max_processing_chunk < len) ? r->max_processing_chunk : len;
|
size_t bytes_to_read = (r->max_processing_chunk && r->max_processing_chunk < len) ? r->max_processing_chunk : len;
|
||||||
if (r->read(r,buf,bytes_to_read) == 0)
|
if (r->read(r,buf,bytes_to_read) == 0) {
|
||||||
|
r->flags |= RIO_FLAG_READ_ERROR;
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
if (r->update_cksum) r->update_cksum(r,buf,bytes_to_read);
|
if (r->update_cksum) r->update_cksum(r,buf,bytes_to_read);
|
||||||
buf = (char*)buf + bytes_to_read;
|
buf = (char*)buf + bytes_to_read;
|
||||||
len -= bytes_to_read;
|
len -= bytes_to_read;
|
||||||
@ -132,6 +139,22 @@ static inline int rioFlush(rio *r) {
|
|||||||
return r->flush(r);
|
return r->flush(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This function allows to know if there was a read error in any past
|
||||||
|
* operation, since the rio stream was created or since the last call
|
||||||
|
* to rioClearError(). */
|
||||||
|
static inline int rioGetReadError(rio *r) {
|
||||||
|
return (r->flags & RIO_FLAG_READ_ERROR) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Like rioGetReadError() but for write errors. */
|
||||||
|
static inline int rioGetWriteError(rio *r) {
|
||||||
|
return (r->flags & RIO_FLAG_READ_ERROR) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void rioClearErrors(rio *r) {
|
||||||
|
r->flags &= ~(RIO_FLAG_READ_ERROR|RIO_FLAG_WRITE_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
void rioInitWithFile(rio *r, FILE *fp);
|
void rioInitWithFile(rio *r, FILE *fp);
|
||||||
void rioInitWithBuffer(rio *r, sds s);
|
void rioInitWithBuffer(rio *r, sds s);
|
||||||
void rioInitWithFd(rio *r, int fd, size_t read_limit);
|
void rioInitWithFd(rio *r, int fd, size_t read_limit);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user