kdave / btrfs-progs

Development of userspace BTRFS tools
GNU General Public License v2.0
527 stars 239 forks source link

btrfs-progs: hunt down the stray fd close causing race with udev scan #739

Closed adam900710 closed 4 months ago

adam900710 commented 4 months ago

Although my previous flock() based solution is preventing udev scan to get pre-mature super blocks, it in fact masks the root problem:

There is a stray close() on writeable fd.

Commit b2a1be83b85f ("btrfs-progs: mkfs: keep file descriptors open during whole time") tries to solve the problem by extending the lifespan of writeable fds, so that when the fds are closed, the fs is ensured to be properly populated.

The problem is, that patch is not covering all cases, there is a stray fd close just under our noses: open_ctree_fs_info().

The function would open the initial device, then use that initial fd to open the btrfs, then we immediately close the initial fd, as later IO would all go with the device fd.

That close() call is causing problem, especially for mkfs, as at that stage the fs is still using a temporary super block, not using the valid btrfs super magic number.

Thus udev scan would race with mkfs, and if udev wins the race, it would get the temporary super block, making libblk not to detect the new btrfs.

This patchset would address the problem by:

This patchset would work even without the usage of flock() to block udev scan, and since without flock() calls, the procedure is much simpler.

In theory, with this patchset, we can remove the flock(), as the flock() solution still has its own problem, as it can do infinite long wait.

kdave commented 4 months ago

Merged to devel, thanks.