From: Rusty Russell Date: Tue, 1 Mar 2011 12:49:20 +0000 (+1030) Subject: tdb2: remove looping for write X-Git-Url: http://git.ozlabs.org/?p=ccan;a=commitdiff_plain;h=aa12380008323e14f8d7dabe78b174b72f69e2dd;hp=6dbbfabca414018b4c5acb3e6e597d84e2b19caf tdb2: remove looping for write On normal files, pwrite and write should never return short except on error. As we never create sparse files, so any short write is an I/O error. --- diff --git a/ccan/tdb2/io.c b/ccan/tdb2/io.c index 999922b1..bdf86b67 100644 --- a/ccan/tdb2/io.c +++ b/ccan/tdb2/io.c @@ -206,25 +206,6 @@ tdb_off_t tdb_read_off(struct tdb_context *tdb, tdb_off_t off) return ret; } -/* 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) -{ - while (len) { - ssize_t ret; - ret = pwrite(fd, buf, len, off); - if (ret < 0) - return false; - if (ret == 0) { - errno = ENOSPC; - return false; - } - buf = (char *)buf + ret; - off += 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) @@ -246,10 +227,17 @@ static int tdb_write(struct tdb_context *tdb, tdb_off_t off, if (tdb->map_ptr) { memcpy(off + (char *)tdb->map_ptr, buf, len); } else { - if (!tdb_pwrite_all(tdb->fd, buf, len, off)) { + ssize_t ret; + ret = pwrite(tdb->fd, buf, len, off); + if (ret < len) { + /* This shouldn't happen: we avoid sparse files. */ + if (ret >= 0) + errno = ENOSPC; + tdb_logerr(tdb, TDB_ERR_IO, TDB_DEBUG_FATAL, - "tdb_write failed at %zu len=%zu (%s)", - (size_t)off, (size_t)len, strerror(errno)); + "tdb_write: %zi at %zu len=%zu (%s)", + ret, (size_t)off, (size_t)len, + strerror(errno)); return -1; } } @@ -361,10 +349,15 @@ static int fill(struct tdb_context *tdb, { while (len) { size_t n = len > size ? size : len; + ssize_t ret = pwrite(tdb->fd, buf, n, off); + if (ret < n) { + if (ret >= 0) + errno = ENOSPC; - if (!tdb_pwrite_all(tdb->fd, buf, n, off)) { tdb_logerr(tdb, TDB_ERR_IO, TDB_DEBUG_FATAL, - "fill write failed: giving up!"); + "fill failed: %zi at %zu len=%zu (%s)", + ret, (size_t)off, (size_t)len, + strerror(errno)); return -1; } len -= n; diff --git a/ccan/tdb2/private.h b/ccan/tdb2/private.h index 1092f171..75e49c83 100644 --- a/ccan/tdb2/private.h +++ b/ccan/tdb2/private.h @@ -474,9 +474,6 @@ tdb_off_t tdb_find_nonzero_off(struct tdb_context *tdb, tdb_off_t tdb_find_zero_off(struct tdb_context *tdb, tdb_off_t off, uint64_t num); -/* 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); - /* Allocate and make a copy of some offset. */ void *tdb_alloc_read(struct tdb_context *tdb, tdb_off_t offset, tdb_len_t len); diff --git a/ccan/tdb2/tdb.c b/ccan/tdb2/tdb.c index e3b579d0..1aa3baa4 100644 --- a/ccan/tdb2/tdb.c +++ b/ccan/tdb2/tdb.c @@ -101,6 +101,7 @@ static int tdb_new_database(struct tdb_context *tdb, /* We make it up in memory, then write it out if not internal */ struct new_database newdb; unsigned int magic_len; + ssize_t rlen; /* Fill in the header */ newdb.hdr.version = TDB_VERSION; @@ -153,10 +154,13 @@ static int tdb_new_database(struct tdb_context *tdb, if (ftruncate(tdb->fd, 0) == -1) return -1; - if (!tdb_pwrite_all(tdb->fd, &newdb, sizeof(newdb), 0)) { + rlen = write(tdb->fd, &newdb, sizeof(newdb)); + if (rlen != sizeof(newdb)) { + if (rlen >= 0) + errno = ENOSPC; tdb_logerr(tdb, TDB_ERR_IO, TDB_DEBUG_FATAL, - "tdb_new_database: failed to write: %s", - strerror(errno)); + "tdb_new_database: %zi writing header: %s", + rlen, strerror(errno)); return -1; } return 0;