Skip to content

find.flexfs

find.flexfs provides fast filesystem search by querying the metadata server directly, bypassing the FUSE layer. It supports filters on inode attributes, timestamps, size, cost, permissions, and file type.

These flags apply to every subcommand.

FlagTypeDefaultDescriptionVisibility
--reportErrorsboolfalseReport errors and panics to Paradigm4Public
SubcommandDescriptionVisibility
deinit credsRemove the credentials for a volumePublic
init credsStore the credentials for a volumePublic
licensePrint license informationPublic
versionPrint the build versionPublic

The root command searches the volume with the filters below.

Terminal window
find.flexfs [flags] [path...]

If no path is specified, the current directory is used. Run it from within a flexFS mount, or name an unmounted volume with --volume.

A path argument whose name matches a subcommand, such as a directory called init, is taken as the subcommand. Separate it with -- to search the directory instead:

Terminal window
# Runs the init subcommand
find.flexfs init
# Searches the directory named init
find.flexfs -- init
FlagTypeDefaultDescriptionVisibility
--fieldsstring slicepathOutput fields (comma-separated). Use all for all fields.Public
--headerboolfalseInclude header row in outputPublic
--limituint640Maximum number of results (0 = unlimited)Public
--noDecodeboolfalsePrint base32-encoded pathsPublic
--outputFile, -ostring""Output file path. With multiple search paths, all results go to this one file, with a single header row.Public

Results are written to standard output (or the --outputFile file); error messages are written to standard error. This means you can safely pipe results into other commands without error text mixing into the data.

Available fields: path, ino, mode, type, perm, blocks, size, size_bin, cost, nlink, uid, gid, ctime, mtime, atime, btime, xattrs.

The cost field is an estimated monthly storage cost in US dollars ($/month). See the analyze.flexfs cost field documentation for how it is calculated, and for what happens when the rates behind it cannot be fetched.

The xattrs field emits an inode’s extended attributes as a JSON object. See Xattrs field below.

FlagTypeDefaultDescriptionVisibility
--adminAddrstring""Admin server address. Only needed to override the one stored in the credentials, or alongside --token when there are none.Internal
--credsFilestring~/.flexfs/util/creds/<name>Credentials file pathPublic
--mountPathstring""Client mount path. Only needed when querying an unmounted volume whose search path passes through symbolic links with absolute targets (e.g. /mnt/flexfs/data); when run from inside a mount, this is detected automatically.Public
--noAdminSSLboolfalseDisable SSL for admin server connectionsInternal
--noMetaSSLboolfalseDisable SSL for metadata server connectionsInternal
--tokenstring""Volume token to use, instead of reading one from a credentials fileInternal
--volumestring""Volume name, to query a volume that is not mounted here. Selects the credentials file.Public

Search paths may pass through symbolic links. Links that stay within the volume are followed automatically, including a link as the final path component — find.flexfs /mnt/flexfs/current/logs works even when current is a link to a release directory. A link whose target points outside the volume cannot be searched and returns an error that names the link.

FlagTypeDefaultDescriptionVisibility
--emptyboolfalseFilter for empty files or directoriesPublic
--giduint320Filter by group IDPublic
--inouint640Filter by inode numberPublic
--namestring""Filter by dentry name (supports glob patterns)Public
--permstring0Required permission bits (octal, with or without a leading 0755 and 0755 mean the same thing; max 07777). Matches when (mode & permMask) == perm.Public
--permMaskstring0777Bits of the file mode to test (octal, with or without a leading 0; max 07777). The default tests owner/group/other. Set to 7777 to also test setuid/setgid/sticky.Public
--sparseboolfalseFilter for sparse filesPublic
--typestring""Filter by inode type: b, c, d, f, l, p, sPublic
--uiduint320Filter by user IDPublic
FlagTypeDefaultDescriptionVisibility
--maxBlocksuint640Maximum blocks filter (regular files only)Public
--maxCostfloat640Maximum estimated cost filter ($/month, regular files only)Public
--maxNlinkuint320Maximum hard link count filterPublic
--maxSizestring0Maximum byte size filter (regular files only), given as a size (10M, 1G) or bytes (1048576).Public
--maxSizeBinuint320Maximum size bin filter (regular files only, 0-127)Public
--minBlocksuint640Minimum blocks filter (regular files only)Public
--minCostfloat640Minimum estimated cost filter ($/month, regular files only)Public
--minNlinkuint320Minimum hard link count filterPublic
--minSizestring0Minimum byte size filter (regular files only), given as a size (10M, 1G) or bytes (1048576).Public
--minSizeBinuint320Minimum size bin filter (regular files only, 0-127)Public

Timestamp values are given as an RFC3339 time (2026-01-02T15:04:05Z) or seconds since epoch (Unix time).

