From: Hans Reiser <reiser@namesys.com>

This is an update for reiser4 crypto file plugin

Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/fs/reiser4/cluster.h                  |    2 
 25-akpm/fs/reiser4/plugin/compress/compress.c |   57 +++++------
 25-akpm/fs/reiser4/plugin/cryptcompress.c     |  124 ++++++++++++++------------
 25-akpm/fs/reiser4/plugin/cryptcompress.h     |    1 
 25-akpm/fs/reiser4/plugin/item/ctail.c        |    6 -
 25-akpm/fs/reiser4/plugin/plugin.h            |    2 
 6 files changed, 100 insertions(+), 92 deletions(-)

diff -puN fs/reiser4/cluster.h~reiser4-crypto-update fs/reiser4/cluster.h
--- 25/fs/reiser4/cluster.h~reiser4-crypto-update	Fri Nov 12 16:01:48 2004
+++ 25-akpm/fs/reiser4/cluster.h	Fri Nov 12 16:01:48 2004
@@ -178,7 +178,7 @@ void set_nrpages_by_inode(reiser4_cluste
 int grab_cluster_pages(struct inode * inode, reiser4_cluster_t * clust);
 void release_cluster_pages(reiser4_cluster_t * clust, int from);
 void put_cluster_handle(reiser4_cluster_t * clust, tfm_action act);
-int grab_tfm_stream(struct inode * inode, tfm_cluster_t * tc, tfm_stream_id id);
+int grab_tfm_stream(struct inode * inode, tfm_cluster_t * tc, tfm_action act, tfm_stream_id id);
 int tfm_cluster_is_uptodate (tfm_cluster_t * tc);
 void tfm_cluster_set_uptodate (tfm_cluster_t * tc);
 void tfm_cluster_clr_uptodate (tfm_cluster_t * tc);
diff -puN fs/reiser4/plugin/compress/compress.c~reiser4-crypto-update fs/reiser4/plugin/compress/compress.c
--- 25/fs/reiser4/plugin/compress/compress.c~reiser4-crypto-update	Fri Nov 12 16:01:48 2004
+++ 25-akpm/fs/reiser4/plugin/compress/compress.c	Fri Nov 12 16:01:48 2004
@@ -17,6 +17,12 @@
 
 #define NONE_NRCOPY 1
 
+static int
+null_min_tfm_size(void)
+{
+	return 1;
+}
+
 static void
 null_compress(coa_t coa, __u8 * src_first, unsigned src_len,
 	      __u8 * dst_first, unsigned *dst_len)
@@ -114,6 +120,12 @@ static void gzip1_free(coa_t coa, tfm_ac
 	return;
 }
 
+static int
+gzip1_min_tfm_size(void)
+{
+	return 64;
+}
+
 static void
 gzip1_compress(coa_t coa, __u8 * src_first, unsigned src_len,
 	       __u8 * dst_first, unsigned *dst_len)
@@ -121,22 +133,13 @@ gzip1_compress(coa_t coa, __u8 * src_fir
 #if REISER4_GZIP_TFM
 	int ret = 0;
 	struct z_stream_s stream;
-	compression_plugin *cplug =
-	    compression_plugin_by_id(GZIP1_COMPRESSION_ID);
 
 	xmemset(&stream, 0, sizeof(stream));
 
 	assert("edward-842", coa != NULL);
 	assert("edward-875", src_len != 0);
 
-	if (!coa) {
-		coa_t tmp = cplug->alloc(TFM_WRITE);
-		if (IS_ERR(tmp))
-			goto rollback;
-		stream.workspace = tmp;
-	} else
-		stream.workspace = coa;
-
+	stream.workspace = coa;
 	ret = zlib_deflateInit2(&stream, GZIP1_DEF_LEVEL, Z_DEFLATED,
 				-GZIP1_DEF_WINBITS, GZIP1_DEF_MEMLEVEL,
 				Z_DEFAULT_STRATEGY);
@@ -160,12 +163,8 @@ gzip1_compress(coa_t coa, __u8 * src_fir
 		goto rollback;
 	}
 	*dst_len = stream.total_out;
-	if (!coa)
-		cplug->free(stream.workspace, TFM_WRITE);
 	return;
  rollback:
-	if (!coa && stream.workspace)
-		cplug->free(stream.workspace, TFM_WRITE);
 	*dst_len = src_len;
 #endif
 	return;
@@ -178,31 +177,22 @@ gzip1_decompress(coa_t coa, __u8 * src_f
 #if REISER4_GZIP_TFM
 	int ret = 0;
 	struct z_stream_s stream;
-	compression_plugin *cplug =
-	    compression_plugin_by_id(GZIP1_COMPRESSION_ID);
 
 	xmemset(&stream, 0, sizeof(stream));
 
 	assert("edward-843", coa != NULL);
 	assert("edward-876", src_len != 0);
 
-	if (!coa) {
-		coa_t tmp = cplug->alloc(TFM_READ);
-		if (IS_ERR(tmp))
-			goto out;
-		stream.workspace = tmp;
-	} else
-		stream.workspace = coa;
-
+	stream.workspace = coa;
 	ret = zlib_inflateInit2(&stream, -GZIP1_DEF_WINBITS);
 	if (ret != Z_OK) {
 		warning("edward-774", "zlib_inflateInit2 returned %d\n", ret);
-		goto out;
+		return;
 	}
 	ret = zlib_inflateReset(&stream);
 	if (ret != Z_OK) {
 		warning("edward-775", "zlib_inflateReset returned %d\n", ret);
-		goto out;
+		return;
 	}
 
 	stream.next_in = src_first;
@@ -224,12 +214,9 @@ gzip1_decompress(coa_t coa, __u8 * src_f
 	}
 	if (ret != Z_STREAM_END) {
 		warning("edward-776", "zlib_inflate returned %d\n", ret);
-		goto out;
+		return;
 	}
 	*dst_len = stream.total_out;
-      out:
-	if (!coa && stream.workspace)
-		cplug->free(stream.workspace, TFM_READ);
 #endif
 	return;
 }
@@ -302,6 +289,12 @@ lzo1_free(coa_t coa, tfm_action act)
 	return;
 }
 
+static int
+lzo1_min_tfm_size(void)
+{
+	return 256;
+}
+
 static void
 lzo1_compress(coa_t coa, __u8 * src_first, unsigned src_len,
 	      __u8 * dst_first, unsigned *dst_len)
@@ -372,6 +365,7 @@ compression_plugin compression_plugins[L
 				 .overrun = none_overrun,
 				 .alloc = NULL,
 				 .free = NULL,
+				 .min_tfm_size = NULL,
 				 .compress = NULL,
 				 .decompress = NULL}
 	,
@@ -388,6 +382,7 @@ compression_plugin compression_plugins[L
 				 .overrun = none_overrun,
 				 .alloc = NULL,
 				 .free = NULL,
+				 .min_tfm_size = null_min_tfm_size,
 				 .compress = null_compress,
 				 .decompress = null_decompress}
 	,
@@ -404,6 +399,7 @@ compression_plugin compression_plugins[L
 				 .overrun = lzo1_overrun,
 				 .alloc = lzo1_alloc,
 				 .free = lzo1_free,
+				 .min_tfm_size = lzo1_min_tfm_size,
 				 .compress = lzo1_compress,
 				 .decompress = lzo1_decompress}
 	,
@@ -420,6 +416,7 @@ compression_plugin compression_plugins[L
 				  .overrun = gzip1_overrun,
 				  .alloc = gzip1_alloc,
 				  .free = gzip1_free,
+				  .min_tfm_size = gzip1_min_tfm_size,
 				  .compress = gzip1_compress,
 				  .decompress = gzip1_decompress}
 };
