summaryrefslogtreecommitdiffstats
path: root/net/unix/garbage.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/unix/garbage.c')
-rw-r--r--net/unix/garbage.c68
1 files changed, 2 insertions, 66 deletions
diff --git a/net/unix/garbage.c b/net/unix/garbage.c
index c36757e72844..8bbe1b8e4ff7 100644
--- a/net/unix/garbage.c
+++ b/net/unix/garbage.c
@@ -86,77 +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 }
112 return u_sock;
113}
114
115/* Keep the number of times in flight count for the file
116 * descriptor if it is for an AF_UNIX socket.
117 */
118
119void unix_inflight(struct user_struct *user, struct file *fp)
120{
121 struct sock *s = unix_get_socket(fp);
122
123 spin_lock(&unix_gc_lock);
124
125 if (s) {
126 struct unix_sock *u = unix_sk(s);
127
128 if (atomic_long_inc_return(&u->inflight) == 1) {
129 BUG_ON(!list_empty(&u->link));
130 list_add_tail(&u->link, &gc_inflight_list);
131 } else {
132 BUG_ON(list_empty(&u->link));
133 }
134 unix_tot_inflight++;
135 }
136 user->unix_inflight++;
137 spin_unlock(&unix_gc_lock);
138}
139
140void unix_notinflight(struct user_struct *user, struct file *fp)
141{
142 struct sock *s = unix_get_socket(fp);
143
144 spin_lock(&unix_gc_lock);
145
146 if (s) {
147 struct unix_sock *u = unix_sk(s);
148
149 BUG_ON(!atomic_long_read(&u->inflight));
150 BUG_ON(list_empty(&u->link));
151
152 if (atomic_long_dec_and_test(&u->inflight))
153 list_del_init(&u->link);
154 unix_tot_inflight--;
155 }
156 user->unix_inflight--;
157 spin_unlock(&unix_gc_lock);
158}
159
160static void scan_inflight(struct sock *x, void (*func)(struct unix_sock *), 96static void scan_inflight(struct sock *x, void (*func)(struct unix_sock *),
161 struct sk_buff_head *hitlist) 97 struct sk_buff_head *hitlist)
162{ 98{