• Anand Jain's avatar
    btrfs: do not skip re-registration for the mounted device · d565fffa
    Anand Jain authored
    There are reports that since version 6.7 update-grub fails to find the
    device of the root on systems without initrd and on a single device.
    
    This looks like the device name changed in the output of
    /proc/self/mountinfo:
    
    6.5-rc5 working
    
      18 1 0:16 / / rw,noatime - btrfs /dev/sda8 ...
    
    6.7 not working:
    
      17 1 0:15 / / rw,noatime - btrfs /dev/root ...
    
    and "update-grub" shows this error:
    
      /usr/sbin/grub-probe: error: cannot find a device for / (is /dev mounted?)
    
    This looks like it's related to the device name, but grub-probe
    recognizes the "/dev/root" path and tries to find the underlying device.
    However there's a special case for some filesystems, for btrfs in
    particular.
    
    The generic root device detection heuristic is not done and it all
    relies on reading the device infos by a btrfs specific ioctl. This ioctl
    returns the device name as it was saved at the time of device scan (in
    this case it's /dev/root).
    
    The change in 6.7 for temp_fsid to allow several single device
    filesystem to exist with the same fsid (and transparently generate a new
    UUID at mount time) was to skip caching/registering such devices.
    
    This also skipped mounted device. One step of scanning is to check if
    the device name hasn't changed, and if yes then update the cached value.
    
    This broke the grub-probe as it always read the device /dev/root and
    couldn't find it in the system. A temporary workaround is to create a
    symlink but this does not survive reboot.
    
    The right fix is to allow updating the device path of a mounted
    filesystem even if this is a single device one.
    
    In the fix, check if the device's major:minor number matches with the
    cached device. If they do, then we can allow the scan to happen so that
    device_list_add() can take care of updating the device path. The file
    descriptor remains unchanged.
    
    This does not affect the temp_fsid feature, the UUID of the mounted
    filesystem remains the same and the matching is based on device major:minor
    which is unique per mounted filesystem.
    
    This covers the path when the device (that exists for all mounted
    devices) name changes, updating /dev/root to /dev/sdx. Any other single
    device with filesystem and is not mounted is still skipped.
    
    Note that if a system is booted and initial mount is done on the
    /dev/root device, this will be the cached name of the device. Only after
    the command "btrfs device scan" it will change as it triggers the
    rename.
    
    The fix was verified by users whose systems were affected.
    
    Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=218353
    Link: https://lore.kernel.org/lkml/CAKLYgeJ1tUuqLcsquwuFqjDXPSJpEiokrWK2gisPKDZLs8Y2TQ@mail.gmail.com/
    Fixes: bc27d6f0 ("btrfs: scan but don't register device on single device filesystem")
    CC: stable@vger.kernel.org # 6.7+
    Tested-by: default avatarAlex Romosan <aromosan@gmail.com>
    Tested-by: CHECK_1234543212345@protonmail.com
    Signed-off-by: default avatarAnand Jain <anand.jain@oracle.com>
    Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
    Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
    d565fffa
volumes.c 225 KB