diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
new file mode 100644
index b147f64..7b2a390
*** a/src/backend/access/heap/heapam.c
--- b/src/backend/access/heap/heapam.c
*************** heap_xlog_clean(XLogReaderState *record)
*** 8011,8018 ****
  								nowdead, ndead,
  								nowunused, nunused);
  
- 		freespace = PageGetHeapFreeSpace(page); /* needed to update FSM below */
- 
  		/*
  		 * Note: we don't worry about updating the page's prunability hints.
  		 * At worst this will cause an extra prune cycle to occur soon.
--- 8011,8016 ----
*************** heap_xlog_clean(XLogReaderState *record)
*** 8021,8037 ****
  		PageSetLSN(page, lsn);
  		MarkBufferDirty(buffer);
  	}
  	if (BufferIsValid(buffer))
  		UnlockReleaseBuffer(buffer);
  
  	/*
  	 * Update the FSM as well.
  	 *
! 	 * XXX: Don't do this if the page was restored from full page image. We
! 	 * don't bother to update the FSM in that case, it doesn't need to be
! 	 * totally accurate anyway.
  	 */
! 	if (action == BLK_NEEDS_REDO)
  		XLogRecordPageWithFreeSpace(rnode, blkno, freespace);
  }
  
--- 8019,8038 ----
  		PageSetLSN(page, lsn);
  		MarkBufferDirty(buffer);
  	}
+ 	if (action == BLK_NEEDS_REDO || action == BLK_RESTORED)
+ 		freespace = PageGetHeapFreeSpace(BufferGetPage(buffer)); /* needed to update FSM below */
+ 
  	if (BufferIsValid(buffer))
  		UnlockReleaseBuffer(buffer);
  
  	/*
  	 * Update the FSM as well.
  	 *
! 	 * Do this even if the page was restored from full page image. Otherwise
! 	 * a cleaned up page which is also all_visible and nearly empty can go 
! 	 * unreused for prolonged time, or forever if all_frozen.
  	 */
! 	if (action == BLK_NEEDS_REDO || action == BLK_RESTORED)
  		XLogRecordPageWithFreeSpace(rnode, blkno, freespace);
  }
  
