2 * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
16 #include <linux/module.h>
17 #include <linux/crypto.h>
19 #include <linux/jhash.h>
20 #include <linux/hash.h>
21 #include <linux/ktime.h>
22 #include <linux/mempool.h>
24 #include <linux/mount.h>
25 #include <linux/pagemap.h>
26 #include <linux/parser.h>
27 #include <linux/poll.h>
28 #include <linux/swap.h>
29 #include <linux/slab.h>
30 #include <linux/statfs.h>
31 #include <linux/writeback.h>
35 static struct kmem_cache *netfs_trans_dst;
36 static mempool_t *netfs_trans_dst_pool;
38 static void netfs_trans_init_static(struct netfs_trans *t, int num, int size)
42 atomic_set(&t->refcnt, 1);
44 spin_lock_init(&t->dst_lock);
45 INIT_LIST_HEAD(&t->dst_list);
48 static int netfs_trans_send_pages(struct netfs_trans *t, struct netfs_state *st)
51 unsigned int i, attached_pages = t->attached_pages, ci;
53 struct page **pages = (t->eng)?t->eng->pages:t->pages;
59 msg.msg_control = NULL;
60 msg.msg_controllen = 0;
61 msg.msg_flags = MSG_WAITALL | MSG_MORE;
64 for (i=0; i<t->page_num; ++i) {
65 struct page *page = pages[ci];
74 size = page_private(p);
77 io.iov_len = sizeof(struct netfs_cmd);
79 cmd.cmd = NETFS_WRITE_PAGE;
84 cmd.start <<= PAGE_CACHE_SHIFT;
87 cmd.iv = pohmelfs_gen_iv(t);
89 netfs_convert_cmd(&cmd);
93 msg.msg_flags = MSG_WAITALL | MSG_MORE;
95 err = kernel_sendmsg(st->socket, &msg, (struct kvec *)msg.msg_iov, 1, sizeof(struct netfs_cmd));
97 printk("%s: %d/%d failed to send transaction header: t: %p, gen: %u, err: %d.\n",
98 __func__, i, t->page_num, t, t->gen, err);
104 msg.msg_flags = MSG_WAITALL | (attached_pages == 1 ? 0 :
107 err = kernel_sendpage(st->socket, page, 0, size, msg.msg_flags);
109 printk("%s: %d/%d failed to send transaction page: t: %p, gen: %u, size: %u, err: %d.\n",
110 __func__, i, t->page_num, t, t->gen, size, err);
116 dprintk("%s: %d/%d sent t: %p, gen: %u, page: %p/%p, size: %u.\n",
117 __func__, i, t->page_num, t, t->gen, page, p, size);
128 printk("%s: t: %p, gen: %u, err: %d.\n", __func__, t, t->gen, err);
129 netfs_state_exit(st);
136 int netfs_trans_send(struct netfs_trans *t, struct netfs_state *st)
141 BUG_ON(!t->iovec.iov_len);
142 BUG_ON(t->iovec.iov_len > 1024*1024*1024);
144 netfs_state_lock_send(st);
146 err = netfs_state_init(st);
148 goto err_out_unlock_return;
151 msg.msg_iov = &t->iovec;
155 msg.msg_control = NULL;
156 msg.msg_controllen = 0;
157 msg.msg_flags = MSG_WAITALL;
159 if (t->attached_pages)
160 msg.msg_flags |= MSG_MORE;
162 err = kernel_sendmsg(st->socket, &msg, (struct kvec *)msg.msg_iov, 1, t->iovec.iov_len);
164 printk("%s: failed to send contig transaction: t: %p, gen: %u, size: %zu, err: %d.\n",
165 __func__, t, t->gen, t->iovec.iov_len, err);
168 goto err_out_unlock_return;
171 dprintk("%s: sent %s transaction: t: %p, gen: %u, size: %zu, page_num: %u.\n",
172 __func__, (t->page_num)?"partial":"full",
173 t, t->gen, t->iovec.iov_len, t->page_num);
176 if (t->attached_pages)
177 err = netfs_trans_send_pages(t, st);
179 err_out_unlock_return:
182 netfs_state_exit(st);
184 netfs_state_unlock_send(st);
186 dprintk("%s: t: %p, gen: %u, err: %d.\n",
187 __func__, t, t->gen, err);
193 static inline int netfs_trans_cmp(unsigned int gen, unsigned int new)
202 struct netfs_trans_dst *netfs_trans_search(struct netfs_state *st, unsigned int gen)
204 struct rb_root *root = &st->trans_root;
205 struct rb_node *n = root->rb_node;
206 struct netfs_trans_dst *tmp, *ret = NULL;
207 struct netfs_trans *t;
211 tmp = rb_entry(n, struct netfs_trans_dst, state_entry);
214 cmp = netfs_trans_cmp(t->gen, gen);
228 static int netfs_trans_insert(struct netfs_trans_dst *ndst, struct netfs_state *st)
230 struct rb_root *root = &st->trans_root;
231 struct rb_node **n = &root->rb_node, *parent = NULL;
232 struct netfs_trans_dst *ret = NULL, *tmp;
233 struct netfs_trans *t = NULL, *new = ndst->trans;
239 tmp = rb_entry(parent, struct netfs_trans_dst, state_entry);
242 cmp = netfs_trans_cmp(t->gen, new->gen);
244 n = &parent->rb_left;
246 n = &parent->rb_right;
254 printk("%s: exist: old: gen: %u, flags: %x, send_time: %lu, "
255 "new: gen: %u, flags: %x, send_time: %lu.\n",
256 __func__, t->gen, t->flags, ret->send_time,
257 new->gen, new->flags, ndst->send_time);
261 rb_link_node(&ndst->state_entry, parent, n);
262 rb_insert_color(&ndst->state_entry, root);
263 ndst->send_time = jiffies;
268 int netfs_trans_remove_nolock(struct netfs_trans_dst *dst, struct netfs_state *st)
270 if (dst && dst->state_entry.rb_parent_color) {
271 rb_erase(&dst->state_entry, &st->trans_root);
272 dst->state_entry.rb_parent_color = 0;
278 static int netfs_trans_remove_state(struct netfs_trans_dst *dst)
281 struct netfs_state *st = dst->state;
283 mutex_lock(&st->trans_lock);
284 ret = netfs_trans_remove_nolock(dst, st);
285 mutex_unlock(&st->trans_lock);
291 * Create new destination for given transaction associated with given network state.
292 * Transaction's reference counter is bumped and will be dropped when either
293 * reply is received or when async timeout detection task will fail resending
294 * and drop transaction.
296 static int netfs_trans_push_dst(struct netfs_trans *t, struct netfs_state *st)
298 struct netfs_trans_dst *dst;
301 dst = mempool_alloc(netfs_trans_dst_pool, GFP_KERNEL);
311 mutex_lock(&st->trans_lock);
312 err = netfs_trans_insert(dst, st);
313 mutex_unlock(&st->trans_lock);
318 spin_lock(&t->dst_lock);
319 list_add_tail(&dst->trans_entry, &t->dst_list);
320 spin_unlock(&t->dst_lock);
327 mempool_free(dst, netfs_trans_dst_pool);
331 static void netfs_trans_free_dst(struct netfs_trans_dst *dst)
333 netfs_trans_put(dst->trans);
334 mempool_free(dst, netfs_trans_dst_pool);
337 static void netfs_trans_remove_dst(struct netfs_trans_dst *dst)
339 if (netfs_trans_remove_state(dst))
340 netfs_trans_free_dst(dst);
344 * Drop destination transaction entry when we know it.
346 void netfs_trans_drop_dst(struct netfs_trans_dst *dst)
348 struct netfs_trans *t = dst->trans;
350 spin_lock(&t->dst_lock);
351 list_del_init(&dst->trans_entry);
352 spin_unlock(&t->dst_lock);
354 netfs_trans_remove_dst(dst);
358 * Drop destination transaction entry when we know it and when we
359 * already removed dst from state tree.
361 void netfs_trans_drop_dst_nostate(struct netfs_trans_dst *dst)
363 struct netfs_trans *t = dst->trans;
365 spin_lock(&t->dst_lock);
366 list_del_init(&dst->trans_entry);
367 spin_unlock(&t->dst_lock);
369 netfs_trans_free_dst(dst);
373 * This drops destination transaction entry from appropriate network state
374 * tree and drops related reference counter. It is possible that transaction
375 * will be freed here if its reference counter hits zero.
376 * Destination transaction entry will be freed.
378 void netfs_trans_drop_trans(struct netfs_trans *t, struct netfs_state *st)
380 struct netfs_trans_dst *dst, *tmp, *ret = NULL;
382 spin_lock(&t->dst_lock);
383 list_for_each_entry_safe(dst, tmp, &t->dst_list, trans_entry) {
384 if (dst->state == st) {
386 list_del(&dst->trans_entry);
390 spin_unlock(&t->dst_lock);
393 netfs_trans_remove_dst(ret);
397 * This drops destination transaction entry from appropriate network state
398 * tree and drops related reference counter. It is possible that transaction
399 * will be freed here if its reference counter hits zero.
400 * Destination transaction entry will be freed.
402 void netfs_trans_drop_last(struct netfs_trans *t, struct netfs_state *st)
404 struct netfs_trans_dst *dst, *tmp, *ret;
406 spin_lock(&t->dst_lock);
407 ret = list_entry(t->dst_list.prev, struct netfs_trans_dst, trans_entry);
408 if (ret->state != st) {
410 list_for_each_entry_safe(dst, tmp, &t->dst_list, trans_entry) {
411 if (dst->state == st) {
413 list_del_init(&dst->trans_entry);
418 list_del(&ret->trans_entry);
420 spin_unlock(&t->dst_lock);
423 netfs_trans_remove_dst(ret);
426 static int netfs_trans_push(struct netfs_trans *t, struct netfs_state *st)
430 err = netfs_trans_push_dst(t, st);
434 err = netfs_trans_send(t, st);
438 if (t->flags & NETFS_TRANS_SINGLE_DST)
439 pohmelfs_switch_active(st->psb);
445 netfs_trans_drop_last(t, st);
450 int netfs_trans_finish_send(struct netfs_trans *t, struct pohmelfs_sb *psb)
452 struct pohmelfs_config *c;
454 struct netfs_state *st;
456 dprintk("%s: t: %p, gen: %u, size: %u, page_num: %u, active: %p.\n",
457 __func__, t, t->gen, t->iovec.iov_len, t->page_num, psb->active_state);
459 mutex_lock(&psb->state_lock);
460 list_for_each_entry(c, &psb->state_list, config_entry) {
463 if (t->flags & NETFS_TRANS_SINGLE_DST) {
464 if (!(st->ctl.perm & POHMELFS_IO_PERM_READ))
467 if (!(st->ctl.perm & POHMELFS_IO_PERM_WRITE))
471 if (psb->active_state && (psb->active_state->state.ctl.prio >= st->ctl.prio))
472 st = &psb->active_state->state;
474 err = netfs_trans_push(t, st);
475 if (!err && (t->flags & NETFS_TRANS_SINGLE_DST))
479 mutex_unlock(&psb->state_lock);
481 dprintk("%s: fully sent t: %p, gen: %u, size: %u, page_num: %u, err: %d.\n",
482 __func__, t, t->gen, t->iovec.iov_len, t->page_num, err);
489 int netfs_trans_finish(struct netfs_trans *t, struct pohmelfs_sb *psb)
492 struct netfs_cmd *cmd = t->iovec.iov_base;
494 t->gen = atomic_inc_return(&psb->trans_gen);
496 cmd->size = t->iovec.iov_len - sizeof(struct netfs_cmd) +
497 t->attached_size + t->attached_pages * sizeof(struct netfs_cmd);
498 cmd->cmd = NETFS_TRANS;
502 if (psb->perform_crypto) {
503 cmd->ext = psb->crypto_attached_size;
504 cmd->csize = psb->crypto_attached_size;
507 dprintk("%s: t: %u, size: %u, iov_len: %zu, attached_size: %u, attached_pages: %u.\n",
508 __func__, t->gen, cmd->size, t->iovec.iov_len, t->attached_size, t->attached_pages);
509 err = pohmelfs_trans_crypt(t, psb);
512 netfs_convert_cmd(cmd);
513 dprintk("%s: trans: %llu, crypto_attached_size: %u, attached_size: %u, attached_pages: %d, trans_size: %u, err: %d.\n",
514 __func__, cmd->start, psb->crypto_attached_size, t->attached_size, t->attached_pages, cmd->size, err);
521 * Resend transaction to remote server(s).
522 * If new servers were added into superblock, we can try to send data
525 * It is called under superblock's state_lock, so we can safely
526 * dereference psb->state_list. Also, transaction's reference counter is
527 * bumped, so it can not go away under us, thus we can safely access all
528 * its members. State is locked.
530 * This function returns 0 if transaction was successfully sent to at
531 * least one destination target.
533 int netfs_trans_resend(struct netfs_trans *t, struct pohmelfs_sb *psb)
535 struct netfs_trans_dst *dst;
536 struct netfs_state *st;
537 struct pohmelfs_config *c;
538 int err, exist, error = -ENODEV;
540 list_for_each_entry(c, &psb->state_list, config_entry) {
544 spin_lock(&t->dst_lock);
545 list_for_each_entry(dst, &t->dst_list, trans_entry) {
546 if (st == dst->state) {
551 spin_unlock(&t->dst_lock);
554 if (!(t->flags & NETFS_TRANS_SINGLE_DST) ||
555 (c->config_entry.next == &psb->state_list)) {
556 dprintk("%s: resending st: %p, t: %p, gen: %u.\n",
557 __func__, st, t, t->gen);
558 err = netfs_trans_send(t, st);
565 dprintk("%s: pushing/resending st: %p, t: %p, gen: %u.\n",
566 __func__, st, t, t->gen);
567 err = netfs_trans_push(t, st);
571 if (t->flags & NETFS_TRANS_SINGLE_DST)
579 void *netfs_trans_add(struct netfs_trans *t, unsigned int size)
581 struct iovec *io = &t->iovec;
584 if (size > t->total_size) {
585 ptr = ERR_PTR(-EINVAL);
589 if (io->iov_len + size > t->total_size) {
590 dprintk("%s: too big size t: %p, gen: %u, iov_len: %zu, size: %u, total: %u.\n",
591 __func__, t, t->gen, io->iov_len, size, t->total_size);
592 ptr = ERR_PTR(-E2BIG);
596 ptr = io->iov_base + io->iov_len;
600 dprintk("%s: t: %p, gen: %u, size: %u, total: %zu.\n",
601 __func__, t, t->gen, size, io->iov_len);
605 void netfs_trans_free(struct netfs_trans *t)
608 pohmelfs_crypto_thread_make_ready(t->eng->thread);
612 struct netfs_trans *netfs_trans_alloc(struct pohmelfs_sb *psb, unsigned int size,
613 unsigned int flags, unsigned int nr)
615 struct netfs_trans *t;
616 unsigned int num, cont, pad, size_no_trans;
617 unsigned int crypto_added = 0;
618 struct netfs_cmd *cmd;
620 if (psb->perform_crypto)
621 crypto_added = psb->crypto_attached_size;
624 * |sizeof(struct netfs_trans)|
625 * |sizeof(struct netfs_cmd)| - transaction header
626 * |size| - buffer with requested size
627 * |padding| - crypto padding, zero bytes
628 * |nr * sizeof(struct page *)| - array of page pointers
630 * Overall size should be less than PAGE_SIZE for guaranteed allocation.
634 size = ALIGN(size, psb->crypto_align_size);
637 size_no_trans = size + sizeof(struct netfs_cmd) * 2 + crypto_added;
639 cont = sizeof(struct netfs_trans) + size_no_trans;
641 num = (PAGE_SIZE - cont)/sizeof(struct page *);
646 t = kzalloc(cont + nr*sizeof(struct page *), GFP_NOIO);
650 t->iovec.iov_base = (void *)(t + 1);
651 t->pages = (struct page **)(t->iovec.iov_base + size_no_trans);
654 * Reserving space for transaction header.
656 t->iovec.iov_len = sizeof(struct netfs_cmd) + crypto_added;
658 netfs_trans_init_static(t, nr, size_no_trans);
663 cmd = (struct netfs_cmd *)t->iovec.iov_base;
667 cmd->csize = crypto_added;
669 dprintk("%s: t: %p, gen: %u, size: %u, padding: %u, align_size: %u, flags: %x, "
670 "page_num: %u, base: %p, pages: %p.\n",
671 __func__, t, t->gen, size, pad, psb->crypto_align_size, flags, nr,
672 t->iovec.iov_base, t->pages);
680 int netfs_trans_init(void)
684 netfs_trans_dst = kmem_cache_create("netfs_trans_dst", sizeof(struct netfs_trans_dst),
686 if (!netfs_trans_dst)
689 netfs_trans_dst_pool = mempool_create_slab_pool(256, netfs_trans_dst);
690 if (!netfs_trans_dst_pool)
696 kmem_cache_destroy(netfs_trans_dst);
701 void netfs_trans_exit(void)
703 mempool_destroy(netfs_trans_dst_pool);
704 kmem_cache_destroy(netfs_trans_dst);