Fix fillcache() and do_write() error handling
Fix test for interrupted I/O. Catch read hitting EOF unexpectedly. Log errors in more detail.
This commit is contained in:
parent
54f1e9a07f
commit
570ce80edf
1 changed files with 23 additions and 14 deletions
|
@ -294,12 +294,12 @@ ef_read(int type, int id, void *into)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fill cache of EP with elements starting at ID.
|
* Fill cache of file-backed EP with elements starting at ID.
|
||||||
* If any were read, return their number.
|
* If any were read, return their number.
|
||||||
* Else return -1 and leave the cache unchanged.
|
* Else return -1 and leave the cache unchanged.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
fillcache(struct empfile *ep, int start)
|
fillcache(struct empfile *ep, int id)
|
||||||
{
|
{
|
||||||
int n, ret;
|
int n, ret;
|
||||||
char *p;
|
char *p;
|
||||||
|
@ -307,21 +307,27 @@ fillcache(struct empfile *ep, int start)
|
||||||
if (CANT_HAPPEN(ep->fd < 0 || !ep->cache))
|
if (CANT_HAPPEN(ep->fd < 0 || !ep->cache))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (lseek(ep->fd, start * ep->size, SEEK_SET) == (off_t)-1) {
|
if (lseek(ep->fd, id * ep->size, SEEK_SET) == (off_t)-1) {
|
||||||
logerror("Error seeking %s (%s)", ep->file, strerror(errno));
|
logerror("Error seeking %s to elt %d (%s)",
|
||||||
|
ep->file, id, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
p = ep->cache;
|
p = ep->cache;
|
||||||
n = ep->csize * ep->size;
|
n = MIN(ep->csize, ep->fids - id) * ep->size;
|
||||||
while (n > 0) {
|
while (n > 0) {
|
||||||
ret = read(ep->fd, p, n);
|
ret = read(ep->fd, p, n);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
if (errno != EAGAIN) {
|
if (errno != EINTR) {
|
||||||
logerror("Error reading %s (%s)", ep->file, strerror(errno));
|
logerror("Error reading %s elt %d (%s)",
|
||||||
|
ep->file,
|
||||||
|
id + (int)((p - ep->cache) / ep->size),
|
||||||
|
strerror(errno));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (ret == 0) {
|
} else if (ret == 0) {
|
||||||
|
logerror("Unexpected EOF reading %s elt %d",
|
||||||
|
ep->file, id + (int)((p - ep->cache) / ep->size));
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
p += ret;
|
p += ret;
|
||||||
|
@ -332,15 +338,15 @@ fillcache(struct empfile *ep, int start)
|
||||||
if (p == ep->cache)
|
if (p == ep->cache)
|
||||||
return -1; /* nothing read, old cache still ok */
|
return -1; /* nothing read, old cache still ok */
|
||||||
|
|
||||||
ep->baseid = start;
|
ep->baseid = id;
|
||||||
ep->cids = (p - ep->cache) / ep->size;
|
ep->cids = (p - ep->cache) / ep->size;
|
||||||
return ep->cids;
|
return ep->cids;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Write COUNT elements from BUF to EP, starting at ID.
|
* Write COUNT elements starting at ID from BUF to file-backed EP.
|
||||||
* Set the timestamp to NOW if the table has those.
|
* Set the timestamp to NOW if the table has those.
|
||||||
* Return 0 on success, -1 on error.
|
* Return 0 on success, -1 on error (file may be corrupt then).
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
do_write(struct empfile *ep, void *buf, int id, int count, time_t now)
|
do_write(struct empfile *ep, void *buf, int id, int count, time_t now)
|
||||||
|
@ -369,7 +375,8 @@ do_write(struct empfile *ep, void *buf, int id, int count, time_t now)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lseek(ep->fd, id * ep->size, SEEK_SET) == (off_t)-1) {
|
if (lseek(ep->fd, id * ep->size, SEEK_SET) == (off_t)-1) {
|
||||||
logerror("Error seeking %s (%s)", ep->file, strerror(errno));
|
logerror("Error seeking %s to elt %d (%s)",
|
||||||
|
ep->file, id, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -378,9 +385,11 @@ do_write(struct empfile *ep, void *buf, int id, int count, time_t now)
|
||||||
while (n > 0) {
|
while (n > 0) {
|
||||||
ret = write(ep->fd, p, n);
|
ret = write(ep->fd, p, n);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
if (errno != EAGAIN) {
|
if (errno != EINTR) {
|
||||||
logerror("Error writing %s (%s)", ep->file, strerror(errno));
|
logerror("Error writing %s elt %d (%s)",
|
||||||
/* FIXME if this extended file, truncate back to old size */
|
ep->file,
|
||||||
|
id + (int)((p - (char *)buf) / ep->size),
|
||||||
|
strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue