r24738: Fix one more use of pwrite in tdb code in the spirit of r23972 and r23977.
authorMichael Adam <obnox@samba.org>
Tue, 28 Aug 2007 14:25:46 +0000 (14:25 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:30:16 +0000 (12:30 -0500)
Michael

source/lib/tdb/common/io.c

index c8ea26c06cd64235631601e18ac0c3e8776ee509..40b0288ba8ad17b99883929f8915c853cdc52f17 100644 (file)
@@ -88,12 +88,31 @@ 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 (pwrite(tdb->fd, buf, len, off) != (ssize_t)len) {
-               /* Ensure ecode is set for log fn. */
-               tdb->ecode = TDB_ERR_IO;
-               TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_write failed at %d len=%d (%s)\n",
-                          off, len, strerror(errno)));
-               return TDB_ERRCODE(TDB_ERR_IO, -1);
+       } else {
+               ssize_t written = pwrite(tdb->fd, buf, len, off);
+               if ((written != (ssize_t)len) && (written != -1)) {
+                       /* try once more */
+                       TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_write: wrote only "
+                                "%d of %d bytes at %d, trying once more\n",
+                                written, len, off));
+                       errno = ENOSPC;
+                       written = pwrite(tdb->fd, (void *)((char *)buf+written),
+                                        len-written,
+                                        off+written);
+               }
+               if (written == -1) {
+                       /* Ensure ecode is set for log fn. */
+                       tdb->ecode = TDB_ERR_IO;
+                       TDB_LOG((tdb, TDB_DEBUG_FATAL,"tdb_write failed at %d "
+                                "len=%d (%s)\n", off, len, strerror(errno)));
+                       return TDB_ERRCODE(TDB_ERR_IO, -1);
+               } else if (written != (ssize_t)len) {
+                       TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_write: failed to "
+                                "write %d bytes at %d in two attempts\n",
+                                len, off));
+                       errno = ENOSPC;
+                       return TDB_ERRCODE(TDB_ERR_IO, -1);
+               }
        }
        return 0;
 }