(ef_extend): Use do_write() & simplify. Catch table not file-backed.

Catch negative count; used to have no effect with EFF_MEM, and
confusion otherwise.  Try to recover from partially successful
extension.  Need help from ef_write() to do a better job; to be done.
This commit is contained in:
Markus Armbruster 2005-10-24 22:47:16 +00:00
parent 62264f8ada
commit 880a3e399b

View file

@ -293,6 +293,7 @@ do_write(struct empfile *ep, void *buf, int id, int count)
if (ret < 0) { if (ret < 0) {
if (errno != EAGAIN) { if (errno != EAGAIN) {
logerror("Error writing %s (%s)", ep->file, strerror(errno)); logerror("Error writing %s (%s)", ep->file, strerror(errno));
/* FIXME if this extended file, truncate back to old size */
return -1; return -1;
} }
} else { } else {
@ -348,43 +349,36 @@ ef_extend(int type, int count)
{ {
struct empfile *ep; struct empfile *ep;
char *tmpobj; char *tmpobj;
int cur, max; int id, i, how;
int how;
int r;
if (ef_check(type) < 0) if (ef_check(type) < 0)
return 0; return 0;
ep = &empfile[type]; ep = &empfile[type];
max = ep->fids + count; if (CANT_HAPPEN(ep->fd < 0 || count < 0))
cur = ep->fids;
tmpobj = calloc(1, ep->size);
if ((r = lseek(ep->fd, ep->fids * ep->size, SEEK_SET)) < 0) {
logerror("ef_extend: %s +#%d lseek(%d, %d, SEEK_SET) -> %d",
ep->name, count, ep->fd, ep->fids * ep->size, r);
free(tmpobj);
return 0; return 0;
}
for (cur = ep->fids; cur < max; cur++) { tmpobj = calloc(1, ep->size);
id = ep->fids;
for (i = 0; i < count; i++) {
if (ep->init) if (ep->init)
ep->init(cur, tmpobj); ep->init(id + i, tmpobj);
if ((r = write(ep->fd, tmpobj, ep->size)) != ep->size) { if (do_write(ep, tmpobj, id + i, 1) < 0)
logerror("ef_extend: %s +#%d write(%d, %p, %d) -> %d", break;
ep->name, count, ep->fd, tmpobj, ep->size, r);
free(tmpobj);
return 0;
}
} }
free(tmpobj); free(tmpobj);
if (ep->flags & EFF_MEM) { if (ep->flags & EFF_MEM) {
/* FIXME lazy bastards... do this right */
/* XXX this will cause problems if there are ef_ptrs (to the /* XXX this will cause problems if there are ef_ptrs (to the
* old allocated structure) active when we do the re-open */ * old allocated structure) active when we do the re-open */
how = ep->flags & EFF_OPEN; how = ep->flags & EFF_OPEN;
ef_close(type); ef_close(type);
ef_open(type, how); ef_open(type, how);
} else { } else {
ep->fids += count; ep->fids += i;
} }
return 1;
return i == count;
} }
/* /*