diff --git a/t/neo/storage/fs1/filestorage.go b/t/neo/storage/fs1/filestorage.go
index 1ab3627324661dc38bab81fcd4133bda21e0a2e7..05cfcf6e7d63265d1161e375f2a0b931f54365aa 100644
--- a/t/neo/storage/fs1/filestorage.go
+++ b/t/neo/storage/fs1/filestorage.go
@@ -287,7 +287,7 @@ func (txnh *TxnHeader) loadStrings(r io.ReaderAt /* *os.File */) error {
 }
 
 // LoadPrev reads and decodes previous transaction record header
-// prerequisite: txnh .Pos and .LenPrev should be already initialized:
+// prerequisite: txnh .Pos and .LenPrev are initialized:
 //   - by successful call to Load() initially			XXX but EOF also works
 //   - by subsequent successful calls to LoadPrev / LoadNext	XXX recheck
 func (txnh *TxnHeader) LoadPrev(r io.ReaderAt, flags TxnLoadFlags) error {
@@ -340,7 +340,9 @@ func (txnh *TxnHeader) LoadNext(r io.ReaderAt, flags TxnLoadFlags) error {
 
 
 
-// decode reads and decodes data record header
+// load reads and decodes data record header
+// pos: points to data header start
+// no prerequisite requirements are made to previous dh state
 func (dh *DataHeader) load(r io.ReaderAt /* *os.File */, pos int64, tmpBuf *[DataHeaderSize]byte) error {
 	dh.Pos = pos
 	// XXX .Len = 0		= read error ?
@@ -351,7 +353,7 @@ func (dh *DataHeader) load(r io.ReaderAt /* *os.File */, pos int64, tmpBuf *[Dat
 
 	_, err := r.ReadAt(tmpBuf[:], pos)
 	if err != nil {
-		return &ErrDataRecord{pos, "read", noEOF(err)}
+		return dh.err("read", noEOF(err))
 	}
 
 	// XXX also check oid.Valid() ?
@@ -363,9 +365,6 @@ func (dh *DataHeader) load(r io.ReaderAt /* *os.File */, pos int64, tmpBuf *[Dat
 
 	dh.PrevRevPos = int64(binary.BigEndian.Uint64(tmpBuf[16:]))
 	dh.TxnPos = int64(binary.BigEndian.Uint64(tmpBuf[24:]))
-	if dh.PrevRevPos < dataValidFrom {
-		return decodeErr(dh, "invalid prev oid data position: %v", dh.PrevRevPos)
-	}
 	if dh.TxnPos < txnValidFrom {
 		return decodeErr(dh, "invalid txn position: %v", dh.TxnPos)
 	}
@@ -373,12 +372,15 @@ func (dh *DataHeader) load(r io.ReaderAt /* *os.File */, pos int64, tmpBuf *[Dat
 	if dh.TxnPos + TxnHeaderFixSize > pos {
 		return decodeErr(dh, "txn position not decreasing: %v", dh.TxnPos)
 	}
-	if dh.PrevRevPos + DataHeaderSize > dh.TxnPos - 8 {
-		return decodeErr(dh, "prev oid data position (%v) overlaps with txn (%v)", dh.PrevRevPos, dh.TxnPos)	// XXX wording
+	if dh.PrevRevPos != 0 {	// zero means there is no previous revision
+		if dh.PrevRevPos < dataValidFrom {
+			return decodeErr(dh, "invalid prev revision position: %v", dh.PrevRevPos)
+		}
+		if dh.PrevRevPos + DataHeaderSize > dh.TxnPos - 8 {
+			return decodeErr(dh, "prev revision position (%v) overlaps with txn (%v)", dh.PrevRevPos, dh.TxnPos)
+		}
 	}
 
-	// XXX check PrevRevPos vs TxnPos overlap
-
 	verlen := binary.BigEndian.Uint16(tmpBuf[32:])
 	if verlen != 0 {
 		return decodeErr(dh, "non-zero version: #%v", verlen)
@@ -399,6 +401,35 @@ func (dh *DataHeader) Load(r io.ReaderAt, pos int64) error {
 	return dh.load(r, pos, &tmpBuf)
 }
 
+// LoadPrevRev reads and decodes previous revision data record
+// prerequisite: dh .Oid .Tid .PrevRevPos are initialized:
+//   - TODO describe how
+// when there is no previous revision: io.EOF is returned
+func (dh *DataHeader) LoadPrevRev(r io.ReaderAt /* *os.File */) error {
+	if dh.PrevRevPos == 0 {	// XXX -> -1 ?
+		return io.EOF	// no more previous revisions
+	}
+
+	err = dh.Load(r, dh.PrevRevPos)
+	if err != nil {
+		return err
+	}
+
+	if dh.Oid != oid {
+		// data record @...: while loading as prev rev for data record @...: oid mismatch ...
+		return ...
+	}
+
+	if dh.Tid >= tid {
+		// data record @...: while loading as prev rev for data record @...: tid not decreasing: ...
+		return ...
+	}
+
+	return nil
+}
+
+func (dh *DataHeader) LoadBack(r io.ReaderAt /* *os.File */) error {
+}
 
 
 func Open(path string) (*FileStorage, error) {
@@ -477,42 +508,22 @@ func (fs *FileStorage) Load(xid zodb.Xid) (data []byte, tid zodb.Tid, err error)
 		return nil, zodb.Tid(0), &ErrXidLoad{xid, zodb.ErrOidMissing{Oid: xid.Oid}}
 	}
 
-	dh := DataHeader{Tid: zodb.TidMax}
+	dh := DataHeader{Oid: xid.Oid, Tid: zodb.TidMax, PrevRevPos: dataPos}
 	tidBefore := xid.XTid.Tid
 	if !xid.XTid.TidBefore {
 		tidBefore++	// XXX recheck this is ok wrt overflow
 	}
 
 	// search backwards for when we first have data record with tid satisfying xid.XTid
-	for {
-		//prevTid := dh.Tid
-		err = dh.Load(fs.file, dataPos)
+	for dh.Tid >= tidBefore {
+		err = dh.LoadPrevRev(fs.file)
 		if err != nil {
+			if err == io.EOF {
+				// no such oid revision
+				err = &zodb.ErrXidMissing{Xid: xid}
+			}
 			return nil, zodb.Tid(0), &ErrXidLoad{xid, err}
 		}
-
-		// TODO -> LoadPrev()
-		// check data record consistency
-		// TODO reenable
-		// if dh.Oid != oid {
-		// 	// ... header invalid:
-		// 	return nil, zodb.Tid(0), &ErrXidLoad{xid, &ErrDataRecord{dataPos, "consistency check", "TODO unexpected oid")}
-		// }
-
-		// if dh.Tid >= prevTid { ... }
-		// if dh.TxnPos >= dataPos - TxnHeaderSize { ... }
-		// if dh.PrevDataRecPos >= dh.TxnPos - DataHeaderSize - 8 /* XXX */ { ... }
-
-		if dh.Tid < tidBefore {
-			break
-		}
-
-		// continue search
-		dataPos = dh.PrevRevPos
-		if dataPos == 0 {
-			// no such oid revision
-			return nil, zodb.Tid(0), &ErrXidLoad{xid, &zodb.ErrXidMissing{Xid: xid}}
-		}
 	}
 
 	// found dh.Tid < tidBefore; check it really satisfies xid.XTid