summaryrefslogtreecommitdiffstats
path: root/net/unix/garbage.c
diff options
context:
space:
mode:
authorJens Axboe <axboe@kernel.dk>2019-02-08 11:01:44 -0500
committerJens Axboe <axboe@kernel.dk>2019-02-28 10:24:23 -0500
commitf4e65870e5cede5ca1ec0006b6c9803994e5f7b8 (patch)
treeb8fb35e27f64bd350bb4166a2708d7f147719fa1 /net/unix/garbage.c
parentedafccee56ff31678a091ddb7219aba9b28bc3cb (diff)
net: split out functions related to registering inflight socket files
We need this functionality for the io_uring file registration, but we cannot rely on it since CONFIG_UNIX can be modular. Move the helpers to a separate file, that's always builtin to the kernel if CONFIG_UNIX is m/y. No functional changes in this patch, just moving code around. Reviewed-by: Hannes Reinecke <hare@suse.com> Acked-by: David S. Miller <davem@davemloft.net> Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'net/unix/garbage.c')
-rw-r--r--net/unix/garbage.c71
1 files changed, 2 insertions, 69 deletions
diff --git a/net/unix/garbage.c b/net/unix/garbage.c
index f81854d74c7d..8bbe1b8e4ff7 100644
--- a/net/unix/garbage.c
+++ b/net/unix/garbage.c
@@ -86,80 +86,13 @@
86#include <net/scm.h> 86#include <net/scm.h>
87#include <net/tcp_states.h> 87#include <net/tcp_states.h>
88 88
89#include "scm.h"
90
89/* Internal data structures and random procedures: */ 91/* Internal data structures and random procedures: */
90 92
91static LIST_HEAD(gc_inflight_list);
92static LIST_HEAD(gc_candidates); 93static LIST_HEAD(gc_candidates);
93static DEFINE_SPINLOCK(unix_gc_lock);
94static DECLARE_WAIT_QUEUE_HEAD(unix_gc_wait); 94static DECLARE_WAIT_QUEUE_HEAD(unix_gc_wait);
95 95
96unsigned int unix_tot_inflight;
97
98struct sock *unix_get_socket(struct file *filp)
99{
100 struct sock *u_sock = NULL;
101 struct inode *inode = file_inode(filp);
102
103 /* Socket ? */
104 if (S_ISSOCK(inode->i_mode) && !(filp->f_mode & FMODE_PATH)) {
105 struct socket *sock = SOCKET_I(inode);
106 struct sock *s = sock->sk;
107
108 /* PF_UNIX ? */
109 if (s && sock->ops && sock->ops->family == PF_UNIX)
110 u_sock = s;
111 } else {
112 /* Could be an io_uring instance */
113 u_sock = io_uring_get_socket(filp);
114 }
115 return u_sock;
116}
117
118/* Keep the number of times in flight count for the file
119 * descriptor if it is for an AF_UNIX socket.
120 */
121
122void unix_inflight(struct user_struct *user, struct file *fp)
123{
124 struct sock *s = unix_get_socket(fp);
125
126 spin_lock(&unix_gc_lock);
127
128 if (s) {
129 struct unix_sock *u = unix_sk(s);
130
131 if (atomic_long_inc_return(&u->inflight) == 1) {
132 BUG_ON(!list_empty(&u->link));
133 list_add_tail(&u->link, &gc_inflight_list);
134 } else {
135 BUG_ON(list_empty(&u->link));
136 }
137 unix_tot_inflight++;
138 }
139 user->unix_inflight++;
140 spin_unlock(&unix_gc_lock);
141}
142
143void unix_notinflight(struct user_struct *user, struct file *fp)
144{
145 struct sock *s = unix_get_socket(fp);
146
147 spin_lock(&unix_gc_lock);
148
149 if (s) {
150 struct unix_sock *u = unix_sk(s);
151
152 BUG_ON(!atomic_long_read(&u->inflight));
153 BUG_ON(list_empty(&u->link));
154
155 if (atomic_long_dec_and_test(&u->inflight))
156 list_del_init(&u->link);
157 unix_tot_inflight--;
158 }
159 user->unix_inflight--;
160 spin_unlock(&unix_gc_lock);
161}
162
163static void scan_inflight(struct sock *x, void (*func)(struct unix_sock *), 96static void scan_inflight(struct sock *x, void (*func)(struct unix_sock *),
164 struct sk_buff_head *hitlist) 97 struct sk_buff_head *hitlist)
165{ 98{