Use correct parent ID when doing hard/symlinks
[pohmelfs.git] / fs / pohmelfs / pool.c
blobc4572c70aa250f8c15edab68c65dce88184350c5
1 /*
2 * Copyright (C) 2011+ Evgeniy Polyakov <zbr@ioremap.net>
3 */
5 #include <linux/in.h>
6 #include <linux/in6.h>
7 #include <linux/net.h>
9 #include <net/sock.h>
10 #include <net/tcp.h>
12 #include "pohmelfs.h"
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;
19 LIST_HEAD(head);
20 int err;
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);
25 if (IS_ERR(st)) {
26 err = PTR_ERR(st);
28 if (err != -EEXIST)
29 continue;
30 } else {
31 pohmelfs_print_addr(&st->sa, "reconnected\n");
34 list_del(&r->reconnect_entry);
35 kfree(r);
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;
59 int i;
61 if (!conn || !conn_num)
62 return;
64 for (i = 0; i < conn_num; ++i) {
65 c = &conn[i];
67 c->need_exit = 1;
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);
84 kfree(r);
87 destroy_workqueue(c->wq);
90 kfree(conn);
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;
98 char name[16];
100 conn = kzalloc(num * sizeof(struct pohmelfs_connection), GFP_NOIO);
101 if (!conn) {
102 err = -ENOMEM;
103 goto err_out_exit;
106 for (i = 0; i < num; ++i) {
107 c = &conn[i];
109 c->psb = psb;
110 c->idx = 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);
125 if (!c->wq) {
126 err = -ENOMEM;
127 old_conn = conn;
128 old_conn_num = i;
129 goto err_out_free;
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;
144 psb->conn = conn;
145 psb->conn_num = num;
147 psb->meta_num = psb->conn_num / 8 + 1;
148 psb->bulk_num = psb->conn_num - psb->meta_num;
150 psb->meta_idx = 0;
151 psb->bulk_idx = 0;
152 mutex_unlock(&psb->conn_lock);
153 err = 0;
155 err_out_free:
156 pohmelfs_pool_clean(old_conn, old_conn_num);
157 err_out_exit:
158 return err;