Fixing "device is busy" on umount

Fixing "device is busy" on umount

What does "device is busy" actually mean?

Conclusion: Something still uses the filesystem you are trying to unmount - a process, a stacked mount, or swap. The kernel returns EBUSY and refuses umount. The first step is to find what is holding it, not to force it.

A typical failure looks like this:

umount: /mnt/data: target is busy.

On older distributions or some tools, the same condition appears as device is busy or device or resource busy (the EBUSY errno). The wording differs, but the cause is identical: something still references the target.

Holders fall into a few groups. Triage them in this order:

  • A. A process has a file open (most common) - an open file under the mount, a running binary, a log being written
  • B. A current directory inside the mount - a shell or daemon whose cwd is under /mnt/data
  • C. A nested mount - a bind mount or overlay stacked on top of it
  • D. Used as swap / loop - the device backs swap or a loop device

device is busy and Read-only file system are different problems. The former means "in use, cannot detach"; the latter means "writes are blocked." Don't confuse the messages. For read-only, see Fixing "Read-only file system".

How do I find what is holding the mount?

Conclusion: Start with fuser -vm <mountpoint> to list every process using that filesystem. The ACCESS column distinguishes an open file (f), current directory (c), running binary (e), and mmap (m). Use lsof for per-file detail.

Sweep by mount with fuser

-m treats the argument as a mountpoint (or block device) and returns every process using that filesystem. -v adds detail.

fuser -vm /mnt/data
                     USER        PID ACCESS COMMAND
/mnt/data:           root     kernel mount /mnt/data
                     alice       2314 ..c.. bash
                     alice       2890 F.... tail

Read the ACCESS column - it is the direct answer to "why is it busy?"

  • c … the process's current directory is under the mount (pattern B)
  • e … a binary under the mount is executing
  • f … a file is open (uppercase F means open for writing)
  • r … used as a root directory
  • m … a file is mmap'd (shared libraries, etc.)

In the example above, bash (cwd inside) and tail (file open) are the holders.

Drill into individual files with lsof

To know exactly which file is held, use lsof. Use +D to recurse under a mountpoint, or +f -- to query by device.

# Files open under the mountpoint
lsof +D /mnt/data

# By block device (useful when the mountpoint path itself is broken)
lsof +f -- /dev/sdb1

lsof +D stats the whole tree and is slow on large directories. In practice, run fuser -vm first to find the cause, then use lsof for detail.

How do I stop the holders and unmount?

Conclusion: Terminate the holders gracefully first (cd out / stop the service / SIGTERM), then umount. If they persist, fuser -k force-kills them - but SIGKILL risks data loss, so keep it as the last resort.

1. The safe order: leave or stop cleanly

  • If it is just your own shell's cwd, step out:
cd /
  • If a service holds it, stop the service (more reliable and safer than kill):
sudo systemctl stop myapp.service
  • For individual processes, find the PID and start with a gentle signal:
kill 2890        # SIGTERM (lets it clean up)

2. Last resort: fuser -k to kill in bulk

Processes that won't exit cleanly can be killed together with fuser -k. But -k sends SIGKILL by default, which can corrupt data mid-write.

# Confirm first (-i prompts per process)
sudo fuser -kim /mnt/data
/mnt/data:            2890c  2314c
Kill process 2890 ? (y/N) y
  • -k … send a signal to the holders (default SIGKILL)
  • -i … confirm each one (strongly recommended)
  • -m … by mount

Once the holders are cleared, unmount again:

sudo umount /mnt/data

Should I use lazy or force umount?

Conclusion: To detach immediately from the tree, use umount -l (lazy). For an unresponsive NFS mount, use umount -f (force). Both are workarounds that don't resolve the holder, so don't rely on them routinely.

Lazy umount (-l)

Detaches the filesystem from the tree right now and cleans up once references disappear. An emergency exit when you can't (or won't) kill the holders.

sudo umount -l /mnt/data

Caveats:

  • The mountpoint disappears, but open FDs stay alive (processes keep holding the old files). Full release happens only after they exit.
  • Re-mounting the same device immediately can conflict with lingering references.
  • It does not guarantee that unwritten data is flushed. On critical filesystems, fix the cause first.

Force umount (-f)

Mainly for an unresponsive NFS mount - it forcibly detaches a hung mount whose server is down.

sudo umount -f /mnt/nfs

On local ext4/xfs, -f rarely helps (the busy cause is a local process). For NFS hangs, also read Fixing "Stale file handle" on NFS.

What if it's busy but no process shows up?

Conclusion: If fuser/lsof show nothing yet it's still busy, the cause is not an open file. Check four things in order: nested mounts, swap, loop devices, and NFS exports.

1. Check for nested mounts (bind / overlay)

If another mount is stacked on top, the parent stays busy. Inspect the tree with findmnt -R and unmount children first.

findmnt -R /mnt/data
TARGET            SOURCE    FSTYPE OPTIONS
/mnt/data         /dev/sdb1 ext4   rw,relatime
└─/mnt/data/cache tmpfs     tmpfs  rw

Here, unmount the child /mnt/data/cache first. Common with Docker overlays and mount --bind.

2. Is it used as swap?

If the partition backs swap, you obviously can't unmount it. Check with swapon --show and run swapoff.

swapon --show
sudo swapoff /dev/sdb2

3. Is a loop device holding it?

If you loop-mounted an image file, a reference via the loop device remains. Check with losetup -a and detach.

losetup -a
sudo losetup -d /dev/loop0

4. Is it exported over NFS?

If the filesystem is exported by an NFS server, it stays busy. Release exports with exportfs.

sudo exportfs -ua          # temporarily unexport everything

Fastest path: ① fuser -vm /mnt/data to see who holds it → ② terminate gracefully (cd / systemctl stop / kill) → ③ umount again → if it persists ④ check non-process causes with findmnt -R, swapon --show, losetup -a → ⑤ only in emergencies, umount -l. Never skip identifying the cause - that's the one rule that prevents accidents.

Summary / Next Reading