FlagTypeDefaultDescriptionVisibility
--maxAtimestring0Maximum access timePublic
--maxBtimestring0Maximum birth timePublic
--maxCtimestring0Maximum change timePublic
--maxMtimestring0Maximum modification timePublic
--minAtimestring0Minimum access timePublic
--minBtimestring0Minimum birth timePublic
--minCtimestring0Minimum change timePublic
--minMtimestring0Minimum modification timePublic
FlagTypeDefaultDescriptionVisibility
--maxDepthuint320Maximum query depth (0 = unlimited)Public
--minDepthuint320Minimum query depthPublic

Find all files larger than 1 GiB:

Terminal window
find.flexfs --minSize 1G --type f /mnt/flexfs

Find files by name pattern with full metadata:

Terminal window
find.flexfs --name "*.bam" --fields all --header /mnt/flexfs/data

Find empty directories (candidates for cleanup):

Terminal window
find.flexfs --type d --empty /mnt/flexfs

Find all symlinks under a path:

Terminal window
find.flexfs --type l --fields path,size /mnt/flexfs/data

Find the most expensive files (costing more than $1/month):

Terminal window
find.flexfs --minCost 1 --type f --fields path,size,cost --header /mnt/flexfs

Find cold files (not accessed in over 6 months, size bin 6+) that are still large:

Terminal window
find.flexfs --minSizeBin 6 --minSize 1G --type f \
--fields path,size,size_bin,cost --header /mnt/flexfs

Find files not accessed since January 1 2025 (stale data candidates):

Terminal window
find.flexfs --maxAtime 2025-01-01T00:00:00Z --type f /mnt/flexfs

Find files modified in a specific window (e.g. during an incident):

Terminal window
find.flexfs --minMtime 2025-03-15T00:00:00Z --maxMtime 2025-03-16T00:00:00Z --type f \
--fields path,size,mtime --header /mnt/flexfs

Find files created in the last 7 days:

Terminal window
# --minBtime accepts either an RFC3339 time or seconds since epoch:
find.flexfs --minBtime "$(date -u -d '7 days ago' +%Y-%m-%dT%H:%M:%SZ)" --type f /mnt/flexfs
find.flexfs --minBtime "$(date -d '7 days ago' +%s)" --type f /mnt/flexfs

Find files with exact permissions rwxrwxrwx:

Terminal window
find.flexfs --perm 777 --type f --fields path,perm /mnt/flexfs

Find world-writable files (other-write bit set):

Terminal window
find.flexfs --perm 2 --permMask 2 --type f --fields path,perm /mnt/flexfs

Find files with the setuid bit set:

Terminal window
find.flexfs --perm 4000 --permMask 4000 --type f --fields path,perm /mnt/flexfs

Find all files owned by a specific user:

Terminal window
find.flexfs --uid 1001 --type f --fields path,size,uid /mnt/flexfs

Find sparse files (logical size exceeds allocated blocks):

Terminal window
find.flexfs --sparse --type f --fields path,size,blocks /mnt/flexfs

Export a full file inventory to TSV:

Terminal window
find.flexfs --fields all --header --type f \
--outputFile /tmp/inventory.tsv /mnt/flexfs

Query a volume directly without a local mount:

Terminal window
find.flexfs --volume <volume-name> --type d /

Output is tab-separated. The columns correspond to the --fields list. When --header is set, the first line contains field names.

The xattrs field emits all of an inode’s extended attributes as a single JSON object, occupying one tab-separated column:

{"user.department":"cmVzZWFyY2g=","user.project":"Z2Vub21pY3M="}
  • Keys are attribute names, including the namespace prefix, exactly as stored. Names settable with setfattr live in the user., trusted., and security. namespaces; system. and flexfs. also appear, holding attributes flexFS maintains on your behalf (see below).
  • Values are base64-encoded (standard alphabet, with padding). Extended attribute values are arbitrary binary data, so they are never emitted raw. Decode with base64 -d; in the example above the values are the strings research and genomics.
  • Keys are sorted lexicographically, so the object is byte-for-byte stable across runs for a given inode.
  • An inode with no extended attributes emits {}, not an empty column.
  • The object is always one line and always tab-free: base64 values cannot contain a tab or newline, and JSON escapes both characters if an attribute name contains them. An xattrs column therefore never breaks the tab-separated row structure.
  • There are no filter flags for extended attributes. xattrs is an output field only — filter the results downstream (see the examples below).

Everything stored on the inode appears, including attributes flexFS maintains itself. Beyond whatever your applications set under user., expect to see:

AttributeWritten byContents
system.posix_acl_accessACLs (--acl)Packed POSIX ACL structure for the inode’s access ACL
system.posix_acl_defaultACLs (--acl)Packed POSIX ACL structure inherited by new children of a directory
security.capabilitysetcapFile capability set. Stripped automatically on write, so it may disappear between runs.
flexfs.iflagschattrThe immutable and append-only inode flags set with chattr. Present even on volumes mounted without --xattr, and removed entirely once every flag is cleared.

