Skip to main content

Command Palette

Search for a command to run...

The Complete Linux EXT4 Disk Quota Guide

Published
β€’34 min read
The Complete Linux EXT4 Disk Quota Guide

From Absolute Beginner to Production Expert (RHEL 8/9/10)

Last Updated: November 2025
Target Systems: RHEL 8, 9, 10 with EXT4 filesystem
Knowledge Level: Beginner to Advanced


Table of Contents

  1. What is Disk Quota? (The Simple Story)

  2. Understanding Quota Concepts

  3. How Quotas Work Inside Linux

  4. Setting Up Quotas on EXT4 (Step-by-Step)

  5. Managing Quotas (Daily Operations)

  6. Advanced Scenarios & Troubleshooting

  7. Production Best Practices


Part 1: What is Disk Quota? (The Simple Story)

The Library Card Analogy πŸ“š

Imagine you run a public library with 1,000 books. If you let people borrow unlimited books:

  • One person might check out 200 books and keep them for months

  • Others can't find books they need

  • Library becomes unusable

Your library rules:

  • Each person can borrow 5 books normally (comfortable limit)

  • They can temporarily borrow up to 8 books (absolute maximum)

  • If they have 6-8 books, they get 2 weeks to return extras

  • After 2 weeks with too many books, they can't borrow more until they return some

Linux disk quota works exactly the same:

  • 5 books = Soft limit (recommended usage)

  • 8 books = Hard limit (absolute maximum)

  • 2 weeks = Grace period (time to fix the situation)

  • Can't borrow more = Can't write new files

Real-World Example

Without Quota:

Server has 1 TB total space

User John: Downloads 700 GB of videos
User Mary: Has 50 GB of work files
User Tom: Has 20 GB of project data

Result: Server only has 230 GB left
        John's downloads prevent others from working ❌

With Quota:

Server has 1 TB total space

User John: Limited to 200 GB (soft: 180 GB) βœ…
User Mary: Limited to 200 GB (soft: 180 GB) βœ…
User Tom: Limited to 200 GB (soft: 180 GB) βœ…

Result: Fair distribution
        Everyone can work
        400 GB free for new users βœ…

Why Do We Need Quotas?

  1. Fairness - Everyone gets their fair share of storage

  2. Prevention - One user can't accidentally fill the entire disk

  3. Planning - You know exactly how many users you can support

  4. Accountability - Users think twice before saving everything

  5. System Stability - Server never runs completely out of space


Part 2: Understanding Quota Concepts

The Two Types of Limits

Think of your phone:

  • Storage space - How much data you can store (in GB)

  • Number of apps - How many apps you can install (count)

Linux tracks both:

1. Block Quota = Storage Space Limit

  • Controls how much disk space you can use

  • Measured in 1 KB blocks (not filesystem blocks!)

  • Example: "You can store up to 10 GB of files"

  • Important: Linux quota counts in 1024-byte units

Block calculation:

Want 5 GB limit?
5 GB = 5 Γ— 1024 Γ— 1024 KB = 5,242,880 blocks

Want 500 MB limit?
500 MB = 500 Γ— 1024 KB = 512,000 blocks

