wok diff linux-cloop/stuff/cloop.u @ rev 24983

Up xcursor-comix (0.9.2)
author Pascal Bellard <pascal.bellard@slitaz.org>
date Sun May 08 16:45:21 2022 +0000 (2022-05-08)
parents cea6e929d21e
children c81179c4b106
line diff
     1.1 --- a/linux-cloop/stuff/cloop.u	Tue May 05 11:06:44 2020 +0000
     1.2 +++ b/linux-cloop/stuff/cloop.u	Sun May 08 16:45:21 2022 +0000
     1.3 @@ -1,6 +1,6 @@
     1.4  --- cloop.h
     1.5  +++ cloop.h
     1.6 -@@ -1,15 +1,50 @@
     1.7 +@@ -1,3 +1,7 @@
     1.8  +#define CLOOP_SIGNATURE "#!/bin/sh"                      /* @ offset 0  */
     1.9  +#define CLOOP_SIGNATURE_SIZE 9
    1.10  +#define CLOOP_SIGNATURE_OFFSET 0x0
    1.11 @@ -8,99 +8,46 @@
    1.12   #ifndef _COMPRESSED_LOOP_H
    1.13   #define _COMPRESSED_LOOP_H
    1.14   
    1.15 --#define CLOOP_HEADROOM 128
    1.16 -+/*************************************************************************\
    1.17 -+* Starting with Format V4.0 (cloop version 4.x), cloop can now have two   *
    1.18 -+* alternative structures:                                                 *
    1.19 -+*                                                                         *
    1.20 -+* 1. Header first: "robust" format, handles missing blocks well           *
    1.21 -+* 2. Footer (header last): "streaming" format, easier to create           *
    1.22 -+*                                                                         *
    1.23 -+* The cloop kernel module autodetects both formats, and can (currently)   *
    1.24 -+* still handle the V2.0 format as well.                                   *
    1.25 -+*                                                                         *
    1.26 -+* 1. Header first:                                                        *
    1.27 -+*   +---------------------------- FIXED SIZE ---------------------------+ *
    1.28 -+*   |Signature (128 bytes)                                              | *
    1.29 -+*   |block_size (32bit number, network order)                           | *
    1.30 -+*   |num_blocks (32bit number, network order)                           | *
    1.31 -+*   +--------------------------- VARIABLE SIZE -------------------------+ *
    1.32 -+*   |num_blocks * FlagsOffset (upper 4 bits flags, lower 64 bits offset)| *
    1.33 -+*   |compressed data blocks of variable size ...                        | *
    1.34 -+*   +-------------------------------------------------------------------+ *
    1.35 -+*                                                                         *
    1.36 -+* 2. Footer (header last):                                                *
    1.37 -+*   +--------------------------- VARIABLE SIZE -------------------------+ *
    1.38 -+*   |compressed data blocks of variable size ...                        | *
    1.39 -+*   |num_blocks * FlagsOffset (upper 4 bits flags, lower 64 bits offset)| *
    1.40 -+*   +---------------------------- FIXED SIZE ---------------------------+ *
    1.41 -+*   |Signature (128 bytes)                                              | *
    1.42 -+*   |block_size (32bit number, network order)                           | *
    1.43 -+*   |num_blocks (32bit number, network order)                           | *
    1.44 -+*   +-------------------------------------------------------------------+ *
    1.45 -+*                                                                         *
    1.46 -+* Offsets are always relative to beginning of file, in all formats.       *
    1.47 -+* The block index contains num_blocks+1 offsets, followed (1) or          *
    1.48 -+* preceded (2) by the compressed blocks.                                  *
    1.49 -+\*************************************************************************/
    1.50 +@@ -38,10 +42,6 @@
    1.51   
    1.52 --/* The cloop header usually looks like this:          */
    1.53 --/* #!/bin/sh                                          */
    1.54 --/* #V2.00 Format                                      */
    1.55 --/* ...padding up to CLOOP_HEADROOM...                 */
    1.56 --/* block_size (32bit number, network order)           */
    1.57 --/* num_blocks (32bit number, network order)           */
    1.58 -+#include <linux/types.h>   /* u_int32_t */
    1.59 -+
    1.60 -+#define CLOOP_HEADROOM 128
    1.61 + #include <linux/types.h>   /* u_int32_t */
    1.62   
    1.63 -+/* Header of fixed length, can be located at beginning or end of file   */
    1.64 - struct cloop_head
    1.65 - {
    1.66 - 	char preamble[CLOOP_HEADROOM];
    1.67 -@@ -17,9 +52,163 @@
    1.68 +-#ifndef __KERNEL__
    1.69 +-#include <stdint.h> /* regular uint64_t */
    1.70 +-#endif
    1.71 +-
    1.72 + #define CLOOP_HEADROOM 128
    1.73 + 
    1.74 + /* Header of fixed length, can be located at beginning or end of file   */
    1.75 +@@ -52,13 +52,6 @@
    1.76   	u_int32_t num_blocks;
    1.77   };
    1.78   
    1.79 -+/************************************************************************\
    1.80 -+*  CLOOP4 flags for each compressed block                                *
    1.81 -+*  Value   Meaning                                                       *
    1.82 -+*    0     GZIP/7ZIP compression (compatible with V2.0 Format)           *
    1.83 -+*    1     no compression (incompressible data)                          *
    1.84 -+*    2     xz compression (currently best space saver)                   *
    1.85 -+*    3     lz4 compression                                               *
    1.86 -+*    4     lzo compression (fastest)                                     *
    1.87 -+\************************************************************************/
    1.88 -+
    1.89 -+typedef uint64_t cloop_block_ptr;
    1.90 -+
    1.91 -+/* Get value of first 4 bits */
    1.92 -+#define CLOOP_BLOCK_FLAGS(x)  ((unsigned int)(((x) & 0xf000000000000000LLU) >> 60))
    1.93 -+/* Get value of last 60 bits */
    1.94 -+#define CLOOP_BLOCK_OFFSET(x)  ((x) & 0x0fffffffffffffffLLU)
    1.95 -+
    1.96 -+#define CLOOP_COMPRESSOR_ZLIB  0x0
    1.97 -+#define CLOOP_COMPRESSOR_NONE  0x1
    1.98 -+#define CLOOP_COMPRESSOR_XZ    0x2
    1.99 -+#define CLOOP_COMPRESSOR_LZ4   0x3
   1.100 -+#define CLOOP_COMPRESSOR_LZO1X 0x4
   1.101 -+
   1.102 -+#define CLOOP_COMPRESSOR_VALID(x) ((x) >= CLOOP_COMPRESSOR_ZLIB && (x) <= CLOOP_COMPRESSOR_LZO1X)
   1.103 -+
   1.104 +-#define CLOOP2_SIGNATURE "V2.0"                       /* @ offset 0x0b  */
   1.105 +-#define CLOOP2_SIGNATURE_SIZE 4
   1.106 +-#define CLOOP2_SIGNATURE_OFFSET 0x0b
   1.107 +-#define CLOOP4_SIGNATURE "V4.0"                       /* @ offset 0x0b  */
   1.108 +-#define CLOOP4_SIGNATURE_SIZE 4
   1.109 +-#define CLOOP4_SIGNATURE_OFFSET 0x0b
   1.110 +-
   1.111 + /************************************************************************\
   1.112 + *  CLOOP4 flags for each compressed block                                *
   1.113 + *  Value   Meaning                                                       *
   1.114 +@@ -84,6 +77,134 @@
   1.115 + 
   1.116 + #define CLOOP_COMPRESSOR_VALID(x) ((x) >= CLOOP_COMPRESSOR_ZLIB && (x) <= CLOOP_COMPRESSOR_LZO1X)
   1.117 + 
   1.118  +#define CLOOP_COMPRESSOR_LINK  0xF
   1.119  +
   1.120  +
   1.121 - /* data_index (num_blocks 64bit pointers, network order)...      */
   1.122 - /* compressed data (gzip block compressed format)...             */
   1.123 - 
   1.124 ++/* data_index (num_blocks 64bit pointers, network order)...      */
   1.125 ++/* compressed data (gzip block compressed format)...             */
   1.126 ++
   1.127  +struct cloop_tail
   1.128  +{
   1.129  +	u_int32_t table_size; 
   1.130 -+	u_int32_t index_size; /* size:4 comp:3 ctrl-c:1 lastlen:24 */
   1.131 ++	u_int32_t index_size; /* size:4 unused:3 ctrl-c:1 lastlen:24 */
   1.132  +#define CLOOP3_INDEX_SIZE(x)    ((unsigned int)((x) & 0xF))
   1.133 -+#define CLOOP3_BLOCKS_FLAGS(x)  ((unsigned int)((x) & 0x70) >> 4)
   1.134 -+#define CLOOP3_TRUNCATED(x)     ((unsigned int)((x) & 0x80) >> 7)
   1.135 -+#define CLOOP3_LASTLEN(x)       (unsigned int)((x) >> 8)
   1.136  +	u_int32_t num_blocks;
   1.137  +};
   1.138  +
   1.139 @@ -114,8 +61,10 @@
   1.140  +};
   1.141  +
   1.142  +static inline char *build_index(struct block_info *offsets, unsigned long n, 
   1.143 -+			unsigned long block_size, unsigned global_flags)
   1.144 ++			unsigned long block_size)
   1.145  +{
   1.146 ++	static char v[11];
   1.147 ++	u_int32_t flags = 0;
   1.148  +	u_int32_t *ofs32 = (u_int32_t *) offsets;
   1.149  +	loff_t    *ofs64 = (loff_t *) offsets;
   1.150  +
   1.151 @@ -140,8 +89,6 @@
   1.152  +		}
   1.153  +		else { /* V2.0/V4.0 */
   1.154  +			loff_t last = CLOOP_BLOCK_OFFSET(__be64_to_cpu(ofs64[n]));
   1.155 -+			u_int32_t flags;
   1.156 -+			static char v4[11];
   1.157  +			unsigned long i = n;
   1.158  +
   1.159  +			for (flags = 0; n-- ;) {
   1.160 @@ -159,12 +106,7 @@
   1.161  +					offsets[i] = offsets[offsets[i].offset];
   1.162  +				}
   1.163  +			}
   1.164 -+			strcpy(v4, (char *) "64BE v4.0a");
   1.165 -+			v4[10] = 'a' + ((flags-1) & 0xF);	// compressors used
   1.166 -+			if (flags > 0x10) {			// with links ?
   1.167 -+				v4[10] += 'A' - 'a';
   1.168 -+			}
   1.169 -+			return v4;
   1.170 ++			strcpy(v, (char *) "64BE v4.0a");
   1.171  +		}
   1.172  +	}
   1.173  +	else if (ofs32[1] == 0 && v3_64 == 0) { /* V1.0 */
   1.174 @@ -180,7 +122,6 @@
   1.175  +	else { /* V3.0 or V0.68 */
   1.176  +		unsigned long i;
   1.177  +		loff_t j;
   1.178 -+		static char v3[11];
   1.179  +		
   1.180  +		for (i = 0; i < n && ntohl(ofs32[i]) < ntohl(ofs32[i+1]); i++);
   1.181  +		if (i == n && ntohl(ofs32[0]) == (4*n) + 0x8C) { /* V0.68 */
   1.182 @@ -195,28 +136,33 @@
   1.183  +		}
   1.184  +		
   1.185  +		v3_64 = (ofs32[1] == 0);
   1.186 -+		for (i = n; i-- != 0; )
   1.187 ++		for (i = n; i-- != 0; ) {
   1.188  +			offsets[i].size = ntohl(ofs32[i << v3_64]); 
   1.189 ++			if (offsets[i].size == 0xFFFFFFFF) {
   1.190 ++				offsets[i].size = 0x10000000 | block_size;
   1.191 ++			}
   1.192 ++			offsets[i].flags = (offsets[i].size >> 28);
   1.193 ++			offsets[i].size &= 0x0FFFFFFF; 
   1.194 ++		}
   1.195  +		for (i = 0, j = sizeof(struct cloop_head); i < n; i++) {
   1.196  +			offsets[i].offset = j;
   1.197 -+			offsets[i].flags = global_flags;
   1.198 -+			if (offsets[i].size == 0xFFFFFFFF) {
   1.199 -+				offsets[i].flags = CLOOP_COMPRESSOR_NONE;
   1.200 -+				offsets[i].size = block_size;
   1.201 -+			}
   1.202 -+			if ((offsets[i].size & 0x80000000) == 0) {
   1.203 ++			if (offsets[i].flags < 8) {
   1.204  +				j += offsets[i].size;
   1.205  +			}
   1.206  +		}
   1.207  +		for (i = 0; i < n; i++) {
   1.208 -+			if (offsets[i].size & 0x80000000) {
   1.209 -+				offsets[i] = offsets[offsets[i].size & 0x7FFFFFFF];
   1.210 ++			flags |= 1 << offsets[i].flags;
   1.211 ++			if (offsets[i].flags >= 8) {
   1.212 ++				offsets[i] = offsets[offsets[i].size];
   1.213  +			}
   1.214  +		}
   1.215 -+		strcpy(v3, (char *) (v3_64) ? "64BE v3.0a" : "32BE v3.0a");
   1.216 -+		v3[10] += global_flags;
   1.217 -+		return v3;
   1.218 ++		strcpy(v, (char *) (v3_64) ? "64BE v3.0a" : "32BE v3.0a");
   1.219  +	}
   1.220 ++	v[10] = 'a' + ((flags-1) & 0xF);	// compressors used
   1.221 ++	if (flags > 0x10) {			// with links ?
   1.222 ++		v[10] += 'A' - 'a';
   1.223 ++	}
   1.224 ++	return v;
   1.225  +}
   1.226  +
   1.227   /* Cloop suspend IOCTL */
   1.228 @@ -224,661 +170,538 @@
   1.229   
   1.230  --- cloop.c
   1.231  +++ cloop.c
   1.232 -@@ -1,26 +1,23 @@
   1.233 --/*
   1.234 -- *  compressed_loop.c: Read-only compressed loop blockdevice
   1.235 -- *  hacked up by Rusty in 1999, extended and maintained by Klaus Knopper
   1.236 -- *
   1.237 -- *  A cloop file looks like this:
   1.238 -- *  [32-bit uncompressed block size: network order]
   1.239 -- *  [32-bit number of blocks (n_blocks): network order]
   1.240 -- *  [64-bit file offsets of start of blocks: network order]
   1.241 -- *    ...
   1.242 -- *    (n_blocks + 1).
   1.243 -- * n_blocks consisting of:
   1.244 -- *   [compressed block]
   1.245 -- *
   1.246 -- * Every version greatly inspired by code seen in loop.c
   1.247 -- * by Theodore Ts'o, 3/29/93.
   1.248 -- *
   1.249 -- * Copyright 1999-2009 by Paul `Rusty' Russell & Klaus Knopper.
   1.250 -- * Redistribution of this file is permitted under the GNU Public License.
   1.251 -- *
   1.252 -- */
   1.253 -+/************************************************************************\
   1.254 -+* cloop.c: Read-only compressed loop blockdevice                         *
   1.255 -+* hacked up by Rusty in 1999, extended and maintained by Klaus Knopper   *
   1.256 -+*                                                                        *
   1.257 -+* For all supported cloop file formats, please check the file "cloop.h"  *
   1.258 -+* New in Version 4:                                                      *
   1.259 -+* - Header can be first or last in cloop file,                           *
   1.260 -+* - Different compression algorithms supported (compression type         *
   1.261 -+*   encoded in first 4 bytes of block offset address)                    *
   1.262 -+*                                                                        *
   1.263 -+* Every version greatly inspired by code seen in loop.c                  *
   1.264 -+* by Theodore Ts'o, 3/29/93.                                             *
   1.265 -+*                                                                        *
   1.266 -+* Copyright 1999-2009 by Paul `Rusty' Russell & Klaus Knopper.           *
   1.267 -+* Redistribution of this file is permitted under the GNU Public License  *
   1.268 -+* V2.                                                                    *
   1.269 -+\************************************************************************/
   1.270 +@@ -17,7 +17,7 @@
   1.271 + \************************************************************************/
   1.272   
   1.273   #define CLOOP_NAME "cloop"
   1.274 --#define CLOOP_VERSION "2.639"
   1.275 +-#define CLOOP_VERSION "5.3"
   1.276  +#define CLOOP_VERSION "4.12"
   1.277   #define CLOOP_MAX 8
   1.278   
   1.279   #ifndef KBUILD_MODNAME
   1.280 -@@ -47,8 +44,27 @@
   1.281 - #include <asm/div64.h> /* do_div() for 64bit division */
   1.282 - #include <asm/uaccess.h>
   1.283 - #include <asm/byteorder.h>
   1.284 --/* Use zlib_inflate from lib/zlib_inflate */
   1.285 -+/* Check for ZLIB, LZO1X, LZ4 decompression algorithms in kernel. */
   1.286 -+#if (defined(CONFIG_ZLIB_INFLATE) || defined(CONFIG_ZLIB_INFLATE_MODULE))
   1.287 - #include <linux/zutil.h>
   1.288 -+#endif
   1.289 -+#if (defined(CONFIG_LZO_DECOMPRESS) || defined(CONFIG_LZO_DECOMPRESS_MODULE))
   1.290 -+#include <linux/lzo.h>
   1.291 -+#endif
   1.292 -+#if (defined(CONFIG_DECOMPRESS_LZ4) || defined(CONFIG_DECOMPRESS_LZ4_MODULE))
   1.293 -+#include <linux/lz4.h>
   1.294 -+#endif
   1.295 -+#if (defined(CONFIG_DECOMPRESS_LZMA) || defined(CONFIG_DECOMPRESS_LZMA_MODULE))
   1.296 -+#include <linux/decompress/unlzma.h>
   1.297 -+#endif
   1.298 -+#if (defined(CONFIG_DECOMPRESS_XZ) || defined(CONFIG_DECOMPRESS_XZ_MODULE))
   1.299 -+#include <linux/xz.h>
   1.300 -+#endif
   1.301 -+
   1.302 -+#if (!(defined(CONFIG_ZLIB_INFLATE) || defined(CONFIG_ZLIB_INFLATE_MODULE) || defined(CONFIG_LZO_DECOMPRESS) || defined(CONFIG_LZO_DECOMPRESS_MODULE) || defined(CONFIG_DECOMPRESS_LZ4) || defined(CONFIG_DECOMPRESS_LZ4_MODULE) || defined(CONFIG_DECOMPRESS_LZMA) || defined(CONFIG_DECOMPRESS_LZMA_MODULE) || defined(CONFIG_DECOMPRESS_XZ) || defined(CONFIG_DECOMPRESS_XZ_MODULE)))
   1.303 -+#error "No decompression library selected in kernel config!"
   1.304 -+#endif
   1.305 -+
   1.306 +@@ -68,7 +68,6 @@
   1.307   #include <linux/loop.h>
   1.308   #include <linux/kthread.h>
   1.309   #include <linux/compat.h>
   1.310 -@@ -92,47 +108,64 @@
   1.311 - #define DEBUGP(format, x...)
   1.312 - #endif
   1.313 +-#include <linux/blk-mq.h> /* new multiqueue infrastructure */
   1.314 + #include "cloop.h"
   1.315   
   1.316 -+/* Default size of buffer to keep some decompressed blocks in memory to speed up access */
   1.317 -+#define BLOCK_BUFFER_MEM (16*65536)
   1.318 -+
   1.319 - /* One file can be opened at module insertion time */
   1.320 - /* insmod cloop file=/path/to/file */
   1.321 - static char *file=NULL;
   1.322 - static unsigned int preload=0;
   1.323 - static unsigned int cloop_max=CLOOP_MAX;
   1.324 -+static unsigned int buffers=BLOCK_BUFFER_MEM;
   1.325 - module_param(file, charp, 0);
   1.326 - module_param(preload, uint, 0);
   1.327 - module_param(cloop_max, uint, 0);
   1.328 - MODULE_PARM_DESC(file, "Initial cloop image file (full path) for /dev/cloop");
   1.329 - MODULE_PARM_DESC(preload, "Preload n blocks of cloop data into memory");
   1.330 - MODULE_PARM_DESC(cloop_max, "Maximum number of cloop devices (default 8)");
   1.331 -+MODULE_PARM_DESC(buffers, "Size of buffer to keep uncompressed blocks in memory in MiB (default 1)");
   1.332 + /* New License scheme */
   1.333 +@@ -93,10 +92,7 @@
   1.334 + /* Use experimental major for now */
   1.335 + #define MAJOR_NR 240
   1.336   
   1.337 - static struct file *initial_file=NULL;
   1.338 - static int cloop_major=MAJOR_NR;
   1.339 +-#ifndef DEVICE_NAME
   1.340 +-#define DEVICE_NAME CLOOP_NAME
   1.341 +-#endif
   1.342 +-
   1.343 ++/* #define DEVICE_NAME CLOOP_NAME */
   1.344 + /* #define DEVICE_NR(device) (MINOR(device)) */
   1.345 + /* #define DEVICE_ON(device) */
   1.346 + /* #define DEVICE_OFF(device) */
   1.347 +@@ -143,7 +139,7 @@
   1.348 +  u_int32_t allflags;
   1.349   
   1.350 --/* Number of buffered decompressed blocks */
   1.351 --#define BUFFERED_BLOCKS 8
   1.352 - struct cloop_device
   1.353 - {
   1.354 -- /* Copied straight from the file */
   1.355 -+ /* Header filled from the file */
   1.356 -  struct cloop_head head;
   1.357 -+ int header_first;
   1.358 -+ int file_format;
   1.359 - 
   1.360 -- /* An array of offsets of compressed blocks within the file */
   1.361 -- loff_t *offsets;
   1.362 -+ /* An or'd sum of all flags of each compressed block (v3) */
   1.363 -+ u_int32_t allflags;
   1.364 -+
   1.365 -+ /* An array of cloop_ptr flags/offset for compressed blocks within the file */
   1.366 +  /* An array of cloop_ptr flags/offset for compressed blocks within the file */
   1.367 +- cloop_block_ptr *block_ptrs;
   1.368  + struct block_info *block_ptrs;
   1.369   
   1.370    /* We buffer some uncompressed blocks for performance */
   1.371 -- int buffered_blocknum[BUFFERED_BLOCKS];
   1.372 -- int current_bufnum;
   1.373 -- void *buffer[BUFFERED_BLOCKS];
   1.374 -- void *compressed_buffer;
   1.375 -- size_t preload_array_size; /* Size of pointer array in blocks */
   1.376 -- size_t preload_size;       /* Number of successfully allocated blocks */
   1.377 -- char **preload_cache;      /* Pointers to preloaded blocks */
   1.378 -+ size_t num_buffered_blocks;	/* how many uncompressed blocks buffered for performance */
   1.379 -+ int *buffered_blocknum;        /* list of numbers of uncompressed blocks in buffer */
   1.380 -+ int current_bufnum;            /* which block is current */
   1.381 -+ unsigned char **buffer;        /* cache space for num_buffered_blocks uncompressed blocks */
   1.382 -+ void *compressed_buffer;       /* space for the largest compressed block */
   1.383 -+ size_t preload_array_size;     /* Size of pointer array in blocks */
   1.384 -+ size_t preload_size;           /* Number of successfully allocated blocks */
   1.385 -+ char **preload_cache;          /* Pointers to preloaded blocks */
   1.386 - 
   1.387 -+#if (defined(CONFIG_ZLIB_INFLATE) || defined(CONFIG_ZLIB_INFLATE_MODULE))
   1.388 -  z_stream zstream;
   1.389 -+#endif
   1.390 -+#if (defined(CONFIG_DECOMPRESS_XZ) || defined(CONFIG_DECOMPRESS_XZ_MODULE))
   1.391 -+ struct xz_dec *xzdecoderstate;
   1.392 -+ struct xz_buf xz_buffer;
   1.393 -+#endif
   1.394 - 
   1.395 -  struct file   *backing_file;  /* associated file */
   1.396 -  struct inode  *backing_inode; /* for bmap */
   1.397 - 
   1.398 -+ unsigned char *underlying_filename;
   1.399 -  unsigned long largest_block;
   1.400 -  unsigned int underlying_blksize;
   1.401 -+ loff_t underlying_total_size;
   1.402 -  int clo_number;
   1.403 -  int refcnt;
   1.404 -  struct block_device *bdev;
   1.405 -@@ -147,7 +180,6 @@
   1.406 +  size_t num_buffered_blocks;	/* how many uncompressed blocks buffered for performance */
   1.407 +@@ -178,14 +174,16 @@
   1.408 +  spinlock_t queue_lock;
   1.409 +  /* mutex for ioctl() */
   1.410 +  struct mutex clo_ctl_mutex;
   1.411 +- /* mutex for request */
   1.412 +- struct mutex clo_rq_mutex;
   1.413 ++ struct list_head clo_list;
   1.414 ++ struct task_struct *clo_thread;
   1.415 ++ wait_queue_head_t clo_event;
   1.416    struct request_queue *clo_queue;
   1.417    struct gendisk *clo_disk;
   1.418 +- struct blk_mq_tag_set tag_set;
   1.419    int suspended;
   1.420 -- char clo_file_name[LO_NAME_SIZE];
   1.421   };
   1.422   
   1.423 - /* Changed in 2.639: cloop_dev is now a an array of cloop_dev pointers,
   1.424 -@@ -156,52 +188,113 @@
   1.425 ++/* Changed in 2.639: cloop_dev is now a an array of cloop_dev pointers,
   1.426 ++   so we can specify how many devices we need via parameters. */
   1.427 + static struct cloop_device **cloop_dev;
   1.428   static const char *cloop_name=CLOOP_NAME;
   1.429   static int cloop_count = 0;
   1.430 - 
   1.431 --#if (!(defined(CONFIG_ZLIB_INFLATE) || defined(CONFIG_ZLIB_INFLATE_MODULE))) /* Must be compiled into kernel. */
   1.432 --#error  "Invalid Kernel configuration. CONFIG_ZLIB_INFLATE support is needed for cloop."
   1.433 --#endif
   1.434 --
   1.435 --/* Use __get_free_pages instead of vmalloc, allows up to 32 pages,
   1.436 -- * 2MB in one piece */
   1.437 - static void *cloop_malloc(size_t size)
   1.438 - {
   1.439 -- int order = get_order(size);
   1.440 -- if(order <= KMALLOC_MAX_ORDER)
   1.441 --   return (void *)kmalloc(size, GFP_KERNEL);
   1.442 -- else if(order < MAX_ORDER)
   1.443 --   return (void *)__get_free_pages(GFP_KERNEL, order);
   1.444 -+ /* kmalloc will fail after the system is running for a while, */
   1.445 -+ /* when large orders can't return contiguous memory. */
   1.446 -+ /* Let's just use vmalloc for now. :-/ */
   1.447 -+ /* int order = get_order(size); */
   1.448 -+ /* if(order <= KMALLOC_MAX_ORDER) */
   1.449 -+ /*  return (void *)kmalloc(size, GFP_KERNEL); */
   1.450 -+ /* else if(order < MAX_ORDER) */
   1.451 -+ /*  return (void *)__get_free_pages(GFP_KERNEL, order); */
   1.452 -  return (void *)vmalloc(size);
   1.453 +@@ -214,24 +212,21 @@
   1.454 +  vfree(mem);
   1.455   }
   1.456   
   1.457 - static void cloop_free(void *mem, size_t size)
   1.458 - {
   1.459 -- int order = get_order(size);
   1.460 -- if(order <= KMALLOC_MAX_ORDER)
   1.461 --   kfree(mem);
   1.462 -- else if(order < MAX_ORDER)
   1.463 --   free_pages((unsigned long)mem, order);
   1.464 -- else vfree(mem);
   1.465 -+ /* int order = get_order(size); */
   1.466 -+ /* if(order <= KMALLOC_MAX_ORDER) */
   1.467 -+ /*  kfree(mem); */
   1.468 -+ /* else if(order < MAX_ORDER) */
   1.469 -+ /*  free_pages((unsigned long)mem, order); */
   1.470 -+ /* else */
   1.471 -+ vfree(mem);
   1.472 - }
   1.473 - 
   1.474 --static int uncompress(struct cloop_device *clo,
   1.475 --                      unsigned char *dest, unsigned long *destLen,
   1.476 --                      unsigned char *source, unsigned long sourceLen)
   1.477 +-/* static int uncompress(struct cloop_device *clo, unsigned char *dest, unsigned long *destLen, unsigned char *source, unsigned long sourceLen) */
   1.478 +-static int uncompress(struct cloop_device *clo, u_int32_t block_num, u_int32_t compressed_length, unsigned long *uncompressed_length)
   1.479  +static int uncompress(struct cloop_device *clo, unsigned char *dest, unsigned long *destLen, unsigned char *source, unsigned long sourceLen, int flags) 
   1.480   {
   1.481 -- /* Most of this code can be found in fs/cramfs/uncompress.c */
   1.482 -- int err;
   1.483 -- clo->zstream.next_in = source;
   1.484 -- clo->zstream.avail_in = sourceLen;
   1.485 -- clo->zstream.next_out = dest;
   1.486 -- clo->zstream.avail_out = *destLen;
   1.487 -- err = zlib_inflateReset(&clo->zstream);
   1.488 -- if (err != Z_OK)
   1.489 --  {
   1.490 --   printk(KERN_ERR "%s: zlib_inflateReset error %d\n", cloop_name, err);
   1.491 --   zlib_inflateEnd(&clo->zstream); zlib_inflateInit(&clo->zstream);
   1.492 --  }
   1.493 -- err = zlib_inflate(&clo->zstream, Z_FINISH);
   1.494 -- *destLen = clo->zstream.total_out;
   1.495 -- if (err != Z_STREAM_END) return err;
   1.496 -- return Z_OK;
   1.497 -+ int err = -1;
   1.498 -+ switch(flags)
   1.499 -+ {
   1.500 -+  case CLOOP_COMPRESSOR_NONE:
   1.501 +  int err = -1;
   1.502 +- int flags = CLOOP_BLOCK_FLAGS(clo->block_ptrs[block_num]);
   1.503 +  switch(flags)
   1.504 +  {
   1.505 +   case CLOOP_COMPRESSOR_NONE:
   1.506 +-   /* block is umcompressed, swap pointers only! */
   1.507 +-   { char *tmp = clo->compressed_buffer; clo->compressed_buffer = clo->buffer[clo->current_bufnum]; clo->buffer[clo->current_bufnum] = tmp; }
   1.508 +-   DEBUGP("cloop: block %d is uncompressed (flags=%d), just swapping %u bytes\n", block_num, flags, compressed_length);
   1.509  +   memcpy(dest, source, *destLen = sourceLen);
   1.510  +   err = Z_OK;
   1.511 -+   break;
   1.512 -+#if (defined(CONFIG_ZLIB_INFLATE) || defined(CONFIG_ZLIB_INFLATE_MODULE))
   1.513 -+  case CLOOP_COMPRESSOR_ZLIB:
   1.514 +    break;
   1.515 + #if (defined(CONFIG_ZLIB_INFLATE) || defined(CONFIG_ZLIB_INFLATE_MODULE))
   1.516 +   case CLOOP_COMPRESSOR_ZLIB:
   1.517 +-   clo->zstream.next_in = clo->compressed_buffer;
   1.518 +-   clo->zstream.avail_in = compressed_length;
   1.519 +-   clo->zstream.next_out = clo->buffer[clo->current_bufnum];
   1.520 +-   clo->zstream.avail_out = clo->head.block_size;
   1.521  +   clo->zstream.next_in = source;
   1.522  +   clo->zstream.avail_in = sourceLen;
   1.523  +   clo->zstream.next_out = dest;
   1.524  +   clo->zstream.avail_out = *destLen;
   1.525 -+   err = zlib_inflateReset(&clo->zstream);
   1.526 -+   if (err != Z_OK)
   1.527 -+   {
   1.528 -+    printk(KERN_ERR "%s: zlib_inflateReset error %d\n", cloop_name, err);
   1.529 -+    zlib_inflateEnd(&clo->zstream); zlib_inflateInit(&clo->zstream);
   1.530 -+   }
   1.531 -+   err = zlib_inflate(&clo->zstream, Z_FINISH);
   1.532 +    err = zlib_inflateReset(&clo->zstream);
   1.533 +    if (err != Z_OK)
   1.534 +    {
   1.535 +@@ -239,50 +234,50 @@
   1.536 +     zlib_inflateEnd(&clo->zstream); zlib_inflateInit(&clo->zstream);
   1.537 +    }
   1.538 +    err = zlib_inflate(&clo->zstream, Z_FINISH);
   1.539 +-   *uncompressed_length = clo->zstream.total_out;
   1.540  +   *destLen = clo->zstream.total_out;
   1.541 -+   if (err == Z_STREAM_END) err = 0;
   1.542 +    if (err == Z_STREAM_END) err = 0;
   1.543 +-   DEBUGP("cloop: zlib decompression done, ret =%d, size =%lu\n", err, *uncompressed_length);
   1.544  +   DEBUGP("cloop: zlib decompression done, ret =%d, size =%lu\n", err, *destLen);
   1.545 -+   break;
   1.546 -+#endif
   1.547 -+#if (defined(CONFIG_LZO_DECOMPRESS) || defined(CONFIG_LZO_DECOMPRESS_MODULE))
   1.548 -+  case CLOOP_COMPRESSOR_LZO1X:
   1.549 -+   {
   1.550 -+    size_t tmp = (size_t) clo->head.block_size;
   1.551 +    break;
   1.552 + #endif
   1.553 + #if (defined(CONFIG_LZO_DECOMPRESS) || defined(CONFIG_LZO_DECOMPRESS_MODULE))
   1.554 +   case CLOOP_COMPRESSOR_LZO1X:
   1.555 +    {
   1.556 +     size_t tmp = (size_t) clo->head.block_size;
   1.557 +-    err = lzo1x_decompress_safe(clo->compressed_buffer, compressed_length,
   1.558 +-             clo->buffer[clo->current_bufnum], &tmp);
   1.559 +-    if (err == LZO_E_OK) *uncompressed_length = (u_int32_t) tmp;
   1.560  +    err = lzo1x_decompress_safe(source, sourceLen,
   1.561  +             dest, &tmp);
   1.562  +    if (err == LZO_E_OK) *destLen = (u_int32_t) tmp;
   1.563 -+   }
   1.564 -+   break;
   1.565 -+#endif
   1.566 -+#if (defined(CONFIG_DECOMPRESS_LZ4) || defined(CONFIG_DECOMPRESS_LZ4_MODULE))
   1.567 -+  case CLOOP_COMPRESSOR_LZ4:
   1.568 -+   {
   1.569 +    }
   1.570 +    break;
   1.571 + #endif
   1.572 + #if (defined(CONFIG_DECOMPRESS_LZ4) || defined(CONFIG_DECOMPRESS_LZ4_MODULE))
   1.573 +   case CLOOP_COMPRESSOR_LZ4:
   1.574 +    {
   1.575 +-    size_t outputSize = clo->head.block_size;
   1.576  +    size_t outputSize = *destLen;
   1.577 -+    /* We should adjust outputSize here, in case the last block is smaller than block_size */
   1.578 -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0) /* field removed */
   1.579 +     /* We should adjust outputSize here, in case the last block is smaller than block_size */
   1.580 + #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0) /* field removed */
   1.581 +-    err = lz4_decompress(clo->compressed_buffer, (size_t *) &compressed_length,
   1.582 +-                         clo->buffer[clo->current_bufnum], outputSize);
   1.583  +    err = lz4_decompress(source, (size_t *) &sourceLen,
   1.584  +                         dest, outputSize);
   1.585 -+#else
   1.586 + #else
   1.587 +-    err = LZ4_decompress_safe(clo->compressed_buffer,
   1.588 +-                              clo->buffer[clo->current_bufnum],
   1.589 +-                              compressed_length, outputSize);
   1.590  +    err = LZ4_decompress_safe(source,
   1.591  +                              dest,
   1.592  +                              sourceLen, outputSize);
   1.593 -+#endif
   1.594 -+    if (err >= 0) 
   1.595 -+    {
   1.596 -+     err = 0;
   1.597 + #endif
   1.598 +     if (err >= 0) 
   1.599 +     {
   1.600 +      err = 0;
   1.601 +-     *uncompressed_length = outputSize;
   1.602  +     *destLen = outputSize;
   1.603 -+    }
   1.604 -+   }
   1.605 -+  break;
   1.606 -+#endif
   1.607 -+#if (defined(CONFIG_DECOMPRESS_XZ) || defined(CONFIG_DECOMPRESS_XZ_MODULE))
   1.608 -+ case CLOOP_COMPRESSOR_XZ:
   1.609 +     }
   1.610 +    }
   1.611 +   break;
   1.612 + #endif
   1.613 + #if (defined(CONFIG_DECOMPRESS_XZ) || defined(CONFIG_DECOMPRESS_XZ_MODULE))
   1.614 +  case CLOOP_COMPRESSOR_XZ:
   1.615 +-  clo->xz_buffer.in = clo->compressed_buffer;
   1.616  +  clo->xz_buffer.in = source;
   1.617 -+  clo->xz_buffer.in_pos = 0;
   1.618 +   clo->xz_buffer.in_pos = 0;
   1.619 +-  clo->xz_buffer.in_size = compressed_length;
   1.620 +-  clo->xz_buffer.out = clo->buffer[clo->current_bufnum];
   1.621  +  clo->xz_buffer.in_size = sourceLen;
   1.622  +  clo->xz_buffer.out = dest;
   1.623 -+  clo->xz_buffer.out_pos = 0;
   1.624 +   clo->xz_buffer.out_pos = 0;
   1.625 +-  clo->xz_buffer.out_size = clo->head.block_size;
   1.626  +  clo->xz_buffer.out_size = *destLen;
   1.627 -+  xz_dec_reset(clo->xzdecoderstate);
   1.628 -+  err = xz_dec_run(clo->xzdecoderstate, &clo->xz_buffer);
   1.629 -+  if (err == XZ_STREAM_END || err == XZ_OK)
   1.630 -+  {
   1.631 -+   err = 0;
   1.632 -+  }
   1.633 -+  else
   1.634 -+  {
   1.635 -+   printk(KERN_ERR "%s: xz_dec_run error %d\n", cloop_name, err);
   1.636 -+   err = 1;
   1.637 -+  }
   1.638 -+  break;
   1.639 -+#endif
   1.640 -+ default:
   1.641 -+   printk(KERN_ERR "%s: compression method is not supported!\n", cloop_name);
   1.642 -+ }
   1.643 -+ return err;
   1.644 - }
   1.645 - 
   1.646 - static ssize_t cloop_read_from_file(struct cloop_device *clo, struct file *f, char *buf,
   1.647 -@@ -220,7 +313,7 @@
   1.648 +   xz_dec_reset(clo->xzdecoderstate);
   1.649 +   err = xz_dec_run(clo->xzdecoderstate, &clo->xz_buffer);
   1.650 +   if (err == XZ_STREAM_END || err == XZ_OK)
   1.651 +@@ -309,16 +304,12 @@
   1.652 +  while (buf_done < buf_len)
   1.653 +   {
   1.654 +    size_t size = buf_len - buf_done, size_read;
   1.655 +-   mm_segment_t old_fs;
   1.656 +    /* kernel_read() only supports 32 bit offsets, so we use vfs_read() instead. */
   1.657 +    /* int size_read = kernel_read(f, pos, buf + buf_done, size); */
   1.658 +-
   1.659 +-   // mutex_lock(&clo->clo_rq_mutex);
   1.660 +-   old_fs = get_fs();
   1.661 +-   set_fs(KERNEL_DS);
   1.662 ++   mm_segment_t old_fs = get_fs();
   1.663 ++   set_fs(get_ds());
   1.664 +    size_read = vfs_read(f, (void __user *)(buf + buf_done), size, &pos);
   1.665 +    set_fs(old_fs);
   1.666 +-   // mutex_unlock(&clo->clo_rq_mutex);
   1.667   
   1.668      if(size_read <= 0)
   1.669       {
   1.670 --     printk(KERN_ERR "%s: Read error %d at pos %Lu in file %s, "
   1.671 -+     printk(KERN_ERR "%s: Read error %d at pos %llu in file %s, "
   1.672 -                      "%d bytes lost.\n", cloop_name, (int)size_read, pos,
   1.673 - 		     file, (int)size);
   1.674 -      memset(buf + buf_len - size, 0, size);
   1.675 -@@ -232,72 +325,84 @@
   1.676 - }
   1.677 +@@ -358,8 +349,8 @@
   1.678 +    return i;
   1.679 +   }
   1.680   
   1.681 - /* This looks more complicated than it is */
   1.682 --/* Returns number of block buffer to use for this request */
   1.683 -+/* Returns number of cache block buffer to use for this request */
   1.684 - static int cloop_load_buffer(struct cloop_device *clo, int blocknum)
   1.685 - {
   1.686 -- unsigned int buf_done = 0;
   1.687 -- unsigned long buflen;
   1.688 -- unsigned int buf_length;
   1.689 -+ loff_t compressed_block_offset;
   1.690 -+ long compressed_block_len;
   1.691 -+ long uncompressed_block_len=0;
   1.692 -  int ret;
   1.693 -  int i;
   1.694 -- if(blocknum > ntohl(clo->head.num_blocks) || blocknum < 0)
   1.695 --  {
   1.696 --   printk(KERN_WARNING "%s: Invalid block number %d requested.\n",
   1.697 --                       cloop_name, blocknum);
   1.698 --   return -1;
   1.699 --  }
   1.700 -+ if(blocknum > clo->head.num_blocks || blocknum < 0)
   1.701 -+ {
   1.702 -+  printk(KERN_WARNING "%s: Invalid block number %d requested.\n",
   1.703 -+         cloop_name, blocknum);
   1.704 -+  return -1;
   1.705 -+ }
   1.706 - 
   1.707 -  /* Quick return if the block we seek is already in one of the buffers. */
   1.708 -  /* Return number of buffer */
   1.709 -- for(i=0; i<BUFFERED_BLOCKS; i++)
   1.710 -+ for(i=0; i<clo->num_buffered_blocks; i++)
   1.711 -   if (blocknum == clo->buffered_blocknum[i])
   1.712 --   {
   1.713 --    DEBUGP(KERN_INFO "cloop_load_buffer: Found buffered block %d\n", i);
   1.714 --    return i;
   1.715 --   }
   1.716 --
   1.717 -- buf_length = be64_to_cpu(clo->offsets[blocknum+1]) - be64_to_cpu(clo->offsets[blocknum]);
   1.718 --
   1.719 --/* Load one compressed block from the file. */
   1.720 -- cloop_read_from_file(clo, clo->backing_file, (char *)clo->compressed_buffer,
   1.721 --                    be64_to_cpu(clo->offsets[blocknum]), buf_length);
   1.722 -+  {
   1.723 -+   DEBUGP(KERN_INFO "cloop_load_buffer: Found buffered block %d\n", i);
   1.724 -+   return i;
   1.725 -+  }
   1.726 - 
   1.727 -- buflen = ntohl(clo->head.block_size);
   1.728 +- compressed_block_offset = CLOOP_BLOCK_OFFSET(clo->block_ptrs[blocknum]);
   1.729 +- compressed_block_len = (long) (CLOOP_BLOCK_OFFSET(clo->block_ptrs[blocknum+1]) - compressed_block_offset) ;
   1.730  + compressed_block_offset = clo->block_ptrs[blocknum].offset;
   1.731  + compressed_block_len = (long) (clo->block_ptrs[blocknum].size) ;
   1.732   
   1.733 -- /* Go to next position in the block ring buffer */
   1.734 -- clo->current_bufnum++;
   1.735 -- if(clo->current_bufnum >= BUFFERED_BLOCKS) clo->current_bufnum = 0;
   1.736 -+ /* Load one compressed block from the file. */
   1.737 -+ if(compressed_block_offset > 0 && compressed_block_len >= 0) /* sanity check */
   1.738 -+ {
   1.739 -+  size_t n = cloop_read_from_file(clo, clo->backing_file, (char *)clo->compressed_buffer,
   1.740 -+                    compressed_block_offset, compressed_block_len);
   1.741 -+  if (n!= compressed_block_len)
   1.742 -+   {
   1.743 -+    printk(KERN_ERR "%s: error while reading %lu bytes @ %llu from file %s\n",
   1.744 +  /* Load one compressed block from the file. */
   1.745 +  if(compressed_block_offset > 0 && compressed_block_len >= 0) /* sanity check */
   1.746 +@@ -369,12 +360,12 @@
   1.747 +   if (n!= compressed_block_len)
   1.748 +    {
   1.749 +     printk(KERN_ERR "%s: error while reading %lu bytes @ %llu from file %s\n",
   1.750 +-     cloop_name, compressed_block_len, clo->block_ptrs[blocknum], clo->underlying_filename);
   1.751  +     cloop_name, compressed_block_len, clo->block_ptrs[blocknum].offset, clo->underlying_filename);
   1.752 -+    /* return -1; */
   1.753 -+   }
   1.754 -+ } else {
   1.755 -+  printk(KERN_ERR "%s: invalid data block len %ld bytes @ %lld from file %s\n",
   1.756 +     /* return -1; */
   1.757 +    }
   1.758 +  } else {
   1.759 +   printk(KERN_ERR "%s: invalid data block len %ld bytes @ %lld from file %s\n",
   1.760 +-  cloop_name, compressed_block_len, clo->block_ptrs[blocknum], clo->underlying_filename);
   1.761  +  cloop_name, compressed_block_len, clo->block_ptrs[blocknum].offset, clo->underlying_filename);
   1.762 -+  return -1;
   1.763 -+ }
   1.764 -+  
   1.765 -+ /* Go to next position in the cache block buffer (which is used as a cyclic buffer) */
   1.766 -+ if(++clo->current_bufnum >= clo->num_buffered_blocks) clo->current_bufnum = 0;
   1.767 +   return -1;
   1.768 +  }
   1.769 +   
   1.770 +@@ -382,14 +373,16 @@
   1.771 +  if(++clo->current_bufnum >= clo->num_buffered_blocks) clo->current_bufnum = 0;
   1.772   
   1.773    /* Do the uncompression */
   1.774 -- ret = uncompress(clo, clo->buffer[clo->current_bufnum], &buflen, clo->compressed_buffer,
   1.775 --                  buf_length);
   1.776 +- ret = uncompress(clo, blocknum, compressed_block_len, &uncompressed_block_len);
   1.777  + uncompressed_block_len = clo->head.block_size;
   1.778  + ret = uncompress(clo, clo->buffer[clo->current_bufnum], &uncompressed_block_len,
   1.779  +	 clo->compressed_buffer, compressed_block_len, clo->block_ptrs[blocknum].flags);
   1.780    /* DEBUGP("cloop: buflen after uncompress: %ld\n",buflen); */
   1.781    if (ret != 0)
   1.782 --  {
   1.783 --   printk(KERN_ERR "%s: zlib decompression error %i uncompressing block %u %u/%lu/%u/%u "
   1.784 --          "%Lu-%Lu\n", cloop_name, ret, blocknum,
   1.785 --	  ntohl(clo->head.block_size), buflen, buf_length, buf_done,
   1.786 --	  be64_to_cpu(clo->offsets[blocknum]), be64_to_cpu(clo->offsets[blocknum+1]));
   1.787 --   clo->buffered_blocknum[clo->current_bufnum] = -1;
   1.788 --   return -1;
   1.789 --  }
   1.790 -+ {
   1.791 -+  printk(KERN_ERR "%s: decompression error %i uncompressing block %u %lu bytes @ %llu, flags %u\n",
   1.792 -+         cloop_name, ret, blocknum,
   1.793 +  {
   1.794 +   printk(KERN_ERR "%s: decompression error %i uncompressing block %u %lu bytes @ %llu, flags %u\n",
   1.795 +          cloop_name, ret, blocknum,
   1.796 +-         compressed_block_len, CLOOP_BLOCK_OFFSET(clo->block_ptrs[blocknum]),
   1.797 +-         CLOOP_BLOCK_FLAGS(clo->block_ptrs[blocknum]));
   1.798  +         compressed_block_len, clo->block_ptrs[blocknum].offset,
   1.799  +         clo->block_ptrs[blocknum].flags);
   1.800 -+         clo->buffered_blocknum[clo->current_bufnum] = -1;
   1.801 -+  return -1;
   1.802 -+ }
   1.803 -  clo->buffered_blocknum[clo->current_bufnum] = blocknum;
   1.804 +          clo->buffered_blocknum[clo->current_bufnum] = -1;
   1.805 +   return -1;
   1.806 +  }
   1.807 +@@ -397,107 +390,146 @@
   1.808    return clo->current_bufnum;
   1.809   }
   1.810   
   1.811 - /* This function does all the real work. */
   1.812 --/* returns "uptodate" */
   1.813 +-static blk_status_t cloop_handle_request(struct cloop_device *clo, struct request *req)
   1.814 ++/* This function does all the real work. */
   1.815  +/* returns "uptodate"                    */
   1.816 - static int cloop_handle_request(struct cloop_device *clo, struct request *req)
   1.817 ++static int cloop_handle_request(struct cloop_device *clo, struct request *req)
   1.818   {
   1.819    int buffered_blocknum = -1;
   1.820    int preloaded = 0;
   1.821 -  loff_t offset     = (loff_t) blk_rq_pos(req)<<9; /* req->sector<<9 */
   1.822 -- struct bio_vec *bvec;
   1.823 -+ struct bio_vec bvec;
   1.824 +- loff_t offset = (loff_t) blk_rq_pos(req)<<9;
   1.825 ++ loff_t offset     = (loff_t) blk_rq_pos(req)<<9; /* req->sector<<9 */
   1.826 +  struct bio_vec bvec;
   1.827    struct req_iterator iter;
   1.828 +- blk_status_t ret = BLK_STS_OK;
   1.829 +-
   1.830 +- if (unlikely(req_op(req) != REQ_OP_READ ))
   1.831 +- {
   1.832 +-  blk_dump_rq_flags(req, DEVICE_NAME " bad request");
   1.833 +-  return BLK_STS_IOERR;
   1.834 +- }
   1.835 +-
   1.836 +- if (unlikely(!clo->backing_file && !clo->suspended))
   1.837 +- {
   1.838 +-  DEBUGP("cloop_handle_request: not connected to a file\n");
   1.839 +-  return BLK_STS_IOERR;
   1.840 +- }
   1.841 +-
   1.842    rq_for_each_segment(bvec, req, iter)
   1.843 +- {
   1.844 +-  unsigned long len = bvec.bv_len;
   1.845 +-  loff_t to_offset  = bvec.bv_offset;
   1.846 +-
   1.847 +-  while(len > 0)
   1.848     {
   1.849 --   unsigned long len = bvec->bv_len;
   1.850 --   char *to_ptr      = kmap(bvec->bv_page) + bvec->bv_offset;
   1.851 +-   u_int32_t length_in_buffer;
   1.852 +-   loff_t block_offset = offset;
   1.853 +-   u_int32_t offset_in_buffer;
   1.854 +-   char *from_ptr, *to_ptr;
   1.855 +-   /* do_div (div64.h) returns the 64bit division remainder and  */
   1.856 +-   /* puts the result in the first argument, i.e. block_offset   */
   1.857 +-   /* becomes the blocknumber to load, and offset_in_buffer the  */
   1.858 +-   /* position in the buffer */
   1.859 +-   offset_in_buffer = do_div(block_offset, clo->head.block_size);
   1.860 +-   /* Lookup preload cache */
   1.861 +-   if(block_offset < clo->preload_size && clo->preload_cache != NULL && clo->preload_cache[block_offset] != NULL)
   1.862 +-   { /* Copy from cache */
   1.863 +-    preloaded = 1;
   1.864 +-    from_ptr = clo->preload_cache[block_offset];
   1.865 +-   }
   1.866 +-   else
   1.867 +-   {
   1.868 +-    preloaded = 0;
   1.869 +-    buffered_blocknum = cloop_load_buffer(clo,block_offset);
   1.870 +-    if(buffered_blocknum == -1)
   1.871  +   unsigned long len = bvec.bv_len;
   1.872  +   char *to_ptr      = kmap(bvec.bv_page) + bvec.bv_offset;
   1.873 -    while(len > 0)
   1.874 ++   while(len > 0)
   1.875       {
   1.876 -      u_int32_t length_in_buffer;
   1.877 -@@ -308,7 +413,7 @@
   1.878 -      /* puts the result in the first argument, i.e. block_offset   */
   1.879 -      /* becomes the blocknumber to load, and offset_in_buffer the  */
   1.880 -      /* position in the buffer */
   1.881 --     offset_in_buffer = do_div(block_offset, ntohl(clo->head.block_size));
   1.882 +-     ret = BLK_STS_IOERR;
   1.883 +-     break; /* invalid data, leave inner loop */
   1.884 ++     u_int32_t length_in_buffer;
   1.885 ++     loff_t block_offset = offset;
   1.886 ++     u_int32_t offset_in_buffer;
   1.887 ++     char *from_ptr;
   1.888 ++     /* do_div (div64.h) returns the 64bit division remainder and  */
   1.889 ++     /* puts the result in the first argument, i.e. block_offset   */
   1.890 ++     /* becomes the blocknumber to load, and offset_in_buffer the  */
   1.891 ++     /* position in the buffer */
   1.892  +     offset_in_buffer = do_div(block_offset, clo->head.block_size);
   1.893 -      /* Lookup preload cache */
   1.894 -      if(block_offset < clo->preload_size && clo->preload_cache != NULL &&
   1.895 -         clo->preload_cache[block_offset] != NULL)
   1.896 -@@ -325,7 +430,7 @@
   1.897 -        from_ptr = clo->buffer[buffered_blocknum];
   1.898 -       }
   1.899 -      /* Now, at least part of what we want will be in the buffer. */
   1.900 --     length_in_buffer = ntohl(clo->head.block_size) - offset_in_buffer;
   1.901 ++     /* Lookup preload cache */
   1.902 ++     if(block_offset < clo->preload_size && clo->preload_cache != NULL &&
   1.903 ++        clo->preload_cache[block_offset] != NULL)
   1.904 ++      { /* Copy from cache */
   1.905 ++       preloaded = 1;
   1.906 ++       from_ptr = clo->preload_cache[block_offset];
   1.907 ++      }
   1.908 ++     else
   1.909 ++      {
   1.910 ++       preloaded = 0;
   1.911 ++       buffered_blocknum = cloop_load_buffer(clo,block_offset);
   1.912 ++       if(buffered_blocknum == -1) break; /* invalid data, leave inner loop */
   1.913 ++       /* Copy from buffer */
   1.914 ++       from_ptr = clo->buffer[buffered_blocknum];
   1.915 ++      }
   1.916 ++     /* Now, at least part of what we want will be in the buffer. */
   1.917  +     length_in_buffer = clo->head.block_size - offset_in_buffer;
   1.918 -      if(length_in_buffer > len)
   1.919 -       {
   1.920 - /*   DEBUGP("Warning: length_in_buffer=%u > len=%u\n",
   1.921 -@@ -337,18 +442,19 @@
   1.922 -      len         -= length_in_buffer;
   1.923 -      offset      += length_in_buffer;
   1.924 -     } /* while inner loop */
   1.925 --   kunmap(bvec->bv_page);
   1.926 ++     if(length_in_buffer > len)
   1.927 ++      {
   1.928 ++/*   DEBUGP("Warning: length_in_buffer=%u > len=%u\n",
   1.929 ++                      length_in_buffer,len); */
   1.930 ++       length_in_buffer = len;
   1.931 ++      }
   1.932 ++     memcpy(to_ptr, from_ptr + offset_in_buffer, length_in_buffer);
   1.933 ++     to_ptr      += length_in_buffer;
   1.934 ++     len         -= length_in_buffer;
   1.935 ++     offset      += length_in_buffer;
   1.936 ++    } /* while inner loop */
   1.937  +   kunmap(bvec.bv_page);
   1.938  +   cond_resched();
   1.939 -   } /* end rq_for_each_segment*/
   1.940 -  return ((buffered_blocknum!=-1) || preloaded);
   1.941 - }
   1.942 - 
   1.943 - /* Adopted from loop.c, a kernel thread to handle physical reads and
   1.944 -- * decompression. */
   1.945 ++  } /* end rq_for_each_segment*/
   1.946 ++ return ((buffered_blocknum!=-1) || preloaded);
   1.947 ++}
   1.948 ++
   1.949 ++/* Adopted from loop.c, a kernel thread to handle physical reads and
   1.950  +   decompression. */
   1.951 - static int cloop_thread(void *data)
   1.952 - {
   1.953 -  struct cloop_device *clo = data;
   1.954 -  current->flags |= PF_NOFREEZE;
   1.955 -- set_user_nice(current, -15);
   1.956 ++static int cloop_thread(void *data)
   1.957 ++{
   1.958 ++ struct cloop_device *clo = data;
   1.959 ++ current->flags |= PF_NOFREEZE;
   1.960  + set_user_nice(current, 10);
   1.961 -  while (!kthread_should_stop()||!list_empty(&clo->clo_list))
   1.962 -   {
   1.963 -    int err;
   1.964 -@@ -390,10 +496,18 @@
   1.965 -    int rw;
   1.966 -  /* quick sanity checks */
   1.967 -    /* blk_fs_request() was removed in 2.6.36 */
   1.968 --   if (unlikely(req == NULL || (req->cmd_type != REQ_TYPE_FS)))
   1.969 ++ while (!kthread_should_stop()||!list_empty(&clo->clo_list))
   1.970 ++  {
   1.971 ++   int err;
   1.972 ++   err = wait_event_interruptible(clo->clo_event, !list_empty(&clo->clo_list) || 
   1.973 ++                                  kthread_should_stop());
   1.974 ++   if(unlikely(err))
   1.975 ++    {
   1.976 ++     DEBUGP(KERN_ERR "cloop thread activated on error!? Continuing.\n");
   1.977 ++     continue;
   1.978 +     }
   1.979 +-    /* Copy from buffer */
   1.980 +-    from_ptr = clo->buffer[buffered_blocknum];
   1.981 +-   }
   1.982 +-   /* Now, at least part of what we want will be in the buffer. */
   1.983 +-   length_in_buffer = clo->head.block_size - offset_in_buffer;
   1.984 +-   if(length_in_buffer > len)
   1.985 +-   {
   1.986 +-   /* DEBUGP("Warning: length_in_buffer=%u > len=%u\n", length_in_buffer,len); */
   1.987 +-    length_in_buffer = len;
   1.988 +-   }
   1.989 +-   to_ptr      = kmap_atomic(bvec.bv_page);
   1.990 +-   memcpy(to_ptr + to_offset, from_ptr + offset_in_buffer, length_in_buffer);
   1.991 +-   kunmap_atomic(to_ptr);
   1.992 +-   to_offset   += length_in_buffer;
   1.993 +-   len         -= length_in_buffer;
   1.994 +-   offset      += length_in_buffer;
   1.995 +-  } /* while inner loop */
   1.996 +- } /* rq_for_each_segment */
   1.997 +- return ret;
   1.998 +-}
   1.999 +-
  1.1000 +-static blk_status_t cloop_queue_rq(struct blk_mq_hw_ctx *hctx, const struct blk_mq_queue_data *bd)
  1.1001 +-{
  1.1002 +-//  struct request_queue *q  = hctx->queue;
  1.1003 +-//  struct cloop_device *clo = q->queuedata;
  1.1004 +- struct request *req = bd->rq;
  1.1005 +- struct cloop_device *clo = req->rq_disk->private_data;
  1.1006 +- blk_status_t ret         = BLK_STS_OK;
  1.1007 +-
  1.1008 +-#if 1 /* Does it work when loading libraries? */
  1.1009 +- /* Since we have a buffered block list as well as data to read */
  1.1010 +- /* from disk (slow), and are (probably) never called from an   */
  1.1011 +- /* interrupt, we use a simple mutex lock right here to ensure  */
  1.1012 +- /* consistency.                                                */
  1.1013 +-  mutex_lock(&clo->clo_rq_mutex);
  1.1014 +- #else
  1.1015 +-  spin_lock_irq(&clo->queue_lock);
  1.1016 +- #endif
  1.1017 +- blk_mq_start_request(req);
  1.1018 +- do {
  1.1019 +-  ret = cloop_handle_request(clo, req);
  1.1020 +- } while(blk_update_request(req, ret, blk_rq_cur_bytes(req)));
  1.1021 +- blk_mq_end_request(req, ret);
  1.1022 +- #if 1 /* See above */
  1.1023 +-  mutex_unlock(&clo->clo_rq_mutex);
  1.1024 +- #else
  1.1025 +-  spin_unlock_irq(&clo->queue_lock);
  1.1026 +- #endif
  1.1027 +- return ret;
  1.1028 ++   if(!list_empty(&clo->clo_list))
  1.1029 ++    {
  1.1030 ++     struct request *req;
  1.1031 ++     unsigned long flags;
  1.1032 ++     int uptodate;
  1.1033 ++     spin_lock_irq(&clo->queue_lock);
  1.1034 ++     req = list_entry(clo->clo_list.next, struct request, queuelist);
  1.1035 ++     list_del_init(&req->queuelist);
  1.1036 ++     spin_unlock_irq(&clo->queue_lock);
  1.1037 ++     uptodate = cloop_handle_request(clo, req);
  1.1038 ++     spin_lock_irqsave(&clo->queue_lock, flags);
  1.1039 ++     __blk_end_request_all(req, uptodate ? 0 : -EIO);
  1.1040 ++     spin_unlock_irqrestore(&clo->queue_lock, flags);
  1.1041 ++    }
  1.1042 ++  }
  1.1043 ++ DEBUGP(KERN_ERR "cloop_thread exited.\n");
  1.1044 ++ return 0;
  1.1045 ++}
  1.1046 ++
  1.1047 ++/* This is called by the kernel block queue management every now and then,
  1.1048 ++ * with successive read requests qeued and sorted in a (hopefully)
  1.1049 ++ * "most efficient way". spin_lock_irq() is being held by the kernel. */
  1.1050 ++static void cloop_do_request(struct request_queue *q)
  1.1051 ++{
  1.1052 ++ struct request *req;
  1.1053 ++ while((req = blk_fetch_request(q)) != NULL)
  1.1054 ++  {
  1.1055 ++   struct cloop_device *clo;
  1.1056 ++   int rw;
  1.1057 ++ /* quick sanity checks */
  1.1058 ++   /* blk_fs_request() was removed in 2.6.36 */
  1.1059  +   if (unlikely(req == NULL
  1.1060  +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0) /* field removed */
  1.1061  +   || (req->cmd_type != REQ_TYPE_FS)
  1.1062  +#endif
  1.1063  +   ))
  1.1064 -     goto error_continue;
  1.1065 -    rw = rq_data_dir(req);
  1.1066 --   if (unlikely(rw != READ && rw != READA))
  1.1067 ++    goto error_continue;
  1.1068 ++   rw = rq_data_dir(req);
  1.1069  +   if (unlikely(rw != READ
  1.1070  +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 8, 0)
  1.1071  +                && rw != READA
  1.1072  +#endif
  1.1073  +    ))
  1.1074 -     {
  1.1075 -      DEBUGP("cloop_do_request: bad command\n");
  1.1076 -      goto error_continue;
  1.1077 -@@ -409,40 +523,51 @@
  1.1078 -    continue; /* next request */
  1.1079 -   error_continue:
  1.1080 -    DEBUGP(KERN_ERR "cloop_do_request: Discarding request %p.\n", req);
  1.1081 ++    {
  1.1082 ++     DEBUGP("cloop_do_request: bad command\n");
  1.1083 ++     goto error_continue;
  1.1084 ++    }
  1.1085 ++   clo = req->rq_disk->private_data;
  1.1086 ++   if (unlikely(!clo->backing_file && !clo->suspended))
  1.1087 ++    {
  1.1088 ++     DEBUGP("cloop_do_request: not connected to a file\n");
  1.1089 ++     goto error_continue;
  1.1090 ++    }
  1.1091 ++   list_add_tail(&req->queuelist, &clo->clo_list); /* Add to working list for thread */
  1.1092 ++   wake_up(&clo->clo_event);    /* Wake up cloop_thread */
  1.1093 ++   continue; /* next request */
  1.1094 ++  error_continue:
  1.1095 ++   DEBUGP(KERN_ERR "cloop_do_request: Discarding request %p.\n", req);
  1.1096  +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0)
  1.1097 -    req->errors++;
  1.1098 ++   req->errors++;
  1.1099  +#else
  1.1100  +   req->error_count++;
  1.1101  +#endif
  1.1102 -    __blk_end_request_all(req, -EIO);
  1.1103 -   }
  1.1104 ++   __blk_end_request_all(req, -EIO);
  1.1105 ++  }
  1.1106   }
  1.1107   
  1.1108 --/* Read header and offsets from already opened file */
  1.1109 --static int cloop_set_file(int cloop_num, struct file *file, char *filename)
  1.1110 -+/* Read header, flags and offsets from already opened file */
  1.1111 -+static int cloop_set_file(int cloop_num, struct file *file)
  1.1112 - {
  1.1113 -  struct cloop_device *clo = cloop_dev[cloop_num];
  1.1114 -  struct inode *inode;
  1.1115 + /* Read header, flags and offsets from already opened file */
  1.1116 +@@ -508,7 +540,7 @@
  1.1117    char *bbuf=NULL;
  1.1118 -- unsigned int i, offsets_read, total_offsets;
  1.1119 -- int isblkdev;
  1.1120 -- int error = 0;
  1.1121 -+ unsigned int bbuf_size = 0;
  1.1122 -+ const unsigned int header_size = sizeof(struct cloop_head);
  1.1123 +  unsigned int bbuf_size = 0;
  1.1124 +  const unsigned int header_size = sizeof(struct cloop_head);
  1.1125 +- unsigned int i, offsets_read=0, total_offsets=0;
  1.1126  + unsigned int i, total_offsets=0;
  1.1127 -+ loff_t fs_read_position = 0, header_pos[2];
  1.1128 -+ int flags, isblkdev, bytes_read, error = 0;
  1.1129 -+ if (clo->suspended) return error;
  1.1130 -+ #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)
  1.1131 -  inode = file->f_dentry->d_inode;
  1.1132 -+ clo->underlying_filename = kstrdup(file->f_dentry->d_name.name ? file->f_dentry->d_name.name : (const unsigned char *)"anonymous filename", GFP_KERNEL);
  1.1133 -+ #else
  1.1134 -+ inode = file->f_path.dentry->d_inode;
  1.1135 -+ clo->underlying_filename = kstrdup(file->f_path.dentry->d_name.name ? file->f_path.dentry->d_name.name : (const unsigned char *)"anonymous filename", GFP_KERNEL);
  1.1136 -+ #endif
  1.1137 -  isblkdev=S_ISBLK(inode->i_mode)?1:0;
  1.1138 -  if(!isblkdev&&!S_ISREG(inode->i_mode))
  1.1139 +  loff_t fs_read_position = 0, header_pos[2];
  1.1140 +  int isblkdev, bytes_read, error = 0;
  1.1141 +  if (clo->suspended) return error;
  1.1142 +@@ -581,29 +613,19 @@
  1.1143 +     goto error_release;
  1.1144 +    }
  1.1145 +    memcpy(&clo->head, bbuf, header_size);
  1.1146 +-   if (strncmp(bbuf+CLOOP4_SIGNATURE_OFFSET, CLOOP4_SIGNATURE, CLOOP4_SIGNATURE_SIZE)==0)
  1.1147 ++   if (strncmp(bbuf+CLOOP_SIGNATURE_OFFSET, CLOOP_SIGNATURE, CLOOP_SIGNATURE_SIZE)==0)
  1.1148 +    {
  1.1149 +-    clo->file_format=4;
  1.1150 ++    clo->file_format++;
  1.1151 +     clo->head.block_size=ntohl(clo->head.block_size);
  1.1152 +     clo->head.num_blocks=ntohl(clo->head.num_blocks);
  1.1153 +     clo->header_first =  (i==0) ? 1 : 0;
  1.1154 +-    printk(KERN_INFO "%s: file %s version %d, %d blocks of %d bytes, header %s.\n", cloop_name, clo->underlying_filename, clo->file_format, clo->head.num_blocks, clo->head.block_size, (i==0)?"first":"last");
  1.1155 +-    break;
  1.1156 +-   }
  1.1157 +-   else if (strncmp(bbuf+CLOOP2_SIGNATURE_OFFSET, CLOOP2_SIGNATURE, CLOOP2_SIGNATURE_SIZE)==0)
  1.1158 +-   {
  1.1159 +-    clo->file_format=2;
  1.1160 +-    clo->head.block_size=ntohl(clo->head.block_size);
  1.1161 +-    clo->head.num_blocks=ntohl(clo->head.num_blocks);
  1.1162 +-    clo->header_first =  (i==0) ? 1 : 0;
  1.1163 +-    printk(KERN_INFO "%s: file %s version %d, %d blocks of %d bytes, header %s.\n", cloop_name, clo->underlying_filename, clo->file_format, clo->head.num_blocks, clo->head.block_size, (i==0)?"first":"last");
  1.1164 ++    printk(KERN_INFO "%s: file %s, %d blocks of %d bytes, header %s.\n", cloop_name, clo->underlying_filename, clo->head.num_blocks, clo->head.block_size, (i==0)?"first":"last");
  1.1165 +     break;
  1.1166 +    }
  1.1167 +   }
  1.1168 +  if (clo->file_format == 0)
  1.1169     {
  1.1170 -    printk(KERN_ERR "%s: %s not a regular file or block device\n",
  1.1171 --		   cloop_name, filename);
  1.1172 -+		   cloop_name, clo->underlying_filename);
  1.1173 +-   printk(KERN_ERR "%s: Cannot read old 32-bit (version 0.68) images, "
  1.1174 +-                   "please use an older version of %s for this file.\n",
  1.1175 ++   printk(KERN_ERR "%s: Cannot detect %s format.\n",
  1.1176 +                    cloop_name, cloop_name);
  1.1177 +        error=-EBADF; goto error_release;
  1.1178 +   }
  1.1179 +@@ -613,67 +635,133 @@
  1.1180 +           cloop_name, clo->head.block_size);
  1.1181      error=-EBADF; goto error_release;
  1.1182     }
  1.1183 -  clo->backing_file = file;
  1.1184 -  clo->backing_inode= inode ;
  1.1185 -- if(!isblkdev&&inode->i_size<sizeof(struct cloop_head))
  1.1186 -+ clo->underlying_total_size = (isblkdev) ? inode->i_bdev->bd_inode->i_size : inode->i_size;
  1.1187 -+ if(clo->underlying_total_size < header_size)
  1.1188 +- total_offsets=clo->head.num_blocks+1;
  1.1189 +- if (!isblkdev && (sizeof(struct cloop_head)+sizeof(loff_t)*
  1.1190 ++ total_offsets=clo->head.num_blocks;
  1.1191 ++ if (!isblkdev && (sizeof(struct cloop_head)+sizeof(struct block_info)*
  1.1192 +                       total_offsets > inode->i_size))
  1.1193     {
  1.1194 --   printk(KERN_ERR "%s: %lu bytes (must be >= %u bytes)\n",
  1.1195 --                   cloop_name, (unsigned long)inode->i_size,
  1.1196 --		   (unsigned)sizeof(struct cloop_head));
  1.1197 -+   printk(KERN_ERR "%s: %llu bytes (must be >= %u bytes)\n",
  1.1198 -+                   cloop_name, clo->underlying_total_size,
  1.1199 -+		   (unsigned int)header_size);
  1.1200 +    printk(KERN_ERR "%s: file %s too small for %u blocks\n",
  1.1201 +           cloop_name, clo->underlying_filename, clo->head.num_blocks);
  1.1202      error=-EBADF; goto error_release;
  1.1203     }
  1.1204 -- /* In suspended mode, we have done all checks necessary - FF */
  1.1205 -- if (clo->suspended)
  1.1206 --   return error;
  1.1207 -  if(isblkdev)
  1.1208 -   {
  1.1209 -    struct request_queue *q = bdev_get_queue(inode->i_bdev);
  1.1210 -@@ -451,104 +576,225 @@
  1.1211 -    /* blk_queue_max_hw_segments(clo->clo_queue, queue_max_hw_segments(q)); */ /* Removed in 2.6.34 */
  1.1212 -    blk_queue_max_segment_size(clo->clo_queue, queue_max_segment_size(q));
  1.1213 -    blk_queue_segment_boundary(clo->clo_queue, queue_segment_boundary(q));
  1.1214 -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 3, 0)
  1.1215 -    blk_queue_merge_bvec(clo->clo_queue, q->merge_bvec_fn);
  1.1216 -+#endif
  1.1217 -    clo->underlying_blksize = block_size(inode->i_bdev);
  1.1218 -   }
  1.1219 -  else
  1.1220 -    clo->underlying_blksize = PAGE_SIZE;
  1.1221 -- DEBUGP("Underlying blocksize is %u\n", clo->underlying_blksize);
  1.1222 -- bbuf = cloop_malloc(clo->underlying_blksize);
  1.1223 -+
  1.1224 -+ DEBUGP(KERN_INFO "Underlying blocksize of %s is %u\n", clo->underlying_filename, clo->underlying_blksize);
  1.1225 -+ DEBUGP(KERN_INFO "Underlying total size of %s is %llu\n", clo->underlying_filename, clo->underlying_total_size);
  1.1226 -+
  1.1227 -+ /* clo->underlying_blksize should be larger than header_size, even if it's only PAGE_SIZE */
  1.1228 -+ bbuf_size = clo->underlying_blksize;
  1.1229 -+ bbuf = cloop_malloc(bbuf_size);
  1.1230 -  if(!bbuf)
  1.1231 -   {
  1.1232 --   printk(KERN_ERR "%s: out of kernel mem for block buffer (%lu bytes)\n",
  1.1233 --                   cloop_name, (unsigned long)clo->underlying_blksize);
  1.1234 -+   printk(KERN_ERR "%s: out of kernel mem for buffer (%u bytes)\n",
  1.1235 -+                   cloop_name, (unsigned int) bbuf_size);
  1.1236 -+   error=-ENOMEM; goto error_release;
  1.1237 -+  }
  1.1238 -+
  1.1239 -+ header_pos[0] = 0; /* header first */
  1.1240 -+ header_pos[1] = clo->underlying_total_size - sizeof(struct cloop_head); /* header last */
  1.1241 -+ for(i=0; i<2; i++)
  1.1242 -+  {
  1.1243 -+   /* Check for header */
  1.1244 -+   size_t bytes_readable = MIN(clo->underlying_blksize, clo->underlying_total_size - header_pos[i]);
  1.1245 -+   size_t bytes_read = cloop_read_from_file(clo, file, bbuf, header_pos[i], bytes_readable);
  1.1246 -+   if(bytes_read != bytes_readable)
  1.1247 -+   {
  1.1248 -+    printk(KERN_ERR "%s: Bad file %s, read() of %s %u bytes returned %d.\n",
  1.1249 -+                    cloop_name, clo->underlying_filename, (i==0)?"first":"last",
  1.1250 -+		    (unsigned int)header_size, (int)bytes_read);
  1.1251 -+    error=-EBADF;
  1.1252 -+    goto error_release;
  1.1253 -+   }
  1.1254 -+   memcpy(&clo->head, bbuf, header_size);
  1.1255 -+   if (strncmp(bbuf+CLOOP_SIGNATURE_OFFSET, CLOOP_SIGNATURE, CLOOP_SIGNATURE_SIZE)==0)
  1.1256 -+   {
  1.1257 -+    clo->file_format++;
  1.1258 -+    clo->head.block_size=ntohl(clo->head.block_size);
  1.1259 -+    clo->head.num_blocks=ntohl(clo->head.num_blocks);
  1.1260 -+    clo->header_first =  (i==0) ? 1 : 0;
  1.1261 -+    printk(KERN_INFO "%s: file %s, %d blocks of %d bytes, header %s.\n", cloop_name, clo->underlying_filename, clo->head.num_blocks, clo->head.block_size, (i==0)?"first":"last");
  1.1262 -+    break;
  1.1263 -+   }
  1.1264 -+  }
  1.1265 -+ if (clo->file_format == 0)
  1.1266 -+  {
  1.1267 -+   printk(KERN_ERR "%s: Cannot detect %s format.\n",
  1.1268 -+                   cloop_name, cloop_name);
  1.1269 -+       error=-EBADF; goto error_release;
  1.1270 -+  }
  1.1271 -+ if (clo->head.block_size % 512 != 0)
  1.1272 -+  {
  1.1273 -+   printk(KERN_ERR "%s: blocksize %u not multiple of 512\n",
  1.1274 -+          cloop_name, clo->head.block_size);
  1.1275 -+   error=-EBADF; goto error_release;
  1.1276 -+  }
  1.1277 -+ total_offsets=clo->head.num_blocks;
  1.1278 -+ if (!isblkdev && (sizeof(struct cloop_head)+sizeof(struct block_info)*
  1.1279 -+                      total_offsets > inode->i_size))
  1.1280 -+  {
  1.1281 -+   printk(KERN_ERR "%s: file %s too small for %u blocks\n",
  1.1282 -+          cloop_name, clo->underlying_filename, clo->head.num_blocks);
  1.1283 -+   error=-EBADF; goto error_release;
  1.1284 -+  }
  1.1285 +- clo->block_ptrs = cloop_malloc(sizeof(cloop_block_ptr) * total_offsets);
  1.1286 +- if (!clo->block_ptrs)
  1.1287  + /* Allocate Memory for decompressors */
  1.1288  +#if (defined(CONFIG_ZLIB_INFLATE) || defined(CONFIG_ZLIB_INFLATE_MODULE))
  1.1289  + clo->zstream.workspace = cloop_malloc(zlib_inflate_workspacesize());
  1.1290  + if(!clo->zstream.workspace)
  1.1291 -+  {
  1.1292 +   {
  1.1293 +-   printk(KERN_ERR "%s: out of kernel mem for offsets\n", cloop_name);
  1.1294  +   printk(KERN_ERR "%s: out of mem for zlib working area %u\n",
  1.1295  +          cloop_name, zlib_inflate_workspacesize());
  1.1296      error=-ENOMEM; goto error_release;
  1.1297     }
  1.1298 -- total_offsets = 1; /* Dummy total_offsets: will be filled in first time around */
  1.1299 -- for (i = 0, offsets_read = 0; offsets_read < total_offsets; i++)
  1.1300 +- /* Read them offsets! */
  1.1301 +- if(clo->header_first)
  1.1302  + zlib_inflateInit(&clo->zstream);
  1.1303  +#endif
  1.1304  +#if (defined(CONFIG_DECOMPRESS_XZ) || defined(CONFIG_DECOMPRESS_XZ_MODULE))
  1.1305 @@ -890,33 +713,20 @@
  1.1306  +#endif
  1.1307  + if (total_offsets + 1 == 0) /* Version 3 */
  1.1308     {
  1.1309 --   unsigned int offset = 0, num_readable;
  1.1310 --   size_t bytes_read = cloop_read_from_file(clo, file, bbuf,
  1.1311 --                                          i*clo->underlying_blksize,
  1.1312 --                                          clo->underlying_blksize);
  1.1313 --   if(bytes_read != clo->underlying_blksize)
  1.1314 +-   fs_read_position = sizeof(struct cloop_head);
  1.1315  +   struct cloop_tail tail;
  1.1316  +   if (isblkdev)
  1.1317 -     {
  1.1318 --     printk(KERN_ERR "%s: Bad file, read() of first %lu bytes returned %d.\n",
  1.1319 --                   cloop_name, (unsigned long)clo->underlying_blksize, (int)bytes_read);
  1.1320 --     error=-EBADF;
  1.1321 --     goto error_release;
  1.1322 ++    {
  1.1323  +    /* No end of file: can't find index */
  1.1324  +     printk(KERN_ERR "%s: no V3 support for block device\n", 
  1.1325  +            cloop_name);
  1.1326  +     error=-EBADF; goto error_release;
  1.1327 -     }
  1.1328 --   /* Header will be in block zero */
  1.1329 --   if(i==0)
  1.1330 ++    }
  1.1331  +   bytes_read = cloop_read_from_file(clo, file, (void *) &tail,
  1.1332  +			inode->i_size - sizeof(struct cloop_tail),
  1.1333  +			sizeof(struct cloop_tail));
  1.1334  +   if (bytes_read == sizeof(struct cloop_tail))
  1.1335 -     {
  1.1336 --     memcpy(&clo->head, bbuf, sizeof(struct cloop_head));
  1.1337 --     offset = sizeof(struct cloop_head);
  1.1338 --     if (ntohl(clo->head.block_size) % 512 != 0)
  1.1339 ++    {
  1.1340  +     unsigned long len, zlen;
  1.1341  +     int ret;
  1.1342  +     void *zbuf;
  1.1343 @@ -926,79 +736,47 @@
  1.1344  +     zlen = ntohl(tail.table_size);
  1.1345  +     zbuf = cloop_malloc(zlen);
  1.1346  +     if (!clo->block_ptrs || !zbuf)
  1.1347 -       {
  1.1348 --       printk(KERN_ERR "%s: blocksize %u not multiple of 512\n",
  1.1349 --              cloop_name, ntohl(clo->head.block_size));
  1.1350 --       error=-EBADF; goto error_release;
  1.1351 --      }
  1.1352 --     if (clo->head.preamble[0x0B]!='V'||clo->head.preamble[0x0C]<'1')
  1.1353 --      {
  1.1354 --       printk(KERN_ERR "%s: Cannot read old 32-bit (version 0.68) images, "
  1.1355 --		       "please use an older version of %s for this file.\n",
  1.1356 --		       cloop_name, cloop_name);
  1.1357 --       error=-EBADF; goto error_release;
  1.1358 ++      {
  1.1359  +       printk(KERN_ERR "%s: out of kernel mem for index\n", cloop_name);
  1.1360  +       error=-ENOMEM; goto error_release;
  1.1361 -       }
  1.1362 --     if (clo->head.preamble[0x0C]<'2')
  1.1363 ++      }
  1.1364  +     bytes_read = cloop_read_from_file(clo, file, zbuf,
  1.1365  +			inode->i_size - zlen - sizeof(struct cloop_tail),
  1.1366  +			zlen);
  1.1367  +     if (bytes_read != zlen)
  1.1368 -       {
  1.1369 --       printk(KERN_ERR "%s: Cannot read old architecture-dependent "
  1.1370 --		       "(format <= 1.0) images, please use an older "
  1.1371 --		       "version of %s for this file.\n",
  1.1372 --		       cloop_name, cloop_name);
  1.1373 ++      {
  1.1374  +       printk(KERN_ERR "%s: can't read index\n", cloop_name);
  1.1375 -        error=-EBADF; goto error_release;
  1.1376 -       }
  1.1377 --     total_offsets=ntohl(clo->head.num_blocks)+1;
  1.1378 --     if (!isblkdev && (sizeof(struct cloop_head)+sizeof(loff_t)*
  1.1379 --                       total_offsets > inode->i_size))
  1.1380 ++       error=-EBADF; goto error_release;
  1.1381 ++      }
  1.1382  +     len = CLOOP3_INDEX_SIZE(ntohl(tail.index_size)) * total_offsets;
  1.1383 -+     flags = CLOOP3_BLOCKS_FLAGS(ntohl(tail.index_size));
  1.1384 -+// May  3 19:45:20 (none) user.info kernel: cloop: uncompress(clo=e0a78000, block_ptrs=e0c9c000, &len(1440)=ddc05e6c, zbuf=e0c9f000, zlen=43, flag=0)
  1.1385 -+printk(KERN_INFO "%s: uncompress(clo=%p, block_ptrs=%p, &len(%ld)=%p, zbuf=%p, zlen=%ld, flag=%d)\n", cloop_name, 
  1.1386 -+		clo, clo->block_ptrs, len, &len, zbuf, zlen, flags);
  1.1387 -+     ret = uncompress(clo, (void *) clo->block_ptrs, &len, zbuf, zlen, flags);
  1.1388 -+// May  3 19:45:20 (none) user.alert kernel: BUG: unable to handle kernel NULL pointer dereference at   (null)
  1.1389 -+printk(KERN_INFO "%s: uncompressed !\n", cloop_name);
  1.1390 ++     ret = uncompress(clo, (void *) clo->block_ptrs, &len, zbuf, zlen, CLOOP_COMPRESSOR_ZLIB);
  1.1391  +     cloop_free(zbuf, zlen);
  1.1392  +     if (ret != 0)
  1.1393 -       {
  1.1394 --       printk(KERN_ERR "%s: file too small for %u blocks\n",
  1.1395 --              cloop_name, ntohl(clo->head.num_blocks));
  1.1396 -+        printk(KERN_ERR "%s: decompression error %i uncompressing index, flags %u\n",
  1.1397 -+               cloop_name, ret, flags);
  1.1398 -        error=-EBADF; goto error_release;
  1.1399 -       }
  1.1400 --     clo->offsets = cloop_malloc(sizeof(loff_t) * total_offsets);
  1.1401 --     if (!clo->offsets)
  1.1402 --      {
  1.1403 --       printk(KERN_ERR "%s: out of kernel mem for offsets\n", cloop_name);
  1.1404 --       error=-ENOMEM; goto error_release;
  1.1405 --      }
  1.1406 -     }
  1.1407 --   num_readable = MIN(total_offsets - offsets_read,
  1.1408 --                      (clo->underlying_blksize - offset) 
  1.1409 --                      / sizeof(loff_t));
  1.1410 --   memcpy(&clo->offsets[offsets_read], bbuf+offset, num_readable * sizeof(loff_t));
  1.1411 --   offsets_read += num_readable;
  1.1412 --  }
  1.1413 --  { /* Search for largest block rather than estimate. KK. */
  1.1414 --   int i;
  1.1415 --   for(i=0;i<total_offsets-1;i++)
  1.1416 ++      {
  1.1417 ++        printk(KERN_ERR "%s: decompression error %i uncompressing index\n",
  1.1418 ++               cloop_name, ret);
  1.1419 ++       error=-EBADF; goto error_release;
  1.1420 ++      }
  1.1421 ++    }
  1.1422  +   else
  1.1423  +    {
  1.1424  +     printk(KERN_ERR "%s: can't find index\n", cloop_name);
  1.1425  +     error=-ENOMEM; goto error_release;
  1.1426  +    }
  1.1427 -+  }
  1.1428 -+ else
  1.1429 -+  {
  1.1430 +   }
  1.1431 +  else
  1.1432 +   {
  1.1433 +-   fs_read_position = clo->underlying_total_size - sizeof(struct cloop_head) - total_offsets * sizeof(loff_t);
  1.1434 +-  }
  1.1435 +- for(offsets_read=0;offsets_read<total_offsets;)
  1.1436 +-  {
  1.1437 +-   size_t bytes_readable;
  1.1438 +-   unsigned int num_readable, offset = 0;
  1.1439 +-   bytes_readable = MIN(bbuf_size, clo->underlying_total_size - fs_read_position);
  1.1440 +-   if(bytes_readable <= 0) break; /* Done */
  1.1441 +-   bytes_read = cloop_read_from_file(clo, file, bbuf, fs_read_position, bytes_readable);
  1.1442 +-   if(bytes_read != bytes_readable)
  1.1443  +   unsigned int n, total_bytes;
  1.1444 -+   flags = 0;
  1.1445  +   clo->block_ptrs = cloop_malloc(sizeof(struct block_info) * total_offsets);
  1.1446  +   if (!clo->block_ptrs)
  1.1447  +    {
  1.1448 @@ -1007,14 +785,26 @@
  1.1449  +    }
  1.1450  +   /* Read them offsets! */
  1.1451  +   if(clo->header_first)
  1.1452 -+    {
  1.1453 +     {
  1.1454 +-     printk(KERN_ERR "%s: Bad file %s, read() %lu bytes @ %llu returned %d.\n",
  1.1455 +-            cloop_name, clo->underlying_filename, (unsigned long)clo->underlying_blksize, fs_read_position, (int)bytes_read);
  1.1456 +-     error=-EBADF;
  1.1457 +-     goto error_release;
  1.1458  +     total_bytes = total_offsets * sizeof(struct block_info);
  1.1459  +     fs_read_position = sizeof(struct cloop_head);
  1.1460 -+    }
  1.1461 +     }
  1.1462 +-   /* remember where to read the next blk from file */
  1.1463 +-   fs_read_position += bytes_read;
  1.1464 +-   /* calculate how many offsets can be taken from current bbuf */
  1.1465 +-   num_readable = MIN(total_offsets - offsets_read,
  1.1466 +-                      bytes_read / sizeof(loff_t));
  1.1467 +-   DEBUGP(KERN_INFO "cloop: parsing %d offsets %d to %d\n", num_readable, offsets_read, offsets_read+num_readable-1);
  1.1468 +-   for (i=0,offset=0; i<num_readable; i++)
  1.1469  +   else
  1.1470       {
  1.1471 --     loff_t d=be64_to_cpu(clo->offsets[i+1]) - be64_to_cpu(clo->offsets[i]);
  1.1472 --     clo->largest_block=MAX(clo->largest_block,d);
  1.1473 +-     loff_t tmp = be64_to_cpu( *(loff_t*) (bbuf+offset) );
  1.1474 +-     if (i%50==0) DEBUGP(KERN_INFO "cloop: offset %03d: %llu\n", offsets_read, tmp);
  1.1475 +-     if(offsets_read > 0)
  1.1476  +     total_bytes = total_offsets * sizeof(loff_t);
  1.1477  +     fs_read_position = clo->underlying_total_size - sizeof(struct cloop_head) - total_bytes;
  1.1478  +    }
  1.1479 @@ -1025,35 +815,28 @@
  1.1480  +     if(bytes_readable <= 0) break; /* Done */
  1.1481  +     bytes_read = cloop_read_from_file(clo, file, bbuf, fs_read_position, bytes_readable);
  1.1482  +     if(bytes_read != bytes_readable)
  1.1483 -+      {
  1.1484 +       {
  1.1485 +-       loff_t d = CLOOP_BLOCK_OFFSET(tmp) - CLOOP_BLOCK_OFFSET(clo->block_ptrs[offsets_read-1]);
  1.1486 +-       if(d > clo->largest_block) clo->largest_block = d;
  1.1487  +       printk(KERN_ERR "%s: Bad file %s, read() %lu bytes @ %llu returned %d.\n",
  1.1488  +              cloop_name, clo->underlying_filename, (unsigned long)clo->underlying_blksize, fs_read_position, (int)bytes_read);
  1.1489  +       error=-EBADF;
  1.1490  +       goto error_release;
  1.1491 -+      }
  1.1492 +       }
  1.1493 +-     clo->block_ptrs[offsets_read++] = tmp;
  1.1494 +-     offset += sizeof(loff_t);
  1.1495  +     memcpy(((char *)clo->block_ptrs) + n, bbuf, bytes_read);
  1.1496  +     /* remember where to read the next blk from file */
  1.1497  +     fs_read_position += bytes_read;
  1.1498  +     n += bytes_read;
  1.1499       }
  1.1500 --   printk(KERN_INFO "%s: %s: %u blocks, %u bytes/block, largest block is %lu bytes.\n",
  1.1501 --          cloop_name, filename, ntohl(clo->head.num_blocks),
  1.1502 --          ntohl(clo->head.block_size), clo->largest_block);
  1.1503     }
  1.1504 --/* Combo kmalloc used too large chunks (>130000). */
  1.1505 +-  printk(KERN_INFO "%s: %s: %u blocks, %u bytes/block, largest block is %lu bytes.\n",
  1.1506 +-         cloop_name, clo->underlying_filename, clo->head.num_blocks,
  1.1507 +-         clo->head.block_size, clo->largest_block);
  1.1508    {
  1.1509     int i;
  1.1510 --  for(i=0;i<BUFFERED_BLOCKS;i++)
  1.1511 --   {
  1.1512 --    clo->buffer[i] = cloop_malloc(ntohl(clo->head.block_size));
  1.1513 --    if(!clo->buffer[i])
  1.1514 --     {
  1.1515 --      printk(KERN_ERR "%s: out of memory for buffer %lu\n",
  1.1516 --             cloop_name, (unsigned long) ntohl(clo->head.block_size));
  1.1517 --      error=-ENOMEM; goto error_release_free;
  1.1518 --     }
  1.1519 --   }
  1.1520 -+  char *version = build_index(clo->block_ptrs, clo->head.num_blocks, clo->head.block_size, flags);
  1.1521 ++  char *version = build_index(clo->block_ptrs, clo->head.num_blocks, clo->head.block_size);
  1.1522  +  clo->largest_block = 0;
  1.1523  +  for (i = 0; i < clo->head.num_blocks; i++)
  1.1524  +    if (clo->block_ptrs[i].size > clo->largest_block)
  1.1525 @@ -1061,39 +844,15 @@
  1.1526  +  printk(KERN_INFO "%s: %s: %s: %u blocks, %u bytes/block, largest block is %lu bytes.\n",
  1.1527  +         cloop_name, clo->underlying_filename, version, clo->head.num_blocks,
  1.1528  +         clo->head.block_size, clo->largest_block);
  1.1529 -+ }
  1.1530 -+ {
  1.1531 -+  int i;
  1.1532 -+  clo->num_buffered_blocks = (buffers > 0 && clo->head.block_size >= 512) ?
  1.1533 -+                              (buffers / clo->head.block_size) : 1;
  1.1534 -+  clo->buffered_blocknum = cloop_malloc(clo->num_buffered_blocks * sizeof (u_int32_t));
  1.1535 -+  clo->buffer = cloop_malloc(clo->num_buffered_blocks * sizeof (char*));
  1.1536 -+  if (!clo->buffered_blocknum || !clo->buffer)
  1.1537 -+  {
  1.1538 -+   printk(KERN_ERR "%s: out of memory for index of cache buffer (%lu bytes)\n",
  1.1539 -+                    cloop_name, (unsigned long)clo->num_buffered_blocks * sizeof (u_int32_t) + sizeof(char*) );
  1.1540 -+                    error=-ENOMEM; goto error_release;
  1.1541 -+  }
  1.1542 -+  memset(clo->buffer, 0, clo->num_buffered_blocks * sizeof (char*));
  1.1543 -+  for(i=0;i<clo->num_buffered_blocks;i++)
  1.1544 -+  {
  1.1545 -+   clo->buffered_blocknum[i] = -1;
  1.1546 -+   clo->buffer[i] = cloop_malloc(clo->head.block_size);
  1.1547 -+   if(!clo->buffer[i])
  1.1548 -+    {
  1.1549 -+     printk(KERN_ERR "%s: out of memory for cache buffer %lu\n",
  1.1550 -+            cloop_name, (unsigned long) clo->head.block_size);
  1.1551 -+     error=-ENOMEM; goto error_release_free;
  1.1552 -+    }
  1.1553 -+  }
  1.1554 -+  clo->current_bufnum = 0;
  1.1555 -  }
  1.1556 -  clo->compressed_buffer = cloop_malloc(clo->largest_block);
  1.1557 -  if(!clo->compressed_buffer)
  1.1558 -@@ -557,31 +803,7 @@
  1.1559 +   clo->num_buffered_blocks = (buffers > 0 && clo->head.block_size >= 512) ?
  1.1560 +                               (buffers / clo->head.block_size) : 1;
  1.1561 +   clo->buffered_blocknum = cloop_malloc(clo->num_buffered_blocks * sizeof (u_int32_t));
  1.1562 +@@ -705,36 +793,14 @@
  1.1563             cloop_name, clo->largest_block);
  1.1564      error=-ENOMEM; goto error_release_free_buffer;
  1.1565     }
  1.1566 +- /* Allocate Memory for decompressors */
  1.1567 +-#if (defined(CONFIG_ZLIB_INFLATE) || defined(CONFIG_ZLIB_INFLATE_MODULE))
  1.1568  - clo->zstream.workspace = cloop_malloc(zlib_inflate_workspacesize());
  1.1569  - if(!clo->zstream.workspace)
  1.1570  -  {
  1.1571 @@ -1102,443 +861,48 @@
  1.1572  -   error=-ENOMEM; goto error_release_free_all;
  1.1573  -  }
  1.1574  - zlib_inflateInit(&clo->zstream);
  1.1575 -- if(!isblkdev &&
  1.1576 --    be64_to_cpu(clo->offsets[ntohl(clo->head.num_blocks)]) != inode->i_size)
  1.1577 --  {
  1.1578 --   printk(KERN_ERR "%s: final offset wrong (%Lu not %Lu)\n",
  1.1579 +-#endif
  1.1580 +-#if (defined(CONFIG_DECOMPRESS_XZ) || defined(CONFIG_DECOMPRESS_XZ_MODULE))
  1.1581 +-#if XZ_INTERNAL_CRC32
  1.1582 +-  /* This must be called before any other xz_* function to initialize the CRC32 lookup table. */
  1.1583 +-  xz_crc32_init(void);
  1.1584 +-#endif
  1.1585 +-  clo->xzdecoderstate = xz_dec_init(XZ_SINGLE, 0);
  1.1586 +-#endif
  1.1587 +- if(CLOOP_BLOCK_OFFSET(clo->block_ptrs[clo->head.num_blocks]) > clo->underlying_total_size)
  1.1588 ++ set_capacity(clo->clo_disk, (sector_t)(clo->head.num_blocks*(clo->head.block_size>>9)));
  1.1589 ++ clo->clo_thread = kthread_create(cloop_thread, clo, "cloop%d", cloop_num);
  1.1590 ++ if(IS_ERR(clo->clo_thread))
  1.1591 +   {
  1.1592 +-   printk(KERN_ERR "%s: final offset wrong (%llu > %llu)\n",
  1.1593  -          cloop_name,
  1.1594 --          be64_to_cpu(clo->offsets[ntohl(clo->head.num_blocks)]),
  1.1595 --          inode->i_size);
  1.1596 +-	  CLOOP_BLOCK_OFFSET(clo->block_ptrs[clo->head.num_blocks]),
  1.1597 +-          clo->underlying_total_size);
  1.1598 +-#if (defined(CONFIG_ZLIB_INFLATE) || defined(CONFIG_ZLIB_INFLATE_MODULE))
  1.1599  -   cloop_free(clo->zstream.workspace, zlib_inflate_workspacesize()); clo->zstream.workspace=NULL;
  1.1600 --   goto error_release_free_all;
  1.1601 --  }
  1.1602 -- {
  1.1603 --  int i;
  1.1604 --  for(i=0; i<BUFFERED_BLOCKS; i++) clo->buffered_blocknum[i] = -1;
  1.1605 --  clo->current_bufnum=0;
  1.1606 -- }
  1.1607 -- set_capacity(clo->clo_disk, (sector_t)(ntohl(clo->head.num_blocks)*
  1.1608 --              (ntohl(clo->head.block_size)>>9)));
  1.1609 -+ set_capacity(clo->clo_disk, (sector_t)(clo->head.num_blocks*(clo->head.block_size>>9)));
  1.1610 -  clo->clo_thread = kthread_create(cloop_thread, clo, "cloop%d", cloop_num);
  1.1611 -  if(IS_ERR(clo->clo_thread))
  1.1612 -   {
  1.1613 -@@ -591,17 +813,17 @@
  1.1614 +-#endif
  1.1615 ++   error = PTR_ERR(clo->clo_thread);
  1.1616 ++   clo->clo_thread=NULL;
  1.1617 +    goto error_release_free_all;
  1.1618     }
  1.1619 +- set_capacity(clo->clo_disk, (sector_t)(clo->head.num_blocks*(clo->head.block_size>>9)));
  1.1620    if(preload > 0)
  1.1621     {
  1.1622 --   clo->preload_array_size = ((preload<=ntohl(clo->head.num_blocks))?preload:ntohl(clo->head.num_blocks));
  1.1623 -+   clo->preload_array_size = ((preload<=clo->head.num_blocks)?preload:clo->head.num_blocks);
  1.1624 -    clo->preload_size = 0;
  1.1625 -    if((clo->preload_cache = cloop_malloc(clo->preload_array_size * sizeof(char *))) != NULL)
  1.1626 -     {
  1.1627 -      int i;
  1.1628 -      for(i=0; i<clo->preload_array_size; i++)
  1.1629 -       {
  1.1630 --       if((clo->preload_cache[i] = cloop_malloc(ntohl(clo->head.block_size))) == NULL)
  1.1631 -+       if((clo->preload_cache[i] = cloop_malloc(clo->head.block_size)) == NULL)
  1.1632 -         { /* Out of memory */
  1.1633 -          printk(KERN_WARNING "%s: cloop_malloc(%d) failed for preload_cache[%d] (ignored).\n",
  1.1634 --                             cloop_name, ntohl(clo->head.block_size), i);
  1.1635 -+                             cloop_name, clo->head.block_size, i);
  1.1636 - 	 break;
  1.1637 - 	}
  1.1638 -       }
  1.1639 -@@ -612,13 +834,13 @@
  1.1640 -        if(buffered_blocknum >= 0)
  1.1641 -         {
  1.1642 - 	 memcpy(clo->preload_cache[i], clo->buffer[buffered_blocknum],
  1.1643 --	        ntohl(clo->head.block_size));
  1.1644 -+	        clo->head.block_size);
  1.1645 - 	}
  1.1646 -        else
  1.1647 -         {
  1.1648 -          printk(KERN_WARNING "%s: can't read block %d into preload cache, set to zero.\n",
  1.1649 - 	                     cloop_name, i);
  1.1650 --	 memset(clo->preload_cache[i], 0, ntohl(clo->head.block_size));
  1.1651 -+	 memset(clo->preload_cache[i], 0, clo->head.block_size);
  1.1652 - 	}
  1.1653 -       }
  1.1654 -      printk(KERN_INFO "%s: preloaded %d blocks into cache.\n", cloop_name,
  1.1655 -@@ -641,22 +863,19 @@
  1.1656 -  cloop_free(clo->compressed_buffer, clo->largest_block);
  1.1657 -  clo->compressed_buffer=NULL;
  1.1658 - error_release_free_buffer:
  1.1659 -+ if(clo->buffer)
  1.1660 -  {
  1.1661 -   int i;
  1.1662 --  for(i=0; i<BUFFERED_BLOCKS; i++)
  1.1663 --   { 
  1.1664 --    if(clo->buffer[i])
  1.1665 --     {
  1.1666 --      cloop_free(clo->buffer[i], ntohl(clo->head.block_size));
  1.1667 --      clo->buffer[i]=NULL;
  1.1668 --     }
  1.1669 --   }
  1.1670 -+  for(i=0; i<clo->num_buffered_blocks; i++) { if(clo->buffer[i]) { cloop_free(clo->buffer[i], clo->head.block_size); clo->buffer[i]=NULL; }}
  1.1671 -+  cloop_free(clo->buffer, clo->num_buffered_blocks*sizeof(char*)); clo->buffer=NULL;
  1.1672 +    clo->preload_array_size = ((preload<=clo->head.num_blocks)?preload:clo->head.num_blocks);
  1.1673 +@@ -780,6 +846,7 @@
  1.1674 +      clo->preload_array_size = clo->preload_size = 0;
  1.1675 +     }
  1.1676 +   }
  1.1677 ++ wake_up_process(clo->clo_thread);
  1.1678 +  /* Uncheck */
  1.1679 +  return error;
  1.1680 + error_release_free_all:
  1.1681 +@@ -794,9 +861,13 @@
  1.1682    }
  1.1683 -+ if (clo->buffered_blocknum) { cloop_free(clo->buffered_blocknum, sizeof(int)*clo->num_buffered_blocks); clo->buffered_blocknum=NULL; }
  1.1684 +  if (clo->buffered_blocknum) { cloop_free(clo->buffered_blocknum, sizeof(int)*clo->num_buffered_blocks); clo->buffered_blocknum=NULL; }
  1.1685   error_release_free:
  1.1686 -- cloop_free(clo->offsets, sizeof(loff_t) * total_offsets);
  1.1687 -- clo->offsets=NULL;
  1.1688 +- cloop_free(clo->block_ptrs, sizeof(cloop_block_ptr) * total_offsets);
  1.1689  + cloop_free(clo->block_ptrs, sizeof(struct block_info) * total_offsets);
  1.1690 -+ clo->block_ptrs=NULL;
  1.1691 - error_release:
  1.1692 -  if(bbuf) cloop_free(bbuf, clo->underlying_blksize);
  1.1693 -+ if(clo->underlying_filename) { kfree(clo->underlying_filename); clo->underlying_filename=NULL; }
  1.1694 -  clo->backing_file=NULL;
  1.1695 -  return error;
  1.1696 - }
  1.1697 -@@ -673,7 +892,7 @@
  1.1698 -  if(clo->backing_file) return -EBUSY;
  1.1699 -  file = fget(arg); /* get filp struct from ioctl arg fd */
  1.1700 -  if(!file) return -EBADF;
  1.1701 -- error=cloop_set_file(cloop_num,file,"losetup_file");
  1.1702 -+ error=cloop_set_file(cloop_num,file);
  1.1703 -  set_device_ro(bdev, 1);
  1.1704 -  if(error) fput(file);
  1.1705 -  return error;
  1.1706 -@@ -684,29 +903,48 @@
  1.1707 - {
  1.1708 -  struct cloop_device *clo = cloop_dev[cloop_num];
  1.1709 -  struct file *filp = clo->backing_file;
  1.1710 -- int i;
  1.1711 -  if(clo->refcnt > 1)	/* we needed one fd for the ioctl */
  1.1712 -    return -EBUSY;
  1.1713 -  if(filp==NULL) return -EINVAL;
  1.1714 -  if(clo->clo_thread) { kthread_stop(clo->clo_thread); clo->clo_thread=NULL; }
  1.1715 -- if(filp!=initial_file) fput(filp);
  1.1716 -- else { filp_close(initial_file,0); initial_file=NULL; }
  1.1717 -+ if(filp!=initial_file)
  1.1718 -+  fput(filp);
  1.1719 -+ else
  1.1720 -+ {
  1.1721 -+  filp_close(initial_file,0);
  1.1722 -+  initial_file=NULL;
  1.1723 -+ }
  1.1724 -  clo->backing_file  = NULL;
  1.1725 -  clo->backing_inode = NULL;
  1.1726 -- if(clo->offsets) { cloop_free(clo->offsets, clo->underlying_blksize); clo->offsets = NULL; }
  1.1727 -+ if(clo->underlying_filename) { kfree(clo->underlying_filename); clo->underlying_filename=NULL; }
  1.1728 -+ if(clo->block_ptrs) { cloop_free(clo->block_ptrs, clo->head.num_blocks); clo->block_ptrs = NULL; }
  1.1729 -  if(clo->preload_cache)
  1.1730 --  {
  1.1731 --   for(i=0; i < clo->preload_size; i++)
  1.1732 --    cloop_free(clo->preload_cache[i], ntohl(clo->head.block_size));
  1.1733 --   cloop_free(clo->preload_cache, clo->preload_array_size * sizeof(char *));
  1.1734 --   clo->preload_cache = NULL;
  1.1735 --   clo->preload_size = clo->preload_array_size = 0;
  1.1736 --  }
  1.1737 -- for(i=0; i<BUFFERED_BLOCKS; i++)
  1.1738 --      if(clo->buffer[i]) { cloop_free(clo->buffer[i], ntohl(clo->head.block_size)); clo->buffer[i]=NULL; }
  1.1739 -+ {
  1.1740 -+  int i;
  1.1741 -+  for(i=0; i < clo->preload_size; i++)
  1.1742 -+   cloop_free(clo->preload_cache[i], clo->head.block_size);
  1.1743 -+  cloop_free(clo->preload_cache, clo->preload_array_size * sizeof(char *));
  1.1744 -+  clo->preload_cache = NULL;
  1.1745 -+  clo->preload_size = clo->preload_array_size = 0;
  1.1746 -+ }
  1.1747 -+ if (clo->buffered_blocknum)
  1.1748 -+ {
  1.1749 -+  cloop_free(clo->buffered_blocknum, sizeof(int) * clo->num_buffered_blocks); clo->buffered_blocknum = NULL;
  1.1750 -+ }
  1.1751 -+ if (clo->buffer)
  1.1752 -+ {
  1.1753 -+  int i;
  1.1754 -+  for(i=0; i<clo->num_buffered_blocks; i++) { if(clo->buffer[i]) cloop_free(clo->buffer[i], clo->head.block_size); }
  1.1755 -+  cloop_free(clo->buffer, sizeof(char*) * clo->num_buffered_blocks); clo->buffer = NULL;
  1.1756 -+ }
  1.1757 -  if(clo->compressed_buffer) { cloop_free(clo->compressed_buffer, clo->largest_block); clo->compressed_buffer = NULL; }
  1.1758 -+#if (defined(CONFIG_ZLIB_INFLATE) || defined(CONFIG_ZLIB_INFLATE_MODULE))
  1.1759 -  zlib_inflateEnd(&clo->zstream);
  1.1760 -  if(clo->zstream.workspace) { cloop_free(clo->zstream.workspace, zlib_inflate_workspacesize()); clo->zstream.workspace = NULL; }
  1.1761 -+#endif
  1.1762 -+#if (defined(CONFIG_DECOMPRESS_XZ) || defined(CONFIG_DECOMPRESS_XZ_MODULE))
  1.1763 -+  xz_dec_end(clo->xzdecoderstate);
  1.1764 -+#endif
  1.1765 -  if(bdev) invalidate_bdev(bdev);
  1.1766 -  if(clo->clo_disk) set_capacity(clo->clo_disk, 0);
  1.1767 -  return 0;
  1.1768 -@@ -731,8 +969,8 @@
  1.1769 -                             const struct loop_info64 *info)
  1.1770 - {
  1.1771 -  if (!clo->backing_file) return -ENXIO;
  1.1772 -- memcpy(clo->clo_file_name, info->lo_file_name, LO_NAME_SIZE);
  1.1773 -- clo->clo_file_name[LO_NAME_SIZE-1] = 0;
  1.1774 -+ if(clo->underlying_filename) kfree(clo->underlying_filename);
  1.1775 -+ clo->underlying_filename = kstrdup(info->lo_file_name, GFP_KERNEL);
  1.1776 -  return 0;
  1.1777 - }
  1.1778 - 
  1.1779 -@@ -743,7 +981,11 @@
  1.1780 -  struct kstat stat;
  1.1781 -  int err;
  1.1782 -  if (!file) return -ENXIO;
  1.1783 -- err = vfs_getattr(file->f_path.mnt, file->f_path.dentry, &stat);
  1.1784 -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0)
  1.1785 -+ err = vfs_getattr(&file->f_path, &stat);
  1.1786 -+#else
  1.1787 -+ err = vfs_getattr(&file->f_path, &stat, STATX_INO, AT_STATX_SYNC_AS_STAT);
  1.1788 -+#endif
  1.1789 -  if (err) return err;
  1.1790 -  memset(info, 0, sizeof(*info));
  1.1791 -  info->lo_number  = clo->clo_number;
  1.1792 -@@ -753,7 +995,8 @@
  1.1793 -  info->lo_offset  = 0;
  1.1794 -  info->lo_sizelimit = 0;
  1.1795 -  info->lo_flags   = 0;
  1.1796 -- memcpy(info->lo_file_name, clo->clo_file_name, LO_NAME_SIZE);
  1.1797 -+ strncpy(info->lo_file_name, clo->underlying_filename, LO_NAME_SIZE);
  1.1798 -+ info->lo_file_name[LO_NAME_SIZE-1]=0;
  1.1799 -  return 0;
  1.1800 - }
  1.1801 - 
  1.1802 -@@ -833,8 +1076,6 @@
  1.1803 -  if (!err && copy_to_user(arg, &info64, sizeof(info64))) err = -EFAULT;
  1.1804 -  return err;
  1.1805 - }
  1.1806 --/* EOF get/set_status */
  1.1807 --
  1.1808 - 
  1.1809 - static int cloop_ioctl(struct block_device *bdev, fmode_t mode,
  1.1810 - 	unsigned int cmd, unsigned long arg)
  1.1811 -@@ -914,21 +1155,20 @@
  1.1812 -  /* losetup uses write-open and flags=0x8002 to set a new file */
  1.1813 -  if(mode & FMODE_WRITE)
  1.1814 -   {
  1.1815 --   printk(KERN_WARNING "%s: Can't open device read-write in mode 0x%x\n", cloop_name, mode);
  1.1816 -+   printk(KERN_INFO "%s: Open in read-write mode 0x%x requested, ignored.\n", cloop_name, mode);
  1.1817 -    return -EROFS;
  1.1818 -   }
  1.1819 -  cloop_dev[cloop_num]->refcnt+=1;
  1.1820 -  return 0;
  1.1821 - }
  1.1822 - 
  1.1823 --static int cloop_close(struct gendisk *disk, fmode_t mode)
  1.1824 -+static void cloop_close(struct gendisk *disk, fmode_t mode)
  1.1825 - {
  1.1826 -- int cloop_num, err=0;
  1.1827 -- if(!disk) return 0;
  1.1828 -+ int cloop_num;
  1.1829 -+ if(!disk) return;
  1.1830 -  cloop_num=((struct cloop_device *)disk->private_data)->clo_number;
  1.1831 -- if(cloop_num < 0 || cloop_num > (cloop_count-1)) return 0;
  1.1832 -+ if(cloop_num < 0 || cloop_num > (cloop_count-1)) return;
  1.1833 -  cloop_dev[cloop_num]->refcnt-=1;
  1.1834 -- return err;
  1.1835 - }
  1.1836 - 
  1.1837 - static struct block_device_operations clo_fops =
  1.1838 -@@ -973,6 +1213,10 @@
  1.1839 -    goto error_out;
  1.1840 -   }
  1.1841 -  clo->clo_queue->queuedata = clo;
  1.1842 -+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0)
  1.1843 -+ queue_flag_set_unlocked(QUEUE_FLAG_NONROT, clo->clo_queue);
  1.1844 -+ queue_flag_set_unlocked(QUEUE_FLAG_NOMERGES, clo->clo_queue);
  1.1845 -+#endif
  1.1846 -  clo->clo_disk = alloc_disk(1);
  1.1847 -  if(!clo->clo_disk)
  1.1848 -   {
  1.1849 -@@ -1004,6 +1248,11 @@
  1.1850 -  cloop_dev[cloop_num] = NULL;
  1.1851 - }
  1.1852 - 
  1.1853 -+/* LZ4 Stuff */
  1.1854 -+#if (defined USE_LZ4_INTERNAL)
  1.1855 -+#include "lz4_kmod.c"
  1.1856 -+#endif
  1.1857 -+
  1.1858 - static int __init cloop_init(void)
  1.1859 - {
  1.1860 -  int error=0;
  1.1861 -@@ -1044,7 +1293,7 @@
  1.1862 -      initial_file=NULL; /* if IS_ERR, it's NOT open. */
  1.1863 -     }
  1.1864 -    else
  1.1865 --     error=cloop_set_file(0,initial_file,file);
  1.1866 -+     error=cloop_set_file(0,initial_file);
  1.1867 -    if(error)
  1.1868 -     {
  1.1869 -      printk(KERN_ERR
  1.1870 -@@ -1052,9 +1301,6 @@
  1.1871 -             cloop_name, file, error);
  1.1872 -      goto init_out_dealloc;
  1.1873 -     }
  1.1874 --   if(namelen >= LO_NAME_SIZE) namelen = LO_NAME_SIZE-1;
  1.1875 --   memcpy(cloop_dev[0]->clo_file_name, file, namelen);
  1.1876 --   cloop_dev[0]->clo_file_name[namelen] = 0;
  1.1877 -   }
  1.1878 -  return 0;
  1.1879 - init_out_dealloc:
  1.1880 ---- cloop.h
  1.1881 -+++ cloop.h
  1.1882 -@@ -86,11 +86,8 @@
  1.1883 - struct cloop_tail
  1.1884 - {
  1.1885 - 	u_int32_t table_size; 
  1.1886 --	u_int32_t index_size; /* size:4 comp:3 ctrl-c:1 lastlen:24 */
  1.1887 -+	u_int32_t index_size; /* size:4 unused:3 ctrl-c:1 lastlen:24 */
  1.1888 - #define CLOOP3_INDEX_SIZE(x)    ((unsigned int)((x) & 0xF))
  1.1889 --#define CLOOP3_BLOCKS_FLAGS(x)  ((unsigned int)((x) & 0x70) >> 4)
  1.1890 --#define CLOOP3_TRUNCATED(x)     ((unsigned int)((x) & 0x80) >> 7)
  1.1891 --#define CLOOP3_LASTLEN(x)       (unsigned int)((x) >> 8)
  1.1892 - 	u_int32_t num_blocks;
  1.1893 - };
  1.1894 - 
  1.1895 -@@ -104,8 +101,10 @@
  1.1896 - };
  1.1897 - 
  1.1898 - static inline char *build_index(struct block_info *offsets, unsigned long n, 
  1.1899 --			unsigned long block_size, unsigned global_flags)
  1.1900 -+			unsigned long block_size)
  1.1901 - {
  1.1902 -+	static char v[11];
  1.1903 -+	u_int32_t flags = 0;
  1.1904 - 	u_int32_t *ofs32 = (u_int32_t *) offsets;
  1.1905 - 	loff_t    *ofs64 = (loff_t *) offsets;
  1.1906 - 
  1.1907 -@@ -130,8 +129,6 @@
  1.1908 - 		}
  1.1909 - 		else { /* V2.0/V4.0 */
  1.1910 - 			loff_t last = CLOOP_BLOCK_OFFSET(__be64_to_cpu(ofs64[n]));
  1.1911 --			u_int32_t flags;
  1.1912 --			static char v4[11];
  1.1913 - 			unsigned long i = n;
  1.1914 - 
  1.1915 - 			for (flags = 0; n-- ;) {
  1.1916 -@@ -149,12 +146,7 @@
  1.1917 - 					offsets[i] = offsets[offsets[i].offset];
  1.1918 - 				}
  1.1919 - 			}
  1.1920 --			strcpy(v4, (char *) "64BE v4.0a");
  1.1921 --			v4[10] = 'a' + ((flags-1) & 0xF);	// compressors used
  1.1922 --			if (flags > 0x10) {			// with links ?
  1.1923 --				v4[10] += 'A' - 'a';
  1.1924 --			}
  1.1925 --			return v4;
  1.1926 -+			strcpy(v, (char *) "64BE v4.0a");
  1.1927 - 		}
  1.1928 - 	}
  1.1929 - 	else if (ofs32[1] == 0 && v3_64 == 0) { /* V1.0 */
  1.1930 -@@ -170,7 +162,6 @@
  1.1931 - 	else { /* V3.0 or V0.68 */
  1.1932 - 		unsigned long i;
  1.1933 - 		loff_t j;
  1.1934 --		static char v3[11];
  1.1935 - 		
  1.1936 - 		for (i = 0; i < n && ntohl(ofs32[i]) < ntohl(ofs32[i+1]); i++);
  1.1937 - 		if (i == n && ntohl(ofs32[0]) == (4*n) + 0x8C) { /* V0.68 */
  1.1938 -@@ -185,28 +176,33 @@
  1.1939 - 		}
  1.1940 - 		
  1.1941 - 		v3_64 = (ofs32[1] == 0);
  1.1942 --		for (i = n; i-- != 0; )
  1.1943 -+		for (i = n; i-- != 0; ) {
  1.1944 - 			offsets[i].size = ntohl(ofs32[i << v3_64]); 
  1.1945 --		for (i = 0, j = sizeof(struct cloop_head); i < n; i++) {
  1.1946 --			offsets[i].offset = j;
  1.1947 --			offsets[i].flags = global_flags;
  1.1948 - 			if (offsets[i].size == 0xFFFFFFFF) {
  1.1949 --				offsets[i].flags = CLOOP_COMPRESSOR_NONE;
  1.1950 --				offsets[i].size = block_size;
  1.1951 -+				offsets[i].size = 0x10000000 | block_size;
  1.1952 - 			}
  1.1953 --			if ((offsets[i].size & 0x80000000) == 0) {
  1.1954 -+			offsets[i].flags = (offsets[i].size >> 28);
  1.1955 -+			offsets[i].size &= 0x0FFFFFFF; 
  1.1956 -+		}
  1.1957 -+		for (i = 0, j = sizeof(struct cloop_head); i < n; i++) {
  1.1958 -+			offsets[i].offset = j;
  1.1959 -+			if (offsets[i].flags < 8) {
  1.1960 - 				j += offsets[i].size;
  1.1961 - 			}
  1.1962 - 		}
  1.1963 - 		for (i = 0; i < n; i++) {
  1.1964 --			if (offsets[i].size & 0x80000000) {
  1.1965 --				offsets[i] = offsets[offsets[i].size & 0x7FFFFFFF];
  1.1966 -+			flags |= 1 << offsets[i].flags;
  1.1967 -+			if (offsets[i].flags >= 8) {
  1.1968 -+				offsets[i] = offsets[offsets[i].size];
  1.1969 - 			}
  1.1970 - 		}
  1.1971 --		strcpy(v3, (char *) (v3_64) ? "64BE v3.0a" : "32BE v3.0a");
  1.1972 --		v3[10] += global_flags;
  1.1973 --		return v3;
  1.1974 -+		strcpy(v, (char *) (v3_64) ? "64BE v3.0a" : "32BE v3.0a");
  1.1975 -+	}
  1.1976 -+	v[10] = 'a' + ((flags-1) & 0xF);	// compressors used
  1.1977 -+	if (flags > 0x10) {			// with links ?
  1.1978 -+		v[10] += 'A' - 'a';
  1.1979 - 	}
  1.1980 -+	return v;
  1.1981 - }
  1.1982 - 
  1.1983 - /* Cloop suspend IOCTL */
  1.1984 ---- cloop.c
  1.1985 -+++ cloop.c
  1.1986 -@@ -542,7 +542,7 @@
  1.1987 -  const unsigned int header_size = sizeof(struct cloop_head);
  1.1988 -  unsigned int i, total_offsets=0;
  1.1989 -  loff_t fs_read_position = 0, header_pos[2];
  1.1990 -- int flags, isblkdev, bytes_read, error = 0;
  1.1991 -+ int isblkdev, bytes_read, error = 0;
  1.1992 -  if (clo->suspended) return error;
  1.1993 -  #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)
  1.1994 -  inode = file->f_dentry->d_inode;
  1.1995 -@@ -698,18 +698,12 @@
  1.1996 -        error=-EBADF; goto error_release;
  1.1997 -       }
  1.1998 -      len = CLOOP3_INDEX_SIZE(ntohl(tail.index_size)) * total_offsets;
  1.1999 --     flags = CLOOP3_BLOCKS_FLAGS(ntohl(tail.index_size));
  1.2000 --// May  3 19:45:20 (none) user.info kernel: cloop: uncompress(clo=e0a78000, block_ptrs=e0c9c000, &len(1440)=ddc05e6c, zbuf=e0c9f000, zlen=43, flag=0)
  1.2001 --printk(KERN_INFO "%s: uncompress(clo=%p, block_ptrs=%p, &len(%ld)=%p, zbuf=%p, zlen=%ld, flag=%d)\n", cloop_name, 
  1.2002 --		clo, clo->block_ptrs, len, &len, zbuf, zlen, flags);
  1.2003 --     ret = uncompress(clo, (void *) clo->block_ptrs, &len, zbuf, zlen, flags);
  1.2004 --// May  3 19:45:20 (none) user.alert kernel: BUG: unable to handle kernel NULL pointer dereference at   (null)
  1.2005 --printk(KERN_INFO "%s: uncompressed !\n", cloop_name);
  1.2006 -+     ret = uncompress(clo, (void *) clo->block_ptrs, &len, zbuf, zlen, CLOOP_COMPRESSOR_ZLIB);
  1.2007 -      cloop_free(zbuf, zlen);
  1.2008 -      if (ret != 0)
  1.2009 -       {
  1.2010 --        printk(KERN_ERR "%s: decompression error %i uncompressing index, flags %u\n",
  1.2011 --               cloop_name, ret, flags);
  1.2012 -+        printk(KERN_ERR "%s: decompression error %i uncompressing index\n",
  1.2013 -+               cloop_name, ret);
  1.2014 -        error=-EBADF; goto error_release;
  1.2015 -       }
  1.2016 -     }
  1.2017 -@@ -722,7 +716,6 @@
  1.2018 -  else
  1.2019 -   {
  1.2020 -    unsigned int n, total_bytes;
  1.2021 --   flags = 0;
  1.2022 -    clo->block_ptrs = cloop_malloc(sizeof(struct block_info) * total_offsets);
  1.2023 -    if (!clo->block_ptrs)
  1.2024 -     {
  1.2025 -@@ -761,7 +754,7 @@
  1.2026 -   }
  1.2027 -  {
  1.2028 -   int i;
  1.2029 --  char *version = build_index(clo->block_ptrs, clo->head.num_blocks, clo->head.block_size, flags);
  1.2030 -+  char *version = build_index(clo->block_ptrs, clo->head.num_blocks, clo->head.block_size);
  1.2031 -   clo->largest_block = 0;
  1.2032 -   for (i = 0; i < clo->head.num_blocks; i++)
  1.2033 -     if (clo->block_ptrs[i].size > clo->largest_block)
  1.2034 -@@ -769,9 +762,6 @@
  1.2035 -   printk(KERN_INFO "%s: %s: %s: %u blocks, %u bytes/block, largest block is %lu bytes.\n",
  1.2036 -          cloop_name, clo->underlying_filename, version, clo->head.num_blocks,
  1.2037 -          clo->head.block_size, clo->largest_block);
  1.2038 -- }
  1.2039 -- {
  1.2040 --  int i;
  1.2041 -   clo->num_buffered_blocks = (buffers > 0 && clo->head.block_size >= 512) ?
  1.2042 -                               (buffers / clo->head.block_size) : 1;
  1.2043 -   clo->buffered_blocknum = cloop_malloc(clo->num_buffered_blocks * sizeof (u_int32_t));
  1.2044 -@@ -874,6 +864,10 @@
  1.2045 -  cloop_free(clo->block_ptrs, sizeof(struct block_info) * total_offsets);
  1.2046    clo->block_ptrs=NULL;
  1.2047   error_release:
  1.2048  +#if (defined(CONFIG_ZLIB_INFLATE) || defined(CONFIG_ZLIB_INFLATE_MODULE))
  1.2049 @@ -1548,3 +912,146 @@
  1.2050    if(bbuf) cloop_free(bbuf, clo->underlying_blksize);
  1.2051    if(clo->underlying_filename) { kfree(clo->underlying_filename); clo->underlying_filename=NULL; }
  1.2052    clo->backing_file=NULL;
  1.2053 +@@ -829,6 +900,7 @@
  1.2054 +  if(clo->refcnt > 1)	/* we needed one fd for the ioctl */
  1.2055 +    return -EBUSY;
  1.2056 +  if(filp==NULL) return -EINVAL;
  1.2057 ++ if(clo->clo_thread) { kthread_stop(clo->clo_thread); clo->clo_thread=NULL; }
  1.2058 +  if(filp!=initial_file)
  1.2059 +   fput(filp);
  1.2060 +  else
  1.2061 +@@ -839,7 +911,7 @@
  1.2062 +  clo->backing_file  = NULL;
  1.2063 +  clo->backing_inode = NULL;
  1.2064 +  if(clo->underlying_filename) { kfree(clo->underlying_filename); clo->underlying_filename=NULL; }
  1.2065 +- if(clo->block_ptrs) { cloop_free(clo->block_ptrs, clo->head.num_blocks+1); clo->block_ptrs = NULL; }
  1.2066 ++ if(clo->block_ptrs) { cloop_free(clo->block_ptrs, clo->head.num_blocks); clo->block_ptrs = NULL; }
  1.2067 +  if(clo->preload_cache)
  1.2068 +  {
  1.2069 +   int i;
  1.2070 +@@ -1054,15 +1126,15 @@
  1.2071 +   case LOOP_CLR_FD:       /* Change arg */ 
  1.2072 +   case LOOP_GET_STATUS64: /* Change arg */ 
  1.2073 +   case LOOP_SET_STATUS64: /* Change arg */ 
  1.2074 +-    return cloop_ioctl(bdev, mode, cmd, (unsigned long) compat_ptr(arg));
  1.2075 ++	arg = (unsigned long) compat_ptr(arg);
  1.2076 +   case LOOP_SET_STATUS:   /* unchanged */
  1.2077 +   case LOOP_GET_STATUS:   /* unchanged */
  1.2078 +   case LOOP_SET_FD:       /* unchanged */
  1.2079 +   case LOOP_CHANGE_FD:    /* unchanged */
  1.2080 +-    return cloop_ioctl(bdev, mode, cmd, arg);
  1.2081 +-  default:
  1.2082 +-    return -ENOIOCTLCMD;
  1.2083 ++	return cloop_ioctl(bdev, mode, cmd, arg);
  1.2084 ++	break;
  1.2085 +  }
  1.2086 ++ return -ENOIOCTLCMD;
  1.2087 + }
  1.2088 + #endif
  1.2089 + 
  1.2090 +@@ -1093,7 +1165,7 @@
  1.2091 +  cloop_dev[cloop_num]->refcnt-=1;
  1.2092 + }
  1.2093 + 
  1.2094 +-static const struct block_device_operations clo_fops =
  1.2095 ++static struct block_device_operations clo_fops =
  1.2096 + {
  1.2097 +         owner:		THIS_MODULE,
  1.2098 +         open:           cloop_open,
  1.2099 +@@ -1105,12 +1177,6 @@
  1.2100 + 	/* locked_ioctl ceased to exist in 2.6.36 */
  1.2101 + };
  1.2102 + 
  1.2103 +-static const struct blk_mq_ops cloop_mq_ops = {
  1.2104 +-	.queue_rq       = cloop_queue_rq,
  1.2105 +-/*	.init_request	= cloop_init_request, */
  1.2106 +-/*	.complete	= cloop_complete_rq, */
  1.2107 +-};
  1.2108 +-
  1.2109 + static int cloop_register_blkdev(int major_nr)
  1.2110 + {
  1.2111 +  return register_blkdev(major_nr, cloop_name);
  1.2112 +@@ -1124,37 +1190,33 @@
  1.2113 + 
  1.2114 + static int cloop_alloc(int cloop_num)
  1.2115 + {
  1.2116 +- struct cloop_device *clo = (struct cloop_device *) cloop_malloc(sizeof(struct cloop_device));
  1.2117 ++ struct cloop_device *clo = (struct cloop_device *) cloop_malloc(sizeof(struct cloop_device));;
  1.2118 +  if(clo == NULL) goto error_out;
  1.2119 +  cloop_dev[cloop_num] = clo;
  1.2120 +  memset(clo, 0, sizeof(struct cloop_device));
  1.2121 +  clo->clo_number = cloop_num;
  1.2122 +- clo->tag_set.ops = &cloop_mq_ops;
  1.2123 +- clo->tag_set.nr_hw_queues = 1;
  1.2124 +- clo->tag_set.queue_depth = 128;
  1.2125 +- clo->tag_set.numa_node = NUMA_NO_NODE;
  1.2126 +- clo->tag_set.cmd_size = 0; /* No extra data needed */
  1.2127 +- /* BLK_MQ_F_BLOCKING is extremely important if we want to call blocking functions like vfs_read */
  1.2128 +- clo->tag_set.flags = BLK_MQ_F_SHOULD_MERGE | BLK_MQ_F_BLOCKING;
  1.2129 +- clo->tag_set.driver_data = clo;
  1.2130 +- if(blk_mq_alloc_tag_set(&clo->tag_set)) goto error_out_free_clo;
  1.2131 +- clo->clo_queue = blk_mq_init_queue(&clo->tag_set);
  1.2132 +- if(IS_ERR(clo->clo_queue))
  1.2133 ++ clo->clo_thread = NULL;
  1.2134 ++ init_waitqueue_head(&clo->clo_event);
  1.2135 ++ spin_lock_init(&clo->queue_lock);
  1.2136 ++ mutex_init(&clo->clo_ctl_mutex);
  1.2137 ++ INIT_LIST_HEAD(&clo->clo_list);
  1.2138 ++ clo->clo_queue = blk_init_queue(cloop_do_request, &clo->queue_lock);
  1.2139 ++ if(!clo->clo_queue)
  1.2140 +   {
  1.2141 +    printk(KERN_ERR "%s: Unable to alloc queue[%d]\n", cloop_name, cloop_num);
  1.2142 +-   goto error_out_free_tags;
  1.2143 ++   goto error_out;
  1.2144 +   }
  1.2145 +  clo->clo_queue->queuedata = clo;
  1.2146 +- blk_queue_max_hw_sectors(clo->clo_queue, BLK_DEF_MAX_SECTORS);
  1.2147 ++#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0)
  1.2148 ++ queue_flag_set_unlocked(QUEUE_FLAG_NONROT, clo->clo_queue);
  1.2149 ++ queue_flag_set_unlocked(QUEUE_FLAG_NOMERGES, clo->clo_queue);
  1.2150 ++#endif
  1.2151 +  clo->clo_disk = alloc_disk(1);
  1.2152 +  if(!clo->clo_disk)
  1.2153 +   {
  1.2154 +    printk(KERN_ERR "%s: Unable to alloc disk[%d]\n", cloop_name, cloop_num);
  1.2155 +-   goto error_out_free_queue;
  1.2156 ++   goto error_disk;
  1.2157 +   }
  1.2158 +- spin_lock_init(&clo->queue_lock);
  1.2159 +- mutex_init(&clo->clo_ctl_mutex);
  1.2160 +- mutex_init(&clo->clo_rq_mutex);
  1.2161 +  clo->clo_disk->major = cloop_major;
  1.2162 +  clo->clo_disk->first_minor = cloop_num;
  1.2163 +  clo->clo_disk->fops = &clo_fops;
  1.2164 +@@ -1163,12 +1225,8 @@
  1.2165 +  sprintf(clo->clo_disk->disk_name, "%s%d", cloop_name, cloop_num);
  1.2166 +  add_disk(clo->clo_disk);
  1.2167 +  return 0;
  1.2168 +-error_out_free_queue:
  1.2169 ++error_disk:
  1.2170 +  blk_cleanup_queue(clo->clo_queue);
  1.2171 +-error_out_free_tags:
  1.2172 +- blk_mq_free_tag_set(&clo->tag_set);
  1.2173 +-error_out_free_clo:
  1.2174 +- cloop_free(clo, sizeof(struct cloop_device));
  1.2175 + error_out:
  1.2176 +  return -ENOMEM;
  1.2177 + }
  1.2178 +@@ -1179,7 +1237,6 @@
  1.2179 +  if(clo == NULL) return;
  1.2180 +  del_gendisk(clo->clo_disk);
  1.2181 +  blk_cleanup_queue(clo->clo_queue);
  1.2182 +- blk_mq_free_tag_set(&clo->tag_set);
  1.2183 +  put_disk(clo->clo_disk);
  1.2184 +  cloop_free(clo, sizeof(struct cloop_device));
  1.2185 +  cloop_dev[cloop_num] = NULL;
  1.2186 +--- cloop_suspend.c
  1.2187 ++++ cloop_suspend.c
  1.2188 +@@ -14,6 +14,7 @@
  1.2189 + #include <fcntl.h>
  1.2190 + #include <unistd.h>
  1.2191 + #include <stdio.h>
  1.2192 ++#include <stdint.h>
  1.2193 + 
  1.2194 + /* We don't use the structure, so that define does not hurt */
  1.2195 + #define dev_t int