summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2021-11-16 10:27:21 +0100
committerGitHub <noreply@github.com>2021-11-16 10:27:21 +0100
commit7ee587afe388dc99c936159ccadddd77c1746efe (patch)
tree06bc16a1a3986b71f3b6c87059a8ed132e0b8a97
parent947796eac385651f6a66fc0ce925a301b49f6fa4 (diff)
parentad004abe9d9f71fc74db26ad29ea8ab6a84599ee (diff)
downloadsystemd-7ee587afe388dc99c936159ccadddd77c1746efe.tar.gz
Merge pull request #21373 from poettering/filesystems-more-groups
some file system tables/magic love
-rw-r--r--src/analyze/analyze.c64
-rw-r--r--src/basic/filesystems-gperf.gperf21
-rw-r--r--src/basic/filesystems.c50
-rw-r--r--src/basic/filesystems.h4
-rwxr-xr-xsrc/basic/generate-filesystem-list.py3
-rwxr-xr-xsrc/basic/generate-filesystem-switch-case.py63
-rw-r--r--src/basic/meson.build16
-rw-r--r--src/basic/missing_magic.h15
-rw-r--r--src/basic/mountpoint-util.c3
-rw-r--r--src/home/homed-home.c16
-rw-r--r--src/home/homework.c10
11 files changed, 229 insertions, 36 deletions
diff --git a/src/analyze/analyze.c b/src/analyze/analyze.c
index d4c73ab86a..3801cf0ead 100644
--- a/src/analyze/analyze.c
+++ b/src/analyze/analyze.c
@@ -1850,8 +1850,9 @@ static void filesystem_set_remove(Set *s, const FilesystemSet *set) {
}
}
-static void dump_filesystem(const FilesystemSet *set) {
+static void dump_filesystem_set(const FilesystemSet *set) {
const char *filesystem;
+ int r;
if (!set)
return;
@@ -1863,8 +1864,38 @@ static void dump_filesystem(const FilesystemSet *set) {
ansi_normal(),
set->help);
- NULSTR_FOREACH(filesystem, set->value)
- printf(" %s%s%s\n", filesystem[0] == '@' ? ansi_underline() : "", filesystem, ansi_normal());
+ NULSTR_FOREACH(filesystem, set->value) {
+ const statfs_f_type_t *magic;
+
+ if (filesystem[0] == '@') {
+ printf(" %s%s%s\n", ansi_underline(), filesystem, ansi_normal());
+ continue;
+ }
+
+ r = fs_type_from_string(filesystem, &magic);
+ assert_se(r >= 0);
+
+ printf(" %s", filesystem);
+
+ for (size_t i = 0; magic[i] != 0; i++) {
+ const char *primary;
+ if (i == 0)
+ printf(" %s(magic: ", ansi_grey());
+ else
+ printf(", ");
+
+ printf("0x%llx", (unsigned long long) magic[i]);
+
+ primary = fs_type_to_string(magic[i]);
+ if (primary && !streq(primary, filesystem))
+ printf("[%s]", primary);
+
+ if (magic[i+1] == 0)
+ printf(")%s", ansi_normal());
+ }
+
+ printf("\n");
+ }
}
static int dump_filesystems(int argc, char *argv[], void *userdata) {
@@ -1892,7 +1923,7 @@ static int dump_filesystems(int argc, char *argv[], void *userdata) {
if (!first)
puts("");
- dump_filesystem(set);
+ dump_filesystem_set(set);
filesystem_set_remove(kernel, set);
if (i != FILESYSTEM_SET_KNOWN)
filesystem_set_remove(known, set);
@@ -1913,8 +1944,29 @@ static int dump_filesystems(int argc, char *argv[], void *userdata) {
strv_sort(l);
- STRV_FOREACH(filesystem, l)
+ STRV_FOREACH(filesystem, l) {
+ const statfs_f_type_t *magic;
+ bool is_primary = false;
+
+ assert(fs_type_from_string(*filesystem, &magic) >= 0);
+
+ for (size_t i = 0; magic[i] != 0; i++) {
+ const char *primary;
+
+ primary = fs_type_to_string(magic[i]);
+ assert(primary);
+
+ if (streq(primary, *filesystem))
+ is_primary = true;
+ }
+
+ if (!is_primary) {
+ log_debug("Skipping ungrouped file system '%s', because it's an alias for another one.", *filesystem);
+ continue;
+ }
+
printf("# %s\n", *filesystem);
+ }
}
if (k < 0) {
@@ -1956,7 +2008,7 @@ static int dump_filesystems(int argc, char *argv[], void *userdata) {
"Filesystem set \"%s\" not found.", *name);
}
- dump_filesystem(set);
+ dump_filesystem_set(set);
first = false;
}
}
diff --git a/src/basic/filesystems-gperf.gperf b/src/basic/filesystems-gperf.gperf
index f31c9de192..7dd660addf 100644
--- a/src/basic/filesystems-gperf.gperf
+++ b/src/basic/filesystems-gperf.gperf
@@ -34,8 +34,11 @@ binfmt_misc, {BINFMTFS_MAGIC}
bpf, {BPF_FS_MAGIC}
btrfs, {BTRFS_SUPER_MAGIC}
btrfs_test_fs, {BTRFS_TEST_MAGIC}
+# cpuset's magic got reassigned to cgroupfs
+cpuset, {CGROUP_SUPER_MAGIC}
ceph, {CEPH_SUPER_MAGIC}
cgroup2, {CGROUP2_SUPER_MAGIC}
+# note that the cgroupfs magic got reassigned from cpuset
cgroup, {CGROUP_SUPER_MAGIC}
cifs, {CIFS_MAGIC_NUMBER}
coda, {CODA_SUPER_MAGIC}
@@ -45,19 +48,24 @@ dax, {DAXFS_MAGIC}
debugfs, {DEBUGFS_MAGIC}
devmem, {DEVMEM_MAGIC}
devpts, {DEVPTS_SUPER_MAGIC}
+# devtmpfs is just a special instance of tmpfs, hence it reports its magic
+devtmpfs, {TMPFS_MAGIC}
dmabuf, {DMA_BUF_MAGIC}
ecryptfs, {ECRYPTFS_SUPER_MAGIC}
efivarfs, {EFIVARFS_MAGIC}
efs, {EFS_SUPER_MAGIC}
erofs, {EROFS_SUPER_MAGIC_V1}
+# ext2 + ext3 + ext4 use the same magic
ext2, {EXT2_SUPER_MAGIC}
ext3, {EXT3_SUPER_MAGIC}
ext4, {EXT4_SUPER_MAGIC}
exfat, {EXFAT_SUPER_MAGIC}
f2fs, {F2FS_SUPER_MAGIC}
+# fuseblk is so closely related to fuse that it shares the same magic
fuseblk, {FUSE_SUPER_MAGIC}
fuse, {FUSE_SUPER_MAGIC}
fusectl, {FUSE_CTL_SUPER_MAGIC}
+# gfs is an old version of gfs2 and reuses the magic
gfs, {GFS2_MAGIC}
gfs2, {GFS2_MAGIC}
hostfs, {HOSTFS_SUPER_MAGIC}
@@ -67,13 +75,18 @@ iso9660, {ISOFS_SUPER_MAGIC}
jffs2, {JFFS2_SUPER_MAGIC}
minix, {MINIX_SUPER_MAGIC, MINIX_SUPER_MAGIC2, MINIX2_SUPER_MAGIC, MINIX2_SUPER_MAGIC2, MINIX3_SUPER_MAGIC}
mqueue, {MQUEUE_MAGIC}
+# msdos is an older legacy version of vfat, shares the magic
msdos, {MSDOS_SUPER_MAGIC}
+# ncp/ncpfs have been removed from the kernel, but ncpfs was the offical name
ncp, {NCP_SUPER_MAGIC}
ncpfs, {NCP_SUPER_MAGIC}
+# nfs is the old version of nfs4, and they share the same magic
nfs, {NFS_SUPER_MAGIC}
nfs4, {NFS_SUPER_MAGIC}
nilfs2, {NILFS_SUPER_MAGIC}
nsfs, {NSFS_MAGIC}
+ntfs, {NTFS_SB_MAGIC}
+ntfs3, {NTFS3_SUPER_MAGIC}
ocfs2, {OCFS2_SUPER_MAGIC}
openpromfs, {OPENPROM_SUPER_MAGIC}
orangefs, {ORANGEFS_DEVREQ_MAGIC}
@@ -82,27 +95,33 @@ pipefs, {PIPEFS_MAGIC}
ppc-cmm, {PPC_CMM_MAGIC}
proc, {PROC_SUPER_MAGIC}
pstore, {PSTOREFS_MAGIC}
+# pvfs2 is the old version of orangefs
pvfs2, {ORANGEFS_DEVREQ_MAGIC}
qnx4, {QNX4_SUPER_MAGIC}
qnx6, {QNX6_SUPER_MAGIC}
ramfs, {RAMFS_MAGIC}
resctrl, {RDTGROUP_SUPER_MAGIC}
reiserfs, {REISERFS_SUPER_MAGIC}
+rpc_pipefs, {RPC_PIPEFS_SUPER_MAGIC}
secretmem, {SECRETMEM_MAGIC}
securityfs, {SECURITYFS_MAGIC}
selinuxfs, {SELINUX_MAGIC}
shiftfs, {SHIFTFS_MAGIC}
smackfs, {SMACK_MAGIC}
-smb3, {SMB_SUPER_MAGIC}
+# smb3 is an alias for cifs
+smb3, {CIFS_MAGIC_NUMBER}
+# smbfs was removed from the kernel in 2010, the magic remains
smbfs, {SMB_SUPER_MAGIC}
sockfs, {SOCKFS_MAGIC}
squashfs, {SQUASHFS_MAGIC}
sysfs, {SYSFS_MAGIC}
+# note that devtmpfs shares the same magic with tmpfs, given it is just a special named instance of it.
tmpfs, {TMPFS_MAGIC}
tracefs, {TRACEFS_MAGIC}
udf, {UDF_SUPER_MAGIC}
usbdevfs, {USBDEVICE_SUPER_MAGIC}
vboxsf, {VBOXSF_SUPER_MAGIC}
+# note that msdos shares the same magic (and is the older version)
vfat, {MSDOS_SUPER_MAGIC}
v9fs, {V9FS_MAGIC}
xenfs, {XENFS_SUPER_MAGIC}
diff --git a/src/basic/filesystems.c b/src/basic/filesystems.c
index 9fccea2018..0f71f8e07c 100644
--- a/src/basic/filesystems.c
+++ b/src/basic/filesystems.c
@@ -1,6 +1,17 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "filesystems-gperf.h"
+#include "stat-util.h"
+
+const char *fs_type_to_string(statfs_f_type_t magic) {
+
+ switch (magic) {
+#include "filesystem-switch-case.h"
+ }
+
+ return NULL;
+}
+
int fs_type_from_string(const char *name, const statfs_f_type_t **ret) {
const struct FilesystemMagic *fs_magic;
@@ -13,7 +24,6 @@ int fs_type_from_string(const char *name, const statfs_f_type_t **ret) {
return -EINVAL;
*ret = fs_magic->magic;
-
return 0;
}
@@ -47,18 +57,37 @@ const FilesystemSet filesystem_sets[_FILESYSTEM_SET_MAX] = {
"cgroup\0"
"cgroup2\0"
"devpts\0"
+ "devtmpfs\0"
"mqueue\0"
"proc\0"
"sysfs\0"
},
+ [FILESYSTEM_SET_ANONYMOUS] = {
+ .name = "@anonymous",
+ .help = "Anonymous inodes",
+ .value =
+ "anon_inodefs\0"
+ "pipefs\0"
+ "sockfs\0"
+ },
+ [FILESYSTEM_SET_APPLICATION] = {
+ .name = "@application",
+ .help = "Application virtual filesystems",
+ .value =
+ "autofs\0"
+ "fuse\0"
+ "overlay\0"
+ },
[FILESYSTEM_SET_AUXILIARY_API] = {
.name = "@auxiliary-api",
.help = "Auxiliary filesystem API",
.value =
+ "binfmt_misc\0"
"configfs\0"
"efivarfs\0"
"fusectl\0"
"hugetlbfs\0"
+ "rpc_pipefs\0"
"securityfs\0"
},
[FILESYSTEM_SET_COMMON_BLOCK] = {
@@ -66,7 +95,14 @@ const FilesystemSet filesystem_sets[_FILESYSTEM_SET_MAX] = {
.help = "Common block device filesystems",
.value =
"btrfs\0"
+ "erofs\0"
+ "exfat\0"
"ext4\0"
+ "f2fs\0"
+ "iso9660\0"
+ "ntfs3\0"
+ "squashfs\0"
+ "udf\0"
"vfat\0"
"xfs\0"
},
@@ -83,14 +119,16 @@ const FilesystemSet filesystem_sets[_FILESYSTEM_SET_MAX] = {
.help = "Well-known network filesystems",
.value =
"afs\0"
+ "ceph\0"
"cifs\0"
"gfs\0"
"gfs2\0"
- "ncpfs\0"
"ncp\0"
+ "ncpfs\0"
"nfs\0"
"nfs4\0"
"ocfs2\0"
+ "orangefs\0"
"pvfs2\0"
"smb3\0"
"smbfs\0"
@@ -104,6 +142,14 @@ const FilesystemSet filesystem_sets[_FILESYSTEM_SET_MAX] = {
"pstore\0"
"tracefs\0"
},
+ [FILESYSTEM_SET_SECURITY] = {
+ .name = "@security",
+ .help = "Security/MAC API VFS",
+ .value =
+ "apparmorfs\0"
+ "selinuxfs\0"
+ "smackfs\0"
+ },
[FILESYSTEM_SET_TEMPORARY] = {
.name = "@temporary",
.help = "Temporary filesystems",
diff --git a/src/basic/filesystems.h b/src/basic/filesystems.h
index a0964476af..6d07a97ba7 100644
--- a/src/basic/filesystems.h
+++ b/src/basic/filesystems.h
@@ -10,11 +10,14 @@
typedef enum FilesystemGroups {
/* Please leave BASIC_API first and KNOWN last, but sort the rest alphabetically */
FILESYSTEM_SET_BASIC_API,
+ FILESYSTEM_SET_ANONYMOUS,
+ FILESYSTEM_SET_APPLICATION,
FILESYSTEM_SET_AUXILIARY_API,
FILESYSTEM_SET_COMMON_BLOCK,
FILESYSTEM_SET_HISTORICAL_BLOCK,
FILESYSTEM_SET_NETWORK,
FILESYSTEM_SET_PRIVILEGED_API,
+ FILESYSTEM_SET_SECURITY,
FILESYSTEM_SET_TEMPORARY,
FILESYSTEM_SET_KNOWN,
_FILESYSTEM_SET_MAX,
@@ -31,6 +34,7 @@ extern const FilesystemSet filesystem_sets[];
const FilesystemSet *filesystem_set_find(const char *name);
+const char *fs_type_to_string(statfs_f_type_t magic);
int fs_type_from_string(const char *name, const statfs_f_type_t **ret);
int fs_in_group(const struct statfs *s, enum FilesystemGroups fs_group);
diff --git a/src/basic/generate-filesystem-list.py b/src/basic/generate-filesystem-list.py
index 8271b3fbeb..52b74f1763 100755
--- a/src/basic/generate-filesystem-list.py
+++ b/src/basic/generate-filesystem-list.py
@@ -6,6 +6,9 @@ import sys
keywords_section = False
for line in open(sys.argv[1]):
+ if line[0] == '#':
+ continue
+
if keywords_section:
print('"{}\\0"'.format(line.split(',')[0].strip()))
elif line.startswith('%%'):
diff --git a/src/basic/generate-filesystem-switch-case.py b/src/basic/generate-filesystem-switch-case.py
new file mode 100755
index 0000000000..73b1d65657
--- /dev/null
+++ b/src/basic/generate-filesystem-switch-case.py
@@ -0,0 +1,63 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
+import sys
+
+
+def filter_fsname(name):
+ # File system magics are sometimes not unique, because file systems got new
+ # revisions or got renamed. Let's prefer newer over older here, and thus
+ # ignore the old names. Specifically:
+ #
+ # → cgroupfs took over the magic of cpuset
+ # → devtmpfs is not a file system of its own, but just a "named superblock" of tmpfs
+ # → ext4 is the newest revision of ext2 + ext3
+ # → fuseblk is closely related to fuse, so close that they share a single magic, but the latter is more common
+ # → gfs2 is the newest revision of gfs
+ # → vfat is the newest revision of msdos
+ # → ncpfs (not ncp) was the last name of the netware `file_system_type` name before it was removed in 2018
+ # → nfs4 is the newest revision of nfs
+ # → orangefs is the new name of pvfs2
+ # → smb3 is an alias for cifs
+
+ return name in (
+ "cpuset",
+ "devtmpfs",
+ "ext2",
+ "ext3",
+ "fuseblk",
+ "gfs",
+ "msdos",
+ "ncp",
+ "nfs",
+ "pvfs2",
+ "smb3",
+ )
+
+
+gperf_file = sys.argv[1]
+keywords_section = False
+
+for line in open(gperf_file):
+ if line[0] == "#":
+ continue
+
+ if keywords_section:
+ name, ids = line.split(",", 1)
+
+ name = name.strip()
+ if filter_fsname(name):
+ continue
+
+ ids = ids.strip()
+ assert ids[0] == "{"
+ assert ids[-1] == "}"
+ ids = ids[1:-1]
+
+ for id in ids.split(","):
+ print(f"case (statfs_f_type_t) {id.strip()}:")
+
+ print(f' return "{name}";')
+
+ if line.startswith("%%"):
+ keywords_section = True
diff --git a/src/basic/meson.build b/src/basic/meson.build
index 042ab86d5e..f0d5a1d2ea 100644
--- a/src/basic/meson.build
+++ b/src/basic/meson.build
@@ -383,8 +383,8 @@ filesystem_includes = ['linux/magic.h',
check_filesystems = find_program('check-filesystems.sh')
r = run_command([check_filesystems, cpp, 'filesystems-gperf.gperf'] + filesystem_includes)
if r.returncode() != 0
- error('found unknown filesystem(s) defined in kernel headers:\n\n' + r.stdout())
- r.stdout()
+ error('found unknown filesystem(s) defined in kernel headers:\n\n' + r.stdout())
+ r.stdout()
endif
filesystems_gperf_h = custom_target(
@@ -403,7 +403,17 @@ filesystem_list_h = custom_target(
'@INPUT@'],
capture : true)
-basic_sources += [filesystem_list_h, filesystems_gperf_h]
+generate_filesystem_switch_case_h = find_program('generate-filesystem-switch-case.py')
+fname = 'filesystem-switch-case.h'
+filesystem_switch_case_h = custom_target(
+ fname,
+ input : 'filesystems-gperf.gperf',
+ output : 'filesystem-switch-case.h',
+ command : [generate_filesystem_switch_case_h,
+ '@INPUT@'],
+ capture : true)
+
+basic_sources += [filesystem_list_h, filesystem_switch_case_h, filesystems_gperf_h]
libbasic = static_library(
'basic',
diff --git a/src/basic/missing_magic.h b/src/basic/missing_magic.h
index 1f50e565a2..7d9320bb6d 100644
--- a/src/basic/missing_magic.h
+++ b/src/basic/missing_magic.h
@@ -172,3 +172,18 @@
#ifndef EXFAT_SUPER_MAGIC
#define EXFAT_SUPER_MAGIC 0x2011BAB0UL
#endif
+
+/* Not exposed yet, internally actually called RPCAUTH_GSSMAGIC. Defined in net/sunrpc/rpc_pipe.c */
+#ifndef RPC_PIPEFS_SUPER_MAGIC
+#define RPC_PIPEFS_SUPER_MAGIC 0x67596969
+#endif
+
+/* Not exposed yet, defined at fs/ntfs/ntfs.h */
+#ifndef NTFS_SB_MAGIC
+#define NTFS_SB_MAGIC 0x5346544e
+#endif
+
+/* Not exposed yet, encoded literally in fs/ntfs3/super.c. */
+#ifndef NTFS3_SUPER_MAGIC
+#define NTFS3_SUPER_MAGIC 0x7366746e
+#endif
diff --git a/src/basic/mountpoint-util.c b/src/basic/mountpoint-util.c
index 803f36da8d..c813a4f56f 100644
--- a/src/basic/mountpoint-util.c
+++ b/src/basic/mountpoint-util.c
@@ -373,7 +373,6 @@ bool fstype_is_network(const char *fstype) {
/* Filesystems not present in the internal database */
return STR_IN_SET(fstype,
- "ceph",
"davfs",
"glusterfs",
"lustre",
@@ -412,8 +411,8 @@ bool fstype_is_ro(const char *fstype) {
/* All Linux file systems that are necessarily read-only */
return STR_IN_SET(fstype,
"DM_verity_hash",
- "iso9660",
"erofs",
+ "iso9660",
"squashfs");
}
diff --git a/src/home/homed-home.c b/src/home/homed-home.c
index a31e27d051..2453fa31ef 100644
--- a/src/home/homed-home.c
+++ b/src/home/homed-home.c
@@ -17,6 +17,7 @@
#include "errno-util.h"
#include "fd-util.h"
#include "fileio.h"
+#include "filesystems.h"
#include "fs-util.h"
#include "home-util.h"
#include "homed-home-bus.h"
@@ -2466,19 +2467,6 @@ int home_get_disk_status(
ret_access_mode);
}
-static const char *fstype_magic_to_name(statfs_f_type_t magic) {
- /* For now, let's only translate the magic values of the file systems we actually are able to manage */
-
- if (F_TYPE_EQUAL(magic, EXT4_SUPER_MAGIC))
- return "ext4";
- if (F_TYPE_EQUAL(magic, XFS_SUPER_MAGIC))
- return "xfs";
- if (F_TYPE_EQUAL(magic, BTRFS_SUPER_MAGIC))
- return "btrfs";
-
- return NULL;
-}
-
int home_augment_status(
Home *h,
UserRecordLoadFlags flags,
@@ -2518,7 +2506,7 @@ int home_augment_status(
if (r < 0)
return r;
- fstype = fstype_magic_to_name(magic);
+ fstype = fs_type_to_string(magic);
if (disk_floor == UINT64_MAX || (disk_usage != UINT64_MAX && disk_floor < disk_usage))
disk_floor = disk_usage;
diff --git a/src/home/homework.c b/src/home/homework.c
index 94cfd41780..5bb759316f 100644
--- a/src/home/homework.c
+++ b/src/home/homework.c
@@ -8,6 +8,7 @@
#include "copy.h"
#include "fd-util.h"
#include "fileio.h"
+#include "filesystems.h"
#include "fs-util.h"
#include "home-util.h"
#include "homework-cifs.h"
@@ -704,14 +705,7 @@ static const char *file_system_type_fd(int fd) {
return NULL;
}
- if (is_fs_type(&sfs, XFS_SB_MAGIC))
- return "xfs";
- if (is_fs_type(&sfs, EXT4_SUPER_MAGIC))
- return "ext4";
- if (is_fs_type(&sfs, BTRFS_SUPER_MAGIC))
- return "btrfs";
-
- return NULL;
+ return fs_type_to_string(sfs.f_type);
}
int home_extend_embedded_identity(UserRecord *h, UserRecord *used, HomeSetup *setup) {