2. Inode Quota = File Count Limit

  • Controls how many files and folders you can create

  • Measured in number of items (each file/folder = 1 inode)

  • Example: "You can create up to 10,000 files"

  • Important: Every directory counts as 1 inode (this includes the user's home directory)

Why Track Both?

Real scenario:

User Alice: Saves 1 large video file
  - 5 GB size β†’ Uses 5,242,880 blocks βœ…
  - 1 file + 1 directory β†’ Uses 2 inodes βœ…
  - Hits BLOCK quota first

User Bob: Saves 50,000 tiny text files
  - 50 MB total size β†’ Uses 51,200 blocks βœ…
  - 50,000 files + 1 directory β†’ Uses 50,001 inodes βœ…
  - Hits INODE quota first

Different users need different controls!


Soft Limit vs Hard Limit (The Library Card Model)

This is the heart of the quota system. Let's use our library analogy:

Soft Limit = Comfortable Borrowing Limit

  • "This is how many books you should normally have"

  • Can be temporarily exceeded if you need a few extra days

  • Like having 6 books when limit is 5

  • You get a grace period to return the extras

Hard Limit = Absolute Maximum

  • "You can NEVER exceed this, no exceptions"

  • Enforced immediately - no grace period

  • Like trying to borrow a 9th book when maximum is 8

  • Librarian says NO right away

Grace Period = The Warning Timer

  • Time allowed to stay above soft limit

  • "You have 7 days to return those extra books"

  • After grace expires, soft limit becomes as strict as hard limit

  • Grace period is per filesystem, not per user


The Complete Picture (Example)

Block Soft Limit:  180 GB   (comfortable usage)
Block Hard Limit:  200 GB   (absolute ceiling)
Grace Period:      7 days   (time to clean up)

What happens in practice:

User's StorageSystem ResponseCan Write Files?
100 GBβœ… Normal - everything fineYES
185 GB⚠️ Over soft limit - grace timer starts (7 days)YES (temporarily)
185 GB + 8 days later❌ Grace expired - soft acts like hardNO*
201 GB (tries to go over)πŸ›‘ Blocked immediately at hard limitNO
Cleans up to 170 GBβœ… Grace resets - back to normalYES

Note: *Grace enforcement is "lazy" - you'll be blocked on your next write attempt after grace expires, not exactly at the expiration moment.


Visual Timeline: Grace Period in Action

Day 1: User has 150 GB                     [βœ… NORMAL]
       Writing files freely

Day 2: User uploads large dataset β†’ 185 GB [⚠️ SOFT LIMIT EXCEEDED]
       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
       β”‚ Grace period starts: 7 days         β”‚
       β”‚ Warning shown: "Please clean up"    β”‚
       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       Still can write files (temporary allowance)

Day 4: Still at 185 GB                     [⚠️ 5 days remaining]
       Can still write, but should clean up

Day 9: Grace period expired!               [❌ ENFORCEMENT BEGINS]
       Next write attempt:
       $ touch /data/newfile.txt
       touch: cannot touch 'newfile.txt': Disk quota exceeded

       User deletes 20 GB β†’ now at 165 GB  [βœ… GRACE RESETS]
       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
       β”‚ Back under soft limit               β”‚
       β”‚ Grace timer reset                   β”‚
       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       Can write freely again

Key takeaway: Grace period is like a "soft warning phase" that becomes strict enforcement after time expires.


Part 3: How Quotas Work Inside Linux

The Kernel's Job (Simple Explanation)

Every time you create or write to a file, the Linux kernel performs quota checks:

1. User types: echo "hello" > myfile.txt

2. Kernel checks (in this order):

   A. INODE CHECK (file count):
      β”œβ”€ Current inodes used: 500
      β”œβ”€ Inode hard limit: 1000
      β”œβ”€ Is 500 < 1000? βœ… YES β†’ Continue
      └─ If NO β†’ STOP, show error

   B. INODE SOFT LIMIT CHECK:
      β”œβ”€ Current: 500
      β”œβ”€ Soft limit: 800
      β”œβ”€ Is 500 < 800? βœ… YES β†’ No grace timer needed
      └─ If NO β†’ Start/check grace period

   C. BLOCK CHECK (space):
      β”œβ”€ Current blocks: 5,000,000 (about 4.7 GB)
      β”œβ”€ New file needs: 1,024 blocks (1 MB)
      β”œβ”€ Total would be: 5,001,024
      β”œβ”€ Block hard limit: 10,485,760 (10 GB)
      β”œβ”€ Is 5,001,024 < 10,485,760? βœ… YES β†’ Continue
      └─ If NO β†’ STOP, show error

   D. BLOCK SOFT LIMIT CHECK:
      β”œβ”€ Current: 5,001,024
      β”œβ”€ Soft limit: 9,437,184 (9 GB)
      β”œβ”€ Is 5,001,024 < 9,437,184? βœ… YES β†’ No grace needed
      └─ If NO β†’ Start/check grace period

3. All checks passed βœ…
   β†’ File created successfully
   β†’ Quota counters updated

If ANY check fails β†’ Error message: "Disk quota exceeded"


Where Quota Data Lives

Modern EXT4 (RHEL 8/9/10) - Built-in Quota Feature:

When you format with: mkfs.ext4 /dev/sdb1

The filesystem is created with quota support BUILT-IN:
β”œβ”€ Special hidden inodes created automatically
β”‚  β”œβ”€ Inode #3: User quota data
β”‚  β”œβ”€ Inode #4: Group quota data
β”‚  └─ These are invisible to normal users
β”œβ”€ Protected by filesystem journal
β”œβ”€ Can't be accidentally deleted
└─ Updated atomically (safely)

To verify quota feature is enabled:

tune2fs -l /dev/sdb1 | grep quota

Output should show:
Filesystem features: ... quota ...
User quota inode:         3
Group quota inode:        4

Legacy Method (RHEL 6/7 old-style):

External files in filesystem root:
β”œβ”€ aquota.user    (user quota data)
└─ aquota.group   (group quota data)

Problems:
β”œβ”€ Can get corrupted
β”œβ”€ Need manual checking with quotacheck
└─ Not recommended anymore

We'll ONLY use the modern built-in method in this guide.


Evolution of Quota in RHEL

RHEL VersionDefault MethodNotes
RHEL 6External quota filesNeeded quotacheck command
RHEL 7Both methods availableTransition period
RHEL 8+Built-in ext4 quotaExternal files deprecated
RHEL 9/10Built-in only (recommended)quotacheck not needed

This guide focuses on RHEL 8/9/10 modern approach.


Key Commands Overview

CommandWhat It DoesWhen to Use
quotaonEnable quota enforcementAfter mounting filesystem
quotaoffDisable quota enforcementFor maintenance
setquotaSet limits via command lineScripting, automation
edquotaEdit limits interactivelyManual configuration
quotaCheck your own quotaUser self-check
repquotaGenerate quota reportAdmin monitoring

Deprecated commands (don't use with built-in quota):

  • quotacheck - Not needed with built-in ext4 quota

Part 4: Setting Up Quotas on EXT4 (Step-by-Step)

Prerequisites Check

Verify your system:

# 1. Check RHEL version (should be 8, 9, or 10)
cat /etc/redhat-release

Expected output:
Red Hat Enterprise Linux release 9.x (Plow)

# 2. Check available disks
lsblk

Look for an unused disk, example:
NAME   SIZE TYPE
sda    20G  disk         ← We'll use this
sdb   100G  disk         ← Our target disk for quota
└─sdb1 50G  part

# 3. Verify you're root
whoami

Should show: root

# 4. Check if quota tools are installed
rpm -qa | grep quota

Should show: quota-4.x.x (if not, install it)

Install quota tools if missing:

dnf install quota -y

Understanding Our Setup

What we're building:

Physical disk: /dev/sdb (the whole disk device)
    ↓
Partition: /dev/sdb1 (a section of the disk)
    ↓
Filesystem: EXT4 with quota feature enabled
    ↓
Mount point: /quotadata (where users access it)
    ↓
Quota enforcement: Active for users and groups

Important distinction:

  • /dev/sdb = The entire physical disk (like the whole hard drive)

  • /dev/sdb1 = First partition on that disk (like a section of the drive)

  • We'll create the partition, then format it, then mount it


Step 1: Create the Partition

⚠️ WARNING: This will erase all data on /dev/sdb. Make sure it's the right disk!

# Start partitioning tool
fdisk /dev/sdb

Inside fdisk (interactive commands):

Welcome to fdisk (util-linux 2.37.4).

Command (m for help): n                    ← Press 'n' for new partition
Partition type
   p   primary (0 primary, 0 extended, 4 free)
   e   extended (container for logical partitions)
Select (default p): p                       ← Press 'p' for primary

Partition number (1-4, default 1): 1       ← Press '1' (first partition)
First sector (2048-209715199, default 2048): [Press Enter]
Last sector, +/-sectors or +/-size{K,M,G,T,P}: +20G    ← Type '+20G' for 20 GB

Created a new partition 1 of type 'Linux' and of size 20 GiB.

Command (m for help): w                    ← Press 'w' to write and exit
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.

Reload partition table:

partprobe /dev/sdb

Verify partition was created:

lsblk /dev/sdb

Expected output:
NAME   MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sdb      8:16   0  50G  0 disk
└─sdb1   8:17   0  20G  0 part              ← Our new partition

βœ… Step 1 complete! You now have /dev/sdb1 ready for formatting.


Step 2: Create EXT4 Filesystem with Quota

Create the filesystem:

# Format partition as EXT4 with a label
mkfs.ext4 -L QUOTADATA /dev/sdb1

Expected output:

mke2fs 1.46.5 (30-Dec-2021)
Creating filesystem with 5242880 4k blocks and 1310720 inodes
Filesystem UUID: a1b2c3d4-e5f6-...
Superblock backups stored on blocks:
        32768, 98304, 163840, 229376, 294912
...

Check if quota feature is enabled (should be by default):

tune2fs -l /dev/sdb1 | grep -i quota

Expected output:

Filesystem features: ... quota ...
User quota inode:         3
Group quota inode:        4

βœ… If you see this, quota feature is already enabled! Modern ext4 enables it by default.

If quota feature is NOT shown (rare), enable it:

# Enable quota feature
tune2fs -O quota /dev/sdb1

# Verify filesystem integrity (recommended after adding features)
e2fsck -f /dev/sdb1

Understand what happened:

  • mkfs.ext4 created a new ext4 filesystem

  • Quota feature is built-in by default in RHEL 8+

  • Special inodes #3 and #4 store quota data

  • No external files needed


Step 3: Create Mount Point

# Create directory where filesystem will be accessible
mkdir -p /quotadata

# Verify it was created
ls -ld /quotadata

Expected output:
drwxr-xr-x. 2 root root 6 Nov  3 10:00 /quotadata

Step 4: Configure Automatic Mounting

We need to edit /etc/fstab so the filesystem mounts automatically at boot.

# Backup fstab first (safety measure)
cp /etc/fstab /etc/fstab.backup

# Edit fstab
nano /etc/fstab

Add this line at the end:

/dev/sdb1  /quotadata  ext4  defaults,usrquota,grpquota  0  2

Understanding each field:

Field 1: /dev/sdb1              ← The partition to mount
Field 2: /quotadata             ← Where to mount it
Field 3: ext4                   ← Filesystem type
Field 4: defaults,usrquota,grpquota  ← Mount options
         β”œβ”€ defaults: Standard options (rw, suid, dev, exec, auto, nouser, async)
         β”œβ”€ usrquota: Enable user quota tracking
         └─ grpquota: Enable group quota tracking
Field 5: 0                      ← Dump (0 = don't backup with dump command)
Field 6: 2                      ← fsck order (2 = check after root filesystem)

Save and exit:

  • In nano: Press Ctrl+O, then Enter, then Ctrl+X

  • In vim: Press Esc, type :wq, press Enter

Verify your fstab syntax (important!):

# Test fstab without rebooting
mount -a

# Check for errors
echo $?
# Should show: 0 (means success)

Step 5: Mount the Filesystem

# Reload systemd to recognize fstab changes
systemctl daemon-reload

# Mount the filesystem
mount /quotadata

# Verify it's mounted with correct options
mount | grep /quotadata

Expected output:

/dev/sdb1 on /quotadata type ext4 (rw,relatime,seclabel,quota,usrquota,grpquota)

βœ… Critical check: You MUST see usrquota and grpquota in the output!

If you DON'T see quota options:

# Remount with correct options
mount -o remount,usrquota,grpquota /quotadata

# Verify again
mount | grep /quotadata

Check disk space:

df -h /quotadata

Expected output:
Filesystem      Size  Used Avail Use% Mounted on
/dev/sdb1        20G   45M   19G   1% /quotadata

Step 6: Enable Quota Enforcement

With modern built-in ext4 quota, this is simple:

# Turn on quota enforcement
quotaon -v /quotadata

Expected output:

/dev/sdb1 [/quotadata]: user quotas turned on
/dev/sdb1 [/quotadata]: group quotas turned on

βœ… That's it! No quotacheck needed with built-in quota.

Verify quota is active:

# Check quota status
quotaon -p /quotadata

Expected output:

user quota on /quotadata (/dev/sdb1) is on
group quota on /quotadata (/dev/sdb1) is on

Generate initial report:

repquota -a

Expected output:

*** Report for user quotas on device /dev/sdb1
Block grace time: 7days; Inode grace time: 7days
                        Block limits                File limits
User            used    soft    hard  grace    used  soft  hard  grace
----------------------------------------------------------------------
root      --      24       0       0              3     0     0

βœ… Quota system is fully operational!


Step 7: Verify SELinux Context (RHEL-specific)

RHEL systems use SELinux for security. Let's ensure proper context:

# Check SELinux context
ls -Zd /quotadata

Expected output:
unconfined_u:object_r:default_t:s0 /quotadata

If there are issues with quota later, restore SELinux context:

# Restore proper context
restorecon -Rv /quotadata

# Verify again
ls -Zd /quotadata

Complete Setup Verification Checklist

Run these commands to verify everything:

# 1. Partition exists
lsblk | grep sdb1
# βœ… Should show: sdb1 partition

# 2. Filesystem has quota feature
tune2fs -l /dev/sdb1 | grep -i quota
# βœ… Should show: quota in features list

# 3. Mounted with quota options
mount | grep /quotadata
# βœ… Should show: usrquota,grpquota

# 4. Quota is turned on
quotaon -p /quotadata
# βœ… Should show: user quota on ... is on

# 5. Can generate quota report
repquota /quotadata
# βœ… Should show: quota report table

# 6. fstab entry exists
grep quotadata /etc/fstab
# βœ… Should show: your fstab line

If all checks pass βœ…, your quota system is ready for use!


Part 5: Managing Quotas (Daily Operations)

Creating Test Users

Let's create users to practice quota management:

# Create first test user
useradd alice
passwd alice
# (set password when prompted)

# Create second test user
useradd bob
passwd bob

# Verify users were created
id alice
id bob

# Give them access to quota filesystem
mkdir -p /quotadata/alice
mkdir -p /quotadata/bob
chown alice:alice /quotadata/alice
chown bob:bob /quotadata/bob

Important Note: When you create the directories, each one counts as 1 inode in the user's quota. This means users start with 1 inode used (the directory itself), not 0.


Syntax:

setquota -u <username> <block-soft> <block-hard> <inode-soft> <inode-hard> <filesystem>

Remember: Block values are in 1 KB units!

Example 1: Set 5 GB limit for Alice

# Calculate blocks:
# 5 GB soft = 5 Γ— 1024 Γ— 1024 = 5,242,880 blocks
# 6 GB hard = 6 Γ— 1024 Γ— 1024 = 6,291,456 blocks

setquota -u alice 5242880 6291456 10000 12000 /quotadata

What this means:

  • Block soft: 5 GB (5,242,880 KB)

  • Block hard: 6 GB (6,291,456 KB)

  • Inode soft: 10,000 files

  • Inode hard: 12,000 files

Quick calculation helper:

Desired LimitBlock ValueFormula
100 MB102,400100 Γ— 1024
500 MB512,000500 Γ— 1024
1 GB1,048,5761024 Γ— 1024
5 GB5,242,8805 Γ— 1024 Γ— 1024
10 GB10,485,76010 Γ— 1024 Γ— 1024
50 GB52,428,80050 Γ— 1024 Γ— 1024
100 GB104,857,600100 Γ— 1024 Γ— 1024

Example 2: Set 500 MB limit for Bob (for testing)

setquota -u bob 512000 614400 5000 6000 /quotadata

Verify the limits were set:

quota -u alice
quota -u bob

Method 2: Setting Limits with edquota (Interactive)

Edit quota interactively:

edquota -u alice

Your default editor opens with this:

Disk quotas for user alice (uid 1001):
  Filesystem                   blocks       soft       hard     inodes     soft     hard
  /dev/sdb1                         4    5242880    6291456          1    10000    12000

Understanding the columns:

ColumnMeaningYour Action
FilesystemThe diskDon't change
blocks (current)Current usage in KB (4 KB = directory)Don't change (auto-updated)
soft (blocks)Soft limit in KBEdit this
hard (blocks)Hard limit in KBEdit this
inodes (current)Current file count (1 = directory)Don't change
soft (inodes)Soft file limitEdit this
hard (inodes)Hard file limitEdit this

Edit the values, then save and exit:

  • In vim: Esc, :wq, Enter

  • In nano: Ctrl+O, Enter, Ctrl+X


Checking User Quotas

As root, check any user:

# Basic quota check
quota -u alice

Output:
Disk quotas for user alice (uid 1001):
     Filesystem  blocks   quota   limit   grace   files   quota   limit   grace
      /dev/sdb1       4 5242880 6291456               1   10000   12000

Note: The user starts with:

  • 4 blocks = ~4 KB (the /quotadata/alice directory itself)

  • 1 inode = The directory counts as 1 file

Human-readable format:

quota -s -u alice

Output:
Disk quotas for user alice (uid 1001):
     Filesystem  blocks   quota   limit   grace   files   quota   limit   grace
      /dev/sdb1      4K   5120M   6144M               1   10000   12000

As the user themselves:

# Switch to user
su - alice

# Check own quota
quota

Output:
Disk quotas for user alice (uid 1001):
     Filesystem  blocks   quota   limit   grace   files   quota   limit   grace
      /dev/sdb1       4 5242880 6291456               1   10000   12000

# Switch back to root
exit

Setting Grace Periods

Grace periods apply to the entire filesystem, not individual users.

Method 1: Interactive editing

edquota -t

You'll see:

Grace period before enforcing soft limits for users:
Time units may be: days, hours, minutes, or seconds
  Filesystem             Block grace period     Inode grace period
  /dev/sdb1                      7days                  7days

Common grace period values:

ValueMeaningWhen to Use
7days1 weekStandard production (recommended)
3days3 daysFaster cleanup required
1hour60 minutesTesting or very strict policies
30minutes30 minutesEmergency scenarios

Edit and save as desired.

Method 2: Command-line (in seconds)

# Set 2 days grace (172800 seconds)
# Syntax: setquota -t <block-grace-seconds> <inode-grace-seconds> <filesystem>
setquota -t 172800 172800 /quotadata

# Set 1 hour grace (for testing)
setquota -t 3600 3600 /quotadata

# Set 7 days grace (standard)
setquota -t 604800 604800 /quotadata

Verify grace period:

repquota -a | head -5

Output:
*** Report for user quotas on device /dev/sdb1
Block grace time: 7days; Inode grace time: 7days
                        Block limits                File limits
User            used    soft    hard  grace    used  soft  hard  grace

Viewing All User Quotas

Simple report:

repquota /quotadata

All filesystems:

repquota -a

Human-readable sizes:

repquota -asu

Output:
*** Report for user quotas on device /dev/sdb1
Block grace time: 7days; Inode grace time: 7days
                        Block limits                File limits
User            used    soft    hard  grace    used  soft  hard  grace
----------------------------------------------------------------------
root      --    24K       0       0              3       0       0
alice     --     4K   5120M   6144M              1   10000   12000
bob       --     4K    500M    600M              1    5000    6000

Understanding the status indicators:

IndicatorMeaning
--Within limits (normal)
+-Over soft limit, grace period active
++Over soft limit, grace period expired
+Over hard limit (shouldn't happen)

Copy alice's limits to both

edquota -p alice -u david eve


**Verify:**

```bash
quota -u david
quota -u eve

Output for each:
Disk quotas for user david (uid 1003):
     Filesystem  blocks   quota   limit   grace   files   quota   limit   grace
      /dev/sdb1       4 5242880 6291456               1   10000   12000

Setting Group Quotas

Create a group:

groupadd developers
usermod -aG developers alice
usermod -aG developers bob

Set group quota:

# 20 GB for entire group
setquota -g developers 20971520 25165824 50000 60000 /quotadata

Check group quota:

quota -g developers

Disabling and Enabling Quotas

Temporarily turn off quota (for maintenance):

quotaoff -v /quotadata

Output:
/dev/sdb1 [/quotadata]: user quotas turned off
/dev/sdb1 [/quotadata]: group quotas turned off

Turn back on:

quotaon -v /quotadata

Output:
/dev/sdb1 [/quotadata]: user quotas turned on
/dev/sdb1 [/quotadata]: group quotas turned on

Check current status:

quotaon -p /quotadata

Output:
user quota on /quotadata (/dev/sdb1) is on
group quota on /quotadata (/dev/sdb1) is on

Part 6: Advanced Scenarios & Troubleshooting

Scenario 1: Testing Block Quota (Disk Space Limit)

Let's see quota enforcement in action!

Setup: Give bob a small limit for testing

# 50 MB soft, 60 MB hard
setquota -u bob 51200 61440 5000 6000 /quotadata

Test as bob:

# Switch to bob
su - bob

# Go to bob's directory
cd /quotadata/bob

# Check current quota
quota

Output:
Disk quotas for user bob (uid 1002):
     Filesystem  blocks   quota   limit   grace   files   quota   limit   grace
      /dev/sdb1       4   51200   61440               1    5000    6000
                      ↑                               ↑
                   4 KB used                     1 inode (directory)

Test 1: Create 40 MB file (within soft limit)

# Create 40 MB file
dd if=/dev/zero of=file40mb bs=1M count=40

Output:
40+0 records in
40+0 records out
41943040 bytes (42 MB) copied, 0.123456 s, 340 MB/s

# Check quota usage
quota

Output:
Disk quotas for user bob (uid 1002):
     Filesystem  blocks   quota   limit   grace   files   quota   limit   grace
      /dev/sdb1   40964   51200   61440               2    5000    6000
                  ↑                                   ↑
                40 MB + 4 KB directory            2 files (dir + file40mb) βœ…

Test 2: Add 15 MB more (exceeds soft, triggers grace)

# Create another 15 MB file
dd if=/dev/zero of=file15mb bs=1M count=15

# Check quota - grace timer starts
quota

Output:
Disk quotas for user bob (uid 1002):
     Filesystem  blocks   quota   limit   grace   files   quota   limit   grace
      /dev/sdb1   56324   51200   61440  7days       3    5000    6000
                  ↑                      ↑           ↑
                55 MB total          Grace started! 3 files total ⚠️

Test 3: Try to exceed hard limit (blocked immediately)

# Try to create 10 MB file (would exceed 60 MB hard limit)
dd if=/dev/zero of=file10mb bs=1M count=10

Output:
dd: error writing 'file10mb': Disk quota exceeded
5+0 records in                    ← Only wrote partial data
4+1 records out
4943872 bytes (4.9 MB) copied, 0.0234 s, 211 MB/s

What happened:

  • Bob tried to write 10 MB

  • Total would be 55 MB + 10 MB = 65 MB

  • Hard limit is 60 MB

  • Kernel allowed writing up to 60 MB, then stopped βœ…

Clean up:

# Check current usage
du -sh /quotadata/bob

# Delete files to go back under soft limit
rm file15mb file10mb

# Verify grace period reset
quota

Output:
Disk quotas for user bob (uid 1002):
     Filesystem  blocks   quota   limit   grace   files   quota   limit   grace
      /dev/sdb1   40964   51200   61440               2    5000    6000
                                          ↑
                                      Grace reset! βœ…

# Switch back to root
exit

Scenario 2: Testing Inode Quota (File Count Limit)

Setup: Give alice a small inode limit

# 5 GB space, but only 10 files allowed (soft), 15 max (hard)
setquota -u alice 5242880 6291456 10 15 /quotadata

Test as alice:

su - alice
cd /quotadata/alice

# Check quota
quota

Output:
     Filesystem  blocks   quota   limit   grace   files   quota   limit   grace
      /dev/sdb1       4 5242880 6291456               1      10      15
                                                       ↑
                                                    1 inode (directory itself)

Test 1: Create 9 files (reaches soft limit with directory)

# Create 9 small files
for i in {1..9}; do
    echo "File $i" > file$i.txt
done

# Check quota
quota

Output:
     Filesystem  blocks   quota   limit   grace   files   quota   limit   grace
      /dev/sdb1       8 5242880 6291456              10      10      15
                                                      ↑
                                                   At soft limit (1 dir + 9 files = 10) βœ…

Test 2: Create 10th file (exceeds soft, starts grace)

# Create one more file
echo "File 10" > file10.txt

# Check quota
quota

Output:
     Filesystem  blocks   quota   limit   grace   files   quota   limit   grace
      /dev/sdb1       8 5242880 6291456              11      10      15  7days
                                                      ↑                    ↑
                                                   Over soft           Grace started! ⚠️

Test 3: Create files until hard limit

# Create more files (11, 12, 13, 14)
for i in {11..14}; do
    echo "File $i" > file$i.txt
done

# Check quota - now at hard limit
quota

Output:
     Filesystem  blocks   quota   limit   grace   files   quota   limit   grace
      /dev/sdb1      12 5242880 6291456              15      10      15  7days
                                                      ↑
                                                   At hard limit (1 dir + 14 files = 15)

# Try to create 15th file (exceeds hard limit)
echo "File 15" > file15.txt

Output:
bash: file15.txt: Disk quota exceeded ❌

Check final state:

quota

Output:
     Filesystem  blocks   quota   limit   grace   files   quota   limit   grace
      /dev/sdb1      12 5242880 6291456              15      10      15  7days
                                                      ↑
                                                   At hard limit (can't create more)

# List files
ls -1 | wc -l
14                    ← 14 files (plus 1 directory = 15 inodes total)

Clean up:

# Delete some files to go back under soft limit
rm file{10..14}.txt

# Check quota
quota

Output:
     Filesystem  blocks   quota   limit   grace   files   quota   limit   grace
      /dev/sdb1       8 5242880 6291456              10      10      15
                                                      ↑
                                                   Grace reset! βœ…

exit

Scenario 3: Grace Period Expiration Test

Setup: Set very short grace period for testing

# Set 2 minute grace period
setquota -t 120 120 /quotadata

# Verify
repquota -a | head -3

Output:
*** Report for user quotas on device /dev/sdb1
Block grace time: 2minutes; Inode grace time: 2minutes

Test sequence:

# As bob (who has 50 MB soft, 60 MB hard)
su - bob
ls
# remove everything from bob dir 
rm*
cd /quotadata/bob

# Create 55 MB file (exceeds soft limit)
dd if=/dev/zero of=bigfile bs=1M count=55

# Check quota - grace starts
quota

Output:
     Filesystem  blocks   quota   limit   grace   files   quota   limit   grace
      /dev/sdb1   56324   51200   61440  2minutes    2    5000    6000
                                          ↑
                                      Timer started at current time

# Wait exactly 2 minutes (use watch to monitor)
watch -n 10 quota
# Watch the grace countdown: 2minutes -> 1minute -> 30seconds -> ...

# After 2 minutes, try to create new file
dd if=/dev/zero of=smallfile bs=1M count=2

Output:
dd: error writing 'smallfile': Disk quota exceeded❌
1+0 records in
0+0 records out

Here is a technical point that file (smallfile) will be created but it’s size will be remain 0 byte because β€œinode” values is are between 5000 to 6000 you can see below

ls -lh
total 55M
-rw-r--r--. 1 bob bob 55M Nov  5 00:04 bigfile
-rw-r--r--. 1 bob bob   0 Nov  5 00:05 smallfile
# here you can see 55M is bigfile size and smallfile size is 0

Important understanding:

Grace expiration does NOT delete files
It only PREVENTS new writes until usage drops below soft limit

Restore and clean up:

# Delete the big file
rm bigfile smallfile

# Check quota - now can write again
quota

Output:
     Filesystem  blocks   quota   limit   grace   files   quota   limit   grace
      /dev/sdb1       4   51200   61440               1    5000    6000
                                          ↑
                                      No grace timer (back to normal) βœ…

# Reset grace to normal
exit
setquota -t 604800 604800 /quotadata  # 7 days

Troubleshooting Common Issues

Issue 1: Quota Not Enforcing

Symptoms: User can exceed limits without getting errors

Diagnosis:

# Step 1: Check if quota is actually turned on
quotaon -p /quotadata

# Should show: user quota on ... is on
# If shows: user quota on ... is off
quotaon /quotadata

# Step 2: Check if filesystem is mounted with quota options
mount | grep /quotadata

# Should show: usrquota,grpquota in options
# If missing:
mount -o remount,usrquota,grpquota /quotadata

# Step 3: Check if user actually has limits set
quota -u username # user name like bob alice etc so command will be "quota -u bob"

# If all zeros:
setquota -u username 5242880 6291456 10000 12000 /quotadata
#Username cluld be any name so use valid username instead of username

Issue 2: "Cannot find filesystem to check"

Error message:

quotacheck: Cannot find filesystem to check or filesystem not mounted with quota option.

Solution:

# With modern ext4 built-in quota, DON'T use quotacheck!
# Just use quotaon directly:
quotaon /quotadata

# If you still get errors:
# 1. Verify filesystem has quota feature
tune2fs -l /dev/sdb1 | grep quota

# 2. Check mount options
mount | grep quotadata

# 3. Remount if needed
mount -o remount,usrquota,grpquota /quotadata

# 4. Try quotaon again
quotaon /quotadata

Issue 3: Grace Period Shows "none" But User Can't Write

Symptom:

quota -u bob

Output:
     Filesystem  blocks   quota   limit   grace   files   quota   limit   grace
      /dev/sdb1   56324   51200   61440    none       2    5000    6000

User says "I can't write files!" but grace shows "none"

Explanation:

This is lazy enforcement. The grace field updates only when kernel checks it.

Solution:

# As the user, try to actually write something
su - bob
cd /quotadata/bob
echo "test" > testfile

# NOW the grace field updates to show the real status
quota

# If over soft for longer than grace period, it will now show expired

Prevention: Train users to check quota BEFORE they hit limits, not after.


Issue 4: User Deletes Files But Quota Still Shows High Usage

Symptom:

# User deletes 10 GB of files
rm -rf /quotadata/alice/olddata/ # old data could be any file or dir 

# But quota still shows high usage
quota -u alice
# Shows: 15 GB used (should be 5 GB now)

Possible causes:

  1. Files still open by processes
# Check for open files (as root)
lsof +D /quotadata/alice

# If processes are holding files:
# Kill those processes or wait for them to close files
  1. Hidden files or directories
# Check for hidden files
du -sh /quotadata/alice
du -sh /quotadata/alice/.*

# Find large files
find /quotadata/alice -type f -size +100M -exec ls -lh {} \;
  1. Quota database needs refresh (rare with built-in quota)
# Turn off and on quota
quotaoff /quotadata
quotaon /quotadata

# Check again
quota -u alice

Issue 5: After Reboot, Quota Not Working

Cause: Filesystem not in /etc/fstab or quotaon not run at boot

Solution:

# Check fstab
grep quotadata /etc/fstab

# Should show:
/dev/sdb1  /quotadata  ext4  defaults,usrquota,grpquota  0  2

# If missing, add it:
echo "/dev/sdb1  /quotadata  ext4  defaults,usrquota,grpquota  0  2" >> /etc/fstab

# Test without rebooting
systemctl daemon-reload
mount -a
quotaon /quotadata

# Verify
quotaon -p /quotadata

Create systemd service to ensure quotaon at boot (optional):

cat > /etc/systemd/system/quota-enable.service << 'EOF'
[Unit]
Description=Enable disk quotas
After=local-fs.target

[Service]
Type=oneshot
ExecStart=/usr/sbin/quotaon -a
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable quota-enable.service
systemctl start quota-enable.service

Issue 6: SELinux Blocking Quota Operations

Symptoms: Quota commands fail with "Permission denied" even as root

Check for SELinux denials:

# Check recent SELinux denials
ausearch -m avc -ts recent | grep quota

# Check SELinux context of quota filesystem
ls -Zd /quotadata

# Restore proper context
restorecon -Rv /quotadata

# If still issues, check SELinux mode
getenforce

# Temporarily set to permissive for testing (not for production!)
setenforce 0

# Try quota operations again
# If they work now, SELinux is the issue

# Set back to enforcing
setenforce 1

# Create proper SELinux policy (beyond scope of this guide)

Issue 7: Quota Report Shows Wrong Block Sizes

Symptom:

repquota -a

# Shows values that don't match what you set

Understanding:

# Quota reports in 1 KB blocks
# Filesystem uses 4 KB blocks by default

# When you see:
blocks used: 4096

# This means:
4096 KB = 4 MB (quota perspective)

# NOT:
4096 blocks Γ— 4 KB = 16 MB (filesystem perspective)

Always use the -s flag for human-readable output:

 repquota -s -u /quotadata
# Shows: 4M (much clearer!)

Issue 8: "Files used" Shows 1 Even with Empty Directory

Symptom:

# User has empty directory but quota shows 1 file
quota -u alice

Output:
     Filesystem  blocks   quota   limit   grace   files   quota   limit   grace
      /dev/sdb1       4 5242880 6291456               1   10000   12000
                                                       ↑
                                                   Why 1 when directory is empty?

Explanation:

This is normal behavior. The directory /quotadata/alice itself is a file (type: directory) and counts as 1 inode.

# Verify
ls -la /quotadata/alice

Output:
total 8
drwxr-xr-x. 2 alice alice 4096 Nov  3 10:00 .          ← This is the directory (1 inode)
drwxr-xr-x. 5 root  root  4096 Nov  3 09:55 ..

Every directory counts as 1 inode, so users always start with at least 1 file in their quota count.

Tutorial ends here now next things are bonus .


Advanced Testing: Quota Across Different File Types

Setup:

# Give bob varied limits
setquota -u bob 512000 614400 100 120 /quotadata
# 500 MB soft, 600 MB hard, 100 files soft, 120 files hard

Test different scenarios:

su - bob
cd /quotadata/bob

# Scenario A: Many tiny files (hits inode limit first)
for i in {1..99}; do
    echo "tiny" > tiny$i.txt
done
quota  # Shows 100 inodes (1 dir + 99 files), minimal blocks

# Scenario B: Few large files (hits block limit first)
rm tiny*.txt  # Clean up first
dd if=/dev/zero of=large1 bs=1M count=400  # 400 MB
dd if=/dev/zero of=large2 bs=1M count=150  # 150 MB
quota  # Shows ~550 MB blocks (over soft), only 3 inodes (1 dir + 2 files)

# Scenario C: Mix of both
rm large*
for i in {1..10}; do
    dd if=/dev/zero of=mixed$i bs=1M count=50 2>/dev/null  # 10 files Γ— 50 MB = 500 MB
done
quota  # Shows ~500 MB blocks (at soft), 11 inodes (1 dir + 10 files)

Key lesson: Different usage patterns hit different limits!


Part 7: Production Best Practices

1. Planning Your Quota Strategy

Questions to answer before implementing:

QuestionWhy It MattersExample Answer
How many users?Determines total capacity needed200 users
What's the use case?Influences limit sizesDevelopment servers: more space<br>Email servers: many small files
Average expected usage per user?Baseline for soft limit10 GB per developer
Peak usage allowance?Determines hard limit15 GB (50% over average)
How long to clean up?Sets grace period7 days (one work week)
Growth rate?Future capacity planning20% annual growth

Sample calculation:

Scenario: Development team server

Users: 50 developers
Average usage: 10 GB per user
Peak allowance: 15 GB per user
Grace period: 7 days

Calculation:
β”œβ”€ Minimum capacity: 50 Γ— 10 GB = 500 GB
β”œβ”€ With peak allowance: 50 Γ— 15 GB = 750 GB
β”œβ”€ With 20% growth buffer: 750 GB Γ— 1.2 = 900 GB
└─ Recommended purchase: 1 TB disk

Per-user quotas:
β”œβ”€ Soft limit: 10 GB (10,485,760 blocks)
β”œβ”€ Hard limit: 15 GB (15,728,640 blocks)
β”œβ”€ Inode soft: 50,000 files
β”œβ”€ Inode hard: 75,000 files
└─ Grace: 7 days

2. Quota Sizing Formulas

Conservative approach (recommended for most cases):

Soft Limit = Expected Average Usage
Hard Limit = Soft Limit Γ— 1.5
Grace Period = 7 days
Inode Soft = Estimated file count Γ— 2
Inode Hard = Inode Soft Γ— 1.5

Aggressive approach (limited resources):

Soft Limit = Expected Average Usage Γ— 0.8
Hard Limit = Expected Average Usage
Grace Period = 3 days
Inode Soft = Estimated file count
Inode Hard = Inode Soft Γ— 1.2

Generous approach (plenty of space):

Soft Limit = Expected Average Usage Γ— 1.5
Hard Limit = Expected Average Usage Γ— 2
Grace Period = 14 days
Inode Soft = Estimated file count Γ— 3
Inode Hard = Inode Soft Γ— 1.5

Example implementations:

# Conservative (10 GB expected usage)
setquota -u user 10485760 15728640 100000 150000 /quotadata

# Aggressive (10 GB expected usage)
setquota -u user 8388608 10485760 50000 60000 /quotadata

# Generous (10 GB expected usage)
setquota -u user 15728640 20971520 150000 225000 /quotadata

3. Monitoring and Alerting

Daily monitoring script:

#!/bin/bash
# Save as: /usr/local/sbin/quota_monitor.sh

# Configuration
FILESYSTEM="/quotadata"
ALERT_EMAIL="admin@company.com"
WARN_THRESHOLD=80  # Warn at 80% of soft limit
CRITICAL_THRESHOLD=95  # Critical at 95% of soft limit

# Generate report
REPORT_FILE="/tmp/quota_report_$(date +%Y%m%d).txt"

echo "Disk Quota Report - $(date)" > "$REPORT_FILE"
echo "======================================" >> "$REPORT_FILE"
echo "" >> "$REPORT_FILE"

# Check users over warning threshold
echo "Users over ${WARN_THRESHOLD}% of quota:" >> "$REPORT_FILE"
repquota -u "$FILESYSTEM" | awk -v threshold="$WARN_THRESHOLD" '
  NR > 5 && $4 > 0 {
    usage_pct = ($3 / $4) * 100
    if (usage_pct >= threshold) {
      printf "%-15s %10s / %10s (%5.1f%%)\n", $1, $3, $4, usage_pct
    }
  }
' >> "$REPORT_FILE"

echo "" >> "$REPORT_FILE"

# Check users in grace period
echo "Users in grace period:" >> "$REPORT_FILE"
repquota -u "$FILESYSTEM" | grep -E "[0-9]days|[0-9]hours" >> "$REPORT_FILE"

echo "" >> "$REPORT_FILE"

# Check users over hard limit (shouldn't happen, but check anyway)
echo "Users at hard limit:" >> "$REPORT_FILE"
repquota -u "$FILESYSTEM" | awk 'NR > 5 && $3 >= $5 && $5 > 0 {print $0}' >> "$REPORT_FILE"

# Send email if any issues found
if grep -q "%" "$REPORT_FILE"; then
    mail -s "Quota Alert - $(date +%Y-%m-%d)" "$ALERT_EMAIL" < "$REPORT_FILE"
fi

# Keep report for 30 days
find /tmp -name "quota_report_*.txt" -mtime +30 -delete

Make it executable and schedule:

chmod +x /usr/local/sbin/quota_monitor.sh

# Add to cron (run daily at 8 AM)
crontab -e

# Add this line:
0 8 * * * /usr/local/sbin/quota_monitor.sh

Real-time monitoring dashboard (simple):

#!/bin/bash
# Save as: /usr/local/sbin/quota_dashboard.sh

watch -n 60 '
echo "=== Disk Quota Dashboard ==="
echo "Last update: $(date)"
echo ""
echo "=== Top 10 Space Users ==="
repquota -su /quotadata | sort -k3 -n -r | head -15 | tail -10
echo ""
echo "=== Users in Grace Period ==="
repquota -su /quotadata | grep -E "[0-9]days|[0-9]hours"
echo ""
echo "=== Overall Filesystem Usage ==="
df -h /quotadata
'

4. User Communication Templates

Email Template 1: Warning (80% of soft limit)

Subject: Disk Quota Warning - Action Recommended

Hello [Username],

Your disk usage on /quotadata is approaching the recommended limit:

Current Usage: 8.2 GB
Soft Limit: 10 GB (82% used)
Hard Limit: 15 GB

Recommendation:
Please review your files and remove unnecessary data to stay under 10 GB.

What happens if you exceed 10 GB:
- You'll have 7 days to reduce usage
- After 7 days, you won't be able to create new files until usage drops below 10 GB

Need help?
- Reply to this email
- Check our wiki: https://wiki.company.com/disk-quota
- Contact IT: helpdesk@company.com

Thank you for keeping our systems running smoothly!
IT Team

Email Template 2: Critical (in grace period)

Subject: URGENT: Disk Quota Exceeded - 7 Days to Comply

Hello [Username],

Your disk usage has exceeded the recommended limit:

Current Usage: 12.5 GB
Soft Limit: 10 GB (EXCEEDED)
Hard Limit: 15 GB
Grace Period: 7 days remaining

REQUIRED ACTION:
You MUST reduce your usage below 10 GB within 7 days.

What happens if you don't:
After 7 days, you will NOT be able to save any new files until your usage is below 10 GB.

How to check your quota:
$ quota

How to find large files:
$ du -sh ~/quotadata/* | sort -h

Need a quota increase?
Submit a request: https://helpdesk.company.com/quota-request

This is automated notification #1 of 3.

IT Team

Email Template 3: Grace expired

Subject: CRITICAL: Disk Quota Grace Period Expired

Hello [Username],

Your grace period has expired. You can no longer create new files.

Current Usage: 12.5 GB
Soft Limit: 10 GB
Hard Limit: 15 GB
Grace Period: EXPIRED

To restore write access:
1. Delete files to get below 10 GB
2. Verify with: quota
3. Try creating a test file

Large file cleanup commands:
# Find files over 100 MB
$ find ~/quotadata -type f -size +100M -ls

# Find old files (over 180 days)
$ find ~/quotadata -type f -mtime +180 -ls

Need immediate assistance?
Contact IT: helpdesk@company.com or ext. 1234

IT Team

5. Backup and Disaster Recovery

Backup quota settings (not just data):

#!/bin/bash
# Save as: /usr/local/sbin/backup_quota_settings.sh

BACKUP_DIR="/backup/quota"
DATE=$(date +%Y%m%d)

mkdir -p "$BACKUP_DIR"

# Backup quota report (shows current usage and limits)
repquota -a > "$BACKUP_DIR/quota_report_$DATE.txt"

# Backup quota limits in machine-readable format
{
  echo "# Quota backup created on $(date)"
  echo "# Format: username:uid:soft_blocks:hard_blocks:soft_inodes:hard_inodes"
  repquota -u /quotadata | awk 'NR > 5 && $1 != "root" {
    print $1":"$4":"$5":"$7":"$8
  }'
} > "$BACKUP_DIR/quota_limits_$DATE.csv"

# Keep last 90 days
find "$BACKUP_DIR" -name "quota_*" -mtime +90 -delete

echo "Quota settings backed up to $BACKUP_DIR"

Restore quota settings after disaster:

#!/bin/bash
# Save as: /usr/local/sbin/restore_quota_settings.sh

BACKUP_FILE="/backup/quota/quota_limits_20251103.csv"
FILESYSTEM="/quotadata"

if [ ! -f "$BACKUP_FILE" ]; then
    echo "Backup file not found!"
    exit 1
fi

echo "Restoring quota settings from $BACKUP_FILE..."

# Read CSV and restore each user
while IFS=: read -r username uid soft_blocks hard_blocks soft_inodes hard_inodes; do
    # Skip comments
    [[ "$username" =~ ^#.* ]] && continue

    # Check if user exists
    if id "$username" &>/dev/null; then
        setquota -u "$username" "$soft_blocks" "$hard_blocks" "$soft_inodes" "$hard_inodes" "$FILESYSTEM"
        echo "Restored quota for: $username"
    else
        echo "Skipped $username (user doesn't exist)"
    fi
done < "$BACKUP_FILE"

echo "Quota restoration complete!"
repquota "$FILESYSTEM"

Schedule backups:

# Add to cron (daily at 2 AM)
crontab -e

# Add:
0 2 * * * /usr/local/sbin/backup_quota_settings.sh

6. Security Best Practices

Prevent quota manipulation:

# Only root should modify quotas
chmod 700 /usr/sbin/*quota*

# Protect fstab
chmod 644 /etc/fstab
chown root:root /etc/fstab

# Audit quota changes
auditctl -w /usr/sbin/setquota -p x -k quota_set
auditctl -w /usr/sbin/edquota -p x -k quota_edit
auditctl -w /etc/fstab -p wa -k fstab_changes

# Make audit rules permanent
echo "-w /usr/sbin/setquota -p x -k quota_set" >> /etc/audit/rules.d/quota.rules
echo "-w /usr/sbin/edquota -p x -k quota_edit" >> /etc/audit/rules.d/quota.rules
echo "-w /etc/fstab -p wa -k fstab_changes" >> /etc/audit/rules.d/quota.rules

# Reload audit rules
augenrules --load

# View quota-related audit logs
ausearching Limits to Multiple Users

**Copy alice's limits to another user:**

```bash
edquota -p alice -u charlie