@@ -13,6 +13,7 @@ import (
13
13
"strings"
14
14
"sync"
15
15
"time"
16
+ "unsafe"
16
17
17
18
"github.com/yookoala/realpath"
18
19
"golang.org/x/sys/unix"
@@ -368,6 +369,12 @@ func mountRootFs(dev, fstype string) error {
368
369
wg := loadModules (fstype )
369
370
wg .Wait ()
370
371
372
+ if fstype == "btrfs" {
373
+ if err := waitForBtrfsDevicesReady (dev ); err != nil {
374
+ return err
375
+ }
376
+ }
377
+
371
378
rootMountingMutex .Lock ()
372
379
defer rootMountingMutex .Unlock ()
373
380
@@ -390,6 +397,27 @@ func mountRootFs(dev, fstype string) error {
390
397
return nil
391
398
}
392
399
400
+ // Wait until all devices of a multiple-device filesystem are scanned and registered within the kernel module
401
+ func waitForBtrfsDevicesReady (dev string ) error {
402
+ controlFile , err := os .OpenFile ("/dev/btrfs-control" , os .O_RDWR , 0 )
403
+ if err != nil {
404
+ return err
405
+ }
406
+ defer controlFile .Close ()
407
+
408
+ /* this should be 4k */
409
+ var btrfsIoctlVolArgs struct {
410
+ fs int64
411
+ name [4088 ]uint8
412
+ }
413
+
414
+ copy (btrfsIoctlVolArgs .name [:], dev )
415
+
416
+ var BTRFS_IOCTL_MAGIC uintptr = 0x94
417
+ BTRFS_IOC_DEVICES_READY := ior (BTRFS_IOCTL_MAGIC , 39 , unsafe .Sizeof (btrfsIoctlVolArgs ))
418
+ return ioctl (controlFile .Fd (), BTRFS_IOC_DEVICES_READY , uintptr (unsafe .Pointer (& btrfsIoctlVolArgs )))
419
+ }
420
+
393
421
func mountFlags () (uintptr , string ) {
394
422
rootMountFlags , options := sunderMountFlags (rootFlags , rootAutodiscoveryMountFlags )
395
423
if rootRo {
0 commit comments