You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: mount.go
    path of file: ./repos/goldfish/vendor/github.com/hashicorp/vault/vault
    
    the code of the file until where you have to start completion: package vault

import (
	"crypto/sha1"
	"encoding/json"
	"errors"
	"fmt"
	"sort"
	"strings"
	"time"

	"github.com/hashicorp/errwrap"
	"github.com/hashicorp/go-uuid"
	"github.com/hashicorp/vault/helper/consts"
	"github.com/hashicorp/vault/helper/jsonutil"
	"github.com/hashicorp/vault/helper/strutil"
	"github.com/hashicorp/vault/logical"
	"github.com/mitchellh/copystructure"
)

const (
	// coreMountConfigPath is used to store the mount configuration.
	// Mounts are protected within the Vault itself, which means they
	// can only be viewed or modified after an unseal.
	coreMountConfigPath = "core/mounts"

	// coreLocalMountConfigPath is used to store mount configuration for local
	// (non-replicated) mounts
	coreLocalMountConfigPath = "core/local-mounts"

	// backendBarrierPrefix is the prefix to the UUID used in the
	// barrier view for the backends.
	backendBarrierPrefix = "logical/"

	// systemBarrierPrefix is the prefix used for the
	// system logical backend.
	systemBarrierPrefix = "sys/"

	// mountTableType is the value we expect to find for the mount table and
	// corresponding entries
	mountTableType = "mounts"
)

var (
	// loadMountsFailed if loadMounts encounters a
    
func (c *Core) unmountInternal(path string) error {
	// Verify exact match of the route
	match := c.router.MatchingMount(path)
	if match == "" || path != match {
		return fmt.Errorf("no matching mount")
	}

	// Get the view for this backend
	view := c.router.MatchingStorageByAPIPath(path)

	// Get the backend/mount entry for this path, used to remove ignored
	// replication prefixes
	backend := c.router.MatchingBackend(path)
	entry := c.router.MatchingMountEntry(path)

	// Mark the entry as tainted
	if err := c.taintMountEntry(path); err != nil {
		c.logger.Error("core: failed to taint mount entry for path being unmounted", "error", err, "path", path)
		return err
	}

	// Taint the router path to prevent routing. Note that in-flight requests
	// are uncertain, right now.
	if err := c.router.Taint(path); err != nil {
		return err
	}

	if backend != nil {
		// Invoke the rollback manager a final time
		if err := c.rollback.Rollback(path); err != nil {
			return err
		}

		// Revoke all the dynamic keys
		if err := c.expiration.RevokePrefix(path); err != nil {
			return err
		}

		// Call cleanup function if it exists
		backend.Cleanup()
	}

	// Unmount the backend entirely
	if err := c.router.Unmount(path); err != nil {
		return err
	}

	switch {
	case entry.Local, !c.replicationState.HasState(consts.ReplicationPerformanceSecondary):
		// Have writable storage, remove the whole thing
		if err := logical.ClearView(view); err != nil {
			c.logger.Error("core: failed to clear view for path being unmounted", "error", err, "path", path)
			return err
		}
	}

	// Remove the mount table entry
	if err := c.removeMountEntry(path); err != nil {
		c.logger.Error("core: failed to remove mount entry for path being unmounted", "error", err, "path", path)
		return err
	}

	if c.logger.IsInfo() {
		c.logger.Info("core: successfully unmounted", "path", path)
	}
	return nil
}