Skip to content

Storage and quotas

Our clusters provide several filesystems, each designed for a different purpose. Understanding which one to use for what saves you from running out of space, slow I/O, or losing data. For the full filesystem layout and quota limits on each cluster, see Data transfer.

Where to put your files

What Where Why
Job scripts, input files, simulation output /scratch High-performance parallel filesystem, accessible from all compute nodes
Source code, dotfiles, small configs /dipc (home) Persistent across sessions, backed up on Atlas clusters
Large datasets you want to keep long-term /data (Hyperion only) 10 TB quota, read-only from compute nodes
Temporary files during a single job /lscratch Local disk on the compute node, fastest I/O, deleted when the job ends
Conda environments, container images, caches /scratch or /data Avoids filling home quota with thousands of small files

The general rule: run everything from /scratch. Use /dipc for things you want to keep safe and small, and /lscratch when a single job needs very fast temporary I/O.

Atlas: /dipc is not visible from compute nodes

On Atlas EDR and Atlas FDR, compute nodes cannot access /dipc. If your job reads input from or writes output to /dipc, it will fail silently or write to /scratch instead (where /dipc is a symlink). Always work from /scratch on Atlas.

Checking your quota

getquota-home       # /dipc quota
getquota-scratch    # /scratch quota
getquota-data       # /data quota
getquota            # shows all quotas

When you run out of space

Running out of quota is the most common storage issue. Symptoms include failed jobs, "disk quota exceeded" errors, or inability to log in (if your home is full).

