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:MSG_MORE
;
106 err
= kernel_sendpage(st
->socket
, page
, 0, size
, msg
.msg_flags
);
108 printk("%s: %d/%d failed to send transaction page: t: %p, gen: %u, size: %u, err: %d.\n",
109 __func__
, i
, t
->page_num
, t
, t
->gen
, size
, err
);
115 dprintk("%s: %d/%d sent t: %p, gen: %u, page: %p/%p, size: %u.\n",
116 __func__
, i
, t
->page_num
, t
, t
->gen
, page
, p
, size
);
127 printk("%s: t: %p, gen: %u, err: %d.\n", __func__
, t
, t
->gen
, err
);
128 netfs_state_exit(st
);
135 int netfs_trans_send(struct netfs_trans
*t
, struct netfs_state
*st
)
140 BUG_ON(!t
->iovec
.iov_len
);
141 BUG_ON(t
->iovec
.iov_len
> 1024*1024*1024);
143 netfs_state_lock_send(st
);
145 err
= netfs_state_init(st
);
147 goto err_out_unlock_return
;
150 msg
.msg_iov
= &t
->iovec
;
154 msg
.msg_control
= NULL
;
155 msg
.msg_controllen
= 0;
156 msg
.msg_flags
= MSG_WAITALL
;
158 if (t
->attached_pages
)
159 msg
.msg_flags
|= MSG_MORE
;
161 err
= kernel_sendmsg(st
->socket
, &msg
, (struct kvec
*)msg
.msg_iov
, 1, t
->iovec
.iov_len
);
163 printk("%s: failed to send contig transaction: t: %p, gen: %u, size: %zu, err: %d.\n",
164 __func__
, t
, t
->gen
, t
->iovec
.iov_len
, err
);
167 goto err_out_unlock_return
;
170 dprintk("%s: sent %s transaction: t: %p, gen: %u, size: %zu, page_num: %u.\n",
171 __func__
, (t
->page_num
)?"partial":"full",
172 t
, t
->gen
, t
->iovec
.iov_len
, t
->page_num
);
175 if (t
->attached_pages
)
176 err
= netfs_trans_send_pages(t
, st
);
178 err_out_unlock_return
:
180 if (st
->need_reset
) {
181 netfs_state_exit(st
);
183 netfs_state_unlock_send(st
);
185 dprintk("%s: t: %p, gen: %u, err: %d.\n",
186 __func__
, t
, t
->gen
, err
);
192 static inline int netfs_trans_cmp(unsigned int gen
, unsigned int new)
201 struct netfs_trans_dst
*netfs_trans_search(struct netfs_state
*st
, unsigned int gen
)
203 struct rb_root
*root
= &st
->trans_root
;
204 struct rb_node
*n
= root
->rb_node
;
205 struct netfs_trans_dst
*tmp
, *ret
= NULL
;
206 struct netfs_trans
*t
;
210 tmp
= rb_entry(n
, struct netfs_trans_dst
, state_entry
);
213 cmp
= netfs_trans_cmp(t
->gen
, gen
);
227 static int netfs_trans_insert(struct netfs_trans_dst
*ndst
, struct netfs_state
*st
)
229 struct rb_root
*root
= &st
->trans_root
;
230 struct rb_node
**n
= &root
->rb_node
, *parent
= NULL
;
231 struct netfs_trans_dst
*ret
= NULL
, *tmp
;
232 struct netfs_trans
*t
= NULL
, *new = ndst
->trans
;
238 tmp
= rb_entry(parent
, struct netfs_trans_dst
, state_entry
);
241 cmp
= netfs_trans_cmp(t
->gen
, new->gen
);
243 n
= &parent
->rb_left
;
245 n
= &parent
->rb_right
;
253 printk("%s: exist: old: gen: %u, flags: %x, send_time: %lu, "
254 "new: gen: %u, flags: %x, send_time: %lu.\n",
255 __func__
, t
->gen
, t
->flags
, ret
->send_time
,
256 new->gen
, new->flags
, ndst
->send_time
);
260 rb_link_node(&ndst
->state_entry
, parent
, n
);
261 rb_insert_color(&ndst
->state_entry
, root
);
262 ndst
->send_time
= jiffies
;
267 int netfs_trans_remove_nolock(struct netfs_trans_dst
*dst
, struct netfs_state
*st
)
269 if (dst
&& dst
->state_entry
.rb_parent_color
) {
270 rb_erase(&dst
->state_entry
, &st
->trans_root
);
271 dst
->state_entry
.rb_parent_color
= 0;
277 static int netfs_trans_remove_state(struct netfs_trans_dst
*dst
)
280 struct netfs_state
*st
= dst
->state
;
282 mutex_lock(&st
->trans_lock
);
283 ret
= netfs_trans_remove_nolock(dst
, st
);
284 mutex_unlock(&st
->trans_lock
);
290 * Create new destination for given transaction associated with given network state.
291 * Transaction's reference counter is bumped and will be dropped when either
292 * reply is received or when async timeout detection task will fail resending
293 * and drop transaction.
295 static int netfs_trans_push_dst(struct netfs_trans
*t
, struct netfs_state
*st
)
297 struct netfs_trans_dst
*dst
;
300 dst
= mempool_alloc(netfs_trans_dst_pool
, GFP_KERNEL
);
310 mutex_lock(&st
->trans_lock
);
311 err
= netfs_trans_insert(dst
, st
);
312 mutex_unlock(&st
->trans_lock
);
317 spin_lock(&t
->dst_lock
);
318 list_add_tail(&dst
->trans_entry
, &t
->dst_list
);
319 spin_unlock(&t
->dst_lock
);
326 mempool_free(dst
, netfs_trans_dst_pool
);
330 static void netfs_trans_free_dst(struct netfs_trans_dst
*dst
)
332 netfs_trans_put(dst
->trans
);
333 mempool_free(dst
, netfs_trans_dst_pool
);
336 static void netfs_trans_remove_dst(struct netfs_trans_dst
*dst
)
338 if (netfs_trans_remove_state(dst
))
339 netfs_trans_free_dst(dst
);
343 * Drop destination transaction entry when we know it.
345 void netfs_trans_drop_dst(struct netfs_trans_dst
*dst
)
347 struct netfs_trans
*t
= dst
->trans
;
349 spin_lock(&t
->dst_lock
);
350 list_del_init(&dst
->trans_entry
);
351 spin_unlock(&t
->dst_lock
);
353 netfs_trans_remove_dst(dst
);
357 * Drop destination transaction entry when we know it and when we
358 * already removed dst from state tree.
360 void netfs_trans_drop_dst_nostate(struct netfs_trans_dst
*dst
)
362 struct netfs_trans
*t
= dst
->trans
;
364 spin_lock(&t
->dst_lock
);
365 list_del_init(&dst
->trans_entry
);
366 spin_unlock(&t
->dst_lock
);
368 netfs_trans_free_dst(dst
);
372 * This drops destination transaction entry from appropriate network state
373 * tree and drops related reference counter. It is possible that transaction
374 * will be freed here if its reference counter hits zero.
375 * Destination transaction entry will be freed.
377 void netfs_trans_drop_trans(struct netfs_trans
*t
, struct netfs_state
*st
)
379 struct netfs_trans_dst
*dst
, *tmp
, *ret
= NULL
;
381 spin_lock(&t
->dst_lock
);
382 list_for_each_entry_safe(dst
, tmp
, &t
->dst_list
, trans_entry
) {
383 if (dst
->state
== st
) {
385 list_del(&dst
->trans_entry
);
389 spin_unlock(&t
->dst_lock
);
392 netfs_trans_remove_dst(ret
);
396 * This drops destination transaction entry from appropriate network state
397 * tree and drops related reference counter. It is possible that transaction
398 * will be freed here if its reference counter hits zero.
399 * Destination transaction entry will be freed.
401 void netfs_trans_drop_last(struct netfs_trans
*t
, struct netfs_state
*st
)
403 struct netfs_trans_dst
*dst
, *tmp
, *ret
;
405 spin_lock(&t
->dst_lock
);
406 ret
= list_entry(t
->dst_list
.prev
, struct netfs_trans_dst
, trans_entry
);
407 if (ret
->state
!= st
) {
409 list_for_each_entry_safe(dst
, tmp
, &t
->dst_list
, trans_entry
) {
410 if (dst
->state
== st
) {
412 list_del_init(&dst
->trans_entry
);
417 list_del(&ret
->trans_entry
);
419 spin_unlock(&t
->dst_lock
);
422 netfs_trans_remove_dst(ret
);
425 static int netfs_trans_push(struct netfs_trans
*t
, struct netfs_state
*st
)
429 err
= netfs_trans_push_dst(t
, st
);
433 err
= netfs_trans_send(t
, st
);
437 if (t
->flags
& NETFS_TRANS_SINGLE_DST
)
438 pohmelfs_switch_active(st
->psb
);
444 netfs_trans_drop_last(t
, st
);
449 int netfs_trans_finish_send(struct netfs_trans
*t
, struct pohmelfs_sb
*psb
)
451 struct pohmelfs_config
*c
;
453 struct netfs_state
*st
;
455 dprintk("%s: t: %p, gen: %u, size: %u, page_num: %u, active: %p.\n",
456 __func__
, t
, t
->gen
, t
->iovec
.iov_len
, t
->page_num
, psb
->active_state
);
458 mutex_lock(&psb
->state_lock
);
459 list_for_each_entry(c
, &psb
->state_list
, config_entry
) {
462 if (t
->flags
& NETFS_TRANS_SINGLE_DST
) {
463 if (!(st
->ctl
.perm
& POHMELFS_IO_PERM_READ
))
466 if (!(st
->ctl
.perm
& POHMELFS_IO_PERM_WRITE
))
470 if (psb
->active_state
&& (psb
->active_state
->state
.ctl
.prio
>= st
->ctl
.prio
))
471 st
= &psb
->active_state
->state
;
473 err
= netfs_trans_push(t
, st
);
474 if (!err
&& (t
->flags
& NETFS_TRANS_SINGLE_DST
))
478 mutex_unlock(&psb
->state_lock
);
480 dprintk("%s: fully sent t: %p, gen: %u, size: %u, page_num: %u, err: %d.\n",
481 __func__
, t
, t
->gen
, t
->iovec
.iov_len
, t
->page_num
, err
);
488 int netfs_trans_finish(struct netfs_trans
*t
, struct pohmelfs_sb
*psb
)
491 struct netfs_cmd
*cmd
= t
->iovec
.iov_base
;
493 t
->gen
= atomic_inc_return(&psb
->trans_gen
);
495 cmd
->size
= t
->iovec
.iov_len
- sizeof(struct netfs_cmd
) +
496 t
->attached_size
+ t
->attached_pages
* sizeof(struct netfs_cmd
);
497 cmd
->cmd
= NETFS_TRANS
;
501 if (psb
->perform_crypto
) {
502 cmd
->ext
= psb
->crypto_attached_size
;
503 cmd
->csize
= psb
->crypto_attached_size
;
506 dprintk("%s: t: %u, size: %u, iov_len: %zu, attached_size: %u, attached_pages: %u.\n",
507 __func__
, t
->gen
, cmd
->size
, t
->iovec
.iov_len
, t
->attached_size
, t
->attached_pages
);
508 err
= pohmelfs_trans_crypt(t
, psb
);
511 netfs_convert_cmd(cmd
);
512 dprintk("%s: trans: %llu, crypto_attached_size: %u, attached_size: %u, attached_pages: %d, trans_size: %u, err: %d.\n",
513 __func__
, cmd
->start
, psb
->crypto_attached_size
, t
->attached_size
, t
->attached_pages
, cmd
->size
, err
);
520 * Resend transaction to remote server(s).
521 * If new servers were added into superblock, we can try to send data
524 * It is called under superblock's state_lock, so we can safely
525 * dereference psb->state_list. Also, transaction's reference counter is
526 * bumped, so it can not go away under us, thus we can safely access all
527 * its members. State is locked.
529 * This function returns 0 if transaction was successfully sent to at
530 * least one destination target.
532 int netfs_trans_resend(struct netfs_trans
*t
, struct pohmelfs_sb
*psb
)
534 struct netfs_trans_dst
*dst
;
535 struct netfs_state
*st
;
536 struct pohmelfs_config
*c
;
537 int err
, exist
, error
= -ENODEV
;
539 list_for_each_entry(c
, &psb
->state_list
, config_entry
) {
543 spin_lock(&t
->dst_lock
);
544 list_for_each_entry(dst
, &t
->dst_list
, trans_entry
) {
545 if (st
== dst
->state
) {
550 spin_unlock(&t
->dst_lock
);
553 if (!(t
->flags
& NETFS_TRANS_SINGLE_DST
) ||
554 (c
->config_entry
.next
== &psb
->state_list
)) {
555 dprintk("%s: resending st: %p, t: %p, gen: %u.\n",
556 __func__
, st
, t
, t
->gen
);
557 err
= netfs_trans_send(t
, st
);
564 dprintk("%s: pushing/resending st: %p, t: %p, gen: %u.\n",
565 __func__
, st
, t
, t
->gen
);
566 err
= netfs_trans_push(t
, st
);
570 if (t
->flags
& NETFS_TRANS_SINGLE_DST
)
578 void *netfs_trans_add(struct netfs_trans
*t
, unsigned int size
)
580 struct iovec
*io
= &t
->iovec
;
583 if (size
> t
->total_size
) {
584 ptr
= ERR_PTR(-EINVAL
);
588 if (io
->iov_len
+ size
> t
->total_size
) {
589 dprintk("%s: too big size t: %p, gen: %u, iov_len: %zu, size: %u, total: %u.\n",
590 __func__
, t
, t
->gen
, io
->iov_len
, size
, t
->total_size
);
591 ptr
= ERR_PTR(-E2BIG
);
595 ptr
= io
->iov_base
+ io
->iov_len
;
599 dprintk("%s: t: %p, gen: %u, size: %u, total: %zu.\n",
600 __func__
, t
, t
->gen
, size
, io
->iov_len
);
604 void netfs_trans_free(struct netfs_trans
*t
)
607 pohmelfs_crypto_thread_make_ready(t
->eng
->thread
);
611 struct netfs_trans
*netfs_trans_alloc(struct pohmelfs_sb
*psb
, unsigned int size
,
612 unsigned int flags
, unsigned int nr
)
614 struct netfs_trans
*t
;
615 unsigned int num
, cont
, pad
, size_no_trans
;
616 unsigned int crypto_added
= 0;
617 struct netfs_cmd
*cmd
;
619 if (psb
->perform_crypto
)
620 crypto_added
= psb
->crypto_attached_size
;
623 * |sizeof(struct netfs_trans)|
624 * |sizeof(struct netfs_cmd)| - transaction header
625 * |size| - buffer with requested size
626 * |padding| - crypto padding, zero bytes
627 * |nr * sizeof(struct page *)| - array of page pointers
629 * Overall size should be less than PAGE_SIZE for guaranteed allocation.
633 size
= ALIGN(size
, psb
->crypto_align_size
);
636 size_no_trans
= size
+ sizeof(struct netfs_cmd
) * 2 + crypto_added
;
638 cont
= sizeof(struct netfs_trans
) + size_no_trans
;
640 num
= (PAGE_SIZE
- cont
)/sizeof(struct page
*);
645 t
= kzalloc(cont
+ nr
*sizeof(struct page
*), GFP_NOIO
);
649 t
->iovec
.iov_base
= (void *)(t
+ 1);
650 t
->pages
= (struct page
**)(t
->iovec
.iov_base
+ size_no_trans
);
653 * Reserving space for transaction header.
655 t
->iovec
.iov_len
= sizeof(struct netfs_cmd
) + crypto_added
;
657 netfs_trans_init_static(t
, nr
, size_no_trans
);
662 cmd
= (struct netfs_cmd
*)t
->iovec
.iov_base
;
666 cmd
->csize
= crypto_added
;
668 dprintk("%s: t: %p, gen: %u, size: %u, padding: %u, align_size: %u, flags: %x, "
669 "page_num: %u, base: %p, pages: %p.\n",
670 __func__
, t
, t
->gen
, size
, pad
, psb
->crypto_align_size
, flags
, nr
,
671 t
->iovec
.iov_base
, t
->pages
);
679 int netfs_trans_init(void)
683 netfs_trans_dst
= kmem_cache_create("netfs_trans_dst", sizeof(struct netfs_trans_dst
),
685 if (!netfs_trans_dst
)
688 netfs_trans_dst_pool
= mempool_create_slab_pool(256, netfs_trans_dst
);
689 if (!netfs_trans_dst_pool
)
695 kmem_cache_destroy(netfs_trans_dst
);
700 void netfs_trans_exit(void)
702 mempool_destroy(netfs_trans_dst_pool
);
703 kmem_cache_destroy(netfs_trans_dst
);