Skip to contentSkip to conversation

reiser4: Auto-punching holes: basic stuff

PATCH In review Edward Shishkin 1 participant 1 message Jul 19, 2015

lore
Share & tools
lore
#0 lore raw

PATCH 1/2 reiser4: Auto-punching holes: basic stuff

. Auto-punching holes: basic stuff;
. Handle empty nodes appeared after node conversions at flush time,
Cache a locked right neighbor in the struct flush_pos (to access it when current node becomes empty, and hence is removed from the tree).

---
 fs/reiser4/flush.c                     |  107 ++++++++++++++++++++++++---------
 fs/reiser4/flush.h                     |    4 -
 fs/reiser4/init_super.c                |    2 
 fs/reiser4/plugin/file/cryptcompress.c |   32 +++++++++
 fs/reiser4/plugin/file/cryptcompress.h |    1 
 fs/reiser4/plugin/item/ctail.c         |   75 +++++++++++++++++------
 fs/reiser4/super.h                     |    4 -
 7 files changed, 175 insertions(+), 50 deletions(-)
fs/reiser4/plugin/file/cryptcompress.c +30 -2
@@ -921,12 +921,34 @@ static unsigned deflate_overrun(struct i
 	return coa_overrun(inode_compression_plugin(inode), ilen);
 }
 
+static bool is_all_zero(char const* mem, size_t size)
+{
+	while (size-- > 0)
+		if (*mem++)
+			return false;
+	return true;
+}
+
+static inline bool should_punch_hole(struct tfm_cluster *tc)
+{
+	if (!reiser4_is_set(reiser4_get_current_sb(), REISER4_DONT_PUNCH_HOLES)
+	    && is_all_zero(tfm_stream_data(tc, INPUT_STREAM), tc->lsize)) {
+		/*
+		 * the logical cluster is filled with zeros,
+		 * so we'll punch a hole
+		 */
+		tc->all_zero = 1;
+		return true;
+	}
+	return false;
+}
+
 /* Estimating compressibility of a logical cluster by various
    policies represented by compression mode plugin.
    If this returns false, then compressor won't be called for
    the cluster of index @index.
 */
-static int should_compress(struct tfm_cluster * tc, cloff_t index,
+static int should_compress(struct tfm_cluster *tc, cloff_t index,
 			   struct inode *inode)
 {
 	compression_plugin *cplug = inode_compression_plugin(inode);
@@ -936,6 +958,12 @@ static int should_compress(struct tfm_cl
 	assert("edward-1322", cplug != NULL);
 	assert("edward-1323", mplug != NULL);
 
+	if (should_punch_hole(tc))
+		/*
+		 * we are about to punch a hole,
+		 * so don't compress data
+		 */
+		return 0;
 	return /* estimate by size */
 		(cplug->min_size_deflate ?
 		 tc->len >= cplug->min_size_deflate() :
@@ -3368,7 +3396,7 @@ static int prune_cryptcompress(struct in
 	       clust.dstat == UNPR_DISK_CLUSTER);
 
 	assert("edward-1191", inode->i_size == new_size);
-	assert("edward-1206", body_truncate_ok(inode, ridx));
+
  truncate_fake:
 	/* drop all the pages that don't have jnodes (i.e. pages
 	   which can not be truncated by cut_file_items() because
fs/reiser4/plugin/file/cryptcompress.h +1 -0
@@ -159,6 +159,7 @@ struct tfm_cluster {
 	int uptodate;
 	int lsize;        /* number of bytes in logical cluster */
 	int len;          /* length of the transform stream */
+	int all_zero;     /* logical cluster is filled with zeros */
 };
 
 static inline coa_t get_coa(struct tfm_cluster * tc, reiser4_compression_id id,
fs/reiser4/plugin/item/ctail.c +57 -18

139 lines not on this page · raw message

fs/reiser4/flush.h +3 -1
@@ -74,6 +74,8 @@ struct convert_info {
 	item_plugin *iplug;	/* current item plugin */
 	struct convert_item_info *itm;	/* current item info */
 	struct cluster_handle clust;	/* transform cluster */
+	lock_handle right_lock; /* lock handle of the right neighbor */
+	int right_locked;
 };
 
 typedef enum flush_position_state {
@@ -231,7 +233,7 @@ static inline int should_terminate_squal
 	    item_convert_count(pos) >= SQUALLOC_THRESHOLD;
 }
 
-#if 1
+#if REISER4_DEBUG
 #define check_convert_info(pos)						\
 do {							        	\
 	if (unlikely(should_convert_right_neighbor(pos))) {		\
fs/reiser4/flush.c +79 -28

144 lines not on this page · raw message

fs/reiser4/init_super.c +2 -0
@@ -496,6 +496,8 @@ int reiser4_init_super_data(struct super
 	PUSH_BIT_OPT("no_write_barrier", REISER4_NO_WRITE_BARRIER);
 	/* enable issuing of discard requests */
 	PUSH_BIT_OPT("discard", REISER4_DISCARD);
+	/* disable hole punching at flush time */
+	PUSH_BIT_OPT("dont_punch_holes", REISER4_DONT_PUNCH_HOLES);
 
 	PUSH_OPT(p, opts,
 	{
fs/reiser4/super.h +3 -1
@@ -53,7 +53,9 @@ typedef enum {
 	/* don't use write barriers in the log writer code. */
 	REISER4_NO_WRITE_BARRIER = 7,
 	/* enable issuing of discard requests */
-	REISER4_DISCARD = 8
+	REISER4_DISCARD = 8,
+	/* disable hole punching at flush time */
+	REISER4_DONT_PUNCH_HOLES = 9
 } reiser4_fs_flag;
 
 /*