Commit 6dbbfabc authored by Rusty Russell's avatar Rusty Russell

tdb2: remove looping for read on normal files.

Simply assume that any short read on a TDB in an I/O error.
parent 1ac26f37
......@@ -225,44 +225,6 @@ bool tdb_pwrite_all(int fd, const void *buf, size_t len, tdb_off_t off)
return true;
}
/* Even on files, we can get partial reads due to signals. */
bool tdb_pread_all(int fd, void *buf, size_t len, tdb_off_t off)
{
while (len) {
ssize_t ret;
ret = pread(fd, buf, len, off);
if (ret < 0)
return false;
if (ret == 0) {
/* ETOOSHORT? */
errno = EWOULDBLOCK;
return false;
}
buf = (char *)buf + ret;
off += ret;
len -= ret;
}
return true;
}
bool tdb_read_all(int fd, void *buf, size_t len)
{
while (len) {
ssize_t ret;
ret = read(fd, buf, len);
if (ret < 0)
return false;
if (ret == 0) {
/* ETOOSHORT? */
errno = EWOULDBLOCK;
return false;
}
buf = (char *)buf + ret;
len -= ret;
}
return true;
}
/* write a lump of data at a specified offset */
static int tdb_write(struct tdb_context *tdb, tdb_off_t off,
const void *buf, tdb_len_t len)
......@@ -305,13 +267,14 @@ static int tdb_read(struct tdb_context *tdb, tdb_off_t off, void *buf,
if (tdb->map_ptr) {
memcpy(buf, off + (char *)tdb->map_ptr, len);
} else {
if (!tdb_pread_all(tdb->fd, buf, len, off)) {
ssize_t r = pread(tdb->fd, buf, len, off);
if (r != len) {
tdb_logerr(tdb, TDB_ERR_IO, TDB_DEBUG_FATAL,
"tdb_read failed at %zu "
"tdb_read failed with %zi at %zu "
"len=%zu (%s) map_size=%zu",
(size_t)off, (size_t)len,
strerror(errno),
(size_t)tdb->map_size);
r, (size_t)off, (size_t)len,
strerror(errno),
(size_t)tdb->map_size);
return -1;
}
}
......
......@@ -476,8 +476,6 @@ tdb_off_t tdb_find_zero_off(struct tdb_context *tdb, tdb_off_t off,
/* Even on files, we can get partial writes due to signals. */
bool tdb_pwrite_all(int fd, const void *buf, size_t len, tdb_off_t off);
bool tdb_pread_all(int fd, void *buf, size_t len, tdb_off_t off);
bool tdb_read_all(int fd, void *buf, size_t len);
/* Allocate and make a copy of some offset. */
void *tdb_alloc_read(struct tdb_context *tdb, tdb_off_t offset, tdb_len_t len);
......
......@@ -22,6 +22,24 @@ static bool tdb_already_open(dev_t device, ino_t ino)
return false;
}
static bool read_all(int fd, void *buf, size_t len)
{
while (len) {
ssize_t ret;
ret = read(fd, buf, len);
if (ret < 0)
return false;
if (ret == 0) {
/* ETOOSHORT? */
errno = EWOULDBLOCK;
return false;
}
buf = (char *)buf + ret;
len -= ret;
}
return true;
}
static uint64_t random_number(struct tdb_context *tdb)
{
int fd;
......@@ -30,7 +48,7 @@ static uint64_t random_number(struct tdb_context *tdb)
fd = open("/dev/urandom", O_RDONLY);
if (fd >= 0) {
if (tdb_read_all(fd, &ret, sizeof(ret))) {
if (read_all(fd, &ret, sizeof(ret))) {
tdb_logerr(tdb, TDB_SUCCESS, TDB_DEBUG_TRACE,
"tdb_open: random from /dev/urandom");
close(fd);
......@@ -153,6 +171,7 @@ struct tdb_context *tdb_open(const char *name, int tdb_flags,
int saved_errno = 0;
uint64_t hash_test;
unsigned v;
ssize_t rlen;
struct tdb_header hdr;
struct tdb_attribute_seed *seed = NULL;
......@@ -253,17 +272,25 @@ struct tdb_context *tdb_open(const char *name, int tdb_flags,
goto fail;
}
if (!tdb_pread_all(tdb->fd, &hdr, sizeof(hdr), 0)
|| strcmp(hdr.magic_food, TDB_MAGIC_FOOD) != 0) {
if (!(open_flags & O_CREAT)) {
tdb_logerr(tdb, TDB_ERR_IO, TDB_DEBUG_ERROR,
"tdb_open: %s is not a tdb file", name);
goto fail;
}
/* If they used O_TRUNC, read will return 0. */
rlen = read(tdb->fd, &hdr, sizeof(hdr));
if (rlen == 0 && (open_flags & O_CREAT)) {
if (tdb_new_database(tdb, seed, &hdr) == -1) {
goto fail;
}
} else if (hdr.version != TDB_VERSION) {
} else if (rlen < 0) {
tdb_logerr(tdb, TDB_ERR_IO, TDB_DEBUG_ERROR,
"tdb_open: error %s reading %s",
strerror(errno), name);
goto fail;
} else if (rlen < sizeof(hdr)
|| strcmp(hdr.magic_food, TDB_MAGIC_FOOD) != 0) {
tdb_logerr(tdb, TDB_ERR_IO, TDB_DEBUG_ERROR,
"tdb_open: %s is not a tdb file", name);
goto fail;
}
if (hdr.version != TDB_VERSION) {
if (hdr.version == bswap_64(TDB_VERSION))
tdb->flags |= TDB_CONVERT;
else {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment