<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">diff -urN linux-2.4.6/drivers/block/loop.c linux-int-2.4.6/drivers/block/loop.c
--- linux-2.4.6/drivers/block/loop.c	Sat Jun 30 01:16:56 2001
+++ linux-int-2.4.6/drivers/block/loop.c	Sat Jul  7 10:52:41 2001
@@ -36,6 +36,9 @@
  * Al Viro too.
  * Jens Axboe &lt;axboe@suse.de&gt;, Nov 2000
  *
+ * Fixed and made IV calculation customizable by lo_iv_mode
+ * Herbert Valerio Riedel &lt;hvr@gnu.org&gt;, Apr 2001
+ *
  * Still To Fix:
  * - Advisory locking is ignored here. 
  * - Should use an own CAP_* category instead of CAP_SYS_ADMIN 
@@ -164,6 +167,43 @@
 					lo-&gt;lo_device);
 }
 
+static inline int loop_get_bs(struct loop_device *lo)
+{
+	int bs = 0;
+
+	if (blksize_size[MAJOR(lo-&gt;lo_device)])
+		bs = blksize_size[MAJOR(lo-&gt;lo_device)][MINOR(lo-&gt;lo_device)];
+	if (!bs)
+		bs = BLOCK_SIZE;	
+
+	return bs;
+}
+
+static inline unsigned long loop_get_iv(struct loop_device *lo,
+					unsigned long sector)
+{
+	unsigned long offset, IV;
+	int bs;
+
+	switch (lo-&gt;lo_iv_mode) {
+		case LO_IV_MODE_SECTOR:
+			IV = sector + (lo-&gt;lo_offset &gt;&gt; LO_IV_SECTOR_BITS);
+			break;
+
+		default:
+			printk (KERN_WARNING "loop: unexpected lo_iv_mode\n");
+		case LO_IV_MODE_DEFAULT:
+			bs = loop_get_bs(lo);
+			IV = sector / (bs &gt;&gt; 9) + lo-&gt;lo_offset / bs;
+			offset = ((sector % (bs &gt;&gt; 9)) &lt;&lt; 9) + lo-&gt;lo_offset % bs;
+			if (offset &gt;= bs)
+				IV++;
+			break;
+	}
+
+	return IV;
+}
+
 static int lo_send(struct loop_device *lo, struct buffer_head *bh, int bsize,
 		   loff_t pos)
 {
@@ -181,7 +221,8 @@
 	len = bh-&gt;b_size;
 	data = bh-&gt;b_data;
 	while (len &gt; 0) {
-		int IV = index * (PAGE_CACHE_SIZE/bsize) + offset/bsize;
+		unsigned long IV = loop_get_iv(lo, (pos - lo-&gt;lo_offset) &gt;&gt; LO_IV_SECTOR_BITS);
+
 		size = PAGE_CACHE_SIZE - offset;
 		if (size &gt; len)
 			size = len;
@@ -232,7 +273,10 @@
 	unsigned long count = desc-&gt;count;
 	struct lo_read_data *p = (struct lo_read_data*)desc-&gt;buf;
 	struct loop_device *lo = p-&gt;lo;
-	int IV = page-&gt;index * (PAGE_CACHE_SIZE/p-&gt;bsize) + offset/p-&gt;bsize;
+	unsigned long IV = loop_get_iv(lo,
+		((page-&gt;index &lt;&lt;  (PAGE_CACHE_SHIFT - LO_IV_SECTOR_BITS))
+		+ (offset &gt;&gt; LO_IV_SECTOR_BITS)
+		- (lo-&gt;lo_offset &gt;&gt; LO_IV_SECTOR_BITS)));
 
 	if (size &gt; count)
 		size = count;
@@ -272,32 +316,6 @@
 	return desc.error;
 }
 
-static inline int loop_get_bs(struct loop_device *lo)
-{
-	int bs = 0;
-
-	if (blksize_size[MAJOR(lo-&gt;lo_device)])
-		bs = blksize_size[MAJOR(lo-&gt;lo_device)][MINOR(lo-&gt;lo_device)];
-	if (!bs)
-		bs = BLOCK_SIZE;	
-
-	return bs;
-}
-
-static inline unsigned long loop_get_iv(struct loop_device *lo,
-					unsigned long sector)
-{
-	int bs = loop_get_bs(lo);
-	unsigned long offset, IV;
-
-	IV = sector / (bs &gt;&gt; 9) + lo-&gt;lo_offset / bs;
-	offset = ((sector % (bs &gt;&gt; 9)) &lt;&lt; 9) + lo-&gt;lo_offset % bs;
-	if (offset &gt;= bs)
-		IV++;
-
-	return IV;
-}
-
 static int do_bh_filebacked(struct loop_device *lo, struct buffer_head *bh, int rw)
 {
 	loff_t pos;
@@ -474,9 +492,11 @@
 	/*
 	 * piggy old buffer on original, and submit for I/O
 	 */
+	IV = loop_get_iv(lo, rbh-&gt;b_rsector);
+
 	bh = loop_get_buffer(lo, rbh);
 	bh-&gt;b_private = rbh;
-	IV = loop_get_iv(lo, bh-&gt;b_rsector);
+
 	if (rw == WRITE) {
 		set_bit(BH_Dirty, &amp;bh-&gt;b_state);
 		if (lo_do_transfer(lo, WRITE, bh-&gt;b_data, rbh-&gt;b_data,
@@ -646,6 +666,7 @@
 	lo-&gt;lo_backing_file = file;
 	lo-&gt;transfer = NULL;
 	lo-&gt;ioctl = NULL;
+	lo-&gt;lo_iv_mode = LO_IV_MODE_DEFAULT;
 	figure_loop_size(lo);
 	lo-&gt;old_gfp_mask = inode-&gt;i_mapping-&gt;gfp_mask;
 	inode-&gt;i_mapping-&gt;gfp_mask = GFP_NOIO;
@@ -655,7 +676,7 @@
 		bs = blksize_size[MAJOR(lo_device)][MINOR(lo_device)];
 	if (!bs)
 		bs = BLOCK_SIZE;
-
+	  
 	set_blocksize(dev, bs);
 
 	lo-&gt;lo_bh = lo-&gt;lo_bhtail = NULL;
diff -urN linux-2.4.6/include/linux/loop.h linux-int-2.4.6/include/linux/loop.h
--- linux-2.4.6/include/linux/loop.h	Wed Mar  7 04:35:36 2001
+++ linux-int-2.4.6/include/linux/loop.h	Sat Jul  7 10:42:18 2001
@@ -24,6 +24,13 @@
 	Lo_rundown,
 };
 
+/* IV calculation related constants */
+#define LO_IV_MODE_DEFAULT 0 /* old logical block size based mode */
+#define LO_IV_MODE_SECTOR  1 /* calculate IV based on relative 
+				512 byte sectors */
+#define LO_IV_SECTOR_BITS 9
+#define LO_IV_SECTOR_SIZE (1 &lt;&lt; LO_IV_SECTOR_BITS)
+
 struct loop_device {
 	int		lo_number;
 	int		lo_refcnt;
@@ -56,6 +63,8 @@
 	struct semaphore	lo_ctl_mutex;
 	struct semaphore	lo_bh_mutex;
 	atomic_t		lo_pending;
+
+	int			lo_iv_mode;
 };
 
 typedef	int (* transfer_proc_t)(struct loop_device *, int cmd,
@@ -121,6 +130,7 @@
 #define LO_CRYPT_IDEA     6
 #define LO_CRYPT_DUMMY    9
 #define LO_CRYPT_SKIPJACK 10
+#define LO_CRYPT_CRYPTOAPI 18  /* international crypto patch */
 #define MAX_LO_CRYPT	20
 
 #ifdef __KERNEL__
</pre></body></html>