[CRIU] [PATCH 8/9] mount: Introduce BTRFS engine

Pavel Emelyanov xemul at parallels.com
Tue Dec 3 10:45:56 PST 2013


On 12/03/2013 07:58 PM, Cyrill Gorcunov wrote:
> 
> It is been found that BTRFS uses per subvolume device
> numbering scheme  which causes some of our tests to fail
> if they are laying on this filesystem.
> 
> Here we introduce minimal engine which parses subvolumes
> present on mount point.
> 
> Basically the interface is one function btrfs_try_demangle()
> which should be called when one need to examinate if
> particular device has been mangled by btrfs.
> 
> The function is implemented in lazy fashion -- internally
> we scans the mount point remembering which subvolumes
> are present there. If the function is called for second
> time we don't scan mountpoint again but use already obtained
> results.
> 
> In the code we assume that cpu we're running on
> is little endian, thus if one day we run on big
> ending machine the code must be updated accordingly.
> 
> Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
> ---
>  Makefile.crtools      |   1 +
>  include/mount-btrfs.h |  78 +++++++++
>  mount-btrfs.c         | 465 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 544 insertions(+)
>  create mode 100644 include/mount-btrfs.h
>  create mode 100644 mount-btrfs.c
> 

The parse_entry() doesn't honor overmounts. Add this FIXME.


> +int btrfs_try_demangle(dev_t *dev, dev_t vfs_dev)
> +{
> +	struct btrfs_subvol_node *node;
> +	struct mount_info *m;
> +
> +	m = lookup_mnt_sdev(vfs_dev);
> +	if (!m || strcmp(m->kfstype, "btrfs"))
> +		return 0;
> +
> +	if (!m->private) {
> +		m->private = btrfs_parse_entry(m);
> +		if (!m->private)
> +			return -1;
> +	}
> +
> +	node = btrfs_node_lookup_dev(m->private, *dev);
> +	if (node)
> +		*dev = (dev_t)node->subvol_root->m->s_dev;

With that logic we don't need to do *dev = <something else>; as
we expect it to be vfs_dev. This routine should look like this instead

bool is_btrfs_volume(dev_t vol_id, dev_t dev_id)
{
	m = lookup_mnt_sdev(dev_id);
	if (!m->private)
		btrfs_parse_entry(m);
	return btrfs_node_lookup_dev(m->private, vol_id) != NULL;
}

and callers should be fixed respectively.

> +	return 0;
> +}


More information about the CRIU mailing list