[patch 1/4] reiser4: fixups in cryptcompress plugin

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




Fix up the main search procedure of cryptcompress plugin:
. make full-fledged tree traversal in the case when we
  encountered empty right neighbor;
. unlock the left neighbor only in the case when we moved
  to right.

Signed-off-by: Edward Shishkin <edward.shishkin@xxxxxxxxx>
---
 fs/reiser4/carry_ops.c                 |    6 +
 fs/reiser4/forward.h                   |    4 -
 fs/reiser4/plugin/file/cryptcompress.c |  124 +++++++++++++++++++++++----------
 fs/reiser4/plugin/item/ctail.c         |    5 +
 4 files changed, 101 insertions(+), 38 deletions(-)

--- linux-3.5.3.orig/fs/reiser4/plugin/file/cryptcompress.c
+++ linux-3.5.3/fs/reiser4/plugin/file/cryptcompress.c
@@ -703,8 +703,11 @@ static void free_reserved4cluster(struct
 	ch->reserved = 0;
 }
 
-/* The core search procedure of the cryptcompress plugin.
-   If returned value is not cbk_errored, then current znode is locked */
+/*
+ * The core search procedure of the cryptcompress plugin.
+ * If returned value is not cbk_errored, then current position
+ * is locked.
+ */
 static int find_cluster_item(hint_t * hint,
 			     const reiser4_key * key, /* key of the item we are
 							 looking for */
@@ -713,7 +716,6 @@ static int find_cluster_item(hint_t * hi
 {
 	int result;
 	reiser4_key ikey;
-	int went_right = 0;
 	coord_t *coord = &hint->ext_coord.coord;
 	coord_t orig = *coord;
 
@@ -730,58 +732,110 @@ static int find_cluster_item(hint_t * hi
 		hint_set_valid(hint);
 	}
 	assert("edward-709", znode_is_any_locked(coord->node));
-
-	/* In-place lookup is going here, it means we just need to
-	   check if next item of the @coord match to the @keyhint) */
-
+	/*
+	 * Hint is valid, so we perform in-place lookup.
+	 * It means we just need to check if the next item in
+	 * the tree (relative to the current position @coord)
+	 * has key @key.
+	 *
+	 * Valid hint means in particular, that node is not
+	 * empty and at least one its item has been processed
+	 */
 	if (equal_to_rdk(coord->node, key)) {
-		result = goto_right_neighbor(coord, &hint->lh);
-		if (result == -E_NO_NEIGHBOR) {
-			assert("edward-1217", 0);
-			return RETERR(-EIO);
+		/*
+		 * Look for the item in the right neighbor
+		 */
+		lock_handle lh_right;
+
+		init_lh(&lh_right);
+		result = reiser4_get_right_neighbor(&lh_right, coord->node,
+				    znode_is_wlocked(coord->node) ?
+				    ZNODE_WRITE_LOCK : ZNODE_READ_LOCK,
+				    GN_CAN_USE_UPPER_LEVELS);
+		if (result) {
+			done_lh(&lh_right);
+			reiser4_unset_hint(hint);
+			if (result == -E_NO_NEIGHBOR)
+				return RETERR(-EIO);
+			return result;
 		}
-		if (result)
+		assert("edward-1218",
+		       equal_to_ldk(lh_right.node, key));
+		result = zload(lh_right.node);
+		if (result) {
+			done_lh(&lh_right);
+			reiser4_unset_hint(hint);
 			return result;
-		assert("edward-1218", equal_to_ldk(coord->node, key));
-		went_right = 1;
+		}
+		coord_init_first_unit_nocheck(coord, lh_right.node);
+
+		if (!coord_is_existing_item(coord)) {
+			zrelse(lh_right.node);
+			done_lh(&lh_right);
+			goto traverse_tree;
+		}
+		item_key_by_coord(coord, &ikey);
+		zrelse(coord->node);
+		if (unlikely(!keyeq(key, &ikey))) {
+			warning("edward-1608",
+				"Expected item not found. Fsck?");
+			done_lh(&lh_right);
+			goto not_found;
+		}
+		/*
+		 * item has been found in the right neighbor;
+		 * move lock to the right
+		 */
+		done_lh(&hint->lh);
+		move_lh(&hint->lh, &lh_right);
+
+		dclust_inc_extension_ncount(hint);
+
+		return CBK_COORD_FOUND;
 	} else {
+		/*
+		 *  Look for the item in the current node
+		 */
 		coord->item_pos++;
 		coord->unit_pos = 0;
 		coord->between = AT_UNIT;
-	}
-	result = zload(coord->node);
-	if (result)
-		return result;
-	assert("edward-1219", !node_is_empty(coord->node));
 
-	if (!coord_is_existing_item(coord)) {
+		result = zload(coord->node);
+		if (result) {
+			done_lh(&hint->lh);
+			return result;
+		}
+		if (!coord_is_existing_item(coord)) {
+			zrelse(coord->node);
+			goto not_found;
+		}
+		item_key_by_coord(coord, &ikey);
 		zrelse(coord->node);
-		goto not_found;
+		if (!keyeq(key, &ikey))
+			goto not_found;
+		/*
+		 * item has been found in the current node
+		 */
+		return CBK_COORD_FOUND;
 	}
-	item_key_by_coord(coord, &ikey);
-	zrelse(coord->node);
-	if (!keyeq(key, &ikey))
-		goto not_found;
-	/* Ok, item is found, update node counts */
-	if (went_right)
-		dclust_inc_extension_ncount(hint);
-	return CBK_COORD_FOUND;
-
  not_found:
-	assert("edward-1220", coord->item_pos > 0);
-	//coord->item_pos--;
-	/* roll back */
+	/*
+	 * The tree doesn't contain an item with @key;
+	 * roll back the coord
+	 */
 	*coord = orig;
 	ON_DEBUG(coord_update_v(coord));
 	return CBK_COORD_NOTFOUND;
 
  traverse_tree:
-	assert("edward-713", hint->lh.owner == NULL);
-	assert("edward-714", reiser4_schedulable());
 
 	reiser4_unset_hint(hint);
 	dclust_init_extension(hint);
 	coord_init_zero(coord);
+
+	assert("edward-713", hint->lh.owner == NULL);
+	assert("edward-714", reiser4_schedulable());
+
 	result = coord_by_key(current_tree, key, coord, &hint->lh,
 			      lock_mode, bias, LEAF_LEVEL, LEAF_LEVEL,
 			      CBK_UNIQUE | flags, ra_info);
--- linux-3.5.3.orig/fs/reiser4/carry_ops.c
+++ linux-3.5.3/fs/reiser4/carry_ops.c
@@ -943,7 +943,7 @@ static int enough_space_for_whole_flow(c
 #define MIN_FLOW_FRACTION 1
 static int enough_space_for_min_flow_fraction(carry_op * op)
 {
-	assert("vs-902", coord_is_after_rightmost(flow_insert_point(op)));
+	//assert("vs-902", coord_is_after_rightmost(flow_insert_point(op)));
 
 	return what_can_fit_into_node(op) >= MIN_FLOW_FRACTION;
 }
@@ -1096,6 +1096,10 @@ make_space_for_flow_insertion(carry_op *
 		/* whole flow fits into insert point node */
 		return 0;
 	}
+	if ((flags & COPI_SWEEP) &&
+	    enough_space_for_min_flow_fraction(op))
+		/* use the rest of space in the current node */
+		return 0;
 
 	if (!(flags & COPI_DONT_SHIFT_LEFT)
 	    && (make_space_by_shift_left(op, doing, todo) == 0)) {
--- linux-3.5.3.orig/fs/reiser4/forward.h
+++ linux-3.5.3/fs/reiser4/forward.h
@@ -224,7 +224,9 @@ typedef enum {
 	COPI_GO_RIGHT = (1 << 6),
 	/* try to step back into original node if insertion into new node
 	   fails after shifting data there. */
-	COPI_STEP_BACK = (1 << 7)
+	COPI_STEP_BACK = (1 << 7),
+	/* use all possible space in the node */
+	COPI_SWEEP = (1 << 8)
 } cop_insert_flag;
 
 typedef enum {
--- linux-3.5.3.orig/fs/reiser4/plugin/item/ctail.c
+++ linux-3.5.3/fs/reiser4/plugin/item/ctail.c
@@ -935,7 +935,10 @@ insert_cryptcompress_flow(coord_t * coor
 	data->length = 0;
 	data->data = NULL;
 
-	op->u.insert_flow.flags = COPI_DONT_SHIFT_LEFT | COPI_DONT_SHIFT_RIGHT;
+	op->u.insert_flow.flags =
+		COPI_SWEEP |
+		COPI_DONT_SHIFT_LEFT |
+		COPI_DONT_SHIFT_RIGHT;
 	op->u.insert_flow.insert_point = coord;
 	op->u.insert_flow.flow = f;
 	op->u.insert_flow.data = data;

[Index of Archives]     [Linux File System Development]     [Linux BTRFS]     [Linux NFS]     [Linux Filesystems]     [Ext4 Filesystem]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite Forum]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Device Mapper]     [Linux Resources]

  Powered by Linux