fd-tracker: remove use of VLA for unsuspendable_fd APIs
authorJérémie Galarneau <jeremie.galarneau@efficios.com>
Wed, 15 Jan 2020 23:41:34 +0000 (18:41 -0500)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Thu, 30 Jan 2020 06:55:34 +0000 (01:55 -0500)
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

src/common/fd-tracker/fd-tracker.c

index 65cbba99c0579378a2f89192f2cf2096c267f7b8..5e6c8f30ed64e4999990351bf383361aac93e15f 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * 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
@@ -585,9 +585,13 @@ int fd_tracker_open_unsuspendable_fd(struct fd_tracker *tracker,
 {
        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);
 
@@ -599,7 +603,7 @@ int fd_tracker_open_unsuspendable_fd(struct fd_tracker *tracker,
                        ret = fd_tracker_suspend_handles(
                                        tracker, fds_to_suspend);
                        if (ret) {
                        ret = fd_tracker_suspend_handles(
                                        tracker, fds_to_suspend);
                        if (ret) {
-                               goto end;
+                               goto end_unlock;
                        }
                } else {
                        /*
                        }
                } else {
                        /*
@@ -610,14 +614,14 @@ int fd_tracker_open_unsuspendable_fd(struct fd_tracker *tracker,
                        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;
-                       goto end;
+                       goto end_unlock;
                }
        }
 
        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;
-               goto end;
+               goto end_unlock;
        }
 
        /*
        }
 
        /*
@@ -657,14 +661,16 @@ int fd_tracker_open_unsuspendable_fd(struct fd_tracker *tracker,
        tracker->count.unsuspendable += fd_count;
        rcu_read_unlock();
        ret = user_ret;
        tracker->count.unsuspendable += fd_count;
        rcu_read_unlock();
        ret = user_ret;
-end:
+end_unlock:
        pthread_mutex_unlock(&tracker->lock);
        pthread_mutex_unlock(&tracker->lock);
+end:
+       free(entries);
        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]);
        }
-       goto end;
+       goto end_unlock;
 }
 
 int fd_tracker_close_unsuspendable_fd(struct fd_tracker *tracker,
 }
 
 int fd_tracker_close_unsuspendable_fd(struct fd_tracker *tracker,
@@ -674,12 +680,17 @@ 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;
-       int fds[fd_count];
+       int *fds = NULL;
 
        /*
         * 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);
@@ -689,7 +700,7 @@ int fd_tracker_close_unsuspendable_fd(struct fd_tracker *tracker,
        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;
-               goto end;
+               goto end_unlock;
        }
 
        /* Untrack the fds that were just closed by the user's callback. */
        }
 
        /* Untrack the fds that were just closed by the user's callback. */
@@ -709,7 +720,7 @@ int fd_tracker_close_unsuspendable_fd(struct fd_tracker *tracker,
                        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;
-                       goto end;
+                       goto end_unlock;
                }
                entry = caa_container_of(
                                node, struct unsuspendable_fd, tracker_node);
                }
                entry = caa_container_of(
                                node, struct unsuspendable_fd, tracker_node);
@@ -721,9 +732,11 @@ int fd_tracker_close_unsuspendable_fd(struct fd_tracker *tracker,
 
        tracker->count.unsuspendable -= fd_count;
        ret = 0;
 
        tracker->count.unsuspendable -= fd_count;
        ret = 0;
-end:
+end_unlock:
        rcu_read_unlock();
        pthread_mutex_unlock(&tracker->lock);
        rcu_read_unlock();
        pthread_mutex_unlock(&tracker->lock);
+       free(fds);
+end:
        return ret;
 }
 
        return ret;
 }
 
This page took 0.028268 seconds and 5 git commands to generate.