⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 socklnd_lib-linux.c

📁 非常经典的一个分布式系统
💻 C
📖 第 1 页 / 共 3 页
字号:
        rc = ksocknal_connsock_addref(conn);        if (rc != 0) {                LASSERT (conn->ksnc_closing);                *txmem = *rxmem = *nagle = 0;                return (-ESHUTDOWN);        }        rc = libcfs_sock_getbuf(sock, txmem, rxmem);        if (rc == 0) {                len = sizeof(*nagle);                set_fs(KERNEL_DS);                rc = sock->ops->getsockopt(sock, SOL_TCP, TCP_NODELAY,                                           (char *)nagle, &len);                set_fs(oldmm);        }        ksocknal_connsock_decref(conn);        if (rc == 0)                *nagle = !*nagle;        else                *txmem = *rxmem = *nagle = 0;        return (rc);}intksocknal_lib_setup_sock (struct socket *sock){        mm_segment_t    oldmm = get_fs ();        int             rc;        int             option;        int             keep_idle;        int             keep_intvl;        int             keep_count;        int             do_keepalive;        struct linger   linger;        sock->sk->sk_allocation = GFP_NOFS;        /* Ensure this socket aborts active sends immediately when we close         * it. */        linger.l_onoff = 0;        linger.l_linger = 0;        set_fs (KERNEL_DS);        rc = sock_setsockopt (sock, SOL_SOCKET, SO_LINGER,                              (char *)&linger, sizeof (linger));        set_fs (oldmm);        if (rc != 0) {                CERROR ("Can't set SO_LINGER: %d\n", rc);                return (rc);        }        option = -1;        set_fs (KERNEL_DS);        rc = sock->ops->setsockopt (sock, SOL_TCP, TCP_LINGER2,                                    (char *)&option, sizeof (option));        set_fs (oldmm);        if (rc != 0) {                CERROR ("Can't set SO_LINGER2: %d\n", rc);                return (rc);        }        if (!*ksocknal_tunables.ksnd_nagle) {                option = 1;                set_fs (KERNEL_DS);                rc = sock->ops->setsockopt (sock, SOL_TCP, TCP_NODELAY,                                            (char *)&option, sizeof (option));                set_fs (oldmm);                if (rc != 0) {                        CERROR ("Can't disable nagle: %d\n", rc);                        return (rc);                }        }        rc = libcfs_sock_setbuf(sock,                                *ksocknal_tunables.ksnd_tx_buffer_size,                                *ksocknal_tunables.ksnd_rx_buffer_size);        if (rc != 0) {                CERROR ("Can't set buffer tx %d, rx %d buffers: %d\n",                        *ksocknal_tunables.ksnd_tx_buffer_size,                        *ksocknal_tunables.ksnd_rx_buffer_size, rc);                return (rc);        }/* TCP_BACKOFF_* sockopt tunables unsupported in stock kernels */#ifdef SOCKNAL_BACKOFF        if (*ksocknal_tunables.ksnd_backoff_init > 0) {                option = *ksocknal_tunables.ksnd_backoff_init;                set_fs (KERNEL_DS);                rc = sock->ops->setsockopt (sock, SOL_TCP, TCP_BACKOFF_INIT,                                            (char *)&option, sizeof (option));                set_fs (oldmm);                if (rc != 0) {                        CERROR ("Can't set initial tcp backoff %d: %d\n",                                option, rc);                        return (rc);                }        }        if (*ksocknal_tunables.ksnd_backoff_max > 0) {                option = *ksocknal_tunables.ksnd_backoff_max;                set_fs (KERNEL_DS);                rc = sock->ops->setsockopt (sock, SOL_TCP, TCP_BACKOFF_MAX,                                            (char *)&option, sizeof (option));                set_fs (oldmm);                if (rc != 0) {                        CERROR ("Can't set maximum tcp backoff %d: %d\n",                                option, rc);                        return (rc);                }        }#endif        /* snapshot tunables */        keep_idle  = *ksocknal_tunables.ksnd_keepalive_idle;        keep_count = *ksocknal_tunables.ksnd_keepalive_count;        keep_intvl = *ksocknal_tunables.ksnd_keepalive_intvl;        do_keepalive = (keep_idle > 0 && keep_count > 0 && keep_intvl > 0);        option = (do_keepalive ? 1 : 0);        set_fs (KERNEL_DS);        rc = sock_setsockopt (sock, SOL_SOCKET, SO_KEEPALIVE,                              (char *)&option, sizeof (option));        set_fs (oldmm);        if (rc != 0) {                CERROR ("Can't set SO_KEEPALIVE: %d\n", rc);                return (rc);        }        if (!do_keepalive)                return (0);        set_fs (KERNEL_DS);        rc = sock->ops->setsockopt (sock, SOL_TCP, TCP_KEEPIDLE,                                    (char *)&keep_idle, sizeof (keep_idle));        set_fs (oldmm);        if (rc != 0) {                CERROR ("Can't set TCP_KEEPIDLE: %d\n", rc);                return (rc);        }        set_fs (KERNEL_DS);        rc = sock->ops->setsockopt (sock, SOL_TCP, TCP_KEEPINTVL,                                    (char *)&keep_intvl, sizeof (keep_intvl));        set_fs (oldmm);        if (rc != 0) {                CERROR ("Can't set TCP_KEEPINTVL: %d\n", rc);                return (rc);        }        set_fs (KERNEL_DS);        rc = sock->ops->setsockopt (sock, SOL_TCP, TCP_KEEPCNT,                                    (char *)&keep_count, sizeof (keep_count));        set_fs (oldmm);        if (rc != 0) {                CERROR ("Can't set TCP_KEEPCNT: %d\n", rc);                return (rc);        }        return (0);}#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))struct tcp_opt *sock2tcp_opt(struct sock *sk){        return &(sk->tp_pinfo.af_tcp);}#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10))#define sock2tcp_opt(sk) tcp_sk(sk)#elsestruct tcp_opt *sock2tcp_opt(struct sock *sk){        struct tcp_sock *s = (struct tcp_sock *)sk;        return &s->tcp;}#endifvoidksocknal_lib_push_conn (ksock_conn_t *conn){        struct sock    *sk;#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11))        struct tcp_opt *tp;#else        struct tcp_sock *tp;#endif        int             nonagle;        int             val = 1;        int             rc;        mm_segment_t    oldmm;        rc = ksocknal_connsock_addref(conn);        if (rc != 0)                            /* being shut down */                return;        sk = conn->ksnc_sock->sk;        tp = sock2tcp_opt(sk);        lock_sock (sk);        nonagle = tp->nonagle;        tp->nonagle = 1;        release_sock (sk);        oldmm = get_fs ();        set_fs (KERNEL_DS);        rc = sk->sk_prot->setsockopt (sk, SOL_TCP, TCP_NODELAY,                                      (char *)&val, sizeof (val));        LASSERT (rc == 0);        set_fs (oldmm);        lock_sock (sk);        tp->nonagle = nonagle;        release_sock (sk);        ksocknal_connsock_decref(conn);}extern void ksocknal_read_callback (ksock_conn_t *conn);extern void ksocknal_write_callback (ksock_conn_t *conn);/* * socket call back in Linux */static voidksocknal_data_ready (struct sock *sk, int n){        ksock_conn_t  *conn;        ENTRY;        /* interleave correctly with closing sockets... */        LASSERT(!in_irq());        read_lock (&ksocknal_data.ksnd_global_lock);        conn = sk->sk_user_data;        if (conn == NULL) {             /* raced with ksocknal_terminate_conn */                LASSERT (sk->sk_data_ready != &ksocknal_data_ready);                sk->sk_data_ready (sk, n);        } else                ksocknal_read_callback(conn);        read_unlock (&ksocknal_data.ksnd_global_lock);        EXIT;}static voidksocknal_write_space (struct sock *sk){        ksock_conn_t  *conn;        int            wspace;        int            min_wpace;        /* interleave correctly with closing sockets... */        LASSERT(!in_irq());        read_lock (&ksocknal_data.ksnd_global_lock);        conn = sk->sk_user_data;        wspace = SOCKNAL_WSPACE(sk);        min_wpace = SOCKNAL_MIN_WSPACE(sk);        CDEBUG(D_NET, "sk %p wspace %d low water %d conn %p%s%s%s\n",               sk, wspace, min_wpace, conn,               (conn == NULL) ? "" : (conn->ksnc_tx_ready ?                                      " ready" : " blocked"),               (conn == NULL) ? "" : (conn->ksnc_tx_scheduled ?                                      " scheduled" : " idle"),               (conn == NULL) ? "" : (list_empty (&conn->ksnc_tx_queue) ?                                      " empty" : " queued"));        if (conn == NULL) {             /* raced with ksocknal_terminate_conn */                LASSERT (sk->sk_write_space != &ksocknal_write_space);                sk->sk_write_space (sk);                read_unlock (&ksocknal_data.ksnd_global_lock);                return;        }        if (wspace >= min_wpace) {              /* got enough space */                ksocknal_write_callback(conn);                /* Clear SOCK_NOSPACE _after_ ksocknal_write_callback so the                 * ENOMEM check in ksocknal_transmit is race-free (think about                 * it). */                clear_bit (SOCK_NOSPACE, &sk->sk_socket->flags);        }        read_unlock (&ksocknal_data.ksnd_global_lock);}voidksocknal_lib_save_callback(struct socket *sock, ksock_conn_t *conn){        conn->ksnc_saved_data_ready = sock->sk->sk_data_ready;        conn->ksnc_saved_write_space = sock->sk->sk_write_space;}voidksocknal_lib_set_callback(struct socket *sock,  ksock_conn_t *conn){        sock->sk->sk_user_data = conn;        sock->sk->sk_data_ready = ksocknal_data_ready;        sock->sk->sk_write_space = ksocknal_write_space;        return;}voidksocknal_lib_reset_callback(struct socket *sock, ksock_conn_t *conn){        /* Remove conn's network callbacks.         * NB I _have_ to restore the callback, rather than storing a noop,         * since the socket could survive past this module being unloaded!! */        sock->sk->sk_data_ready = conn->ksnc_saved_data_ready;        sock->sk->sk_write_space = conn->ksnc_saved_write_space;        /* A callback could be in progress already; they hold a read lock         * on ksnd_global_lock (to serialise with me) and NOOP if         * sk_user_data is NULL. */        sock->sk->sk_user_data = NULL;        return ;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -