2 * Copyright (c) 2008 The DragonFly Project. All rights reserved.
4 * This code is derived from software contributed to The DragonFly Project
5 * by Matthew Dillon <dillon@backplane.com>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * 3. Neither the name of The DragonFly Project nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific, prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * $DragonFly: src/sys/vfs/hammer/hammer_mirror.c,v 1.1 2008/06/24 17:38:17 dillon Exp $
37 * HAMMER mirroring ioctls - serialize and deserialize modifications made
44 hammer_ioc_mirror_read(hammer_transaction_t trans
, hammer_inode_t ip
,
45 struct hammer_ioc_mirror_rw
*mirror
)
47 struct hammer_cursor cursor
;
48 hammer_btree_elm_t elm
;
51 if ((mirror
->key_beg
.localization
| mirror
->key_end
.localization
) &
52 HAMMER_LOCALIZE_PSEUDOFS_MASK
) {
55 if (hammer_btree_cmp(&mirror
->key_beg
, &mirror
->key_end
) > 0)
58 mirror
->key_cur
= mirror
->key_beg
;
59 mirror
->key_cur
.localization
+= ip
->obj_localization
;
62 error
= hammer_init_cursor(trans
, &cursor
, NULL
, NULL
);
64 hammer_done_cursor(&cursor
);
67 cursor
.key_beg
= mirror
->key_cur
;
68 cursor
.key_end
= mirror
->key_end
;
69 cursor
.key_end
.localization
+= ip
->obj_localization
;
71 cursor
.flags
|= HAMMER_CURSOR_END_INCLUSIVE
;
72 cursor
.flags
|= HAMMER_CURSOR_BACKEND
;
75 * This flag allows the btree scan code to return internal nodes
76 * at every index, giving the mirroring code the ability to skip
77 * whole sub-trees based on mirror_tid.
79 cursor
.flags
|= HAMMER_CURSOR_MIRRORING
;
81 error
= hammer_btree_first(&cursor
);
84 * Internal or Leaf node
86 elm
= &cursor
.node
->ondisk
->elms
[cursor
.index
];
87 reblock
->key_cur
.obj_id
= elm
->base
.obj_id
;
88 reblock
->key_cur
.localization
= elm
->base
.localization
;
91 * Yield to more important tasks
93 if ((error
= hammer_signal_check(trans
->hmp
)) != 0)
95 if (trans
->hmp
->sync_lock
.wanted
) {
96 tsleep(trans
, 0, "hmrslo", hz
/ 10);
98 if (trans
->hmp
->locked_dirty_count
+
99 trans
->hmp
->io_running_count
> hammer_limit_dirtybufs
) {
100 hammer_flusher_async(trans
->hmp
);
101 tsleep(trans
, 0, "hmrslo", hz
/ 10);
106 * Acquiring the sync_lock prevents the operation from
107 * crossing a synchronization boundary.
109 * NOTE: cursor.node may have changed on return.
111 hammer_sync_lock_sh(trans
);
112 error
= hammer_reblock_helper(reblock
, &cursor
, elm
);
113 hammer_sync_unlock(trans
);
116 cursor
.flags
|= HAMMER_CURSOR_ATEDISK
;
117 error
= hammer_btree_iterate(&cursor
);
122 hammer_done_cursor(&cursor
);
123 if (error
== EDEADLK
)
125 if (error
== EINTR
) {
126 reblock
->head
.flags
|= HAMMER_IOC_HEAD_INTR
;
130 mirror
->key_cur
.localization
&= HAMMER_LOCALIZE_MASK
;