changeset 844:77fd01b82fd7

objstore: direct page lookup fills to the correct objver mid-txn When we are in the middle of a transaction and get a page_lookup with a PG_FILL, we need to (1) use the correct objver, and (2) zero-fill as necessary. Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
date Fri, 16 Dec 2022 19:48:03 -0500
parents 5427f4e9dcb6
children f1876d613da0
files src/objstore/cache.c
diffstat 1 files changed, 19 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/objstore/cache.c	Fri Dec 16 19:46:24 2022 -0500
+++ b/src/objstore/cache.c	Fri Dec 16 19:48:03 2022 -0500
@@ -167,16 +167,30 @@
 		 *   (2) all pages before the shortest truncation must be
 		 *       read in from disk
 		 *
-		 * The shortest truncation point takes care of all cases -
-		 * including those where we extend the file after truncating
-		 * it.
+		 * Note that if we tried to look up a page that was modified
+		 * by a previous write in the same transaction, that page is
+		 * still in memory and we would have returned it earlier in
+		 * this function.
 		 */
 
+		struct objver *readver;
+		uint64_t size;
 		int ret;
 
-		if (pgno < (p2roundup(ver->attrs.size, PAGE_SIZE) / PAGE_SIZE)) {
+		if (ver->txn.txn) {
+			/* this objver belongs to a txn */
+			readver = ver->txn.prev_ver ? ver->txn.prev_ver : ver;
+			size = ver->txn.min_data_size;
+		} else {
+			/* non-txn lookup */
+			readver = ver;
+			size = ver->attrs.size;
+		}
+
+		if (pgno < (p2roundup(size, PAGE_SIZE) / PAGE_SIZE)) {
 			/* existed before */
-			ret = ver->obj->ops->read_page(ver, page->ptr, pgno);
+			ret = readver->obj->ops->read_page(readver, page->ptr,
+							   pgno);
 			if (ret) {
 				free_page(page);
 				return ERR_PTR(ret);