[lxc-devel] [lxd/master] btrfs: only enable quota when necessary

brauner on Github lxc-bot at linuxcontainers.org
Tue Jun 6 17:58:44 UTC 2017


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 525 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20170606/8bdca462/attachment.bin>
-------------- next part --------------
From 1c03e33288f2df297653f96b1e7a6d30676e5873 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Tue, 6 Jun 2017 19:57:19 +0200
Subject: [PATCH] btrfs: only enable quota when necessary

Enabling quota is an expensive operation that seems to have consequences for
every other operation after it has been enabled. So let's only do it on demand.

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/storage_btrfs.go | 40 ++++++++++++++++++++++------------------
 1 file changed, 22 insertions(+), 18 deletions(-)

diff --git a/lxd/storage_btrfs.go b/lxd/storage_btrfs.go
index a2956971a..19d93ec4f 100644
--- a/lxd/storage_btrfs.go
+++ b/lxd/storage_btrfs.go
@@ -222,16 +222,9 @@ func (s *storageBtrfs) StoragePoolCreate() error {
 		return err1
 	}
 
-	// Enable quotas
-	output, err := shared.RunCommand(
-		"btrfs", "quota", "enable", poolMntPoint)
-	if err != nil && !runningInUserns {
-		return fmt.Errorf("Failed to enable quotas on BTRFS pool: %s", output)
-	}
-
 	// Create default subvolumes.
 	dummyDir := getContainerMountPoint(s.pool.Name, "")
-	err = btrfsSubVolumeCreate(dummyDir)
+	err := btrfsSubVolumeCreate(dummyDir)
 	if err != nil {
 		return fmt.Errorf("Could not create btrfs subvolume: %s", dummyDir)
 	}
@@ -1068,9 +1061,19 @@ func (s *storageBtrfs) ContainerSetQuota(container container, size int64) error
 
 	subvol := container.Path()
 
-	_, err := btrfsSubVolumeQGroup(subvol)
-	if err != nil {
-		return err
+	_, status := btrfsSubVolumeQGroup(subvol)
+	if status != 0 {
+		if status == 1 {
+			return fmt.Errorf("no quota group found")
+		}
+
+		// Enable quotas
+		poolMntPoint := getStoragePoolMountPoint(s.pool.Name)
+		output, err := shared.RunCommand(
+			"btrfs", "quota", "enable", poolMntPoint)
+		if err != nil && !runningInUserns {
+			return fmt.Errorf("Failed to enable quotas on BTRFS pool: %s", output)
+		}
 	}
 
 	output, err := shared.RunCommand(
@@ -1440,7 +1443,7 @@ func btrfsSubVolumeCreate(subvol string) error {
 	return nil
 }
 
-func btrfsSubVolumeQGroup(subvol string) (string, error) {
+func btrfsSubVolumeQGroup(subvol string) (string, int) {
 	output, err := shared.RunCommand(
 		"btrfs",
 		"qgroup",
@@ -1450,7 +1453,8 @@ func btrfsSubVolumeQGroup(subvol string) (string, error) {
 		"-f")
 
 	if err != nil {
-		return "", fmt.Errorf("BTRFS quotas not supported. Try enabling them with \"btrfs quota enable\"")
+		logger.Errorf("BTRFS quotas not supported. Try enabling them with \"btrfs quota enable\"")
+		return "", -1
 	}
 
 	var qgroup string
@@ -1468,10 +1472,10 @@ func btrfsSubVolumeQGroup(subvol string) (string, error) {
 	}
 
 	if qgroup == "" {
-		return "", fmt.Errorf("Unable to find quota group")
+		return "", 1
 	}
 
-	return qgroup, nil
+	return qgroup, 0
 }
 
 func (s *storageBtrfs) btrfsPoolVolumeQGroupUsage(subvol string) (int64, error) {
@@ -1510,8 +1514,8 @@ func (s *storageBtrfs) btrfsPoolVolumeQGroupUsage(subvol string) (int64, error)
 
 func btrfsSubVolumeDelete(subvol string) error {
 	// Attempt (but don't fail on) to delete any qgroup on the subvolume
-	qgroup, err := btrfsSubVolumeQGroup(subvol)
-	if err == nil {
+	qgroup, status := btrfsSubVolumeQGroup(subvol)
+	if status == 0 {
 		shared.RunCommand(
 			"btrfs",
 			"qgroup",
@@ -1524,7 +1528,7 @@ func btrfsSubVolumeDelete(subvol string) error {
 	shared.RunCommand("btrfs", "property", "set", subvol, "ro", "false")
 
 	// Delete the subvolume itself
-	_, err = shared.RunCommand(
+	_, err := shared.RunCommand(
 		"btrfs",
 		"subvolume",
 		"delete",


More information about the lxc-devel mailing list