HAMMER 60C/many: Mirroring
authorMatthew Dillon <dillon@dragonflybsd.org>
Fri, 4 Jul 2008 07:25:36 +0000 (07:25 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Fri, 4 Jul 2008 07:25:36 +0000 (07:25 +0000)
* Clean up the B-Tree mirror_tid update code, rewiring it a bit
  to reduce code pollution.

* Properly detect the mirroring mode (master, slave, or no-mirror mode)
  via the pfs configuration.

sys/vfs/hammer/hammer.h
sys/vfs/hammer/hammer_btree.c
sys/vfs/hammer/hammer_cursor.c
sys/vfs/hammer/hammer_inode.c
sys/vfs/hammer/hammer_mirror.c
sys/vfs/hammer/hammer_object.c
sys/vfs/hammer/hammer_prune.c
sys/vfs/hammer/hammer_subs.c

index 3780f85..de04094 100644 (file)
@@ -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.101 2008/07/03 04:24:51 dillon Exp $
+ * $DragonFly: src/sys/vfs/hammer/hammer.h,v 1.102 2008/07/04 07:25:36 dillon Exp $
  */
 /*
  * This header file contains structures used internally by the HAMMERFS
@@ -389,6 +389,12 @@ typedef struct hammer_record *hammer_record_t;
 #define HAMMER_RECF_WANTED             0x0040  /* wanted by the frontend */
 #define HAMMER_RECF_CONVERT_DELETE     0x0100 /* special case */
 
+/*
+ * hammer_delete_at_cursor() flags
+ */
+#define HAMMER_DELETE_ADJUST           0x0001
+#define HAMMER_DELETE_DESTROY          0x0002
+
 /*
  * In-memory structures representing on-disk structures.
  */
@@ -794,7 +800,8 @@ int hammer_ip_next(hammer_cursor_t cursor);
 int    hammer_ip_resolve_data(hammer_cursor_t cursor);
 int    hammer_ip_delete_record(hammer_cursor_t cursor, hammer_inode_t ip,
                        hammer_tid_t tid);
-int    hammer_delete_at_cursor(hammer_cursor_t cursor, int64_t *stat_bytes);
+int    hammer_delete_at_cursor(hammer_cursor_t cursor, int delete_flags,
+                       int64_t *stat_bytes);
 int    hammer_ip_check_directory_empty(hammer_transaction_t trans,
                        hammer_inode_t ip);
 int    hammer_sync_hmp(hammer_mount_t hmp, int waitfor);
@@ -853,7 +860,6 @@ int hammer_init_cursor(hammer_transaction_t trans, hammer_cursor_t cursor,
 int    hammer_reinit_cursor(hammer_cursor_t cursor);
 void   hammer_normalize_cursor(hammer_cursor_t cursor);
 void   hammer_done_cursor(hammer_cursor_t cursor);
-void   hammer_mem_done(hammer_cursor_t cursor);
 
 int    hammer_btree_lookup(hammer_cursor_t cursor);
 int    hammer_btree_first(hammer_cursor_t cursor);
@@ -862,12 +868,10 @@ int       hammer_btree_extract(hammer_cursor_t cursor, int flags);
 int    hammer_btree_iterate(hammer_cursor_t cursor);
 int    hammer_btree_iterate_reverse(hammer_cursor_t cursor);
 int    hammer_btree_insert(hammer_cursor_t cursor,
-                           hammer_btree_leaf_elm_t elm);
+                           hammer_btree_leaf_elm_t elm, int *doprop);
 int    hammer_btree_delete(hammer_cursor_t cursor);
-int    hammer_btree_mirror_propagate(hammer_transaction_t trans,
-                           hammer_node_t node, int index,
-                           hammer_tid_t mirror_tid);
-
+void   hammer_btree_do_propagation(hammer_cursor_t cursor, hammer_inode_t ip,
+                           hammer_btree_leaf_elm_t leaf);
 int    hammer_btree_cmp(hammer_base_elm_t key1, hammer_base_elm_t key2);
 int    hammer_btree_chkts(hammer_tid_t ts, hammer_base_elm_t key);
 int    hammer_btree_correct_rhb(hammer_cursor_t cursor, hammer_tid_t tid);
index 257af53..b71c63a 100644 (file)
@@ -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.61 2008/07/02 21:57:54 dillon Exp $
+ * $DragonFly: src/sys/vfs/hammer/hammer_btree.c,v 1.62 2008/07/04 07:25:36 dillon Exp $
  */
 
 /*
@@ -87,19 +87,11 @@ 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 void hammer_make_separator(hammer_base_elm_t key1,
                        hammer_base_elm_t key2, hammer_base_elm_t dest);
 
-static __inline
-int
-hammer_do_mirror_propagate(hammer_cursor_t cursor)
-{
-       return(1);
-       /*
-            (cursor->trans->hmp->hflags & (HMNT_MASTERID|HMNT_SLAVE)))
-       */
-}
-
 /*
  * Iterate records after a search.  The cursor is iterated forwards past
  * the current record until a record matching the key-range requirements
@@ -678,12 +670,14 @@ hammer_btree_extract(hammer_cursor_t cursor, int flags)
  * ENOSPC is returned if there is no room to insert a new record.
  */
 int
