mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-12-24 21:34:08 +03:00
core: avoid calling path_simplify() unnecessarilly for u.requires_mounts_for keys
We would always call path_simplify() before doing a lookup, which requires the path key to be duplicated first. But the hashmap lookup doesn't require this… So let's opportunistically skip the allocation if the key is already present. Inspired by https://github.com/systemd/systemd/pull/19973.
This commit is contained in:
parent
0fb789af20
commit
ac19bdd04b
@ -4511,16 +4511,14 @@ void manager_status_printf(Manager *m, StatusType type, const char *status, cons
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
Set *manager_get_units_requiring_mounts_for(Manager *m, const char *path) {
|
||||
char p[strlen(path)+1];
|
||||
|
||||
Set* manager_get_units_requiring_mounts_for(Manager *m, const char *path) {
|
||||
assert(m);
|
||||
assert(path);
|
||||
|
||||
strcpy(p, path);
|
||||
path_simplify(p);
|
||||
if (path_equal(path, "/"))
|
||||
path = "";
|
||||
|
||||
return hashmap_get(m->units_requiring_mounts_for, streq(p, "/") ? "" : p);
|
||||
return hashmap_get(m->units_requiring_mounts_for, path);
|
||||
}
|
||||
|
||||
int manager_update_failed_units(Manager *m, Unit *u, bool failed) {
|
||||
|
@ -4562,45 +4562,43 @@ int unit_kill_context(
|
||||
}
|
||||
|
||||
int unit_require_mounts_for(Unit *u, const char *path, UnitDependencyMask mask) {
|
||||
_cleanup_free_ char *p = NULL;
|
||||
UnitDependencyInfo di;
|
||||
int r;
|
||||
|
||||
assert(u);
|
||||
assert(path);
|
||||
|
||||
/* Registers a unit for requiring a certain path and all its prefixes. We keep a hashtable of these paths in
|
||||
* the unit (from the path to the UnitDependencyInfo structure indicating how to the dependency came to
|
||||
* be). However, we build a prefix table for all possible prefixes so that new appearing mount units can easily
|
||||
* determine which units to make themselves a dependency of. */
|
||||
/* Registers a unit for requiring a certain path and all its prefixes. We keep a hashtable of these
|
||||
* paths in the unit (from the path to the UnitDependencyInfo structure indicating how to the
|
||||
* dependency came to be). However, we build a prefix table for all possible prefixes so that new
|
||||
* appearing mount units can easily determine which units to make themselves a dependency of. */
|
||||
|
||||
if (!path_is_absolute(path))
|
||||
return -EINVAL;
|
||||
|
||||
r = hashmap_ensure_allocated(&u->requires_mounts_for, &path_hash_ops);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (hashmap_contains(u->requires_mounts_for, path)) /* Exit quickly if the path is already covered. */
|
||||
return 0;
|
||||
|
||||
p = strdup(path);
|
||||
_cleanup_free_ char *p = strdup(path);
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Use the canonical form of the path as the stored key. We call path_is_normalized()
|
||||
* only after simplification, since path_is_normalized() rejects paths with '.'.
|
||||
* path_is_normalized() also verifies that the path fits in PATH_MAX. */
|
||||
path = path_simplify(p);
|
||||
|
||||
if (!path_is_normalized(path))
|
||||
return -EPERM;
|
||||
|
||||
if (hashmap_contains(u->requires_mounts_for, path))
|
||||
return 0;
|
||||
|
||||
di = (UnitDependencyInfo) {
|
||||
UnitDependencyInfo di = {
|
||||
.origin_mask = mask
|
||||
};
|
||||
|
||||
r = hashmap_put(u->requires_mounts_for, path, di.data);
|
||||
r = hashmap_ensure_put(&u->requires_mounts_for, &path_hash_ops, p, di.data);
|
||||
if (r < 0)
|
||||
return r;
|
||||
p = NULL;
|
||||
assert(r > 0);
|
||||
TAKE_PTR(p); /* path remains a valid pointer to the string stored in the hashmap */
|
||||
|
||||
char prefix[strlen(path) + 1];
|
||||
PATH_FOREACH_PREFIX_MORE(prefix, path) {
|
||||
|
Loading…
Reference in New Issue
Block a user