Selaa lähdekoodia

Merge pull request #3256 from alexlarsson/blkdiscard

Discard all data on devicemapper devices when deleting them
Michael Crosby 11 vuotta sitten
vanhempi
commit
a60f0a0754

+ 9 - 0
graphdriver/devmapper/deviceset.go

@@ -568,6 +568,15 @@ func (devices *DeviceSet) removeDevice(hash string) error {
 		return fmt.Errorf("hash %s doesn't exists", hash)
 	}
 
+	// This is a workaround for the kernel not discarding block so
+	// on the thin pool when we remove a thinp device, so we do it
+	// manually
+	if err := devices.activateDeviceIfNeeded(hash); err == nil {
+		if err := BlockDeviceDiscard(info.DevName()); err != nil {
+			utils.Debugf("Error discarding block on device: %s (ignoring)\n", err)
+		}
+	}
+
 	devinfo, _ := getInfo(info.Name())
 	if devinfo != nil && devinfo.Exists != 0 {
 		if err := removeDevice(info.Name()); err != nil {

+ 24 - 0
graphdriver/devmapper/devmapper.go

@@ -7,6 +7,7 @@ import (
 	"fmt"
 	"github.com/dotcloud/docker/utils"
 	"runtime"
+	"syscall"
 )
 
 type DevmapperLogger interface {
@@ -288,6 +289,29 @@ func GetBlockDeviceSize(file *osFile) (uint64, error) {
 	return uint64(size), nil
 }
 
+func BlockDeviceDiscard(path string) error {
+	file, err := osOpenFile(path, osORdWr, 0)
+	if err != nil {
+		return err
+	}
+	defer file.Close()
+
+	size, err := GetBlockDeviceSize(file)
+	if err != nil {
+		return err
+	}
+
+	if err := ioctlBlkDiscard(file.Fd(), 0, size); err != nil {
+		return err
+	}
+
+	// Without this sometimes the remove of the device that happens after
+	// discard fails with EBUSY.
+	syscall.Sync()
+
+	return nil
+}
+
 // This is the programmatic example of "dmsetup create"
 func createPool(poolName string, dataFile, metadataFile *osFile) error {
 	task, err := createTask(DeviceCreate, poolName)

+ 1 - 0
graphdriver/devmapper/devmapper_wrapper.go

@@ -66,6 +66,7 @@ type (
 // IOCTL consts
 const (
 	BlkGetSize64 = C.BLKGETSIZE64
+	BlkDiscard   = C.BLKDISCARD
 
 	LoopSetFd       = C.LOOP_SET_FD
 	LoopCtlGetFree  = C.LOOP_CTL_GET_FREE

+ 4 - 0
graphdriver/devmapper/driver_test.go

@@ -641,6 +641,10 @@ func TestDriverRemove(t *testing.T) {
 			"DmTaskSetMessage",
 			"DmTaskCreate",
 			"DmTaskGetInfo",
+			"DmTaskSetCookie",
+			"DmTaskSetTarget",
+			"DmTaskSetAddNode",
+			"DmUdevWait",
 			"Mounted",
 			"sysUnmount",
 		)

+ 11 - 0
graphdriver/devmapper/ioctl.go

@@ -58,3 +58,14 @@ func ioctlBlkGetSize64(fd uintptr) (int64, error) {
 	}
 	return size, nil
 }
+
+func ioctlBlkDiscard(fd uintptr, offset, length uint64) error {
+	var r [2]uint64
+	r[0] = offset
+	r[1] = length
+
+	if _, _, err := sysSyscall(sysSysIoctl, fd, BlkDiscard, uintptr(unsafe.Pointer(&r[0]))); err != 0 {
+		return err
+	}
+	return nil
+}