From a8bbffa90ae3823580e96dfec91b631f06304622 Mon Sep 17 00:00:00 2001
From: Kirill Smelkov <kirr@nexedi.com>
Date: Mon, 2 Mar 2020 17:48:00 +0300
Subject: [PATCH] .

---
 wcfs/client/wcfs.cpp | 20 +++++++++-----------
 wcfs/client/wcfs.h   | 13 +++++--------
 2 files changed, 14 insertions(+), 19 deletions(-)

diff --git a/wcfs/client/wcfs.cpp b/wcfs/client/wcfs.cpp
index b052d788..69e5888a 100644
--- a/wcfs/client/wcfs.cpp
+++ b/wcfs/client/wcfs.cpp
@@ -676,22 +676,22 @@ retry:
     f->_headfsize = 0;
     f->_state     = _FileHOpening;
     f->_nopen     = 1;
-    f->_closed    = false;
 
     bool retok = false;
     wconn._filehTab[foid] = f;
     defer([&]() {
+        wconn._mu.Lock();
+        if (wconn._filehTab.get(foid) != f) {
+            wconn._mu.Unlock();
+            panic("BUG: wconn.open: wconn.filehTab[foid] mutated while file open was in progress");
+        }
         if (!retok) {
-            wconn._mu.Lock();
             // don't care about f->_nopen-- since f is not returned anywhere
-            if (wconn._filehTab.get(foid) != f) {
-                wconn._mu.Unlock();
-                panic("BUG: wconn.open: wconn.filehTab[foid] mutated while file open was in progress");
-            }
             wconn._filehTab.erase(foid);
-            wconn._mu.Unlock();
+        } else {
+            f->_state = _FileHOpened;
         }
-        f->_state = _FileHOpened;   // XXX move under wconn._mu ?
+        wconn._mu.Unlock();
         f->_openReady.close();
     });
     wconn._mu.Unlock();
@@ -768,7 +768,6 @@ error _FileH::close() {
     });
 
     // fileh.close can be called several times. just return nil for second close.
-//  if (fileh._closed)
     if (fileh._state >= _FileHClosing)
         return nil;
 
@@ -818,7 +817,6 @@ error _FileH::close() {
     fileh._state = _FileHClosed; // XXX locking
     fileh._closedq.close();
 
-    fileh._closed = true;
     return E(eret);
 }
 
@@ -840,7 +838,7 @@ pair<Mapping, error> _FileH::mmap(int64_t blk_start, int64_t blk_len, VMA *vma)
 
     xerr::Contextf E("%s: mmap f<%s> [blk%ld +blk%ld)", v(f.wconn), v(f.foid), blk_start, blk_len);
 
-    if (f._closed)  // XXX locking
+    if (f._state >= _FileHClosing)  // XXX locking
         return make_pair(nil, E(os::ErrClosed));
 
     error err;
diff --git a/wcfs/client/wcfs.h b/wcfs/client/wcfs.h
index 7af3127f..34e42781 100644
--- a/wcfs/client/wcfs.h
+++ b/wcfs/client/wcfs.h
@@ -231,6 +231,11 @@ struct _FileH : object {
     Conn        wconn;
     zodb::Oid   foid;       // ZBigFile root object ID (does not change after fileh open)
 
+    // protect by wconn.mu
+    _FileHState _state;  // opening/opened/closing/closed
+    int         _nopen;  // number of times Conn.open returned this fileh
+    bool        _closed; // y after .close()
+
     chan<structZ> _openReady; // in-flight open completed
     error         _openErr;   // error result from open
     chan<structZ> _closedq;   // in-flight close completed
@@ -246,14 +251,6 @@ struct _FileH : object {
     dict<int64_t, zodb::Tid>  _pinned; // {} blk -> rev   that wcfs already sent us for this file
     vector<Mapping>           _mmaps;  // []Mapping ↑blk_start    mappings of this file
 
-    // XXX protect by wconn.mu ?
-    enum _FileHState          _state;  // opening/opened/closing/closed
-    int                       _nopen;  // number of times Conn.open returned this fileh
-    bool                      _closed; // y after .close()
-
-    // "watch <.foid> ..." requests we send to wcfs are serialized via FileH._watchMu
-    // XXX sync::Mutex        _watchMu;     XXX kill
-
     // don't new - create via Conn.open
 private:
     _FileH();
-- 
2.30.9