hammer2 - Refactor file unlink w/open descriptor (3)
authorMatthew Dillon <dillon@apollo.backplane.com>
Fri, 13 Dec 2013 01:24:47 +0000 (17:24 -0800)
committerMatthew Dillon <dillon@apollo.backplane.com>
Fri, 13 Dec 2013 01:27:18 +0000 (17:27 -0800)
* Fix a bug where hammer2_inode_connect() was not calling
  hammer2_chain_lookup() to properly adjust the parent chain pointer
  to the correct insertion point when moving an unlinked-but-open file
  to the hidden directory.

  (triggered with poudriere which uses open/unlinked filesystem FIFO nodes).

* Minor documentation cleanup.

sys/vfs/hammer2/hammer2_chain.c
sys/vfs/hammer2/hammer2_flush.c
sys/vfs/hammer2/hammer2_inode.c

index 0eccfb3..548676d 100644 (file)
@@ -2491,6 +2491,11 @@ done:
  * insertion, based on the supplied key/keybits, and may involve creating
  * indirect blocks and moving other chains around via delete/duplicate.
  *
+ * THE CALLER MUST HAVE ALREADY PROPERLY SEEKED (*parentp) TO THE INSERTION
+ * POINT SANS ANY REQUIRED INDIRECT BLOCK CREATIONS DUE TO THE ARRAY BEING
+ * FULL.  This typically means that the caller is creating the chain after
+ * doing a hammer2_chain_lookup().
+ *
  * (*parentp) must be exclusive locked and may be replaced on return
  * depending on how much work the function had to do.
  *
@@ -2766,7 +2771,13 @@ done:
 /*
  * Replace (*chainp) with a duplicate in-memory chain structure which shares
  * the same core and media state as the orignal.  The original *chainp is
- * unlocked and the replacement will be returned locked.
+ * unlocked and the replacement will be returned locked.  The duplicated
+ * chain is inserted under (*parentp).
+ *
+ * THE CALLER MUST HAVE ALREADY PROPERLY SEEKED (*parentp) TO THE INSERTION
+ * POINT SANS ANY REQUIRED INDIRECT BLOCK CREATIONS DUE TO THE ARRAY BEING
+ * FULL.  This typically means that the caller is creating the chain after
+ * doing a hammer2_chain_lookup().
  *
  * The old chain must be in a DELETED state unless snapshot is non-zero.
  *
index 086b275..f07e8c2 100644 (file)
@@ -78,7 +78,7 @@ static void hammer2_rollup_stats(hammer2_chain_t *parent,
  * Can we ignore a chain for the purposes of flushing modifications
  * to the media?
  *
- * This code is no degenerate.  We used to have to distinguish between
+ * This code is now degenerate.  We used to have to distinguish between
  * deleted chains and deleted chains associated with inodes that were
  * still open.  This mechanic has been fixed so the function is now
  * a simple test.
index 06f74b6..d295947 100644 (file)
@@ -876,7 +876,9 @@ retry:
 
 /*
  * Connect the target inode represented by (*chainp) to the media topology
- * at (dip, name, len).
+ * at (dip, name, len).  The caller can pass a rough *chainp, this function
+ * will issue lookup()s to position the parent chain properly for the
+ * chain insertion.
  *
  * If hlink is TRUE this function creates an OBJTYPE_HARDLINK directory
  * entry instead of connecting (*chainp).
@@ -936,6 +938,14 @@ hammer2_inode_connect(hammer2_trans_t *trans,
                        nchain = NULL;
                        ++lhc;
                }
+       } else {
+               /*
+                * Reconnect to specific key (used when moving
+                * unlinked-but-open files into the hidden directory).
+                */
+               nchain = hammer2_chain_lookup(dchainp, &key_dummy,
+                                             lhc, lhc, &cache_index, 0);
+               KKASSERT(nchain == NULL);
        }
 
        if (error == 0) {
@@ -1419,8 +1429,8 @@ hammer2_inode_move_to_hidden(hammer2_trans_t *trans, hammer2_chain_t **chainp,
        pmp = chain->pmp;
        KKASSERT(pmp != NULL);
        KKASSERT(pmp->ihidden != NULL);
-
        hammer2_chain_delete(trans, chain, 0);
+
        dchain = hammer2_inode_lock_ex(pmp->ihidden);
         error = hammer2_inode_connect(trans, chainp, 0,
                                       pmp->ihidden, &dchain,