<commit_before>package mount

import (
	"errors"
	"fmt"
	"strings"
	"sync"
	"syscall"

	log "github.com/Sirupsen/logrus"
	"github.com/docker/docker/pkg/mount"
)

// Ops defines the interface for keep track of volume driver mounts.
type Ops interface {
	// String representation of the mount table
	String() string
	// Load mount table for all devices that match the prefix. An empty prefix may
	// be provided.
	Load(devPrefix string) error
	// Inspect mount table for specified device. ErrEnoent may be returned.
	Inspect(device string) (Info, error)
	// Exists returns true if the device is mounted at specified path.
	// returned if the device does not exists.
	Exists(device, path string) (bool, error)
	// Mount device at mountpoint or increment refcnt if device is already mounted
	// at specified mountpoint.
	Mount(Minor int32, device, path, fs string, flags uintptr, data string) error
	// Unmount device at mountpoint or decrement refcnt. If device has no
	// mountpoints left after this operation, it is removed from the matrix.
	// ErrEnoent is returned if the device or mountpoint for the device is not found.
	Unmount(device, path string) error
}

// DeviceMap map device name to Info
type DeviceMap map[string]*Info

// PathInfo is a reference counted path
type PathInfo struct {
	Path string
	ref  int
}

// Info per device
type Info struct {
	Device     string
	Minor      int
	Mountpoint []PathInfo
	Fs         string
}

// Matrix implements Ops and keeps track of active mounts for volume drivers.
type Matrix struct {
	sync.Mutex
	mounts DeviceMap
}

var (
	// ErrEnoent is returned for a non existent mount point
	ErrEnoent = errors.New("Mountpath is not mounted")
	// ErrEinval is returned is fields for an entry do no match
	// existing fields
	ErrEinval = errors.New("Invalid arguments for mount entry")
)

// New instance of Matrix
func New(devPrefix string) (*Matrix, error) {
	m := &Matrix{
		mounts: make(DeviceMap),
	}
	err := m.Load(devPrefix)
	if err != nil {
		return nil, err
	}
	return m, nil
}

// Exists scans mountpaths for specified device and returns true if path is one of the
// mountpaths. ErrEnoent may be retuned if the device is not found
func (m *Matrix) Exists(devPath string, path string) (bool, error) {
	m.Lock()
	defer m.Unlock()

	v, ok := m.mounts[devPath]
	if !ok {
		return false, ErrEnoent
	}
	for _, p := range v.Mountpoint {
		if p.Path == path {
			return true, nil
		}
	}
	return false, nil
}

// Mount new mountpoint for specified device.
func (m *Matrix) Mount(minor int, device, path, fs string, flags uintptr, data string) error {
	m.Lock()
	defer m.Unlock()

	info, ok := m.mounts[device]
	if !ok {
		info = &Info{
			Device:     device,
			Mountpoint: make([]PathInfo, 8),<commit_msg>add function to determine runtime device mounts<commit_after>// +build linux

package mount

import (
	"errors"
	"fmt"
	"strings"
	"sync"
	"syscall"

	log "github.com/Sirupsen/logrus"
	"github.com/docker/docker/pkg/mount"
)

// Ops defines the interface for keep track of volume driver mounts.
type Ops interface {
	// String representation of the mount table
	String() string
	// Load mount table for all devices that match the prefix. An empty prefix may
	// be provided.
	Load(devPrefix string) error
	// Inspect mount table for specified device. ErrEnoent may be returned.
	Inspect(device string) (Info, error)
	// HasMounts determines returns the number of mounts for the device.
	HasMounts(devPath string)
	// Exists returns true if the device is mounted at specified path.
	// returned if the device does not exists.
	Exists(device, path string) (bool, error)
	// Mount device at mountpoint or increment refcnt if device is already mounted
	// at specified mountpoint.
	Mount(Minor int32, device, path, fs string, flags uintptr, data string) error
	// Unmount device at mountpoint or decrement refcnt. If device has no
	// mountpoints left after this operation, it is removed from the matrix.
	// ErrEnoent is returned if the device or mountpoint for the device is not found.
	Unmount(device, path string) error
}

// DeviceMap map device name to Info
type DeviceMap map[string]*Info

// PathInfo is a reference counted path
type PathInfo struct {
	Path string
	ref  int
}

// Info per device
type Info struct {
	Device     string
	Minor      int
	Mountpoint []PathInfo
	Fs         string
}

// Matrix implements Ops and keeps track of active mounts for volume drivers.
type Matrix struct {
	sync.Mutex
	mounts DeviceMap
}

var (
	// ErrEnoent is returned for a non existent mount point
	ErrEnoent = errors.New("Mountpath is not mounted")
	// ErrEinval is returned is fields for an entry do no match
	// existing fields
	ErrEinval = errors.New("Invalid arguments for mount entry")
)

// New instance of Matrix
func New(devPrefix string) (*Matrix, error) {
	m := &Matrix{
		mounts: make(DeviceMap),
	}
	err := m.Load(devPrefix)
	if err != nil {
		return nil, err
	}
	return m, nil
}

// HasMounts determines returns the number of mounts for the device.
func (m *Matrix) HasMounts(devPath string) int {
	m.Lock()
	defer m.Unlock()

	v, ok := m.mounts[devPath]
	if !ok {
		return 0
	}
	return len(v.Mountpoint)
}

// Exists scans mountpaths for specified device and returns true if path is one of the
// mountpaths. ErrEnoent may be retuned if the device is not found
func (m *Matrix) Exists(devPath string, path string) (bool, error) {
	m.Lock()
	defer m.Unlock()

	v, ok := m.mounts[devPath]
	if !ok {
		return false, ErrEnoent
	}
	for _, p := range v.Mountpoint {
		if p.Path == path {
			return true, nil
		}
	}
	return false, nil
}

// Mount new mountpoint for specified device.
func (m *Matrix) Mount(minor int, device, path, fs string, flags uintptr, data string) error {
	m.Lock()
	defer m.Unlock()

	info, ok := m.mounts[device]
	if !ok {
		info = &Info{
			Device:     device,
			Mountpoint: make([]PathInfo, 8),
{'fraction_non_alphanumeric': 0.089857045609258, 'fraction_numerical': 0.001191286589516678, 'mean_word_length': 3.5, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5587095', 'n_tokens_mistral': 1883, 'n_tokens_neox': 1819, 'n_words': 770}