Skip to main content

Variable-Size Directories

QA teams sometimes send requests like this:

For testing purposes, I need the /opt/test/xxx directory limited to 10 Megabytes. This directory is used by the abc123 application, which runs as user tester.

Can a directory’s size be limited in Linux? Yes. You need to:

  1. Use the directory as a mount point for a size-limited storage device.
  2. Set mount options so the specified non-root user has full access.
  3. Disable SELinux (easy) or allow that particular user to access data on mount points (complicated).

Choosing the storage device

There are several options:

  • A loop device: a regular file used as a file system.
  • A logical volume (LVM): assuming your disk setup is already LVM-based and has enough free space for the new volume.
  • A newly attached storage device: for example, in a cloud environment like Amazon Web Services.

Each has pros and cons. The loop device is by far the simplest to implement, but its I/O performance is lower than the other options.

Example: loop device

# Create a directory to hold the image file
mkdir /var/spool/loop-files

# Create a 10 MB zero-filled image file
dd if=/dev/zero of=/var/spool/loop-files/xxx.img bs=1024 count=10240

# Find the first unused loop device
losetup -f
# /dev/loop2

# Associate the image file with the loop device
losetup /dev/loop2 /var/spool/loop-files/xxx.img

# Create the file system on the device
mkfs.ext4 /dev/loop2

# Update fstab to allow non-privileged user mounting
echo "/dev/loop2  /opt/test/xxx  ext4  defaults,noauto,user  0 0" >> /etc/fstab

# Mount as the non-privileged user
su - tester -c "mount /opt/test/xxx"

# Check the mounted devices
df

Note: The file system size cannot be set to an exact value because of block, superblock, journal, and other metadata overhead. The usable space after creating the file system also varies, so a “10 Megabytes” request can only be met to a close possible value, through some trial and error with the image size.

Follow-up: more than 8 loop devices

A default installation supports only 8 loop devices. To increase this:

# Tell the kernel module to support more devices
modprobe loop max_loop=64

# Create the devices, e.g.:
mknod -m 660 /dev/loop36 b 7 36

This should solve the problem. Thanks for reading!