summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
7ceefac)
fd_tracker_open_unsuspendable_fd() and
fd_tracker_close_unsuspendable_fd() make use of variable-length arrays
to track unsuspendable entries to open/close. These uses of VLA can
easily be replaced by using dynamic allocations. This is not expected
to cause any performance problem as it is used in slow paths.
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
Change-Id: I4d4e95e23eb6df9a66663ecabad40162c321525b
- * Copyright (C) 2018 - Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ * Copyright (C) 2018, 2020 - Jérémie Galarneau <jeremie.galarneau@efficios.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License, version 2 only, as
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License, version 2 only, as
{
int ret, user_ret, i, fds_to_suspend;
unsigned int active_fds;
{
int ret, user_ret, i, fds_to_suspend;
unsigned int active_fds;
- struct unsuspendable_fd *entries[fd_count];
+ struct unsuspendable_fd **entries;
- memset(entries, 0, sizeof(entries));
+ entries = zmalloc(fd_count * sizeof(*entries));
+ if (!entries) {
+ ret = -1;
+ goto end;
+ }
pthread_mutex_lock(&tracker->lock);
pthread_mutex_lock(&tracker->lock);
ret = fd_tracker_suspend_handles(
tracker, fds_to_suspend);
if (ret) {
ret = fd_tracker_suspend_handles(
tracker, fds_to_suspend);
if (ret) {
WARN("Cannot open unsuspendable fd, too many unsuspendable file descriptors are opened (%u)",
tracker->count.unsuspendable);
ret = -EMFILE;
WARN("Cannot open unsuspendable fd, too many unsuspendable file descriptors are opened (%u)",
tracker->count.unsuspendable);
ret = -EMFILE;
}
}
user_ret = open(user_data, out_fds);
if (user_ret) {
ret = user_ret;
}
}
user_ret = open(user_data, out_fds);
if (user_ret) {
ret = user_ret;
tracker->count.unsuspendable += fd_count;
rcu_read_unlock();
ret = user_ret;
tracker->count.unsuspendable += fd_count;
rcu_read_unlock();
ret = user_ret;
pthread_mutex_unlock(&tracker->lock);
pthread_mutex_unlock(&tracker->lock);
return ret;
end_free_entries:
for (i = 0; i < fd_count; i++) {
unsuspendable_fd_destroy(entries[i]);
}
return ret;
end_free_entries:
for (i = 0; i < fd_count; i++) {
unsuspendable_fd_destroy(entries[i]);
}
}
int fd_tracker_close_unsuspendable_fd(struct fd_tracker *tracker,
}
int fd_tracker_close_unsuspendable_fd(struct fd_tracker *tracker,
void *user_data)
{
int i, ret, user_ret;
void *user_data)
{
int i, ret, user_ret;
/*
* Maintain a local copy of fds_in as the user's callback may modify its
* contents (e.g. setting the fd(s) to -1 after close).
*/
/*
* Maintain a local copy of fds_in as the user's callback may modify its
* contents (e.g. setting the fd(s) to -1 after close).
*/
+ fds = malloc(sizeof(*fds) * fd_count);
+ if (!fds) {
+ ret = -1;
+ goto end;
+ }
memcpy(fds, fds_in, sizeof(*fds) * fd_count);
pthread_mutex_lock(&tracker->lock);
memcpy(fds, fds_in, sizeof(*fds) * fd_count);
pthread_mutex_lock(&tracker->lock);
user_ret = close(user_data, fds_in);
if (user_ret) {
ret = user_ret;
user_ret = close(user_data, fds_in);
if (user_ret) {
ret = user_ret;
}
/* Untrack the fds that were just closed by the user's callback. */
}
/* Untrack the fds that were just closed by the user's callback. */
WARN("Untracked file descriptor %d passed to fd_tracker_close_unsuspendable_fd()",
fds[i]);
ret = -EINVAL;
WARN("Untracked file descriptor %d passed to fd_tracker_close_unsuspendable_fd()",
fds[i]);
ret = -EINVAL;
}
entry = caa_container_of(
node, struct unsuspendable_fd, tracker_node);
}
entry = caa_container_of(
node, struct unsuspendable_fd, tracker_node);
tracker->count.unsuspendable -= fd_count;
ret = 0;
tracker->count.unsuspendable -= fd_count;
ret = 0;
rcu_read_unlock();
pthread_mutex_unlock(&tracker->lock);
rcu_read_unlock();
pthread_mutex_unlock(&tracker->lock);