19362: Sync s3 updates to long-lived session for same token.
[arvados.git] / sdk / go / arvados / fs_base.go
index b0096140cecec46bc50831a3e78abfcf1394c61d..274d20702287ed464d4ea8f3796e528c3f61b30b 100644 (file)
@@ -420,10 +420,20 @@ func (n *treenode) Sync() error {
 }
 
 func (n *treenode) MemorySize() (size int64) {
+       // To avoid making other callers wait while we count the
+       // entire filesystem size, we lock the node only long enough
+       // to copy the list of children. We accept that the resulting
+       // size will sometimes be misleading (e.g., we will
+       // double-count an item that moves from A to B after we check
+       // A's size but before we check B's size).
        n.RLock()
-       defer n.RUnlock()
        debugPanicIfNotLocked(n, false)
+       todo := make([]inode, 0, len(n.inodes))
        for _, inode := range n.inodes {
+               todo = append(todo, inode)
+       }
+       n.RUnlock()
+       for _, inode := range todo {
                size += inode.MemorySize()
        }
        return 64 + size
@@ -632,7 +642,7 @@ func (fs *fileSystem) Rename(oldname, newname string) error {
        locked := map[sync.Locker]bool{}
        for i := len(needLock) - 1; i >= 0; i-- {
                n := needLock[i]
-               if fs, ok := n.(FileSystem); ok {
+               if fs, ok := n.(interface{ rootnode() inode }); ok {
                        // Lock the fs's root dir directly, not
                        // through the fs. Otherwise our "locked" map
                        // would not reliably prevent double-locking