diff -puN fs/reiser4/plugin/cryptcompress.c~reiser4-crypto-update fs/reiser4/plugin/cryptcompress.c
--- 25/fs/reiser4/plugin/cryptcompress.c~reiser4-crypto-update	Fri Nov 12 16:01:48 2004
+++ 25-akpm/fs/reiser4/plugin/cryptcompress.c	Fri Nov 12 16:01:48 2004
@@ -866,12 +866,26 @@ compress_overhead(struct inode * inode, 
 	return inode_compression_plugin(inode)->overrun(in_len);
 }
 
+/* Since small input stream can not get compressed,
+   we try to awoid a lot of useless job */
+static int
+min_size_to_compress(struct inode * inode)
+{
+	assert("edward-1036",
+	       inode_compression_plugin(inode)->min_tfm_size != NULL);
+	return inode_compression_plugin(inode)->min_tfm_size();
+}
+
+
 /* The following two functions represent reiser4 compression policy */
 static int
 try_compress(tfm_cluster_t * tc, struct inode * inode)
 {
+	assert("edward-1037", min_size_to_compress(inode) > 0 &&
+	       min_size_to_compress(inode) < inode_cluster_size(inode));
+
 	return (inode_compression_plugin(inode) != compression_plugin_by_id(NONE_COMPRESSION_ID)) &&
-		(tc->len >= MIN_SIZE_FOR_COMPRESSION);
+		(tc->len >= min_size_to_compress(inode));
 }
 
 static int
