X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/6b0d4ac8df4b5b4255eb56b1d76865f06089ca2a..ffe48ca94f89f3d7b71305b394e1f57ee633efed:/sdk/go/arvados/fs_base.go diff --git a/sdk/go/arvados/fs_base.go b/sdk/go/arvados/fs_base.go index b0096140ce..274d207022 100644 --- a/sdk/go/arvados/fs_base.go +++ b/sdk/go/arvados/fs_base.go @@ -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