svn commit: samba r23983 - in branches/SAMBA_3_0_25/source/tdb/common: .

obnox at samba.org obnox at samba.org
Sat Jul 21 19:56:28 GMT 2007


Author: obnox
Date: 2007-07-21 19:56:28 +0000 (Sat, 21 Jul 2007)
New Revision: 23983

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=23983

Log:
Merge r23972 and r23977:

Fix a bug in pwrite error detection in tdb_expand_file():
The proper error condition is (ret == -1) instead of
(ret != number_of_byte_told_to_write).

* 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



Modified:
   branches/SAMBA_3_0_25/source/tdb/common/io.c


Changeset:
Modified: branches/SAMBA_3_0_25/source/tdb/common/io.c
===================================================================
--- branches/SAMBA_3_0_25/source/tdb/common/io.c	2007-07-21 10:14:46 UTC (rev 23982)
+++ branches/SAMBA_3_0_25/source/tdb/common/io.c	2007-07-21 19:56:28 UTC (rev 23983)
@@ -233,15 +233,28 @@
 	   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 != n) {
-			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 -= n;
-		size += n;
+		addition -= written;
+		size += written;
 	}
 	return 0;
 }



More information about the samba-cvs mailing list