Skip to content

Commit

Permalink
HAMMER 60E/Many: Mirroring, bug fixes
Browse files Browse the repository at this point in the history
* Work on the mirror_tid propagation code.  The code now retries on
  EDEADLK so propagation is guaranteed to reach the root.

* Get most of the mirror_write code working.

* Add PFS support for NFS exports.  Change fid_reserved to fid_ext and use
  it to store the localization parameter that selects the PFS.  This isn't
  well tested yet.

* BUGFIX: Fix a bug in vol0_last_tid updates.  Flush sequences might
  not always update the field, creating issues with mirroring and snapshots.

* BUGFIX: Properly update the volume header CRC.

* CLEANUP: Fix some obj_id's that were u_int64_t's. They should be int64_t's.

* CLEANUP: #if 0 out unused code, remove other bits of unused code.
  • Loading branch information
Matthew Dillon committed Jul 7, 2008
1 parent 0dbb0ed commit adf0174
Show file tree
Hide file tree
Showing 11 changed files with 278 additions and 152 deletions.
9 changes: 6 additions & 3 deletions sys/vfs/hammer/hammer.h
Expand Up @@ -31,7 +31,7 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $DragonFly: src/sys/vfs/hammer/hammer.h,v 1.103 2008/07/05 18:59:27 dillon Exp $
* $DragonFly: src/sys/vfs/hammer/hammer.h,v 1.104 2008/07/07 00:24:31 dillon Exp $
*/
/*
* This header file contains structures used internally by the HAMMERFS
Expand Down Expand Up @@ -248,7 +248,7 @@ struct hammer_inode {
int flush_group;
TAILQ_ENTRY(hammer_inode) flush_entry;
struct hammer_record_list target_list; /* target of dependant recs */
u_int64_t obj_id; /* (key) object identifier */
int64_t obj_id; /* (key) object identifier */
hammer_tid_t obj_asof; /* (key) snapshot or 0 */
u_int32_t obj_localization; /* (key) pseudo-fs */
struct hammer_mount *hmp;
Expand Down Expand Up @@ -778,7 +778,7 @@ int hammer_vop_inactive(struct vop_inactive_args *);
int hammer_vop_reclaim(struct vop_reclaim_args *);
int hammer_get_vnode(struct hammer_inode *ip, struct vnode **vpp);
struct hammer_inode *hammer_get_inode(hammer_transaction_t trans,
hammer_inode_t dip, u_int64_t obj_id,
hammer_inode_t dip, int64_t obj_id,
hammer_tid_t asof, u_int32_t localization,
int flags, int *errorp);
void hammer_scan_inode_snapshots(hammer_mount_t hmp,
Expand Down Expand Up @@ -862,6 +862,9 @@ int hammer_init_cursor(hammer_transaction_t trans, hammer_cursor_t cursor,
void hammer_normalize_cursor(hammer_cursor_t cursor);
void hammer_done_cursor(hammer_cursor_t cursor);
int hammer_recover_cursor(hammer_cursor_t cursor);
void hammer_unlock_cursor(hammer_cursor_t cursor);
int hammer_lock_cursor(hammer_cursor_t cursor);
void hammer_dup_cursor(hammer_cursor_t ocursor, hammer_cursor_t ncursor);

void hammer_cursor_replaced_node(hammer_node_t onode, hammer_node_t nnode);
void hammer_cursor_removed_node(hammer_node_t onode, hammer_node_t parent,
Expand Down
106 changes: 65 additions & 41 deletions sys/vfs/hammer/hammer_btree.c
Expand Up @@ -31,7 +31,7 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $DragonFly: src/sys/vfs/hammer/hammer_btree.c,v 1.63 2008/07/05 18:59:27 dillon Exp $
* $DragonFly: src/sys/vfs/hammer/hammer_btree.c,v 1.64 2008/07/07 00:24:31 dillon Exp $
*/

/*
Expand Down Expand Up @@ -87,8 +87,8 @@ static int btree_split_internal(hammer_cursor_t cursor);
static int btree_split_leaf(hammer_cursor_t cursor);
static int btree_remove(hammer_cursor_t cursor);
static int btree_node_is_full(hammer_node_ondisk_t node);
static int hammer_btree_mirror_propagate(hammer_transaction_t trans,
hammer_node_t node, int index, hammer_tid_t mirror_tid);
static int hammer_btree_mirror_propagate(hammer_cursor_t cursor,
hammer_tid_t mirror_tid);
static void hammer_make_separator(hammer_base_elm_t key1,
hammer_base_elm_t key2, hammer_base_elm_t dest);

Expand Down Expand Up @@ -1777,6 +1777,8 @@ btree_split_leaf(hammer_cursor_t cursor)
return (error);
}

#if 0

/*
* Recursively correct the right-hand boundary's create_tid to (tid) as
* long as the rest of the key matches. We have to recurse upward in
Expand Down Expand Up @@ -1997,6 +1999,8 @@ hammer_btree_correct_lhb(hammer_cursor_t cursor, hammer_tid_t tid)
return (error);
}

#endif

/*
* Attempt to remove the locked, empty or want-to-be-empty B-Tree node at
* (cursor->node). Returns 0 on success, EDEADLK if we could not complete
Expand Down Expand Up @@ -2121,6 +2125,8 @@ hammer_btree_do_propagation(hammer_cursor_t cursor, hammer_inode_t ip,
hammer_btree_leaf_elm_t leaf)
{
hammer_pseudofs_inmem_t pfsm;
hammer_cursor_t ncursor;
hammer_tid_t mirror_tid;
int error;

/*
Expand All @@ -2134,10 +2140,28 @@ hammer_btree_do_propagation(hammer_cursor_t cursor, hammer_inode_t ip,
return;
}

error = hammer_btree_mirror_propagate(cursor->trans,
cursor->parent, cursor->parent_index,
cursor->node->ondisk->mirror_tid);
/* XXX */
/*
* This is a bit of a hack because we cannot deadlock or return
* EDEADLK here. The related operation has already completed and
* we must propagate the mirror_tid now regardless.
*
* Generate a new cursor which inherits the original's locks and
* unlock the original. Use the new cursor to propagate the
* mirror_tid. Then clean up the new cursor and reacquire locks
* on the original.
*
* hammer_dup_cursor() cannot dup locks. The dup inherits the
* original's locks and the original is tracked and must be
* re-locked.
*/
mirror_tid = cursor->node->ondisk->mirror_tid;
ncursor = kmalloc(sizeof(*ncursor), M_HAMMER, M_WAITOK | M_ZERO);
hammer_dup_cursor(cursor, ncursor);
error = hammer_btree_mirror_propagate(ncursor, mirror_tid);
KKASSERT(error == 0);
hammer_done_cursor(ncursor);
kfree(ncursor, M_HAMMER);
hammer_lock_cursor(cursor); /* shared-lock */
}


Expand All @@ -2151,47 +2175,47 @@ hammer_btree_do_propagation(hammer_cursor_t cursor, hammer_inode_t ip,
* adjusts the node's aggregation mirror_tid, and then recurses upwards.
*/
static int
hammer_btree_mirror_propagate(hammer_transaction_t trans, hammer_node_t node,
int index, hammer_tid_t mirror_tid)
hammer_btree_mirror_propagate(hammer_cursor_t cursor, hammer_tid_t mirror_tid)
{
hammer_btree_internal_elm_t elm;
hammer_node_t parent;
int parent_index;
hammer_node_t node;
int error;

KKASSERT (node->ondisk->type == HAMMER_BTREE_TYPE_INTERNAL);

/*
* Adjust the node's element
*/
elm = &node->ondisk->elms[index].internal;
if (elm->mirror_tid >= mirror_tid)
return(0);
hammer_modify_node(trans, node, &elm->mirror_tid,
sizeof(elm->mirror_tid));
elm->mirror_tid = mirror_tid;
hammer_modify_node_done(node);
for (;;) {
error = hammer_cursor_up(cursor);
if (error == 0)
error = hammer_cursor_upgrade(cursor);
while (error == EDEADLK) {
hammer_recover_cursor(cursor);
error = hammer_cursor_upgrade(cursor);
}
if (error)
break;
node = cursor->node;
KKASSERT (node->ondisk->type == HAMMER_BTREE_TYPE_INTERNAL);

/*
* Adjust the node's mirror_tid aggregator
*/
if (node->ondisk->mirror_tid >= mirror_tid)
return(0);
hammer_modify_node_field(trans, node, mirror_tid);
node->ondisk->mirror_tid = mirror_tid;
hammer_modify_node_done(node);
/*
* Adjust the node's element
*/
elm = &node->ondisk->elms[cursor->index].internal;
if (elm->mirror_tid >= mirror_tid)
break;
hammer_modify_node(cursor->trans, node, &elm->mirror_tid,
sizeof(elm->mirror_tid));
elm->mirror_tid = mirror_tid;
hammer_modify_node_done(node);

error = 0;
if (node->ondisk->parent) {
parent = hammer_btree_get_parent(node, &parent_index,
&error, 1);
if (parent) {
hammer_btree_mirror_propagate(trans, parent,
parent_index, mirror_tid);
hammer_unlock(&parent->lock);
hammer_rel_node(parent);
}
/*
* Adjust the node's mirror_tid aggregator
*/
if (node->ondisk->mirror_tid >= mirror_tid)
return(0);
hammer_modify_node_field(cursor->trans, node, mirror_tid);
node->ondisk->mirror_tid = mirror_tid;
hammer_modify_node_done(node);
}
if (error == ENOENT)
error = 0;
return(error);
}

Expand Down

0 comments on commit adf0174

Please sign in to comment.