Quick fixes

  1. Find what is using the space. From the filesystem that is full:

    du -sh /scratch/<username>/*  | sort -rh | head -20
    
  2. Clean up common offenders:

    # Conda package cache (often several GB)
    conda clean --all
    
    # Apptainer image cache
    apptainer cache clean
    
    # Nextflow work directories from old runs
    nextflow clean -f
    
    # Pip cache
    pip cache purge
    
  3. Find large old files. This only lists them; it does not delete anything:

    find /scratch/<username> -size +100M -mtime +30 -ls
    

    Review the output and manually remove what you no longer need.

Requesting a temporary quota increase

If you need more space temporarily (e.g., for a large dataset or a burst of simulations), contact us at support-hpc@dipc.org with:

  • Which filesystem (/scratch, /data)
  • How much additional space you need
  • For how long
  • A brief explanation of why

We can increase your quota temporarily. Once you are done, clean up and let us know so we can restore the default limits.

Small files and performance

Parallel filesystems like BeeGFS (Hyperion) are optimized for large sequential I/O, not for millions of small files. Conda environments, Python packages, and Node.js projects can generate tens of thousands of small files, which degrades performance for everyone on the shared filesystem and consumes your inode (file count) quota quickly.

If you have a large number of small files:

  • Conda environments: package them inside an Apptainer container. The entire environment becomes a single .sif file.
  • Datasets with many small files: combine them into a single archive (.tar) or use a format like HDF5.
  • Temporary files: use /lscratch (local disk) instead of /scratch for jobs that create and delete many files during execution.
How do I check my inode (file count) usage?

The same getquota commands show both space and file count usage. If your file count is near the limit, you will not be able to create new files even if you have space left.

Sharing a directory with collaborators

Our clusters do not provide predefined group directories, but you can set one up yourself on any of the available filesystems. The recipes below work the same on /dipc, /scratch, or /data; pick the location that fits the lifetime of the data you want to share:

  • /data (Hyperion only) for long-lived shared project data.
  • /scratch for data being actively processed by jobs.
  • /dipc for small shared scripts or configs (mind the home quota).

The examples assume the directory you want to share lives at /path/to/shared. Pick the approach below that matches your situation.

Group permissions

The simplest option when everyone who needs access already shares the same Unix group. The commands rely on standard chmod / rwx notation; if you already know it, jump straight to Setting up the share below. Otherwise, here is a quick recap.

Reading ls -l

   d   rwx   r-x   ---
   │    │     │     │
   │    │     │     └── others   no access
   │    │     └──────── group    read + traverse only
   │    └────────────── owner    read, write, traverse
   └─────────────────── type     d = directory · - = file · l = symlink

Three triplets in fixed order: owner → group → others. Each slot has slightly different meaning on files vs. directories:

              r              w               x
 file         read content   modify          run as a program
 directory    list (ls)      create/rename   enter (cd)

A - means the slot is not granted.

Changing with chmod

        chmod   u+x   script.sh
                │ │
       class ───┘ └── add  execute
 class       u owner    g group     o others    a all
 operator    + add      - remove    = set exact
 permission  r read     w write     x execute   X (dirs only)
chmod u+x   script.sh       # owner can execute it
chmod g-w   notes.txt       # remove write from the group
chmod a+r   notes.txt       # everyone can read
chmod -R g+rX project/      # recursive: group reads files, traverses subdirs

Two things to watch for

  • Uppercase X applies execute only to directories (and files that already had x set). Safer than x for recursive grants.
  • chmod g+s dir/ (setgid bit) makes new files inside dir/ inherit the directory's group instead of the creator's primary group.
What does the digit in chmod 755 mean?

Octal notation packs each triplet into one digit: r=4, w=2, x=1. So 755 is rwx r-x r-x; 640 is rw- r-- ---.

Setting up the share

Check who is in the group first

A Unix group can include users beyond the collaborators you have in mind. Granting g+r (or g+rw) on a directory exposes it to every member of that group. List the membership before applying any permissions:

getent group <group>

If the group contains users who should not have access, use ACL-based permissions instead and grant access user by user.

Set the group recursively on the directory:

chgrp -R <group> /path/to/shared

Grant read on files and read+execute on directories. The capital X is important: it adds execute permission only to directories (and to files that already had it), so plain data files do not become executable by accident:

chmod -R g+rX /path/to/shared

Every parent directory also needs +x for the group, otherwise members will not be able to cd into the shared directory:

chmod g+x /path/to

If group members should also be able to write to the directory, replace g+rX with g+rwX and set the setgid bit so new files inherit the group automatically:

chmod g+s /path/to/shared

Verify the result with:

ls -ld /path/to /path/to/shared
namei -l /path/to/shared/some_file

ACL-based permissions

Useful when collaborators do not all share a single Unix group, or when you prefer per-user access. Access Control Lists (ACLs) extend the basic owner/group/others model: instead of three permission triplets, you attach an arbitrary list of entries, each granting permissions to a specific user or group. The original owner/group/others bits stay in place; ACLs are layered on top.

A file or directory with ACLs shows a + at the end of its permission string in ls -l:

$ ls -l /path/to
drwxr-x---+ 2 <username> <group> 4096 May  5 10:23 shared

View the full list with getfacl:

$ getfacl /path/to/shared
# file: path/to/shared
# owner: <username>
# group: <group>
user::rwx
user:alice:r-x
group::r-x
group:project-x:r-x
mask::r-x
other::---

Each entry has the form <type>:<name>:<permissions>:

   u   :   alice   :   r-x
   │        │           │
   │        │           └── permissions (r/w/x bits, `-` for not granted)
   │        └────────────── name of the user or group (empty for the classic owner/group entries)
   └─────────────────────── type:  u = user, g = group, m = mask, o = other

The r/w/x bits mean exactly the same as in standard Unix mode:

              r              w               x
 file         read content   modify          run as a program
 directory    list (ls)      create/rename   enter (cd)

Entries without a name (e.g., user::rwx) correspond to the classic owner / file group / others bits and mirror what ls -l already shows. Named entries are the ACL additions: in the example above, user alice and group project-x are each granted r-x.

The setfacl flags used below are:

Flag Name What it does
-m modify Add the ACL entry that follows, or update it if one already exists for the same user/group. The workhorse for granting access.
-x remove Delete a specific entry. Only the type and name are needed (u:<username>, g:<group>); no permissions, since you are dropping the whole entry.
-b blank Strip all ACL entries at once, leaving only the standard owner/group/others bits. Useful for resetting a directory to plain Unix permissions.
-R recursive Apply the change to the directory and everything already inside it. Without it, only the target path is touched.
-d default Operate on the directory's default ACL: the template that new files and directories created inside will inherit. Combine with -m/-x/-b to manage the template the same way.

For an entire group:

# Applies to everything that already exists
setfacl -R -m g:<group>:rX /path/to/shared

# Default ACL: inherited by new files and directories created inside
setfacl -R -d -m g:<group>:rX /path/to/shared

# Parent directories need traversal permission for the group (r-x also works)
setfacl -m g:<group>:--x /path/to

For individual users (repeat per username):

setfacl -R -m u:<username>:rX /path/to/shared
setfacl -R -d -m u:<username>:rX /path/to/shared
setfacl -m u:<username>:--x /path/to

Inspect the configured ACLs at any time with:

getfacl /path/to/shared

To revoke access:

# Remove a specific user's entry, both from the current ACL and from the default ACL
setfacl -R -x u:<username> /path/to/shared
setfacl -R -d -x u:<username> /path/to/shared

# Remove all ACL entries, leaving only the standard owner/group/others bits
setfacl -R -b /path/to/shared
Walkthrough: sharing a scratch directory with two collaborators

alice has a dataset in /scratch/alice/project-x and wants to give bob read-only access and carol read-write access. The three do not share a Unix group, so ACLs are the right tool.

1. Starting point

$ ls -ld /scratch/alice /scratch/alice/project-x
drwx------ 5 alice alice 4096 May  5 10:20 /scratch/alice
drwxr-x--- 3 alice alice 4096 May  5 10:23 /scratch/alice/project-x

Nobody but alice can even traverse /scratch/alice.

2. Open traversal on the parent directory

Execute-only (--x) is enough: it lets them cd through without listing the contents.

setfacl -m u:bob:--x /scratch/alice
setfacl -m u:carol:--x /scratch/alice

3. Grant access to the shared directory itself

setfacl -R -m u:bob:rX    /scratch/alice/project-x
setfacl -R -m u:carol:rwX /scratch/alice/project-x

4. Make the grant apply to future files too

Step 3 only touched what exists right now. The default ACL is the template new entries inherit:

setfacl -R -d -m u:bob:rX    /scratch/alice/project-x
setfacl -R -d -m u:carol:rwX /scratch/alice/project-x

5. Verify

$ getfacl /scratch/alice/project-x
# file: scratch/alice/project-x
# owner: alice
# group: alice
user::rwx
user:bob:r-x
user:carol:rwx
group::r-x
mask::rwx
other::---
default:user::rwx
default:user:bob:r-x
default:user:carol:rwx
default:group::r-x
default:mask::rwx
default:other::---

The default: entries are the template from step 4. To confirm the whole path is traversable for bob:

$ namei -l /scratch/alice/project-x/data.csv
f: /scratch/alice/project-x/data.csv
 drwxr-xr-x  root  root  /
 drwxr-xr-x  root  root  scratch
 drwx------+ alice alice alice
 drwxr-x---+ alice alice project-x
 -rw-r-----+ alice alice data.csv

The + on each component shows an ACL is in place.

6. What happens with new files

carol creates a file inside the directory:

$ getfacl /scratch/alice/project-x/results.dat
# file: scratch/alice/project-x/results.dat
# owner: carol
# group: carol
user::rw-
user:bob:r-x                    #effective:r--
user:carol:rwx                  #effective:rw-
group::r-x                      #effective:r--
mask::rw-
other::---

The entries were inherited from the default ACL, but mask::rw- trims them: a regular file created with a standard umask never gets the execute bit, so the mask drops x. The read/write access is intact, which is what matters here.

7. Revoking later

When bob leaves the project:

setfacl -R -x u:bob /scratch/alice/project-x
setfacl -R -d -x u:bob /scratch/alice/project-x
setfacl -x u:bob /scratch/alice
What is the mask line in getfacl output?

The mask is an upper bound on the effective permissions granted by any named user or group entry (and by the file's group entry). If an entry grants rwx but the mask is r-x, the effective permission is r-x. The mask is recomputed automatically whenever you add or modify an ACL entry, so you rarely need to set it by hand. If getfacl shows #effective:<perms> next to an entry, that is telling you the mask is restricting it.