2 * Copyright (C) 2011+ Evgeniy Polyakov <zbr@ioremap.net>
14 static void pohmelfs_reconnect(struct work_struct
*work
)
16 struct pohmelfs_connection
*conn
= container_of(to_delayed_work(work
), struct pohmelfs_connection
, reconnect_work
);
17 struct pohmelfs_reconnect
*r
, *tmp
;
18 struct pohmelfs_state
*st
, *stmp
;
22 mutex_lock(&conn
->reconnect_lock
);
23 list_for_each_entry_safe(r
, tmp
, &conn
->reconnect_list
, reconnect_entry
) {
24 st
= pohmelfs_state_create(conn
, &r
->sa
, r
->addrlen
, 1, r
->group_id
);
31 pohmelfs_print_addr(&st
->sa
, "reconnected\n");
34 list_del(&r
->reconnect_entry
);
37 mutex_unlock(&conn
->reconnect_lock
);
39 spin_lock(&conn
->state_lock
);
40 list_for_each_entry_safe(st
, stmp
, &conn
->kill_state_list
, state_entry
) {
41 list_move(&st
->state_entry
, &head
);
43 spin_unlock(&conn
->state_lock
);
45 list_for_each_entry_safe(st
, stmp
, &head
, state_entry
) {
46 list_del_init(&st
->state_entry
);
47 pohmelfs_state_kill(st
);
50 if (!list_empty(&conn
->reconnect_list
) && !conn
->need_exit
)
51 queue_delayed_work(conn
->wq
, &conn
->reconnect_work
, conn
->psb
->reconnect_timeout
);
54 void pohmelfs_pool_clean(struct pohmelfs_connection
*conn
, int conn_num
)
56 struct pohmelfs_connection
*c
;
57 struct pohmelfs_state
*st
, *tmp
;
58 struct pohmelfs_reconnect
*r
, *rtmp
;
61 if (!conn
|| !conn_num
)
64 for (i
= 0; i
< conn_num
; ++i
) {
69 cancel_delayed_work_sync(&c
->reconnect_work
);
71 list_for_each_entry_safe(st
, tmp
, &c
->state_list
, state_entry
) {
72 list_del_init(&st
->state_entry
);
74 pohmelfs_state_kill(st
);
77 list_for_each_entry_safe(st
, tmp
, &c
->kill_state_list
, state_entry
) {
78 list_del_init(&st
->state_entry
);
79 pohmelfs_state_kill(st
);
82 list_for_each_entry_safe(r
, rtmp
, &c
->reconnect_list
, reconnect_entry
) {
83 list_del(&r
->reconnect_entry
);
87 destroy_workqueue(c
->wq
);
93 int pohmelfs_pool_resize(struct pohmelfs_sb
*psb
, int num
)
95 int err
= 0, old_conn_num
, i
;
96 struct pohmelfs_connection
*conn
, *old_conn
, *c
;
97 struct pohmelfs_addr
*a
;
100 conn
= kzalloc(num
* sizeof(struct pohmelfs_connection
), GFP_NOIO
);
106 for (i
= 0; i
< num
; ++i
) {
112 c
->route_root
= RB_ROOT
;
113 spin_lock_init(&c
->state_lock
);
114 INIT_LIST_HEAD(&c
->state_list
);
116 INIT_LIST_HEAD(&c
->kill_state_list
);
118 mutex_init(&c
->reconnect_lock
);
119 INIT_LIST_HEAD(&c
->reconnect_list
);
121 INIT_DELAYED_WORK(&c
->reconnect_work
, pohmelfs_reconnect
);
123 snprintf(name
, sizeof(name
), "pohmelfs-%d-%d", psb
->bdi_num
, i
);
124 c
->wq
= alloc_workqueue(name
, WQ_NON_REENTRANT
| WQ_UNBOUND
| WQ_FREEZABLE
| WQ_MEM_RECLAIM
, 0);
132 mutex_lock(&psb
->conn_lock
);
133 list_for_each_entry(a
, &psb
->addr_list
, addr_entry
) {
134 pohmelfs_state_create(c
, &a
->sa
, a
->addrlen
, 1, 0);
136 mutex_unlock(&psb
->conn_lock
);
140 mutex_lock(&psb
->conn_lock
);
141 old_conn
= psb
->conn
;
142 old_conn_num
= psb
->conn_num
;
147 psb
->meta_num
= psb
->conn_num
/ 8 + 1;
148 psb
->bulk_num
= psb
->conn_num
- psb
->meta_num
;
152 mutex_unlock(&psb
->conn_lock
);
156 pohmelfs_pool_clean(old_conn
, old_conn_num
);