summaryrefslogtreecommitdiffstats
path: root/src/mtab.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mtab.c')
-rw-r--r--src/mtab.c77
1 files changed, 45 insertions, 32 deletions
diff --git a/src/mtab.c b/src/mtab.c
index c76f403..40a9885 100644
--- a/src/mtab.c
+++ b/src/mtab.c
@@ -2,23 +2,27 @@
// SPDX-License-Identifier: 0BSD
#include "mtab.h"
+
#include "alloc.h"
+#include "bfs.h"
#include "bfstd.h"
-#include "config.h"
#include "stat.h"
#include "trie.h"
+
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
-#if !defined(BFS_USE_MNTENT) && BFS_USE_MNTENT_H
-# define BFS_USE_MNTENT true
-#elif !defined(BFS_USE_MNTINFO) && BSD
-# define BFS_USE_MNTINFO true
-#elif !defined(BFS_USE_MNTTAB) && __SVR4
-# define BFS_USE_MNTTAB true
+#ifndef BFS_USE_MNTENT
+# define BFS_USE_MNTENT BFS_HAS_GETMNTENT_1
+#endif
+#ifndef BFS_USE_MNTINFO
+# define BFS_USE_MNTINFO (!BFS_USE_MNTENT && BFS_HAS_GETMNTINFO)
+#endif
+#ifndef BFS_USE_MNTTAB
+# define BFS_USE_MNTTAB (!BFS_USE_MNTINFO && BFS_HAS_GETMNTENT_2)
#endif
#if BFS_USE_MNTENT
@@ -27,7 +31,6 @@
# include <stdio.h>
#elif BFS_USE_MNTINFO
# include <sys/mount.h>
-# include <sys/ucred.h>
#elif BFS_USE_MNTTAB
# include <stdio.h>
# include <sys/mnttab.h>
@@ -41,11 +44,16 @@ struct bfs_mount {
char *path;
/** The filesystem type. */
char *type;
+ /** Buffer for the strings. */
+ char buf[];
};
struct bfs_mtab {
+ /** Mount point arena. */
+ struct varena varena;
+
/** The array of mount points. */
- struct bfs_mount *mounts;
+ struct bfs_mount **mounts;
/** The number of mount points. */
size_t nmounts;
@@ -61,30 +69,39 @@ struct bfs_mtab {
/**
* Add an entry to the mount table.
*/
-attr(maybe_unused)
+_maybe_unused
static int bfs_mtab_add(struct bfs_mtab *mtab, const char *path, const char *type) {
- struct bfs_mount *mount = RESERVE(struct bfs_mount, &mtab->mounts, &mtab->nmounts);
+ size_t path_size = strlen(path) + 1;
+ size_t type_size = strlen(type) + 1;
+ size_t size = path_size + type_size;
+ struct bfs_mount *mount = varena_alloc(&mtab->varena, size);
if (!mount) {
return -1;
}
- mount->path = strdup(path);
- mount->type = strdup(type);
- if (!mount->path || !mount->type) {
- goto fail;
+ struct bfs_mount **ptr = RESERVE(struct bfs_mount *, &mtab->mounts, &mtab->nmounts);
+ if (!ptr) {
+ goto free;
}
+ *ptr = mount;
+
+ mount->path = mount->buf;
+ memcpy(mount->path, path, path_size);
+
+ mount->type = mount->buf + path_size;
+ memcpy(mount->type, type, type_size);
const char *name = path + xbaseoff(path);
if (!trie_insert_str(&mtab->names, name)) {
- goto fail;
+ goto shrink;
}
return 0;
-fail:
- free(mount->type);
- free(mount->path);
+shrink:
--mtab->nmounts;
+free:
+ varena_free(&mtab->varena, mount, size);
return -1;
}
@@ -94,6 +111,8 @@ struct bfs_mtab *bfs_mtab_parse(void) {
return NULL;
}
+ VARENA_INIT(&mtab->varena, struct bfs_mount, buf);
+
trie_init(&mtab->names);
trie_init(&mtab->types);
@@ -132,7 +151,7 @@ struct bfs_mtab *bfs_mtab_parse(void) {
bfs_statfs *mntbuf;
int size = getmntinfo(&mntbuf, MNT_WAIT);
- if (size < 0) {
+ if (size <= 0) {
error = errno;
goto fail;
}
@@ -195,7 +214,7 @@ static int bfs_mtab_fill_types(struct bfs_mtab *mtab) {
struct bfs_stat parent_stat;
for (size_t i = 0; i < mtab->nmounts; ++i) {
- struct bfs_mount *mount = &mtab->mounts[i];
+ struct bfs_mount *mount = mtab->mounts[i];
const char *path = mount->path;
int fd = AT_FDCWD;
@@ -237,10 +256,7 @@ static int bfs_mtab_fill_types(struct bfs_mtab *mtab) {
continue;
}
- struct trie_leaf *leaf = trie_insert_mem(&mtab->types, &sb.dev, sizeof(sb.dev));
- if (leaf) {
- leaf->value = mount->type;
- } else {
+ if (trie_set_mem(&mtab->types, &sb.mnt_id, sizeof(sb.mnt_id), mount->type) != 0) {
goto fail;
}
}
@@ -263,9 +279,9 @@ const char *bfs_fstype(const struct bfs_mtab *mtab, const struct bfs_stat *statb
}
}
- const struct trie_leaf *leaf = trie_find_mem(&mtab->types, &statbuf->dev, sizeof(statbuf->dev));
- if (leaf) {
- return leaf->value;
+ const char *type = trie_get_mem(&mtab->types, &statbuf->mnt_id, sizeof(statbuf->mnt_id));
+ if (type) {
+ return type;
} else {
return "unknown";
}
@@ -280,11 +296,8 @@ void bfs_mtab_free(struct bfs_mtab *mtab) {
trie_destroy(&mtab->types);
trie_destroy(&mtab->names);
- for (size_t i = 0; i < mtab->nmounts; ++i) {
- free(mtab->mounts[i].type);
- free(mtab->mounts[i].path);
- }
free(mtab->mounts);
+ varena_destroy(&mtab->varena);
free(mtab);
}