Skip to content

Commit

Permalink
lxd/storage/drivers/driver/btrfs/volumes: Enable nodatacow on block r…
Browse files Browse the repository at this point in the history
…aw disk files

Enable nodatacow so that random writes don't cause fragmentation and old extents to be kept.
BTRFS extents are immutable so when blocks are written they end up in new extents and the old
ones remains until all of its data is dereferenced or rewritten. These old extents are counted
in the quota, and so leaving CoW enabled can cause the BTRFS subvolume quota to be reached even
if the block volume file isn't full.

Fixes canonical#9124

Signed-off-by: Thomas Parrott <thomas.parrott@canonical.com>
  • Loading branch information
tomponline committed Dec 3, 2021
1 parent 68cf3d0 commit 2d05655
Showing 1 changed file with 17 additions and 0 deletions.
17 changes: 17 additions & 0 deletions lxd/storage/drivers/driver_btrfs_volumes.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,23 @@ func (d *btrfs) CreateVolume(vol Volume, filler *VolumeFiller, op *operations.Op
if err != nil {
return err
}

// Create empty file so we can set the compression property on it.
f, err := os.OpenFile(rootBlockPath, os.O_RDWR|os.O_CREATE, 0600)
if err != nil {
return errors.Wrapf(err, "Failed to open %s", rootBlockPath)
}
f.Close()

// Enable nodatacow so that random writes don't cause fragmentation and old extents to be kept.
// BTRFS extents are immutable so when blocks are written they end up in new extents and the old
// ones remains until all of its data is dereferenced or rewritten. These old extents are counted
// in the quota, and so leaving CoW enabled can cause the BTRFS subvolume quota to be reached even
// if the block volume file isn't full.
_, err = shared.RunCommand("chattr", "+C", rootBlockPath)
if err != nil {
return fmt.Errorf("Failed setting nodatacow on %q: %w", rootBlockPath, err)
}
}

err = d.runFiller(vol, rootBlockPath, filler)
Expand Down

0 comments on commit 2d05655

Please sign in to comment.