Mount Error – System Call Failed: File Exists

btrfslvmmount

When I try to mount an lvm snapshot device, I get an error:

$ sudo mount -o loop /dev/mapper/matrix-snap--of--core /home/me/mountpoint
mount: /home/me/mountpoint: mount(2) system call failed: File exists.
  • What is the “File exists.” error trying to tell me?
  • What can I do to mount the lvm snapshot device?

The mount command has “always worked before”, though last time I checked was in October 2018. A similar error has been encountered in this three-year-old question. However, the error message is slightly different and it’s 2019 now …


This is my output for lsblk.

NAME                          MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINT
sda                             8:0    0 465.8G  0 disk  
└─sda1                          8:1    0 465.8G  0 part  
  └─core                      254:0    0 465.8G  0 crypt 
    ├─matrix-swapvolume       254:1    0     4G  0 lvm   [SWAP]
    └─matrix-core-real        254:3    0 461.8G  0 lvm   
      ├─matrix-core           254:2    0 461.8G  0 lvm   /
      └─matrix-snap--of--core 254:5    0 461.8G  0 lvm   
sdb                             8:16   1  59.5G  0 disk  
└─matrix-snap--of--core-cow   254:4    0  59.5G  0 lvm   
  └─matrix-snap--of--core     254:5    0 461.8G  0 lvm   

I run Parabola Linux, my system is up-to-date. The logical volume /dev/matrix/core uses btrfs, which I suspect has something to do with the error. This is my output of uname -rvs.

Linux 5.2.5-gnu-1 #1 SMP PREEMPT Sun Aug 4 02:02:20 UTC 2019

Best Answer

(I'm not sure why you're using the -o loop mount option, as the LVM snapshot device should be just as good a disk device as its original is.)

"File exists" is the standard English text for errno value 17, or EEXIST as it is named in #include <errno.h>.

That error result is not documented for the mount(2) system call, so a bit of source code reading is in order.

Linux kernel cross-referencer at elixir.bootlin.com can list all the locations where EEXIST is used in the kernel code. Since you're attempting to loop-mount a btrfs filesystem, the places that might be relevant are:

  • drivers/block/loop.c, related to loop device management
  • fs/btrfs/super.c, which would be used when mounting a btrfs filesystem.

In drivers/block/loop.c, the EEXIST error is generated if you're trying to allocate a particular loop device that is already in use (e.g. mount -o loop=/dev/loop3 ... and /dev/loop3 is already occupied). But that should not be the issue here, unless something is creating a race condition with your mount command.

The fs/btrfs/super.c actually has a btrfs-specific function for translating error codes into error messages. It translates EEXIST into Object already exists.

You are trying to mount what looks like a clone of a btrfs filesystem that is already mounted, so it actually makes sense: historically, this used to confuse btrfs, but it appears some protection has been (sensibly) added at some point.

Since this seems to be a LVM-level snapshot, as opposed to a snapshot made with btrfs's built-in snapshot functionality, you must treat the snapshot like a cloned filesystem if you wish to mount it while its origin filesystem is mounted: only the LVM will "know" that it's a snapshot, not an actual 1:1 clone. So, you'll need to change the metadata UUID of the snapshot/clone filesystem if you need to mount it on the same system as the original.

Warning: I don't have much experience on btrfs, so the below might be wrong or incomplete.

Since your kernel is newer than 5.0, you may have the option of using btrfstune -m /dev/mapper/matrix-snap--of--core to make the change. Otherwise you whould have to use btrfstune -u /dev/mapper/matrix-snap--of--core which would be slower as it needs to update all the filesystem metadata, not just the metadata_uuid field in the filesystem superblock.

Related Question