You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

2555 lines
58 KiB

<!doctype html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="description" content="mergerfs - a featureful union filesystem">
<link rel="canonical" href="https://trapexit.github.io/mergerfs/2.41.0/intro_to_filesystems/">
<link rel="prev" href="../terminology/">
<link rel="next" href="../config/options/">
<link rel="icon" href="../logo.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.6.18">
<title>Intro to Filesystems - mergerfs</title>
<link rel="stylesheet" href="../assets/stylesheets/main.7e37652d.min.css">
<link rel="stylesheet" href="../assets/stylesheets/palette.06af60db.min.css">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback">
<style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style>
<script>__md_scope=new URL("..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
</head>
<body dir="ltr" data-md-color-scheme="default" data-md-color-primary="indigo" data-md-color-accent="indigo">
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" for="__drawer"></label>
<div data-md-component="skip">
<a href="#intro-to-filesystems" class="md-skip">
Skip to content
</a>
</div>
<div data-md-component="announce">
</div>
<div data-md-color-scheme="default" data-md-component="outdated" hidden>
</div>
<header class="md-header md-header--shadow" data-md-component="header">
<nav class="md-header__inner md-grid" aria-label="Header">
<a href=".." title="mergerfs" class="md-header__button md-logo" aria-label="mergerfs" data-md-component="logo">
<img src="../logo.png" alt="logo">
</a>
<label class="md-header__button md-icon" for="__drawer">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg>
</label>
<div class="md-header__title" data-md-component="header-title">
<div class="md-header__ellipsis">
<div class="md-header__topic">
<span class="md-ellipsis">
mergerfs
</span>
</div>
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
Intro to Filesystems
</span>
</div>
</div>
</div>
<form class="md-header__option" data-md-component="palette">
<input class="md-option" data-md-color-media="(prefers-color-scheme)" data-md-color-scheme="default" data-md-color-primary="indigo" data-md-color-accent="indigo" aria-label="Switch to light mode" type="radio" name="__palette" id="__palette_0">
<label class="md-header__button md-icon" title="Switch to light mode" for="__palette_1" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m14.3 16-.7-2h-3.2l-.7 2H7.8L11 7h2l3.2 9zM20 8.69V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12zm-9.15 3.96h2.3L12 9z"/></svg>
</label>
<input class="md-option" data-md-color-media="(prefers-color-scheme: light)" data-md-color-scheme="default" data-md-color-primary="indigo" data-md-color-accent="indigo" aria-label="Switch to dark mode" type="radio" name="__palette" id="__palette_1">
<label class="md-header__button md-icon" title="Switch to dark mode" for="__palette_2" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a4 4 0 0 0-4 4 4 4 0 0 0 4 4 4 4 0 0 0 4-4 4 4 0 0 0-4-4m0 10a6 6 0 0 1-6-6 6 6 0 0 1 6-6 6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z"/></svg>
</label>
<input class="md-option" data-md-color-media="(prefers-color-scheme: dark)" data-md-color-scheme="slate" data-md-color-primary="indigo" data-md-color-accent="indigo" aria-label="Switch to system preference" type="radio" name="__palette" id="__palette_2">
<label class="md-header__button md-icon" title="Switch to system preference" for="__palette_0" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 18c-.89 0-1.74-.2-2.5-.55C11.56 16.5 13 14.42 13 12s-1.44-4.5-3.5-5.45C10.26 6.2 11.11 6 12 6a6 6 0 0 1 6 6 6 6 0 0 1-6 6m8-9.31V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12z"/></svg>
</label>
</form>
<script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
<label class="md-header__button md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
</label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
<label class="md-search__icon md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
</label>
<nav class="md-search__options" aria-label="Search">
<a href="javascript:void(0)" class="md-search__icon md-icon" title="Share" aria-label="Share" data-clipboard data-clipboard-text="" data-md-component="search-share" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.15c-.05.21-.08.43-.08.66 0 1.61 1.31 2.91 2.92 2.91s2.92-1.3 2.92-2.91A2.92 2.92 0 0 0 18 16.08"/></svg>
</a>
<button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
</button>
</nav>
<div class="md-search__suggest" data-md-component="search-suggest"></div>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" tabindex="0" data-md-scrollfix>
<div class="md-search-result" data-md-component="search-result">
<div class="md-search-result__meta">
Initializing search
</div>
<ol class="md-search-result__list" role="presentation"></ol>
</div>
</div>
</div>
</div>
</div>
<div class="md-header__source">
<a href="https://github.com/trapexit/mergerfs" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path fill="currentColor" d="M439.6 236.1 244 40.5c-5.4-5.5-12.8-8.5-20.4-8.5s-15 3-20.4 8.4L162.5 81l51.5 51.5c27.1-9.1 52.7 16.8 43.4 43.7l49.7 49.7c34.2-11.8 61.2 31 35.5 56.7-26.5 26.5-70.2-2.9-56-37.3L240.3 199v121.9c25.3 12.5 22.3 41.8 9.1 55-6.4 6.4-15.2 10.1-24.3 10.1s-17.8-3.6-24.3-10.1c-17.6-17.6-11.1-46.9 11.2-56v-123c-20.8-8.5-24.6-30.7-18.6-45L142.6 101 8.5 235.1C3 240.6 0 247.9 0 255.5s3 15 8.5 20.4l195.6 195.7c5.4 5.4 12.7 8.4 20.4 8.4s15-3 20.4-8.4l194.7-194.7c5.4-5.4 8.4-12.8 8.4-20.4s-3-15-8.4-20.4"/></svg>
</div>
<div class="md-source__repository">
mergerfs
</div>
</a>
</div>
</nav>
</header>
<div class="md-container" data-md-component="container">
<main class="md-main" data-md-component="main">
<div class="md-main__inner md-grid">
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary" aria-label="Navigation" data-md-level="0">
<label class="md-nav__title" for="__drawer">
<a href=".." title="mergerfs" class="md-nav__button md-logo" aria-label="mergerfs" data-md-component="logo">
<img src="../logo.png" alt="logo">
</a>
mergerfs
</label>
<div class="md-nav__source">
<a href="https://github.com/trapexit/mergerfs" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path fill="currentColor" d="M439.6 236.1 244 40.5c-5.4-5.5-12.8-8.5-20.4-8.5s-15 3-20.4 8.4L162.5 81l51.5 51.5c27.1-9.1 52.7 16.8 43.4 43.7l49.7 49.7c34.2-11.8 61.2 31 35.5 56.7-26.5 26.5-70.2-2.9-56-37.3L240.3 199v121.9c25.3 12.5 22.3 41.8 9.1 55-6.4 6.4-15.2 10.1-24.3 10.1s-17.8-3.6-24.3-10.1c-17.6-17.6-11.1-46.9 11.2-56v-123c-20.8-8.5-24.6-30.7-18.6-45L142.6 101 8.5 235.1C3 240.6 0 247.9 0 255.5s3 15 8.5 20.4l195.6 195.7c5.4 5.4 12.7 8.4 20.4 8.4s15-3 20.4-8.4l194.7-194.7c5.4-5.4 8.4-12.8 8.4-20.4s-3-15-8.4-20.4"/></svg>
</div>
<div class="md-source__repository">
mergerfs
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href=".." class="md-nav__link">
<span class="md-ellipsis">
Home
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../quickstart/" class="md-nav__link">
<span class="md-ellipsis">
QuickStart
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3" >
<label class="md-nav__link" for="__nav_3" id="__nav_3_label" tabindex="0">
<span class="md-ellipsis">
Installation
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_3_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_3">
<span class="md-nav__icon md-icon"></span>
Installation
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../setup/installation/" class="md-nav__link">
<span class="md-ellipsis">
Installation
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../setup/upgrade/" class="md-nav__link">
<span class="md-ellipsis">
Upgrade
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../setup/build/" class="md-nav__link">
<span class="md-ellipsis">
Build
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../terminology/" class="md-nav__link">
<span class="md-ellipsis">
Terminology
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
<span class="md-ellipsis">
Intro to Filesystems
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<a href="./" class="md-nav__link md-nav__link--active">
<span class="md-ellipsis">
Intro to Filesystems
</span>
</a>
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#terminology" class="md-nav__link">
<span class="md-ellipsis">
Terminology
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#files" class="md-nav__link">
<span class="md-ellipsis">
Files
</span>
</a>
<nav class="md-nav" aria-label="Files">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#types" class="md-nav__link">
<span class="md-ellipsis">
Types
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#inodes" class="md-nav__link">
<span class="md-ellipsis">
inodes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#links-names" class="md-nav__link">
<span class="md-ellipsis">
links / names
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#permissions" class="md-nav__link">
<span class="md-ellipsis">
permissions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#ownership" class="md-nav__link">
<span class="md-ellipsis">
ownership
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#timestamps" class="md-nav__link">
<span class="md-ellipsis">
timestamps
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#functions" class="md-nav__link">
<span class="md-ellipsis">
Functions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#workflows" class="md-nav__link">
<span class="md-ellipsis">
Workflows
</span>
</a>
<nav class="md-nav" aria-label="Workflows">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#creating-a-file" class="md-nav__link">
<span class="md-ellipsis">
Creating a file
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#reading-or-writing-to-a-file" class="md-nav__link">
<span class="md-ellipsis">
Reading or writing to a file
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#copying-a-file" class="md-nav__link">
<span class="md-ellipsis">
Copying a file
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#moving-a-file" class="md-nav__link">
<span class="md-ellipsis">
Moving a file
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#summary" class="md-nav__link">
<span class="md-ellipsis">
Summary
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_6" >
<label class="md-nav__link" for="__nav_6" id="__nav_6_label" tabindex="0">
<span class="md-ellipsis">
Config
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_6_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_6">
<span class="md-nav__icon md-icon"></span>
Config
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../config/options/" class="md-nav__link">
<span class="md-ellipsis">
Options
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../config/deprecated_options/" class="md-nav__link">
<span class="md-ellipsis">
Deprecated Options
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../config/branches/" class="md-nav__link">
<span class="md-ellipsis">
branches
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../config/branches-mount-timeout/" class="md-nav__link">
<span class="md-ellipsis">
branches-mount-timeout
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../config/functions_categories_policies/" class="md-nav__link">
<span class="md-ellipsis">
functions, categories and policies
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../config/minfreespace/" class="md-nav__link">
<span class="md-ellipsis">
minfreespace
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../config/func_readdir/" class="md-nav__link">
<span class="md-ellipsis">
func.readdir
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../config/rename_and_link/" class="md-nav__link">
<span class="md-ellipsis">
rename and link
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../config/moveonenospc/" class="md-nav__link">
<span class="md-ellipsis">
moveonenospc
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../config/cache/" class="md-nav__link">
<span class="md-ellipsis">
caching
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../config/passthrough/" class="md-nav__link">
<span class="md-ellipsis">
passthrough
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../config/readahead/" class="md-nav__link">
<span class="md-ellipsis">
readahead
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../config/inodecalc/" class="md-nav__link">
<span class="md-ellipsis">
inodecalc
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../config/threads/" class="md-nav__link">
<span class="md-ellipsis">
threads
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../config/pin-threads/" class="md-nav__link">
<span class="md-ellipsis">
pin-threads
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../config/link_cow/" class="md-nav__link">
<span class="md-ellipsis">
link_cow
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../config/fuse_msg_size/" class="md-nav__link">
<span class="md-ellipsis">
fuse_msg_size
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../config/follow-symlinks/" class="md-nav__link">
<span class="md-ellipsis">
follow-symlinks
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../config/link-exdev/" class="md-nav__link">
<span class="md-ellipsis">
link-exdev
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../config/rename-exdev/" class="md-nav__link">
<span class="md-ellipsis">
rename-exdev
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../config/symlinkify/" class="md-nav__link">
<span class="md-ellipsis">
symlinkify
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../config/nullrw/" class="md-nav__link">
<span class="md-ellipsis">
nullrw
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../config/xattr/" class="md-nav__link">
<span class="md-ellipsis">
xattr
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../config/nfsopenhack/" class="md-nav__link">
<span class="md-ellipsis">
nfsopenhack
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../config/statfs/" class="md-nav__link">
<span class="md-ellipsis">
statfs / statvfs
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../config/flush-on-close/" class="md-nav__link">
<span class="md-ellipsis">
flush-on-close
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../config/export-support/" class="md-nav__link">
<span class="md-ellipsis">
export-support
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../config/kernel-permissions-check/" class="md-nav__link">
<span class="md-ellipsis">
kernel-permissions-check
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../error_handling_and_logging/" class="md-nav__link">
<span class="md-ellipsis">
Error Handling and Logging
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../resource_usage/" class="md-nav__link">
<span class="md-ellipsis">
Resource Usage and Management
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../runtime_interface/" class="md-nav__link">
<span class="md-ellipsis">
Runtime Interface
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../remote_filesystems/" class="md-nav__link">
<span class="md-ellipsis">
Remote Filesystems
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../tips_notes/" class="md-nav__link">
<span class="md-ellipsis">
Tips and Notes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../known_issues_bugs/" class="md-nav__link">
<span class="md-ellipsis">
Known Issues and Bugs
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../project_comparisons/" class="md-nav__link">
<span class="md-ellipsis">
Project Comparisons
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../benchmarking/" class="md-nav__link">
<span class="md-ellipsis">
Benchmarking
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../performance/" class="md-nav__link">
<span class="md-ellipsis">
Tweaking Performance
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../tooling/" class="md-nav__link">
<span class="md-ellipsis">
Tooling
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../extended_usage_patterns/" class="md-nav__link">
<span class="md-ellipsis">
Extended Usage Patterns
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_18" >
<label class="md-nav__link" for="__nav_18" id="__nav_18_label" tabindex="0">
<span class="md-ellipsis">
FAQ
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_18_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_18">
<span class="md-nav__icon md-icon"></span>
FAQ
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../faq/why_isnt_it_working/" class="md-nav__link">
<span class="md-ellipsis">
"Why isn't it working?"
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../faq/reliability_and_scalability/" class="md-nav__link">
<span class="md-ellipsis">
Reliability and Scalability
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../faq/usage_and_functionality/" class="md-nav__link">
<span class="md-ellipsis">
Usage and Functionality
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../faq/configuration_and_policies/" class="md-nav__link">
<span class="md-ellipsis">
Configuration and Policies
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../faq/compatibility_and_integration/" class="md-nav__link">
<span class="md-ellipsis">
Compatibility and Integration
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../faq/recommendations_and_warnings/" class="md-nav__link">
<span class="md-ellipsis">
Recommendations and Warnings
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../faq/technical_behavior_and_limitations/" class="md-nav__link">
<span class="md-ellipsis">
Technical Behavior and Limitations
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../faq/have_you_considered/" class="md-nav__link">
<span class="md-ellipsis">
"Have You Considered?"
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../faq/limit_drive_spinup/" class="md-nav__link">
<span class="md-ellipsis">
Limiting drive spinup
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../related_projects/" class="md-nav__link">
<span class="md-ellipsis">
Related Projects
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../media_and_publicity/" class="md-nav__link">
<span class="md-ellipsis">
Media and Publicity
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../support/" class="md-nav__link">
<span class="md-ellipsis">
Support
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../sponsorship_and_donations/" class="md-nav__link">
<span class="md-ellipsis">
Sponsorship and Donations
</span>
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#terminology" class="md-nav__link">
<span class="md-ellipsis">
Terminology
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#files" class="md-nav__link">
<span class="md-ellipsis">
Files
</span>
</a>
<nav class="md-nav" aria-label="Files">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#types" class="md-nav__link">
<span class="md-ellipsis">
Types
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#inodes" class="md-nav__link">
<span class="md-ellipsis">
inodes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#links-names" class="md-nav__link">
<span class="md-ellipsis">
links / names
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#permissions" class="md-nav__link">
<span class="md-ellipsis">
permissions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#ownership" class="md-nav__link">
<span class="md-ellipsis">
ownership
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#timestamps" class="md-nav__link">
<span class="md-ellipsis">
timestamps
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#functions" class="md-nav__link">
<span class="md-ellipsis">
Functions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#workflows" class="md-nav__link">
<span class="md-ellipsis">
Workflows
</span>
</a>
<nav class="md-nav" aria-label="Workflows">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#creating-a-file" class="md-nav__link">
<span class="md-ellipsis">
Creating a file
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#reading-or-writing-to-a-file" class="md-nav__link">
<span class="md-ellipsis">
Reading or writing to a file
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#copying-a-file" class="md-nav__link">
<span class="md-ellipsis">
Copying a file
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#moving-a-file" class="md-nav__link">
<span class="md-ellipsis">
Moving a file
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#summary" class="md-nav__link">
<span class="md-ellipsis">
Summary
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<article class="md-content__inner md-typeset">
<a href="https://github.com/trapexit/mergerfs/edit/master/mkdocs/docs/intro_to_filesystems.md" title="Edit this page" class="md-content__button md-icon" rel="edit">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10 20H6V4h7v5h5v3.1l2-2V8l-6-6H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h4zm10.2-7c.1 0 .3.1.4.2l1.3 1.3c.2.2.2.6 0 .8l-1 1-2.1-2.1 1-1c.1-.1.2-.2.4-.2m0 3.9L14.1 23H12v-2.1l6.1-6.1z"/></svg>
</a>
<a href="https://github.com/trapexit/mergerfs/raw/master/mkdocs/docs/intro_to_filesystems.md" title="View source of this page" class="md-content__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M17 18c.56 0 1 .44 1 1s-.44 1-1 1-1-.44-1-1 .44-1 1-1m0-3c-2.73 0-5.06 1.66-6 4 .94 2.34 3.27 4 6 4s5.06-1.66 6-4c-.94-2.34-3.27-4-6-4m0 6.5a2.5 2.5 0 0 1-2.5-2.5 2.5 2.5 0 0 1 2.5-2.5 2.5 2.5 0 0 1 2.5 2.5 2.5 2.5 0 0 1-2.5 2.5M9.27 20H6V4h7v5h5v4.07c.7.08 1.36.25 2 .49V8l-6-6H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h4.5a8.2 8.2 0 0 1-1.23-2"/></svg>
</a>
<h1 id="intro-to-filesystems">Intro to Filesystems</h1>
<p><strong>!! WORK IN PROGRESS !!</strong></p>
<p>mergerfs is a union filesystem that manages other filesystems. To
understand how mergerfs works and what the features do and mean you
must understand at least the basics of how filesystems work. Much of
the confusion with mergerfs is based in a lack of knowledge about
filesystems. This section of the documentation is provide a primer for
those needing that knowledge.</p>
<h2 id="terminology">Terminology</h2>
<ul>
<li><a href="https://en.wikipedia.org/wiki/File_system">filesystem</a>: A method,
data structures, and API used to organize and store files on
computer storage devices. Often in a tree like structure / hierarchy.</li>
<li><a href="https://en.wikipedia.org/wiki/Computer_file">file</a>: A named
collection of data stored as a unique object. Filesystems can have
numerous file types and "file" can be used to reference any of those
types or a "regular" file.</li>
<li>regular file: A file as commonly understood as a named collection of data.</li>
<li><a href="https://en.wikipedia.org/wiki/Directory_(computing)">directory</a>: A
container which holds files and, typically, other directories. In
Unix/Linux/POSIX filesystems a directory is technically also a file.</li>
<li>root filesystem: The primary filesystem for which other filesystems
within a system are mounted.</li>
<li><a href="https://en.wikipedia.org/wiki/Root_directory">root directory</a>: The
top-level directory in POSIX and POSIX-like filesystems. Denoted by
"/".</li>
<li><a href="https://en.wikipedia.org/wiki/Path_(computing)">path</a>: The location
of a file within a filesystem hierarchy.</li>
<li><a href="https://en.wikipedia.org/wiki/Inode">inode</a>: A unique integer
identifier for a file. Like a primary key. Also used to refer to the
underlying data structure which stores metadata about the file.</li>
<li><a href="https://en.wikipedia.org/wiki/Hard_link">link</a>: A reference to an
inode in the form of a name. An inode may have 0 to N links.</li>
<li><a href="https://en.wikipedia.org/wiki/Symbolic_link">symlink</a>: A file type
which stores data that may, but is not required to, be a path to
another file.</li>
<li>device id: A runtime, unique identification value assigned to a
filesystem.</li>
<li><a href="https://en.wikipedia.org/wiki/Mount_(computing)#MOUNT-POINT">mount
point</a>:
The directory where a filesystem is "mounted" or presented within a
directory hierarchy.</li>
<li><a href="https://en.wikipedia.org/wiki/File-system_permissions">permissions</a>:
Access rights for files.</li>
<li><a href="https://en.wikipedia.org/wiki/User_identifier">owner</a>: System user
which has rights to a file.</li>
<li><a href="https://en.wikipedia.org/wiki/File_descriptor">file descriptor</a>: A
handle used by software, provided by the operating system, to
reference open files.</li>
</ul>
<h2 id="files">Files</h2>
<p>In POSIX filesystems there are several types of files. Interacting
with them is often similar but they offer different capabilities.</p>
<h3 id="types">Types</h3>
<ul>
<li>regular: The typical file type. An array of data which can be
randomly accessed.</li>
<li>directory: A container which holds other files including other
directories allowing for a tree like layout.</li>
<li>symlink: A special file which can store a limited amount of data,
typically a file path, which may be transparently interpreted by
some filesystem functions as a path. symlinks do <em>not</em> need to be a
valid path or a path at all. They can be used as a key/value like
storage mechanism for instance.</li>
<li>character device: A special file typically representing some
physical or logical hardware device offering, typically, an
unbuffered byte stream based interface.</li>
<li>block device: A special file which represents a physical or logical
hardware device (typically storage) allowing for buffered,
fixed-size blocks data transfers.</li>
<li>fifo: Also referred to as a "named pipe." A FIFO, First In, First
Out, is a special file which acts as a non-persistent,
unidirectional conduit for data.</li>
<li>unix domain socket: Also referred to as a "local socket" or "IPC
socket" a "UDS" works similar to a FIFO but bidirectional and
offering more features similar to TCP/IP or UDP/IP but local to the
system.</li>
</ul>
<h3 id="inodes">inodes</h3>
<p>The inode in practical terms <strong>is</strong> the file within a POSIX
filesystem. It is, typically, a unique identifier within a filesystem
similar to a primary key, represented as a 32 or 64bit integer, which
is what the typical user imagines as the file and its metadata
(ownership, permissions, type, internal filesystem details, etc.).</p>
<p>"typically unique" because some filesystems, such as FUSE based ones,
may reuse an inode value for multiple logical files despite them being
separate entities in the traditional sense. From the user's
perspective multiple files may have the same inode but as mentioned
above the inode is the true reference for a file and the "file" people
interact with is really a link (see below.)</p>
<h3 id="links-names">links / names</h3>
<p>To make inodes more useful and accessible POSIX filesystems provide
"links". A link (or sometimes referred to as "hardlink") is a file
name which references an inode. A single inode can be referenced by
multiple links (except for directories typically.) If the number of
links to an inode reach zero, and no programs have the inode actively
in use, the filesystem will logically remove the inode/file.</p>
<p>When a regular file is first created think of it as the filesystem
first creating the underlying structure, assigning an inode, then
creating a link (name) for it in one shot. When a file is "link"ed to
in the future a new "link" / "name" is being created and referencing
the source file which will then cause the "nlink" value within the
inode, which holds a reference count of the number of links/names that
inode has, to be increased by 1. This is why deleting a file is
referred to as an "unlink". Technically you are requesting the removal
of the "link" and once all the links to a file are removed/unlinked,
and the file is not in active use, the filesystem will then logically
remove the file.</p>
<p>Knowing the details above the API for POSIX filesystems is a little
odd in that the programmer does not first create an inode then a
link. Instead that is done together with no way to do the former alone
despite being able to add additional links afterwards. Modern Linux
filesystems do allow for this using the
<a href="https://man7.org/linux/man-pages/man2/openat.2.html">O_TMPFILE</a>
flag. Since there is no link on creation should the program which
created the file then release the handle on that file the filesystem
would see it has no references and remove it. To keep the temporary
file around the program must explicitly create a link.</p>
<h3 id="permissions">permissions</h3>
<p>File permissions are a security mechanism and apply to all files and
directories. They, in combination with ownership information, dictate
who is allowed to read, write, and execute a file (as well as some
other niche allowances and behaviors.)</p>
<p>While there are more advanced and complicated forms of permissioning
the traditional POSIX permissions come in the form of 3 sets of 3
permissions (the read, write, and execute.) One set for the individual
user owner of the file, one for the group owner, and one for "others".</p>
<p>Execute in POSIX systems indicates that a regular file is a piece of
software and can be run (like a Windows ".exe" file) and for
directories means you are allowed to list the contents. A directory
can be marked as "read" and not "executable" to allow users to access
content within the directory but not list it in a soft form of
security through obscurity. You must know the path and name of the
file to read it and can not simply search for it.</p>
<h3 id="ownership">ownership</h3>
<p>Each file has 2 owner values. The individual user identifier and the
group identifier. These values are the raw integer value known to the
kernel and not the human readable user name or group name most people
typically use. In fact the kernel has no awareness of the human
readable identifiers. Those are managed entirely by userspace. This is
why if you mount a filesystem on a different system with different
users tools like <code>ls</code> may report different user names or only show
integer values for owners because the value stored in the inode is
"1000" and the name associated with integer 1000 on system A is
different from system B (or may not exist at all.)</p>
<h3 id="timestamps">timestamps</h3>
<ul>
<li>mtime: The time the file <em>data</em> was last modified. Can be explicitly modified.</li>
<li>ctime: The time the file <em>metadata</em> was last modified. Can not be modified.</li>
<li>atime: The time the file was last accessed. Note that Linux
generally uses a heuristic to update atime so that it does not in
fact have to write to the filesystem every time a file is
accessed. Can be explicitly modified.</li>
<li>btime: The "birth" time of the file. Only available in certain
filesystems and via a newer system call. Can not be modified.</li>
</ul>
<h2 id="functions">Functions</h2>
<ul>
<li>open():</li>
<li>creat():</li>
<li>close():</li>
<li>opendir():</li>
<li>readdir():</li>
<li>closedir():</li>
<li>mkdir():</li>
<li>link():</li>
<li>unlink():</li>
<li>symlink():</li>
<li>rename():</li>
<li>read():</li>
<li>write():</li>
<li>lseek():</li>
<li>tell():</li>
<li>stat():</li>
</ul>
<h2 id="workflows">Workflows</h2>
<p>Filesystems tend to be
<a href="../faq/technical_behavior_and_limitations/#how-does-mergerfs-handle-moving-and-copying-of-files">misunderstood</a>. A
number of behaviors users are familiar with are actually high level
concepts which are made up of numerous steps/functions. As a result
high level context that users expect to be available to mergerfs when
certain actions are taken and decisions made are in fact not
available. Below are explanations of a number of those situations.</p>
<h3 id="creating-a-file">Creating a file</h3>
<p><a href="https://www.man7.org/linux/man-pages/man3/creat.3p.html">Creating</a> a
file can range from a single call to a semi-complex procedure
depending on the requirements and expectations of the calling
application.</p>
<p>Most important to understand is that when a file is created there is
very limited information needed / provided. The file path, some flags
to control a bit how the file is created and if it is to be for
reading and/or writing, and the permissions. mergerfs knows a bit more
details like which user id is making the request and from what process
but that is all the data immediately available. There is no size. The
initial size is always zero. Any data that may be written to the file
would come in the future via other function calls. The source of that
data is completely unknown.</p>
<p>Keep in mind that while there exists this ability to create a file in
a single call to the operating system that call has numerous
aspects which my be exploitable by malicious software.</p>
<p>If software wishes to create a file in more secure manner it must do
some form of the following.</p>
<ol>
<li>Attempt to open the directory where you wish to create the file.</li>
<li>If that succeeds check the directory to ensure it is the directory
you expect it to be. Checking ownership, permissions, perhaps
existence of other files, the filesystem, etc.</li>
<li>Using the handle to the directory, attempt to open the file using a
flag which make the open fail should a file name/link already exist
with that same name. Also set the permissions to the absolute minimum
possible to ensure no interference from others.</li>
<li>If it succeeds then continue on with whatever you had planned. If
it fails try to unlink the unexpected file and try again at step 3. If
it fails multiple times then something is suspicious and the program
should stop trying to create the file and report an error.</li>
</ol>
<p>The above can be made even more involved as you will see below.</p>
<h3 id="reading-or-writing-to-a-file">Reading or writing to a file</h3>
<p>To write:</p>
<ol>
<li>Assuming the file is already created/opened...</li>
<li>Allocate memory to hold a portion of the data.</li>
<li>Fill the memory with the data to write from wherever it may come
from. Another file, network, programmatically generated, etc.</li>
<li>Call <code>write()</code> function on the open file pointing to the memory to
write and how much to write.</li>
<li>The kernel will take the request and attempt it. On success it will
report back to the program how much was written from 1 byte to the
amount requested. A write of fewer than the requested amount is
called a <code>short write.</code></li>
<li>If a short write occurred the program must then adjust the data to
ensure it doesn't write the same data again and lower the amount to
write by the previously written amount and attempt another
write. Continuing this till there is nothing left to write. A short
write could also mean that the filesystem has no more available
space and following write requests may fail completely.</li>
<li>Go back to step 2 or 3 and do it all again with any additional data
to write.</li>
<li>If at any time there is an error it may be necessary to query the
size of the file or other details to know how to continue depending
on the needs of the program.</li>
</ol>
<p>Reading is similar and <code>short reads</code> are also possible.</p>
<h3 id="copying-a-file">Copying a file</h3>
<p>The "proper" way to copy a file is quite involved.</p>
<ol>
<li>Open the source file. Do so with certain flags to ensure it is the
type of file you expect. You may also need to perform a similar
"open directory, check things out, then open file" workflow as
mentioned above for security purposes.</li>
<li><code>stat</code> the file to get its metadata such as the file size,
timestamps, etc.</li>
<li>Securely open a file as described previously. The name of the file
should not be that of the destination but a temporary file name
with some amount of randomness. Often also making it "hidden" by
prepending a "." to it.</li>
<li>In a loop read data from the source file and write it to the
temporary file as described above. There are some platform specific
ways to copy the data which may be tried first such as
FICLONE/reflink which takes advantage of CoW (copy-on-write)
filesystem features. Falling back to the read then write loop if
necessary.</li>
<li>Request a list of all the extended attribute keys from the source
file and one by one query the value. For each key value pair
attempt to write it to the destination file.</li>
<li>Request file attributes from the source file and write them to the
destination file but first filtering out flags such as "immutable"
as that would make it impossible to make further changes.</li>
<li>Using the details captured in step 2 change the ownership to the
destination file to match the source.</li>
<li>Using the details captured in step 2 change the permissions (mode)
of the destination file to match the source.</li>
<li>Using the details captured in step 2 change the mtime and atime of
the destination to match the source.</li>
<li>Query the source file's metadata again as in step 2. Using those
details as well as those from step 2 check the source file to see
if it may have changed since the copy procedure started. If it had
determine the changes and go back to step 4. Perhaps unlinking the
temporary file and going back to step 2.</li>
<li>Ensure the data and metadata are flushed to the storage device by
calling appropriate sync functions.</li>
<li><code>rename</code> the file from the temporary name to the destination name.</li>
<li>If the file had a special flag such as the immutable attribute set
then set such attribute.</li>
<li>Close the destination and source files.</li>
</ol>
<p>There can be additional steps too depending on the platform, available
features, and safety concerns. For instance it might be possible to
put a lock or lease on the source file to limit possibility of
changes while the copy occurs.</p>
<h3 id="moving-a-file">Moving a file</h3>
<p>The moving of a file is similar to copying a file.</p>
<ol>
<li>Attempt a <code>rename</code> between source and destination. If it succeeds,
done. Note that the rename itself may require setup similar to
securely opening or creating a file. IE... requiring the opening of
the source and destination directories, confirming they are what is
expected, then issuing the actual rename.</li>
<li>If it fails... perform a copy of the file as described above.</li>
<li>After the rename and close'ing of the copy <code>unlink</code> the source
file.</li>
</ol>
<h3 id="summary">Summary</h3>
<p>As seen in the above descriptions these high level concepts users
perceive are in fact involved sets of steps with loops and conditional
behaviors. All leveraging low level functions which alone have very
little context. For instance: there is no practical way of knowing a
file is being copied or from where. There is no way to decide at
creation time what to do based on size because its size doesn't exist
yet. Even making a decision based on the destination file name is
complicated by the fact that "well written" software will create
randomly named temporary files and then rename the file. Only at
<code>rename</code> would you know the name as the end user chose and at that
point it may be too late.</p>
</article>
</div>
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
</div>
<button type="button" class="md-top md-icon" data-md-component="top" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8z"/></svg>
Back to top
</button>
</main>
<footer class="md-footer">
<nav class="md-footer__inner md-grid" aria-label="Footer" >
<a href="../terminology/" class="md-footer__link md-footer__link--prev" aria-label="Previous: Terminology">
<div class="md-footer__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
</div>
<div class="md-footer__title">
<span class="md-footer__direction">
Previous
</span>
<div class="md-ellipsis">
Terminology
</div>
</div>
</a>
<a href="../config/options/" class="md-footer__link md-footer__link--next" aria-label="Next: Options">
<div class="md-footer__title">
<span class="md-footer__direction">
Next
</span>
<div class="md-ellipsis">
Options
</div>
</div>
<div class="md-footer__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4 11v2h12l-5.5 5.5 1.42 1.42L19.84 12l-7.92-7.92L10.5 5.5 16 11z"/></svg>
</div>
</a>
</nav>
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-copyright">
Made with
<a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
Material for MkDocs
</a>
</div>
</div>
</div>
</footer>
</div>
<div class="md-dialog" data-md-component="dialog">
<div class="md-dialog__inner md-typeset"></div>
</div>
<script id="__config" type="application/json">{"base": "..", "features": ["content.action.edit", "content.action.view", "content.code.copy", "content.code.select", "navigation.footer", "navigation.instant", "navigation.instant.prefetch", "navigation.path", "navigation.top", "navigation.tracking", "optimize", "search.share", "search.suggest", "toc.follow"], "search": "../assets/javascripts/workers/search.973d3a69.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": {"provider": "mike"}}</script>
<script src="../assets/javascripts/bundle.92b07e13.min.js"></script>
</body>
</html>