From a3a8d8cce688430bf88fcab9ad2bca051667dff6 Mon Sep 17 00:00:00 2001 From: "Bradley C. Kuszmaul" Date: Tue, 16 Apr 2013 23:58:55 -0400 Subject: [PATCH] Merge from 2212 branch. Fixes #2212. Fixes[t:2212]. git-svn-id: file:///svn/toku/tokudb@16106 c7de825b-a66e-492c-adef-691d508d4ae1 --- db-benchmark-test-cxx/Makefile | 4 +- linux/file.c | 12 ++--- newbrt/brt-serialize.c | 78 ++++++--------------------------- toku_include/toku_portability.h | 5 ++- windows/file.c | 10 +++-- 5 files changed, 30 insertions(+), 79 deletions(-) diff --git a/db-benchmark-test-cxx/Makefile b/db-benchmark-test-cxx/Makefile index 2be7700bd1c..46714ae226c 100644 --- a/db-benchmark-test-cxx/Makefile +++ b/db-benchmark-test-cxx/Makefile @@ -50,10 +50,10 @@ build: $(TARGETS) check: check-default check-default: $(TARGET_TDB) - $(VALGRIND) ./$(TARGET_TDB) $(QUIET) $(SUMMARIZE_CMD) + $(VGRIND) ./$(TARGET_TDB) $(QUIET) $(SUMMARIZE_CMD) check-x: $(TARGET_TDB) - $(VALGRIND) ./$(TARGET_TDB) -x $(QUIET) $(SUMMARIZE_CMD) + $(VGRIND) ./$(TARGET_TDB) -x $(QUIET) $(SUMMARIZE_CMD) clean: rm -rf $(TARGETS) $(BENCHDBS) *.gcno *.gcda *.gcov diff --git a/linux/file.c b/linux/file.c index 14e8b35506b..e1d1c3593c4 100644 --- a/linux/file.c +++ b/linux/file.c @@ -48,8 +48,8 @@ toku_set_func_pwrite (ssize_t (*pwrite_fun)(int, const void *, size_t, off_t)) { return 0; } -ssize_t -toku_os_pwrite (int fd, const void *buf, size_t len, off_t off) { +void +toku_os_full_pwrite (int fd, const void *buf, size_t len, off_t off) { ssize_t r; again: if (t_pwrite) { @@ -59,7 +59,7 @@ again: } if (try_again_after_handling_write_error(fd, len, r)) goto again; - return r; + assert(r==(ssize_t)len); } static ssize_t (*t_write)(int, const void *, size_t) = 0; @@ -70,8 +70,8 @@ toku_set_func_write (ssize_t (*write_fun)(int, const void *, size_t)) { return 0; } -ssize_t -toku_os_write (int fd, const void *buf, size_t len) { +void +toku_os_full_write (int fd, const void *buf, size_t len) { ssize_t r; again: if (t_write) { @@ -81,7 +81,7 @@ again: } if (try_again_after_handling_write_error(fd, len, r)) goto again; - return r; + assert(r==(ssize_t)len); } static uint64_t get_tnow(void) { diff --git a/newbrt/brt-serialize.c b/newbrt/brt-serialize.c index 2b7142b3bb6..8c19fc336e1 100644 --- a/newbrt/brt-serialize.c +++ b/newbrt/brt-serialize.c @@ -124,42 +124,23 @@ maybe_preallocate_in_file (int fd, u_int64_t size) memset(wbuf, 0, N); toku_off_t start_write = alignup(file_size, 4096); assert(start_write >= file_size); - ssize_t r = toku_os_pwrite(fd, wbuf, N, start_write); - if (r==-1) { - int e=errno; // must save errno before calling toku_free. - toku_free(wbuf); - return e; - } + toku_os_full_pwrite(fd, wbuf, N, start_write); toku_free(wbuf); - assert(r==N); // We don't handle short writes properly, which is the case where 0<= r < N. } return 0; } -static int -toku_pwrite_extend (int fd, const void *buf, size_t count, toku_off_t offset, ssize_t *num_wrote) +static void +toku_full_pwrite_extend (int fd, const void *buf, size_t count, toku_off_t offset) // requires that the pwrite has been locked -// Returns 0 on success (and fills in *num_wrote for how many bytes are written) -// Returns nonzero error number problems. +// On failure, this does not return (an assertion fails or something). { assert(pwrite_is_locked); { int r = maybe_preallocate_in_file(fd, offset+count); - if (r!=0) { - *num_wrote = 0; - return r; - } - } - { - *num_wrote = toku_os_pwrite(fd, buf, count, offset); - if (*num_wrote < 0) { - int r = errno; - *num_wrote = 0; - return r; - } else { - return 0; - } + assert(r==0); } + toku_os_full_pwrite(fd, buf, count, offset); } // Don't include the compression header @@ -532,7 +513,6 @@ int toku_serialize_brtnode_to (int fd, BLOCKNUM blocknum, BRTNODE node, struct b } //write_now: printf("%s:%d Writing %d bytes\n", __FILE__, __LINE__, w.ndone); - int r; { // If the node has never been written, then write the whole buffer, including the zeros assert(blocknum.b>=0); @@ -546,14 +526,8 @@ int toku_serialize_brtnode_to (int fd, BLOCKNUM blocknum, BRTNODE node, struct b //h will be dirtied toku_blocknum_realloc_on_disk(h->blocktable, blocknum, n_to_write, &offset, h, for_checkpoint); - ssize_t n_wrote; lock_for_pwrite(); - r=toku_pwrite_extend(fd, compressed_buf, n_to_write, offset, &n_wrote); - if (r) { - // fprintf(stderr, "%s:%d: Error writing data to file. errno=%d (%s)\n", __FILE__, __LINE__, r, strerror(r)); - } else { - r=0; - } + toku_full_pwrite_extend(fd, compressed_buf, n_to_write, offset); unlock_for_pwrite(); } @@ -562,7 +536,7 @@ int toku_serialize_brtnode_to (int fd, BLOCKNUM blocknum, BRTNODE node, struct b toku_free(buf); toku_free(compressed_buf); node->dirty = 0; // See #1957. Must set the node to be clean after serializing it so that it doesn't get written again on the next checkpoint or eviction. - return r; + return 0; } #define DO_DECOMPRESS_WORKER 1 @@ -1223,44 +1197,20 @@ int toku_serialize_brt_header_to (int fd, struct brt_header *h) { assert(w_main.ndone==size_main); } toku_brtheader_unlock(h); - char *writing_what; lock_for_pwrite(); { //Actual Write translation table - ssize_t nwrote; - rr = toku_pwrite_extend(fd, w_translation.buf, - size_translation, address_translation, &nwrote); - if (rr) { - writing_what = "translation"; - goto panic; - } - assert(nwrote==size_translation); + toku_full_pwrite_extend(fd, w_translation.buf, + size_translation, address_translation); } { - //Actual Write main header - ssize_t nwrote; //Alternate writing header to two locations: // Beginning (0) or BLOCK_ALLOCATOR_HEADER_RESERVE toku_off_t main_offset; //TODO: #1623 uncomment next line when ready for 2 headers main_offset = (h->checkpoint_count & 0x1) ? 0 : BLOCK_ALLOCATOR_HEADER_RESERVE; - rr = toku_pwrite_extend(fd, w_main.buf, w_main.ndone, main_offset, &nwrote); - if (rr) { - writing_what = "header"; - panic: - if (h->panic==0) { - char *e = strerror(rr); - int l = 200 + strlen(e); - char s[l]; - h->panic=rr; - snprintf(s, l-1, "%s:%d: Error writing %s to data file. errno=%d (%s)\n", __FILE__, __LINE__, writing_what, rr, e); - h->panic_string = toku_strdup(s); - } - goto finish; - } - assert((u_int64_t)nwrote==size_main); + toku_full_pwrite_extend(fd, w_main.buf, w_main.ndone, main_offset); } - finish: toku_free(w_main.buf); toku_free(w_translation.buf); unlock_for_pwrite(); @@ -1288,7 +1238,7 @@ serialize_descriptor_contents_to_wbuf(struct wbuf *wb, struct descriptor *desc) //Descriptors are NOT written during the header checkpoint process. int toku_serialize_descriptor_contents_to_fd(int fd, struct descriptor *desc, DISKOFF offset) { - int r; + int r = 0; // make the checksum int64_t size = toku_serialize_descriptor_size(desc)+4; //4 for checksum struct wbuf w; @@ -1303,10 +1253,8 @@ toku_serialize_descriptor_contents_to_fd(int fd, struct descriptor *desc, DISKOF { lock_for_pwrite(); //Actual Write translation table - ssize_t nwrote; - r = toku_pwrite_extend(fd, w.buf, size, offset, &nwrote); + toku_full_pwrite_extend(fd, w.buf, size, offset); unlock_for_pwrite(); - if (r==0) assert(nwrote==size); } toku_free(w.buf); return r; diff --git a/toku_include/toku_portability.h b/toku_include/toku_portability.h index cb896be5e6b..d1aa3384c0a 100644 --- a/toku_include/toku_portability.h +++ b/toku_include/toku_portability.h @@ -119,8 +119,9 @@ void *realloc(void*, size_t) __attribute__((__deprecated__)); void *os_malloc(size_t); void *os_realloc(void*,size_t); void os_free(void*); -ssize_t toku_os_pwrite (int fd, const void *buf, size_t len, toku_off_t off); -ssize_t toku_os_write (int fd, const void *buf, size_t len); +// full_pwrite and full_write performs a pwrite, and checks errors. It doesn't return unless all the data was written. */ +void toku_os_full_pwrite (int fd, const void *buf, size_t len, toku_off_t off); +void toku_os_full_write (int fd, const void *buf, size_t len); // wrapper around fsync int toku_file_fsync(int fd); diff --git a/windows/file.c b/windows/file.c index fccf7ff2622..f471d6aee51 100644 --- a/windows/file.c +++ b/windows/file.c @@ -98,14 +98,16 @@ int toku_set_func_write (ssize_t (*write_fun)(int, const void *, size_t)) { } -ssize_t -toku_os_pwrite (int fd, const void *buf, size_t len, toku_off_t off) +void +toku_os_full_pwrite (int fd, const void *buf, size_t len, toku_off_t off) { + ssize_t r; if (t_pwrite) { - return t_pwrite(fd, buf, len, off); + r = t_pwrite(fd, buf, len, off); } else { - return pwrite(fd, buf, len, off); + r = pwrite(fd, buf, len, off); } + assert(r==len); } static int (*t_fsync)(int) = 0;