mirror of
https://github.com/kopia/kopia.git
synced 2026-01-20 04:17:54 -05:00
This removes big shared lock held for for the duration of each request and replaces it with trivially short lock to capture the current state of the server/repository before passing it to handlers. Handlers are now limited to only accessing a small subset of Server functionality to be able to better reason about them.
69 lines
1.4 KiB
Go
69 lines
1.4 KiB
Go
package server
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/pkg/errors"
|
|
|
|
"github.com/kopia/kopia/internal/mount"
|
|
"github.com/kopia/kopia/repo"
|
|
"github.com/kopia/kopia/repo/object"
|
|
"github.com/kopia/kopia/snapshot/snapshotfs"
|
|
)
|
|
|
|
func (s *Server) getMountController(ctx context.Context, rep repo.Repository, oid object.ID, createIfNotFound bool) (mount.Controller, error) {
|
|
s.serverMutex.Lock()
|
|
defer s.serverMutex.Unlock()
|
|
|
|
c := s.mounts[oid]
|
|
if c != nil {
|
|
return c, nil
|
|
}
|
|
|
|
if !createIfNotFound {
|
|
return nil, nil
|
|
}
|
|
|
|
log(ctx).Debugf("mount controller for %v not found, starting", oid)
|
|
|
|
c, err := mount.Directory(ctx, snapshotfs.DirectoryEntry(rep, oid, nil), "*", mount.Options{})
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "unable to mount")
|
|
}
|
|
|
|
s.mounts[oid] = c
|
|
|
|
return c, nil
|
|
}
|
|
|
|
func (s *Server) listMounts() map[object.ID]mount.Controller {
|
|
s.serverMutex.RLock()
|
|
defer s.serverMutex.RUnlock()
|
|
|
|
result := map[object.ID]mount.Controller{}
|
|
|
|
for oid, c := range s.mounts {
|
|
result[oid] = c
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
func (s *Server) deleteMount(oid object.ID) {
|
|
s.serverMutex.Lock()
|
|
defer s.serverMutex.Unlock()
|
|
|
|
delete(s.mounts, oid)
|
|
}
|
|
|
|
// +checklocks:s.serverMutex
|
|
func (s *Server) unmountAllLocked(ctx context.Context) {
|
|
for oid, c := range s.mounts {
|
|
if err := c.Unmount(ctx); err != nil {
|
|
log(ctx).Errorf("unable to unmount %v", oid)
|
|
}
|
|
|
|
delete(s.mounts, oid)
|
|
}
|
|
}
|