summaryrefslogtreecommitdiff
path: root/source4/lib/tdb/common
diff options
context:
space:
mode:
authorMichael Adam <obnox@samba.org>2007-07-20 14:23:12 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 15:01:13 -0500
commitaf8432e692eeb94bce80f155c6b9ab158258fff8 (patch)
tree98e8e49087e64c07c37860c73a27fa2149fe08ff /source4/lib/tdb/common
parentd568e2b1d3ae65d2f7a7fd2c6e7e317b396ebbcf (diff)
downloadsamba-af8432e692eeb94bce80f155c6b9ab158258fff8.tar.gz
samba-af8432e692eeb94bce80f155c6b9ab158258fff8.tar.bz2
samba-af8432e692eeb94bce80f155c6b9ab158258fff8.zip
r23977: Im prove the pwrite-patch to tdb_expand_file of r23972:
* prevent infinite loops due to 0 bytes written: try once more. if we still get 0 as return, set errno to ENOSPC and return -1 (error) * replace int by correct types (ssize_t and size_t). * print a warning log message in case "written < requested to write" usually this means, that the next call to pwrite will fail with return value -1 and set errno accordingly. Note that the former error condition "written != requested to write" is not a correct error condition of write/pwrite. If this is due to an error, a subsequent call to (p)write will reveal the cause (typically "no space left on device" - ENOSPC). Michael (This used to be commit 7f415d12239fc67eb2c7894c6359b9507fe122c6)
Diffstat (limited to 'source4/lib/tdb/common')
-rw-r--r--source4/lib/tdb/common/io.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/source4/lib/tdb/common/io.c b/source4/lib/tdb/common/io.c
index ea925f3895..a24b5e24a2 100644
--- a/source4/lib/tdb/common/io.c
+++ b/source4/lib/tdb/common/io.c
@@ -232,15 +232,28 @@ static int tdb_expand_file(struct tdb_context *tdb, tdb_off_t size, tdb_off_t ad
disk. This must be done with write, not via mmap */
memset(buf, TDB_PAD_BYTE, sizeof(buf));
while (addition) {
- int n = addition>sizeof(buf)?sizeof(buf):addition;
- int ret = pwrite(tdb->fd, buf, n, size);
- if (ret == -1) {
- TDB_LOG((tdb, TDB_DEBUG_FATAL, "expand_file write of %d failed (%s)\n",
- n, strerror(errno)));
+ size_t n = addition>sizeof(buf)?sizeof(buf):addition;
+ ssize_t written = pwrite(tdb->fd, buf, n, size);
+ if (written == 0) {
+ /* prevent infinite loops: try _once_ more */
+ written = pwrite(tdb->fd, buf, n, size);
+ }
+ if (written == 0) {
+ /* give up, trying to provide a useful errno */
+ TDB_LOG((tdb, TDB_DEBUG_FATAL, "expand_file write "
+ "returned 0 twice: giving up!\n"));
+ errno = ENOSPC;
+ return -1;
+ } else if (written == -1) {
+ TDB_LOG((tdb, TDB_DEBUG_FATAL, "expand_file write of "
+ "%d bytes failed (%s)\n", n, strerror(errno)));
return -1;
+ } else if (written != n) {
+ TDB_LOG((tdb, TDB_DEBUG_WARNING, "expand_file: wrote "
+ "only %d of %d bytes - retrying\n", written,n));
}
- addition -= ret;
- size += ret;
+ addition -= written;
+ size += written;
}
return 0;
}