mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Merge pull request #29835 from yongtang/29810-btrfs-rescan
Run btrfs rescan only if userDiskQuota is enabled
This commit is contained in:
commit
93e322f5be
1 changed files with 82 additions and 38 deletions
|
@ -35,11 +35,6 @@ func init() {
|
|||
graphdriver.Register("btrfs", Init)
|
||||
}
|
||||
|
||||
var (
|
||||
quotaEnabled = false
|
||||
userDiskQuota = false
|
||||
)
|
||||
|
||||
type btrfsOptions struct {
|
||||
minSpace uint64
|
||||
size uint64
|
||||
|
@ -70,18 +65,11 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
|
|||
return nil, err
|
||||
}
|
||||
|
||||
opt, err := parseOptions(options)
|
||||
opt, userDiskQuota, err := parseOptions(options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if userDiskQuota {
|
||||
if err := subvolEnableQuota(home); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
quotaEnabled = true
|
||||
}
|
||||
|
||||
driver := &Driver{
|
||||
home: home,
|
||||
uidMaps: uidMaps,
|
||||
|
@ -89,39 +77,47 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
|
|||
options: opt,
|
||||
}
|
||||
|
||||
if userDiskQuota {
|
||||
if err := driver.subvolEnableQuota(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return graphdriver.NewNaiveDiffDriver(driver, uidMaps, gidMaps), nil
|
||||
}
|
||||
|
||||
func parseOptions(opt []string) (btrfsOptions, error) {
|
||||
func parseOptions(opt []string) (btrfsOptions, bool, error) {
|
||||
var options btrfsOptions
|
||||
userDiskQuota := false
|
||||
for _, option := range opt {
|
||||
key, val, err := parsers.ParseKeyValueOpt(option)
|
||||
if err != nil {
|
||||
return options, err
|
||||
return options, userDiskQuota, err
|
||||
}
|
||||
key = strings.ToLower(key)
|
||||
switch key {
|
||||
case "btrfs.min_space":
|
||||
minSpace, err := units.RAMInBytes(val)
|
||||
if err != nil {
|
||||
return options, err
|
||||
return options, userDiskQuota, err
|
||||
}
|
||||
userDiskQuota = true
|
||||
options.minSpace = uint64(minSpace)
|
||||
default:
|
||||
return options, fmt.Errorf("Unknown option %s", key)
|
||||
return options, userDiskQuota, fmt.Errorf("Unknown option %s", key)
|
||||
}
|
||||
}
|
||||
return options, nil
|
||||
return options, userDiskQuota, nil
|
||||
}
|
||||
|
||||
// Driver contains information about the filesystem mounted.
|
||||
type Driver struct {
|
||||
//root of the file system
|
||||
home string
|
||||
uidMaps []idtools.IDMap
|
||||
gidMaps []idtools.IDMap
|
||||
options btrfsOptions
|
||||
home string
|
||||
uidMaps []idtools.IDMap
|
||||
gidMaps []idtools.IDMap
|
||||
options btrfsOptions
|
||||
quotaEnabled bool
|
||||
}
|
||||
|
||||
// String prints the name of the driver (btrfs).
|
||||
|
@ -150,10 +146,8 @@ func (d *Driver) GetMetadata(id string) (map[string]string, error) {
|
|||
|
||||
// Cleanup unmounts the home directory.
|
||||
func (d *Driver) Cleanup() error {
|
||||
if quotaEnabled {
|
||||
if err := subvolDisableQuota(d.home); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := d.subvolDisableQuota(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return mount.Unmount(d.home)
|
||||
|
@ -294,8 +288,17 @@ func subvolDelete(dirpath, name string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func subvolEnableQuota(path string) error {
|
||||
dir, err := openDir(path)
|
||||
func (d *Driver) subvolEnableQuota() error {
|
||||
if d.quotaEnabled {
|
||||
return nil
|
||||
}
|
||||
// In case quotaEnabled is not set, check qgroup and update quotaEnabled as needed
|
||||
if _, err := subvolLookupQgroup(d.home); err == nil {
|
||||
d.quotaEnabled = true
|
||||
return nil
|
||||
}
|
||||
|
||||
dir, err := openDir(d.home)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -309,11 +312,22 @@ func subvolEnableQuota(path string) error {
|
|||
return fmt.Errorf("Failed to enable btrfs quota for %s: %v", dir, errno.Error())
|
||||
}
|
||||
|
||||
d.quotaEnabled = true
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func subvolDisableQuota(path string) error {
|
||||
dir, err := openDir(path)
|
||||
func (d *Driver) subvolDisableQuota() error {
|
||||
if !d.quotaEnabled {
|
||||
// In case quotaEnabled is not set, check qgroup and update quotaEnabled as needed
|
||||
if _, err := subvolLookupQgroup(d.home); err != nil {
|
||||
// quota is still not enabled
|
||||
return nil
|
||||
}
|
||||
d.quotaEnabled = true
|
||||
}
|
||||
|
||||
dir, err := openDir(d.home)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -327,11 +341,22 @@ func subvolDisableQuota(path string) error {
|
|||
return fmt.Errorf("Failed to disable btrfs quota for %s: %v", dir, errno.Error())
|
||||
}
|
||||
|
||||
d.quotaEnabled = false
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func subvolRescanQuota(path string) error {
|
||||
dir, err := openDir(path)
|
||||
func (d *Driver) subvolRescanQuota() error {
|
||||
if !d.quotaEnabled {
|
||||
// In case quotaEnabled is not set, check qgroup and update quotaEnabled as needed
|
||||
if _, err := subvolLookupQgroup(d.home); err != nil {
|
||||
// quota is still not enabled
|
||||
return nil
|
||||
}
|
||||
d.quotaEnabled = true
|
||||
}
|
||||
|
||||
dir, err := openDir(d.home)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -366,6 +391,28 @@ func subvolLimitQgroup(path string, size uint64) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func subvolLookupQgroup(path string) (uint64, error) {
|
||||
dir, err := openDir(path)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer closeDir(dir)
|
||||
|
||||
var args C.struct_btrfs_ioctl_ino_lookup_args
|
||||
args.objectid = C.BTRFS_FIRST_FREE_OBJECTID
|
||||
|
||||
_, _, errno := syscall.Syscall(syscall.SYS_IOCTL, getDirFd(dir), C.BTRFS_IOC_INO_LOOKUP,
|
||||
uintptr(unsafe.Pointer(&args)))
|
||||
if errno != 0 {
|
||||
return 0, fmt.Errorf("Failed to lookup qgroup for %s: %v", dir, errno.Error())
|
||||
}
|
||||
if args.treeid == 0 {
|
||||
return 0, fmt.Errorf("Invalid qgroup id for %s: 0", dir)
|
||||
}
|
||||
|
||||
return uint64(args.treeid), nil
|
||||
}
|
||||
|
||||
func (d *Driver) subvolumesDir() string {
|
||||
return path.Join(d.home, "subvolumes")
|
||||
}
|
||||
|
@ -468,11 +515,8 @@ func (d *Driver) setStorageSize(dir string, driver *Driver) error {
|
|||
return fmt.Errorf("btrfs: storage size cannot be less than %s", units.HumanSize(float64(d.options.minSpace)))
|
||||
}
|
||||
|
||||
if !quotaEnabled {
|
||||
if err := subvolEnableQuota(d.home); err != nil {
|
||||
return err
|
||||
}
|
||||
quotaEnabled = true
|
||||
if err := d.subvolEnableQuota(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := subvolLimitQgroup(dir, driver.options.size); err != nil {
|
||||
|
@ -494,7 +538,7 @@ func (d *Driver) Remove(id string) error {
|
|||
if err := os.RemoveAll(dir); err != nil && !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
if err := subvolRescanQuota(d.home); err != nil {
|
||||
if err := d.subvolRescanQuota(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
|
Loading…
Reference in a new issue