-hammer_btree_insert(hammer_cursor_t cursor, hammer_btree_leaf_elm_t elm)
+hammer_btree_insert(hammer_cursor_t cursor, hammer_btree_leaf_elm_t elm,
+                   int *doprop)
 {
        hammer_node_ondisk_t node;
        int i;
        int error;
 
+       *doprop = 0;
        if ((error = hammer_cursor_upgrade_node(cursor)) != 0)
                return(error);
        ++hammer_stats_btree_inserts;
@@ -715,22 +709,15 @@ hammer_btree_insert(hammer_cursor_t cursor, hammer_btree_leaf_elm_t elm)
         * Update the leaf node's aggregate mirror_tid for mirroring
         * support.
         */
-       if (node->mirror_tid < elm->base.delete_tid)
+       if (node->mirror_tid < elm->base.delete_tid) {
                node->mirror_tid = elm->base.delete_tid;
-       if (node->mirror_tid < elm->base.create_tid)
+               *doprop = 1;
+       }
+       if (node->mirror_tid < elm->base.create_tid) {
                node->mirror_tid = elm->base.create_tid;
-       hammer_modify_node_done(cursor->node);
-
-       /*
-        * What we really want to do is propagate mirror_tid all the way
-        * up the parent chain to the B-Tree root.  That would be
-        * ultra-expensive, though.
-        */
-       if (cursor->parent && hammer_do_mirror_propagate(cursor)) {
-               hammer_btree_mirror_propagate(cursor->trans, cursor->parent,
-                                             cursor->parent_index,
-                                             node->mirror_tid);
+               *doprop = 1;
        }
+       hammer_modify_node_done(cursor->node);
 
        /*
         * Debugging sanity checks.
@@ -2052,19 +2039,6 @@ btree_remove(hammer_cursor_t cursor)
 
        parent = cursor->parent;
 
-       /*
-        * If another thread deadlocked trying to propagate mirror_tid up
-        * we have to finish the job before deleting node. XXX
-        */
-       if (parent->ondisk->mirror_tid < node->ondisk->mirror_tid &&
-           hammer_do_mirror_propagate(cursor)) {
-               hammer_btree_mirror_propagate(cursor->trans,
-                                             parent,
-                                             cursor->parent_index,
-                                             node->ondisk->mirror_tid);
-
-       }
-
        /*
         * Attempt to remove the parent's reference to the child.  If the
         * parent would become empty we have to recurse.  If we fail we 
@@ -2129,6 +2103,42 @@ btree_remove(hammer_cursor_t cursor)
        return (error);
 }
 
+/*
+ * Propagate cursor->trans->tid up the B-Tree starting at the current
+ * cursor position using pseudofs info gleaned from the passed inode.
+ *
+ * The passed inode has no relationship to the cursor position other
+ * then being in the same pseudofs as the insertion or deletion we
+ * are propagating the mirror_tid for.
+ */
+void
+hammer_btree_do_propagation(hammer_cursor_t cursor, hammer_inode_t ip,
+                           hammer_btree_leaf_elm_t leaf)
+{
+       hammer_pseudofs_inmem_t pfsm;
+       int error;
+
+       /*
+        * We only propagate the mirror_tid up if we are in master or slave
+        * mode.  We do not bother if we are in no-mirror mode.
+        */
+       pfsm = ip->pfsm;
+       KKASSERT(pfsm != NULL);
+       if (pfsm->pfsd.master_id < 0 &&
+           (pfsm->pfsd.mirror_flags & HAMMER_PFSD_SLAVE) == 0) {
+               return;
+       }
+
+       /*
+        * Get as far as we can without deadlocking.
+        */
+       error = hammer_btree_mirror_propagate(cursor->trans,
+                                       cursor->parent, cursor->parent_index,
+                                       cursor->node->ondisk->mirror_tid);
+       /* XXX */
+}
+
+
 /*
  * Propagate a mirror TID update upwards through the B-Tree to the root.
  *
@@ -2138,7 +2148,7 @@ btree_remove(hammer_cursor_t cursor)
  * This function syncs mirror_tid at the specified internal node's element,
  * adjusts the node's aggregation mirror_tid, and then recurses upwards.
  */
-int
+static int
 hammer_btree_mirror_propagate(hammer_transaction_t trans, hammer_node_t node,
                              int index, hammer_tid_t mirror_tid)
 {
@@ -2161,7 +2171,7 @@ hammer_btree_mirror_propagate(hammer_transaction_t trans, hammer_node_t node,
        hammer_modify_node_done(node);
 
        /*
-        * Adjust the node's mirror_tid aggragator
+        * Adjust the node's mirror_tid aggregator
         */
        if (node->ondisk->mirror_tid >= mirror_tid)
                return(0);
@@ -2170,7 +2180,6 @@ hammer_btree_mirror_propagate(hammer_transaction_t trans, hammer_node_t node,
        hammer_modify_node_done(node);
 
        error = 0;
-               error = 0;
        if (node->ondisk->parent) {
                parent = hammer_btree_get_parent(node, &parent_index,
                                                 &error, 1);
index 0ee9592..549bf1e 100644 (file)
@@ -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_cursor.c,v 1.35 2008/07/02 21:57:54 dillon Exp $
+ * $DragonFly: src/sys/vfs/hammer/hammer_cursor.c,v 1.36 2008/07/04 07:25:36 dillon Exp $
  */
 
 /*
@@ -172,12 +172,13 @@ hammer_done_cursor(hammer_cursor_t cursor)
                 cursor->record_buffer = NULL;
         }
        if ((ip = cursor->ip) != NULL) {
-               hammer_mem_done(cursor);
+               if (cursor->iprec) {
+                       hammer_rel_mem_record(cursor->iprec);
+                       cursor->iprec = NULL;
+               }
                 KKASSERT(ip->cursor_ip_refs > 0);
                 --ip->cursor_ip_refs;
-#if 1
                hammer_unlock(&ip->lock);
-#endif
                 cursor->ip = NULL;
         }
 
index 8276b33..de0407c 100644 (file)
@@ -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_inode.c,v 1.92 2008/07/03 04:24:51 dillon Exp $
+ * $DragonFly: src/sys/vfs/hammer/hammer_inode.c,v 1.93 2008/07/04 07:25:36 dillon Exp $
  */
 
 #include "hammer.h"
@@ -719,6 +719,7 @@ retry:
                        ip->flags |= HAMMER_INODE_PFSD;
                }
        } else {
+               kprintf("cannot load pfsm error %d\n", error);
                kfree(pfsm, M_HAMMER);
        }
        return(error);
@@ -1854,7 +1855,6 @@ hammer_flush_inode_done(hammer_inode_t ip)
         * flush group to the new one.
         */
        if (ip->flags & HAMMER_INODE_WOULDBLOCK) {
-               kprintf("B");
                ip->flush_state = HAMMER_FST_IDLE;
                hammer_flush_inode_core(ip, HAMMER_FLUSH_SIGNAL);
                ip->flags &= ~HAMMER_INODE_WOULDBLOCK;
index 94e5722..ea112e3 100644 (file)
@@ -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_mirror.c,v 1.5 2008/07/02 21:57:54 dillon Exp $
+ * $DragonFly: src/sys/vfs/hammer/hammer_mirror.c,v 1.6 2008/07/04 07:25:36 dillon Exp $
  */
 /*
  * HAMMER mirroring ioctls - serialize and deserialize modifications made
@@ -46,7 +46,7 @@ static int hammer_mirror_update(hammer_cursor_t cursor,
                                struct hammer_ioc_mrecord *mrec);
 static int hammer_mirror_write(hammer_cursor_t cursor,
                                struct hammer_ioc_mrecord *mrec,
-                               char *udata);
+                               hammer_inode_t ip, char *udata);
 static int hammer_mirror_localize_data(hammer_data_ondisk_t data,
                                hammer_btree_leaf_elm_t leaf);
 
@@ -199,6 +199,8 @@ failed:
 /*
  * Copy records from userland to the target mirror.  Records which already
  * exist may only have their delete_tid updated.
+ *
+ * The passed ip is the root ip of the pseudofs
  */
 int
 hammer_ioc_mirror_write(hammer_transaction_t trans, hammer_inode_t ip,
@@ -282,7 +284,7 @@ retry:
                        hammer_sync_unlock(trans);
                } else if (error == ENOENT && mrec.leaf.base.delete_tid == 0) {
                        hammer_sync_lock_sh(trans);
-                       error = hammer_mirror_write(&cursor, &mrec,
+                       error = hammer_mirror_write(&cursor, &mrec, ip,
                                                    uptr + head_size);
                        hammer_sync_unlock(trans);
                }
@@ -357,12 +359,13 @@ hammer_mirror_update(hammer_cursor_t cursor, struct hammer_ioc_mrecord *mrec)
 static
 int
 hammer_mirror_write(hammer_cursor_t cursor, struct hammer_ioc_mrecord *mrec,
-                   char *udata)
+                   hammer_inode_t ip, char *udata)
 {
        hammer_buffer_t data_buffer = NULL;
        hammer_off_t ndata_offset;
        void *ndata;
        int error;
+       int doprop;
        int wanted_skip = 0;
 
        if (mrec->leaf.data_len && mrec->leaf.data_offset) {
@@ -405,7 +408,9 @@ hammer_mirror_write(hammer_cursor_t cursor, struct hammer_ioc_mrecord *mrec,
        /*
         * Physical insertion
         */
-       error = hammer_btree_insert(cursor, &mrec->leaf);
+       error = hammer_btree_insert(cursor, &mrec->leaf, &doprop);
+       if (error == 0 && doprop)
+               hammer_btree_do_propagation(cursor, ip, &mrec->leaf);
 
 failed:
        /*
index 4cf883c..25a421a 100644 (file)
@@ -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_object.c,v 1.81 2008/07/02 21:57:54 dillon Exp $
+ * $DragonFly: src/sys/vfs/hammer/hammer_object.c,v 1.82 2008/07/04 07:25:36 dillon Exp $
  */
 
 #include "hammer.h"
@@ -560,15 +560,6 @@ hammer_mem_first(hammer_cursor_t cursor)
        return(ENOENT);
 }
 
-void
-hammer_mem_done(hammer_cursor_t cursor)
-{
-        if (cursor->iprec) {
-               hammer_rel_mem_record(cursor->iprec);
-               cursor->iprec = NULL;
-       }
-}
-
 /************************************************************************
  *                  HAMMER IN-MEMORY RECORD FUNCTIONS                  *
  ************************************************************************
@@ -994,6 +985,7 @@ hammer_ip_sync_record_cursor(hammer_cursor_t cursor, hammer_record_t record)
        int bytes;
        void *bdata;
        int error;
+       int doprop;
 
        KKASSERT(record->flush_state == HAMMER_FST_FLUSH);
        KKASSERT(record->flags & HAMMER_RECF_INTERLOCK_BE);
@@ -1144,7 +1136,7 @@ hammer_ip_sync_record_cursor(hammer_cursor_t cursor, hammer_record_t record)
                record->leaf.data_crc = 0;
        }
 
-       error = hammer_btree_insert(cursor, &record->leaf);
+       error = hammer_btree_insert(cursor, &record->leaf, &doprop);
        if (hammer_debug_inode && error)
                kprintf("BTREE INSERT error %d @ %016llx:%d key %016llx\n", error, cursor->node->node_offset, cursor->index, record->leaf.base.key);
 
@@ -1156,6 +1148,10 @@ hammer_ip_sync_record_cursor(hammer_cursor_t cursor, hammer_record_t record)
         * visibility on the synced entry.
         */
        if (error == 0) {
+               if (doprop) {
+                       hammer_btree_do_propagation(cursor, record->ip,
+                                                   &record->leaf);
+               }
                if (record->flags & HAMMER_RECF_CONVERT_DELETE) {
                        KKASSERT(record->type == HAMMER_MEM_RECORD_ADD);
                        record->flags &= ~HAMMER_RECF_DELETED_FE;
@@ -1893,7 +1889,6 @@ hammer_ip_delete_record(hammer_cursor_t cursor, hammer_inode_t ip,
        hammer_btree_elm_t elm;
        hammer_mount_t hmp;
        int error;
-       int dodelete;
 
        KKASSERT(cursor->flags & HAMMER_CURSOR_BACKEND);
        KKASSERT(tid != 0);
@@ -1937,80 +1932,134 @@ hammer_ip_delete_record(hammer_cursor_t cursor, hammer_inode_t ip,
        error = hammer_btree_extract(cursor, HAMMER_CURSOR_GET_LEAF);
        elm = NULL;
 
-       /*
-        * If we were mounted with the nohistory option, we physically
-        * delete the record.
-        */
-       dodelete = hammer_nohistory(ip);
-
        if (error == 0) {
-               error = hammer_cursor_upgrade(cursor);
-               if (error == 0) {
-                       elm = &cursor->node->ondisk->elms[cursor->index];
-                       hammer_modify_node(cursor->trans, cursor->node,
-                                          elm, sizeof(*elm));
-                       elm->leaf.base.delete_tid = tid;
-                       elm->leaf.delete_ts = cursor->trans->time32;
-                       hammer_modify_node_done(cursor->node);
-
-                       /*
-                        * An on-disk record cannot have the same delete_tid
-                        * as its create_tid.  In a chain of record updates
-                        * this could result in a duplicate record.
-                        */
-                       KKASSERT(elm->leaf.base.delete_tid != elm->leaf.base.create_tid);
-               }
-       }
-
-       if (error == 0 && dodelete) {
-               error = hammer_delete_at_cursor(cursor, NULL);
-               if (error) {
-                       panic("hammer_ip_delete_record: unable to physically delete the record!\n");
-                       error = 0;
-               }
+               error = hammer_delete_at_cursor(
+                               cursor,
+                               HAMMER_DELETE_ADJUST | hammer_nohistory(ip),
+                               NULL);
        }
        return(error);
 }
 
+/*
+ * Delete the B-Tree element at the current cursor and do any necessary
+ * mirror propagation.
+ *
+ * The cursor must be properly positioned for an iteration on return but
+ * may be pointing at an internal element.
+ */
 int
-hammer_delete_at_cursor(hammer_cursor_t cursor, int64_t *stat_bytes)
+hammer_delete_at_cursor(hammer_cursor_t cursor, int delete_flags,
+                       int64_t *stat_bytes)
 {
+       struct hammer_btree_leaf_elm save_leaf;
+       hammer_btree_leaf_elm_t leaf;
+       hammer_node_t node;
        hammer_btree_elm_t elm;
        hammer_off_t data_offset;
        int32_t data_len;
        u_int16_t rec_type;
        int error;
+       int doprop;
 
-       elm = &cursor->node->ondisk->elms[cursor->index];
+       error = hammer_cursor_upgrade(cursor);
+       if (error)
+               return(error);
+
+       node = cursor->node;
+       elm = &node->ondisk->elms[cursor->index];
+       leaf = &elm->leaf;
        KKASSERT(elm->base.btype == HAMMER_BTREE_TYPE_RECORD);
 
-       data_offset = elm->leaf.data_offset;
-       data_len = elm->leaf.data_len;
-       rec_type = elm->leaf.base.rec_type;
+       /*
+        * Adjust the delete_tid.  Update the mirror_tid propagation field
+        * as well.
+        */
+       doprop = 0;
+       if (delete_flags & HAMMER_DELETE_ADJUST) {
+               hammer_modify_node(cursor->trans, node, elm, sizeof(*elm));
+               elm->leaf.base.delete_tid = cursor->trans->tid;
+               elm->leaf.delete_ts = cursor->trans->time32;
+               hammer_modify_node_done(node);
+
+               if (elm->leaf.base.delete_tid > node->ondisk->mirror_tid) {
+                       hammer_modify_node_field(cursor->trans, node, mirror_tid);
+                       node->ondisk->mirror_tid = elm->leaf.base.delete_tid;
+                       hammer_modify_node_done(node);
+                       doprop = 1;
+               }
 
-       error = hammer_btree_delete(cursor);
-       if (error == 0) {
                /*
-                * This forces a fixup for the iteration because
-                * the cursor is now either sitting at the 'next'
-                * element or sitting at the end of a leaf.
+                * Adjust for the iteration.  We have deleted the current
+                * element and want to clear ATEDISK so the iteration does
+                * not skip the element after, which now becomes the current
+                * element.
                 */
                if ((cursor->flags & HAMMER_CURSOR_DISKEOF) == 0) {
                        cursor->flags |= HAMMER_CURSOR_DELBTREE;
                        cursor->flags &= ~HAMMER_CURSOR_ATEDISK;
                }
+
+               /*
+                * An on-disk record cannot have the same delete_tid
+                * as its create_tid.  In a chain of record updates
+                * this could result in a duplicate record.
+                */
+               KKASSERT(elm->leaf.base.delete_tid !=
+                        elm->leaf.base.create_tid);
        }
-       if (error == 0) {
-               switch(data_offset & HAMMER_OFF_ZONE_MASK) {
-               case HAMMER_ZONE_LARGE_DATA:
-               case HAMMER_ZONE_SMALL_DATA:
-               case HAMMER_ZONE_META:
-                       hammer_blockmap_free(cursor->trans,
-                                            data_offset, data_len);
-                       break;
-               default:
-                       break;
+
+       /*
+        * Destroy the B-Tree element if asked (typically if a nohistory
+        * file or mount, or when called by the pruning code).
+        *
+        * Adjust the ATEDISK flag to properly support iterations.
+        */
+       if (delete_flags & HAMMER_DELETE_DESTROY) {
+               data_offset = elm->leaf.data_offset;
+               data_len = elm->leaf.data_len;
+               rec_type = elm->leaf.base.rec_type;
+               if (doprop) {
+                       save_leaf = elm->leaf;
+                       leaf = &save_leaf;
                }
+
+               error = hammer_btree_delete(cursor);
+               if (error == 0) {
+                       /*
+                        * This forces a fixup for the iteration because
+                        * the cursor is now either sitting at the 'next'
+                        * element or sitting at the end of a leaf.
+                        */
+                       if ((cursor->flags & HAMMER_CURSOR_DISKEOF) == 0) {
+                               cursor->flags |= HAMMER_CURSOR_DELBTREE;
+                               cursor->flags &= ~HAMMER_CURSOR_ATEDISK;
+                       }
+               }
+               if (error == 0) {
+                       switch(data_offset & HAMMER_OFF_ZONE_MASK) {
+                       case HAMMER_ZONE_LARGE_DATA:
+                       case HAMMER_ZONE_SMALL_DATA:
+                       case HAMMER_ZONE_META:
+                               hammer_blockmap_free(cursor->trans,
+                                                    data_offset, data_len);
+                               break;
+                       default:
+                               break;
+                       }
+               }
+       }
+
+       /*
+        * mirror_tid propagation occurs if the node's mirror_tid had to be
+        * updated while adjusting the delete_tid.
+        *
+        * This occurs when deleting even in nohistory mode, but does not
+        * occur when pruning an already-deleted node.
+        */
+       if (doprop) {
+               KKASSERT(cursor->ip != NULL);
+               hammer_btree_do_propagation(cursor, cursor->ip, leaf);
        }
        return (error);
 }
index 56974cd..7f1103e 100644 (file)
@@ -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_prune.c,v 1.11 2008/07/01 17:30:42 dillon Exp $
+ * $DragonFly: src/sys/vfs/hammer/hammer_prune.c,v 1.12 2008/07/04 07:25:36 dillon Exp $
  */
 
 #include "hammer.h"
@@ -179,6 +179,7 @@ retry:
                        isdir = (elm->base.rec_type == HAMMER_RECTYPE_DIRENTRY);
 
                        error = hammer_delete_at_cursor(&cursor,
+                                                       HAMMER_DELETE_DESTROY,
                                                        &prune->stat_bytes);
                        if (error)
                                break;
index 6ef57be..a732294 100644 (file)
@@ -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_subs.c,v 1.28 2008/06/23 21:42:48 dillon Exp $
+ * $DragonFly: src/sys/vfs/hammer/hammer_subs.c,v 1.29 2008/07/04 07:25:36 dillon Exp $
  */
 /*
  * HAMMER structural locking
@@ -396,13 +396,16 @@ hammer_get_obj_type(enum vtype vtype)
        /* not reached */
 }
 
+/*
+ * Return flags for hammer_delete_at_cursor()
+ */
 int
 hammer_nohistory(hammer_inode_t ip)
 {
        if (ip->hmp->hflags & HMNT_NOHISTORY)
-               return(1);
+               return(HAMMER_DELETE_DESTROY);
        if (ip->ino_data.uflags & (SF_NOHISTORY|UF_NOHISTORY))
-               return(1);
+               return(HAMMER_DELETE_DESTROY);
        return(0);
 }