@@ -913,14 +927,15 @@ static void set_compression_magic(__u8 *
 }
 
 reiser4_internal int
-grab_tfm_stream(struct inode * inode, tfm_cluster_t * tc, tfm_stream_id id)
+grab_tfm_stream(struct inode * inode, tfm_cluster_t * tc,
+		tfm_action act, tfm_stream_id id)
 {
 	size_t size = inode_scaled_cluster_size(inode);
-	compression_plugin * cplug = inode_compression_plugin(inode);
 	
 	assert("edward-901", tc != NULL);
+	assert("edward-1027", inode_compression_plugin(inode) != NULL);
 	
-	if (cplug)
+	if (act == TFM_WRITE)
 		size += compress_overhead(inode, inode_cluster_size(inode));
 
 	if (!tfm_stream(tc, id) && id == INPUT_STREAM)
@@ -957,7 +972,7 @@ deflate_cluster(reiser4_cluster_t * clus
 		
 		assert("edward-602", cplug != NULL);
 		
-		result = grab_tfm_stream(inode, tc, OUTPUT_STREAM);
+		result = grab_tfm_stream(inode, tc, TFM_WRITE, OUTPUT_STREAM);
 		if (result)
 			return result;
 		dst_len = tfm_stream_size(tc, OUTPUT_STREAM);
@@ -986,7 +1001,7 @@ deflate_cluster(reiser4_cluster_t * clus
 		cplug = inode_crypto_plugin(inode);
 		if (transformed)
 			alternate_streams(tc);
-		result = grab_tfm_stream(inode, tc, OUTPUT_STREAM);
+		result = grab_tfm_stream(inode, tc, TFM_WRITE, OUTPUT_STREAM);
 		if (result)
 			return result;
 		/* FIXME: set src_len, dst_len, encrypt */
@@ -1020,7 +1035,7 @@ inflate_cluster(reiser4_cluster_t * clus
 		cplug = inode_crypto_plugin(inode);
 		assert("edward-617", cplug != NULL);
 		
-		result = grab_tfm_stream(inode, tc, OUTPUT_STREAM);
+		result = grab_tfm_stream(inode, tc, TFM_READ, OUTPUT_STREAM);
 		if (result)
 			return result;
 		assert("edward-909", tfm_cluster_is_set(tc));
@@ -1038,7 +1053,7 @@ inflate_cluster(reiser4_cluster_t * clus
 		if(transformed)
 			alternate_streams(tc);
 		
-		result = grab_tfm_stream(inode, tc, OUTPUT_STREAM);
+		result = grab_tfm_stream(inode, tc, TFM_READ, OUTPUT_STREAM);
 		if (result)
 			return result;
 		assert("edward-910", tfm_cluster_is_set(tc));
@@ -1168,49 +1183,20 @@ set_cluster_pages_dirty(reiser4_cluster_
 	}
 }
 
-/* This is the interface to capture cluster nodes via their struct page reference.
-   Any two blocks of the same cluster contain dependent modification and should
-   commit at the same time */
-static int
-try_capture_cluster(reiser4_cluster_t * clust)
-{
-	int result = 0;
-	jnode * node;
-
-	assert("edward-911", clust != NULL);
-	assert("edward-969", clust->reserved == 1);
-	assert("edward-912", clust->nr_pages != 0);
-	assert("edward-913", clust->pages != NULL);
-	assert("edward-914", clust->pages[0] != NULL);
-	
-	node = jprivate(clust->pages[0]);
-
-	assert("edward-915", node != NULL);
-
-	LOCK_JNODE(node);
-	result = try_capture(node, ZNODE_WRITE_LOCK, 0/* not non-blocking */, 0 /* no can_coc */);
-	UNLOCK_JNODE(node);
-	
-	assert("edward-970", !result);
-	return result;
-}
-
 /* . reserve space for a disk cluster if its jnode is not dirty;
    . update set of pages referenced by this jnode
    . update jnode's counter of referenced pages (excluding first one)
 */
 static void
-make_cluster_jnode_dirty(reiser4_cluster_t * clust, struct inode * inode)
+make_cluster_jnode_dirty_locked(reiser4_cluster_t * clust,
+				jnode * node, struct inode * inode)
 {
 	int i;
 	int count;
-	jnode * node = jprivate(clust->pages[0]);
 	
 	assert("edward-221", node != NULL);
 	assert("edward-971", clust->reserved == 1);
-	
-	LOCK_JNODE(node);
-
+	assert("edward-1028", spin_jnode_is_locked(node));
 	assert("edward-972", node->page_count < inode_cluster_pages(inode));
 	
 	if (jnode_is_dirty(node)) {
@@ -1243,11 +1229,42 @@ make_cluster_jnode_dirty(reiser4_cluster
 #if REISER4_DEBUG
 	node->page_count = max_count(node->page_count, clust->nr_pages - 1);
 #endif
-	UNLOCK_JNODE(node);
 	jput(node);
 	return;
 }
 
+/* This is the interface to capture cluster nodes via their struct page reference.
+   Any two blocks of the same cluster contain dependent modification and should
+   commit at the same time */
+static int
+try_capture_cluster(reiser4_cluster_t * clust, struct inode * inode)
+{
+	int result = 0;
+	jnode * node;
+
+	assert("edward-1029", clust != NULL);
+	assert("edward-1030", clust->reserved == 1);
+	assert("edward-1031", clust->nr_pages != 0);
+	assert("edward-1032", clust->pages != NULL);
+	assert("edward-1033", clust->pages[0] != NULL);
+
+	node = jprivate(clust->pages[0]);
+
+	assert("edward-1035", node != NULL);
+
+	LOCK_JNODE(node);
+	result = try_capture(node, ZNODE_WRITE_LOCK, 0/* not non-blocking */, 0 /* no can_coc */);
+	if (result) {
+		assert("edward-1034", 0);
+		UNLOCK_JNODE(node);
+		return result;
+	}
+	make_cluster_jnode_dirty_locked(clust, node, inode);
+	UNLOCK_JNODE(node);
+
+	return 0;
+}
+
 reiser4_internal jnode *
 jnode_of_page_cluster(reiser4_cluster_t * clust)
 {
@@ -1541,7 +1558,7 @@ struct inode * inode)
 	
 	UNLOCK_JNODE(node);
 	
-	result = grab_tfm_stream(inode, tc, INPUT_STREAM);
+	result = grab_tfm_stream(inode, tc, TFM_WRITE, INPUT_STREAM);
 	if (result)
 		return result;
 	
@@ -1675,11 +1692,9 @@ write_hole(struct inode *inode, reiser4_
 		/* only zeroes, try to flush */
 
 		set_cluster_pages_dirty(clust);
-		result = try_capture_cluster(clust);
+		result = try_capture_cluster(clust, inode);
 		if (result)
 			return result;
-		make_cluster_jnode_dirty(clust, inode);
-		/* hint for updated cluster will be set here */
 		result = balance_dirty_page_cluster(clust, file_off, to_file);
 	}
 	else 
@@ -2119,7 +2134,7 @@ write_cryptcompress_flow(struct file * f
 		
 		assert("edward-750", schedulable());
 		
-		result = prepare_cluster(inode, file_off, f.length, NULL, &clust, "write cryptcompress flow");  /* j+p+ */
+		result = prepare_cluster(inode, file_off, f.length, NULL, &clust, "write cryptcompress flow");
 		if (result)
 			goto out;
 		
@@ -2133,7 +2148,7 @@ write_cryptcompress_flow(struct file * f
                 /* copy user's data to cluster pages */
 		for (i = off_to_pg(clust.off), src = f.data; i < count_to_nrpages(clust.off + clust.count); i++, src += page_count) {
 			page_count = min_count(PAGE_CACHE_SIZE - page_off, off_to_pgcount(clust.off + clust.count, i));
-			//page_count = off_to_pgcount(clust.off + clust.count, i);
+
 			assert("edward-287", clust.pages[i] != NULL);
 			
 			lock_page(clust.pages[i]);
@@ -2151,7 +2166,7 @@ write_cryptcompress_flow(struct file * f
 		
 		set_cluster_pages_dirty(&clust);
 		
-		result = try_capture_cluster(&clust);
+		result = try_capture_cluster(&clust, inode);
 		if (result)
 			goto err2;
 		
@@ -2160,7 +2175,6 @@ write_cryptcompress_flow(struct file * f
 		move_flow_forward(&f, clust.count);
 		
 		/* disk cluster may be already clean at this point */
-		make_cluster_jnode_dirty(&clust, inode);
 		
 		/* . update cluster
 		   . set hint for new offset
@@ -2176,7 +2190,7 @@ write_cryptcompress_flow(struct file * f
 	err3:
 		page_cache_release(clust.pages[0]);
 	err2:
-		release_cluster_pages_and_jnode(&clust);                            /* j-p- */
+		release_cluster_pages_and_jnode(&clust);
 	err1:
 		if (clust.reserved)
 			free_reserved4cluster(inode, &clust);
@@ -2451,10 +2465,9 @@ shorten_cryptcompress(struct inode * ino
 	unlock_page(clust.pages[clust.nr_pages - 1]);
 	
 	set_cluster_pages_dirty(&clust);
-	result = try_capture_cluster(&clust);
+	result = try_capture_cluster(&clust, inode);
 	if (result)
 		goto err2;
-	make_cluster_jnode_dirty(&clust, inode);
 	
 	/* FIXME-EDWARD: Update this using balance dirty cluster pages */
 	assert("edward-757", 0 /* don't free reserved4cluster when success */);
@@ -2547,20 +2560,17 @@ cryptcompress_writepage(struct page * pa
 	clust.count = PAGE_CACHE_SIZE;
 	nrpages = count_to_nrpages(fsize_to_count(&clust, inode));
 
-	result = prepare_cluster(page->mapping->host, 0, 0, &nrpages, &clust, "cryptcompress_writepage");  /* jp+ */
+	result = prepare_cluster(page->mapping->host, 0, 0, &nrpages, &clust, "cryptcompress_writepage");
 	if(result)
 		goto exit;
 
 	set_cluster_pages_dirty(&clust); 
-	result = try_capture_cluster(&clust);
+	result = try_capture_cluster(&clust, inode);
 	if (result) {
 		free_reserved4cluster(inode, &clust);
-		put_cluster_jnode(&clust);                                     /* j- */
 		goto exit;
 	}
 	lock_page(page);
-	make_cluster_jnodes_dirty(&clust);
-	put_cluster_jnode(&clust);                                             /* j- */
  exit:
 	reiser4_kfree(clust.pages);
 	return result;
diff -puN fs/reiser4/plugin/cryptcompress.h~reiser4-crypto-update fs/reiser4/plugin/cryptcompress.h
--- 25/fs/reiser4/plugin/cryptcompress.h~reiser4-crypto-update	Fri Nov 12 16:01:48 2004
+++ 25-akpm/fs/reiser4/plugin/cryptcompress.h	Fri Nov 12 16:01:48 2004
@@ -14,7 +14,6 @@
 #define MAX_CLUSTER_SHIFT 4
 #define MAX_CLUSTER_NRPAGES (1 << MAX_CLUSTER_SHIFT)
 #define DEFAULT_CLUSTER_SHIFT 0
-#define MIN_SIZE_FOR_COMPRESSION 64
 #define MIN_CRYPTO_BLOCKSIZE 8
 #define CLUSTER_MAGIC_SIZE (MIN_CRYPTO_BLOCKSIZE >> 1)
 
diff -puN fs/reiser4/plugin/item/ctail.c~reiser4-crypto-update fs/reiser4/plugin/item/ctail.c
--- 25/fs/reiser4/plugin/item/ctail.c~reiser4-crypto-update	Fri Nov 12 16:01:48 2004
+++ 25-akpm/fs/reiser4/plugin/item/ctail.c	Fri Nov 12 16:01:48 2004
@@ -534,11 +534,12 @@ ctail_read_cluster (reiser4_cluster_t * 
 	
 	if (!hint_prev_cluster(clust)) {
 		done_lh(clust->hint->coord.lh);
+		clust->hint->coord.valid = 0;
 		unset_hint(clust->hint);
 	}
 	
 	/* set input stream */
-	result = grab_tfm_stream(inode, &clust->tc, INPUT_STREAM);
+	result = grab_tfm_stream(inode, &clust->tc, TFM_READ, INPUT_STREAM);
 	if (result)
 		goto out;
 
@@ -783,11 +784,10 @@ readpages_ctail(void *vp, struct address
 		unlock_page(page);
 	}
 	assert("edward-870", !tfm_cluster_is_uptodate(&clust.tc));
-	hint.coord.valid = 0;
 	save_file_hint(clust.file, &hint);
  out:	
 	done_lh(&lh);
-	/* free array */
+	hint.coord.valid = 0;
 	put_cluster_handle(&clust, TFM_READ);
 	pagevec_lru_add(&lru_pvec);
 	return;
diff -puN fs/reiser4/plugin/plugin.h~reiser4-crypto-update fs/reiser4/plugin/plugin.h
--- 25/fs/reiser4/plugin/plugin.h~reiser4-crypto-update	Fri Nov 12 16:01:48 2004
+++ 25-akpm/fs/reiser4/plugin/plugin.h	Fri Nov 12 16:01:48 2004
@@ -441,6 +441,8 @@ typedef struct compression_plugin {
 	int (*overrun) (unsigned src_len);
 	coa_t (*alloc) (tfm_action act);
 	void (*free) (coa_t coa, tfm_action act);
+	/* minimal size of the flow we still try to compress */
+	int (*min_tfm_size) (void);
 	/* main transform procedures */
 	void (*compress)   (coa_t coa, __u8 *src_first, unsigned src_len,
 			    __u8 *dst_first, unsigned *dst_len);
_