// diskFree inspects the filesystem for path and returns the volume name and
// the total and free bytes available on the file system.
503569
func (f *StorageFingerprint) diskFree(path string) (volume string, total, free uint64, err error) {
	absPath, err := filepath.Abs(path)
	if err != nil {
		return "", 0, 0, fmt.Errorf("failed to determine absolute path for %s", path)
	}

	// Use -k to standardize the output values between darwin and linux
	var dfArgs string
	if runtime.GOOS == "linux" {
		// df on linux needs the -P option to prevent linebreaks on long filesystem paths
		dfArgs = "-kP"
	} else {
		dfArgs = "-k"
	}

	mountOutput, err := exec.Command("df", dfArgs, absPath).Output()
	if err != nil {
		return "", 0, 0, fmt.Errorf("failed to determine mount point for %s", absPath)
	}
	// Output looks something like:
	//	Filesystem 1024-blocks      Used Available Capacity   iused    ifree %iused  Mounted on
	//	/dev/disk1   487385240 423722532  63406708    87% 105994631 15851677   87%   /
	//	[0] volume [1] capacity [2] SKIP  [3] free
	lines := strings.Split(string(mountOutput), "\n")
	if len(lines) < 2 {
		return "", 0, 0, fmt.Errorf("failed to parse `df` output; expected at least 2 lines")
	}
	fields := strings.Fields(lines[1])
	if len(fields) < 4 {
		return "", 0, 0, fmt.Errorf("failed to parse `df` output; expected at least 4 columns")
	}
	volume = fields[0]

	total, err = strconv.ParseUint(fields[1], 10, 64)
	if err != nil {
		return "", 0, 0, fmt.Errorf("failed to parse storage.bytestotal size in kilobytes")
	}
	// convert to bytes
	total *= 1024

	free, err = strconv.ParseUint(fields[3], 10, 64)
	if err != nil {
		return "", 0, 0, fmt.Errorf("failed to parse storage.bytesfree size in kilobytes")
	}
	// convert to bytes
	free *= 1024

	return volume, total, free, nil
}
1128040
func (d *Diskv) pathFor(pathKey *PathKey) string {
	return filepath.Join(d.BasePath, filepath.Join(pathKey.Path...))
}
358628
func (f *FS) GetDiskFreeSpace(ctx context.Context) (freeSpace dokan.FreeSpace, err error) {
	// TODO should this be refused to other users?
	// As the mount is limited to current session there is little need.
	f.logEnter(ctx, "FS GetDiskFreeSpace")
	// Refuse private directories while we are in a error state.
	if f.remoteStatus.ExtraFileName() != "" {
		f.log.Warning("Dummy disk free space while errors are present!")
		return dokan.FreeSpace{
			TotalNumberOfBytes:     dummyFreeSpace,
			TotalNumberOfFreeBytes: dummyFreeSpace,
			FreeBytesAvailable:     dummyFreeSpace,
		}, nil
	}
	defer func() {
		if err == nil {
			f.vlog.CLogf(ctx, libkb.VLog1, "Request complete")
		} else {
			// Don't report the error (perhaps resulting in a user
			// notification) since this method is mostly called by the
			// OS and not because of a user action.
			f.log.CDebugf(ctx, err.Error())
		}
	}()
	_, usageBytes, _, limitBytes, err := f.quotaUsage.Get(
		ctx, quotaUsageStaleTolerance/2, quotaUsageStaleTolerance)
	if err != nil {
		return dokan.FreeSpace{}, errToDokan(err)
	}
	free := uint64(limitBytes - usageBytes)
	return dokan.FreeSpace{
		TotalNumberOfBytes:     uint64(limitBytes),
		TotalNumberOfFreeBytes: free,
		FreeBytesAvailable:     free,
	}, nil
}
1256413
func (os *OpenStack) DetachDisk(instanceID, volumeID string) error {
	volume, err := os.getVolume(volumeID)
	if err != nil {
		return err
	}
	if volume.Status == volumeAvailableStatus {
		// "available" is fine since that means the volume is detached from instance already.
		klog.V(2).Infof("volume: %s has been detached from compute: %s ", volume.ID, instanceID)
		return nil
	}

	if volume.Status != volumeInUseStatus {
		return fmt.Errorf("can not detach volume %s, its status is %s", volume.Name, volume.Status)
	}
	cClient, err := os.NewComputeV2()
	if err != nil {
		return err
	}
	if volume.AttachedServerID != instanceID {
		return fmt.Errorf("disk: %s has no attachments or is not attached to compute: %s", volume.Name, instanceID)
	}

	startTime := time.Now()
	// This is a blocking call and effects kubelet's performance directly.
	// We should consider kicking it out into a separate routine, if it is bad.
	err = volumeattach.Delete(cClient, instanceID, volume.ID).ExtractErr()
	timeTaken := time.Since(startTime).Seconds()
	recordOpenstackOperationMetric("detach_disk", timeTaken, err)
	if err != nil {
		return fmt.Errorf("failed to delete volume %s from compute %s attached %v", volume.ID, instanceID, err)
	}
	klog.V(2).Infof("Successfully detached volume: %s from compute: %s", volume.ID, instanceID)

	return nil
}
249601
func (n *NodeDevice) Free() error {
	var err C.virError
	ret := C.virNodeDeviceFreeWrapper(n.ptr, &err)
	if ret == -1 {
		return makeError(&err)
	}
	return nil
}
628481
func getFSType(path string) string {
	var volumeNameSize uint32 = 260
	var nFileSystemNameSize, lpVolumeSerialNumber uint32
	var lpFileSystemFlags, lpMaximumComponentLength uint32
	var lpFileSystemNameBuffer, volumeName [260]byte
	var ps = syscall.StringToUTF16Ptr(filepath.VolumeName(path))

	// Extract values safely
	// BOOL WINAPI GetVolumeInformation(
	// _In_opt_  LPCTSTR lpRootPathName,
	// _Out_opt_ LPTSTR  lpVolumeNameBuffer,
	// _In_      DWORD   nVolumeNameSize,
	// _Out_opt_ LPDWORD lpVolumeSerialNumber,
	// _Out_opt_ LPDWORD lpMaximumComponentLength,
	// _Out_opt_ LPDWORD lpFileSystemFlags,
	// _Out_opt_ LPTSTR  lpFileSystemNameBuffer,
	// _In_      DWORD   nFileSystemNameSize
	// );

	_, _, _ = GetVolumeInformation.Call(uintptr(unsafe.Pointer(ps)),
		uintptr(unsafe.Pointer(&volumeName)),
		uintptr(volumeNameSize),
		uintptr(unsafe.Pointer(&lpVolumeSerialNumber)),
		uintptr(unsafe.Pointer(&lpMaximumComponentLength)),
		uintptr(unsafe.Pointer(&lpFileSystemFlags)),
		uintptr(unsafe.Pointer(&lpFileSystemNameBuffer)),
		uintptr(unsafe.Pointer(&nFileSystemNameSize)), 0)
	var bytes []byte
	if lpFileSystemNameBuffer[6] == 0 {
		bytes = []byte{lpFileSystemNameBuffer[0], lpFileSystemNameBuffer[2],
			lpFileSystemNameBuffer[4]}
	} else {
		bytes = []byte{lpFileSystemNameBuffer[0], lpFileSystemNameBuffer[2],
			lpFileSystemNameBuffer[4], lpFileSystemNameBuffer[6]}
	}

	return string(bytes)
}
1048909
func getDiskLimits(path string) (
	availableBytes, totalBytes, availableFiles, totalFiles uint64, err error) {
	pathPtr, err := windows.UTF16PtrFromString(path)
	if err != nil {
		return 0, 0, 0, 0, errors.WithStack(err)
	}

	dll := windows.NewLazySystemDLL("kernel32.dll")
	proc := dll.NewProc("GetDiskFreeSpaceExW")
	r1, _, err := proc.Call(uintptr(unsafe.Pointer(pathPtr)),
		uintptr(unsafe.Pointer(&availableBytes)),
		uintptr(unsafe.Pointer(&totalBytes)), 0)
	// err is always non-nil, but meaningful only when r1 == 0
	// (which signifies function failure).
	if r1 == 0 {
		return 0, 0, 0, 0, errors.WithStack(err)
	}

	// TODO: According to http://superuser.com/a/104224 , on
	// Windows, the available file limit is determined just from
	// the filesystem type. Detect the filesystem type and use
	// that to determine and return availableFiles.

	// For now, assume all FSs on Windows are NTFS, or have
	// similarly large file limits.
	return availableBytes, totalBytes, math.MaxInt64, math.MaxInt64, nil
}
831362
func (u *volumeUtil) GetFsCapacityByte(fullPath string) (int64, error) {
	_, capacity, _, _, _, _, err := fs.FsInfo(fullPath)
	return capacity, err
}
440570
func (client *storageRESTClient) DiskInfo() (info DiskInfo, err error) {
	respBody, err := client.call(storageRESTMethodDiskInfo, nil, nil, -1)
	if err != nil {
		return
	}
	defer http.DrainBody(respBody)
	err = gob.NewDecoder(respBody).Decode(&info)
	return info, err
}
1226240
func diskCount(disks []StorageAPI) int {
	diskCount := 0
	for _, disk := range disks {
		if disk == nil {
			continue
		}
		diskCount++
	}
	return diskCount
}
546026
func (d *RsyncDriver) Get(volumeName string) (volume.Volume, error) {
	volumePath := filepath.Join(d.root, volumeName)
	volume := &RsyncVolume{
		timeout: 30 * time.Second,
		name:    volumeName,
		path:    volumePath,
		driver:  d,
		tenant:  getTenant(volumeName),
	}
	return volume, nil
}
579277
func CheckFreeDiskSpace(dir string, thresholdMib uint64) error {
	usage := du.NewDiskUsage(dir)
	available := usage.Available()
	if available < thresholdMib*humanize.MiByte {
		return errors.Errorf("not enough free disk space on %q for upgrade: %s available, require %dMiB",
			dir, humanize.IBytes(available), thresholdMib)
	}
	return nil
}
779046
func (c *Host) GetVolume(volumeID string) (*volume.Info, error) {
	var volume volume.Info
	return &volume, c.c.Get(fmt.Sprintf("/storage/volumes/%s", volumeID), &volume)
}
577041
func (d Data) IsFree(split uint) error {
	want := d.filesize + split
	if d.freeSpace() < want {
		return errors.Errorf("there is not sufficient free space in a disk")
	}

	return nil
}
240875
func (d *driver) getNFSVolumePath(v *api.Volume) (string, error) {
	parentPath, err := d.getNFSPath(v)
	if err != nil {
		return "", err
	}

	return path.Join(parentPath, v.Id), nil
}
376442
func volumeName(dir string) (string, error) {
	volName := path.Base(dir)
	if volName == "." || volName == "/" {
		err := fmt.Errorf("Bad volume name: %v", volName)
		return "", err
	}
	s := strings.Split(volName, " ")
	if len(s) == 0 {
		return "", fmt.Errorf("Bad volume name: %v", volName)
	}
	return s[0], nil
}
819988
func (n *node) free() {
	if n.pgid != 0 {
		n.bucket.tx.db.freelist.free(n.bucket.tx.meta.txid, n.bucket.tx.page(n.pgid))
		n.pgid = 0
	}
}