- addr.sin_addr.s_addr = INADDR_ANY
-
- rc = sock->ops->bind(sock, &addr, sizeof(addr));
- if (rc != 0) {
- CERROR("Can't bind to port %d\n", port);
- goto out_2;
- }
-
- rc = sock->ops->listen(sock, kra_tunalbes.kra_backlog);
- if (rc != 0) {
- CERROR("Can't set listen backlog %d: %d\n", backlog, rc);
- goto out_2;
- }
-
- LASSERT (kranal_data.kra_listener_sock == NULL);
- kranal_data.kra_listener_sock = sock;
-
- /* unblock waiting parent */
- LASSERT (kranal_data.kra_listener_shutdown == 0);
- up(&kranal_data.kra_listener_signal);
-
- /* Wake me any time something happens on my socket */
- add_wait_queue(sock->sk->sk_sleep, &wait);
-
- while (kranal_data.kra_listener_shutdown == 0) {
-
- newsock = sock_alloc();
- if (newsock == NULL) {
- CERROR("Can't allocate new socket for accept\n");
- kranal_pause(HZ);
- continue;
- }
-
- set_current_state(TASK_INTERRUPTIBLE);
-
- rc = sock->ops->accept(sock, newsock, O_NONBLOCK);
-
- if (rc == -EAGAIN &&
- kranal_data.kra_listener_shutdown == 0)
- schedule();
-
- set_current_state(TASK_RUNNING);
-
- if (rc != 0) {
- sock_release(newsock);
- if (rc != -EAGAIN) {
- CERROR("Accept failed: %d\n", rc);
- kranal_pause(HZ);
- }
- continue;
- }
-
- kranal_conn_handshake(newsock, NULL);
- sock_release(newsock);
- }
-
- rc = 0;
- remove_wait_queue(sock->sk->sk_sleep, &wait);
- out_2:
- sock_release(sock);
- kranal_data.kra_listener_sock = NULL;
+ addr.sin_addr.s_addr = INADDR_ANY;
+
+ rc = sock->ops->bind(sock, (struct sockaddr *)&addr, sizeof(addr));
+ if (rc != 0) {
+ CERROR("Can't bind to port %d\n", port);
+ goto out_1;
+ }
+
+ rc = sock->ops->listen(sock, kranal_tunables.kra_backlog);
+ if (rc != 0) {
+ CERROR("Can't set listen backlog %d: %d\n",
+ kranal_tunables.kra_backlog, rc);
+ goto out_1;
+ }
+
+ LASSERT (kranal_data.kra_listener_sock == NULL);
+ kranal_data.kra_listener_sock = sock;
+
+ /* unblock waiting parent */
+ LASSERT (kranal_data.kra_listener_shutdown == 0);
+ up(&kranal_data.kra_listener_signal);
+
+ /* Wake me any time something happens on my socket */
+ add_wait_queue(sock->sk->sk_sleep, &wait);
+ ras = NULL;
+
+ while (kranal_data.kra_listener_shutdown == 0) {
+
+ if (ras == NULL) {
+ PORTAL_ALLOC(ras, sizeof(*ras));
+ if (ras == NULL) {
+ CERROR("Out of Memory: pausing...\n");
+ kranal_pause(HZ);
+ continue;
+ }
+ ras->ras_sock = NULL;
+ }
+
+ if (ras->ras_sock == NULL) {
+ ras->ras_sock = sock_alloc();
+ if (ras->ras_sock == NULL) {
+ CERROR("Can't allocate socket: pausing...\n");
+ kranal_pause(HZ);
+ continue;
+ }
+ /* XXX this should add a ref to sock->ops->owner, if
+ * TCP could be a module */
+ ras->ras_sock->type = sock->type;
+ ras->ras_sock->ops = sock->ops;
+ }
+
+ set_current_state(TASK_INTERRUPTIBLE);
+
+ rc = sock->ops->accept(sock, ras->ras_sock, O_NONBLOCK);
+
+ /* Sleep for socket activity? */
+ if (rc == -EAGAIN &&
+ kranal_data.kra_listener_shutdown == 0)
+ schedule();
+
+ set_current_state(TASK_RUNNING);
+
+ if (rc == 0) {
+ spin_lock_irqsave(&kranal_data.kra_connd_lock, flags);
+
+ list_add_tail(&ras->ras_list,
+ &kranal_data.kra_connd_acceptq);
+
+ spin_unlock_irqrestore(&kranal_data.kra_connd_lock, flags);
+ wake_up(&kranal_data.kra_connd_waitq);
+
+ ras = NULL;
+ continue;
+ }
+
+ if (rc != -EAGAIN) {
+ CERROR("Accept failed: %d, pausing...\n", rc);
+ kranal_pause(HZ);
+ }
+ }
+
+ if (ras != NULL) {
+ if (ras->ras_sock != NULL)
+ sock_release(ras->ras_sock);
+ PORTAL_FREE(ras, sizeof(*ras));
+ }
+
+ rc = 0;
+ remove_wait_queue(sock->sk->sk_sleep, &wait);