Staging: get cowloop to build properly
[cascardo/linux.git] / drivers / staging / cowloop / cowloop.c
1 /*
2 **       COWLOOP block device driver (2.6 kernel compliant)
3 ** =======================================================================
4 ** Read-write loop-driver with copy-on-write functionality.
5 **
6 ** Synopsis:
7 **
8 **     modprobe cowloop [maxcows=..] [rdofile=..... cowfile=.... [option=r]]
9 **
10 ** Definition of number of configured cowdevices:
11 **   maxcows=   number of configured cowdevices (default: 16)
12 ** (do not confuse this with MAXCOWS: absolute maximum as compiled)
13 **
14 ** One pair of filenames can be supplied during insmod/modprobe to open
15 ** the first cowdevice:
16 **   rdofile=   read-only file (or filesystem)
17 **   cowfile=   storage-space for modified blocks of read-only file(system)
18 **   option=r   repair cowfile automatically if it appears to be dirty
19 **
20 ** Other cowdevices can be activated via the command "cowdev"
21 ** whenever the cowloop-driver is loaded.
22 **
23 ** The read-only file may be of type 'regular' or 'block-device'.
24 **
25 ** The cowfile must be of type 'regular'.
26 ** If an existing regular file is used as cowfile, its contents will be
27 ** used again for the current read-only file. When the cowfile has not been
28 ** closed properly during a previous session (i.e. rmmod cowloop), the
29 ** cowloop-driver refuses to open it unless the parameter "option=r" is
30 ** specified.
31 **
32 ** Layout of cowfile:
33 **
34 **      +-----------------------------+
35 **      |       cow head block        |   MAPUNIT bytes
36 **      |-----------------------------|
37 **      |                             |   MAPUNIT bytes
38 **      |---                       ---|
39 **      |                             |   MAPUNIT bytes
40 **      |---                       ---|
41 **      |      used-block bitmap      |   MAPUNIT bytes
42 **      |-----------------------------|
43 **      |  gap to align start-offset  |
44 **      |        to 4K multiple       |
45 **      |-----------------------------|  <---- start-offset cow blocks
46 **      |                             |
47 **      |    written cow blocks       |   MAPUNIT bytes
48 **      |          .....              |
49 **
50 **      cowhead block:
51 **        - contains general info about the rdofile which is related
52 **          to this cowfile
53 **
54 **      used-block bitmap:
55 **        - contains one bit per block with a size of MAPUNIT bytes
56 **        - bit-value '1' = block has been written on cow
57 **                    '0' = block unused on cow
58 **        - total bitmap rounded to multiples of MAPUNIT
59 **
60 ** ============================================================================
61 ** Author:             Gerlof Langeveld - AT Computing (March 2003)
62 ** Current maintainer: Hendrik-Jan Thomassen - AT Computing (Summer 2006)
63 ** Email:              hjt@ATComputing.nl
64 ** ----------------------------------------------------------------------------
65 ** Copyright (C) 2003-2009 AT Consultancy
66 **
67 ** This program is free software; you can redistribute it and/or modify it
68 ** under the terms of the GNU General Public License as published by the
69 ** Free Software Foundation; either version 2, or (at your option) any
70 ** later version.
71 **
72 ** This program is distributed in the hope that it will be useful, but
73 ** WITHOUT ANY WARRANTY; without even the implied warranty of
74 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
75 ** See the GNU General Public License for more details.
76 **
77 ** You should have received a copy of the GNU General Public License
78 ** along with this program; if not, write to the Free Software
79 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
80 ** ----------------------------------------------------------------------------
81 **
82 ** Major modifications:
83 **
84 **      200405  Ported to kernel-version 2.6            Hendrik-Jan Thomassen
85 **      200405  Added cowhead to cowfile to garantee
86 **              consistency with read-only file         Gerlof Langeveld
87 **      200405  Postponed flushing of bitmaps to improve
88 **              performance.                            Gerlof Langeveld
89 **      200405  Inline recovery for dirty cowfiles.     Gerlof Langeveld
90 **      200502  Redesign to support more cowdevices.    Gerlof Langeveld
91 **      200502  Support devices/file > 2 Gbytes.        Gerlof Langeveld
92 **      200507  Check for free space to expand cowfile. Gerlof Langeveld
93 **      200902  Upgrade for kernel 2.6.28               Hendrik-Jan Thomassen
94 **
95 ** Inspired by
96 **    loop.c  by Theodore Ts'o and
97 **    cloop.c by Paul `Rusty' Russell & Klaus Knopper.
98 **
99 ** Design-considerations:
100 **
101 **   For the first experiments with the cowloop-driver, the request-queue
102 **   made use of the do_generic_file_read() which worked fine except
103 **   in combination with the cloop-driver; that combination
104 **   resulted in a non-interruptible hangup of the system during
105 **   heavy load. Other experiments using the `make_request' interface also
106 **   resulted in unpredictable system hangups (with proper use of spinlocks).
107 **
108 **   To overcome these problems, the cowloop-driver starts a kernel-thread
109 **   for every active cowdevice.
110 **   All read- and write-request on the read-only file and copy-on-write file
111 **   are handled in the context of that thread.
112 **   A scheme has been designed to wakeup the kernel-thread as
113 **   soon as I/O-requests are available in the request-queue; this thread
114 **   handles the requests one-by-one by calling the proper read- or
115 **   write-function related to the open read-only file or copy-on-write file.
116 **   When all pending requests have been handled, the kernel-thread goes
117 **   back to sleep-state.
118 **   This approach requires some additional context-switches; however the
119 **   performance loss during heavy I/O is less than 3%.
120 **
121 ** -------------------------------------------------------------------------*/
122 /* The following is the cowloop package version number. It must be
123    identical to the content of the include-file "version.h" that is
124    used in all supporting utilities:                                  */
125 char revision[] = "$Revision: 3.1 $"; /* cowlo_init_module() has
126                              assumptions about this string's format   */
127
128 /* Note that the following numbers are *not* the cowloop package version
129    numbers, but separate revision history numbers to track the
130    modifications of this particular source file:                      */
131 /* $Log: cowloop.c,v $
132 **
133 ** Revision 1.30  2009/02/08 hjt
134 ** Integrated earlier fixes
135 ** Upgraded to kernel 2.6.28 (thanks Jerome Poulin)
136 **
137 ** Revision 1.29  2006/12/03 22:12:00  hjt
138 ** changed 'cowdevlock' from spinlock to semaphore, to avoid
139 ** "scheduling while atomic". Contributed by Juergen Christ.
140 ** Added version.h again
141 **
142 ** Revision 1.28  2006/08/16 16:00:00  hjt
143 ** malloc each individual cowloopdevice struct separately
144 **
145 ** Revision 1.27  2006/03/14 14:57:03  root
146 ** Removed include version.h
147 **
148 ** Revision 1.26  2005/08/08 11:22:48  root
149 ** Implement possibility to close a cow file or reopen a cowfile read-only.
150 **
151 ** Revision 1.25  2005/08/03 14:00:39  root
152 ** Added modinfo info to driver.
153 **
154 ** Revision 1.24  2005/07/21 06:14:53  root
155 ** Cosmetic changes source code.
156 **
157 ** Revision 1.23  2005/07/20 13:07:32  root
158 ** Supply ioctl to write watchdog program to react on lack of cowfile space.
159 **
160 ** Revision 1.22  2005/07/20 07:53:34  root
161 ** Regular verification of free space in filesystem holding the cowfile
162 ** (give warnings whenever space is almost exhausted).
163 ** Terminology change: checksum renamed to fingerprint.
164 **
165 ** Revision 1.21  2005/07/19 09:21:52  root
166 ** Removing maximum limit of 16 Gb per cowdevice.
167 **
168 ** Revision 1.20  2005/07/19 07:50:33  root
169 ** Minor bugfixes and cosmetic changes.
170 **
171 ** Revision 1.19  2005/06/10 12:29:55  root
172 ** Removed lock/unlock operation from cowlo_open().
173 **
174 ** Revision 1.18  2005/05/09 12:56:26  root
175 ** Allow a cowdevice to be open more than once
176 ** (needed for support of ReiserFS and XFS).
177 **
178 ** Revision 1.17  2005/03/17 14:36:16  root
179 ** Fixed some license issues.
180 **
181 ** Revision 1.16  2005/03/07 14:42:05  root
182 ** Only allow one parallel open per cowdevice.
183 **
184 ** Revision 1.15  2005/02/18 11:52:04  gerlof
185 ** Redesign to support more than one cowdevice > 2 Gb space.
186 **
187 ** Revision 1.14  2004/08/17 14:19:16  gerlof
188 ** Modified output of /proc/cowloop.
189 **
190 ** Revision 1.13  2004/08/16 07:21:10  gerlof
191 ** Separate statistical counter for read on rdofile and cowfile.
192 **
193 ** Revision 1.12  2004/08/11 06:52:11  gerlof
194 ** Modified messages.
195 **
196 ** Revision 1.11  2004/08/11 06:44:11  gerlof
197 ** Modified log messages.
198 **
199 ** Revision 1.10  2004/08/10 12:27:27  gerlof
200 ** Cosmetic changes.
201 **
202 ** Revision 1.9  2004/08/09 11:43:37  gerlof
203 ** Removed double definition of major number (COWMAJOR).
204 **
205 ** Revision 1.8  2004/08/09 08:03:39  gerlof
206 ** Cleanup of messages.
207 **
208 ** Revision 1.7  2004/05/27 06:37:33  gerlof
209 ** Modified /proc message.
210 **
211 ** Revision 1.6  2004/05/26 21:23:28  gerlof
212 ** Modified /proc output.
213 **
214 ** Revision 1.5  2004/05/26 13:23:34  gerlof
215 ** Support cowsync to force flushing the bitmaps and cowhead.
216 **
217 ** Revision 1.4  2004/05/26 11:11:10  gerlof
218 ** Updated the comment to the actual situation.
219 **
220 ** Revision 1.3  2004/05/26 10:50:00  gerlof
221 ** Implemented recovery-option.
222 **
223 ** Revision 1.2  2004/05/25 15:14:41  gerlof
224 ** Modified bitmap flushing strategy.
225 **
226 */
227
228 #define COWMAJOR        241
229
230 // #define COWDEBUG
231
232 #ifdef  COWDEBUG
233 #define DEBUGP          printk
234 #define DCOW            KERN_ALERT
235 #else
236 #define DEBUGP(format, x...)
237 #endif
238
239 #include <linux/types.h>
240 #include <linux/autoconf.h>
241 #ifndef AUTOCONF_INCLUDED
242 #include <linux/config.h>
243 #endif
244 #include <linux/module.h>
245 #include <linux/version.h>
246 #include <linux/moduleparam.h>
247 #include <linux/init.h>
248 #include <linux/errno.h>
249 #include <linux/kernel.h>
250 #include <linux/major.h>
251 #include <linux/sched.h>
252 #include <linux/fs.h>
253 #include <linux/file.h>
254 #include <linux/stat.h>
255 #include <linux/vmalloc.h>
256 #include <linux/slab.h>
257 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))
258 #include <linux/semaphore.h>
259 #else
260 #include <asm/semaphore.h>
261 #endif
262 #include <asm/uaccess.h>
263 #include <linux/proc_fs.h>
264 #include <linux/blkdev.h>
265 #include <linux/buffer_head.h>
266 #include <linux/hdreg.h>
267 #include <linux/genhd.h>
268 #include <linux/statfs.h>
269
270 #include "cowloop.h"
271
272 MODULE_LICENSE("GPL");
273 /* MODULE_AUTHOR("Gerlof Langeveld <gerlof@ATComputing.nl>");     obsolete address */
274 MODULE_AUTHOR("Hendrik-Jan Thomassen <hjt@ATComputing.nl>"); /* current maintainer */
275 MODULE_DESCRIPTION("Copy-on-write loop driver");
276 MODULE_PARM_DESC(maxcows, " Number of configured cowdevices (default 16)");
277 MODULE_PARM_DESC(rdofile, " Read-only file for /dev/cow/0");
278 MODULE_PARM_DESC(cowfile, " Cowfile for /dev/cow/0");
279 MODULE_PARM_DESC(option, "  Repair cowfile if inconsistent: option=r");
280
281 #define DEVICE_NAME     "cow"
282
283 #define DFLCOWS         16              /* default cowloop devices      */
284
285 static int maxcows = DFLCOWS;
286 module_param(maxcows, int, 0);
287 static char *rdofile = "";
288 module_param(rdofile, charp, 0);
289 static char *cowfile = "";
290 module_param(cowfile, charp, 0);
291 static char *option = "";
292 module_param(option, charp, 0);
293
294 /*
295 ** per cowdevice several bitmap chunks are allowed of MAPCHUNKSZ each
296 **
297 ** each bitmap chunk can describe MAPCHUNKSZ * 8 * MAPUNIT bytes of data
298 ** suppose:
299 **      MAPCHUNKSZ 4096 and MAPUNIT 1024 --> 4096 * 8 * 1024 = 32 Mb per chunk
300 */
301 #define MAPCHUNKSZ      4096    /* #bytes per bitmap chunk  (do not change)  */
302
303 #define SPCMINBLK       100     /* space threshold to give warning messages  */
304 #define SPCDFLINTVL     16      /* once every SPCDFLINTVL writes to cowfile, */
305                                 /* available space in filesystem is checked  */
306
307 #define CALCMAP(x)      ((x)/(MAPCHUNKSZ*8))
308 #define CALCBYTE(x)     (((x)%(MAPCHUNKSZ*8))>>3)
309 #define CALCBIT(x)      ((x)&7)
310
311 #define ALLCOW          1
312 #define ALLRDO          2
313 #define MIXEDUP         3
314
315 static char     allzeroes[MAPUNIT];
316
317 /*
318 ** administration per cowdevice (pair of cowfile/rdofile)
319 */
320
321 /* bit-values for state */
322 #define COWDEVOPEN      0x01    /* cowdevice opened                          */
323 #define COWRWCOWOPEN    0x02    /* cowfile opened read-write                 */
324 #define COWRDCOWOPEN    0x04    /* cowfile opened read-only                  */
325 #define COWWATCHDOG     0x08    /* ioctl for watchdog cowfile space active   */
326
327 #define COWCOWOPEN      (COWRWCOWOPEN|COWRDCOWOPEN)
328
329 struct cowloop_device
330 {
331         /*
332         ** current status
333         */
334         int             state;                  /* bit-values (see above)    */
335         int             opencnt;                /* # opens for cowdevice     */
336
337         /*
338         ** open file pointers
339         */
340         struct file     *rdofp,   *cowfp;       /* open file pointers        */
341         char            *rdoname, *cowname;     /* file names                */
342
343         /*
344         ** request queue administration
345         */
346         struct request_queue    *rqueue;
347         spinlock_t              rqlock;
348         struct gendisk          *gd;
349
350         /*
351         ** administration about read-only file
352         */
353         unsigned int         numblocks; /* # blocks input file in MAPUNIT    */
354         unsigned int         blocksz;   /* minimum unit to access this dev   */
355         unsigned long        fingerprint; /* fingerprint of current rdofile  */
356         struct block_device  *belowdev; /* block device below us             */
357         struct gendisk       *belowgd;  /* gendisk for blk dev below us      */
358         struct request_queue *belowq;   /* req. queue of blk dev below us    */
359
360         /*
361         ** bitmap administration to register which blocks are modified
362         */
363         long int        mapsize;        /* total size of bitmap (bytes)      */
364         long int        mapremain;      /* remaining bytes in last bitmap    */
365         int             mapcount;       /* number of bitmaps in use          */
366         char            **mapcache;     /* area with pointers to bitmaps     */
367
368         char            *iobuf;         /* databuffer of MAPUNIT bytes       */
369         struct cowhead  *cowhead;       /* buffer containing cowhead         */
370
371         /*
372         ** administration for interface with the kernel-thread
373         */
374         int             pid;            /* pid==0: no thread available       */
375         struct request  *req;           /* request to be handled now         */
376         wait_queue_head_t waitq;        /* wait-Q: thread waits for work     */
377         char            closedown;      /* boolean: thread exit required     */
378         char            qfilled;        /* boolean: I/O request pending      */
379         char            iobusy;         /* boolean: req under treatment      */
380
381         /*
382         ** administration to keep track of free space in cowfile filesystem
383         */
384         unsigned long   blksize;        /* block size of fs (bytes)          */
385         unsigned long   blktotal;       /* recent total space in fs (blocks) */
386         unsigned long   blkavail;       /* recent free  space in fs (blocks) */
387
388         wait_queue_head_t watchq;       /* wait-Q: watcher awaits threshold  */
389         unsigned long   watchthresh;    /* threshold of watcher (blocks)     */
390
391         /*
392         ** statistical counters
393         */
394         unsigned long   rdoreads;       /* number of  read-actions rdo       */
395         unsigned long   cowreads;       /* number of  read-actions cow       */
396         unsigned long   cowwrites;      /* number of write-actions           */
397         unsigned long   nrcowblocks;    /* number of blocks in use on cow    */
398 };
399
400 static struct cowloop_device    **cowdevall;    /* ptr to ptrs to all cowdevices */
401 static struct semaphore         cowdevlock;     /* generic lock for cowdevs      */
402
403 static struct gendisk           *cowctlgd;      /* gendisk control channel       */
404 static spinlock_t               cowctlrqlock;   /* for req.q. of ctrl. channel   */
405
406 /*
407 ** private directory /proc/cow
408 */
409 struct proc_dir_entry   *cowlo_procdir;
410
411 /*
412 ** function prototypes
413 */
414 static long int cowlo_do_request (struct request *req);
415 static void     cowlo_sync       (void);
416 static int      cowlo_checkio    (struct cowloop_device *,         int, loff_t);
417 static int      cowlo_readmix    (struct cowloop_device *, void *, int, loff_t);
418 static int      cowlo_writemix   (struct cowloop_device *, void *, int, loff_t);
419 static long int cowlo_readrdo    (struct cowloop_device *, void *, int, loff_t);
420 static long int cowlo_readcow    (struct cowloop_device *, void *, int, loff_t);
421 static long int cowlo_readcowraw (struct cowloop_device *, void *, int, loff_t);
422 static long int cowlo_writecow   (struct cowloop_device *, void *, int, loff_t);
423 static long int cowlo_writecowraw(struct cowloop_device *, void *, int, loff_t);
424
425 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28))
426 static int      cowlo_ioctl      (struct block_device *, fmode_t,
427                                                 unsigned int, unsigned long);
428 #else
429 static int      cowlo_ioctl      (struct inode *, struct file *,
430                                                 unsigned int, unsigned long);
431 #endif
432
433 static int      cowlo_makepair    (struct cowpair __user *);
434 static int      cowlo_removepair  (unsigned long  __user *);
435 static int      cowlo_watch       (struct cowpair __user *);
436 static int      cowlo_cowctl      (unsigned long  __user *, int);
437 static int      cowlo_openpair    (char *, char *, int, int);
438 static int      cowlo_closepair   (struct cowloop_device *);
439 static int      cowlo_openrdo     (struct cowloop_device *, char *);
440 static int      cowlo_opencow     (struct cowloop_device *, char *, int);
441 static void     cowlo_undo_openrdo(struct cowloop_device *);
442 static void     cowlo_undo_opencow(struct cowloop_device *);
443
444 /*****************************************************************************/
445 /* System call handling                                                      */
446 /*****************************************************************************/
447
448 /*
449 ** handle system call open()/mount()
450 **
451 ** returns:
452 **      0   - okay
453 **    < 0   - error value
454 */
455 static int
456 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28))
457 cowlo_open(struct block_device *bdev, fmode_t mode)
458 #else
459 cowlo_open(struct inode *inode, struct file *file)
460 #endif
461 {
462 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28))
463         struct inode *inode = bdev->bd_inode;
464 #endif
465         if (!inode)
466                 return -EINVAL;
467
468         if (imajor(inode) != COWMAJOR) {
469                 printk(KERN_WARNING
470                        "cowloop - unexpected major %d\n", imajor(inode));
471                 return -ENODEV;
472         }
473
474         switch (iminor(inode)) {
475            case COWCTL:
476                 DEBUGP(DCOW"cowloop - open %d control\n", COWCTL);
477                 break;
478
479            default:
480                 DEBUGP(DCOW"cowloop - open minor %d\n", iminor(inode));
481
482                 if ( iminor(inode) >= maxcows )
483                         return -ENODEV;
484
485                 if ( !((cowdevall[iminor(inode)])->state & COWDEVOPEN) )
486                         return -ENODEV;
487
488                 (cowdevall[iminor(inode)])->opencnt++;
489         }
490
491         return 0;
492 }
493
494 /*
495 ** handle system call close()/umount()
496 **
497 ** returns:
498 **      0   - okay
499 */
500 static int
501 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28))
502 cowlo_release(struct gendisk *gd, fmode_t mode)
503 #else
504 cowlo_release(struct inode *inode, struct file *file)
505 #endif
506 {
507 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28))
508         struct block_device *bdev;
509         struct inode *inode;
510
511         bdev = bdget_disk(gd, 0);
512         inode = bdev->bd_inode;
513 #endif
514         if (!inode)
515                 return 0;
516
517         DEBUGP(DCOW"cowloop - release (close) minor %d\n", iminor(inode));
518
519         if ( iminor(inode) != COWCTL)
520                 (cowdevall[iminor(inode)])->opencnt--;
521
522         return 0;
523 }
524
525 /*
526 ** handle system call ioctl()
527 **
528 ** returns:
529 **      0   - okay
530 **    < 0   - error value
531 */
532 static int
533 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28))
534 cowlo_ioctl(struct block_device *bdev, fmode_t mode,
535             unsigned int cmd, unsigned long arg)
536 #else
537 cowlo_ioctl(struct inode *inode, struct file *filp,
538             unsigned int cmd, unsigned long arg)
539 #endif
540 {
541         struct hd_geometry      geo;
542 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28))
543         struct inode *inode = bdev->bd_inode;
544 #endif
545
546         DEBUGP(DCOW "cowloop - ioctl cmd %x\n", cmd);
547
548         switch ( iminor(inode) ) {
549
550            /*
551            ** allowed via control device only
552            */
553            case COWCTL:
554                 switch (cmd) {
555                    /*
556                    ** write all bitmap chunks and cowheaders to cowfiles
557                    */
558                    case COWSYNC:
559                         down(&cowdevlock);
560                         cowlo_sync();
561                         up(&cowdevlock);
562                         return 0;
563
564                    /*
565                    ** open a new cowdevice (pair of rdofile/cowfile)
566                    */
567                    case COWMKPAIR:
568                         return cowlo_makepair((void __user *)arg);
569
570                    /*
571                    ** close a cowdevice (pair of rdofile/cowfile)
572                    */
573                    case COWRMPAIR:
574                         return cowlo_removepair((void __user *)arg);
575
576                    /*
577                    ** watch free space of filesystem containing cowfile
578                    */
579                    case COWWATCH:
580                         return cowlo_watch((void __user *)arg);
581
582                    /*
583                    ** close cowfile for active device
584                    */
585                    case COWCLOSE:
586                         return cowlo_cowctl((void __user *)arg, COWCLOSE);
587
588                    /*
589                    ** reopen cowfile read-only for active device
590                    */
591                    case COWRDOPEN:
592                         return cowlo_cowctl((void __user *)arg, COWRDOPEN);
593
594                    default:
595                         return -EINVAL;
596                 } /* end of switch on command */
597
598            /*
599            ** allowed for any other cowdevice
600            */
601            default:
602                 switch (cmd) {
603                    /*
604                    ** HDIO_GETGEO must be supported for fdisk, etc
605                    */
606                    case HDIO_GETGEO:
607                         geo.cylinders = 0;
608                         geo.heads     = 0;
609                         geo.sectors   = 0;
610
611                         if (copy_to_user((void __user *)arg, &geo, sizeof geo))
612                                 return -EFAULT;
613                         return 0;
614
615                    default:
616                         return -EINVAL;
617                 } /* end of switch on ioctl-cmd code parameter */
618         } /* end of switch on minor number */
619 }
620
621 static struct block_device_operations cowlo_fops =
622 {
623         .owner   =     THIS_MODULE,
624         .open    =     cowlo_open,      /* called upon open  */
625         .release =     cowlo_release,   /* called upon close */
626         .ioctl   =     cowlo_ioctl,     /* called upon ioctl */
627 };
628
629 /*
630 ** handle ioctl-command COWMKPAIR:
631 **      open a new cowdevice (pair of rdofile/cowfile) on-the-fly
632 **
633 ** returns:
634 **      0   - okay
635 **    < 0   - error value
636 */
637 static int
638 cowlo_makepair(struct cowpair __user *arg)
639 {
640         int             i, rv=0;
641         struct cowpair  cowpair;
642         unsigned char   *cowpath;
643         unsigned char   *rdopath;
644
645         /*
646         ** retrieve info about pathnames
647         */
648         if ( copy_from_user(&cowpair, arg, sizeof cowpair) )
649                 return -EFAULT;
650
651         if ( (MAJOR(cowpair.device) != COWMAJOR) && (cowpair.device != ANYDEV) )
652                 return -EINVAL;
653
654         if ( (MINOR(cowpair.device) >= maxcows)  && (cowpair.device != ANYDEV) )
655                 return -EINVAL;
656
657         /*
658         ** retrieve pathname strings
659         */
660         if ( (cowpair.cowflen > PATH_MAX) || (cowpair.rdoflen > PATH_MAX) )
661                 return -ENAMETOOLONG;
662
663         if ( !(cowpath = kmalloc(cowpair.cowflen+1, GFP_KERNEL)) )
664                 return -ENOMEM;
665
666         if ( copy_from_user(cowpath, (void __user *)cowpair.cowfile,
667                                                     cowpair.cowflen) ) {
668                 kfree(cowpath);
669                 return -EFAULT;
670         }
671         *(cowpath+cowpair.cowflen) = 0;
672
673         if ( !(rdopath = kmalloc(cowpair.rdoflen+1, GFP_KERNEL)) ) {
674                 kfree(cowpath);
675                 return -ENOMEM;
676         }
677
678         if ( copy_from_user(rdopath, (void __user *)cowpair.rdofile,
679                                                     cowpair.rdoflen) ) {
680                 kfree(rdopath);
681                 kfree(cowpath);
682                 return -EFAULT;
683         }
684         *(rdopath+cowpair.rdoflen) = 0;
685
686         /*
687         ** open new cowdevice
688         */
689         if ( cowpair.device == ANYDEV) {
690                 /*
691                 ** search first unused minor
692                 */
693                 for (i=0, rv=-EBUSY; i < maxcows; i++) {
694                         if ( !((cowdevall[i])->state & COWDEVOPEN) ) {
695                                 rv = cowlo_openpair(rdopath, cowpath, 0, i);
696                                 break;
697                         }
698                 }
699
700                 if (rv) {               /* open failed? */
701                         kfree(rdopath);
702                         kfree(cowpath);
703                         return rv;
704                 }
705
706                 /*
707                 ** return newly allocated cowdevice to user space
708                 */
709                 cowpair.device = MKDEV(COWMAJOR, i);
710
711                 if ( copy_to_user(arg, &cowpair, sizeof cowpair)) {
712                         kfree(rdopath);
713                         kfree(cowpath);
714                         return -EFAULT;
715                 }
716         } else {                /* specific minor requested */
717                 if ( (rv = cowlo_openpair(rdopath, cowpath, 0,
718                                                 MINOR(cowpair.device)))) {
719                         kfree(rdopath);
720                         kfree(cowpath);
721                         return rv;
722                 }
723         }
724
725         return 0;
726 }
727
728 /*
729 ** handle ioctl-command COWRMPAIR:
730 **      deactivate an existing cowdevice (pair of rdofile/cowfile) on-the-fly
731 **
732 ** returns:
733 **      0   - okay
734 **    < 0   - error value
735 */
736 static int
737 cowlo_removepair(unsigned long __user *arg)
738 {
739         unsigned long           cowdevice;
740         struct cowloop_device   *cowdev;
741
742         /*
743         ** retrieve info about device to be removed
744         */
745         if ( copy_from_user(&cowdevice, arg, sizeof cowdevice))
746                 return -EFAULT;
747
748         /*
749         ** verify major-minor number
750         */
751         if ( MAJOR(cowdevice) != COWMAJOR)
752                 return -EINVAL;
753
754         if ( MINOR(cowdevice) >= maxcows)
755                 return -EINVAL;
756
757         cowdev = cowdevall[MINOR(cowdevice)];
758
759         if ( !(cowdev->state & COWDEVOPEN) )
760                 return -ENODEV;
761
762         /*
763         ** synchronize bitmaps and close cowdevice
764         */
765         if (cowdev->state & COWRWCOWOPEN) {
766                 down(&cowdevlock);
767                 cowlo_sync();
768                 up(&cowdevlock);
769         }
770
771         return cowlo_closepair(cowdev);
772 }
773
774 /*
775 ** handle ioctl-command COWWATCH:
776 **      watch the free space of the filesystem containing a cowfile
777 **      of an open cowdevice
778 **
779 ** returns:
780 **      0   - okay
781 **    < 0   - error value
782 */
783 static int
784 cowlo_watch(struct cowpair __user *arg)
785 {
786         struct cowloop_device   *cowdev;
787         struct cowwatch         cowwatch;
788
789         /*
790         ** retrieve structure holding info
791         */
792         if ( copy_from_user(&cowwatch, arg, sizeof cowwatch))
793                 return -EFAULT;
794
795         /*
796         ** verify if cowdevice exists and is currently open
797         */
798         if ( MINOR(cowwatch.device) >= maxcows)
799                 return -EINVAL;
800
801         cowdev = cowdevall[MINOR(cowwatch.device)];
802
803         if ( !(cowdev->state & COWDEVOPEN) )
804                 return -ENODEV;
805
806         /*
807         ** if the WATCHWAIT-option is set, wait until the indicated
808         ** threshold is reached (only one waiter allowed)
809         */
810         if (cowwatch.flags & WATCHWAIT) {
811                 /*
812                 ** check if already another waiter active
813                 ** for this cowdevice
814                 */
815                 if (cowdev->state & COWWATCHDOG)
816                         return -EAGAIN;
817
818                 cowdev->state |= COWWATCHDOG;
819
820                 cowdev->watchthresh = (unsigned long long)
821                                       cowwatch.threshold /
822                                       (cowdev->blksize / 1024);
823
824                 if (wait_event_interruptible(cowdev->watchq,
825                                     cowdev->watchthresh >= cowdev->blkavail)) {
826                         cowdev->state &= ~COWWATCHDOG;
827                         return EINTR;
828                 }
829
830                 cowdev->state &= ~COWWATCHDOG;
831         }
832
833         cowwatch.totalkb = (unsigned long long)cowdev->blktotal *
834                                                cowdev->blksize / 1024;
835         cowwatch.availkb = (unsigned long long)cowdev->blkavail *
836                                                cowdev->blksize / 1024;
837
838         if ( copy_to_user(arg, &cowwatch, sizeof cowwatch))
839                 return -EFAULT;
840
841         return 0;
842 }
843
844 /*
845 ** handle ioctl-commands COWCLOSE and COWRDOPEN:
846 **      COWCLOSE  - close the cowfile while the cowdevice remains open;
847 **                  this allows an unmount of the filesystem on which
848 **                  the cowfile resides
849 **      COWRDOPEN - close the cowfile and reopen it for read-only;
850 **                  this allows a remount read-ony of the filesystem
851 **                  on which the cowfile resides
852 **
853 ** returns:
854 **      0   - okay
855 **    < 0   - error value
856 */
857 static int
858 cowlo_cowctl(unsigned long __user *arg, int cmd)
859 {
860         struct cowloop_device   *cowdev;
861         unsigned long           cowdevice;
862
863         /*
864         ** retrieve info about device to be removed
865         */
866         if ( copy_from_user(&cowdevice, arg, sizeof cowdevice))
867                 return -EFAULT;
868
869         /*
870         ** verify major-minor number
871         */
872         if ( MAJOR(cowdevice) != COWMAJOR)
873                 return -EINVAL;
874
875         if ( MINOR(cowdevice) >= maxcows)
876                 return -EINVAL;
877
878         cowdev = cowdevall[MINOR(cowdevice)];
879
880         if ( !(cowdev->state & COWDEVOPEN) )
881                 return -ENODEV;
882
883         /*
884         ** synchronize bitmaps and close cowfile
885         */
886         if (cowdev->state & COWRWCOWOPEN) {
887                 down(&cowdevlock);
888                 cowlo_sync();
889                 up(&cowdevlock);
890         }
891
892         /*
893         ** handle specific ioctl-command
894         */
895         switch (cmd) {
896            case COWRDOPEN:
897                 /*
898                 ** if the cowfile is still opened read-write
899                 */
900                 if (cowdev->state & COWRWCOWOPEN) {
901                         /*
902                         ** close the cowfile
903                         */
904                         if (cowdev->cowfp)
905                                 filp_close(cowdev->cowfp, 0);
906
907                         cowdev->state &= ~COWRWCOWOPEN;
908
909                         /*
910                         ** open again for read-only
911                         */
912                         cowdev->cowfp = filp_open(cowdev->cowname,
913                                           O_RDONLY|O_LARGEFILE, 0600);
914
915                         if ( (cowdev->cowfp == NULL) || IS_ERR(cowdev->cowfp) ) {
916                                 printk(KERN_ERR
917                                      "cowloop - failed to reopen cowfile %s\n",
918                                      cowdev->cowname);
919                                 return -EINVAL;
920                         }
921
922                         /*
923                         ** mark cowfile open for read-only
924                         */
925                         cowdev->state |= COWRDCOWOPEN;
926                 } else {
927                         return -EINVAL;
928                 }
929                 break;
930
931            case COWCLOSE:
932                 /*
933                 ** if the cowfile is still open
934                 */
935                 if (cowdev->state & COWCOWOPEN) {
936                         /*
937                         ** close the cowfile
938                         */
939                         if (cowdev->cowfp)
940                                 filp_close(cowdev->cowfp, 0);
941
942                         cowdev->state &= ~COWCOWOPEN;
943                 }
944         }
945
946         return 0;
947 }
948
949
950 /*****************************************************************************/
951 /* Handling of I/O-requests for a cowdevice                                  */
952 /*****************************************************************************/
953
954 /*
955 ** function to be called by core-kernel to handle the I/O-requests
956 ** in the queue
957 */
958 static void
959 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25))
960 cowlo_request(struct request_queue *q)
961 #else
962 cowlo_request(request_queue_t *q)
963 #endif
964 {
965         struct request          *req;
966         struct cowloop_device   *cowdev;
967
968         DEBUGP(DCOW "cowloop - request function called....\n");
969
970         while((req = blk_peek_request(q)) != NULL) {
971                 DEBUGP(DCOW "cowloop - got next request\n");
972
973                 if (! blk_fs_request(req)) {
974                          /* this is not a normal file system request */
975                         __blk_end_request_cur(req, -EIO);
976                         continue;
977                 }
978                 cowdev = req->rq_disk->private_data;
979
980                 if (cowdev->iobusy)
981                         return;
982                 else
983                         cowdev->iobusy = 1;
984
985                 /*
986                 ** when no kernel-thread is available, the request will
987                 ** produce an I/O-error
988                 */
989                 if (!cowdev->pid) {
990                         printk(KERN_ERR"cowloop - no thread available\n");
991                         __blk_end_request_cur(req, -EIO);       /* request failed */
992                         cowdev->iobusy  = 0;
993                         continue;
994                 }
995
996                 /*
997                 ** handle I/O-request in the context of the kernel-thread
998                 */
999                 cowdev->req     = req;
1000                 cowdev->qfilled = 1;
1001
1002                 wake_up_interruptible_sync(&cowdev->waitq);
1003
1004                 /*
1005                 ** get out of this function now while the I/O-request is
1006                 ** under treatment of the kernel-thread; this function
1007                 ** will be called again after the current I/O-request has
1008                 ** been finished by the thread
1009                 */
1010                 return;
1011         }
1012 }
1013
1014 /*
1015 ** daemon-process (kernel-thread) executes this function
1016 */
1017 static int
1018 cowlo_daemon(struct cowloop_device *cowdev)
1019 {
1020         int     rv;
1021         int     minor;
1022         char    myname[16];
1023
1024         for (minor = 0; minor < maxcows; minor++) {
1025                 if (cowdev == cowdevall[minor]) break;
1026         }
1027         sprintf(myname, "cowloopd%d", minor);
1028
1029         daemonize(myname);
1030
1031         while (!cowdev->closedown) {
1032                 /*
1033                 ** sleep while waiting for an I/O request;
1034                 ** note that no non-interruptible wait has been used
1035                 ** because the non-interruptible version of
1036                 ** a *synchronous* wake_up does not exist (any more)
1037                 */
1038                 if (wait_event_interruptible(cowdev->waitq, cowdev->qfilled)){
1039                         flush_signals(current); /* ignore signal-based wakeup */
1040                         continue;
1041                 }
1042
1043                 if (cowdev->closedown)          /* module will be unloaded ? */{
1044                         cowdev->pid = 0;
1045                         return 0;
1046                 }
1047
1048                 /*
1049                 ** woken up by the I/O-request handler: treat requested I/O
1050                 */
1051                 cowdev->qfilled = 0;
1052
1053                 rv = cowlo_do_request(cowdev->req);
1054
1055                 /*
1056                 ** reacquire the queue-spinlock for manipulating
1057                 ** the request-queue and dequeue the request
1058                 */
1059                 spin_lock_irq(&cowdev->rqlock);
1060
1061                 __blk_end_request_cur(cowdev->req, rv);
1062                 cowdev->iobusy = 0;
1063
1064                 /*
1065                 ** initiate the next request from the queue
1066                 */
1067                 cowlo_request(cowdev->rqueue);
1068
1069                 spin_unlock_irq(&cowdev->rqlock);
1070         }
1071         return 0;
1072 }
1073
1074 /*
1075 ** function to be called in the context of the kernel thread
1076 ** to handle the queued I/O-requests
1077 **
1078 ** returns:
1079 **      0   - fail
1080 **      1   - success
1081 */
1082 static long int
1083 cowlo_do_request(struct request *req)
1084 {
1085         unsigned long           len;
1086         long int                rv;
1087         loff_t                  offset;
1088         struct cowloop_device   *cowdev = req->rq_disk->private_data;
1089
1090         /*
1091         ** calculate some variables which are needed later on
1092         */
1093         len     =          blk_rq_cur_sectors(req) << 9;
1094         offset  = (loff_t) blk_rq_pos(req)         << 9;
1095
1096         DEBUGP(DCOW"cowloop - req cmd=%d offset=%lld len=%lu addr=%p\n",
1097                                 *(req->cmd), offset, len, req->buffer);
1098
1099         /*
1100         ** handle READ- or WRITE-request
1101         */
1102         switch (rq_data_dir(req)) {
1103            /**********************************************************/
1104            case READ:
1105                 switch ( cowlo_checkio(cowdev, len, offset) ) {
1106                    case ALLCOW:
1107                         rv = cowlo_readcow(cowdev, req->buffer, len, offset);
1108                         break;
1109
1110                    case ALLRDO:
1111                         rv = cowlo_readrdo(cowdev, req->buffer, len, offset);
1112                         break;
1113
1114                    case MIXEDUP:
1115                         rv = cowlo_readmix(cowdev, req->buffer, len, offset);
1116                         break;
1117
1118                    default:
1119                         rv = 0; /* never happens */
1120                 }
1121                 break;
1122
1123            /**********************************************************/
1124            case WRITE:
1125                 switch ( cowlo_checkio(cowdev, len, offset) ) {
1126                    case ALLCOW:
1127                         /*
1128                         ** straight-forward write will do...
1129                         */
1130                         DEBUGP(DCOW"cowloop - write straight ");
1131
1132                         rv = cowlo_writecow(cowdev, req->buffer, len, offset);
1133                         break;  /* from switch */
1134
1135                    case ALLRDO:
1136                         if ( (len & MUMASK) == 0) {
1137                                 DEBUGP(DCOW"cowloop - write straight ");
1138
1139                                 rv = cowlo_writecow(cowdev, req->buffer,
1140                                                                 len, offset);
1141                                 break;
1142                         }
1143
1144                    case MIXEDUP:
1145                         rv = cowlo_writemix(cowdev, req->buffer, len, offset);
1146                         break;
1147
1148                    default:
1149                         rv = 0; /* never happens */
1150                 }
1151                 break;
1152
1153            default:
1154                 printk(KERN_ERR
1155                        "cowloop - unrecognized command %d\n", *(req->cmd));
1156                 rv = 0;
1157         }
1158
1159         return (rv <= 0 ? 0 : 1);
1160 }
1161
1162 /*
1163 ** check for a given I/O-request if all underlying blocks
1164 ** (with size MAPUNIT) are either in the read-only file or in
1165 ** the cowfile (or a combination of the two)
1166 **
1167 ** returns:
1168 **      ALLRDO  - all underlying blocks in rdofile
1169 **      ALLCOW  - all underlying blocks in cowfile
1170 **      MIXEDUP - underlying blocks partly in rdofile and partly in cowfile
1171 */
1172 static int
1173 cowlo_checkio(struct cowloop_device *cowdev, int len, loff_t offset)
1174 {
1175         unsigned long   mapnum, bytenum, bitnum, blocknr, partlen;
1176         long int        totcnt, cowcnt;
1177         char            *mc;
1178
1179         /*
1180         ** notice that the requested block might cross
1181         ** a blocksize boundary while one of the concerned
1182         ** blocks resides in the read-only file and another
1183         ** one in the copy-on-write file; in that case the
1184         ** request will be broken up into pieces
1185         */
1186         if ( (len <= MAPUNIT) &&
1187              (MAPUNIT - (offset & MUMASK) <= len) ) {
1188                 /*
1189                 ** easy situation:
1190                 ** requested data-block entirely fits within
1191                 ** the mapunit used for the bitmap
1192                 ** check if that block is located in rdofile or
1193                 ** cowfile
1194                 */
1195                 blocknr = offset >> MUSHIFT;
1196
1197                 mapnum  = CALCMAP (blocknr);
1198                 bytenum = CALCBYTE(blocknr);
1199                 bitnum  = CALCBIT (blocknr);
1200
1201                 if (*(*(cowdev->mapcache+mapnum)+bytenum)&(1<<bitnum))
1202                         return ALLCOW;
1203                 else
1204                         return ALLRDO;
1205         }
1206
1207         /*
1208         ** less easy situation:
1209         ** the requested data-block does not fit within the mapunit
1210         ** used for the bitmap
1211         ** check if *all* underlying blocks involved reside on the rdofile
1212         ** or the cowfile (so still no breakup required)
1213         */
1214         for (cowcnt=totcnt=0; len > 0; len-=partlen, offset+=partlen, totcnt++){
1215                 /*
1216                 ** calculate blocknr of involved block
1217                 */
1218                 blocknr = offset >> MUSHIFT;
1219
1220                 /*
1221                 ** calculate partial length for this transfer
1222                 */
1223                 partlen = MAPUNIT - (offset & MUMASK);
1224                 if (partlen > len)
1225                         partlen = len;
1226
1227                 /*
1228                 ** is this block located in the cowfile
1229                 */
1230                 mapnum  = CALCMAP (blocknr);
1231                 bytenum = CALCBYTE(blocknr);
1232                 bitnum  = CALCBIT (blocknr);
1233
1234                 mc      = *(cowdev->mapcache+mapnum);
1235
1236                 if (*(mc+bytenum)&(1<<bitnum))
1237                         cowcnt++;;
1238
1239                 DEBUGP(DCOW
1240                        "cowloop - check %lu - map %lu, byte %lu, bit %lu, "
1241                        "cowcnt %ld, totcnt %ld %02x %p\n",
1242                         blocknr, mapnum, bytenum, bitnum, cowcnt, totcnt,
1243                         *(mc+bytenum), mc);
1244         }
1245
1246         if (cowcnt == 0)        /* all involved blocks on rdofile? */
1247                 return ALLRDO;
1248
1249         if (cowcnt == totcnt)   /* all involved blocks on cowfile? */
1250                 return ALLCOW;
1251
1252         /*
1253         ** situation somewhat more complicated:
1254         ** involved underlying blocks spread over both files
1255         */
1256         return MIXEDUP;
1257 }
1258
1259 /*
1260 ** read requested chunk partly from rdofile and partly from cowfile
1261 **
1262 ** returns:
1263 **      0   - fail
1264 **      1   - success
1265 */
1266 static int
1267 cowlo_readmix(struct cowloop_device *cowdev, void *buf, int len, loff_t offset)
1268 {
1269         unsigned long   mapnum, bytenum, bitnum, blocknr, partlen;
1270         long int        rv;
1271         char            *mc;
1272
1273         /*
1274         ** complicated approach: breakup required of read-request
1275         */
1276         for (rv=1; len > 0; len-=partlen, buf+=partlen, offset+=partlen) {
1277                 /*
1278                 ** calculate blocknr of entire block
1279                 */
1280                 blocknr = offset >> MUSHIFT;
1281
1282                 /*
1283                 ** calculate partial length for this transfer
1284                 */
1285                 partlen = MAPUNIT - (offset & MUMASK);
1286                 if (partlen > len)
1287                         partlen = len;
1288
1289                 /*
1290                 ** is this block located in the cowfile
1291                 */
1292                 mapnum  = CALCMAP (blocknr);
1293                 bytenum = CALCBYTE(blocknr);
1294                 bitnum  = CALCBIT (blocknr);
1295                 mc      = *(cowdev->mapcache+mapnum);
1296
1297                 if (*(mc+bytenum)&(1<<bitnum)) {
1298                         /*
1299                         ** read (partial) block from cowfile
1300                         */
1301                         DEBUGP(DCOW"cowloop - split read "
1302                                 "cow partlen=%ld off=%lld\n", partlen, offset);
1303
1304                         if (cowlo_readcow(cowdev, buf, partlen, offset) <= 0)
1305                                 rv = 0;
1306                 } else {
1307                         /*
1308                         ** read (partial) block from rdofile
1309                         */
1310                         DEBUGP(DCOW"cowloop - split read "
1311                                 "rdo partlen=%ld off=%lld\n", partlen, offset);
1312
1313                         if (cowlo_readrdo(cowdev, buf, partlen, offset) <= 0)
1314                                 rv = 0;
1315                 }
1316         }
1317
1318         return rv;
1319 }
1320
1321 /*
1322 ** chunk to be written to the cowfile needs pieces to be
1323 ** read from the rdofile
1324 **
1325 ** returns:
1326 **      0   - fail
1327 **      1   - success
1328 */
1329 static int
1330 cowlo_writemix(struct cowloop_device *cowdev, void *buf, int len, loff_t offset)
1331 {
1332         unsigned long   mapnum, bytenum, bitnum, blocknr, partlen;
1333         long int        rv;
1334         char            *mc;
1335
1336         /*
1337         ** somewhat more complicated stuff is required:
1338         ** if the request is larger than one underlying
1339         ** block or is spread over two underlying blocks,
1340         ** split the request into pieces; if a block does not
1341         ** start at a block boundary, take care that
1342         ** surrounding data is read first (if needed),
1343         ** fit the new data in and write it as a full block
1344         */
1345         for (rv=1; len > 0; len-=partlen, buf+=partlen, offset+=partlen) {
1346                 /*
1347                 ** calculate partial length for this transfer
1348                 */
1349                 partlen = MAPUNIT - (offset & MUMASK);
1350                 if (partlen > len)
1351                         partlen = len;
1352
1353                 /*
1354                 ** calculate blocknr of entire block
1355                 */
1356                 blocknr = offset >> MUSHIFT;
1357
1358                 /*
1359                 ** has this block been written before?
1360                 */
1361                 mapnum  = CALCMAP (blocknr);
1362                 bytenum = CALCBYTE(blocknr);
1363                 bitnum  = CALCBIT (blocknr);
1364                 mc      = *(cowdev->mapcache+mapnum);
1365
1366                 if (*(mc+bytenum)&(1<<bitnum)) {
1367                         /*
1368                         ** block has been written before;
1369                         ** write transparantly to cowfile
1370                         */
1371                         DEBUGP(DCOW
1372                                "cowloop - splitwr transp\n");
1373
1374                         if (cowlo_writecow(cowdev, buf, partlen, offset) <= 0)
1375                                 rv = 0;
1376                 } else {
1377                         /*
1378                         ** block has never been written before,
1379                         ** so read entire block from
1380                         ** read-only file first, unless
1381                         ** a full block is requested to
1382                         ** be written
1383                         */
1384                         if (partlen < MAPUNIT) {
1385                                 if (cowlo_readrdo(cowdev, cowdev->iobuf,
1386                                       MAPUNIT, (loff_t)blocknr << MUSHIFT) <= 0)
1387                                         rv = 0;
1388                         }
1389
1390                         /*
1391                         ** transfer modified part into
1392                         ** the block just read
1393                         */
1394                         memcpy(cowdev->iobuf + (offset & MUMASK), buf, partlen);
1395
1396                         /*
1397                         ** write entire block to cowfile
1398                         */
1399                         DEBUGP(DCOW"cowloop - split "
1400                                 "partlen=%ld off=%lld\n",
1401                                 partlen, (loff_t)blocknr << MUSHIFT);
1402
1403                         if (cowlo_writecow(cowdev, cowdev->iobuf, MAPUNIT,
1404                                              (loff_t)blocknr << MUSHIFT) <= 0)
1405                                 rv = 0;
1406                 }
1407         }
1408
1409         return rv;
1410 }
1411
1412 /*****************************************************************************/
1413 /* I/O-support for read-only file and copy-on-write file                     */
1414 /*****************************************************************************/
1415
1416 /*
1417 ** read data from the read-only file
1418 **
1419 ** return-value: similar to user-mode read
1420 */
1421 static long int
1422 cowlo_readrdo(struct cowloop_device *cowdev, void *buf, int len, loff_t offset)
1423 {
1424         long int        rv;
1425         mm_segment_t    old_fs;
1426         loff_t          saveoffset = offset;
1427
1428         DEBUGP(DCOW"cowloop - readrdo called\n");
1429
1430         old_fs = get_fs();
1431         set_fs( get_ds() );
1432         rv = cowdev->rdofp->f_op->read(cowdev->rdofp, buf, len, &offset);
1433         set_fs(old_fs);
1434
1435         if (rv < len) {
1436                 printk(KERN_WARNING "cowloop - read-failure %ld on rdofile"
1437                                     "- offset=%lld len=%d\n",
1438                                         rv, saveoffset, len);
1439         }
1440
1441         cowdev->rdoreads++;
1442         return rv;
1443 }
1444
1445 /*
1446 ** read cowfile from a modified offset, i.e. skipping the bitmap and cowhead
1447 **
1448 ** return-value: similar to user-mode read
1449 */
1450 static long int
1451 cowlo_readcow(struct cowloop_device *cowdev, void *buf, int len, loff_t offset)
1452 {
1453         DEBUGP(DCOW"cowloop - readcow called\n");
1454
1455         offset += cowdev->cowhead->doffset;
1456
1457         return cowlo_readcowraw(cowdev, buf, len, offset);
1458 }
1459
1460 /*
1461 ** read cowfile from an absolute offset
1462 **
1463 ** return-value: similar to user-mode read
1464 */
1465 static long int
1466 cowlo_readcowraw(struct cowloop_device *cowdev,
1467                                         void *buf, int len, loff_t offset)
1468 {
1469         long int        rv;
1470         mm_segment_t    old_fs;
1471         loff_t          saveoffset = offset;
1472
1473         DEBUGP(DCOW"cowloop - readcowraw called\n");
1474
1475         /*
1476         ** be sure that cowfile is opened for read-write
1477         */
1478         if ( !(cowdev->state & COWCOWOPEN) ) {
1479                  printk(KERN_WARNING
1480                         "cowloop - read request from cowfile refused\n");
1481
1482                 return -EBADF;
1483         }
1484
1485         /*
1486         ** issue low level read
1487         */
1488         old_fs = get_fs();
1489         set_fs( get_ds() );
1490         rv = cowdev->cowfp->f_op->read(cowdev->cowfp, buf, len, &offset);
1491         set_fs(old_fs);
1492
1493         if (rv < len) {
1494                 printk(KERN_WARNING
1495                        "cowloop - read-failure %ld on cowfile"
1496                        "- offset=%lld len=%d\n", rv, saveoffset, len);
1497         }
1498
1499         cowdev->cowreads++;
1500         return rv;
1501 }
1502
1503 /*
1504 ** write cowfile from a modified offset, i.e. skipping the bitmap and cowhead
1505 **
1506 ** if a block is written for the first time while its contents consists
1507 ** of binary zeroes only, the concerning bitmap is flushed to the cowfile
1508 **
1509 ** return-value: similar to user-mode write
1510 */
1511 static long int
1512 cowlo_writecow(struct cowloop_device *cowdev, void *buf, int len, loff_t offset)
1513 {
1514         long int        rv;
1515         unsigned long   mapnum=0, mapbyte=0, mapbit=0, cowblock=0, partlen;
1516         char            *tmpptr,  *mapptr = NULL;
1517         loff_t          tmpoffset, mapoffset = 0;
1518
1519         DEBUGP(DCOW"cowloop - writecow called\n");
1520
1521         /*
1522         ** be sure that cowfile is opened for read-write
1523         */
1524         if ( !(cowdev->state & COWRWCOWOPEN) ) {
1525                  printk(KERN_WARNING
1526                         "cowloop - Write request to cowfile refused\n");
1527
1528                 return -EBADF;
1529         }
1530
1531         /*
1532         ** write the entire block to the cowfile
1533         */
1534         tmpoffset = offset + cowdev->cowhead->doffset;
1535
1536         rv = cowlo_writecowraw(cowdev, buf, len, tmpoffset);
1537
1538         /*
1539         ** verify if enough space available on filesystem holding
1540         ** the cowfile
1541         **   - when the last write failed (might be caused by lack of space)
1542         **   - when a watcher is active (to react adequatly)
1543         **   - when the previous check indicated fs was almost full
1544         **   - with regular intervals
1545         */
1546         if ( (rv <= 0)                                 ||
1547              (cowdev->state        & COWWATCHDOG)      ||
1548              (cowdev->blkavail / 2 < SPCDFLINTVL)      ||
1549              (cowdev->cowwrites    % SPCDFLINTVL == 0) ) {
1550                 struct kstatfs          ks;
1551
1552 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18))
1553                 if (vfs_statfs(cowdev->cowfp->f_dentry, &ks)==0){
1554 #else
1555                 if (vfs_statfs(cowdev->cowfp->f_dentry->d_inode->i_sb, &ks)==0){
1556 #endif
1557                         if (ks.f_bavail <= SPCMINBLK) {
1558                                 switch (ks.f_bavail) {
1559                                    case 0:
1560                                    case 1:
1561                                    case 2:
1562                                    case 3:
1563                                         printk(KERN_ALERT
1564                                                "cowloop - "
1565                                                "ALERT: cowfile full!\n");
1566                                         break;
1567
1568                                    default:
1569                                         printk(KERN_WARNING
1570                                                "cowloop - cowfile almost "
1571                                                "full (only %llu Kb free)\n",
1572                                                 (unsigned long long)
1573                                                 ks.f_bsize * ks.f_bavail /1024);
1574                                 }
1575                         }
1576
1577                         cowdev->blktotal = ks.f_blocks;
1578                         cowdev->blkavail = ks.f_bavail;
1579
1580                         /*
1581                         ** wakeup watcher if threshold has been reached
1582                         */
1583                         if ( (cowdev->state & COWWATCHDOG) &&
1584                             (cowdev->watchthresh >= cowdev->blkavail) ) {
1585                                 wake_up_interruptible(&cowdev->watchq);
1586                         }
1587                 }
1588         }
1589
1590         if (rv <= 0)
1591                 return rv;
1592
1593         DEBUGP(DCOW"cowloop - block written\n");
1594
1595         /*
1596         ** check if block(s) is/are written to the cowfile
1597         ** for the first time; if so, adapt the bitmap
1598         */
1599         for (; len > 0; len-=partlen, offset+=partlen, buf+=partlen) {
1600                 /*
1601                 ** calculate partial length for this transfer
1602                 */
1603                 partlen = MAPUNIT - (offset & MUMASK);
1604                 if (partlen > len)
1605                         partlen = len;
1606
1607                 /*
1608                 ** calculate bitnr of written chunk of cowblock
1609                 */
1610                 cowblock = offset >> MUSHIFT;
1611
1612                 mapnum   = CALCMAP (cowblock);
1613                 mapbyte  = CALCBYTE(cowblock);
1614                 mapbit   = CALCBIT (cowblock);
1615
1616                 if (*(*(cowdev->mapcache+mapnum)+mapbyte) & (1<<mapbit))
1617                         continue;       /* already written before */
1618
1619                 /*
1620                 ** if the block is written for the first time,
1621                 ** the corresponding bit should be set in the bitmap
1622                 */
1623                 *(*(cowdev->mapcache+mapnum)+mapbyte) |= (1<<mapbit);
1624
1625                 cowdev->nrcowblocks++;
1626
1627                 DEBUGP(DCOW"cowloop - bitupdate blk=%ld map=%ld "
1628                         "byte=%ld bit=%ld\n",
1629                         cowblock, mapnum, mapbyte, mapbit);
1630
1631                 /*
1632                 ** check if the cowhead in the cowfile is currently
1633                 ** marked clean; if so, mark it dirty and flush it
1634                 */
1635                 if ( !(cowdev->cowhead->flags &= COWDIRTY)) {
1636                         cowdev->cowhead->flags  |= COWDIRTY;
1637
1638                         cowlo_writecowraw(cowdev, cowdev->cowhead,
1639                                                         MAPUNIT, (loff_t)0);
1640                 }
1641
1642                 /*
1643                 ** if the written datablock contained binary zeroes,
1644                 ** the bitmap block should be marked to be flushed to disk
1645                 ** (blocks containing all zeroes cannot be recovered by
1646                 ** the cowrepair-program later on if cowloop is not properly
1647                 ** removed via rmmod)
1648                 */
1649                 if ( memcmp(buf, allzeroes, partlen) ) /* not all zeroes? */
1650                         continue;                      /* no flush needed */
1651
1652                 /*
1653                 ** calculate positions of bitmap block to be flushed
1654                 ** - pointer of bitmap block in memory
1655                 ** - offset  of bitmap block in cowfile
1656                 */
1657                 tmpptr    = *(cowdev->mapcache+mapnum) + (mapbyte & (~MUMASK));
1658                 tmpoffset = (loff_t) MAPUNIT + mapnum * MAPCHUNKSZ +
1659                                                        (mapbyte & (~MUMASK));
1660
1661                 /*
1662                 ** flush a bitmap block at the moment that all bits have
1663                 ** been set in that block, i.e. at the moment that we
1664                 ** switch to another bitmap block
1665                 */
1666                 if ( (mapoffset != 0) && (mapoffset != tmpoffset) ) {
1667                         if (cowlo_writecowraw(cowdev, mapptr, MAPUNIT,
1668                                                         mapoffset) < 0) {
1669                                 printk(KERN_WARNING
1670                                        "cowloop - write-failure on bitmap - "
1671                                        "blk=%ld map=%ld byte=%ld bit=%ld\n",
1672                                         cowblock, mapnum, mapbyte, mapbit);
1673                         }
1674
1675                         DEBUGP(DCOW"cowloop - bitmap blk written %lld\n",
1676                                                                 mapoffset);
1677                 }
1678
1679                 /*
1680                 ** remember offset in cowfile and offset in memory
1681                 ** for bitmap to be flushed; flushing will be done
1682                 ** as soon as all updates in this bitmap block have
1683                 ** been done
1684                 */
1685                 mapoffset = tmpoffset;
1686                 mapptr    = tmpptr;
1687         }
1688
1689         /*
1690         ** any new block written containing binary zeroes?
1691         */
1692         if (mapoffset) {
1693                 if (cowlo_writecowraw(cowdev, mapptr, MAPUNIT, mapoffset) < 0) {
1694                         printk(KERN_WARNING
1695                                "cowloop - write-failure on bitmap - "
1696                                "blk=%ld map=%ld byte=%ld bit=%ld\n",
1697                                cowblock, mapnum, mapbyte, mapbit);
1698                 }
1699
1700                 DEBUGP(DCOW"cowloop - bitmap block written %lld\n", mapoffset);
1701         }
1702
1703         return rv;
1704 }
1705
1706 /*
1707 ** write cowfile from an absolute offset
1708 **
1709 ** return-value: similar to user-mode write
1710 */
1711 static long int
1712 cowlo_writecowraw(struct cowloop_device *cowdev,
1713                                         void *buf, int len, loff_t offset)
1714 {
1715         long int        rv;
1716         mm_segment_t    old_fs;
1717         loff_t          saveoffset = offset;
1718
1719         DEBUGP(DCOW"cowloop - writecowraw called\n");
1720
1721         /*
1722         ** be sure that cowfile is opened for read-write
1723         */
1724         if ( !(cowdev->state & COWRWCOWOPEN) ) {
1725                  printk(KERN_WARNING
1726                         "cowloop - write request to cowfile refused\n");
1727
1728                 return -EBADF;
1729         }
1730
1731         /*
1732         ** issue low level write
1733         */
1734         old_fs = get_fs();
1735         set_fs( get_ds() );
1736         rv = cowdev->cowfp->f_op->write(cowdev->cowfp, buf, len, &offset);
1737         set_fs(old_fs);
1738
1739         if (rv < len) {
1740                 printk(KERN_WARNING
1741                        "cowloop - write-failure %ld on cowfile"
1742                        "- offset=%lld len=%d\n", rv, saveoffset, len);
1743         }
1744
1745         cowdev->cowwrites++;
1746         return rv;
1747 }
1748
1749
1750 /*
1751 ** readproc-function: called when the corresponding /proc-file is read
1752 */
1753 static int
1754 cowlo_readproc(char *buf, char **start, off_t pos, int cnt, int *eof, void *p)
1755 {
1756         struct cowloop_device *cowdev = p;
1757
1758         revision[sizeof revision - 3] = '\0';
1759
1760         return sprintf(buf,
1761                 "   cowloop version: %9s\n\n"
1762                 "      device state: %s%s%s%s\n"
1763                 "   number of opens: %9d\n"
1764                 "     pid of thread: %9d\n\n"
1765                 "    read-only file: %9s\n"
1766                 "          rdoreads: %9lu\n\n"
1767                 "copy-on-write file: %9s\n"
1768                 "     state cowfile: %9s\n"
1769                 "     bitmap-blocks: %9lu (of %d bytes)\n"
1770                 "  cowblocks in use: %9lu (of %d bytes)\n"
1771                 "          cowreads: %9lu\n"
1772                 "         cowwrites: %9lu\n",
1773                         &revision[11],
1774
1775                         cowdev->state & COWDEVOPEN   ? "devopen "   : "",
1776                         cowdev->state & COWRWCOWOPEN ? "cowopenrw " : "",
1777                         cowdev->state & COWRDCOWOPEN ? "cowopenro " : "",
1778                         cowdev->state & COWWATCHDOG  ? "watchdog "  : "",
1779
1780                         cowdev->opencnt,
1781                         cowdev->pid,
1782                         cowdev->rdoname,
1783                         cowdev->rdoreads,
1784                         cowdev->cowname,
1785                         cowdev->cowhead->flags & COWDIRTY ? "dirty":"clean",
1786                         cowdev->mapsize >> MUSHIFT, MAPUNIT,
1787                         cowdev->nrcowblocks, MAPUNIT,
1788                         cowdev->cowreads,
1789                         cowdev->cowwrites);
1790 }
1791
1792 /*****************************************************************************/
1793 /* Setup and destroy cowdevices                                              */
1794 /*****************************************************************************/
1795
1796 /*
1797 ** open and prepare a cowdevice (rdofile and cowfile) and allocate bitmaps
1798 **
1799 ** returns:
1800 **      0   - okay
1801 **    < 0   - error value
1802 */
1803 static int
1804 cowlo_openpair(char *rdof, char *cowf, int autorecover, int minor)
1805 {
1806         long int                rv;
1807         struct cowloop_device   *cowdev = cowdevall[minor];
1808         struct kstatfs          ks;
1809
1810         down(&cowdevlock);
1811
1812         /*
1813         ** requested device exists?
1814         */
1815         if (minor >= maxcows) {
1816                 up(&cowdevlock);
1817                 return -ENODEV;
1818         }
1819
1820         /*
1821         ** requested device already assigned to cowdevice?
1822         */
1823         if (cowdev->state & COWDEVOPEN) {
1824                 up(&cowdevlock);
1825                 return -EBUSY;
1826         }
1827
1828         /*
1829         ** initialize administration
1830         */
1831         memset(cowdev, 0, sizeof *cowdev);
1832
1833         spin_lock_init     (&cowdev->rqlock);
1834         init_waitqueue_head(&cowdev->waitq);
1835         init_waitqueue_head(&cowdev->watchq);
1836
1837         /*
1838         ** open the read-only file
1839         */
1840         DEBUGP(DCOW"cowloop - call openrdo....\n");
1841
1842         if ( (rv = cowlo_openrdo(cowdev, rdof)) ) {
1843                 cowlo_undo_openrdo(cowdev);
1844                 up(&cowdevlock);
1845                 return rv;
1846         }
1847
1848         /*
1849         ** open the cowfile
1850         */
1851         DEBUGP(DCOW"cowloop - call opencow....\n");
1852
1853         if ( (rv = cowlo_opencow(cowdev, cowf, autorecover)) ) {
1854                 cowlo_undo_openrdo(cowdev);
1855                 cowlo_undo_opencow(cowdev);
1856                 up(&cowdevlock);
1857                 return rv;
1858         }
1859
1860         /*
1861         ** administer total and available size of filesystem holding cowfile
1862         */
1863 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18))
1864                 if (vfs_statfs(cowdev->cowfp->f_dentry, &ks)==0){
1865 #else
1866                 if (vfs_statfs(cowdev->cowfp->f_dentry->d_inode->i_sb, &ks)==0){
1867 #endif
1868                 cowdev->blksize  = ks.f_bsize;
1869                 cowdev->blktotal = ks.f_blocks;
1870                 cowdev->blkavail = ks.f_bavail;
1871         } else {
1872                 cowdev->blksize  = 1024;        /* avoid division by zero */
1873         }
1874
1875         /*
1876         ** flush the (recovered) bitmaps and cowhead to the cowfile
1877         */
1878         DEBUGP(DCOW"cowloop - call cowsync....\n");
1879
1880         cowlo_sync();
1881
1882         /*
1883         ** allocate gendisk for the cow device
1884         */
1885         DEBUGP(DCOW"cowloop - alloc disk....\n");
1886
1887         if ((cowdev->gd = alloc_disk(1)) == NULL) {
1888                 printk(KERN_WARNING
1889                        "cowloop - unable to alloc_disk for cowloop\n");
1890
1891                 cowlo_undo_openrdo(cowdev);
1892                 cowlo_undo_opencow(cowdev);
1893                 up(&cowdevlock);
1894                 return -ENOMEM;
1895         }
1896
1897         cowdev->gd->major        = COWMAJOR;
1898         cowdev->gd->first_minor  = minor;
1899         cowdev->gd->minors       = 1;
1900         cowdev->gd->fops         = &cowlo_fops;
1901         cowdev->gd->private_data = cowdev;
1902         sprintf(cowdev->gd->disk_name, "%s%d", DEVICE_NAME, minor);
1903
1904         /* in .5 Kb units */
1905         set_capacity(cowdev->gd, (cowdev->numblocks*(MAPUNIT/512)));
1906
1907         DEBUGP(DCOW"cowloop - init request queue....\n");
1908
1909         if ((cowdev->rqueue = blk_init_queue(cowlo_request, &cowdev->rqlock))
1910                                                                 == NULL) {
1911                 printk(KERN_WARNING
1912                        "cowloop - unable to get request queue for cowloop\n");
1913
1914                 del_gendisk(cowdev->gd);
1915                 cowlo_undo_openrdo(cowdev);
1916                 cowlo_undo_opencow(cowdev);
1917                 up(&cowdevlock);
1918                 return -EINVAL;
1919         }
1920
1921         blk_queue_logical_block_size(cowdev->rqueue, cowdev->blocksz);
1922         cowdev->gd->queue = cowdev->rqueue;
1923
1924         /*
1925         ** start kernel thread to handle requests
1926         */
1927         DEBUGP(DCOW"cowloop - kickoff daemon....\n");
1928
1929         cowdev->pid = kernel_thread((int (*)(void *))cowlo_daemon, cowdev, 0);
1930
1931         /*
1932         ** create a file below directory /proc/cow for this new cowdevice
1933         */
1934         if (cowlo_procdir) {
1935                 char    tmpname[64];
1936
1937                 sprintf(tmpname, "%d", minor);
1938
1939                 create_proc_read_entry(tmpname, 0 , cowlo_procdir,
1940                                                 cowlo_readproc, cowdev);
1941         }
1942
1943         cowdev->state   |= COWDEVOPEN;
1944
1945         cowdev->rdoname = rdof;
1946         cowdev->cowname = cowf;
1947
1948         /*
1949         ** enable the new disk; this triggers the first request!
1950         */
1951         DEBUGP(DCOW"cowloop - call add_disk....\n");
1952
1953         add_disk(cowdev->gd);
1954
1955         up(&cowdevlock);
1956         return 0;
1957 }
1958
1959 /*
1960 ** close a cowdevice (pair of rdofile/cowfile) and release memory
1961 **
1962 ** returns:
1963 **      0   - okay
1964 **    < 0   - error value
1965 */
1966 static int
1967 cowlo_closepair(struct cowloop_device *cowdev)
1968 {
1969         int minor;
1970
1971         down(&cowdevlock);
1972
1973         /*
1974         ** if cowdevice is not activated at all, refuse
1975         */
1976         if ( !(cowdev->state & COWDEVOPEN) ) {
1977                 up(&cowdevlock);
1978                 return -ENODEV;
1979         }
1980
1981         /*
1982         ** if this cowdevice is still open, refuse
1983         */
1984         if (cowdev->opencnt > 0) {
1985                 up(&cowdevlock);
1986                 return -EBUSY;
1987         }
1988
1989         up(&cowdevlock);
1990
1991         /*
1992         ** wakeup watcher (if any)
1993         */
1994         if (cowdev->state & COWWATCHDOG) {
1995                 cowdev->watchthresh = cowdev->blkavail;
1996                 wake_up_interruptible(&cowdev->watchq);
1997         }
1998
1999         /*
2000         ** wakeup kernel-thread to be able to exit
2001         ** and wait until it has exited
2002         */
2003         cowdev->closedown = 1;
2004         cowdev->qfilled   = 1;
2005         wake_up_interruptible(&cowdev->waitq);
2006
2007         while (cowdev->pid)
2008                 schedule();
2009
2010         del_gendisk(cowdev->gd);  /* revert the alloc_disk() */
2011         put_disk(cowdev->gd);     /* revert the add_disk()   */
2012
2013         if (cowlo_procdir) {
2014                 char    tmpname[64];
2015
2016                 for (minor = 0; minor < maxcows; minor++) {
2017                         if (cowdev == cowdevall[minor]) break;
2018                 }
2019                 sprintf(tmpname, "%d", minor);
2020
2021                 remove_proc_entry(tmpname, cowlo_procdir);
2022         }
2023
2024         blk_cleanup_queue(cowdev->rqueue);
2025
2026         /*
2027         ** release memory for filenames if these names have
2028         ** been allocated dynamically
2029         */
2030         if ( (cowdev->cowname) && (cowdev->cowname != cowfile))
2031                 kfree(cowdev->cowname);
2032
2033         if ( (cowdev->rdoname) && (cowdev->rdoname != rdofile))
2034                 kfree(cowdev->rdoname);
2035
2036         cowlo_undo_openrdo(cowdev);
2037         cowlo_undo_opencow(cowdev);
2038
2039         cowdev->state &= ~COWDEVOPEN;
2040
2041         return 0;
2042 }
2043
2044 /*
2045 ** open the read-only file
2046 **
2047 ** returns:
2048 **      0   - okay
2049 **    < 0   - error value
2050 */
2051 static int
2052 cowlo_openrdo(struct cowloop_device *cowdev, char *rdof)
2053 {
2054         struct file     *f;
2055         struct inode    *inode;
2056         long int        i, nrval;
2057
2058         DEBUGP(DCOW"cowloop - openrdo called\n");
2059
2060         /*
2061         ** open the read-only file
2062         */
2063         if(*rdof == '\0') {
2064                 printk(KERN_ERR
2065                        "cowloop - specify name for read-only file\n\n");
2066                 return -EINVAL;
2067         }
2068
2069         f = filp_open(rdof, O_RDONLY|O_LARGEFILE, 0);
2070
2071         if ( (f == NULL) || IS_ERR(f) ) {
2072                 printk(KERN_ERR
2073                        "cowloop - open of rdofile %s failed\n", rdof);
2074                 return -EINVAL;
2075         }
2076
2077         cowdev->rdofp = f;
2078
2079         inode = f->f_dentry->d_inode;
2080
2081         if ( !S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode) ) {
2082                 printk(KERN_ERR
2083                        "cowloop - %s not regular file or blockdev\n", rdof);
2084                 return -EINVAL;
2085         }
2086
2087         DEBUGP(DCOW"cowloop - determine size rdo....\n");
2088
2089         /*
2090         ** determine block-size and total size of read-only file
2091         */
2092         if (S_ISREG(inode->i_mode)) {
2093                 /*
2094                 ** read-only file is a regular file
2095                 */
2096                 cowdev->blocksz   = 512;        /* other value fails */
2097                 cowdev->numblocks = inode->i_size >> MUSHIFT;
2098
2099                 if (inode->i_size & MUMASK) {
2100                         printk(KERN_WARNING
2101                                "cowloop - rdofile %s truncated to multiple "
2102                                "of %d bytes\n", rdof, MAPUNIT);
2103                 }
2104
2105                 DEBUGP(DCOW"cowloop - RO=regular: numblocks=%d, blocksz=%d\n",
2106                         cowdev->numblocks, cowdev->blocksz);
2107         } else {
2108                 /*
2109                 ** read-only file is a block device
2110                 */
2111                 cowdev->belowdev  = inode->i_bdev;
2112                 cowdev->belowgd   = cowdev->belowdev->bd_disk; /* gendisk */
2113
2114                 if (cowdev->belowdev->bd_part) {
2115                         cowdev->numblocks = cowdev->belowdev->bd_part->nr_sects
2116                                                                 / (MAPUNIT/512);
2117                 }
2118
2119                 if (cowdev->belowgd) {
2120                         cowdev->belowq = cowdev->belowgd->queue;
2121
2122                         if (cowdev->numblocks == 0) {
2123 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))
2124                                 cowdev->numblocks = get_capacity(cowdev->belowgd)
2125                                                                 / (MAPUNIT/512);
2126 #else
2127                                 cowdev->numblocks = cowdev->belowgd->capacity
2128                                                                 / (MAPUNIT/512);
2129 #endif
2130                         }
2131                 }
2132
2133
2134                 if (cowdev->belowq)
2135                         cowdev->blocksz = queue_logical_block_size(cowdev->belowq);
2136
2137                 if (cowdev->blocksz == 0)
2138                         cowdev->blocksz = BLOCK_SIZE; /* default 2^10 */
2139
2140                 DEBUGP(DCOW"cowloop - numblocks=%d, "
2141                            "blocksz=%d, belowgd=%p, belowq=%p\n",
2142                         cowdev->numblocks, cowdev->blocksz,
2143                         cowdev->belowgd, cowdev->belowq);
2144
2145                 DEBUGP(DCOW"cowloop - belowdev.bd_block_size=%d\n",
2146                         cowdev->belowdev->bd_block_size);
2147         }
2148
2149         if (cowdev->numblocks == 0) {
2150                 printk(KERN_ERR "cowloop - %s has no contents\n", rdof);
2151                 return -EINVAL;
2152         }
2153
2154         /*
2155         ** reserve space in memory as generic I/O buffer
2156         */
2157         cowdev->iobuf  = kmalloc(MAPUNIT, GFP_KERNEL);
2158
2159         if (!cowdev->iobuf) {
2160                 printk(KERN_ERR
2161                        "cowloop - cannot get space for buffer %d\n", MAPUNIT);
2162                 return -ENOMEM;
2163         }
2164
2165         DEBUGP(DCOW"cowloop - determine fingerprint rdo....\n");
2166
2167         /*
2168         ** determine fingerprint for read-only file
2169         **      calculate fingerprint from first four datablocks
2170         **      which do not contain binary zeroes
2171         */
2172         for (i=0, cowdev->fingerprint=0, nrval=0;
2173                         (nrval < 4)&&(i < cowdev->numblocks); i++) {
2174                 int             j;
2175                 unsigned char   cs;
2176
2177                 /*
2178                 ** read next block
2179                 */
2180                 if (cowlo_readrdo(cowdev, cowdev->iobuf, MAPUNIT,
2181                                                 (loff_t)i << MUSHIFT) < 1)
2182                         break;
2183
2184                 /*
2185                 ** calculate fingerprint by adding all byte-values
2186                 */
2187                 for (j=0, cs=0; j < MAPUNIT; j++)
2188                         cs += *(cowdev->iobuf+j);
2189
2190                 if (cs == 0)    /* block probably contained zeroes */
2191                         continue;
2192
2193                 /*
2194                 ** shift byte-value to proper place in final fingerprint
2195                 */
2196                 cowdev->fingerprint |= cs << (nrval*8);
2197                 nrval++;
2198         }
2199
2200         return 0;
2201 }
2202
2203 /*
2204 ** undo memory allocs and file opens issued so far
2205 ** related to the read-only file
2206 */
2207 static void
2208 cowlo_undo_openrdo(struct cowloop_device *cowdev)
2209 {
2210         if(cowdev->iobuf);
2211                 kfree(cowdev->iobuf);
2212
2213         if (cowdev->rdofp)
2214                 filp_close(cowdev->rdofp, 0);
2215 }
2216
2217 /*
2218 ** open the cowfile
2219 **
2220 ** returns:
2221 **      0   - okay
2222 **    < 0   - error value
2223 */
2224 static int
2225 cowlo_opencow(struct cowloop_device *cowdev, char *cowf, int autorecover)
2226 {
2227         long int                i, rv;
2228         int                     minor;
2229         unsigned long           nb;
2230         struct file             *f;
2231         struct inode            *inode;
2232         loff_t                  offset;
2233         struct cowloop_device   *cowtmp;
2234
2235         DEBUGP(DCOW"cowloop - opencow called\n");
2236
2237         /*
2238         ** open copy-on-write file (read-write)
2239         */
2240         if (cowf[0] == '\0') {
2241                 printk(KERN_ERR
2242                  "cowloop - specify name of copy-on-write file\n\n");
2243                 return -EINVAL;
2244         }
2245
2246         f = filp_open(cowf, O_RDWR|O_LARGEFILE, 0600);
2247
2248         if ( (f == NULL) || IS_ERR(f) ) {
2249                 /*
2250                 ** non-existing cowfile: try to create
2251                 */
2252                 f = filp_open(cowf, O_RDWR|O_CREAT|O_LARGEFILE, 0600);
2253
2254                 if ( (f == NULL) || IS_ERR(f) ) {
2255                         printk(KERN_ERR
2256                           "cowloop - failed to open file %s for read-write\n\n",
2257                                                                 cowf);
2258                         return -EINVAL;
2259                 }
2260         }
2261
2262         cowdev->cowfp = f;
2263
2264         inode = f->f_dentry->d_inode;
2265
2266         if (!S_ISREG(inode->i_mode)) {
2267                 printk(KERN_ERR "cowloop - %s is not regular file\n", cowf);
2268                 return -EINVAL;
2269         }
2270
2271         /*
2272         ** check if this cowfile is already in use for another cowdevice
2273         */
2274         for (minor = 0; minor < maxcows; minor++) {
2275
2276                 cowtmp = cowdevall[minor];
2277
2278                 if ( !(cowtmp->state & COWDEVOPEN) )
2279                         continue;
2280
2281                 if (cowtmp == cowdev)
2282                         continue;
2283
2284                 if (cowtmp->cowfp->f_dentry->d_inode == f->f_dentry->d_inode) {
2285                         printk(KERN_ERR
2286                                "cowloop - %s: already in use as cow\n", cowf);
2287                         return -EBUSY;
2288                 }
2289         }
2290
2291         /*
2292         ** mark cowfile open for read-write
2293         */
2294         cowdev->state |= COWRWCOWOPEN;
2295
2296         /*
2297         ** calculate size (in bytes) for total bitmap in cowfile;
2298         ** when the size of the cowhead block is added, the start-offset
2299         ** for the modified data blocks can be found
2300         */
2301         nb = cowdev->numblocks;
2302
2303         if (nb%8)               /* transform #bits to #bytes */
2304                 nb+=8;          /* rounded if necessary      */
2305         nb /= 8;
2306
2307         if (nb & MUMASK)        /* round up #bytes to MAPUNIT chunks */
2308                 cowdev->mapsize = ( (nb>>MUSHIFT) +1) << MUSHIFT;
2309         else
2310                 cowdev->mapsize = nb;
2311
2312         /*
2313         ** reserve space in memory for the cowhead
2314         */
2315         cowdev->cowhead = kmalloc(MAPUNIT, GFP_KERNEL);
2316
2317         if (!cowdev->cowhead) {
2318                 printk(KERN_ERR "cowloop - cannot get space for cowhead %d\n",
2319                                                                      MAPUNIT);
2320                 return -ENOMEM;
2321         }
2322
2323         memset(cowdev->cowhead, 0, MAPUNIT);
2324
2325         DEBUGP(DCOW"cowloop - prepare cowhead....\n");
2326
2327         /*
2328         ** check if the cowfile exists or should be created
2329         */
2330         if (inode->i_size != 0) {
2331                 /*
2332                 ** existing cowfile: read the cow head
2333                 */
2334                 if (inode->i_size < MAPUNIT) {
2335                         printk(KERN_ERR
2336                                "cowloop - existing cowfile %s too small\n",
2337                                 cowf);
2338                         return -EINVAL;
2339                 }
2340
2341                 cowlo_readcowraw(cowdev, cowdev->cowhead, MAPUNIT, (loff_t) 0);
2342
2343                 /*
2344                 ** verify if the existing file is really a cowfile
2345                 */
2346                 if (cowdev->cowhead->magic != COWMAGIC) {
2347                         printk(KERN_ERR
2348                                "cowloop - cowfile %s has incorrect format\n",
2349                                 cowf);
2350                         return -EINVAL;
2351                 }
2352
2353                 /*
2354                 ** verify the cowhead version of the cowfile
2355                 */
2356                 if (cowdev->cowhead->version > COWVERSION) {
2357                         printk(KERN_ERR
2358                                "cowloop - cowfile %s newer than this driver\n",
2359                                 cowf);
2360                         return -EINVAL;
2361                 }
2362
2363                 /*
2364                 ** make sure that this is not a packed cowfile
2365                 */
2366                 if (cowdev->cowhead->flags & COWPACKED) {
2367                         printk(KERN_ERR
2368                             "cowloop - packed cowfile %s not accepted\n", cowf);
2369                         return -EINVAL;
2370                 }
2371
2372                 /*
2373                 ** verify if the cowfile has been properly closed
2374                 */
2375                 if (cowdev->cowhead->flags & COWDIRTY) {
2376                         /*
2377                         ** cowfile was not properly closed;
2378                         ** check if automatic recovery is required
2379                         ** (actual recovery will be done later on)
2380                         */
2381                         if (!autorecover) {
2382                                 printk(KERN_ERR
2383                                        "cowloop - cowfile %s is dirty "
2384                                        "(not properly closed by rmmod?)\n",
2385                                         cowf);
2386                                 printk(KERN_ERR
2387                                        "cowloop - run cowrepair or specify "
2388                                        "'option=r' to recover\n");
2389                                 return -EINVAL;
2390                         }
2391                 }
2392
2393                 /*
2394                 ** verify if the cowfile is really related to this rdofile
2395                 */
2396                 if (cowdev->cowhead->rdoblocks != cowdev->numblocks) {
2397                         printk(KERN_ERR
2398                                "cowloop - cowfile %s (size %lld) not related "
2399                                "to rdofile (size %lld)\n",
2400                                 cowf,
2401                                 (long long)cowdev->cowhead->rdoblocks <<MUSHIFT,
2402                                 (long long)cowdev->numblocks <<MUSHIFT);
2403                         return -EINVAL;
2404                 }
2405
2406                 if (cowdev->cowhead->rdofingerprint != cowdev->fingerprint) {
2407                         printk(KERN_ERR
2408                              "cowloop - cowfile %s not related to rdofile "
2409                              " (fingerprint err - rdofile modified?)\n", cowf);
2410                         return -EINVAL;
2411                 }
2412         } else {
2413                 /*
2414                 ** new cowfile: determine the minimal size (cowhead+bitmap)
2415                 */
2416                 offset = (loff_t) MAPUNIT + cowdev->mapsize - 1;
2417
2418                 if ( cowlo_writecowraw(cowdev, "", 1, offset) < 1) {
2419                         printk(KERN_ERR
2420                                "cowloop - cannot set cowfile to size %lld\n",
2421                                 offset+1);
2422                         return -EINVAL;
2423                 }
2424
2425                 /*
2426                 ** prepare new cowhead
2427                 */
2428                 cowdev->cowhead->magic          = COWMAGIC;
2429                 cowdev->cowhead->version        = COWVERSION;
2430                 cowdev->cowhead->mapunit        = MAPUNIT;
2431                 cowdev->cowhead->mapsize        = cowdev->mapsize;
2432                 cowdev->cowhead->rdoblocks      = cowdev->numblocks;
2433                 cowdev->cowhead->rdofingerprint = cowdev->fingerprint;
2434                 cowdev->cowhead->cowused        = 0;
2435
2436                 /*
2437                 ** calculate start offset of data in cowfile,
2438                 ** rounded up to multiple of 4K to avoid
2439                 ** unnecessary disk-usage for written datablocks in
2440                 ** the sparsed cowfile on e.g. 4K filesystems
2441                 */
2442                 cowdev->cowhead->doffset =
2443                         ((MAPUNIT+cowdev->mapsize+4095)>>12)<<12;
2444         }
2445
2446         cowdev->cowhead->flags  = 0;
2447
2448         DEBUGP(DCOW"cowloop - reserve space bitmap....\n");
2449
2450         /*
2451         ** reserve space in memory for the entire bitmap and
2452         ** fill it with the bitmap-data from disk; the entire
2453         ** bitmap is allocated in several chunks because kmalloc
2454         ** has restrictions regarding the allowed size per kmalloc
2455         */
2456         cowdev->mapcount = (cowdev->mapsize+MAPCHUNKSZ-1)/MAPCHUNKSZ;
2457
2458         /*
2459         ** the size of every bitmap chunk will be MAPCHUNKSZ bytes, except for
2460         ** the last bitmap chunk: calculate remaining size for this chunk
2461         */
2462         if (cowdev->mapsize % MAPCHUNKSZ == 0)
2463                 cowdev->mapremain = MAPCHUNKSZ;
2464         else
2465                 cowdev->mapremain = cowdev->mapsize % MAPCHUNKSZ;
2466
2467         /*
2468         ** allocate space to store all pointers for the bitmap-chunks
2469         ** (initialize area with zeroes to allow proper undo)
2470         */
2471         cowdev->mapcache = kmalloc(cowdev->mapcount * sizeof(char *),
2472                                                                 GFP_KERNEL);
2473         if (!cowdev->mapcache) {
2474                 printk(KERN_ERR
2475                        "cowloop - can not allocate space for bitmap ptrs\n");
2476                 return -ENOMEM;
2477         }
2478
2479         memset(cowdev->mapcache, 0, cowdev->mapcount * sizeof(char *));
2480
2481         /*
2482         ** allocate space to store the bitmap-chunks themselves
2483         */
2484         for (i=0; i < cowdev->mapcount; i++) {
2485                 if (i < (cowdev->mapcount-1))
2486                         *(cowdev->mapcache+i) = kmalloc(MAPCHUNKSZ, GFP_KERNEL);
2487                 else
2488                         *(cowdev->mapcache+i) = kmalloc(cowdev->mapremain,
2489                                                                   GFP_KERNEL);
2490
2491                 if (*(cowdev->mapcache+i) == NULL) {
2492                         printk(KERN_ERR "cowloop - no space for bitmapchunk %ld"
2493                                         " totmapsz=%ld, mapcnt=%d mapunit=%d\n",
2494                                         i, cowdev->mapsize, cowdev->mapcount,
2495                                         MAPUNIT);
2496                         return -ENOMEM;
2497                 }
2498         }
2499
2500         DEBUGP(DCOW"cowloop - read bitmap from cow....\n");
2501
2502         /*
2503         ** read the entire bitmap from the cowfile into the in-memory cache;
2504         ** count the number of blocks that are in use already
2505         ** (statistical purposes)
2506         */
2507         for (i=0, offset=MAPUNIT; i < cowdev->mapcount;
2508                                         i++, offset+=MAPCHUNKSZ) {
2509                 unsigned long   numbytes;
2510
2511                 if (i < (cowdev->mapcount-1))
2512                         /*
2513                         ** full bitmap chunk
2514                         */
2515                         numbytes = MAPCHUNKSZ;
2516                 else
2517                         /*
2518                         ** last bitmap chunk: might be partly filled
2519                         */
2520                         numbytes = cowdev->mapremain;
2521
2522                 cowlo_readcowraw(cowdev, *(cowdev->mapcache+i),
2523                                                         numbytes, offset);
2524         }
2525
2526         /*
2527         ** if the cowfile was dirty and automatic recovery is required,
2528         ** reconstruct a proper bitmap in memory now
2529         */
2530         if (cowdev->cowhead->flags & COWDIRTY) {
2531                 unsigned long long      blocknum;
2532                 char                    databuf[MAPUNIT];
2533                 unsigned long           mapnum, mapbyte, mapbit;
2534
2535                 printk(KERN_NOTICE "cowloop - recover dirty cowfile %s....\n",
2536                                                         cowf);
2537
2538                 /*
2539                 ** read all data blocks
2540                 */
2541                 for (blocknum=0, rv=1, offset=0;
2542                         cowlo_readcow(cowdev, databuf, MAPUNIT, offset) > 0;
2543                         blocknum++, offset += MAPUNIT) {
2544
2545                         /*
2546                         ** if this datablock contains real data (not binary
2547                         ** zeroes), set the corresponding bit in the bitmap
2548                         */
2549                         if ( memcmp(databuf, allzeroes, MAPUNIT) == 0)
2550                                 continue;
2551
2552                         mapnum  = CALCMAP (blocknum);
2553                         mapbyte = CALCBYTE(blocknum);
2554                         mapbit  = CALCBIT (blocknum);
2555
2556                         *(*(cowdev->mapcache+mapnum)+mapbyte) |= (1<<mapbit);
2557                 }
2558
2559                 printk(KERN_NOTICE "cowloop - cowfile recovery completed\n");
2560         }
2561
2562         /*
2563         ** count all bits set in the bitmaps for statistical purposes
2564         */
2565         for (i=0, cowdev->nrcowblocks = 0; i < cowdev->mapcount; i++) {
2566                 long    numbytes;
2567                 char    *p;
2568
2569                 if (i < (cowdev->mapcount-1))
2570                         numbytes = MAPCHUNKSZ;
2571                 else
2572                         numbytes = cowdev->mapremain;
2573
2574                 p = *(cowdev->mapcache+i);
2575
2576                 for (numbytes--; numbytes >= 0; numbytes--, p++) {
2577                         /*
2578                         ** for only eight checks the following construction
2579                         ** is faster than a loop-construction
2580                         */
2581                         if ((*p) & 0x01)        cowdev->nrcowblocks++;
2582                         if ((*p) & 0x02)        cowdev->nrcowblocks++;
2583                         if ((*p) & 0x04)        cowdev->nrcowblocks++;
2584                         if ((*p) & 0x08)        cowdev->nrcowblocks++;
2585                         if ((*p) & 0x10)        cowdev->nrcowblocks++;
2586                         if ((*p) & 0x20)        cowdev->nrcowblocks++;
2587                         if ((*p) & 0x40)        cowdev->nrcowblocks++;
2588                         if ((*p) & 0x80)        cowdev->nrcowblocks++;
2589                 }
2590         }
2591
2592         /*
2593         ** consistency-check for number of bits set in bitmap
2594         */
2595         if ( !(cowdev->cowhead->flags & COWDIRTY) &&
2596             (cowdev->cowhead->cowused != cowdev->nrcowblocks) ) {
2597                 printk(KERN_ERR "cowloop - inconsistent cowfile admi\n");
2598                 return -EINVAL;
2599         }
2600
2601         return 0;
2602 }
2603
2604 /*
2605 ** undo memory allocs and file opens issued so far
2606 ** related to the cowfile
2607 */
2608 static void
2609 cowlo_undo_opencow(struct cowloop_device *cowdev)
2610 {
2611         int     i;
2612
2613         if (cowdev->mapcache) {
2614                 for (i=0; i < cowdev->mapcount; i++) {
2615                         if (*(cowdev->mapcache+i) != NULL)
2616                                 kfree( *(cowdev->mapcache+i) );
2617                 }
2618
2619                 kfree(cowdev->mapcache);
2620         }
2621
2622         if (cowdev->cowhead)
2623                 kfree(cowdev->cowhead);
2624
2625         if ( (cowdev->state & COWCOWOPEN) && (cowdev->cowfp) )
2626                 filp_close(cowdev->cowfp, 0);
2627
2628         /*
2629         ** mark cowfile closed
2630         */
2631         cowdev->state &= ~COWCOWOPEN;
2632 }
2633
2634 /*
2635 ** flush the entire bitmap and the cowhead (clean) to the cowfile
2636 **
2637 ** must be called with the cowdevices-lock set
2638 */
2639 static void
2640 cowlo_sync(void)
2641 {
2642         int                     i, minor;
2643         loff_t                  offset;
2644         struct cowloop_device   *cowdev;
2645
2646         for (minor=0; minor < maxcows;  minor++) {
2647                 cowdev = cowdevall[minor];
2648                 if ( ! (cowdev->state & COWRWCOWOPEN) )
2649                         continue;
2650
2651                 for (i=0, offset=MAPUNIT; i < cowdev->mapcount;
2652                                         i++, offset += MAPCHUNKSZ) {
2653                         unsigned long   numbytes;
2654
2655                         if (i < (cowdev->mapcount-1))
2656                                 /*
2657                                 ** full bitmap chunk
2658                                 */
2659                                 numbytes = MAPCHUNKSZ;
2660                         else
2661                                 /*
2662                                 ** last bitmap chunk: might be partly filled
2663                                 */
2664                                 numbytes = cowdev->mapremain;
2665
2666                         DEBUGP(DCOW
2667                                "cowloop - flushing bitmap %2d (%3ld Kb)\n",
2668                                                         i, numbytes/1024);
2669
2670                         if (cowlo_writecowraw(cowdev, *(cowdev->mapcache+i),
2671                                                 numbytes, offset) < numbytes) {
2672                                 break;
2673                         }
2674                 }
2675
2676                 /*
2677                 ** flush clean up-to-date cowhead to cowfile
2678                 */
2679                 cowdev->cowhead->cowused         = cowdev->nrcowblocks;
2680                 cowdev->cowhead->flags          &= ~COWDIRTY;
2681
2682                 DEBUGP(DCOW "cowloop - flushing cowhead (%3d Kb)\n",
2683                                                         MAPUNIT/1024);
2684
2685                 cowlo_writecowraw(cowdev, cowdev->cowhead, MAPUNIT, (loff_t) 0);
2686         }
2687 }
2688
2689 /*****************************************************************************/
2690 /* Module loading/unloading                                                  */
2691 /*****************************************************************************/
2692
2693 /*
2694 ** called during insmod/modprobe
2695 */
2696 static int __init
2697 cowlo_init_module(void)
2698 {
2699         int     rv;
2700         int     minor, uptocows;
2701
2702         revision[sizeof revision - 3] = '\0';
2703
2704         printk(KERN_NOTICE "cowloop - (C) 2009 ATComputing.nl - version: %s\n", &revision[11]);
2705         printk(KERN_NOTICE "cowloop - info: www.ATComputing.nl/cowloop\n");
2706
2707         memset(allzeroes, 0, MAPUNIT);
2708
2709         /*
2710         ** Setup administration for all possible cowdevices.
2711         ** Note that their minor numbers go from 0 to MAXCOWS-1 inclusive
2712         ** and minor == MAXCOWS-1 is reserved for the control device.
2713         */
2714         if ((maxcows < 1) || (maxcows > MAXCOWS)) {
2715                 printk(KERN_WARNING
2716                        "cowloop - maxcows exceeds maximum of %d\n", MAXCOWS);
2717
2718                 maxcows = DFLCOWS;
2719         }
2720
2721         /* allocate room for a table with a pointer to each cowloop_device: */
2722         if ( (cowdevall = kmalloc(maxcows * sizeof(struct cowloop_device *),
2723                                                         GFP_KERNEL)) == NULL) {
2724                 printk(KERN_WARNING
2725                         "cowloop - can not alloc table for %d devs\n", maxcows);
2726                 uptocows = 0;
2727                 rv = -ENOMEM;
2728                 goto error_out;
2729         }
2730         memset(cowdevall, 0, maxcows * sizeof(struct cowloop_device *));
2731         /* then hook an actual cowloop_device struct to each pointer: */
2732         for (minor=0; minor < maxcows; minor++) {
2733                 if ((cowdevall[minor] = kmalloc(sizeof(struct cowloop_device),
2734                                                 GFP_KERNEL)) == NULL) {
2735                         printk(KERN_WARNING
2736                            "cowloop - can not alloc admin-struct for dev no %d\n", minor);
2737
2738                         uptocows = minor; /* this is how far we got.... */
2739                         rv = -ENOMEM;
2740                         goto error_out;
2741                 }
2742                 memset(cowdevall[minor], 0, sizeof(struct cowloop_device));
2743         }
2744         uptocows = maxcows; /* we got all devices */
2745
2746         sema_init(&cowdevlock, 1);
2747
2748         /*
2749         ** register cowloop module
2750         */
2751         if ( register_blkdev(COWMAJOR, DEVICE_NAME) < 0) {
2752                 printk(KERN_WARNING
2753                     "cowloop - unable to get major %d for cowloop\n", COWMAJOR);
2754                 rv = -EIO;
2755                 goto error_out;
2756         }
2757
2758         /*
2759         ** create a directory below /proc to allocate a file
2760         ** for each cowdevice that is allocated later on
2761         */
2762         cowlo_procdir = proc_mkdir("cow", NULL);
2763
2764         /*
2765         ** check if a cowdevice has to be opened during insmod/modprobe;
2766         ** two parameters should be specified then: rdofile= and cowfile=
2767         */
2768         if( (rdofile[0] != '\0') && (cowfile[0] != '\0') ) {
2769                 char    *po = option;
2770                 int     wantrecover = 0;
2771
2772                 /*
2773                 ** check if automatic recovery is wanted
2774                 */
2775                 while (*po) {
2776                         if (*po == 'r') {
2777                                 wantrecover = 1;
2778                                 break;
2779                         }
2780                         po++;
2781                 }
2782
2783                 /*
2784                 ** open new cowdevice with minor number 0
2785                 */
2786                 if ( (rv = cowlo_openpair(rdofile, cowfile, wantrecover, 0))) {
2787                         remove_proc_entry("cow", NULL);
2788                         unregister_blkdev(COWMAJOR, DEVICE_NAME);
2789                         goto error_out;
2790                 }
2791         } else {
2792                 /*
2793                 ** check if only one parameter has been specified
2794                 */
2795                 if( (rdofile[0] != '\0') || (cowfile[0] != '\0') ) {
2796                         printk(KERN_ERR
2797                                "cowloop - only one filename specified\n");
2798                         remove_proc_entry("cow", NULL);
2799                         unregister_blkdev(COWMAJOR, DEVICE_NAME);
2800                         rv = -EINVAL;
2801                         goto error_out;
2802                 }
2803         }
2804
2805         /*
2806         ** allocate fake disk as control channel to handle the requests
2807         ** to activate and deactivate cowdevices dynamically
2808         */
2809         if (!(cowctlgd = alloc_disk(1))) {
2810                 printk(KERN_WARNING
2811                        "cowloop - unable to alloc_disk for cowctl\n");
2812
2813                 remove_proc_entry("cow", NULL);
2814                 (void) cowlo_closepair(cowdevall[0]);
2815                 unregister_blkdev(COWMAJOR, DEVICE_NAME);
2816                 rv = -ENOMEM;
2817                 goto error_out;
2818         }
2819
2820         spin_lock_init(&cowctlrqlock);
2821         cowctlgd->major        = COWMAJOR;
2822         cowctlgd->first_minor  = COWCTL;
2823         cowctlgd->minors       = 1;
2824         cowctlgd->fops         = &cowlo_fops;
2825         cowctlgd->private_data = NULL;
2826         /* the device has capacity 0, so there will be no q-requests */
2827         cowctlgd->queue = blk_init_queue(NULL, &cowctlrqlock);
2828         sprintf(cowctlgd->disk_name, "cowctl");
2829         set_capacity(cowctlgd, 0);
2830
2831         add_disk(cowctlgd);
2832
2833         printk(KERN_NOTICE "cowloop - number of configured cowdevices: %d\n",
2834                                                                 maxcows);
2835         if (rdofile[0] != '\0') {
2836             printk(KERN_NOTICE "cowloop - initialized on rdofile=%s\n",
2837                                                                 rdofile);
2838         } else {
2839             printk(KERN_NOTICE "cowloop - initialized without rdofile yet\n");
2840         }
2841         return 0;
2842
2843 error_out:
2844         for (minor=0; minor < uptocows ; minor++) {
2845                 kfree(cowdevall[minor]);
2846         }
2847         kfree(cowdevall);
2848         return rv;
2849 }
2850
2851 /*
2852 ** called during rmmod
2853 */
2854 static void __exit
2855 cowlo_cleanup_module(void)
2856 {
2857         int     minor;
2858
2859         /*
2860         ** flush bitmaps and cowheads to the cowfiles
2861         */
2862         down(&cowdevlock);
2863         cowlo_sync();
2864         up(&cowdevlock);
2865
2866         /*
2867         ** close all cowdevices
2868         */
2869         for (minor=0; minor < maxcows;  minor++)
2870                 (void) cowlo_closepair(cowdevall[minor]);
2871
2872 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23))
2873         unregister_blkdev(COWMAJOR, DEVICE_NAME);
2874 #else
2875         if (unregister_blkdev(COWMAJOR, DEVICE_NAME) != 0)
2876                 printk(KERN_WARNING "cowloop - cannot unregister blkdev\n");
2877 #endif
2878
2879         /*
2880         ** get rid of /proc/cow and unregister the driver
2881         */
2882         remove_proc_entry("cow", NULL);
2883
2884         for (minor = 0; minor < maxcows; minor++) {
2885                 kfree(cowdevall[minor]);
2886         }
2887         kfree(cowdevall);
2888
2889         del_gendisk(cowctlgd);  /* revert the alloc_disk() */
2890         put_disk   (cowctlgd);  /* revert the add_disk()   */
2891         blk_cleanup_queue(cowctlgd->queue); /* cleanup the empty queue */
2892
2893         printk(KERN_NOTICE "cowloop - unloaded\n");
2894 }
2895
2896 module_init(cowlo_init_module);
2897 module_exit(cowlo_cleanup_module);