Setting and reading extended attributes through a mount requires --xattr, but that option gates the FUSE layer only. find.flexfs queries the metadata server, so it reports stored attributes regardless of how any mount is currently configured — including attributes written earlier on a volume now mounted without --xattr.

find.flexfs queries the metadata server directly and reads the stored form of each attribute. On a volume using metadata encryption, encryption and decryption happen only in the mount client, so attribute names and values reach find.flexfs as ciphertext:

{"5LJ0aBv...=":"n4Kc2Rv1Zt8..."}

The name is base64 of the AES-256-GCM ciphertext of the name; the value is base64 of the AES-256-GCM ciphertext of the value. Neither is recoverable from find.flexfs output. Reading extended attributes in plaintext on an encrypted volume requires going through a mount — getfattr on the mounted path. Note that --noDecode is unrelated: it governs base32 path encoding only and has no effect on the xattrs column.

List every file that carries any extended attribute:

Terminal window
find.flexfs --type f --fields path,xattrs /mnt/flexfs | awk -F'\t' '$2 != "{}"'

Report a specific attribute in plaintext, one file per line:

Terminal window
find.flexfs --type f --fields path,xattrs /mnt/flexfs \
| jq -Rr 'split("\t") | (.[1] | fromjson)["user.project"] as $v
| select($v != null) | .[0] + "\t" + ($v | @base64d)'

Find files carrying a POSIX ACL:

Terminal window
find.flexfs --type f --fields path,perm,xattrs /mnt/flexfs \
| grep 'system.posix_acl_access'

Store the volume token find.flexfs uses for a volume.

Terminal window
find.flexfs init creds --adminAddr <admin-host:port> [flags]

The token is prompted for unless --token is given. The volume’s name is taken from the admin server, so the credentials are always filed under the name a mount reports, and the token is checked for the admin flag before anything is written.

FlagTypeDefaultDescriptionVisibility
--adminAddrstring""Admin server address (required)Public
--credsFilestring~/.flexfs/util/creds/<name>Credentials file pathPublic
--forceboolfalseOverwrite existing credentials filePublic
--noAdminSSLboolfalseDisable SSL for admin server connectionsInternal
--tokenstring""Volume token (prompted for if omitted)Public
--volumestring""Volume name, checked against the tokenPublic

init on its own does the same thing as init creds.

find.flexfs queries the metadata server, which requires a volume token carrying the admin flag. Store one per volume:

Terminal window
find.flexfs init creds --adminAddr admin.example.com:443

The command prompts for the token, confirms with the admin server that it allows reporting queries, and files it under the volume’s name. See Volume Tokens for how to obtain one.

Credentials are looked for in this order:

  1. ~/.flexfs/util/creds/<volume-name>, written by find.flexfs init creds.
  2. ~/.flexfs/mount/creds/<volume-name>, written by mount.flexfs init creds for the same user.

analyze.flexfs, dedup.flexfs and find.flexfs share the first of these, so one init creds serves all three — and one deinit creds removes the credentials all three were using.

Both files must be readable only by their owner (chmod 600); a file readable by others is refused.

--credsFile moves the first of these. Give the same value to init creds and to the query, or credentials will be written somewhere the query does not look — and to the other two utilities as well, if they are to go on sharing one file.

Each user needs their own credentials. A mount created by root keeps its credentials under /root, which other users cannot read, so give each person who runs reporting queries a token of their own.

A volume token can be issued for one subdirectory of a volume rather than the whole of it (see Volume Tokens). Every query made with such a token is answered from that subdirectory, whichever part of the volume the mount itself shows.

find.flexfs accounts for the difference, so paths are always given the way they look on this machine. With a volume mounted whole at /flexfs-1 and a token scoped to /sub-1:

Terminal window
find.flexfs /flexfs-1/sub-1 # the token's whole subtree
find.flexfs /flexfs-1/sub-1/data # part of it
find.flexfs /flexfs-1 # refused: outside the token's subtree

The first of those is the same query as find.flexfs --volume <name> /, which names the path as the token sees it because no mount is involved to interpret it against.

To make the adjustment, find.flexfs asks the admin server what the token is scoped to — once per volume, on every run. Nothing about the token is cached on disk, so a token that is reissued or re-scoped needs no re-initialization, and a token passed with --token is treated exactly like a stored one. The admin server must therefore be reachable for a query made inside a mount.

Remove the credentials for a volume.

Terminal window
find.flexfs deinit creds <volume-name>

Removing credentials that are not there succeeds, so this is safe to run twice.

FlagTypeDefaultDescriptionVisibility
--credsFilestring~/.flexfs/util/creds/<name>Credentials file pathPublic