Skip to contentSkip to conversation

reiser4: rewrite handling compressed files at flush time

PATCH New Edward Shishkin 1 participant 1 message Nov 30, 2014

lore
Share & tools
lore
#0 lore raw

PATCH 1/3 reiser4: rewrite handling compressed files at flush time

This is mostly equivalent transform.
The result looks better, there are more chances to understand what is going on.

---

---
 fs/reiser4/flush.c                     |  222 ++++++++-----
 fs/reiser4/flush.h                     |   80 +---
 fs/reiser4/plugin/file/cryptcompress.h |    9 
 fs/reiser4/plugin/item/ctail.c         |  563 +++++++++++++++++++--------------
 4 files changed, 518 insertions(+), 356 deletions(-)
fs/reiser4/flush.c +143 -79
@@ -1535,7 +1535,7 @@ out:
 static void item_convert_invariant(flush_pos_t *pos)
 {
 	assert("edward-1225", coord_is_existing_item(&pos->coord));
-	if (chaining_data_present(pos)) {
+	if (convert_data_attached(pos)) {
 		item_plugin *iplug = item_convert_plug(pos);
 
 		assert("edward-1000",
@@ -1550,15 +1550,32 @@ static void item_convert_invariant(flush
 
 #endif
 
-/* Scan node items starting from the first one and apply for each
-   item its flush ->convert() method (if any). This method may
-   resize/kill the item so the tree will be changed.
-*/
+/*
+ * Scan all node's items and apply for each one
+ * its ->convert() method. This method may:
+ * . resize the item;
+ * . kill the item;
+ * . insert a group of items/nodes on the right,
+ *   which possess the following properties:
+ *   . all new nodes are dirty and not convertible;
+ *   . for all new items ->convert() method is a noop.
+ *
+ * NOTE: this function makes the tree unbalanced!
+ * This intended to be used by flush squalloc() in a
+ * combination with squeeze procedure.
+ *
+ * GLOSSARY
+ *
+ * Chained nodes and items.
+ *   Two neighboring nodes @left and @right are chained,
+ *   iff the last item of @left and the first item of @right
+ *   belong to the same item cluster. In this case those
+ *   items are called chained.
+ */
 static int convert_node(flush_pos_t *pos, znode * node)
 {
 	int ret = 0;
 	item_plugin *iplug;
-
 	assert("edward-304", pos != NULL);
 	assert("edward-305", pos->child == NULL);
 	assert("edward-475", znode_convertible(node));
@@ -1587,34 +1604,68 @@ static int convert_node(flush_pos_t *pos
 		assert("edward-307", pos->child == NULL);
 
 		if (coord_next_item(&pos->coord)) {
-			/* node is over */
-
-			if (!chaining_data_present(pos))
-				/* finished this node */
-				break;
-			if (should_chain_next_node(pos)) {
-				/* go to next node */
-				move_chaining_data(pos, 0/* to next node */);
+			/*
+			 * node is over
+			 */
+			if (convert_data_attached(pos))
+				/*
+				 * the last item was convertible and
+				 * there still is an unprocesssed flow
+				 */
+				if (next_node_is_chained(pos)) {
+					/*
+					 * next node contains items of
+					 * the same disk cluster,
+					 * so finish with this node
+					 */
+					update_chaining_state(pos, 0/* move
+								       to next
+								       node */);
+					break;
+				}
+				else {
+					/*
+					 * perform one more iteration
+					 * for the same item and the
+					 * rest of flow
+					 */
+					update_chaining_state(pos, 1/* this
+								       node */);
+				}
+			else
+				/*
+				 * the last item wasn't convertible, or
+				 * convert date was detached in the last
+				 * iteration,
+				 * go to next node
+				 */
 				break;
-			}
-			/* repeat this node */
-			move_chaining_data(pos, 1/* this node */);
-			continue;
-		}
-		/* Node is not over.
-		   Check if there is attached convert data.
-		   If so roll one item position back and repeat
-		   on this node
-		 */
-		if (chaining_data_present(pos)) {
+		} else {
+			/*
+			 * Node is not over, item position got decremented.
+			 */
+			if (convert_data_attached(pos)) {
+				/*
+				 * disk cluster should be increased, so roll
+				 * one item position back and perform the
+				 * iteration with the previous item and the
+				 * rest of attached data
+				 */
+				if (iplug != item_plugin_by_coord(&pos->coord))
+					set_item_convert_count(pos, 0);
 
-			if (iplug != item_plugin_by_coord(&pos->coord))
-				set_item_convert_count(pos, 0);
+				ret = coord_prev_item(&pos->coord);
+				assert("edward-1003", !ret);
 
-			ret = coord_prev_item(&pos->coord);
-			assert("edward-1003", !ret);
-
-			move_chaining_data(pos, 1/* this node */);
+				update_chaining_state(pos, 1/* this node */);
+			}
+			else
+				/*
+				 * previous item was't convertible, or
+				 * convert date was detached in the last
+				 * iteration, go to next item
+				 */
+				;
 		}
 	}
 	JF_CLR(ZJNODE(node), JNODE_CONVERTIBLE);
@@ -1863,8 +1914,10 @@ out:
 	return ret;
 }
 
-/* Process nodes on leaf level until unformatted node or rightmost node in the
- * slum reached.  */
+/*
+ * Process nodes on leaf level until unformatted node or
+ * rightmost node in the slum reached
+ */
 static int handle_pos_on_formatted(flush_pos_t *pos)
 {
 	int ret;
@@ -1874,32 +1927,33 @@ static int handle_pos_on_formatted(flush
 	init_lh(&right_lock);
 	init_load_count(&right_load);
 
-	if (should_convert_node(pos, pos->lock.node)) {
+	if (znode_convertible(pos->lock.node)) {
 		ret = convert_node(pos, pos->lock.node);
 		if (ret)
 			return ret;
 	}
-
 	while (1) {
 		int expected;
-		expected = should_convert_next_node(pos);
+		expected = should_convert_right_neighbor(pos);
 		ret = neighbor_in_slum(pos->lock.node, &right_lock, RIGHT_SIDE,
 				       ZNODE_WRITE_LOCK, !expected, expected);
 		if (ret) {
 			if (expected)
 				warning("edward-1495",
-				"Expected neighbor not found (ret = %d). Fsck?",
+		        "Right neighbor is expected but not found (%d). Fsck?",
 					ret);
 			break;
 		}
-
-		/* we don't prep(allocate) nodes for flushing twice. This can be
+		/*
+		 * we don't prep(allocate) nodes for flushing twice. This can be
 		 * suboptimal, or it can be optimal. For now we choose to live
 		 * with the risk that it will be suboptimal because it would be
-		 * quite complex to code it to be smarter. */
+		 * quite complex to code it to be smarter.
+		 */
 		if (znode_check_flushprepped(right_lock.node)
 		    && !znode_convertible(right_lock.node)) {
-			assert("edward-1005", !should_convert_next_node(pos));
+			assert("edward-1005",
+			       !should_convert_right_neighbor(pos));
 			pos_stop(pos);
 			break;
 		}
@@ -1907,59 +1961,67 @@ static int handle_pos_on_formatted(flush
 		ret = incr_load_count_znode(&right_load, right_lock.node);
 		if (ret)
 			break;
-		if (should_convert_node(pos, right_lock.node)) {
+		if (znode_convertible(right_lock.node)) {
 			ret = convert_node(pos, right_lock.node);
 			if (ret)
 				break;
-			if (node_is_empty(right_lock.node)) {
-				/* node became empty after converting, repeat */
+			if (unlikely(node_is_empty(right_lock.node))) {
+				/*
+				 * node became empty after convertion,
+				 * skip this
+				 */
 				done_load_count(&right_load);
 				done_lh(&right_lock);
 				continue;
 			}
 		}
-
-		/* squeeze _before_ going upward. */
-		ret =
-		    squeeze_right_neighbor(pos, pos->lock.node,
-					   right_lock.node);
+		/*
+		 * Current node and its right neighbor are converted.
+		 * Squeeze them _before_ going upward.
+		 */
+		ret = squeeze_right_neighbor(pos, pos->lock.node,
+					     right_lock.node);
 		if (ret < 0)
 			break;
 
+		if (node_is_empty(right_lock.node)) {
+			/*
+                         * right node was squeezed completely,
+                         * skip this
+                         */
+                        done_load_count(&right_load);
+                        done_lh(&right_lock);
+                        continue;
+                }
 		if (znode_check_flushprepped(right_lock.node)) {
-			if (should_convert_next_node(pos)) {
-				/* in spite of flushprepped status of the node,
-				   its right slum neighbor should be converted*/
+			if (should_convert_right_neighbor(pos)) {
+				/*
+				 * in spite of flushprepped status of the node,
+				 * its right slum neighbor should be converted
+				 */
 				assert("edward-953", convert_data(pos));
 				assert("edward-954", item_convert_data(pos));
 
-				if (node_is_empty(right_lock.node)) {
-					done_load_count(&right_load);
-					done_lh(&right_lock);
-				} else
-					move_flush_pos(pos, &right_lock,
-						       &right_load, NULL);
+				move_flush_pos(pos, &right_lock, &right_load, NULL);
 				continue;
+			} else {
+				pos_stop(pos);
+				break;
 			}
-			pos_stop(pos);
-			break;
-		}
-
-		if (node_is_empty(right_lock.node)) {
-			/* repeat if right node was squeezed completely */
-			done_load_count(&right_load);
-			done_lh(&right_lock);
-			continue;
 		}
-
-		/* parent(right_lock.node) has to be processed before
-		 * (right_lock.node) due to "parent-first" allocation order. */
-		ret =
-		    check_parents_and_squalloc_upper_levels(pos, pos->lock.node,
-							    right_lock.node);
+		/*
+		 * parent(right_lock.node) has to be processed before
+		 * (right_lock.node) due to "parent-first" allocation
+		 * order
+		 */
+		ret = check_parents_and_squalloc_upper_levels(pos,
+							      pos->lock.node,
+							      right_lock.node);
 		if (ret)
 			break;
-		/* (re)allocate _after_ going upward */
+		/*
+		 * (re)allocate _after_ going upward
+		 */
 		ret = lock_parent_and_allocate_znode(right_lock.node, pos);
 		if (ret)
 			break;
@@ -1967,8 +2029,9 @@ static int handle_pos_on_formatted(flush
 			set_item_convert_count(pos, 0);
 			break;
 		}
-
-		/* advance the flush position to the right neighbor */
+		/*
+		 * advance the flush position to the right neighbor
+		 */
 		move_flush_pos(pos, &right_lock, &right_load, NULL);
 
 		ret = rapid_flush(pos);
@@ -1978,9 +2041,10 @@ static int handle_pos_on_formatted(flush
 	check_convert_info(pos);
 	done_load_count(&right_load);
 	done_lh(&right_lock);
-
-	/* This function indicates via pos whether to stop or go to twig or
-	 * continue on current level. */
+	/*
+	 * This function indicates via pos whether to stop or go to twig or
+	 * continue on current level
+	 */
 	return ret;
 
 }
fs/reiser4/flush.h +34 -46

117 lines not on this page · raw message

fs/reiser4/plugin/file/cryptcompress.h +5 -4
@@ -136,10 +136,11 @@ static inline void free_ts_data(struct t
 
 /* Write modes for item conversion in flush convert phase */
 typedef enum {
-	CRC_APPEND_ITEM = 1,
-	CRC_OVERWRITE_ITEM = 2,
-	CRC_CUT_ITEM = 3
-} cryptcompress_write_mode_t;
+	CTAIL_INVAL_CONVERT_MODE = 0,
+	CTAIL_APPEND_ITEM = 1,
+	CTAIL_OVERWRITE_ITEM = 2,
+	CTAIL_CUT_ITEM = 3
+} ctail_convert_mode_t;
 
 typedef enum {
 	LC_INVAL  = 0,   /* invalid value */
fs/reiser4/plugin/item/ctail.c +336 -227

738 lines not on this page · raw message